Move C labels to start-of-line
[coreboot.git] / src / northbridge / amd / amdk8 / raminit_test.c
1 #include <unistd.h>
2 #include <limits.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <setjmp.h>
6 #include <device/pci_def.h>
7 #include <stdlib.h>
8 #include "amdk8.h"
9
10 jmp_buf end_buf;
11
12 static int is_cpu_pre_c0(void)
13 {
14         return 0;
15 }
16
17 #define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
18         (((BUS) & 0xFF) << 16) | \
19         (((DEV) & 0x1f) << 11) | \
20         (((FN) & 0x07) << 8) | \
21         ((WHERE) & 0xFF))
22
23 #define PCI_DEV(BUS, DEV, FN) ( \
24         (((BUS) & 0xFF) << 16) | \
25         (((DEV) & 0x1f) << 11) | \
26         (((FN)  & 0x7) << 8))
27
28 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
29         ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
30
31 typedef unsigned device_t;
32
33 unsigned char pci_register[256*5*3*256];
34
35 static uint8_t pci_read_config8(device_t dev, unsigned where)
36 {
37         unsigned addr;
38         addr = dev | where;
39         return pci_register[addr];
40 }
41
42 static uint16_t pci_read_config16(device_t dev, unsigned where)
43 {
44         unsigned addr;
45         addr = dev | where;
46         return pci_register[addr] | (pci_register[addr + 1]  << 8);
47 }
48
49 static uint32_t pci_read_config32(device_t dev, unsigned where)
50 {
51         unsigned addr;
52         uint32_t value;
53         addr = dev | where;
54         value =  pci_register[addr] |
55                 (pci_register[addr + 1]  << 8) |
56                 (pci_register[addr + 2]  << 16) |
57                 (pci_register[addr + 3]  << 24);
58
59 #if 0
60         print_debug("pcir32(");
61         print_debug_hex32(addr);
62         print_debug("):");
63         print_debug_hex32(value);
64         print_debug("\n");
65 #endif
66         return value;
67
68 }
69
70 static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
71 {
72         unsigned addr;
73         addr = dev | where;
74         pci_register[addr] = value;
75 }
76
77 static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
78 {
79         unsigned addr;
80         addr = dev | where;
81         pci_register[addr] = value & 0xff;
82         pci_register[addr + 1] = (value >> 8) & 0xff;
83 }
84
85 static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
86 {
87         unsigned addr;
88         addr = dev | where;
89         pci_register[addr] = value & 0xff;
90         pci_register[addr + 1] = (value >> 8) & 0xff;
91         pci_register[addr + 2] = (value >> 16) & 0xff;
92         pci_register[addr + 3] = (value >> 24) & 0xff;
93
94 #if 0
95         print_debug("pciw32(");
96         print_debug_hex32(addr);
97         print_debug(", ");
98         print_debug_hex32(value);
99         print_debug(")\n");
100 #endif
101 }
102
103 #define PCI_DEV_INVALID (0xffffffffU)
104 static device_t pci_locate_device(unsigned pci_id, device_t dev)
105 {
106         for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
107                 unsigned int id;
108                 id = pci_read_config32(dev, 0);
109                 if (id == pci_id) {
110                         return dev;
111                 }
112         }
113         return PCI_DEV_INVALID;
114 }
115
116
117
118
119 static void uart_tx_byte(unsigned char data)
120 {
121         write(STDOUT_FILENO, &data, 1);
122 }
123 static void hlt(void)
124 {
125         longjmp(end_buf, 2);
126 }
127 #include "console/console.c"
128
129 unsigned long log2(unsigned long x)
130 {
131         // assume 8 bits per byte.
132         unsigned long i = 1 << (sizeof(x)*8 - 1);
133         unsigned long pow = sizeof(x) * 8 - 1;
134
135         if (! x) {
136                 static const char errmsg[] = " called with invalid parameter of 0\n";
137                 write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
138                 write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
139                 hlt();
140         }
141         for(; i > x; i >>= 1, pow--)
142                 ;
143
144         return pow;
145 }
146
147 typedef struct msr_struct
148 {
149         unsigned lo;
150         unsigned hi;
151 } msr_t;
152
153 static inline msr_t rdmsr(unsigned index)
154 {
155         msr_t result;
156         result.lo = 0;
157         result.hi = 0;
158         return result;
159 }
160
161 static inline void wrmsr(unsigned index, msr_t msr)
162 {
163 }
164
165 #include "raminit.h"
166
167 #define SIO_BASE 0x2e
168
169 static void hard_reset(void)
170 {
171         /* FIXME implement the hard reset case... */
172         longjmp(end_buf, 3);
173 }
174
175 static void memreset_setup(void)
176 {
177         /* Nothing to do */
178 }
179
180 static void memreset(int controllers, const struct mem_controller *ctrl)
181 {
182         /* Nothing to do */
183 }
184
185 static inline void activate_spd_rom(const struct mem_controller *ctrl)
186 {
187         /* nothing to do */
188 }
189
190
191 static uint8_t spd_mt4lsdt464a[256] =
192 {
193         0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70,
194         0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01,
195         0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
196
197         0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
198         0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
199         0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
200         0x06, 0x07, 0x08, 0x09, 0x00,
201 };
202
203 static uint8_t spd_micron_512MB_DDR333[256] =
204 {
205         0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60,
206         0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
207         0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
208         0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
209         0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211         0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
212         0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31,
213         0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43,
214         0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00,
215         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
218         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
219         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
220         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
221         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
222         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
223         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
224         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
225         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
226         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
227         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
228         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
229         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
230         0xff, 0xff, 0xff, 0xff, 0xff, 0xff
231 };
232
233 static uint8_t spd_micron_256MB_DDR333[256] =
234 {
235         0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60,
236         0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
237         0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
238         0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
239         0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
240         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241         0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
242         0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36,
243         0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
244         0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
245         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
248         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
249         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
250         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
251         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
252         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
253         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
254         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
255         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
256         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
257         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
258         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
259         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
260         0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
261 };
262
263 #define MAX_DIMMS 16
264 static uint8_t spd_data[MAX_DIMMS*256];
265
266 static unsigned spd_count, spd_fail_count;
267 static int spd_read_byte(unsigned device, unsigned address)
268 {
269         int result;
270         spd_count++;
271         if ((device < DIMM0) || (device >= (DIMM0 + MAX_DIMMS))) {
272                 result = -1;
273         }
274         else {
275                 device -= DIMM0; /* 0x50 */
276
277                 if (address > 256) {
278                         result = -1;
279                 }
280                 else if (spd_data[(device << 8) | 2] != 7) {
281                         result = -1;
282                 }
283                 else {
284                         result = spd_data[(device << 8) | address];
285                 }
286         }
287 #if 0
288         print_debug("spd_read_byte(");
289         print_debug_hex32(device);
290         print_debug(", ");
291         print_debug_hex32(address);
292         print_debug(") -> ");
293         print_debug_hex32(result);
294         print_debug("\n");
295 #endif
296         if (spd_count >= spd_fail_count) {
297                 result = -1;
298         }
299         return result;
300 }
301
302 /* no specific code here. this should go away completely */
303 static void coherent_ht_mainboard(unsigned cpus)
304 {
305 }
306
307 #include "raminit.c"
308 #include "../../../lib/generic_sdram.c"
309
310 #define FIRST_CPU  1
311 #define SECOND_CPU 1
312 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
313 static void raminit_main(void)
314 {
315         /*
316          * GPIO28 of 8111 will control H0_MEMRESET_L
317          * GPIO29 of 8111 will control H1_MEMRESET_L
318          */
319         static const struct mem_controller cpu[] = {
320 #if FIRST_CPU
321                 {
322                         .node_id = 0,
323                         .f0 = PCI_DEV(0, 0x18, 0),
324                         .f1 = PCI_DEV(0, 0x18, 1),
325                         .f2 = PCI_DEV(0, 0x18, 2),
326                         .f3 = PCI_DEV(0, 0x18, 3),
327                         .channel0 = { DIMM0+0, DIMM0+2, DIMM0+4, DIMM0+6 },
328                         .channel1 = { DIMM0+1, DIMM0+3, DIMM0+5, DIMM0+7 },
329                 },
330 #endif
331 #if SECOND_CPU
332                 {
333                         .node_id = 1,
334                         .f0 = PCI_DEV(0, 0x19, 0),
335                         .f1 = PCI_DEV(0, 0x19, 1),
336                         .f2 = PCI_DEV(0, 0x19, 2),
337                         .f3 = PCI_DEV(0, 0x19, 3),
338                         .channel0 = { DIMM0+8, DIMM0+10, DIMM0+12, DIMM0+14 },
339                         .channel1 = { DIMM0+9, DIMM0+11, DIMM0+13, DIMM0+15 },
340                 },
341 #endif
342         };
343         console_init();
344         memreset_setup();
345         sdram_initialize(ARRAY_SIZE(cpu), cpu);
346
347 }
348
349 static void reset_tests(void)
350 {
351         /* Clear the results of any previous tests */
352         memset(pci_register, 0, sizeof(pci_register));
353         memset(spd_data, 0, sizeof(spd_data));
354         spd_count = 0;
355         spd_fail_count = UINT_MAX;
356
357         pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
358                 NBCAP_128Bit |
359                 NBCAP_MP|  NBCAP_BIG_MP |
360                 /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
361                 (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
362                 NBCAP_MEMCTRL);
363
364         pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
365                 NBCAP_128Bit |
366                 NBCAP_MP|  NBCAP_BIG_MP |
367                 /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
368                 (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
369                 NBCAP_MEMCTRL);
370
371 #if 0
372         pci_read_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP);
373 #endif
374 }
375
376 static void test1(void)
377 {
378         reset_tests();
379
380         memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
381         memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
382 #if 0
383         memcpy(&spd_data[2*256], spd_micron_512MB_DDR333, 256);
384         memcpy(&spd_data[3*256], spd_micron_512MB_DDR333, 256);
385
386         memcpy(&spd_data[8*256], spd_micron_512MB_DDR333, 256);
387         memcpy(&spd_data[9*256], spd_micron_512MB_DDR333, 256);
388         memcpy(&spd_data[10*256], spd_micron_512MB_DDR333, 256);
389         memcpy(&spd_data[11*256], spd_micron_512MB_DDR333, 256);
390 #endif
391
392         raminit_main();
393
394 #if 0
395         print_debug("spd_count: ");
396         print_debug_hex32(spd_count);
397         print_debug("\n");
398 #endif
399
400 }
401
402
403 static void do_test2(int i)
404 {
405         jmp_buf tmp_buf;
406         memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
407         if (setjmp(end_buf) != 0) {
408                 goto done;
409         }
410         reset_tests();
411         spd_fail_count = i;
412
413         print_debug("\nSPD will fail after: ");
414         print_debug_hex32(spd_fail_count);
415         print_debug(" accesses.\n");
416
417         memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
418         memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
419
420         raminit_main();
421
422 done:
423         memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
424 }
425
426 static void test2(void)
427 {
428         int i;
429         for(i = 0; i < 0x48; i++) {
430                 do_test2(i);
431         }
432
433 }
434
435 int main(int argc, char **argv)
436 {
437         if (setjmp(end_buf) != 0) {
438                 return -1;
439         }
440         test1();
441         test2();
442         return 0;
443 }