Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-51
[coreboot.git] / src / mainboard / tyan / s2895 / cache_as_ram_auto.c
1 #define ASSEMBLY 1
2 #define __ROMCC__
3  
4 #include <stdint.h>
5 #include <device/pci_def.h>
6 #include <arch/io.h>
7 #include <device/pnp_def.h>
8 #include <arch/romcc_io.h>
9 #include <cpu/x86/lapic.h>
10 #include "option_table.h"
11 #include "pc80/mc146818rtc_early.c"
12 #include "pc80/serial.c"
13 #include "arch/i386/lib/console.c"
14 #include "ram/ramtest.c"
15
16
17 #include "northbridge/amd/amdk8/cpu_rev.c"
18 #define K8_HT_FREQ_1G_SUPPORT 0
19 #include "northbridge/amd/amdk8/incoherent_ht.c"
20 #include "southbridge/nvidia/ck804/ck804_early_smbus.c"
21 #include "northbridge/amd/amdk8/raminit.h"
22 #include "cpu/amd/model_fxx/apic_timer.c"
23 #include "lib/delay.c"
24
25 #if CONFIG_USE_INIT == 0
26 #include "lib/memcpy.c"
27 #endif
28
29 #include "cpu/x86/lapic/boot_cpu.c"
30 #include "northbridge/amd/amdk8/reset_test.c"
31 #include "northbridge/amd/amdk8/debug.c"
32 #include "superio/smsc/lpc47b397/lpc47b397_early_serial.c"
33
34 #include "cpu/amd/mtrr/amd_earlymtrr.c"
35 #include "cpu/x86/bist.h"
36
37 #include "superio/smsc/lpc47b397/lpc47b397_early_gpio.c"
38
39 #include "northbridge/amd/amdk8/setup_resource_map.c"
40
41 #define SERIAL_DEV PNP_DEV(0x2e, LPC47B397_SP1)
42
43 static void hard_reset(void)
44 {
45         set_bios_reset();
46
47         /* full reset */
48         outb(0x0a, 0x0cf9);
49         outb(0x0e, 0x0cf9);
50 }
51
52 static void soft_reset(void)
53 {
54         set_bios_reset();
55 #if 1
56         /* link reset */
57         outb(0x02, 0x0cf9);
58         outb(0x06, 0x0cf9);
59 #endif
60 }
61
62 static void memreset_setup(void)
63 {
64 }
65
66 static void memreset(int controllers, const struct mem_controller *ctrl)
67 {
68 }
69
70 #define SUPERIO_GPIO_DEV PNP_DEV(0x2e, LPC47B397_RT)
71
72 #define SUPERIO_GPIO_IO_BASE 0x400
73
74 static void sio_gpio_setup(void){
75
76         unsigned value;
77
78
79 #if 1
80         /*Enable onboard scsi*/
81         lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x2c, (1<<7)|(0<<2)|(0<<1)|(0<<0)); // GP21, offset 0x2c, DISABLE_SCSI_L 
82         value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x4c);
83         lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x4c, (value|(1<<1)));
84 #endif
85
86 }
87
88 static inline void activate_spd_rom(const struct mem_controller *ctrl)
89 {
90         /* nothing to do */
91 }
92
93 static inline int spd_read_byte(unsigned device, unsigned address)
94 {
95         return smbus_read_byte(device, address);
96 }
97
98 #define K8_4RANK_DIMM_SUPPORT 1
99
100 #include "northbridge/amd/amdk8/raminit.c"
101 #if 0
102         #define ENABLE_APIC_EXT_ID 1
103         #define APIC_ID_OFFSET 0x10
104         #define LIFT_BSP_APIC_ID 0
105 #else
106         #define ENABLE_APIC_EXT_ID 0
107 #endif
108 #include "northbridge/amd/amdk8/coherent_ht.c"
109 #include "sdram/generic_sdram.c"
110
111  /* tyan does not want the default */
112 #include "resourcemap.c" 
113
114 #if CONFIG_LOGICAL_CPUS==1
115 #define SET_NB_CFG_54 1
116 #include "cpu/amd/dualcore/dualcore.c"
117 #endif
118
119 #define FIRST_CPU  1
120 #define SECOND_CPU 1
121 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
122
123 #define CK804_NUM 2
124 //#define CK804B_BUSN 0x80
125 #define CK804B_BUSN 0xc
126 #define CK804_USE_NIC 1
127 #define CK804_USE_ACI 1
128
129 #include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
130
131 //set GPIO to input mode
132 #define CK804_MB_SETUP \
133                 RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 5, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* M9,GPIO6, PCIXB2_PRSNT1_L*/  \
134                 RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+15, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* M8,GPIO16, PCIXB2_PRSNT2_L*/ \
135                 RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+44, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P5,GPIO45, PCIXA_PRSNT1_L*/  \
136                 RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 7, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* M5,GPIO8, PCIXA_PRSNT2_L*/   \
137                 RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/  \
138                 RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/
139
140 #include "southbridge/nvidia/ck804/ck804_early_setup.c"
141
142 #include "cpu/amd/car/copy_and_run.c"
143
144 #if USE_FALLBACK_IMAGE == 1
145
146 #include "southbridge/nvidia/ck804/ck804_enable_rom.c"
147 #include "northbridge/amd/amdk8/early_ht.c"
148
149
150 static void sio_setup(void)
151 {
152
153         unsigned value;
154         uint32_t dword;
155         uint8_t byte;
156
157         
158         pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1, 0), 0xac, 0x047f0400);
159         
160         byte = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b);
161         byte |= 0x20; 
162         pci_write_config8(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b, byte);
163         
164         dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0);
165         dword |= (1<<29)|(1<<0);
166         pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0, dword);
167         
168 #if  1  
169         lpc47b397_enable_serial(SUPERIO_GPIO_DEV, SUPERIO_GPIO_IO_BASE);
170                 
171         value =  lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x77);
172         value &= 0xbf; 
173         lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x77, value);
174 #endif
175
176 }
177
178 void real_main(unsigned long bist);
179
180 void amd64_main(unsigned long bist)
181 {
182 #if CONFIG_LOGICAL_CPUS==1
183         struct node_core_id id;
184 #else
185         unsigned nodeid;
186 #endif
187         /* Make cerain my local apic is useable */
188 //        enable_lapic();
189         
190 #if CONFIG_LOGICAL_CPUS==1
191         id = get_node_core_id_x();
192         /* Is this a cpu only reset? */
193         if (cpu_init_detected(id.nodeid)) {
194 #else   
195 //        nodeid = lapicid() & 0xf;
196         nodeid = get_node_id();
197         /* Is this a cpu only reset? */
198         if (cpu_init_detected(nodeid)) {
199 #endif
200                 if (last_boot_normal()) {
201                         goto normal_image;
202                 } else {
203                         goto cpu_reset;
204                 }
205         }
206
207         /* Is this a secondary cpu? */
208         if (!boot_cpu()) {
209                 if (last_boot_normal()) {
210                         goto normal_image;
211                 } else {
212                         goto fallback_image;
213                 }
214         }
215
216         /* Nothing special needs to be done to find bus 0 */
217         /* Allow the HT devices to be found */
218
219         enumerate_ht_chain();
220
221         sio_setup();
222
223         /* Setup the ck804 */
224         ck804_enable_rom();
225
226         /* Is this a deliberate reset by the bios */
227         if (bios_reset_detected() && last_boot_normal()) {
228                 goto normal_image;
229         }
230         /* This is the primary cpu how should I boot? */
231         else if (do_normal_boot()) {
232                 goto normal_image;
233         }
234         else {
235                 goto fallback_image;
236         }
237  normal_image:
238         __asm__ volatile ("jmp __normal_image"
239                 : /* outputs */
240                 : "a" (bist) /* inputs */
241                 );
242  cpu_reset:
243 #if 0
244         //CPU reset will reset memtroller ???
245         asm volatile ("jmp __cpu_reset" 
246                 : /* outputs */ 
247                 : "a"(bist) /* inputs */
248                 );
249 #endif
250
251  fallback_image:
252         real_main(bist);
253 }
254 void real_main(unsigned long bist)
255 #else
256 void amd64_main(unsigned long bist)
257 #endif
258 {
259         static const struct mem_controller cpu[] = {
260 #if FIRST_CPU
261                 {
262                         .node_id = 0,
263                         .f0 = PCI_DEV(0, 0x18, 0),
264                         .f1 = PCI_DEV(0, 0x18, 1),
265                         .f2 = PCI_DEV(0, 0x18, 2),
266                         .f3 = PCI_DEV(0, 0x18, 3),
267                         .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 },
268                         .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 },
269                 },
270 #endif
271 #if SECOND_CPU
272                 {
273                         .node_id = 1,
274                         .f0 = PCI_DEV(0, 0x19, 0),
275                         .f1 = PCI_DEV(0, 0x19, 1),
276                         .f2 = PCI_DEV(0, 0x19, 2),
277                         .f3 = PCI_DEV(0, 0x19, 3),
278                         .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 },
279                         .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 },
280                 },
281 #endif
282         };
283
284         int needs_reset;
285
286         unsigned cpu_reset = 0;
287
288         if (bist == 0) {
289 #if CONFIG_LOGICAL_CPUS==1
290                 struct node_core_id id;
291 #else
292                 unsigned nodeid;
293 #endif
294                 /* Skip this if there was a built in self test failure */
295 //                amd_early_mtrr_init(); # don't need, already done in cache_as_ram
296
297 #if CONFIG_LOGICAL_CPUS==1
298                 set_apicid_cpuid_lo();
299                 id = get_node_core_id_x(); // that is initid
300         #if ENABLE_APIC_EXT_ID == 1
301                 if(id.coreid == 0) {
302                         enable_apic_ext_id(id.nodeid);
303                 }
304         #endif
305 #else
306                 nodeid = get_node_id();
307         #if ENABLE_APIC_EXT_ID == 1
308                 enable_apic_ext_id(nodeid);
309         #endif
310 #endif
311
312                 enable_lapic();
313
314                 init_timer();
315
316
317 #if CONFIG_LOGICAL_CPUS==1
318         #if ENABLE_APIC_EXT_ID == 1
319             #if LIFT_BSP_APIC_ID == 0
320                 if( id.nodeid != 0 ) //all except cores in node0
321             #endif
322                         lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) );
323         #endif
324                 if(id.coreid == 0) {
325                         if (cpu_init_detected(id.nodeid)) {
326                                 cpu_reset = 1;
327                                 goto cpu_reset_x;
328                         }
329                         distinguish_cpu_resets(id.nodeid);
330                 }
331 #else
332         #if ENABLE_APIC_EXT_ID == 1
333             #if LIFT_BSP_APIC_ID == 0
334                 if(nodeid != 0)
335             #endif
336                         lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10
337
338         #endif
339                 if (cpu_init_detected(nodeid)) {
340                                 cpu_reset = 1;
341                                 goto cpu_reset_x;
342                 }
343                 distinguish_cpu_resets(nodeid);
344 #endif
345
346
347                 if (!boot_cpu()
348 #if CONFIG_LOGICAL_CPUS==1 
349                         || (id.coreid != 0)
350 #endif
351                 ) {
352                         // We need stop the CACHE as RAM for this CPU too
353                         #include "cpu/amd/car/cache_as_ram_post.c"
354                         stop_this_cpu(); // it will stop all cores except core0 of cpu0
355                 }
356         }
357
358
359         lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE);
360         uart_init();
361         console_init();
362         
363         /* Halt if there was a built in self test failure */
364         report_bist_failure(bist);
365
366         setup_s2895_resource_map();
367 #if 0
368         dump_pci_device(PCI_DEV(0, 0x18, 0));
369         dump_pci_device(PCI_DEV(0, 0x19, 0));
370 #endif
371
372         needs_reset = setup_coherent_ht_domain();
373
374 #if CONFIG_LOGICAL_CPUS==1
375         // It is said that we should start core1 after all core0 launched
376         start_other_cores();
377 #endif
378
379 #if CK804B_BUSN == 0x80 
380         // You need to preset bus num in PCI_DEV(0, 0x18,1) 0xe0, 0xe4, 0xe8, 0xec
381         needs_reset |= ht_setup_chains(3);
382 #else
383         // automatically set that for you, but you might meet tight space
384         // Bcause it has two Ck804, we need to set CK804B_BUSN to 0xc (ht_setup_chains_x will let second CK804 use that bus num.    
385     // otherwise ck804_eary_setup can not work rightly.
386         needs_reset |= ht_setup_chains_x();
387 #endif
388
389         needs_reset |= ck804_early_setup_x();
390
391         if (needs_reset) {
392                 print_info("ht reset -\r\n");
393                 soft_reset();
394         }
395
396         enable_smbus();
397 #if 0
398         dump_spd_registers(&cpu[0]);
399 #endif
400 #if 0
401         dump_smbus_registers();
402 #endif
403
404         memreset_setup();
405         sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
406
407 #if 0
408         dump_pci_devices();
409 #endif
410
411 #if 1
412         {       
413         /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
414         unsigned v_esp;
415         __asm__ volatile (
416                 "movl   %%esp, %0\n\t"
417                 : "=a" (v_esp)
418         );
419 #if CONFIG_USE_INIT
420         printk_debug("v_esp=%08x\r\n", v_esp); 
421 #else
422         print_debug("v_esp="); print_debug_hex32(v_esp); print_debug("\r\n");
423 #endif
424         }
425
426 #endif
427
428 cpu_reset_x:    
429
430 #if CONFIG_USE_INIT
431         printk_debug("cpu_reset = %08x\r\n",cpu_reset);
432 #else
433         print_debug("cpu_reset = "); print_debug_hex32(cpu_reset); print_debug("\r\n");
434 #endif
435
436         if(cpu_reset == 0) {
437                 print_debug("Clearing initial memory region: ");
438         }       
439         print_debug("No cache as ram now - ");
440         
441         /* store cpu_reset to ebx */
442         __asm__ volatile (
443                 "movl %0, %%ebx\n\t"
444                 ::"a" (cpu_reset)
445         );      
446
447         if(cpu_reset==0) {
448 #define CLEAR_FIRST_1M_RAM 1
449 #include "cpu/amd/car/cache_as_ram_post.c"
450         }
451         else {
452 #undef CLEAR_FIRST_1M_RAM 
453 #include "cpu/amd/car/cache_as_ram_post.c"
454         }
455
456         __asm__ volatile (
457                 /* set new esp */ /* before _RAMBASE */
458                 "movl   %0, %%ebp\n\t"
459                 "movl   %0, %%esp\n\t"
460                 ::"a"( _RAMBASE - 4 )
461         );
462
463         {
464                 unsigned new_cpu_reset;
465
466                 /* get back cpu_reset from ebx */
467                 __asm__ volatile (
468                         "movl %%ebx, %0\n\t"
469                         :"=a" (new_cpu_reset)
470                 );
471
472                 /* We can not go back any more, we lost old stack data in cache as ram*/
473                 if(new_cpu_reset==0) {
474                         print_debug("Use Ram as Stack now - done\r\n");
475                 } else
476                 {  
477                         print_debug("Use Ram as Stack now - \r\n");
478                 }
479 #if CONFIG_USE_INIT
480                 printk_debug("new_cpu_reset = %08x\r\n", new_cpu_reset);
481 #else
482                 print_debug("new_cpu_reset = "); print_debug_hex32(new_cpu_reset); print_debug("\r\n");
483 #endif
484
485                 /*copy and execute linuxbios_ram */
486                 copy_and_run(new_cpu_reset);
487                 /* We will not return */
488         }
489
490
491         print_err("should not be here -\r\n");
492 }