diff options
Diffstat (limited to 'src/cpu/p6/mtrr.c')
-rw-r--r-- | src/cpu/p6/mtrr.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/src/cpu/p6/mtrr.c b/src/cpu/p6/mtrr.c index ac6fd1db37..7e2eb06e95 100644 --- a/src/cpu/p6/mtrr.c +++ b/src/cpu/p6/mtrr.c @@ -104,7 +104,8 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l if (sizek < 4*1024*1024) { mask.hi = ADDRESS_MASK_HIGH; mask.lo = ~((sizek << 10) -1); - } else { + } + else { mask.hi = ADDRESS_MASK_HIGH & (~((sizek >> 22) -1)); mask.lo = 0; } @@ -131,6 +132,36 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l enable_cache(); } +/* setting variable mtrr, comes from linux kernel source */ +void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type) +{ + if (reg >= 8) + return; + + // it is recommended that we disable and enable cache when we + // do this. + disable_cache(); + if (size == 0) { + /* The invalid bit is kept in the mask, so we simply clear the + relevant mask register to disable a range. */ + msr_t zero; + zero.lo = zero.hi = 0; + wrmsr (MTRRphysMask_MSR(reg), zero); + } else { + /* Bit 32-35 of MTRRphysMask should be set to 1 */ + msr_t basem, maskm; + basem.lo = base | type; + basem.hi = 0; + maskm.lo = ~(size - 1) | 0x800; + maskm.hi = 0x0F; + wrmsr (MTRRphysBase_MSR(reg), basem); + wrmsr (MTRRphysMask_MSR(reg), maskm); + } + + // turn cache back on. + enable_cache(); +} + /* fms: find most sigificant bit set, stolen from Linux Kernel Source. */ static inline unsigned int fms(unsigned int x) { @@ -250,7 +281,7 @@ static unsigned int range_to_mtrr(unsigned int reg, } sizek = 1 << align; printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type WB\n", - reg, range_startk >>10, sizek >> 10); + reg, range_startk >>10, sizek >> 10); intel_set_var_mtrr(reg++, range_startk, sizek, MTRR_TYPE_WRBACK); range_startk += sizek; range_sizek -= sizek; @@ -274,7 +305,7 @@ void setup_mtrrs(struct mem_range *mem) /* Initialized the fixed_mtrrs to uncached */ printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n", 0, NUM_FIXED_RANGES); - set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHABLE); + set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE); /* Now see which of the fixed mtrrs cover ram. */ |