diff --git a/src/cpu/p6/l2_cache.c b/src/cpu/p6/l2_cache.c index c70a299166..1a5c463419 100644 --- a/src/cpu/p6/l2_cache.c +++ b/src/cpu/p6/l2_cache.c @@ -35,24 +35,21 @@ static char rcsid[] = "$Id$"; #include #include +#include #include /* Include debugging code and outputs */ //#define DEBUG #include -static int signal_l2(unsigned int address_high, - unsigned int address_low, - unsigned int data_high, - unsigned int data_low, int way, int command); +static int signal_l2(unsigned int address_high, unsigned int address_low, + unsigned int data_high, unsigned int data_low, + int way, int command); static int read_l2(unsigned int address); static int write_l2(unsigned int address, int data); -static int write_l2_2(unsigned int address, - unsigned int data1, unsigned int data2); -static int test_l2_address_alias(unsigned int address1, - unsigned int address2, - unsigned int data_high, - unsigned int data_low); +static int write_l2_2(unsigned int address, unsigned int data1, unsigned int data2); +static int test_l2_address_alias(unsigned int address1, unsigned int address2, + unsigned int data_high, unsigned int data_low); static int calculate_l2_latency(void); static int set_l2_register4(int l); static int calculate_l2_cache_size(void); @@ -65,6 +62,7 @@ static void cache_disable(void) /* Disable cache */ printk( KERN_INFO "Disable Cache\n"); + /* Write back the cache and flush TLB */ asm volatile ("movl %%cr0, %0\n\t" "orl $0x40000000, %0\n\t" @@ -82,6 +80,7 @@ static void cache_enable(void) "andl $0x9fffffff, %0\n\t" "movl %0, %%cr0\n\t" :"=r" (tmp) : : "memory"); + printk( KERN_INFO "Enable Cache\n"); } @@ -118,7 +117,7 @@ int intel_l2_configure() } /* Read BBL_CR_CTL3 */ - rdmsr(0x11e, eax, edx); + rdmsr(BBL_CR_CTL3, eax, edx); /* If bit 23 (L2 Hardware disable) is set then done */ if (eax & 0x800000) { DBG("L2 Hardware disabled\n"); @@ -129,7 +128,7 @@ int intel_l2_configure() /* 0x630 signature setup */ /* Read EBL_CR_POWERON */ - rdmsr(0x2a, eax, edx); + rdmsr(EBL_CR_POWERON, eax, edx); /* Mask out [22-24] Clock frequency ratio */ eax &= 0x1c00000; @@ -141,7 +140,7 @@ int intel_l2_configure() cache_disable(); /* Read BBL_CR_CTL3 */ - rdmsr(0x11e, eax, edx); + rdmsr(BBL_CR_CTL3, eax, edx); /* Mask out: * [0] L2 Configured * [5] ECC Check Enable @@ -161,7 +160,7 @@ int intel_l2_configure() */ eax |= 0x44000; /* Write BBL_CR_CTL3 */ - wrmsr(0x11e, eax, edx); + wrmsr(BBL_CR_CTL3, eax, edx); } else { int calc_eax; int v; diff --git a/src/cpu/p6/mtrr.c b/src/cpu/p6/mtrr.c index 2df8f6d965..64c6b18fa5 100644 --- a/src/cpu/p6/mtrr.c +++ b/src/cpu/p6/mtrr.c @@ -31,6 +31,7 @@ static char rcsid[] = "$Id$"; #include #include +#define DEBUG #include #define arraysize(x) (sizeof(x)/sizeof((x)[0])) @@ -155,6 +156,23 @@ void intel_set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size } + +/* + * fms: find most sigificant bit set. + * + * stolen from Linux Kernel Source + */ +static __inline__ int fms(int x) +{ + int r; + + __asm__("bsrl %1,%0\n\t" + "jnz 1f\n\t" + "movl $0,%0\n" + "1:" : "=r" (r) : "g" (x)); + return r; +} + /* setting up variable and fixed mtrr ToDo: 1. still need to find out how to set size and alignment correctly 2. should we invalid cache by INVLD or WBINVD ?? */ @@ -162,33 +180,32 @@ void intel_set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size #ifdef ENABLE_FIXED_AND_VARIABLE_MTRRS void intel_set_mtrr(unsigned long rambase, unsigned long ramsizeK) { + unsigned int reg = 0; + unsigned long range; -#ifdef SIS630 - /* hardcoded for 128MB SDRAM, 4 MB SMA */ - // change this 10/29/00 RGM - // set WRBACk to the size of ram, and SMA to the last 4M - // This works because Ollie fixed Dram setup with SPD - // coming in, from sis sizeram, the size is size of ram - - // 256M. We should probably change the way this is done. - // For now, take ramsizeK, add 4M, that's it. - // you have to round up the ramsize because MTRRs - // have to be on a power of two boundary. - // BUT: UC and WB types are allowed to overlap. - // so there is no problem with letting MTRR 0 overlap MTRR 1 - printk(KERN_INFO "set_mtrr: rambase is 0x%x, ramsizeK is 0x%x\n", - rambase, ramsizeK); + DBG("\n"); + while (ramsizeK != 0 && reg <= 3) { + intel_post(0x60 + reg); - printk(KERN_INFO "setting MTRR 0 size to 0x%x\n", - (ramsizeK + 4096) * 1024); - intel_set_var_mtrr(0, 0, (ramsizeK + 4096) * 1024, MTRR_TYPE_WRBACK); - intel_set_var_mtrr(1, (ramsizeK * 1024), - 4096 * 1024, MTRR_TYPE_UNCACHABLE); - printk(KERN_INFO "MTRRs set\n"); + range = 1 << fms(ramsizeK); + DBG("Setting variable MTRR %d, base: %dMB, range: %dMB, type: WB\n", + reg, rambase >> 10, range >> 10); -#else /* SIS630 */ - printk("Setting variable MTRR 0 to %dK\n", ramsizeK); - intel_set_var_mtrr(0, 0, ramsizeK * 1024, MTRR_TYPE_WRBACK); -#endif /* SIS630 */ + intel_set_var_mtrr(reg, rambase * 1024, range * 1024, MTRR_TYPE_WRBACK); + + rambase += range; + ramsizeK -= range; + reg++; + } + + /* The "remainder" of the memory ranges. FixMe: should we secrify this range or set it + as WB and trust Linux Kernel (or Intel CPU ?? ) */ + if (ramsizeK != 0) { + range = 1 << (fms(ramsizeK) + 1); + DBG("Setting variable MTRR %d, base: %dMB, range: %dMB, type: UC\n", + reg, rambase >> 10, range >> 10); + intel_set_var_mtrr(reg, rambase * 1024, range * 1024, MTRR_TYPE_UNCACHABLE); + } intel_set_fixed_mtrr(); @@ -201,7 +218,7 @@ void intel_set_mtrr(unsigned long rambase, unsigned long ramsizeK) { intel_set_var_mtrr(0, 0, ramsizeK * 1024, MTRR_TYPE_WRBACK); intel_enable_var_mtrr(); -// intel_set_fixed_mtrr(); + //intel_set_fixed_mtrr(); } #endif /* ENABLE_FIXED_AND_VARIABLE_MTRRS */ #endif /* INTEL_PPRO_MTRR */ diff --git a/src/lib/subr.c b/src/lib/subr.c index cf182b8903..a8b1a14bd4 100644 --- a/src/lib/subr.c +++ b/src/lib/subr.c @@ -142,7 +142,7 @@ void intel_cache_on(unsigned long base, unsigned long totalram) // set_mtrr is responsible for getting it into the right units! intel_set_mtrr(base, totalram); #endif - intel_post(0x62); + intel_post(0x6A); } void intel_interrupts_on()