Intel architecture ia-32 User Manual

Page of 636
Vol. 3A 10-39
MEMORY CACHE CONTROL
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 algo-
rithm 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 inval-
idations occur.
10.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.