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