- Massive set of cleanups/fixes for romcc. Lots of corner cases now work
[coreboot.git] / util / romcc / tests / raminit_test5.c
1
2
3
4
5
6
7
8 typedef unsigned char uint8_t;
9 typedef signed char int8_t;
10
11 typedef unsigned short uint16_t;
12 typedef signed short int16_t;
13
14 typedef unsigned int uint32_t;
15 typedef signed int int32_t;
16
17
18
19
20
21
22
23 typedef unsigned char uint_least8_t;
24 typedef signed char int_least8_t;
25
26 typedef unsigned short uint_least16_t;
27 typedef signed short int_least16_t;
28
29 typedef unsigned int uint_least32_t;
30 typedef signed int int_least32_t;
31
32
33
34
35
36
37
38 typedef unsigned char uint_fast8_t;
39 typedef signed char int_fast8_t;
40
41 typedef unsigned int uint_fast16_t;
42 typedef signed int int_fast16_t;
43
44 typedef unsigned int uint_fast32_t;
45 typedef signed int int_fast32_t;
46
47
48
49
50
51
52
53 typedef int intptr_t;
54 typedef unsigned int uintptr_t;
55
56
57
58
59
60
61 typedef long int intmax_t;
62 typedef unsigned long int uintmax_t;
63
64
65
66
67 static void outb(unsigned char value, unsigned short port)
68 {
69         __builtin_outb(value, port);
70 }
71
72 static void outw(unsigned short value, unsigned short port)
73 {
74         __builtin_outw(value, port);
75 }
76
77 static void outl(unsigned int value, unsigned short port)
78 {
79         __builtin_outl(value, port);
80 }
81
82
83 static unsigned char inb(unsigned short port)
84 {
85         return __builtin_inb(port);
86 }
87
88
89 static unsigned char inw(unsigned short port)
90 {
91         return __builtin_inw(port);
92 }
93
94 static unsigned char inl(unsigned short port)
95 {
96         return __builtin_inl(port);
97 }
98
99 static void hlt(void)
100 {
101         __builtin_hlt();
102 }
103
104 int log2(int value)
105 {
106
107
108
109
110
111
112         return __builtin_bsr(value);
113 }
114
115
116 typedef __builtin_msr_t msr_t;
117
118 static msr_t rdmsr(unsigned long index)
119 {
120         return __builtin_rdmsr(index);
121 }
122
123 static void wrmsr(unsigned long index, msr_t msr)
124 {
125         __builtin_wrmsr(index, msr.lo, msr.hi);
126 }
127
128 typedef unsigned device_t;
129
130 static unsigned char pci_read_config8(device_t dev, unsigned where)
131 {
132         unsigned addr;
133         addr = dev | where;
134         outl(0x80000000 | (addr & ~3), 0xCF8);
135         return inb(0xCFC + (addr & 3));
136 }
137
138 static unsigned short pci_read_config16(device_t dev, unsigned where)
139 {
140         unsigned addr;
141         addr = dev | where;
142         outl(0x80000000 | (addr & ~3), 0xCF8);
143         return inw(0xCFC + (addr & 2));
144 }
145
146 static unsigned int pci_read_config32(device_t dev, unsigned where)
147 {
148         unsigned addr;
149         addr = dev | where;
150         outl(0x80000000 | (addr & ~3), 0xCF8);
151         return inl(0xCFC);
152 }
153
154 static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
155 {
156         unsigned addr;
157         addr = dev | where;
158         outl(0x80000000 | (addr & ~3), 0xCF8);
159         outb(value, 0xCFC + (addr & 3));
160 }
161
162 static void pci_write_config16(device_t dev, unsigned where, unsigned short value)
163 {
164         unsigned addr;
165         addr = dev | where;
166         outl(0x80000000 | (addr & ~3), 0xCF8);
167         outw(value, 0xCFC + (addr & 2));
168 }
169
170 static void pci_write_config32(device_t dev, unsigned where, unsigned int value)
171 {
172         unsigned addr;
173         addr = dev | where;
174         outl(0x80000000 | (addr & ~3), 0xCF8);
175         outl(value, 0xCFC);
176 }
177
178
179 static device_t pci_locate_device(unsigned pci_id, device_t dev)
180 {
181         for(; dev <= ( (((255) & 0xFF) << 16) | (((31) & 0x1f) << 11) | (((7) & 0x7) << 8)); dev += ( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((1) & 0x7) << 8))) {
182                 unsigned int id;
183                 id = pci_read_config32(dev, 0);
184                 if (id == pci_id) {
185                         return dev;
186                 }
187         }
188         return (0xffffffffU);
189 }
190
191
192
193
194
195 static int uart_can_tx_byte(void)
196 {
197         return inb(0x3f8 + 0x05) & 0x20;
198 }
199
200 static void uart_wait_to_tx_byte(void)
201 {
202         while(!uart_can_tx_byte())
203                 ;
204 }
205
206 static void uart_wait_until_sent(void)
207 {
208         while(!(inb(0x3f8 + 0x05) & 0x40))
209                 ;
210 }
211
212 static void uart_tx_byte(unsigned char data)
213 {
214         uart_wait_to_tx_byte();
215         outb(data, 0x3f8 + 0x00);
216
217         uart_wait_until_sent();
218 }
219
220 static void uart_init(void)
221 {
222
223         outb(0x0, 0x3f8 + 0x01);
224
225         outb(0x01, 0x3f8 + 0x02);
226
227         outb(0x80 | 0x3, 0x3f8 + 0x03);
228
229         outb((115200/115200) & 0xFF, 0x3f8 + 0x00);
230         outb(((115200/115200) >> 8) & 0xFF, 0x3f8 + 0x01);
231
232         outb(0x3, 0x3f8 + 0x03);
233 }
234
235
236
237
238
239 static void __console_tx_byte(unsigned char byte)
240 {
241         uart_tx_byte(byte);
242 }
243
244 static void __console_tx_nibble(unsigned nibble)
245 {
246         unsigned char digit;
247         digit = nibble + '0';
248         if (digit > '9') {
249                 digit += 39;
250         }
251         __console_tx_byte(digit);
252 }
253
254 static void __console_tx_char(int loglevel, unsigned char byte)
255 {
256         if (8 > loglevel) {
257                 uart_tx_byte(byte);
258         }
259 }
260
261 static void __console_tx_hex8(int loglevel, unsigned char value)
262 {
263         if (8 > loglevel) {
264                 __console_tx_nibble((value >> 4U) & 0x0fU);
265                 __console_tx_nibble(value & 0x0fU);
266         }
267 }
268
269 static void __console_tx_hex16(int loglevel, unsigned short value)
270 {
271         if (8 > loglevel) {
272                 __console_tx_nibble((value >> 12U) & 0x0fU);
273                 __console_tx_nibble((value >> 8U) & 0x0fU);
274                 __console_tx_nibble((value >> 4U) & 0x0fU);
275                 __console_tx_nibble(value & 0x0fU);
276         }
277 }
278
279 static void __console_tx_hex32(int loglevel, unsigned int value)
280 {
281         if (8 > loglevel) {
282                 __console_tx_nibble((value >> 28U) & 0x0fU);
283                 __console_tx_nibble((value >> 24U) & 0x0fU);
284                 __console_tx_nibble((value >> 20U) & 0x0fU);
285                 __console_tx_nibble((value >> 16U) & 0x0fU);
286                 __console_tx_nibble((value >> 12U) & 0x0fU);
287                 __console_tx_nibble((value >> 8U) & 0x0fU);
288                 __console_tx_nibble((value >> 4U) & 0x0fU);
289                 __console_tx_nibble(value & 0x0fU);
290         }
291 }
292
293 static void __console_tx_string(int loglevel, const char *str)
294 {
295         if (8 > loglevel) {
296                 unsigned char ch;
297                 while((ch = *str++) != '\0') {
298                         __console_tx_byte(ch);
299                 }
300         }
301 }
302
303 static void print_emerg_char(unsigned char byte) { __console_tx_char(0, byte); }
304 static void print_emerg_hex8(unsigned char value){ __console_tx_hex8(0, value); }
305 static void print_emerg_hex16(unsigned short value){ __console_tx_hex16(0, value); }
306 static void print_emerg_hex32(unsigned int value) { __console_tx_hex32(0, value); }
307 static void print_emerg(const char *str) { __console_tx_string(0, str); }
308
309 static void print_alert_char(unsigned char byte) { __console_tx_char(1, byte); }
310 static void print_alert_hex8(unsigned char value) { __console_tx_hex8(1, value); }
311 static void print_alert_hex16(unsigned short value){ __console_tx_hex16(1, value); }
312 static void print_alert_hex32(unsigned int value) { __console_tx_hex32(1, value); }
313 static void print_alert(const char *str) { __console_tx_string(1, str); }
314
315 static void print_crit_char(unsigned char byte) { __console_tx_char(2, byte); }
316 static void print_crit_hex8(unsigned char value) { __console_tx_hex8(2, value); }
317 static void print_crit_hex16(unsigned short value){ __console_tx_hex16(2, value); }
318 static void print_crit_hex32(unsigned int value) { __console_tx_hex32(2, value); }
319 static void print_crit(const char *str) { __console_tx_string(2, str); }
320
321 static void print_err_char(unsigned char byte) { __console_tx_char(3, byte); }
322 static void print_err_hex8(unsigned char value) { __console_tx_hex8(3, value); }
323 static void print_err_hex16(unsigned short value){ __console_tx_hex16(3, value); }
324 static void print_err_hex32(unsigned int value) { __console_tx_hex32(3, value); }
325 static void print_err(const char *str) { __console_tx_string(3, str); }
326
327 static void print_warning_char(unsigned char byte) { __console_tx_char(4, byte); }
328 static void print_warning_hex8(unsigned char value) { __console_tx_hex8(4, value); }
329 static void print_warning_hex16(unsigned short value){ __console_tx_hex16(4, value); }
330 static void print_warning_hex32(unsigned int value) { __console_tx_hex32(4, value); }
331 static void print_warning(const char *str) { __console_tx_string(4, str); }
332
333 static void print_notice_char(unsigned char byte) { __console_tx_char(5, byte); }
334 static void print_notice_hex8(unsigned char value) { __console_tx_hex8(5, value); }
335 static void print_notice_hex16(unsigned short value){ __console_tx_hex16(5, value); }
336 static void print_notice_hex32(unsigned int value) { __console_tx_hex32(5, value); }
337 static void print_notice(const char *str) { __console_tx_string(5, str); }
338
339 static void print_info_char(unsigned char byte) { __console_tx_char(6, byte); }
340 static void print_info_hex8(unsigned char value) { __console_tx_hex8(6, value); }
341 static void print_info_hex16(unsigned short value){ __console_tx_hex16(6, value); }
342 static void print_info_hex32(unsigned int value) { __console_tx_hex32(6, value); }
343 static void print_info(const char *str) { __console_tx_string(6, str); }
344
345 static void print_debug_char(unsigned char byte) { __console_tx_char(7, byte); }
346 static void print_debug_hex8(unsigned char value) { __console_tx_hex8(7, value); }
347 static void print_debug_hex16(unsigned short value){ __console_tx_hex16(7, value); }
348 static void print_debug_hex32(unsigned int value) { __console_tx_hex32(7, value); }
349 static void print_debug(const char *str) { __console_tx_string(7, str); }
350
351 static void print_spew_char(unsigned char byte) { __console_tx_char(8, byte); }
352 static void print_spew_hex8(unsigned char value) { __console_tx_hex8(8, value); }
353 static void print_spew_hex16(unsigned short value){ __console_tx_hex16(8, value); }
354 static void print_spew_hex32(unsigned int value) { __console_tx_hex32(8, value); }
355 static void print_spew(const char *str) { __console_tx_string(8, str); }
356
357 static void console_init(void)
358 {
359         static const char console_test[] =
360                 "\r\n\r\nLinuxBIOS-"
361                 "1.1.0"
362                 ".0Fallback"
363                 " "
364                 "Thu Jun 19 05:42:16 MDT 2003"
365                 " starting...\r\n";
366         print_info(console_test);
367 }
368
369
370 static void die(const char *str)
371 {
372         print_emerg(str);
373         do {
374                 hlt();
375         } while(1);
376 }
377
378
379
380
381
382
383
384
385
386 static void write_phys(unsigned long addr, unsigned long value)
387 {
388
389         asm volatile(
390                 "movnti %1, (%0)"
391                 :
392                 : "r" (addr), "r" (value)
393                 :
394                 );
395
396
397
398
399
400 }
401
402 static unsigned long read_phys(unsigned long addr)
403 {
404         volatile unsigned long *ptr;
405         ptr = (void *)addr;
406         return *ptr;
407 }
408
409 static void ram_fill(unsigned long start, unsigned long stop)
410 {
411         unsigned long addr;
412
413
414
415         print_debug("DRAM fill: ");
416         print_debug_hex32(start);
417         print_debug("-");
418         print_debug_hex32(stop);
419         print_debug("\r\n");
420         for(addr = start; addr < stop ; addr += 4) {
421
422                 if (!(addr & 0xffff)) {
423                         print_debug_hex32(addr);
424                         print_debug("\r");
425                 }
426                 write_phys(addr, addr);
427         };
428
429         print_debug_hex32(addr);
430         print_debug("\r\nDRAM filled\r\n");
431 }
432
433 static void ram_verify(unsigned long start, unsigned long stop)
434 {
435         unsigned long addr;
436
437
438
439         print_debug("DRAM verify: ");
440         print_debug_hex32(start);
441         print_debug_char('-');
442         print_debug_hex32(stop);
443         print_debug("\r\n");
444         for(addr = start; addr < stop ; addr += 4) {
445                 unsigned long value;
446
447                 if (!(addr & 0xffff)) {
448                         print_debug_hex32(addr);
449                         print_debug("\r");
450                 }
451                 value = read_phys(addr);
452                 if (value != addr) {
453
454                         print_err_hex32(addr);
455                         print_err_char(':');
456                         print_err_hex32(value);
457                         print_err("\r\n");
458                 }
459         }
460
461         print_debug_hex32(addr);
462         print_debug("\r\nDRAM verified\r\n");
463 }
464
465
466 void ram_check(unsigned long start, unsigned long stop)
467 {
468         int result;
469
470
471
472
473
474         print_debug("Testing DRAM : ");
475         print_debug_hex32(start);
476         print_debug("-");
477         print_debug_hex32(stop);
478         print_debug("\r\n");
479         ram_fill(start, stop);
480         ram_verify(start, stop);
481         print_debug("Done.\n");
482 }
483
484
485 static void enumerate_ht_chain(void)
486 {
487
488
489
490
491
492         unsigned next_unitid, last_unitid;;
493         next_unitid = 1;
494         do {
495                 uint32_t id;
496                 uint8_t hdr_type, pos;
497                 last_unitid = next_unitid;
498
499                 id = pci_read_config32(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x00);
500
501                 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
502                         (((id >> 16) & 0xffff) == 0xffff) ||
503                         (((id >> 16) & 0xffff) == 0x0000)) {
504                         break;
505                 }
506                 hdr_type = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x0e);
507                 pos = 0;
508                 hdr_type &= 0x7f;
509
510                 if ((hdr_type == 0) ||
511                         (hdr_type == 1)) {
512                         pos = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x34);
513                 }
514                 while(pos != 0) {
515                         uint8_t cap;
516                         cap = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 0);
517                         if (cap == 0x08) {
518                                 uint16_t flags;
519                                 flags = pci_read_config16(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 2);
520                                 if ((flags >> 13) == 0) {
521                                         unsigned count;
522                                         flags &= ~0x1f;
523                                         flags |= next_unitid & 0x1f;
524                                         count = (flags >> 5) & 0x1f;
525                                         pci_write_config16(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 2, flags);
526                                         next_unitid += count;
527                                         break;
528                                 }
529                         }
530                         pos = pci_read_config8(( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8)), pos + 1);
531                 }
532         } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
533 }
534
535
536
537 static void enable_smbus(void)
538 {
539         device_t dev;
540         dev = pci_locate_device(((((0x746b) & 0xFFFF) << 16) | ((0x1022) & 0xFFFF)), 0);
541         if (dev == (0xffffffffU)) {
542                 die("SMBUS controller not found\r\n");
543         }
544         uint8_t enable;
545         print_debug("SMBus controller enabled\r\n");
546         pci_write_config32(dev, 0x58, 0x1000 | 1);
547         enable = pci_read_config8(dev, 0x41);
548         pci_write_config8(dev, 0x41, enable | (1 << 7));
549 }
550
551
552 static inline void smbus_delay(void)
553 {
554         outb(0x80, 0x80);
555 }
556
557 static int smbus_wait_until_ready(void)
558 {
559         unsigned long loops;
560         loops = (100*1000*10);
561         do {
562                 unsigned short val;
563                 smbus_delay();
564                 val = inw(0x1000 + 0xe0);
565                 if ((val & 0x800) == 0) {
566                         break;
567                 }
568         } while(--loops);
569         return loops?0:-1;
570 }
571
572 static int smbus_wait_until_done(void)
573 {
574         unsigned long loops;
575         loops = (100*1000*10);
576         do {
577                 unsigned short val;
578                 smbus_delay();
579
580                 val = inw(0x1000 + 0xe0);
581                 if (((val & 0x8) == 0) | ((val & 0x437) != 0)) {
582                         break;
583                 }
584         } while(--loops);
585         return loops?0:-1;
586 }
587
588 static int smbus_read_byte(unsigned device, unsigned address)
589 {
590         unsigned char global_control_register;
591         unsigned char global_status_register;
592         unsigned char byte;
593
594         if (smbus_wait_until_ready() < 0) {
595                 return -1;
596         }
597
598
599
600         outw(inw(0x1000 + 0xe2) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), 0x1000 + 0xe2);
601
602         outw(((device & 0x7f) << 1) | 1, 0x1000 + 0xe4);
603
604         outb(address & 0xFF, 0x1000 + 0xe8);
605
606         outw((inw(0x1000 + 0xe2) & ~7) | (0x2), 0x1000 + 0xe2);
607
608
609
610         outw(inw(0x1000 + 0xe0), 0x1000 + 0xe0);
611
612
613         outw(0, 0x1000 + 0xe6);
614
615
616         outw((inw(0x1000 + 0xe2) | (1 << 3)), 0x1000 + 0xe2);
617
618
619
620         if (smbus_wait_until_done() < 0) {
621                 return -1;
622         }
623
624         global_status_register = inw(0x1000 + 0xe0);
625
626
627         byte = inw(0x1000 + 0xe6) & 0xff;
628
629         if (global_status_register != (1 << 4)) {
630                 return -1;
631         }
632         return byte;
633 }
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649 static void setup_resource_map(const unsigned int *register_values, int max)
650 {
651         int i;
652         print_debug("setting up resource map....\r\n");
653         for(i = 0; i < max; i += 3) {
654                 device_t dev;
655                 unsigned where;
656                 unsigned long reg;
657
658
659
660
661
662
663                 dev = register_values[i] & ~0xff;
664                 where = register_values[i] & 0xff;
665                 reg = pci_read_config32(dev, where);
666                 reg &= register_values[i+1];
667                 reg |= register_values[i+2];
668                 pci_write_config32(dev, where, reg);
669
670
671
672
673
674
675         }
676         print_debug("done.\r\n");
677 }
678
679 static void setup_default_resource_map(void)
680 {
681         static const unsigned int register_values[] = {
682
683         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x44) & 0xFF)), 0x0000f8f8, 0x00000000,
684         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x0000f8f8, 0x00000001,
685         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x54) & 0xFF)), 0x0000f8f8, 0x00000002,
686         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000f8f8, 0x00000003,
687         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x64) & 0xFF)), 0x0000f8f8, 0x00000004,
688         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x6C) & 0xFF)), 0x0000f8f8, 0x00000005,
689         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x74) & 0xFF)), 0x0000f8f8, 0x00000006,
690         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x7C) & 0xFF)), 0x0000f8f8, 0x00000007,
691
692         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x40) & 0xFF)), 0x0000f8fc, 0x00000000,
693         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x48) & 0xFF)), 0x0000f8fc, 0x00000000,
694         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x50) & 0xFF)), 0x0000f8fc, 0x00000000,
695         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x58) & 0xFF)), 0x0000f8fc, 0x00000000,
696         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x60) & 0xFF)), 0x0000f8fc, 0x00000000,
697         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x68) & 0xFF)), 0x0000f8fc, 0x00000000,
698         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x70) & 0xFF)), 0x0000f8fc, 0x00000000,
699         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x78) & 0xFF)), 0x0000f8fc, 0x00000000,
700
701         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00000048, 0x00000000,
702         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x8C) & 0xFF)), 0x00000048, 0x00000000,
703         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x94) & 0xFF)), 0x00000048, 0x00000000,
704         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x9C) & 0xFF)), 0x00000048, 0x00000000,
705         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA4) & 0xFF)), 0x00000048, 0x00000000,
706         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xAC) & 0xFF)), 0x00000048, 0x00000000,
707         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB4) & 0xFF)), 0x00000048, 0x00000000,
708         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xBC) & 0xFF)), 0x00000048, 0x00000000,
709
710         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x80) & 0xFF)), 0x000000f0, 0x00000000,
711         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x88) & 0xFF)), 0x000000f0, 0x00000000,
712         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x90) & 0xFF)), 0x000000f0, 0x00000000,
713         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x98) & 0xFF)), 0x000000f0, 0x00000000,
714         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA0) & 0xFF)), 0x000000f0, 0x00000000,
715         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA8) & 0xFF)), 0x000000f0, 0x00000000,
716         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB0) & 0xFF)), 0x000000f0, 0x00000000,
717         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB8) & 0xFF)), 0x000000f0, 0x00000000,
718
719         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC4) & 0xFF)), 0xFE000FC8, 0x01fff000,
720         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xCC) & 0xFF)), 0xFE000FC8, 0x00000000,
721         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD4) & 0xFF)), 0xFE000FC8, 0x00000000,
722         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xDC) & 0xFF)), 0xFE000FC8, 0x00000000,
723
724         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC0) & 0xFF)), 0xFE000FCC, 0x00000003,
725         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC8) & 0xFF)), 0xFE000FCC, 0x00000000,
726         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD0) & 0xFF)), 0xFE000FCC, 0x00000000,
727         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD8) & 0xFF)), 0xFE000FCC, 0x00000000,
728
729         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE0) & 0xFF)), 0x0000FC88, 0xff000003,
730         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE4) & 0xFF)), 0x0000FC88, 0x00000000,
731         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE8) & 0xFF)), 0x0000FC88, 0x00000000,
732         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xEC) & 0xFF)), 0x0000FC88, 0x00000000,
733         };
734         int max;
735         max = sizeof(register_values)/sizeof(register_values[0]);
736         setup_resource_map(register_values, max);
737 }
738
739 static void sdram_set_registers(void)
740 {
741         static const unsigned int register_values[] = {
742
743         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x44) & 0xFF)), 0x0000f8f8, 0x003f0000,
744         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x0000f8f8, 0x00000001,
745
746         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x54) & 0xFF)), 0x0000f8f8, 0x00000002,
747         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000f8f8, 0x00000003,
748         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x64) & 0xFF)), 0x0000f8f8, 0x00000004,
749         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x6C) & 0xFF)), 0x0000f8f8, 0x00000005,
750         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x74) & 0xFF)), 0x0000f8f8, 0x00000006,
751         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x7C) & 0xFF)), 0x0000f8f8, 0x00000007,
752
753         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x40) & 0xFF)), 0x0000f8fc, 0x00000003,
754
755         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x48) & 0xFF)), 0x0000f8fc, 0x00400000,
756         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x50) & 0xFF)), 0x0000f8fc, 0x00400000,
757         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x58) & 0xFF)), 0x0000f8fc, 0x00400000,
758         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x60) & 0xFF)), 0x0000f8fc, 0x00400000,
759         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x68) & 0xFF)), 0x0000f8fc, 0x00400000,
760         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x70) & 0xFF)), 0x0000f8fc, 0x00400000,
761         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x78) & 0xFF)), 0x0000f8fc, 0x00400000,
762
763         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00000048, 0x00e1ff00,
764         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x8C) & 0xFF)), 0x00000048, 0x00dfff00,
765         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x94) & 0xFF)), 0x00000048, 0x00e3ff00,
766         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x9C) & 0xFF)), 0x00000048, 0x00000000,
767         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA4) & 0xFF)), 0x00000048, 0x00000000,
768         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xAC) & 0xFF)), 0x00000048, 0x00000000,
769         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB4) & 0xFF)), 0x00000048, 0x00000b00,
770         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xBC) & 0xFF)), 0x00000048, 0x00fe0b00,
771
772         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x80) & 0xFF)), 0x000000f0, 0x00e00003,
773         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x88) & 0xFF)), 0x000000f0, 0x00d80003,
774         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x90) & 0xFF)), 0x000000f0, 0x00e20003,
775         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0x98) & 0xFF)), 0x000000f0, 0x00000000,
776         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA0) & 0xFF)), 0x000000f0, 0x00000000,
777         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xA8) & 0xFF)), 0x000000f0, 0x00000000,
778         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB0) & 0xFF)), 0x000000f0, 0x00000a03,
779
780
781         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xB8) & 0xFF)), 0x000000f0, 0x00400003,
782
783         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC4) & 0xFF)), 0xFE000FC8, 0x0000d000,
784         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xCC) & 0xFF)), 0xFE000FC8, 0x000ff000,
785         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD4) & 0xFF)), 0xFE000FC8, 0x00000000,
786         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xDC) & 0xFF)), 0xFE000FC8, 0x00000000,
787
788         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC0) & 0xFF)), 0xFE000FCC, 0x0000d003,
789         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xC8) & 0xFF)), 0xFE000FCC, 0x00001013,
790         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD0) & 0xFF)), 0xFE000FCC, 0x00000000,
791         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xD8) & 0xFF)), 0xFE000FCC, 0x00000000,
792
793         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE0) & 0xFF)), 0x0000FC88, 0xff000003,
794         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE4) & 0xFF)), 0x0000FC88, 0x00000000,
795         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xE8) & 0xFF)), 0x0000FC88, 0x00000000,
796         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((1) & 0x07) << 8) | ((0xEC) & 0xFF)), 0x0000FC88, 0x00000000,
797
798         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x40) & 0xFF)), 0x001f01fe, 0x00000000,
799         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x44) & 0xFF)), 0x001f01fe, 0x00000000,
800         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x48) & 0xFF)), 0x001f01fe, 0x00000000,
801         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x4C) & 0xFF)), 0x001f01fe, 0x00000000,
802
803         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x50) & 0xFF)), 0x001f01fe, 0x00000000,
804         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x54) & 0xFF)), 0x001f01fe, 0x00000000,
805         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x58) & 0xFF)), 0x001f01fe, 0x00000000,
806         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x001f01fe, 0x00000000,
807
808         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x60) & 0xFF)), 0xC01f01ff, 0x00000000,
809         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x64) & 0xFF)), 0xC01f01ff, 0x00000000,
810         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x68) & 0xFF)), 0xC01f01ff, 0x00000000,
811         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x6C) & 0xFF)), 0xC01f01ff, 0x00000000,
812
813         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x70) & 0xFF)), 0xC01f01ff, 0x00000000,
814         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x74) & 0xFF)), 0xC01f01ff, 0x00000000,
815         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x78) & 0xFF)), 0xC01f01ff, 0x00000000,
816         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x7C) & 0xFF)), 0xC01f01ff, 0x00000000,
817
818         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x80) & 0xFF)), 0xffff8888, 0x00000000,
819
820         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x88) & 0xFF)), 0xe8088008, 0x03623125,
821
822         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x8c) & 0xFF)), 0xff8fe08e, 0x00000930,
823
824         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x90) & 0xFF)), 0xf0000000,
825         (4 << 25)|(0 << 24)|
826         (0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)|
827         (1 << 19)|(1 << 18)|(0 << 17)|(0 << 16)|
828         (2 << 14)|(0 << 13)|(0 << 12)|
829         (0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)|
830         (0 << 3) |(0 << 1) |(0 << 0),
831
832         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x94) & 0xFF)), 0xc180f0f0, 0x0e2b0a05,
833
834         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x07) << 8) | ((0x98) & 0xFF)), 0xfc00ffff, 0x00000000,
835
836         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((3) & 0x07) << 8) | ((0x58) & 0xFF)), 0xffe0e0e0, 0x00000000,
837
838         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((3) & 0x07) << 8) | ((0x5C) & 0xFF)), 0x0000003e, 0x00000000,
839
840
841
842
843
844         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((3) & 0x07) << 8) | ((0x60) & 0xFF)), 0xffffff00, 0x00000000,
845         };
846         int i;
847         int max;
848         print_debug("setting up CPU0 northbridge registers\r\n");
849         max = sizeof(register_values)/sizeof(register_values[0]);
850         for(i = 0; i < max; i += 3) {
851                 device_t dev;
852                 unsigned where;
853                 unsigned long reg;
854
855
856
857
858
859
860                 dev = register_values[i] & ~0xff;
861                 where = register_values[i] & 0xff;
862                 reg = pci_read_config32(dev, where);
863                 reg &= register_values[i+1];
864                 reg |= register_values[i+2];
865                 pci_write_config32(dev, where, reg);
866
867
868
869
870
871
872
873         }
874         print_debug("done.\r\n");
875 }
876
877
878 struct dimm_size {
879         unsigned long side1;
880         unsigned long side2;
881 };
882 static struct dimm_size spd_get_dimm_size(unsigned device)
883 {
884
885         struct dimm_size sz;
886         int value, low;
887         sz.side1 = 0;
888         sz.side2 = 0;
889
890
891
892
893
894         value = smbus_read_byte(device, 3);
895         if (value < 0) return sz;
896         sz.side1 += value & 0xf;
897
898         value = smbus_read_byte(device, 4);
899         if (value < 0) return sz;
900         sz.side1 += value & 0xf;
901
902         value = smbus_read_byte(device, 17);
903         if (value < 0) return sz;
904         sz.side1 += log2(value & 0xff);
905
906
907         value = smbus_read_byte(device, 7);
908         if (value < 0) return sz;
909         value &= 0xff;
910         value <<= 8;
911
912         low = smbus_read_byte(device, 6);
913         if (low < 0) return sz;
914         value = value | (low & 0xff);
915         sz.side1 += log2(value);
916
917
918         value = smbus_read_byte(device, 5);
919         if (value <= 1) return sz;
920
921
922         sz.side2 = sz.side1;
923
924         value = smbus_read_byte(device, 3);
925         if (value < 0) return sz;
926         if ((value & 0xf0) == 0) return sz;
927         sz.side2 -= (value & 0x0f);
928         sz.side2 += ((value >> 4) & 0x0f);
929
930         value = smbus_read_byte(device, 4);
931         if (value < 0) return sz;
932         sz.side2 -= (value & 0x0f);
933         sz.side2 += ((value >> 4) & 0x0f);
934         return sz;
935 }
936
937 static unsigned spd_to_dimm(unsigned device)
938 {
939         return (device - (0xa << 3));
940 }
941
942 static void set_dimm_size(struct dimm_size sz, unsigned index)
943 {
944         uint32_t base0, base1, map;
945
946
947         print_debug("set_dimm_size: (");
948         print_debug_hex32(sz.side1);
949         print_debug_char(',');
950         print_debug_hex32(sz.side2);
951         print_debug_char(',');
952         print_debug_hex32(index);
953         print_debug(")\r\n");
954
955         if (sz.side1 != sz.side2) {
956                 sz.side2 = 0;
957         }
958         map = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x80);
959         map &= ~(0xf << (index + 4));
960
961
962
963
964
965
966
967         base0 = base1 = 0;
968
969
970         if (sz.side1 >= (25 + 3)) {
971                 base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
972                 map |= (sz.side1 - (25 + 3)) << (index *4);
973         }
974
975
976         if (sz.side2 >= (25 + 3)) {
977                 base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
978         }
979
980
981         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (((index << 1)+0)<<2), base0);
982         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (((index << 1)+1)<<2), base1);
983         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x80, map);
984 }
985
986 static void spd_set_ram_size(void)
987 {
988         unsigned device;
989         for(device = (0xa << 3);
990                 device <= ((0xa << 3) +1);
991                 device += 1)
992         {
993                 struct dimm_size sz;
994                 sz = spd_get_dimm_size(device);
995                 set_dimm_size(sz, spd_to_dimm(device));
996         }
997 }
998
999 static void set_top_mem(unsigned tom_k)
1000 {
1001
1002         if (!tom_k) {
1003                 die("No memory");
1004         }
1005
1006         msr_t msr;
1007         msr.lo = (tom_k & 0x003fffff) << 10;
1008         msr.hi = (tom_k & 0xffc00000) >> 22;
1009         wrmsr(0xC001001A, msr);
1010
1011
1012
1013
1014
1015
1016
1017 }
1018
1019 static void order_dimms(void)
1020 {
1021         unsigned long tom;
1022         unsigned mask;
1023         unsigned index;
1024
1025
1026         tom = 0;
1027         for(;;) {
1028
1029                 unsigned canidate;
1030                 uint32_t csbase, csmask;
1031                 unsigned size;
1032                 csbase = 0;
1033                 canidate = 0;
1034                 for(index = 0; index < 8; index++) {
1035                         uint32_t value;
1036                         value = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (index << 2));
1037
1038
1039                         if (!(value & 1)) {
1040                                 continue;
1041                         }
1042
1043
1044                         if (value <= csbase) {
1045                                 continue;
1046                         }
1047
1048
1049                         if (tom & (1 << (index + 24))) {
1050                                 continue;
1051                         }
1052
1053                         csbase = value;
1054                         canidate = index;
1055                 }
1056
1057                 if (csbase == 0) {
1058                         break;
1059                 }
1060
1061
1062                 tom |= (1 << (canidate + 24));
1063
1064
1065                 size = csbase >> 21;
1066
1067
1068                 csbase = (tom << 21) | 1;
1069
1070
1071                 tom += size;
1072
1073
1074                 csmask = ((size -1) << 21);
1075                 csmask |= 0xfe00;
1076
1077
1078                 pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x40 + (canidate << 2), csbase);
1079
1080                 pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x60 + (canidate << 2), csmask);
1081
1082         }
1083         set_top_mem((tom & ~0xff000000) << 15);
1084 }
1085
1086 static void spd_set_dram_timing(void)
1087 {
1088
1089 }
1090
1091 static void spd_set_ecc_mode(void)
1092 {
1093         unsigned long dcl;
1094         dcl = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90);
1095
1096         dcl &= ~(1<<17);
1097         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90, dcl);
1098
1099 }
1100 static void sdram_set_spd_registers(void)
1101 {
1102         spd_set_ram_size();
1103         spd_set_dram_timing();
1104         spd_set_ecc_mode();
1105         order_dimms();
1106 }
1107
1108
1109 static void sdram_enable(void)
1110 {
1111         unsigned long dcl;
1112
1113
1114         dcl = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90);
1115         print_debug("dcl: ");
1116         print_debug_hex32(dcl);
1117         print_debug("\r\n");
1118         dcl |= (1<<3);
1119         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90, dcl);
1120         dcl &= ~(1<<3);
1121         dcl &= ~(1<<0);
1122         dcl &= ~(1<<1);
1123         dcl &= ~(1<<2);
1124         dcl |= (1<<8);
1125         pci_write_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90, dcl);
1126
1127         print_debug("Initializing memory: ");
1128         int loops = 0;
1129         do {
1130                 dcl = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)), 0x90);
1131                 loops += 1;
1132                 if ((loops & 1023) == 0) {
1133                         print_debug(".");
1134                 }
1135         } while(((dcl & (1<<8)) != 0) && (loops < 300000));
1136         if (loops >= 300000) {
1137                 print_debug(" failed\r\n");
1138         } else {
1139                 print_debug(" done\r\n");
1140         }
1141
1142 }
1143
1144 static void sdram_first_normal_reference(void) {}
1145 static void sdram_enable_refresh(void) {}
1146 static void sdram_special_finishup(void) {}
1147
1148
1149 static void setup_coherent_ht_domain(void)
1150 {
1151         static const unsigned int register_values[] = {
1152
1153         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x40) & 0xFF)), 0xfff0f0f0, 0x00010101,
1154         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x44) & 0xFF)), 0xfff0f0f0, 0x00010101,
1155         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x48) & 0xFF)), 0xfff0f0f0, 0x00010101,
1156         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x4c) & 0xFF)), 0xfff0f0f0, 0x00010101,
1157         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x50) & 0xFF)), 0xfff0f0f0, 0x00010101,
1158         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x54) & 0xFF)), 0xfff0f0f0, 0x00010101,
1159         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x58) & 0xFF)), 0xfff0f0f0, 0x00010101,
1160         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x5c) & 0xFF)), 0xfff0f0f0, 0x00010101,
1161
1162         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x68) & 0xFF)), 0x00800000, 0x0f00840f,
1163
1164         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x6C) & 0xFF)), 0xffffff8c, 0x00000000 | (1 << 6) |(1 << 5)| (1 << 4),
1165
1166         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x84) & 0xFF)), 0x00009c05, 0x11110020,
1167
1168         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x88) & 0xFF)), 0xfffff0ff, 0x00000200,
1169
1170         ( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x07) << 8) | ((0x94) & 0xFF)), 0xff000000, 0x00ff0000,
1171
1172
1173
1174
1175
1176         };
1177         int i;
1178         int max;
1179         print_debug("setting up coherent ht domain....\r\n");
1180         max = sizeof(register_values)/sizeof(register_values[0]);
1181         for(i = 0; i < max; i += 3) {
1182                 device_t dev;
1183                 unsigned where;
1184                 unsigned long reg;
1185
1186
1187
1188
1189
1190
1191                 dev = register_values[i] & ~0xff;
1192                 where = register_values[i] & 0xff;
1193                 reg = pci_read_config32(dev, where);
1194                 reg &= register_values[i+1];
1195                 reg |= register_values[i+2];
1196                 pci_write_config32(dev, where, reg);
1197
1198
1199
1200
1201
1202
1203         }
1204         print_debug("done.\r\n");
1205 }
1206
1207
1208 void sdram_no_memory(void)
1209 {
1210         print_err("No memory!!\r\n");
1211         while(1) {
1212                 hlt();
1213         }
1214 }
1215
1216
1217 void sdram_initialize(void)
1218 {
1219         print_debug("Ram1\r\n");
1220
1221         sdram_set_registers();
1222
1223         print_debug("Ram2\r\n");
1224
1225         sdram_set_spd_registers();
1226
1227         print_debug("Ram3\r\n");
1228
1229
1230
1231
1232         sdram_enable();
1233
1234         print_debug("Ram4\r\n");
1235         sdram_first_normal_reference();
1236
1237         print_debug("Ram5\r\n");
1238         sdram_enable_refresh();
1239         sdram_special_finishup();
1240
1241         print_debug("Ram6\r\n");
1242 }
1243
1244
1245 static int boot_cpu(void)
1246 {
1247         volatile unsigned long *local_apic;
1248         unsigned long apic_id;
1249         int bsp;
1250         msr_t msr;
1251         msr = rdmsr(0x1b);
1252         bsp = !!(msr.lo & (1 << 8));
1253         if (bsp) {
1254                 print_debug("Bootstrap processor\r\n");
1255         } else {
1256                 print_debug("Application processor\r\n");
1257         }
1258
1259         return bsp;
1260 }
1261
1262 static int cpu_init_detected(void)
1263 {
1264         unsigned long dcl;
1265         int cpu_init;
1266
1267         unsigned long htic;
1268
1269         htic = pci_read_config32(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((0) & 0x7) << 8)), 0x6c);
1270
1271         cpu_init = (htic & (1<<6));
1272         if (cpu_init) {
1273                 print_debug("CPU INIT Detected.\r\n");
1274         }
1275         return cpu_init;
1276 }
1277
1278
1279 static void print_debug_pci_dev(unsigned dev)
1280 {
1281         print_debug("PCI: ");
1282         print_debug_hex8((dev >> 16) & 0xff);
1283         print_debug_char(':');
1284         print_debug_hex8((dev >> 11) & 0x1f);
1285         print_debug_char('.');
1286         print_debug_hex8((dev >> 8) & 7);
1287 }
1288
1289 static void print_pci_devices(void)
1290 {
1291         device_t dev;
1292         for(dev = ( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((0) & 0x7) << 8));
1293                 dev <= ( (((0) & 0xFF) << 16) | (((0x1f) & 0x1f) << 11) | (((0x7) & 0x7) << 8));
1294                 dev += ( (((0) & 0xFF) << 16) | (((0) & 0x1f) << 11) | (((1) & 0x7) << 8))) {
1295                 uint32_t id;
1296                 id = pci_read_config32(dev, 0x00);
1297                 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
1298                         (((id >> 16) & 0xffff) == 0xffff) ||
1299                         (((id >> 16) & 0xffff) == 0x0000)) {
1300                         continue;
1301                 }
1302                 print_debug_pci_dev(dev);
1303                 print_debug("\r\n");
1304         }
1305 }
1306
1307
1308 static void dump_pci_device(unsigned dev)
1309 {
1310         int i;
1311         print_debug_pci_dev(dev);
1312         print_debug("\r\n");
1313
1314         for(i = 0; i <= 255; i++) {
1315                 unsigned char val;
1316                 if ((i & 0x0f) == 0) {
1317                         print_debug_hex8(i);
1318                         print_debug_char(':');
1319                 }
1320                 val = pci_read_config8(dev, i);
1321                 print_debug_char(' ');
1322                 print_debug_hex8(val);
1323                 if ((i & 0x0f) == 0x0f) {
1324                         print_debug("\r\n");
1325                 }
1326         }
1327 }
1328
1329 static void dump_spd_registers(void)
1330 {
1331         unsigned device;
1332         device = (0xa << 3);
1333         print_debug("\r\n");
1334         while(device <= ((0xa << 3) +1)) {
1335                 int i;
1336                 print_debug("dimm: ");
1337                 print_debug_hex8(device);
1338                 for(i = 0; i < 256; i++) {
1339                         int status;
1340                         unsigned char byte;
1341                         if ((i & 0xf) == 0) {
1342                                 print_debug("\r\n");
1343                                 print_debug_hex8(i);
1344                                 print_debug(": ");
1345                         }
1346                         status = smbus_read_byte(device, i);
1347                         if (status < 0) {
1348                                 print_debug("bad device\r\n");
1349                                 break;
1350                         }
1351                         byte = status & 0xff;
1352                         print_debug_hex8(byte);
1353                         print_debug_char(' ');
1354                 }
1355                 device += 1;
1356                 print_debug("\r\n");
1357         }
1358 }
1359
1360
1361 static void main(void)
1362 {
1363         uart_init();
1364         console_init();
1365
1366
1367
1368
1369
1370
1371
1372         if (boot_cpu() && !cpu_init_detected()) {
1373                 setup_default_resource_map();
1374                 setup_coherent_ht_domain();
1375                 enumerate_ht_chain();
1376                 print_pci_devices();
1377                 enable_smbus();
1378                 sdram_initialize();
1379
1380                 dump_spd_registers();
1381                 dump_pci_device(( (((0) & 0xFF) << 16) | (((0x18) & 0x1f) << 11) | (((2) & 0x7) << 8)));
1382
1383
1384                 msr_t msr;
1385                 msr = rdmsr(0xC001001A);
1386                 print_debug("TOP_MEM: ");
1387                 print_debug_hex32(msr.hi);
1388                 print_debug_hex32(msr.lo);
1389                 print_debug("\r\n");
1390                 ram_check(0x00000000, msr.lo);
1391         }
1392 }