Drop the need for cpu_reset, it's really just a short cut to stage2.
[coreboot.git] / src / mainboard / dell / s1850 / romstage.c
1 #include <stdint.h>
2 #include <device/pci_def.h>
3 #include <arch/io.h>
4 #include <device/pnp_def.h>
5 #include <arch/romcc_io.h>
6 #include <cpu/x86/lapic.h>
7 #include <stdlib.h>
8 #include "option_table.h"
9 #include "pc80/mc146818rtc_early.c"
10 #include "pc80/serial.c"
11 #include "console/console.c"
12 #include "lib/ramtest.c"
13 #include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
14 #include "northbridge/intel/e7520/raminit.h"
15 #include "superio/nsc/pc8374/pc8374_early_init.c"
16 #include "cpu/x86/lapic/boot_cpu.c"
17 #include "cpu/x86/mtrr/earlymtrr.c"
18 #include "debug.c"
19 #include "watchdog.c"
20 // Remove comment if resets in this file are actually used.
21 // #include "reset.c"
22 #include "s1850_fixups.c"
23 #include "northbridge/intel/e7520/memory_initialized.c"
24 #include "cpu/x86/bist.h"
25
26 #define SIO_GPIO_BASE 0x680
27 #define SIO_XBUS_BASE 0x4880
28
29 #define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, PC8374_SP1)
30
31 #define DEVPRES_CONFIG  ( \
32         DEVPRES_D0F0 | \
33         DEVPRES_D1F0 | \
34         DEVPRES_D2F0 | \
35         DEVPRES_D3F0 | \
36         DEVPRES_D4F0 | \
37         DEVPRES_D6F0 | \
38         0 )
39 #define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
40
41 #define RECVENA_CONFIG  0x0808090a
42 #define RECVENB_CONFIG  0x0808090a
43
44 static inline void activate_spd_rom(const struct mem_controller *ctrl)
45 {
46         /* nothing to do */
47 }
48 static inline int spd_read_byte(unsigned device, unsigned address)
49 {
50         return smbus_read_byte(device, address);
51 }
52
53 /* this is very highly mainboard dependent, related to wiring */
54 /* from factory BIOS via lspci */
55 #define DIMM_MAP_LOGICAL 0x2841
56 #include "northbridge/intel/e7520/raminit.c"
57 #include "lib/generic_sdram.c"
58
59 /* IPMI garbage. This is all test stuff, if it really works we'll move it somewhere
60  */
61
62 #define nftransport  0xc
63
64 #define OBF  0
65 #define IBF 1
66
67 #define ipmidata  0xca0
68 #define ipmicsr  0xca4
69
70 static inline void  ibfzero(void)
71 {
72         while(inb(ipmicsr) &  (1<<IBF)) 
73                 ;
74 }
75 static inline void  clearobf(void)
76 {
77         (void) inb(ipmidata);
78 }
79
80 static inline void  waitobf(void)
81 {
82         while((inb(ipmicsr) &  (1<<OBF)) == 0) 
83                 ;
84 }
85 /* quite possibly the stupidest interface ever designed. */
86 static inline void  first_cmd_byte(unsigned char byte)
87 {
88         ibfzero();
89         clearobf();
90         outb(0x61, ipmicsr);
91         ibfzero();
92         clearobf();
93         outb(byte, ipmidata);
94 }
95
96 static inline void  next_cmd_byte(unsigned char byte)
97 {
98
99         ibfzero();
100         clearobf();
101         outb(byte, ipmidata);
102 }
103
104 static inline void  last_cmd_byte(unsigned char byte)
105 {
106         outb(0x62, ipmicsr);
107
108         ibfzero();
109         clearobf();
110         outb(byte,  ipmidata);
111 }
112
113 static inline void read_response_byte(void)
114 {
115         int val = -1;
116         if ((inb(ipmicsr)>>6) != 1)
117                 return;
118
119         ibfzero();
120         waitobf();
121         val = inb(ipmidata);
122         outb(0x68, ipmidata);
123
124         /* see if it is done */
125         if ((inb(ipmicsr)>>6) != 1){
126                 /* wait for the dummy read. Which describes this protocol */
127                 waitobf();
128                 (void)inb(ipmidata);
129         }
130 }
131
132 static inline void ipmidelay(void)
133 {
134         int i;
135         for(i = 0; i < 1000; i++) {
136                 inb(0x80);
137         }
138 }
139
140 static inline void bmc_foad(void)
141 {
142         unsigned char c;
143         /* be safe; make sure it is really ready */
144         while ((inb(ipmicsr)>>6)) {
145                 outb(0x60, ipmicsr);
146                 inb(ipmidata);
147         }
148         first_cmd_byte(nftransport << 2);
149         ipmidelay();
150         next_cmd_byte(0x12);
151         ipmidelay();
152         next_cmd_byte(2);
153         ipmidelay();
154         last_cmd_byte(3);
155         ipmidelay();
156 }
157
158 /* end IPMI garbage */
159
160 #include "arch/i386/lib/stages.c"
161
162 static void main(unsigned long bist)
163 {
164         u8 b;
165         u16 w;
166         u32 l;
167         int do_reset;
168         /*
169          * 
170          * 
171          */
172         static const struct mem_controller mch[] = {
173                 {
174                         .node_id = 0,
175                         /*
176                         .f0 = PCI_DEV(0, 0x00, 0),
177                         .f1 = PCI_DEV(0, 0x00, 1),
178                         .f2 = PCI_DEV(0, 0x00, 2),
179                         .f3 = PCI_DEV(0, 0x00, 3),
180                         */
181                         /* the wiring on this part is really messed up */
182                         /* this is my best guess so far */
183                         .channel0 = {(0xa<<3)|0, (0xa<<3)|1, (0xa<<3)|2, (0xa<<3)|3, },
184                         .channel1 = {(0xa<<3)|4, (0xa<<3)|5, (0xa<<3)|6, (0xa<<3)|7, },
185                 }
186         };
187
188         /* superio setup */
189         /* observed from serialice */
190         static const u8 earlyinit[] = {
191                 0x21, 0x11, 0x11,
192                 0x22, 1, 1,
193                 0x23, 05, 05,
194                 0x24, 0x81, 0x81,
195                 0x26, 0, 0,
196                 0,
197         };
198
199         /* using SerialICE, we've seen this basic reset sequence on the dell. 
200          * we don't understand it as it uses undocumented registers, but
201          * we're going to clone it. 
202          */
203         /* enable a hidden device. */
204         b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4);
205         b |= 0x8;
206         pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b);
207
208         /* read-write lock in CMOS on LPC bridge on ICH5 */
209         pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd8, 4);
210
211         /* operate on undocumented device */
212         l = pci_read_config32(PCI_DEV(0, 0, 2), 0xa4);
213         l |= 0x1000;
214         pci_write_config32(PCI_DEV(0, 0, 2), 0xa4, l);
215
216         l = pci_read_config32(PCI_DEV(0, 0, 2), 0x9c);
217         l |= 0x8000;
218         pci_write_config32(PCI_DEV(0, 0, 2), 0x9c, l);
219
220         /* disable undocumented device */
221         b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4);
222         b &= ~0x8;
223         pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b);
224         
225         /* set up LPC bridge bits, some of which reply on undocumented
226          * registers
227          */
228         
229         b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xd8);
230         b |= 4;
231         pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd8, b);
232
233         b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xd4);
234         b |= 2;
235         pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xd4, b);
236
237         /* ACPI base address */
238         pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x40, 0x800);
239
240         /* Enable specific ACPI features */
241         b= pci_read_config8(PCI_DEV(0, 0x1f, 0), 0x44);
242         b |= 0x10;
243         pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44, b);
244
245         /* ACPI control */
246         w = inw(0x868);
247         outw(w|0x800, 0x868);
248         w = inw(0x866);
249         outw(w|2, 0x866);
250
251 #if 0 
252         /*seriaice shows
253         dell does this so leave it here so I don't forget 
254          */
255         /* SMBUS */
256         pci_write_config16(PCI_DEV(0, 0x1f, 3), 0x20, 0x08c0);
257
258         /* unknown */
259         b = inb(0x8c2);
260         outb(0xdf, 0x8c2);
261 #endif
262
263         /* another device enable? */
264         b = pci_read_config8(PCI_DEV(0, 0, 0), 0xf4);
265         b |= 2;
266         pci_write_config8(PCI_DEV(0, 0, 0), 0xf4, b);
267         
268         /* ?? */
269         l = pci_read_config32(PCI_DEV(0, 8, 0), 0xc0);
270         do_reset = l & 0x8000000;
271         l |= 0x8000000;
272         pci_write_config32(PCI_DEV(0, 8, 0), 0xc0, l);
273
274         if (! do_reset) {
275                 outb(2, 0xcf9);
276                 outb(6, 0xcf9);
277         }
278         if (bist == 0) {
279                 /* Skip this if there was a built in self test failure */
280                 early_mtrr_init();
281                 if (memory_initialized()) {
282                         skip_romstage();
283                 }
284         }
285         /* Setup the console */
286         mainboard_set_ich5();
287         //bmc_foad();
288         pc8374_enable_dev(CONSOLE_SERIAL_DEV, CONFIG_TTYS0_BASE);
289         uart_init();
290         console_init();
291
292         /* stuff we seem to need */
293         pc8374_enable_dev(PNP_DEV(0x2e, PC8374_KBCK), 0);
294
295         /* GPIOs */
296         pc8374_enable_dev(PNP_DEV(0x2e, PC8374_GPIO), 0xc20);
297
298         /* keep this in mind.
299         SerialICE-hlp: outb 002e <= 23
300         SerialICE-hlp:  inb 002f => 05
301         SerialICE-hlp: outb 002f <= 05
302         SerialICE-hlp: outb 002e <= 24
303         SerialICE-hlp:  inb 002f => c1
304         SerialICE-hlp: outb 002f <= c1
305          */
306
307         /* Halt if there was a built in self test failure */
308 //      report_bist_failure(bist);
309
310         /* MOVE ME TO A BETTER LOCATION !!! */
311         /* config LPC decode for flash memory access */
312         device_t dev;
313         dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
314         if (dev == PCI_DEV_INVALID) {
315                 die("Missing ich5?");
316         }
317         pci_write_config32(dev, 0xe8, 0x00000000);
318         pci_write_config8(dev, 0xf0, 0x00);
319
320 #if 0
321         display_cpuid_update_microcode();
322 #endif
323 #if 1
324         print_pci_devices();
325 #endif
326 #if 1
327         enable_smbus();
328 #endif
329 #if 0
330 //      dump_spd_registers(&cpu[0]);
331         int i;
332         for(i = 0; i < 1; i++) {
333                 dump_spd_registers();
334         }
335 #endif
336 #if 1
337         show_dram_slots();
338 #endif
339         disable_watchdogs();
340 //      dump_ipmi_registers();
341         mainboard_set_e7520_leds();     
342 //      memreset_setup();
343
344         sdram_initialize(ARRAY_SIZE(mch), mch);
345 #if 0
346         dump_pci_devices();
347 #endif
348 #if 1
349         dump_pci_device(PCI_DEV(0, 0x00, 0));
350 //      dump_bar14(PCI_DEV(0, 0x00, 0));
351 #endif
352
353 #if 1 // temporarily disabled 
354         /* Check the first 1M */
355 //      ram_check(0x00000000, 0x000100000);
356 //      ram_check(0x00000000, 0x000a0000);
357 //      ram_check(0x00100000, 0x01000000);
358         ram_check(0x00100000, 0x00100100);
359         /* check the first 1M in the 3rd Gig */
360 //      ram_check(0x30100000, 0x31000000);
361 #endif
362 #if 0
363         ram_check(0x00000000, 0x02000000);
364 #endif
365         
366 #if 0   
367         while(1) {
368                 hlt();
369         }
370 #endif
371 }
372