diff options
Diffstat (limited to 'src/cpu/k8')
-rw-r--r-- | src/cpu/k8/cpufixup.c | 59 | ||||
-rw-r--r-- | src/cpu/k8/earlymtrr.inc | 99 |
2 files changed, 158 insertions, 0 deletions
diff --git a/src/cpu/k8/cpufixup.c b/src/cpu/k8/cpufixup.c new file mode 100644 index 0000000000..9f306d1156 --- /dev/null +++ b/src/cpu/k8/cpufixup.c @@ -0,0 +1,59 @@ +/* Needed so the AMD K8 runs correctly. */ +#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) + +void k8_cpufixup(struct mem_range *mem) +{ + unsigned long lo = 0, hi = 0, 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. + */ + for(i = 0; mem[i].sizek; i++) + ; + if (i == 0) + return; + ram_megabytes = (mem[i-1].basek + mem[i-1].sizek) *1024; + + + // 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); + rdmsr(TOP_MEM, lo, hi); + printk_spew("TOPMEM was 0x%02x:0x%02x\n", hi, lo); + hi = 0; + lo = ram_megabytes; + wrmsr(TOP_MEM, lo, hi); + + // I am setting this even though I won't enable it + wrmsr(TOP_MEM2, lo, hi); + + /* zero the IORR's before we enable to prevent + * undefined side effects + */ + lo = hi = 0; + for (i = IORR_FIRST; i <= IORR_LAST; i++) + wrmsr(i, lo, hi); + + rdmsr(SYSCFG, lo, hi); + printk_spew("SYSCFG was 0x%x:0x%x\n", hi, lo); + lo |= MTRRVARDRAMEN; + wrmsr(SYSCFG, lo, hi); + rdmsr(SYSCFG, lo, hi); + printk_spew("SYSCFG IS NOW 0x%x:0x%x\n", hi, lo); +} + diff --git a/src/cpu/k8/earlymtrr.inc b/src/cpu/k8/earlymtrr.inc new file mode 100644 index 0000000000..7cd8443618 --- /dev/null +++ b/src/cpu/k8/earlymtrr.inc @@ -0,0 +1,99 @@ +#include <cpu/k8/mtrr.h> + +/* The fixed and variable MTRRs are powered-up with random values, clear them to + * MTRR_TYPE_UNCACHABLE for safty reason + */ + +earlymtrr_start: + xorl %eax, %eax # clear %eax and %edx + xorl %edx, %edx # + movl $fixed_mtrr_msr, %esi + +clear_fixed_var_mtrr: + lodsl (%esi), %eax + testl %eax, %eax + jz clear_fixed_var_mtrr_out + + movl %eax, %ecx + xorl %eax, %eax + wrmsr + + jmp clear_fixed_var_mtrr +clear_fixed_var_mtrr_out: + +/* enable memory access for 0 - 8MB using top_mem */ + movl $TOP_MEM, %ecx + xorl %edx, %edx + movl $0x0800000, %eax + wrmsr + +set_var_mtrr: + /* enable caching for 0 - 128MB using variable mtrr */ + movl $0x200, %ecx + rdmsr + andl $0xfffffff0, %edx + orl $0x00000000, %edx + andl $0x00000f00, %eax + orl $0x00000006, %eax + wrmsr + + movl $0x201, %ecx + rdmsr + andl $0xfffffff0, %edx + orl $0x0000000f, %edx + andl $0x000007ff, %eax + orl $0xf0000800, %eax + wrmsr + +#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE) + /* enable write protect caching so we can do execute in place + * on the flash rom. + */ + movl $0x202, %ecx + xorl %edx, %edx + movl $(XIP_ROM_BASE | 0x005), %eax + wrmsr + + movl $0x203, %ecx + movl $0x0000000f, %edx + movl $(~(XIP_ROM_SIZE - 1) | 0x800), %eax + wrmsr +#endif /* XIP_ROM_SIZE && XIP_ROM_BASE */ + +enable_mtrr: + /* Set the default memory type and enable fixed and variable MTRRs */ + movl $0x2ff, %ecx + xorl %edx, %edx + /* Enable Variable MTRRs */ + movl $0x00000800, %eax + wrmsr + + /* Enable the MTRRs in SYSCFG */ + movl $SYSCFG_MSR, %ecx + rdmsr + orl $(SYSCFG_MSR_MtrrVarDramEn), %eax + wrmsr + + /* enable cache */ + movl %cr0, %eax + andl $0x9fffffff,%eax + movl %eax, %cr0 + + jmp earlymtrr_end + +fixed_mtrr_msr: + .long 0x250, 0x258, 0x259 + .long 0x268, 0x269, 0x26A + .long 0x26B, 0x26C, 0x26D + .long 0x26E, 0x26F +var_mtrr_msr: + .long 0x200, 0x201, 0x202, 0x203 + .long 0x204, 0x205, 0x206, 0x207 + .long 0x208, 0x209, 0x20A, 0x20B + .long 0x20C, 0x20D, 0x20E, 0x20F +var_iorr_msr: + .long 0xC0010016, 0xC0010017, 0xC0010018, 0xC0010019 +mem_top: + .long 0xC001001A, 0xC001001D + .long 0x000 /* NULL, end of table */ +earlymtrr_end: |