MTRR: Difference between revisions

6,846 bytes added ,  8 months ago
[unchecked revision][unchecked revision]
No edit summary
 
(6 intermediate revisions by 5 users not shown)
Line 1:
'''MTRR''', stands foror '''Memory -Type Range Registers.''' are a group of x86 [[Model Specific Registers]]
providing a way to control access and cacheability of physical memory regions. These were introduced
in the Intel Pentium Pro (P6) processor, intended to extend and enhance the memory type information
provided by page tables (i.e. the write-through and cache disable bits).
 
The set of registers is provided in two groups: 11 registers for 88 fixed ranges and a number of base-mask pairs
==History==
for custom range configuration. The exact number of the latter can be known by reading the capabilities register.
The MTRR were introduced in the Intel Pentium Pro (P6) processor. They were intended to extend and enhance the memory type information provided by page tables (i.e. the write-through and cache disable bits).
 
While this method is available in most new Intel and AMD processors, preference
==Implementation Details==
should be given to [[Page Attribute Tables]] instead, as many of the systems usually
* Register IA32_MTRRCAP is MSR[FE]
configure these during early boot from UEFI/BIOS and changing MTRRs which were set up by the firmware
* There are 8 variable ranges, split into a base and mask:
may lead to unexpected problems.
** IA32_MTRR_PHYSBASE{x=0..7}, in MSR[200+x*2]
** IA32_MTRR_PHYSMASK{x=0..7}, in MSR[201+x*2]
* There are 88 fixed ranges, covering the bottom 1MB
** IA32_MTRR_FIX64K_00000, in MSR[250] - 8 regions of 64 KB each (512 KB total)
** IA32_MTRR_FIX16K_80000, in MSR[258] - 8 regions of 16 KB each (128 KB total)
** IA32_MTRR_FIX16K_A0000, in MSR[259] - 8 regions of 16 KB each (128 KB total)
** IA32_MTRR_FIX4K_C0000, in MSR[268] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_C8000, in MSR[269] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_D0000, in MSR[26A] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_D8000, in MSR[26B] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_E0000, in MSR[26C] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_E8000, in MSR[26D] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_F0000, in MSR[26E] - 8 regions of 4 KB each (32 KB total)
** IA32_MTRR_FIX4K_F8000, in MSR[26F] - 8 regions of 4 KB each (32 KB total)
 
==Memory types==
[[Category:Stubs]]
 
There are 5 memory types defined for use in MTRRs:
 
{| class="wikitable" border="1"
|-
! Number
! Name
! Description
|-
| 0
| UC — Uncacheable
| All accesses are uncacheable. Write combining is not allowed. Speculative accesses are not allowed.
|-
| 1
| WC — Write-Combining
| All accesses are uncacheable. Write combining is allowed. Speculative reads are allowed.
|-
| 4
| WT — Writethrough
| Reads allocate cache lines on a cache miss. Cache lines are not allocated on a write miss.
Write hits update the cache and main memory.
|-
| 5
| WP — Write-Protect
| Reads allocate cache lines on a cache miss. All writes update main memory.
Cache lines are not allocated on a write miss. Write hits invalidate the cache
line and update main memory.
|-
| 6
| WB — Writeback
| Reads allocate cache lines on a cache miss, and can allocate to either the shared,
exclusive, or modified state. Writes allocate to the modified state on a cache miss.
|}
 
==Accessing MTRRs==
 
Before attempting reads/writes to MTRRs, the operating system should first check the availability
of this feature by checking if [[CPUID]].01h:EDX[bit 12] is set.
 
Once the feature is known to be available, the following MSRs can be used for configuration:
 
====IA32_MTRRCAP (MSR 0xFE)====
 
This register describes memory range types and count supported by the implementation. The register is read-only.
 
{| class="wikitable" border="1"
|-
! Bit(s)
! Label
! Description
|-
| 63..11
| -
| Reserved
|-
| 10
| WC
| Write-combining type is available
|-
| 9
| -
| Reserved
|-
| 8
| FIX
| ''All'' fixed-size MTRRs are available
|-
| 7..0
| VCNT
| Count of variable-size MTRRs supported
|}
 
====IA32_MTRRdefType (MSR 0x2FF)====
 
