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