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