0612989337605bc9903ce6b58fb4e0635eb8a178
[coreboot.git] / src / mainboard / tyan / s2880 / auto.c
1 #define ASSEMBLY 1
2 #include <stdint.h>
3 #include <device/pci_def.h>
4 #include "arch/romcc_io.h"
5 #include "pc80/serial.c"
6 #include "arch/i386/lib/console.c"
7 #include "ram/ramtest.c"
8 #include "northbridge/amd/amdk8/early_ht.c"
9 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
10 #include "northbridge/amd/amdk8/raminit.h"
11 /*
12 #warning "FIXME move these delay functions somewhere more appropriate"
13 #warning "FIXME use the apic timer instead it needs no calibration on an Opteron it runs at 200Mhz"
14 static void print_clock_multiplier(void)
15 {
16         msr_t msr;
17         print_debug("clock multipler: 0x");
18         msr = rdmsr(0xc0010042);
19         print_debug_hex32(msr.lo & 0x3f);
20         print_debug(" = 0x");
21         print_debug_hex32(((msr.lo & 0x3f) + 8) * 100);
22         print_debug("Mhz\r\n");
23 }
24
25 static unsigned usecs_to_ticks(unsigned usecs)
26 {
27 #warning "FIXME make usecs_to_ticks work properly"
28 #if 1
29         return usecs *2000;
30 #else
31         // This can only be done if cpuid says fid changing is supported
32         // I need to look up the base frequency another way for other
33         // cpus.  Is it worth dedicating a global register to this?
34         // Are the PET timers useable for this purpose?
35          
36         msr_t msr;
37         msr = rdmsr(0xc0010042);
38         return ((msr.lo & 0x3f) + 8) * 100 *usecs;
39 #endif
40 }
41
42 static void init_apic_timer(void)
43 {
44         volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
45         uint32_t start, end;
46         // Set the apic timer to no interrupts and periodic mode 
47         apic_reg[0x320 >> 2] = (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0);
48         // Set the divider to 1, no divider 
49         apic_reg[0x3e0 >> 2] = (1 << 3) | 3;
50         // Set the initial counter to 0xffffffff 
51         apic_reg[0x380 >> 2] = 0xffffffff;
52 }
53
54 static void udelay(unsigned usecs)
55 {
56 #if 1
57         uint32_t start, ticks;
58         tsc_t tsc;
59         // Calculate the number of ticks to run for 
60         ticks = usecs_to_ticks(usecs);
61         // Find the current time 
62         tsc = rdtsc();
63         start = tsc.lo;
64         do {
65                 tsc = rdtsc();
66         } while((tsc.lo - start) < ticks);
67 #else
68         volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
69         uint32_t start, value, ticks;
70         // Calculate the number of ticks to run for 
71         ticks = usecs * 200;
72         start = apic_reg[0x390 >> 2];
73         do {
74                 value = apic_reg[0x390 >> 2];
75         } while((start - value) < ticks);
76 #endif
77 }
78
79 static void mdelay(unsigned msecs)
80 {
81         int i;
82         for(i = 0; i < msecs; i++) {
83                 udelay(1000);
84         }
85 }
86
87 static void delay(unsigned secs)
88 {
89         int i;
90         for(i = 0; i < secs; i++) {
91                 mdelay(1000);
92         }
93 }
94
95 static void memreset_setup(const struct mem_controller *ctrl)
96 {
97         // Set the memreset low 
98         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
99         // Ensure the BIOS has control of the memory lines 
100         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
101         print_debug("memreset lo\r\n");
102 }
103
104 static void memreset(const struct mem_controller *ctrl)
105 {
106         udelay(800);
107         // Set memreset_high 
108         outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
109         print_debug("memreset hi\r\n");
110         udelay(50);
111 }
112 */              
113
114 #include "northbridge/amd/amdk8/raminit.c"
115 #include "northbridge/amd/amdk8/coherent_ht.c"
116 #include "sdram/generic_sdram.c"
117
118 #define NODE_ID         0x60
119 #define HT_INIT_CONTROL 0x6c
120  
121 #define HTIC_ColdR_Detect  (1<<4)
122 #define HTIC_BIOSR_Detect  (1<<5)
123 #define HTIC_INIT_Detect   (1<<6)
124  
125 #define APIC_DEFAULT_BASE 0xfee00000
126
127 #define APIC_ID         0x020
128
129 static int boot_cpu(void)
130 {
131         volatile unsigned long *local_apic;
132         unsigned long apic_id;
133         int bsp;
134         int apicEn;
135         msr_t msr;
136         msr = rdmsr(0x1b);
137         bsp = !!(msr.lo & (1 << 8));
138         apicEn = !!(msr.lo & (1<<11));
139         if(apicEn) {
140                 print_debug("apic enabled\r\n");
141         } else {
142                 msr.lo |= (1<<11);
143                 wrmsr(0x1b,msr);
144         }
145         apic_id = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
146         print_debug("apic_id: ");
147         print_debug_hex32(apic_id>>24);
148         print_debug("\r\n");
149         
150         if (bsp) {
151                 print_debug("Bootstrap cpu\r\n");
152         } else {
153                 print_debug("Application processor\r\n");
154         //      asm("hlt"); // move to end before halt should notify BSP
155                    // if you start AP in coherent.c you can just stop it here   
156         }
157
158         return bsp;
159 }
160
161 static int cpu_init_detected(void)
162 {
163         unsigned long dcl;
164         int cpu_init;
165
166         unsigned long htic;
167
168         htic = pci_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL);
169 #if 0
170         print_debug("htic: ");
171         print_debug_hex32(htic);
172         print_debug("\r\n");
173
174         if (!(htic & HTIC_ColdR_Detect)) {
175                 print_debug("Cold Reset.\r\n");
176         }
177         if ((htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect)) {
178                 print_debug("BIOS generated Reset.\r\n");
179         }
180         if (htic & HTIC_INIT_Detect) {
181                 print_debug("Init event.\r\n");
182         }
183 #endif
184         cpu_init = (htic & HTIC_INIT_Detect);
185         if (cpu_init) {
186                 print_debug("CPU INIT Detected.\r\n");
187         }
188         return cpu_init;
189 }
190 /*
191 static void print_debug_pci_dev(unsigned dev)
192 {
193         print_debug("PCI: ");
194         print_debug_hex8((dev >> 16) & 0xff);
195         print_debug_char(':');
196         print_debug_hex8((dev >> 11) & 0x1f);
197         print_debug_char('.');
198         print_debug_hex8((dev >> 8) & 7);
199 }
200
201
202 static void print_pci_devices(void)
203 {
204         device_t dev;
205         for(dev = PCI_DEV(0, 0, 0); 
206                 dev <= PCI_DEV(0, 0x1f, 0x7); 
207                 dev += PCI_DEV(0,0,1)) {
208                 uint32_t id;
209                 id = pci_read_config32(dev, PCI_VENDOR_ID);
210                 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
211                         (((id >> 16) & 0xffff) == 0xffff) ||
212                         (((id >> 16) & 0xffff) == 0x0000)) {
213                         continue;
214                 }
215                 print_debug_pci_dev(dev);
216                 print_debug("\r\n");
217         }
218 }
219 */
220 /*
221 static void dump_pci_device(unsigned dev)
222 {
223         int i;
224         print_debug_pci_dev(dev);
225         print_debug("\r\n");
226
227         for(i = 0; i <= 255; i++) {
228                 unsigned char val;
229                 if ((i & 0x0f) == 0) {
230                         print_debug_hex8(i);
231                         print_debug_char(':');
232                 }
233                 val = pci_read_config8(dev, i);
234                 print_debug_char(' ');
235                 print_debug_hex8(val);
236                 if ((i & 0x0f) == 0x0f) {
237                         print_debug("\r\n");
238                 }
239         }
240 }
241 static void dump_pci_devices(void)
242 {
243         device_t dev;
244         for(dev = PCI_DEV(0, 0, 0);
245                 dev <= PCI_DEV(0, 0x1f, 0x7);
246                 dev += PCI_DEV(0,0,1)) {
247                 uint32_t id;
248                 id = pci_read_config32(dev, PCI_VENDOR_ID);
249                 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
250                         (((id >> 16) & 0xffff) == 0xffff) ||
251                         (((id >> 16) & 0xffff) == 0x0000)) {
252                         continue;
253                 }
254                 dump_pci_device(dev);
255         }
256 }
257
258
259
260 static void dump_spd_registers(const struct mem_controller *ctrl)
261 {
262         int i;
263         print_debug("\r\n");
264         for(i = 0; i < 4; i++) {
265                 unsigned device;
266                 device = ctrl->channel0[i];
267                 if (device) {
268                         int j;
269                         print_debug("dimm: ");
270                         print_debug_hex8(i);
271                         print_debug(".0: ");
272                         print_debug_hex8(device);
273                         for(j = 0; j < 256; j++) {
274                                 int status;
275                                 unsigned char byte;
276                                 if ((j & 0xf) == 0) {
277                                         print_debug("\r\n");
278                                         print_debug_hex8(j);
279                                         print_debug(": ");
280                                 }
281                                 status = smbus_read_byte(device, j);
282                                 if (status < 0) {
283                                         print_debug("bad device\r\n");
284      
285                                         break;
286                                 }
287                                 byte = status & 0xff;
288                                 print_debug_hex8(byte);
289                                 print_debug_char(' ');
290                         }
291                         print_debug("\r\n");
292                 }
293                 device = ctrl->channel1[i];
294                 if (device) {
295                         int j;
296                         print_debug("dimm: ");
297                         print_debug_hex8(i);
298                         print_debug(".1: ");
299                         print_debug_hex8(device);
300                         for(j = 0; j < 256; j++) {
301                                 int status;
302                                 unsigned char byte;
303                                 if ((j & 0xf) == 0) {
304                                         print_debug("\r\n");
305                                         print_debug_hex8(j);
306                                         print_debug(": ");
307                                 }
308                                 status = smbus_read_byte(device, j);
309       
310                                 if (status < 0) {
311                                         print_debug("bad device\r\n");
312                                         break;
313                                 }
314                                 byte = status & 0xff;
315                                 print_debug_hex8(byte);
316                                 print_debug_char(' ');
317                         }
318                         print_debug("\r\n");
319                 }
320         }
321 }
322
323 */
324
325
326
327 static void main(void)
328 {
329         static const struct mem_controller cpu0 = {
330                 .f0 = PCI_DEV(0, 0x18, 0),
331                 .f1 = PCI_DEV(0, 0x18, 1),
332                 .f2 = PCI_DEV(0, 0x18, 2),
333                 .f3 = PCI_DEV(0, 0x18, 3),
334                 .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 },
335                 .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 },
336         };
337         static const struct mem_controller cpu1 = {
338                 .f0 = PCI_DEV(0, 0x19, 0),
339                 .f1 = PCI_DEV(0, 0x19, 1),
340                 .f2 = PCI_DEV(0, 0x19, 2),
341                 .f3 = PCI_DEV(0, 0x19, 3),
342                 .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 },
343                 .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 },
344         };
345
346  //               device_t dev;
347  //               unsigned where;
348                 unsigned long reg;
349 //                dev = PCI_ADDR(0, 0x19, 0, 0x6C) & ~0xff;
350 //                where = PCI_ADDR(0, 0x19, 0, 0x6C) & 0xff;
351 #if 0
352                 init_apic_timer();
353 #endif
354   
355         uart_init();
356         console_init();
357         if (boot_cpu() && !cpu_init_detected()) {
358                 setup_default_resource_map();
359                 setup_coherent_ht_domain();
360                 enumerate_ht_chain();
361 //              print_pci_devices();
362                 enable_smbus();
363 //              sdram_initialize();
364  //               dump_spd_registers(&cpu0);
365                 sdram_initialize(&cpu0);
366  //               dump_spd_registers(&cpu1);
367 //                sdram_initialize(&cpu1);
368
369 //              dump_pci_device(PCI_DEV(0, 0x18, 2));
370 #if 0
371                 ram_fill(  0x00100000, 0x00180000);
372                 ram_verify(0x00100000, 0x00180000);
373 #endif
374 //#ifdef MEMORY_1024MB
375 //              ram_fill(  0x00000000, 0x00001000);
376 //              ram_verify(0x00000000, 0x00001000);
377 //#endif
378 //#ifdef MEMROY_512MB
379 //              ram_fill(  0x00000000, 0x01ffffff);
380 //              ram_verify(0x00000000, 0x01ffffff);
381 //#endif
382                                 /* Check the first 512M */
383 /*                msr_t msr;
384                 msr = rdmsr(TOP_MEM);
385                 print_debug("TOP_MEM: ");
386                 print_debug_hex32(msr.hi);
387                 print_debug_hex32(msr.lo);
388                 print_debug("\r\n");
389                 ram_check(0x00000000, msr.lo);
390   */            
391 /*
392         reg = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
393         print_debug("bootstrap cpu apic_id: ");
394         print_debug_hex32(reg>>24);
395         print_debug("\r\n");
396 */
397
398                 // Start AP now
399                 reg = pci_read_config32(PCI_DEV(0, 0x19, 0), 0x6C);
400                 reg &= 0xffffff8c;
401                 reg |= 0x00000070;
402                 pci_write_config32(PCI_DEV(0, 0x19, 0), 0x6C, reg); //start AP
403                 for(;;) {
404                         reg = pci_read_config32(PCI_DEV(0, 0x19, 0), 0x6C);
405                         if((reg & (1<<4))==0) break;  // wait until AP stop
406                 }
407                 reg |= 1<<4;
408                 pci_write_config32(PCI_DEV(0, 0x19, 0), 0x6C, reg);
409
410         }
411  else {
412           // Need to init second cpu's APIC id
413         // It's AP 
414  
415 //      apic_write(APIC_ID,(1<<24));
416         reg = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
417 /*      print_debug("applicaton cpu apic_id: ");
418         print_debug_hex32(reg>>24);
419         print_debug("\r\n");
420         if((reg>>24)==7){ // FIXME: Need to read NodeID at first.
421                 *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID))=1<<24;
422         }*/
423         if((reg>>24)!=0) {
424 //              before hlt clear the ColdResetbit
425                 
426                 //notify BSP that AP is stopped
427                 reg = pci_read_config32(PCI_DEV(0, 0x19, 0), 0x6C);
428                 reg &= ~(1<<4);
429                 pci_write_config32(PCI_DEV(0, 0x19, 0),  0x6C, reg);
430
431                 asm("hlt");
432         }
433        
434
435         }
436         
437 }