Describes the default type used for physical addresses which are outside of any configured memory ranges,
as well as whether MTRRs and fixed ranges are enabled.
 
{| class="wikitable" border="1"
|-
! Bit(s)
! Label
! Description
|-
| 63..12
| -
| Reserved
|-
| 11
| E
| MTRR enable
|-
| 10
| FE
| Fixed range enable
|-
| 9..8
| -
| Reserved
|-
| 7..0
| Type
| Default memory type
|}
 
====IA32_MTRRphysBase''n'' and IA32_MTRRphysMask''n'' registers====
 
These allow defining custom memory ranges using base-mask pairs and have the following addresses:
 
* IA32_MTRRphysBase''n'' = 0x200 + (n * 2)
* IA32_MTRRphysMask''n'' = 0x201 + (n * 2)
 
Where ''n'' parameter ranges from 0 to IA32_MTRRdefType[VCNT].
 
Base register has the following bits:
 
{| class="wikitable" border="1"
|-
! Bit(s)
! Label
! Description
|-
| 63..52
| -
| Reserved
|-
| 51..12
| PhysBase
| Range base address
|-
| 11..8
| -
| Reserved
|-
| 7..0
| Type
| Range memory type
|}
 
"Mask" registers use bits 51:12 to specify the region mask
and bit 11 ("Valid" bit) tells if the region is enabled.
If your CPU supports address widths of less than 52 bits, the remaining bits are reserved.
Writing to these reserved bits will trigger a General Protection Fault.
 
The processor uses the following algorithm to check if an address
is covered by an MTRR:
 
MaskBase = PhysMask AND PhysBase
MaskTarget = PhysMask AND Target_Address[51:12]
IF MaskBase == MaskTarget
target address is in range
ELSE
target address is not in range
 
The mask is calculated like this: <code>~(size - 1) & ((1 << ADDRESS_WIDTH) - 1)</code> where <code>ADDRESS WIDTH</code> is the maximum supported address width of your CPU. Both the mask and base must be
aligned to at least 4K boundary (thus must be shifted to the right by 12 to fit into the 51:12 range) and the size '''must''' be equal to
the boundary, on which the range is aligned. So, in order to have, for
example, a 6M-long range, one would need to set up two MTRRs, one
4M and the other 2M.
 
====IA32_MTRRfix''size''_''base''====
 
If supported by implementation, the specification defines a set of
11 registers allowing the configuration of addresses in lowest 1M
block.
 
Each fixed-size range register contains 8 eight-bit type fields
and the address block is split in different sizes:
 
{| class="wikitable" border="1"
|-
! 63-56
! 55-48
! 47-40
! 39-32
! 31-24
! 23-16
! 15-8
! 7-0
!rowspan=2| Register
|-
!colspan=8| Address range
|-
| 70000-7FFFF
| 60000-6FFFF
| 50000-5FFFF
| 40000-4FFFF
| 30000-3FFFF
| 20000-2FFFF
| 10000-1FFFF
| 00000-0FFFF
| MTRRfix64K_00000
|-
| 9C000-9FFFF
| 98000-9BFFF
| 94000-97FFF
| 90000-93FFF
| 8C000-8FFFF
| 88000-8BFFF
| 84000-87FFF
| 80000-83FFF
| MTRRfix16K_80000
|-
| BC000-BFFFF
| B8000-BBFFF
| B4000-B7FFF
| B0000-B3FFF
| AC000-AFFFF
| A8000-ABFFF
| A4000-A7FFF
| A0000-A3FFF
| MTRRfix16K_A0000
|-
| C7000-C7FFF
| C6000-C6FFF
| C5000-C5FFF
| C4000-C4FFF
| C3000-C3FFF
| C2000-C2FFF
| C1000-C1FFF
| C0000-C0FFF
| MTRRfix4K_C0000
|-
| CF000-CFFFF
| CE000-CEFFF
| CD000-CDFFF
| CC000-CCFFF
| CB000-CBFFF
| CA000-CAFFF
| C9000-C9FFF
| C8000-C8FFF
| MTRRfix4K_C8000
|-
| D7000-D7FFF
| D6000-D6FFF
| D5000-D5FFF
| D4000-D4FFF
| D3000-D3FFF
| D2000-D2FFF
| D1000-D1FFF
| D0000-D0FFF
| MTRRfix4K_D0000
|-
| DF000-DFFFF
| DE000-DEFFF
| DD000-DDFFF
| DC000-DCFFF
| DB000-DBFFF
| DA000-DAFFF
| D9000-D9FFF
| D8000-D8FFF
| MTRRfix4K_D8000
|-
| E7000-E7FFF
| E6000-E6FFF
| E5000-E5FFF
| E4000-E4FFF
| E3000-E3FFF
| E2000-E2FFF
| E1000-E1FFF
| E0000-E0FFF
| MTRRfix4K_E0000
|-
| EF000-EFFFF
| EE000-EEFFF
| ED000-EDFFF
| EC000-ECFFF
| EB000-EBFFF
| EA000-EAFFF
| E9000-E9FFF
| E8000-E8FFF
| MTRRfix4K_E8000
|-
| F7000-F7FFF
| F6000-F6FFF
| F5000-F5FFF
| F4000-F4FFF
| F3000-F3FFF
| F2000-F2FFF
| F1000-F1FFF
| F0000-F0FFF
| MTRRfix4K_F0000
|-
| FF000-FFFFF
| FE000-FEFFF
| FD000-FDFFF
| FC000-FCFFF
| FB000-FBFFF
| FA000-FAFFF
| F9000-F9FFF
| F8000-F8FFF
| MTRRfix4K_F8000
|}
 
