diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/k8/cpufixup.c | 74 |
1 files changed, 33 insertions, 41 deletions
diff --git a/src/cpu/k8/cpufixup.c b/src/cpu/k8/cpufixup.c index 8e7ad95d5d..573064071d 100644 --- a/src/cpu/k8/cpufixup.c +++ b/src/cpu/k8/cpufixup.c @@ -2,60 +2,52 @@ #include <console/console.h> #include <mem.h> #include <cpu/p6/msr.h> - -#define TOP_MEM 0xc001001A -#define TOP_MEM2 0xc001001D -#define IORR_FIRST 0xC0010016 -#define IORR_LAST 0xC0010019 -#define SYSCFG 0xC0010010 - -#define MTRRVARDRAMEN (1 << 20) +#include <cpu/k8/mtrr.h> +#include <device/device.h> void k8_cpufixup(struct mem_range *mem) { - msr_t msr; + unsigned long mmio_basek, tomk; unsigned long i; - unsigned long ram_megabytes; - - /* For now no Athlon board has significant holes in it's - * address space so just find the last memory region - * and compute the end of memory from that. + msr_t msr; + /* Except for the PCI MMIO hold just before 4GB there are no + * significant holes in the address space, so just account + * for those two and move on. */ - for(i = 0; mem[i].sizek; i++) - ; - if (i == 0) - return; - ram_megabytes = (mem[i-1].basek + mem[i-1].sizek) *1024; - - -#warning "FIXME handle > 4GB of ram" - // 8 MB alignment please - ram_megabytes += 0x7fffff; - ram_megabytes &= (~0x7fffff); - - // set top_mem registers to ram size - printk_spew("Setting top_mem to 0x%x\n", ram_megabytes); - msr = rdmsr(TOP_MEM); - printk_spew("TOPMEM was 0x%02x:0x%02x\n", msr.hi, msr.lo); - msr.hi = 0; - msr.lo = ram_megabytes; + mmio_basek = tomk = 0; + for(i = 0; mem[i].sizek; i++) { + unsigned long topk; + topk = mem[i].basek + mem[i].sizek; + if (tomk < topk) { + tomk = topk; + } + if ((topk < 4*1024*1024) && (mmio_basek < topk)) { + mmio_basek = topk; + } + } + if (mmio_basek > tomk) { + mmio_basek = tomk; + } + + /* Setup TOP_MEM */ + msr.hi = mmio_basek >> 22; + msr.lo = mmio_basek << 10; wrmsr(TOP_MEM, msr); - // I am setting this even though I won't enable it + /* Setup TOP_MEM2 */ + msr.hi = tomk >> 22; + msr.lo = tomk << 12; wrmsr(TOP_MEM2, msr); /* zero the IORR's before we enable to prevent - * undefined side effects + * undefined side effects. */ msr.lo = msr.hi = 0; - for (i = IORR_FIRST; i <= IORR_LAST; i++) + for(i = IORR_FIRST; i <= IORR_LAST; i++) { wrmsr(i, msr); - + } + msr = rdmsr(SYSCFG); - printk_spew("SYSCFG was 0x%x:0x%x\n", msr.hi, msr.lo); - msr.lo |= MTRRVARDRAMEN; + msr.lo |= SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_TOM2En; wrmsr(SYSCFG, msr); - msr = rdmsr(SYSCFG); - printk_spew("SYSCFG IS NOW 0x%x:0x%x\n", msr.hi, msr.lo); } - |