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