background image

11-32 Vol. 3A

MEMORY CACHE CONTROL

flush TLBs;

disable MTRRs;

IF multiprocessing

THEN maintain consistency through IPIs;

FI;

END

post_mtrr_change()

BEGIN

flush caches and TLBs;

enable MTRRs;

enable caches;

restore value of CR4;

enable interrupts;

END

The physical address to variable range mapping algorithm in the MemTypeSet function detects conflicts with 
current variable range registers by cycling through them and determining whether the physical address in question 
matches any of the current ranges. During this scan, the algorithm can detect whether any current variable ranges 
overlap and can be concatenated into a single range.
The pre_mtrr_change() function disables interrupts prior to changing the MTRRs, to avoid executing code with a 
partially valid MTRR setup. The algorithm disables caching by setting the CD flag and clearing the NW flag in control 
register CR0. The caches are invalidated using the WBINVD instruction. The algorithm flushes all TLB entries either 
by clearing the page-global enable (PGE) flag in control register CR4 (if PGE was already set) or by updating control 
register CR3 (if PGE was already clear). Finally, it disables MTRRs by clearing the E flag in the 
IA32_MTRR_DEF_TYPE MSR.
After the memory type is updated, the post_mtrr_change() function re-enables the MTRRs and again invalidates 
the caches and TLBs. This second invalidation is required because of the processor's aggressive prefetch of both 
instructions and data. The algorithm restores interrupts and re-enables caching by setting the CD flag.
An operating system can batch multiple MTRR updates so that only a single pair of cache invalidations occur.

11.11.8  MTRR Considerations in MP Systems

In MP (multiple-processor) systems, the operating systems must maintain MTRR consistency between all the 
processors in the system. The Pentium 4, Intel Xeon, and P6 family processors provide no hardware support to 
maintain this consistency. In general, all processors must have the same MTRR values.
This requirement implies that when the operating system initializes an MP system, it must load the MTRRs of the 
boot processor while the E flag in register MTRRdefType is 0. The operating system then directs other processors to 
load their MTRRs with the same memory map. After all the processors have loaded their MTRRs, the operating 
system signals them to enable their MTRRs. Barrier synchronization is used to prevent further memory accesses 
until all processors indicate that the MTRRs are enabled. This synchronization is likely to be a shoot-down style 
algorithm, with shared variables and interprocessor interrupts.
Any change to the value of the MTRRs in an MP system requires the operating system to repeat the loading and 
enabling process to maintain consistency, using the following procedure:
1. Broadcast to all processors to execute the following code sequence.
2. Disable interrupts.
3. Wait for all processors to reach this point.
4. Enter the no-fill cache mode. (Set the CD flag in control register CR0 to 1 and the NW flag to 0.)
5. Flush all caches using the WBINVD instructions. Note on a processor that supports self-snooping, CPUID 

feature flag bit 27, this step is unnecessary.

6. If the PGE flag is set in control register CR4, flush all TLBs by clearing that flag.