Handout
This commit is contained in:
103
arch/core_msr.h
Normal file
103
arch/core_msr.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*! \file
|
||||
* \brief \ref Core::MSRs "Identifiers" for \ref Core::MSR "Model-Specific
|
||||
* Register"
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
|
||||
namespace Core {
|
||||
/*! \brief Model-Specific Register Identifiers
|
||||
*
|
||||
* Selection of useful identifiers.
|
||||
*
|
||||
* \see [ISDMv4](intel_manual_vol4.pdf)
|
||||
*/
|
||||
enum MSRs {
|
||||
MSR_PLATFORM_INFO =
|
||||
0xce, ///< Platform information including bus frequency (Intel)
|
||||
MSR_TSC_DEADLINE = 0x6e0, ///< Register for \ref LAPIC::Timer Deadline mode
|
||||
// Fast system calls
|
||||
// XXX: Remove if we don't do fast syscalls
|
||||
MSR_EFER =
|
||||
0xC0000080, ///< Extended Feature Enable Register, \see Core::MSR_EFER
|
||||
MSR_STAR = 0xC0000081, ///< eip (protected mode), ring 0 and 3 segment bases
|
||||
MSR_LSTAR = 0xC0000082, ///< rip (long mode)
|
||||
MSR_SFMASK = 0xC0000084, ///< lower 32 bit: flag mask, if bit is set
|
||||
///< corresponding rflag is cleared through syscall
|
||||
|
||||
// CPU local variables
|
||||
MSR_FS_BASE = 0xC0000100,
|
||||
MSR_GS_BASE = 0xC0000101, ///< Current GS base pointer
|
||||
MSR_SHADOW_GS_BASE = 0xC0000102, ///< Usually called `MSR_KERNEL_GS_BASE` but
|
||||
///< this is misleading
|
||||
};
|
||||
|
||||
/* \brief Important bits in Extended Feature Enable Register (EFER)
|
||||
*
|
||||
* \see [ISDMv3, 2.2.1 Extended Feature Enable
|
||||
* Register](intel_manual_vol3.pdf#page=69)
|
||||
* \see [AAPMv2, 3.1.7 Extended Feature Enable
|
||||
* Register](amd64_manual_vol2.pdf#page=107)
|
||||
*/
|
||||
enum MSR_EFER {
|
||||
MSR_EFER_SCE = 1 << 0, ///< System Call Extensions
|
||||
MSR_EFER_LME = 1 << 8, ///< Long mode enable
|
||||
MSR_EFER_LMA = 1 << 10, ///< Long mode active
|
||||
MSR_EFER_NXE = 1 << 11, ///< No-Execute Enable
|
||||
MSR_EFER_SVME = 1 << 12, ///< Secure Virtual Machine Enable
|
||||
MSR_EFER_LMSLE = 1 << 13, ///< Long Mode Segment Limit Enable
|
||||
MSR_EFER_FFXSR = 1 << 14, ///< Fast `FXSAVE`/`FXRSTOR` instruction
|
||||
MSR_EFER_TCE = 1 << 15, ///< Translation Cache Extension
|
||||
};
|
||||
|
||||
/*! \brief Access to the Model-Specific Register (MSR)
|
||||
*
|
||||
* \see [ISDMv3, 9.4 Model-Specific Registers
|
||||
* (MSRs)](intel_manual_vol3.pdf#page=319)
|
||||
* \see [ISDMv4](intel_manual_vol4.pdf)
|
||||
* \tparam id ID of the Model-Specific Register to access
|
||||
*/
|
||||
template <enum MSRs id>
|
||||
class MSR {
|
||||
/*! \brief Helper to access low and high bits of a 64 bit value
|
||||
* \internal
|
||||
*/
|
||||
union uint64_parts {
|
||||
struct {
|
||||
uint32_t low;
|
||||
uint32_t high;
|
||||
} __attribute__((packed));
|
||||
uint64_t value;
|
||||
|
||||
explicit uint64_parts(uint64_t value = 0) : value(value) {}
|
||||
};
|
||||
|
||||
public:
|
||||
/*! \brief Read the value of the current MSR
|
||||
*
|
||||
* \return Value stored in the MSR
|
||||
*
|
||||
* \see [ISDMv2, Chapter 4. RDMSR - Read from Model Specific
|
||||
* Register](intel_manual_vol2.pdf#page=1186)
|
||||
*/
|
||||
static inline uint64_t read() {
|
||||
uint64_parts p;
|
||||
asm volatile("rdmsr \n\t" : "=a"(p.low), "=d"(p.high) : "c"(id));
|
||||
return p.value;
|
||||
}
|
||||
|
||||
/*! \brief Write a value into the current MSR
|
||||
*
|
||||
* \param value Value to write into the MSR
|
||||
*
|
||||
* \see [ISDMv2, Chapter 5. WRMSR - Write to Model Specific
|
||||
* Register](intel_manual_vol2.pdf#page=1912)
|
||||
*/
|
||||
static inline void write(uint64_t value) {
|
||||
uint64_parts p(value);
|
||||
asm volatile("wrmsr \n\t" : : "c"(id), "a"(p.low), "d"(p.high));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
Reference in New Issue
Block a user