Commit 8bc25c76 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Make MTRR init conform with recommended procedure

From: Zwane Mwaikambo <zwane@linuxpower.ca>

This is a patch to make the MTRR initialisation more conformant with what
is stated in volume 3 of (10-36 Memory Cache Control).  The most notable
change is entering the no-fill cache mode before clearing the PGE bit in
cr4.  Intel also states that we should do the cache flush via the cr3
register shuffle.  If there is a problem with the patch please don't
hesitate to beat me vigorously with a clue-by-four.

It has been tested on a 3x Pentium 133, 8x PIII Xeon 700, 1x Celeron 550 and 32x
PIII 500 NUMAQ (hardware courtesy of OSDL)
parent 66c37726
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/tlbflush.h>
#include "mtrr.h" #include "mtrr.h"
struct mtrr_state { struct mtrr_state {
...@@ -241,18 +242,20 @@ static void prepare_set(void) ...@@ -241,18 +242,20 @@ static void prepare_set(void)
more invasive changes to the way the kernel boots */ more invasive changes to the way the kernel boots */
spin_lock(&set_atomicity_lock); spin_lock(&set_atomicity_lock);
/* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
cr0 = read_cr0() | 0x40000000; /* set CD flag */
wbinvd();
write_cr0(cr0);
wbinvd();
/* Save value of CR4 and clear Page Global Enable (bit 7) */ /* Save value of CR4 and clear Page Global Enable (bit 7) */
if ( cpu_has_pge ) { if ( cpu_has_pge ) {
cr4 = read_cr4(); cr4 = read_cr4();
write_cr4(cr4 & (unsigned char) ~(1 << 7)); write_cr4(cr4 & (unsigned char) ~(1 << 7));
} }
/* Disable and flush caches. Note that wbinvd flushes the TLBs as /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
a side-effect */ __flush_tlb();
cr0 = read_cr0() | 0x40000000;
wbinvd();
write_cr0(cr0);
wbinvd();
/* Save MTRR state */ /* Save MTRR state */
rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
...@@ -265,6 +268,7 @@ static void post_set(void) ...@@ -265,6 +268,7 @@ static void post_set(void)
{ {
/* Flush caches and TLBs */ /* Flush caches and TLBs */
wbinvd(); wbinvd();
__flush_tlb();
/* Intel (P6) standard MTRRs */ /* Intel (P6) standard MTRRs */
wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); wrmsr(MTRRdefType_MSR, deftype_lo, deftype_hi);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment