AMD Rev F support
authorYinghai Lu <yinghailu@gmail.com>
Wed, 4 Oct 2006 20:46:15 +0000 (20:46 +0000)
committerYinghai Lu <yinghailu@gmail.com>
Wed, 4 Oct 2006 20:46:15 +0000 (20:46 +0000)
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2435 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

130 files changed:
src/arch/i386/Config.lb
src/arch/i386/boot/acpi.c
src/arch/i386/include/arch/acpi.h
src/arch/i386/include/arch/cpu.h
src/arch/i386/include/arch/romcc_io.h
src/arch/i386/init/ldscript.lb
src/arch/i386/init/ldscript_apc.lb [new file with mode: 0644]
src/arch/i386/init/ldscript_failover.lb [new file with mode: 0644]
src/arch/i386/init/ldscript_fallback.lb [new file with mode: 0644]
src/arch/i386/lib/cpu.c
src/arch/i386/lib/pci_ops_conf1.c
src/arch/i386/lib/pci_ops_conf2.c
src/config/Config.lb
src/config/Options.lb
src/config/linuxbios_ram.ld
src/cpu/amd/car/cache_as_ram.inc
src/cpu/amd/car/copy_and_run.c
src/cpu/amd/car/post_cache_as_ram.c
src/cpu/amd/dualcore/amd_sibling.c
src/cpu/amd/dualcore/dualcore.c
src/cpu/amd/dualcore/dualcore_id.c
src/cpu/amd/model_fxx/Config.lb
src/cpu/amd/model_fxx/fidvid.c
src/cpu/amd/model_fxx/init_cpus.c
src/cpu/amd/model_fxx/model_fxx_init.c
src/cpu/amd/model_fxx/model_fxx_update_microcode.c
src/cpu/amd/model_gx2/vsmsetup.c
src/cpu/amd/model_lx/vsmsetup.c
src/cpu/amd/mtrr/amd_earlymtrr.c
src/cpu/amd/mtrr/amd_mtrr.c
src/cpu/amd/socket_AM2/Config.lb [new file with mode: 0644]
src/cpu/amd/socket_AM2/chip.h [new file with mode: 0644]
src/cpu/amd/socket_AM2/socket_AM2.c [new file with mode: 0644]
src/cpu/amd/socket_F/Config.lb [new file with mode: 0644]
src/cpu/amd/socket_F/chip.h [new file with mode: 0644]
src/cpu/amd/socket_F/socket_F.c [new file with mode: 0644]
src/cpu/x86/car/copy_and_run.c
src/cpu/x86/lapic/lapic.c
src/cpu/x86/lapic/lapic_cpu_init.c
src/cpu/x86/mtrr/earlymtrr.c
src/cpu/x86/mtrr/mtrr.c
src/devices/device_util.c
src/devices/hypertransport.c
src/include/cpu/amd/microcode.h
src/include/cpu/amd/model_fxx_rev.h
src/include/cpu/x86/mem.h
src/include/device/device.h
src/include/device/hypertransport_def.h
src/include/device/pci.h
src/include/device/pci_def.h
src/lib/nrv2b.c
src/mainboard/Iwill/DK8HTX/auto.c
src/mainboard/Iwill/DK8S2/auto.c
src/mainboard/Iwill/DK8X/auto.c
src/mainboard/agami/aruma/Options.lb
src/mainboard/amd/serenade/auto.c
src/mainboard/amd/serengeti_cheetah/Config.lb [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/Options.lb [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/a [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/acpi_tables.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/apc_auto.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/cache_as_ram_auto.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/chip.h [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/cmos.layout [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/amd8111.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/amd8111_isa.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/amd8111_pic.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/amd8131.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/amd8151.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/amdk8_util.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/dsdt_lb.dsl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/pci0_hc.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/pci2.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/pci2_hc.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/dx/superio.asl [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/fadt.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/get_bus_conf.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/irq_tables.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/mainboard.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/mb_sysconf.h [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/mptable.c [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/readme_acpi.txt [new file with mode: 0644]
src/mainboard/amd/serengeti_cheetah/resourcemap.c [new file with mode: 0644]
src/mainboard/amd/serengeti_leopard/Config.lb
src/mainboard/amd/serengeti_leopard/Options.lb
src/mainboard/arima/hdama/auto.c
src/mainboard/broadcom/blast/Options.lb
src/mainboard/ibm/e325/auto.c
src/mainboard/ibm/e326/auto.c
src/mainboard/newisys/khepri/auto.c
src/mainboard/sunw/ultra40/Options.lb
src/mainboard/tyan/s2850/Options.lb
src/mainboard/tyan/s2875/Options.lb
src/mainboard/tyan/s2880/Options.lb
src/mainboard/tyan/s2881/Options.lb
src/mainboard/tyan/s2882/Options.lb
src/mainboard/tyan/s2885/Options.lb
src/mainboard/tyan/s2891/Options.lb
src/mainboard/tyan/s2892/Options.lb
src/mainboard/tyan/s2895/Options.lb
src/mainboard/tyan/s4880/Options.lb
src/mainboard/tyan/s4882/Options.lb
src/northbridge/amd/amdk8/Config.lb
src/northbridge/amd/amdk8/amdk8.h
src/northbridge/amd/amdk8/amdk8_acpi.c
src/northbridge/amd/amdk8/amdk8_f.h [new file with mode: 0644]
src/northbridge/amd/amdk8/amdk8_f_pci.c [new file with mode: 0644]
src/northbridge/amd/amdk8/coherent_ht.c
src/northbridge/amd/amdk8/coherent_ht_car.c
src/northbridge/amd/amdk8/get_sblk_pci1234.c
src/northbridge/amd/amdk8/incoherent_ht.c
src/northbridge/amd/amdk8/misc_control.c
src/northbridge/amd/amdk8/northbridge.c
src/northbridge/amd/amdk8/raminit.c
src/northbridge/amd/amdk8/raminit.h
src/northbridge/amd/amdk8/raminit_f.c [new file with mode: 0644]
src/northbridge/amd/amdk8/raminit_f_dqs.c [new file with mode: 0644]
src/northbridge/amd/amdk8/setup_resource_map.c
src/northbridge/amd/amdk8/spd_ddr2.h [new file with mode: 0644]
src/northbridge/amd/amdk8/ssdt.dsl [new file with mode: 0644]
src/southbridge/amd/amd8111/amd8111_early_ctrl.c
src/southbridge/amd/amd8111/amd8111_enable_rom.c
src/southbridge/amd/amd8111/amd8111_reset.c
src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c
src/southbridge/nvidia/ck804/ck804_early_setup.c
src/southbridge/nvidia/ck804/ck804_early_setup_car.c
src/stream/rom_stream.c
targets/amd/serengeti_cheetah/Config.lb [new file with mode: 0644]
targets/amd/serengeti_cheetah/VERSION [new file with mode: 0644]

index c13427042a91bed0297c9d3e1521ed040108719d..2b197f867e1d08586514b79bdf427e5030c9ec38 100644 (file)
@@ -1,9 +1,25 @@
 uses CONFIG_SMP
 uses CONFIG_PRECOMPRESSED_ROM_STREAM
 uses CONFIG_USE_INIT
+uses HAVE_FAILOVER_BOOT
+uses USE_FAILOVER_IMAGE
+uses USE_FALLBACK_IMAGE
 
 init init/crt0.S.lb
-ldscript init/ldscript.lb
+
+if HAVE_FAILOVER_BOOT
+      if USE_FAILOVER_IMAGE
+              ldscript init/ldscript_failover.lb
+      else
+              ldscript init/ldscript.lb
+      end
+else
+      if USE_FALLBACK_IMAGE
+              ldscript init/ldscript_fallback.lb
+      else
+              ldscript init/ldscript.lb
+      end
+end
 
 makerule all
        depends "linuxbios.rom"
@@ -21,7 +37,7 @@ end
 
 makerule payload
        depends "$(PAYLOAD)"
-       action  "cp -f $< $@"
+       action  "cp $< $@"
 end
 
 makerule payload.nrv2b
@@ -53,9 +69,19 @@ if CONFIG_PRECOMPRESSED_ROM_STREAM
        makedefine PAYLOAD-1:=payload
 end
 
-makerule linuxbios.rom 
-       depends "linuxbios.strip buildrom $(PAYLOAD-1)" 
-       action "./buildrom $< $@ $(PAYLOAD-1) $(ROM_IMAGE_SIZE) $(ROM_SECTION_SIZE)"
+if USE_FAILOVER_IMAGE
+       makedefine LINUXBIOS_APC:=
+       makedefine LINUXBIOS_RAM_ROM:=
+
+       makerule linuxbios.rom 
+               depends "linuxbios.strip" 
+               action "cp $< $@"
+       end
+else
+       makerule linuxbios.rom 
+               depends "linuxbios.strip buildrom $(PAYLOAD-1)" 
+               action "./buildrom $< $@ $(PAYLOAD-1) $(ROM_IMAGE_SIZE) $(ROM_SECTION_SIZE)"
+       end
 end
 
 makerule crt0.S
@@ -72,11 +98,11 @@ if CONFIG_USE_INIT
                action  "$(OBJCOPY) --rename-section .text=.init.text --rename-section .data=.init.data --rename-section .rodata=.init.rodata --rename-section .rodata.str1.1=.init.rodata.str1.1 init.pre.o init.o"
        end
 
-       makerule linuxbios   
-               depends "crt0.o init.o linuxbios_ram.rom ldscript.ld"
+        makerule linuxbios   
+               depends "crt0.o $(INIT-OBJECTS) $(LINUXBIOS_APC) $(LINUXBIOS_RAM_ROM) ldscript.ld"
                action  "$(CC) -nostdlib -nostartfiles -static -o $@ -T ldscript.ld crt0.o init.o"
                action  "$(CROSS_COMPILE)nm -n linuxbios | sort > linuxbios.map"
-       end
+        end
 
 end
 
index 3393b89fee7c0f318ee492f9c7dc8dcc4d87dae9..e1734d80e7cc1f4ca8dcc33cbbc972d47d6b0bde 100644 (file)
@@ -203,6 +203,31 @@ void acpi_create_srat(acpi_srat_t *srat)
         header->checksum        = acpi_checksum((void *)srat, header->length);
 }
 
+void acpi_create_slit(acpi_slit_t *slit)
+{
+
+        acpi_header_t *header=&(slit->header);
+        unsigned long current=(unsigned long)slit+sizeof(acpi_slit_t);
+
+        memset((void *)slit, 0, sizeof(acpi_slit_t));
+
+        /* fill out header fields */
+        memcpy(header->signature, SLIT_NAME, 4);
+        memcpy(header->oem_id, OEM_ID, 6);
+        memcpy(header->oem_table_id, SLIT_TABLE, 8);
+        memcpy(header->asl_compiler_id, ASLC, 4);
+
+        header->length = sizeof(acpi_slit_t);
+        header->revision = 1;
+
+//        current = acpi_fill_slit(current);
+
+        /* recalculate length */
+        header->length= current - (unsigned long)slit;
+
+        header->checksum        = acpi_checksum((void *)slit, header->length);
+}
+
 void acpi_create_hpet(acpi_hpet_t *hpet)
 {
 #define HPET_ADDR  0xfed00000ULL
index 12d57549bc7f4560232fce37518b238e289ff9a0..333057b13b74da0d17bfd61e124566e03ba52352 100644 (file)
@@ -6,12 +6,9 @@
  *
  * The ACPI table structs are based on the Linux kernel sources.
  * 
- * ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
+ */
+/* ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
  * those parts (C) 2004 Nick Barker
- * 
- * ACPI SRAT support added in 2005.9 by yhlu
- * Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
- *
  */
 
 
@@ -32,11 +29,13 @@ typedef unsigned long long u64;
 #define HPET_NAME             "HPET"
 #define MADT_NAME             "APIC"
 #define SRAT_NAME             "SRAT"
+#define SLIT_NAME            "SLIT"
 
 #define RSDT_TABLE            "RSDT    "
 #define HPET_TABLE            "AMD64   "
 #define MADT_TABLE            "MADT    "
 #define SRAT_TABLE           "SRAT    "
+#define SLIT_TABLE           "SLIT    "
 
 #define OEM_ID                "LXBIOS"
 #define ASLC                  "NONE"
@@ -49,7 +48,7 @@ typedef struct acpi_rsdp {
        char  oem_id[6];        /* OEM ID, "LXBIOS" */
        u8    revision;         /* 0 for APCI 1.0, 2 for ACPI 2.0 */
        u32   rsdt_address;     /* physical address of RSDT */
-       u32   length;           /* total length of RSDP (incl. extended part) */
+       u32   length;           /* total length of RSDP (including extended part) */
        u64   xsdt_address;     /* physical address of XSDT */
        u8    ext_checksum;     /* chechsum of whole table */
        u8    reserved[3];
@@ -84,16 +83,15 @@ typedef struct acpi_table_header         /* ACPI common table header */
 /* RSDT */
 typedef struct acpi_rsdt {
        struct acpi_table_header header;
-       u32 entry[5+ACPI_SSDTX_NUM]; /* HPET, FADT, SRAT, MADT(APIC), SSDT, SSDTX */
+       u32 entry[6+ACPI_SSDTX_NUM]; /* HPET, FADT, SRAT, SLIT, MADT(APIC), SSDT, SSDTX*/
 } __attribute__ ((packed)) acpi_rsdt_t;
 
 /* XSDT */
 typedef struct acpi_xsdt {
        struct acpi_table_header header;
-       u64 entry[5+ACPI_SSDTX_NUM];
+       u64 entry[6+ACPI_SSDTX_NUM];
 } __attribute__ ((packed)) acpi_xsdt_t;
 
-
 /* HPET TIMERS */
 typedef struct acpi_hpet {
        struct acpi_table_header header;
@@ -138,6 +136,11 @@ typedef struct acpi_srat_mem {
         u32 resv2[2];
 } __attribute__ ((packed)) acpi_srat_mem_t;
 
+/* SLIT */
+typedef struct acpi_slit {
+        struct acpi_table_header header;
+       /* followed by static resource allocation 8+byte[num*num]*/
+} __attribute__ ((packed)) acpi_slit_t;
 
 
 /* MADT */
index 4cdeded8bc590146dcb2facb4ee46d328e9ba9eb..ebe6ed155c088c920e025edf2750610e6cea4d2f 100644 (file)
@@ -141,6 +141,25 @@ static inline unsigned long cpu_index(void)
        return ci->index;
 }
 
+
+struct cpuinfo_x86 {
+        uint8_t    x86;            /* CPU family */
+        uint8_t    x86_vendor;     /* CPU vendor */
+        uint8_t    x86_model;
+        uint8_t    x86_mask;
+};
+
+static void inline get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
+{
+        c->x86 = (tfms >> 8) & 0xf;
+        c->x86_model = (tfms >> 4) & 0xf;
+        c->x86_mask = tfms & 0xf;
+        if (c->x86 == 0xf)
+                c->x86 += (tfms >> 20) & 0xff;
+        if (c->x86 >= 0x6)
+                c->x86_model += ((tfms >> 16) & 0xF) << 4;
+
+}
 #endif
 
 #endif /* ARCH_CPU_H */
index 983835a09334e41efc2f01afa153976f452eecb4..6fafbd99a912eb6e0c7adb018c89b0a2338ff7a2 100644 (file)
@@ -4,74 +4,35 @@
 #include <stdint.h>
 
 
-static inline uint8_t read8(unsigned long addr)
+static inline __attribute__((always_inline)) uint8_t read8(unsigned long addr)
 {
        return *((volatile uint8_t *)(addr));
 }
 
-static inline uint16_t read16(unsigned long addr)
+static inline __attribute__((always_inline)) uint16_t read16(unsigned long addr)
 {
        return *((volatile uint16_t *)(addr));
 }
 
-static inline uint32_t read32(unsigned long addr)
+static inline __attribute__((always_inline)) uint32_t read32(unsigned long addr)
 {
        return *((volatile uint32_t *)(addr));
 }
 
-static inline void write8(unsigned long addr, uint8_t value)
+static inline __attribute__((always_inline)) void write8(unsigned long addr, uint8_t value)
 {
        *((volatile uint8_t *)(addr)) = value;
 }
 
-static inline void write16(unsigned long addr, uint16_t value)
+static inline __attribute__((always_inline)) void write16(unsigned long addr, uint16_t value)
 {
        *((volatile uint16_t *)(addr)) = value;
 }
 
-static inline void write32(unsigned long addr, uint32_t value)
+static inline __attribute__((always_inline)) void write32(unsigned long addr, uint32_t value)
 {
        *((volatile uint32_t *)(addr)) = value;
 }
-#if 0
-typedef __builtin_div_t div_t;
-typedef __builtin_ldiv_t ldiv_t;
-typedef __builtin_udiv_t udiv_t;
-typedef __builtin_uldiv_t uldiv_t;
-
-static inline div_t div(int numer, int denom)
-{
-       return __builtin_div(numer, denom);
-}
-
-static inline ldiv_t ldiv(long numer, long denom)
-{
-       return __builtin_ldiv(numer, denom);
-}
-
-static inline udiv_t udiv(unsigned numer, unsigned denom)
-{
-       return __builtin_udiv(numer, denom);
-}
-
-static inline uldiv_t uldiv(unsigned long numer, unsigned long denom)
-{
-       return __builtin_uldiv(numer, denom);
-}
-
-
-
-inline int log2(int value)
-{
-       /* __builtin_bsr is a exactly equivalent to the x86 machine
-        * instruction with the exception that it returns -1  
-        * when the value presented to it is zero.
-        * Otherwise __builtin_bsr returns the zero based index of
-        * the highest bit set.
-        */
-       return __builtin_bsr(value);
-}
-#endif
 
 static inline int log2(int value)
 {
@@ -98,16 +59,16 @@ static inline int log2f(int value)
 
 }
 
-#define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
-       (((BUS) & 0xFF) << 16) | \
-       (((DEV) & 0x1f) << 11) | \
-       (((FN) & 0x07) << 8) | \
-       ((WHERE) & 0xFF))
+#define PCI_ADDR(SEGBUS, DEV, FN, WHERE) ( \
+        (((SEGBUS) & 0xFFF) << 20) | \
+        (((DEV) & 0x1F) << 15) | \
+        (((FN) & 0x07) << 12) | \
+        ((WHERE) & 0xFFF))
 
-#define PCI_DEV(BUS, DEV, FN) ( \
-       (((BUS) & 0xFF) << 16) | \
-       (((DEV) & 0x1f) << 11) | \
-       (((FN)  & 0x7) << 8))
+#define PCI_DEV(SEGBUS, DEV, FN) ( \
+        (((SEGBUS) & 0xFFF) << 20) | \
+        (((DEV) & 0x1F) << 15) | \
+        (((FN)  & 0x07) << 12))
 
 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
        ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
@@ -117,58 +78,103 @@ static inline int log2f(int value)
 
 typedef unsigned device_t;
 
-static inline __attribute__((always_inline)) uint8_t pci_read_config8(device_t dev, unsigned where)
+static inline __attribute__((always_inline)) uint8_t pci_io_read_config8(device_t dev, unsigned where)
 {
        unsigned addr;
-       addr = dev | where;
+       addr = (dev>>4) | where;
        outl(0x80000000 | (addr & ~3), 0xCF8);
        return inb(0xCFC + (addr & 3));
 }
 
-static inline __attribute__((always_inline)) uint16_t pci_read_config16(device_t dev, unsigned where)
+static inline __attribute__((always_inline)) uint8_t pci_read_config8(device_t dev, unsigned where)
+{
+       return pci_io_read_config8(dev, where);
+}
+
+static inline __attribute__((always_inline)) uint16_t pci_io_read_config16(device_t dev, unsigned where)
 {
        unsigned addr;
-       addr = dev | where;
+        addr = (dev>>4) | where;
        outl(0x80000000 | (addr & ~3), 0xCF8);
        return inw(0xCFC + (addr & 2));
 }
 
-static inline __attribute__((always_inline)) uint32_t pci_read_config32(device_t dev, unsigned where)
+static inline __attribute__((always_inline)) uint16_t pci_read_config16(device_t dev, unsigned where)
+{
+        return pci_io_read_config16(dev, where);
+}
+
+
+static inline __attribute__((always_inline)) uint32_t pci_io_read_config32(device_t dev, unsigned where)
 {
        unsigned addr;
-       addr = dev | where;
+        addr = (dev>>4) | where;
        outl(0x80000000 | (addr & ~3), 0xCF8);
        return inl(0xCFC);
 }
 
-static inline __attribute__((always_inline)) void pci_write_config8(device_t dev, unsigned where, uint8_t value)
+static inline __attribute__((always_inline)) uint32_t pci_read_config32(device_t dev, unsigned where)
+{
+        return pci_io_read_config32(dev, where);
+}
+
+static inline __attribute__((always_inline)) void pci_io_write_config8(device_t dev, unsigned where, uint8_t value)
 {
        unsigned addr;
-       addr = dev | where;
+        addr = (dev>>4) | where;
        outl(0x80000000 | (addr & ~3), 0xCF8);
        outb(value, 0xCFC + (addr & 3));
 }
 
+static inline __attribute__((always_inline)) void pci_write_config8(device_t dev, unsigned where, uint8_t value)
+{
+        pci_io_write_config8(dev, where, value);
+}
+
+
+static inline __attribute__((always_inline)) void pci_io_write_config16(device_t dev, unsigned where, uint16_t value)
+{
+        unsigned addr;
+        addr = (dev>>4) | where;
+        outl(0x80000000 | (addr & ~3), 0xCF8);
+        outw(value, 0xCFC + (addr & 2));
+}
+
 static inline __attribute__((always_inline)) void pci_write_config16(device_t dev, unsigned where, uint16_t value)
 {
-       unsigned addr;
-       addr = dev | where;
-       outl(0x80000000 | (addr & ~3), 0xCF8);
-       outw(value, 0xCFC + (addr & 2));
+       pci_io_write_config16(dev, where, value);
 }
 
-static inline __attribute__((always_inline)) void pci_write_config32(device_t dev, unsigned where, uint32_t value)
+
+static inline __attribute__((always_inline)) void pci_io_write_config32(device_t dev, unsigned where, uint32_t value)
 {
        unsigned addr;
-       addr = dev | where;
+        addr = (dev>>4) | where;
        outl(0x80000000 | (addr & ~3), 0xCF8);
        outl(value, 0xCFC);
 }
 
+static inline __attribute__((always_inline)) void pci_write_config32(device_t dev, unsigned where, uint32_t value)
+{
+        pci_io_write_config32(dev, where, value);
+}
+
 #define PCI_DEV_INVALID (0xffffffffU)
+static device_t pci_io_locate_device(unsigned pci_id, device_t dev)
+{
+        for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
+                unsigned int id;
+                id = pci_io_read_config32(dev, 0);
+                if (id == pci_id) {
+                        return dev;
+                }
+        }
+        return PCI_DEV_INVALID;
+}
+
 static device_t pci_locate_device(unsigned pci_id, device_t dev)
 {
-       for(; dev <= PCI_DEV(CONFIG_MAX_PCI_BUSES, 31, 7); dev += PCI_DEV(0,0,1)) {
+       for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
                unsigned int id;
                id = pci_read_config32(dev, 0);
                if (id == pci_id) {
@@ -180,11 +186,11 @@ static device_t pci_locate_device(unsigned pci_id, device_t dev)
 
 static device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
 {
-        device_t dev, last;
+       device_t dev, last;
 
         dev = PCI_DEV(bus, 0, 0);
         last = PCI_DEV(bus, 31, 7);
-
+       
         for(; dev <=last; dev += PCI_DEV(0,0,1)) {
                 unsigned int id;
                 id = pci_read_config32(dev, 0);
@@ -195,8 +201,6 @@ static device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
         return PCI_DEV_INVALID;
 }
 
-
-
 /* Generic functions for pnp devices */
 static inline __attribute__((always_inline)) void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
 {
index e647fb42fe53b2b5f475bfc2fa136334e6286abd..c9027826819136a5da6476ce9436e970a71f4e70 100644 (file)
@@ -36,16 +36,13 @@ INPUT(linuxbios_ram.rom)
 SECTIONS
 {
        . = _ROMBASE;
-       
+
        .ram . : {
                _ram = . ;
                linuxbios_ram.rom(*)
                _eram = . ;
        }
 
-       _x = .;
-       . = (_x < (_ROMBASE - 0x10000 +  ROM_IMAGE_SIZE)) ? (_ROMBASE - 0x10000 +  ROM_IMAGE_SIZE) : _x;
-
        /* This section might be better named .setup */
        .rom . : {
                _rom = .;
diff --git a/src/arch/i386/init/ldscript_apc.lb b/src/arch/i386/init/ldscript_apc.lb
new file mode 100644 (file)
index 0000000..43570eb
--- /dev/null
@@ -0,0 +1,13 @@
+INPUT(linuxbios_apc.rom)
+SECTIONS
+{
+        .apcrom . : {
+                _apcrom = .;
+                linuxbios_apc.rom(*)
+                _eapcrom = .;
+        }
+        _iseg_apc = DCACHE_RAM_BASE;
+        _eiseg_apc = _iseg_apc + SIZEOF(.apcrom);
+        _liseg_apc = _apcrom;
+        _eliseg_apc = _eapcrom;
+}
diff --git a/src/arch/i386/init/ldscript_failover.lb b/src/arch/i386/init/ldscript_failover.lb
new file mode 100644 (file)
index 0000000..12cb3fe
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *     Memory map:
+ *
+ *     _RAMBASE                
+ *                             : data segment
+ *                             : bss segment
+ *                             : heap
+ *                             : stack
+ *     _ROMBASE
+ *                             : linuxbios text 
+ *                             : readonly text
+ */
+/*
+ * Bootstrap code for the STPC Consumer
+ * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
+ *
+ */
+
+/*
+ *     Written by Johan Rydberg, based on work by Daniel Kahlin.
+ *      Rewritten by Eric Biederman
+ */
+/*
+ *     We use ELF as output format. So that we can
+ *     debug the code in some form. 
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+
+/*
+ENTRY(_start)
+*/
+
+TARGET(binary)
+SECTIONS
+{
+       . = _ROMBASE;
+
+       /* This section might be better named .setup */
+       .rom . : {
+               _rom = .;
+               *(.rom.text);
+               *(.rom.data);
+               *(.rom.data.*);
+               . = ALIGN(16);
+               _erom = .;
+       }
+
+       _lrom = LOADADDR(.rom);
+       _elrom = LOADADDR(.rom) + SIZEOF(.rom);
+
+       /DISCARD/ : {
+               *(.comment)
+               *(.note)
+       }
+}
diff --git a/src/arch/i386/init/ldscript_fallback.lb b/src/arch/i386/init/ldscript_fallback.lb
new file mode 100644 (file)
index 0000000..f2ffd12
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *     Memory map:
+ *
+ *     _RAMBASE                
+ *                             : data segment
+ *                             : bss segment
+ *                             : heap
+ *                             : stack
+ *     _ROMBASE
+ *                             : linuxbios text 
+ *                             : readonly text
+ */
+/*
+ * Bootstrap code for the STPC Consumer
+ * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
+ *
+ */
+
+/*
+ *     Written by Johan Rydberg, based on work by Daniel Kahlin.
+ *      Rewritten by Eric Biederman
+ */
+/*
+ *     We use ELF as output format. So that we can
+ *     debug the code in some form. 
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+
+/*
+ENTRY(_start)
+*/
+
+TARGET(binary)
+INPUT(linuxbios_ram.rom)
+SECTIONS
+{
+       . = _ROMBASE;
+
+       .ram . : {
+               _ram = . ;
+               linuxbios_ram.rom(*)
+               _eram = . ;
+       }
+
+       /* cut _start into last 64k*/
+       _x = .;
+       . = (_x < (_ROMBASE - 0x10000 +  ROM_IMAGE_SIZE)) ? (_ROMBASE - 0x10000 +  ROM_IMAGE_SIZE) : _x;
+
+       /* This section might be better named .setup */
+       .rom . : {
+               _rom = .;
+               *(.rom.text);
+               *(.rom.data);
+               *(.rom.data.*);
+               . = ALIGN(16);
+               _erom = .;
+       }
+
+       _lrom = LOADADDR(.rom);
+       _elrom = LOADADDR(.rom) + SIZEOF(.rom);
+       _iseg = _RAMBASE;
+       _eiseg = _iseg + SIZEOF(.ram);
+       _liseg = _ram;
+       _eliseg = _eram;
+
+       /DISCARD/ : {
+               *(.comment)
+               *(.note)
+       }
+}
index 11ccee211fc3363822c8c0bc9fb256237f6d88a6..aee230d075f9b967a722f5fb754472da33b312fa 100644 (file)
@@ -222,6 +222,8 @@ void cpu_initialize(void)
         */
        struct device *cpu;
        struct cpu_info *info;
+       struct cpuinfo_x86 c;
+
        info = cpu_info();
 
        printk_notice("Initializing CPU #%d\n", info->index);
@@ -245,6 +247,11 @@ void cpu_initialize(void)
                identify_cpu(cpu);
                printk_debug("CPU: vendor %s device %x\n",
                        cpu_vendor_name(cpu->vendor), cpu->device);
+
+               get_fms(&c, cpu->device);
+
+               printk_debug("CPU: family %02x, model %02x, stepping %02x\n", c.x86, c.x86_model, c.x86_mask);
+
                        
                /* Lookup the cpu's operations */
                set_cpu_ops(cpu);
index fb0a434d53b9713ec7ff4f893db948f693b2de1e..b4181e39bc8caf408ecf3411adade33604fd41d9 100644 (file)
 
 #define CONFIG_CMD(bus,devfn, where)   (0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3))
 
-static uint8_t pci_conf1_read_config8(struct bus *pbus, unsigned char bus, int devfn, int where)
+static uint8_t pci_conf1_read_config8(struct bus *pbus, int bus, int devfn, int where)
 {
-       outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
-       return inb(0xCFC + (where & 3));
+               outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
+               return inb(0xCFC + (where & 3));
 }
 
-static uint16_t pci_conf1_read_config16(struct bus *pbus, unsigned char bus, int devfn, int where)
+static uint16_t pci_conf1_read_config16(struct bus *pbus, int bus, int devfn, int where)
 {
-       outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
-       return inw(0xCFC + (where & 2));
+               outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
+               return inw(0xCFC + (where & 2));
 }
 
-static uint32_t pci_conf1_read_config32(struct bus *pbus, unsigned char bus, int devfn, int where)
+static uint32_t pci_conf1_read_config32(struct bus *pbus, int bus, int devfn, int where)
 {
-       outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
-       return inl(0xCFC);
+               outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
+               return inl(0xCFC);
 }
 
-static void  pci_conf1_write_config8(struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t value)
+static void  pci_conf1_write_config8(struct bus *pbus, int bus, int devfn, int where, uint8_t value)
 {
-       outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
-       outb(value, 0xCFC + (where & 3));
+               outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
+               outb(value, 0xCFC + (where & 3));
 }
 
-static void pci_conf1_write_config16(struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t value)
+static void pci_conf1_write_config16(struct bus *pbus, int bus, int devfn, int where, uint16_t value)
 {
-       outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
-       outw(value, 0xCFC + (where & 2));
+               outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
+               outw(value, 0xCFC + (where & 2));
 }
 
-static void pci_conf1_write_config32(struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t value)
+static void pci_conf1_write_config32(struct bus *pbus, int bus, int devfn, int where, uint32_t value)
 {
-       outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
-       outl(value, 0xCFC);
+               outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
+               outl(value, 0xCFC);
 }
 
 #undef CONFIG_CMD
index 10fde93346680b3d10d9fa5743af0a9388a27260..839f5b44c7af9ed9a68c42b7c70b796a30bab669 100644 (file)
@@ -12,7 +12,7 @@
 #define FUNC(devfn)            (((devfn & 7) << 1) | 0xf0)
 #define SET(bus,devfn)         outb(FUNC(devfn), 0xCF8); outb(bus, 0xCFA);
 
-static uint8_t pci_conf2_read_config8(struct bus *pbus, unsigned char bus, int devfn, int where)
+static uint8_t pci_conf2_read_config8(struct bus *pbus, int bus, int devfn, int where)
 {
        uint8_t value;
        SET(bus, devfn);
@@ -21,7 +21,7 @@ static uint8_t pci_conf2_read_config8(struct bus *pbus, unsigned char bus, int d
        return value;
 }
 
-static uint16_t pci_conf2_read_config16(struct bus *pbus, unsigned char bus, int devfn, int where)
+static uint16_t pci_conf2_read_config16(struct bus *pbus, int bus, int devfn, int where)
 {
        uint16_t value;
        SET(bus, devfn);
@@ -30,7 +30,7 @@ static uint16_t pci_conf2_read_config16(struct bus *pbus, unsigned char bus, int
        return value;
 }
 
-static uint32_t pci_conf2_read_config32(struct bus *pbus, unsigned char bus, int devfn, int where)
+static uint32_t pci_conf2_read_config32(struct bus *pbus, int bus, int devfn, int where)
 {
        uint32_t value;
        SET(bus, devfn);
@@ -39,21 +39,21 @@ static uint32_t pci_conf2_read_config32(struct bus *pbus, unsigned char bus, int
        return value;
 }
 
-static void pci_conf2_write_config8(struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t value)
+static void pci_conf2_write_config8(struct bus *pbus, int bus, int devfn, int where, uint8_t value)
 {
        SET(bus, devfn);
        outb(value, IOADDR(devfn, where));
        outb(0, 0xCF8);
 }
 
-static void pci_conf2_write_config16(struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t value)
+static void pci_conf2_write_config16(struct bus *pbus, int bus, int devfn, int where, uint16_t value)
 {
        SET(bus, devfn);
        outw(value, IOADDR(devfn, where));
        outb(0, 0xCF8);
 }
 
-static void pci_conf2_write_config32(struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t value)
+static void pci_conf2_write_config32(struct bus *pbus, int bus, int devfn, int where, uint32_t value)
 {
        SET(bus, devfn);
        outl(value, IOADDR(devfn, where));
index 40bccb110c4fd8783789b327b1d72b80b3ed301d..f56f53aca393e481dbb09b2dc87515a088a519ce 100644 (file)
@@ -1,6 +1,7 @@
 ## This is Architecture independant part of the makefile
 
 uses HAVE_OPTION_TABLE
+uses CONFIG_AP_CODE_IN_CAR
 
 makedefine CPP:= $(CC) -x assembler-with-cpp -DASSEMBLY -E
 makedefine LIBGCC_FILE_NAME := $(shell $(CC) -print-libgcc-file-name)
@@ -31,6 +32,12 @@ makerule linuxbios.strip
        action  "$(OBJCOPY) -O binary linuxbios linuxbios.strip"
 end
 
+makerule linuxbios.a
+        depends "$(OBJECTS)"
+        action  "rm -f linuxbios.a"
+        action  "ar cr linuxbios.a $(OBJECTS)"
+end
+
 makerule linuxbios_ram.o
        depends "$(DRIVER) linuxbios.a $(LIBGCC_FILE_NAME)" 
        action  "$(CC) -nostdlib -r -o $@ c_start.o $(DRIVER) linuxbios.a $(LIBGCC_FILE_NAME)"
@@ -63,18 +70,61 @@ makerule linuxbios_ram.rom
        action  "cp $(LINUXBIOS_RAM-1) linuxbios_ram.rom"
 end
 
+makedefine LINUXBIOS_APC:=
+
+if CONFIG_AP_CODE_IN_CAR
+       #for ap code in cache
+
+       makerule linuxbios_apc.a
+               depends "apc_auto.o"
+               action  "rm -f linuxbios_apc.a"
+               action  "ar cr linuxbios_apc.a apc_auto.o"
+       end
+
+       makerule linuxbios_apc.o
+               depends "linuxbios_apc.a c_start.o $(LIBGCC_FILE_NAME)"
+        action  "$(CC) -nostdlib -r -o $@ c_start.o linuxbios_apc.a $(LIBGCC_FILE_NAME)"
+       end
+
+       makerule linuxbios_apc
+               depends "linuxbios_apc.o $(TOP)/src/config/linuxbios_apc.ld ldoptions"
+               action  "$(CC) -nostdlib -nostartfiles -static -o $@ -T $(TOP)/src/config/linuxbios_apc.ld linuxbios_apc.o"
+               action  "$(CROSS_COMPILE)nm -n linuxbios_apc | sort > linuxbios_apc.map"
+       end
+
+       ##
+       ## By default compress the part of linuxbios that runs from cache as ram
+       ##
+       makedefine LINUXBIOS_APC-$(CONFIG_COMPRESS):=linuxbios_apc.nrv2b
+       makedefine LINUXBIOS_APC-$(CONFIG_UNCOMPRESSED):=linuxbios_apc.bin
+
+       makerule linuxbios_apc.bin
+               depends "linuxbios_apc"
+               action  "$(OBJCOPY) -O binary $< $@"
+       end
+
+       makerule linuxbios_apc.nrv2b
+        depends "linuxbios_apc.bin nrv2b"
+        action  "./nrv2b e $< $@"
+       end
+
+       makerule linuxbios_apc.rom
+               depends "$(LINUXBIOS_APC-1)"
+               action  "cp $(LINUXBIOS_APC-1) linuxbios_apc.rom"
+       end
+
+       makedefine LINUXBIOS_APC:=linuxbios_apc.rom
+
+end
+
+makedefine LINUXBIOS_RAM_ROM:=linuxbios_ram.rom
+
 makerule linuxbios   
-       depends "crt0.o $(INIT-OBJECTS) linuxbios_ram.rom ldscript.ld"
+       depends "crt0.o $(INIT-OBJECTS) $(LINUXBIOS_APC) $(LINUXBIOS_RAM_ROM) ldscript.ld"
        action  "$(CC) -nostdlib -nostartfiles -static -o $@ -T ldscript.ld crt0.o $(INIT-OBJECTS)"
        action  "$(CROSS_COMPILE)nm -n linuxbios | sort > linuxbios.map"
 end
 
-makerule linuxbios.a   
-       depends "$(OBJECTS)" 
-       action  "rm -f linuxbios.a"
-       action  "ar cr linuxbios.a $(OBJECTS)"
-end
-
 #makerule crt0.S   
 #      depends "$(CRT0)" 
 #      action          "cp $< $@"
@@ -159,7 +209,7 @@ makerule clean
        action  "rm -f ldscript.ld"
        action  "rm -f a.out *.s *.l *.o *.E *.inc"
        action  "rm -f TAGS tags romcc*"
-       action  "rm -f docipl buildrom* chips.c *chip.c linuxbios_ram* linuxbios_pay*"
+       action  "rm -f docipl buildrom* chips.c *chip.c linuxbios_apc* linuxbios_ram* linuxbios_pay*"
        action  "rm -f build_opt_tbl* nrv2b* option_table.c crt0.S"
 end
 
index bbf2dce6022fafd59ca2a0feb5acf0c9cbb76e57..0d8aa765e3834eadee45b8cad6e2bea0fc02b7ae 100644 (file)
@@ -178,18 +178,36 @@ define HAVE_FALLBACK_BOOT
        export always
        comment "Set if fallback booting required"
 end
+define HAVE_FAILOVER_BOOT
+       format "%d"
+       default 0
+       export always
+       comment "Set if failover booting required"
+end
 define USE_FALLBACK_IMAGE
        format "%d"
        default 0
        export used
        comment "Set to build a fallback image"
 end
+define USE_FAILOVER_IMAGE
+        format "%d"
+        default 0
+        export used
+        comment "Set to build a failover image"
+end
 define FALLBACK_SIZE
        default 65536
        format "0x%x"
        export used
        comment "Default fallback image size"
 end
+define FAILOVER_SIZE
+        default 0
+        format "0x%x"
+        export used
+        comment "Default failover image size"
+end
 define ROM_SIZE
        default none
        format "0x%x"
@@ -274,9 +292,9 @@ define USE_DCACHE_RAM
        comment "Use data cache as temporary RAM if possible"
 end
 define DCACHE_RAM_BASE
-       default none
+       default 0xc0000
        format "0x%x"
-       export used
+       export always
        comment "Base address of data cache when using it for temporary RAM"
 end
 define DCACHE_RAM_SIZE
@@ -291,6 +309,21 @@ define DCACHE_RAM_GLOBAL_VAR_SIZE
        export always
        comment "Size of region that for global variable of cache as ram stage"
 end
+define CONFIG_AP_CODE_IN_CAR
+        default 0
+        export always
+        comment "will copy linuxbios_apc to AP cache ane execute in AP"
+end
+define MEM_TRAIN_SEQ
+        default 0
+        export always
+        comment "0: three for in bsp, 1: on every core0, 2: one for on bsp"
+end
+define WAIT_BEFORE_CPUS_INIT
+        default 0
+        export always
+        comment "execute cpus_ready_for_init if it is set to 1"
+end
 define XIP_ROM_BASE
        default 0
        format "0x%x"
@@ -853,7 +886,7 @@ end
 define HT_CHAIN_UNITID_BASE
        default 1
        export always
-       comment "first hypertransport device's unitid base. if southbridge ht chain only has one ht device, it could be 0"
+       comment "this will be first hypertransport device's unitid base, if sb ht chain only has one ht device, it could be 0"
 end
 
 define HT_CHAIN_END_UNITID_BASE
@@ -868,30 +901,67 @@ define SB_HT_CHAIN_UNITID_OFFSET_ONLY
         comment "this will decided if only offset SB hypertransport chain"
 end
 
-define K8_SB_HT_CHAIN_ON_BUS0
+define SB_HT_CHAIN_ON_BUS0
         default 0 
         export always
-        comment "this will make SB hypertransport chain sit on bus 0, if it is 2 will put other chain on 0x40, 0x80, 0xc0"
+        comment "this will make SB hypertransport chain sit on bus 0, if it is 1, will put sb ht chain on bus 0, if it is 2 will put other chain on 0x40, 0x80, 0xc0"
 end
 
-define K8_HW_MEM_HOLE_SIZEK
+define HW_MEM_HOLE_SIZEK
         default 0
         export always
         comment "Opteron E0 later memory hole size in K, 0 mean disable"
 end
 
-define K8_HW_MEM_HOLE_SIZE_AUTO_INC
+define HW_MEM_HOLE_SIZE_AUTO_INC
         default 0
         export always
         comment "Opteron E0 later memory hole size auto increase to avoid hole startk equal to basek"
 end
 
 define K8_HT_FREQ_1G_SUPPORT
-       default 0
+       default 0 
        export always
        comment "Optern E0 later could support 1G HT, but still depends MB design"
 end
 
+define K8_REV_F_SUPPORT
+        default 0
+        export always
+        comment "Opteron Rev F (DDR2) support"
+end
+
+define CBB
+       default 0
+       export always
+       comment "Opteron cpu bus num base"
+end
+
+define CDB
+       default 0x18
+       export always
+       comment "Opteron cpu device num base"
+end
+
+define DIMM_SUPPORT
+        default 0x0108
+       format "0x%x"
+        export always
+        comment "DIMM support: bit 0 - sdram, bit 1: ddr1, bit 2: ddr2, bit 3: ddr3, bit 4: fbdimm, bit 8: reg"
+end
+
+define CPU_SOCKET_TYPE
+       default 0x10
+       export always
+       comment "cpu socket type, 0x10 mean Socket F, 0x11 mean socket M2, 0x20, Soxket G, and 0x21 mean socket M3"
+end
+
+define CPU_ADDR_BITS
+       default 36
+       export always
+       comment "CPU hardware address lines num, for AMD K8 could be 40, and GH could be 48"
+end
+
 define CONFIG_PCI_ROM_RUN
        default 0
        export always
index 5d84bddac5abd84850d10ab9a7b8940cee3ca312..fb68373f1b187af9893e6b49f74969f25dc110dc 100644 (file)
@@ -109,7 +109,7 @@ SECTIONS
        _ram_seg = _text; 
        _eram_seg = _eheap;
 
-       _bogus = ASSERT( ((_eram_seg>>10)<CONFIG_LB_MEM_TOPK) , "please increase CONFIG_LB_MEM_TOPK");
+       _bogus = ASSERT( ( (_eram_seg>>10) < (CONFIG_LB_MEM_TOPK)) , "please increase CONFIG_LB_MEM_TOPK");
 
         _bogus = ASSERT( !((CONFIG_CONSOLE_VGA || CONFIG_PCI_ROM_RUN) && ((_ram_seg<0xa0000) && (_eram_seg>0xa0000))) , "please increase CONFIG_LB_MEM_TOPK and if still fail, try to set _RAMBASE more than 1M");
 
index 1cf141230b17e2a6a2f54e2a16ae72e421073b5a..58570167a9aaa89521027fb4e55207e62c629929 100644 (file)
@@ -17,7 +17,7 @@
 cache_as_ram_setup:
 
        /* hope we can skip the double set for normal part */
-#if USE_FALLBACK_IMAGE == 1
+#if ((HAVE_FAILOVER_BOOT==1) && (USE_FAILOVER_IMAGE==1)) || ((HAVE_FAILOVER_BOOT==0) && (USE_FALLBACK_IMAGE==1))
        /* check if cpu_init_detected */
        movl    $MTRRdefType_MSR, %ecx
        rdmsr
@@ -56,16 +56,32 @@ clear_fixed_var_mtrr_out:
         wrmsr
        movl    $0x269, %ecx
        wrmsr
-#else
+#endif
 
-  #if CacheSize == 0x8000
+#if CacheSize == 0xc000
+        /* enable caching for 16K using fixed mtrr */
+        movl    $0x268, %ecx  /* fix4k_c4000*/
+        movl    $0x06060606, %edx /* WB IO type */
+        xorl    %eax, %eax
+        wrmsr
+        /* enable caching for 32K using fixed mtrr */
+        movl    $0x269, %ecx  /* fix4k_c8000*/
+        movl    $0x06060606, %eax /* WB IO type */
+        movl    %eax, %edx
+        wrmsr
+
+#endif
+
+
+#if CacheSize == 0x8000
         /* enable caching for 32K using fixed mtrr */
         movl    $0x269, %ecx  /* fix4k_c8000*/
         movl    $0x06060606, %eax /* WB IO type */
        movl    %eax, %edx
        wrmsr
-  #else
+#endif
 
+#if CacheSize < 0x8000
         /* enable caching for 16K/8K/4K using fixed mtrr */
         movl    $0x269, %ecx  /* fix4k_cc000*/
     #if CacheSize == 0x4000
@@ -79,8 +95,6 @@ clear_fixed_var_mtrr_out:
     #endif
        xorl    %eax, %eax
        wrmsr
-  #endif
-
 #endif
 
         /* enable memory access for first MBs using top_mem */
@@ -88,9 +102,10 @@ clear_fixed_var_mtrr_out:
         xorl    %edx, %edx
         movl    $(((CONFIG_LB_MEM_TOPK << 10) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
         wrmsr
-#endif /*  USE_FALLBACK_IMAGE == 1*/
+#endif /*  USE_FAILOVER_IMAGE == 1*/
+
 
-#if USE_FALLBACK_IMAGE == 0
+#if ((HAVE_FAILOVER_BOOT==1) && (USE_FAILOVER_IMAGE == 0)) || ((HAVE_FAILOVER_BOOT==0) && (USE_FALLBACK_IMAGE==0))
         /* disable cache */
         movl    %cr0, %eax
         orl    $(0x1<<30),%eax
@@ -108,12 +123,12 @@ clear_fixed_var_mtrr_out:
         wrmsr
 
         movl    $0x203, %ecx
-        movl    $0x0000000f, %edx  /* AMD 40 bit */
+        movl    $((1<<(CPU_ADDR_BITS-32))-1), %edx  /* AMD 40 bit */
         movl    $(~(XIP_ROM_SIZE - 1) | 0x800), %eax
         wrmsr
 #endif /* XIP_ROM_SIZE && XIP_ROM_BASE */
 
-#if USE_FALLBACK_IMAGE == 1
+#if ((HAVE_FAILOVER_BOOT==1) && (USE_FAILOVER_IMAGE==1)) || ((HAVE_FAILOVER_BOOT==0) && (USE_FALLBACK_IMAGE==1))
         /* Set the default memory type and enable fixed and variable MTRRs */
         movl    $MTRRdefType_MSR, %ecx
         xorl    %edx, %edx
@@ -133,23 +148,25 @@ clear_fixed_var_mtrr_out:
         andl    $0x9fffffff,%eax
         movl    %eax, %cr0
 
-#if USE_FALLBACK_IMAGE == 1
+#if ((HAVE_FAILOVER_BOOT==1) && (USE_FAILOVER_IMAGE==1)) || ((HAVE_FAILOVER_BOOT==0) && (USE_FALLBACK_IMAGE==1))
 
         /* Read the range with lodsl*/
        cld
         movl    $CacheBase, %esi
         movl    $(CacheSize>>2), %ecx
-        rep     lodsl
+        rep     
+               lodsl
         /* Clear the range */
         movl    $CacheBase, %edi
         movl    $(CacheSize>>2), %ecx
         xorl    %eax, %eax
-        rep     stosl
+        rep     
+               stosl
 
-#endif /*USE_FALLBACK_IMAGE == 1*/
+#endif /*USE_FAILOVER_IMAGE == 1*/
 
        /* set up the stack pointer */
-       movl    $(CacheBase+CacheSize - 4 - GlobalVarSize), %eax 
+       movl    $(CacheBase+CacheSize - GlobalVarSize), %eax 
        movl    %eax, %esp
 
        /* Restore the BIST result */
index 76b8a8b84783b53224bf493fc395667ec56b8008..7471a53076963a7fd4a4c971b24e0fa0d6a9a786 100644 (file)
@@ -2,7 +2,6 @@
        moved from nrv2v.c and some lines from crt0.S
    2006/05/02 - stepan: move nrv2b to an extra file.
 */
-
 static inline void print_debug_cp_run(const char *strval, uint32_t val)
 {
 #if CONFIG_USE_INIT
@@ -46,8 +45,13 @@ static void copy_and_run(void)
        print_debug_cp_run("src=",(uint32_t)src); 
        print_debug_cp_run("dst=",(uint32_t)dst);
 
-       olen = unrv2b(src, dst);
+//     dump_mem(src, src+0x100);
+
+       olen = unrv2b(src, dst, &ilen);
+       print_debug_cp_run("linxbios_ram.nrv2b length = ", ilen);
+
 #endif
+//     dump_mem(dst, dst+0x100);
 
        print_debug_cp_run("linxbios_ram.bin   length = ", olen);
 
@@ -61,3 +65,55 @@ static void copy_and_run(void)
        );
 
 }
+
+#if CONFIG_AP_CODE_IN_CAR == 1
+
+static void copy_and_run_ap_code_in_car(unsigned ret_addr)
+{
+        uint8_t *src, *dst;
+        unsigned long ilen, olen;
+
+//        print_debug("Copying LinuxBIOS AP code to CAR.\r\n");
+
+#if !CONFIG_COMPRESS
+        __asm__ volatile (
+                "leal _liseg_apc, %0\n\t"
+                "leal _iseg_apc, %1\n\t"
+                "leal _eiseg_apc, %2\n\t"
+                "subl %1, %2\n\t"
+                : "=a" (src), "=b" (dst), "=c" (olen)
+        );
+        memcpy(dst, src, olen);
+#else
+
+        __asm__ volatile (
+                "leal _liseg_apc, %0\n\t"
+                "leal _iseg_apc,  %1\n\t"
+                : "=a" (src) , "=b" (dst)
+        );
+
+//        print_debug_cp_run("src=",(uint32_t)src);
+//        print_debug_cp_run("dst=",(uint32_t)dst);
+
+//      dump_mem(src, src+0x100);
+
+        olen = unrv2b(src, dst, &ilen);
+//        print_debug_cp_run("linxbios_apc.nrv2b length = ", ilen);
+
+#endif
+//      dump_mem(dst, dst+0x100);
+
+//        print_debug_cp_run("linxbios_apc.bin   length = ", olen);
+
+//        print_debug("Jumping to LinuxBIOS AP code in CAR.\r\n");
+
+        __asm__ volatile (
+                "movl %0, %%ebp\n\t" /* cpu_reset for hardwaremain dummy */
+                "cli\n\t"
+                "leal    _iseg_apc, %%edi\n\t"
+                "jmp     *%%edi\n\t"
+               :: "a"(ret_addr)
+        );
+
+}
+#endif
index 0a91326b858190d772633614c507da78a9d80677..813745d66e192b6e66a8279b1461498da33e134b 100644 (file)
@@ -18,12 +18,13 @@ static void inline __attribute__((always_inline))  memcopy(void *dest, const voi
 {
         __asm__ volatile(
                 "cld\n\t"
-                "rep movsl\n\t"
+                "rep; movsl\n\t"
                 : /* No outputs */
                 : "S" (src), "D" (dest), "c" ((bytes)>>2)
                 );
 }
 
+
 static void post_cache_as_ram(void)
 {
 
@@ -49,24 +50,34 @@ static void post_cache_as_ram(void)
         #error "You need to set CONFIG_LB_MEM_TOPK greater than 1024"
 #endif
        
-       set_init_ram_access();
+       set_init_ram_access(); /* So we can access RAM from [1M, CONFIG_LB_MEM_TOPK) */
 
+//     dump_mem(DCACHE_RAM_BASE+DCACHE_RAM_SIZE-0x8000, DCACHE_RAM_BASE+DCACHE_RAM_SIZE-0x7c00);
        print_debug("Copying data from cache to ram -- switching to use ram as stack... ");
 
        /* from here don't store more data in CAR */
+#if 0
         __asm__ volatile (
                "pushl  %eax\n\t"
         );
-        memcopy((CONFIG_LB_MEM_TOPK<<10)-DCACHE_RAM_SIZE, DCACHE_RAM_BASE, DCACHE_RAM_SIZE); //inline
+#endif
+
+        memcopy((void *)((CONFIG_LB_MEM_TOPK<<10)-DCACHE_RAM_SIZE), (void *)DCACHE_RAM_BASE, DCACHE_RAM_SIZE); //inline
+//        dump_mem((CONFIG_LB_MEM_TOPK<<10) - 0x8000, (CONFIG_LB_MEM_TOPK<<10) - 0x7c00);
+
         __asm__ volatile (
                 /* set new esp */ /* before _RAMBASE */
                 "subl   %0, %%ebp\n\t"
                 "subl   %0, %%esp\n\t"
                 ::"a"( (DCACHE_RAM_BASE + DCACHE_RAM_SIZE)- (CONFIG_LB_MEM_TOPK<<10) )
         ); // We need to push %eax to the stack (CAR) before copy stack and pop it later after copy stack and change esp
+#if 0
         __asm__ volatile (
                "popl   %eax\n\t"
         );
+#endif
+
+
        /* We can put data to stack again */
 
         /* only global variable sysinfo in cache need to be offset */
@@ -77,14 +88,27 @@ static void post_cache_as_ram(void)
        disable_cache_as_ram_bsp();  
 
         print_debug("Clearing initial memory region: ");
-        clear_init_ram(); //except the range from [(CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_SIZE, (CONFIG_LB_MEM_TOPK<<10)), that is used as stack in ram
+        clear_init_ram(); //except the range from [(CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_SIZE, (CONFIG_LB_MEM_TOPK<<10))
         print_debug("Done\r\n");
 
+//     dump_mem((CONFIG_LB_MEM_TOPK<<10) - 0x8000, (CONFIG_LB_MEM_TOPK<<10) - 0x7c00);
+
+#ifndef MEM_TRAIN_SEQ
+#define MEM_TRAIN_SEQ 0
+#endif
+        set_sysinfo_in_ram(1); // So other core0 could start to train mem
+
+#if MEM_TRAIN_SEQ == 1
+//     struct sys_info *sysinfox = ((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE);
+
+        // wait for ap memory to trained
+//        wait_all_core0_mem_trained(sysinfox); // moved to lapic_init_cpus.c
+#endif
         /*copy and execute linuxbios_ram */
         copy_and_run();
         /* We will not return */
 
-       print_debug("should not be here -\r\n");
+        print_debug("should not be here -\r\n");
 
 }
 
index f961f50b2cd319cc0feead493dcf3647a3946457..3bd604a79f520e23bfbeb8fc96e81304b68c869e 100644 (file)
@@ -11,6 +11,7 @@
 #include <cpu/x86/mtrr.h>
 #include <cpu/amd/model_fxx_msr.h>
 #include <cpu/amd/model_fxx_rev.h>
+#include <cpu/amd/amdk8_sysconf.h>
 
 static int first_time = 1;
 static int disable_siblings = !CONFIG_LOGICAL_CPUS;
@@ -168,6 +169,15 @@ void amd_sibling_init(device_t cpu)
                /* Build the cpu device path */
                cpu_path.type = DEVICE_PATH_APIC;
                cpu_path.u.apic.apic_id = cpu->path.u.apic.apic_id + i * (nb_cfg_54?1:8);
+                if(id.nodeid == 0) {
+                        // need some special processing, because may the bsp is not lifted, but the core1 is lifted
+                       //defined in northbridge.c
+                        if(sysconf.enabled_apic_ext_id && (!sysconf.lift_bsp_apicid)) {
+                               cpu->path.u.apic.apic_id += sysconf.apicid_offset;
+                        }
+
+                }
+
 
                 /* See if I can find the cpu */
                 new = find_dev_path(cpu->bus, &cpu_path);
index e2158424e639b0d1bb9d3b1127d7957fe34c7d5e..51ef6034f7efb7e83cf3dad10da7f8cddfa7f4cd 100644 (file)
@@ -19,7 +19,9 @@ static inline unsigned get_core_num_in_bsp(unsigned nodeid)
 #if SET_NB_CFG_54 == 1
 static inline uint8_t set_apicid_cpuid_lo(void)
 {
+#if K8_REV_F_SUPPORT == 0
         if(is_cpu_pre_e0()) return 0; // pre_e0 can not be set
+#endif
 
         // set the NB_CFG[54]=1; why the OS will be happy with that ???
         msr_t msr;
index 389969795b49fd5c9a9304fbb2b5712366aceb90..c8c8d8d443bd2ef575c41bcc692f3c2eebefb109 100644 (file)
@@ -20,6 +20,8 @@ static inline unsigned get_initial_apicid(void)
 }
 
 //called by amd_siblings too
+#define CORE_ID_BIT 1
+#define NODE_ID_BIT 3
 struct node_core_id get_node_core_id(unsigned nb_cfg_54) 
 {
        struct node_core_id id;
@@ -27,15 +29,15 @@ struct node_core_id get_node_core_id(unsigned nb_cfg_54)
        if( nb_cfg_54) {
                 //   when NB_CFG[54] is set, nodeid = ebx[27:25], coreid = ebx[24]
                 id.coreid = (cpuid_ebx(1) >> 24) & 0xf;
-                id.nodeid = (id.coreid>>1);
-                id.coreid &= 1;
+                id.nodeid = (id.coreid>>CORE_ID_BIT);
+                id.coreid &= ((1<<CORE_ID_BIT)-1);
         } 
        else 
        {
                 // when NB_CFG[54] is clear, nodeid = ebx[26:24], coreid = ebx[27]
                 id.nodeid = (cpuid_ebx(1) >> 24) & 0xf;
-                id.coreid = (id.nodeid>>3);
-                id.nodeid &= 7;
+                id.coreid = (id.nodeid>>NODE_ID_BIT);
+                id.nodeid &= ((1<<NODE_ID_BIT)-1);
        }
        return id;
 }
index ca83a1def114d4e9feea6cdc1cf30be13de0d2d4..0adfa28d088dc382ffa8874924828976c5d68e24 100644 (file)
@@ -1,7 +1,10 @@
 uses HAVE_INIT_TIMER
 uses HAVE_MOVNTI
+uses CPU_ADDR_BITS
+
 default HAVE_INIT_TIMER=1
 default HAVE_MOVNTI=1
+default CPU_ADDR_BITS=40
 dir /cpu/x86/tsc
 dir /cpu/x86/fpu
 dir /cpu/x86/mmx
index 8d1b84c24fde7c3acb59809ce6c114790249c908..255a6828ed420cfaf77d474812e4526a56773209 100644 (file)
@@ -4,6 +4,12 @@
 
 #define K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST 1
 
+#ifndef SB_VFSMAF 
+#define        SB_VFSMAF 1
+#endif
+
+#define FX_SUPPORT 1
+
 static inline void print_debug_fv(const char *str, unsigned val)
 {
 #if K8_SET_FIDVID_DEBUG == 1
@@ -59,7 +65,7 @@ static void enable_fid_change(void)
                dword |= (1<<14);// disable the DRAM interface at first, it will be enabled by raminit again
                pci_write_config32(PCI_DEV(0, 0x18+i, 2), 0x94, dword);
 
-                dword = 0x23070000; //enable FID/VID change
+                dword = 0x23070700; //enable FID/VID change
 //             dword = 0x00070000; //enable FID/VID change
                 pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0x80, dword);
 
@@ -122,13 +128,27 @@ static unsigned set_fidvid(unsigned apicid, unsigned fidvid, int showmessage)
        if((vid_cur==vid) && (fid_cur==fid)) return fidvid; 
 
         vid_max = (msr.hi>>(48-32)) & 0x3f;
-        fid_max = (msr.lo>>16) & 0x3f;
+        fid_max = ((msr.lo>>16) & 0x3f); //max fid
+#if FX_SUPPORT
+        if(fid_max>=((25-4)*2)) { // FX max fid is 5G
+                fid_max = ((msr.lo>>8) & 0x3f) + 5*2; // max FID is min fid + 1G
+                if(fid_max >= ((25-4)*2)) {
+                        fid_max = (10-4)*2; // hard set to 2G
+                }
+        }
+#endif
 
         //set vid to max
         msr.hi = 1;
         msr.lo = (vid_max<<8) | (fid_cur);
+#if SB_VFSMAF == 1
         msr.lo |= (1<<16); // init changes
+#endif
         wrmsr(0xc0010041, msr);
+#if SB_VFSMAF == 0
+       ldtstop_sb();
+#endif
+       
 
         for(loop=0;loop<100000;loop++){
                msr = rdmsr(0xc0010042);
@@ -159,8 +179,13 @@ static unsigned set_fidvid(unsigned apicid, unsigned fidvid, int showmessage)
                //set target fid
                msr.hi = (100000/5);
                msr.lo = (vid_cur<<8) | fid_cur;
+#if SB_VFSMAF == 1
                msr.lo |= (1<<16); // init changes
+#endif
                wrmsr(0xc0010041, msr);
+#if SB_VFSMAF == 0
+               ldtstop_sb();
+#endif
 
 
 #if K8_SET_FIDVID_DEBUG == 1
@@ -186,8 +211,13 @@ static unsigned set_fidvid(unsigned apicid, unsigned fidvid, int showmessage)
         //set vid to final 
         msr.hi = 1;
         msr.lo = (vid<<8) | (fid_cur);
+#if SB_VFSMAF == 1
         msr.lo |= (1<<16); // init changes
+#endif
         wrmsr(0xc0010041, msr);
+#if SB_VFSMAF == 0
+       ldtstop_sb();
+#endif
 
         for(loop=0;loop<100000;loop++){
                 msr = rdmsr(0xc0010042);
@@ -215,10 +245,21 @@ static void init_fidvid_ap(unsigned bsp_apicid, unsigned apicid)
        msr_t msr;
         uint32_t vid_cur;
         uint32_t fid_cur;
+       uint32_t fid_max;
        int loop;
 
         msr =  rdmsr(0xc0010042);
-        send = ((msr.lo>>16) & 0x3f) << 8; //max fid
+       fid_max = ((msr.lo>>16) & 0x3f); //max fid
+#if FX_SUPPORT
+        if(fid_max>=((25-4)*2)) { // FX max fid is 5G
+                fid_max = ((msr.lo>>8) & 0x3f) + 5*2; // max FID is min fid + 1G
+                if(fid_max >= ((25-4)*2)) {
+                        fid_max = (10-4)*2; // hard set to 2G
+                }
+        }
+#endif
+       send = fid_max<<8;
+
         send |= ((msr.hi>>(48-32)) & 0x3f) << 16; //max vid
        send |= (apicid<<24); // ap apicid
 
@@ -342,6 +383,14 @@ static void init_fidvid_bsp(unsigned bsp_apicid)
         msr_t msr;
         msr =  rdmsr(0xc0010042);
         fid_max = ((msr.lo>>16) & 0x3f); //max fid
+#if FX_SUPPORT == 1
+       if(fid_max>=((25-4)*2)) { // FX max fid is 5G
+               fid_max = ((msr.lo>>8) & 0x3f) + 5*2; // max FID is min fid + 1G        
+               if(fid_max >= ((25-4)*2)) {
+                       fid_max = (10-4)*2; // hard set to 2G
+               }
+       }
+#endif
         vid_max = ((msr.hi>>(48-32)) & 0x3f); //max vid
        fv.common_fidvid = (fid_max<<8)|(vid_max<<16);
 
@@ -366,6 +415,29 @@ static void init_fidvid_bsp(unsigned bsp_apicid)
 #endif
 
 
+#if 0
+       unsigned fid, vid;
+       // Can we use max only? So we can only set fid in one around, otherwise we need to set that to max after raminit
+       // set fid vid to DQS training required
+       fid = (fv.common_fidvid >> 8)  & 0x3f;
+       vid = (fv.common_fidvid >> 16) & 0x3f;
+
+        if(fid>(10-4)*2) {
+                fid = (10-4)*2; //x10 
+        }
+
+        if(vid>=0x1f) {
+                vid+= 4; //unit is 12.5mV
+        } else {
+                vid+= 2; //unit is 25mV
+        }
+
+       fv.common_fidvid = (fid<<8) | (vid<<16);
+
+       print_debug_fv("common_fidvid=", fv.common_fidvid);
+
+#endif
+
         // set BSP fid and vid
        print_debug_fv("bsp apicid=", bsp_apicid);
        fv.common_fidvid = set_fidvid(bsp_apicid, fv.common_fidvid, 1);
index 50b1532f267804c438bf60a2345740d3de5e70f5..4e38a23be0aec55e5e508786a534d75e33979841 100644 (file)
@@ -1,6 +1,12 @@
 //it takes the ENABLE_APIC_EXT_ID and APIC_ID_OFFSET and LIFT_BSP_APIC_ID
 #ifndef K8_SET_FIDVID
-       #define K8_SET_FIDVID 0
+       #if K8_REV_F_SUPPORT == 0
+               #define K8_SET_FIDVID 0
+       #else
+               // for rev F, need to set FID to max
+               #define K8_SET_FIDVID 1
+       #endif
+       
 #endif
 
 #ifndef K8_SET_FIDVID_CORE0_ONLY
@@ -8,6 +14,43 @@
                #define K8_SET_FIDVID_CORE0_ONLY 1
 #endif
 
+static inline void print_initcpu8 (const char *strval, unsigned val)
+{
+#if CONFIG_USE_INIT
+        printk_debug("%s%02x\r\n", strval, val);
+#else
+        print_debug(strval); print_debug_hex8(val); print_debug("\r\n");
+#endif
+}
+
+static inline void print_initcpu8_nocr (const char *strval, unsigned val)
+{
+#if CONFIG_USE_INIT
+        printk_debug("%s%02x", strval, val);
+#else
+        print_debug(strval); print_debug_hex8(val);
+#endif
+}
+
+
+static inline void print_initcpu16 (const char *strval, unsigned val)
+{
+#if CONFIG_USE_INIT
+        printk_debug("%s%04x\r\n", strval, val);
+#else
+        print_debug(strval); print_debug_hex16(val); print_debug("\r\n");
+#endif
+}
+
+static inline void print_initcpu(const char *strval, unsigned val)
+{
+#if CONFIG_USE_INIT
+        printk_debug("%s%08x\r\n", strval, val);
+#else
+        print_debug(strval); print_debug_hex32(val); print_debug("\r\n");
+#endif
+}
+
 typedef void (*process_ap_t)(unsigned apicid, void *gp);
 
 //core_range = 0 : all cores
@@ -44,7 +87,11 @@ static void for_each_ap(unsigned bsp_apicid, unsigned core_range, process_ap_t p
                 j = ((pci_read_config32(PCI_DEV(0, 0x18+i, 3), 0xe8) >> 12) & 3);
                 if(nb_cfg_54) {
                       if(j == 0 ){ // if it is single core, we need to increase siblings for apic calculation 
-                              e0_later_single_core = is_e0_later_in_bsp(i);  // single core
+                       #if K8_REV_F_SUPPORT == 0
+                              e0_later_single_core = is_e0_later_in_bsp(i);  // single core
+                       #else
+                               e0_later_single_core = is_cpu_f0_in_bsp(i);  // We can read cpuid(1) from Func3
+                       #endif
                        } 
                        if(e0_later_single_core) {
                                 j=1;
@@ -57,14 +104,17 @@ static void for_each_ap(unsigned bsp_apicid, unsigned core_range, process_ap_t p
                 if(core_range == 2) {
                         jstart = 1;
                 }
+               else {
+                       jstart = 0;
+               }
 
                 if(e0_later_single_core || disable_siblings || (core_range==1)) {
                         jend = 0;
                 } else {
                         jend = siblings;
-                }
-
-
+               }       
+               
+       
                 for(j=jstart; j<=jend; j++) {
 
                         ap_apicid = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
@@ -141,10 +191,10 @@ static void wait_cpu_state(unsigned apicid, unsigned state)
                 if((readback & 0xff) == state) break; //target cpu is in stage started
         }
 }
-
 static void wait_ap_started(unsigned ap_apicid, void *gp )
 {
         wait_cpu_state(ap_apicid, 0x33); // started
+        print_initcpu8_nocr(" ", ap_apicid);
 }
 
 static void wait_all_aps_started(unsigned bsp_apicid)
@@ -152,9 +202,11 @@ static void wait_all_aps_started(unsigned bsp_apicid)
         for_each_ap(bsp_apicid, 0 , wait_ap_started, (void *)0);
 }
 
-static void wait_all_other_cores_started(unsigned bsp_apicid)
+static void wait_all_other_cores_started(unsigned bsp_apicid) // all aps other than core0
 {
+        print_debug("started ap apicid: ");
         for_each_ap(bsp_apicid, 2 , wait_ap_started, (void *)0);
+        print_debug("\r\n");
 }
 
 static void allow_all_aps_stop(unsigned bsp_apicid)
@@ -162,8 +214,23 @@ static void allow_all_aps_stop(unsigned bsp_apicid)
         lapic_write(LAPIC_MSG_REG, (bsp_apicid<<24) | 0x44); // allow aps to stop
 }
 
+static void STOP_CAR_AND_CPU(void)
+{
+       disable_cache_as_ram(); // inline
+       stop_this_cpu(); // inline, it will stop all cores except node0/core0 the bsp ....
+}
+#if RAMINIT_SYSINFO == 1
+
+#if MEM_TRAIN_SEQ != 1
+static inline void train_ram_on_node(unsigned nodeid, unsigned coreid, struct sys_info *sysinfo, unsigned retcall) {}
+#else
+static inline void train_ram_on_node(unsigned nodeid, unsigned coreid, struct sys_info *sysinfo, unsigned retcall); 
+#endif
+
+#endif
 
 #if RAMINIT_SYSINFO == 1
+
 static unsigned init_cpus(unsigned cpu_init_detectedx ,struct sys_info *sysinfo)
 #else
 static unsigned init_cpus(unsigned cpu_init_detectedx)
@@ -251,14 +318,16 @@ static unsigned init_cpus(unsigned cpu_init_detectedx)
                                        init_fidvid_ap(bsp_apicid, apicid);
        #endif
 
-                        // We need to stop the CACHE as RAM for this CPU, really?
-                       wait_cpu_state(bsp_apicid, 0x44);
-                       lapic_write(LAPIC_MSG_REG, (apicid<<24) | 0x44); // bsp can not check it before stop_this_cpu
+                       // We need to stop the CACHE as RAM for this CPU, really?
+                        wait_cpu_state(bsp_apicid, 0x44);
+                        lapic_write(LAPIC_MSG_REG, (apicid<<24) | 0x44); // bsp can not check it before stop_this_cpu
+                        set_init_ram_access();
+       #if RAMINIT_SYSINFO == 1
+                       train_ram_on_node(id.nodeid, id.coreid, sysinfo, STOP_CAR_AND_CPU);
+       #endif
 
-                       set_init_ram_access();
-                       disable_cache_as_ram(); // inline
-                        stop_this_cpu(); // inline, it will stop all cores except node0/core0 the bsp .... 
-                }
+                       STOP_CAR_AND_CPU();
+                } 
 
                return bsp_apicid;
 }
@@ -281,9 +350,13 @@ static void wait_all_core0_started(void)
        unsigned i;
        unsigned nodes = get_nodes();
 
-       for(i=1;i<nodes;i++) { // skip bsp, because it is running on bsp
-               while(!is_core0_started(i)) {}
-       }
+        print_debug("core0 started: ");
+        for(i=1;i<nodes;i++) { // skip bsp, because it is running on bsp
+                while(!is_core0_started(i)) {}
+                print_initcpu8_nocr(" ", i);
+        }
+        print_debug("\r\n");
+
 }
 
 #endif
index 16d6509430c0fc6fcc932f22368211656a3392a7..9e0ba84802ab249f4544f1c7b02e39ace2903195 100644 (file)
@@ -13,6 +13,7 @@
 #include <device/device.h>
 #include <device/pci.h>
 #include <string.h>
+#include <cpu/x86/msr.h>
 #include <cpu/x86/pae.h>
 #include <pc80/mc146818rtc.h>
 #include <cpu/x86/lapic.h>
 
 #include <cpu/amd/model_fxx_msr.h>
 
+void cpus_ready_for_init(void)
+{
+#if MEM_TRAIN_SEQ == 1
+        struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE);
+        // wait for ap memory to trained
+        wait_all_core0_mem_trained(sysinfox);
+#endif
+}
+
+
+#if K8_REV_F_SUPPORT == 0
 int is_e0_later_in_bsp(int nodeid)
 {
         uint32_t val;
@@ -53,6 +65,18 @@ int is_e0_later_in_bsp(int nodeid)
 
         return e0_later;
 }
+#endif
+
+#if K8_REV_F_SUPPORT == 1
+int is_cpu_f0_in_bsp(int nodeid)
+{
+        uint32_t dword;
+        device_t dev;
+        dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid, 3));
+        dword = pci_read_config32(dev, 0xfc);
+        return (dword & 0xfff00) == 0x40f00;
+}
+#endif
 
 #define MCI_STATUS 0x401
 
@@ -265,16 +289,20 @@ static void init_ecc_memory(unsigned node_id)
        startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >> 2;
        endk   = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000) >> 2) + 0x4000;
 
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
+       #if K8_REV_F_SUPPORT == 0
         if (!is_cpu_pre_e0()) 
        {
+       #endif
 
                 uint32_t val;
                 val = pci_read_config32(f1_dev, 0xf0);
                 if(val & 1) {
                        hole_startk = ((val & (0xff<<24)) >> 10);
                 }
+       #if K8_REV_F_SUPPORT == 0
         }
+       #endif
 #endif
        
 
@@ -294,7 +322,7 @@ static void init_ecc_memory(unsigned node_id)
        disable_lapic();
 
        /* Walk through 2M chunks and zero them */
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
        /* here hole_startk can not be equal to begink, never. Also hole_startk is in 2M boundary, 64M? */
         if ( (hole_startk != 0) && ((begink < hole_startk) && (endk>(4*1024*1024)))) {
                        for(basek = begink; basek < hole_startk;
@@ -336,9 +364,11 @@ static void init_ecc_memory(unsigned node_id)
        printk_debug(" done\n");
 }
 
+
 static inline void k8_errata(void)
 {
        msr_t msr;
+#if K8_REV_F_SUPPORT == 0
        if (is_cpu_pre_c0()) {
                /* Erratum 63... */
                msr = rdmsr(HWCR_MSR);
@@ -406,8 +436,11 @@ static inline void k8_errata(void)
                msr.hi |=1;
                wrmsr_amd(CPU_ID_HYPER_EXT_FEATURES, msr);
        }
+#endif
 
+#if K8_REV_F_SUPPORT == 0
        if (!is_cpu_pre_e0()) 
+#endif
        {
                /* Erratum 110 ... */
                 msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
@@ -420,8 +453,95 @@ static inline void k8_errata(void)
        msr.lo |= 1 << 6;
        wrmsr(HWCR_MSR, msr);
 
+#if K8_REV_F_SUPPORT == 1
+        /* Erratum 131... */
+        msr = rdmsr(NB_CFG_MSR);
+        msr.lo |= 1 << 20;
+        wrmsr(NB_CFG_MSR, msr);
+#endif
+
 }
 
+#if K8_REV_F_SUPPORT == 1
+static void amd_set_name_string_f(device_t dev)
+{
+       unsigned socket;
+       unsigned cmpCap;
+       unsigned pwrLmt;
+       unsigned brandId;
+       unsigned brandTableIndex;
+       unsigned nN;
+       unsigned unknown = 1;
+
+       uint8_t str[48];
+       uint32_t *p;
+
+       msr_t msr;
+       unsigned i;
+       
+       brandId = cpuid_ebx(0x80000001) & 0xffff;
+
+       printk_debug("brandId=%04x\n", brandId);        
+       pwrLmt = ((brandId>>14) & 1) | ((brandId>>5) & 0x0e);
+       brandTableIndex = (brandId>>9) & 0x1f;
+       nN = (brandId & 0x3f) | ((brandId>>(15-6)) &(1<<6));
+
+       socket = (dev->device >> 4) & 0x3;
+
+       cmpCap = cpuid_ecx(0x80000008) & 0xff;
+
+
+        if((brandTableIndex == 0) && (pwrLmt == 0)) {
+               memset(str, 0, 48);
+                sprintf(str, "AMD Engineering Sample");
+                unknown = 0;
+        } else {
+
+               memset(str, 0, 48);
+               sprintf(str, "AMD Processor model unknown");
+
+       #if CPU_SOCKET_TYPE == 0x10 
+               if(socket == 0x01) { // socket F
+                       if ((cmpCap == 1) && ((brandTableIndex==0) ||(brandTableIndex ==1) ||(brandTableIndex == 4)) ) {
+                               uint8_t pc[2];
+                               unknown = 0;
+                               switch (pwrLmt) {
+                                       case   2: pc[0]= 'E'; pc[1] = 'E'; break;
+                                       case   6: pc[0]= 'H'; pc[1] = 'E'; break;
+                                       case 0xa: pc[0]= ' '; pc[1] = ' '; break;
+                                       case 0xc: pc[0]= 'S'; pc[1] = 'E'; break;
+                                       default: unknown = 1;
+                                       
+                               }
+                               if(!unknown) {
+                                       memset(str, 0, 48);
+                                       sprintf(str, "Dual-Core AMD Opteron(tm) Processor %1d2%2d %c%c", brandTableIndex<<1, (nN-1)&0x3f, pc[0], pc[1]);
+                               }
+                       }
+               }
+       #else
+               #if CPU_SOCKET_TYPE == 0x11
+               if(socket == 0x00) { // socket AM2
+                       if(cmpCap == 0) {
+                               sprintf(str, "Athlon 64");      
+                       } else {
+                               sprintf(str, "Athlon 64 Dual Core");
+                       }
+
+               }
+               #endif
+       #endif
+       }
+
+       p = str; 
+       for(i=0;i<6;i++) {
+               msr.lo = *p;  p++; msr.hi = *p; p++;
+               wrmsr(0xc0010030+i, msr);
+       }
+       
+
+}
+#endif
 
 extern void model_fxx_update_microcode(unsigned cpu_deviceid);
 int init_processor_name(void);
@@ -435,6 +555,16 @@ void model_fxx_init(device_t dev)
        unsigned siblings;
 #endif
 
+#if K8_REV_F_SUPPORT == 1
+       struct cpuinfo_x86 c;
+       
+       get_fms(&c, dev->device);
+
+       if((c.x86_model & 0xf0) == 0x40) {
+               amd_set_name_string_f(dev);
+       } 
+#endif
+
        /* Turn on caching if we haven't already */
        x86_enable_cache();
        amd_setup_mtrrs();
@@ -504,6 +634,7 @@ static struct device_operations cpu_dev_ops = {
        .init = model_fxx_init,
 };
 static struct cpu_device_id cpu_table[] = {
+#if K8_REV_F_SUPPORT == 0
        { X86_VENDOR_AMD, 0xf50 }, /* B3 */
        { X86_VENDOR_AMD, 0xf51 }, /* SH7-B3 */
        { X86_VENDOR_AMD, 0xf58 }, /* SH7-C0 */
@@ -540,6 +671,25 @@ static struct cpu_device_id cpu_table[] = {
         { X86_VENDOR_AMD, 0x20fc2 },
         { X86_VENDOR_AMD, 0x20f12 }, /* JH-E6 */
         { X86_VENDOR_AMD, 0x20f32 },
+#endif
+
+#if K8_REV_F_SUPPORT == 1
+//AMD_F0_SUPPORT
+       { X86_VENDOR_AMD, 0x40f50 }, /* SH-F0      Socket F (1207): Opteron */ 
+       { X86_VENDOR_AMD, 0x40f70 },            /*        AM2: Athlon64/Athlon64 FX  */
+       { X86_VENDOR_AMD, 0x40f40 },            /*        S1g1: Mobile Athlon64 */
+       { X86_VENDOR_AMD, 0x40f11 }, /* JH-F1      Socket F (1207): Opteron Dual Core */
+       { X86_VENDOR_AMD, 0x40f31 },            /*        AM2: Athlon64 x2/Athlon64 FX Dual Core */ 
+       { X86_VENDOR_AMD, 0x40f01 },            /*        S1g1: Mobile Athlon64 */
+        { X86_VENDOR_AMD, 0x40f12 }, /* JH-F2      Socket F (1207): Opteron Dual Core */
+        { X86_VENDOR_AMD, 0x40f32 },            /*        AM2 : Opteron Dual Core/Athlon64 x2/ Athlon64 FX Dual Core */
+        { X86_VENDOR_AMD, 0x40fb2 }, /* BH-F2      Socket AM2:Athlon64 x2/ Mobile Athlon64 x2 */
+       { X86_VENDOR_AMD, 0x40f82 },            /*        S1g1:Turion64 x2 */
+        { X86_VENDOR_AMD, 0x40ff2 }, /* DH-F2      Socket AM2: Athlon64 */
+        { X86_VENDOR_AMD, 0x40fc2 },            /*        S1g1:Turion64 */
+        { X86_VENDOR_AMD, 0x40f13 }, /* JH-F3      Socket F (1207): Opteron Dual Core */
+        { X86_VENDOR_AMD, 0x40f33 },            /*        AM2 : Opteron Dual Core/Athlon64 x2/ Athlon64 FX Dual Core */
+#endif
 
        { 0, 0 },
 };
index 63820f5bed096f370987fdd7651d1bab2c9f4bf7..e2108464794ccde9f3754b5e1011710ac94a4af0 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright 2005 AMD
- * 2005.08 yhlu add microcode support 
+ * 2005.08 yhlu add microcode support
  */
 /*============================================================================
 Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
@@ -52,10 +52,15 @@ $1.0$
 
 static uint8_t microcode_updates[] __attribute__ ((aligned(16))) = {
 
-#include "microcode_rev_c.h"
-#include "microcode_rev_d.h"
-#include "microcode_rev_e.h"
+#if K8_REV_F_SUPPORT == 0
+       #include "microcode_rev_c.h"
+       #include "microcode_rev_d.h"
+       #include "microcode_rev_e.h"
+#endif
 
+#if K8_REV_F_SUPPORT == 1
+//     #include "microcode_rev_f.h"
+#endif
         /*  Dummy terminator  */
         0x0, 0x0, 0x0, 0x0,
         0x0, 0x0, 0x0, 0x0,
@@ -65,6 +70,7 @@ static uint8_t microcode_updates[] __attribute__ ((aligned(16))) = {
 
 static unsigned get_equivalent_processor_rev_id(unsigned orig_id) {
        static unsigned id_mapping_table[] = {
+       #if K8_REV_F_SUPPORT == 0
                0x0f48, 0x0048,
                0x0f58, 0x0048,
 
@@ -85,6 +91,11 @@ static unsigned get_equivalent_processor_rev_id(unsigned orig_id) {
                0x20f12, 0x0210,
                0x20f32, 0x0210,
                0x20fb1, 0x0210,
+       #endif
+
+       #if K8_REV_F_SUPPORT == 1
+       
+       #endif
 
        };
 
index 61cc9154886867ed4b642b864ec7b276c062635f..add010b7907f306faf9f7f0a7c4ccbd733643983 100644 (file)
@@ -254,6 +254,7 @@ void do_vsmbios(void)
        unsigned char *buf;
        unsigned int size = SMM_SIZE*1024;
        int i;
+       unsigned long ilen, olen;
        
        printk_err("do_vsmbios\n");
        /* clear vsm bios data area */
@@ -273,7 +274,8 @@ void do_vsmbios(void)
        rom = ((unsigned long) 0) - (ROM_SIZE  + 64*1024);
 
        buf = (unsigned char *) 0x60000;
-       unrv2b((uint8_t *)rom, buf);
+       olen = unrv2b((uint8_t *)rom, buf, &ilen);
+       printk_debug("buf ilen %d olen%d\n", ilen, olen);
        printk_debug("buf %p *buf %d buf[256k] %d\n",
                     buf, buf[0], buf[SMM_SIZE*1024]);
        printk_debug("buf[0x20] signature is %x:%x:%x:%x\n",
index 3edced36e3fad89fe059f1e35ae251aa5921412c..0a5f792b496a7ed4d7331f5a08b8a3dbf91d7491 100644 (file)
@@ -295,6 +295,7 @@ void do_vsmbios(void)
        unsigned char *buf;
        unsigned int size = SMM_SIZE*1024;
        int i;
+       unsigned long ilen, olen;       
        
        printk_err("do_vsmbios\n");
        /* clear vsm bios data area */
@@ -316,7 +317,8 @@ void do_vsmbios(void)
        rom = 0xfffc8000;
 
        buf = (unsigned char *) VSA2_BUFFER;
-       unrv2b((uint8_t *)rom, buf);
+       olen = unrv2b((uint8_t *)rom, buf, &ilen);
+       printk_debug("buf ilen %d olen%d\n", ilen, olen);
        printk_debug("buf %p *buf %d buf[256k] %d\n",
                     buf, buf[0], buf[SMM_SIZE*1024]);
        printk_debug("buf[0x20] signature is %x:%x:%x:%x\n",
index f2de79102be89e954a8482312705afc18e1f0f49..948d4ac83b9edb529fc32ce158108dfc4b3a4ead 100644 (file)
@@ -15,7 +15,6 @@ static void do_amd_early_mtrr_init(const unsigned long *mtrr_msrs)
          */
         msr_t msr;
         const unsigned long *msr_addr;
-        unsigned long cr0;
 #if 0
         /* Enable the access to AMD RdDram and WrDram extension bits */
         msr = rdmsr(SYSCFG_MSR);
index b422f9f42502bf985bc0532dff7a5febcd4ad1ef..e8e92738685aa5c975088e9df262f2cfade87b4a 100644 (file)
@@ -149,7 +149,7 @@ void amd_setup_mtrrs(void)
        msr.lo = state.mmio_basek << 10;
        wrmsr(TOP_MEM, msr);
 
-       if(state.tomk>(4*1024*1024)) {
+       if(state.tomk > (4*1024*1024)) {
                /* Setup TOP_MEM2 */
                msr.hi = state.tomk >> 22;
                msr.lo = state.tomk << 10;
@@ -180,7 +180,7 @@ void amd_setup_mtrrs(void)
        /* FIXME we should probably query the cpu for this
         * but so far this is all any recent AMD cpu has supported.
         */
-       address_bits = 40;
+       address_bits = CPU_ADDR_BITS; //K8 could be 40, and GH could be 48
 
        /* Now that I have mapped what is memory and what is not
         * Setup the mtrrs so we can cache the memory.
diff --git a/src/cpu/amd/socket_AM2/Config.lb b/src/cpu/amd/socket_AM2/Config.lb
new file mode 100644 (file)
index 0000000..4b12629
--- /dev/null
@@ -0,0 +1,19 @@
+uses CONFIG_CHIP_NAME
+uses K8_REV_F_SUPPORT
+uses K8_HT_FREQ_1G_SUPPORT
+uses DIMM_SUPPORT
+uses CPU_SOCKET_TYPE
+
+if CONFIG_CHIP_NAME
+       config chip.h
+end
+
+default K8_REV_F_SUPPORT=1
+#Opteron K8 1G HT Support
+default K8_HT_FREQ_1G_SUPPORT=1
+default DIMM_SUPPORT=0x0004  #DDR2 unbuffered
+default CPU_SOCKET_TYPE=0x11
+
+object socket_AM2.o
+
+dir /cpu/amd/model_fxx
diff --git a/src/cpu/amd/socket_AM2/chip.h b/src/cpu/amd/socket_AM2/chip.h
new file mode 100644 (file)
index 0000000..6b3290c
--- /dev/null
@@ -0,0 +1,4 @@
+extern struct chip_operations cpu_amd_socket_AM2_ops;
+
+struct cpu_amd_socket_AM2_config {
+};
diff --git a/src/cpu/amd/socket_AM2/socket_AM2.c b/src/cpu/amd/socket_AM2/socket_AM2.c
new file mode 100644 (file)
index 0000000..0fd649d
--- /dev/null
@@ -0,0 +1,6 @@
+#include <device/device.h>
+#include "chip.h"
+
+struct chip_operations cpu_amd_socket_AM2_ops = {
+       CHIP_NAME("socket AM2")
+};
diff --git a/src/cpu/amd/socket_F/Config.lb b/src/cpu/amd/socket_F/Config.lb
new file mode 100644 (file)
index 0000000..7406391
--- /dev/null
@@ -0,0 +1,19 @@
+uses CONFIG_CHIP_NAME
+uses K8_REV_F_SUPPORT
+uses K8_HT_FREQ_1G_SUPPORT
+uses DIMM_SUPPORT
+uses CPU_SOCKET_TYPE
+
+if CONFIG_CHIP_NAME
+       config chip.h
+end
+
+default K8_REV_F_SUPPORT=1
+#Opteron K8 1G HT Support
+default K8_HT_FREQ_1G_SUPPORT=1
+default DIMM_SUPPORT=0x0104  #DDR2 and REG
+default CPU_SOCKET_TYPE=0x10
+
+object socket_F.o
+
+dir /cpu/amd/model_fxx
diff --git a/src/cpu/amd/socket_F/chip.h b/src/cpu/amd/socket_F/chip.h
new file mode 100644 (file)
index 0000000..ce2fde0
--- /dev/null
@@ -0,0 +1,4 @@
+extern struct chip_operations cpu_amd_socket_F_ops;
+
+struct cpu_amd_socket_F_config {
+};
diff --git a/src/cpu/amd/socket_F/socket_F.c b/src/cpu/amd/socket_F/socket_F.c
new file mode 100644 (file)
index 0000000..a4cbefe
--- /dev/null
@@ -0,0 +1,6 @@
+#include <device/device.h>
+#include "chip.h"
+
+struct chip_operations cpu_amd_socket_F_ops = {
+       CHIP_NAME("socket F")
+};
index 5c61177a10014009a7b7619782f0f0530949fbe4..4000a09e18f198dc0b50504f917dea85ab01bc0d 100644 (file)
@@ -44,7 +44,7 @@ static void copy_and_run(unsigned cpu_reset)
        
 //     dump_mem(src, src+0x100);
 
-       olen=unrv2b(src, dst);
+       olen = unrv2b(src, dst, &ilen);
 
 #endif
 //     dump_mem(dst, dst+0x100);
index 8282890bf7687b906daf5f438a266a6897651569..8c111e8d71be4267ba9ca69e1847a9d6dd12dce0 100644 (file)
@@ -55,7 +55,7 @@ void setup_lapic(void)
                        LAPIC_DELIVERY_MODE_NMI)
                );
 
-       printk_debug(" apic_id: %d ", lapicid());
+       printk_debug(" apic_id: 0x%02x ", lapicid());
 
 #else /* !NEED_LLAPIC */
        /* Only Pentium Pro and later have those MSR stuff */
index 4b5acad2c47d23d0d136fe274b217f8828e99726..1adafc8d18baeffd94e82e2951b4d3fde6841929 100644 (file)
@@ -322,7 +322,7 @@ static void start_other_cpus(struct bus *cpu_bus, device_t bsp_cpu)
 
                if (!start_cpu(cpu)) {
                        /* Record the error in cpu? */
-                       printk_err("CPU  %u would not start!\n",
+                       printk_err("CPU 0x%02x would not start!\n",
                                cpu->path.u.apic.apic_id);
                }
 #if SERIAL_CPU_INIT == 1
@@ -354,7 +354,7 @@ static void wait_other_cpus_stop(struct bus *cpu_bus)
                        continue;
                }
                if (!cpu->initialized) {
-                       printk_err("CPU %u did not initialize!\n", 
+                       printk_err("CPU 0x%02x did not initialize!\n", 
                                cpu->path.u.apic.apic_id);
 #warning "FIXME do I need a mainboard_cpu_fixup function?"
                }
@@ -366,6 +366,10 @@ static void wait_other_cpus_stop(struct bus *cpu_bus)
 #define initialize_other_cpus(root) do {} while(0)
 #endif /* CONFIG_SMP */
 
+#if WAIT_BEFORE_CPUS_INIT==0
+       #define cpus_ready_for_init() do {} while(0)
+#endif
+
 void initialize_cpus(struct bus *cpu_bus)
 {
        struct device_path cpu_path;
@@ -394,6 +398,8 @@ void initialize_cpus(struct bus *cpu_bus)
        copy_secondary_start_to_1m_below(); // why here? In case some day we can start core1 in amd_sibling_init
 #endif
        
+        cpus_ready_for_init(); 
+
 #if CONFIG_SMP == 1
        #if SERIAL_CPU_INIT == 0
        /* start all aps at first, so we can init ECC all together */
@@ -407,7 +413,6 @@ void initialize_cpus(struct bus *cpu_bus)
 
 #if CONFIG_SMP == 1
         #if SERIAL_CPU_INIT == 1
-        /* start all aps */
         start_other_cpus(cpu_bus, info->cpu);
         #endif
 
index aea8e258d4c41ef78d70519e4dd00a7e7e2bddb6..1c00bd7dcce747dba20e890673e89bf1ccfc8e56 100644 (file)
@@ -47,10 +47,29 @@ static void set_var_mtrr(
        basem.hi = 0;
        wrmsr(MTRRphysBase_MSR(reg), basem);
        maskm.lo = ~(size - 1) | 0x800;
-       maskm.hi = 0x0f;
+       maskm.hi = (1<<(CPU_ADDR_BITS-32))-1;
        wrmsr(MTRRphysMask_MSR(reg), maskm);
 }
 
+static void set_var_mtrr_x(
+        unsigned reg, uint32_t base_lo, uint32_t base_hi, uint32_t size_lo, uint32_t size_hi, unsigned type)
+
+{
+        /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
+        msr_t basem, maskm;
+        basem.lo = (base_lo & 0xfffff000) | type;
+        basem.hi = base_hi & ((1<<(CPU_ADDR_BITS-32))-1);
+        wrmsr(MTRRphysBase_MSR(reg), basem);
+               maskm.hi = (1<<(CPU_ADDR_BITS-32))-1;
+       if(size_lo) {
+               maskm.lo = ~(size_lo - 1) | 0x800;
+       } else {
+               maskm.lo = 0x800;
+               maskm.hi &= ~(size_hi - 1);
+       }
+        wrmsr(MTRRphysMask_MSR(reg), maskm);
+}
+
 static void cache_lbmem(int type)
 {
        /* Enable caching for 0 - 1MB using variable mtrr */
@@ -70,7 +89,6 @@ static void do_early_mtrr_init(const unsigned long *mtrr_msrs)
         */
        msr_t msr;
        const unsigned long *msr_addr;
-       unsigned long cr0;
 
        /* Inialize all of the relevant msrs to 0 */
        msr.lo = 0;
index 1226713cf5803db0e47596df186fc48ea4f1554e..101d11d5e262357feadba5804d2c8869857ac178 100644 (file)
@@ -70,6 +70,25 @@ static void set_var_mtrr(
        msr_t base, mask;
        unsigned address_mask_high;
 
+        if (reg >= 8)
+                return;
+
+        // it is recommended that we disable and enable cache when we
+        // do this.
+        if (sizek == 0) {
+               disable_cache();
+       
+                msr_t zero;
+                zero.lo = zero.hi = 0;
+                /* The invalid bit is kept in the mask, so we simply clear the
+                   relevant mask register to disable a range. */
+                wrmsr (MTRRphysMask_MSR(reg), zero);
+
+               enable_cache();
+               return;
+        }
+
+
        address_mask_high = ((1u << (address_bits - 32u)) - 1u);
 
        base.hi = basek >> 22;
@@ -86,25 +105,16 @@ static void set_var_mtrr(
                mask.lo = 0;
        }
 
-       if (reg >= 8)
-               return;
-
        // it is recommended that we disable and enable cache when we 
        // do this. 
        disable_cache();
-       if (sizek == 0) {
-               msr_t zero;
-               zero.lo = zero.hi = 0;
-               /* The invalid bit is kept in the mask, so we simply clear the
-                  relevant mask register to disable a range. */
-               wrmsr (MTRRphysMask_MSR(reg), zero);
-       } else {
-               /* Bit 32-35 of MTRRphysMask should be set to 1 */
-               base.lo |= type;
-               mask.lo |= 0x800;
-               wrmsr (MTRRphysBase_MSR(reg), base);
-               wrmsr (MTRRphysMask_MSR(reg), mask);
-       }
+
+       /* Bit 32-35 of MTRRphysMask should be set to 1 */
+       base.lo |= type;
+       mask.lo |= 0x800;
+       wrmsr (MTRRphysBase_MSR(reg), base);
+       wrmsr (MTRRphysMask_MSR(reg), mask);
+
        enable_cache();
 }
 
index fa2adaef4f947aadb00bfbfa0a2fa339df6ff69b..a2741e3e98d006860a79ef59bec4f41699c3059c 100644 (file)
@@ -430,7 +430,7 @@ void report_resource_stored(device_t dev, struct resource *resource, const char
                end = resource_end(resource);
                buf[0] = '\0';
                if (resource->flags & IORESOURCE_PCI_BRIDGE) {
-                       sprintf(buf, "bus %d ", dev->link[0].secondary);
+                       sprintf(buf, "bus %02x ", dev->link[0].secondary);
                }
                printk_debug(
                        "%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s\n",
index 6d37ab5764880325d57f0a40337dd8376eee5df8..f0bd817bf49db35ede09532959ddf37db79490fd 100644 (file)
@@ -3,7 +3,6 @@
 
 */
 
-
 #include <bitops.h>
 #include <console/console.h>
 #include <device/device.h>
@@ -78,9 +77,11 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
        /* AMD K8 Unsupported 1Ghz? */
        if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) {
 #if K8_HT_FREQ_1G_SUPPORT == 1 
+       #if K8_REV_F_SUPPORT == 0 
                if (is_cpu_pre_e0()) { // only e0 later suupport 1GHz HT
                        freq_cap &= ~(1 << HT_FREQ_1000Mhz);
                } 
+       #endif
 #else
                freq_cap &= ~(1 << HT_FREQ_1000Mhz);
 #endif
@@ -450,8 +451,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
                }
 
                flags &= ~0x1f; /* mask out base Unit ID */
-                       flags |= next_unitid & 0x1f;
-                       pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
+                flags |= next_unitid & 0x1f;
+                pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
 
                /* Update the Unitd id in the device structure */
                static_count = 1;
@@ -490,7 +491,6 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
                        dev->vendor, dev->device, 
                        (dev->enabled? "enabled": "disabled"), next_unitid);
 
-
        } while((last_unitid != next_unitid) && (next_unitid <= (max_devfn >> 3)));
  end_of_chain:
 #if OPT_HT_LINK == 1
@@ -560,9 +560,17 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
  *
  * @return The maximum bus number found, after scanning all subordinate busses
  */
+unsigned int hypertransport_scan_chain_x(struct bus *bus,
+        unsigned min_devfn, unsigned max_devfn, unsigned int max)
+{
+       unsigned ht_unitid_base[4];
+       unsigned offset_unitid = 1;
+       return hypertransport_scan_chain(bus, min_devfn, max_devfn, max, ht_unitid_base, offset_unitid);
+}
+
 unsigned int ht_scan_bridge(struct device *dev, unsigned int max)
 {
-       return do_pci_scan_bridge(dev, max, hypertransport_scan_chain);
+       return do_pci_scan_bridge(dev, max, hypertransport_scan_chain_x);
 }
 
 
index 9621090ff2fa05b3206d9610eddf0af80bb8dc93..0ebdeb95ff6116b94a6395ea8e2dabd72ff6233a 100644 (file)
@@ -2,4 +2,5 @@
 #define CPU_AMD_MICORCODE_H
 
 void amd_update_microcode(void *microcode_updates, unsigned processor_rev_id);
-#endif /* CPU_AMD_MICROCODE_H */
\ No newline at end of file
+#endif /* CPU_AMD_MICROCODE_H */
+
index 4c2a7ce940d318e513b3a285cf3ea73ca3d7b0e5..ca6d69d7a02212eac2f3551a327ab278e161bb0f 100644 (file)
@@ -1,5 +1,6 @@
 #include <arch/cpu.h>
 
+#if K8_REV_F_SUPPORT == 0
 static inline int is_cpu_rev_a0(void)
 {
        return (cpuid_eax(1) & 0xfffef) == 0x0f00;
@@ -74,5 +75,46 @@ static int is_e0_later_in_bsp(int nodeid)
 int is_e0_later_in_bsp(int nodeid); //defined model_fxx_init.c
 #endif
 
+#endif
+
+#if K8_REV_F_SUPPORT == 1
+//AMD_F0_SUPPORT
+static inline int is_cpu_pre_f0(void)
+{
+        return (cpuid_eax(1) & 0xfff0f) < 0x40f00;
+}
+
+static inline int is_cpu_f0(void)
+{
+        return (cpuid_eax(1) & 0xfff00) ==  0x40f00;
+}
+
+static inline int is_cpu_pre_f2(void)
+{
+        return (cpuid_eax(1) & 0xfff0f) <  0x40f02;
+}
 
+#ifdef __ROMCC__
+//AMD_F0_SUPPORT
+static int is_cpu_f0_in_bsp(int nodeid)
+{
+       uint32_t dword;
+       device_t dev;
+       dev = PCI_DEV(0, 0x18+nodeid, 3);
+       dword = pci_read_config32(dev, 0xfc);
+        return (dword & 0xfff00) == 0x40f00;
+}
+static int is_cpu_pre_f2_in_bsp(int nodeid)
+{
+        uint32_t dword;
+       device_t dev;
+        dev = PCI_DEV(0, 0x18+nodeid, 3);
+        dword = pci_read_config32(dev, 0xfc);
+        return (dword & 0xfff0f) < 0x40f02;
+}
+#else
+int is_cpu_f0_in_bsp(int nodeid); // defined in model_fxx_init.c
+#endif
+
+#endif
 
index 532fc79e0a0f0422400f463b04dabf328c77fd5d..530c653277f1a36a7ca5cb2c742d87aa648e1b53 100644 (file)
@@ -6,7 +6,7 @@ static inline void clear_memory(void *addr, unsigned long size)
 {
         asm volatile(
                 "cld \n\t"
-                "rep stosl\n\t"
+                "rep; stosl\n\t"
                 : /* No outputs */
                 : "a" (0), "D" (addr), "c" (size>>2)
                 );
index aff5616a880ef8f781e7c380f82f054539fb05b4..b922e2687e457f2b8c1a58871d52bce0aae22639 100644 (file)
@@ -48,14 +48,14 @@ struct bus {
        device_t        children;       /* devices behind this bridge */
        unsigned        bridge_ctrl;    /* Bridge control register */
        unsigned char   link;           /* The index of this link */
-       unsigned char   secondary;      /* secondary bus number */
-       unsigned char   subordinate;    /* max subordinate bus number */
+       uint16_t        secondary;      /* secondary bus number */
+       uint16_t        subordinate;    /* max subordinate bus number */
        unsigned char   cap;            /* PCi capability offset */
        unsigned        reset_needed : 1;
        unsigned        disable_relaxed_ordering : 1;
 };
 
-#define MAX_RESOURCES 12
+#define MAX_RESOURCES 12 
 #define MAX_LINKS    8 
 /*
  * There is one device structure for each slot-number/function-number
index 0b44109f9fe73d21ad3e75dc6a14ef8fe5f31f3d..6c12dcf39f360bae7b1c417b7fd377642d11e760 100644 (file)
 #define HT_FREQ_1200Mhz  7
 #define HT_FREQ_1400Mhz  8
 #define HT_FREQ_1600Mhz  9
+#define HT_FREQ_1800Mhz 10 
+#define HT_FREQ_2000Mhz 11
+#define HT_FREQ_2200Mhz 12
+#define HT_FREQ_2400Mhz 13
+#define HT_FREQ_2600Mhz 14
 #define HT_FREQ_VENDOR  15  /* AMD defines this to be 100Mhz */
 
 #endif /* DEVICE_HYPERTRANSPORT_DEF_H */
index 2daa1ca03e0c543cd47b8d1a7a5d41ae813876d0..decc20d29bd97d2c4c87a5d8bb64c38b079dfb21 100644 (file)
@@ -29,12 +29,12 @@ struct pci_operations {
 
 /* Common pci bus operations */
 struct pci_bus_operations {
-       uint8_t (*read8)   (struct bus *pbus, unsigned char bus, int devfn, int where);
-       uint16_t (*read16) (struct bus *pbus, unsigned char bus, int devfn, int where);
-       uint32_t (*read32) (struct bus *pbus, unsigned char bus, int devfn, int where);
-       void (*write8)  (struct bus *pbus, unsigned char bus, int devfn, int where, uint8_t val);
-       void (*write16) (struct bus *pbus, unsigned char bus, int devfn, int where, uint16_t val);
-       void (*write32) (struct bus *pbus, unsigned char bus, int devfn, int where, uint32_t val);
+       uint8_t (*read8)   (struct bus *pbus, int bus, int devfn, int where);
+       uint16_t (*read16) (struct bus *pbus, int bus, int devfn, int where);
+       uint32_t (*read32) (struct bus *pbus, int bus, int devfn, int where);
+       void (*write8)  (struct bus *pbus, int bus, int devfn, int where, uint8_t val);
+       void (*write16) (struct bus *pbus, int bus, int devfn, int where, uint16_t val);
+       void (*write32) (struct bus *pbus, int bus, int devfn, int where, uint32_t val);
 };
 
 struct pci_driver {
index 6fb7ebd385a8e657123adc893095d22950a80a97..1e27647d4b618d086f50c0ef4e7d132870cdb483 100644 (file)
 #define PCI_HT_CAP_SLAVE_FREQ1    0x011        /* Slave frequency to */
 #define PCI_HT_CAP_SLAVE_FREQ_CAP0 0x0e        /* Frequency capability from */
 #define PCI_HT_CAP_SLAVE_FREQ_CAP1 0x12        /* Frequency capability to */
+#define PCI_HT_CAP_SLAVE_LINK_ENUM   0x14 /* Link Enumeration Scratchpad */
 
 /* Power Management Registers */
 
index db92ceb15474b111bd582d50d2aaa7cfafe8daa4..c91eda50477729ed9b90ba96e46562aeedd91a73 100644 (file)
 #if ENDIAN == 0 && BITSIZE == 32
 #define GETBIT(bb, src, ilen) GETBIT_LE32(bb, src, ilen)
 #endif
-
-static unsigned long unrv2b(uint8_t * src, uint8_t * dst)
+static unsigned long unrv2b(uint8_t * src, uint8_t * dst, unsigned long *ilen_p)
 {
        unsigned long ilen = 0, olen = 0, last_m_off = 1;
        uint32_t bb = 0;
        unsigned bc = 0;
        const uint8_t *m_pos;
-//     unsigned long file_len = *(unsigned long *) src;
 
-       // we only have printk_debug in copy_and_run.c if CONFIG_USE_INIT is
-       // not set, so comment it out.
-       // printk_debug("compressed file len is supposed to be %d bytes\n", file_len);
        // skip length
        src += 4;
        /* FIXME: check olen with the length stored in first 4 bytes */ 
@@ -81,9 +76,8 @@ static unsigned long unrv2b(uint8_t * src, uint8_t * dst)
                } while (--m_len > 0);
        }
 
-       // we only have printk_debug in copy_and_run.c if CONFIG_USE_INIT is
-       // not set, so comment it out.
-       //printk_debug("computed len is %d, file len is %d\n", olen, file_len);
+       *ilen_p = ilen;
+
        return olen;
 
 }
index e42b9ce7fff5c52146c0e3859fe43a1b0d668daa..f54c76a8ba2f7b7544922c1beae2d8ac5fd92a20 100644 (file)
@@ -11,7 +11,6 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -23,7 +22,6 @@
 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
@@ -126,8 +124,10 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 
 #include "northbridge/amd/amdk8/raminit.c"
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
index 9a301fb9d48eb338048e2cdab01db4066781fc6c..06b3e42cdfeb98cc09ef35d933808a6874d8b7a8 100644 (file)
@@ -11,7 +11,6 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -23,7 +22,6 @@
 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
@@ -126,8 +124,10 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 
 #include "northbridge/amd/amdk8/raminit.c"
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "northbridge/amd/amdk8/resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
index 0883b26fc9bd2f87e890d2ed20241a6ce8ef424e..52dfb87074f6767e5233d69b30ec96ef789524d5 100644 (file)
@@ -11,7 +11,6 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -24,7 +23,6 @@
 #include "superio/NSC/pc87360/pc87360_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
 
@@ -128,8 +126,10 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 
 #include "northbridge/amd/amdk8/raminit.c"
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "northbridge/amd/amdk8/resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
index 847bf82a482bb48b3d9562f2b2016b10d0538547..575c76a581d5a498594c1da3668ca8d227326507 100644 (file)
@@ -138,7 +138,7 @@ default LIFT_BSP_APIC_ID=0
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcc000
 default DCACHE_RAM_SIZE=0x4000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index b95932876870a03a3096542d54d840424a413180..72b064878a25632ad9edcc2b953774a81b5d8d9b 100644 (file)
@@ -13,7 +13,6 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -25,7 +24,6 @@
 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
@@ -128,8 +126,10 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 
 #include "northbridge/amd/amdk8/raminit.c"
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
diff --git a/src/mainboard/amd/serengeti_cheetah/Config.lb b/src/mainboard/amd/serengeti_cheetah/Config.lb
new file mode 100644 (file)
index 0000000..f395e41
--- /dev/null
@@ -0,0 +1,406 @@
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FAILOVER_IMAGE
+       default ROM_SECTION_SIZE   = FAILOVER_SIZE
+       default ROM_SECTION_OFFSET = ( ROM_SIZE - FAILOVER_SIZE )
+else
+    if USE_FALLBACK_IMAGE
+       default ROM_SECTION_SIZE   = FALLBACK_SIZE
+       default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE - FAILOVER_SIZE )
+    else
+       default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE - FAILOVER_SIZE )
+       default ROM_SECTION_OFFSET = 0
+    end
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=65536
+
+if USE_FAILOVER_IMAGE
+       default XIP_ROM_BASE = ( _ROMBASE - XIP_ROM_SIZE + ROM_IMAGE_SIZE)
+else
+    if USE_FALLBACK_IMAGE
+       default XIP_ROM_BASE = ( _ROMBASE - XIP_ROM_SIZE + ROM_IMAGE_SIZE + FAILOVER_SIZE)
+    else
+       default XIP_ROM_BASE = ( _ROMBASE - XIP_ROM_SIZE + ROM_IMAGE_SIZE)
+    end
+end
+
+arch i386 end 
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+
+#dir /drivers/si/3114
+
+#needed by irq_tables and mptable and acpi_tables
+object get_bus_conf.o
+
+if HAVE_MP_TABLE 
+       object mptable.o 
+end
+
+if HAVE_PIRQ_TABLE 
+       object irq_tables.o 
+end
+
+#if HAVE_ACPI_TABLES
+#       object acpi_tables.o
+#       object fadt.o
+#       if SB_HT_CHAIN_ON_BUS0
+#               object dsdt_bus0.o
+#       else
+#               object dsdt.o
+#       end
+#       object ssdt.o
+#       if ACPI_SSDTX_NUM
+#                if SB_HT_CHAIN_ON_BUS0
+#                 object ssdt2_bus0.o
+#                else
+#                 object ssdt2.o
+#                end
+#       end
+#end
+
+if HAVE_ACPI_TABLES
+        object acpi_tables.o
+        object fadt.o
+       makerule dsdt.c
+               depends "$(MAINBOARD)/dx/dsdt_lb.dsl"
+               action  "/usr/sbin/iasl -tc $(MAINBOARD)/dx/dsdt_lb.dsl"
+               action  "mv dsdt_lb.hex dsdt.c"
+       end
+        object ./dsdt.o
+
+       #./ssdt.o is moved to northbridge/amd/amdk8/Config.lb
+       
+        if ACPI_SSDTX_NUM
+            makerule ssdt2.c
+                        depends "$(MAINBOARD)/dx/pci2.asl"
+                        action  "/usr/sbin/iasl -tc $(MAINBOARD)/dx/pci2.asl"
+                        action  "perl -pi -e 's/AmlCode/AmlCode_ssdt2/g' pci2.hex"
+                        action  "mv pci2.hex ssdt2.c"
+            end
+            object ./ssdt2.o
+        end
+end
+
+if USE_DCACHE_RAM
+
+       if CONFIG_USE_INIT
+               # compile cache_as_ram.c to auto.o
+               makerule ./cache_as_ram_auto.o
+                       depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+                       action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o $@" 
+               end
+
+       else   
+               #compile cache_as_ram.c to auto.inc 
+               makerule ./cache_as_ram_auto.inc
+                       depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+                       action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@"         
+                       action "perl -e 's/.rodata/.rom.data/g' -pi $@"
+                       action "perl -e 's/.text/.section .rom.text/g' -pi $@"
+               end
+
+       end
+end
+
+if USE_FAILOVER_IMAGE
+else
+    if CONFIG_AP_CODE_IN_CAR
+       makerule ./apc_auto.o
+               depends "$(MAINBOARD)/apc_auto.c option_table.h"
+               action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/apc_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o $@"
+       end
+       ldscript /arch/i386/init/ldscript_apc.lb
+    end
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+
+if HAVE_FAILOVER_BOOT
+    if USE_FAILOVER_IMAGE
+       mainboardinit cpu/x86/16bit/entry16.inc
+       ldscript /cpu/x86/16bit/entry16.lds
+    end
+else
+    if USE_FALLBACK_IMAGE
+       mainboardinit cpu/x86/16bit/entry16.inc
+       ldscript /cpu/x86/16bit/entry16.lds
+    end
+end
+
+mainboardinit cpu/x86/32bit/entry32.inc
+if USE_DCACHE_RAM
+        if CONFIG_USE_INIT
+                ldscript /cpu/x86/32bit/entry32.lds
+        end
+
+        if CONFIG_USE_INIT
+                ldscript /cpu/amd/car/cache_as_ram.lds
+        end
+end
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if HAVE_FAILOVER_BOOT
+    if USE_FAILOVER_IMAGE 
+       mainboardinit cpu/x86/16bit/reset16.inc 
+       ldscript /cpu/x86/16bit/reset16.lds 
+    else
+       mainboardinit cpu/x86/32bit/reset32.inc 
+       ldscript /cpu/x86/32bit/reset32.lds 
+    end
+else
+    if USE_FALLBACK_IMAGE 
+       mainboardinit cpu/x86/16bit/reset16.inc 
+       ldscript /cpu/x86/16bit/reset16.lds 
+    else
+       mainboardinit cpu/x86/32bit/reset32.inc 
+       ldscript /cpu/x86/32bit/reset32.lds 
+    end
+end
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+if USE_DCACHE_RAM
+       ##
+       ## Setup Cache-As-Ram
+       ##
+       mainboardinit cpu/amd/car/cache_as_ram.inc
+end
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if HAVE_FAILOVER_BOOT
+    if USE_FAILOVER_IMAGE
+       if USE_DCACHE_RAM
+               ldscript /arch/i386/lib/failover_failover.lds
+       end
+    end
+else
+    if USE_FALLBACK_IMAGE
+       if USE_DCACHE_RAM
+               ldscript /arch/i386/lib/failover.lds
+       end
+    end
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+if USE_DCACHE_RAM
+
+       if CONFIG_USE_INIT
+               initobject cache_as_ram_auto.o
+       else
+               mainboardinit ./cache_as_ram_auto.inc
+       end
+
+end
+
+##
+## Include the secondary Configuration files 
+##
+if CONFIG_CHIP_NAME
+       config chip.h
+end
+
+# sample config for amd/serengeti_cheetah 
+chip northbridge/amd/amdk8/root_complex
+        device apic_cluster 0 on
+                chip cpu/amd/socket_F
+                        device apic 0 on end
+                end
+        end
+       device pci_domain 0 on
+               chip northbridge/amd/amdk8
+                       device pci 18.0 on #  northbridge 
+                               #  devices on link 0, link 0 == LDT 0
+                               chip southbridge/amd/amd8132
+                                       # the on/off keyword is mandatory
+                                       device pci 0.0 on end
+                                       device pci 0.1 on end
+                                       device pci 1.0 on end
+                                       device pci 1.1 on end
+                               end
+                               chip southbridge/amd/amd8111
+                                       # this "device pci 0.0" is the parent the next one
+                                       # PCI bridge
+                                       device pci 0.0 on
+                                               device pci 0.0 on end
+                                               device pci 0.1 on end
+                                               device pci 0.2 off end
+                                               device pci 1.0 off end
+                                       end
+                                       device pci 1.0 on
+                                               chip superio/winbond/w83627hf
+                                                       device pnp 2e.0 off #  Floppy
+                                                               io 0x60 = 0x3f0
+                                                               irq 0x70 = 6
+                                                               drq 0x74 = 2
+                                                       end
+                                                       device pnp 2e.1 off #  Parallel Port
+                                                               io 0x60 = 0x378
+                                                               irq 0x70 = 7
+                                                       end
+                                                       device pnp 2e.2 on #  Com1
+                                                               io 0x60 = 0x3f8
+                                                               irq 0x70 = 4
+                                                       end
+                                                       device pnp 2e.3 off #  Com2
+                                                               io 0x60 = 0x2f8
+                                                               irq 0x70 = 3
+                                                       end
+                                                       device pnp 2e.5 on #  Keyboard
+                                                               io 0x60 = 0x60
+                                                               io 0x62 = 0x64
+                                                               irq 0x70 = 1
+                                                               irq 0x72 = 12
+                                                       end
+                                                       device pnp 2e.6 off #  CIR
+                                                               io 0x60 = 0x100
+                                                       end
+                                                       device pnp 2e.7 off #  GAME_MIDI_GIPO1
+                                                               io 0x60 = 0x220
+                                                               io 0x62 = 0x300
+                                                               irq 0x70 = 9
+                                                       end                                             
+                                                       device pnp 2e.8 off end #  GPIO2
+                                                       device pnp 2e.9 off end #  GPIO3
+                                                       device pnp 2e.a off end #  ACPI
+                                                       device pnp 2e.b on #  HW Monitor
+                                                               io 0x60 = 0x290
+                                                               irq 0x70 = 5
+                                                       end
+                                               end
+                                       end
+                                       device pci 1.1 on end
+                                       device pci 1.2 on end
+                                       device pci 1.3 on
+                                                chip drivers/i2c/i2cmux # pca9556 smbus mux
+                                                        device i2c 18 on #0 pca9516 1
+                                                                chip drivers/generic/generic #dimm 0-0-0
+                                                                        device i2c 50 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 0-0-1
+                                                                        device i2c 51 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 0-1-0
+                                                                        device i2c 52 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 0-1-1
+                                                                        device i2c 53 on end
+                                                                end
+                                                        end
+                                                        device i2c 18 on #1 pca9516 2
+                                                                chip drivers/generic/generic #dimm 1-0-0
+                                                                        device i2c 50 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-0-1
+                                                                        device i2c 51 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-1-0
+                                                                        device i2c 52 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-1-1
+                                                                        device i2c 53 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-2-0
+                                                                        device i2c 54 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-2-1
+                                                                        device i2c 55 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-3-0
+                                                                        device i2c 56 on end
+                                                                end
+                                                                chip drivers/generic/generic #dimm 1-3-1
+                                                                        device i2c 57 on end
+                                                                end
+                                                        end
+                                               end
+                                       end # acpi
+                                       device pci 1.5 off end
+                                       device pci 1.6 off end
+                                       register "ide0_enable" = "1"
+                                       register "ide1_enable" = "1"
+                               end
+                       end #  device pci 18.0
+
+                        device pci 18.0 on end
+                        device pci 18.0 on end  
+                       device pci 18.1 on end
+                       device pci 18.2 on end
+                       device pci 18.3 on end
+               end
+                chip northbridge/amd/amdk8
+                        device pci 19.0 on #  northbridge
+                                chip southbridge/amd/amd8151
+                                        # the on/off keyword is mandatory
+                                        device pci 0.0 on end
+                                        device pci 1.0 on end
+                                end
+                        end #  device pci 19.0
+
+                        device pci 19.0 on end
+                        device pci 19.0 on end
+                        device pci 19.1 on end
+                        device pci 19.2 on end
+                        device pci 19.3 on end
+                end
+
+
+       end #pci_domain
+#        chip drivers/generic/debug
+#              device pnp 0.0 off end # chip name
+#                device pnp 0.1 on end # pci_regs_all
+#                device pnp 0.2 off end # mem
+#                device pnp 0.3 off end # cpuid
+#                device pnp 0.4 off end # smbus_regs_all
+#                device pnp 0.5 off end # dual core msr
+#                device pnp 0.6 off end # cache size
+#                device pnp 0.7 off end # tsc
+#       end
+
+end
+
+
diff --git a/src/mainboard/amd/serengeti_cheetah/Options.lb b/src/mainboard/amd/serengeti_cheetah/Options.lb
new file mode 100644 (file)
index 0000000..91712ec
--- /dev/null
@@ -0,0 +1,329 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses HAVE_ACPI_TABLES
+uses ACPI_SSDTX_NUM
+uses USE_FALLBACK_IMAGE
+uses USE_FAILOVER_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_FAILOVER_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_MAX_CPUS
+uses CONFIG_MAX_PHYSICAL_CPUS
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses FAILOVER_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses CONFIG_COMPRESSED_ROM_STREAM
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses _RAMBASE
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_SERIAL8250
+uses HAVE_INIT_TIMER
+uses CONFIG_GDB_STUB
+uses CONFIG_GDB_STUB
+uses CROSS_COMPILE
+uses CC
+uses HOSTCC
+uses OBJCOPY
+uses CONFIG_CHIP_NAME
+uses CONFIG_CONSOLE_VGA
+uses CONFIG_PCI_ROM_RUN
+uses HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZE_AUTO_INC
+uses K8_HT_FREQ_1G_SUPPORT
+
+uses HT_CHAIN_UNITID_BASE
+uses HT_CHAIN_END_UNITID_BASE
+uses SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
+
+uses USE_DCACHE_RAM
+uses DCACHE_RAM_BASE
+uses DCACHE_RAM_SIZE
+uses DCACHE_RAM_GLOBAL_VAR_SIZE
+uses CONFIG_USE_INIT
+
+uses SERIAL_CPU_INIT
+
+uses ENABLE_APIC_EXT_ID
+uses APIC_ID_OFFSET
+uses LIFT_BSP_APIC_ID
+
+uses CONFIG_PCI_64BIT_PREF_MEM
+
+uses CONFIG_LB_MEM_TOPK
+
+uses CONFIG_AP_CODE_IN_CAR
+
+uses MEM_TRAIN_SEQ
+
+uses WAIT_BEFORE_CPUS_INIT
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=524288
+
+##
+## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use
+##
+#default FALLBACK_SIZE=131072
+#default FALLBACK_SIZE=0x40000
+
+#FALLBACK: 256K-4K
+default FALLBACK_SIZE=0x3f000
+#FAILOVER: 4K
+default FAILOVER_SIZE=0x01000
+
+#more 1M for pgtbl
+default CONFIG_LB_MEM_TOPK=2048
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+default HAVE_FAILOVER_BOOT=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=11
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+## ACPI tables will be included
+default HAVE_ACPI_TABLES=1
+## extra SSDT num
+default ACPI_SSDTX_NUM=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=8
+default CONFIG_MAX_PHYSICAL_CPUS=4
+default CONFIG_LOGICAL_CPUS=1
+
+default SERIAL_CPU_INIT=0
+
+default ENABLE_APIC_EXT_ID=0
+default APIC_ID_OFFSET=0x8
+default LIFT_BSP_APIC_ID=1
+
+#CHIP_NAME ?
+default CONFIG_CHIP_NAME=1
+
+#memory hole size, 0 mean disable, others will enable the hole, at that case if it is small than mmio_basek, it will use mmio_basek instead. 
+#2G
+#default HW_MEM_HOLE_SIZEK=0x200000
+#1G
+default HW_MEM_HOLE_SIZEK=0x100000
+#512M
+#default HW_MEM_HOLE_SIZEK=0x80000
+
+#make auto increase hole size to avoid hole_startk equal to basek so as to make some kernel happy
+#default HW_MEM_HOLE_SIZE_AUTO_INC=1
+
+#Opteron K8 1G HT Support
+default K8_HT_FREQ_1G_SUPPORT=1
+
+#VGA Console
+default CONFIG_CONSOLE_VGA=1
+default CONFIG_PCI_ROM_RUN=1
+
+#HT Unit ID offset, default is 1, the typical one
+default HT_CHAIN_UNITID_BASE=0xa
+
+#real SB Unit ID, default is 0x20, mean dont touch it at last
+default HT_CHAIN_END_UNITID_BASE=0x6
+
+#make the SB HT chain on bus 0, default is not (0)
+default SB_HT_CHAIN_ON_BUS0=2
+
+#only offset for SB chain?, default is yes(1)
+#default SB_HT_CHAIN_UNITID_OFFSET_ONLY=0
+
+#allow capable device use that above 4G
+#default CONFIG_PCI_64BIT_PREF_MEM=1
+
+##
+## enable CACHE_AS_RAM specifics
+##
+default USE_DCACHE_RAM=1
+default DCACHE_RAM_BASE=0xc8000
+default DCACHE_RAM_SIZE=0x08000
+default DCACHE_RAM_GLOBAL_VAR_SIZE=0x01000
+default CONFIG_USE_INIT=0
+
+default CONFIG_AP_CODE_IN_CAR=1
+default MEM_TRAIN_SEQ=1
+
+default WAIT_BEFORE_CPUS_INIT=1
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="serengeti_cheetah"
+default MAINBOARD_VENDOR="AMD"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x1022
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2b80
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = (!USE_FALLBACK_IMAGE) && (!USE_FAILOVER_IMAGE )
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00100000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM = 1
+
+#default CONFIG_COMPRESSED_ROM_STREAM = 1
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc-3.4.5 -m32"
+default HOSTCC="gcc-3.4.5"
+
+##
+## Disable the gdb stub by default
+## 
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+### End Options.lb
+end
diff --git a/src/mainboard/amd/serengeti_cheetah/a b/src/mainboard/amd/serengeti_cheetah/a
new file mode 100644 (file)
index 0000000..d6a8f39
--- /dev/null
@@ -0,0 +1,25 @@
+echo "Creating for ACPI hex for bus 1 Conf"
+cd dx
+iasl -tc dsdt_lb.dsl
+rm DSDT.aml
+mv dsdt_lb.hex ../dsdt.c
+iasl -tc pci2.asl
+rm SSDT2.aml
+perl -e 's/AmlCode/AmlCode_ssdt2/g' -pi pci2.hex
+mv pci2.hex ../ssdt2.c
+cd ..
+echo "Creating for ACPI hex for bus 0 Conf"
+cd dx_bus0
+iasl -tc dsdt_lb.dsl
+rm DSDT.aml
+mv dsdt_lb.hex ../dsdt_bus0.c
+iasl -tc pci2.asl
+rm SSDT2.aml
+perl -e 's/AmlCode/AmlCode_ssdt2/g' -pi pci2.hex
+mv pci2.hex ../ssdt2_bus0.c
+cd ..
+echo "Creating ssdt"
+iasl -tc ssdt_lb_x.dsl
+rm SSDT.aml
+perl -e 's/AmlCode/AmlCode_ssdt/g' -pi ssdt_lb_x.hex
+mv ssdt_lb_x.hex ssdt.c
diff --git a/src/mainboard/amd/serengeti_cheetah/acpi_tables.c b/src/mainboard/amd/serengeti_cheetah/acpi_tables.c
new file mode 100644 (file)
index 0000000..e4cf72b
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Island Aruma ACPI support
+ * written by Stefan Reinauer <stepan@openbios.org>
+ *  (C) 2005 Stefan Reinauer
+ *
+ *
+ *  Copyright 2005 AMD
+ *  2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB
+ */
+
+#include <console/console.h>
+#include <string.h>
+#include <arch/acpi.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <cpu/amd/amdk8_sysconf.h>
+
+#include "mb_sysconf.h"
+
+#define DUMP_ACPI_TABLES 0
+
+#if DUMP_ACPI_TABLES == 1
+static void dump_mem(unsigned start, unsigned end)
+{
+        
+       unsigned i;
+        print_debug("dump_mem:");
+        for(i=start;i<end;i++) {
+                if((i & 0xf)==0) {
+                        printk_debug("\n%08x:", i);
+                }
+                printk_debug(" %02x", (unsigned char)*((unsigned char *)i));
+        }
+        print_debug("\n");
+ }
+#endif
+
+extern unsigned char AmlCode[];
+extern unsigned char AmlCode_ssdt[];
+
+#if ACPI_SSDTX_NUM >= 1
+extern unsigned char AmlCode_ssdt2[];
+//extern unsigned char AmlCode_ssdt3[];
+//extern unsigned char AmlCode_ssdt4[];
+//extern unsigned char AmlCode_ssdt5[];
+//extern unsigned char AmlCode_ssdt6[];
+//extern unsigned char AmlCode_ssdt7[];
+//extern unsigned char AmlCode_ssdt8[];
+#endif
+
+#define IO_APIC_ADDR   0xfec00000UL
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+       unsigned int gsi_base=0x18;
+
+        struct mb_sysconf_t *m;
+
+        m = sysconf.mb;
+       /* create all subtables for processors */
+       current = acpi_create_madt_lapics(current);
+       
+       /* Write 8111 IOAPIC */
+       current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8111,
+                       IO_APIC_ADDR, 0);
+
+        /* Write all 8131 IOAPICs */
+        {
+                device_t dev;
+                struct resource *res;
+                dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN((sysconf.hcdn[0]&0xff), 1));
+                if (dev) {
+                        res = find_resource(dev, PCI_BASE_ADDRESS_0);
+                        if (res) {
+                               current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132_1,
+                                       res->base, gsi_base );
+                               gsi_base+=7;
+
+                        }
+                }
+                dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN((sysconf.hcdn[0] & 0xff)+1, 1));
+                if (dev) {
+                        res = find_resource(dev, PCI_BASE_ADDRESS_0);
+                        if (res) {
+                                current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132_2,
+                                        res->base, gsi_base );
+                                gsi_base+=7;
+                        }
+                }
+        }
+
+       current += acpi_create_madt_irqoverride( (acpi_madt_irqoverride_t *)
+                       current, 0, 0, 2, 5 );
+               /* 0: mean bus 0--->ISA */
+               /* 0: PIC 0 */
+               /* 2: APIC 2 */ 
+               /* 5 mean: 0101 --> Edige-triggered, Active high*/
+
+
+               /* create all subtables for processors */
+        current = acpi_create_madt_lapic_nmis(current, 5, 1);
+               /* 1: LINT1 connect to NMI */
+
+
+       return current;
+}
+
+extern void get_bus_conf(void);
+
+extern void update_ssdt(void *ssdt);
+
+unsigned long write_acpi_tables(unsigned long start)
+{
+       unsigned long current;
+       acpi_rsdp_t *rsdp;
+       acpi_rsdt_t *rsdt;
+       acpi_hpet_t *hpet;
+       acpi_madt_t *madt;
+       acpi_srat_t *srat;
+       acpi_slit_t *slit;
+       acpi_fadt_t *fadt;
+       acpi_facs_t *facs;
+       acpi_header_t *dsdt;
+       acpi_header_t *ssdt;
+       acpi_header_t *ssdtx;
+
+       unsigned char *AmlCode_ssdtx[HC_POSSIBLE_NUM];
+
+       int i;
+
+       get_bus_conf(); //it will get sblk, pci1234, hcdn, and sbdn
+
+       /* Align ACPI tables to 16byte */
+       start   = ( start + 0x0f ) & -0x10;
+       current = start;
+       
+       printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
+
+       /* We need at least an RSDP and an RSDT Table */
+       rsdp = (acpi_rsdp_t *) current;
+       current += sizeof(acpi_rsdp_t);
+       rsdt = (acpi_rsdt_t *) current;
+       current += sizeof(acpi_rsdt_t);
+
+       /* clear all table memory */
+       memset((void *)start, 0, current - start);
+       
+       acpi_write_rsdp(rsdp, rsdt);
+       acpi_write_rsdt(rsdt);
+
+       /*
+        * We explicitly add these tables later on:
+        */
+       printk_debug("ACPI:    * HPET\n");
+       hpet = (acpi_hpet_t *) current;
+       current += sizeof(acpi_hpet_t);
+       acpi_create_hpet(hpet);
+       acpi_add_table(rsdt,hpet);
+
+       /* If we want to use HPET Timers Linux wants an MADT */
+       printk_debug("ACPI:    * MADT\n");
+       madt = (acpi_madt_t *) current;
+       acpi_create_madt(madt);
+       current+=madt->header.length;
+       acpi_add_table(rsdt,madt);
+
+
+       /* SRAT */
+        printk_debug("ACPI:    * SRAT\n");
+        srat = (acpi_srat_t *) current;
+        acpi_create_srat(srat);
+        current+=srat->header.length;
+        acpi_add_table(rsdt,srat);
+
+       /* SLIT */
+        printk_debug("ACPI:    * SLIT\n");
+        slit = (acpi_slit_t *) current;
+        acpi_create_slit(slit);
+        current+=slit->header.length;
+        acpi_add_table(rsdt,slit);
+
+       /* SSDT */
+       printk_debug("ACPI:    * SSDT\n");
+       ssdt = (acpi_header_t *)current;
+       current += ((acpi_header_t *)AmlCode_ssdt)->length;
+       memcpy((void *)ssdt, (void *)AmlCode_ssdt, ((acpi_header_t *)AmlCode_ssdt)->length);
+       //Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c
+       update_ssdt((void*)ssdt);
+        /* recalculate checksum */
+        ssdt->checksum = 0;
+        ssdt->checksum = acpi_checksum((unsigned char *)ssdt,ssdt->length);
+       acpi_add_table(rsdt,ssdt);
+
+#if ACPI_SSDTX_NUM >= 1
+       // we need to make ssdt2 match to PCI2 in pci2.asl,... pci1234[1] 
+       AmlCode_ssdtx[1] = AmlCode_ssdt2;
+//     AmlCode_ssdtx[2] = AmlCode_ssdt3;
+//     AmlCode_ssdtx[3] = AmlCode_ssdt4;
+//      AmlCode_ssdtx[4] = AmlCode_ssdt5;
+//      AmlCode_ssdtx[5] = AmlCode_ssdt6;
+//      AmlCode_ssdtx[6] = AmlCode_ssdt7;
+//      AmlCode_ssdtx[7] = AmlCode_ssdt8;
+
+       //same htio, but different possition? We may have to copy, change HCIN, and recalculate the checknum and add_table
+       
+       for(i=1;i<sysconf.hc_possible_num;i++) {  // 0: is hc sblink
+               if((sysconf.pci1234[i] & 1) != 1 ) continue;
+               printk_debug("ACPI:    * SSDT for PCI%d\n", i+1); //pci0 and pci1 are in dsdt
+               ssdtx = (acpi_header_t *)current;
+               current += ((acpi_header_t *)AmlCode_ssdtx[i])->length;
+               memcpy((void *)ssdtx, (void *)AmlCode_ssdtx[i], ((acpi_header_t *)AmlCode_ssdtx[i])->length);
+               acpi_add_table(rsdt,ssdtx);
+       }
+#endif
+
+
+       /* FACS */
+       printk_debug("ACPI:    * FACS\n");
+       facs = (acpi_facs_t *) current;
+       current += sizeof(acpi_facs_t);
+       acpi_create_facs(facs);
+
+       /* DSDT */
+       printk_debug("ACPI:    * DSDT\n");
+       dsdt = (acpi_header_t *)current;
+       current += ((acpi_header_t *)AmlCode)->length;
+       memcpy((void *)dsdt,(void *)AmlCode, \
+                       ((acpi_header_t *)AmlCode)->length);
+       printk_debug("ACPI:    * DSDT @ %08x Length %x\n",dsdt,dsdt->length);
+
+       /* FDAT */
+       printk_debug("ACPI:    * FADT\n");
+       fadt = (acpi_fadt_t *) current;
+       current += sizeof(acpi_fadt_t);
+
+       acpi_create_fadt(fadt,facs,dsdt);
+       acpi_add_table(rsdt,fadt);
+
+#if DUMP_ACPI_TABLES == 1
+       printk_debug("rsdp\n");
+       dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t));
+
+        printk_debug("rsdt\n");
+        dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t));
+
+        printk_debug("madt\n");
+        dump_mem(madt, ((void *)madt) + madt->header.length);
+
+        printk_debug("srat\n");
+        dump_mem(srat, ((void *)srat) + srat->header.length);
+
+        printk_debug("slit\n");
+        dump_mem(slit, ((void *)slit) + slit->header.length);
+
+        printk_debug("ssdt\n");
+        dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
+
+        printk_debug("fadt\n");
+        dump_mem(fadt, ((void *)fadt) + fadt->header.length);
+#endif
+
+       printk_info("ACPI: done.\n");
+       return current;
+}
+
diff --git a/src/mainboard/amd/serengeti_cheetah/apc_auto.c b/src/mainboard/amd/serengeti_cheetah/apc_auto.c
new file mode 100644 (file)
index 0000000..d6a19e6
--- /dev/null
@@ -0,0 +1,108 @@
+#define ASSEMBLY 1
+#define __ROMCC__
+
+#define RAMINIT_SYSINFO 1
+#define CACHE_AS_RAM_ADDRESS_DEBUG 0
+
+#define SET_NB_CFG_54 1 
+
+//used by raminit
+#define QRANK_DIMM_SUPPORT 1
+
+#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+
+#if 0 
+static void post_code(uint8_t value) {
+#if 1
+        int i;
+        for(i=0;i<0x80000;i++) {
+                outb(value, 0x80);
+        }
+#endif
+}
+#endif
+
+#include <cpu/amd/model_fxx_rev.h>
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/amd/model_fxx/apic_timer.c"
+
+#include "lib/delay.c"
+
+#if CONFIG_USE_INIT == 0
+       #include "lib/memcpy.c"
+#endif
+
+
+//#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+
+#include "northbridge/amd/amdk8/debug.c"
+
+#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+
+#include "northbridge/amd/amdk8/amdk8_f.h"
+
+#include "cpu/x86/mtrr.h"
+#include "cpu/amd/mtrr.h"
+#include "cpu/x86/tsc.h"
+
+#include "northbridge/amd/amdk8/amdk8_f_pci.c"
+#include "northbridge/amd/amdk8/raminit_f_dqs.c"
+
+#include "cpu/amd/dualcore/dualcore.c"
+
+void hardwaremain(int ret_addr)
+{
+       struct sys_info *sysinfo = (DCACHE_RAM_BASE + DCACHE_RAM_SIZE - DCACHE_RAM_GLOBAL_VAR_SIZE); // in CACHE
+        struct sys_info *sysinfox = ((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
+
+       struct node_core_id id;
+
+       id = get_node_core_id_x();
+
+        print_debug("CODE IN CACHE ON NODE:"); print_debug_hex8(id.nodeid); print_debug("\r\n");
+
+       train_ram(id.nodeid, sysinfo, sysinfox);
+
+       /*
+               go back, but can not use stack any more, because we only keep ret_addr and can not restore esp, and ebp
+       */
+
+        __asm__ volatile (
+                "movl  %0, %%edi\n\t"
+                "jmp     *%%edi\n\t"
+                :: "a"(ret_addr)
+        );
+
+
+
+}
+struct eregs {
+        uint32_t eax, ecx, edx, ebx, esp, ebp, esi, edi;
+        uint32_t vector;
+        uint32_t error_code;
+        uint32_t eip;
+        uint32_t cs;
+        uint32_t eflags;
+};
+
+void x86_exception(struct eregs *info)
+{
+        do {
+                hlt();
+        } while(1);
+}
+
+
diff --git a/src/mainboard/amd/serengeti_cheetah/c b/src/mainboard/amd/serengeti_cheetah/c
new file mode 100644 (file)
index 0000000..0abeb0e
--- /dev/null
@@ -0,0 +1,5 @@
+rm dsdt.c
+rm ssdt2.c
+rm dsdt_bus0.c
+rm ssdt2_bus0.c
+rm ssdt.c
diff --git a/src/mainboard/amd/serengeti_cheetah/cache_as_ram_auto.c b/src/mainboard/amd/serengeti_cheetah/cache_as_ram_auto.c
new file mode 100644 (file)
index 0000000..c338704
--- /dev/null
@@ -0,0 +1,395 @@
+#define ASSEMBLY 1
+#define __ROMCC__
+
+#define RAMINIT_SYSINFO 1
+#define CACHE_AS_RAM_ADDRESS_DEBUG 0
+
+#define SET_NB_CFG_54 1 
+
+//used by raminit
+#define QRANK_DIMM_SUPPORT 1
+
+//used by incoherent_ht
+//#define K8_SCAN_PCI_BUS 1
+//#define K8_ALLOCATE_IO_RANGE 1
+
+
+//used by init_cpus and fidvid
+#define K8_SET_FIDVID 1
+//if we want to wait for core1 done before DQS training, set it to 0
+#define K8_SET_FIDVID_CORE0_ONLY 1
+
+//0: three for in bsp, only this one support F0_F1 workaround
+//1: on every core0
+//2: one for on bsp
+//#define MEM_TRAIN_SEQ 1
+
+#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+
+#if 0 
+static void post_code(uint8_t value) {
+#if 1
+        int i;
+        for(i=0;i<0x80000;i++) {
+                outb(value, 0x80);
+        }
+#endif
+}
+#endif
+#if USE_FAILOVER_IMAGE==0
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include <cpu/amd/model_fxx_rev.h>
+#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/amd/model_fxx/apic_timer.c"
+#endif
+
+
+
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+#include "cpu/x86/bist.h"
+
+#if USE_FAILOVER_IMAGE==0
+
+#include "lib/delay.c"
+
+#if CONFIG_USE_INIT == 0
+       #include "lib/memcpy.c"
+#endif
+#include "northbridge/amd/amdk8/debug.c"
+#include "cpu/amd/mtrr/amd_earlymtrr.c"
+#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
+
+#include "northbridge/amd/amdk8/setup_resource_map.c"
+
+#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+
+#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+
+static void memreset_setup(void)
+{
+       //GPIO on amd8111 to enable MEMRST ????
+        outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 16);  //REVC_MEMRST_EN=1
+        outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 17);
+}
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+}
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+#define SMBUS_HUB 0x18
+        int ret,i;
+        unsigned device=(ctrl->channel0[0])>>8;
+        /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
+        i=2;
+        do {
+                ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
+        } while ((ret!=0) && (i-->0));
+
+        smbus_write_byte(SMBUS_HUB, 0x03, 0);
+}
+#if 0
+static inline void change_i2c_mux(unsigned device)
+{
+#define SMBUS_HUB 0x18
+        int ret, i;
+        print_debug("change_i2c_mux i="); print_debug_hex8(device); print_debug("\r\n");
+        i=2;
+        do {
+                ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
+                print_debug("change_i2c_mux 1 ret="); print_debug_hex32(ret); print_debug("\r\n");
+        } while ((ret!=0) && (i-->0));
+        ret = smbus_write_byte(SMBUS_HUB, 0x03, 0);
+        print_debug("change_i2c_mux 2 ret="); print_debug_hex32(ret); print_debug("\r\n");
+}
+#endif
+
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+        return smbus_read_byte(device, address);
+}
+
+#include "northbridge/amd/amdk8/amdk8_f.h"
+#include "northbridge/amd/amdk8/coherent_ht.c"
+
+#include "northbridge/amd/amdk8/incoherent_ht.c"
+
+#include "northbridge/amd/amdk8/raminit_f.c"
+
+#include "sdram/generic_sdram.c"
+
+ /* tyan does not want the default */
+#include "resourcemap.c" 
+
+#include "cpu/amd/dualcore/dualcore.c"
+
+#define RC0 ((1<<0)<<8)
+#define RC1 ((1<<1)<<8)
+#define RC2 ((1<<2)<<8)
+#define RC3 ((1<<3)<<8)
+
+#define DIMM0 0x50
+#define DIMM1 0x51
+#define DIMM2 0x52
+#define DIMM3 0x53
+#define DIMM4 0x54
+#define DIMM5 0x55
+#define DIMM6 0x56
+#define DIMM7 0x57
+
+
+#include "cpu/amd/car/copy_and_run.c"
+#include "cpu/amd/car/post_cache_as_ram.c"
+
+#include "cpu/amd/model_fxx/init_cpus.c"
+
+#include "cpu/amd/model_fxx/fidvid.c"
+#endif
+
+#if ((HAVE_FAILOVER_BOOT==1) && (USE_FAILOVER_IMAGE == 1)) || ((HAVE_FAILOVER_BOOT==0) && (USE_FALLBACK_IMAGE == 1))
+
+#include "southbridge/amd/amd8111/amd8111_enable_rom.c"
+#include "northbridge/amd/amdk8/early_ht.c"
+
+void failover_process(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+
+       unsigned last_boot_normal_x = last_boot_normal();
+
+        /* Is this a cpu only reset? or Is this a secondary cpu? */
+        if ((cpu_init_detectedx) || (!boot_cpu())) {
+                if (last_boot_normal_x) {
+                        goto normal_image;
+                } else {
+                        goto fallback_image;
+                }
+        }
+
+        /* Nothing special needs to be done to find bus 0 */
+        /* Allow the HT devices to be found */
+
+        enumerate_ht_chain();
+
+        /* Setup the rom access for 4M */
+        amd8111_enable_rom();
+
+        /* Is this a deliberate reset by the bios */
+        if (bios_reset_detected() && last_boot_normal_x) {
+                goto normal_image;
+        }
+        /* This is the primary cpu how should I boot? */
+        else if (do_normal_boot()) {
+                goto normal_image;
+        }
+        else {
+                goto fallback_image;
+        }
+ normal_image:
+        __asm__ volatile ("jmp __normal_image"
+                : /* outputs */
+                : "a" (bist), "b" (cpu_init_detectedx) /* inputs */
+                );
+
+ fallback_image:
+#if HAVE_FAILOVER_BOOT==1
+        __asm__ volatile ("jmp __fallback_image"
+                : /* outputs */
+                : "a" (bist), "b" (cpu_init_detectedx) /* inputs */
+                )
+#endif
+       ;
+}
+#endif
+
+void real_main(unsigned long bist, unsigned long cpu_init_detectedx);
+
+void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+#if HAVE_FAILOVER_BOOT==1 
+    #if USE_FAILOVER_IMAGE==1
+       failover_process(bist, cpu_init_detectedx);     
+    #else
+       real_main(bist, cpu_init_detectedx);
+    #endif
+#else
+    #if USE_FALLBACK_IMAGE == 1
+       failover_process(bist, cpu_init_detectedx);     
+    #endif
+       real_main(bist, cpu_init_detectedx);
+#endif
+}
+
+#if USE_FAILOVER_IMAGE==0
+
+void real_main(unsigned long bist, unsigned long cpu_init_detectedx)
+{
+       static const uint16_t spd_addr[] = {
+                       //first node
+                        RC0|DIMM0, RC0|DIMM2, 0, 0,
+                        RC0|DIMM1, RC0|DIMM3, 0, 0,
+#if CONFIG_MAX_PHYSICAL_CPUS > 1
+                       //second node
+                        RC1|DIMM0, RC1|DIMM2, RC1|DIMM4, RC1|DIMM6,
+                        RC1|DIMM1, RC1|DIMM3, RC1|DIMM5, RC1|DIMM7,
+#endif
+#if CONFIG_MAX_PHYSICAL_CPUS > 2
+                        // third node
+                        RC2|DIMM0, RC2|DIMM2, 0, 0,
+                        RC2|DIMM1, RC2|DIMM3, 0, 0,
+                        // four node
+                        RC3|DIMM0, RC3|DIMM2, RC3|DIMM4, RC3|DIMM6,
+                        RC3|DIMM1, RC3|DIMM3, RC3|DIMM5, RC3|DIMM7,
+#endif
+
+       };
+
+       struct sys_info *sysinfo = (DCACHE_RAM_BASE + DCACHE_RAM_SIZE - DCACHE_RAM_GLOBAL_VAR_SIZE);
+
+        int needs_reset; int i;
+        unsigned bsp_apicid = 0;
+
+        if (bist == 0) {
+               //It's the time to set ctrl in sysinfo now;
+               fill_mem_ctrl(CONFIG_MAX_PHYSICAL_CPUS, sysinfo->ctrl, spd_addr);
+               bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
+        }
+
+//     post_code(0x32);
+
+       w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE);
+        uart_init();
+        console_init();
+
+//     dump_mem(DCACHE_RAM_BASE+DCACHE_RAM_SIZE-0x200, DCACHE_RAM_BASE+DCACHE_RAM_SIZE);
+       
+       /* Halt if there was a built in self test failure */
+       report_bist_failure(bist);
+
+        print_debug("*sysinfo range: ["); print_debug_hex32(sysinfo); print_debug(",");  print_debug_hex32((unsigned long)sysinfo+sizeof(struct sys_info)); print_debug(")\r\n");
+
+        setup_serengeti_cheetah_resource_map();
+#if 0
+        dump_pci_device(PCI_DEV(0, 0x18, 0));
+       dump_pci_device(PCI_DEV(0, 0x19, 0));
+#endif
+
+       print_debug("bsp_apicid="); print_debug_hex8(bsp_apicid); print_debug("\r\n");
+
+#if MEM_TRAIN_SEQ == 1
+        set_sysinfo_in_ram(0); // in BSP so could hold all ap until sysinfo is in ram 
+#endif
+       setup_coherent_ht_domain(); // routing table and start other core0
+
+       wait_all_core0_started();
+#if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
+       /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain, 
+        * So here need to make sure last core0 is started, esp for two way system,
+        * (there may be apic id conflicts in that case) 
+        */
+        start_other_cores();
+       wait_all_other_cores_started(bsp_apicid);
+#endif
+       
+       /* it will set up chains and store link pair for optimization later */
+        ht_setup_chains_x(sysinfo); // it will init sblnk and sbbusn, nodes, sbdn
+
+#if 0
+       //it your CPU min fid is 1G, you can change HT to 1G and FID to max one time.
+        needs_reset = optimize_link_coherent_ht();
+        needs_reset |= optimize_link_incoherent_ht(sysinfo);
+#endif
+
+#if K8_SET_FIDVID == 1
+
+        {
+                msr_t msr;
+                msr=rdmsr(0xc0010042);
+                print_debug("begin msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\r\n");
+
+        }
+
+       enable_fid_change();
+
+       enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
+
+        init_fidvid_bsp(bsp_apicid);
+
+        // show final fid and vid
+        {
+                msr_t msr;
+                msr=rdmsr(0xc0010042);
+                print_debug("end   msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\r\n"); 
+
+        }
+#endif
+
+#if 1
+       needs_reset = optimize_link_coherent_ht();
+       needs_reset |= optimize_link_incoherent_ht(sysinfo);
+
+        // fidvid change will issue one LDTSTOP and the HT change will be effective too
+        if (needs_reset) {
+                print_info("ht reset -\r\n");
+                soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn);
+        }
+#endif
+       allow_all_aps_stop(bsp_apicid);
+
+#if 0
+        //It's the time to set ctrl in sysinfo now;
+       fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
+#endif
+
+       enable_smbus();
+
+#if 0
+       for(i=0;i<4;i++) {
+               activate_spd_rom(&cpu[i]);
+               dump_smbus_registers();
+       }
+#endif
+
+#if 0
+        for(i=1;i<256;i<<=1) {
+                change_i2c_mux(i);
+                dump_smbus_registers();
+        }
+#endif
+
+       memreset_setup();
+
+       //do we need apci timer, tsc...., only debug need it for better output
+        /* all ap stopped? */
+//        init_timer(); // Need to use TMICT to synconize FID/VID
+
+       sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
+
+#if 0
+        print_pci_devices();
+#endif
+
+#if 0
+//        dump_pci_devices();
+        dump_pci_device_index_wait(PCI_DEV(0, 0x18, 2), 0x98);
+       dump_pci_device_index_wait(PCI_DEV(0, 0x19, 2), 0x98);
+#endif
+
+        post_cache_as_ram(); // bsp swtich stack to ram and copy sysinfo ram now
+
+}
+#endif
diff --git a/src/mainboard/amd/serengeti_cheetah/chip.h b/src/mainboard/amd/serengeti_cheetah/chip.h
new file mode 100644 (file)
index 0000000..258d16d
--- /dev/null
@@ -0,0 +1,6 @@
+extern struct chip_operations mainboard_amd_serengeti_cheetah_ops;
+
+struct mainboard_amd_serengeti_cheetah_config {
+//     int fixup_scsi;
+//     int fixup_vga;
+};
diff --git a/src/mainboard/amd/serengeti_cheetah/cmos.layout b/src/mainboard/amd/serengeti_cheetah/cmos.layout
new file mode 100644 (file)
index 0000000..0daae92
--- /dev/null
@@ -0,0 +1,98 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       1        hw_scrubber
+396          1       e       1        interleave_chip_selects
+397          2       e       8        max_mem_clock
+399         1       e       2        dual_core
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432         8       h       0        boot_countdown
+440          4       e       9        slow_cpu
+444          1       e       1        nmi
+445          1       e       1        iommu
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+8     0     400Mhz
+8     1     333Mhz
+8     2     266Mhz
+8     3     200Mhz
+9     0     off
+9     1     87.5%
+9     2     75.0%
+9     3     62.5%
+9     4     50.0%
+9     5     37.5%
+9     6     25.0%
+9     7     12.5%
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/amd8111.asl b/src/mainboard/amd/serengeti_cheetah/dx/amd8111.asl
new file mode 100644 (file)
index 0000000..e64bc4a
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2005 AMD
+ */
+//AMD8111
+            Name (APIC, Package (0x04)
+            {
+                Package (0x04) { 0x0004FFFF, 0x00, 0x00, 0x10},// 0x0004ffff : assusme 8131 is present 
+                Package (0x04) { 0x0004FFFF, 0x01, 0x00, 0x11}, 
+                Package (0x04) { 0x0004FFFF, 0x02, 0x00, 0x12}, 
+                Package (0x04) { 0x0004FFFF, 0x03, 0x00, 0x13}
+            })
+
+            Name (PICM, Package (0x04)
+            {
+                Package (0x04) { 0x0004FFFF, 0x00, \_SB.PCI0.LNKA, 0x00}, 
+                Package (0x04) { 0x0004FFFF, 0x01, \_SB.PCI0.LNKB, 0x00}, 
+                Package (0x04) { 0x0004FFFF, 0x02, \_SB.PCI0.LNKC, 0x00}, 
+                Package (0x04) { 0x0004FFFF, 0x03, \_SB.PCI0.LNKD, 0x00}
+            })
+
+           Name (DNCG, Ones)
+
+            Method (_PRT, 0, NotSerialized)
+            {
+               If (LEqual (^DNCG, Ones)) {
+                       Store (DADD(\_SB.PCI0.SBDN, 0x0001ffff), Local0)
+                       // Update the Device Number according to SBDN
+                        Store(Local0, Index (DeRefOf (Index (PICM, 0)), 0))
+                        Store(Local0, Index (DeRefOf (Index (PICM, 1)), 0))
+                        Store(Local0, Index (DeRefOf (Index (PICM, 2)), 0))
+                        Store(Local0, Index (DeRefOf (Index (PICM, 3)), 0))
+
+                        Store(Local0, Index (DeRefOf (Index (APIC, 0)), 0))
+                        Store(Local0, Index (DeRefOf (Index (APIC, 1)), 0))
+                        Store(Local0, Index (DeRefOf (Index (APIC, 2)), 0))
+                        Store(Local0, Index (DeRefOf (Index (APIC, 3)), 0))
+                       
+                       Store (0x00, ^DNCG)
+                       
+               }
+
+                If (LNot (PICF)) { 
+                       Return (PICM) 
+               }
+                Else {
+                       Return (APIC) 
+               }
+            }
+
+            Device (SBC3)
+            {
+                /*  acpi smbus   it should be 0x00040003 if 8131 present */
+               Method (_ADR, 0, NotSerialized)
+               {
+                       Return (DADD(\_SB.PCI0.SBDN, 0x00010003))
+               }
+                OperationRegion (PIRQ, PCI_Config, 0x56, 0x02)
+                Field (PIRQ, ByteAcc, Lock, Preserve)
+                {
+                    PIBA,   8, 
+                    PIDC,   8
+                }
+/*
+                OperationRegion (TS3_, PCI_Config, 0xC4, 0x02)
+                Field (TS3_, DWordAcc, NoLock, Preserve)
+                {
+                    PTS3,   16
+                }
+*/
+            }
+
+            Device (HPET)
+            {
+                Name (HPT, 0x00)
+                Name (_HID, EisaId ("PNP0103"))
+                Name (_UID, 0x00)
+                Method (_STA, 0, NotSerialized)
+                {
+                    Return (0x0F)
+                }
+
+                Method (_CRS, 0, NotSerialized)
+                {
+                    Name (BUF0, ResourceTemplate ()
+                    {
+                        Memory32Fixed (ReadWrite, 0xFED00000, 0x00000400)
+                    })
+                    Return (BUF0)
+                }
+            }
+
+           Include ("amd8111_pic.asl")
+
+           Include ("amd8111_isa.asl")
+
+            Device (TP2P)
+            {
+                /* 8111 P2P and it should 0x00030000 when 8131 present*/
+                Method (_ADR, 0, NotSerialized)
+                {
+                       Return (DADD(\_SB.PCI0.SBDN, 0x00000000))
+                }
+
+                Method (_PRW, 0, NotSerialized)
+                {
+                    If (CondRefOf (\_S3, Local0)) { Return (Package (0x02) { 0x08, 0x03 }) }
+                    Else { Return (Package (0x02) { 0x08, 0x01 }) }
+                }
+
+                Device (USB0)
+                {
+                    Name (_ADR, 0x00000000)
+                    Method (_PRW, 0, NotSerialized)
+                    {
+                        If (CondRefOf (\_S3, Local0)) { Return (Package (0x02) { 0x0F, 0x03 }) }
+                        Else { Return (Package (0x02) { 0x0F, 0x01 }) }
+                    }
+                }
+
+                Device (USB1)
+                {
+                    Name (_ADR, 0x00000001)
+                    Method (_PRW, 0, NotSerialized)
+                    {
+                        If (CondRefOf (\_S3, Local0)) { Return (Package (0x02) { 0x0F, 0x03 }) }
+                        Else { Return (Package (0x02) { 0x0F, 0x01 }) }
+                    }
+                }
+
+                Name (APIC, Package (0x0C)
+                {
+                    Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x10 }, //USB
+                    Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x11 },
+                    Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x12 },
+                    Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x13 },
+
+                    Package (0x04) { 0x0004FFFF, 0x00, 0x00, 0x10 }, //Slot 4
+                    Package (0x04) { 0x0004FFFF, 0x01, 0x00, 0x11 },
+                    Package (0x04) { 0x0004FFFF, 0x02, 0x00, 0x12 },
+                    Package (0x04) { 0x0004FFFF, 0x03, 0x00, 0x13 },
+
+                    Package (0x04) { 0x0005FFFF, 0x00, 0x00, 0x11 }, //Slot 3
+                    Package (0x04) { 0x0005FFFF, 0x01, 0x00, 0x12 },
+                    Package (0x04) { 0x0005FFFF, 0x02, 0x00, 0x13 },
+                    Package (0x04) { 0x0005FFFF, 0x03, 0x00, 0x10 }
+                })
+       
+                Name (PICM, Package (0x0C)
+                {
+                    Package (0x04) { 0x0000FFFF, 0x00, \_SB.PCI0.LNKA, 0x00 }, //USB
+                    Package (0x04) { 0x0000FFFF, 0x01, \_SB.PCI0.LNKB, 0x00 },
+                    Package (0x04) { 0x0000FFFF, 0x02, \_SB.PCI0.LNKC, 0x00 },
+                    Package (0x04) { 0x0000FFFF, 0x03, \_SB.PCI0.LNKD, 0x00 },
+
+                    Package (0x04) { 0x0004FFFF, 0x00, \_SB.PCI0.LNKA, 0x00 }, //Slot 4
+                    Package (0x04) { 0x0004FFFF, 0x01, \_SB.PCI0.LNKB, 0x00 },
+                    Package (0x04) { 0x0004FFFF, 0x02, \_SB.PCI0.LNKC, 0x00 },
+                    Package (0x04) { 0x0004FFFF, 0x03, \_SB.PCI0.LNKD, 0x00 },
+
+                    Package (0x04) { 0x0005FFFF, 0x00, \_SB.PCI0.LNKB, 0x00 }, //Slot 3
+                    Package (0x04) { 0x0005FFFF, 0x01, \_SB.PCI0.LNKC, 0x00 },
+                    Package (0x04) { 0x0005FFFF, 0x02, \_SB.PCI0.LNKD, 0x00 },
+                    Package (0x04) { 0x0005FFFF, 0x03, \_SB.PCI0.LNKA, 0x00 }
+                })
+
+                Method (_PRT, 0, NotSerialized)
+                {
+                    If (LNot (PICF)) { Return (PICM) }
+                    Else { Return (APIC) }
+                }
+            }
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/amd8111_isa.asl b/src/mainboard/amd/serengeti_cheetah/dx/amd8111_isa.asl
new file mode 100644 (file)
index 0000000..b682306
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2005 AMD
+ */
+//AMD8111 isa
+
+            Device (ISA)
+            {
+                /* lpc  0x00040000 */ 
+                Method (_ADR, 0, NotSerialized)
+                {
+                       Return (DADD(\_SB.PCI0.SBDN, 0x00010000))
+                }
+
+                OperationRegion (PIRY, PCI_Config, 0x51, 0x02) // LPC Decode Registers
+                Field (PIRY, ByteAcc, NoLock, Preserve)
+                {
+                    Z000,   2,  // Parallel Port Range
+                        ,   1, 
+                    ECP,    1,  // ECP Enable
+                    FDC1,   1,  // Floppy Drive Controller 1
+                    FDC2,   1,  // Floppy Drive Controller 2
+                    Offset (0x01), 
+                    Z001,   3,  // Serial Port A Range
+                    SAEN,   1,  // Serial Post A Enabled
+                    Z002,   3,  // Serial Port B Range
+                    SBEN,   1  // Serial Post B Enabled
+                }
+
+                Device (PIC)
+                {
+                    Name (_HID, EisaId ("PNP0000"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0020, 0x0020, 0x01, 0x02)
+                        IO (Decode16, 0x00A0, 0x00A0, 0x01, 0x02)
+                        IRQ (Edge, ActiveHigh, Exclusive) {2}
+                    })
+                }
+
+                Device (DMA1)
+                {
+                    Name (_HID, EisaId ("PNP0200"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0000, 0x0000, 0x01, 0x10)
+                        IO (Decode16, 0x0080, 0x0080, 0x01, 0x10)
+                        IO (Decode16, 0x00C0, 0x00C0, 0x01, 0x20)
+                        DMA (Compatibility, NotBusMaster, Transfer16) {4}
+                    })
+                }
+
+                Device (TMR)
+                {
+                    Name (_HID, EisaId ("PNP0100"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0040, 0x0040, 0x01, 0x04)
+                        IRQ (Edge, ActiveHigh, Exclusive) {0}
+                    })
+                }
+
+                Device (RTC)
+                {
+                    Name (_HID, EisaId ("PNP0B00"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0070, 0x0070, 0x01, 0x06)
+                        IRQ (Edge, ActiveHigh, Exclusive) {8}
+                    })
+                }
+
+                Device (SPKR)
+                {
+                    Name (_HID, EisaId ("PNP0800"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0061, 0x0061, 0x01, 0x01)
+                    })
+                }
+
+                Device (COPR)
+                {
+                    Name (_HID, EisaId ("PNP0C04"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x00F0, 0x00F0, 0x01, 0x10)
+                        IRQ (Edge, ActiveHigh, Exclusive) {13}
+                    })
+                }
+
+                Device (SYSR)
+                {
+                    Name (_HID, EisaId ("PNP0C02"))
+                    Name (_UID, 0x00)
+                    Name (SYR1, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x04D0, 0x04D0, 0x01, 0x02) //wrh092302 - added to report Thor NVRAM
+                        IO (Decode16, 0x1100, 0x117F, 0x01, 0x80) //wrh092302 - added to report Thor NVRAM
+                        IO (Decode16, 0x1180, 0x11FF, 0x01, 0x80)
+                        IO (Decode16, 0x0010, 0x0010, 0x01, 0x10)
+                        IO (Decode16, 0x0022, 0x0022, 0x01, 0x1E)
+                        IO (Decode16, 0x0044, 0x0044, 0x01, 0x1C)
+                        IO (Decode16, 0x0062, 0x0062, 0x01, 0x02)
+                        IO (Decode16, 0x0065, 0x0065, 0x01, 0x0B)
+                        IO (Decode16, 0x0076, 0x0076, 0x01, 0x0A)
+                        IO (Decode16, 0x0090, 0x0090, 0x01, 0x10)
+                        IO (Decode16, 0x00A2, 0x00A2, 0x01, 0x1E)
+                        IO (Decode16, 0x00E0, 0x00E0, 0x01, 0x10)
+                        IO (Decode16, 0x0B78, 0x0B78, 0x01, 0x04) // Added this to remove ACPI Unrepoted IO Error 
+                        IO (Decode16, 0x0190, 0x0190, 0x01, 0x04) // Added this to remove ACPI Unrepoted IO Error
+                    })
+                    Method (_CRS, 0, NotSerialized)
+                    {
+                        Return (SYR1)
+                    }
+                }
+
+                Device (MEM)
+                {
+                    Name (_HID, EisaId ("PNP0C02"))
+                    Name (_UID, 0x01)
+                    Method (_CRS, 0, NotSerialized)
+                    {
+                        Name (BUF0, ResourceTemplate ()
+                        {
+                            Memory32Fixed (ReadWrite, 0x000E0000, 0x00020000) // BIOS E4000-FFFFF
+                            Memory32Fixed (ReadWrite, 0x000C0000, 0x00000000) // video BIOS c0000-c8404
+                            Memory32Fixed (ReadWrite, 0xFEC00000, 0x00001000) // I/O APIC
+                            Memory32Fixed (ReadWrite, 0xFFC00000, 0x00380000) // LPC forwarded, 4 MB w/ROM
+                            Memory32Fixed (ReadWrite, 0xFEE00000, 0x00001000) // Local APIC
+                            Memory32Fixed (ReadWrite, 0xFFF80000, 0x00080000) // Overlay BIOS
+                            Memory32Fixed (ReadWrite, 0x00000000, 0x00000000) // Overlay BIOS
+                            Memory32Fixed (ReadWrite, 0x00000000, 0x00000000) // Overlay BIOS
+                            Memory32Fixed (ReadWrite, 0x00000000, 0x00000000) //Overlay BIOS
+                            Memory32Fixed (ReadWrite, 0x00000000, 0x00000000) //Overlay BIOS
+                        })
+                       // Read the Video Memory length 
+                        CreateDWordField (BUF0, 0x14, CLEN)
+                        CreateDWordField (BUF0, 0x10, CBAS)
+
+                        ShiftLeft (VGA1, 0x09, Local0)
+                        Store (Local0, CLEN)
+
+                        Return (BUF0)
+                    }
+                }
+
+                Device (PS2M)
+                {
+                    Name (_HID, EisaId ("PNP0F13"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IRQNoFlags () {12}
+                    })
+                    Method (_STA, 0, NotSerialized)
+                    {
+                        And (FLG0, 0x04, Local0)
+                        If (LEqual (Local0, 0x04)) { Return (0x0F) }
+                        Else { Return (0x00) }
+                    }
+                }
+
+                Device (PS2K)
+                {
+                    Name (_HID, EisaId ("PNP0303"))
+                    Name (_CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0060, 0x0060, 0x01, 0x01)
+                        IO (Decode16, 0x0064, 0x0064, 0x01, 0x01)
+                        IRQNoFlags () {1}
+                    })
+                }
+               Include ("superio.asl")
+
+            }
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/amd8111_pic.asl b/src/mainboard/amd/serengeti_cheetah/dx/amd8111_pic.asl
new file mode 100644 (file)
index 0000000..228f3f8
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2005 AMD
+ */
+//AMD8111 pic LNKA B C D
+
+            Device (LNKA)
+            {
+                Name (_HID, EisaId ("PNP0C0F"))
+                Name (_UID, 0x01)
+                Method (_STA, 0, NotSerialized)
+                {
+                    And (\_SB.PCI0.SBC3.PIBA, 0x0F, Local0)
+                    If (LEqual (Local0, 0x00)) { Return (0x09) } //Disabled
+                    Else { Return (0x0B) } //Enabled
+                }
+
+                Method (_PRS, 0, NotSerialized)
+                {
+                    Name (BUFA, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {3,5,10,11}
+                    })
+                    Return (BUFA)
+                }
+
+                Method (_DIS, 0, NotSerialized)
+                {
+                    Store (0x01, Local3)
+                    And (\_SB.PCI0.SBC3.PIBA, 0x0F, Local1)
+                    Store (Local1, Local2)
+                    If (LGreater (Local1, 0x07))
+                    {
+                        Subtract (Local1, 0x08, Local1)
+                    }
+
+                    ShiftLeft (Local3, Local1, Local3)
+                    Not (Local3, Local3)
+                    And (\_SB.PCI0.SBC3.PIBA, 0xF0, \_SB.PCI0.SBC3.PIBA)
+                }
+
+                Method (_CRS, 0, NotSerialized)
+                {
+                    Name (BUFA, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {}
+                    })
+                    CreateByteField (BUFA, 0x01, IRA1)
+                    CreateByteField (BUFA, 0x02, IRA2)
+                    Store (0x00, Local3)
+                    Store (0x00, Local4)
+                    And (\_SB.PCI0.SBC3.PIBA, 0x0F, Local1)
+                    If (LNot (LEqual (Local1, 0x00)))
+                    {  // Routing enable
+                        If (LGreater (Local1, 0x07))
+                        {
+                            Subtract (Local1, 0x08, Local2)
+                            ShiftLeft (One, Local2, Local4)
+                        }
+                        Else
+                        {
+                            If (LGreater (Local1, 0x00))
+                            {
+                                ShiftLeft (One, Local1, Local3)
+                            }
+                        }
+
+                        Store (Local3, IRA1)
+                        Store (Local4, IRA2)
+                    }
+
+                    Return (BUFA)
+                }
+
+                Method (_SRS, 1, NotSerialized)
+                {
+                    CreateByteField (Arg0, 0x01, IRA1)
+                    CreateByteField (Arg0, 0x02, IRA2)
+                    ShiftLeft (IRA2, 0x08, Local0)
+                    Or (Local0, IRA1, Local0)
+                    Store (0x00, Local1)
+                    ShiftRight (Local0, 0x01, Local0)
+                    While (LGreater (Local0, 0x00))
+                    {
+                        Increment (Local1)
+                        ShiftRight (Local0, 0x01, Local0)
+                    }
+
+                    And (\_SB.PCI0.SBC3.PIBA, 0xF0, \_SB.PCI0.SBC3.PIBA)
+                    Or (\_SB.PCI0.SBC3.PIBA, Local1, \_SB.PCI0.SBC3.PIBA)
+                }
+            }
+
+            Device (LNKB)
+            {
+                Name (_HID, EisaId ("PNP0C0F"))
+                Name (_UID, 0x02)
+                Method (_STA, 0, NotSerialized)
+                {
+                    And (\_SB.PCI0.SBC3.PIBA, 0xF0, Local0)
+                    If (LEqual (Local0, 0x00)) { Return (0x09) }
+                    Else { Return (0x0B) }
+                }
+
+                Method (_PRS, 0, NotSerialized)
+                {
+                    Name (BUFB, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {3,5,10,11}
+                    })
+                    Return (BUFB)
+                }
+
+                Method (_DIS, 0, NotSerialized)
+                {
+                    Store (0x01, Local3)
+                    And (\_SB.PCI0.SBC3.PIBA, 0xF0, Local1)
+                    ShiftRight (Local1, 0x04, Local1)
+                    Store (Local1, Local2)
+                    If (LGreater (Local1, 0x07))
+                    {
+                        Subtract (Local1, 0x08, Local1)
+                    }
+
+                    ShiftLeft (Local3, Local1, Local3)
+                    Not (Local3, Local3)
+                    And (\_SB.PCI0.SBC3.PIBA, 0x0F, \_SB.PCI0.SBC3.PIBA)
+                }
+
+                Method (_CRS, 0, NotSerialized)
+                {
+                    Name (BUFB, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {}
+                    })
+                    CreateByteField (BUFB, 0x01, IRB1)
+                    CreateByteField (BUFB, 0x02, IRB2)
+                    Store (0x00, Local3)
+                    Store (0x00, Local4)
+                    And (\_SB.PCI0.SBC3.PIBA, 0xF0, Local1)
+                    ShiftRight (Local1, 0x04, Local1)
+                    If (LNot (LEqual (Local1, 0x00)))
+                    {
+                        If (LGreater (Local1, 0x07))
+                        {
+                            Subtract (Local1, 0x08, Local2)
+                            ShiftLeft (One, Local2, Local4)
+                        }
+                        Else
+                        {
+                            If (LGreater (Local1, 0x00))
+                            {
+                                ShiftLeft (One, Local1, Local3)
+                            }
+                        }
+
+                        Store (Local3, IRB1)
+                        Store (Local4, IRB2)
+                    }
+
+                    Return (BUFB)
+                }
+
+                Method (_SRS, 1, NotSerialized)
+                {
+                    CreateByteField (Arg0, 0x01, IRB1)
+                    CreateByteField (Arg0, 0x02, IRB2)
+                    ShiftLeft (IRB2, 0x08, Local0)
+                    Or (Local0, IRB1, Local0)
+                    Store (0x00, Local1)
+                    ShiftRight (Local0, 0x01, Local0)
+                    While (LGreater (Local0, 0x00))
+                    {
+                        Increment (Local1)
+                        ShiftRight (Local0, 0x01, Local0)
+                    }
+
+                    And (\_SB.PCI0.SBC3.PIBA, 0x0F, \_SB.PCI0.SBC3.PIBA)
+                    ShiftLeft (Local1, 0x04, Local1)
+                    Or (\_SB.PCI0.SBC3.PIBA, Local1, \_SB.PCI0.SBC3.PIBA)
+                }
+            }
+
+            Device (LNKC)
+            {
+                Name (_HID, EisaId ("PNP0C0F"))
+                Name (_UID, 0x03)
+                Method (_STA, 0, NotSerialized)
+                {
+                    And (\_SB.PCI0.SBC3.PIDC, 0x0F, Local0)
+                    If (LEqual (Local0, 0x00)) { Return (0x09) }
+                    Else { Return (0x0B) }
+                }
+
+                Method (_PRS, 0, NotSerialized)
+                {
+                    Name (BUFA, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {3,5,10,11}
+                    })
+                    Return (BUFA)
+                }
+
+                Method (_DIS, 0, NotSerialized)
+                {
+                    Store (0x01, Local3)
+                    And (\_SB.PCI0.SBC3.PIDC, 0x0F, Local1)
+                    Store (Local1, Local2)
+                    If (LGreater (Local1, 0x07))
+                    {
+                        Subtract (Local1, 0x08, Local1)
+                    }
+
+                    ShiftLeft (Local3, Local1, Local3)
+                    Not (Local3, Local3)
+                    And (\_SB.PCI0.SBC3.PIDC, 0xF0, \_SB.PCI0.SBC3.PIDC)
+                }
+
+                Method (_CRS, 0, NotSerialized)
+                {
+                    Name (BUFA, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {}
+                    })
+                    CreateByteField (BUFA, 0x01, IRA1)
+                    CreateByteField (BUFA, 0x02, IRA2)
+                    Store (0x00, Local3)
+                    Store (0x00, Local4)
+                    And (\_SB.PCI0.SBC3.PIDC, 0x0F, Local1)
+                    If (LNot (LEqual (Local1, 0x00)))
+                    {
+                        If (LGreater (Local1, 0x07))
+                        {
+                            Subtract (Local1, 0x08, Local2)
+                            ShiftLeft (One, Local2, Local4)
+                        }
+                        Else
+                        {
+                            If (LGreater (Local1, 0x00))
+                            {
+                                ShiftLeft (One, Local1, Local3)
+                            }
+                        }
+
+                        Store (Local3, IRA1)
+                        Store (Local4, IRA2)
+                    }
+
+                    Return (BUFA)
+                }
+
+                Method (_SRS, 1, NotSerialized)
+                {
+                    CreateByteField (Arg0, 0x01, IRA1)
+                    CreateByteField (Arg0, 0x02, IRA2)
+                    ShiftLeft (IRA2, 0x08, Local0)
+                    Or (Local0, IRA1, Local0)
+                    Store (0x00, Local1)
+                    ShiftRight (Local0, 0x01, Local0)
+                    While (LGreater (Local0, 0x00))
+                    {
+                        Increment (Local1)
+                        ShiftRight (Local0, 0x01, Local0)
+                    }
+
+                    And (\_SB.PCI0.SBC3.PIDC, 0xF0, \_SB.PCI0.SBC3.PIDC)
+                    Or (\_SB.PCI0.SBC3.PIDC, Local1, \_SB.PCI0.SBC3.PIDC)
+                }
+            }
+
+            Device (LNKD)
+            {
+                Name (_HID, EisaId ("PNP0C0F"))
+                Name (_UID, 0x04)
+                Method (_STA, 0, NotSerialized)
+                {
+                    And (\_SB.PCI0.SBC3.PIDC, 0xF0, Local0)
+                    If (LEqual (Local0, 0x00)) { Return (0x09) }
+                    Else { Return (0x0B) }
+                }
+
+                Method (_PRS, 0, NotSerialized)
+                {
+                    Name (BUFB, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {3,5,10,11}
+                    })
+                    Return (BUFB)
+                }
+
+                Method (_DIS, 0, NotSerialized)
+                {
+                    Store (0x01, Local3)
+                    And (\_SB.PCI0.SBC3.PIDC, 0xF0, Local1)
+                    ShiftRight (Local1, 0x04, Local1)
+                    Store (Local1, Local2)
+                    If (LGreater (Local1, 0x07))
+                    {
+                        Subtract (Local1, 0x08, Local1)
+                    }
+
+                    ShiftLeft (Local3, Local1, Local3)
+                    Not (Local3, Local3)
+                    And (\_SB.PCI0.SBC3.PIDC, 0x0F, \_SB.PCI0.SBC3.PIDC)
+                }
+
+                Method (_CRS, 0, NotSerialized)
+                {
+                    Name (BUFB, ResourceTemplate ()
+                    {
+                        IRQ (Level, ActiveLow, Shared) {}
+                    })
+                    CreateByteField (BUFB, 0x01, IRB1)
+                    CreateByteField (BUFB, 0x02, IRB2)
+                    Store (0x00, Local3)
+                    Store (0x00, Local4)
+                    And (\_SB.PCI0.SBC3.PIDC, 0xF0, Local1)
+                    ShiftRight (Local1, 0x04, Local1)
+                    If (LNot (LEqual (Local1, 0x00)))
+                    {
+                        If (LGreater (Local1, 0x07))
+                        {
+                            Subtract (Local1, 0x08, Local2)
+                            ShiftLeft (One, Local2, Local4)
+                        }
+                        Else
+                        {
+                            If (LGreater (Local1, 0x00))
+                            {
+                                ShiftLeft (One, Local1, Local3)
+                            }
+                        }
+
+                        Store (Local3, IRB1)
+                        Store (Local4, IRB2)
+                    }
+
+                    Return (BUFB)
+                }
+
+                Method (_SRS, 1, NotSerialized)
+                {
+                    CreateByteField (Arg0, 0x01, IRB1)
+                    CreateByteField (Arg0, 0x02, IRB2)
+                    ShiftLeft (IRB2, 0x08, Local0)
+                    Or (Local0, IRB1, Local0)
+                    Store (0x00, Local1)
+                    ShiftRight (Local0, 0x01, Local0)
+                    While (LGreater (Local0, 0x00))
+                    {
+                        Increment (Local1)
+                        ShiftRight (Local0, 0x01, Local0)
+                    }
+
+                    And (\_SB.PCI0.SBC3.PIDC, 0x0F, \_SB.PCI0.SBC3.PIDC)
+                    ShiftLeft (Local1, 0x04, Local1)
+                    Or (\_SB.PCI0.SBC3.PIDC, Local1, \_SB.PCI0.SBC3.PIDC)
+                }
+            }
+
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/amd8131.asl b/src/mainboard/amd/serengeti_cheetah/dx/amd8131.asl
new file mode 100644 (file)
index 0000000..e209665
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2005 AMD
+ */
+               
+            Device (PG0A)
+            {
+                /*  8132 pcix bridge*/
+                Method (_ADR, 0, NotSerialized)
+                {
+                        Return (DADD(GHCD(HCIN, 0), 0x00000000))
+                }
+
+                Method (_PRW, 0, NotSerialized)
+                {
+                    If (CondRefOf (\_S3, Local0)) { Return (Package (0x02) { 0x29, 0x03 }) }
+                    Else { Return (Package (0x02) { 0x29, 0x01 }) }
+                }
+
+                Name (APIC, Package (0x14)
+                {
+                   // Slot A - PIRQ BCDA
+                    Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x19 }, //Slot 2 
+                    Package (0x04) { 0x0001FFFF, 0x01, 0x00, 0x1A }, 
+                    Package (0x04) { 0x0001FFFF, 0x02, 0x00, 0x1B }, 
+                    Package (0x04) { 0x0001FFFF, 0x03, 0x00, 0x18 },
+                   //Cypress Slot A - PIRQ BCDA
+                    Package (0x04) { 0x0003FFFF, 0x00, 0x00, 0x19 }, //?
+                    Package (0x04) { 0x0003FFFF, 0x01, 0x00, 0x1A }, 
+                    Package (0x04) { 0x0003FFFF, 0x02, 0x00, 0x1B }, 
+                    Package (0x04) { 0x0003FFFF, 0x03, 0x00, 0x18 }, 
+
+                   //Cypress Slot B - PIRQ CDAB
+                    Package (0x04) { 0x0004FFFF, 0x00, 0x00, 0x1A }, //?
+                    Package (0x04) { 0x0004FFFF, 0x01, 0x00, 0x1B }, 
+                    Package (0x04) { 0x0004FFFF, 0x02, 0x00, 0x18 }, 
+                    Package (0x04) { 0x0004FFFF, 0x03, 0x00, 0x19 }, 
+
+                   //Cypress Slot C - PIRQ DABC
+                    Package (0x04) { 0x0005FFFF, 0x00, 0x00, 0x1B }, //?
+                    Package (0x04) { 0x0005FFFF, 0x01, 0x00, 0x18 }, 
+                    Package (0x04) { 0x0005FFFF, 0x02, 0x00, 0x19 }, 
+                    Package (0x04) { 0x0005FFFF, 0x03, 0x00, 0x1A }, 
+
+                   //Cypress Slot D - PIRQ ABCD
+                    Package (0x04) { 0x0006FFFF, 0x00, 0x00, 0x18 }, //?
+                    Package (0x04) { 0x0006FFFF, 0x01, 0x00, 0x19 }, 
+                    Package (0x04) { 0x0006FFFF, 0x02, 0x00, 0x1A }, 
+                    Package (0x04) { 0x0006FFFF, 0x03, 0x00, 0x1B }
+                })
+                Name (PICM, Package (0x14)
+                {
+                    Package (0x04) { 0x0001FFFF, 0x00, \_SB.PCI0.LNKB, 0x00 },//Slot 2 
+                    Package (0x04) { 0x0001FFFF, 0x01, \_SB.PCI0.LNKC, 0x00 }, 
+                    Package (0x04) { 0x0001FFFF, 0x02, \_SB.PCI0.LNKD, 0x00 }, 
+                    Package (0x04) { 0x0001FFFF, 0x03, \_SB.PCI0.LNKA, 0x00 }, 
+
+                    Package (0x04) { 0x0003FFFF, 0x00, \_SB.PCI0.LNKB, 0x00 }, 
+                    Package (0x04) { 0x0003FFFF, 0x01, \_SB.PCI0.LNKC, 0x00 }, 
+                    Package (0x04) { 0x0003FFFF, 0x02, \_SB.PCI0.LNKD, 0x00 }, 
+                    Package (0x04) { 0x0003FFFF, 0x03, \_SB.PCI0.LNKA, 0x00 }, 
+
+                    Package (0x04) { 0x0004FFFF, 0x00, \_SB.PCI0.LNKC, 0x00 }, 
+                    Package (0x04) { 0x0004FFFF, 0x01, \_SB.PCI0.LNKD, 0x00 }, 
+                    Package (0x04) { 0x0004FFFF, 0x02, \_SB.PCI0.LNKA, 0x00 }, 
+                    Package (0x04) { 0x0004FFFF, 0x03, \_SB.PCI0.LNKB, 0x00 }, 
+
+                    Package (0x04) { 0x0005FFFF, 0x00, \_SB.PCI0.LNKD, 0x00 }, 
+                    Package (0x04) { 0x0005FFFF, 0x01, \_SB.PCI0.LNKA, 0x00 }, 
+                    Package (0x04) { 0x0005FFFF, 0x02, \_SB.PCI0.LNKB, 0x00 }, 
+                    Package (0x04) { 0x0005FFFF, 0x03, \_SB.PCI0.LNKC, 0x00 }, 
+
+                    Package (0x04) { 0x0006FFFF, 0x00, \_SB.PCI0.LNKA, 0x00 }, 
+                    Package (0x04) { 0x0006FFFF, 0x01, \_SB.PCI0.LNKB, 0x00 }, 
+                    Package (0x04) { 0x0006FFFF, 0x02, \_SB.PCI0.LNKC, 0x00 }, 
+                    Package (0x04) { 0x0006FFFF, 0x03, \_SB.PCI0.LNKD, 0x00 }
+                })
+                Method (_PRT, 0, NotSerialized)
+                {
+                    If (LNot (PICF)) { Return (PICM) }
+                    Else { Return (APIC) }
+                }
+            }
+
+            Device (PG0B)
+            {
+                /* 8132 pcix bridge 2 */
+                Method (_ADR, 0, NotSerialized)
+                {
+                        Return (DADD(GHCD(HCIN, 0), 0x00010000))
+                }
+
+                Method (_PRW, 0, NotSerialized)
+                {
+                    If (CondRefOf (\_S3, Local0)) { Return (Package (0x02) { 0x22, 0x03 }) }
+                    Else { Return (Package (0x02) { 0x22, 0x01 }) }
+                }
+
+                Name (APIC, Package (0x04)
+                {
+                   // Slot A - PIRQ ABCD
+                    Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x1F },// Slot 1
+                    Package (0x04) { 0x0001FFFF, 0x01, 0x00, 0x20 }, 
+                    Package (0x04) { 0x0001FFFF, 0x02, 0x00, 0x21 }, 
+                    Package (0x04) { 0x0001FFFF, 0x03, 0x00, 0x22 }
+                })
+                Name (PICM, Package (0x04)
+                {
+                    Package (0x04) { 0x0001FFFF, 0x00, \_SB.PCI0.LNKA, 0x00 },//Slot 1 
+                    Package (0x04) { 0x0001FFFF, 0x01, \_SB.PCI0.LNKB, 0x00 }, 
+                    Package (0x04) { 0x0001FFFF, 0x02, \_SB.PCI0.LNKC, 0x00 }, 
+                    Package (0x04) { 0x0001FFFF, 0x03, \_SB.PCI0.LNKD, 0x00 }
+                })
+                Method (_PRT, 0, NotSerialized)
+                {
+                    If (LNot (PICF)) { Return (PICM) }
+                    Else { Return (APIC) }
+                }
+            }
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/amd8151.asl b/src/mainboard/amd/serengeti_cheetah/dx/amd8151.asl
new file mode 100644 (file)
index 0000000..001d45b
--- /dev/null
@@ -0,0 +1,29 @@
+// AMD8151 
+            Device (AGPB)
+            {
+                Method (_ADR, 0, NotSerialized)
+                {
+                        Return (DADD(GHCD(HCIN, 0), 0x00010000))
+                }
+
+                Name (APIC, Package (0x04)
+                {
+                    Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x10 }, 
+                    Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x11 }, 
+                    Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x12 }, 
+                    Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x13 }
+                })
+                Name (PICM, Package (0x04)
+                {
+                    Package (0x04) { 0x0000FFFF, 0x00, \_SB.PCI0.LNKA, 0x00 }, 
+                    Package (0x04) { 0x0000FFFF, 0x01, \_SB.PCI0.LNKB, 0x00 }, 
+                    Package (0x04) { 0x0000FFFF, 0x02, \_SB.PCI0.LNKC, 0x00 }, 
+                    Package (0x04) { 0x0000FFFF, 0x03, \_SB.PCI0.LNKD, 0x00 }
+                })
+                Method (_PRT, 0, NotSerialized)
+                {
+                    If (LNot (PICF)) { Return (PICM) }
+                    Else { Return (APIC) }
+                }
+            }
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/amdk8_util.asl b/src/mainboard/amd/serengeti_cheetah/dx/amdk8_util.asl
new file mode 100644 (file)
index 0000000..e915547
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2005 AMD
+ */
+
+//AMD k8 util for BUSB and res range
+
+    Scope (\_SB)
+    {
+
+        Name (OSTB, Ones)
+        Method (OSTP, 0, NotSerialized)
+        {
+            If (LEqual (^OSTB, Ones))
+            {
+                Store (0x00, ^OSTB)
+            }
+
+            Return (^OSTB)
+        }
+
+       Method (SEQL, 2, Serialized)
+        {
+            Store (SizeOf (Arg0), Local0)
+            Store (SizeOf (Arg1), Local1)
+            If (LNot (LEqual (Local0, Local1))) { Return (Zero) }
+
+            Name (BUF0, Buffer (Local0) {})
+            Store (Arg0, BUF0)
+            Name (BUF1, Buffer (Local0) {})
+            Store (Arg1, BUF1)
+            Store (Zero, Local2)
+            While (LLess (Local2, Local0))
+            {
+                Store (DerefOf (Index (BUF0, Local2)), Local3)
+                Store (DerefOf (Index (BUF1, Local2)), Local4)
+                If (LNot (LEqual (Local3, Local4))) { Return (Zero) }
+
+                Increment (Local2)
+            }
+
+            Return (One)
+        }
+
+
+        Method (DADD, 2, NotSerialized)
+        {
+                Store( Arg1, Local0)
+                Store( Arg0, Local1)
+                Add( ShiftLeft(Local1,16), Local0, Local0)
+                Return (Local0)
+        }
+
+
+       Method (GHCE, 1, NotSerialized) // check if the HC enabled
+       {
+                Store (DerefOf (Index (\_SB.PCI0.HCLK, Arg0)), Local1)
+                if(LEqual ( And(Local1, 0x01), 0x01)) { Return (0x0F) }
+                Else { Return (0x00) }
+       }
+
+        Method (GHCN, 1, NotSerialized) // get the node num for the HC
+        {
+                Store (0x00, Local0)
+                Store (DerefOf (Index (\_SB.PCI0.HCLK, Arg0)), Local1)
+               Store (ShiftRight( And (Local1, 0xf0), 0x04), Local0)
+               Return (Local0)
+        }
+
+        Method (GHCL, 1, NotSerialized) // get the link num on node for the HC
+        {
+                Store (0x00, Local0)
+                Store (DerefOf (Index (\_SB.PCI0.HCLK, Arg0)), Local1)
+                Store (ShiftRight( And (Local1, 0xf00), 0x08), Local0)
+                Return (Local0)
+        }
+
+        Method (GHCD, 2, NotSerialized) // get the unit id base for the HT device in HC
+        {
+                Store (0x00, Local0)
+                Store (DerefOf (Index (\_SB.PCI0.HCDN, Arg0)), Local1)
+               Store (Arg1, Local2) // Arg1 could be 3, 2, 1, 0
+               Multiply (Local2, 0x08, Local2) // change to 24, 16, 8, 0
+                Store (And (ShiftRight( Local1, Local2), 0xff), Local0)
+                Return (Local0)
+        }
+
+        Method (GBUS, 2, NotSerialized)
+        {
+            Store (0x00, Local0)
+            While (LLess (Local0, 0x04))
+            {
+                Store (DerefOf (Index (\_SB.PCI0.BUSN, Local0)), Local1)
+                If (LEqual (And (Local1, 0x03), 0x03))
+                {
+                    If (LEqual (Arg0, ShiftRight (And (Local1, 0x70), 0x04)))
+                    {
+                        If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local1, 0x0300), 0x08))))
+                        {
+                            Return (ShiftRight (And (Local1, 0x00FF0000), 0x10))
+                        }
+                    }
+                }
+
+                Increment (Local0)
+            }
+
+            Return (0x00)
+        }
+
+        Method (GWBN, 2, NotSerialized)
+        {
+            Name (BUF0, ResourceTemplate ()
+            {
+                WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+                    0x0000, // Address Space Granularity
+                    0x0000, // Address Range Minimum
+                    0x0000, // Address Range Maximum
+                    0x0000, // Address Translation Offset
+                    0x0000,,,)
+            })
+            CreateWordField (BUF0, 0x08, BMIN)
+            CreateWordField (BUF0, 0x0A, BMAX)
+            CreateWordField (BUF0, 0x0E, BLEN)
+            Store (0x00, Local0)
+            While (LLess (Local0, 0x04))
+            {
+                Store (DerefOf (Index (\_SB.PCI0.BUSN, Local0)), Local1)
+                If (LEqual (And (Local1, 0x03), 0x03))
+                {
+                    If (LEqual (Arg0, ShiftRight (And (Local1, 0x70), 0x04)))
+                    {
+                        If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local1, 0x0300), 0x08))))
+                        {
+                            Store (ShiftRight (And (Local1, 0x00FF0000), 0x10), BMIN)
+                            Store (ShiftRight (Local1, 0x18), BMAX)
+                            Subtract (BMAX, BMIN, BLEN)
+                            Increment (BLEN)
+                            Return (RTAG (BUF0))
+                        }
+                    }
+                }
+
+                Increment (Local0)
+            }
+
+            Return (RTAG (BUF0))
+        }
+
+        Method (GMEM, 2, NotSerialized)
+        {
+            Name (BUF0, ResourceTemplate ()
+            {
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+                    0x00000000, // Address Space Granularity
+                    0x00000000, // Address Range Minimum
+                    0x00000000, // Address Range Maximum
+                    0x00000000, // Address Translation Offset
+                    0x00000000,,,
+                    , AddressRangeMemory, TypeStatic)
+            })
+            CreateDWordField (BUF0, 0x0A, MMIN)
+            CreateDWordField (BUF0, 0x0E, MMAX)
+            CreateDWordField (BUF0, 0x16, MLEN)
+            Store (0x00, Local0)
+            Store (0x00, Local4)
+           Store (0x00, Local3)
+            While (LLess (Local0, 0x10))
+            {
+                Store (DerefOf (Index (\_SB.PCI0.MMIO, Local0)), Local1)
+                Increment (Local0)
+                Store (DerefOf (Index (\_SB.PCI0.MMIO, Local0)), Local2)
+                If (LEqual (And (Local1, 0x03), 0x03))
+                {
+                    If (LEqual (Arg0, And (Local2, 0x07)))
+                    {
+                        If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local2, 0x30), 0x04))))
+                        {
+                            Store (ShiftLeft (And (Local1, 0xFFFFFF00), 0x08), MMIN)
+                            Store (ShiftLeft (And (Local2, 0xFFFFFF00), 0x08), MMAX)
+                            Or (MMAX, 0xFFFF, MMAX)
+                            Subtract (MMAX, MMIN, MLEN)
+
+                            If (Local4)
+                            {
+                                Concatenate (RTAG (BUF0), Local3, Local5)
+                                       Store (Local5, Local3)
+                            }
+                            Else
+                            {
+                                If (LOr (LAnd (LEqual (Arg1, 0xFF), LEqual (Arg0, 0x00)), LEqual (Arg1, \_SB.PCI0.SBLK)))
+                                {
+                                    Store (\_SB.PCI0.TOM1, MMIN)
+                                    Subtract (MMAX, MMIN, MLEN)
+                                    Increment (MLEN)
+                                }
+
+                                Store (RTAG (BUF0), Local3)
+                            }
+
+                            Increment (Local4)
+                        }
+                    }
+                }
+
+                Increment (Local0)
+            }
+
+            If (LNot (Local4))
+            {
+                Store (BUF0, Local3)
+            }
+
+            Return (Local3)
+        }
+
+        Method (GIOR, 2, NotSerialized)
+        {
+            Name (BUF0, ResourceTemplate ()
+            {
+                DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x00000000, // Address Space Granularity
+                    0x00000000, // Address Range Minimum
+                    0x00000000, // Address Range Maximum
+                    0x00000000, // Address Translation Offset
+                    0x00000000,,,
+                    , TypeStatic)
+            })
+            CreateDWordField (BUF0, 0x0A, PMIN)
+            CreateDWordField (BUF0, 0x0E, PMAX)
+            CreateDWordField (BUF0, 0x16, PLEN)
+            Store (0x00, Local0)
+            Store (0x00, Local4)
+           Store (0x00, Local3)
+            While (LLess (Local0, 0x08))
+            {
+                Store (DerefOf (Index (\_SB.PCI0.PCIO, Local0)), Local1)
+                Increment (Local0)
+                Store (DerefOf (Index (\_SB.PCI0.PCIO, Local0)), Local2)
+                If (LEqual (And (Local1, 0x03), 0x03))
+                {
+                    If (LEqual (Arg0, And (Local2, 0x07)))
+                    {
+                        If (LOr (LEqual (Arg1, 0xFF), LEqual (Arg1, ShiftRight (And (Local2, 0x30), 0x04))))
+                        {
+                            Store (And (Local1, 0x01FFF000), PMIN)
+                            Store (And (Local2, 0x01FFF000), PMAX)
+                            Or (PMAX, 0x0FFF, PMAX)
+                            Subtract (PMAX, PMIN, PLEN)
+                            Increment (PLEN)
+
+                            If (Local4)
+                            {
+                                Concatenate (RTAG (BUF0), Local3, Local5)
+                                       Store (Local5, Local3)
+                            }
+                            Else
+                            {
+                                If (LGreater (PMAX, PMIN))
+                                {
+                                    If (LOr (LAnd (LEqual (Arg1, 0xFF), LEqual (Arg0, 0x00)), LEqual (Arg1, \_SB.PCI0.SBLK)))
+                                    {
+                                        Store (0x0D00, PMIN)
+                                        Subtract (PMAX, PMIN, PLEN)
+                                        Increment (PLEN)
+                                    }
+
+                                    Store (RTAG (BUF0), Local3)
+                                    Increment (Local4)
+                                }
+
+                                If (And (Local1, 0x10))
+                                {
+                                    Store (0x03B0, PMIN)
+                                    Store (0x03DF, PMAX)
+                                    Store (0x30, PLEN)
+                                    If (Local4)
+                                    {
+                                        Concatenate (RTAG (BUF0), Local3, Local5)
+                                        Store (Local5, Local3)
+                                    }
+                                    Else
+                                    {
+                                        Store (RTAG (BUF0), Local3)
+                                    }
+                                }
+                            }
+
+                            Increment (Local4)
+                        }
+                    }
+                }
+
+                Increment (Local0)
+            }
+
+            If (LNot (Local4))
+            {
+                Store (RTAG (BUF0), Local3)
+            }
+
+            Return (Local3)
+        }
+
+        Method (RTAG, 1, NotSerialized)
+        {
+            Store (Arg0, Local0)
+            Store (SizeOf (Local0), Local1)
+            Subtract (Local1, 0x02, Local1)
+            Multiply (Local1, 0x08, Local1)
+            CreateField (Local0, 0x00, Local1, RETB)
+            Store (RETB, Local2)
+            Return (Local2)
+        }
+    }
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/dsdt_lb.dsl b/src/mainboard/amd/serengeti_cheetah/dx/dsdt_lb.dsl
new file mode 100644 (file)
index 0000000..04ec830
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2005 AMD
+ */
+DefinitionBlock ("DSDT.aml", "DSDT", 1, "AMD-K8", "AMDACPI", 100925440)
+{
+    Scope (_PR)
+    {
+        Processor (CPU0, 0x00, 0x0000C010, 0x06) {}
+        Processor (CPU1, 0x01, 0x00000000, 0x00) {}
+        Processor (CPU2, 0x02, 0x00000000, 0x00) {}
+        Processor (CPU3, 0x03, 0x00000000, 0x00) {}
+
+    }
+
+    Method (FWSO, 0, NotSerialized) { }
+
+    Name (_S0, Package (0x04) { 0x00, 0x00, 0x00, 0x00 })
+    Name (_S1, Package (0x04) { 0x01, 0x01, 0x01, 0x01 })
+    Name (_S3, Package (0x04) { 0x05, 0x05, 0x05, 0x05 })
+    Name (_S5, Package (0x04) { 0x07, 0x07, 0x07, 0x07 })
+
+    Scope (_SB)
+    {
+        Device (PCI0)
+        {
+           /* BUS0 root bus */
+
+           External (BUSN)
+           External (MMIO)
+           External (PCIO)
+           External (SBLK)
+           External (TOM1)
+           External (HCLK)
+           External (SBDN)
+           External (HCDN)
+           External (CBST)
+
+
+            Name (_HID, EisaId ("PNP0A03"))
+            Name (_ADR, 0x00180000)
+            Name (_UID, 0x01)
+
+            Name (HCIN, 0x00)  // HC1
+
+            Method (_BBN, 0, NotSerialized)
+            {
+                Return (GBUS (GHCN(HCIN), GHCL(HCIN)))
+            }
+
+            Method (_CRS, 0, NotSerialized)
+            {
+                Name (BUF0, ResourceTemplate ()
+                {
+                    IO (Decode16, 0x0CF8, 0x0CF8, 0x01, 0x08) //CF8-CFFh
+                    IO (Decode16, 0xC000, 0xC000, 0x01, 0x80) //8000h
+                    IO (Decode16, 0xC080, 0xC080, 0x01, 0x80) //8080h
+
+                    WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                        0x0000, // Address Space Granularity
+                        0x8100, // Address Range Minimum
+                        0xFFFF, // Address Range Maximum
+                        0x0000, // Address Translation Offset
+                        0x7F00,,,
+                        , TypeStatic)    //8100h-FFFFh
+
+                    DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                        0x00000000, // Address Space Granularity
+                        0x000C0000, // Address Range Minimum
+                        0x00000000, // Address Range Maximum
+                        0x00000000, // Address Translation Offset
+                        0x00000000,,,
+                        , AddressRangeMemory, TypeStatic)   //Video BIOS A0000h-C7FFFh
+
+                    Memory32Fixed (ReadWrite, 0x000D8000, 0x00004000)//USB HC D8000-DBFFF
+
+                    WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                        0x0000, // Address Space Granularity
+                        0x0000, // Address Range Minimum
+                        0x03AF, // Address Range Maximum
+                        0x0000, // Address Translation Offset
+                        0x03B0,,,
+                        , TypeStatic)  //0-CF7h
+
+                    WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                        0x0000, // Address Space Granularity
+                        0x03E0, // Address Range Minimum
+                        0x0CF7, // Address Range Maximum
+                        0x0000, // Address Translation Offset
+                        0x0918,,,
+                        , TypeStatic)  //0-CF7h
+                })
+                \_SB.OSTP ()
+                CreateDWordField (BUF0, 0x3E, VLEN)
+                CreateDWordField (BUF0, 0x36, VMAX)
+                CreateDWordField (BUF0, 0x32, VMIN)
+                ShiftLeft (VGA1, 0x09, Local0)
+                Add (VMIN, Local0, VMAX)
+                Decrement (VMAX)
+                Store (Local0, VLEN)
+                Concatenate (\_SB.GMEM (0x00, \_SB.PCI0.SBLK), BUF0, Local1)
+                Concatenate (\_SB.GIOR (0x00, \_SB.PCI0.SBLK), Local1, Local2)
+                Concatenate (\_SB.GWBN (0x00, \_SB.PCI0.SBLK), Local2, Local3)
+                Return (Local3) 
+           }
+
+           Include ("pci0_hc.asl")
+               
+        }
+        Device (PCI1)
+        {
+            Name (_HID, "PNP0A03")
+            Name (_ADR, 0x00000000)
+            Name (_UID, 0x02)
+            Method (_STA, 0, NotSerialized)
+            {
+                Return (\_SB.PCI0.CBST)
+            }
+           Name (_BBN, 0x00)
+        }
+
+
+    }
+
+    Scope (_GPE)
+    {
+        Method (_L08, 0, NotSerialized)
+        {
+            Notify (\_SB.PCI0, 0x02) //PME# Wakeup
+        }
+
+        Method (_L0F, 0, NotSerialized)
+        {
+            Notify (\_SB.PCI0.TP2P.USB0, 0x02)  //USB Wakeup
+        }
+
+        Method (_L22, 0, NotSerialized) // GPIO18 (LID) - Pogo 0 Bridge B
+        {
+            Notify (\_SB.PCI0.PG0B, 0x02)
+        }
+
+        Method (_L29, 0, NotSerialized) // GPIO25 (Suspend) - Pogo 0 Bridge A 
+        {
+            Notify (\_SB.PCI0.PG0A, 0x02)
+        }
+    }
+
+    Method (_PTS, 1, NotSerialized)
+    {
+        Or (Arg0, 0xF0, Local0)
+        Store (Local0, DBG1)
+    }
+/*
+    Method (_WAK, 1, NotSerialized)
+    {
+        Or (Arg0, 0xE0, Local0)
+        Store (Local0, DBG1)
+    }
+*/
+    Name (PICF, 0x00) //Flag Variable for PIC vs. I/O APIC Mode
+    Method (_PIC, 1, NotSerialized) //PIC Flag and Interface Method
+    {
+        Store (Arg0, PICF)
+    }
+
+    OperationRegion (DEBG, SystemIO, 0x80, 0x01)
+    Field (DEBG, ByteAcc, Lock, Preserve)
+    {
+        DBG1,   8
+    }
+
+    OperationRegion (EXTM, SystemMemory, 0x000FF83C, 0x04)
+    Field (EXTM, WordAcc, Lock, Preserve)
+    {
+        AMEM,   32
+    }
+
+    OperationRegion (VGAM, SystemMemory, 0x000C0002, 0x01)
+    Field (VGAM, ByteAcc, Lock, Preserve)
+    {
+        VGA1,   8
+    }
+
+    OperationRegion (GRAM, SystemMemory, 0x0400, 0x0100)
+    Field (GRAM, ByteAcc, Lock, Preserve)
+    {
+        Offset (0x10), 
+        FLG0,   8
+    }
+
+    OperationRegion (GSTS, SystemIO, 0xC028, 0x02)
+    Field (GSTS, ByteAcc, NoLock, Preserve)
+    {
+            ,   4, 
+        IRQR,   1
+    }
+
+    OperationRegion (Z007, SystemIO, 0x21, 0x01)
+    Field (Z007, ByteAcc, NoLock, Preserve)
+    {
+        Z008,   8
+    }
+
+    OperationRegion (Z009, SystemIO, 0xA1, 0x01)
+    Field (Z009, ByteAcc, NoLock, Preserve)
+    {
+        Z00A,   8
+    }
+
+    Include ("amdk8_util.asl")
+
+}
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/pci0_hc.asl b/src/mainboard/amd/serengeti_cheetah/dx/pci0_hc.asl
new file mode 100644 (file)
index 0000000..b1e9562
--- /dev/null
@@ -0,0 +1,2 @@
+       Include ("amd8111.asl") //real SB at first
+       Include ("amd8131.asl")
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/pci2.asl b/src/mainboard/amd/serengeti_cheetah/dx/pci2.asl
new file mode 100644 (file)
index 0000000..a62ba98
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2005 AMD
+ */
+DefinitionBlock ("SSDT2.aml", "SSDT", 1, "AMD-K8", "AMDACPI", 100925440)
+{
+    Scope (_SB)
+    {
+       External (DADD, MethodObj)
+       External (GHCE, MethodObj)
+       External (GHCN, MethodObj)
+       External (GHCL, MethodObj)
+       External (GHCD, MethodObj)
+       External (GNUS, MethodObj)
+       External (GIOR, MethodObj)
+       External (GMEM, MethodObj)
+       External (GWBN, MethodObj)
+       External (GBUS, MethodObj)
+
+       External (PICF)
+
+       External (\_SB.PCI0.LNKA, DeviceObj)
+       External (\_SB.PCI0.LNKB, DeviceObj)
+       External (\_SB.PCI0.LNKC, DeviceObj)
+       External (\_SB.PCI0.LNKD, DeviceObj)
+
+        Device (PCI2)
+        {
+
+           // BUS ? Second HT Chain
+           Name (HCIN, 0x01)  // HC2
+
+           Name (_HID, "PNP0A03") 
+
+            Method (_ADR, 0, NotSerialized) //Fake bus should be 0
+           {
+               Return (DADD(GHCN(HCIN), 0x00180000))
+           }
+       
+            Name (_UID,  0x03) 
+
+            Method (_BBN, 0, NotSerialized)
+            {
+                Return (GBUS (GHCN(HCIN), GHCL(HCIN)))
+            }
+
+            Method (_STA, 0, NotSerialized)
+            {
+                Return (\_SB.GHCE(HCIN)) 
+            }
+
+            Method (_CRS, 0, NotSerialized)
+            {
+                Name (BUF0, ResourceTemplate () { })
+               Store( GHCN(HCIN), Local4)
+               Store( GHCL(HCIN), Local5)
+
+                Concatenate (\_SB.GIOR (Local4, Local5), BUF0, Local1)
+                Concatenate (\_SB.GMEM (Local4, Local5), Local1, Local2)
+                Concatenate (\_SB.GWBN (Local4, Local5), Local2, Local3)
+                Return (Local3)
+            }
+
+           Include ("pci2_hc.asl")
+        }
+    }
+
+}
+
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/pci2_hc.asl b/src/mainboard/amd/serengeti_cheetah/dx/pci2_hc.asl
new file mode 100644 (file)
index 0000000..045d090
--- /dev/null
@@ -0,0 +1 @@
+       Include ("amd8151.asl")
diff --git a/src/mainboard/amd/serengeti_cheetah/dx/superio.asl b/src/mainboard/amd/serengeti_cheetah/dx/superio.asl
new file mode 100644 (file)
index 0000000..86a10a9
--- /dev/null
@@ -0,0 +1 @@
+//     Include ("w83627hf.asl")
diff --git a/src/mainboard/amd/serengeti_cheetah/fadt.c b/src/mainboard/amd/serengeti_cheetah/fadt.c
new file mode 100644 (file)
index 0000000..3442082
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * ACPI - create the Fixed ACPI Description Tables (FADT)
+ * (C) Copyright 2005 Stefan Reinauer <stepan@openbios.org>
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+
+extern unsigned pm_base; /* pm_base should be set in sb acpi */
+
+void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs,void *dsdt){
+
+       acpi_header_t *header=&(fadt->header);
+
+       printk_debug("pm_base: 0x%04x\n", pm_base);
+
+       /* Prepare the header */
+       memset((void *)fadt,0,sizeof(acpi_fadt_t));
+       memcpy(header->signature,"FACP",4);
+       header->length = 244;
+       header->revision = 1;
+       memcpy(header->oem_id,OEM_ID,6);
+       memcpy(header->oem_table_id,"LXBACPI ",8);
+       memcpy(header->asl_compiler_id,ASLC,4);
+       header->asl_compiler_revision=0;
+
+       fadt->firmware_ctrl=(u32)facs;
+       fadt->dsdt= (u32)dsdt;
+       fadt->res1=0x0;
+       // 3=Workstation,4=Enterprise Server, 7=Performance Server
+       fadt->preferred_pm_profile=0x03;
+       fadt->sci_int=9;
+       // disable system management mode by setting to 0: 
+       fadt->smi_cmd = 0;//pm_base+0x2f;
+       fadt->acpi_enable = 0xf0;
+       fadt->acpi_disable = 0xf1;
+       fadt->s4bios_req = 0x0;
+       fadt->pstate_cnt = 0xe2;
+
+       fadt->pm1a_evt_blk = pm_base;
+       fadt->pm1b_evt_blk = 0x0000;
+       fadt->pm1a_cnt_blk = pm_base+0x04;
+       fadt->pm1b_cnt_blk = 0x0000;
+       fadt->pm2_cnt_blk  = 0x0000;
+       fadt->pm_tmr_blk   = pm_base+0x08;
+       fadt->gpe0_blk     = pm_base+0x20;
+       fadt->gpe1_blk     = pm_base+0xb0;
+
+       fadt->pm1_evt_len  =  4;
+       fadt->pm1_cnt_len  =  2;
+       fadt->pm2_cnt_len  =  0;
+       fadt->pm_tmr_len   =  4;
+       fadt->gpe0_blk_len =  4;
+       fadt->gpe1_blk_len =  8;
+       fadt->gpe1_base    = 16;
+       
+       fadt->cst_cnt    = 0xe3;
+       fadt->p_lvl2_lat =  101;
+       fadt->p_lvl3_lat = 1001;
+       fadt->flush_size = 0;
+       fadt->flush_stride = 0;
+       fadt->duty_offset = 1;
+       fadt->duty_width = 3;
+       fadt->day_alrm = 0; // 0x7d these have to be
+       fadt->mon_alrm = 0; // 0x7e added to cmos.layout
+       fadt->century =  0; // 0x7f to make rtc alrm work
+       fadt->iapc_boot_arch = 0x3; // See table 5-11
+       fadt->flags = 0x25;
+       
+       fadt->res2 = 0;
+
+       fadt->reset_reg.space_id = 1;
+       fadt->reset_reg.bit_width = 8;
+       fadt->reset_reg.bit_offset = 0;
+       fadt->reset_reg.resv = 0;
+       fadt->reset_reg.addrl = 0xcf9;
+       fadt->reset_reg.addrh = 0x0;
+
+       fadt->reset_value = 6;
+       fadt->x_firmware_ctl_l = (u32)facs;
+       fadt->x_firmware_ctl_h = 0;
+       fadt->x_dsdt_l = (u32)dsdt;
+       fadt->x_dsdt_h = 0;
+
+       fadt->x_pm1a_evt_blk.space_id = 1;
+       fadt->x_pm1a_evt_blk.bit_width = 32;
+       fadt->x_pm1a_evt_blk.bit_offset = 0;
+       fadt->x_pm1a_evt_blk.resv = 0;
+       fadt->x_pm1a_evt_blk.addrl = pm_base;
+       fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+       fadt->x_pm1b_evt_blk.space_id = 1;
+       fadt->x_pm1b_evt_blk.bit_width = 4;
+       fadt->x_pm1b_evt_blk.bit_offset = 0;
+       fadt->x_pm1b_evt_blk.resv = 0;
+       fadt->x_pm1b_evt_blk.addrl = 0x0;
+       fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+
+       fadt->x_pm1a_cnt_blk.space_id = 1;
+       fadt->x_pm1a_cnt_blk.bit_width = 16;
+       fadt->x_pm1a_cnt_blk.bit_offset = 0;
+       fadt->x_pm1a_cnt_blk.resv = 0;
+       fadt->x_pm1a_cnt_blk.addrl = pm_base+4;
+       fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+       fadt->x_pm1b_cnt_blk.space_id = 1;
+       fadt->x_pm1b_cnt_blk.bit_width = 2;
+       fadt->x_pm1b_cnt_blk.bit_offset = 0;
+       fadt->x_pm1b_cnt_blk.resv = 0;
+       fadt->x_pm1b_cnt_blk.addrl = 0x0;
+       fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+
+       fadt->x_pm2_cnt_blk.space_id = 1;
+       fadt->x_pm2_cnt_blk.bit_width = 0;
+       fadt->x_pm2_cnt_blk.bit_offset = 0;
+       fadt->x_pm2_cnt_blk.resv = 0;
+       fadt->x_pm2_cnt_blk.addrl = 0x0;
+       fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+
+       fadt->x_pm_tmr_blk.space_id = 1;
+       fadt->x_pm_tmr_blk.bit_width = 32;
+       fadt->x_pm_tmr_blk.bit_offset = 0;
+       fadt->x_pm_tmr_blk.resv = 0;
+       fadt->x_pm_tmr_blk.addrl = pm_base+0x08;
+       fadt->x_pm_tmr_blk.addrh = 0x0;
+
+
+       fadt->x_gpe0_blk.space_id = 1;
+       fadt->x_gpe0_blk.bit_width = 32;
+       fadt->x_gpe0_blk.bit_offset = 0;
+       fadt->x_gpe0_blk.resv = 0;
+       fadt->x_gpe0_blk.addrl = pm_base+0x20;
+       fadt->x_gpe0_blk.addrh = 0x0;
+
+
+       fadt->x_gpe1_blk.space_id = 1;
+       fadt->x_gpe1_blk.bit_width = 64;
+       fadt->x_gpe1_blk.bit_offset = 16;
+       fadt->x_gpe1_blk.resv = 0;
+       fadt->x_gpe1_blk.addrl = pm_base+0xb0;
+       fadt->x_gpe1_blk.addrh = 0x0;
+
+       header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t));
+
+}
diff --git a/src/mainboard/amd/serengeti_cheetah/get_bus_conf.c b/src/mainboard/amd/serengeti_cheetah/get_bus_conf.c
new file mode 100644 (file)
index 0000000..cc4c0e4
--- /dev/null
@@ -0,0 +1,140 @@
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <string.h>
+#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#endif
+
+#include <cpu/amd/amdk8_sysconf.h>
+
+#include "mb_sysconf.h"
+
+// Global variables for MB layouts and these will be shared by irqtable mptable and acpi_tables
+struct mb_sysconf_t mb_sysconf;
+
+static unsigned pci1234x[] = 
+{        //Here you only need to set value in pci1234 for HT-IO that could be installed or not
+        //You may need to preset pci1234 for HTIO board, please refer to src/northbridge/amd/amdk8/get_sblk_pci1234.c for detail
+        0x0000ff0,
+        0x0000ff0,
+//        0x0000ff0,
+//        0x0000ff0,
+//        0x0000ff0,
+//        0x0000ff0,
+//        0x0000ff0,
+//        0x0000ff0
+};
+static unsigned hcdnx[] = 
+{ //HT Chain device num, actually it is unit id base of every ht device in chain, assume every chain only have 4 ht device at most
+       0x20202020,
+       0x20202020,
+//        0x20202020,
+//        0x20202020,
+//        0x20202020,
+//        0x20202020,
+//        0x20202020,
+//        0x20202020,
+};
+
+extern void get_sblk_pci1234(void);
+
+static unsigned get_bus_conf_done = 0;
+
+void get_bus_conf(void)
+{
+
+       unsigned apicid_base;
+
+        device_t dev;
+       int i;
+       struct mb_sysconf_t *m;
+
+       if(get_bus_conf_done == 1) return; //do it only once
+
+       get_bus_conf_done = 1;
+
+       sysconf.mb = &mb_sysconf;
+       
+       m = sysconf.mb;
+
+       sysconf.hc_possible_num = sizeof(pci1234x)/sizeof(pci1234x[0]); 
+       for(i=0;i<sysconf.hc_possible_num; i++) {
+               sysconf.pci1234[i] = pci1234x[i];
+               sysconf.hcdn[i] = hcdnx[i];
+       }
+       
+       get_sblk_pci1234();
+       
+       sysconf.sbdn = (sysconf.hcdn[0] >> 8) & 0xff;
+       m->sbdn3 = sysconf.hcdn[0] & 0xff;
+       m->sbdn5 = sysconf.hcdn[1] & 0xff;
+
+       m->bus_8132_0 = (sysconf.pci1234[0] >> 16) & 0xff;
+       m->bus_8111_0 = m->bus_8132_0;
+
+                /* 8111 */
+        dev = dev_find_slot(m->bus_8111_0, PCI_DEVFN(sysconf.sbdn,0));
+        if (dev) {
+                m->bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if HT_CHAIN_END_UNITID_BASE >= HT_CHAIN_UNITID_BASE
+                m->bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                m->bus_isa++;
+//             printk_debug("bus_isa=%d\n",bus_isa);
+#endif
+        }
+       else {
+                printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", m->bus_8111_0, sysconf.sbdn);
+        }
+
+        /* 8132-1 */
+        dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3,0));
+        if (dev) {
+                m->bus_8132_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+        }
+        else {
+                printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", m->bus_8132_0, m->sbdn3);
+        }
+
+        /* 8132-2 */
+        dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1,0));
+        if (dev) {
+                m->bus_8132_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
+                m->bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                m->bus_isa++;
+//              printk_debug("bus_isa=%d\n",bus_isa);
+#endif
+        }
+        else {
+                printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", m->bus_8132_0, m->sbdn3+1);
+        }
+
+        /* HT chain 1 */
+       if((sysconf.pci1234[1] & 0x1) == 1) {
+               m->bus_8151_0 = (sysconf.pci1234[1] >> 16) & 0xff;
+                /* 8151 */
+               dev = dev_find_slot(m->bus_8151_0, PCI_DEVFN(m->sbdn5+1, 0));
+
+               if (dev) {
+                               m->bus_8151_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+//                        printk_debug("bus_8151_1=%d\n",bus_8151_1);
+                               m->bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                       m->bus_isa++;
+               }
+                       else {
+                       printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", m->bus_8151_0, m->sbdn5+1);
+               }
+        }
+
+/*I/O APICs:   APIC ID Version State           Address*/
+#if CONFIG_LOGICAL_CPUS==1
+       apicid_base = get_apicid_base(3);
+#else 
+       apicid_base = CONFIG_MAX_PHYSICAL_CPUS; 
+#endif
+       m->apicid_8111 = apicid_base+0;
+       m->apicid_8132_1 = apicid_base+1;
+       m->apicid_8132_2 = apicid_base+2;
+}
diff --git a/src/mainboard/amd/serengeti_cheetah/irq_tables.c b/src/mainboard/amd/serengeti_cheetah/irq_tables.c
new file mode 100644 (file)
index 0000000..fb79307
--- /dev/null
@@ -0,0 +1,139 @@
+/* This file was generated by getpir.c, do not modify! 
+   (but if you do, please run checkpir on it to verify)
+   Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
+
+   Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
+*/
+#include <console/console.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+#include <arch/pirq_routing.h>
+#include <cpu/amd/amdk8_sysconf.h>
+
+#include "mb_sysconf.h"
+
+static void write_pirq_info(struct irq_info *pirq_info, uint8_t bus, uint8_t devfn, uint8_t link0, uint16_t bitmap0, 
+               uint8_t link1, uint16_t bitmap1, uint8_t link2, uint16_t bitmap2,uint8_t link3, uint16_t bitmap3,
+               uint8_t slot, uint8_t rfu)
+{
+        pirq_info->bus = bus; 
+        pirq_info->devfn = devfn;
+
+       pirq_info->irq[0].link = link0;
+       pirq_info->irq[0].bitmap = bitmap0;
+       pirq_info->irq[1].link = link1;
+       pirq_info->irq[1].bitmap = bitmap1;
+       pirq_info->irq[2].link = link2;
+       pirq_info->irq[2].bitmap = bitmap2;
+       pirq_info->irq[3].link = link3;
+       pirq_info->irq[3].bitmap = bitmap3;
+
+       pirq_info->slot = slot;
+        pirq_info->rfu = rfu;
+}
+
+
+extern void get_bus_conf(void);
+
+unsigned long write_pirq_routing_table(unsigned long addr)
+{
+
+       struct irq_routing_table *pirq;
+       struct irq_info *pirq_info;
+       unsigned slot_num;
+       uint8_t *v;
+
+        uint8_t sum=0;
+        int i;
+
+       struct mb_sysconf_t *m;
+
+       get_bus_conf(); // it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c
+       
+       m = sysconf.mb;
+
+        /* Align the table to be 16 byte aligned. */
+        addr += 15;
+        addr &= ~15;
+
+        /* This table must be betweeen 0xf0000 & 0x100000 */
+        printk_info("Writing IRQ routing tables to 0x%x...", addr);
+
+       pirq = (void *)(addr);
+       v = (uint8_t *)(addr);
+       
+       pirq->signature = PIRQ_SIGNATURE;
+       pirq->version  = PIRQ_VERSION;
+       
+       pirq->rtr_bus = m->bus_8111_0;
+       pirq->rtr_devfn = ((sysconf.sbdn+1)<<3)|0;
+
+       pirq->exclusive_irqs = 0;
+       
+       pirq->rtr_vendor = 0x1022;
+       pirq->rtr_device = 0x746b;
+
+       pirq->miniport_data = 0;
+
+       memset(pirq->rfu, 0, sizeof(pirq->rfu));
+       
+       pirq_info = (void *) ( &pirq->checksum + 1);
+       slot_num = 0;
+       
+        {
+                device_t dev;
+                dev = dev_find_slot(m->bus_8111_0, PCI_DEVFN(sysconf.sbdn+1,3));
+                if (dev) {
+                        /* initialize PCI interupts - these assignments depend
+                        on the PCB routing of PINTA-D
+
+                        PINTA = IRQ3
+                        PINTB = IRQ5
+                        PINTC = IRQ10
+                        PINTD = IRQ11
+                        */
+                        pci_write_config16(dev, 0x56, 0xba53);
+                }
+        }
+
+//pci bridge
+        printk_debug("setting Onboard AMD Southbridge \n");
+        static const unsigned char slotIrqs_1_4[4] = { 3, 5, 10, 11 };
+        pci_assign_irqs(m->bus_8111_0, sysconf.sbdn+1, slotIrqs_1_4);
+       write_pirq_info(pirq_info, m->bus_8111_0, ((sysconf.sbdn+1)<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
+       pirq_info++; slot_num++;
+
+        printk_debug("setting Onboard AMD USB \n");
+        static const unsigned char slotIrqs_8111_1_0[4] = { 0, 0, 0, 11};
+        pci_assign_irqs(m->bus_8111_1, 0, slotIrqs_8111_1_0);
+        write_pirq_info(pirq_info, m->bus_8111_1,0, 0, 0, 0, 0, 0, 0, 0x4, 0xdef8, 0, 0);
+        pirq_info++; slot_num++;
+
+//pcix bridge
+//        write_pirq_info(pirq_info, m->bus_8132_0, (sbdn3<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
+//        pirq_info++; slot_num++;
+       
+       if(sysconf.pci1234[1] & 0xf) {
+       //agp bridge
+               write_pirq_info(pirq_info, m->bus_8151_0, (m->sbdn5<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0); 
+       }       
+
+        pirq_info++; slot_num++;
+             
+       pirq->size = 32 + 16 * slot_num; 
+
+        for (i = 0; i < pirq->size; i++)
+                sum += v[i];   
+
+       sum = pirq->checksum - sum;
+
+        if (sum != pirq->checksum) {
+                pirq->checksum = sum;
+        }
+
+       printk_info("done.\n");
+
+       return  (unsigned long) pirq_info;
+
+}
diff --git a/src/mainboard/amd/serengeti_cheetah/mainboard.c b/src/mainboard/amd/serengeti_cheetah/mainboard.c
new file mode 100644 (file)
index 0000000..7f59296
--- /dev/null
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "chip.h"
+
+#if CONFIG_CHIP_NAME == 1
+struct chip_operations mainboard_amd_serengeti_cheetah_ops = {
+       CHIP_NAME("AMD serengeti_cheetah mainboard")
+};
+#endif
diff --git a/src/mainboard/amd/serengeti_cheetah/mb_sysconf.h b/src/mainboard/amd/serengeti_cheetah/mb_sysconf.h
new file mode 100644 (file)
index 0000000..7368f05
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef MB_SYSCONF_H
+
+#define MB_SYSCONF_H
+
+struct mb_sysconf_t {
+       unsigned char bus_isa;
+       unsigned char bus_8132_0;
+       unsigned char bus_8132_1;
+       unsigned char bus_8132_2;
+       unsigned char bus_8111_0;
+       unsigned char bus_8111_1;
+       unsigned char bus_8151_0;
+       unsigned char bus_8151_1;
+       unsigned apicid_8111;
+       unsigned apicid_8132_1;
+       unsigned apicid_8132_2;
+
+       unsigned sbdn3;
+       unsigned sbdn5;
+};
+
+#endif
+
diff --git a/src/mainboard/amd/serengeti_cheetah/mptable.c b/src/mainboard/amd/serengeti_cheetah/mptable.c
new file mode 100644 (file)
index 0000000..d27c786
--- /dev/null
@@ -0,0 +1,145 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#endif
+
+#include <cpu/amd/amdk8_sysconf.h>
+#include "mb_sysconf.h"
+
+extern void get_bus_conf(void);
+
+void *smp_write_config_table(void *v)
+{
+        static const char sig[4] = "PCMP";
+        static const char oem[8] = "AMD     ";
+        static const char productid[12] = "SERENGETI   ";
+        struct mp_config_table *mc;
+
+        unsigned char bus_num;
+       int i;
+       struct mb_sysconf_t *m;
+
+        mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+        memset(mc, 0, sizeof(*mc));
+
+        memcpy(mc->mpc_signature, sig, sizeof(sig));
+        mc->mpc_length = sizeof(*mc); /* initially just the header */
+        mc->mpc_spec = 0x04;
+        mc->mpc_checksum = 0; /* not yet computed */
+        memcpy(mc->mpc_oem, oem, sizeof(oem));
+        memcpy(mc->mpc_productid, productid, sizeof(productid));
+        mc->mpc_oemptr = 0;
+        mc->mpc_oemsize = 0;
+        mc->mpc_entry_count = 0; /* No entries yet... */
+        mc->mpc_lapic = LAPIC_ADDR;
+        mc->mpe_length = 0;
+        mc->mpe_checksum = 0;
+        mc->reserved = 0;
+
+        smp_write_processors(mc);
+
+       get_bus_conf();
+
+       m = sysconf.mb;
+
+/*Bus:         Bus ID  Type*/
+       /* define bus and isa numbers */
+        for(bus_num = 0; bus_num < m->bus_isa; bus_num++) {
+                smp_write_bus(mc, bus_num, "PCI   ");
+        }
+        smp_write_bus(mc, m->bus_isa, "ISA   ");
+
+/*I/O APICs:   APIC ID Version State           Address*/
+       smp_write_ioapic(mc, m->apicid_8111, 0x11, 0xfec00000); //8111
+        {
+                device_t dev;
+               struct resource *res;
+                dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3, 1));
+                if (dev) {
+                       res = find_resource(dev, PCI_BASE_ADDRESS_0);
+                       if (res) {
+                               smp_write_ioapic(mc, m->apicid_8132_1, 0x11, res->base);
+                       }
+                }
+                dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1, 1));
+                if (dev) {
+                       res = find_resource(dev, PCI_BASE_ADDRESS_0);
+                       if (res) {
+                               smp_write_ioapic(mc, m->apicid_8132_2, 0x11, res->base);
+                       }
+                }
+       }
+  
+/*I/O Ints:    Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN# */ 
+       smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, m->apicid_8111, 0x0);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x1, m->apicid_8111, 0x1);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x0, m->apicid_8111, 0x2);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x3, m->apicid_8111, 0x3);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x4, m->apicid_8111, 0x4);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x5, m->apicid_8111, 0x5);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x6, m->apicid_8111, 0x6);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x7, m->apicid_8111, 0x7);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x8, m->apicid_8111, 0x8);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0x9, m->apicid_8111, 0x9);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0xc, m->apicid_8111, 0xc);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0xd, m->apicid_8111, 0xd);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0xe, m->apicid_8111, 0xe);
+       smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  m->bus_isa, 0xf, m->apicid_8111, 0xf);
+//??? What
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_0, ((sysconf.sbdn+1)<<2)|3, m->apicid_8111, 0x13);
+
+// Onboard AMD USB
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (0<<2)|3, m->apicid_8111, 0x13);
+
+       if(sysconf.pci1234[1] & 0xf) {
+       //  Slot AGP
+               smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8151_1, 0x0, m->apicid_8111, 0x11);
+       }       
+
+//Slot 3  PCI 32
+        for(i=0;i<4;i++) {
+                smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (5<<2)|i, m->apicid_8111, 0x10 + (1+i)%4); //16
+        }
+
+
+//Slot 4 PCI 32
+        for(i=0;i<4;i++) {
+                smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (4<<2)|i, m->apicid_8111, 0x10 + (0+i)%4); //16
+        }
+
+
+//Slot 1 PCI-X 133/100/66
+        for(i=0;i<4;i++) {
+                smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_2, (1<<2)|i, m->apicid_8132_2, (0+i)%4); //
+        }
+
+
+//Slot 2 PCI-X 133/100/66
+        for(i=0;i<4;i++) {
+                smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (1<<2)|i, m->apicid_8132_1, (1+i)%4); //25
+        }
+
+
+/*Local Ints:  Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN#*/
+       smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x0);
+       smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x1);
+       /* There is no extension information... */
+
+       /* Compute the checksums */
+       mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+       mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+       printk_debug("Wrote the mp table end at: %p - %p\n",
+               mc, smp_next_mpe_entry(mc));
+       return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+       void *v;
+       v = smp_write_floating_table(addr);
+       return (unsigned long)smp_write_config_table(v);
+}
diff --git a/src/mainboard/amd/serengeti_cheetah/readme_acpi.txt b/src/mainboard/amd/serengeti_cheetah/readme_acpi.txt
new file mode 100644 (file)
index 0000000..2fb327d
--- /dev/null
@@ -0,0 +1,30 @@
+At this time, For acpi support We got
+1. support AMK K8 SRAT --- dynamically (LinuxBIOS run-time)  (src/northbridge/amd/amdk8/amdk8_acpi.c)
+2. support MADT ---- dynamically (LinuxBIOS run-time)  (src/northbridge/amd/amdk8/amdk8_acpi.c , src/mainboard/amd/serengeti_cheetah/acpi_tables.c)
+3. support DSDT ---- dynamically (Compile time, LinuxBIOS run-time, ACPI run-time) (src/mainboard/amd/serengeti_cheetah/{dx/*, get_bus_conf.c}, src/northbridge/amd/amdk8/get_sblk_pci1234.c)
+4. Chipset support: amd8111, amd8132
+
+The developers need to change for different MB
+
+Change dx/dsdt_lb.dsl, according to MB layout 
+       pci1, pci2, pci3, pci4, ...., pci8
+       if there is HT-IO board, may use pci2.asl.... to create ssdt2.c, and ssdt3,c and ssdt4.c, ....ssdt8.c
+
+Change acpi_tables.c
+       sbdn: Real SB device Num. for 8111 =3 or 1 depend if 8131 presents.  ---- Actually you don't need to change it, it is LinuxBIOS run-time configurable now.
+       if there is HT-IO board, need to adjust SSDTX_NUM...., and preset pci1234 array. acpi_tables.c will decide to put the SSDT on the RSDT or not according if the HT-IO board is installed
+
+Regarding pci bridge apic and pic
+       need to modify entries amd8111.asl and amd8131.asl and amd8151.asl.... acording to your MB laybout, it is like that in mptable.c
+
+About other chipsets, need to develop their special asl such as 
+       ck804.asl  --- NB ck804
+       bcm5785.asl or bcm5780.asl ---- Serverworks HT1000/HT2000
+
+use a to create hex file
+use c to delele hex file
+
+yhlu
+
+09/18/2005
+       
diff --git a/src/mainboard/amd/serengeti_cheetah/resourcemap.c b/src/mainboard/amd/serengeti_cheetah/resourcemap.c
new file mode 100644 (file)
index 0000000..e42bbcc
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * AMD serengeti_cheetah needs a different resource map
+ *
+ */
+
+static void setup_serengeti_cheetah_resource_map(void)
+{
+       static const unsigned int register_values[] = {
+               /* Careful set limit registers before base registers which contain the enables */
+               /* DRAM Limit i Registers
+                * F1:0x44 i = 0
+                * F1:0x4C i = 1
+                * F1:0x54 i = 2
+                * F1:0x5C i = 3
+                * F1:0x64 i = 4
+                * F1:0x6C i = 5
+                * F1:0x74 i = 6
+                * F1:0x7C i = 7
+                * [ 2: 0] Destination Node ID
+                *         000 = Node 0
+                *         001 = Node 1
+                *         010 = Node 2
+                *         011 = Node 3
+                *         100 = Node 4
+                *         101 = Node 5
+                *         110 = Node 6
+                *         111 = Node 7
+                * [ 7: 3] Reserved
+                * [10: 8] Interleave select
+                *         specifies the values of A[14:12] to use with interleave enable.
+                * [15:11] Reserved
+                * [31:16] DRAM Limit Address i Bits 39-24
+                *         This field defines the upper address bits of a 40 bit  address
+                *         that define the end of the DRAM region.
+                */
+               PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
+               PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
+               PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
+               PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
+               PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
+               PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
+               PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
+               /* DRAM Base i Registers
+                * F1:0x40 i = 0
+                * F1:0x48 i = 1
+                * F1:0x50 i = 2
+                * F1:0x58 i = 3
+                * F1:0x60 i = 4
+                * F1:0x68 i = 5
+                * F1:0x70 i = 6
+                * F1:0x78 i = 7
+                * [ 0: 0] Read Enable
+                *         0 = Reads Disabled
+                *         1 = Reads Enabled
+                * [ 1: 1] Write Enable
+                *         0 = Writes Disabled
+                *         1 = Writes Enabled
+                * [ 7: 2] Reserved
+                * [10: 8] Interleave Enable
+                *         000 = No interleave
+                *         001 = Interleave on A[12] (2 nodes)
+                *         010 = reserved
+                *         011 = Interleave on A[12] and A[14] (4 nodes)
+                *         100 = reserved
+                *         101 = reserved
+                *         110 = reserved
+                *         111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
+                * [15:11] Reserved
+                * [13:16] DRAM Base Address i Bits 39-24
+                *         This field defines the upper address bits of a 40-bit address
+                *         that define the start of the DRAM region.
+                */
+               PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
+
+               /* Memory-Mapped I/O Limit i Registers
+                * F1:0x84 i = 0
+                * F1:0x8C i = 1
+                * F1:0x94 i = 2
+                * F1:0x9C i = 3
+                * F1:0xA4 i = 4
+                * F1:0xAC i = 5
+                * F1:0xB4 i = 6
+                * F1:0xBC i = 7
+                * [ 2: 0] Destination Node ID
+                *         000 = Node 0
+                *         001 = Node 1
+                *         010 = Node 2
+                *         011 = Node 3
+                *         100 = Node 4
+                *         101 = Node 5
+                *         110 = Node 6
+                *         111 = Node 7
+                * [ 3: 3] Reserved
+                * [ 5: 4] Destination Link ID
+                *         00 = Link 0
+                *         01 = Link 1
+                *         10 = Link 2
+                *         11 = Reserved
+                * [ 6: 6] Reserved
+                * [ 7: 7] Non-Posted
+                *         0 = CPU writes may be posted
+                *         1 = CPU writes must be non-posted
+                * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
+                *         This field defines the upp adddress bits of a 40-bit address that
+                *         defines the end of a memory-mapped I/O region n
+                */
+               PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00,
+
+               /* Memory-Mapped I/O Base i Registers
+                * F1:0x80 i = 0
+                * F1:0x88 i = 1
+                * F1:0x90 i = 2
+                * F1:0x98 i = 3
+                * F1:0xA0 i = 4
+                * F1:0xA8 i = 5
+                * F1:0xB0 i = 6
+                * F1:0xB8 i = 7
+                * [ 0: 0] Read Enable
+                *         0 = Reads disabled
+                *         1 = Reads Enabled
+                * [ 1: 1] Write Enable
+                *         0 = Writes disabled
+                *         1 = Writes Enabled
+                * [ 2: 2] Cpu Disable
+                *         0 = Cpu can use this I/O range
+                *         1 = Cpu requests do not use this I/O range
+                * [ 3: 3] Lock
+                *         0 = base/limit registers i are read/write
+                *         1 = base/limit registers i are read-only
+                * [ 7: 4] Reserved
+                * [31: 8] Memory-Mapped I/O Base Address i (39-16)
+                *         This field defines the upper address bits of a 40bit address 
+                *         that defines the start of memory-mapped I/O region i
+                */
+               PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003,
+
+               /* PCI I/O Limit i Registers
+                * F1:0xC4 i = 0
+                * F1:0xCC i = 1
+                * F1:0xD4 i = 2
+                * F1:0xDC i = 3
+                * [ 2: 0] Destination Node ID
+                *         000 = Node 0
+                *         001 = Node 1
+                *         010 = Node 2
+                *         011 = Node 3
+                *         100 = Node 4
+                *         101 = Node 5
+                *         110 = Node 6
+                *         111 = Node 7
+                * [ 3: 3] Reserved
+                * [ 5: 4] Destination Link ID
+                *         00 = Link 0
+                *         01 = Link 1
+                *         10 = Link 2
+                *         11 = reserved
+                * [11: 6] Reserved
+                * [24:12] PCI I/O Limit Address i
+                *         This field defines the end of PCI I/O region n
+                * [31:25] Reserved
+                */
+               PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff000,
+               PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
+
+               /* PCI I/O Base i Registers
+                * F1:0xC0 i = 0
+                * F1:0xC8 i = 1
+                * F1:0xD0 i = 2
+                * F1:0xD8 i = 3
+                * [ 0: 0] Read Enable
+                *         0 = Reads Disabled
+                *         1 = Reads Enabled
+                * [ 1: 1] Write Enable
+                *         0 = Writes Disabled
+                *         1 = Writes Enabled
+                * [ 3: 2] Reserved
+                * [ 4: 4] VGA Enable
+                *         0 = VGA matches Disabled
+                *         1 = matches all address < 64K and where A[9:0] is in the 
+                *             range 3B0-3BB or 3C0-3DF independen of the base & limit registers
+                * [ 5: 5] ISA Enable
+                *         0 = ISA matches Disabled
+                *         1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
+                *             from matching agains this base/limit pair
+                * [11: 6] Reserved
+                * [24:12] PCI I/O Base i
+                *         This field defines the start of PCI I/O region n 
+                * [31:25] Reserved
+                */
+               PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000003,
+               PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
+
+               /* Config Base and Limit i Registers
+                * F1:0xE0 i = 0
+                * F1:0xE4 i = 1
+                * F1:0xE8 i = 2
+                * F1:0xEC i = 3
+                * [ 0: 0] Read Enable
+                *         0 = Reads Disabled
+                *         1 = Reads Enabled
+                * [ 1: 1] Write Enable
+                *         0 = Writes Disabled
+                *         1 = Writes Enabled
+                * [ 2: 2] Device Number Compare Enable
+                *         0 = The ranges are based on bus number
+                *         1 = The ranges are ranges of devices on bus 0
+                * [ 3: 3] Reserved
+                * [ 6: 4] Destination Node
+                *         000 = Node 0
+                *         001 = Node 1
+                *         010 = Node 2
+                *         011 = Node 3
+                *         100 = Node 4
+                *         101 = Node 5
+                *         110 = Node 6
+                *         111 = Node 7
+                * [ 7: 7] Reserved
+                * [ 9: 8] Destination Link
+                *         00 = Link 0
+                *         01 = Link 1
+                *         10 = Link 2
+                *         11 - Reserved
+                * [15:10] Reserved
+                * [23:16] Bus Number Base i
+                *         This field defines the lowest bus number in configuration region i
+                * [31:24] Bus Number Limit i
+                *         This field defines the highest bus number in configuration regin i
+                */
+               PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x06000003, // AMD 8111 on link0 of CPU 0
+               PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x08070013, // AMD 8151 on link0 of CPU 1
+               PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
+               PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
+       };
+
+       int max;
+       max = sizeof(register_values)/sizeof(register_values[0]);
+       setup_resource_map(register_values, max);
+}
+
index ea92f8e201814f7200ed6404f04807e9e82d1401..3132377563fe925794b39b8973f4e51c3acb9838 100644 (file)
@@ -56,14 +56,14 @@ end
 #if HAVE_ACPI_TABLES
 #      object acpi_tables.o
 #      object fadt.o
-#      if K8_SB_HT_CHAIN_ON_BUS0
+#      if SB_HT_CHAIN_ON_BUS0
 #              object dsdt_bus0.o
 #      else
 #              object dsdt.o
 #      end
 #      object ssdt.o
 #      if ACPI_SSDTX_NUM
-#                if K8_SB_HT_CHAIN_ON_BUS0
+#                if SB_HT_CHAIN_ON_BUS0
 #                 object ssdt2_bus0.o
 #                else
 #                 object ssdt2.o
@@ -74,7 +74,7 @@ end
 if HAVE_ACPI_TABLES
         object acpi_tables.o
         object fadt.o
-        if K8_SB_HT_CHAIN_ON_BUS0
+        if SB_HT_CHAIN_ON_BUS0
                 makerule dsdt.c
                         depends "$(MAINBOARD)/dx_bus0/dsdt_lb.dsl"
                         action  "/usr/sbin/iasl -tc $(MAINBOARD)/dx_bus0/dsdt_lb.dsl"
@@ -98,7 +98,7 @@ if HAVE_ACPI_TABLES
         object ./ssdt.o
 
         if ACPI_SSDTX_NUM
-            if K8_SB_HT_CHAIN_ON_BUS0
+            if SB_HT_CHAIN_ON_BUS0
                 makerule ssdt2.c
                         depends "$(MAINBOARD)/dx/pci2.asl"
                         action  "/usr/sbin/iasl -tc $(MAINBOARD)/dx/pci2.asl"
index 4164454c8ff92159a89daff8447f68940e4efa4b..46ea2c2a55953842cd75e5bd7d578e91559b5948 100644 (file)
@@ -54,13 +54,13 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
-uses K8_HW_MEM_HOLE_SIZE_AUTO_INC
+uses HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZE_AUTO_INC
 uses K8_HT_FREQ_1G_SUPPORT
 
 uses HT_CHAIN_UNITID_BASE
 uses HT_CHAIN_END_UNITID_BASE
-uses K8_SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_ON_BUS0
 uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
 
 uses USE_DCACHE_RAM
@@ -152,14 +152,14 @@ default CONFIG_CHIP_NAME=1
 
 #memory hole size, 0 mean disable, others will enable the hole, at that case if it is small than mmio_basek, it will use mmio_basek instead. 
 #2G
-default K8_HW_MEM_HOLE_SIZEK=0x200000
+default HW_MEM_HOLE_SIZEK=0x200000
 #1G
-#default K8_HW_MEM_HOLE_SIZEK=0x100000
+#default HW_MEM_HOLE_SIZEK=0x100000
 #512M
-#default K8_HW_MEM_HOLE_SIZEK=0x80000
+#default HW_MEM_HOLE_SIZEK=0x80000
 
 #make auto increase hole size to avoid hole_startk equal to basek so as to make some kernel happy
-#default K8_HW_MEM_HOLE_SIZE_AUTO_INC=1
+#default HW_MEM_HOLE_SIZE_AUTO_INC=1
 
 #Opteron K8 1G HT Support
 default K8_HT_FREQ_1G_SUPPORT=1
@@ -175,7 +175,7 @@ default HT_CHAIN_UNITID_BASE=0x4
 default HT_CHAIN_END_UNITID_BASE=0x1
 
 #make the SB HT chain on bus 0
-default K8_SB_HT_CHAIN_ON_BUS0=1
+default SB_HT_CHAIN_ON_BUS0=1
 
 #allow capable device use that above 4G
 #default CONFIG_PCI_64BIT_PREF_MEM=1
@@ -186,7 +186,7 @@ default K8_SB_HT_CHAIN_ON_BUS0=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcc000
 default DCACHE_RAM_SIZE=0x4000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index f01a824cbf137b08ca2801503739eb387c1fbefa..bb42c0faee3b689834d325883ac2b5b263f7625f 100644 (file)
@@ -12,7 +12,6 @@
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
 #include <cpu/amd/model_fxx_rev.h>
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -22,7 +21,6 @@
 #include "superio/NSC/pc87360/pc87360_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
 
@@ -141,7 +139,9 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 
 #include "northbridge/amd/amdk8/raminit.c"
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
+#include "cpu/amd/dualcore/dualcore.c"
 #include "northbridge/amd/amdk8/resourcemap.c"
 #include "debug.c"
 
index 02bb6eb035a9c5eaee9664bffc9ba5dda0a1fab7..c64c7cf04833b34b8a971351c2d873f03f983354 100644 (file)
@@ -53,10 +53,10 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 uses HT_CHAIN_UNITID_BASE
 uses HT_CHAIN_END_UNITID_BASE
-uses K8_SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_ON_BUS0
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -128,7 +128,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 #default CONFIG_CONSOLE_VGA=1
@@ -141,7 +141,7 @@ default HT_CHAIN_UNITID_BASE=0x6
 default HT_CHAIN_END_UNITID_BASE=0x1
 
 #make the SB HT chain on bus 0
-default K8_SB_HT_CHAIN_ON_BUS0=1
+default SB_HT_CHAIN_ON_BUS0=1
 
 ##
 ## enable CACHE_AS_RAM specifics
index ff3d9ac45d607c84a686e8f0e1034f81bba83eed..be0076847b114cffe22ea0bcd2fada36d22aec8a 100644 (file)
@@ -13,7 +13,6 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -25,7 +24,6 @@
 #include "superio/NSC/pc87366/pc87366_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, PC87366_SP1)
 
@@ -125,8 +123,10 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 #include "northbridge/amd/amdk8/raminit.c"
 
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "mainboard/ibm/e325/resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
index 203a4571fe900bfda538c18073ffcb34e09dfe35..958c7d8ab8cda660ff66400a3fb1562c264cb6ce 100644 (file)
@@ -13,7 +13,6 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
 #include "cpu/amd/model_fxx/apic_timer.c"
@@ -25,7 +24,6 @@
 #include "superio/NSC/pc87366/pc87366_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, PC87366_SP1)
 
@@ -125,8 +123,10 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 #include "northbridge/amd/amdk8/raminit.c"
 
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "mainboard/ibm/e326/resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
index 5f4687c76ea6ed9900759bb9dd49d8ff10142a8f..24c6e3d3b278a11d01ead29291c8c2c13f467b3e 100644 (file)
 #include "cpu/x86/lapic/boot_cpu.c"
 #include "northbridge/amd/amdk8/reset_test.c"
 #include "northbridge/amd/amdk8/debug.c"
-#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include <cpu/amd/model_fxx_rev.h>
 #include "superio/NSC/pc87360/pc87360_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
-#include "cpu/amd/dualcore/dualcore.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
 
@@ -80,11 +78,13 @@ static inline int spd_read_byte(unsigned device, unsigned address)
 #include "northbridge/amd/amdk8/raminit.c"
 
 #include "northbridge/amd/amdk8/coherent_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 
 #include "sdram/generic_sdram.c"
 
 /* newisys khepri does not want the default */
 #include "resourcemap.c"
+#include "cpu/amd/dualcore/dualcore.c"
 
 #define NODE_RAM(x)                     \
        .node_id = 0+x,                 \
index 32748f5f1d9fd5af47e8a2deb762f50720e2f0e3..a81745390da8a48462a0967e1e3ff03fe28b40ce 100644 (file)
@@ -52,7 +52,7 @@ uses CONFIG_GDB_STUB
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 uses K8_HT_FREQ_1G_SUPPORT
 
 uses USE_DCACHE_RAM
@@ -66,7 +66,7 @@ uses LIFT_BSP_APIC_ID
 
 uses HT_CHAIN_UNITID_BASE
 uses HT_CHAIN_END_UNITID_BASE
-uses K8_SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_ON_BUS0
 uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
 
 ## ROM_SIZE is the size of boot ROM that this board will use.
@@ -134,7 +134,7 @@ default CONFIG_LOGICAL_CPUS=1
 #default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #Opteron K8 1G HT Support
 default K8_HT_FREQ_1G_SUPPORT=1
@@ -146,7 +146,7 @@ default HT_CHAIN_UNITID_BASE=0x0
 #default HT_CHAIN_END_UNITID_BASE=0x0
 
 #make the SB HT chain on bus 0, default is not (0)
-default K8_SB_HT_CHAIN_ON_BUS0=2
+default SB_HT_CHAIN_ON_BUS0=2
 
 ##only offset for SB chain?, default is yes(1)
 default SB_HT_CHAIN_UNITID_OFFSET_ONLY=0
index d6db7c1c74f0e4e465f42a9a23aa349fc069770b..ca1aa186c709d9fdd2fecf829b4e476dd0c547d3 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -122,7 +122,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 default CONFIG_CONSOLE_VGA=1
@@ -135,7 +135,7 @@ default CONFIG_PCI_ROM_RUN=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index 99a018c4e92f78d7b833accd0c2be1df0c1d504f..092aefb98c5acd59d8d805eaa3b9a4153c67614d 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -123,7 +123,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 default CONFIG_CONSOLE_VGA=1
@@ -136,7 +136,7 @@ default CONFIG_PCI_ROM_RUN=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index 23b239afb42d6327fa9d24bd312a331616d12f3a..bcb7a1e4c23703947fa75f0aef606f9851539246 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -122,7 +122,7 @@ default CONFIG_LOGICAL_CPUS=0
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 default CONFIG_CONSOLE_VGA=1
@@ -135,7 +135,7 @@ default CONFIG_PCI_ROM_RUN=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index bb92ecfd30b1dc1801bf0d07b26873d24b6269bd..b1e5022c3108afc0cf9596a2ce4f2f93fa78b7b2 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -122,7 +122,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 #default CONFIG_CONSOLE_VGA=1
@@ -135,7 +135,7 @@ default K8_HW_MEM_HOLE_SIZEK=0x100000
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index 5dec67a94707fcd6db2253c7256776e18800d638..da382282c99bcf1f8a741743cf78244c25f947f7 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -122,7 +122,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 default CONFIG_CONSOLE_VGA=1
@@ -135,7 +135,7 @@ default CONFIG_PCI_ROM_RUN=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 ##
 ## Build code to setup a generic IOAPIC
index dcff37450fcf176d416a71c4d97b053efc20cbed..5ca7df6a344617fe445f167841e87f9a72d07ee9 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -126,7 +126,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 default CONFIG_CONSOLE_VGA=1
@@ -139,7 +139,7 @@ default CONFIG_PCI_ROM_RUN=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 default ENABLE_APIC_EXT_ID=1
 default APIC_ID_OFFSET=0x10
index 901836466363a176b9db47fd5d01e516248d5f02..366b745151e52464b353a9a31c965738897cbd82 100644 (file)
@@ -53,7 +53,7 @@ uses CONFIG_GDB_STUB
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 uses K8_HT_FREQ_1G_SUPPORT
 
 uses USE_DCACHE_RAM
@@ -69,7 +69,7 @@ uses CONFIG_PCI_64BIT_PREF_MEM
 
 uses HT_CHAIN_UNITID_BASE
 uses HT_CHAIN_END_UNITID_BASE
-uses K8_SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_ON_BUS0
 uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
 
 uses CONFIG_LB_MEM_TOPK
@@ -137,7 +137,7 @@ default CONFIG_MAX_PHYSICAL_CPUS=2
 default CONFIG_LOGICAL_CPUS=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #Opteron K8 1G HT Support
 default K8_HT_FREQ_1G_SUPPORT=1
@@ -149,7 +149,7 @@ default HT_CHAIN_UNITID_BASE=0x0
 #default HT_CHAIN_END_UNITID_BASE=0x0
 
 #make the SB HT chain on bus 0, default is not (0)
-default K8_SB_HT_CHAIN_ON_BUS0=2
+default SB_HT_CHAIN_ON_BUS0=2
 
 ##only offset for SB chain?, default is yes(1)
 default SB_HT_CHAIN_UNITID_OFFSET_ONLY=0
index 7000126a5de7ba7356f2ad1dd2b629b3dfba32b0..30e6d617c21685271fee1f53b96db12c5233cfa2 100644 (file)
@@ -53,7 +53,7 @@ uses CONFIG_GDB_STUB
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 uses K8_HT_FREQ_1G_SUPPORT
 
 uses USE_DCACHE_RAM
@@ -63,7 +63,7 @@ uses CONFIG_USE_INIT
 
 uses HT_CHAIN_UNITID_BASE
 uses HT_CHAIN_END_UNITID_BASE
-uses K8_SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_ON_BUS0
 uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
 
 ## ROM_SIZE is the size of boot ROM that this board will use.
@@ -129,7 +129,7 @@ default CONFIG_MAX_PHYSICAL_CPUS=2
 default CONFIG_LOGICAL_CPUS=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #Opteron K8 1G HT Support
 default K8_HT_FREQ_1G_SUPPORT=1
@@ -141,7 +141,7 @@ default HT_CHAIN_UNITID_BASE=0x0
 #default HT_CHAIN_END_UNITID_BASE=0x0
 
 #make the SB HT chain on bus 0, default is not (0)
-default K8_SB_HT_CHAIN_ON_BUS0=2
+default SB_HT_CHAIN_ON_BUS0=2
 
 ##only offset for SB chain?, default is yes(1)
 default SB_HT_CHAIN_UNITID_OFFSET_ONLY=0
index c3f8ba3f8c170cd0f4b650f5b4d1661b22e9dc73..cd367ad029e21948960f2748894d134b3007926c 100644 (file)
@@ -52,7 +52,7 @@ uses CONFIG_GDB_STUB
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 uses K8_HT_FREQ_1G_SUPPORT
 
 uses USE_DCACHE_RAM
@@ -66,7 +66,7 @@ uses LIFT_BSP_APIC_ID
 
 uses HT_CHAIN_UNITID_BASE
 uses HT_CHAIN_END_UNITID_BASE
-uses K8_SB_HT_CHAIN_ON_BUS0
+uses SB_HT_CHAIN_ON_BUS0
 uses SB_HT_CHAIN_UNITID_OFFSET_ONLY
 
 ## ROM_SIZE is the size of boot ROM that this board will use.
@@ -134,7 +134,7 @@ default CONFIG_LOGICAL_CPUS=1
 #default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #Opteron K8 1G HT Support
 default K8_HT_FREQ_1G_SUPPORT=1
@@ -146,7 +146,7 @@ default HT_CHAIN_UNITID_BASE=0x0
 #default HT_CHAIN_END_UNITID_BASE=0x0
 
 #make the SB HT chain on bus 0, default is not (0)
-default K8_SB_HT_CHAIN_ON_BUS0=2
+default SB_HT_CHAIN_ON_BUS0=2
 
 ##only offset for SB chain?, default is yes(1)
 default SB_HT_CHAIN_UNITID_OFFSET_ONLY=0
index 9cc8fc84f89347706c3ee9160a499b3f93de70ed..9e74b1121462228dc13d91f2b4fd6eb28dac86e7 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -126,7 +126,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 default CONFIG_CONSOLE_VGA=1
@@ -139,7 +139,7 @@ default CONFIG_PCI_ROM_RUN=1
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 default ENABLE_APIC_EXT_ID=1
 default APIC_ID_OFFSET=0x10
index 57e10153a11cfcc6ec5a7ba534784829a729608d..cd31cfed6b222f14dfcd71a0a31c619dcfd30d97 100644 (file)
@@ -52,7 +52,7 @@ uses OBJCOPY
 uses CONFIG_CHIP_NAME
 uses CONFIG_CONSOLE_VGA
 uses CONFIG_PCI_ROM_RUN
-uses K8_HW_MEM_HOLE_SIZEK
+uses HW_MEM_HOLE_SIZEK
 
 uses USE_DCACHE_RAM
 uses DCACHE_RAM_BASE
@@ -126,7 +126,7 @@ default CONFIG_LOGICAL_CPUS=1
 default CONFIG_CHIP_NAME=1
 
 #1G memory hole
-default K8_HW_MEM_HOLE_SIZEK=0x100000
+default HW_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
 #default CONFIG_CONSOLE_VGA=1
@@ -139,7 +139,7 @@ default K8_HW_MEM_HOLE_SIZEK=0x100000
 default USE_DCACHE_RAM=1
 default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
-default CONFIG_USE_INIT=1
+default CONFIG_USE_INIT=0
 
 default ENABLE_APIC_EXT_ID=1
 default APIC_ID_OFFSET=0x10
index 23245a66b99c6834a2aff18c9efe01209cf86221..bc6054f75d03912076bc824333dc0b12de9f043b 100644 (file)
@@ -19,6 +19,14 @@ end
 
 if HAVE_ACPI_TABLES
        object amdk8_acpi.o
+        makerule ssdt.c
+                depends "$(TOP)/src/northbridge/amd/amdk8/ssdt.dsl"
+                action  "/usr/sbin/iasl -tc $(TOP)/src/northbridge/amd/amdk8/ssdt.dsl"
+                action  "perl -pi -e 's/AmlCode/AmlCode_ssdt/g' ssdt.hex"
+                action  "mv ssdt.hex ssdt.c"
+        end
+        object ./ssdt.o
 end
 
+
 object get_sblk_pci1234.o
index 7e064af974f86f3f1414b013b6f316b434989243..56b92a2349aab6dd1aadb760333b4cdaf045d286 100644 (file)
@@ -2,6 +2,10 @@
 
 #define AMDK8_H
 
+#if K8_REV_F_SUPPORT == 1
+        #include "amdk8_f.h"
+
+#else
 /* Definitions of various K8 registers */
 /* Function 0 */
 #define HT_TRANSACTION_CONTROL 0x68
@@ -55,6 +59,7 @@
 #define DRAM_CSBASE       0x40
 #define DRAM_CSMASK       0x60
 #define DRAM_BANK_ADDR_MAP 0x80
+
 #define DRAM_TIMING_LOW           0x88
 #define         DTL_TCL_SHIFT     0
 #define         DTL_TCL_MASK      0x7
 #define          DTL_TWR_BASE     2
 #define          DTL_TWR_MIN      2
 #define          DTL_TWR_MAX      3
+
 #define DRAM_TIMING_HIGH   0x8c
 #define         DTH_TWTR_SHIFT    0
 #define         DTH_TWTR_MASK     0x1
 #define          DTH_TWCL_BASE     1
 #define          DTH_TWCL_MIN      1
 #define          DTH_TWCL_MAX      2
+
 #define DRAM_CONFIG_LOW           0x90
 #define         DCL_DLL_Disable   (1<<0)
 #define         DCL_D_DRV         (1<<1)
 #define         DCL_DisInRcvrs    (1<<24)
 #define         DCL_BypMax_SHIFT  25
 #define         DCL_En2T          (1<<28)
-#define         DCL_UpperCSMap    (1<<29)
+
 #define DRAM_CONFIG_HIGH   0x94
 #define         DCH_ASYNC_LAT_SHIFT  0
 #define         DCH_ASYNC_LAT_MASK   0xf
 #define ConnectionPending (1 << 4)
 
 #endif
+
+#endif /* AMDK8_H */
index 71bcdbbd1a1eda6b3ea7a4cdefd6c7dff2ba63a1..35945b341e1954bfa9f50b7005d0e93ea3631f3c 100644 (file)
@@ -43,6 +43,7 @@ acknowledgement of AMD's proprietary rights in them.
 #include <device/pci.h>
 #include <cpu/x86/msr.h>
 #include <cpu/amd/mtrr.h>
+#include <cpu/amd/amdk8_sysconf.h>
 
 //it seems these function can be moved arch/i386/boot/acpi.c
 
@@ -112,6 +113,8 @@ unsigned long acpi_create_srat_lapics(unsigned long current)
         return current;
 }
 
+
+
 static unsigned long resk(uint64_t value)
 {
         unsigned long resultk;
@@ -153,7 +156,6 @@ void set_srat_mem(void *gp, struct device *dev, struct resource *res)
         state->current += acpi_create_srat_mem((acpi_srat_mem_t *)state->current, (res->index & 0xf), basek, sizek, 1); // need to figure out NV
 }
 
-
 unsigned long acpi_fill_srat(unsigned long current)
 {
         struct acpi_srat_mem_state srat_mem_state;
@@ -175,5 +177,157 @@ unsigned long acpi_fill_srat(unsigned long current)
 #endif
         return current;
 }
+
+
+unsigned long acpi_fill_slit(unsigned long current)
+{
+       /* need to find out the node num at first */
+       /* fill the first 8 byte with that num */
+       /* fill the next num*num byte with distance, local is 10, 1 hop mean 20, and 2 hop with 30.... */
+       
+       /* because We has assume that we know the topology of the HT connection, So we can have set if we know the node_num */
+       static uint8_t hops_8[] = {   0, 1, 1, 2, 2, 3, 3, 4,
+                                     1, 0, 2, 1, 3, 2, 4, 3,
+                                     1, 2, 0, 1, 1, 2, 2, 3,
+                                     2, 1, 1, 0, 2, 1, 3, 2,
+                                     2, 3, 1, 2, 0, 1, 1, 2,
+                                     3, 2, 2, 1, 1, 0, 2, 1,
+                                     3, 4, 2, 3, 1, 2, 0, 1,    
+                                     4, 4, 3, 2, 2, 1, 1, 0 };
+
+//     uint8_t outer_node[8];
+
+       uint8_t *p = (uint8_t *)current;
+       int nodes = sysconf.nodes;
+       int i,j;
+       memset(p, 0, 8+nodes*nodes);
+//     memset((uint8_t *)outer_node, 0, 8);
+       *p = (uint8_t) nodes;
+       p += 8;
+
+#if 0
+       for(i=0;i<sysconf.hc_possible_num;i++) {
+               if((sysconf.pci1234[i]&1) !=1 ) continue;
+               outer_node[(sysconf.pci1234[i] >> 4) & 0xf] = 1; // mark the outer node         
+       }
+#endif
+       
+       for(i=0;i<nodes;i++) {
+               for(j=0;j<nodes; j++) {
+                       if(i==j) { p[i*nodes+j] = 10; }
+                       else {
+#if 0
+                               int k;
+                               uint8_t latency_factor = 0;
+                               int k_start, k_end;
+                               if(i<j) {
+                                       k_start = i;
+                                       k_end = j;
+                               } else {
+                                       k_start = j;
+                                       k_end = i;
+                               }
+                               for(k=k_start;k<=k_end; k++) {
+                                       if(outer_node[k]) {
+                                               latency_factor = 1;
+                                               break;
+                                       }
+                               }
+                               p[i*nodes+j] = hops_8[i*nodes+j] * 2 + latency_factor + 10;
+#else  
+                               p[i*nodes+j] = hops_8[i*nodes+j] * 2 + 10;
+#endif
+
+
+                       }
+               }
+       }
+
+        current += 8+nodes*nodes;
+
+        return current;
+}
+
+
 //end
 
+
+// moved from mb acpi_tables.c
+static void int_to_stream(uint32_t val, uint8_t *dest)
+{
+        int i;
+        for(i=0;i<4;i++) {
+                *(dest+i) = (val >> (8*i)) & 0xff;
+        }
+}
+
+
+// used by acpi_tables.h
+
+void update_ssdt(void *ssdt)
+{
+        uint8_t *BUSN;
+        uint8_t *MMIO;
+        uint8_t *PCIO;
+        uint8_t *SBLK;
+        uint8_t *TOM1;
+        uint8_t *SBDN;
+        uint8_t *HCLK;
+        uint8_t *HCDN;
+       uint8_t *CBST;
+
+        int i;
+        device_t dev;
+        uint32_t dword;
+        msr_t msr;
+
+        BUSN = ssdt+0x3a; //+5 will be next BUSN
+        MMIO = ssdt+0x57; //+5 will be next MMIO
+        PCIO = ssdt+0xaf; //+5 will be next PCIO
+        SBLK = ssdt+0xdc; // one byte
+        TOM1 = ssdt+0xe3; //
+        SBDN = ssdt+0xed;//
+        HCLK = ssdt+0xfa; //+5 will be next HCLK
+        HCDN = ssdt+0x12a; //+5 will be next HCDN
+       CBST = ssdt+0x157; //
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        for(i=0;i<4;i++) {
+                dword = pci_read_config32(dev, 0xe0+i*4);
+                int_to_stream(dword, BUSN+i*5);
+        }
+        for(i=0;i<0x10;i++) {
+                dword = pci_read_config32(dev, 0x80+i*4);
+                int_to_stream(dword, MMIO+i*5);
+        }
+        for(i=0;i<0x08;i++) {
+                dword = pci_read_config32(dev, 0xc0+i*4);
+                int_to_stream(dword, PCIO+i*5);
+        }
+
+        *SBLK = (uint8_t)(sysconf.sblk);
+
+        msr = rdmsr(TOP_MEM);
+        int_to_stream(msr.lo, TOM1);
+
+        for(i=0;i<sysconf.hc_possible_num;i++) {
+                int_to_stream(sysconf.pci1234[i], HCLK + i*5);
+                int_to_stream(sysconf.hcdn[i],    HCDN + i*5);
+        }
+        for(i=sysconf.hc_possible_num; i<HC_POSSIBLE_NUM; i++) { // in case we set array size to other than 8
+                int_to_stream(0x00000000, HCLK + i*5);
+                int_to_stream(0x20202020, HCDN + i*5);
+        }
+
+        int_to_stream(sysconf.sbdn, SBDN);
+
+       if((sysconf.pci1234[0] >> 12) & 0xff) { //sb chain on  other than bus 0
+               *CBST = (uint8_t) (0x0f);
+       }
+       else {
+               *CBST = (uint8_t) (0x00);
+       }
+
+}
+
+//end
diff --git a/src/northbridge/amd/amdk8/amdk8_f.h b/src/northbridge/amd/amdk8/amdk8_f.h
new file mode 100644 (file)
index 0000000..7901d08
--- /dev/null
@@ -0,0 +1,561 @@
+#ifndef AMDK8_F_H
+
+#define AMDK8_F_H
+/* Definitions of various K8 registers */
+/* Function 0 */
+#define HT_TRANSACTION_CONTROL 0x68
+#define  HTTC_DIS_RD_B_P            (1 << 0)
+#define  HTTC_DIS_RD_DW_P           (1 << 1)
+#define  HTTC_DIS_WR_B_P            (1 << 2)
+#define  HTTC_DIS_WR_DW_P           (1 << 3)
+#define  HTTC_DIS_MTS               (1 << 4)
+#define  HTTC_CPU1_EN               (1 << 5)
+#define  HTTC_CPU_REQ_PASS_PW       (1 << 6)
+#define  HTTC_CPU_RD_RSP_PASS_PW    (1 << 7)
+#define  HTTC_DIS_P_MEM_C           (1 << 8)
+#define  HTTC_DIS_RMT_MEM_C         (1 << 9)
+#define  HTTC_DIS_FILL_P            (1 << 10)
+#define  HTTC_RSP_PASS_PW           (1 << 11)
+#define  HTTC_CHG_ISOC_TO_ORD       (1 << 12)
+#define  HTTC_BUF_REL_PRI_SHIFT     13
+#define  HTTC_BUF_REL_PRI_MASK      3
+#define   HTTC_BUF_REL_PRI_64       0
+#define   HTTC_BUF_REL_PRI_16       1
+#define   HTTC_BUF_REL_PRI_8        2
+#define   HTTC_BUF_REL_PRI_2        3
+#define  HTTC_LIMIT_CLDT_CFG        (1 << 15)
+#define  HTTC_LINT_EN               (1 << 16)
+#define  HTTC_APIC_EXT_BRD_CST      (1 << 17)
+#define  HTTC_APIC_EXT_ID           (1 << 18)
+#define  HTTC_APIC_EXT_SPUR         (1 << 19)
+#define  HTTC_SEQ_ID_SRC_NODE_EN    (1 << 20)
+#define  HTTC_DS_NP_REQ_LIMIT_SHIFT 21
+#define  HTTC_DS_NP_REQ_LIMIT_MASK  3
+#define   HTTC_DS_NP_REQ_LIMIT_NONE 0
+#define   HTTC_DS_NP_REQ_LIMIT_1    1
+#define   HTTC_DS_NP_REQ_LIMIT_4    2
+#define   HTTC_DS_NP_REQ_LIMIT_8    3
+#define  HTTC_MED_PRI_BYP_CNT_SHIFT 24
+#define  HTTC_MED_PRI_BYP_CNT_MASK  3
+#define  HTTC_HI_PRI_BYP_CNT_SHIFT  26
+#define  HTTC_HI_PRI_BYP_CNT_MASK   3
+
+
+/* Function 1 */
+#define PCI_IO_BASE0       0xc0
+#define PCI_IO_BASE1       0xc8
+#define PCI_IO_BASE2       0xd0
+#define PCI_IO_BASE3       0xd8
+#define PCI_IO_BASE_VGA_EN (1 << 4)
+#define PCI_IO_BASE_NO_ISA (1 << 5)
+
+
+/* Function 2 */
+#define DRAM_CSBASE       0x40
+#define DRAM_CSMASK       0x60
+#define DRAM_BANK_ADDR_MAP 0x80
+
+#define DRAM_CTRL      0x78
+#define  DC_RdPtrInit_SHIFT 0
+#define  DC_RdPrtInit_MASK  0xf
+#define  DC_RdPadRcvFifoDly_SHIFT 4
+#define  DC_RdPadRcvFifoDly_MASK  7
+#define   DC_RdPadRcvFiloDly_1_5_CLK 2
+#define   DC_RdPadRcvFiloDly_2_CLK 3
+#define   DC_RdPadRcvFiloDly_2_5_CLK 4
+#define   DC_RdPadRcvFiloDly_3_CLK 5
+#define   DC_RdPadRcvFiloDly_3_5_CLK 6
+#define  DC_AltVidC3MemClkTriEn (1<<16)
+#define  DC_DllTempAdjTime_SHIFT 17
+#define  DC_DllTempAdjTime_MASK 1
+#define   DC_DllTempAdjTime_5_MS 0
+#define   DC_DllTempAdjTime_1_MS 1
+#define  DC_DqsRcvEnTrain (1<<18)
+
+#define DRAM_INIT      0x7c
+#define  DI_MrsAddress_SHIFT 0
+#define  DI_MrsAddress_MASK 0xffff
+#define  DI_MrsBank_SHIFT 16
+#define  DI_MrsBank_MASK 7
+#define  DI_SendRchgAll (1<<24)
+#define  DI_SendAutoRefresh (1<<25)
+#define  DI_SendMrsCmd   (1<<26)
+#define  DI_DeassertMemRstX (1<<27)
+#define  DI_AssertCke   (1<<28)
+#define  DI_EnDramInit  (1<<31)
+
+#define DRAM_TIMING_LOW           0x88
+#define         DTL_TCL_SHIFT     0
+#define         DTL_TCL_MASK      7
+#define          DTL_TCL_BASE     1 
+#define          DTL_TCL_MIN      3
+#define          DTL_TCL_MAX      6
+#define         DTL_TRCD_SHIFT    4
+#define         DTL_TRCD_MASK     3
+#define          DTL_TRCD_BASE    3
+#define          DTL_TRCD_MIN     3
+#define   DTL_TRCD_MAX     6
+#define         DTL_TRP_SHIFT     8
+#define         DTL_TRP_MASK      3
+#define          DTL_TRP_BASE     3
+#define          DTL_TRP_MIN      3
+#define   DTL_TRP_MAX      6
+#define         DTL_TRTP_SHIFT    11
+#define         DTL_TRTP_MASK     1
+#define          DTL_TRTP_BASE    2
+#define          DTL_TRTP_MIN     2  /* 4 for 64 bytes*/
+#define   DTL_TRTP_MAX     3  /* 5 for 64 bytes */
+#define         DTL_TRAS_SHIFT    12
+#define         DTL_TRAS_MASK     0xf
+#define          DTL_TRAS_BASE    3
+#define          DTL_TRAS_MIN     5
+#define          DTL_TRAS_MAX     18
+#define         DTL_TRC_SHIFT     16
+#define         DTL_TRC_MASK      0xf
+#define          DTL_TRC_BASE     11
+#define          DTL_TRC_MIN      11
+#define          DTL_TRC_MAX      26
+#define         DTL_TWR_SHIFT     20
+#define         DTL_TWR_MASK      3
+#define          DTL_TWR_BASE     3
+#define          DTL_TWR_MIN      3
+#define          DTL_TWR_MAX      6
+#define  DTL_TRRD_SHIFT    22
+#define   DTL_TRRD_MASK    3
+#define   DTL_TRRD_BASE    2
+#define   DTL_TRRD_MIN    2
+#define   DTL_TRRD_MAX     5
+#define  DTL_MemClkDis_SHIFT 24    /* Channel A */ 
+#define  DTL_MemClkDis3       (1 << 26)
+#define  DTL_MemClkDis2       (1 << 27)
+#define  DTL_MemClkDis1       (1 << 28)
+#define  DTL_MemClkDis0       (1 << 29)
+#define  DTL_MemClkDis1_AM2       (0x51 << 24)
+#define  DTL_MemClkDis0_AM2       (0xa2 << 24)
+#define  DTL_MemClkDis0_S1g1      (0xa2 << 24)
+
+/* DTL_MemClkDis for m2 and s1g1 is different */
+#define DRAM_TIMING_HIGH   0x8c
+#define  DTH_TRWTTO_SHIFT  4
+#define  DTH_TRWTTO_MASK   7
+#define   DTH_TRWTTO_BASE   2 
+#define   DTH_TRWTTO_MIN    2
+#define   DTH_TRWTTO_MAX    9
+#define         DTH_TWTR_SHIFT    8
+#define         DTH_TWTR_MASK     3
+#define          DTH_TWTR_BASE    0 
+#define          DTH_TWTR_MIN     1
+#define          DTH_TWTR_MAX     3
+#define         DTH_TWRRD_SHIFT   10
+#define         DTH_TWRRD_MASK    3
+#define          DTH_TWRRD_BASE   0
+#define          DTH_TWRRD_MIN    0
+#define          DTH_TWRRD_MAX    3
+#define  DTH_TWRWR_SHIFT   12
+#define  DTH_TWRWR_MASK    3
+#define   DTH_TWRWR_BASE   1 
+#define   DTH_TWRWR_MIN    1
+#define   DTH_TWRWR_MAX    3
+#define  DTH_TRDRD_SHIFT   14
+#define  DTH_TRDRD_MASK    3
+#define   DTH_TRDRD_BASE   2
+#define   DTH_TRDRD_MIN    2
+#define   DTH_TRDRD_MAX    5
+#define         DTH_TREF_SHIFT    16
+#define         DTH_TREF_MASK     3
+#define          DTH_TREF_7_8_US  2
+#define          DTH_TREF_3_9_US  3
+#define  DTH_TRFC0_SHIFT   20 /* for Logical DIMM0 */
+#define  DTH_TRFC_MASK      7  
+#define          DTH_TRFC_75_256M   0
+#define          DTH_TRFC_105_512M  1
+#define   DTH_TRFC_127_5_1G  2
+#define   DTH_TRFC_195_2G    3
+#define   DTH_TRFC_327_5_4G  4
+#define  DTH_TRFC1_SHIFT   23 /*for Logical DIMM1 */
+#define  DTH_TRFC2_SHIFT   26 /*for Logical DIMM2 */
+#define  DTH_TRFC3_SHIFT   29 /*for Logical DIMM3 */
+
+#define DRAM_CONFIG_LOW           0x90
+#define         DCL_InitDram      (1<<0)
+#define         DCL_ExitSelfRef   (1<<1)
+#define  DCL_DramTerm_SHIFT 4
+#define  DCL_DramTerm_MASK  3
+#define   DCL_DramTerm_No   0
+#define   DCL_DramTerm_75_OH 1
+#define   DCL_DramTerm_150_OH 2
+#define   DCL_DramTerm_50_OH 3     
+#define  DCL_DrvWeak      (1<<7)
+#define  DCL_ParEn        (1<<8)
+#define  DCL_SelfRefRateEn (1<<9)
+#define  DCL_BurstLength32 (1<<10)
+#define  DCL_Width128     (1<<11) 
+#define  DCL_X4Dimm_SHIFT  12
+#define  DCL_X4Dimm_MASK   0xf
+#define  DCL_UnBuffDimm    (1<<16)
+#define         DCL_DimmEccEn     (1<<19)
+
+#define DRAM_CONFIG_HIGH   0x94
+#define  DCH_MemClkFreq_SHIFT 0
+#define  DCH_MemClkFreq_MASK  7
+#define   DCH_MemClkFreq_200MHz 0
+#define   DCH_MemClkFreq_266MHz 1
+#define   DCH_MemClkFreq_333MHz 2
+#define          DCH_MemClkFreq_400MHz 3
+#define  DCH_MemClkFreqVal     (1<<3)
+#define         DCH_MaxAsyncLat_SHIFT  4
+#define         DCH_MaxAsyncLat_MASK   0xf
+#define          DCH_MaxAsyncLat_BASE  0
+#define          DCH_MaxAsyncLat_MIN   0
+#define          DCH_MaxAsyncLat_MAX   15
+#define  DCH_RDqsEn          (1<<12)
+#define  DCH_DisDramInterface (1<<14)
+#define  DCH_PowerDownEn      (1<<15)
+#define  DCH_PowerDownMode_SHIFT 16
+#define  DCH_PowerDownMode_MASK 1
+#define   DCH_PowerDownMode_Channel_CKE 0
+#define   DCH_PowerDownMode_ChipSelect_CKE 1
+#define  DCH_FourRankSODimm    (1<<17)
+#define  DCH_FourRankRDimm     (1<<18)
+#define  DCH_SlowAccessMode    (1<<19)
+#define  DCH_BankSwizzleMode    (1<<22)
+#define  DCH_DcqBypassMax_SHIFT 24
+#define  DCH_DcqBypassMax_MASK  0xf
+#define   DCH_DcqBypassMax_BASE 0
+#define   DCH_DcqBypassMax_MIN  0
+#define   DCH_DcqBypassMax_MAX  15
+#define  DCH_FourActWindow_SHIFT 28
+#define  DCH_FourActWindow_MASK 0xf
+#define   DCH_FourActWindow_BASE 7
+#define   DCH_FourActWindow_MIN 8
+#define   DCH_FourActWindow_MAX 20
+
+
+// for 0x98 index and 0x9c data
+#define DRAM_CTRL_ADDI_DATA_OFFSET     0x98
+#define  DCAO_DctOffset_SHIFT  0
+#define  DCAO_DctOffset_MASK   0x3fffffff
+#define  DCAO_DctAccessWrite   (1<<30)
+#define  DCAO_DctAccessDone    (1<<31)
+
+#define DRAM_CTRL_ADDI_DATA_PORT        0x9c
+
+#define DRAM_OUTPUT_DRV_COMP_CTRL      0x00
+#define  DODCC_CkeDrvStren_SHIFT 0
+#define  DODCC_CkeDrvStren_MASK  3
+#define   DODCC_CkeDrvStren_1_0X  0
+#define   DODCC_CkeDrvStren_1_25X 1
+#define   DODCC_CkeDrvStren_1_5X  2
+#define   DODCC_CkeDrvStren_2_0X  3
+#define  DODCC_CsOdtDrvStren_SHIFT 4
+#define  DODCC_CsOdtDrvStren_MASK  3
+#define   DODCC_CsOdtDrvStren_1_0X  0
+#define   DODCC_CsOdtDrvStren_1_25X 1
+#define   DODCC_CsOdtDrvStren_1_5X  2
+#define   DODCC_CsOdtDrvStren_2_0X  3
+#define  DODCC_AddrCmdDrvStren_SHIFT 8
+#define  DODCC_AddrCmdDrvStren_MASK  3
+#define   DODCC_AddrCmdDrvStren_1_0X  0
+#define   DODCC_AddrCmdDrvStren_1_25X 1
+#define   DODCC_AddrCmdDrvStren_1_5X  2
+#define   DODCC_AddrCmdDrvStren_2_0X  3
+#define  DODCC_ClkDrvStren_SHIFT 12
+#define  DODCC_ClkDrvStren_MASK  3
+#define   DODCC_ClkDrvStren_0_75X  0
+#define   DODCC_ClkDrvStren_1_0X 1
+#define   DODCC_ClkDrvStren_1_25X  2
+#define   DODCC_ClkDrvStren_1_5X  3
+#define  DODCC_DataDrvStren_SHIFT 16
+#define  DODCC_DataDrvStren_MASK  3
+#define   DODCC_DataDrvStren_0_75X  0
+#define   DODCC_DataDrvStren_1_0X 1
+#define   DODCC_DataDrvStren_1_25X  2
+#define   DODCC_DataDrvStren_1_5X  3
+#define  DODCC_DqsDrvStren_SHIFT 20
+#define  DODCC_DqsDrvStren_MASK  3
+#define   DODCC_DqsDrvStren_0_75X  0
+#define   DODCC_DqsDrvStren_1_0X 1
+#define   DODCC_DqsDrvStren_1_25X  2
+#define   DODCC_DqsDrvStren_1_5X  3
+#define  DODCC_ProcOdt_SHIFT 28
+#define  DODCC_ProcOdt_MASK  3
+#define   DODCC_ProcOdt_300_OHMS  0
+#define   DODCC_ProcOdt_150_OHMS 1
+#define   DODCC_ProcOdt_75_OHMS  2
+
+#define DRAM_WRITE_DATA_TIMING_CTRL_LOW 0x01
+#define  DWDTCL_WrDatTimeByte0_SHIFT 0
+#define  DWDTC_WrDatTimeByte_MASK  0x3f
+#define   DWDTC_WrDatTimeByte_BASE 0
+#define   DWDTC_WrDatTimeByte_MIN  0
+#define   DWDTC_WrDatTimeByte_MAX  47
+#define  DWDTCL_WrDatTimeByte1_SHIFT 8
+#define  DWDTCL_WrDatTimeByte2_SHIFT 16
+#define  DWDTCL_WrDatTimeByte3_SHIFT 24
+
+#define DRAM_WRITE_DATA_TIMING_CTRL_HIGH 0x02
+#define  DWDTCH_WrDatTimeByte4_SHIFT 0
+#define  DWDTCH_WrDatTimeByte5_SHIFT 8
+#define  DWDTCH_WrDatTimeByte6_SHIFT 16
+#define  DWDTCH_WrDatTimeByte7_SHIFT 24
+
+#define DRAM_WRITE_DATA_ECC_TIMING_CTRL 0x03
+#define  DWDETC_WrChkTime_SHIFT 0
+#define  DWDETC_WrChkTime_MASK  0x3f
+#define   DWDETC_WrChkTime_BASE 0
+#define   DWDETC_WrChkTime_MIN  0
+#define   DWDETC_WrChkTime_MAX  47
+
+#define DRAM_ADDR_TIMING_CTRL 0x04
+#define  DATC_CkeFineDelay_SHIFT 0
+#define  DATC_CkeFineDelay_MASK  0x1f
+#define   DATC_CkeFineDelay_BASE 0
+#define   DATC_CkeFineDelay_MIN  0
+#define   DATC_CkeFineDelay_MAX 31 
+#define  DATC_CkeSetup (1<<5)
+#define  DATC_CsOdtFineDelay_SHIFT 8
+#define  DATC_CsOdtFineDelay_MASK  0x1f
+#define   DATC_CsOdtFineDelay_BASE 0
+#define   DATC_CsOdtFineDelay_MIN  0
+#define   DATC_CsOdtFineDelay_MAX 31
+#define  DATC_CsOdtSetup   (1<<13)
+#define  DATC_AddrCmdFineDelay_SHIFT 16 
+#define  DATC_AddrCmdFineDelay_MASK  0x1f
+#define   DATC_AddrCmdFineDelay_BASE 0
+#define   DATC_AddrCmdFineDelay_MIN  0
+#define   DATC_AddrCmdFineDelay_MAX 31
+#define  DATC_AddrCmdSetup   (1<<21)
+
+#define DRAM_READ_DQS_TIMING_CTRL_LOW 0x05
+#define  DRDTCL_RdDqsTimeByte0_SHIFT 0
+#define  DRDTC_RdDqsTimeByte_MASK  0x3f
+#define   DRDTC_RdDqsTimeByte_BASE 0
+#define   DRDTC_RdDqsTimeByte_MIN  0
+#define   DRDTC_RdDqsTimeByte_MAX  47
+#define  DRDTCL_RdDqsTimeByte1_SHIFT 8
+#define  DRDTCL_RdDqsTimeByte2_SHIFT 16
+#define  DRDTCL_RdDqsTimeByte3_SHIFT 24
+
+#define DRAM_READ_DQS_TIMING_CTRL_HIGH 0x06
+#define  DRDTCH_RdDqsTimeByte4_SHIFT 0
+#define  DRDTCH_RdDqsTimeByte5_SHIFT 8
+#define  DRDTCH_RdDqsTimeByte6_SHIFT 16
+#define  DRDTCH_RdDqsTimeByte7_SHIFT 24
+
+#define DRAM_READ_DQS_ECC_TIMING_CTRL 0x07
+#define  DRDETC_RdDqsTimeCheck_SHIFT 0
+#define  DRDETC_RdDqsTimeCheck_MASK  0x3f
+#define   DRDETC_RdDqsTimeCheck_BASE 0
+#define   DRDETC_RdDqsTimeCheck_MIN  0
+#define   DRDETC_RdDqsTimeCheck_MAX  47
+
+#define DRAM_DQS_RECV_ENABLE_TIME0 0x10
+#define  DDRET_DqsRcvEnDelay_SHIFT 0
+#define  DDRET_DqsRcvEnDelay_MASK 0xff
+#define   DDRET_DqsRcvEnDelay_BASE 0
+#define   DDRET_DqsRcvEnDelay_MIN  0
+#define   DDRET_DqsRcvEnDelay_MAX  0xae   /* unit is 50ps */
+
+#define DRAM_DQS_RECV_ENABLE_TIME1 0x13
+#define DRAM_DQS_RECV_ENABLE_TIME2 0x16
+#define DRAM_DQS_RECV_ENABLE_TIME3 0x19
+
+/* there are index        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x30, 0x33, 0x36, 0x39 
+that are corresponding to 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x13, 0x16, 0x19
+*/
+#define DRAM_CTRL_MISC 0xa0
+#define  DCM_MemClrStatus (1<<0)
+#define  DCM_DisableJitter (1<<1)
+#define  DCM_RdWrQByp_SHIFT 2
+#define  DCM_RdWrQByp_MASK  3
+#define   DCM_RdWrQByp_2 0
+#define   DCM_RdWrQByp_4 1
+#define   DCM_RdWrQByp_8 2
+#define   DCM_RdWrQByp_16 3
+#define  DCM_Mode64BitMux (1<<4)
+#define  DCM_DCC_EN (1<<5)
+#define  DCM_ILD_lmt_SHIFT 6
+#define  DCM_ILD_lmt_MASK 7
+#define   DCM_ILD_lmt_0 0
+#define   DCM_ILD_lmt_4 1
+#define   DCM_ILD_lmt_8 2
+#define   DCM_ILD_lmt_16 3
+#define   DCM_ILD_lmt_32 4
+#define   DCM_ILD_lmt_64 5
+#define   DCM_ILD_lmt_128 6
+#define   DCM_ILD_lmt_256 7
+#define  DCM_DramEnabled (1<<9)
+#define  DCM_MemClkDis_SHIFT 24                /* Channel B */
+#define  DCM_MemClkDis3       (1 << 26)
+#define  DCM_MemClkDis2       (1 << 27)
+#define  DCM_MemClkDis1       (1 << 28)
+#define  DCM_MemClkDis0       (1 << 29)
+
+
+/* Function 3 */
+#define MCA_NB_CONFIG      0x44
+#define   MNC_ECC_EN       (1 << 22)
+#define   MNC_CHIPKILL_EN  (1 << 23)
+
+#define SCRUB_CONTROL     0x58
+#define          SCRUB_NONE        0
+#define          SCRUB_40ns        1
+#define          SCRUB_80ns        2
+#define          SCRUB_160ns       3
+#define          SCRUB_320ns       4
+#define          SCRUB_640ns       5
+#define          SCRUB_1_28us      6
+#define          SCRUB_2_56us      7
+#define          SCRUB_5_12us      8
+#define          SCRUB_10_2us      9
+#define          SCRUB_20_5us     10
+#define          SCRUB_41_0us     11
+#define          SCRUB_81_9us     12
+#define          SCRUB_163_8us    13
+#define          SCRUB_327_7us    14
+#define          SCRUB_655_4us    15
+#define          SCRUB_1_31ms     16
+#define          SCRUB_2_62ms     17
+#define          SCRUB_5_24ms     18 
+#define          SCRUB_10_49ms    19
+#define          SCRUB_20_97ms    20
+#define          SCRUB_42ms       21
+#define          SCRUB_84ms       22
+#define         SC_DRAM_SCRUB_RATE_SHFIT  0
+#define         SC_DRAM_SCRUB_RATE_MASK   0x1f
+#define         SC_L2_SCRUB_RATE_SHIFT    8
+#define         SC_L2_SCRUB_RATE_MASK     0x1f
+#define         SC_L1D_SCRUB_RATE_SHIFT   16
+#define         SC_L1D_SCRUB_RATE_MASK    0x1f
+
+#define SCRUB_ADDR_LOW    0x5C
+
+#define SCRUB_ADDR_HIGH           0x60
+
+#define NORTHBRIDGE_CAP           0xE8
+#define         NBCAP_128Bit         (1 << 0)
+#define         NBCAP_MP             (1 << 1)
+#define         NBCAP_BIG_MP         (1 << 2)
+#define         NBCAP_ECC            (1 << 3)
+#define         NBCAP_CHIPKILL_ECC   (1 << 4)
+#define         NBCAP_MEMCLK_SHIFT   5
+#define         NBCAP_MEMCLK_MASK    3
+#define          NBCAP_MEMCLK_200MHZ  3
+#define          NBCAP_MEMCLK_266MHZ  2
+#define          NBCAP_MEMCLK_333MHZ  1
+#define          NBCAP_MEMCLK_NOLIMIT  0
+#define         NBCAP_MEMCTRL        (1 << 8)
+#define  NBCAP_HtcCap          (1<<10)
+#define  NBCAP_CmpCap_SHIFT    12
+#define  NBCAP_CmpCap_MASK     3
+
+
+#define LinkConnected     (1 << 0)
+#define InitComplete      (1 << 1)
+#define NonCoherent       (1 << 2)
+#define ConnectionPending (1 << 4)
+
+
+#include "raminit.h"
+//struct definitions
+
+struct dimm_size {
+        uint8_t per_rank; // it is rows + col + bank_lines + data lines */
+        uint8_t rows;
+        uint8_t col;
+        uint8_t bank; //1, 2, 3 mean 2, 4, 8
+        uint8_t rank;
+} __attribute__((packed));
+
+struct mem_info { // pernode
+        uint32_t dimm_mask;
+        struct dimm_size sz[DIMM_SOCKETS];
+        uint32_t x4_mask;
+        uint32_t x16_mask;
+       uint32_t single_rank_mask;
+        uint32_t page_1k_mask;
+//        uint32_t ecc_mask;
+//        uint32_t registered_mask;
+        uint8_t is_opteron;
+        uint8_t is_registered;
+        uint8_t is_ecc;
+        uint8_t is_Width128;
+        uint8_t memclk_set; // we need to use this to retrieve the mem param
+       uint8_t rsv[3];
+} __attribute__((packed));
+
+struct link_pair_st {
+        device_t udev;
+        uint32_t upos;
+        uint32_t uoffs;
+        device_t dev;
+        uint32_t pos;
+        uint32_t offs;
+
+} __attribute__((packed));
+
+struct sys_info {
+        uint8_t ctrl_present[NODE_NUMS];
+        struct mem_info meminfo[NODE_NUMS];
+       struct mem_controller ctrl[NODE_NUMS];
+        uint8_t mem_trained[NODE_NUMS];
+        uint32_t tom_k;
+        uint32_t tom2_k;
+
+       uint32_t mem_base[NODE_NUMS];
+       uint32_t cs_base[NODE_NUMS*8]; //8 cs_idx
+       uint32_t hole_reg[NODE_NUMS]; // can we spare it to one, and put ctrl idx in it
+
+       uint8_t dqs_delay_a[NODE_NUMS*2*2*9]; //8 node channel 2, direction 2 , bytelane *9
+       uint8_t dqs_rcvr_dly_a[NODE_NUMS*2*8]; //8 node, channel 2, receiver 8
+       uint32_t nodes;
+        struct link_pair_st link_pair[16];// enough? only in_conherent
+        uint32_t link_pair_num;
+        uint32_t ht_c_num;
+       uint32_t sbdn;
+       uint32_t sblk;
+       uint32_t sbbusn;
+} __attribute__((packed));
+
+#if MEM_TRAIN_SEQ == 1
+
+static void wait_all_core0_mem_trained(struct sys_info *sysinfo)
+{
+        int i;
+        uint32_t mask = 0;
+
+       if(sysinfo->nodes == 1) return; // in case only one cpu installed       
+
+        for(i=1; i<sysinfo->nodes; i++) {
+                if (!sysinfo->ctrl_present[ i ])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+                if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+                mask |= (1<<i);
+
+        }
+
+        i = 1;
+        while(1) {
+               if(mask & (1<<i)) {
+                       if((sysinfo->mem_trained[i])) {
+                               mask &= ~(1<<i);
+                       }
+               }
+
+                if(!mask) break;
+
+               /* cpu_relax */
+               __asm__ __volatile__("rep;nop": : :"memory");
+
+                i++;
+                i%=sysinfo->nodes;
+       }
+
+}
+#endif
+
+#endif /* AMDK8_F_H */
diff --git a/src/northbridge/amd/amdk8/amdk8_f_pci.c b/src/northbridge/amd/amdk8/amdk8_f_pci.c
new file mode 100644 (file)
index 0000000..579d9fe
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef AMDK8_F_PCI_C
+
+#define AMDK8_F_PCI_C
+/* bit [10,8] are dev func, bit[1,0] are dev index */
+static uint32_t pci_read_config32_index(device_t dev, uint32_t index_reg, uint32_t index)
+{
+        uint32_t dword;
+
+        pci_write_config32(dev, index_reg, index);
+
+        dword = pci_read_config32(dev, index_reg+0x4);
+
+        return dword;
+}
+
+static void pci_write_config32_index(device_t dev, uint32_t index_reg, uint32_t index, uint32_t data)
+{
+
+        pci_write_config32(dev, index_reg, index);
+
+        pci_write_config32(dev, index_reg + 0x4, data);
+
+}
+
+static uint32_t pci_read_config32_index_wait(device_t dev, uint32_t index_reg, uint32_t index)
+{
+
+        uint32_t dword;
+
+        index &= ~(1<<30);
+        pci_write_config32(dev, index_reg, index);
+
+        do {
+                dword = pci_read_config32(dev, index_reg);
+        } while (!(dword & (1<<31)));
+
+        dword = pci_read_config32(dev, index_reg+0x4);
+
+        return dword;
+}
+
+static void pci_write_config32_index_wait(device_t dev, uint32_t index_reg, uint32_t index, uint32_t data)
+{
+
+        uint32_t dword;
+
+        pci_write_config32(dev, index_reg + 0x4, data);
+
+        index |= (1<<30);
+        pci_write_config32(dev, index_reg, index);
+        do {
+                dword = pci_read_config32(dev, index_reg);
+        } while (!(dword & (1<<31)));
+
+}
+
+#endif
index d29831b74b362cb3da67e45fde8afc38c067354e..943d586bc3da9c0a7aec9efd0f3de7a377f9cdaa 100644 (file)
@@ -1642,6 +1642,10 @@ static unsigned count_cpus(unsigned nodes)
 #endif
                
 }
+static inline unsigned get_nodes(void)
+{
+        return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
+}
 
 static void coherent_ht_finalize(unsigned nodes)
 {
index 5b9a87ac63e00d93ffa8944ab836f6dc77607096..c0c4b338b9568e807e981893e7835e11d67b375d 100644 (file)
@@ -285,11 +285,13 @@ static uint16_t read_freq_cap(device_t dev, uint8_t pos)
        freq_cap = pci_read_config16(dev, pos);
        freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
 
+#if K8_REV_F_SUPPORT == 0
 #if K8_HT_FREQ_1G_SUPPORT == 1
        if (!is_cpu_pre_e0())
        {
                return freq_cap;
        }
+#endif
 #endif
 
        id = pci_read_config32(dev, 0);
@@ -1590,7 +1592,9 @@ static unsigned verify_dualcore(unsigned nodes)
 static void coherent_ht_finalize(unsigned nodes)
 {
        unsigned node;
+#if K8_REV_F_SUPPORT == 0
        int rev_a0;
+#endif
 #if CONFIG_LOGICAL_CPUS==1
        unsigned total_cpus;
 
@@ -1609,7 +1613,11 @@ static void coherent_ht_finalize(unsigned nodes)
         */
 
        print_spew("coherent_ht_finalize\r\n");
+
+#if K8_REV_F_SUPPORT == 0
        rev_a0 = is_cpu_rev_a0();
+#endif
+
        for (node = 0; node < nodes; node++) {
                device_t dev;
                uint32_t val;
@@ -1638,11 +1646,13 @@ static void coherent_ht_finalize(unsigned nodes)
                        (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
                pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
 
+#if K8_REV_F_SUPPORT == 0
                if (rev_a0) {
                        pci_write_config32(dev, 0x94, 0);
                        pci_write_config32(dev, 0xb4, 0);
                        pci_write_config32(dev, 0xd4, 0);
                }
+#endif
        }
 
        print_spew("done\r\n");
@@ -1656,6 +1666,7 @@ static int apply_cpu_errata_fixes(unsigned nodes)
                device_t dev;
                uint32_t cmd;
                dev = NODE_MC(node);
+#if K8_REV_F_SUPPORT == 0
                if (is_cpu_pre_c0()) {
 
                        /* Errata 66
@@ -1697,6 +1708,7 @@ static int apply_cpu_errata_fixes(unsigned nodes)
                                needs_reset = 1; /* Needed? */
                        }
                }
+#endif
        }
        return needs_reset;
 }
@@ -1734,6 +1746,11 @@ static int optimize_link_read_pointers(unsigned nodes)
        return needs_reset;
 }
 
+static inline unsigned get_nodes(void)
+{
+        return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
+}
+
 static int optimize_link_coherent_ht(void)
 {
         int needs_reset = 0;
index eff6ca1c629b0c963c999252f1054ee83e1cff47..61e89028e139a260baa8e853fa8c3f25f7c38211 100644 (file)
@@ -39,6 +39,8 @@ acknowledgement of AMD's proprietary rights in them.
 #include <string.h>
 #include <stdint.h>
 
+#include <cpu/amd/amdk8_sysconf.h>
+
 
 #if 0
 unsigned node_link_to_bus(unsigned node, unsigned link)
@@ -77,13 +79,6 @@ unsigned node_link_to_bus(unsigned node, unsigned link)
 #endif
 
 
-extern unsigned pci1234[];
-extern  unsigned hcdn[];
-extern unsigned hc_possible_num;
-extern unsigned sblk;
-
-unsigned hcdn_reg[4]; // defined in northbridge.c
-
 /* why we need pci1234 array
         final result for pci1234 will be
                 pci1234[0] will record sblink and bus range
@@ -152,6 +147,13 @@ unsigned hcdn_reg[4]; // defined in northbridge.c
 
         So Max HC_POSSIBLE_NUM is 8
 
+        1n: 3
+        2n: 2x2 - 1
+        4n: 1x4 - 2 
+        6n: 2 
+        8n: 2 
+       Total: 12 
+
         just put all the possible ht node/link to the list tp pci1234[] in  get_bus_conf.c on MB dir
 
        Also don't forget to increase the ACPI_SSDTX_NUM etc if you have too much SSDT
@@ -169,11 +171,11 @@ void get_sblk_pci1234(void)
         /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
         dev = dev_find_slot(0, PCI_DEVFN(0x18,0));
         dword = pci_read_config32(dev, 0x64);
-        sblk = (dword>>8) & 0x3;
+        sysconf.sblk = (dword>>8) & 0x3;
 
         dword &=0x0300;
         dword |= 1;
-        pci1234[0] = dword;
+        sysconf.pci1234[0] = dword;
 
         /*about hardcode numbering for HT_IO support
                 set the node_id and link_id that could have ht chain in the one array,
@@ -189,35 +191,35 @@ void get_sblk_pci1234(void)
                 dwordx = pci_read_config32(dev, 0xe0+j*4);
                 dwordx &=0xffff0ff1; //keep bus num, node_id, link_num, enable bits
                 if((dwordx & 0xff1) == dword) { //SBLINK
-                        pci1234[0] = dwordx;
-                       hcdn[0] = hcdn_reg[j];
+                        sysconf.pci1234[0] = dwordx;
+                       sysconf.hcdn[0] = sysconf.hcdn_reg[j];
                         continue;
                 }
                 if((dwordx & 1) == 1) {
                         // We need to find out the number of HC
                         // for exact match
-                        for(i=1;i<hc_possible_num;i++) {
-                                if((dwordx & 0xff0) == (pci1234[i] & 0xff0)) {
-                                        pci1234[i] = dwordx;
-                                       hcdn[i] = hcdn_reg[j];
+                        for(i=1;i<sysconf.hc_possible_num;i++) {
+                                if((dwordx & 0xff0) == (sysconf.pci1234[i] & 0xff0)) {
+                                        sysconf.pci1234[i] = dwordx;
+                                       sysconf.hcdn[i] = sysconf.hcdn_reg[j];
                                         break;
                                 }
                         }
                         // for 0xff0 match or same node
-                        for(i=1;i<hc_possible_num;i++) {
-                                if((dwordx & 0xff0) == (dwordx & pci1234[i] & 0xff0)) {
-                                        pci1234[i] = dwordx;
-                                       hcdn[i] = hcdn_reg[j];
+                        for(i=1;i<sysconf.hc_possible_num;i++) {
+                                if((dwordx & 0xff0) == (dwordx & sysconf.pci1234[i] & 0xff0)) {
+                                        sysconf.pci1234[i] = dwordx;
+                                       sysconf.hcdn[i] = sysconf.hcdn_reg[j];
                                         break;
                                 }
                         }
                 }
         }
 
-        for(i=1;i<hc_possible_num;i++) {
-                if((pci1234[i] & 1) != 1) {
-                        pci1234[i] = 0;
-                       hcdn[i] = 0x20202020;
+        for(i=1;i<sysconf.hc_possible_num;i++) {
+                if((sysconf.pci1234[i] & 1) != 1) {
+                        sysconf.pci1234[i] = 0;
+                       sysconf.hcdn[i] = 0x20202020;
                 }
         }
 
index b07c62a5dc776a4b4b4060e079439a22b4b217d1..012caf15019cc8bde44e02d3d4aaec46c0a1aa8a 100644 (file)
@@ -1,11 +1,8 @@
 /*
- *    incoherent hypertransport enumeration
- *     originally written by Eric Biederman
- * 
- *  2004.12 yhlu    add multi ht chain dynamically support
- *  2005.11 yhlu    add let real sb to use small unitid
- *  2006.03 stepan  cleanups
- */
+       This should be done by Eric
+       2004.12 yhlu add multi ht chain dynamically support
+       2005.11 yhlu add let real sb to use small unitid
+*/
 #include <device/pci_def.h>
 #include <device/pci_ids.h>
 #include <device/hypertransport_def.h>
         #define K8_ALLOCATE_IO_RANGE 0
 #endif
 
-/* Do we need to allocate MMIO? Currently we direct the last 64M 
- * to the southbridge link only. We have to remain access to the
- * 4G-4M range for the southbridge (Flash ROM)
- */
+// Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM 
 #ifndef K8_ALLOCATE_MMIO_RANGE
         #define K8_ALLOCATE_MMIO_RANGE 0
 #endif
@@ -55,9 +49,7 @@ static uint8_t ht_lookup_capability(device_t dev, uint16_t val)
        if (pos > PCI_CAP_LIST_NEXT) {
                pos = pci_read_config8(dev, pos);
        }
-
-       /* loop through the linked list */
-       while(pos != 0) {
+       while(pos != 0) { /* loop through the linked list */
                uint8_t cap;
                cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
                if (cap == PCI_CAP_ID_HT) {
@@ -89,7 +81,7 @@ static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid
        device_t dev;
        uint32_t id;
 
-       // actually, only for one HT device HT chain, and unitid is 0
+       //actually, only for one HT device HT chain, and unitid is 0
 #if HT_CHAIN_UNITID_BASE == 0
        if(offset_unitid) {
                return;
@@ -158,9 +150,11 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
        /* AMD K8 Unsupported 1Ghz? */
        if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
        #if K8_HT_FREQ_1G_SUPPORT == 1 
+               #if K8_REV_F_SUPPORT == 0 
                if (is_cpu_pre_e0()) {  // only E0 later support 1GHz
                        freq_cap &= ~(1 << HT_FREQ_1000Mhz);
                }
+               #endif
        #else   
                 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
        #endif
@@ -268,33 +262,22 @@ static int ht_optimize_link(
 
        return needs_reset;
 }
-
 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
 
 #if RAMINIT_SYSINFO == 1
-static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, 
-               unsigned offset_unitid, struct sys_info *sysinfo);
-
-static int scan_pci_bus(unsigned bus, struct sys_info *sysinfo) 
+static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo);
+static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo) 
 #else
-static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, 
-               unsigned offset_unitid);
-
-static int scan_pci_bus(unsigned bus)
+static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid);
+static int scan_pci_bus( unsigned bus)
 #endif
 {
-        /* Here we already can access PCI_DEV(bus, 0, 0) to 
-        * PCI_DEV(bus, 0x1f, 0x7).
-        * 
-        * So scan these devices to find out whether there are more bridges.
-        * 
-        * - If we find a pci bridge, set the bus number in the bridge, and
-        *   continue with the next device.
-        *   
-        * - For hypertransport bridges, set the bus number in the bridge and 
-        *   call ht_setup_chainx(), and scan_pci_bus()
-        *
-         */    
+        /*      
+                here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
+                So We can scan these devices to find out if they are bridge 
+                If it is pci bridge, We need to set busn in bridge, and go on
+                For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
+        */    
        unsigned int devfn;
        unsigned new_bus;
        unsigned max_bus;
@@ -356,18 +339,12 @@ static int scan_pci_bus(unsigned bus)
                                        ((unsigned int) max_bus << 16));
                                pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
                                
-                               /* Here we need to figure out if dev is a ht 
-                                * bridge. If it is, we need to call 
-                                * ht_setup_chainx() first
-                                * 
-                                * Not verified --- yhlu
-                                */
-                               
-                               uint8_t upos; // is this valid C?
-                               
-                               // one func one ht sub
-                               upos = ht_lookup_host_capability(dev); 
-                               
+                               /* here we need to figure out if dev is a ht bridge
+                                       if it is ht bridge, we need to call ht_setup_chainx at first
+                                  Not verified --- yhlu
+                               */
+                               uint8_t upos;
+                               upos = ht_lookup_host_capability(dev); // one func one ht sub
                                if (upos) { // sub ht chain
                                        uint8_t busn;
                                        busn = (new_bus & 0xff);
@@ -390,7 +367,7 @@ static int scan_pci_bus(unsigned bus)
 
                                buses = (buses & 0xff00ffff) |
                                        ((unsigned int) (new_bus & 0xff) << 16);
-                                       pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
+                               pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
 
                                pci_write_config16(dev, PCI_COMMAND, cr);
 
@@ -405,7 +382,6 @@ static int scan_pci_bus(unsigned bus)
                  * time probing another function. 
                  * Skip to next device. 
                  */
-               
                 if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
                 {
                         devfn += 0x07;
@@ -422,9 +398,7 @@ static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned o
 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid)
 #endif
 {
-       // execute this function even with HT_CHAIN_UNITID_BASE == 0, 
-       // because of the end_of_chain check, and we need it to 
-       // optimize the links
+       //even HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link
 
        uint8_t next_unitid, last_unitid;
        unsigned uoffs;
@@ -434,8 +408,7 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
 #endif
 
 #if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
-        // record the device id of last ht device, so we can set the 
-       // unit id to HT_CHAIN_END_UNITID_BASE
+        //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
         unsigned real_last_unitid;
         uint8_t real_last_pos;
        int ht_dev_num = 0;
@@ -519,17 +492,15 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
 
                 next_unitid += count;
 
-               /* Find which side of the ht link we are on, by reading
-                * which direction our last write to PCI_CAP_FLAGS came
-                * from.
+               /* Find which side of the ht link we are on,
+                * by reading which direction our last write to PCI_CAP_FLAGS
+                * came from.
                 */
                flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
                 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
                
                #if RAMINIT_SYSINFO == 1
-                /* store the link pair here and we will setup the 
-                * Hypertransport link later, after we get final FID/VID 
-                */
+                /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
                {
                        struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
                        link_pair->udev = udev;
@@ -544,7 +515,7 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
                reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
                #endif
 
-               /* Remember the location of the last device */
+               /* Remeber the location of the last device */
                udev = dev;
                upos = pos;
                uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
@@ -586,8 +557,6 @@ end_of_chain: ;
 
 }
 
-
-
 #if RAMINIT_SYSINFO == 1
 static void ht_setup_chain(device_t udev, unsigned upos, struct sys_info *sysinfo)
 #else
@@ -618,10 +587,7 @@ static int ht_setup_chain(device_t udev, unsigned upos)
         return ht_setup_chainx(udev, upos, 0, offset_unitid);
 #endif
 }
-
-
-static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, 
-               uint8_t linkt, uint8_t val)
+static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
 {
        uint32_t dword, dword_old;
        uint8_t link_type;
@@ -630,17 +596,16 @@ static int optimize_link_read_pointer(uint8_t node, uint8_t linkn,
        dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
        link_type = dword & 0xff;
        
-       dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
        
-       /* coherent link only linkt = 3, non coherent = 7*/
-       if ( (link_type & 7) == linkt ) { 
+       if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
+               dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
                dword &= ~( 0xff<<(linkn *8) );
                dword |= val << (linkn *8);
-       }
        
-       if (dword != dword_old) {
-               pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
-               return 1;
+               if (dword != dword_old) {
+                       pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
+                       return 1;
+               }
        }
        
        return 0;
@@ -658,14 +623,22 @@ static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
                uint8_t nodeid, linkn;
                uint8_t busn;
                uint8_t val;
+               unsigned devn = 1;
+
+        #if HT_CHAIN_UNITID_BASE != 1
+                #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
+                if(i==0) // to check if it is sb ht chain
+                #endif
+                        devn = HT_CHAIN_UNITID_BASE;
+        #endif
 
                reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
                
                nodeid = ((reg & 0xf0)>>4); // nodeid
                linkn = ((reg & 0xf00)>>8); // link n
                busn = (reg & 0xff0000)>>16; //busn
-       
-               reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID);
+
+               reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); // ? the chain dev maybe offseted
                if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
                        val = 0x25;
                } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
@@ -681,18 +654,79 @@ static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
        return reset_needed;
 }
 
+static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
+{
+        uint32_t dword;
+        uint8_t link_type;
+       unsigned regpos;
+       device_t dev;
+
+        /* This works on an Athlon64 because unimplemented links return 0 */
+       regpos = 0x98 + (linkn * 0x20);
+       dev = PCI_DEV(0,0x18+node,0);
+        dword = pci_read_config32(dev, regpos);
+        link_type = dword & 0xff;
+
+        if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
+               regpos = 0x90 + (linkn * 0x20);
+               dword = pci_read_config32(dev, regpos );
+
+               if (dword != val) {
+                       pci_write_config32(dev, regpos, val);
+                       return 1;
+               }
+       }
+
+        return 0;
+}
+static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid,  unsigned val)
+{
+        int reset_needed;
+        uint8_t i;
+
+        reset_needed = 0;
+
+        for (i = 0; i < ht_c_num; i++) {
+                uint32_t reg;
+                uint8_t nodeid, linkn;
+                uint8_t busn;
+                unsigned devn = 1;
+
+        #if HT_CHAIN_UNITID_BASE != 1
+                #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
+                if(i==0) // to check if it is sb ht chain
+                #endif
+                        devn = HT_CHAIN_UNITID_BASE;
+        #endif
+
+                reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
+                if((reg & 3) != 3) continue; // not enabled
+
+                nodeid = ((reg & 0xf0)>>4); // nodeid
+                linkn = ((reg & 0xf00)>>8); // link n
+                busn = (reg & 0xff0000)>>16; //busn
+
+                reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
+                if ( (reg & 0xffff) == vendorid ) {
+                        reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
+                }
+        }
+
+        return reset_needed;
+}
+
+
 #if RAMINIT_SYSINFO == 1
 static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
 #else
 static int ht_setup_chains(uint8_t ht_c_num)
 #endif
 {
-       /* Assumption: The HT chain that is bus 0 has the HT I/O Hub on it. 
-        * On most boards this just happens. If a cpu has multiple 
-        * non coherent links the appropriate bus registers for the
+       /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. 
+        * On most boards this just happens.  If a cpu has multiple
+        * non Coherent links the appropriate bus registers for the
         * links needs to be programed to point at bus 0.
         */
-       
         uint8_t upos;
         device_t udev;
        uint8_t i;
@@ -717,14 +751,9 @@ static int ht_setup_chains(uint8_t ht_c_num)
                
                reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
 
-               // We need to setup 0x94, 0xb4, and 0xd4 according to reg
-               
-               // nodeid; it will decide 0x18 or 0x19
-               devpos = ((reg & 0xf0)>>4)+0x18; 
-               
-               // link n; it will decide 0x94 or 0xb4, 0x0xd4;
-               regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; 
-               
+               //We need setup 0x94, 0xb4, and 0xd4 according to the reg
+               devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19
+               regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4;
                busn = (reg & 0xff0000)>>16;
                
                dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ;
@@ -753,15 +782,12 @@ static int ht_setup_chains(uint8_t ht_c_num)
 #endif
 
                #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
-               /* You can not use use this in romcc, because recursive
-                * function calls in romcc will kill you 
-                */
+               /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
                bus = busn; // we need 32 bit 
 #if RAMINIT_SYSINFO == 1
                scan_pci_bus(bus, sysinfo);
 #else
-               // take out reset_needed that is stored in upword
-               reset_needed |= (scan_pci_bus(bus)>>16); 
+               reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
 #endif
                #endif
        }
@@ -774,11 +800,9 @@ static int ht_setup_chains(uint8_t ht_c_num)
 
 }
 
-static inline unsigned get_nodes(void)
-{
-        return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
-}
-
+#if defined (__GNUC__)
+static inline unsigned get_nodes(void);
+#endif
 
 #if RAMINIT_SYSINFO == 1
 static void ht_setup_chains_x(struct sys_info *sysinfo)
@@ -803,15 +827,14 @@ static int ht_setup_chains_x(void)
         /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
        print_linkn_in("SBLink=", ((reg>>8) & 3) );
 #if RAMINIT_SYSINFO == 1
-       sysinfo->sblnk = (reg>>8) & 3;
+       sysinfo->sblk = (reg>>8) & 3;
        sysinfo->sbbusn = 0;
        sysinfo->nodes = nodes;
 #endif
         tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
 
-       /* 0 will be used ht chain with SB we need to keep SB in bus 0 in auto stage */
-       next_busn=0x3f+1; 
+       next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
 
 #if K8_ALLOCATE_IO_RANGE == 1
        /* io range allocation */
@@ -825,9 +848,12 @@ static int ht_setup_chains_x(void)
        /* clean others */
         for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
+
+#if K8_ALLOCATE_IO_RANGE == 1
                /* io range allocation */
                pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
                pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
+#endif
         }
  
         for(nodeid=0; nodeid<nodes; nodeid++) {
@@ -836,67 +862,38 @@ static int ht_setup_chains_x(void)
                 dev = PCI_DEV(0, 0x18+nodeid,0);
                 for(linkn = 0; linkn<3; linkn++) {
                         unsigned regpos;
-                       
                         regpos = 0x98 + 0x20 * linkn;
                         reg = pci_read_config32(dev, regpos);
-                       
-                       /* skip if link is non conherent or not connected*/
-                        if ((reg & 0x17) != 7) continue; 
-                       
-                       print_linkn_in("NC node|link=", 
-                                       ((nodeid & 0xf)<<4)|(linkn & 0xf));
-                       
+                        if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
+                       print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
                         tempreg = 3 | (nodeid <<4) | (linkn<<8);
-                       
-                        /* compare (temp & 0xffff) with 
-                        * (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) 
-                        */
+                        /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
                         for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
-                                reg = pci_read_config32( PCI_DEV(0, 0x18, 1), 
-                                               0xe0 + ht_c_num * 4);
-                               
-                                if ( ((reg & 0xffff) == (tempreg & 0xffff)) 
-                                               || ((reg & 0xffff) == 0x0000) ) {  
-                                       /*we got it*/
+                                reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
+                                if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) {  /*we got it*/
                                         break;
                                 }
                         }
-                       
-                       /* used up the maximum allowed 4 non conherent links */
-                        if(ht_c_num == 4) break; 
-                       
-                        /* update to 0xe0...*/
-                       if((reg & 0xf) == 3) continue; /* SbLink so don't touch it */
-                       
+                        if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
+                        /*update to 0xe0...*/
+                       if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
                        print_linkn_in("\tbusn=", next_busn);
-                       
                         tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
-                        pci_write_config32(PCI_DEV(0, 0x18, 1), 
-                                       0xe0 + ht_c_num * 4, tempreg);
-                       
+                        pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
                        next_busn+=0x3f+1;
 
 #if K8_ALLOCATE_IO_RANGE == 1                  
                        /* io range allocation */
-                       
-                       // limit
-                       tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); 
-                       pci_write_config32( PCI_DEV(0, 0x18, 1), 
-                                       0xC4 + ht_c_num * 8, tempreg);
-                       
-                       // base :ISA and VGA ?
-                       tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); 
-                       pci_write_config32(PCI_DEV(0, 0x18, 1), 
-                                       0xC0 + ht_c_num * 8, tempreg);
-                       
+                       tempreg = nodeid | (linkn<<4) |  ((next_io_base+0x3)<<12); //limit
+                       pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
+                       tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12);        //base :ISA and VGA ?
+                       pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
                        next_io_base += 0x3+0x1;
 #endif
+
                 }
         }
-       
-        /* update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) 
-        * to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);
-        */
+        /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
 
         for(nodeid = 1; nodeid<nodes; nodeid++) {
                 int i;
@@ -938,6 +935,7 @@ static int ht_setup_chains_x(void)
 #if RAMINIT_SYSINFO == 1
        sysinfo->ht_c_num = i;
         ht_setup_chains(i, sysinfo);
+       sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
 #else
        return ht_setup_chains(i);
 #endif
@@ -947,7 +945,7 @@ static int ht_setup_chains_x(void)
 #if RAMINIT_SYSINFO == 1
 static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
 {
-       // We need to use the recorded link pair info to optimize the link
+       // We need to use recorded link pair info to optimize the link
        int i;
        int reset_needed = 0;
        
@@ -955,12 +953,10 @@ static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
 
        for(i=0; i< link_pair_num; i++) {       
                struct link_pair_st *link_pair= &sysinfo->link_pair[i];
-               reset_needed |= ht_optimize_link(link_pair->udev, 
-                               link_pair->upos, link_pair->uoffs, 
-                               link_pair->dev, link_pair->pos, link_pair->offs);
+               reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
        }
 
-       reset_needed |= optimize_link_read_pointers(sysinfo->ht_c_num);
+       reset_needed |= optimize_link_read_pointers_chain(sysinfo->ht_c_num);
 
        return reset_needed;
 
index c7176c3b0d7712e15c23c3ff190e42b73991183a..b7072b2df375b5ab3e10548d8c1947b6b67fcedb 100644 (file)
@@ -121,6 +121,7 @@ static void misc_control_init(struct device *dev)
        cmd = pci_read_config32(dev, 0x44);
        cmd |= (1<<6) | (1<<25);
        pci_write_config32(dev, 0x44, cmd );
+#if K8_REV_F_SUPPORT == 0
        if (is_cpu_pre_c0()) {
 
                /* Errata 58
@@ -177,6 +178,7 @@ static void misc_control_init(struct device *dev)
                        needs_reset = 1; /* Needed? */
                }
        }
+#endif
        /* Optimize the Link read pointers */
        f0_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3);
        if (f0_dev) {
index c36990dea75c206ce92abf96ecb988ddcd8f9e8e..a91c54a7236ab4797452b92fa87313df59fb4111 100644 (file)
 
 #include "amdk8.h"
 
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
 #include <cpu/amd/model_fxx_rev.h>
 #endif
 
+#include <cpu/amd/amdk8_sysconf.h>
+
+struct amdk8_sysconf_t sysconf;
+
 #define FX_DEVS 8
 static device_t __f0_dev[FX_DEVS];
 static device_t __f1_dev[FX_DEVS];
@@ -97,8 +101,6 @@ static unsigned int amdk8_nodeid(device_t dev)
        return (dev->path.u.pci.devfn >> 3) - 0x18;
 }
 
-unsigned hcdn_reg[4]; // it will be used by get_sblk_pci1234
-
 static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned link, unsigned sblink, unsigned int max, unsigned offset_unitid)
 {
 #if 0
@@ -160,17 +162,17 @@ static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned lin
                 * We have no idea how many busses are behind this bridge yet,
                 * so we set the subordinate bus number to 0xff for the moment.
                 */
-#if K8_SB_HT_CHAIN_ON_BUS0 > 0
+#if SB_HT_CHAIN_ON_BUS0 > 0
                 // first chain will on bus 0
                if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
                         min_bus = max;
                 } 
-       #if K8_SB_HT_CHAIN_ON_BUS0 > 1
+       #if SB_HT_CHAIN_ON_BUS0 > 1
                // second chain will be on 0x40, third 0x80, forth 0xc0
                 else {
-                        min_bus = ((max>>6) + 1) * 0x40;
+                        min_bus = ((max>>6) + 1) * 0x40; 
                 }
-               max = min_bus;
+                max = min_bus;
         #else
                 //other ...
                 else  {
@@ -248,7 +250,7 @@ static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned lin
                                temp |= (ht_unitid_base[i] & 0xff) << (i*8);
                        }
 
-                       hcdn_reg[index] = temp;
+                       sysconf.hcdn_reg[index] = temp;
 
                }
 
@@ -277,7 +279,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
 
         if(nodeid==0) {
                 sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
-#if K8_SB_HT_CHAIN_ON_BUS0 > 0
+#if SB_HT_CHAIN_ON_BUS0 > 0
        #if HT_CHAIN_UNITID_BASE != 1
                 offset_unitid = 1;
         #endif
@@ -286,7 +288,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
         }
 
         for(link = 0; link < dev->links; link++) {
-#if K8_SB_HT_CHAIN_ON_BUS0 > 0
+#if SB_HT_CHAIN_ON_BUS0 > 0
                if( (nodeid == 0) && (sblink == link) ) continue; //already done
 #endif
                offset_unitid = 0;
@@ -773,7 +775,7 @@ static uint32_t find_pci_tolm(struct bus *bus)
 #define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
 #endif
 
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
 
 struct hw_mem_hole_info {
        unsigned hole_startk;
@@ -785,7 +787,7 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void)
                struct hw_mem_hole_info mem_hole;
                int i;
 
-                mem_hole.hole_startk = K8_HW_MEM_HOLE_SIZEK;
+                mem_hole.hole_startk = HW_MEM_HOLE_SIZEK;
                mem_hole.node_id = -1;
 
                 for (i = 0; i < 8; i++) {
@@ -931,7 +933,7 @@ static void pci_domain_set_resources(device_t dev)
        unsigned long mmio_basek;
        uint32_t pci_tolm;
        int i, idx;
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
        struct hw_mem_hole_info mem_hole;
        unsigned reset_memhole = 1;
 #endif
@@ -1015,12 +1017,14 @@ static void pci_domain_set_resources(device_t dev)
        mmio_basek &= ~((64*1024) - 1);
 #endif
 
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
     /* if the hw mem hole is already set in raminit stage, here we will compare mmio_basek and hole_basek
      * if mmio_basek is bigger that hole_basek and will use hole_basek as mmio_basek and we don't need to reset hole.
      * otherwise We reset the hole to the mmio_basek
      */
+    #if K8_REV_F_SUPPORT == 0
         if (!is_cpu_pre_e0()) {
+    #endif
 
                mem_hole = get_hw_mem_hole_info();
 
@@ -1032,13 +1036,13 @@ static void pci_domain_set_resources(device_t dev)
                //mmio_basek = 3*1024*1024; // for debug to meet boundary
 
                if(reset_memhole) {
-                       if(mem_hole.node_id!=-1) { // We need to select K8_HW_MEM_HOLE_SIZEK for raminit, it can not make hole_startk to some basek too....!
+                       if(mem_hole.node_id!=-1) { // We need to select HW_MEM_HOLE_SIZEK for raminit, it can not make hole_startk to some basek too....!
                               // We need to reset our Mem Hole, because We want more big HOLE than we already set
                               //Before that We need to disable mem hole at first, becase memhole could already be set on i+1 instead
                                disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
                        }
 
-               #if K8_HW_MEM_HOLE_SIZE_AUTO_INC == 1
+               #if HW_MEM_HOLE_SIZE_AUTO_INC == 1
                        //We need to double check if the mmio_basek is valid for hole setting, if it is equal to basek, we need to decrease it some
                        uint32_t basek_pri; 
                        for (i = 0; i < 8; i++) {
@@ -1059,7 +1063,9 @@ static void pci_domain_set_resources(device_t dev)
                #endif  
                }
 
+#if K8_REV_F_SUPPORT == 0
        } // is_cpu_pre_e0
+#endif
 
 #endif
 
@@ -1098,9 +1104,11 @@ static void pci_domain_set_resources(device_t dev)
                                        idx += 0x10;
                                        sizek -= pre_sizek;
                                }
-                               #if K8_HW_MEM_HOLE_SIZEK != 0
+                               #if HW_MEM_HOLE_SIZEK != 0
                                if(reset_memhole) 
+                                       #if K8_REV_F_SUPPORT == 0
                                        if(!is_cpu_pre_e0() ) 
+                                       #endif
                                                         sizek += hoist_memory(mmio_basek,i);
                                #endif
                                
@@ -1139,7 +1147,6 @@ static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
                f0_dev = __f0_dev[i];
                if (f0_dev && f0_dev->enabled) {
                        uint32_t httc;
-                       int j;
                        httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
                        httc &= ~HTTC_RSP_PASS_PW;
                        if (!dev->link[0].disable_relaxed_ordering) {
@@ -1169,24 +1176,20 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
        struct bus *cpu_bus;
        device_t dev_mc;
        int bsp_apicid;
-       int apicid_offset;
        int i,j;
-       int nodes;
        unsigned nb_cfg_54;
-       int enable_apic_ext_id;
        unsigned siblings;
        int e0_later_single_core; 
        int disable_siblings;
-       unsigned lift_bsp_apicid;
 
        nb_cfg_54 = 0;
-       enable_apic_ext_id = 0;
-       lift_bsp_apicid = 0;
+       sysconf.enabled_apic_ext_id = 0;
+       sysconf.lift_bsp_apicid = 0;
        siblings = 0;
 
        /* Find the bootstrap processors apicid */
        bsp_apicid = lapicid();
-       apicid_offset = bsp_apicid;
+       sysconf.apicid_offset = bsp_apicid;
 
        disable_siblings = !CONFIG_LOGICAL_CPUS;
 #if CONFIG_LOGICAL_CPUS == 1
@@ -1203,24 +1206,25 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
                die("0:18.0 not found?");
        }
 
-       nodes = ((pci_read_config32(dev_mc, 0x60)>>4) & 7) + 1;
+       sysconf.nodes = ((pci_read_config32(dev_mc, 0x60)>>4) & 7) + 1;
+       
 
        if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
        {
-               enable_apic_ext_id = 1;
+               sysconf.enabled_apic_ext_id = 1;
                if(bsp_apicid == 0) {
                        /* bsp apic id is not changed */
-                       apicid_offset = APIC_ID_OFFSET;
+                       sysconf.apicid_offset = APIC_ID_OFFSET;
                } else 
                {
-                       lift_bsp_apicid = 1;
+                       sysconf.lift_bsp_apicid = 1;
                }       
                
        }
 
        /* Find which cpus are present */
        cpu_bus = &dev->link[0];
-       for(i = 0; i < nodes; i++) {
+       for(i = 0; i < sysconf.nodes; i++) {
                device_t dev, cpu;
                struct device_path cpu_path;
 
@@ -1262,7 +1266,11 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
                                // That is the typical case
 
                                if(j == 0 ){
+                                      #if K8_REV_F_SUPPORT == 0
                                        e0_later_single_core = is_e0_later_in_bsp(i);  // single core 
+                                      #else
+                                       e0_later_single_core = is_cpu_f0_in_bsp(i);  // We can read cpuid(1) from Func3
+                                      #endif
                                } else {
                                       e0_later_single_core = 0;
                                        }
@@ -1321,13 +1329,13 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
                        if (cpu) {
                                cpu->path.u.apic.node_id = i;
                                cpu->path.u.apic.core_id = j;
-                                if(enable_apic_ext_id) {
-                                       if(lift_bsp_apicid) { 
-                                               cpu->path.u.apic.apic_id += apicid_offset;
+                                if(sysconf.enabled_apic_ext_id) {
+                                       if(sysconf.lift_bsp_apicid) { 
+                                               cpu->path.u.apic.apic_id += sysconf.apicid_offset;
                                        } else 
                                        {
                                                if (cpu->path.u.apic.apic_id != 0) 
-                                                       cpu->path.u.apic.apic_id += apicid_offset;
+                                                       cpu->path.u.apic.apic_id += sysconf.apicid_offset;
                                         }
                                }
                                printk_debug("CPU: %s %s\n",
index 2141b31843d61621760161e00e1b044bf9cdff5c..f7a12e77f8502ef90692a05f4b8e19a473d085dc 100644 (file)
@@ -18,7 +18,7 @@
 #define K8_4RANK_DIMM_SUPPORT 0
 #endif
 
-#if USE_DCACHE_RAM == 1
+#if defined (__GNUC__)
 static void hard_reset(void);
 #endif
 
@@ -44,8 +44,8 @@ static void setup_resource_map(const unsigned int *register_values, int max)
                print_debug("\r\n");
        #endif
 #endif
-               dev = register_values[i] & ~0xff;
-               where = register_values[i] & 0xff;
+               dev = register_values[i] & ~0xfff;
+               where = register_values[i] & 0xfff;
                reg = pci_read_config32(dev, where);
                reg &= register_values[i+1];
                reg |= register_values[i+2];
@@ -555,8 +555,8 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
                print_spew("\r\n");
        #endif
 #endif
-               dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x18, 0) + ctrl->f0;
-               where = register_values[i] & 0xff;
+               dev = (register_values[i] & ~0xfff) - PCI_DEV(0, 0x18, 0) + ctrl->f0;
+               where = register_values[i] & 0xfff;
                reg = pci_read_config32(dev, where);
                reg &= register_values[i+1];
                reg |= register_values[i+2];
@@ -886,7 +886,7 @@ static void set_top_mem(unsigned tom_k, unsigned hole_startk)
 
        /* Now set top of memory */
        msr_t msr;
-       if(tom_k>(4*1024*1024)) {
+       if(tom_k > (4*1024*1024)) {
                msr.lo = (tom_k & 0x003fffff) << 10;
                msr.hi = (tom_k & 0xffc00000) >> 22;
                wrmsr(TOP_MEM2, msr);
@@ -896,7 +896,7 @@ static void set_top_mem(unsigned tom_k, unsigned hole_startk)
         * so I can see my rom chip and other I/O devices.
         */
        if (tom_k >= 0x003f0000) {
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
                 if(hole_startk != 0) {
                         tom_k = hole_startk;
                 } else
@@ -2183,7 +2183,7 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl)
        return;
 }
 
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
 static uint32_t hoist_memory(int controllers, const struct mem_controller *ctrl,unsigned hole_startk, int i)
 {
         int ii;
@@ -2242,9 +2242,9 @@ static void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl)
         uint32_t hole_startk;
         int i;
 
-        hole_startk = 4*1024*1024 - K8_HW_MEM_HOLE_SIZEK;
+        hole_startk = 4*1024*1024 - HW_MEM_HOLE_SIZEK;
 
-#if K8_HW_MEM_HOLE_SIZE_AUTO_INC == 1 
+#if HW_MEM_HOLE_SIZE_AUTO_INC == 1 
         //We need to double check if the hole_startk is valid, if it is equal to basek, we need to decrease it some
         uint32_t basek_pri;
         for(i=0; i<controllers; i++) {
@@ -2388,7 +2388,7 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
                print_debug(" done\r\n");
        }
 
-#if K8_HW_MEM_HOLE_SIZEK != 0
+#if HW_MEM_HOLE_SIZEK != 0
          // init hw mem hole here
         /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
        if(!is_cpu_pre_e0())
@@ -2450,6 +2450,10 @@ static int mem_inited(int controllers, const struct mem_controller *ctrl)
 
 }
 #if USE_DCACHE_RAM == 1
+static void set_sysinfo_in_ram(unsigned val)
+{
+}
+
 static void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a, const uint16_t *spd_addr)
 {
         int i;
index 157dd13ee330281862d123513de12611485b2343..f46e58defe5421a23e5982ca3eb9f4d54a64ccde 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef RAMINIT_H
 #define RAMINIT_H
 
+#define NODE_NUMS 8
+
 #define DIMM_SOCKETS 4
 struct mem_controller {
        unsigned node_id;
@@ -9,5 +11,4 @@ struct mem_controller {
        uint16_t channel1[DIMM_SOCKETS];
 };
 
-
 #endif /* RAMINIT_H */
diff --git a/src/northbridge/amd/amdk8/raminit_f.c b/src/northbridge/amd/amdk8/raminit_f.c
new file mode 100644 (file)
index 0000000..3c83410
--- /dev/null
@@ -0,0 +1,3065 @@
+/*     This should be done by Eric
+       2004.11 yhlu add 4 rank DIMM support
+       2004.12 yhlu add D0 support
+       2005.02 yhlu add E0 memory hole support
+       2005.10 yhlu make it support DDR2 only
+*/
+
+#include <cpu/x86/mem.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/tsc.h>
+
+#include "raminit.h"
+#include "amdk8_f.h"
+#include "spd_ddr2.h"
+
+#ifndef QRANK_DIMM_SUPPORT
+#define QRANK_DIMM_SUPPORT 0
+#endif
+
+static inline void print_raminit(const char *strval, uint32_t val)
+{
+#if CONFIG_USE_INIT
+        printk_debug("%s:%08x\r\n", strval, val);
+#else
+        print_debug(strval); print_debug_hex32(val); print_debug("\r\n");
+#endif
+}
+
+#define RAM_TIMING_DEBUG 0
+
+static inline void print_tx(const char *strval, uint32_t val)
+{
+#if RAM_TIMING_DEBUG == 1
+       print_raminit(strval, val);
+#endif
+}
+
+
+static inline void print_t(const char *strval)
+{
+#if RAM_TIMING_DEBUG == 1
+        print_debug(strval); 
+#endif
+}
+
+
+
+#if (CONFIG_LB_MEM_TOPK & (CONFIG_LB_MEM_TOPK -1)) != 0
+# error "CONFIG_LB_MEM_TOPK must be a power of 2"
+#endif
+
+#include "amdk8_f_pci.c"
+
+
+       // for PCI_ADDR(0, 0x18, 2, 0x98) index, and PCI_ADDR(0x, 0x18, 2, 0x9c) data
+       /*
+               index: 
+               [29: 0] DctOffset (Dram Controller Offset)
+               [30:30] DctAccessWrite (Dram Controller Read/Write Select)      
+                       0 = read access
+                       1 = write access
+               [31:31] DctAccessDone (Dram Controller Access Done)
+                       0 = Access in progress
+                       1 = No access is progress
+
+               Data:
+               [31: 0] DctOffsetData (Dram Controller Offset Data)
+               
+               Read:
+                       - Write the register num to DctOffset with DctAccessWrite = 0
+                       - poll the DctAccessDone until it = 1
+                       - Read the data from DctOffsetData
+               Write:
+                       - Write the data to DctOffsetData
+                       - Write register num to DctOffset with DctAccessWrite = 1
+                       - poll the DctAccessDone untio it = 1
+               
+       */
+
+
+#if 1
+static void setup_resource_map(const unsigned int *register_values, int max)
+{
+       int i;
+
+       for(i = 0; i < max; i += 3) {
+               device_t dev;
+               unsigned where;
+               unsigned long reg;
+
+               dev = register_values[i] & ~0xff;
+               where = register_values[i] & 0xff;
+               reg = pci_read_config32(dev, where);
+               reg &= register_values[i+1];
+               reg |= register_values[i+2];
+               pci_write_config32(dev, where, reg);
+       }
+}
+#endif
+
+static int controller_present(const struct mem_controller *ctrl)
+{
+        return pci_read_config32(ctrl->f0, 0) == 0x11001022;
+}
+
+static void sdram_set_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo)
+{
+       static const unsigned int register_values[] = {
+
+       /* Careful set limit registers before base registers which contain the enables */
+       /* DRAM Limit i Registers
+        * F1:0x44 i = 0
+        * F1:0x4C i = 1
+        * F1:0x54 i = 2
+        * F1:0x5C i = 3
+        * F1:0x64 i = 4
+        * F1:0x6C i = 5
+        * F1:0x74 i = 6
+        * F1:0x7C i = 7
+        * [ 2: 0] Destination Node ID
+        *         000 = Node 0
+        *         001 = Node 1
+        *         010 = Node 2
+        *         011 = Node 3
+        *         100 = Node 4
+        *         101 = Node 5
+        *         110 = Node 6
+        *         111 = Node 7
+        * [ 7: 3] Reserved
+        * [10: 8] Interleave select
+        *         specifies the values of A[14:12] to use with interleave enable.
+        * [15:11] Reserved
+        * [31:16] DRAM Limit Address i Bits 39-24
+        *         This field defines the upper address bits of a 40 bit  address
+        *         that define the end of the DRAM region.
+        */
+       PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
+       PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
+       PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
+       PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
+       PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
+       PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
+       PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
+       /* DRAM Base i Registers
+        * F1:0x40 i = 0
+        * F1:0x48 i = 1
+        * F1:0x50 i = 2
+        * F1:0x58 i = 3
+        * F1:0x60 i = 4
+        * F1:0x68 i = 5
+        * F1:0x70 i = 6
+        * F1:0x78 i = 7
+        * [ 0: 0] Read Enable
+        *         0 = Reads Disabled
+        *         1 = Reads Enabled
+        * [ 1: 1] Write Enable
+        *         0 = Writes Disabled
+        *         1 = Writes Enabled
+        * [ 7: 2] Reserved
+        * [10: 8] Interleave Enable
+        *         000 = No interleave
+        *         001 = Interleave on A[12] (2 nodes)
+        *         010 = reserved
+        *         011 = Interleave on A[12] and A[14] (4 nodes)
+        *         100 = reserved
+        *         101 = reserved
+        *         110 = reserved
+        *         111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
+        * [15:11] Reserved
+        * [13:16] DRAM Base Address i Bits 39-24
+        *         This field defines the upper address bits of a 40-bit address
+        *         that define the start of the DRAM region.
+        */
+       PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
+
+       /* DRAM CS Base Address i Registers
+        * F2:0x40 i = 0
+        * F2:0x44 i = 1
+        * F2:0x48 i = 2
+        * F2:0x4C i = 3
+        * F2:0x50 i = 4
+        * F2:0x54 i = 5
+        * F2:0x58 i = 6
+        * F2:0x5C i = 7
+        * [ 0: 0] Chip-Select Bank Enable
+        *         0 = Bank Disabled
+        *         1 = Bank Enabled
+        * [ 1: 1] Spare Rank
+        * [ 2: 2] Memory Test Failed
+        * [ 4: 3] Reserved
+        * [13: 5] Base Address (21-13)
+        *         An optimization used when all DIMM are the same size...
+        * [18:14] Reserved
+        * [28:19] Base Address (36-27)
+        *         This field defines the top 11 addresses bit of a 40-bit
+        *         address that define the memory address space.  These
+        *         bits decode 32-MByte blocks of memory.
+        * [31:29] Reserved
+        */
+       PCI_ADDR(0, 0x18, 2, 0x40), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x44), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x48), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x4C), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x50), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x54), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x58), 0xe007c018, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x5C), 0xe007c018, 0x00000000,
+       /* DRAM CS Mask Address i Registers
+        * F2:0x60 i = 0,1
+        * F2:0x64 i = 2,3
+        * F2:0x68 i = 4,5
+        * F2:0x6C i = 6,7
+        * Select bits to exclude from comparison with the DRAM Base address register.
+        * [ 4: 0] Reserved
+        * [13: 5] Address Mask (21-13)
+        *         Address to be excluded from the optimized case
+        * [18:14] Reserved
+        * [28:19] Address Mask (36-27)
+        *         The bits with an address mask of 1 are excluded from address comparison
+        * [31:29] Reserved
+        * 
+        */
+       PCI_ADDR(0, 0x18, 2, 0x60), 0xe007c01f, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x64), 0xe007c01f, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x68), 0xe007c01f, 0x00000000,
+       PCI_ADDR(0, 0x18, 2, 0x6C), 0xe007c01f, 0x00000000,
+
+        /* DRAM Control Register
+         * F2:0x78
+         * [ 3: 0] RdPtrInit ( Read Pointer Initial Value)
+        *      0x03-0x00: reserved
+        * [ 6: 4] RdPadRcvFifoDly (Read Delay from Pad Receive FIFO)
+        *      000 = reserved
+        *      001 = reserved
+        *      010 = 1.5 Memory Clocks
+        *      011 = 2 Memory Clocks
+        *      100 = 2.5 Memory Clocks
+        *      101 = 3 Memory Clocks
+        *      110 = 3.5 Memory Clocks
+        *      111 = Reseved
+         * [15: 7] Reserved
+         * [16:16] AltVidC3MemClkTriEn (AltVID Memory Clock Tristate Enable)
+        *      Enables the DDR memory clocks to be tristated when alternate VID mode is enabled. This bit has no effect if the DisNbClkRamp bit (F3, 0x88) is set
+        * [17:17] DllTempAdjTime (DLL Temperature Adjust Cycle Time)
+        *      0 = 5 ms
+        *      1 = 1 ms
+        * [18:18] DqsRcvEnTrain (DQS Receiver Enable Training Mode)
+        *      0 = Normal DQS Receiver enable operation
+        *      1 = DQS receiver enable training mode
+         * [31:19] reverved
+        */
+        PCI_ADDR(0, 0x18, 2, 0x78), 0xfff80000, (6<<4)|(6<<0),
+
+        /* DRAM Initialization Register
+         * F2:0x7C
+         * [15: 0] MrsAddress (Address for MRS/EMRS Commands)
+         *      this field specifies the dsata driven on the DRAM address pins 15-0 for MRS and EMRS commands
+         * [18:16] MrsBank (Bank Address for MRS/EMRS Commands)
+        *      this files specifies the data driven on the DRAM bank pins for the MRS and EMRS commands
+        * [23:19] reverved
+         * [24:24] SendPchgAll (Send Precharge All Command)
+        *      Setting this bit causes the DRAM controller to send a precharge all command. This bit is cleared by the hardware after the command completes
+        * [25:25] SendAutoRefresh (Send Auto Refresh Command)
+        *      Setting this bit causes the DRAM controller to send an auto refresh command. This bit is cleared by the hardware after the command completes
+        * [26:26] SendMrsCmd (Send MRS/EMRS Command)
+        *      Setting this bit causes the DRAM controller to send the MRS or EMRS command defined by the MrsAddress and MrsBank fields. This bit is cleared by the hardware adter the commmand completes
+        * [27:27] DeassertMemRstX (De-assert Memory Reset)
+        *      Setting this bit causes the DRAM controller to de-assert the memory reset pin. This bit cannot be used to assert the memory reset pin
+        * [28:28] AssertCke (Assert CKE)
+        *      setting this bit causes the DRAM controller to assert the CKE pins. This bit cannot be used to de-assert the CKE pins
+        * [30:29] reverved
+        * [31:31] EnDramInit (Enable DRAM Initialization)
+        *      Setting this bit puts the DRAM controller in a BIOS controlled DRAM initialization mode. BIOS must clear this bit aster DRAM initialization is complete.
+        */
+//        PCI_ADDR(0, 0x18, 2, 0x7C), 0x60f80000, 0, 
+
+
+       /* DRAM Bank Address Mapping Register
+        * F2:0x80
+        * Specify the memory module size
+        * [ 3: 0] CS1/0 
+        * [ 7: 4] CS3/2
+        * [11: 8] CS5/4
+        * [15:12] CS7/6
+        * [31:16]
+             row    col   bank
+         0:  13     9      2    :128M
+         1:  13     10     2    :256M
+         2:  14     10     2    :512M
+         3:  13     11     2    :512M
+         4:  13     10     3    :512M
+         5:  14     10     3    :1G
+         6:  14     11     2    :1G
+         7:  15     10     3    :2G
+         8:  14     11     3    :2G
+         9:  15     11     3    :4G
+        10:  16     10     3    :4G
+        11:  16     11     3    :8G
+       */
+       PCI_ADDR(0, 0x18, 2, 0x80), 0xffff0000, 0x00000000,
+       /* DRAM Timing Low Register
+        * F2:0x88
+        * [ 2: 0] Tcl (Cas# Latency, Cas# to read-data-valid)
+        *         000 = reserved
+        *         001 = reserved
+        *         010 = CL 3
+        *         011 = CL 4
+        *         100 = CL 5
+        *         101 = CL 6
+        *         110 = reserved
+        *         111 = reserved
+        * [ 3: 3] Reserved
+        * [ 5: 4] Trcd (Ras#-active to Cas# read/write delay)
+        *         00 = 3 clocks
+        *         01 = 4 clocks
+        *         10 = 5 clocks
+        *         11 = 6 clocks
+         * [ 7: 6] Reserved
+        * [ 9: 8] Trp (Row Precharge Time, Precharge-to-Active or Auto-Refresh)
+        *         00 = 3 clocks
+        *         01 = 4 clocks
+        *         10 = 5 clocks
+        *         11 = 6 clocks
+        * [10:10] Reserved
+        * [11:11] Trtp (Read to Precharge Time, read Cas# to precharge time)
+        *         0 = 2 clocks for Burst Length of 32 Bytes
+        *             4 clocks for Burst Length of 64 Bytes
+         *         1 = 3 clocks for Burst Length of 32 Bytes
+         *             5 clocks for Burst Length of 64 Bytes
+        * [15:12] Tras (Minimum Ras# Active Time)
+         *         0000 = reserved
+        *         0001 = reserved
+         *         0010 = 5 bus clocks
+         *         ...
+         *         1111 = 18 bus clocks
+        * [19:16] Trc (Row Cycle Time, Ras#-active to Ras#-active or auto refresh of the same bank)
+        *         0000 = 11 bus clocks
+        *         0010 = 12 bus clocks
+         *        ...
+        *         1110 = 25 bus clocks
+        *         1111 = 26 bus clocks
+        * [21:20] Twr (Write Recovery Time, From the last data to precharge, writes can go back-to-back) 
+         *         00 = 3 bus clocks
+         *         01 = 4 bus clocks
+         *         10 = 5 bus clocks
+         *         11 = 6 bus clocks
+         * [23:22] Trrd (Active-to-active (Ras#-to-Ras#) Delay of different banks)
+         *         00 = 2 bus clocks
+         *         01 = 3 bus clocks
+         *         10 = 4 bus clocks
+         *         11 = 5 bus clocks
+        * [31:24] MemClkDis ( Disable the MEMCLK outputs for DRAM channel A, BIOS should set it to reduce the power consumption)
+         *         Bit         F(1207)         M2 Package      S1g1 Package
+        *          0           N/A             MA1_CLK1        N/A
+        *          1           N/A             MA0_CLK1        MA0_CLK1
+         *         2           MA3_CLK         N/A             N/A
+        *          3           MA2_CLK         N/A             N/A
+        *          4           MA1_CLK         MA1_CLK0        N/A
+        *          5           MA0_CLK         MA0_CLK0        MA0_CLK0
+        *          6           N/A             MA1_CLK2        N/A
+        *          7           N/A             MA0_CLK2        MA0_CLK2
+        */
+       PCI_ADDR(0, 0x18, 2, 0x88), 0x000004c8, 0xff000002 /* 0x03623125 */ ,
+       /* DRAM Timing High Register
+        * F2:0x8C
+        * [ 3: 0] Reserved
+        * [ 6: 4] TrwtTO (Read-to-Write Turnaround for Data, DQS Contention)
+        *         000 = 2 bus clocks
+        *         001 = 3 bus clocks
+        *         010 = 4 bus clocks
+        *         011 = 5 bus clocks
+        *         100 = 6 bus clocks
+        *         101 = 7 bus clocks
+        *         110 = 8 bus clocks
+        *         111 = 9 bus clocks
+        * [ 7: 7] Reserved
+        * [ 9: 8] Twtr (Internal DRAM Write-to-Read Command Delay, minium write-to-read delay when both access the same chip select)
+         *         00 = Reserved
+         *         01 = 1 bus clocks
+         *         10 = 2 bus clocks
+         *         11 = 3 bus clocks
+        * [11:10] Twrrd (Write to Read DIMM Termination Turnaround, minimum write-to-read delay when accessing two different DIMMs)
+         *         00 = 0 bus clocks
+         *         01 = 1 bus clocks
+         *         10 = 2 bus clocks
+         *         11 = 3 bus clocks
+         * [13:12] Twrwr (Write to Write Timing)
+         *         00 = 1 bus clocks ( 0 idle cycle on the bus)
+         *         01 = 2 bus clocks ( 1 idle cycle on the bus)
+         *         10 = 3 bus clocks ( 2 idle cycles on the bus)
+         *         11 = Reserved
+         * [15:14] Trdrd ( Read to Read Timing)
+         *         00 = 2 bus clocks ( 1 idle cycle on the bus)
+         *         01 = 3 bus clocks ( 2 idle cycles on the bus)
+         *         10 = 4 bus clocks ( 3 idle cycles on the bus)
+         *         11 = 5 bus clocks ( 4 idel cycles on the bus)
+         * [17:16] Tref (Refresh Rate)
+         *         00 = Undefined behavior
+         *         01 = Reserved
+         *         10 = Refresh interval of 7.8 microseconds
+         *         11 = Refresh interval of 3.9 microseconds
+        * [19:18] Reserved
+        * [22:20] Trfc0 ( Auto-Refresh Row Cycle Time for the Logical DIMM0, based on DRAM density and speed)
+         *         000 = 75 ns (all speeds, 256Mbit)
+         *         001 = 105 ns (all speeds, 512Mbit)
+         *         010 = 127.5 ns (all speeds, 1Gbit)
+         *         011 = 195 ns (all speeds, 2Gbit)
+         *         100 = 327.5 ns (all speeds, 4Gbit)
+         *         101 = reserved
+         *         110 = reserved
+         *         111 = reserved
+        * [25:23] Trfc1 ( Auto-Refresh Row Cycle Time for the Logical DIMM1, based on DRAM density and speed)
+        * [28:26] Trfc2 ( Auto-Refresh Row Cycle Time for the Logical DIMM2, based on DRAM density and speed)
+        * [31:29] Trfc3 ( Auto-Refresh Row Cycle Time for the Logical DIMM3, based on DRAM density and speed)
+        */
+       PCI_ADDR(0, 0x18, 2, 0x8c), 0x000c008f, (2 << 16)|(1 << 8),
+       /* DRAM Config Low Register
+        * F2:0x90
+        * [ 0: 0] InitDram (Initialize DRAM)
+        *         1 = write 1 cause DRAM controller to execute the DRAM initialization, when done it read to 0
+        * [ 1: 1] ExitSelfRef ( Exit Self Refresh Command )
+        *         1 = write 1 causes the DRAM controller to bring the DRAMs out fo self refresh mode
+        * [ 3: 2] Reserved
+        * [ 5: 4] DramTerm (DRAM Termination)
+         *         00 = On die termination disabled
+         *         01 = 75 ohms
+         *         10 = 150 ohms
+         *         11 = 50 ohms
+        * [ 6: 6] Reserved
+        * [ 7: 7] DramDrvWeak ( DRAM Drivers Weak Mode)
+        *         0 = Normal drive strength mode.
+        *         1 = Weak drive strength mode
+        * [ 8: 8] ParEn (Parity Enable)
+        *         1 = Enable address parity computation output, PAR, and enables the parity error input, ERR
+         * [ 9: 9] SelfRefRateEn (Faster Self Refresh Rate Enable)
+         *         1 = Enable high temperature ( two times normal ) self refresh rate
+        * [10:10] BurstLength32 ( DRAM Burst Length Set for 32 Bytes)
+        *         0 = 64-byte mode
+        *         1 = 32-byte mode
+        * [11:11] Width128 ( Width of DRAM interface) 
+        *         0 = the controller DRAM interface is 64-bits wide
+        *         1 = the controller DRAM interface is 128-bits wide
+         * [12:12] X4Dimm (DIMM 0 is x4)
+         * [13:13] X4Dimm (DIMM 1 is x4)
+         * [14:14] X4Dimm (DIMM 2 is x4)
+         * [15:15] X4Dimm (DIMM 3 is x4)
+         *         0 = DIMM is not x4
+         *         1 = x4 DIMM present
+        * [16:16] UnBuffDimm ( Unbuffered DIMMs)
+        *         0 = Buffered DIMMs
+        *         1 = Unbuffered DIMMs
+        * [18:17] Reserved
+        * [19:19] DimmEccEn ( DIMM ECC Enable )
+                  1 =  ECC checking is being enabled for all DIMMs on the DRAM controller ( Through F3 0x44[EccEn])
+        * [31:20] Reserved
+        */
+       PCI_ADDR(0, 0x18, 2, 0x90), 0xfff6004c, 0x00000010,
+       /* DRAM Config High Register
+        * F2:0x94
+        * [ 0: 2] MemClkFreq ( Memory Clock Frequency)
+        *         000 = 200MHz
+        *         001 = 266MHz
+        *         010 = 333MHz
+         *        011 = reserved
+        *         1xx = reserved
+        * [ 3: 3] MemClkFreqVal (Memory Clock Freqency Valid)
+        *         1 = BIOS need to set the bit when setting up MemClkFreq to the proper value  
+        * [ 7: 4] MaxAsyncLat ( Maximum Asynchronous Latency)
+         *         0000 = 0 ns
+         *         ...
+         *         1111 = 15 ns
+         * [11: 8] Reserved
+         * [12:12] RDqsEn ( Read DQS Enable) This bit is only be set if x8 registered DIMMs are present in the system
+         *         0 = DM pins function as data mask pins
+         *         1 = DM pins function as read DQS pins
+         * [13:13] Reserved
+         * [14:14] DisDramInterface ( Disable the DRAM interface ) When this bit is set, the DRAM controller is disabled, and interface in low power state
+         *         0 = Enabled (default)
+         *         1 = Disabled
+         * [15:15] PowerDownEn ( Power Down Mode Enable ) 
+         *         0 = Disabled (default)
+         *         1 = Enabled
+         * [16:16] PowerDown ( Power Down Mode )
+         *         0 = Channel CKE Control
+         *         1 = Chip Select CKE Control
+         * [17:17] FourRankSODimm (Four Rank SO-DIMM) 
+         *         1 = this bit is set by BIOS to indicate that a four rank SO-DIMM is present
+         * [18:18] FourRankRDimm (Four Rank Registered DIMM)
+         *         1 = this bit is set by BIOS to indicate that a four rank registered DIMM is present
+        * [19:19] Reserved
+         * [20:20] SlowAccessMode (Slow Access Mode (2T Mode))
+         *         0 = DRAM address and control signals are driven for one MEMCLK cycle
+         *         1 = One additional MEMCLK of setup time is provided on all DRAM address and control signals except CS, CKE, and ODT; i.e., these signals are drivern for two MEMCLK cycles rather than one
+        * [21:21] Reserved
+         * [22:22] BankSwizzleMode ( Bank Swizzle Mode), 
+         *         0 = Disabled (default)
+         *         1 = Enabled
+         * [23:23] Reserved
+        * [27:24] DcqBypassMax ( DRAM Controller Queue Bypass Maximum)
+        *         0000 = No bypass; the oldest request is never bypassed
+        *         0001 = The oldest request may be bypassed no more than 1 time
+        *         ...
+        *         1111 = The oldest request may be bypassed no more than 15 times
+         * [31:28] FourActWindow ( Four Bank Activate Window) , not more than 4 banks in a 8 bank device are activated
+         *         0000 = No tFAW window restriction 
+         *         0001 = 8 MEMCLK cycles
+         *        0010 = 9 MEMCLK cycles
+         *         ...
+         *         1101 = 20 MEMCLK cycles
+        *         111x = reserved
+        */
+       PCI_ADDR(0, 0x18, 2, 0x94), 0x00a82f00,0x00008000,
+       /* DRAM Delay Line Register
+        * F2:0xa0
+        * [ 0: 0] MemClrStatus (Memory Clear Status) :    ---------Readonly 
+        *         when set, this bit indicates that the memory clear function is complete. Only clear by reset. BIOS should not write or read the DRAM until this bit is set by hardware
+        * [ 1: 1] DisableJitter ( Disable Jitter)
+        *         When set the DDR compensation circuit will not change the values unless the change is more than one step from the current value 
+        * [ 3: 2] RdWrQByp ( Read/Write Queue Bypass Count)
+        *         00 = 2
+        *         01 = 4
+        *         10 = 8
+        *         11 = 16
+        * [ 4: 4] Mode64BitMux (Mismatched DIMM Support Enable)
+        *         1 When bit enables support for mismatched DIMMs when using 128-bit DRAM interface, the Width128 no effect, only for M2 and s1g1
+        * [ 5: 5] DCC_EN ( Dynamica Idle Cycle Counter Enable)
+        *         When set to 1, indicates that each entry in the page tables dynamically adjusts the idle cycle limit based on page Conflict/Page Miss (PC/PM) traffic
+        * [ 8: 6] ILD_lmt ( Idle Cycle Limit)
+        *         000 = 0 cycles
+        *         001 = 4 cycles
+        *         010 = 8 cycles
+        *         011 = 16 cycles
+        *         100 = 32 cycles
+        *         101 = 64 cycles
+        *         110 = 128 cycles
+        *         111 = 256 cycles 
+        * [ 9: 9] DramEnabled ( DRAM Enabled)
+        *         When Set, this bit indicates that the DRAM is enabled, this bit is set by hardware after DRAM initialization or on an exit from self refresh. The DRAM controller is intialized after the
+        *         hardware-controlled initialization process ( initiated by the F2 0x90[DramInit]) completes or when the BIOS-controlled initialization process completes (F2 0x7c(EnDramInit] is 
+        *         written from 1 to 0)
+        * [23:10] Reserved
+         * [31:24] MemClkDis ( Disable the MEMCLK outputs for DRAM channel B, BIOS should set it to reduce the power consumption)
+         *         Bit          F(1207)         M2 Package      S1g1 Package
+         *          0           N/A             MA1_CLK1        N/A
+         *          1           N/A             MA0_CLK1        MA0_CLK1
+         *          2           MA3_CLK         N/A             N/A
+         *          3           MA2_CLK         N/A             N/A
+         *          4           MA1_CLK         MA1_CLK0        N/A
+         *          5           MA0_CLK         MA0_CLK0        MA0_CLK0
+         *          6           N/A             MA1_CLK2        N/A
+         *          7           N/A             MA0_CLK2        MA0_CLK2
+        */
+       PCI_ADDR(0, 0x18, 2, 0xa0), 0x00fffc00, 0xff000000, 
+
+       /* DRAM Scrub Control Register
+        * F3:0x58
+        * [ 4: 0] DRAM Scrube Rate
+        * [ 7: 5] reserved
+        * [12: 8] L2 Scrub Rate
+        * [15:13] reserved
+        * [20:16] Dcache Scrub
+        * [31:21] reserved
+        *         Scrub Rates
+        *         00000 = Do not scrub
+        *         00001 =  40.00 ns
+        *         00010 =  80.00 ns
+        *         00011 = 160.00 ns
+        *         00100 = 320.00 ns
+        *         00101 = 640.00 ns
+        *         00110 =   1.28 us
+        *         00111 =   2.56 us
+        *         01000 =   5.12 us
+        *         01001 =  10.20 us
+        *         01011 =  41.00 us
+        *         01100 =  81.90 us
+        *         01101 = 163.80 us
+        *         01110 = 327.70 us
+        *         01111 = 655.40 us
+        *         10000 =   1.31 ms
+        *         10001 =   2.62 ms
+        *         10010 =   5.24 ms
+        *         10011 =  10.49 ms
+        *         10100 =  20.97 ms
+        *         10101 =  42.00 ms
+        *         10110 =  84.00 ms
+        *         All Others = Reserved
+        */
+       PCI_ADDR(0, 0x18, 3, 0x58), 0xffe0e0e0, 0x00000000,
+       /* DRAM Scrub Address Low Register
+        * F3:0x5C
+        * [ 0: 0] DRAM Scrubber Redirect Enable
+        *         0 = Do nothing
+        *         1 = Scrubber Corrects errors found in normal operation
+        * [ 5: 1] Reserved
+        * [31: 6] DRAM Scrub Address 31-6
+        */
+       PCI_ADDR(0, 0x18, 3, 0x5C), 0x0000003e, 0x00000000,
+       /* DRAM Scrub Address High Register
+        * F3:0x60
+        * [ 7: 0] DRAM Scrubb Address 39-32
+        * [31: 8] Reserved
+        */
+       PCI_ADDR(0, 0x18, 3, 0x60), 0xffffff00, 0x00000000,
+       };
+       // for PCI_ADDR(0, 0x18, 2, 0x98) index, and PCI_ADDR(0x, 0x18, 2, 0x9c) data
+       /*
+               index: 
+               [29: 0] DctOffset (Dram Controller Offset)
+               [30:30] DctAccessWrite (Dram Controller Read/Write Select)      
+                       0 = read access
+                       1 = write access
+               [31:31] DctAccessDone (Dram Controller Access Done)
+                       0 = Access in progress
+                       1 = No access is progress
+
+               Data:
+               [31: 0] DctOffsetData (Dram Controller Offset Data)
+               
+               Read:
+                       - Write the register num to DctOffset with DctAccessWrite = 0
+                       - poll the DctAccessDone until it = 1
+                       - Read the data from DctOffsetData
+               Write:
+                       - Write the data to DctOffsetData
+                       - Write register num to DctOffset with DctAccessWrite = 1
+                       - poll the DctAccessDone untio it = 1
+               
+       */
+#if 0
+       static const unsigned int index_register_values[] = {
+       /* Output Driver Compensation Control Register
+        * Index: 0x00
+        * [ 1: 0] CkeDrvStren (CKE Drive Strength)
+        *      00 = 1.0x
+        *      01 = 1.25x
+        *      10 = 1.5x (Default)
+        *      11 = 2.0x
+        * [ 3: 2] reserved
+        * [ 5: 4] CsOdtDrvStren (CS/ODT Drive Strength)
+         *      00 = 1.0x
+         *      01 = 1.25x
+         *      10 = 1.5x (Default)
+         *      11 = 2.0x
+         * [ 7: 6] reserved
+        * [ 9: 8] AddrCmdDrvStren (Address/Command Drive Strength)
+         *      00 = 1.0x
+         *      01 = 1.25x
+         *      10 = 1.5x (Default)
+         *      11 = 2.0x
+         * [11:10] reserved
+        * [13:12] ClkDrvStren (MEMCLK Drive Strength)
+         *      00 = 0.75x
+         *      01 = 1.0x Default)
+         *      10 = 1.25x 
+         *      11 = 1.5x
+         * [15:14] reserved
+         * [17:16] DataDrvStren (Data Drive Strength)
+         *      00 = 0.75x
+         *      01 = 1.0x Default)
+         *      10 = 1.25x
+         *      11 = 1.5x
+         * [19:18] reserved
+         * [21:20] DqsDrvStren (DQS Drive Strength)
+         *      00 = 0.75x
+         *      01 = 1.0x Default)
+         *      10 = 1.25x
+         *      11 = 1.5x
+         * [27:22] reserved
+         * [29:28] ProcOdt ( Processor On-die Termination)
+         *      00 = 300 ohms +/- 20%
+         *      01 = 150 ohms +/- 20%
+         *      10 = 75 ohms +/- 20%
+         *      11 = reserved
+         * [31:30] reserved
+        */
+       0x00, 0xcfcccccc, 0x00000000, 
+       0x20, 0xcfcccccc, 0x00000000, 
+       /* Write Data Timing Low Control Register
+        * Index 0x01
+        * [ 5: 0] WrDatTimeByte0 (Write Data Byte 0 Timing Control)
+        *      000000 =  no delay
+        *      000001 = 1/96 MEMCLK delay
+        *      000010 = 2/96 MEMCLK delay
+        *      ...
+        *      101111 = 47/96 MEMCLK delay
+        *      11xxxx = reserved
+        * [ 7: 6] reserved
+         * [13: 8] WrDatTimeByte1 (Write Data Byte 1 Timing Control)
+         * [15:14] reserved
+         * [21:16] WrDatTimeByte2 (Write Data Byte 2 Timing Control)
+         * [23:22] reserved
+         * [29:24] WrDatTimeByte3 (Write Data Byte 3 Timing Control)
+         * [31:30] reserved
+        */
+       0x01, 0xc0c0c0c0, 0x00000000,
+       0x21, 0xc0c0c0c0, 0x00000000,
+       /* Write Data Timing High Control Register
+        * Index 0x02
+        * [ 5: 0] WrDatTimeByte4 (Write Data Byte 4 Timing Control)
+        * [ 7: 6] reserved
+         * [13: 8] WrDatTimeByte5 (Write Data Byte 5 Timing Control)
+         * [15:14] reserved
+         * [21:16] WrDatTimeByte6 (Write Data Byte 6 Timing Control)
+         * [23:22] reserved
+         * [29:24] WrDatTimeByte7 (Write Data Byte 7 Timing Control)
+         * [31:30] reserved
+        */
+       0x02, 0xc0c0c0c0, 0x00000000,
+       0x22, 0xc0c0c0c0, 0x00000000,
+
+       /* Write Data ECC Timing Control Register
+        * Index 0x03
+        * [ 5: 0] WrChkTime (Write Data ECC Timing Control)
+        *      000000 =  no delay
+        *      000001 = 1/96 MEMCLK delay
+        *      000010 = 2/96 MEMCLK delay
+        *      ...
+        *      101111 = 47/96 MEMCLK delay
+        *      11xxxx = reserved
+         * [31: 6] reserved
+        */
+       0x03, 0x000000c0, 0x00000000,
+       0x23, 0x000000c0, 0x00000000,
+
+       /* Address Timing Control Register
+        * Index 0x04
+        * [ 4: 0] CkeFineDelay (CKE Fine Delay)
+        *      00000 =  no delay
+        *      00001 = 1/64 MEMCLK delay
+        *      00010 = 2/64 MEMCLK delay
+        *      ...
+        *      11111 = 31/64 MEMCLK delay
+        * [ 5: 5] CkeSetup (CKE Setup Time)
+        *      0 = 1/2 MEMCLK
+        *      1 = 1 MEMCLK
+         * [ 7: 6] reserved
+        * [12: 8] CsOdtFineDelay (CS/ODT Fine Delay)
+        *      00000 =  no delay
+        *      00001 = 1/64 MEMCLK delay
+        *      00010 = 2/64 MEMCLK delay
+        *      ...
+        *      11111 = 31/64 MEMCLK delay
+        * [13:13] CsOdtSetup (CS/ODT Setup Time)
+        *      0 = 1/2 MEMCLK
+        *      1 = 1 MEMCLK
+         * [15:14] reserved
+        * [20:16] AddrCmdFineDelay (Address/Command Fine Delay)
+        *      00000 =  no delay
+        *      00001 = 1/64 MEMCLK delay
+        *      00010 = 2/64 MEMCLK delay
+        *      ...
+        *      11111 = 31/64 MEMCLK delay
+        * [21:21] AddrCmdSetup (Address/Command Setup Time)
+        *      0 = 1/2 MEMCLK
+        *      1 = 1 MEMCLK
+         * [31:22] reserved
+        */
+       0x04, 0xffc0c0c0, 0x00000000,
+       0x24, 0xffc0c0c0, 0x00000000,
+
+       /* Read DQS Timing Low Control Register
+        * Index 0x05
+        * [ 5: 0] RdDqsTimeByte0 (Read DQS Byte 0 Timing Control)
+        *      000000 =  no delay
+        *      000001 = 1/96 MEMCLK delay
+        *      000010 = 2/96 MEMCLK delay
+        *      ...
+        *      101111 = 47/96 MEMCLK delay
+        *      11xxxx = reserved
+        * [ 7: 6] reserved
+         * [13: 8] RdDqsTimeByte1 (Read DQS Byte 1 Timing Control)
+         * [15:14] reserved
+         * [21:16] RdDqsTimeByte2 (Read DQS Byte 2 Timing Control)
+         * [23:22] reserved
+         * [29:24] RdDqsTimeByte3 (Read DQS Byte 3 Timing Control)
+         * [31:30] reserved
+        */
+       0x05, 0xc0c0c0c0, 0x00000000,
+       0x25, 0xc0c0c0c0, 0x00000000,
+
+       /* Read DQS Timing High Control Register
+        * Index 0x06
+        * [ 5: 0] RdDqsTimeByte4 (Read DQS Byte 4 Timing Control)
+        * [ 7: 6] reserved
+         * [13: 8] RdDqsTimeByte5 (Read DQS Byte 5 Timing Control)
+         * [15:14] reserved
+         * [21:16] RdDqsTimeByte6 (Read DQS Byte 6 Timing Control)
+         * [23:22] reserved
+         * [29:24] RdDqsTimeByte7 (Read DQS Byte 7 Timing Control)
+         * [31:30] reserved
+        */
+       0x06, 0xc0c0c0c0, 0x00000000,
+       0x26, 0xc0c0c0c0, 0x00000000,
+
+       /* Read DQS ECC Timing Control Register
+        * Index 0x07
+        * [ 5: 0] RdDqsTimeCheck (Read DQS ECC Timing Control)
+        *      000000 =  no delay
+        *      000001 = 1/96 MEMCLK delay
+        *      000010 = 2/96 MEMCLK delay
+        *      ...
+        *      101111 = 47/96 MEMCLK delay
+        *      11xxxx = reserved
+         * [31: 6] reserved
+        */
+       0x07, 0x000000c0, 0x00000000,
+       0x27, 0x000000c0, 0x00000000,
+
+       /* DQS Receiver Enable Timing Control Register
+        * Index 0x10, 0x13, 0x16, 0x19,
+        * [ 7: 0] Dqs RcvEnDelay (DQS Receiver Enable Delay)
+        *      0x00 =  0 ps
+        *      0x01 = 50 ps
+        *      0x02 = 100 ps
+        *      ...
+        *      0xae = 8.7 ns
+        *      0xaf-0xff = reserved
+         * [31: 6] reserved
+        */
+       0x10, 0x000000ff, 0x00000000,
+       0x13, 0x000000ff, 0x00000000,
+       0x16, 0x000000ff, 0x00000000,
+       0x19, 0x000000ff, 0x00000000,
+       0x30, 0x000000ff, 0x00000000,
+       0x33, 0x000000ff, 0x00000000,
+       0x36, 0x000000ff, 0x00000000,
+       0x39, 0x000000ff, 0x00000000,
+       };
+#endif
+
+       int i;
+       int max;
+
+#if 1
+        if (!controller_present(ctrl)) {
+//                print_debug("No memory controller present\r\n");
+               sysinfo->ctrl_present[ctrl->node_id] = 0;
+                return;
+        }
+#endif
+       sysinfo->ctrl_present[ctrl->node_id] = 1;
+       
+       print_spew("setting up CPU");
+       print_spew_hex8(ctrl->node_id);
+       print_spew(" northbridge registers\r\n");
+       max = sizeof(register_values)/sizeof(register_values[0]);
+       for(i = 0; i < max; i += 3) {
+               device_t dev;
+               unsigned where;
+               unsigned long reg;
+               dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x18, 0) + ctrl->f0;
+               where = register_values[i] & 0xff;
+               reg = pci_read_config32(dev, where);
+               reg &= register_values[i+1];
+               reg |= register_values[i+2];
+               pci_write_config32(dev, where, reg);
+       }
+
+#if 0
+       // for index regs
+       max = sizeof(index_register_values)/sizeof(index_register_values[0]);
+       for(i = 0; i < max; i += 3) {
+               unsigned long reg;
+               unsigned index;
+               index = register_values[i];
+               reg = pci_read_config32_index_wait(ctrl->f2, DRAM_CTRL_ADDI_DATA_OFFSET, index);
+               reg &= register_values[i+1];
+               reg |= register_values[i+2];
+               pci_write_config32_index_wait(ctrl->f2, DRAM_CTRL_ADDI_DATA_OFFSET, index, reg);
+       }
+#endif
+
+       print_spew("done.\r\n");
+}
+
+static int is_dual_channel(const struct mem_controller *ctrl)
+{
+       uint32_t dcl;
+       dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+       return dcl & DCL_Width128;
+}
+
+static int is_registered(const struct mem_controller *ctrl)
+{
+       /* Test to see if we are dealing with registered SDRAM.
+        * If we are not registered we are unbuffered.
+        * This function must be called after spd_handle_unbuffered_dimms.
+        */
+       uint32_t dcl;
+       dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+       return !(dcl & DCL_UnBuffDimm);
+}
+
+static void spd_get_dimm_size(unsigned device, struct dimm_size *sz)
+{
+       /* Calculate the log base 2 size of a DIMM in bits */
+       int value;
+       sz->per_rank = 0;
+       sz->rows = 0;
+       sz->col = 0;
+       sz->rank = 0;
+
+       value = spd_read_byte(device, SPD_ROW_NUM);     /* rows */
+       if (value < 0) goto hw_err;
+       if ((value & 0xff) == 0) goto val_err; // max is 16 ?
+       sz->per_rank += value & 0xff;
+       sz->rows = value & 0xff;
+
+       value = spd_read_byte(device, SPD_COL_NUM);     /* columns */
+       if (value < 0) goto hw_err;
+       if ((value & 0xff) == 0) goto val_err;  //max is 11
+       sz->per_rank += value & 0xff;
+       sz->col = value & 0xff;
+
+       value = spd_read_byte(device, SPD_BANK_NUM);    /* banks */
+       if (value < 0) goto hw_err;
+       if ((value & 0xff) == 0) goto val_err;
+       sz->bank = log2(value & 0xff);  // convert 4 to 2, and 8 to 3
+       sz->per_rank += sz->bank;
+
+       /* Get the module data width and convert it to a power of two */
+       value = spd_read_byte(device, SPD_DATA_WIDTH);  
+       if (value < 0) goto hw_err;
+       value &= 0xff;
+       if ((value != 72) && (value != 64)) goto val_err;
+       sz->per_rank += log2(value) - 3; //64 bit So another 3 lines
+
+       /* How many ranks? */
+       value = spd_read_byte(device, SPD_MOD_ATTRIB_RANK);     /* number of physical banks */
+       if (value < 0) goto hw_err;
+//     value >>= SPD_MOD_ATTRIB_RANK_NUM_SHIFT;
+       value &= SPD_MOD_ATTRIB_RANK_NUM_MASK;
+       value += SPD_MOD_ATTRIB_RANK_NUM_BASE; // 0-->1, 1-->2, 3-->4
+       /*
+         rank == 1 only one rank or say one side
+         rank == 2 two side , and two ranks
+         rank == 4 two side , and four ranks total
+         Some one side two ranks, because of stacked
+       */
+       if ((value != 1) && (value != 2) && (value != 4 )) {
+               goto val_err;
+       }
+       sz->rank = value;
+
+       /* verify if per_rank is equal byte 31 
+         it has the DIMM size as a multiple of 128MB.
+         */
+        value = spd_read_byte(device, SPD_RANK_SIZE);
+        if (value < 0) goto hw_err;
+        value &= 0xff;
+       value = log2(value);
+       if(value <=4 ) value += 8; // add back to 1G to high
+       value += (27-5); // make 128MB to the real lines
+       if( value != (sz->per_rank)) { 
+               print_err("Bad RANK Size --\r\n");
+               goto val_err;
+       }
+
+       goto out;
+
+ val_err:
+       die("Bad SPD value\r\n");
+       /* If an hw_error occurs report that I have no memory */
+hw_err:
+       sz->per_rank = 0;
+       sz->rows = 0;
+       sz->col = 0;
+       sz->bank = 0;
+       sz->rank = 0;
+ out:
+       return;
+}
+
+static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size *sz, unsigned index, int is_Width128)
+{
+       uint32_t base0, base1;
+
+
+       /* For each base register.
+        * Place the dimm size in 32 MB quantities in the bits 31 - 21.
+        * The initialize dimm size is in bits.
+        * Set the base enable bit0.
+        */
+       
+       base0 = base1 = 0;
+
+       /* Make certain side1 of the dimm is at least 128MB */
+       if (sz->per_rank >= 27) {
+               base0 = (1 << ((sz->per_rank - 27 ) + 19)) | 1;
+       }
+       
+       /* Make certain side2 of the dimm is at least 128MB */
+       if (sz->rank > 1) { // 2 ranks or 4 ranks
+               base1 = (1 << ((sz->per_rank - 27 ) + 19)) | 1;
+       }
+
+       /* Double the size if we are using dual channel memory */
+       if (is_Width128) {
+               base0 = (base0 << 1) | (base0 & 1);
+               base1 = (base1 << 1) | (base1 & 1);
+       }
+
+       /* Clear the reserved bits */
+       base0 &= ~0xe007fffe;
+       base1 &= ~0xe007fffe;
+
+       /* Set the appropriate DIMM base address register */
+       pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), base0);
+       pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), base1);
+#if QRANK_DIMM_SUPPORT == 1
+       if(sz->rank == 4) {
+               pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+4)<<2), base0);
+               pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+5)<<2), base1);
+       }
+#endif
+
+       /* Enable the memory clocks for this DIMM by Clear the MemClkDis bit*/
+       if (base0) {
+               uint32_t dword;
+               uint32_t ClkDis0;
+#if CPU_SOCKET_TYPE == 0x10 /* L1 */
+               ClkDis0 = DTL_MemClkDis0;
+#else 
+       #if CPU_SOCKET_TYPE == 0x11 /* AM2 */
+               ClkDis0 = DTL_MemClkDis0_AM2;
+       #endif
+#endif 
+
+               dword = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW); //Channel A
+               dword &= ~(ClkDis0 >> index);
+#if QRANK_DIMM_SUPPORT == 1
+               if(sz->rank == 4) {
+                       dword &= ~(ClkDis0 >> (index+2));
+               }
+#endif
+               pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dword);
+       
+               if (is_Width128) { //Channel B  
+                       dword = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
+                       dword &= ~(ClkDis0 >> index);
+#if QRANK_DIMM_SUPPORT == 1
+                       if(sz->rank == 4) {
+                               dword &= ~(ClkDis0 >> (index+2));
+                       }
+#endif
+                       pci_write_config32(ctrl->f2, DRAM_CTRL_MISC, dword);
+               }
+
+       }
+}
+
+/*    row    col   bank  for 64 bit
+  0:  13     9      2    :128M
+  1:  13     10     2    :256M
+  2:  14     10     2    :512M
+  3:  13     11     2    :512M
+  4:  13     10     3    :512M
+  5:  14     10     3    :1G
+  6:  14     11     2    :1G
+  7:  15     10     3    :2G
+  8:  14     11     3    :2G
+  9:  15     11     3    :4G
+ 10:  16     10     3    :4G
+ 11:  16     11     3    :8G
+*/
+
+static void set_dimm_cs_map(const struct mem_controller *ctrl, struct dimm_size *sz, unsigned index)
+{
+       static const uint8_t cs_map_aaa[24] = {
+               /* (bank=2, row=13, col=9)(3, 16, 11) ---> (0, 0, 0) (1, 3, 2) */
+       //Bank2
+               0, 1, 3,
+               0, 2, 6,
+               0, 0, 0,
+               0, 0, 0,
+       //Bank3
+               0, 4, 0,
+               0, 5, 8,
+               0, 7, 9,
+               0,10,11,
+       };
+
+        uint32_t map;
+
+        map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
+        map &= ~(0xf << (index * 4));
+#if QRANK_DIMM_SUPPORT == 1
+        if(sz->rank == 4) {
+                map &= ~(0xf << ( (index + 2) * 4));
+        }
+#endif
+
+        /* Make certain side1 of the dimm is at least 128MB */
+        if (sz->per_rank >= 27) {
+                unsigned temp_map;
+                temp_map = cs_map_aaa[(sz->bank-2)*3*4 + (sz->rows - 13)*3 + (sz->col - 9) ];
+                map |= temp_map << (index*4);
+#if QRANK_DIMM_SUPPORT == 1
+                if(sz->rank == 4) {
+                       map |=  temp_map << ( (index + 2) * 4);
+                }
+#endif
+        }
+
+        pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);
+
+}
+
+static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask, struct mem_info *meminfo)
+{
+       int i;
+       
+       for(i = 0; i < DIMM_SOCKETS; i++) {
+               struct dimm_size *sz = &(meminfo->sz[i]);
+               if (!(dimm_mask & (1 << i))) {
+                       continue;
+               }
+               spd_get_dimm_size(ctrl->channel0[i], sz);
+               if (sz->per_rank == 0) {
+                       return -1; /* Report SPD error */
+               }
+               set_dimm_size(ctrl, sz, i, meminfo->is_Width128);
+               set_dimm_cs_map (ctrl, sz, i);
+       }
+       return dimm_mask;
+}
+
+static void route_dram_accesses(const struct mem_controller *ctrl,
+       unsigned long base_k, unsigned long limit_k)
+{
+       /* Route the addresses to the controller node */
+       unsigned node_id;
+       unsigned limit;
+       unsigned base;
+       unsigned index;
+       unsigned limit_reg, base_reg;
+       device_t device;
+
+       node_id = ctrl->node_id;
+       index = (node_id << 3);
+       limit = (limit_k << 2);
+       limit &= 0xffff0000;
+       limit -= 0x00010000;
+       limit |= ( 0 << 8) | (node_id << 0);
+       base = (base_k << 2);
+       base &= 0xffff0000;
+       base |= (0 << 8) | (1<<1) | (1<<0);
+
+       limit_reg = 0x44 + index;
+       base_reg = 0x40 + index;
+       for(device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device += PCI_DEV(0, 1, 0)) {
+               pci_write_config32(device, limit_reg, limit);
+               pci_write_config32(device, base_reg, base);
+       }
+}
+
+static void set_top_mem(unsigned tom_k, unsigned hole_startk)
+{
+       /* Error if I don't have memory */
+       if (!tom_k) {
+               die("No memory?");
+       }
+
+       /* Report the amount of memory. */
+       print_debug("RAM: 0x");
+       print_debug_hex32(tom_k);
+       print_debug(" KB\r\n");
+
+       msr_t msr;
+       if(tom_k > (4*1024*1024)) {
+               /* Now set top of memory */
+               msr.lo = (tom_k & 0x003fffff) << 10;
+               msr.hi = (tom_k & 0xffc00000) >> 22;
+               wrmsr(TOP_MEM2, msr);
+       }
+
+       /* Leave a 64M hole between TOP_MEM and TOP_MEM2
+        * so I can see my rom chip and other I/O devices.
+        */
+       if (tom_k >= 0x003f0000) {
+#if HW_MEM_HOLE_SIZEK != 0
+               if(hole_startk != 0) {
+                       tom_k = hole_startk;
+               } else
+#endif
+               tom_k = 0x3f0000;
+       }
+       msr.lo = (tom_k & 0x003fffff) << 10;
+       msr.hi = (tom_k & 0xffc00000) >> 22;
+       wrmsr(TOP_MEM, msr);
+}
+
+static unsigned long interleave_chip_selects(const struct mem_controller *ctrl, int is_Width128)
+{
+       /* 35 - 27 */
+
+        static const uint8_t csbase_low_f0_shift[] = {
+        /* 128MB */       (14 - (13-5)),
+        /* 256MB */       (15 - (13-5)),
+        /* 512MB */       (15 - (13-5)),
+       /* 512MB */       (16 - (13-5)),
+        /* 512MB */       (16 - (13-5)),
+        /* 1GB   */       (16 - (13-5)),
+        /* 1GB   */       (16 - (13-5)),
+        /* 2GB   */       (16 - (13-5)),
+        /* 2GB   */       (17 - (13-5)),
+       /* 4GB   */       (17 - (13-5)),
+        /* 4GB   */       (16 - (13-5)),
+       /* 8GB   */       (17 - (13-5)),
+        };
+
+       /* cs_base_high is not changed */
+
+       uint32_t csbase_inc;
+       int chip_selects, index;
+       int bits;
+       unsigned common_size;
+       unsigned common_cs_mode;
+       uint32_t csbase, csmask;
+
+       /* See if all of the memory chip selects are the same size
+        * and if so count them.
+        */
+       chip_selects = 0;
+       common_size = 0;
+       common_cs_mode = 0xff;
+       for(index = 0; index < 8; index++) {
+               unsigned size;
+               unsigned cs_mode;
+               uint32_t value;
+               
+               value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
+               
+               /* Is it enabled? */
+               if (!(value & 1)) {
+                       continue;
+               }
+               chip_selects++;
+               size = (value >> 19) & 0x3ff;
+               if (common_size == 0) {
+                       common_size = size;
+               }
+               /* The size differed fail */
+               if (common_size != size) {
+                       return 0;
+               }
+
+               value = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
+                cs_mode =( value >> ((index>>1)*4)) & 0xf;
+                if(common_cs_mode == 0xff) {
+                       common_cs_mode = cs_mode;
+                }
+                /* The cs_mode differed fail */
+                if(common_cs_mode != cs_mode) {
+                        return 0;
+                }
+       }
+
+       /* Chip selects can only be interleaved when there is
+        * more than one and their is a power of two of them.
+        */
+       bits = log2(chip_selects);
+       if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) { //chip_selects max = 8
+               return 0;
+       }
+
+       /* Find the bits of csbase that we need to interleave on */
+       csbase_inc = 1 << (csbase_low_f0_shift[common_cs_mode]);
+       if(is_Width128) {
+               csbase_inc <<=1;
+        }   
+       
+
+       /* Compute the initial values for csbase and csbask. 
+        * In csbase just set the enable bit and the base to zero.
+        * In csmask set the mask bits for the size and page level interleave.
+        */
+       csbase = 0 | 1;
+       csmask = (((common_size  << bits) - 1) << 19);
+       csmask |= 0x3fe0 & ~((csbase_inc << bits) - csbase_inc);
+       for(index = 0; index < 8; index++) {
+               uint32_t value;
+
+               value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
+               /* Is it enabled? */
+               if (!(value & 1)) {
+                       continue;
+               }
+               pci_write_config32(ctrl->f2, DRAM_CSBASE + (index << 2), csbase);
+               if((index & 1) == 0) {  //only have 4 CSMASK
+                       pci_write_config32(ctrl->f2, DRAM_CSMASK + ((index>>1) << 2), csmask);
+               }
+               csbase += csbase_inc;
+       }
+       
+       print_debug("Interleaved\r\n");
+
+       /* Return the memory size in K */ 
+       return common_size << ((27-10) + bits);
+}
+static unsigned long order_chip_selects(const struct mem_controller *ctrl)
+{
+       unsigned long tom;
+
+       /* Remember which registers we have used in the high 8 bits of tom */
+       tom = 0;
+       for(;;) {
+               /* Find the largest remaining canidate */
+               unsigned index, canidate;
+               uint32_t csbase, csmask;
+               unsigned size;
+               csbase = 0;
+               canidate = 0;
+               for(index = 0; index < 8; index++) {
+                       uint32_t value;
+                       value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
+
+                       /* Is it enabled? */
+                       if (!(value & 1)) {
+                               continue;
+                       }
+                       
+                       /* Is it greater? */
+                       if (value <= csbase) {
+                               continue;
+                       }
+                       
+                       /* Has it already been selected */
+                       if (tom & (1 << (index + 24))) {
+                               continue;
+                       }
+                       /* I have a new canidate */
+                       csbase = value;
+                       canidate = index;
+               }
+               /* See if I have found a new canidate */
+               if (csbase == 0) {
+                       break;
+               }
+
+               /* Remember the dimm size */
+               size = csbase >> 19;
+
+               /* Remember I have used this register */
+               tom |= (1 << (canidate + 24));
+
+               /* Recompute the cs base register value */
+               csbase = (tom << 19) | 1;
+
+               /* Increment the top of memory */
+               tom += size;
+
+               /* Compute the memory mask */
+               csmask = ((size -1) << 19);
+               csmask |= 0x3fe0;               /* For now don't optimize */
+
+               /* Write the new base register */
+               pci_write_config32(ctrl->f2, DRAM_CSBASE + (canidate << 2), csbase);
+               /* Write the new mask register */
+                if((canidate & 1) == 0) {  //only have 4 CSMASK
+                        pci_write_config32(ctrl->f2, DRAM_CSMASK + ((canidate>>1) << 2), csmask);
+                }
+               
+       }
+       /* Return the memory size in K */ 
+       return (tom & ~0xff000000) << (27-10);
+}
+
+unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id)
+{
+       unsigned node_id;
+       unsigned end_k;
+       /* Find the last memory address used */
+       end_k = 0;
+       for(node_id = 0; node_id < max_node_id; node_id++) {
+               uint32_t limit, base;
+               unsigned index;
+               index = node_id << 3;
+               base = pci_read_config32(ctrl->f1, 0x40 + index);
+               /* Only look at the limit if the base is enabled */
+               if ((base & 3) == 3) {
+                       limit = pci_read_config32(ctrl->f1, 0x44 + index);
+                       end_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
+               }
+       }
+       return end_k;
+}
+
+static void order_dimms(const struct mem_controller *ctrl, struct mem_info *meminfo)
+{
+       unsigned long tom_k, base_k;
+
+       if (read_option(CMOS_VSTART_interleave_chip_selects, CMOS_VLEN_interleave_chip_selects, 1) != 0) {
+               tom_k = interleave_chip_selects(ctrl, meminfo->is_Width128);
+       } else {
+               print_debug("Interleaving disabled\r\n");
+               tom_k = 0;
+       }
+       if (!tom_k) {
+               tom_k = order_chip_selects(ctrl);
+       }
+       /* Compute the memory base address */
+       base_k = memory_end_k(ctrl, ctrl->node_id);
+       tom_k += base_k;
+       route_dram_accesses(ctrl, base_k, tom_k);
+       set_top_mem(tom_k, 0);
+}
+
+static long disable_dimm(const struct mem_controller *ctrl, unsigned index, long dimm_mask, struct mem_info *meminfo)
+{
+       print_debug("disabling dimm"); 
+       print_debug_hex8(index); 
+       print_debug("\r\n");
+       pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), 0);
+       pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), 0);
+#if QRANK_DIMM_SUPPORT == 1
+        if(meminfo->sz[index].rank == 4) {
+                pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+4)<<2), 0);
+                pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+5)<<2), 0);
+        }
+#endif
+
+       dimm_mask &= ~(1 << index);
+       return dimm_mask;
+}
+
+static long spd_handle_unbuffered_dimms(const struct mem_controller *ctrl, long dimm_mask, struct mem_info *meminfo)
+{
+       int i;
+       uint32_t registered;
+       uint32_t dcl;
+       registered = 0;
+       for(i = 0; (i < DIMM_SOCKETS); i++) {
+               int value;
+               if (!(dimm_mask & (1 << i))) {
+                       continue;
+               }
+               value = spd_read_byte(ctrl->channel0[i], SPD_DIMM_TYPE);
+               if (value < 0) {
+                       return -1;
+               }
+               /* Registered dimm ? */
+               value &= 0x3f;
+               if ((value == SPD_DIMM_TYPE_RDIMM) || (value == SPD_DIMM_TYPE_mRDIMM)) {
+                       //check SPD_MOD_ATTRIB to verify it is SPD_MOD_ATTRIB_REGADC (0x11)?
+                       registered |= (1<<i);
+               } 
+       }
+
+       dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+       dcl &= ~DCL_UnBuffDimm;
+       meminfo->is_registered = 1;
+       if (!registered) {
+               dcl |= DCL_UnBuffDimm;
+               meminfo->is_registered = 0;
+       }
+       pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
+       
+#if 1
+       if (meminfo->is_registered) {
+               print_debug("Registered\r\n");
+       } else {
+               print_debug("Unbuffered\r\n");
+       }
+#endif
+       return dimm_mask;
+}
+
+static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
+{
+       unsigned dimm_mask;
+       int i;
+       dimm_mask = 0;
+       for(i = 0; i < DIMM_SOCKETS; i++) {
+               int byte;
+               unsigned device;
+               device = ctrl->channel0[i];
+               if (device) {
+                       byte = spd_read_byte(ctrl->channel0[i], SPD_MEM_TYPE);  /* Type */
+                       if (byte == SPD_MEM_TYPE_SDRAM_DDR2) {
+                               dimm_mask |= (1 << i);
+                       }
+               }
+               device = ctrl->channel1[i];
+               if (device) {
+                       byte = spd_read_byte(ctrl->channel1[i], SPD_MEM_TYPE);
+                       if (byte == SPD_MEM_TYPE_SDRAM_DDR2) {
+                               dimm_mask |= (1 << (i + DIMM_SOCKETS));
+                       }
+               }
+       }
+       return dimm_mask;
+}
+
+static long spd_enable_2channels(const struct mem_controller *ctrl, long dimm_mask, struct mem_info *meminfo)
+{
+       int i;
+       uint32_t nbcap;
+       /* SPD addresses to verify are identical */
+       static const uint8_t addresses[] = {
+               2,      /* Type should be DDR2 SDRAM */
+               3,      /* *Row addresses */
+               4,      /* *Column addresses */
+               5,      /* *Number of DIMM Ranks */
+               6,      /* *Module Data Width*/
+               9,      /* *Cycle time at highest CAS Latency CL=X */
+               11,     /* *DIMM Conf Type */
+               13,     /* *Pri SDRAM Width */
+               17,     /* *Logical Banks */
+               18,     /* *Supported CAS Latencies */
+               20,     /* *DIMM Type Info */
+               21,     /* *SDRAM Module Attributes */
+               23,     /* *Cycle time at CAS Latnecy (CLX - 1) */
+               26,     /* *Cycle time at CAS Latnecy (CLX - 2) */
+               27,     /* *tRP Row precharge time */
+               28,     /* *Minimum Row Active to Row Active Delay (tRRD) */
+               29,     /* *tRCD RAS to CAS */
+               30,     /* *tRAS Activate to Precharge */
+               36,     /* *Write recovery time (tWR) */
+               37,     /* *Internal write to read command delay (tRDP) */
+               38,     /* *Internal read to precharge commanfd delay (tRTP) */
+               41,     /* *Extension of Byte 41 tRC and Byte 42 tRFC */
+               41,     /* *Minimum Active to Active/Auto Refresh Time(Trc) */
+               42,     /* *Minimum Auto Refresh Command Time(Trfc) */
+       };
+       /* If the dimms are not in pairs do not do dual channels */
+       if ((dimm_mask & ((1 << DIMM_SOCKETS) - 1)) !=
+               ((dimm_mask >> DIMM_SOCKETS) & ((1 << DIMM_SOCKETS) - 1))) { 
+               goto single_channel;
+       }
+       /* If the cpu is not capable of doing dual channels don't do dual channels */
+       nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
+       if (!(nbcap & NBCAP_128Bit)) {
+               goto single_channel;
+       }
+       for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
+               unsigned device0, device1;
+               int value0, value1;
+               int j;
+               /* If I don't have a dimm skip this one */
+               if (!(dimm_mask & (1 << i))) {
+                       continue;
+               }
+               device0 = ctrl->channel0[i];
+               device1 = ctrl->channel1[i];
+               for(j = 0; j < sizeof(addresses)/sizeof(addresses[0]); j++) {
+                       unsigned addr;
+                       addr = addresses[j];
+                       value0 = spd_read_byte(device0, addr);
+                       if (value0 < 0) {
+                               return -1;
+                       }
+                       value1 = spd_read_byte(device1, addr);
+                       if (value1 < 0) {
+                               return -1;
+                       }
+                       if (value0 != value1) {
+                               goto single_channel;
+                       }
+               }
+       }
+       print_spew("Enabling dual channel memory\r\n");
+       uint32_t dcl;
+       dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+       dcl &= ~DCL_BurstLength32;  /*  32byte mode may be preferred in platforms that include graphics controllers that generate a lot of 32-bytes system memory accesses
+                                       32byte mode is not supported when the DRAM interface is 128 bits wides, even 32byte mode is set, system still use 64 byte mode  */
+       dcl |= DCL_Width128;
+       pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
+       meminfo->is_Width128 = 1;
+       return dimm_mask;
+ single_channel:
+       dimm_mask &= ~((1 << (DIMM_SOCKETS *2)) - (1 << DIMM_SOCKETS));
+       meminfo->is_Width128 = 0;
+       return dimm_mask;
+}
+
+struct mem_param {
+       uint16_t cycle_time;
+       uint8_t divisor; /* In 1/40 ns increments */
+       uint8_t TrwtTO;
+        uint8_t Twrrd;
+        uint8_t Twrwr;
+        uint8_t Trdrd;
+        uint8_t DcqByPassMax;
+       uint32_t dch_memclk;
+       char name[9];
+};
+
+       static const struct mem_param speed[] = {
+               {
+                       .name       = "200Mhz\r\n",
+                       .cycle_time = 0x500,
+                       .divisor    = 200, // how many 1/40ns per clock 
+                       .dch_memclk = DCH_MemClkFreq_200MHz, //0
+                       .TrwtTO     = 7,
+                       .Twrrd      = 2,
+                       .Twrwr      = 2,
+                       .Trdrd      = 3,
+                       .DcqByPassMax = 4,
+
+               },
+               {
+                       .name       = "266Mhz\r\n",
+                       .cycle_time = 0x375,
+                       .divisor    = 150, //????
+                       .dch_memclk = DCH_MemClkFreq_266MHz, //1
+                        .TrwtTO     = 7,
+                        .Twrrd      = 2,
+                        .Twrwr      = 2,
+                        .Trdrd      = 3,
+                        .DcqByPassMax = 4,
+               },
+                {
+                        .name       = "333Mhz\r\n",
+                        .cycle_time = 0x300,
+                        .divisor    = 120,
+                        .dch_memclk = DCH_MemClkFreq_333MHz, //2
+                        .TrwtTO     = 7,
+                        .Twrrd      = 2,
+                        .Twrwr      = 2,
+                        .Trdrd      = 3,
+                        .DcqByPassMax = 4,
+
+                },
+               {
+                       .name       = "400Mhz\r\n",
+                       .cycle_time = 0x250,
+                       .divisor    = 100,
+                       .dch_memclk = DCH_MemClkFreq_400MHz,//3
+                        .TrwtTO     = 7,
+                        .Twrrd      = 2,
+                        .Twrwr      = 2,
+                        .Trdrd      = 3,
+                        .DcqByPassMax = 4,
+               },
+               {
+                       .cycle_time = 0x000,
+               },
+       };
+
+static const struct mem_param *get_mem_param(unsigned min_cycle_time)
+{
+
+       const struct mem_param *param;
+       for(param = &speed[0]; param->cycle_time ; param++) {
+               if (min_cycle_time > (param+1)->cycle_time) {
+                       break;
+               }
+       }
+       if (!param->cycle_time) {
+               die("min_cycle_time to low");
+       }
+       print_spew(param->name);
+#ifdef DRAM_MIN_CYCLE_TIME
+       print_debug(param->name);
+#endif
+       return param;
+}
+
+static uint8_t get_exact_divisor(int i, uint8_t divisor)
+{
+       //input divisor could be 200(200), 150(266), 120(333), 100 (400)
+       static const uint8_t dv_a[] = {
+              /* 200  266  333  400 */
+        /*4 */   250, 250, 250, 250,
+        /*5 */   200, 200, 200, 100,
+        /*6 */   200, 166, 166, 100,
+        /*7 */   200, 171, 142, 100,
+
+         /*8 */   200, 150, 125, 100,
+         /*9 */   200, 156, 133, 100,
+         /*10*/   200, 160, 120, 100,
+         /*11*/   200, 163, 127, 100,
+
+         /*12*/   200, 150, 133, 100,
+         /*13*/   200, 153, 123, 100,
+         /*14*/   200, 157, 128, 100,
+         /*15*/   200, 160, 120, 100,
+       }; 
+       
+       unsigned fid_cur;
+       int index;
+       
+       msr_t msr;
+       msr = rdmsr(0xc0010042);
+        fid_cur = msr.lo & 0x3f;
+
+       index = fid_cur>>1;
+
+       if(index>12) return divisor;
+
+       if(i>3) return divisor;
+
+       return dv_a[index * 4+i];
+
+}
+
+struct spd_set_memclk_result {
+       const struct mem_param *param;
+       long dimm_mask;
+};
+
+static unsigned convert_to_linear(unsigned value)
+{
+         static const unsigned fraction[] = { 0x25, 0x33, 0x66, 0x75 };
+         unsigned valuex;
+
+         /* We need to convert value to more readable */
+         if((value & 0xf) < 10) { //no .25, .33, .66, .75
+                value <<= 4;
+         } else {
+               valuex = ((value & 0xf0) << 4) | fraction [(value & 0xf)-10];
+                value = valuex;
+         }
+        return value;
+}
+
+static struct spd_set_memclk_result spd_set_memclk(const struct mem_controller *ctrl, long dimm_mask, struct mem_info *meminfo)
+{
+       /* Compute the minimum cycle time for these dimms */
+       struct spd_set_memclk_result result;
+       unsigned min_cycle_time, min_latency, bios_cycle_time;
+       int i;
+       uint32_t value;
+
+       static const uint8_t latency_indicies[] = { 25, 23, 9 };
+
+       static const uint16_t min_cycle_times[] = { // use full speed to compare
+               [NBCAP_MEMCLK_NOLIMIT] = 0x250, /*2.5ns */
+               [NBCAP_MEMCLK_333MHZ] = 0x300, /* 3.0ns */
+               [NBCAP_MEMCLK_266MHZ] = 0x375, /* 3.75ns */
+               [NBCAP_MEMCLK_200MHZ] = 0x500, /* 5.0s */
+       };
+
+
+       value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
+       min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
+       bios_cycle_time = min_cycle_times[
+               read_option(CMOS_VSTART_max_mem_clock, CMOS_VLEN_max_mem_clock, 0)];
+       if (bios_cycle_time > min_cycle_time) {
+               min_cycle_time = bios_cycle_time;
+       }
+       min_latency = 3; 
+
+        print_tx("1 min_cycle_time:", min_cycle_time); 
+
+       /* Compute the least latency with the fastest clock supported
+        * by both the memory controller and the dimms.
+        */
+       for(i = 0; i < DIMM_SOCKETS; i++) {
+               int new_cycle_time, new_latency;
+               int index;
+               int latencies;
+               int latency;
+
+               if (!(dimm_mask & (1 << i))) {
+                       continue;
+               }
+
+               /* First find the supported CAS latencies
+                * Byte 18 for DDR SDRAM is interpreted:
+                * bit 3 == CAS Latency = 3
+                * bit 4 == CAS Latency = 4
+                * bit 5 == CAS Latency = 5
+                * bit 6 == CAS Latency = 6
+                */
+               new_cycle_time = 0x500;
+               new_latency = 6;
+
+               latencies = spd_read_byte(ctrl->channel0[i], SPD_CAS_LAT);
+               if (latencies <= 0) continue;
+
+               print_tx("i:",i);
+               print_tx("\tlatencies:", latencies);
+               /* Compute the lowest cas latency supported */
+               latency = log2(latencies) - 2;
+
+               /* Loop through and find a fast clock with a low latency */
+               for(index = 0; index < 3; index++, latency++) {
+                       int value;
+                       if ((latency < 3) || (latency > 6) ||
+                               (!(latencies & (1 << latency)))) {
+                               continue;
+                       }
+                       value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
+                       if (value < 0) {
+                               goto hw_error;
+                       }
+                       print_tx("\tindex:", index);    
+                       print_tx("\t\tlatency:", latency); 
+                       print_tx("\t\tvalue1:", value);         
+
+                       value = convert_to_linear(value);
+
+                       print_tx("\t\tvalue2:", value); 
+
+                       /* Only increase the latency if we decreas the clock */
+                       if (value >= min_cycle_time ) {
+                               if(value < new_cycle_time) {
+                                       new_cycle_time = value;
+                                       new_latency = latency;
+                               } else if (value == new_cycle_time) {
+                                       if(new_latency > latency) {
+                                               new_latency = latency;
+                                       }
+                               }
+                       }
+                        print_tx("\t\tnew_cycle_time:", new_cycle_time);
+                        print_tx("\t\tnew_latency:", new_latency);
+
+               }
+               if (new_latency > 6){
+                       continue;
+               }
+               /* Does min_latency need to be increased? */
+               if (new_cycle_time > min_cycle_time) {
+                       min_cycle_time = new_cycle_time;
+               }
+               /* Does min_cycle_time need to be increased? */
+               if (new_latency > min_latency) {
+                       min_latency = new_latency;
+               }
+
+               print_tx("2 min_cycle_time:", min_cycle_time); 
+               print_tx("2 min_latency:", min_latency); 
+       }
+       /* Make a second pass through the dimms and disable
+        * any that cannot support the selected memclk and cas latency.
+        */
+
+       print_tx("3 min_cycle_time:", min_cycle_time); 
+       print_tx("3 min_latency:", min_latency); 
+       
+       for(i = 0; (i < DIMM_SOCKETS) && (ctrl->channel0[i]); i++) {
+               int latencies;
+               int latency;
+               int index;
+               int value;
+               if (!(dimm_mask & (1 << i))) {
+                       continue;
+               }
+               latencies = spd_read_byte(ctrl->channel0[i], SPD_CAS_LAT);
+               if (latencies < 0) goto hw_error;
+               if (latencies == 0) {
+                       continue;
+//                     goto dimm_err;
+               }
+
+               /* Compute the lowest cas latency supported */
+               latency = log2(latencies) -2;
+
+               /* Walk through searching for the selected latency */
+               for(index = 0; index < 3; index++, latency++) {
+                       if (!(latencies & (1 << latency))) {
+                               continue;
+                       }
+                       if (latency == min_latency)
+                               break;
+               }
+               /* If I can't find the latency or my index is bad error */
+               if ((latency != min_latency) || (index >= 3)) {
+                       goto dimm_err;
+               }
+       
+               /* Read the min_cycle_time for this latency */
+               value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
+               if (value < 0) goto hw_error;
+       
+               value = convert_to_linear(value);       
+               /* All is good if the selected clock speed 
+                * is what I need or slower.
+                */
+               if (value <= min_cycle_time) {
+                       continue;
+               }
+               /* Otherwise I have an error, disable the dimm */
+       dimm_err:
+               dimm_mask = disable_dimm(ctrl, i, dimm_mask, meminfo);
+       }
+
+       print_tx("4 min_cycle_time:", min_cycle_time); 
+       
+       /* Now that I know the minimum cycle time lookup the memory parameters */
+       result.param = get_mem_param(min_cycle_time);
+
+       /* Update DRAM Config High with our selected memory speed */
+       value = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+       value &= ~(DCH_MemClkFreq_MASK << DCH_MemClkFreq_SHIFT);
+
+       value |= result.param->dch_memclk << DCH_MemClkFreq_SHIFT;
+       pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
+
+       print_debug(result.param->name);
+
+       /* Update DRAM Timing Low with our selected cas latency */
+       value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
+       value &= ~(DTL_TCL_MASK << DTL_TCL_SHIFT);
+       value |= (min_latency - DTL_TCL_BASE)  << DTL_TCL_SHIFT;
+       pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, value);
+       
+       result.dimm_mask = dimm_mask;
+       return result;
+ hw_error:
+       result.param = (const struct mem_param *)0;
+       result.dimm_mask = -1;
+       return result;
+}
+
+static unsigned convert_to_1_4(unsigned value)
+{
+         static const uint8_t fraction[] = { 0, 1, 2, 2, 3, 3, 0 };
+         unsigned valuex;
+
+         /* We need to convert value to more readable */
+         valuex =  fraction [value & 0x7];
+         return valuex;
+}
+static int update_dimm_Trc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+       unsigned clocks, old_clocks;
+       uint32_t dtl;
+       int value;
+       int value2;
+       value = spd_read_byte(ctrl->channel0[i], SPD_TRC);
+       if (value < 0) return -1;
+
+               value2 = spd_read_byte(ctrl->channel0[i], SPD_TRC -1);
+               value <<= 2;
+               value += convert_to_1_4(value2>>4);
+
+       value *=10;
+
+       clocks = (value + param->divisor - 1)/param->divisor;
+       
+       if (clocks < DTL_TRC_MIN) {
+               clocks = DTL_TRC_MIN;
+       }
+       if (clocks > DTL_TRC_MAX) {
+               return 0;
+       }
+
+       dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
+       old_clocks = ((dtl >> DTL_TRC_SHIFT) & DTL_TRC_MASK) + DTL_TRC_BASE;
+       if (old_clocks >= clocks) {  //?? someone did it 
+               // clocks = old_clocks;
+               return 1;
+       }
+       dtl &= ~(DTL_TRC_MASK << DTL_TRC_SHIFT);
+       dtl |=  ((clocks - DTL_TRC_BASE) << DTL_TRC_SHIFT);
+       pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
+       return 1;
+}
+
+static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i, struct mem_info *meminfo)
+{
+       unsigned clocks, old_clocks;
+       uint32_t dth;
+       int value;
+
+#if 0
+       int value2;
+
+       value = spd_read_byte(ctrl->channel0[i], SPD_TRFC);
+       if (value < 0) return -1;
+
+        value2 = spd_read_byte(ctrl->channel0[i], SPD_TRC -1);
+       if(value2 & 1) value += 256;
+        value <<= 2;
+        value += convert_to_1_4(value2>>1);
+
+       if (value == 0) {
+               value = param->tRFC;
+       }
+       value *= 10;
+       clocks = (value + param->divisor - 1)/param->divisor;
+#endif
+       //get the cs_size --> logic dimm size
+       value = spd_read_byte(ctrl->channel0[i], SPD_PRI_WIDTH);
+        if (value < 0) {
+                return -1;
+        }
+
+       value = 6 - log2(value); //4-->4, 8-->3, 16-->2
+
+       clocks = meminfo->sz[i].per_rank - 27 + 2 - value;
+
+       dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
+
+       old_clocks = ((dth >> (DTH_TRFC0_SHIFT+i*3)) & DTH_TRFC_MASK);
+       if (old_clocks >= clocks) { // some one did it?
+//             clocks = old_clocks;
+               return 1;
+       }
+       dth &= ~(DTH_TRFC_MASK << (DTH_TRFC0_SHIFT+i*3));
+       dth |= clocks  << (DTH_TRFC0_SHIFT+i*3);
+       pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
+       return 1;
+}
+
+static int update_dimm_TT_1_4(const struct mem_controller *ctrl, const struct mem_param *param, int i, 
+                                       unsigned TT_REG, 
+                                       unsigned SPD_TT, unsigned TT_SHIFT, unsigned TT_MASK, unsigned TT_BASE, unsigned TT_MIN, unsigned TT_MAX )
+{
+        unsigned clocks, old_clocks;
+        uint32_t dtl;
+        int value;
+        value = spd_read_byte(ctrl->channel0[i], SPD_TT); //already in 1/4 ns
+        if (value < 0) return -1;
+       value *=10;
+        clocks = (value + param->divisor -1)/param->divisor;
+        if (clocks < TT_MIN) {
+                clocks = TT_MIN;
+        }
+        if (clocks > TT_MAX) {
+                return 0;
+        }
+        dtl = pci_read_config32(ctrl->f2, TT_REG);
+
+        old_clocks = ((dtl >> TT_SHIFT) & TT_MASK) + TT_BASE;
+        if (old_clocks >= clocks) { //some one did it?
+//              clocks = old_clocks;
+                return 1;
+        }
+        dtl &= ~(TT_MASK << TT_SHIFT);
+        dtl |= ((clocks - TT_BASE) << TT_SHIFT);
+        pci_write_config32(ctrl->f2, TT_REG, dtl);
+        return 1;
+}
+
+static int update_dimm_Trcd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+       return update_dimm_TT_1_4(ctrl, param, i, DRAM_TIMING_LOW, SPD_TRCD, DTL_TRCD_SHIFT, DTL_TRCD_MASK, DTL_TRCD_BASE, DTL_TRCD_MIN, DTL_TRCD_MAX);
+}
+
+static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+       return update_dimm_TT_1_4(ctrl, param, i, DRAM_TIMING_LOW, SPD_TRRD, DTL_TRRD_SHIFT, DTL_TRRD_MASK, DTL_TRRD_BASE, DTL_TRRD_MIN, DTL_TRRD_MAX);
+}
+
+static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+       unsigned clocks, old_clocks;
+       uint32_t dtl;
+       int value;
+       value = spd_read_byte(ctrl->channel0[i], SPD_TRAS); //in 1 ns
+       if (value < 0) return -1;
+       print_tx("update_dimm_Tras: 0 value=", value); 
+       
+       value<<=2; //convert it to in 1/4ns
+
+       value *= 10;
+       print_tx("update_dimm_Tras:  1 value=", value); 
+
+       clocks = (value  + param->divisor - 1)/param->divisor;
+       print_tx("update_dimm_Tras: divisor=", param->divisor); 
+       print_tx("update_dimm_Tras: clocks=", clocks); 
+       if (clocks < DTL_TRAS_MIN) {
+               clocks = DTL_TRAS_MIN;
+       }
+       if (clocks > DTL_TRAS_MAX) {
+               return 0;
+       }
+       dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
+       old_clocks = ((dtl >> DTL_TRAS_SHIFT) & DTL_TRAS_MASK) + DTL_TRAS_BASE;
+       if (old_clocks >= clocks) { // someone did it?
+//             clocks = old_clocks;
+               return 1;
+       }
+       dtl &= ~(DTL_TRAS_MASK << DTL_TRAS_SHIFT);
+       dtl |= ((clocks - DTL_TRAS_BASE) << DTL_TRAS_SHIFT);
+       pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
+       return 1;
+}
+
+static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+       return update_dimm_TT_1_4(ctrl, param, i, DRAM_TIMING_LOW, SPD_TRP, DTL_TRP_SHIFT, DTL_TRP_MASK, DTL_TRP_BASE, DTL_TRP_MIN, DTL_TRP_MAX);
+}
+
+static int update_dimm_Trtp(const struct mem_controller *ctrl, const struct mem_param *param, int i, struct mem_info *meminfo)
+{
+       //need to figure if it is 32 byte burst or 64 bytes burst
+       int offset = 2;
+       if(!meminfo->is_Width128) {
+               uint32_t dword;
+               dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+               if((dword &  DCL_BurstLength32)) offset = 0;
+       }
+        return update_dimm_TT_1_4(ctrl, param, i, DRAM_TIMING_LOW, SPD_TRTP, DTL_TRTP_SHIFT, DTL_TRTP_MASK, DTL_TRTP_BASE+offset, DTL_TRTP_MIN+offset, DTL_TRTP_MAX+offset);
+}
+
+
+static int update_dimm_Twr(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+       return update_dimm_TT_1_4(ctrl, param, i, DRAM_TIMING_LOW, SPD_TWR, DTL_TWR_SHIFT, DTL_TWR_MASK, DTL_TWR_BASE, DTL_TWR_MIN, DTL_TWR_MAX);
+}
+
+
+static int update_dimm_Tref(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+        uint32_t dth, dth_old;
+        int value;
+        value = spd_read_byte(ctrl->channel0[i], SPD_TREF); // 0: 15.625us, 1: 3.9us 2: 7.8 us....
+        if (value < 0) return -1;
+
+       if(value == 1 ) {
+               value = 3;
+       } else {
+               value = 2;
+       }
+
+       dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
+
+       dth_old = dth;
+       dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
+       dth |= (value << DTH_TREF_SHIFT);
+       if(dth_old != dth) {
+               pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
+       }
+       return 1;
+}
+
+static void set_4RankRDimm(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
+{
+#if QRANK_DIMM_SUPPRT == 1
+        int value;
+       int i;
+       
+
+       if(!(meminfo->is_registered)) return; 
+
+       value = 0;
+
+        for(i = 0; i < DIMM_SOCKETS; i++) {
+                if (!(dimm_mask & (1 << i))) {
+                        continue;
+                }
+
+               if(meminfo->sz.rank == 4) {
+                       value = 1;
+                       break;
+               }
+       }
+
+       if(value == 1) {
+               uint32_t dch;
+               dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+               dch |= DCH_FourRankRDimm;
+               pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
+       }
+#endif
+}
+
+
+static uint32_t get_extra_dimm_mask(const struct mem_controller *ctrl, struct mem_info *meminfo)
+{
+        int i;
+
+        uint32_t mask_x4;
+       uint32_t mask_x16;
+       uint32_t mask_single_rank;
+       uint32_t mask_page_1k;
+       int value;
+#if QRANK_DIMM_SUPPORT == 1
+        int rank;
+#endif
+
+       long dimm_mask = meminfo->dimm_mask;
+
+
+        mask_x4 = 0;
+       mask_x16 = 0;
+       mask_single_rank = 0;
+       mask_page_1k = 0;
+
+        for(i = 0; i < DIMM_SOCKETS; i++) {
+               
+                if (!(dimm_mask & (1 << i))) {
+                        continue;
+                }
+
+               if(meminfo->sz[i].rank == 1) {
+                       mask_single_rank |= 1<<i;
+               }
+
+                if(meminfo->sz[i].col==10) {
+                        mask_page_1k |= 1<<i;
+                }
+
+
+               value = spd_read_byte(ctrl->channel0[i], SPD_PRI_WIDTH);
+
+               #if QRANK_DIMM_SUPPORT == 1
+                       rank = meminfo->sz[i].rank;
+               #endif
+
+               if(value==4) {
+                       mask_x4 |= (1<<i);
+                       #if QRANK_DIMM_SUPPORT == 1
+                       if(rank==4) {
+                               mask_x4 |= 1<<(i+2);
+                       }
+                       #endif
+               } else if(value==16) {
+                       mask_x16 |= (1<<i);
+                       #if QRANK_DIMM_SUPPORT == 1
+                        if(rank==4) {
+                                mask_x16 |= 1<<(i+2);
+                        }
+                       #endif
+               }
+                
+        }
+       
+        meminfo->x4_mask= mask_x4;
+       meminfo->x16_mask = mask_x16;
+       
+       meminfo->single_rank_mask = mask_single_rank;
+       meminfo->page_1k_mask = mask_page_1k;
+
+        return mask_x4;
+
+}
+
+
+static void set_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
+{
+       uint32_t dcl;
+       dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+       dcl &= ~(DCL_X4Dimm_MASK<<DCL_X4Dimm_SHIFT);
+       dcl |= ((meminfo->x4_mask) & 0xf) << (DCL_X4Dimm_SHIFT);
+       pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
+}
+
+static int count_ones(uint32_t dimm_mask)
+{
+        int dimms;
+        unsigned index;
+        dimms = 0;
+        for(index = 0; index < DIMM_SOCKETS; index++, dimm_mask>>=1) {
+                if (dimm_mask & 1) {
+                        dimms++;
+                }
+        }
+        return dimms;
+}
+
+
+static void set_DramTerm(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
+{
+        uint32_t dcl;
+       unsigned odt;
+       odt = 1; // 75 ohms
+
+       if(param->divisor == 100) { //DDR2 800
+               if(meminfo->is_Width128) {
+                       if(count_ones(meminfo->dimm_mask & 0x0f)==2) {
+                               odt = 3;  //50 ohms
+                       }
+               }
+
+       }       
+        dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+        dcl &= ~(DCL_DramTerm_MASK<<DCL_DramTerm_SHIFT);
+        dcl |= (odt & DCL_DramTerm_MASK) << (DCL_DramTerm_SHIFT);
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
+}
+
+
+static void set_ecc(const struct mem_controller *ctrl,const struct mem_param *param, long dimm_mask, struct mem_info *meminfo)
+{
+       int i;
+       int value;
+       
+        uint32_t dcl, nbcap;
+        nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
+        dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+        dcl &= ~DCL_DimmEccEn;
+        if (nbcap & NBCAP_ECC) {
+                dcl |= DCL_DimmEccEn;
+        }
+        if (read_option(CMOS_VSTART_ECC_memory, CMOS_VLEN_ECC_memory, 1) == 0) {
+                dcl &= ~DCL_DimmEccEn;
+        }
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
+
+       meminfo->is_ecc = 1;
+       if(!(dcl & DCL_DimmEccEn)) {
+               meminfo->is_ecc = 0;
+               return; // already disabled the ECC, so don't need to read SPD any more
+       }
+
+        for(i = 0; i < DIMM_SOCKETS; i++) {
+               
+                if (!(dimm_mask & (1 << i))) {
+                        continue;
+                }
+
+               value = spd_read_byte(ctrl->channel0[i], SPD_DIMM_CONF_TYPE);
+
+               if(!(value & SPD_DIMM_CONF_TYPE_ECC)) {
+                       dcl &= ~DCL_DimmEccEn;
+                       pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
+                       meminfo->is_ecc = 0;
+                       return;
+               }
+
+        }
+}
+
+static int update_dimm_Twtr(const struct mem_controller *ctrl, const struct mem_param *param, int i)
+{
+
+       return update_dimm_TT_1_4(ctrl, param, i, DRAM_TIMING_HIGH, SPD_TWTR, DTH_TWTR_SHIFT, DTH_TWTR_MASK, DTH_TWTR_BASE, DTH_TWTR_MIN, DTH_TWTR_MAX);
+
+}
+
+static void set_TT(const struct mem_controller *ctrl, const struct mem_param *param, unsigned TT_REG,
+                unsigned TT_SHIFT, unsigned TT_MASK, unsigned TT_BASE, unsigned TT_MIN, unsigned TT_MAX, unsigned val, const char *str)
+{
+        uint32_t reg;
+
+        if ((val < TT_MIN) || (val > TT_MAX)) {
+                print_err(str);
+                die(" Unknown\r\n");
+        }
+
+        reg = pci_read_config32(ctrl->f2, TT_REG);
+        reg &= ~(TT_MASK << TT_SHIFT);
+        reg |= ((val - TT_BASE) << TT_SHIFT);
+        pci_write_config32(ctrl->f2, TT_REG, reg);
+        return;
+}
+
+static void set_TrwtTO(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+       set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TRWTTO_SHIFT, DTH_TRWTTO_MASK,DTH_TRWTTO_BASE, DTH_TRWTTO_MIN, DTH_TRWTTO_MAX, param->TrwtTO, "TrwtTO");
+}
+
+static void set_Twrrd(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+        set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TWRRD_SHIFT, DTH_TWRRD_MASK,DTH_TWRRD_BASE, DTH_TWRRD_MIN, DTH_TWRRD_MAX, param->Twrrd, "Twrrd");
+}
+
+static void set_Twrwr(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+        set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TWRWR_SHIFT, DTH_TWRWR_MASK,DTH_TWRWR_BASE, DTH_TWRWR_MIN, DTH_TWRWR_MAX, param->Twrwr, "Twrwr");
+}
+
+static void set_Trdrd(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+        set_TT(ctrl, param, DRAM_TIMING_HIGH, DTH_TRDRD_SHIFT, DTH_TRDRD_MASK,DTH_TRDRD_BASE, DTH_TRDRD_MIN, DTH_TRDRD_MAX, param->Trdrd, "Trdrd");
+}
+
+static void set_DcqBypassMax(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+        set_TT(ctrl, param, DRAM_CONFIG_HIGH, DCH_DcqBypassMax_SHIFT, DCH_DcqBypassMax_MASK,DCH_DcqBypassMax_BASE, DCH_DcqBypassMax_MIN, DCH_DcqBypassMax_MAX, param->DcqByPassMax, "DcqBypassMax"); // value need to be in CMOS
+}
+
+static void set_Tfaw(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
+{
+        static const uint8_t faw_1k[] = {8, 10, 13, 14};
+        static const uint8_t faw_2k[] = {10, 14, 17, 18};
+        unsigned memclkfreq_index;
+        unsigned faw;
+
+
+        memclkfreq_index = param->dch_memclk;
+
+        if(meminfo->page_1k_mask != 0) { //1k page
+                faw = faw_1k[memclkfreq_index];
+        }
+        else {
+                faw = faw_2k[memclkfreq_index];
+        }
+
+        set_TT(ctrl, param, DRAM_CONFIG_HIGH, DCH_FourActWindow_SHIFT, DCH_FourActWindow_MASK, DCH_FourActWindow_BASE, DCH_FourActWindow_MIN, DCH_FourActWindow_MAX, faw, "FourActWindow");
+
+}
+
+
+static void set_max_async_latency(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+       uint32_t dch;
+       unsigned async_lat;
+
+
+       dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+       dch &= ~(DCH_MaxAsyncLat_MASK << DCH_MaxAsyncLat_SHIFT);
+
+       async_lat = 6+6;
+       
+       
+       dch |= ((async_lat - DCH_MaxAsyncLat_BASE) << DCH_MaxAsyncLat_SHIFT);
+       pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
+}
+
+static void set_SlowAccessMode(const struct mem_controller *ctrl)
+{
+        uint32_t dch;
+
+        dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+
+        dch |= (1<<20);
+
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
+}
+
+
+/*
+       DRAM_OUTPUT_DRV_COMP_CTRL 0, 0x20
+       DRAM_ADDR_TIMING_CTRL 04, 0x24
+*/
+static void set_misc_timing(const struct mem_controller *ctrl, struct mem_info *meminfo)
+{
+        uint32_t dword;
+       uint32_t dwordx;
+       unsigned SlowAccessMode = 0;
+
+       long dimm_mask = meminfo->dimm_mask & 0x0f;
+
+#if DIMM_SUPPORT==0x0104   /* DDR2 and REG */
+       /* for REG DIMM */      
+        dword = 0x00111222;
+        dwordx = 0x002f0000;
+        switch (meminfo->memclk_set) {
+        case DCH_MemClkFreq_266MHz:
+                if( (dimm_mask == 0x03) || (dimm_mask == 0x02) || (dimm_mask == 0x01)) { 
+                       dwordx = 0x002f2700; 
+                }
+                break;
+        case DCH_MemClkFreq_333MHz:
+               if( (dimm_mask == 0x03) || (dimm_mask == 0x02) || (dimm_mask == 0x01)) {
+                        if ((meminfo->single_rank_mask & 0x03)!=0x03) { //any double rank there?
+                                dwordx = 0x002f2f00;
+                        }
+                }
+                break;
+        case DCH_MemClkFreq_400MHz:
+                dwordx = 0x002f3300;
+                break;
+       }
+
+#endif
+
+#if DIMM_SUPPORT==0x0004  /* DDR2 and unbuffered */
+        /* for UNBUF DIMM */
+        dword = 0x00111222;
+       dwordx = 0x002f2f00;
+       switch (meminfo->memclk_set) {
+       case DCH_MemClkFreq_200MHz:
+               if(dimm_mask == 0x03) {
+                       SlowAccessMode = 1;
+                       dword = 0x00111322;
+               }
+               break;
+       case DCH_MemClkFreq_266MHz:
+               if(dimm_mask == 0x03) {
+                       SlowAccessMode = 1;
+                       dword = 0x00111322;
+                       if((meminfo->x4_mask == 0 ) && (meminfo->x16_mask == 0)) {
+                               switch (meminfo->single_rank_mask) {
+                               case 0x03:
+                                       dwordx = 0x00002f00; //x8 single Rank
+                                       break;
+                               case 0x00:
+                                       dwordx = 0x00342f00; //x8 double Rank
+                                       break;
+                               default: 
+                                       dwordx = 0x00372f00; //x8 single Rank and double Rank mixed
+                               }
+                       } else if((meminfo->x4_mask == 0 ) && (meminfo->x16_mask == 0x01) && (meminfo->single_rank_mask == 0x01)) {
+                                        dwordx = 0x00382f00; //x8 Double Rank and x16 single Rank mixed
+                        } else if((meminfo->x4_mask == 0 ) && (meminfo->x16_mask == 0x02) && (meminfo->single_rank_mask == 0x02)) {
+                                        dwordx = 0x00382f00; //x16 single Rank and x8 double Rank mixed
+                       }
+
+               }
+               else {
+                       if((meminfo->x4_mask == 0 ) && (meminfo->x16_mask == 0x00) && ((meminfo->single_rank_mask == 0x01)||(meminfo->single_rank_mask == 0x02)))  { //x8 single rank
+                               dwordx = 0x002f2f00;
+                       } else {
+                               dwordx = 0x002b2f00;
+                       }
+               }
+               break;
+       case DCH_MemClkFreq_333MHz:
+               dwordx = 0x00202220;
+                if(dimm_mask == 0x03) {
+                        SlowAccessMode = 1;
+                        dword = 0x00111322;
+                        if((meminfo->x4_mask == 0 ) && (meminfo->x16_mask == 0)) {
+                                switch (meminfo->single_rank_mask) {
+                                case 0x03:
+                                        dwordx = 0x00302220; //x8 single Rank
+                                        break;
+                                case 0x00:
+                                        dwordx = 0x002b2220; //x8 double Rank
+                                        break;
+                                defalut:
+                                        dwordx = 0x002a2220; //x8 single Rank and double Rank mixed
+                                }
+                        } else if((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x01) && (meminfo->single_rank_mask == 0x01)) {
+                                        dwordx = 0x002c2220; //x8 Double Rank and x16 single Rank mixed
+                        } else if((meminfo->x4_mask == 0) && (meminfo->x16_mask == 0x02) && (meminfo->single_rank_mask == 0x02)) {
+                                        dwordx = 0x002c2220; //x16 single Rank and x8 double Rank mixed
+                        }
+                }
+                break;
+       case DCH_MemClkFreq_400MHz:
+                dwordx = 0x00202520;
+               SlowAccessMode = 1;
+                if(dimm_mask == 0x03) {
+                        dword = 0x00113322;
+                } else {
+                        dword = 0x00113222;
+               }
+                break;
+       } 
+
+       print_raminit("\tdimm_mask = ", meminfo->dimm_mask);
+       print_raminit("\tx4_mask = ", meminfo->x4_mask);
+       print_raminit("\tx16_mask = ", meminfo->x16_mask);
+       print_raminit("\tsingle_rank_mask = ", meminfo->single_rank_mask);
+       print_raminit("\tODC = ", dword);
+       print_raminit("\tAddr Timing= ", dwordx);
+#endif
+
+#if (DIMM_SUPPORT & 0x0100)==0x0000 /* 2T mode only used for unbuffered DIMM */
+       if(SlowAccessMode) {
+               set_SlowAccessMode(ctrl);
+       }
+#endif
+
+        /* Program the Output Driver Compensation Control Registers (Function 2:Offset 0x9c, index 0, 0x20) */
+        pci_write_config32_index_wait(ctrl->f2, 0x98, 0, dword);
+       if(meminfo->is_Width128) {      
+               pci_write_config32_index_wait(ctrl->f2, 0x98, 0x20, dword);
+       }
+
+        /* Program the Address Timing Control Registers (Function 2:Offset 0x9c, index 4, 0x24) */
+        pci_write_config32_index_wait(ctrl->f2, 0x98, 4, dwordx);
+       if(meminfo->is_Width128) {
+               pci_write_config32_index_wait(ctrl->f2, 0x98, 0x24, dwordx);
+       }
+
+}
+
+
+static void set_RDqsEn(const struct mem_controller *ctrl, const struct mem_param *param, struct mem_info *meminfo)
+{
+#if CPU_SOCKET_TYPE==0x10
+       //only need to set for reg and x8
+        uint32_t dch;
+
+        dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+
+       dch &= ~DCH_RDqsEn;
+       if((!meminfo->x4_mask) && (!meminfo->x16_mask)) {
+               dch |= DCH_RDqsEn;
+       }
+
+               pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
+#endif
+}
+
+
+static void set_idle_cycle_limit(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+       uint32_t dcm;
+       /* AMD says to Hardcode this */
+       dcm = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
+       dcm &= ~(DCM_ILD_lmt_MASK << DCM_ILD_lmt_SHIFT);
+       dcm |= DCM_ILD_lmt_16 << DCM_ILD_lmt_SHIFT;
+       dcm |= DCM_DCC_EN;
+       pci_write_config32(ctrl->f2, DRAM_CTRL_MISC, dcm);
+}
+
+static void set_RdWrQByp(const struct mem_controller *ctrl, const struct mem_param *param)
+{
+       set_TT(ctrl, param, DRAM_CTRL_MISC, DCM_RdWrQByp_SHIFT, DCM_RdWrQByp_MASK,0, 0, 3, 2, "RdWrQByp");
+}
+
+
+
+static long spd_set_dram_timing(const struct mem_controller *ctrl, const struct mem_param *param, long dimm_mask, struct mem_info *meminfo)
+{
+       int i;
+
+       for(i = 0; i < DIMM_SOCKETS; i++) {
+               int rc;
+               if (!(dimm_mask & (1 << i))) {
+                       continue;
+               }
+               print_tx("dimm socket: ", i);
+               /* DRAM Timing Low Register */
+               print_t("\ttrc\r\n");
+               if ((rc = update_dimm_Trc (ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttrcd\r\n");
+               if ((rc = update_dimm_Trcd(ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttrrd\r\n");
+               if ((rc = update_dimm_Trrd(ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttras\r\n");
+               if ((rc = update_dimm_Tras(ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttrp\r\n");
+               if ((rc = update_dimm_Trp (ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttrtp\r\n");
+               if ((rc = update_dimm_Trtp(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
+
+               print_t("\ttwr\r\n");
+               if ((rc = update_dimm_Twr (ctrl, param, i)) <= 0) goto dimm_err;
+
+               /* DRAM Timing High Register */
+               print_t("\ttref\r\n");
+               if ((rc = update_dimm_Tref(ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttwtr\r\n");
+               if ((rc = update_dimm_Twtr(ctrl, param, i)) <= 0) goto dimm_err;
+
+               print_t("\ttrfc\r\n");
+               if ((rc = update_dimm_Trfc(ctrl, param, i, meminfo)) <= 0) goto dimm_err;
+
+               /* DRAM Config Low */
+
+               continue;
+       dimm_err:
+               if (rc < 0) {
+                       return -1;
+               }
+               dimm_mask = disable_dimm(ctrl, i, dimm_mask, meminfo);
+       }
+
+       meminfo->dimm_mask = dimm_mask; // store final dimm_mask
+
+       get_extra_dimm_mask(ctrl, meminfo); // will be used by RDqsEn and dimm_x4
+       /* DRAM Timing Low Register */
+
+       /* DRAM Timing High Register */
+       set_TrwtTO(ctrl, param);
+       set_Twrrd (ctrl, param);
+       set_Twrwr (ctrl, param);
+       set_Trdrd (ctrl, param);
+        
+       set_4RankRDimm(ctrl, param, meminfo);
+
+       /* DRAM Config High */
+       set_Tfaw(ctrl, param, meminfo);
+       set_DcqBypassMax(ctrl, param);
+       set_max_async_latency(ctrl, param);
+       set_RDqsEn(ctrl, param, meminfo);
+
+       /* DRAM Config Low */
+       set_ecc(ctrl, param, dimm_mask, meminfo);
+       set_dimm_x4(ctrl, param, meminfo);
+       set_DramTerm(ctrl, param, meminfo);
+       
+       /* DRAM Control Misc */
+       set_idle_cycle_limit(ctrl, param);
+       set_RdWrQByp(ctrl, param);
+
+       return dimm_mask;
+}
+
+static void sdram_set_spd_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo) 
+{
+       struct spd_set_memclk_result result;
+       const struct mem_param *param;
+       struct mem_param paramx;
+       struct mem_info *meminfo;
+       long dimm_mask;
+#if 1
+       if (!sysinfo->ctrl_present[ctrl->node_id]) {
+//             print_debug("No memory controller present\r\n");
+               return;
+       }
+#endif
+       meminfo = &sysinfo->meminfo[ctrl->node_id];
+
+       print_debug_addr("sdram_set_spd_registers: paramx :", &paramx);
+       
+       activate_spd_rom(ctrl);
+       dimm_mask = spd_detect_dimms(ctrl);
+       if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
+               print_debug("No memory for this cpu\r\n");
+               return;
+       }
+       dimm_mask = spd_enable_2channels(ctrl, dimm_mask, meminfo);        
+       if (dimm_mask < 0) 
+               goto hw_spd_err;
+       dimm_mask = spd_set_ram_size(ctrl , dimm_mask, meminfo);           
+       if (dimm_mask < 0) 
+               goto hw_spd_err;
+       dimm_mask = spd_handle_unbuffered_dimms(ctrl, dimm_mask, meminfo); 
+       if (dimm_mask < 0) 
+               goto hw_spd_err;
+       result = spd_set_memclk(ctrl, dimm_mask, meminfo);
+       param     = result.param;
+       dimm_mask = result.dimm_mask;
+       if (dimm_mask < 0) 
+               goto hw_spd_err;
+
+       //store memclk set to sysinfo, incase we need rebuilt param again
+       meminfo->memclk_set = param->dch_memclk;
+
+       memcpy(&paramx, param, sizeof(paramx));
+       
+       paramx.divisor = get_exact_divisor(param->dch_memclk, paramx.divisor);
+
+       dimm_mask = spd_set_dram_timing(ctrl, &paramx , dimm_mask, meminfo); // dimm_mask will be stored to meminfo->dimm_mask
+       if (dimm_mask < 0)
+               goto hw_spd_err;
+       
+       order_dimms(ctrl, meminfo);
+
+       return;
+ hw_spd_err:
+       /* Unrecoverable error reading SPD data */
+       print_err("SPD error - reset\r\n");
+       hard_reset();
+       return;
+}
+
+#define TIMEOUT_LOOPS 300000
+
+#include "raminit_f_dqs.c"
+
+#if HW_MEM_HOLE_SIZEK != 0
+static uint32_t hoist_memory(int controllers, const struct mem_controller *ctrl,unsigned hole_startk, int i)
+{
+        int ii;
+        uint32_t carry_over;
+        device_t dev;
+        uint32_t base, limit;
+        uint32_t basek;
+        uint32_t hoist;
+       int j;
+
+        carry_over = (4*1024*1024) - hole_startk;
+
+        for(ii=controllers - 1;ii>i;ii--) {
+                base  = pci_read_config32(ctrl[0].f1, 0x40 + (ii << 3));
+                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
+                        continue;
+                }
+               limit = pci_read_config32(ctrl[0].f1, 0x44 + (ii << 3));
+               limit += (carry_over << 2 );
+               base  += (carry_over << 2 );
+               for(j = 0; j < controllers; j++) {      
+                       pci_write_config32(ctrl[j].f1, 0x44 + (ii << 3), limit);
+                       pci_write_config32(ctrl[j].f1, 0x40 + (ii << 3), base );
+               }
+        }
+        limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
+       limit += (carry_over << 2);
+       for(j = 0; j < controllers; j++) {
+               pci_write_config32(ctrl[j].f1, 0x44 + (i << 3), limit);
+       }
+        dev = ctrl[i].f1;
+        base  = pci_read_config32(dev, 0x40 + (i << 3));
+        basek  = (base & 0xffff0000) >> 2;
+        if(basek == hole_startk) {
+                //don't need set memhole here, because hole off set will be 0, overflow
+                //so need to change base reg instead, new basek will be 4*1024*1024
+                base &= 0x0000ffff;
+                base |= (4*1024*1024)<<2;
+               for(j = 0; j < controllers; j++) {
+                       pci_write_config32(ctrl[j].f1, 0x40 + (i<<3), base);
+               }
+        }
+        else
+        {
+               hoist = /* hole start address */
+                       ((hole_startk << 10) & 0xff000000) +
+                       /* hole address to memory controller address */
+                       (((basek + carry_over) >> 6) & 0x0000ff00) +
+                       /* enable */
+                       1;
+               pci_write_config32(dev, 0xf0, hoist);
+       }       
+
+        return carry_over;
+}
+
+static void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl)
+{
+
+        uint32_t hole_startk;
+       int i;
+
+        hole_startk = 4*1024*1024 - HW_MEM_HOLE_SIZEK;
+
+#if HW_MEM_HOLE_SIZE_AUTO_INC == 1
+       //We need to double check if the hole_startk is valid, if it is equal to basek, we need to decrease it some
+       uint32_t basek_pri;
+        for(i=0; i<controllers; i++) {
+                        uint32_t base;
+                        unsigned base_k;
+                        base  = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
+                        if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
+                                continue;
+                        }
+                        base_k = (base & 0xffff0000) >> 2;
+                        if(base_k == hole_startk) {
+                                hole_startk -= (base_k - basek_pri)>>1; // decrease mem hole startk to make sure it is on middle of previous node
+                                break; //only one hole
+                        }
+                       basek_pri = base_k;
+        }
+#endif
+        //find node index that need do set hole
+        for(i=0; i<controllers; i++) {
+                        uint32_t base, limit;
+                        unsigned base_k, limit_k;
+                        base  = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
+                        if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
+                                continue;
+                        }
+                        limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
+                        base_k = (base & 0xffff0000) >> 2;
+                        limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
+                        if ((base_k <= hole_startk) && (limit_k > hole_startk)) {
+                                unsigned end_k;
+                                hoist_memory(controllers, ctrl, hole_startk, i);
+                               end_k = memory_end_k(ctrl, controllers);
+                                set_top_mem(end_k, hole_startk);
+                               break; //only one hole
+                        }
+        }
+
+}
+
+#endif
+
+static void sdram_enable(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
+{
+       int i;
+
+
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+        unsigned cpu_f0_f1[8];
+       tsc_t tsc, tsc0[8];
+       
+       print_debug_addr("sdram_enable: tsc0[8]: ", &tsc0[0]);
+#endif
+       uint32_t dword;
+
+       /* Error if I don't have memory */
+       if (memory_end_k(ctrl, controllers) == 0) {
+               die("No memory\r\n");
+       }
+
+       /* Before enabling memory start the memory clocks */
+       for(i = 0; i < controllers; i++) {
+               uint32_t dtl, dch;
+               if (!sysinfo->ctrl_present[ i ])
+                       continue;
+                dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
+
+               // if no memory installed, disabled the interface
+               if(sysinfo->meminfo[i].dimm_mask==0x00){
+                        dch |= DCH_DisDramInterface;
+                        pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
+
+                }
+               else {
+                        dch |= DCH_MemClkFreqVal;
+                        pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
+                       /* address timing and Output driver comp Control */
+                       set_misc_timing(ctrl+i, sysinfo->meminfo+i );
+               }
+       }
+
+       /* We need to wait a mimmium of 20 MEMCLKS to enable the  InitDram */
+       memreset(controllers, ctrl);
+
+       for(i = 0; i < controllers; i++) {
+               uint32_t dcl, dch;
+               if (!sysinfo->ctrl_present[ i ])
+                       continue;
+               /* Skip everything if I don't have any memory on this controller */
+               dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
+               if (!(dch & DCH_MemClkFreqVal)) {
+                       continue;
+               }
+
+               /* ChipKill */
+               dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
+               if (dcl & DCL_DimmEccEn) {
+                       uint32_t mnc;
+                       print_spew("ECC enabled\r\n");
+                       mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
+                       mnc |= MNC_ECC_EN;
+                       if (dcl & DCL_Width128) {
+                               mnc |= MNC_CHIPKILL_EN;
+                       }
+                       pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
+               }
+
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+               cpu_f0_f1[i] = is_cpu_pre_f2_in_bsp(i);
+               if(cpu_f0_f1[i]) {
+                       //Rev F0/F1 workaround
+#if 1
+                               /* Set the DqsRcvEnTrain bit */
+                       dword = pci_read_config32(ctrl[i].f2, DRAM_CTRL);
+                       dword |= DC_DqsRcvEnTrain;
+                       pci_write_config32(ctrl[i].f2, DRAM_CTRL, dword);
+#endif
+                       tsc0[i] = rdtsc();                      
+               }
+#endif
+
+#if 0
+                               /* Set the DqsRcvEnTrain bit */
+                        dword = pci_read_config32(ctrl[i].f2, DRAM_CTRL);
+                        dword |= DC_DqsRcvEnTrain;
+                        pci_write_config32(ctrl[i].f2, DRAM_CTRL, dword);
+#endif
+
+               pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+               dcl |= DCL_InitDram;
+               pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
+
+       }
+
+       for(i = 0; i < controllers; i++) {
+               uint32_t dcl, dch, dcm;
+               if (!sysinfo->ctrl_present[ i ])
+                       continue;
+               /* Skip everything if I don't have any memory on this controller */
+               if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+               print_debug("Initializing memory: ");
+               int loops = 0;
+               do {
+                       dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
+                       loops++;
+                       if ((loops & 1023) == 0) {
+                               print_debug(".");
+                       }
+               } while(((dcl & DCL_InitDram) != 0) && (loops < TIMEOUT_LOOPS));
+               if (loops >= TIMEOUT_LOOPS) {
+                       print_debug(" failed\r\n");
+                       continue;
+               }
+
+               /* Wait until it is safe to touch memory */
+               do {
+                       dcm = pci_read_config32(ctrl[i].f2, DRAM_CTRL_MISC);
+               } while(((dcm & DCM_MemClrStatus) == 0) /* || ((dcm & DCM_DramEnabled) == 0)*/ );
+
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+               if(cpu_f0_f1[i]) {
+                       tsc= rdtsc();
+
+                       print_debug_dqs_tsc("\r\nbegin tsc0", i, tsc0[i].hi, tsc0[i].lo, 2); 
+                       print_debug_dqs_tsc("end   tsc ", i, tsc.hi, tsc.lo, 2); 
+
+                       if(tsc.lo<tsc0[i].lo) {
+                               tsc.hi--;
+                       }
+                       tsc.lo -= tsc0[i].lo;
+                       tsc.hi -= tsc0[i].hi;
+
+                       tsc0[i].lo = tsc.lo;
+                       tsc0[i].hi = tsc.hi;
+
+                       print_debug_dqs_tsc("     dtsc0", i, tsc0[i].hi, tsc0[i].lo, 2);
+               }
+#endif
+               print_debug(" done\r\n");
+       }
+
+#if HW_MEM_HOLE_SIZEK != 0
+        // init hw mem hole here
+       /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
+       set_hw_mem_hole(controllers, ctrl);
+#endif
+       
+        //store tom to sysinfo, and it will be used by dqs_timing
+        {
+                msr_t msr;
+                //[1M, TOM)
+                msr = rdmsr(TOP_MEM);
+                sysinfo->tom_k = ((msr.hi<<24) | (msr.lo>>8))>>2;
+
+                //[4G, TOM2)
+                msr = rdmsr(TOP_MEM2);
+                sysinfo->tom2_k = ((msr.hi<<24)| (msr.lo>>8))>>2;
+        }
+
+        for(i = 0; i < controllers; i++) {
+                sysinfo->mem_trained[i] = 0;
+        }
+
+#if MEM_TRAIN_SEQ ==  0
+   #if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+       dqs_timing(controllers, ctrl, tsc0, sysinfo);
+   #else
+       dqs_timing(controllers, ctrl, sysinfo);
+   #endif
+#else
+
+   #if MEM_TRAIN_SEQ == 2
+           //need to enable mtrr, so dqs training could access the test address
+        setup_mtrr_dqs(sysinfo->tom_k, sysinfo->tom2_k);
+   #endif
+
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[ i ])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+                if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+                dqs_timing(i, ctrl, sysinfo, 1);
+
+   #if MEM_TRAIN_SEQ == 1
+                break; // only train the first node with ram
+   #endif
+        }
+
+   #if MEM_TRAIN_SEQ == 2
+        clear_mtrr_dqs(sysinfo->tom2_k);
+   #endif
+
+#endif
+
+
+}
+static void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a, const uint16_t *spd_addr)
+{
+       int i; 
+       int j;
+       struct mem_controller *ctrl;
+        for(i=0;i<controllers; i++) {
+                ctrl = &ctrl_a[i];
+                ctrl->node_id = i;
+                ctrl->f0 = PCI_DEV(0, 0x18+i, 0);
+                ctrl->f1 = PCI_DEV(0, 0x18+i, 1);
+                ctrl->f2 = PCI_DEV(0, 0x18+i, 2);
+                ctrl->f3 = PCI_DEV(0, 0x18+i, 3);
+
+               if(spd_addr == (void *)0) continue;
+
+                for(j=0;j<DIMM_SOCKETS;j++) {
+                        ctrl->channel0[j] = spd_addr[(i*2+0)*DIMM_SOCKETS + j];
+                        ctrl->channel1[j] = spd_addr[(i*2+1)*DIMM_SOCKETS + j];
+                }
+        }
+}
diff --git a/src/northbridge/amd/amdk8/raminit_f_dqs.c b/src/northbridge/amd/amdk8/raminit_f_dqs.c
new file mode 100644 (file)
index 0000000..f77b6d6
--- /dev/null
@@ -0,0 +1,2036 @@
+/*
+       yhlu 2005.10 dqs training
+*/
+//0: mean no debug info
+#define DQS_TRAIN_DEBUG 0
+
+static inline void print_debug_dqs(const char *str, unsigned val, unsigned level) 
+{
+#if DQS_TRAIN_DEBUG > 0
+       if(DQS_TRAIN_DEBUG > level) {
+               #if CONFIG_USE_INIT == 1
+               printk_debug("%s%x\r\n", str, val);
+               #else
+               print_debug(str); print_debug_hex32(val); print_debug("\r\n");
+               #endif
+       }
+#endif
+}
+
+static inline void print_debug_dqs_pair(const char *str, unsigned val, const char *str2, unsigned val2, unsigned level)
+{
+#if DQS_TRAIN_DEBUG > 0
+        if(DQS_TRAIN_DEBUG > level) {
+                #if CONFIG_USE_INIT == 1
+                printk_debug("%s%08x%s%08x\r\n", str, val, str2, val2);
+                #else
+                print_debug(str); print_debug_hex32(val); print_debug(str2); print_debug_hex32(val2); print_debug("\r\n");
+                #endif
+        }
+#endif
+}
+
+static inline void print_debug_dqs_tsc(const char *str, unsigned i, unsigned val, unsigned val2, unsigned level)
+{
+#if DQS_TRAIN_DEBUG > 0
+        if(DQS_TRAIN_DEBUG > level) {
+                #if CONFIG_USE_INIT == 1
+                printk_debug("%s[%02x]=%08x%08x\r\n", str, i, val, val2);
+                #else
+               print_debug(str); print_debug("["); print_debug_hex8(i); print_debug("]="); print_debug_hex32(val); print_debug_hex32(val2); print_debug("\r\n");
+                #endif
+        }
+#endif
+}
+
+static inline void print_debug_dqs_tsc_x(const char *str, unsigned i, unsigned val, unsigned val2)
+{
+       #if CONFIG_USE_INIT == 1
+        printk_debug("%s[%02x]=%08x%08x\r\n", str, i, val, val2);
+        #else
+        print_debug(str); print_debug("["); print_debug_hex8(i); print_debug("]="); print_debug_hex32(val); print_debug_hex32(val2); print_debug("\r\n");
+        #endif
+
+}
+
+static void fill_mem_cs_sysinfo(unsigned nodeid, const struct mem_controller *ctrl, struct sys_info *sysinfo)
+{
+
+       int i;
+        sysinfo->mem_base[nodeid] = pci_read_config32(ctrl->f1, 0x40 + (nodeid<<3));
+
+       for(i=0;i<8; i++) {
+               sysinfo->cs_base[nodeid*8+i] = pci_read_config32(ctrl->f2, 0x40 + (i<<2));
+       }
+
+       sysinfo->hole_reg[nodeid] = pci_read_config32(ctrl->f1, 0xf0);  
+
+}
+static unsigned Get_MCTSysAddr(const struct mem_controller *ctrl,  unsigned cs_idx, struct sys_info *sysinfo)
+{
+       uint32_t dword;
+       uint32_t mem_base;
+       unsigned nodeid = ctrl->node_id;
+
+#if HW_MEM_HOLE_SIZEK != 0     
+       uint32_t hole_reg;
+#endif
+
+       //get the local base addr of the chipselect
+       dword = sysinfo->cs_base[nodeid * 8 + cs_idx];
+       dword &= 0xfffffff0;
+
+       //sys addr= node base + local cs base
+       mem_base = sysinfo->mem_base[nodeid];
+       mem_base &= 0xffff0000;
+
+       dword += mem_base;
+#if HW_MEM_HOLE_SIZEK != 0
+       hole_reg = sysinfo->hole_reg[nodeid];
+       if(hole_reg & 1) {
+               unsigned hole_startk;
+               hole_startk = (hole_reg & (0xff<<24)) >> 10;
+               if( (dword >= (hole_startk<<2)) && (dword < ((4*1024*1024)<<2))) { 
+                       dword += ((4*1024*1024 - hole_startk)<<2);
+               }
+       }  
+#endif
+
+       //add 1MB offset to avoid compat area
+       dword += (1<<(20-8));
+               
+       //So final result is upper 32 bit addr 
+       
+       return dword;
+
+}
+
+static unsigned Get_RcvrSysAddr(const struct mem_controller * ctrl, unsigned channel, unsigned cs_idx, struct sys_info *sysinfo)
+{
+#if 0
+       //get SB_64MuxedMode
+       uint32_t dword;
+       dword = pci_read_config32(ctrl->f2, DRAM_CTRL_MISC);
+       if((dword & DCM_Mode64BitMux) == DCM_Mode64BitMux) {
+               if(channel) cs_idx += 4; // translate Receiver number to Chipsel
+       }
+#endif
+       
+       return Get_MCTSysAddr(ctrl, cs_idx, sysinfo);
+
+}
+
+static inline unsigned long read_cr4(void)
+{
+        unsigned long cr4;
+        asm volatile ("movl %%cr4, %0" : "=r" (cr4));
+        return cr4;
+}
+
+static inline void write_cr4(unsigned long cr4)
+{
+        asm volatile ("movl %0, %%cr4" : : "r" (cr4));
+}
+
+
+static inline void enable_sse2()
+{
+       unsigned long cr4;
+       cr4 = read_cr4();
+       cr4 |= (1<<9);
+       write_cr4(cr4);
+}
+
+static inline void disable_sse2()
+{
+        unsigned long cr4;
+        cr4 = read_cr4();
+        cr4 &= ~(1<<9);
+        write_cr4(cr4);
+}
+
+
+static void set_wrap32dis(void) {
+       msr_t msr;
+       
+       msr = rdmsr(0xc0010015);
+       msr.lo |= (1<<17);
+       
+       wrmsr(0xc0010015, msr);
+
+}
+
+static void clear_wrap32dis(void) {
+        msr_t msr;
+
+        msr = rdmsr(0xc0010015);
+        msr.lo &= ~(1<<17);
+
+        wrmsr(0xc0010015, msr);
+
+}
+
+static void set_FSBASE(uint32_t addr_hi)
+{
+        msr_t msr;
+
+        //set fs and use fs prefix to access the mem
+        msr.hi = addr_hi;
+        msr.lo = 0;
+        wrmsr(0xc0000100, msr); //FS_BASE
+
+}
+
+#if 0
+static void write_mem(uint32_t addr_hi, uint32_t addr_lo, uint32_t value) 
+{
+       if(addr_hi == 0) {
+               *((uint32_t *)addr_lo) = value;
+               return;
+       } 
+
+       set_FSBASE(addr_hi);
+
+        __asm__ volatile (
+               "movl %1, %%fs:(%0)\n\t"
+                :: "a" (addr_lo), "b" (value) 
+        );
+       
+}
+
+static uint32_t read_mem(uint32_t addr_hi, uint32_t addr_lo)
+{
+       unsigned value;
+        if(addr_hi == 0) {
+                value = *((uint32_t *)addr_lo);
+               return value; 
+        }
+
+       set_FSBASE(addr_hi);
+
+        __asm__ volatile (
+                "movl %%fs:(%1), %0\n\t"
+                :"=b"(value): "a" (addr_lo)
+        );
+       
+       return value;
+
+}
+#endif
+
+static unsigned ChipSelPresent(const struct mem_controller *ctrl, unsigned cs_idx, struct sys_info *sysinfo)
+{
+        unsigned enabled;
+       unsigned nodeid = ctrl->node_id;
+       
+
+        enabled = sysinfo->cs_base[nodeid * 8 + cs_idx];
+        enabled &= 1;
+
+        return enabled;
+
+}
+
+static unsigned RcvrRankEnabled(const struct mem_controller *ctrl, int channel, int cs_idx, unsigned is_Width128, struct sys_info *sysinfo)
+{
+        if(!is_Width128) {
+               if(channel) return 0; // no channel b
+        }
+
+       return ChipSelPresent(ctrl, cs_idx, sysinfo);
+}
+
+static void WriteLNTestPattern(unsigned addr_lo, uint8_t *buf_a, unsigned line_num)
+{
+        __asm__ volatile (
+                "1:\n\t"
+               "movdqa (%3), %%xmm0\n\t"
+               "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
+                "addl %1, %0\n\t"
+                "addl %1, %3\n\t"
+                "loop 1b\n\t"
+
+                :: "a" (addr_lo), "d" (16), "c" (line_num * 4), "b"(buf_a)
+        );
+
+
+}
+
+static void Write1LTestPattern(unsigned addr, unsigned p, uint8_t *buf_a, uint8_t *buf_b) 
+{
+       uint8_t *buf;
+       if(p==1) { buf = buf_b; }
+       else { buf = buf_a; }
+
+       set_FSBASE (addr>>24);
+
+       WriteLNTestPattern(addr<<8, buf, 1);
+}
+
+static void Read1LTestPattern(unsigned addr) 
+{
+        unsigned value;
+
+       set_FSBASE(addr>>24);
+       
+       /* 1st move causes read fill (to exclusive or shared)*/
+        __asm__ volatile (
+                "movl %%fs:(%1), %0\n\t"
+                :"=b"(value): "a" (addr<<8)
+        );
+       
+}
+
+#define DQS_PASS 0
+#define DQS_FAIL 1
+
+#define DQS_FIRST_PASS 1
+#define DQS_SECOND_PASS 2
+
+#define SB_NORCVREN 11
+#define RCVREN_MARGIN 6
+#define SB_SmallRCVR 13
+#define SB_CHA2BRCVREN 12
+#define SB_NODQSPOS  14
+#define MIN_DQS_WNDW 3
+#define SB_SMALLDQS 15
+
+
+static unsigned CompareTestPatternQW0(unsigned channel, unsigned addr, unsigned pattern, const uint32_t *TestPattern0, const uint32_t *TestPattern1, const uint32_t *TestPattern2, unsigned Pass, unsigned is_Width128)
+{
+       uint32_t addr_lo;
+       uint32_t *test_buf;
+       uint32_t value;
+       uint32_t value_test;
+       unsigned result = DQS_FAIL;
+
+       if(Pass == DQS_FIRST_PASS) {
+               if(pattern==1) {
+                       test_buf = (uint32_t *)TestPattern1;
+               }
+               else {
+                       test_buf = (uint32_t *)TestPattern0;
+               }
+       }
+       else {
+               test_buf = (uint32_t *)TestPattern2;
+       }
+
+       set_FSBASE(addr>>24);   
+       
+       addr_lo = addr<<8;
+       
+       if(is_Width128 && (channel == 1)) {
+               addr_lo += 8; //second channel
+               test_buf += 2;
+       }
+       
+        __asm__ volatile (
+                "movl %%fs:(%1), %0\n\t"
+                :"=b"(value): "a" (addr_lo)
+        );
+
+       value_test = *test_buf;
+
+       
+        print_debug_dqs_pair("\t\t\t\t\t\tQW0.lo : test_buf= ", (unsigned)test_buf, " value = ", value_test, 4); 
+        print_debug_dqs_pair("\t\t\t\t\t\tQW0.lo : addr_lo = ", addr_lo, " value = ", value, 4); 
+
+       if(value == value_test) {
+               addr_lo += 4;
+               test_buf++;
+               __asm__ volatile (
+                       "movl %%fs:(%1), %0\n\t"
+                       :"=b"(value): "a" (addr_lo)
+               );
+               value_test = *test_buf;
+               print_debug_dqs_pair("\t\t\t\t\t\tQW0.hi : test_buf= ", (unsigned)test_buf, " value = ", value_test, 4);
+               print_debug_dqs_pair("\t\t\t\t\t\tQW0.hi : addr_lo = ", addr_lo, " value = ", value, 4);
+
+               if(value == value_test){
+                       result =  DQS_PASS;
+               }
+       }
+       
+       if(Pass == DQS_SECOND_PASS) { // second pass need to be inverted
+               if(result==DQS_PASS) {
+                       result = DQS_FAIL;
+               }
+               else {
+                       result = DQS_PASS;
+               }
+       }
+
+       return result;
+
+}
+
+static void SetMaxAL_RcvrDly(const struct mem_controller *ctrl, unsigned dly) 
+{
+        uint32_t reg;
+
+       dly += (20-1); // round it
+       dly /= 20; // convert from unit 50ps to 1ns
+       
+       dly += 6;
+
+
+        reg = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+        reg &= ~(DCH_MaxAsyncLat_MASK <<DCH_MaxAsyncLat_SHIFT);
+        reg |= ((dly - DCH_MaxAsyncLat_BASE) << DCH_MaxAsyncLat_SHIFT);
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, reg);
+       
+}
+
+/*
+       Set the Target range to WT IO (using an IORR overlapping the already existing 
+       WB dram type). Use IORR0
+*/
+static void SetTargetWTIO(unsigned addr)
+{
+       msr_t msr;
+       msr.hi = addr>>24;
+       msr.lo = addr<<8;
+       wrmsr(0xc0010016, msr); //IORR0 BASE
+       
+       msr.hi = 0xff;
+       msr.lo = 0xfc000800;  // 64MB Mask
+       wrmsr(0xc0010017, msr); // IORR0 Mask 
+}
+
+static void ResetTargetWTIO(void)
+{
+        msr_t msr;
+
+        msr.hi = 0;
+        msr.lo = 0;  
+        wrmsr(0xc0010017, msr); // IORR0 Mask
+}
+
+static void proc_CLFLUSH(unsigned addr)
+{
+
+       set_FSBASE(addr>>24);
+
+        /* 1st move causes read fill (to exclusive or shared)*/
+        __asm__ volatile (
+                       /* clflush fs:[eax] */
+               "clflush %%fs:(%0)\n\t"
+                ::"a" (addr<<8)
+        );
+       
+}
+static void proc_IOCLFLUSH(unsigned addr)
+{
+       SetTargetWTIO(addr);
+       proc_CLFLUSH(addr);
+       ResetTargetWTIO();
+}
+
+static void ResetDCTWrPtr(const struct mem_controller *ctrl)
+{
+       uint32_t dword;
+       unsigned index = 0x10;
+       
+       dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
+       pci_write_config32_index_wait(ctrl->f2, 0x98, index, dword);
+
+}
+
+
+static uint16_t get_exact_T1000(unsigned i)
+{
+        //                                200   266,   333,  400
+       const static uint16_t T1000_a[]= { 5000, 3759, 3003, 2500 };
+
+        static const uint16_t TT_a[] = {
+                 /*200   266   333   400 */
+         /*4 */   6250, 6250, 6250, 6250,
+         /*5 */   5000, 5000, 5000, 2500,
+         /*6 */   5000, 4166, 4166, 2500,
+         /*7 */   5000, 4285, 3571, 2500,
+
+         /*8 */   5000, 3750, 3125, 2500,
+         /*9 */   5000, 3888, 3333, 2500,
+         /*10*/   5000, 4000, 3000, 2500,
+         /*11*/   5000, 4090, 3181, 2500,
+
+         /*12*/   5000, 3750, 3333, 2500,
+         /*13*/   5000, 3846, 3076, 2500,
+         /*14*/   5000, 3928, 3214, 2500,
+         /*15*/   5000, 4000, 3000, 2500,
+        };
+
+        unsigned fid_cur;
+        int index;
+
+        msr_t msr;
+        msr = rdmsr(0xc0010042);
+        fid_cur = msr.lo & 0x3f;
+
+        index = fid_cur>>1;
+
+        if(index>12) return T1000_a[i];
+
+        return TT_a[index * 4+i];
+
+}
+
+static void InitDQSPos4RcvrEn(const struct mem_controller *ctrl)
+{
+       int i;
+       uint32_t dword;
+       
+       dword = 0x00000000;
+       for(i=1; i<=3; i++) {
+               /* Program the DQS Write Timing Control Registers (Function 2:Offset 0x9c, index 0x01-0x03, 0x21-0x23) to 0x00 for all bytes */
+               pci_write_config32_index_wait(ctrl->f2, 0x98, i, dword);
+               pci_write_config32_index_wait(ctrl->f2, 0x98, i+0x20, dword);
+       }
+
+        dword = 0x2f2f2f2f;
+        for(i=5; i<=7; i++) {
+                /* Program the DQS Write Timing Control Registers (Function 2:Offset 0x9c, index 0x05-0x07, 0x25-0x27) to 0x2f for all bytes */
+                pci_write_config32_index_wait(ctrl->f2, 0x98, i, dword);
+                pci_write_config32_index_wait(ctrl->f2, 0x98, i+0x20, dword);
+        }
+
+
+}
+#ifndef K8_REV_F_SUPPORT_F0_F1_WORKAROUND 
+#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 1
+#endif
+
+static void TrainRcvrEn(const struct mem_controller *ctrl, unsigned Pass, struct sys_info *sysinfo)
+{
+
+       const static uint32_t TestPattern0[] = {
+                       0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+                       0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+                       0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+                       0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+               };
+        const static uint32_t TestPattern1[] = {
+                        0x55555555, 0x55555555, 0x55555555, 0x55555555,
+                       0x55555555, 0x55555555, 0x55555555, 0x55555555,
+                       0x55555555, 0x55555555, 0x55555555, 0x55555555,
+                       0x55555555, 0x55555555, 0x55555555, 0x55555555,
+               };
+       const static uint32_t TestPattern2[] = { 
+                       0x12345678, 0x87654321, 0x23456789, 0x98765432,
+                       0x59385824, 0x30496724, 0x24490795, 0x99938733,
+                        0x40385642, 0x38465245, 0x29432163, 0x05067894,
+                        0x12349045, 0x98723467, 0x12387634, 0x34587623,
+               };
+
+       uint8_t pattern_buf_x[64 * 4 + 16]; // We need to two cache line So have more 16 bytes to keep 16 byte alignment */ 
+       uint8_t *buf_a, *buf_b; 
+       uint32_t ecc_bit;
+       uint32_t dword;
+       uint8_t *dqs_rcvr_dly_a = &sysinfo->dqs_rcvr_dly_a[ctrl->node_id * 2* 8] ; //8 node, channel 2, receiver 8
+
+       int i;
+
+       unsigned channel, receiver;
+
+       unsigned Errors;
+       unsigned CTLRMaxDelay;
+       unsigned T1000;
+
+       unsigned LastTest;
+       unsigned CurrTest;
+       unsigned Test0, Test1;
+
+       unsigned RcvrEnDlyRmin;
+
+       unsigned two_ranks;
+       unsigned RcvrEnDly;
+
+       unsigned PatternA;
+       unsigned PatternB;
+
+       unsigned TestAddr0, TestAddr0B, TestAddr1, TestAddr1B;
+
+       unsigned CurrRcvrCHADelay;
+
+       unsigned tmp;
+
+       unsigned is_Width128 = sysinfo->meminfo[ctrl->node_id].is_Width128;
+
+       unsigned cpu_f0_f1;
+
+       if(Pass == DQS_FIRST_PASS) {
+               InitDQSPos4RcvrEn(ctrl);
+       }
+
+       //enable SSE2
+       enable_sse2();
+
+       //wrap32dis
+       set_wrap32dis();
+
+       //disable ECC temp
+       dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+       ecc_bit = dword & DCL_DimmEccEn;
+       dword &= ~(DCL_DimmEccEn); 
+       pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
+
+
+       if(Pass == DQS_FIRST_PASS) {
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+       cpu_f0_f1 = is_cpu_pre_f2_in_bsp(ctrl->node_id);
+       if(!cpu_f0_f1) 
+#endif
+       {
+#if 1
+               /* Set the DqsRcvEnTrain bit */
+               dword = pci_read_config32(ctrl->f2, DRAM_CTRL);
+               dword |= DC_DqsRcvEnTrain;
+               pci_write_config32(ctrl->f2, DRAM_CTRL, dword);
+#endif
+       }
+       }
+
+       //get T1000 figures (cycle time (ns)) * 1K
+       dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
+       dword &= DCH_MemClkFreq_MASK;
+
+       T1000 = get_exact_T1000(dword); 
+
+       // SetupRcvrPattern 
+       buf_a = (uint8_t *)(((uint32_t)(&pattern_buf_x[0]) + 0x10) & (0xfffffff0));
+        buf_b = buf_a + 128; //??
+       if(Pass==DQS_FIRST_PASS) {
+               for(i=0;i<16;i++) {
+                       *((uint32_t *)(buf_a + i*4)) = TestPattern0[i];
+                       *((uint32_t *)(buf_b + i*4)) = TestPattern1[i];
+               }
+       }
+       else {
+                for(i=0;i<16;i++) {
+                        *((uint32_t *)(buf_a + i*4)) = TestPattern2[i];
+                       *((uint32_t *)(buf_b + i*4)) = TestPattern2[i];
+                }
+       }
+
+       print_debug_dqs("\r\nTrainRcvEn: 0 ctrl", ctrl->node_id, 0);
+
+       print_debug_addr("TrainRcvEn: buf_a:", buf_a); 
+
+       Errors = 0;
+       /* for each channel */
+       CTLRMaxDelay = 0;
+       for(channel = 0; (channel < 2) && (!Errors); channel++) 
+       { 
+               print_debug_dqs("\tTrainRcvEn51: channel ",channel, 1); 
+               
+               /* for each rank */ 
+               /* there are four recriver pairs, loosely associated with CS */ 
+               for( receiver = 0; (receiver < 8) && (!Errors); receiver+=2) 
+               {
+                       
+                       unsigned index=(receiver>>1) * 3 + 0x10;
+
+                       print_debug_dqs("\t\tTrainRcvEn52: index ", index, 2); 
+
+                       if(is_Width128) {
+                               if(channel) {
+                                       dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
+                                       CurrRcvrCHADelay= dword & 0xff;
+                               }
+                       }
+                       else {
+                               if(channel) { 
+                                       index += 0x20;
+                               }
+                       }       
+
+                       LastTest = DQS_FAIL;
+                       RcvrEnDlyRmin = 0xaf;
+                               
+                       if(!RcvrRankEnabled(ctrl, channel, receiver, is_Width128, sysinfo)) continue;
+
+                       /* for each DQS receiver enable setting */
+       
+                       TestAddr0 = Get_RcvrSysAddr(ctrl, channel, receiver, sysinfo);
+
+                       TestAddr0B = TestAddr0 + (1<<(20+2-8)); // 4MB
+       
+                       if(RcvrRankEnabled(ctrl, channel, receiver+1, is_Width128, sysinfo)) {
+                               TestAddr1 = Get_RcvrSysAddr(ctrl, channel, receiver+1, sysinfo);
+                               TestAddr1B = TestAddr1 + (1<<(20+2-8)); //4MB
+                               two_ranks = 1;
+                       }
+                       else {
+                               two_ranks = 0;
+                       }
+
+                       print_debug_dqs("\t\tTrainRcvEn53: TestAddr0B ", TestAddr0B, 2); 
+
+                       Write1LTestPattern(TestAddr0, 0, buf_a, buf_b); // rank0 of dimm, test p0
+                       Write1LTestPattern(TestAddr0B, 1, buf_a, buf_b); //rank0 of dimm, test p1
+
+                       if(two_ranks == 1) {
+                               Write1LTestPattern(TestAddr1, 0, buf_a, buf_b); //rank 1 of dimm
+                               Write1LTestPattern(TestAddr1B, 1, buf_a, buf_b);//rank 1 of dimm
+                       }
+
+                       if(Pass == DQS_FIRST_PASS) {
+                               RcvrEnDly = 0; 
+                       } else {
+                               RcvrEnDly = dqs_rcvr_dly_a[channel * 8 + receiver];
+                       }
+
+                       while ( RcvrEnDly < 0xaf) { // Sweep Delay value here
+                               print_debug_dqs("\t\t\tTrainRcvEn541: RcvrEnDly ", RcvrEnDly, 3);
+
+                               if(RcvrEnDly & 1) {
+                                       /* Odd steps get another pattern such that even
+                                          and odd steps alternate.
+                                          The pointers to the patterns will be swapped
+                                          at the end of the loop so they are correspond
+                                       */
+                                       PatternA = 1;
+                                       PatternB = 0;
+                               }
+                               else {
+                                       /* Even step */
+                                       PatternA = 0;
+                                       PatternB = 1;
+                               }
+
+                               /* Program current Receiver enable delay */
+                               pci_write_config32_index_wait(ctrl->f2, 0x98, index, RcvrEnDly);
+       
+                               if(is_Width128) {
+                                       /* Program current Receiver enable delay chaannel b */
+                                       pci_write_config32_index_wait(ctrl->f2, 0x98, index+ 0x20, RcvrEnDly);
+                               }
+                       
+                                /* Program the MaxAsyncLat filed with the
+                                   current DQS receiver enable setting plus 6ns
+                                */     
+                               /*Porgram MaxAsyncLat to correspond with current delay */
+                               SetMaxAL_RcvrDly(ctrl, RcvrEnDly);
+
+                               CurrTest = DQS_FAIL;
+
+                               Read1LTestPattern(TestAddr0);  //Cache Fill
+                               /* ROM vs cache compare */
+                               Test0 = CompareTestPatternQW0(channel, TestAddr0, PatternA, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
+                               proc_IOCLFLUSH(TestAddr0);
+
+                               ResetDCTWrPtr(ctrl);
+
+                               print_debug_dqs("\t\t\tTrainRcvEn542: Test0 ", Test0, 3); 
+
+                               if(Test0 == DQS_PASS) {
+
+                                       Read1LTestPattern(TestAddr0B);
+                                               Test1 = CompareTestPatternQW0(channel, TestAddr0B, PatternB, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
+                                       proc_IOCLFLUSH(TestAddr0B);
+
+                                       ResetDCTWrPtr(ctrl);
+
+                                       print_debug_dqs("\t\t\tTrainRcvEn543: Test1 ", Test1, 3); 
+                                       
+                                       if(Test1 == DQS_PASS) {
+                                               if(two_ranks) {
+                                                       Read1LTestPattern(TestAddr1);
+                                                       Test0 = CompareTestPatternQW0(channel, TestAddr1, PatternA, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
+                                                       proc_IOCLFLUSH(TestAddr1);
+                                                       ResetDCTWrPtr(ctrl);
+
+                                                       if(Test0 == DQS_PASS) {
+                                                               Read1LTestPattern(TestAddr1B);
+                                                               Test1 = CompareTestPatternQW0(channel, TestAddr1B, PatternB, TestPattern0, TestPattern1, TestPattern2, Pass, is_Width128);
+                                                               proc_IOCLFLUSH(TestAddr1B);
+                                                               ResetDCTWrPtr(ctrl);
+
+                                                               if(Test1 == DQS_PASS) {
+                                                                       CurrTest = DQS_PASS;
+                                                               }
+                                                       } 
+                                                       print_debug_dqs("\t\t\tTrainRcvEn544: Test0 ", Test0, 3); 
+                                               }
+                                               else {
+                                                       CurrTest = DQS_PASS;
+                                               }
+                                       }
+                               }
+
+                               print_debug_dqs("\t\t\tTrainRcvEn55: RcvrEnDly ", RcvrEnDly, 3); 
+
+                               if(CurrTest == DQS_PASS) {
+                                       if(LastTest == DQS_FAIL) {
+                                               RcvrEnDlyRmin = RcvrEnDly;
+                                               break;
+                                       }
+                               }
+                               
+                               LastTest = CurrTest;
+                               
+                               /* swap the rank 0 pointers */
+                               tmp = TestAddr0;
+                               TestAddr0 = TestAddr0B;
+                               TestAddr0B = tmp;
+
+                               /* swap the rank 1 pointers */
+                                tmp = TestAddr1;
+                                TestAddr1 = TestAddr1B;
+                                TestAddr1B = tmp;
+
+                               print_debug_dqs("\t\t\tTrainRcvEn56: RcvrEnDly ", RcvrEnDly, 3); 
+                               
+                               RcvrEnDly++;
+                               
+                       } // while RcvrEnDly
+
+                       print_debug_dqs("\t\tTrainRcvEn61: RcvrEnDly ", RcvrEnDly, 2); 
+
+                       if(RcvrEnDlyRmin == 0xaf) {
+                               //no passing window
+                               Errors |= SB_NORCVREN;
+                       }
+
+                        if(Pass == DQS_FIRST_PASS) {
+                                // We need a better value for DQSPos trainning
+                                RcvrEnDly = RcvrEnDlyRmin /* + RCVREN_MARGIN * T1000/64/50 */;
+                        } else {
+                                RcvrEnDly = RcvrEnDlyRmin;
+                        }
+
+                        if(RcvrEnDly > 0xae) {
+                                //passing window too narrow, too far delayed
+                                Errors |= SB_SmallRCVR;
+                                RcvrEnDly = 0xae;
+                        }
+
+                        if(Pass == DQS_SECOND_PASS) { //second pass must average vales
+                                RcvrEnDly += dqs_rcvr_dly_a[channel * 8 + receiver] /* - (RCVREN_MARGIN * T1000/64/50)*/;
+                                RcvrEnDly >>= 1;
+                        }
+               
+                       dqs_rcvr_dly_a[channel * 8 + receiver] = RcvrEnDly; 
+       
+                       //Set final RcvrEnDly for this DIMM and Channel 
+                       pci_write_config32_index_wait(ctrl->f2, 0x98, index, RcvrEnDly);
+               
+                       if(is_Width128) {
+                               pci_write_config32_index_wait(ctrl->f2, 0x98, index+0x20, RcvrEnDly); // channel B
+                               if(channel) { 
+                                       pci_write_config32_index_wait(ctrl->f2, 0x98, index, CurrRcvrCHADelay);
+                                       if(RcvrEnDly > CurrRcvrCHADelay) {
+                                               dword = RcvrEnDly - CurrRcvrCHADelay;   
+                                       }
+                                       else {
+                                               dword = CurrRcvrCHADelay - RcvrEnDly;
+                                       }
+                                       dword *= 50;
+                                       if(dword > T1000) {
+                                               Errors |= SB_CHA2BRCVREN;
+                                       }
+                               }
+                       }
+
+                       print_debug_dqs("\t\tTrainRcvEn63: RcvrEnDly ", RcvrEnDly, 2); 
+
+                       if(RcvrEnDly > CTLRMaxDelay) {
+                               CTLRMaxDelay = RcvrEnDly;
+                       }
+
+                       print_debug_dqs("\t\tTrainRcvEn64: CTLRMaxDelay ", CTLRMaxDelay, 2); 
+                       
+               } /* receiver */
+       } /* channel */
+
+       print_debug_dqs("\tTrainRcvEn65: CTLRMaxDelay ", CTLRMaxDelay, 1); 
+
+        /* Program the MaxAsysncLat field with the largest DQS Receiver Enable setting */
+       SetMaxAL_RcvrDly(ctrl, CTLRMaxDelay);
+       ResetDCTWrPtr(ctrl);
+
+       //Enable ECC again 
+        dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+        dword &= ~(DCL_DimmEccEn);
+       dword |= ecc_bit;
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
+
+       if(Pass == DQS_FIRST_PASS) {
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+       if(!cpu_f0_f1) 
+#endif
+       {
+               dword = pci_read_config32(ctrl->f2, DRAM_CTRL);
+               dword &= ~DC_DqsRcvEnTrain;
+               pci_write_config32(ctrl->f2, DRAM_CTRL, dword);
+       }
+       }
+
+       //Clear wrap32dis 
+
+       clear_wrap32dis();
+
+       //restore SSE2 setting
+       disable_sse2();
+
+#if MEM_TRAIN_SEQ != 1  
+       /* We need tidy output for type 1 */
+       #if CONFIG_USE_INIT == 1
+       printk_debug(" CTLRMaxDelay=%02x", CTLRMaxDelay);
+       #else
+       print_debug(" CTLRMaxDelay="); print_debug_hex8(CTLRMaxDelay); 
+       #endif
+#endif
+
+       if(CTLRMaxDelay==0xae) {
+               soft_reset(); // try more or downgrade?
+       }
+
+}
+
+#define DQS_READDIR 1
+#define DQS_WRITEDIR 0
+
+
+static void SetDQSDelayCSR(const struct mem_controller *ctrl, unsigned channel, unsigned bytelane, unsigned direction, unsigned dqs_delay)
+{ //ByteLane could be 0-8, last is for ECC
+        unsigned index;
+        uint32_t dword;
+       unsigned shift;
+
+        dqs_delay &= 0xff;
+
+        index = (bytelane>>2) + 1 + channel * 0x20 + (direction << 2);
+       shift = bytelane;
+       while(shift>3) {
+               shift-=4;
+       }
+       shift <<= 3; // 8 bit
+
+        dword = pci_read_config32_index_wait(ctrl->f2, 0x98, index);
+       dword &= ~(0x3f<<shift);
+       dword |= (dqs_delay<<shift);
+       pci_write_config32_index_wait(ctrl->f2, 0x98, index, dword);
+
+}
+
+static void SetDQSDelayAllCSR(const struct mem_controller *ctrl, unsigned channel, unsigned direction, unsigned dqs_delay)
+{
+       unsigned index;
+       uint32_t dword;
+       int i;
+       
+       dword = 0;
+       dqs_delay &= 0xff;
+       for(i=0;i<4;i++) { 
+               dword |= dqs_delay<<(i*8);
+       }
+
+       index = 1 + channel * 0x20 + direction * 4;
+
+       for(i=0; i<2; i++) {
+               pci_write_config32_index_wait(ctrl->f2, 0x98, index + i, dword);
+       }
+       
+}
+
+static unsigned MiddleDQS(unsigned min_d, unsigned max_d)
+{
+       unsigned size_d;
+       size_d = max_d-min_d;
+       if(size_d & 1) { //need round up
+               min_d++;
+       }
+       return ( min_d + (size_d>>1));
+}
+
+static  inline void save_dqs_delay(unsigned channel, unsigned bytelane, unsigned direction, uint8_t *dqs_delay_a, uint8_t dqs_delay)
+{
+        dqs_delay_a[channel * 2*9 + direction * 9 + bytelane] = dqs_delay;
+}
+
+static void WriteDQSTestPattern(unsigned addr_lo, unsigned pattern , uint8_t *buf_a)
+{
+       WriteLNTestPattern(addr_lo, buf_a, (pattern+1) * 9);
+}
+
+static void ReadL18TestPattern(unsigned addr_lo) 
+{
+        //set fs and use fs prefix to access the mem
+        __asm__ volatile (
+                "movl %%fs:-128(%%esi), %%eax\n\t"  //TestAddr cache line
+               "movl %%fs:-64(%%esi), %%eax\n\t"   //+1
+               "movl %%fs:(%%esi), %%eax\n\t"  //+2
+               "movl %%fs:64(%%esi), %%eax\n\t"   //+3
+
+                "movl %%fs:-128(%%edi), %%eax\n\t"     //+4
+                "movl %%fs:-64(%%edi), %%eax\n\t"      //+5
+                "movl %%fs:(%%edi), %%eax\n\t" //+6
+                "movl %%fs:64(%%edi), %%eax\n\t"       //+7
+
+                "movl %%fs:-128(%%ebx), %%eax\n\t"  //+8
+                "movl %%fs:-64(%%ebx), %%eax\n\t"      //+9
+                "movl %%fs:(%%ebx), %%eax\n\t" //+10
+                "movl %%fs:64(%%ebx), %%eax\n\t"       //+11
+
+                "movl %%fs:-128(%%ecx), %%eax\n\t"     //+12
+                "movl %%fs:-64(%%ecx), %%eax\n\t"      //+13
+                "movl %%fs:(%%ecx), %%eax\n\t" //+14
+                "movl %%fs:64(%%ecx), %%eax\n\t"       //+15
+
+                "movl %%fs:-128(%%edx), %%eax\n\t"     //+16
+                "movl %%fs:-64(%%edx), %%eax\n\t"      //+17
+
+                :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64), "d" (addr_lo +128+16*64), "S"(addr_lo+128), "D"(addr_lo+128+4*64)
+        );
+
+}
+
+static void ReadL9TestPattern(unsigned addr_lo) 
+{
+
+        //set fs and use fs prefix to access the mem
+        __asm__ volatile (
+
+                "movl %%fs:-128(%%ecx), %%eax\n\t"  //TestAddr cache line
+                "movl %%fs:-64(%%ecx), %%eax\n\t"   //+1
+                "movl %%fs:(%%ecx), %%eax\n\t"      //+2
+                "movl %%fs:64(%%ecx), %%eax\n\t"   //+3
+
+                "movl %%fs:-128(%%edx), %%eax\n\t"  //+4
+                "movl %%fs:-64(%%edx), %%eax\n\t"   //+5
+                "movl %%fs:(%%edx), %%eax\n\t"      //+6
+                "movl %%fs:64(%%edx), %%eax\n\t"   //+7
+
+                "movl %%fs:-128(%%ebx), %%eax\n\t"      //+8
+
+                :: "a"(0), "b" (addr_lo+128+8*64), "c"(addr_lo+128), "d"(addr_lo+128+4*64) 
+        );
+
+}
+
+
+static void ReadDQSTestPattern(unsigned addr_lo, unsigned pattern)
+{
+       if(pattern == 0) {
+               ReadL9TestPattern(addr_lo);
+       }
+       else {
+               ReadL18TestPattern(addr_lo);
+       }
+}
+
+static void FlushDQSTestPattern_L9(unsigned addr_lo)
+{
+        __asm__ volatile (
+                "clflush %%fs:-128(%%ecx)\n\t"
+                "clflush %%fs:-64(%%ecx)\n\t"
+                "clflush %%fs:(%%ecx)\n\t"
+                "clflush %%fs:64(%%ecx)\n\t"
+
+                "clflush %%fs:-128(%%eax)\n\t"
+                "clflush %%fs:-64(%%eax)\n\t"
+                "clflush %%fs:(%%eax)\n\t"
+                "clflush %%fs:64(%%eax)\n\t"
+
+                "clflush %%fs:-128(%%ebx)\n\t"
+
+                ::  "b" (addr_lo+128+8*64), "c"(addr_lo+128), "a"(addr_lo+128+4*64)
+       );
+
+}
+static __attribute__((noinline)) void FlushDQSTestPattern_L18(unsigned addr_lo)
+{
+       __asm__ volatile (
+                "clflush %%fs:-128(%%eax)\n\t"
+                "clflush %%fs:-64(%%eax)\n\t"
+                "clflush %%fs:(%%eax)\n\t"
+                "clflush %%fs:64(%%eax)\n\t"
+
+                "clflush %%fs:-128(%%edi)\n\t"
+                "clflush %%fs:-64(%%edi)\n\t"
+                "clflush %%fs:(%%edi)\n\t"
+                "clflush %%fs:64(%%edi)\n\t"
+
+                "clflush %%fs:-128(%%ebx)\n\t"
+                "clflush %%fs:-64(%%ebx)\n\t"
+                "clflush %%fs:(%%ebx)\n\t"
+                "clflush %%fs:64(%%ebx)\n\t"
+
+                "clflush %%fs:-128(%%ecx)\n\t"
+                "clflush %%fs:-64(%%ecx)\n\t"
+                "clflush %%fs:(%%ecx)\n\t"
+                "clflush %%fs:64(%%ecx)\n\t"
+
+                "clflush %%fs:-128(%%edx)\n\t"
+                "clflush %%fs:-64(%%edx)\n\t"
+
+                :: "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64), "d" (addr_lo +128+16*64), "a"(addr_lo+128), "D"(addr_lo+128+4*64)
+       );
+}
+
+static void FlushDQSTestPattern(unsigned addr_lo, unsigned pattern )
+{
+       
+       if(pattern == 0){
+               FlushDQSTestPattern_L9(addr_lo);
+       }
+       else {
+               FlushDQSTestPattern_L18(addr_lo);
+       }
+}
+
+static unsigned CompareDQSTestPattern(unsigned channel, unsigned addr_lo, unsigned pattern, uint8_t *buf_a)
+{
+        uint32_t *test_buf;
+       unsigned bitmap = 0xff;
+       unsigned bytelane;
+       int i;
+       uint32_t value;
+       int j;
+       uint32_t value_test;
+
+        test_buf = (uint32_t *)buf_a;
+       
+
+        if(pattern && channel) {
+                addr_lo += 8; //second channel
+                test_buf+= 2;
+        }
+
+       bytelane = 0;
+       for(i=0;i<9*64/4;i++) {
+               __asm__ volatile (
+                       "movl %%fs:(%1), %0\n\t"
+                       :"=b"(value): "a" (addr_lo)
+               );
+               value_test = *test_buf;
+
+               print_debug_dqs_pair("\t\t\t\t\t\ttest_buf= ", (unsigned)test_buf, " value = ", value_test, 7); 
+               print_debug_dqs_pair("\t\t\t\t\t\ttaddr_lo = ",addr_lo, " value = ", value, 7);
+
+               for(j=0;j<4*8;j+=8) {
+                       if(((value>>j)&0xff) != ((value_test>>j)& 0xff)) {
+                               bitmap &= ~(1<<bytelane);
+                       }
+               
+                       bytelane++;
+                       bytelane &= 0x7; 
+               }
+               print_debug_dqs("\t\t\t\t\t\tbitmap = ", bitmap, 7);  
+
+               if(bytelane == 0) {
+                       if(pattern == 1) { //dual channel 
+                               addr_lo += 8; //skip over other channel's data
+                               test_buf += 2;
+                       }
+               }
+               addr_lo += 4;
+               test_buf +=1;
+               
+       }
+
+
+        return bitmap;
+
+}
+
+static unsigned TrainDQSPos(const struct mem_controller *ctrl, unsigned channel, unsigned Direction, unsigned Pattern, uint8_t *buf_a, uint8_t *dqs_delay_a, struct sys_info *sysinfo)
+{
+       unsigned ByteLane;
+       unsigned Errors;
+       unsigned BanksPresent;
+
+       unsigned MutualCSPassW[48];     
+
+       unsigned ChipSel;
+       unsigned DQSDelay;
+       
+       unsigned TestAddr;
+
+       unsigned LastTest;
+       unsigned RnkDlyFilterMax, RnkDlyFilterMin;
+       unsigned RnkDlySeqPassMax, RnkDlySeqPassMin;
+
+       Errors = 0;
+       BanksPresent = 0;
+
+       print_debug_dqs("\t\t\tTrainDQSPos begin ", 0, 3);
+
+       print_debug_addr("TrainDQSPos: MutualCSPassW[48] :", MutualCSPassW);
+
+       for(DQSDelay=0; DQSDelay<48; DQSDelay++) {
+               MutualCSPassW[DQSDelay] = 0xff; // Bitmapped status per delay setting, 0xff=All positions passing (1= PASS)
+       }
+
+       for(ChipSel = 0; ChipSel < 8; ChipSel++) { //logical register chipselects 0..7
+               print_debug_dqs("\t\t\t\tTrainDQSPos: 11 ChipSel ", ChipSel, 4); 
+               if(!ChipSelPresent(ctrl, ChipSel, sysinfo)) continue;
+               BanksPresent  = 1;
+
+               TestAddr = Get_MCTSysAddr(ctrl, ChipSel, sysinfo);
+
+               print_debug_dqs("\t\t\t\tTrainDQSPos: 12 TestAddr ", TestAddr, 4); 
+
+               //set fs and use fs prefix to access the mem
+               set_FSBASE(TestAddr>>24);
+
+               if(Direction == DQS_READDIR) {
+                       print_debug_dqs("\t\t\t\tTrainDQSPos: 13 for read so write at first", 0, 4);
+                       WriteDQSTestPattern(TestAddr<<8, Pattern, buf_a);
+               }
+
+               for(DQSDelay = 0; DQSDelay < 48; DQSDelay++ ){
+                       print_debug_dqs("\t\t\t\t\tTrainDQSPos: 141 DQSDelay ", DQSDelay, 5); 
+                       if(MutualCSPassW[DQSDelay] == 0) continue; //skip current delay value if other chipselects have failed all 8 bytelanes
+                       SetDQSDelayAllCSR(ctrl, channel, Direction, DQSDelay);
+                       print_debug_dqs("\t\t\t\t\tTrainDQSPos: 142 MutualCSPassW ", MutualCSPassW[DQSDelay], 5); 
+                       if(Direction == DQS_WRITEDIR) {
+                               print_debug_dqs("\t\t\t\t\tTrainDQSPos: 143 for write", 0, 5);
+                               WriteDQSTestPattern(TestAddr<<8, Pattern, buf_a); 
+                       }
+                       print_debug_dqs("\t\t\t\t\tTrainDQSPos: 144 Pattern ", Pattern, 5);
+                       ReadDQSTestPattern(TestAddr<<8, Pattern); 
+                       print_debug_dqs("\t\t\t\t\tTrainDQSPos: 145 MutualCSPassW ", MutualCSPassW[DQSDelay], 5);
+                       MutualCSPassW[DQSDelay] &= CompareDQSTestPattern(channel, TestAddr<<8, Pattern, buf_a); //0: fail, 1=pass
+                       print_debug_dqs("\t\t\t\t\tTrainDQSPos: 146 MutualCSPassW ", MutualCSPassW[DQSDelay], 5); 
+                       SetTargetWTIO(TestAddr);
+                       FlushDQSTestPattern(TestAddr<<8, Pattern); 
+                       ResetTargetWTIO();
+               }
+       }
+
+       if(BanksPresent) 
+       for(ByteLane = 0; ByteLane < 8; ByteLane++) {
+               print_debug_dqs("\t\t\t\tTrainDQSPos: 31 ByteLane ",ByteLane, 4); 
+
+               LastTest = DQS_FAIL;
+               RnkDlySeqPassMax = 0;
+               RnkDlyFilterMax = 0;
+               RnkDlyFilterMin = 0;
+               for(DQSDelay=0; DQSDelay<48; DQSDelay++) {
+                       if(MutualCSPassW[DQSDelay] & (1<<ByteLane)) {
+
+                               print_debug_dqs("\t\t\t\t\tTrainDQSPos: 321 DQSDelay ", DQSDelay, 5); 
+                               print_debug_dqs("\t\t\t\t\tTrainDQSPos: 322 MutualCSPassW ", MutualCSPassW[DQSDelay], 5); 
+
+                               RnkDlySeqPassMax = DQSDelay;
+                               if(LastTest == DQS_FAIL) {
+                                       RnkDlySeqPassMin = DQSDelay; //start sequential run
+                               }
+                               if((RnkDlySeqPassMax - RnkDlySeqPassMin)>(RnkDlyFilterMax-RnkDlyFilterMin)){
+                                       RnkDlyFilterMin = RnkDlySeqPassMin;
+                                       RnkDlyFilterMax = RnkDlySeqPassMax;
+                               }
+                               LastTest = DQS_PASS;
+                       }
+                       else {
+                               LastTest = DQS_FAIL;
+                       }
+               }
+               print_debug_dqs("\t\t\t\tTrainDQSPos: 33 RnkDlySeqPassMax ", RnkDlySeqPassMax, 4); 
+
+               if(RnkDlySeqPassMax == 0) {
+                       Errors |= SB_NODQSPOS; // no passing window
+               }
+               else {
+                       print_debug_dqs("\t\t\t\tTrainDQSPos: 34 RnkDlyFilterMax ", RnkDlyFilterMax, 4); 
+                       print_debug_dqs("\t\t\t\tTrainDQSPos: 34 RnkDlyFilterMin ", RnkDlyFilterMin, 4); 
+                       if((RnkDlyFilterMax - RnkDlyFilterMin)< MIN_DQS_WNDW){
+                               Errors |= SB_SMALLDQS;
+                       }
+                       else {
+                               unsigned middle_dqs;
+                               middle_dqs = MiddleDQS(RnkDlyFilterMin, RnkDlyFilterMax); 
+                               print_debug_dqs("\t\t\t\tTrainDQSPos: 35 middle_dqs ",middle_dqs, 4); 
+                               SetDQSDelayCSR(ctrl, channel, ByteLane, Direction, middle_dqs);
+                               save_dqs_delay(channel, ByteLane, Direction, dqs_delay_a, middle_dqs);
+                       }
+               }       
+
+       }
+
+       print_debug_dqs("\t\t\tTrainDQSPos: end", 0xff, 3);
+       
+       return Errors;
+       
+
+}
+
+static unsigned TrainReadDQS(const struct mem_controller *ctrl, unsigned channel, unsigned pattern, uint8_t *buf_a, uint8_t *dqs_delay_a, struct sys_info *sysinfo)
+{
+       print_debug_dqs("\t\tTrainReadPos", 0, 2); 
+       return TrainDQSPos(ctrl, channel, DQS_READDIR, pattern, buf_a, dqs_delay_a, sysinfo);   
+}
+
+static unsigned TrainWriteDQS(const struct mem_controller *ctrl, unsigned channel, unsigned pattern, uint8_t *buf_a, uint8_t *dqs_delay_a, struct sys_info *sysinfo)
+{
+       print_debug_dqs("\t\tTrainWritePos", 0, 2);
+        return TrainDQSPos(ctrl, channel, DQS_WRITEDIR, pattern, buf_a, dqs_delay_a, sysinfo);
+}
+
+
+
+static unsigned TrainDQSRdWrPos(const struct mem_controller *ctrl, struct sys_info *sysinfo)
+{
+        const static uint32_t TestPatternJD1a[] = {
+                                       0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, // QW0-1, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW2-3, ALL-EVEN
+                                        0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, // QW4-5, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW6-7, ALL-EVEN
+                                        0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, // QW0-1, DQ0-ODD
+                                        0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, // QW2-3, DQ0-ODD
+                                        0x01010101,0x01010101,0xFeFeFeFe,0xFeFeFeFe, // QW4-5, DQ0-ODD
+                                        0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, // QW6-7, DQ0-ODD
+                                        0x02020202,0x02020202,0x02020202,0x02020202, // QW0-1, DQ1-ODD
+                                        0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW2-3, DQ1-ODD
+                                        0xFdFdFdFd,0xFdFdFdFd,0x02020202,0x02020202, // QW4-5, DQ1-ODD
+                                        0x02020202,0x02020202,0x02020202,0x02020202, // QW6-7, DQ1-ODD
+                                        0x04040404,0x04040404,0xfBfBfBfB,0xfBfBfBfB, // QW0-1, DQ2-ODD
+                                        0x04040404,0x04040404,0x04040404,0x04040404, // QW2-3, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW4-5, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW6-7, DQ2-ODD
+                                        0x08080808,0x08080808,0xF7F7F7F7,0xF7F7F7F7, // QW0-1, DQ3-ODD
+                                        0x08080808,0x08080808,0x08080808,0x08080808, // QW2-3, DQ3-ODD
+                                        0xF7F7F7F7,0xF7F7F7F7,0x08080808,0x08080808, // QW4-5, DQ3-ODD
+                                        0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW6-7, DQ3-ODD
+                                        0x10101010,0x10101010,0x10101010,0x10101010, // QW0-1, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, // QW2-3, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW4-5, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, // QW6-7, DQ4-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW0-1, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0x20202020,0x20202020, // QW2-3, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW4-5, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW6-7, DQ5-ODD
+                                        0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW0-1, DQ6-ODD
+                                        0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, // QW2-3, DQ6-ODD
+                                        0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, // QW4-5, DQ6-ODD
+                                        0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, // QW6-7, DQ6-ODD
+                                        0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, // QW0-1, DQ7-ODD
+                                        0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, // QW2-3, DQ7-ODD
+                                        0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, // QW4-5, DQ7-ODD
+                                        0x80808080,0x80808080,0x80808080,0x80808080  // QW6-7, DQ7-ODD
+                };
+        const static uint32_t TestPatternJD1b[] = {
+                                       0x00000000,0x00000000,0x00000000,0x00000000, // QW0,CHA-B, ALL-EVEN
+                                        0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, // QW1,CHA-B, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW2,CHA-B, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW3,CHA-B, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW4,CHA-B, ALL-EVEN
+                                        0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, // QW5,CHA-B, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW6,CHA-B, ALL-EVEN
+                                        0x00000000,0x00000000,0x00000000,0x00000000, // QW7,CHA-B, ALL-EVEN
+                                        0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW0,CHA-B, DQ0-ODD
+                                        0x01010101,0x01010101,0x01010101,0x01010101, // QW1,CHA-B, DQ0-ODD
+                                        0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW2,CHA-B, DQ0-ODD
+                                        0x01010101,0x01010101,0x01010101,0x01010101, // QW3,CHA-B, DQ0-ODD
+                                        0x01010101,0x01010101,0x01010101,0x01010101, // QW4,CHA-B, DQ0-ODD
+                                        0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW5,CHA-B, DQ0-ODD
+                                        0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, // QW6,CHA-B, DQ0-ODD
+                                        0x01010101,0x01010101,0x01010101,0x01010101, // QW7,CHA-B, DQ0-ODD
+                                       0x02020202,0x02020202,0x02020202,0x02020202, // QW0,CHA-B, DQ1-ODD
+                                       0x02020202,0x02020202,0x02020202,0x02020202, // QW1,CHA-B, DQ1-ODD
+                                        0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW2,CHA-B, DQ1-ODD
+                                        0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW3,CHA-B, DQ1-ODD
+                                       0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, // QW4,CHA-B, DQ1-ODD
+                                       0x02020202,0x02020202,0x02020202,0x02020202, // QW5,CHA-B, DQ1-ODD
+                                        0x02020202,0x02020202,0x02020202,0x02020202, // QW6,CHA-B, DQ1-ODD
+                                        0x02020202,0x02020202,0x02020202,0x02020202, // QW7,CHA-B, DQ1-ODD
+                                        0x04040404,0x04040404,0x04040404,0x04040404, // QW0,CHA-B, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW1,CHA-B, DQ2-ODD
+                                        0x04040404,0x04040404,0x04040404,0x04040404, // QW2,CHA-B, DQ2-ODD
+                                        0x04040404,0x04040404,0x04040404,0x04040404, // QW3,CHA-B, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW4,CHA-B, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW5,CHA-B, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW6,CHA-B, DQ2-ODD
+                                        0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, // QW7,CHA-B, DQ2-ODD
+                                        0x08080808,0x08080808,0x08080808,0x08080808, // QW0,CHA-B, DQ3-ODD
+                                        0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW1,CHA-B, DQ3-ODD
+                                        0x08080808,0x08080808,0x08080808,0x08080808, // QW2,CHA-B, DQ3-ODD
+                                        0x08080808,0x08080808,0x08080808,0x08080808, // QW3,CHA-B, DQ3-ODD
+                                        0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW4,CHA-B, DQ3-ODD
+                                        0x08080808,0x08080808,0x08080808,0x08080808, // QW5,CHA-B, DQ3-ODD
+                                        0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW6,CHA-B, DQ3-ODD
+                                        0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, // QW7,CHA-B, DQ3-ODD
+                                        0x10101010,0x10101010,0x10101010,0x10101010, // QW0,CHA-B, DQ4-ODD
+                                        0x10101010,0x10101010,0x10101010,0x10101010, // QW1,CHA-B, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW2,CHA-B, DQ4-ODD
+                                        0x10101010,0x10101010,0x10101010,0x10101010, // QW3,CHA-B, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW4,CHA-B, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW5,CHA-B, DQ4-ODD
+                                        0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, // QW6,CHA-B, DQ4-ODD
+                                        0x10101010,0x10101010,0x10101010,0x10101010, // QW7,CHA-B, DQ4-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW0,CHA-B, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW1,CHA-B, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW2,CHA-B, DQ5-ODD
+                                        0x20202020,0x20202020,0x20202020,0x20202020, // QW3,CHA-B, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW4,CHA-B, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW5,CHA-B, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW6,CHA-B, DQ5-ODD
+                                        0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, // QW7,CHA-B, DQ5-ODD
+                                        0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW0,CHA-B, DQ6-ODD
+                                        0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW1,CHA-B, DQ6-ODD
+                                        0x40404040,0x40404040,0x40404040,0x40404040, // QW2,CHA-B, DQ6-ODD
+                                        0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW3,CHA-B, DQ6-ODD
+                                        0x40404040,0x40404040,0x40404040,0x40404040, // QW4,CHA-B, DQ6-ODD
+                                        0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW5,CHA-B, DQ6-ODD
+                                        0x40404040,0x40404040,0x40404040,0x40404040, // QW6,CHA-B, DQ6-ODD
+                                        0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, // QW7,CHA-B, DQ6-ODD
+                                        0x80808080,0x80808080,0x80808080,0x80808080, // QW0,CHA-B, DQ7-ODD
+                                        0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, // QW1,CHA-B, DQ7-ODD
+                                        0x80808080,0x80808080,0x80808080,0x80808080, // QW2,CHA-B, DQ7-ODD
+                                        0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, // QW3,CHA-B, DQ7-ODD
+                                        0x80808080,0x80808080,0x80808080,0x80808080, // QW4,CHA-B, DQ7-ODD
+                                        0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, // QW5,CHA-B, DQ7-ODD
+                                        0x80808080,0x80808080,0x80808080,0x80808080, // QW6,CHA-B, DQ7-ODD
+                                        0x80808080,0x80808080,0x80808080,0x80808080  // QW7,CHA-B, DQ7-ODD
+                };
+        uint8_t pattern_buf_x[64 * 18 + 16]; // We need to two cache line So have more 16 bytes to keep 16 byte alignment */
+        uint8_t *buf_a;
+
+       unsigned pattern;
+       uint32_t dword;
+       uint32_t ecc_bit;
+       unsigned Errors;
+       unsigned channel;
+       int i;
+       unsigned DQSWrDelay;
+       unsigned is_Width128 = sysinfo->meminfo[ctrl->node_id].is_Width128;
+       uint8_t *dqs_delay_a = &sysinfo->dqs_delay_a[ctrl->node_id * 2*2*9]; //channel 2, direction 2 , bytelane *9
+
+        //enable SSE2
+        enable_sse2();
+
+        //wrap32dis
+        set_wrap32dis();
+
+        //disable ECC temp
+        dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+        ecc_bit = dword & DCL_DimmEccEn;
+        dword &= ~(DCL_DimmEccEn);
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
+
+       //SetupDqsPattern
+       buf_a = (uint8_t *)(((uint32_t)(&pattern_buf_x[0]) + 0x10) & (~0xf));
+
+       if(is_Width128){
+               pattern = 1;
+               for(i=0;i<16*18;i++) {
+                       *((uint32_t *)(buf_a + i*4)) = TestPatternJD1b[i];
+                        }
+       }
+       else {
+               pattern = 0;
+               for(i=0; i<16*9;i++) {
+                       *((uint32_t *)(buf_a + i*4)) = TestPatternJD1a[i];
+               }
+               
+       }
+
+       print_debug_dqs("\r\nTrainDQSRdWrPos: 0 ctrl ", ctrl->node_id, 0); 
+
+       print_debug_addr("TrainDQSRdWrPos: buf_a:", buf_a);
+
+       Errors = 0;
+
+       channel = 0;
+       while( (channel<2) && (!Errors)) {
+               print_debug_dqs("\tTrainDQSRdWrPos: 1 channel ",channel, 1); 
+               for(DQSWrDelay = 0; DQSWrDelay < 48; DQSWrDelay++) {
+                       unsigned err;
+                       SetDQSDelayAllCSR(ctrl, channel, DQS_WRITEDIR, DQSWrDelay);
+                       print_debug_dqs("\t\tTrainDQSRdWrPos: 21 DQSWrDelay ", DQSWrDelay, 2); 
+                       err= TrainReadDQS(ctrl, channel, pattern, buf_a, dqs_delay_a, sysinfo);
+                       print_debug_dqs("\t\tTrainDQSRdWrPos: 22 err ",err, 2); 
+                       if(err == 0) break;
+                       Errors |= err;
+               }
+
+               print_debug_dqs("\tTrainDQSRdWrPos: 3 DQSWrDelay ", DQSWrDelay, 1); 
+
+               if(DQSWrDelay < 48) {
+                       Errors = TrainWriteDQS(ctrl, channel, pattern, buf_a, dqs_delay_a, sysinfo);
+                       print_debug_dqs("\tTrainDQSRdWrPos: 4 Errors ", Errors, 1); 
+
+               }
+               channel++;
+               if(!is_Width128){
+                       channel++; // skip channel if 64-bit mode
+               }
+       }
+
+        //Enable ECC again
+        dword = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
+        dword &= ~(DCL_DimmEccEn);
+        dword |= ecc_bit;
+        pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dword);
+
+        //Clear wrap32dis
+
+        clear_wrap32dis();
+
+        //restore SSE2 setting
+        disable_sse2();
+
+       print_debug_dqs("TrainDQSRdWrPos: ", 5, 0); 
+       
+       return Errors;
+
+}
+static inline uint8_t get_dqs_delay(unsigned channel, unsigned bytelane, unsigned direction, uint8_t *dqs_delay_a)
+{
+       return dqs_delay_a[channel * 2*9 + direction * 9 + bytelane];
+}
+
+static unsigned CalcEccDQSPos(unsigned channel,unsigned ByteLane0, unsigned ByteLane1, unsigned InterFactor, unsigned Direction, uint8_t *dqs_delay_a)
+/* InterFactor: 0: 100% ByteLane 0
+                0x80: 50% between ByteLane 0 and 1
+               0xff: 99.6% ByteLane 1 and 0.4% like 0
+*/
+{
+       unsigned DQSDelay0, DQSDelay1;
+       unsigned DQSDelay;
+       
+       DQSDelay0 = get_dqs_delay(channel, ByteLane0, Direction, dqs_delay_a);
+       DQSDelay1 = get_dqs_delay(channel, ByteLane1, Direction, dqs_delay_a); 
+       
+       if(DQSDelay0>DQSDelay1) {
+               DQSDelay = DQSDelay0 - DQSDelay1;
+               InterFactor = 0xff - InterFactor;
+       }
+       else {
+               DQSDelay = DQSDelay1 - DQSDelay0;
+       }
+
+       DQSDelay *= InterFactor;
+
+       DQSDelay >>= 8; // /255
+
+        if(DQSDelay0>DQSDelay1) {
+                DQSDelay += DQSDelay1;
+        }
+        else {
+                DQSDelay += DQSDelay0;
+        }
+
+       return DQSDelay;
+
+}
+
+static void SetEccDQSRdWrPos(const struct mem_controller *ctrl, struct sys_info *sysinfo)
+{      
+       unsigned channel;
+       unsigned ByteLane;
+       unsigned Direction;
+       unsigned lane0, lane1, ratio;
+       unsigned dqs_delay;
+
+       unsigned direction[] = { DQS_READDIR, DQS_WRITEDIR };
+       int i;
+       uint8_t *dqs_delay_a = &sysinfo->dqs_delay_a[ctrl->node_id * 2*2*9]; //channel 2, direction 2 , bytelane *9
+
+       ByteLane = 8;
+
+       for(channel = 0; channel < 2; channel++) {
+               for(i=0;i<2;i++) {
+                       Direction = direction[i];
+                       lane0 = 4; lane1 = 5; ratio = 0;
+                       dqs_delay = CalcEccDQSPos(channel, lane0, lane1, ratio, Direction, dqs_delay_a);
+                       print_debug_dqs_pair("\t\tSetEccDQSRdWrPos: channel ", channel, Direction==DQS_READDIR? " R dqs_delay":" W dqs_delay",  dqs_delay, 2); 
+                       SetDQSDelayCSR(ctrl, channel, ByteLane, Direction, dqs_delay);
+                       save_dqs_delay(channel, ByteLane, Direction, dqs_delay_a, dqs_delay);
+               }
+       }
+}
+
+static void train_DqsRcvrEn(const struct mem_controller *ctrl, unsigned Pass, struct sys_info *sysinfo)
+{
+       print_debug_dqs("\r\ntrain_DqsRcvrEn: begin ctrl ", ctrl->node_id, 0); 
+       TrainRcvrEn(ctrl, Pass, sysinfo);
+       print_debug_dqs("\r\ntrain_DqsRcvrEn: end ctrl ", ctrl->node_id, 0); 
+       
+}
+static  void train_DqsPos(const struct mem_controller *ctrl, struct sys_info *sysinfo)
+{
+       print_debug_dqs("\r\ntrain_DqsPos: begin ctrl ", ctrl->node_id, 0); 
+       if(TrainDQSRdWrPos(ctrl, sysinfo) != 0) {
+                print_err("\r\nDQS Training Rd Wr failed ctrl"); print_err_hex8(ctrl->node_id); print_err("\r\n");
+               soft_reset();
+       }
+       else {
+               SetEccDQSRdWrPos(ctrl, sysinfo);
+       }
+       print_debug_dqs("\r\ntrain_DqsPos: end ctrl ", ctrl->node_id, 0); 
+       
+}
+
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+static void f0_svm_workaround(int controllers, const struct mem_controller *ctrl, tsc_t *tsc0, struct sys_info *sysinfo)
+{
+        tsc_t tsc1[8];
+       unsigned cpu_f0_f1[8];
+       int i;
+
+        print_debug_addr("dqs_timing: tsc1[8] :", tsc1);
+
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[i])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+               if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+                uint32_t dword;
+
+                cpu_f0_f1[i] = is_cpu_pre_f2_in_bsp(i);
+
+                if(!cpu_f0_f1[i]) continue;
+
+                dword = pci_read_config32(ctrl[i].f2, DRAM_CTRL);
+                dword &= ~DC_DqsRcvEnTrain;
+                pci_write_config32(ctrl[i].f2, DRAM_CTRL, dword);
+
+                dword = pci_read_config32(ctrl[i].f2, DRAM_INIT);
+                dword |= DI_EnDramInit;
+                pci_write_config32(ctrl[i].f2, DRAM_INIT, dword);
+                dword &= ~DI_EnDramInit;
+                pci_write_config32(ctrl[i].f2, DRAM_INIT, dword);
+
+                tsc1[i] = rdtsc();
+                print_debug_dqs_tsc("begin: tsc1", i, tsc1[i].hi, tsc1[i].lo, 2);
+
+                dword = tsc1[i].lo + tsc0[i].lo;
+                if((dword<tsc1[i].lo) || (dword<tsc0[i].lo)) {
+                        tsc1[i].hi++;
+                }
+                tsc1[i].lo = dword;
+                tsc1[i].hi+= tsc0[i].hi;
+
+                print_debug_dqs_tsc("end  : tsc1", i, tsc1[i].hi, tsc1[i].lo, 2);
+
+        }
+
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[i])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+               if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+               if(!cpu_f0_f1[i]) continue;
+
+                tsc_t tsc;
+
+                do {
+                        tsc = rdtsc();
+                } while ((tsc1[i].hi>tsc.hi) || ((tsc1[i].hi==tsc.hi) && (tsc1[i].lo>tsc.lo)));
+
+                print_debug_dqs_tsc("end  : tsc ", i, tsc.hi, tsc.lo, 2);
+        }
+
+}
+
+#endif
+
+
+/* setting variable mtrr, comes from linux kernel source */
+static void set_var_mtrr_dqs(
+        unsigned int reg, unsigned long basek, unsigned long sizek,
+        unsigned char type, unsigned address_bits)
+{
+        msr_t base, mask;
+        unsigned address_mask_high;
+
+        address_mask_high = ((1u << (address_bits - 32u)) - 1u);
+
+        base.hi = basek >> 22;
+        base.lo  = basek << 10;
+
+        if (sizek < 4*1024*1024) {
+                mask.hi = address_mask_high;
+                mask.lo = ~((sizek << 10) -1);
+        }
+        else {
+                mask.hi = address_mask_high & (~((sizek >> 22) -1));
+                mask.lo = 0;
+        }
+
+        if (reg >= 8)
+                return;
+
+        if (sizek == 0) {
+                msr_t zero;
+                zero.lo = zero.hi = 0;
+                /* The invalid bit is kept in the mask, so we simply clear the
+                   relevant mask register to disable a range. */
+                wrmsr (MTRRphysMask_MSR(reg), zero);
+        } else {
+                /* Bit 32-35 of MTRRphysMask should be set to 1 */
+                base.lo |= type;
+                mask.lo |= 0x800;
+                wrmsr (MTRRphysBase_MSR(reg), base);
+                wrmsr (MTRRphysMask_MSR(reg), mask);
+        }
+}
+
+
+/* fms: find most sigificant bit set, stolen from Linux Kernel Source. */
+static inline unsigned int fms(unsigned int x)
+{
+        int r;
+
+        __asm__("bsrl %1,%0\n\t"
+                "jnz 1f\n\t"
+                "movl $0,%0\n"
+                "1:" : "=r" (r) : "g" (x));
+        return r;
+}
+
+/* fms: find least sigificant bit set */
+static inline unsigned int fls(unsigned int x)
+{
+        int r;
+
+        __asm__("bsfl %1,%0\n\t"
+                "jnz 1f\n\t"
+                "movl $32,%0\n"
+                "1:" : "=r" (r) : "g" (x));
+        return r;
+}
+
+static unsigned int range_to_mtrr(unsigned int reg,
+        unsigned long range_startk, unsigned long range_sizek,
+        unsigned long next_range_startk, unsigned char type, unsigned address_bits)
+{
+        if (!range_sizek || (reg >= 8)) {
+                return reg;
+        }
+        while(range_sizek) {
+                unsigned long max_align, align;
+                unsigned long sizek;
+                /* Compute the maximum size I can make a range */
+                max_align = fls(range_startk);
+                align = fms(range_sizek);
+                if (align > max_align) {
+                        align = max_align;
+                }
+                sizek = 1 << align;
+#if MEM_TRAIN_SEQ != 1
+       #if CONFIG_USE_INIT == 1
+                printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type %s\r\n",
+                        reg, range_startk >>10, sizek >> 10,
+                        (type==MTRR_TYPE_UNCACHEABLE)?"UC":
+                            ((type==MTRR_TYPE_WRBACK)?"WB":"Other")
+                        );
+       #else
+                print_debug("Setting variable MTRR "); print_debug_hex8(reg); print_debug(", base: "); print_debug_hex16(range_startk>>10); 
+                       print_debug("MB, range: "); print_debug_hex16(sizek >> 10); print_debug("MB, type "); 
+                       print_debug( (type==MTRR_TYPE_UNCACHEABLE)?"UC\r\n":
+                                      ((type==MTRR_TYPE_WRBACK)?"WB\r\n":"Other\r\n")
+                                   );
+       #endif
+#endif
+                set_var_mtrr_dqs(reg++, range_startk, sizek, type, address_bits);
+                range_startk += sizek;
+                range_sizek -= sizek;
+                if (reg >= 8)
+                        break;
+        }
+        return reg;
+}
+
+static void set_top_mem_ap(unsigned tom_k, unsigned tom2_k)
+{
+        msr_t msr;
+
+        /* Now set top of memory */
+        msr.lo = (tom2_k & 0x003fffff) << 10;
+        msr.hi = (tom2_k & 0xffc00000) >> 22;
+        wrmsr(TOP_MEM2, msr);
+
+        msr.lo = (tom_k & 0x003fffff) << 10;
+        msr.hi = (tom_k & 0xffc00000) >> 22;
+        wrmsr(TOP_MEM, msr);
+}
+
+static void setup_mtrr_dqs(unsigned tom_k, unsigned tom2_k){
+        unsigned reg;
+        msr_t msr;
+
+#if 0
+        //still enable from cache_as_ram.inc
+        msr = rdmsr(SYSCFG_MSR);
+        msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
+        wrmsr(SYSCFG_MSR,msr);
+#endif
+
+        //[0,512k), [512k, 640k)
+        msr.hi = 0x1e1e1e1e;
+        msr.lo = msr.hi;
+        wrmsr(0x250, msr);
+        wrmsr(0x258, msr);
+
+        //[1M, TOM)
+        reg = range_to_mtrr(2, 0, tom_k,4*1024*1024, MTRR_TYPE_WRBACK, 40);
+
+        //[4G, TOM2)
+        if(tom2_k) {
+                //enable tom2 and type
+                msr = rdmsr(SYSCFG_MSR);
+                msr.lo |= (1<<21) | (1<<22); //MtrrTom2En and Tom2ForceMemTypeWB
+                wrmsr(SYSCFG_MSR, msr);
+        }
+
+}
+
+static void clear_mtrr_dqs(unsigned tom2_k){
+        msr_t msr;
+        unsigned i;
+
+        //still enable from cache_as_ram.inc
+        msr = rdmsr(SYSCFG_MSR);
+        msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
+        wrmsr(SYSCFG_MSR,msr);
+
+        //[0,512k), [512k, 640k)
+        msr.hi = 0;
+        msr.lo = msr.hi;
+        wrmsr(0x250, msr);
+        wrmsr(0x258, msr);
+
+        //[1M, TOM)
+        for(i=0x204;i<0x210;i++) {
+                wrmsr(i, msr);
+        }
+
+        //[4G, TOM2)
+        if(tom2_k) {
+                //enable tom2 and type
+                msr = rdmsr(SYSCFG_MSR);
+                msr.lo &= ~((1<<21) | (1<<22)); //MtrrTom2En and Tom2ForceMemTypeWB
+                wrmsr(SYSCFG_MSR, msr);
+        }
+}
+
+static void set_htic_bit(unsigned i, unsigned val, unsigned bit)
+{
+        uint32_t dword;
+        dword = pci_read_config32(PCI_DEV(0, 0x18+i, 0), HT_INIT_CONTROL);
+        dword &= ~(1<<bit);
+        dword |= ((val & 1) <<bit);
+        pci_write_config32(PCI_DEV(0, 0x18+i, 0), HT_INIT_CONTROL, dword);
+}
+
+
+static unsigned get_htic_bit(unsigned i, unsigned bit)
+{
+        uint32_t dword;
+        dword = pci_read_config32(PCI_DEV(0, 0x18+i, 0), HT_INIT_CONTROL);
+        dword &= (1<<bit);
+        return dword;
+}
+
+static void wait_till_sysinfo_in_ram(void)
+{
+        while(1) {
+                if(get_htic_bit(0, 9)) return;
+        }
+}
+
+static void set_sysinfo_in_ram(unsigned val)
+{
+        set_htic_bit(0, val, 9);
+}
+
+
+#if MEM_TRAIN_SEQ == 0
+
+
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+static void dqs_timing(int controllers, const struct mem_controller *ctrl, tsc_t *tsc0, struct sys_info *sysinfo)
+#else
+static void dqs_timing(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
+#endif
+{
+       int  i;
+
+       tsc_t tsc[5];
+
+        //need to enable mtrr, so dqs training could access the test address
+        setup_mtrr_dqs(sysinfo->tom_k, sysinfo->tom2_k);
+
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[ i ])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+                if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+               fill_mem_cs_sysinfo(i, ctrl+i, sysinfo);
+       }
+
+       tsc[0] = rdtsc();
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[ i ])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+               if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+                print_debug("DQS Training:RcvrEn:Pass1: ");
+                print_debug_hex8(i);
+                train_DqsRcvrEn(ctrl+i, 1, sysinfo);
+                       print_debug(" done\r\n");
+        }
+
+       tsc[1] = rdtsc();
+#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
+       f0_svm_workaround(controllers, ctrl, tsc0, sysinfo);
+#endif
+
+       tsc[2] = rdtsc();
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[i])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+               if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+                print_debug("DQS Training:DQSPos: ");
+                print_debug_hex8(i);
+                train_DqsPos(ctrl+i, sysinfo);
+                print_debug(" done\r\n");
+        }
+
+       tsc[3] = rdtsc();
+        for(i = 0; i < controllers; i++) {
+                if (!sysinfo->ctrl_present[i])
+                        continue;
+
+                /* Skip everything if I don't have any memory on this controller */
+               if(sysinfo->meminfo[i].dimm_mask==0x00) continue;
+
+                print_debug("DQS Training:RcvrEn:Pass2: ");
+                print_debug_hex8(i);
+                train_DqsRcvrEn(ctrl+i, 2, sysinfo);
+                print_debug(" done\r\n");
+               sysinfo->mem_trained[i]=1;
+        }
+
+       tsc[4] = rdtsc();
+       clear_mtrr_dqs(sysinfo->tom2_k);
+
+
+       for(i=0;i<5;i++) {
+               print_debug_dqs_tsc_x("DQS Training:tsc", i,  tsc[i].hi, tsc[i].lo);
+       }
+
+
+       
+}
+
+#endif
+
+
+#if MEM_TRAIN_SEQ > 0 
+
+static void dqs_timing(int i, const struct mem_controller *ctrl, struct sys_info *sysinfo, unsigned v)
+{
+
+        int ii;
+
+         tsc_t tsc[4];
+
+
+#if MEM_TRAIN_SEQ == 1
+       if(sysinfo->mem_trained[i]) return;
+        //need to enable mtrr, so dqs training could access the test address
+        setup_mtrr_dqs(sysinfo->tom_k, sysinfo->tom2_k);
+#endif
+
+       fill_mem_cs_sysinfo(i, ctrl+i, sysinfo);
+
+       if(v) {
+               tsc[0] = rdtsc();
+
+               print_debug("set DQS timing:RcvrEn:Pass1: ");
+               print_debug_hex8(i);
+       }
+        train_DqsRcvrEn(ctrl+i, 1,  sysinfo);
+
+       if(v) {
+               print_debug(" done\r\n");
+               tsc[1] = rdtsc();
+               print_debug("set DQS timing:DQSPos: ");
+               print_debug_hex8(i);
+       }
+
+        train_DqsPos(ctrl+i, sysinfo);
+       
+       if(v) {
+               print_debug(" done\r\n");
+               tsc[2] = rdtsc();
+
+               print_debug("set DQS timing:RcvrEn:Pass2: ");
+               print_debug_hex8(i);
+       }
+        train_DqsRcvrEn(ctrl+i, 2,  sysinfo);
+
+       if(v) {
+               print_debug(" done\r\n");
+
+               tsc[3] = rdtsc();
+       }
+
+#if MEM_TRAIN_SEQ == 1
+        clear_mtrr_dqs(sysinfo->tom2_k);
+#endif
+
+       if(v) {
+               for(ii=0;ii<4;ii++) {
+                     print_debug_dqs_tsc_x("Total DQS Training : tsc ", ii,  tsc[ii].hi, tsc[ii].lo);
+               }
+       }
+
+       sysinfo->mem_trained[i]=1;
+
+}
+#endif
+
+#if MEM_TRAIN_SEQ == 1
+static void train_ram(unsigned nodeid, struct sys_info *sysinfo, struct sys_info *sysinfox)
+{
+       dqs_timing(nodeid, sysinfo->ctrl,sysinfo, 0); // keep the output tidy
+//      memcpy(&sysinfox->dqs_rcvr_dly_a[nodeid * 2 * 8],&sysinfo->dqs_rcvr_dly_a[nodeid * 2 * 8], 2*8);
+//      memcpy(&sysinfox->dqs_delay_a[nodeid * 2 * 2 * 9], &sysinfo->dqs_delay_a[nodeid * 2 * 2 * 9], 2 * 2 * 9);
+       sysinfox->mem_trained[nodeid] = sysinfo->mem_trained[nodeid];
+
+}
+static void copy_and_run_ap_code_in_car(unsigned ret_addr);
+static inline void train_ram_on_node(unsigned nodeid, unsigned coreid, struct sys_info *sysinfo, unsigned retcall)
+{
+       if(coreid) return; // only do it on core0
+       struct sys_info *sysinfox = ((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE);
+       wait_till_sysinfo_in_ram(); // use pci to get it
+
+       if(sysinfox->mem_trained[nodeid] == 0) {
+               if (sysinfox->ctrl_present[ nodeid ] &&  sysinfox->meminfo[nodeid].dimm_mask) {
+                       sysinfo->tom_k = sysinfox->tom_k;
+                       sysinfo->tom2_k = sysinfox->tom2_k;
+                       sysinfo->meminfo[nodeid].is_Width128 = sysinfox->meminfo[nodeid].is_Width128;
+                       set_top_mem_ap(sysinfo->tom_k, sysinfo->tom2_k); // keep the ap's tom consistent with bsp's
+               #if CONFIG_AP_CODE_IN_CAR == 0
+                       print_debug("CODE IN ROM AND RUN ON NODE:"); print_debug_hex8(nodeid); print_debug("\r\n");
+                       train_ram(nodeid, sysinfo, sysinfox);
+               #else
+                       /* Can copy dqs_timing to ap cache and run from cache?
+                       * we need linuxbios_ap_car.rom? and treat it as linuxbios_ram.rom for ap ?
+                       */
+                       copy_and_run_ap_code_in_car(retcall);
+                       // will go back by jump
+               #endif
+               }
+       }
+}
+#endif
index 27da719409a6822a03c45c87f78ec7c8d0b1fe12..6b710334e45426146ee8564323f118ef3f5ee0b4 100644 (file)
@@ -21,8 +21,8 @@ static void setup_resource_map_offset(const unsigned int *register_values, int m
                 print_debug("\r\n");
         #endif
 #endif
-                dev = (register_values[i] & ~0xff) + offset_pci_dev;
-                where = register_values[i] & 0xff;
+                dev = (register_values[i] & ~0xfff) + offset_pci_dev;
+                where = register_values[i] & 0xfff;
                 reg = pci_read_config32(dev, where);
                 reg &= register_values[i+1];
                 reg |= register_values[i+2] + offset_io_base;
@@ -58,13 +58,13 @@ static void setup_resource_map_x_offset(const unsigned int *register_values, int
 #if RES_DEBUG
        #if CONFIG_USE_INIT
                 printk_debug("%04x: %02x %08x <- & %08x | %08x\r\n", 
-                       i/4, register_values[i], 
+                       i>>2, register_values[i], 
                        register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0), 
                        register_values[i+2], 
                        register_values[i+3] + ( ( (register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
                        );
        #else           
-                print_debug_hex16(i/4);
+                print_debug_hex16(i>>2);
                 print_debug(": ");
                 print_debug_hex8(register_values[i]);
                 print_debug(" ");
@@ -84,8 +84,8 @@ static void setup_resource_map_x_offset(const unsigned int *register_values, int
                        device_t dev;
                        unsigned where;
                        unsigned long reg;
-                       dev = (register_values[i+1] & ~0xff) + offset_pci_dev;
-                       where = register_values[i+1] & 0xff;
+                       dev = (register_values[i+1] & ~0xfff) + offset_pci_dev;
+                       where = register_values[i+1] & 0xfff;
                        reg = pci_read_config32(dev, where);
                        reg &= register_values[i+2];
                        reg |= register_values[i+3];
@@ -173,8 +173,8 @@ static void setup_resource_map_x(const unsigned int *register_values, int max)
                         device_t dev;
                         unsigned where;
                         unsigned long reg;
-                        dev = register_values[i+1] & ~0xff;
-                        where = register_values[i+1] & 0xff;
+                        dev = register_values[i+1] & ~0xfff;
+                        where = register_values[i+1] & 0xfff;
                         reg = pci_read_config32(dev, where);
                         reg &= register_values[i+2];
                         reg |= register_values[i+3];
diff --git a/src/northbridge/amd/amdk8/spd_ddr2.h b/src/northbridge/amd/amdk8/spd_ddr2.h
new file mode 100644 (file)
index 0000000..e70020d
--- /dev/null
@@ -0,0 +1,66 @@
+/*   SPDs for DDR2 SDRAM */
+#define SPD_MEM_TYPE    2                                     
+       #define SPD_MEM_TYPE_SDRAM_DDR    0x07        
+       #define SPD_MEM_TYPE_SDRAM_DDR2   0x08     
+
+#define SPD_DIMM_TYPE    20    /* x  bit0 or bit4 =1 mean registered*/
+       #define SPD_DIMM_TYPE_RDIMM     (1<<0)
+       #define SPD_DIMM_TYPE_UDIMM     (1<<1)
+       #define SPD_DIMM_TYPE_SODIMM    (1<<2)
+       #define SPD_DIMM_TYPE_uDIMM     (1<<3)
+       #define SPD_DIMM_TYPE_mRDIMM    (1<<4)
+       #define SPD_DIMM_TYPE_mUDIMM    (1<<5)
+#define SPD_MOD_ATTRIB      21
+       #define SPD_MOD_ATTRIB_DIFCK    0x20           
+       #define SPD_MOD_ATTRIB_REGADC   0x11   /* x */   
+       #define SPD_MOD_ATTRIB_PROBE    0x40  
+
+#define SPD_DEV_ATTRIB   22  /* Device attributes --- general */
+#define SPD_DIMM_CONF_TYPE     11
+       #define SPD_DIMM_CONF_TYPE_ECC          0x02
+       #define SPD_DIMM_CONF_TYPE_ADDR_PARITY  0x04     /* ? */
+
+#define SPD_ROW_NUM        3        /* Number of Row addresses */
+#define SPD_COL_NUM        4       /* Number of Column addresses */
+#define SPD_BANK_NUM      17        /* SDRAM Device attributes - Number of Banks on SDRAM device, it could be 0x4, 0x8, so address lines for that would be 2, and 3 */ 
+#define SPD_MOD_ATTRIB_RANK      5       /* include Number of Ranks bit [2:0], Package (bit4, 1=stack, 0=planr), Height bit[7:5] */ 
+       #define SPD_MOD_ATTRIB_RANK_NUM_SHIFT 0
+       #define SPD_MOD_ATTRIB_RANK_NUM_MASK 0x07 
+               #define SPD_MOD_ATTRIB_RANK_NUM_BASE 1
+               #define SPD_MOD_ATTRIB_RANK_NUM_MIN 1
+               #define SPD_MOD_ATTRIB_RANK_NUM_MAX 8
+
+#define SPD_RANK_SIZE      31       /* Only one bit is set */ 
+       #define SPD_RANK_SIZE_1GB   (1<<0)
+       #define SPD_RANK_SIZE_2GB   (1<<1)
+       #define SPD_RANK_SIZE_4GB   (1<<2)
+       #define SPD_RANK_SIZE_8GB   (1<<3)
+       #define SPD_RANK_SIZE_16GB  (1<<4)
+       #define SPD_RANK_SIZE_128MB (1<<5)
+       #define SPD_RANK_SIZE_256MB (1<<6)
+       #define SPD_RANK_SIZE_512MB (1<<7)
+
+#define SPD_DATA_WIDTH  6  /* valid value 0, 32, 33, 36, 64, 72, 80, 128, 144, 254, 255 */
+#define SPD_PRI_WIDTH    13   /* Primary SDRAM Width, it could be 0x08 or 0x10 */
+#define SPD_ERR_WIDTH   14   /* Error Checking SDRAM Width, it could be 0x08 or 0x10 */
+
+#define SPD_CAS_LAT      18   /* SDRAM Device Attributes -- CAS Latency */
+       #define SPD_CAS_LAT_2   (1<<2)
+       #define SPD_CAS_LAT_3   (1<<3)
+       #define SPD_CAS_LAT_4   (1<<4)
+       #define SPD_CAS_LAT_5   (1<<5)
+       #define SPD_CAS_LAT_6   (1<<6)
+
+#define SPD_TRP         27  /* bit [7:2] = 1-63 ns, bit [1:0] 0.25ns+, final value ((val>>2) + (val & 3) * 0.25)ns */
+#define SPD_TRRD        28
+#define SPD_TRCD        29
+#define SPD_TRAS        30
+#define SPD_TWR         36            /* x */
+#define SPD_TWTR        37            /* x */
+#define SPD_TRTP        38            /* x */  
+
+#define SPD_TRC         41            /* add byte 0x40 bit [3:1] , so final val41+ table[((val40>>1) & 0x7)]  ... table[]={0, 0.25, 0.33, 0.5, 0.75, 0, 0}*/
+#define SPD_TRFC        42           /* add byte 0x40 bit [6:4] , so final val42+ table[((val40>>4) & 0x7)] + (val40 & 1)*256*/
+
+#define SPD_TREF       12
diff --git a/src/northbridge/amd/amdk8/ssdt.dsl b/src/northbridge/amd/amdk8/ssdt.dsl
new file mode 100644 (file)
index 0000000..0fa0026
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005 AMD
+ */
+DefinitionBlock ("SSDT.aml", "SSDT", 1, "AMD-K8", "AMD-ACPI", 100925440)
+{
+    /*
+     * These objects were referenced but not defined in this table
+     */
+    External (\_SB_.PCI0, DeviceObj)
+
+    Scope (\_SB.PCI0)
+    {
+         Name (BUSN, Package (0x04)
+        {
+            0x11111111,
+            0x22222222,
+            0x33333333,
+            0x44444444
+        })
+        Name (MMIO, Package (0x10)
+        {
+            0x11111111,
+            0x22222222,
+            0x33333333,
+            0x44444444,
+            0x55555555,
+            0x66666666,
+            0x77777777,
+            0x88888888,
+            0x99999999,
+            0xaaaaaaaa,
+            0xbbbbbbbb,
+            0xcccccccc,
+            0xdddddddd,
+            0xeeeeeeee,
+            0x11111111,
+            0x22222222
+        })
+        Name (PCIO, Package (0x08)
+        {
+            0x77777777,
+            0x88888888,
+            0x99999999,
+            0xaaaaaaaa,
+            0xbbbbbbbb,
+            0xcccccccc,
+            0xdddddddd,
+            0xeeeeeeee
+        })
+        Name (SBLK, 0x11)
+        Name (TOM1, 0xaaaaaaaa)
+       Name (SBDN, 0xbbbbbbbb)
+       Name (HCLK, Package (0x08)
+       {
+           0x11111111,
+           0x22222222,
+           0x33333333,
+           0x44444444,
+            0x55555555,
+            0x66666666,
+            0x77777777,
+            0x88888888
+       })
+        Name (HCDN, Package (0x08)
+        {
+            0x11111111,
+            0x22222222,
+            0x33333333,
+            0x44444444,
+            0x55555555,
+            0x66666666,
+            0x77777777,
+            0x88888888
+        })
+       Name (CBST, 0x88)
+    }
+}
+
index 542864a58c14a235f24dc6a80cc7b33fda3a04ca..9d40076bea75109577827c4415b51575ba61f7a9 100644 (file)
@@ -10,7 +10,7 @@ static unsigned get_sbdn(unsigned bus)
                 PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_PCI),
                 bus);
 
-        return (dev>>11) & 0x1f;
+        return (dev>>15) & 0x1f;
 
 }
 
index 8c4e4da5da98959a1b0539079f2023cdc6c4a078..b8cc5b1a84ae30c3f4912575b0fb440732807c43 100644 (file)
@@ -6,10 +6,10 @@ static void amd8111_enable_rom(void)
 
        /* Enable 5MB rom access at 0xFFB00000 - 0xFFFFFFFF */
        /* Locate the amd8111 */
-       dev = pci_locate_device(PCI_ID(0x1022, 0x7468), 0);
+       dev = pci_io_locate_device(PCI_ID(0x1022, 0x7468), 0);
 
        /* Set the 5MB enable bits */
-       byte = pci_read_config8(dev, 0x43);
+       byte = pci_io_read_config8(dev, 0x43);
        byte |= 0xC0;
-       pci_write_config8(dev, 0x43, byte);
+       pci_io_write_config8(dev, 0x43, byte);
 }
index 8a5f3a5135cd023d811f21a91b041bfa53962a3e..e3c061d4579e929e8f26035d0595919167346463 100644 (file)
@@ -2,9 +2,9 @@
 #include <device/pci_ids.h>
 
 #define PCI_DEV(BUS, DEV, FN) ( \
-       (((BUS) & 0xFF) << 16) | \
-       (((DEV) & 0x1f) << 11) | \
-       (((FN)  & 0x7) << 8))
+       (((BUS) & 0xFFF) << 20) | \
+       (((DEV) & 0x1F) << 15) | \
+       (((FN)  & 0x7) << 12))
 
 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
        ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
@@ -14,7 +14,7 @@ typedef unsigned device_t;
 static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
 {
         unsigned addr;
-        addr = dev | where;
+        addr = (dev>>4) | where;
         outl(0x80000000 | (addr & ~3), 0xCF8);
         outb(value, 0xCFC + (addr & 3));
 }
@@ -22,7 +22,7 @@ static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
 static void pci_write_config32(device_t dev, unsigned where, unsigned value)
 {
        unsigned addr;
-        addr = dev | where;
+        addr = (dev>>4) | where;
         outl(0x80000000 | (addr & ~3), 0xCF8);
         outl(value, 0xCFC);
 }
@@ -30,7 +30,7 @@ static void pci_write_config32(device_t dev, unsigned where, unsigned value)
 static unsigned pci_read_config32(device_t dev, unsigned where)
 {
        unsigned addr;
-        addr = dev | where;
+        addr = (dev>>4) | where;
         outl(0x80000000 | (addr & ~3), 0xCF8);
         return inl(0xCFC);
 }
@@ -58,8 +58,8 @@ void hard_reset(void)
 {
        device_t dev;
        unsigned bus;
-        unsigned node = 0;
-        unsigned link = get_sblk();
+       unsigned node = 0;
+       unsigned link = get_sblk();
 
        /* Find the device.
         * There can only be one 8111 on a hypertransport chain/bus.
index ab9432748183c946527c3e7b86b00b6cf86d3f70..8167691dea04057296ef66a05f9bd50ff7bb72a8 100644 (file)
@@ -71,6 +71,48 @@ static void bcm5785_enable_wdt_port_cf9(void)
         pci_write_config8(dev, 0x40, (1<<2));
 }
 
+static unsigned get_sbdn(unsigned bus)
+{
+        device_t dev;
+
+        /* Find the device.
+         * There can only be one 8111 on a hypertransport chain/bus.
+         */
+        dev = pci_locate_device_on_bus(
+                PCI_ID(0x1166, 0x0036),
+                bus);
+
+        return (dev>>15) & 0x1f;
+
+}
+
+#define SB_VFSMAF 0
+
+static void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
+{
+       //ACPI Decode Enable    
+       outb(0x0e, 0xcd6);
+       outb((1<<3), 0xcd7);
+
+       // set port to 0x2060
+       outb(0x67, 0xcd6);
+       outb(0x60, 0xcd7);
+        outb(0x68, 0xcd6);
+        outb(0x20, 0xcd7);
+
+       outb(0x69, 0xcd6);
+       outb(7, 0xcd7);
+
+       outb(0x64, 0xcd6);
+       outb(9, 0xcd7);
+}
+
+static void ldtstop_sb(void)
+{
+       outb(1, 0x2060);
+}
+
+
 static void hard_reset(void)
 {
         bcm5785_enable_wdt_port_cf9();
index bd146355418216af8d34ba15fe41e07278b97d23..8e0df326c027e6d0b217db67eb2acf4b3b0a3822 100644 (file)
@@ -2,58 +2,13 @@
  * Copyright 2004 Tyan Computer
  *  by yhlu@tyan.com
  */
-static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
-{
-        uint32_t dword, dword_old;
-        uint8_t link_type;
-        
-        dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
-        link_type = dword & 0xff;
-        
-        dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x90 + (linkn * 0x20) );
-        
-        if ( (link_type & 0x7) == linkt ) { 
-                dword = val; 
-        }       
-        
-        if (dword != dword_old) {
-                pci_write_config32(PCI_DEV(0,0x18+node,0), 0x90 + (linkn * 0x20), dword);
-                return 1;
-        }       
-        
-        return 0;
-}
 static int set_ht_link_ck804(uint8_t ht_c_num)
 {
-        int reset_needed;
-        uint8_t i;
-
-        reset_needed = 0;
-
-        for (i = 0; i < ht_c_num; i++) {
-                uint32_t reg;
-                uint8_t nodeid, linkn;
-                uint8_t busn;
-                unsigned val;
-
-                reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
-               if((reg & 3) != 3) continue; 
-
-                nodeid = ((reg & 0xf0)>>4); 
-                linkn = ((reg & 0xf00)>>8); 
-                busn = (reg & 0xff0000)>>16; 
-
-                reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID);
-                if ( (reg & 0xffff) == 0x10de ) {
-                        val = 0x01610169;
-                        reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
-                } 
-        }
-
-        return reset_needed;
+        unsigned vendorid = 0x10de;
+        unsigned val = 0x01610169;
+        set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
 }
 
-
 static void setup_ss_table(unsigned index, unsigned where, unsigned control, const unsigned int *register_values, int max)
 {
         int i;
index a144f1227a81da0bb7e6313b415532f90dd909b0..206ea0f90a66cd25de573a6f3b1dffd2449853e4 100644 (file)
@@ -3,59 +3,14 @@
  *  by yhlu@tyan.com
  * 2005.12 yhlu make it for car so it could support more ck804s
  */
-static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
-{
-        uint32_t dword, dword_old;
-        uint8_t link_type;
-        
-        /* This works on an Athlon64 because unimplemented links return 0 */
-        dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
-        link_type = dword & 0xff;
-        
-        dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x90 + (linkn * 0x20) );
-        
-        if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
-                dword = val; 
-        }       
-        
-        if (dword != dword_old) {
-                pci_write_config32(PCI_DEV(0,0x18+node,0), 0x90 + (linkn * 0x20), dword);
-                return 1;
-        }       
-        
-        return 0;
-}
+
 static int set_ht_link_ck804(uint8_t ht_c_num)
 {
-        int reset_needed;
-        uint8_t i;
-
-        reset_needed = 0;
-
-        for (i = 0; i < ht_c_num; i++) {
-                uint32_t reg;
-                uint8_t nodeid, linkn;
-                uint8_t busn;
-                unsigned val;
-
-                reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
-               if((reg & 3) != 3) continue; 
-
-                nodeid = ((reg & 0xf0)>>4);
-                linkn = ((reg & 0xf00)>>8); 
-                busn = (reg & 0xff0000)>>16; 
-
-                reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID);
-                if ( (reg & 0xffff) == 0x10de ) {
-                        val = 0x01610169;
-                        reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
-                } 
-        }
-
-        return reset_needed;
+        unsigned vendorid = 0x10de;
+        unsigned val = 0x01610169;
+        set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
 }
 
-
 static void setup_ss_table(unsigned index, unsigned where, unsigned control, const unsigned int *register_values, int max)
 {
         int i;
index 9521318e5e97192698bc3df035724d0260e5ac73..5e5a1ed66db84bfcf29b3d71c18f4c9fdc2ebc8b 100644 (file)
@@ -54,7 +54,8 @@ unsigned long
 uncompress(uint8_t * rom_start, uint8_t *dest )
 {
 #if (CONFIG_COMPRESSED_ROM_STREAM) || (CONFIG_COMPRESSED_ROM_STREAM_NRV2B) 
-       return unrv2b(rom_start, dest);
+       unsigned long ilen; // used compressed stream length
+       return unrv2b(rom_start, dest, &ilen);
 #endif
 #if (CONFIG_COMPRESSED_ROM_STREAM_LZMA)
        return ulzma(rom_start, dest);
diff --git a/targets/amd/serengeti_cheetah/Config.lb b/targets/amd/serengeti_cheetah/Config.lb
new file mode 100644 (file)
index 0000000..aab9b38
--- /dev/null
@@ -0,0 +1,85 @@
+# Sample config file for 
+# the amd serengeti_cheetah 
+# This will make a target directory of ./serengeti_cheetah
+
+target serengeti_cheetah
+mainboard amd/serengeti_cheetah
+
+# serengeti_leopard
+romimage "normal"
+#       48K for SCSI FW
+#        option ROM_SIZE = 475136
+#       48K for SCSI FW and 48K for ATI ROM
+#       option ROM_SIZE = 425984 
+#       64K for Etherboot
+#        option ROM_SIZE = 458752 
+       option USE_FAILOVER_IMAGE=0
+       option USE_FALLBACK_IMAGE=0
+#      option ROM_IMAGE_SIZE=0x13800
+#      option ROM_IMAGE_SIZE=0x18800
+       option ROM_IMAGE_SIZE=0x20000
+#      option ROM_IMAGE_SIZE=0x15800
+       option XIP_ROM_SIZE=0x40000
+       option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
+#       payload ../../../payloads/tg3--ide_disk.zelf
+#        payload ../../../payloads/filo.elf
+#        payload ../../../payloads/filo_mem.elf
+#        payload ../../../payloads/filo.zelf
+#        payload ../../../payloads/tg3--filo_hda2.zelf
+#      payload ../../../payloads/tg3.zelf
+#      payload ../../../../payloads/tg3_vga.zelf
+#      payload ../../../../payloads/tg3--filo_hda2_vga.zelf
+       payload ../../../../payloads/tg3--filo_hda2_vga_5.4.1.zelf
+#      payload ../../../../payloads/e1000_vga.zelf
+#      payload ../../../../payloads/tg3--filo_hda2_vga_5_4.zelf
+#      payload ../../../payloads/tg3_com2.zelf
+#       payload ../../../payloads/e1000--filo.zelf
+#        payload ../../../payloads/tg3--e1000--filo.zelf
+#        payload ../../../payloads/tg3--eepro100--e1000--filo_hda2.zelf
+#      payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_5.3.zelf
+#      payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_com2.zelf
+end
+
+romimage "fallback" 
+       option USE_FAILOVER_IMAGE=0
+       option USE_FALLBACK_IMAGE=1
+#      option ROM_IMAGE_SIZE=0x13800
+#      option ROM_IMAGE_SIZE=0x19800
+       option ROM_IMAGE_SIZE=0x20000
+#      option ROM_IMAGE_SIZE=0x15800
+       option XIP_ROM_SIZE=0x40000
+       option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
+#       payload ../../../payloads/tg3--ide_disk.zelf
+#        payload ../../../payloads/filo.elf
+#        payload ../../../payloads/filo_mem.elf
+#        payload ../../../payloads/filo.zelf
+#        payload ../../../payloads/tg3--filo_hda2.zelf
+#      payload ../../../payloads/tg3.zelf
+#      payload ../../../../payloads/tg3_vga.zelf
+#      payload ../../../../payloads/memtest
+#      payload ../../../../payloads/adlo.elf
+#      payload ../../../../payloads/e1000_vga.zelf
+#      payload ../../../../payloads/filo_hda.zelf
+#      payload ../../../../payloads/tg3--filo_hda2_vga.zelf
+#      payload ../../../../payloads/tg3--filo_hda2_vga_5_4.zelf
+       payload ../../../../payloads/tg3--filo_hda2_vga_5.4.1.zelf
+#      payload ../../../../payloads/filo_hda2_novga.zelf
+#      payload ../../../payloads/tg3_com2.zelf
+#       payload ../../../payloads/e1000--filo.zelf
+#        payload ../../../payloads/tg3--e1000--filo.zelf
+#        payload ../../../payloads/tg3--eepro100--e1000--filo_hda2.zelf
+#      payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_5.3.zelf
+#      payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_com2.zelf
+end
+
+romimage "failover"
+       option USE_FAILOVER_IMAGE=1
+        option USE_FALLBACK_IMAGE=0
+        option ROM_IMAGE_SIZE=FAILOVER_SIZE
+        option XIP_ROM_SIZE=FAILOVER_SIZE
+        option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Failover"
+end
+
+
+buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback" "failover"
+#buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback" 
diff --git a/targets/amd/serengeti_cheetah/VERSION b/targets/amd/serengeti_cheetah/VERSION
new file mode 100644 (file)
index 0000000..e70b27c
--- /dev/null
@@ -0,0 +1 @@
+_serengenti_cheetah