#pragma once #if !defined(BAD_APPLE_OS_CPU_HPP_INCLUDED) #define BAD_APPLE_OS_CPU_HPP_INCLUDED #include namespace baos::cpu { enum class MSR : std::uint32_t { IA32_EFER = 0xC000'0080, STAR = 0xC000'0081, // segments for syscall LSTAR = 0xC000'0082, // instruction pointer for syscall }; inline constexpr std::uint64_t IA32_EFER_SYSTEM_CALL_EXTENSIONS_BIT = (1 << 0); inline constexpr std::uint64_t IA32_EFER_LONG_MODE_ENABLE_BIT = (1 << 8); inline constexpr std::uint64_t IA32_EFER_LONG_MODE_ACTIVE_BIT = (1 << 10); inline constexpr std::uint64_t IA32_EFER_NO_EXECUTE_ENABLE_BIT = (1 << 11); // ... inline std::uint64_t readMSR(MSR msr) noexcept { std::uint32_t lowHalf = 0; std::uint32_t highHalf = 0; __asm__ __volatile__( "rdmsr" : "=a"(lowHalf), "=d"(highHalf) : "c"(msr) ); return static_cast(highHalf) << 32 | lowHalf; } inline void writeMSR(MSR msr, std::uint64_t value) noexcept { std::uint32_t lowHalf = static_cast(value & 0xFFFFFFFF); std::uint32_t highHalf = static_cast(value >> 32); __asm__ __volatile__( "wrmsr" : : "a"(lowHalf), "d"(highHalf), "c"(msr) ); } inline void setMSRBits(MSR msr, std::uint64_t bits) noexcept { writeMSR(msr, readMSR(msr) | bits); } inline void unsetMSRBits(MSR msr, std::uint64_t bits) noexcept { writeMSR(msr, readMSR(msr) & ~bits); } } #endif // !defined(BAD_APPLE_OS_CPU_HPP_INCLUDED)