coreboot/src/mainboard/amd/serengeti_cheetah_fam10/romstage.c
<<
>>
Prefs
   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
  55static 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
  62static 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
  78static 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
  98static 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
 191void 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        printk(BIOS_DEBUG, "\n*** Yes, the copy/decompress is taking a while, FIXME!\n");
 335        post_cache_as_ram();    // BSP switch stack to ram, copy then execute LB.
 336        post_code(0x43);        // Should never see this post code.
 337}
 338
 339/**
 340 * BOOL AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List)
 341 * Description:
 342 *      This routine is called every time a non-coherent chain is processed.
 343 *      BUID assignment may be controlled explicitly on a non-coherent chain. Provide a
 344 *      swap list. The first part of the list controls the BUID assignment and the
 345 *      second part of the list provides the device to device linking.  Device orientation
 346 *      can be detected automatically, or explicitly.  See documentation for more details.
 347 *
 348 *      Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially
 349 *      based on each device's unit count.
 350 *
 351 * Parameters:
 352 *      @param[in]  u8  node    = The node on which this chain is located
 353 *      @param[in]  u8  link    = The link on the host for this chain
 354 *      @param[out] u8** list   = supply a pointer to a list
 355 *      @param[out] BOOL result = true to use a manual list
 356 *                                false to initialize the link automatically
 357 */
 358BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List)
 359{
 360        static const u8 swaplist[] = { 0xFF, CONFIG_HT_CHAIN_UNITID_BASE, CONFIG_HT_CHAIN_END_UNITID_BASE, 0xFF };
 361        /* If the BUID was adjusted in early_ht we need to do the manual override */
 362        if ((CONFIG_HT_CHAIN_UNITID_BASE != 0) && (CONFIG_HT_CHAIN_END_UNITID_BASE != 0)) {
 363                printk(BIOS_DEBUG, "AMD_CB_ManualBUIDSwapList()\n");
 364                if ((node == 0) && (link == 0)) {       /* BSP SB link */
 365                        *List = swaplist;
 366                        return 1;
 367                }
 368        }
 369
 370        return 0;
 371}
 372
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.