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