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