Model Specific Registers
Processors from the P6 family onwards (including PentiumPro, Pentium II, III, 4 and Intel Core) have a collection of registers that allow configuration of OS-relevant things such as memory type-range, sysenter/sysexit, local APIC, etc. These MSRs are accessed using special instructions such as RDMSR (Read MSR), WRMSR (Write MSR), and RDTSC.
Contents |
Accessing Model Specific Registers
Each MSR that is accessed by the RDMSR and WRMSR group of instructions is identified by a 32-bit integer. MSRs are 64-bit wide. The presence of MSRs on your processor is indicated by CPUID.01h:EDX[bit 5].
const uint32_t CPUID_FLAG_MSR = 1 << 5; bool cpuHasMSR() { uint32_t a, d; // eax, edx cpuid(1, &a, &d); return d & CPUID_FLAG_MSR; } void cpuGetMSR(uint32_t msr, uint32_t *lo, uint32_t *hi) { asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); } void cpuSetMSR(uint32_t msr, uint32_t lo, uint32_t hi) { asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); }
Other way to access MSRs
rdmsr and wrmsr are privileged instructions. However, there are a few MSRs that can be accessed from non-privileged code using special instructions. For example, the rdtsc instruction is a non-privileged instruction that reads the timestamp counter, which is actually situated in an MSR (index 10h).