Fixed-size range registers have are:
 
* MTRRfix64K_00000 — MSR 0x250
* MTRRfix16K_80000 — MSR 0x258
* MTRRfix16K_A0000 — MSR 0x259
* MTRRfix4K_C0000 — MSR 0x268
* MTRRfix4K_C8000 — MSR 0x269
* MTRRfix4K_D0000 — MSR 0x26A
* MTRRfix4K_D8000 — MSR 0x26B
* MTRRfix4K_E0000 — MSR 0x26C
* MTRRfix4K_E8000 — MSR 0x26D
* MTRRfix4K_F0000 — MSR 0x26E
* MTRRfix4K_F8000 — MSR 0x26F
 
==Combining with page-level control==
 
Both MTRR and [[Page Tables]] allow setting cache-disable and writethrough
attributes for memory regions — there may be cases when such ranges overlap. How MTRR and page entry bits work in combination (if the PAT register wasn't modified):
 
=== Without PAT ===
 
{| class="wikitable" border="1"
|-
! MTRR type !! Page CD bit !! Page WT bit !! Resulting type
|-
| UC || — || — || UC
|-
|rowspan=3|WC || 0 || — || WC
|-
| 1 || 0 || WC (impl. dependent)
|-
| 1 || 1 || UC
|-
|rowspan=2|WP || 0 || — || WP
|-
| 1 || — || UC
|-
|rowspan=2|WT || 0 || — || WT
|-
| 1 || — || UC
|-
|rowspan=3|WB || 0 || 0 || WB
|-
| 0 || 1 || WT
|-
| 1 || — || UC
|}
 
=== With PAT ===
 
{| class="wikitable" border="1"
|-
! MTRR type !! PAT Entry Value !! Resulting type
|-
|rowspan=6|UC || UC || UC
|-
| UC- || UC
|-
| WC || WC
|-
| WT || UC
|-
| WB || UC
|-
| WP || UC
|-
|rowspan=6|WC || UC || UC
|-
| UC- || WC
|-
| WC || WC
|-
| WT || UC
|-
| WB || WC
|-
| WP || UC
|-
|rowspan=6|WT || UC || UC
|-
| UC- || UC
|-
| WC || WC
|-
| WT || WT
|-
| WB || WT
|-
| WP || WP
|-
|rowspan=6|WB || UC || UC
|-
| UC- || UC
|-
| WC || WC
|-
| WT || WT
|-
| WB || WB
|-
| WP || WP
|-
|rowspan=6|WP || UC || UC
|-
| UC- || WC
|-
| WC || WC
|-
| WT || WT
|-
| WB || WP
|-
| WP || WP
|}
 
[[Category:X86 CPU‏‎]]
Anonymous user