summaryrefslogtreecommitdiff
path: root/src/cpu/k8
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/k8')
-rw-r--r--src/cpu/k8/cpufixup.c59
-rw-r--r--src/cpu/k8/earlymtrr.inc99
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: