11-46 Vol. 3
MEMORY CACHE CONTROL
END
The physical address to variable range mapping algorithm in the MemTypeSet func-
tion 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.