Intel 64 and IA-32 Architectures Software Developers Manual Volume 3A, System Programming Guide, Part 1

10-42 Vol. 3A
MEMORY CACHE CONTROL
pre_mtrr_change()
BEGIN
disable interrupts;
Save current value of CR4;
disable and flush caches;
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 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.