- First stab at running linuxbios without the old static device tree.
[coreboot.git] / src / cpu / amd / model_fxx / model_fxx_init.c
1 /* Needed so the AMD K8 runs correctly.  */
2 #include <console/console.h>
3 #include <cpu/x86/msr.h>
4 #include <cpu/amd/mtrr.h>
5 #include <device/device.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <string.h>
9 #include <cpu/x86/msr.h>
10 #include <cpu/x86/pae.h>
11 #include <pc80/mc146818rtc.h>
12 #include <cpu/x86/lapic.h>
13 #include "../../../northbridge/amd/amdk8/amdk8.h"
14 #include "../../../northbridge/amd/amdk8/cpu_rev.c"
15 #include <cpu/cpu.h>
16 #include <cpu/x86/cache.h>
17 #include <cpu/x86/mtrr.h>
18 #include <cpu/x86/mem.h>
19 #include "model_fxx_msr.h"
20
21 #define MCI_STATUS 0x401
22
23 static inline msr_t rdmsr_amd(unsigned index)
24 {
25         msr_t result;
26         __asm__ __volatile__ (
27                 "rdmsr"
28                 : "=a" (result.lo), "=d" (result.hi)
29                 : "c" (index), "D" (0x9c5a203a)
30                 );
31         return result;
32 }
33
34 static inline void wrmsr_amd(unsigned index, msr_t msr)
35 {
36         __asm__ __volatile__ (
37                 "wrmsr"
38                 : /* No outputs */
39                 : "c" (index), "a" (msr.lo), "d" (msr.hi), "D" (0x9c5a203a)
40                 );
41 }
42
43
44
45 #define MTRR_COUNT 8
46 #define ZERO_CHUNK_KB 0x800UL /* 2M */
47 #define TOLM_KB 0x400000UL
48
49 struct mtrr {
50         msr_t base;
51         msr_t mask;
52 };
53 struct mtrr_state {
54         struct mtrr mtrrs[MTRR_COUNT];
55         msr_t top_mem, top_mem2;
56         msr_t def_type;
57 };
58
59 static void save_mtrr_state(struct mtrr_state *state)
60 {
61         int i;
62         for(i = 0; i < MTRR_COUNT; i++) {
63                 state->mtrrs[i].base = rdmsr(MTRRphysBase_MSR(i));
64                 state->mtrrs[i].mask = rdmsr(MTRRphysMask_MSR(i));
65         }
66         state->top_mem  = rdmsr(TOP_MEM);
67         state->top_mem2 = rdmsr(TOP_MEM2);
68         state->def_type = rdmsr(MTRRdefType_MSR);
69 }
70
71 static void restore_mtrr_state(struct mtrr_state *state)
72 {
73         int i;
74         disable_cache();
75
76         for(i = 0; i < MTRR_COUNT; i++) {
77                 wrmsr(MTRRphysBase_MSR(i), state->mtrrs[i].base);
78                 wrmsr(MTRRphysMask_MSR(i), state->mtrrs[i].mask);
79         }
80         wrmsr(TOP_MEM,         state->top_mem);
81         wrmsr(TOP_MEM2,        state->top_mem2);
82         wrmsr(MTRRdefType_MSR, state->def_type);
83
84         enable_cache();
85 }
86
87
88 #if 0
89 static void print_mtrr_state(struct mtrr_state *state)
90 {
91         int i;
92         for(i = 0; i < MTRR_COUNT; i++) {
93                 printk_debug("var mtrr %d: %08x%08x mask: %08x%08x\n",
94                         i,
95                         state->mtrrs[i].base.hi, state->mtrrs[i].base.lo,
96                         state->mtrrs[i].mask.hi, state->mtrrs[i].mask.lo);
97         }
98         printk_debug("top_mem:  %08x%08x\n",
99                 state->top_mem.hi, state->top_mem.lo);
100         printk_debug("top_mem2: %08x%08x\n",
101                 state->top_mem2.hi, state->top_mem2.lo);
102         printk_debug("def_type: %08x%08x\n",
103                 state->def_type.hi, state->def_type.lo);
104 }
105 #endif
106
107 static void set_init_ecc_mtrrs(void)
108 {
109         msr_t msr;
110         int i;
111         disable_cache();
112
113         /* First clear all of the msrs to be safe */
114         for(i = 0; i < MTRR_COUNT; i++) {
115                 msr_t zero;
116                 zero.lo = zero.hi = 0;
117                 wrmsr(MTRRphysBase_MSR(i), zero);
118                 wrmsr(MTRRphysMask_MSR(i), zero);
119         }
120
121         /* Write back cache the first 1MB */
122         msr.hi = 0x00000000;
123         msr.lo = 0x00000000 | MTRR_TYPE_WRBACK;
124         wrmsr(MTRRphysBase_MSR(0), msr);
125         msr.hi = 0x000000ff;
126         msr.lo = ~((CONFIG_LB_MEM_TOPK << 10) - 1) | 0x800;
127         wrmsr(MTRRphysMask_MSR(0), msr);
128
129         /* Set the default type to write combining */
130         msr.hi = 0x00000000;
131         msr.lo = 0xc00 | MTRR_TYPE_WRCOMB;
132         wrmsr(MTRRdefType_MSR, msr);
133
134         /* Set TOP_MEM to 4G */
135         msr.hi = 0x00000001;
136         msr.lo = 0x00000000;
137         wrmsr(TOP_MEM, msr);
138
139         enable_cache();
140 }
141
142
143 static void init_ecc_memory(void)
144 {
145         unsigned long startk, begink, endk;
146         unsigned long basek;
147         struct mtrr_state mtrr_state;
148         device_t f1_dev, f2_dev, f3_dev;
149         int node_id;
150         int enable_scrubbing;
151         uint32_t dcl;
152         
153         /* For now there is a 1-1 mapping between node_id and cpu_id */
154         node_id = lapicid();
155
156         f1_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 1));
157         if (!f1_dev) {
158                 die("Cannot find cpu function 1\n");
159         }
160         f2_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 2));
161         if (!f2_dev) {
162                 die("Cannot find cpu function 2\n");
163         }
164         f3_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 3));
165         if (!f3_dev) {
166                 die("Cannot find cpu function 3\n");
167         }
168
169         /* See if we scrubbing should be enabled */
170         enable_scrubbing = 1;
171         get_option(&enable_scrubbing, "hw_scrubber");
172
173         /* Enable cache scrubbing at the lowest possible rate */
174         if (enable_scrubbing) {
175                 pci_write_config32(f3_dev, SCRUB_CONTROL,
176                         (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_NONE << 0));
177         } else {
178                 pci_write_config32(f3_dev, SCRUB_CONTROL,
179                         (SCRUB_NONE << 16) | (SCRUB_NONE << 8) | (SCRUB_NONE << 0));
180                 printk_debug("Scrubbing Disabled\n");
181         }
182         
183
184         /* If ecc support is not enabled don't touch memory */
185         dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
186         if (!(dcl & DCL_DimmEccEn)) {
187                 return;
188         }
189
190         startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >> 2;
191         endk   = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000) >> 2) + 0x4000;
192
193         /* Don't start too early */
194         begink = startk;
195         if (begink < CONFIG_LB_MEM_TOPK) {
196                 begink = CONFIG_LB_MEM_TOPK;
197         }
198         printk_debug("Clearing memory %uK - %uK: ", startk, endk);
199
200         /* Save the normal state */
201         save_mtrr_state(&mtrr_state);
202
203         /* Switch to the init ecc state */
204         set_init_ecc_mtrrs();
205         disable_lapic();
206
207         /* Walk through 2M chunks and zero them */
208         for(basek = begink; basek < endk; basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
209                 unsigned long limitk;
210                 unsigned long size;
211                 void *addr;
212
213                 /* Report every 64M */
214                 if ((basek % (64*1024)) == 0) {
215                         /* Restore the normal state */
216                         map_2M_page(0);
217                         restore_mtrr_state(&mtrr_state);
218                         enable_lapic();
219
220                         /* Print a status message */
221                         printk_debug("%c", (basek >= TOLM_KB)?'+':'-');
222
223                         /* Return to the initialization state */
224                         set_init_ecc_mtrrs();
225                         disable_lapic();
226                 }
227                 limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1);
228                 if (limitk > endk) {
229                         limitk = endk;
230                 }
231                 size = (limitk - basek) << 10;
232                 addr = map_2M_page(basek >> 11);
233                 addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
234                 if (addr == MAPPING_ERROR) {
235                         continue;
236                 }
237
238                 /* clear memory 2M (limitk - basek) */
239                 clear_memory(addr, size);
240         }
241         /* Restore the normal state */
242         map_2M_page(0);
243         restore_mtrr_state(&mtrr_state);
244         enable_lapic();
245
246         /* Set the scrub base address registers */
247         pci_write_config32(f3_dev, SCRUB_ADDR_LOW,  startk << 10);
248         pci_write_config32(f3_dev, SCRUB_ADDR_HIGH, startk >> 22);
249
250         /* Enable the scrubber? */
251         if (enable_scrubbing) {
252                 /* Enable scrubbing at the lowest possible rate */
253                 pci_write_config32(f3_dev, SCRUB_CONTROL,
254                         (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_84ms << 0));
255         }
256
257         printk_debug(" done\n");
258 }
259
260 static inline void k8_errata(void)
261 {
262         msr_t msr;
263         if (is_cpu_pre_c0()) {
264                 /* Erratum 63... */
265                 msr = rdmsr(HWCR_MSR);
266                 msr.lo |= (1 << 6);
267                 wrmsr(HWCR_MSR, msr);
268
269                 /* Erratum 69... */
270                 msr = rdmsr_amd(BU_CFG_MSR);
271                 msr.hi |= (1 << (45 - 32));
272                 wrmsr_amd(BU_CFG_MSR, msr);
273
274                 /* Erratum 81... */
275                 msr = rdmsr_amd(DC_CFG_MSR);
276                 msr.lo |=  (1 << 10);
277                 wrmsr_amd(DC_CFG_MSR, msr);
278                         
279         }
280         /* I can't touch this msr on early buggy cpus */
281         if (!is_cpu_pre_b3()) {
282
283                 /* Erratum 89 ... */
284                 msr = rdmsr(NB_CFG_MSR);
285                 msr.lo |= 1 << 3;
286                 
287                 if (!is_cpu_pre_c0()) {
288                         /* Erratum 86 Disable data masking on C0 and 
289                          * later processor revs.
290                          * FIXME this is only needed if ECC is enabled.
291                          */
292                         msr.hi |= 1 << (36 - 32);
293                 }       
294                 wrmsr(NB_CFG_MSR, msr);
295         }
296         
297         /* Erratum 97 ... */
298         if (!is_cpu_pre_c0()) {
299                 msr = rdmsr_amd(DC_CFG_MSR);
300                 msr.lo |= 1 << 3;
301                 wrmsr_amd(DC_CFG_MSR, msr);
302         }       
303         
304         /* Erratum 94 ... */
305         msr = rdmsr_amd(IC_CFG_MSR);
306         msr.lo |= 1 << 11;
307         wrmsr_amd(IC_CFG_MSR, msr);
308
309         /* Erratum 91 prefetch miss is handled in the kernel */
310 }
311
312 void model_fxx_init(device_t dev)
313 {
314         unsigned long mmio_basek, tomk;
315         unsigned long i;
316         msr_t msr;
317
318         /* Turn on caching if we haven't already */
319         x86_enable_cache();
320         amd_setup_mtrrs();
321         x86_mtrr_check();
322
323         disable_cache();
324         
325         /* zero the machine check error status registers */
326         msr.lo = 0;
327         msr.hi = 0;
328         for(i=0; i<5; i++) {
329                 wrmsr(MCI_STATUS + (i*4),msr);
330         }
331
332         k8_errata();
333         
334         enable_cache();
335
336         /* Is this a bad location?  In particular can another node prefecth
337          * data from this node before we have initialized it?
338          */
339         init_ecc_memory();
340
341         /* Enable the local cpu apics */
342         setup_lapic();
343 }
344
345 static struct device_operations cpu_dev_ops = {
346         .init = model_fxx_init,
347 };
348 static struct cpu_device_id cpu_table[] = {
349         { X86_VENDOR_AMD, 0xf50 }, /* B3 */
350         { X86_VENDOR_AMD, 0xf51 }, /* SH7-B3 */
351         { X86_VENDOR_AMD, 0xf58 }, /* SH7-C0 */
352         { X86_VENDOR_AMD, 0xf48 },
353 #if 1
354         { X86_VENDOR_AMD, 0xf5A }, /* SH7-CG */
355         { X86_VENDOR_AMD, 0xf4A },
356         { X86_VENDOR_AMD, 0xf7A },
357         { X86_VENDOR_AMD, 0xfc0 }, /* DH7-CG */
358         { X86_VENDOR_AMD, 0xfe0 },
359         { X86_VENDOR_AMD, 0xff0 },
360         { X86_VENDOR_AMD, 0xf82 }, /* CH7-CG */
361         { X86_VENDOR_AMD, 0xfb2 },
362 #endif
363         { 0, 0 },
364 };
365 static struct cpu_driver model_fxx __cpu_driver = {
366         .ops      = &cpu_dev_ops,
367         .id_table = cpu_table,
368 };