Model Specific Registers

From OSDev.wiki
Revision as of 15:38, 8 May 2013 by osdev>Demonkoryu (Minor cleanup)
Jump to navigation Jump to search

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.

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).

See Also

Articles

External Links