cb5c070f63ea8c01bb0dfa88c9fa00d2639e496f
[coreboot.git] / src / mainboard / amd / serengeti_cheetah_fam10 / romstage.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #define SYSTEM_TYPE 0   /* SERVER */
21 //#define SYSTEM_TYPE 1 /* DESKTOP */
22 //#define SYSTEM_TYPE 2 /* MOBILE */
23
24 //used by incoherent_ht
25 #define FAM10_SCAN_PCI_BUS 0
26 #define FAM10_ALLOCATE_IO_RANGE 0
27
28 #include <stdint.h>
29 #include <string.h>
30 #include <device/pci_def.h>
31 #include <device/pci_ids.h>
32 #include <arch/io.h>
33 #include <device/pnp_def.h>
34 #include <arch/romcc_io.h>
35 #include <cpu/x86/lapic.h>
36 #include <console/console.h>
37 #include <cpu/amd/model_10xxx_rev.h>
38 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
39 #include "northbridge/amd/amdfam10/raminit.h"
40 #include "northbridge/amd/amdfam10/amdfam10.h"
41 #include <lib.h>
42 #include <spd.h>
43
44 #include "cpu/x86/lapic/boot_cpu.c"
45 #include "northbridge/amd/amdfam10/reset_test.c"
46
47 #include <console/loglevel.h>
48 #if 0
49 void die(const char *msg);
50 int do_printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
51 #define printk(BIOS_EMERG, fmt, arg...)   do_printk(BIOS_EMERG   ,fmt, ##arg)
52 #endif
53 #include "cpu/x86/bist.h"
54
55 #include "northbridge/amd/amdfam10/debug.c"
56 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
57 #include "cpu/x86/mtrr/earlymtrr.c"
58 #include "northbridge/amd/amdfam10/setup_resource_map.c"
59
60 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
61 #include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
62
63 static void memreset_setup(void)
64 {
65         //GPIO on amd8111 to enable MEMRST ????
66         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 16); // REVC_MEMRST_EN=1
67         outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 17);
68 }
69
70 static void activate_spd_rom(const struct mem_controller *ctrl)
71 {
72 #define SMBUS_HUB 0x18
73         int ret,i;
74         u8 device = ctrl->spd_switch_addr;
75
76         printk(BIOS_DEBUG, "switch i2c to : %02x for node %02x \n", device, ctrl->node_id);
77
78         /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
79         i=2;
80         do {
81                 ret = smbus_write_byte(SMBUS_HUB, 0x01, (1<<(device & 0x7)));
82         } while ((ret!=0) && (i-->0));
83         smbus_write_byte(SMBUS_HUB, 0x03, 0);
84 }
85
86 static int spd_read_byte(u32 device, u32 address)
87 {
88         int result;
89         result = smbus_read_byte(device, address);
90         return result;
91 }
92
93 #include "northbridge/amd/amdfam10/amdfam10.h"
94
95 #include "northbridge/amd/amdfam10/raminit_sysinfo_in_ram.c"
96 #include "northbridge/amd/amdfam10/amdfam10_pci.c"
97
98 #include "resourcemap.c"
99 #include "cpu/amd/quadcore/quadcore.c"
100
101 #include "cpu/amd/car/post_cache_as_ram.c"
102 #include "cpu/amd/microcode/microcode.c"
103 #include "cpu/amd/model_10xxx/update_microcode.c"
104 #include "cpu/amd/model_10xxx/init_cpus.c"
105
106 #include "southbridge/amd/amd8111/amd8111_enable_rom.c"
107 #include "northbridge/amd/amdfam10/early_ht.c"
108
109 static const u8 spd_addr[] = {
110         //first node
111         RC00, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
112 #if CONFIG_MAX_PHYSICAL_CPUS > 1
113         //second node
114         RC01, DIMM0, DIMM2, DIMM4, DIMM6, DIMM1, DIMM3, DIMM5, DIMM7,
115 #endif
116 #if CONFIG_MAX_PHYSICAL_CPUS > 2
117         // third node
118         RC02, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
119         // forth node
120         RC03, DIMM0, DIMM2, DIMM4, DIMM6, DIMM1, DIMM3, DIMM5, DIMM7,
121 #endif
122 #if CONFIG_MAX_PHYSICAL_CPUS > 4
123         RC04, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
124         RC05, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
125 #endif
126 #if CONFIG_MAX_PHYSICAL_CPUS > 6
127         RC06, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
128         RC07, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
129 #endif
130 #if CONFIG_MAX_PHYSICAL_CPUS > 8
131         RC08, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
132         RC09, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
133         RC10, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
134         RC11, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
135 #endif
136 #if CONFIG_MAX_PHYSICAL_CPUS > 12
137         RC12, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
138         RC13, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
139         RC14, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
140         RC15, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
141 #endif
142 #if CONFIG_MAX_PHYSICAL_CPUS > 16
143         RC16, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
144         RC17, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
145         RC18, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
146         RC19, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
147 #endif
148 #if CONFIG_MAX_PHYSICAL_CPUS > 20
149         RC20, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
150         RC21, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
151         RC22, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
152         RC23, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
153 #endif
154 #if CONFIG_MAX_PHYSICAL_CPUS > 24
155         RC24, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
156         RC25, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
157         RC26, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
158         RC27, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
159         RC28, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
160         RC29, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
161         RC30, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
162         RC31, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
163 #endif
164 #if CONFIG_MAX_PHYSICAL_CPUS > 32
165         RC32, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
166         RC33, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
167         RC34, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
168         RC35, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
169         RC36, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
170         RC37, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
171         RC38, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
172         RC39, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
173         RC40, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
174         RC41, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
175         RC42, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
176         RC43, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
177         RC44, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
178         RC45, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
179         RC46, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
180         RC47, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
181 #endif
182 #if CONFIG_MAX_PHYSICAL_CPUS > 48
183         RC48, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
184         RC49, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
185         RC50, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
186         RC51, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
187         RC52, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
188         RC53, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
189         RC54, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
190         RC55, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
191         RC56, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
192         RC57, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
193         RC58, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
194         RC59, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
195         RC60, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
196         RC61, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
197         RC62, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
198         RC63, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
199 #endif
200 };
201
202 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
203 {
204
205         struct sys_info *sysinfo = (struct sys_info *)(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
206         u32 bsp_apicid = 0;
207         u32 val;
208         msr_t msr;
209
210         if (!cpu_init_detectedx && boot_cpu()) {
211                 /* Nothing special needs to be done to find bus 0 */
212                 /* Allow the HT devices to be found */
213                 /* mov bsp to bus 0xff when > 8 nodes */
214                 set_bsp_node_CHtExtNodeCfgEn();
215                 enumerate_ht_chain();
216
217                 /* Setup the rom access for 4M */
218                 amd8111_enable_rom();
219         }
220
221         post_code(0x30);
222
223         if (bist == 0) {
224                 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo); /* mmconf is inited in init_cpus */
225                 /* All cores run this but the BSP(node0,core0) is the only core that returns. */
226         }
227
228         post_code(0x32);
229
230         w83627hf_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
231         uart_init();
232         console_init();
233         printk(BIOS_DEBUG, "\n");
234
235 //      dump_mem(CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x200, CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE);
236
237         /* Halt if there was a built in self test failure */
238         report_bist_failure(bist);
239
240         // Load MPB
241         val = cpuid_eax(1);
242         printk(BIOS_DEBUG, "BSP Family_Model: %08x \n", val);
243         printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
244         printk(BIOS_DEBUG, "bsp_apicid = %02x \n", bsp_apicid);
245         printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx);
246
247         /* Setup sysinfo defaults */
248         set_sysinfo_in_ram(0);
249
250         update_microcode(val);
251         post_code(0x33);
252
253         cpuSetAMDMSR();
254         post_code(0x34);
255
256         amd_ht_init(sysinfo);
257         post_code(0x35);
258
259         /* Setup nodes PCI space and start core 0 AP init. */
260         finalize_node_setup(sysinfo);
261
262         /* Setup any mainboard PCI settings etc. */
263         setup_mb_resource_map();
264         post_code(0x36);
265
266         /* wait for all the APs core0 started by finalize_node_setup. */
267         /* FIXME: A bunch of cores are going to start output to serial at once.
268            It would be nice to fixup prink spinlocks for ROM XIP mode.
269            I think it could be done by putting the spinlock flag in the cache
270            of the BSP located right after sysinfo.
271          */
272         wait_all_core0_started();
273
274  #if CONFIG_LOGICAL_CPUS==1
275         /* Core0 on each node is configured. Now setup any additional cores. */
276         printk(BIOS_DEBUG, "start_other_cores()\n");
277         start_other_cores();
278         post_code(0x37);
279         wait_all_other_cores_started(bsp_apicid);
280  #endif
281
282         post_code(0x38);
283
284  #if CONFIG_SET_FIDVID
285         msr = rdmsr(0xc0010071);
286         printk(BIOS_DEBUG, "\nBegin FIDVID MSR 0xc0010071 0x%08x 0x%08x \n", msr.hi, msr.lo);
287
288         /* FIXME: The sb fid change may survive the warm reset and only
289            need to be done once.*/
290         enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
291
292         post_code(0x39);
293
294         if (!warm_reset_detect(0)) {                    // BSP is node 0
295                 init_fidvid_bsp(bsp_apicid, sysinfo->nodes);
296         } else {
297                 init_fidvid_stage2(bsp_apicid, 0);      // BSP is node 0
298         }
299
300         post_code(0x3A);
301
302         /* show final fid and vid */
303         msr=rdmsr(0xc0010071);
304         printk(BIOS_DEBUG, "End FIDVIDMSR 0xc0010071 0x%08x 0x%08x \n", msr.hi, msr.lo);
305  #endif
306
307         /* Reset for HT, FIDVID, PLL and errata changes to take affect. */
308         if (!warm_reset_detect(0)) {
309                 print_info("...WARM RESET...\n\n\n");
310                 soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn);
311                 die("After soft_reset_x - shouldn't see this message!!!\n");
312         }
313
314         post_code(0x3B);
315
316         /* FIXME:  Move this to chipset init.
317         enable cf9 for hard reset */
318         print_debug("enable_cf9_x()\n");
319         enable_cf9_x(sysinfo->sbbusn, sysinfo->sbdn);
320         post_code(0x3C);
321
322         /* It's the time to set ctrl in sysinfo now; */
323         printk(BIOS_DEBUG, "fill_mem_ctrl()\n");
324         fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
325         post_code(0x3D);
326
327         printk(BIOS_DEBUG, "enable_smbus()\n");
328         enable_smbus();
329         post_code(0x3E);
330
331         memreset_setup();
332         post_code(0x40);
333
334 //      die("Die Before MCT init.");
335
336         printk(BIOS_DEBUG, "raminit_amdmct()\n");
337         raminit_amdmct(sysinfo);
338         post_code(0x41);
339
340 /*
341         dump_pci_device_range(PCI_DEV(0, 0x18, 0), 0, 0x200);
342         dump_pci_device_range(PCI_DEV(0, 0x18, 1), 0, 0x200);
343         dump_pci_device_range(PCI_DEV(0, 0x18, 2), 0, 0x200);
344         dump_pci_device_range(PCI_DEV(0, 0x18, 3), 0, 0x200);
345 */
346
347 //      ram_check(0x00200000, 0x00200000 + (640 * 1024));
348 //      ram_check(0x40200000, 0x40200000 + (640 * 1024));
349
350 //      die("After MCT init before CAR disabled.");
351
352         post_code(0x42);
353         printk(BIOS_DEBUG, "\n*** Yes, the copy/decompress is taking a while, FIXME!\n");
354         post_cache_as_ram();    // BSP switch stack to ram, copy then execute LB.
355         post_code(0x43);        // Should never see this post code.
356
357 }
358