58 lines
1.5 KiB
C++

#pragma once
#if !defined(BAD_APPLE_OS_CPU_HPP_INCLUDED)
#define BAD_APPLE_OS_CPU_HPP_INCLUDED
#include <cstdint>
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<std::uint64_t>(highHalf) << 32 | lowHalf;
}
inline void writeMSR(MSR msr, std::uint64_t value) noexcept
{
std::uint32_t lowHalf = static_cast<std::uint32_t>(value & 0xFFFFFFFF);
std::uint32_t highHalf = static_cast<std::uint32_t>(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)