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