2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
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.
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.
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
20 #define SYSTEM_TYPE 0 /* SERVER */
21 //#define SYSTEM_TYPE 1 /* DESKTOP */
22 //#define SYSTEM_TYPE 2 /* MOBILE */
24 //used by incoherent_ht
25 #define FAM10_SCAN_PCI_BUS 0
26 #define FAM10_ALLOCATE_IO_RANGE 0
30 #include <device/pci_def.h>
31 #include <device/pci_ids.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"
44 #include "cpu/x86/lapic/boot_cpu.c"
45 #include "northbridge/amd/amdfam10/reset_test.c"
47 #include <console/loglevel.h>
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)
53 #include "cpu/x86/bist.h"
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"
60 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
61 #include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
63 static void memreset_setup(void)
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);
70 static void activate_spd_rom(const struct mem_controller *ctrl)
72 #define SMBUS_HUB 0x18
74 u8 device = ctrl->spd_switch_addr;
76 printk(BIOS_DEBUG, "switch i2c to : %02x for node %02x \n", device, ctrl->node_id);
78 /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
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);
86 static int spd_read_byte(u32 device, u32 address)
89 result = smbus_read_byte(device, address);
93 #include "northbridge/amd/amdfam10/amdfam10.h"
95 #include "northbridge/amd/amdfam10/raminit_sysinfo_in_ram.c"
96 #include "northbridge/amd/amdfam10/amdfam10_pci.c"
98 #include "resourcemap.c"
99 #include "cpu/amd/quadcore/quadcore.c"
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"
106 #include "southbridge/amd/amd8111/amd8111_enable_rom.c"
107 #include "northbridge/amd/amdfam10/early_ht.c"
109 static const u8 spd_addr[] = {
111 RC00, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
112 #if CONFIG_MAX_PHYSICAL_CPUS > 1
114 RC01, DIMM0, DIMM2, DIMM4, DIMM6, DIMM1, DIMM3, DIMM5, DIMM7,
116 #if CONFIG_MAX_PHYSICAL_CPUS > 2
118 RC02, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
120 RC03, DIMM0, DIMM2, DIMM4, DIMM6, DIMM1, DIMM3, DIMM5, DIMM7,
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,
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,
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,
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,
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,
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,
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,
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,
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,
202 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
205 struct sys_info *sysinfo = (struct sys_info *)(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
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();
217 /* Setup the rom access for 4M */
218 amd8111_enable_rom();
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. */
230 w83627hf_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
233 printk(BIOS_DEBUG, "\n");
235 // dump_mem(CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x200, CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE);
237 /* Halt if there was a built in self test failure */
238 report_bist_failure(bist);
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);
247 /* Setup sysinfo defaults */
248 set_sysinfo_in_ram(0);
250 update_microcode(val);
256 amd_ht_init(sysinfo);
259 /* Setup nodes PCI space and start core 0 AP init. */
260 finalize_node_setup(sysinfo);
262 /* Setup any mainboard PCI settings etc. */
263 setup_mb_resource_map();
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.
272 wait_all_core0_started();
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");
279 wait_all_other_cores_started(bsp_apicid);
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);
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);
294 if (!warm_reset_detect(0)) { // BSP is node 0
295 init_fidvid_bsp(bsp_apicid, sysinfo->nodes);
297 init_fidvid_stage2(bsp_apicid, 0); // BSP is node 0
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);
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");
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);
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);
327 printk(BIOS_DEBUG, "enable_smbus()\n");
334 // die("Die Before MCT init.");
336 printk(BIOS_DEBUG, "raminit_amdmct()\n");
337 raminit_amdmct(sysinfo);
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);
347 // ram_check(0x00200000, 0x00200000 + (640 * 1024));
348 // ram_check(0x40200000, 0x40200000 + (640 * 1024));
350 // die("After MCT init before CAR disabled.");
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.