Model Specific Registers: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
m (Fixed link)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(10 intermediate revisions by 8 users not shown)
Line 1: Line 1:
Processors from P6 family (including Pentium PRO, Pentium 3 & 4) have a collection of registers that allows configuration of various things such as memory type-range, sysenter/sysexit, local APIC, etc.
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 ==
== Accessing Model Specific Registers ==


Each MSR has a single 32-bit identification number that will be given to RDMSR or WRMSR assembly instructions to operate it. MSRs are 64-bit wide. The presence of MSRs on your processor is indicated by [[CPUID]].01h:EDX[bit 5].
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].

<syntaxhighlight lang="c">

const uint32_t CPUID_FLAG_MSR = 1 << 5;


<source lang="c">
bool cpuHasMSR()
bool cpuHasMSR()
{
{
uint32_t a, d;
static uint32_t a, d; // eax, edx
cpuid(1, &a, &d);
cpuid(1, &a, &d);
return d & CPUID_FLAG_MSR;
return d & CPUID_FLAG_MSR;
Line 15: Line 19:
void cpuGetMSR(uint32_t msr, uint32_t *lo, uint32_t *hi)
void cpuGetMSR(uint32_t msr, uint32_t *lo, uint32_t *hi)
{
{
asm volatile("rdmsr":"=a"(*lo),"=d"(*hi):"c"(msr));
asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr));
}
}


void cpuSetMSR(uint32_t msr, uint32_t lo, uint32_t hi)
void cpuSetMSR(uint32_t msr, uint32_t lo, uint32_t hi)
{
{
asm volatile("wrmsr"::"a"(lo),"d"(hi),"c"(msr));
asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr));
}
}
</syntaxhighlight>
</source>

===Other way to access MSRs===

<code>rdmsr</code> and <code>wrmsr</code> are privileged instructions. However, there are a few MSRs that can be accessed from non-privileged code using special instructions. For example, the <code>rdtsc</code> instruction is a non-privileged instruction that reads the timestamp counter, which is actually situated in an MSR (index 10h).

==Additional x86_64 Registers==

AMD added the [[CPU_Registers_x86-64#IA32_EFER|EFER]] register for controlling specific long mode features. It has since been adopted by Intel.


{|
===Other access to MSRs===
|Bit 0
|System Call Extensions (SCE)
|-
|Bits 1-7
|Reserved
|-
|Bit 8
|Long Mode Enable (LME)
|-
|Bit 9
|Reserved
|-
|Bit 10
|Long Mode Active (LMA)
|-
|Bit 11
|No-Execute Enable (NXE)
|-
|Bit 12
|Secure Virtual Machine Enable (SVME)
|-
|Bit 13
|Long Mode Segment Limit Enable (LMSLE)
|-
|Bit 14
|fast FXSAVE/FXSTOR (FFXSR)
|-
|Bit 15
|Translation Cache Extension (TCE)
|-
|Bits 16-63
|Reserved
|}


The by far most interesting is the SCE Bit, as it enables the <code>syscall</code> instruction.
As <code>rdmsr</code> and <code>wrmsr</code> are priveleged instructions, there are a few MSRs which are deemed safe for non-priveleged access. For example, the <code>rdtsc</code> instruction is a non priveleged instruction which will read the timestamp counter which is actually situated in an MSR (index 10h).


==See Also==
==See Also==
===Articles===
===Articles===
*[[CPUID]]
*[[CPUID]]
*[[CPU Registers x86]]
*[[CPU Registers x86-64]]


===External Links===
===External Links===
*http://sandpile.org/x86/msr.htm
*http://sandpile.org/x86/msr.htm for documented MSRs
*https://github.com/xen-project/xen/blob/master/xen/include/asm-x86/msr-index.h for MSRs relevant to Xen emulation (including Intel's 0x35)


[[Category:x86 CPU]]
[[Category:x86 CPU]]
[[Category:CPU Registers]]
[[de:Model-Specific_Register]]

Latest revision as of 05:37, 9 June 2024

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()
{
   static 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).

Additional x86_64 Registers

AMD added the EFER register for controlling specific long mode features. It has since been adopted by Intel.

Bit 0 System Call Extensions (SCE)
Bits 1-7 Reserved
Bit 8 Long Mode Enable (LME)
Bit 9 Reserved
Bit 10 Long Mode Active (LMA)
Bit 11 No-Execute Enable (NXE)
Bit 12 Secure Virtual Machine Enable (SVME)
Bit 13 Long Mode Segment Limit Enable (LMSLE)
Bit 14 fast FXSAVE/FXSTOR (FFXSR)
Bit 15 Translation Cache Extension (TCE)
Bits 16-63 Reserved

The by far most interesting is the SCE Bit, as it enables the syscall instruction.

See Also

Articles

External Links