Remove old AMD fam10 fixme comment
[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/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/early_serial.c"
49 #include "cpu/x86/mtrr/earlymtrr.c"
50 #include "northbridge/amd/amdfam10/setup_resource_map.c"
51 #include "southbridge/amd/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/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
91 #if CONFIG_UPDATE_CPU_MICROCODE
92 #include "cpu/amd/model_10xxx/update_microcode.c"
93 #endif
94
95 #include "cpu/amd/model_10xxx/init_cpus.c"
96 #include "northbridge/amd/amdfam10/early_ht.c"
97
98 static const u8 spd_addr[] = {
99         //first node
100         RC00, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
101 #if CONFIG_MAX_PHYSICAL_CPUS > 1
102         //second node
103         RC01, DIMM0, DIMM2, DIMM4, DIMM6, DIMM1, DIMM3, DIMM5, DIMM7,
104 #endif
105 #if CONFIG_MAX_PHYSICAL_CPUS > 2
106         // third node
107         RC02, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
108         // forth node
109         RC03, DIMM0, DIMM2, DIMM4, DIMM6, DIMM1, DIMM3, DIMM5, DIMM7,
110 #endif
111 #if CONFIG_MAX_PHYSICAL_CPUS > 4
112         RC04, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
113         RC05, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
114 #endif
115 #if CONFIG_MAX_PHYSICAL_CPUS > 6
116         RC06, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
117         RC07, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
118 #endif
119 #if CONFIG_MAX_PHYSICAL_CPUS > 8
120         RC08, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
121         RC09, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
122         RC10, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
123         RC11, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
124 #endif
125 #if CONFIG_MAX_PHYSICAL_CPUS > 12
126         RC12, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
127         RC13, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
128         RC14, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
129         RC15, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
130 #endif
131 #if CONFIG_MAX_PHYSICAL_CPUS > 16
132         RC16, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
133         RC17, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
134         RC18, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
135         RC19, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
136 #endif
137 #if CONFIG_MAX_PHYSICAL_CPUS > 20
138         RC20, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
139         RC21, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
140         RC22, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
141         RC23, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
142 #endif
143 #if CONFIG_MAX_PHYSICAL_CPUS > 24
144         RC24, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
145         RC25, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
146         RC26, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
147         RC27, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
148         RC28, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
149         RC29, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
150         RC30, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
151         RC31, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
152 #endif
153 #if CONFIG_MAX_PHYSICAL_CPUS > 32
154         RC32, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
155         RC33, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
156         RC34, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
157         RC35, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
158         RC36, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
159         RC37, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
160         RC38, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
161         RC39, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
162         RC40, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
163         RC41, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
164         RC42, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
165         RC43, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
166         RC44, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
167         RC45, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
168         RC46, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
169         RC47, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
170 #endif
171 #if CONFIG_MAX_PHYSICAL_CPUS > 48
172         RC48, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
173         RC49, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
174         RC50, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
175         RC51, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
176         RC52, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
177         RC53, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
178         RC54, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
179         RC55, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
180         RC56, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
181         RC57, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
182         RC58, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
183         RC59, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
184         RC60, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
185         RC61, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
186         RC62, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
187         RC63, DIMM0, DIMM2, 0, 0, DIMM1, DIMM3, 0, 0,
188 #endif
189 };
190
191 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
192 {
193         struct sys_info *sysinfo = (struct sys_info *)(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
194         u32 bsp_apicid = 0, val;
195         msr_t msr;
196
197         if (!cpu_init_detectedx && boot_cpu()) {
198                 /* Nothing special needs to be done to find bus 0 */
199                 /* Allow the HT devices to be found */
200                 /* mov bsp to bus 0xff when > 8 nodes */
201                 set_bsp_node_CHtExtNodeCfgEn();
202                 enumerate_ht_chain();
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         console_init();
216
217 //      dump_mem(CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x200, CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE);
218
219         /* Halt if there was a built in self test failure */
220         report_bist_failure(bist);
221
222         // Load MPB
223         val = cpuid_eax(1);
224         printk(BIOS_DEBUG, "BSP Family_Model: %08x \n", val);
225         printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
226         printk(BIOS_DEBUG, "bsp_apicid = %02x \n", bsp_apicid);
227         printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx);
228
229         /* Setup sysinfo defaults */
230         set_sysinfo_in_ram(0);
231
232 #if CONFIG_UPDATE_CPU_MICROCODE
233         update_microcode(val);
234 #endif
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 //      die("After MCT init before CAR disabled.");
332
333         post_code(0x42);
334         post_cache_as_ram();    // BSP switch stack to ram, copy then execute LB.
335         post_code(0x43);        // Should never see this post code.
336 }
337
338 /**
339  * BOOL AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List)
340  * Description:
341  *      This routine is called every time a non-coherent chain is processed.
342  *      BUID assignment may be controlled explicitly on a non-coherent chain. Provide a
343  *      swap list. The first part of the list controls the BUID assignment and the
344  *      second part of the list provides the device to device linking.  Device orientation
345  *      can be detected automatically, or explicitly.  See documentation for more details.
346  *
347  *      Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially
348  *      based on each device's unit count.
349  *
350  * Parameters:
351  *      @param[in]  u8  node    = The node on which this chain is located
352  *      @param[in]  u8  link    = The link on the host for this chain
353  *      @param[out] u8** list   = supply a pointer to a list
354  *      @param[out] BOOL result = true to use a manual list
355  *                                false to initialize the link automatically
356  */
357 BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List)
358 {
359         static const u8 swaplist[] = { 0xFF, CONFIG_HT_CHAIN_UNITID_BASE, CONFIG_HT_CHAIN_END_UNITID_BASE, 0xFF };
360         /* If the BUID was adjusted in early_ht we need to do the manual override */
361         if ((CONFIG_HT_CHAIN_UNITID_BASE != 0) && (CONFIG_HT_CHAIN_END_UNITID_BASE != 0)) {
362                 printk(BIOS_DEBUG, "AMD_CB_ManualBUIDSwapList()\n");
363                 if ((node == 0) && (link == 0)) {       /* BSP SB link */
364                         *List = swaplist;
365                         return 1;
366                 }
367         }
368
369         return 0;
370 }