d5ccfc299dde0c333395aa164c6d3a9ead90930d
[coreboot.git] / src / cpu / k8 / cpufixup.c
1 /* Needed so the AMD K8 runs correctly.  */
2 #include <console/console.h>
3 #include <mem.h>
4 #include <cpu/p6/msr.h>
5 #include <cpu/k8/mtrr.h>
6 #include <device/device.h>
7 #include <device/chip.h>
8
9 #include "chip.h"
10
11 void k8_cpufixup(struct mem_range *mem)
12 {
13         unsigned long mmio_basek, tomk;
14         unsigned long i;
15         msr_t msr;
16         /* Except for the PCI MMIO hold just before 4GB there are no
17          * significant holes in the address space, so just account
18          * for those two and move on.
19          */
20         mmio_basek = tomk = 0;
21         for(i = 0; mem[i].sizek; i++) {
22                 unsigned long topk;
23                 topk = mem[i].basek + mem[i].sizek;
24                 if (tomk < topk) {
25                         tomk = topk;
26                 }
27                 if ((topk < 4*1024*1024) && (mmio_basek < topk)) {
28                         mmio_basek = topk;
29                 }
30         }
31         if (mmio_basek > tomk) {
32                 mmio_basek = tomk;
33         }
34
35 #if 1
36         /* Report the amount of memory. */
37         print_debug("cpufixup RAM: 0x");
38         print_debug_hex32(tomk);
39         print_debug(" KB\r\n");
40 #endif
41
42         /* Now set top of memory */
43         msr.lo = (tomk & 0x003fffff) << 10;
44         msr.hi = (tomk & 0xffc00000) >> 22;
45         wrmsr(TOP_MEM2, msr);
46
47         /* Leave a 64M hole between TOP_MEM and TOP_MEM2
48          * so I can see my rom chip and other I/O devices.
49          */
50         if (tomk >= 0x003f0000) {
51                 tomk = 0x3f0000;
52         } //    tom_k = 0x3c0000;
53         msr.lo = (tomk & 0x003fffff) << 10;
54         msr.hi = (tomk & 0xffc00000) >> 22;
55         wrmsr(TOP_MEM, msr);
56
57
58         /* zero the IORR's before we enable to prevent
59          * undefined side effects.
60          */
61         msr.lo = msr.hi = 0;
62         for(i = IORR_FIRST; i <= IORR_LAST; i++) {
63                 wrmsr(i, msr);
64         }
65         
66         msr = rdmsr(SYSCFG_MSR);
67         msr.lo |= SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_TOM2En;
68         wrmsr(SYSCFG_MSR, msr);
69 }
70
71 static
72 void k8_enable(struct chip *chip, enum chip_pass pass)
73 {
74
75         struct cpu_k8_config *conf = (struct cpu_k8_config *)chip->chip_info;
76
77         switch (pass) {
78         case CONF_PASS_PRE_CONSOLE:
79                 break;
80         case CONF_PASS_PRE_PCI:
81                 init_timer();
82                 break;
83         default:
84                 /* nothing yet */
85                 break;
86         }
87 }
88
89 struct chip_control cpu_k8_control = {
90         enable: k8_enable,
91         name:   "AMD K8"
92 };
93
94
95
96