- Moved hlt() to it's own header.
[coreboot.git] / src / cpu / p6 / mtrr.c
index 413acb18839b6d860d70ee76dd2c7adeae5286fc..7e2eb06e95646b977542d0cc4ec60af038f0422f 100644 (file)
 
 #define arraysize(x)   (sizeof(x)/sizeof((x)[0]))
 
+#ifdef k8
+# define ADDRESS_BITS 40
+#else
+# define ADDRESS_BITS 36
+#endif
+#define ADDRESS_BITS_HIGH (ADDRESS_BITS - 32)
+#define ADDRESS_MASK_HIGH ((1u << ADDRESS_BITS_HIGH) - 1)
+
 static unsigned int mtrr_msr[] = {
        MTRRfix64K_00000_MSR, MTRRfix16K_80000_MSR, MTRRfix16K_A0000_MSR,
        MTRRfix4K_C0000_MSR, MTRRfix4K_C8000_MSR, MTRRfix4K_D0000_MSR, MTRRfix4K_D8000_MSR,
@@ -40,20 +48,20 @@ static unsigned int mtrr_msr[] = {
 
 static void intel_enable_fixed_mtrr(void)
 {
-       unsigned long low, high;
+       msr_t msr;
 
-       rdmsr(MTRRdefType_MSR, low, high);
-       low |= 0xc00;
-       wrmsr(MTRRdefType_MSR, low, high);
+       msr = rdmsr(MTRRdefType_MSR);
+       msr.lo |= 0xc00;
+       wrmsr(MTRRdefType_MSR, msr);
 }
 
 static void intel_enable_var_mtrr(void)
 {
-       unsigned long low, high;
+       msr_t msr;
 
-       rdmsr(MTRRdefType_MSR, low, high);
-       low |= 0x800;
-       wrmsr(MTRRdefType_MSR, low, high);
+       msr = rdmsr(MTRRdefType_MSR);
+       msr.lo |= 0x800;
+       wrmsr(MTRRdefType_MSR, msr);
 }
 
 static inline void disable_cache(void)
@@ -86,19 +94,20 @@ static inline void enable_cache(void)
 /* setting variable mtrr, comes from linux kernel source */
 static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
 {
-       unsigned long base_high, base_low;
-       unsigned long  mask_high, mask_low;
+       msr_t base, mask;
+
+       base.hi = basek >> 22;
+       base.lo  = basek << 10;
 
-       base_high = basek >> 22;
-       base_low  = basek << 10;
+       //printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
 
        if (sizek < 4*1024*1024) {
-               mask_high = 0x0F;
-               mask_low = ~((sizek << 10) -1);
+               mask.hi = ADDRESS_MASK_HIGH;
+               mask.lo = ~((sizek << 10) -1);
        }
        else {
-               mask_high = 0x0F & (~((sizek >> 22) -1));
-               mask_low = 0;
+               mask.hi = ADDRESS_MASK_HIGH & (~((sizek >> 22) -1));
+               mask.lo = 0;
        }
 
        if (reg >= 8)
@@ -108,13 +117,17 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
        // do this. 
        disable_cache();
        if (sizek == 0) {
+               msr_t zero;
+               zero.lo = zero.hi = 0;
                /* The invalid bit is kept in the mask, so we simply clear the
                   relevant mask register to disable a range. */
-               wrmsr (MTRRphysMask_MSR (reg), 0, 0);
+               wrmsr (MTRRphysMask_MSR(reg), zero);
        } else {
                /* Bit 32-35 of MTRRphysMask should be set to 1 */
-               wrmsr (MTRRphysBase_MSR(reg), base_low | type, base_high);
-               wrmsr (MTRRphysMask_MSR(reg), mask_low | 0x800, mask_high);
+               base.lo |= type;
+               mask.lo |= 0x800;
+               wrmsr (MTRRphysBase_MSR(reg), base);
+               wrmsr (MTRRphysMask_MSR(reg), mask);
        }
        enable_cache();
 }
@@ -131,11 +144,18 @@ void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsi
        if (size == 0) {
                /* The invalid bit is kept in the mask, so we simply clear the
                   relevant mask register to disable a range. */
-               wrmsr (MTRRphysMask_MSR (reg), 0, 0);
+               msr_t zero;
+               zero.lo = zero.hi = 0;
+               wrmsr (MTRRphysMask_MSR(reg), zero);
        } else {
                /* Bit 32-35 of MTRRphysMask should be set to 1 */
-               wrmsr (MTRRphysBase_MSR (reg), base | type, 0);
-               wrmsr (MTRRphysMask_MSR (reg), ~(size - 1) | 0x800, 0x0F);
+               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. 
@@ -197,32 +217,32 @@ static void set_fixed_mtrrs(unsigned int first, unsigned int last, unsigned char
 {
        unsigned int i;
        unsigned int fixed_msr = NUM_FIXED_RANGES >> 3;
-       unsigned long low, high;
-       low = high = 0; /* Shut up gcc */
+       msr_t msr;
+       msr.lo = msr.hi = 0; /* Shut up gcc */
        for(i = first; i < last; i++) {
                /* When I switch to a new msr read it in */
                if (fixed_msr != i >> 3) {
                        /* But first write out the old msr */
                        if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
                                disable_cache();
-                               wrmsr(mtrr_msr[fixed_msr], low, high);
+                               wrmsr(mtrr_msr[fixed_msr], msr);
                                enable_cache();
                        }
                        fixed_msr = i>>3;
-                       rdmsr(mtrr_msr[fixed_msr], low, high);
+                       msr = rdmsr(mtrr_msr[fixed_msr]);
                }
                if ((i & 7) < 4) {
-                       low &= ~(0xff << ((i&3)*8));
-                       low |= type << ((i&3)*8);
+                       msr.lo &= ~(0xff << ((i&3)*8));
+                       msr.lo |= type << ((i&3)*8);
                } else {
-                       high &= ~(0xff << ((i&3)*8));
-                       high |= type << ((i&3)*8);
+                       msr.hi &= ~(0xff << ((i&3)*8));
+                       msr.hi |= type << ((i&3)*8);
                }
        }
        /* Write out the final msr */
        if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
                disable_cache();
-               wrmsr(mtrr_msr[fixed_msr], low, high);
+               wrmsr(mtrr_msr[fixed_msr], msr);
                enable_cache();
        }
 }
@@ -285,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.
         */