Enable mahogany_fam10 and Kino family 10h to run the SB HT link at the expected HT3...
[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         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 #if CONFIG_UPDATE_CPU_MICROCODE
235         update_microcode(val);
236 #endif
237         post_code(0x33);
238
239         cpuSetAMDMSR();
240         post_code(0x34);
241
242         amd_ht_init(sysinfo);
243         post_code(0x35);
244
245         /* Setup nodes PCI space and start core 0 AP init. */
246         finalize_node_setup(sysinfo);
247
248         /* Setup any mainboard PCI settings etc. */
249         setup_mb_resource_map();
250         post_code(0x36);
251
252         /* wait for all the APs core0 started by finalize_node_setup. */
253         /* FIXME: A bunch of cores are going to start output to serial at once.
254            It would be nice to fixup prink spinlocks for ROM XIP mode.
255            I think it could be done by putting the spinlock flag in the cache
256            of the BSP located right after sysinfo.
257          */
258         wait_all_core0_started();
259
260  #if CONFIG_LOGICAL_CPUS==1
261         /* Core0 on each node is configured. Now setup any additional cores. */
262         printk(BIOS_DEBUG, "start_other_cores()\n");
263         start_other_cores();
264         post_code(0x37);
265         wait_all_other_cores_started(bsp_apicid);
266  #endif
267
268         post_code(0x38);
269
270  #if CONFIG_SET_FIDVID
271         msr = rdmsr(0xc0010071);
272         printk(BIOS_DEBUG, "\nBegin FIDVID MSR 0xc0010071 0x%08x 0x%08x \n", msr.hi, msr.lo);
273
274         /* FIXME: The sb fid change may survive the warm reset and only
275            need to be done once.*/
276         enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
277
278         post_code(0x39);
279
280         if (!warm_reset_detect(0)) {                    // BSP is node 0
281                 init_fidvid_bsp(bsp_apicid, sysinfo->nodes);
282         } else {
283                 init_fidvid_stage2(bsp_apicid, 0);      // BSP is node 0
284         }
285
286         post_code(0x3A);
287
288         /* show final fid and vid */
289         msr=rdmsr(0xc0010071);
290         printk(BIOS_DEBUG, "End FIDVIDMSR 0xc0010071 0x%08x 0x%08x \n", msr.hi, msr.lo);
291  #endif
292
293         /* Reset for HT, FIDVID, PLL and errata changes to take affect. */
294         if (!warm_reset_detect(0)) {
295                 print_info("...WARM RESET...\n\n\n");
296                 soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn);
297                 die("After soft_reset_x - shouldn't see this message!!!\n");
298         }
299
300         post_code(0x3B);
301
302         /* FIXME:  Move this to chipset init.
303         enable cf9 for hard reset */
304         print_debug("enable_cf9_x()\n");
305         enable_cf9_x(sysinfo->sbbusn, sysinfo->sbdn);
306         post_code(0x3C);
307
308         /* It's the time to set ctrl in sysinfo now; */
309         printk(BIOS_DEBUG, "fill_mem_ctrl()\n");
310         fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
311         post_code(0x3D);
312
313         printk(BIOS_DEBUG, "enable_smbus()\n");
314         enable_smbus();
315         post_code(0x3E);
316
317         memreset_setup();
318         post_code(0x40);
319
320 //      die("Die Before MCT init.");
321
322         printk(BIOS_DEBUG, "raminit_amdmct()\n");
323         raminit_amdmct(sysinfo);
324         post_code(0x41);
325
326 /*
327         dump_pci_device_range(PCI_DEV(0, 0x18, 0), 0, 0x200);
328         dump_pci_device_range(PCI_DEV(0, 0x18, 1), 0, 0x200);
329         dump_pci_device_range(PCI_DEV(0, 0x18, 2), 0, 0x200);
330         dump_pci_device_range(PCI_DEV(0, 0x18, 3), 0, 0x200);
331 */
332
333 //      die("After MCT init before CAR disabled.");
334
335         post_code(0x42);
336         printk(BIOS_DEBUG, "\n*** Yes, the copy/decompress is taking a while, FIXME!\n");
337         post_cache_as_ram();    // BSP switch stack to ram, copy then execute LB.
338         post_code(0x43);        // Should never see this post code.
339 }
340
341 /**
342  * BOOL AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List)
343  * Description:
344  *      This routine is called every time a non-coherent chain is processed.
345  *      BUID assignment may be controlled explicitly on a non-coherent chain. Provide a
346  *      swap list. The first part of the list controls the BUID assignment and the
347  *      second part of the list provides the device to device linking.  Device orientation
348  *      can be detected automatically, or explicitly.  See documentation for more details.
349  *
350  *      Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially
351  *      based on each device's unit count.
352  *
353  * Parameters:
354  *      @param[in]  u8  node    = The node on which this chain is located
355  *      @param[in]  u8  link    = The link on the host for this chain
356  *      @param[out] u8** list   = supply a pointer to a list
357  *      @param[out] BOOL result = true to use a manual list
358  *                                false to initialize the link automatically
359  */
360 BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List)
361 {
362         static const u8 swaplist[] = { 0xFF, CONFIG_HT_CHAIN_UNITID_BASE, CONFIG_HT_CHAIN_END_UNITID_BASE, 0xFF };
363         /* If the BUID was adjusted in early_ht we need to do the manual override */
364         if ((CONFIG_HT_CHAIN_UNITID_BASE != 0) && (CONFIG_HT_CHAIN_END_UNITID_BASE != 0)) {
365                 printk(BIOS_DEBUG, "AMD_CB_ManualBUIDSwapList()\n");
366                 if ((node == 0) && (link == 0)) {       /* BSP SB link */
367                         *List = swaplist;
368                         return 1;
369                 }
370         }
371
372         return 0;
373 }