diff options
Diffstat (limited to 'resources/libreboot/patch/coreboot')
45 files changed, 10453 insertions, 0 deletions
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch new file mode 100644 index 0000000..1b8b917 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch @@ -0,0 +1,312 @@ +From 00b7f63bd7bd400d9fdf92974c5e295b30ba1d2f Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Fri, 14 Aug 2015 15:20:42 -0500 +Subject: [PATCH 01/45] southbridge/amd/sr5650: Add MCFG ACPI table support + +Change-Id: I0c4ba74ddcc727cd92b848d5d3240e6f9f392101 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdfam10/northbridge.c | 22 +++--- + src/southbridge/amd/rs780/rs780.c | 11 +++ + src/southbridge/amd/rs780/rs780.h | 1 + + src/southbridge/amd/sb700/lpc.c | 6 -- + src/southbridge/amd/sb800/lpc.c | 7 +- + src/southbridge/amd/sr5650/Kconfig | 9 +++ + src/southbridge/amd/sr5650/ht.c | 107 ++++++++++++++++++++++++++++- + src/southbridge/amd/sr5650/sr5650.c | 18 +++++ + 8 files changed, 156 insertions(+), 25 deletions(-) + +diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c +index c8bf8fa..b376171 100644 +--- a/src/northbridge/amd/amdfam10/northbridge.c ++++ b/src/northbridge/amd/amdfam10/northbridge.c +@@ -737,16 +737,18 @@ static void amdfam10_domain_read_resources(device_t dev) + + pci_domain_read_resources(dev); + +-#if CONFIG_MMCONF_SUPPORT +- struct resource *res = new_resource(dev, 0xc0010058); +- res->base = CONFIG_MMCONF_BASE_ADDRESS; +- res->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256; +- res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | +- IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +- +- /* Reserve lower DRAM region to force PCI MMIO region to correct location above 0xefffffff */ +- ram_resource(dev, 7, 0, rdmsr(TOP_MEM).lo >> 10); +-#endif ++ if (IS_ENABLED(CONFIG_MMCONF_SUPPORT) && !IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) { ++ struct resource *res = new_resource(dev, 0xc0010058); ++ res->base = CONFIG_MMCONF_BASE_ADDRESS; ++ res->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256; ++ res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | ++ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; ++ } ++ ++ if (IS_ENABLED(CONFIG_MMCONF_SUPPORT)) { ++ /* Reserve lower DRAM region to force PCI MMIO region to correct location above 0xefffffff */ ++ ram_resource(dev, 7, 0, rdmsr(TOP_MEM).lo >> 10); ++ } + + if (is_fam15h()) { + enable_cc6 = 0; +diff --git a/src/southbridge/amd/rs780/rs780.c b/src/southbridge/amd/rs780/rs780.c +index c82a629..0d482ae 100644 +--- a/src/southbridge/amd/rs780/rs780.c ++++ b/src/southbridge/amd/rs780/rs780.c +@@ -349,6 +349,17 @@ void rs780_enable(device_t dev) + } + } + ++#if !IS_ENABLED(CONFIG_AMD_SB_CIMX) ++unsigned long acpi_fill_mcfg(unsigned long current) ++{ ++ /* FIXME ++ * Leave table blank until proper contents ++ * are determined. ++ */ ++ return current; ++} ++#endif ++ + struct chip_operations southbridge_amd_rs780_ops = { + CHIP_NAME("ATI RS780") + .enable_dev = rs780_enable, +diff --git a/src/southbridge/amd/rs780/rs780.h b/src/southbridge/amd/rs780/rs780.h +index 341de0d..abc601f 100644 +--- a/src/southbridge/amd/rs780/rs780.h ++++ b/src/southbridge/amd/rs780/rs780.h +@@ -17,6 +17,7 @@ + #define __RS780_H__ + + #include <stdint.h> ++#include <arch/acpi.h> + #include <device/pci_ids.h> + #include "chip.h" + #include "rev.h" +diff --git a/src/southbridge/amd/sb700/lpc.c b/src/southbridge/amd/sb700/lpc.c +index a71fe1f..78933fa 100644 +--- a/src/southbridge/amd/sb700/lpc.c ++++ b/src/southbridge/amd/sb700/lpc.c +@@ -30,12 +30,6 @@ + #include <cpu/amd/powernow.h> + #include "sb700.h" + +-unsigned long acpi_fill_mcfg(unsigned long current) +-{ +- /* Just a dummy */ +- return current; +-} +- + static void lpc_init(device_t dev) + { + u8 byte; +diff --git a/src/southbridge/amd/sb800/lpc.c b/src/southbridge/amd/sb800/lpc.c +index 756a0c4..18d4471 100644 +--- a/src/southbridge/amd/sb800/lpc.c ++++ b/src/southbridge/amd/sb800/lpc.c +@@ -2,6 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -25,12 +26,6 @@ + #include <arch/acpi.h> + #include "sb800.h" + +-unsigned long acpi_fill_mcfg(unsigned long current) +-{ +- /* Just a dummy */ +- return current; +-} +- + static void lpc_init(device_t dev) + { + u8 byte; +diff --git a/src/southbridge/amd/sr5650/Kconfig b/src/southbridge/amd/sr5650/Kconfig +index 29017c6..f2d12ff 100644 +--- a/src/southbridge/amd/sr5650/Kconfig ++++ b/src/southbridge/amd/sr5650/Kconfig +@@ -15,3 +15,12 @@ + + config SOUTHBRIDGE_AMD_SR5650 + bool ++ ++if SOUTHBRIDGE_AMD_SR5650 ++config EXT_CONF_SUPPORT ++ bool "Enable PCI-E MMCONFIG support" ++ default n ++ help ++ Select to enable PCI-E MMCONFIG support on the SR5650. ++ ++endif +diff --git a/src/southbridge/amd/sr5650/ht.c b/src/southbridge/amd/sr5650/ht.c +index 6119985..e74d36b 100644 +--- a/src/southbridge/amd/sr5650/ht.c ++++ b/src/southbridge/amd/sr5650/ht.c +@@ -20,7 +20,9 @@ + #include <device/pci_ids.h> + #include <device/pci_ops.h> + #include <arch/ioapic.h> ++#include <lib.h> + #include "sr5650.h" ++#include "cmn.h" + + /* Table 6-6 Recommended Interrupt Routing Configuration */ + typedef struct _apic_device_info { +@@ -154,11 +156,29 @@ static void pcie_init(struct device *dev) + + static void sr5690_read_resource(struct device *dev) + { ++ struct resource *res; ++ ++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) { ++ printk(BIOS_DEBUG,"%s: %s\n", __func__, dev_path(dev)); ++ set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 1 << 3); /* Hide BAR3 */ ++ } ++ + pci_dev_read_resources(dev); + + /* rpr6.2.(1). Write the Base Address Register (BAR) */ +- pci_write_config32(dev, 0xF8, 0x1); /* set IOAPIC's index as 1 and make sure no one changes it. */ +- pci_get_resource(dev, 0xFC); /* APIC located in sr5690 */ ++ pci_write_config32(dev, 0xf8, 0x1); /* Set IOAPIC's index to 1 and make sure no one changes it */ ++ pci_get_resource(dev, 0xfc); /* APIC located in sr5690 */ ++ ++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) { ++ res = new_resource(dev, 0x1c); /* PCIe MCFG space */ ++ res->base = EXT_CONF_BASE_ADDRESS; ++ res->size = CONFIG_MMCONF_BUS_NUMBER * 1024 * 1024; /* Each bus needs 1M */ ++ res->align = log2(res->size); ++ res->gran = log2(res->size); ++ res->limit = 0xffffffffffffffffULL; /* 64-bit location allowed */ ++ res->flags = IORESOURCE_FIXED | IORESOURCE_MEM | IORESOURCE_PCI64 ++ | IORESOURCE_ASSIGNED | IORESOURCE_RESERVE | IORESOURCE_BRIDGE; ++ } + + compact_resources(dev); + } +@@ -166,7 +186,88 @@ static void sr5690_read_resource(struct device *dev) + /* If IOAPIC's index changes, we should replace the pci_dev_set_resource(). */ + static void sr5690_set_resources(struct device *dev) + { +- pci_write_config32(dev, 0xF8, 0x1); /* set IOAPIC's index as 1 and make sure no one changes it. */ ++ pci_write_config32(dev, 0xf8, 0x1); /* Set IOAPIC's index to 1 and make sure no one changes it */ ++ ++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) { ++ uint32_t reg; ++ device_t amd_ht_cfg_dev; ++ device_t amd_addr_map_dev; ++ resource_t res_base; ++ resource_t res_end; ++ uint32_t base; ++ uint32_t limit; ++ struct resource *res; ++ ++ printk(BIOS_DEBUG,"%s %s\n", dev_path(dev), __func__); ++ ++ res = probe_resource(dev, 0x1c); ++ if (res) { ++ /* Find requisite AMD CPU devices */ ++ amd_ht_cfg_dev = dev_find_slot(0, PCI_DEVFN(0x18, 0)); ++ amd_addr_map_dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); ++ ++ if (!amd_ht_cfg_dev || !amd_addr_map_dev) { ++ printk(BIOS_WARNING, "%s: %s Unable to locate CPU control devices\n", __func__, dev_path(dev)); ++ } ++ else { ++ /* Set up MMCONFIG bus range */ ++ set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 0 << 3); /* Make BAR3 visible */ ++ set_nbcfg_enable_bits(dev, 0x7c, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register */ ++ set_nbcfg_enable_bits(dev, 0x84, 7 << 16, 0 << 16); /* Program bus range = 255 busses */ ++ pci_write_config32(dev, 0x1c, res->base); ++ ++ /* Enable MMCONFIG decoding. */ ++ set_htiu_enable_bits(dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */ ++ set_nbcfg_enable_bits(dev, 0x7c, 1 << 30, 0 << 30); /* Disable writes to the BAR3 register */ ++ set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 1 << 3); /* Hide BAR3 */ ++ ++ /* Set up nonposted resource in MMIO space */ ++ res_base = res->base; /* Get the base address */ ++ res_end = resource_end(res); /* Get the limit (rounded up) */ ++ printk(BIOS_DEBUG, "%s: %s[0x1c] base = %0llx limit = %0llx\n", __func__, dev_path(dev), res_base, res_end); ++ ++ /* Locate an unused MMIO resource */ ++ for (reg = 0xb8; reg >= 0x80; reg -= 8) { ++ base = pci_read_config32(amd_addr_map_dev, reg); ++ limit = pci_read_config32(amd_addr_map_dev, reg + 4); ++ if (!(base & 0x3)) ++ break; /* Unused resource found */ ++ } ++ ++ /* If an unused MMIO resource was available, set up the mapping */ ++ if (!(base & 0x3)) { ++ uint32_t sblk; ++ ++ /* Remember this resource has been stored. */ ++ res->flags |= IORESOURCE_STORED; ++ report_resource_stored(dev, res, " <mmconfig>"); ++ ++ /* Get SBLink value (HyperTransport I/O Hub Link ID). */ ++ sblk = (pci_read_config32(amd_ht_cfg_dev, 0x64) >> 8) & 0x3; ++ ++ /* Calculate the MMIO mapping base */ ++ base &= 0x000000f0; ++ base |= ((res_base >> 8) & 0xffffff00); ++ base |= 3; ++ ++ /* Calculate the MMIO mapping limit */ ++ limit &= 0x00000048; ++ limit |= ((res_end >> 8) & 0xffffff00); ++ limit |= (sblk << 4); ++ limit |= (1 << 7); ++ ++ /* Configure and enable MMIO mapping */ ++ printk(BIOS_INFO, "%s: %s <- index %x base %04x limit %04x\n", __func__, dev_path(amd_addr_map_dev), reg, base, limit); ++ pci_write_config32(amd_addr_map_dev, reg + 4, limit); ++ pci_write_config32(amd_addr_map_dev, reg, base); ++ } ++ else { ++ printk(BIOS_WARNING, "%s: %s No free MMIO resources available\n", __func__, dev_path(dev)); ++ } ++ } ++ } ++ } ++ + pci_dev_set_resources(dev); + } + +diff --git a/src/southbridge/amd/sr5650/sr5650.c b/src/southbridge/amd/sr5650/sr5650.c +index 07b4a02..54f0071 100644 +--- a/src/southbridge/amd/sr5650/sr5650.c ++++ b/src/southbridge/amd/sr5650/sr5650.c +@@ -796,6 +796,24 @@ static void add_ivrs_device_entries(struct device *parent, struct device *dev, i + free(root_level); + } + ++unsigned long acpi_fill_mcfg(unsigned long current) ++{ ++ struct resource *res; ++ resource_t mmconf_base = EXT_CONF_BASE_ADDRESS; ++ ++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) { ++ device_t dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ /* Report MMCONF base */ ++ res = probe_resource(dev, 0x1c); ++ if (res) ++ mmconf_base = res->base; ++ ++ current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, mmconf_base, 0x0, 0x0, 0x1f); ++ } ++ ++ return current; ++} ++ + static unsigned long acpi_fill_ivrs(acpi_ivrs_t* ivrs, unsigned long current) + { + uint8_t *p; +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch new file mode 100644 index 0000000..31e47fd --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch @@ -0,0 +1,132 @@ +From 964824b31218e5e63c2b52a11491e1b44692eb83 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Mon, 18 May 2015 16:04:10 -0500 +Subject: [PATCH 02/45] src/console: Add x86 romstage spinlock option and + printk spinlock support + +This paves the way for AP printk spinlock on AMD platforms + +Change-Id: Ice42a0d3177736bf6e1bc601092e413601866f20 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/Kconfig | 4 ++++ + src/arch/x86/include/arch/smp/spinlock.h | 11 ++++++++++- + src/console/printk.c | 15 +++++++++++++++ + src/cpu/amd/car/post_cache_as_ram.c | 4 ++++ + 4 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/src/Kconfig b/src/Kconfig +index 8439a00..b8da62a 100644 +--- a/src/Kconfig ++++ b/src/Kconfig +@@ -468,6 +468,10 @@ config HAVE_HARD_RESET + This variable specifies whether a given board has a hard_reset + function, no matter if it's provided by board code or chipset code. + ++config HAVE_ROMSTAGE_CONSOLE_SPINLOCK ++ bool ++ default n ++ + config HAVE_MONOTONIC_TIMER + def_bool n + help +diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h +index 32be2f2..74e532c 100644 +--- a/src/arch/x86/include/arch/smp/spinlock.h ++++ b/src/arch/x86/include/arch/smp/spinlock.h +@@ -1,7 +1,7 @@ + #ifndef ARCH_SMP_SPINLOCK_H + #define ARCH_SMP_SPINLOCK_H + +-#ifndef __PRE_RAM__ ++#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) + + /* + * Your basic SMP spinlocks, allowing only a single CPU anywhere +@@ -11,9 +11,18 @@ typedef struct { + volatile unsigned int lock; + } spinlock_t; + ++#ifdef __PRE_RAM__ ++spinlock_t *romstage_console_lock(void); ++void initialize_romstage_console_lock(void); ++#endif + + #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } ++ ++#ifndef __PRE_RAM__ + #define DECLARE_SPIN_LOCK(x) static spinlock_t x = SPIN_LOCK_UNLOCKED; ++#else ++#define DECLARE_SPIN_LOCK(x) ++#endif + + /* + * Simple spin lock operations. There are two variants, one clears IRQ's +diff --git a/src/console/printk.c b/src/console/printk.c +index aab7ff5..99f90a8 100644 +--- a/src/console/printk.c ++++ b/src/console/printk.c +@@ -2,6 +2,7 @@ + * blatantly copied from linux/kernel/printk.c + * + * Copyright (C) 1991, 1992 Linus Torvalds ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering + * + */ + +@@ -13,7 +14,9 @@ + #include <stddef.h> + #include <trace.h> + ++#if (!defined(__PRE_RAM__) && IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)) || !IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) + DECLARE_SPIN_LOCK(console_lock) ++#endif + + void do_putchar(unsigned char byte) + { +@@ -39,7 +42,13 @@ int do_printk(int msg_level, const char *fmt, ...) + #endif + + DISABLE_TRACE; ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) ++ spin_lock(romstage_console_lock()); ++#endif ++#else + spin_lock(&console_lock); ++#endif + + va_start(args, fmt); + i = vtxprintf(wrap_putchar, fmt, args, NULL); +@@ -47,7 +56,13 @@ int do_printk(int msg_level, const char *fmt, ...) + + console_tx_flush(); + ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) ++ spin_unlock(romstage_console_lock()); ++#endif ++#else + spin_unlock(&console_lock); ++#endif + ENABLE_TRACE; + + return i; +diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c +index fb09cd4..8c5757e 100644 +--- a/src/cpu/amd/car/post_cache_as_ram.c ++++ b/src/cpu/amd/car/post_cache_as_ram.c +@@ -76,6 +76,10 @@ static void prepare_ramstage_region(void *resume_backup_memory) + memset_((void*)0, 0, CONFIG_RAMTOP - backup_top); + } + ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) ++ initialize_romstage_console_lock(); ++#endif ++ + print_car_debug(" Done\n"); + } + +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch new file mode 100644 index 0000000..2d49a2f --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch @@ -0,0 +1,72 @@ +From 013c91f9f6699cfefcda0d0745db7bd999d7cdb5 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Thu, 5 Nov 2015 13:16:55 -0600 +Subject: [PATCH 03/45] mainboard/asus/kgpe-d16: Enable romstage spinlocks + +Change-Id: Iac1adbeacdcded7faff2443b78a491cbb8a90fe8 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/Kconfig | 1 + + src/mainboard/asus/kgpe-d16/romstage.c | 20 +++++++++++++++----- + 2 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig +index c4f3962..67b43ca 100644 +--- a/src/mainboard/asus/kgpe-d16/Kconfig ++++ b/src/mainboard/asus/kgpe-d16/Kconfig +@@ -14,6 +14,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy + select SOUTHBRIDGE_AMD_SUBTYPE_SP5100 + select SUPERIO_NUVOTON_NCT5572D + select PARALLEL_CPU_INIT ++ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK + select HAVE_HARD_RESET + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT +diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c +index df76ab4..13eacd2 100644 +--- a/src/mainboard/asus/kgpe-d16/romstage.c ++++ b/src/mainboard/asus/kgpe-d16/romstage.c +@@ -312,6 +312,18 @@ static void execute_memory_test(void) + } + #endif + ++static spinlock_t printk_spinlock CAR_GLOBAL; ++ ++spinlock_t* romstage_console_lock(void) ++{ ++ return car_get_var_ptr(&printk_spinlock); ++} ++ ++void initialize_romstage_console_lock(void) ++{ ++ car_get_var(printk_spinlock) = SPIN_LOCK_UNLOCKED; ++} ++ + void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + { + uint32_t esp; +@@ -338,6 +350,9 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + timestamp_init(timestamp_get()); + timestamp_add_now(TS_START_ROMSTAGE); + ++ /* Initialize the printk spinlock */ ++ initialize_romstage_console_lock(); ++ + /* Nothing special needs to be done to find bus 0 */ + /* Allow the HT devices to be found */ + set_bsp_node_CHtExtNodeCfgEn(); +@@ -407,11 +422,6 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + post_code(0x36); + + /* Wait for all the APs core0 started by finalize_node_setup. */ +- /* FIXME: A bunch of cores are going to start output to serial at once. +- * It would be nice to fix up prink spinlocks for ROM XIP mode. +- * I think it could be done by putting the spinlock flag in the cache +- * of the BSP located right after sysinfo. +- */ + wait_all_core0_started(); + + /* run _early_setup before soft-reset. */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch new file mode 100644 index 0000000..3f9fa8b --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch @@ -0,0 +1,175 @@ +From cac177b845bea4469b7e7c4345f90d02eb11ce5a Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Fri, 28 Aug 2015 19:52:05 -0500 +Subject: [PATCH 04/45] drivers/pc80: Add optional spinlock for nvram CBFS + access + +When enabling the IOMMU on certain systems dmesg is spammed with I/O page faults like the following: +AMD-Vi: Event logged [IO_PAGE_FAULT device=00:14.0 domain=0x000a address=0x000000fdf9103300 flags=0x0030] + +Decoding the faulting address: +0x000000fdf9103300 + fdf91x Hypertransport system management region + 33 SysMgtCmd (System Management Command) = 0x33 + 3 Base Command Type = 0x3: STPCLK (Stop Clock request) + 3 SMAF (System Management Action Field) = [3:1] = 0x1 + 1 Signal State Bit Map = [0] = 0x1 + +Therefore, the error appears to be triggered by an upstream C1E request. + +This was eventually traced to concurrent access to the SP5100's SPI Flash controller by +multiple APs during startup. Calls to the nvram read functions get_option and read_option +call CBFS functions, which in turn make near-simultaneous requests to the SPI Flash +controller, thus placing the SP5100 in an invalid state. This limitation is not documented +in any public AMD errata, and was only discovered through considerable debugging effort. + +Change-Id: I4e61b1ab767b1b7958ac7c1cf20eee41d2261bef +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/Kconfig | 4 +++ + src/arch/x86/include/arch/smp/spinlock.h | 4 ++- + src/cpu/amd/car/post_cache_as_ram.c | 3 +++ + src/drivers/pc80/mc146818rtc.c | 43 ++++++++++++++++++++++++++++++-- + 4 files changed, 51 insertions(+), 3 deletions(-) + +diff --git a/src/Kconfig b/src/Kconfig +index b8da62a..5c38b7e 100644 +--- a/src/Kconfig ++++ b/src/Kconfig +@@ -472,6 +472,10 @@ config HAVE_ROMSTAGE_CONSOLE_SPINLOCK + bool + default n + ++config HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK ++ bool ++ default n ++ + config HAVE_MONOTONIC_TIMER + def_bool n + help +diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h +index 74e532c..057d9e3 100644 +--- a/src/arch/x86/include/arch/smp/spinlock.h ++++ b/src/arch/x86/include/arch/smp/spinlock.h +@@ -1,7 +1,7 @@ + #ifndef ARCH_SMP_SPINLOCK_H + #define ARCH_SMP_SPINLOCK_H + +-#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) ++#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) + + /* + * Your basic SMP spinlocks, allowing only a single CPU anywhere +@@ -14,6 +14,8 @@ typedef struct { + #ifdef __PRE_RAM__ + spinlock_t *romstage_console_lock(void); + void initialize_romstage_console_lock(void); ++spinlock_t* romstage_nvram_cbfs_lock(void); ++void initialize_romstage_nvram_cbfs_lock(void); + #endif + + #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } +diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c +index 8c5757e..435fdcb 100644 +--- a/src/cpu/amd/car/post_cache_as_ram.c ++++ b/src/cpu/amd/car/post_cache_as_ram.c +@@ -79,6 +79,9 @@ static void prepare_ramstage_region(void *resume_backup_memory) + #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) + initialize_romstage_console_lock(); + #endif ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ initialize_romstage_nvram_cbfs_lock(); ++#endif + + print_car_debug(" Done\n"); + } +diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c +index 0c95265..0afc12b 100644 +--- a/src/drivers/pc80/mc146818rtc.c ++++ b/src/drivers/pc80/mc146818rtc.c +@@ -2,6 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright 2014 The Chromium OS Authors. All rights reserved. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -33,6 +34,11 @@ + #define LB_CKS_LOC 0 + #endif + ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++#include <smp/spinlock.h> ++#endif ++#endif + + static void cmos_reset_date(void) + { +@@ -204,6 +210,12 @@ enum cb_err get_option(void *dest, const char *name) + if (!IS_ENABLED(CONFIG_USE_OPTION_TABLE)) + return CB_CMOS_OTABLE_DISABLED; + ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ spin_lock(romstage_nvram_cbfs_lock()); ++#endif ++#endif ++ + /* Figure out how long name is */ + namelen = strnlen(name, CMOS_MAX_NAME_LENGTH); + +@@ -213,6 +225,11 @@ enum cb_err get_option(void *dest, const char *name) + if (!ct) { + printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. " + "Options are disabled\n"); ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ spin_unlock(romstage_nvram_cbfs_lock()); ++#endif ++#endif + return CB_CMOS_LAYOUT_NOT_FOUND; + } + ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length); +@@ -225,13 +242,35 @@ enum cb_err get_option(void *dest, const char *name) + } + if (!found) { + printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name); ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ spin_unlock(romstage_nvram_cbfs_lock()); ++#endif ++#endif + return CB_CMOS_OPTION_NOT_FOUND; + } + +- if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS) ++ if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS) { ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ spin_unlock(romstage_nvram_cbfs_lock()); ++#endif ++#endif + return CB_CMOS_ACCESS_ERROR; +- if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC)) ++ } ++ if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC)) { ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ spin_unlock(romstage_nvram_cbfs_lock()); ++#endif ++#endif + return CB_CMOS_CHECKSUM_INVALID; ++ } ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++ spin_unlock(romstage_nvram_cbfs_lock()); ++#endif ++#endif + return CB_SUCCESS; + } + +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch new file mode 100644 index 0000000..4bc79ea --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch @@ -0,0 +1,61 @@ +From 0c194e790a3b6550afc298beaeeb4a537fae4bfb Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Fri, 28 Aug 2015 20:02:45 -0500 +Subject: [PATCH 05/45] mainboard/asus/kgpe-d16: Enable CBFS spinlocks + +Change-Id: I8f6226d3e74ac5c7f29f708128a7502ced1287bf +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/Kconfig | 1 + + src/mainboard/asus/kgpe-d16/romstage.c | 15 ++++++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig +index 67b43ca..49dd37b 100644 +--- a/src/mainboard/asus/kgpe-d16/Kconfig ++++ b/src/mainboard/asus/kgpe-d16/Kconfig +@@ -15,6 +15,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy + select SUPERIO_NUVOTON_NCT5572D + select PARALLEL_CPU_INIT + select HAVE_ROMSTAGE_CONSOLE_SPINLOCK ++ select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK + select HAVE_HARD_RESET + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT +diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c +index 13eacd2..f9af195 100644 +--- a/src/mainboard/asus/kgpe-d16/romstage.c ++++ b/src/mainboard/asus/kgpe-d16/romstage.c +@@ -324,6 +324,18 @@ void initialize_romstage_console_lock(void) + car_get_var(printk_spinlock) = SPIN_LOCK_UNLOCKED; + } + ++static spinlock_t nvram_cbfs_spinlock CAR_GLOBAL; ++ ++spinlock_t* romstage_nvram_cbfs_lock(void) ++{ ++ return car_get_var_ptr(&nvram_cbfs_spinlock); ++} ++ ++void initialize_romstage_nvram_cbfs_lock(void) ++{ ++ car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED; ++} ++ + void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + { + uint32_t esp; +@@ -350,8 +362,9 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + timestamp_init(timestamp_get()); + timestamp_add_now(TS_START_ROMSTAGE); + +- /* Initialize the printk spinlock */ ++ /* Initialize the printk and nvram CBFS spinlocks */ + initialize_romstage_console_lock(); ++ initialize_romstage_nvram_cbfs_lock(); + + /* Nothing special needs to be done to find bus 0 */ + /* Allow the HT devices to be found */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch new file mode 100644 index 0000000..8fc1513 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch @@ -0,0 +1,155 @@ +From 1c25371e5826f756af16314bccd8dcc106deae71 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Fri, 28 Aug 2015 20:48:17 -0500 +Subject: [PATCH 06/45] cpu/amd/microcode: Introduce CBFS access spinlock to + avoid IOMMU failure + +Change-Id: Ib7e8cb171f44833167053ca98a85cca23021dfba +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/Kconfig | 4 ++++ + src/arch/x86/include/arch/smp/spinlock.h | 7 ++++++- + src/cpu/amd/microcode/microcode.c | 24 +++++++++++++++++++++++- + src/mainboard/asus/kgpe-d16/Kconfig | 1 + + src/mainboard/asus/kgpe-d16/romstage.c | 15 ++++++++++++++- + 5 files changed, 48 insertions(+), 3 deletions(-) + +diff --git a/src/Kconfig b/src/Kconfig +index 5c38b7e..ca29a16 100644 +--- a/src/Kconfig ++++ b/src/Kconfig +@@ -476,6 +476,10 @@ config HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK + bool + default n + ++config HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK ++ bool ++ default n ++ + config HAVE_MONOTONIC_TIMER + def_bool n + help +diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h +index 057d9e3..39a81d2 100644 +--- a/src/arch/x86/include/arch/smp/spinlock.h ++++ b/src/arch/x86/include/arch/smp/spinlock.h +@@ -1,7 +1,10 @@ + #ifndef ARCH_SMP_SPINLOCK_H + #define ARCH_SMP_SPINLOCK_H + +-#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) ++#if !defined(__PRE_RAM__) \ ++ || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) \ ++ || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) \ ++ || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) + + /* + * Your basic SMP spinlocks, allowing only a single CPU anywhere +@@ -16,6 +19,8 @@ spinlock_t *romstage_console_lock(void); + void initialize_romstage_console_lock(void); + spinlock_t* romstage_nvram_cbfs_lock(void); + void initialize_romstage_nvram_cbfs_lock(void); ++spinlock_t* romstage_microcode_cbfs_lock(void); ++void initialize_romstage_microcode_cbfs_lock(void); + #endif + + #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } +diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c +index 37d395a..5f3280c 100644 +--- a/src/cpu/amd/microcode/microcode.c ++++ b/src/cpu/amd/microcode/microcode.c +@@ -21,6 +21,12 @@ + #include <cbfs.h> + #include <arch/io.h> + ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) ++#include <smp/spinlock.h> ++#endif ++#endif ++ + #define UCODE_DEBUG(fmt, args...) \ + do { printk(BIOS_DEBUG, "[microcode] "fmt, ##args); } while(0) + +@@ -197,14 +203,30 @@ void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id) + return; + } + ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) ++ spin_lock(romstage_microcode_cbfs_lock()); ++#endif ++#endif ++ + ucode = cbfs_boot_map_with_leak(microcode_cbfs_file[i], + CBFS_TYPE_MICROCODE, &ucode_len); + if (!ucode) { + UCODE_DEBUG("microcode file not found. Skipping updates.\n"); +- ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) ++ spin_unlock(romstage_microcode_cbfs_lock()); ++#endif ++#endif + return; + } + + amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id); ++ ++#ifdef __PRE_RAM__ ++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK) ++ spin_unlock(romstage_microcode_cbfs_lock()); ++#endif ++#endif + } + } +diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig +index 49dd37b..f394ca9 100644 +--- a/src/mainboard/asus/kgpe-d16/Kconfig ++++ b/src/mainboard/asus/kgpe-d16/Kconfig +@@ -16,6 +16,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy + select PARALLEL_CPU_INIT + select HAVE_ROMSTAGE_CONSOLE_SPINLOCK + select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK ++ select HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK + select HAVE_HARD_RESET + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT +diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c +index f9af195..09de4b5 100644 +--- a/src/mainboard/asus/kgpe-d16/romstage.c ++++ b/src/mainboard/asus/kgpe-d16/romstage.c +@@ -336,6 +336,18 @@ void initialize_romstage_nvram_cbfs_lock(void) + car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED; + } + ++static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL; ++ ++spinlock_t* romstage_microcode_cbfs_lock(void) ++{ ++ return car_get_var_ptr(µcode_cbfs_spinlock); ++} ++ ++void initialize_romstage_microcode_cbfs_lock(void) ++{ ++ car_get_var(microcode_cbfs_spinlock) = SPIN_LOCK_UNLOCKED; ++} ++ + void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + { + uint32_t esp; +@@ -362,9 +374,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + timestamp_init(timestamp_get()); + timestamp_add_now(TS_START_ROMSTAGE); + +- /* Initialize the printk and nvram CBFS spinlocks */ ++ /* Initialize the printk, nvram CBFS, and microcode CBFS spinlocks */ + initialize_romstage_console_lock(); + initialize_romstage_nvram_cbfs_lock(); ++ initialize_romstage_microcode_cbfs_lock(); + + /* Nothing special needs to be done to find bus 0 */ + /* Allow the HT devices to be found */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0007-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0007-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch new file mode 100644 index 0000000..739ea61 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0007-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch @@ -0,0 +1,34 @@ +From b1f7214a611061ebe1b4441999880a9b93f7e9bc Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Thu, 4 Jun 2015 00:07:05 -0500 +Subject: [PATCH 07/45] cpu/amd/car: Initialize entire CAR space instead of + only half + +Change-Id: If2b6c875e523f595e662d5d62322c3c3f96ccb4a +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/car/cache_as_ram.inc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu/amd/car/cache_as_ram.inc b/src/cpu/amd/car/cache_as_ram.inc +index 5305603..d532bb4 100644 +--- a/src/cpu/amd/car/cache_as_ram.inc ++++ b/src/cpu/amd/car/cache_as_ram.inc +@@ -474,12 +474,12 @@ fam10_end_part1: + /* Read the range with lodsl. */ + cld + movl $CacheBase, %esi +- movl $(CacheSize >> 2), %ecx ++ movl $CacheSize, %ecx + rep lodsl + + /* Clear the range. */ + movl $CacheBase, %edi +- movl $(CacheSize >> 2), %ecx ++ movl $CacheSize, %ecx + xorl %eax, %eax + rep stosl + +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch new file mode 100644 index 0000000..a5c547d --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch @@ -0,0 +1,423 @@ +From 4d620e5796f863926d6926d85326091847970974 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:47 -0600 +Subject: [PATCH 08/45] northbridge/amd/amdfam10: Update DRAM speed limits for + C32 sockets + +The existing code applied G34-specific speed limits to all socket +types. Update G34 and C32 specific speed limits to be in line with +BKDG recommendations. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdfam10/raminit_amdmct.c | 346 +++++++++++++++++++------- + 1 file changed, 259 insertions(+), 87 deletions(-) + +diff --git a/src/northbridge/amd/amdfam10/raminit_amdmct.c b/src/northbridge/amd/amdfam10/raminit_amdmct.c +index a40c5a1..1407631 100644 +--- a/src/northbridge/amd/amdfam10/raminit_amdmct.c ++++ b/src/northbridge/amd/amdfam10/raminit_amdmct.c +@@ -180,141 +180,313 @@ static uint16_t mct_MaxLoadFreq(uint8_t count, uint8_t highest_rank_count, uint8 + } + + if (is_fam15h()) { +- if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) { +- /* Fam15h BKDG Rev. 3.14 Table 27 */ +- if (voltage & 0x4) { +- /* 1.25V */ +- if (count > 1) { +- if (highest_rank_count > 1) { +- /* Limit to DDR3-1066 */ +- if (freq > 533) { +- freq = 533; +- printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ if (CONFIG_CPU_SOCKET_TYPE == 0x15) { ++ /* Socket G34 */ ++ if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) { ++ /* Fam15h BKDG Rev. 3.14 Table 27 */ ++ if (voltage & 0x4) { ++ /* 1.25V */ ++ if (count > 1) { ++ if (highest_rank_count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } + } + } else { + /* Limit to DDR3-1333 */ + if (freq > 666) { + freq = 666; ++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else if (voltage & 0x2) { ++ /* 1.35V */ ++ if (count > 1) { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; + printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); + } ++ } else { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } + } +- } else { +- /* Limit to DDR3-1333 */ +- if (freq > 666) { +- freq = 666; +- printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } else if (voltage & 0x1) { ++ /* 1.50V */ ++ if (count > 1) { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1866 */ ++ if (freq > 933) { ++ freq = 933; ++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage)); ++ } + } + } +- } else if (voltage & 0x2) { +- /* 1.35V */ +- if (count > 1) { +- /* Limit to DDR3-1333 */ +- if (freq > 666) { +- freq = 666; +- printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); +- } +- } else { +- /* Limit to DDR3-1600 */ +- if (freq > 800) { +- freq = 800; +- printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } else { ++ /* Fam15h BKDG Rev. 3.14 Table 26 */ ++ if (voltage & 0x4) { ++ /* 1.25V */ ++ if (count > 1) { ++ if (highest_rank_count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } + } +- } +- } else if (voltage & 0x1) { +- /* 1.50V */ +- if (count > 1) { +- /* Limit to DDR3-1600 */ +- if (freq > 800) { +- freq = 800; +- printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } else if (voltage & 0x2) { ++ /* 1.35V */ ++ if (MaxDimmsInstallable > 1) { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } + } +- } else { +- /* Limit to DDR3-1866 */ +- if (freq > 933) { +- freq = 933; +- printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage)); ++ } else if (voltage & 0x1) { ++ if (MaxDimmsInstallable == 1) { ++ if (count > 1) { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1866 */ ++ if (freq > 933) { ++ freq = 933; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else { ++ if (count > 1) { ++ if (highest_rank_count > 1) { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } + } + } + } +- } else { +- /* Fam15h BKDG Rev. 3.14 Table 26 */ +- if (voltage & 0x4) { +- /* 1.25V */ +- if (count > 1) { +- if (highest_rank_count > 1) { +- /* Limit to DDR3-1066 */ +- if (freq > 533) { +- freq = 533; +- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } else if (CONFIG_CPU_SOCKET_TYPE == 0x14) { ++ /* Socket C32 */ ++ if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) { ++ /* Fam15h BKDG Rev. 3.14 Table 30 */ ++ if (voltage & 0x4) { ++ /* 1.25V */ ++ if (count > 1) { ++ if (highest_rank_count > 2) { ++ /* Limit to DDR3-800 */ ++ if (freq > 400) { ++ freq = 400; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } + } + } else { + /* Limit to DDR3-1333 */ + if (freq > 666) { + freq = 666; +- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); + } + } +- } else { +- /* Limit to DDR3-1333 */ +- if (freq > 666) { +- freq = 666; +- printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); +- } +- } +- } else if (voltage & 0x2) { +- /* 1.35V */ +- if (MaxDimmsInstallable > 1) { +- /* Limit to DDR3-1333 */ +- if (freq > 666) { +- freq = 666; +- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); +- } +- } else { +- /* Limit to DDR3-1600 */ +- if (freq > 800) { +- freq = 800; +- printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); +- } +- } +- } else if (voltage & 0x1) { +- if (MaxDimmsInstallable == 1) { ++ } else if (voltage & 0x2) { ++ /* 1.35V */ + if (count > 1) { ++ if (highest_rank_count > 2) { ++ /* Limit to DDR3-800 */ ++ if (freq > 400) { ++ freq = 400; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else if (highest_rank_count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else { + /* Limit to DDR3-1600 */ + if (freq > 800) { + freq = 800; +- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); +- } +- } else { +- /* Limit to DDR3-1866 */ +- if (freq > 933) { +- freq = 933; +- printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage)); ++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); + } + } +- } else { ++ } else if (voltage & 0x1) { ++ /* 1.50V */ + if (count > 1) { +- if (highest_rank_count > 1) { ++ if (highest_rank_count > 2) { ++ /* Limit to DDR3-800 */ ++ if (freq > 400) { ++ freq = 400; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else if (highest_rank_count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { + /* Limit to DDR3-1333 */ + if (freq > 666) { + freq = 666; +- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else { ++ if (highest_rank_count > 2) { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); + } + } else { + /* Limit to DDR3-1600 */ + if (freq > 800) { + freq = 800; +- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } ++ } ++ } else { ++ /* Fam15h BKDG Rev. 3.14 Table 29 */ ++ if (voltage & 0x4) { ++ /* 1.25V */ ++ if (count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else if (voltage & 0x2) { ++ if (count > 1) { ++ if (highest_rank_count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); + } + } + } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else if (voltage & 0x1) { ++ if (MaxDimmsInstallable == 1) { + /* Limit to DDR3-1600 */ + if (freq > 800) { + freq = 800; + printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); + } ++ } else { ++ if (count > 1) { ++ if (highest_rank_count > 1) { ++ /* Limit to DDR3-1066 */ ++ if (freq > 533) { ++ freq = 533; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } else { ++ /* Limit to DDR3-1333 */ ++ if (freq > 666) { ++ freq = 666; ++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } ++ } else { ++ /* Limit to DDR3-1600 */ ++ if (freq > 800) { ++ freq = 800; ++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage)); ++ } ++ } + } + } + } ++ } else { ++ /* TODO ++ * Other socket support unimplemented ++ */ + } + } else { + if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) { +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch new file mode 100644 index 0000000..5d50aae --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch @@ -0,0 +1,980 @@ +From 864c5d310f3a833e1317053c1d9886ac6e95a56e Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:47 -0600 +Subject: [PATCH 09/45] northbridge/amd/amdmct: Add termination and timing + values for C32 sockets + +The existing MCT initialization code was largely missing C32 socket- +specific configuration data. Add C32 socket-specific timing and ODT +values as specified in the BKDG. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 543 ++++++++++++++++++++++++++- + src/northbridge/amd/amdmct/mct_ddr3/mctrci.c | 58 +++ + src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 254 +++++++++++++ + 3 files changed, 851 insertions(+), 4 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +index cb83fe1..ac5220e 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +@@ -1092,6 +1092,152 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT + */ + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ if (pDCTstat->Status & (1 << SB_Registered)) { ++ /* RDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x00112222; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x10112222; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x20112222; ++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { ++ /* DDR3-1333 - DDR3-1600 */ ++ calibration_code = 0x30112222; ++ } ++ ++ if (rank_count_dimm0 == 4) { ++ calibration_code &= ~(0xff << 16); ++ calibration_code |= 0x22 << 16; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x00112222; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x10112222; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x20112222; ++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { ++ /* DDR3-1333 - DDR3-1600 */ ++ calibration_code = 0x30112222; ++ } ++ ++ if ((rank_count_dimm0 == 4) || (rank_count_dimm1 == 4)) { ++ calibration_code &= ~(0xff << 16); ++ calibration_code |= 0x22 << 16; ++ } ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x10222222; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x20222222; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x30222222; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x30222222; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ calibration_code = 0x30222222; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { ++ /* LRDIMM */ ++ /* TODO ++ * LRDIMM support unimplemented ++ */ ++ } else { ++ /* UDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */ ++ if (MaxDimmsInstallable == 1) { ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x00112222; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x10112222; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x20112222; ++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { ++ /* DDR3-1333 - DDR3-1600 */ ++ calibration_code = 0x30112222; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x00112222; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x10112222; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x20112222; ++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { ++ /* DDR3-1333 - DDR3-1600 */ ++ calibration_code = 0x30112222; ++ } ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x10222222; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x20222222; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x30222222; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x30222222; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) ++ calibration_code = 0x30222222; ++ else ++ calibration_code = 0x30112222; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } + } else { + /* TODO + * Other socket support unimplemented +@@ -1116,11 +1262,165 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC + uint8_t rank_count_dimm0; + uint8_t rank_count_dimm1; + +- if (package_type == PT_GR) { +- /* Socket G34 */ ++ if (package_type == PT_GR) { ++ /* Socket G34 */ ++ if (pDCTstat->Status & (1 << SB_Registered)) { ++ /* RDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */ ++ if (MaxDimmsInstallable == 1) { ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ calibration_code = 0x00000000; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x003c3c3c; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x003a3a3a; ++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { ++ /* DDR3-1600 - DDR3-1866 */ ++ calibration_code = 0x00393939; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ calibration_code = 0x00000000; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x00393c39; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x00373a37; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ calibration_code = 0x00363936; ++ } ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ calibration_code = 0x00000000; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x003a3c3a; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x00383a38; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ calibration_code = 0x00353935; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { ++ /* LRDIMM */ ++ /* TODO ++ * LRDIMM support unimplemented ++ */ ++ } else { ++ /* UDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ if (rank_count_dimm0 == 1) ++ calibration_code = 0x00000000; ++ else ++ calibration_code = 0x003b0000; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ if (rank_count_dimm0 == 1) ++ calibration_code = 0x00000000; ++ else ++ calibration_code = 0x003b0000; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x00383837; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x00363635; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ if (rank_count_dimm0 == 1) ++ calibration_code = 0x00353533; ++ else ++ calibration_code = 0x00003533; ++ } else if (MemClkFreq == 0x16) { ++ /* DDR3-1866 */ ++ calibration_code = 0x00333330; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ if (rank_count_dimm0 == 1) ++ calibration_code = 0x00000000; ++ else ++ calibration_code = 0x003b0000; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ if (rank_count_dimm0 == 1) ++ calibration_code = 0x00000000; ++ else ++ calibration_code = 0x003b0000; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x00383837; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x00363635; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ if (rank_count_dimm0 == 1) ++ calibration_code = 0x00353533; ++ else ++ calibration_code = 0x00003533; ++ } ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (MemClkFreq == 0x4) { ++ /* DDR3-667 */ ++ calibration_code = 0x00390039; ++ } else if (MemClkFreq == 0x6) { ++ /* DDR3-800 */ ++ calibration_code = 0x00390039; ++ } else if (MemClkFreq == 0xa) { ++ /* DDR3-1066 */ ++ calibration_code = 0x003a3a3a; ++ } else if (MemClkFreq == 0xe) { ++ /* DDR3-1333 */ ++ calibration_code = 0x00003939; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) ++ calibration_code = 0x00003738; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } ++ } else if (package_type == PT_C3) { ++ /* Socket C32 */ + if (pDCTstat->Status & (1 << SB_Registered)) { + /* RDIMM */ +- /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */ + if (MaxDimmsInstallable == 1) { + if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { + /* DDR3-667 - DDR3-800 */ +@@ -1179,7 +1479,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC + */ + } else { + /* UDIMM */ +- /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */ + if (MaxDimmsInstallable == 1) { + rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; + +@@ -1357,6 +1657,69 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc + */ + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ if (pDCTstat->Status & (1 << SB_Registered)) { ++ /* RDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */ ++ slow_access = 0; ++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { ++ /* LRDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 78 */ ++ slow_access = 0; ++ } else { ++ /* UDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) ++ || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { ++ /* DDR3-667 - DDR3-1333 */ ++ slow_access = 0; ++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { ++ /* DDR3-1600 - DDR3-1866 */ ++ if (rank_count_dimm0 == 1) ++ slow_access = 0; ++ else ++ slow_access = 1; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) ++ || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { ++ /* DDR3-667 - DDR3-1333 */ ++ slow_access = 0; ++ } else if (MemClkFreq == 0x12) { ++ /* DDR3-1600 */ ++ if (rank_count_dimm0 == 1) ++ slow_access = 0; ++ else ++ slow_access = 1; ++ } ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) ++ || (MemClkFreq == 0xa)) { ++ /* DDR3-667 - DDR3-1066 */ ++ slow_access = 0; ++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { ++ /* DDR3-1333 - DDR3-1600 */ ++ slow_access = 1; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } + } else { + /* TODO + * Other socket support unimplemented +@@ -1466,6 +1829,92 @@ static uint8_t fam15h_odt_tristate_enable_code(struct DCTStatStruc *pDCTstat, ui + */ + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ if (pDCTstat->Status & (1 << SB_Registered)) { ++ /* RDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm0 == 1) ++ odt_tristate_code = 0xe; ++ else ++ odt_tristate_code = 0xa; ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm1 == 1) ++ odt_tristate_code = 0xd; ++ else ++ odt_tristate_code = 0x5; ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) ++ odt_tristate_code = 0xc; ++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 >= 2)) ++ odt_tristate_code = 0x4; ++ else if ((rank_count_dimm0 >= 2) && (rank_count_dimm1 == 1)) ++ odt_tristate_code = 0x8; ++ else ++ odt_tristate_code = 0x0; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { ++ /* LRDIMM */ ++ ++ /* TODO ++ * Implement LRDIMM support ++ * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108 ++ */ ++ } else { ++ /* UDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm0 == 1) ++ odt_tristate_code = 0xe; ++ else ++ odt_tristate_code = 0xa; ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm0 == 1) ++ odt_tristate_code = 0xd; ++ else ++ odt_tristate_code = 0x5; ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) ++ odt_tristate_code = 0xc; ++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) ++ odt_tristate_code = 0x4; ++ else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) ++ odt_tristate_code = 0x8; ++ else ++ odt_tristate_code = 0x0; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } + } else { + /* TODO + * Other socket support unimplemented +@@ -1575,6 +2024,92 @@ static uint8_t fam15h_cs_tristate_enable_code(struct DCTStatStruc *pDCTstat, uin + */ + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ if (pDCTstat->Status & (1 << SB_Registered)) { ++ /* RDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm0 < 4) ++ cs_tristate_code = 0xfc; ++ else ++ cs_tristate_code = 0xcc; ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm1 < 4) ++ cs_tristate_code = 0xf3; ++ else ++ cs_tristate_code = 0x33; ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) ++ cs_tristate_code = 0xf0; ++ else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4)) ++ cs_tristate_code = 0x30; ++ else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4)) ++ cs_tristate_code = 0xc0; ++ else ++ cs_tristate_code = 0x0; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { ++ /* LRDIMM */ ++ ++ /* TODO ++ * Implement LRDIMM support ++ * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108 ++ */ ++ } else { ++ /* UDIMM */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm0 == 1) ++ cs_tristate_code = 0xfe; ++ else ++ cs_tristate_code = 0xfc; ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if (rank_count_dimm0 == 1) ++ cs_tristate_code = 0xfb; ++ else ++ cs_tristate_code = 0xf3; ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) ++ cs_tristate_code = 0xfa; ++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) ++ cs_tristate_code = 0xf2; ++ else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) ++ cs_tristate_code = 0xf8; ++ else ++ cs_tristate_code = 0xf0; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } + } else { + /* TODO + * Other socket support unimplemented +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c +index 4455391..f5d488a 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c +@@ -77,6 +77,51 @@ static uint8_t fam15h_rdimm_rc2_ibt_code(struct DCTStatStruc *pDCTstat, uint8_t + * 3 DIMM/channel support unimplemented + */ + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.7.1.2.1 Table 86 */ ++ if (MaxDimmsInstallable == 1) { ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ control_code = 0x1; ++ } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { ++ /* DDR3-1066 - DDR3-1333 */ ++ if (num_registers == 1) { ++ control_code = 0x0; ++ } else { ++ control_code = 0x1; ++ } ++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { ++ /* DDR3-1600 - DDR3-1866 */ ++ control_code = 0x0; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ if (dimm_count == 1) { ++ /* 1 DIMM detected */ ++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ control_code = 0x1; ++ } else if ((MemClkFreq >= 0xa) && (MemClkFreq <= 0x12)) { ++ /* DDR3-1066 - DDR3-1600 */ ++ if (num_registers == 1) { ++ control_code = 0x0; ++ } else { ++ control_code = 0x1; ++ } ++ } ++ } else if (dimm_count == 2) { ++ /* 2 DIMMs detected */ ++ if (num_registers == 1) { ++ control_code = 0x1; ++ } else { ++ control_code = 0x8; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } + } else { + /* TODO + * Other socket support unimplemented +@@ -166,6 +211,13 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, + val = 0x4; + } + } ++ else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ if (MaxDimmsInstallable == 2) { ++ if (Dimms > 1) ++ val = 0x4; ++ } ++ } + } + } else if (CtrlWordNum == 3) { + val = (pDCTstat->CtrlWrd3 >> (DimmNum << 2)) & 0xff; +@@ -183,6 +235,12 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat, + val = 0x0; + } + } ++ else if (package_type == PT_C3) { ++ /* Socket C32 */ ++ if (MaxDimmsInstallable == 2) { ++ val = 0x0; ++ } ++ } + } + } else if (CtrlWordNum == 9) { + val = 0xd; /* DBA1, DBA0, DA3 = 0 */ +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +index 143290f..822d813 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +@@ -117,6 +117,67 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d + term = 0x2; + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32: Fam15h BKDG v3.14 Table 60 */ ++ if (MaxDimmsInstallable == 1) { ++ if ((frequency_index == 0x4) || (frequency_index == 0x6) ++ || (frequency_index == 0xa) || (frequency_index == 0xe)) { ++ /* DDR3-667 - DDR3-1333 */ ++ if (rank_count < 3) ++ term = 0x0; ++ else ++ term = 0x2; ++ } else { ++ /* DDR3-1600 */ ++ term = 0x0; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ if ((number_of_dimms == 1) && ((rank_count_dimm0 < 4) ++ && (rank_count_dimm1 < 4))) ++ term = 0x0; ++ else ++ term = 0x2; ++ } else if (frequency_index == 0xa) { ++ /* DDR3-1066 */ ++ if (number_of_dimms == 1) { ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) ++ term = 0x0; ++ else ++ term = 0x2; ++ } else { ++ term = 0x1; ++ } ++ } else if (frequency_index == 0xe) { ++ /* DDR3-1333 */ ++ term = 0x2; ++ } else { ++ /* DDR3-1600 */ ++ if (number_of_dimms == 1) ++ term = 0x0; ++ else ++ term = 0x1; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ rank_count_dimm2 = pDCTstat->DimmRanks[(2 * 2) + dct]; ++ ++ if ((frequency_index == 0xa) || (frequency_index == 0xe)) { ++ /* DDR3-1066 - DDR3-1333 */ ++ if (rank_count_dimm2 < 4) ++ term = 0x1; ++ else ++ term = 0x2; ++ } else if (frequency_index == 0x12) { ++ /* DDR3-1600 */ ++ term = 0x1; ++ } else { ++ term = 0x2; ++ } ++ } + } else { + /* TODO + * Other sockets unimplemented +@@ -151,6 +212,33 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d + term = 0x2; + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32: Fam15h BKDG v3.14 Table 59 */ ++ if (MaxDimmsInstallable == 1) { ++ term = 0x0; ++ } else if (MaxDimmsInstallable == 2) { ++ if ((number_of_dimms == 2) && (frequency_index == 0x12)) { ++ term = 0x1; ++ } else if (number_of_dimms == 1) { ++ term = 0x0; ++ } else { ++ term = 0x2; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ if (number_of_dimms == 1) { ++ if (frequency_index <= 0xa) { ++ term = 0x2; ++ } else { ++ if (rank_count < 3) { ++ term = 0x1; ++ } else { ++ term = 0x2; ++ } ++ } ++ } else if (number_of_dimms == 2) { ++ term = 0x2; ++ } ++ } + } else { + /* TODO + * Other sockets unimplemented +@@ -302,6 +390,125 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t + * 3 DIMM/channel support unimplemented + */ + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32: Fam15h BKDG v3.14 Table 60 */ ++ if (MaxDimmsInstallable == 1) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ ++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ if (rank_count_dimm0 < 4) { ++ term = 0x2; ++ } else { ++ if (!rank) ++ term = 0x2; ++ else ++ term = 0x0; ++ } ++ } else if (frequency_index == 0xa) { ++ /* DDR3-1066 */ ++ term = 0x1; ++ } else if (frequency_index == 0xe) { ++ /* DDR3-1333 */ ++ if (rank_count_dimm0 < 4) { ++ term = 0x1; ++ } else { ++ if (!rank) ++ term = 0x3; ++ else ++ term = 0x0; ++ } ++ } else { ++ term = 0x3; ++ } ++ } else if (MaxDimmsInstallable == 2) { ++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; ++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; ++ ++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) { ++ /* DDR3-667 - DDR3-800 */ ++ if (number_of_dimms == 1) { ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) ++ term = 0x2; ++ else if (rank) ++ term = 0x0; ++ else ++ term = 0x2; ++ } else { ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) { ++ term = 0x3; ++ } else { ++ if (rank_count_dimm0 == 4) { ++ if (rank_count_dimm1 == 1) ++ term = 0x5; ++ else ++ term = 0x1; ++ } else if (rank_count_dimm1 == 4) { ++ if (rank_count_dimm0 == 1) ++ term = 0x5; ++ else ++ term = 0x1; ++ } ++ if (rank) ++ term = 0x0; ++ } ++ } ++ } else if (frequency_index == 0xa) { ++ /* DDR3-1066 */ ++ if (number_of_dimms == 1) { ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) ++ term = 0x1; ++ else if (rank) ++ term = 0x0; ++ else ++ term = 0x1; ++ } else { ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) { ++ term = 0x3; ++ } else { ++ if (rank_count_dimm0 == 4) { ++ if (rank_count_dimm1 == 1) ++ term = 0x5; ++ else ++ term = 0x1; ++ } else if (rank_count_dimm1 == 4) { ++ if (rank_count_dimm0 == 1) ++ term = 0x5; ++ else ++ term = 0x1; ++ } ++ if (rank) ++ term = 0x0; ++ } ++ } ++ } else if (frequency_index == 0xe) { ++ /* DDR3-1333 */ ++ if (number_of_dimms == 1) { ++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) ++ term = 0x1; ++ else if (rank) ++ term = 0x0; ++ else ++ term = 0x3; ++ } else { ++ term = 0x5; ++ } ++ } else { ++ /* DDR3-1600 */ ++ if (number_of_dimms == 1) ++ term = 0x3; ++ else ++ term = 0x4; ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ /* TODO ++ * 3 DIMM/channel support unimplemented ++ */ ++ } ++ } else { ++ /* TODO ++ * Other sockets unimplemented ++ */ + } + } else { + /* UDIMM */ +@@ -352,6 +559,53 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t + } + } + } ++ } else if (package_type == PT_C3) { ++ /* Socket C32: Fam15h BKDG v3.14 Table 62 */ ++ if (MaxDimmsInstallable == 1) { ++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) ++ term = 0x2; ++ else if ((frequency_index == 0xa) || (frequency_index == 0xe)) ++ term = 0x1; ++ else ++ term = 0x3; ++ } ++ if (MaxDimmsInstallable == 2) { ++ if (number_of_dimms == 1) { ++ if (frequency_index <= 0x6) { ++ term = 0x2; ++ } else if (frequency_index <= 0xe) { ++ term = 0x1; ++ } else { ++ term = 0x3; ++ } ++ } else { ++ if (frequency_index <= 0xa) { ++ term = 0x3; ++ } else if (frequency_index <= 0xe) { ++ term = 0x5; ++ } else { ++ term = 0x4; ++ } ++ } ++ } else if (MaxDimmsInstallable == 3) { ++ if (number_of_dimms == 1) { ++ term = 0x0; ++ } else if (number_of_dimms == 2) { ++ if (frequency_index <= 0xa) { ++ if (rank == 1) { ++ term = 0x0; ++ } else { ++ term = 0x3; ++ } ++ } else if (frequency_index <= 0xe) { ++ if (rank == 1) { ++ term = 0x0; ++ } else { ++ term = 0x5; ++ } ++ } ++ } ++ } + } else { + /* TODO + * Other sockets unimplemented +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch new file mode 100644 index 0000000..35d0d6c --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch @@ -0,0 +1,99 @@ +From c4669801294d56534e4ac4de3ab71de39afe90d8 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:47 -0600 +Subject: [PATCH 10/45] cpu/amd/family_10h-family_15h: Set LDT tristate + correctly on C32 sockets + +The existing code unconditionally cleared the LDT tristate enable bit, +which was incorrect for C32 sockets. Update the code to be in line +with the BKDG recommendations. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/defaults.h | 19 ------------- + src/cpu/amd/family_10h-family_15h/init_cpus.c | 39 +++++++++++++++++++++++++++ + 2 files changed, 39 insertions(+), 19 deletions(-) + +diff --git a/src/cpu/amd/family_10h-family_15h/defaults.h b/src/cpu/amd/family_10h-family_15h/defaults.h +index 57c0518..3618cb8 100644 +--- a/src/cpu/amd/family_10h-family_15h/defaults.h ++++ b/src/cpu/amd/family_10h-family_15h/defaults.h +@@ -260,25 +260,6 @@ static const struct { + { 0, 0xE4, AMD_FAM10_ALL, AMD_PTYPE_ALL, + 0x00002000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */ + +- /* FIXME +- * Non-C32 packages only +- */ +- { 0, 0x84, AMD_FAM15_ALL, AMD_PTYPE_ALL, +- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */ +- +- { 0, 0xA4, AMD_FAM15_ALL, AMD_PTYPE_ALL, +- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */ +- +- { 0, 0xC4, AMD_FAM15_ALL, AMD_PTYPE_ALL, +- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */ +- +- { 0, 0xE4, AMD_FAM15_ALL, AMD_PTYPE_ALL, +- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */ +- +- /* FIXME +- * C32 package is not supported at this time +- */ +- + /* Link Global Retry Control Register */ + { 0, 0x150, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, + 0x00073900, 0x00073f70 }, /* TotalRetryAttempts = 0x7, +diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c +index bf1862b..1794072 100644 +--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c ++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c +@@ -1095,6 +1095,45 @@ static void cpuSetAMDPCI(u8 node) + } + } + ++ if (is_fam15h()) { ++ if (CONFIG_CPU_SOCKET_TYPE == 0x14) { ++ /* Socket C32 */ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0x84); ++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */ ++ pci_write_config32(NODE_PCI(node, 0), 0x84, dword); ++ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xa4); ++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */ ++ pci_write_config32(NODE_PCI(node, 0), 0xa4, dword); ++ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xc4); ++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */ ++ pci_write_config32(NODE_PCI(node, 0), 0xc4, dword); ++ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xe4); ++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */ ++ pci_write_config32(NODE_PCI(node, 0), 0xe4, dword); ++ } ++ else { ++ /* Other socket (G34, etc.) */ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0x84); ++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */ ++ pci_write_config32(NODE_PCI(node, 0), 0x84, dword); ++ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xa4); ++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */ ++ pci_write_config32(NODE_PCI(node, 0), 0xa4, dword); ++ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xc4); ++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */ ++ pci_write_config32(NODE_PCI(node, 0), 0xc4, dword); ++ ++ dword = pci_read_config32(NODE_PCI(node, 0), 0xe4); ++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */ ++ pci_write_config32(NODE_PCI(node, 0), 0xe4, dword); ++ } ++ } ++ + #ifdef DEBUG_HT_SETUP + /* Dump link settings */ + for (i = 0; i < 4; i++) { +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch new file mode 100644 index 0000000..1c25598 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch @@ -0,0 +1,107 @@ +From 908455aa41424aefbb328fd8c826be2e2b344ce6 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:48 -0600 +Subject: [PATCH 11/45] cpu/amd/family_10h-family_15h: Move CBMEM storage out + of CC6 save region + +The existing CBMEM TOM calculations did not account for the CC6 save region +(when enabled); this resulted in CBMEM storage being placed on top of the +CC6 save region, which resulted in corrupt CBMEM data and a boot hang. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/ram_calc.c | 51 +++++++++++++++++++++++++++- + src/cpu/amd/family_10h-family_15h/ram_calc.h | 1 + + 2 files changed, 51 insertions(+), 1 deletion(-) + +diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.c b/src/cpu/amd/family_10h-family_15h/ram_calc.c +index 9ac2c99..4fe997e 100644 +--- a/src/cpu/amd/family_10h-family_15h/ram_calc.c ++++ b/src/cpu/amd/family_10h-family_15h/ram_calc.c +@@ -18,11 +18,30 @@ + #include <cpu/x86/msr.h> + #include <cpu/amd/mtrr.h> + ++#include <arch/io.h> ++#include <device/device.h> ++#include <device/pci.h> ++ + #include <cbmem.h> + + #include "ram_calc.h" + + #if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT) ++static inline uint8_t is_fam15h(void) ++{ ++ uint8_t fam15h = 0; ++ uint32_t family; ++ ++ family = cpuid_eax(0x80000001); ++ family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); ++ ++ if (family >= 0x6f) ++ /* Family 15h or later */ ++ fam15h = 1; ++ ++ return fam15h; ++} ++ + uint64_t get_uma_memory_size(uint64_t topmem) + { + uint64_t uma_size = 0; +@@ -41,10 +60,40 @@ uint64_t get_uma_memory_size(uint64_t topmem) + return uma_size; + } + ++uint64_t get_cc6_memory_size() ++{ ++ uint8_t enable_cc6; ++ ++ uint64_t cc6_size = 0; ++ ++ if (is_fam15h()) { ++ enable_cc6 = 0; ++ ++#ifdef __PRE_RAM__ ++ if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18)) ++ enable_cc6 = 1; ++#else ++ device_t dct_dev = dev_find_slot(0, PCI_DEVFN(0x18, 2)); ++ if (pci_read_config32(dct_dev, 0x118) & (0x1 << 18)) ++ enable_cc6 = 1; ++#endif ++ ++ if (enable_cc6) { ++ /* Preserve the maximum possible CC6 save region ++ * This needs to be kept in sync with ++ * amdfam10_domain_read_resources() in northbridge.c ++ */ ++ cc6_size = 0x8000000; ++ } ++ } ++ ++ return cc6_size; ++} ++ + void *cbmem_top(void) + { + uint32_t topmem = rdmsr(TOP_MEM).lo; + +- return (void *) topmem - get_uma_memory_size(topmem); ++ return (void *) topmem - get_uma_memory_size(topmem) - get_cc6_memory_size(); + } + #endif +diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.h b/src/cpu/amd/family_10h-family_15h/ram_calc.h +index 8cfc199..0bb4cac 100644 +--- a/src/cpu/amd/family_10h-family_15h/ram_calc.h ++++ b/src/cpu/amd/family_10h-family_15h/ram_calc.h +@@ -17,5 +17,6 @@ + #define _AMD_MODEL_10XXX_RAM_CALC_H_ + + uint64_t get_uma_memory_size(uint64_t topmem); ++uint64_t get_cc6_memory_size(void); + + #endif +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch new file mode 100644 index 0000000..36efd72 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch @@ -0,0 +1,89 @@ +From 2eb03f516b6555636282713527bf9f2e672bf97b Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:50 -0600 +Subject: [PATCH 12/45] northbridge/amd/amdmct/mct_ddr3: Enable fast refresh on + ETR devices + +When an Extended Temperature Range DIMM is installed on a channel +the refresh rate should be increased per the BKDG recommendations +to allow correct operation at higher temperature ranges. + +Set fast refresh on a channel if an ETR DIMM is installed on that +channel. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 12 +++++++++++- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 5 +++-- + 2 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +index ac5220e..beb71f9 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +@@ -3993,6 +3993,7 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, + u32 DramTimingLo, DramTimingHi; + u8 tCK16x; + u16 Twtr; ++ uint8_t Etr[2]; + u8 LDIMM; + u8 MTB16x; + u8 byte; +@@ -4011,6 +4012,8 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, + Trc = 0; + Twr = 0; + Twtr = 0; ++ for (i=0; i < 2; i++) ++ Etr[i] = 0; + for (i=0; i < 4; i++) + Trfc[i] = 0; + Tfaw = 0; +@@ -4077,6 +4080,10 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, + val *= MTB16x; + if (Tfaw < val) + Tfaw = val; ++ ++ /* Determine if the DIMMs on this channel support 95°C ETR */ ++ if (pDCTstat->spd_data.spd_bytes[dct + i][SPD_Thermal] & 0x1) ++ Etr[dct] = 1; + } /* Dimm Present */ + } + +@@ -4248,7 +4255,10 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, + dev = pDCTstat->dev_dct; + + dword = Get_NB32_DCT(dev, dct, 0x8c); /* DRAM Timing High */ +- val = 2; /* Tref = 7.8us */ ++ if (Etr[dct]) ++ val = 3; /* Tref = 3.9us */ ++ else ++ val = 2; /* Tref = 7.8us */ + dword &= ~(0x3 << 16); + dword |= (val & 0x3) << 16; + Set_NB32_DCT(dev, dct, 0x8c, dword); /* DRAM Timing High */ +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +index 5f72ff3..e7361ac 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +@@ -217,8 +217,8 @@ + #define SPD_CASHigh 15 + #define SPD_tAAmin 16 + +-#define SPD_DEVATTRIB 22 +-#define SPD_EDCTYPE 11 ++#define SPD_DEVATTRIB 22 ++#define SPD_EDCTYPE 11 + #define JED_ADRCPAR 0x04 + + #define SPD_tWRmin 17 +@@ -232,6 +232,7 @@ + #define SPD_tRTPmin 27 + #define SPD_Upper_tFAW 28 + #define SPD_tFAWmin 29 ++#define SPD_Thermal 31 + + #define SPD_RefRawCard 62 + #define SPD_AddressMirror 63 +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch new file mode 100644 index 0000000..d9b70ca --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch @@ -0,0 +1,149 @@ +From cebd4b26e543f7284ee6fa48531315bc6d40523d Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:50 -0600 +Subject: [PATCH 13/45] nb/amd/mct_ddr3: Update drive strength configuration + +The existing drive strength calibration code did not strictly +follow the BKDG-defined setup process. Bring the calibration +code in line with the BKDG recommendations. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 49 +++++++++++++++++++---------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +index beb71f9..9724008 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +@@ -6828,7 +6828,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, + /* Program TxPreP/TxPreN for data lanes (Stage 1) */ + for (index = 0; index < 0x9; index++) { + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8)); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8), dword); + } +@@ -6841,13 +6841,13 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, + /* Program TxPreP/TxPreN for data lanes (Stage 2) */ + for (index = 0; index < 0x9; index++) { + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8)); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8), dword); + } + for (index = 0; index < 0x9; index++) { + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8), dword); + } +@@ -6859,15 +6859,15 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, + + /* Program TxPreP/TxPreN for command/address lines (Stage 1) */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002, dword); + +@@ -6878,31 +6878,31 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, + + /* Program TxPreP/TxPreN for command/address lines (Stage 2) */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= tx_pre; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102, dword); + +@@ -6913,7 +6913,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, + + /* Program TxPreP/TxPreN for command/address lines (Stage 3) */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002, dword); + +@@ -6924,17 +6924,32 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, + + /* Program TxPreP/TxPreN for clock lines */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102, dword); + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202); +- dword &= ~(0xfff); ++ dword &= ~(0xffff); + dword |= (0x8000 | tx_pre); + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202, dword); ++ ++ /* Be extra safe and wait for the predriver calibration to be applied ++ * to the hardware. The BKDG does not require this, but it does take ++ * some time for the data to propagate, so it's probably a good idea. ++ */ ++ uint8_t predriver_cal_pending = 1; ++ printk(BIOS_DEBUG, "Waiting for predriver calibration to be applied..."); ++ while (predriver_cal_pending) { ++ predriver_cal_pending = 0; ++ for (index = 0; index < 0x9; index++) { ++ if (Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)) & 0x8000) ++ predriver_cal_pending = 1; ++ } ++ } ++ printk(BIOS_DEBUG, "done!\n"); + } else { + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00); + dword = 0; +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch new file mode 100644 index 0000000..5264c8f --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch @@ -0,0 +1,63 @@ +From 99fae7d439a9eaac33ce4a4f7e9a78696dfd3547 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:52 -0600 +Subject: [PATCH 14/45] nb/amd/mct_ddr3: Add additional verbose-level debug + statements + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c | 10 ++++++++-- + src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c | 2 ++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +index 4cc87de..22e9836 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +@@ -1428,8 +1428,9 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat, + + if (check_antiphase == 0) { + /* Check for early abort before analyzing per-nibble status */ +- dword = Get_NB32_DCT(dev, dct, 0x264) & 0x1ffffff; +- if (dword != 0) { ++ dword = Get_NB32_DCT(dev, dct, 0x264); ++ if ((dword & 0x1ffffff) != 0) { ++ print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 162 early abort: F2x264 ", dword, 6); + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 0; /* Fail */ + continue; + } +@@ -1439,6 +1440,7 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat, + * Record pass / fail status + */ + dword = Get_NB32_DCT(dev, dct, 0x268) & 0x3ffff; ++ print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 163 read results: F2x268 ", dword, 6); + if (dword & (0x3 << (lane * 2))) + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 0; /* Fail */ + else +@@ -1737,6 +1739,10 @@ static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat, + printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc_D_Fam15 Receiver %d lane %d initial phy delay %04x: iterating from %04x to %04x\n", Receiver, lane, initial_phy_phase_delay[lane], rx_en_offset, 0x3ff); + #endif + for (current_phy_phase_delay[lane] = rx_en_offset; current_phy_phase_delay[lane] < 0x3ff; current_phy_phase_delay[lane] += ren_step) { ++#if DQS_TRAIN_DEBUG > 0 ++ printk(BIOS_DEBUG, "%s: Receiver %d lane %d current phy delay: %04x\n", __func__, Receiver, lane, current_phy_phase_delay[lane]); ++#endif ++ + /* 2.10.5.8.3 (4 A) */ + write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg); + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c +index 1c756ab..d316d27 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c +@@ -228,6 +228,8 @@ static uint16_t fam15_receiver_enable_training_seed(struct DCTStatStruc *pDCTsta + } + } + ++ printk(BIOS_DEBUG, "%s: using seed: %04x\n", __func__, seed); ++ + return seed; + } + +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch new file mode 100644 index 0000000..dd76550 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch @@ -0,0 +1,30 @@ +From 5f5614ca862cecec27a3cf1fe843a4c30cbde69b Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:52 -0600 +Subject: [PATCH 15/45] nb/amd/mct_ddr3: Properly set MR0 WR value + +The existing code accidentally truncated the MSB from the MR0 +WR value. While this probably had a minimal effect in reality, +it should be configured correctly for maximal system stability. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +index 822d813..bcf6031 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +@@ -967,7 +967,7 @@ static u32 mct_MR0(struct MCTStatStruc *pMCTstat, + + /* Load data into MRS word */ + ret |= (ppd & 0x1) << 12; +- ret |= (wr_ap & 0x3) << 9; ++ ret |= (wr_ap & 0x7) << 9; + ret |= (dll_reset & 0x1) << 8; + ret |= (test_mode & 0x1) << 7; + ret |= ((cas_latency & 0xe) >> 1) << 4; +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch new file mode 100644 index 0000000..ab731ac --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch @@ -0,0 +1,32 @@ +From 2888ba1b3ac0056183b05a37e6f24018a00339fa Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:52 -0600 +Subject: [PATCH 16/45] nb/amd/mct_ddr3: Fix RDIMM training failure on Fam15h + +Certain registered DIMMs failed training due to an error +likely introduced during historical rebase. Ensure that +the SubMemclkRegDly bit is set according to BKDG +recommendations on Family 15 processors. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mctproc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c +index cf13b40..fc62afb 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c +@@ -66,6 +66,9 @@ u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, + misc2 |= ((cs_mux_67 & 0x1) << 27); + misc2 &= ~(0x1 << 26); /* CsMux45 = cs_mux_45 */ + misc2 |= ((cs_mux_45 & 0x1) << 26); ++ ++ if (pDCTstat->Status & (1 << SB_Registered)) ++ misc2 |= 1 << SubMemclkRegDly; + } else if (pDCTstat->LogicalCPUID & (AMD_DR_Dx | AMD_DR_Cx)) { + if (pDCTstat->Status & (1 << SB_Registered)) { + misc2 |= 1 << SubMemclkRegDly; +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch new file mode 100644 index 0000000..987f041 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch @@ -0,0 +1,59 @@ +From eb9dc9e1f48f8f6bdb7e97a2d0ec4b5db93db0e0 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:53 -0600 +Subject: [PATCH 17/45] cpu/amd/fam10h-fam15h: Correctly create APIC ID on + single node systems + +The existing code generated an incorrect boot APIC ID from node and +core number for single node packages, leading to a boot failure when +the second node was installed. + +Properly generate the boot APIC ID from node and core number. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/init_cpus.c | 6 +++++- + src/northbridge/amd/amdfam10/northbridge.c | 4 +++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c +index 1794072..5a67601 100644 +--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c ++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c +@@ -127,13 +127,17 @@ uint32_t get_boot_apic_id(uint8_t node, uint32_t core) { + } + } else { + if (fam15h) { +- ap_apicid = (node * (siblings + 1)) + core; ++ ap_apicid = 0; ++ ap_apicid |= (node & 0x7) << 4; /* Node ID */ ++ ap_apicid |= core & 0xf; /* Core ID */ + } else { + ap_apicid = node * (nb_cfg_54 ? (siblings + 1) : 1) + + core * (nb_cfg_54 ? 1 : 64); + } + } + ++ printk(BIOS_DEBUG, "%s: using %d as APIC ID for node %d, core %d\n", __func__, ap_apicid, node, core); ++ + return ap_apicid; + } + +diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c +index b376171..35d0925 100644 +--- a/src/northbridge/amd/amdfam10/northbridge.c ++++ b/src/northbridge/amd/amdfam10/northbridge.c +@@ -1636,7 +1636,9 @@ static void cpu_bus_scan(device_t dev) + } + } else { + if (fam15h) { +- apic_id = (i * (siblings + 1)) + j; ++ apic_id = 0; ++ apic_id |= (i & 0x7) << 4; /* Node ID */ ++ apic_id |= j & 0xf; /* Core ID */ + } else { + apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ? + } +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch new file mode 100644 index 0000000..7b2fdc2 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch @@ -0,0 +1,73 @@ +From 7c59896199f78e3b7ededce1a9c2eb9a9bfa795d Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:53 -0600 +Subject: [PATCH 18/45] nb/amdmct/mct_ddr3: Enable mainboard voltage set + +The existing code used an incorrect macro name to check for mainboard +DRAM voltage set support, and as a result no voltages were actually +set. Furthermore, the existing code did not contain a centralized +voltage assumption for boards that did not have a DIMM voltage set +implementation. + +Use the correct macro name to test for boards with voltage set +implementation, and provide a basic fallback to 1.5V operation +for boards without a voltage set implementation. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +index 9724008..e1c0d4f 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +@@ -254,6 +254,10 @@ static uint8_t dct_ddr_voltage_index(struct DCTStatStruc *pDCTstat, uint8_t dct) + uint8_t dimm; + uint8_t ddr_voltage_index = 0; + ++ /* If no DIMMs are present on this DCT, report 1.5V operation and skip checking the hardware */ ++ if (pDCTstat->DIMMValidDCT[dct] == 0) ++ return 0x1; ++ + /* Find current DDR supply voltage for this DCT */ + for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { + if (pDCTstat->DIMMValidDCT[dct] & (1 << dimm)) +@@ -2409,6 +2413,7 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, + */ + u8 Node, NodesWmem; + u32 node_sys_base; ++ uint8_t dimm; + uint8_t nvram; + uint8_t enable_cc6; + uint8_t allow_config_restore; +@@ -2498,10 +2503,25 @@ restartinit: + nvram = 0; + set_option("allow_spd_nvram_cache_restore", &nvram); + +-#if IS_ENABLED(DIMM_VOLTAGE_SET_SUPPORT) ++#if IS_ENABLED(CONFIG_DIMM_VOLTAGE_SET_SUPPORT) + printk(BIOS_DEBUG, "%s: DIMMSetVoltage\n", __func__); + DIMMSetVoltages(pMCTstat, pDCTstatA); /* Set the DIMM voltages (mainboard specific) */ + #endif ++ if (!IS_ENABLED(CONFIG_DIMM_VOLTAGE_SET_SUPPORT)) { ++ /* Assume 1.5V operation */ ++ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { ++ struct DCTStatStruc *pDCTstat; ++ pDCTstat = pDCTstatA + Node; ++ ++ if (!pDCTstat->NodePresent) ++ continue; ++ ++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { ++ if (pDCTstat->DIMMValid & (1 << dimm)) ++ pDCTstat->DimmConfiguredVoltage[dimm] = 0x1; ++ } ++ } ++ } + + /* If DIMM configuration has not changed since last boot restore training values */ + allow_config_restore = 1; +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch new file mode 100644 index 0000000..4e94f4f --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch @@ -0,0 +1,40 @@ +From b4b1b5269981dd559ef30efea8025e76e8c0a7ba Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:54 -0600 +Subject: [PATCH 19/45] mainboard/asus/kgpe-d16: Move memory test before IMD + setup + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/romstage.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c +index 09de4b5..20ba6f2 100644 +--- a/src/mainboard/asus/kgpe-d16/romstage.c ++++ b/src/mainboard/asus/kgpe-d16/romstage.c +@@ -541,6 +541,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + raminit_amdmct(sysinfo); + timestamp_add_now(TS_AFTER_INITRAM); + ++#ifdef TEST_MEMORY ++ execute_memory_test(); ++#endif ++ + #if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT) + if (s3resume) + cbmem_initialize(); +@@ -565,10 +569,6 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + + timestamp_add_now(TS_END_ROMSTAGE); + +-#ifdef TEST_MEMORY +- execute_memory_test(); +-#endif +- + post_cache_as_ram(); // BSP switch stack to ram, copy then execute LB. + post_code(0x43); // Should never see this post code. + } +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch new file mode 100644 index 0000000..99b8778 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch @@ -0,0 +1,31 @@ +From 4484fa77860f3595a4c0fd634bcd8648c3f12764 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:55 -0600 +Subject: [PATCH 20/45] mainboard/asus/kgpe-d16: Enable ASUS MIO audio option + +The KGPE-D16 supports an optional MIO audio card, which connects +to the on-board HDA interface of the SP5100. + +Enable the HDA interface for use with the MIO card. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/devicetree.cb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/mainboard/asus/kgpe-d16/devicetree.cb b/src/mainboard/asus/kgpe-d16/devicetree.cb +index 014a35f..96372f9 100644 +--- a/src/mainboard/asus/kgpe-d16/devicetree.cb ++++ b/src/mainboard/asus/kgpe-d16/devicetree.cb +@@ -175,7 +175,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + end + end + device pci 14.1 on end # IDE 0x439c +- device pci 14.2 off end # HDA 0x4383 (KGPE-D16 omits audio option) ++ device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card) + device pci 14.3 on # LPC 0x439d (SMBUS primary controller) + chip superio/nuvoton/nct5572d # Super I/O + device pnp 2e.0 off end # FDC; Not available on the KGPE-D16 +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch new file mode 100644 index 0000000..9926855 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch @@ -0,0 +1,74 @@ +From bd28638ec8e08636346d8fe2d276267dc0a06a1c Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:55 -0600 +Subject: [PATCH 21/45] mainboard/asus/kgpe-d16: Use stock PS/2 ACPI ASL file + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/dsdt.asl | 43 +++--------------------------------- + 1 file changed, 3 insertions(+), 40 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/dsdt.asl b/src/mainboard/asus/kgpe-d16/dsdt.asl +index 8445eb3..44b6a98 100644 +--- a/src/mainboard/asus/kgpe-d16/dsdt.asl ++++ b/src/mainboard/asus/kgpe-d16/dsdt.asl +@@ -92,8 +92,8 @@ DefinitionBlock ( + /* Keyboard controller PME# */ + Method(_L08) { + /* Level-Triggered GPE */ +- Notify(\_SB.PCI0.LPC.KBD, 0x02) /* NOTIFY_DEVICE_WAKE */ +- Notify(\_SB.PCI0.LPC.MOU, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify(\_SB.PCI0.LPC.PS2K, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify(\_SB.PCI0.LPC.PS2M, 0x02) /* NOTIFY_DEVICE_WAKE */ + Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ + } + +@@ -490,44 +490,7 @@ DefinitionBlock ( + Name (_HID, EisaId ("PNP0A05")) + Name (_ADR, 0x00140003) + +- /* PS/2 keyboard (seems to be important for WinXP install) */ +- Device (KBD) +- { +- Name (_HID, EisaId ("PNP0303")) +- Name (_CID, EisaId ("PNP030B")) +- Method (_STA, 0, NotSerialized) +- { +- Return (0x0f) +- } +- Method (_CRS, 0, Serialized) +- { +- Name (TMP, ResourceTemplate () { +- IO (Decode16, 0x0060, 0x0060, 0x01, 0x01) +- IO (Decode16, 0x0064, 0x0064, 0x01, 0x01) +- IRQNoFlags () {1} +- }) +- Return (TMP) +- } +- } +- +- /* PS/2 mouse */ +- Device (MOU) +- { +- Name (_HID, EisaId ("PNP0F03")) +- Name (_CID, EisaId ("PNP0F13")) +- Method (_STA, 0, NotSerialized) +- { +- Return (0x0f) +- } +- Method (_CRS, 0, Serialized) +- { +- Name (TMP, ResourceTemplate () { +- IRQNoFlags () {12} +- }) +- Return (TMP) +- } +- } +- ++ #include "../../../drivers/pc80/ps2_controller.asl" + + /* UART 1 */ + Device (URT1) +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch new file mode 100644 index 0000000..596cab9 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch @@ -0,0 +1,30 @@ +From c104a49921424687b0aacea660582ea3c027024a Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:56 -0600 +Subject: [PATCH 22/45] southbridge/amd/sb700: Add missing DMA setup step from + AMD RRG + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/southbridge/amd/sb700/early_setup.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/southbridge/amd/sb700/early_setup.c b/src/southbridge/amd/sb700/early_setup.c +index 06c6c77..544447e 100644 +--- a/src/southbridge/amd/sb700/early_setup.c ++++ b/src/southbridge/amd/sb700/early_setup.c +@@ -420,6 +420,11 @@ static void sb700_devices_por_init(void) + /* Legacy DMA Prefetch Enhancement, CIM masked it. */ + /* pci_write_config8(dev, 0x43, 0x1); */ + ++ /* Enable DMA verify bugfix */ ++ byte = pci_read_config8(dev, 0x67); ++ byte |= 0x1 << 1; ++ pci_write_config8(dev, 0x67, byte); ++ + /* Disabling Legacy USB Fast SMI# */ + byte = pci_read_config8(dev, 0x62); + byte |= 0x24; +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch new file mode 100644 index 0000000..1f41eaf --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch @@ -0,0 +1,53 @@ +From 01f84b46b749454f6c93c3273fac65be780a128b Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:56 -0600 +Subject: [PATCH 23/45] southbridge/amd/sb700: Add CMOS option to disable + legacy USB support + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/southbridge/amd/sb700/sm.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c +index 04f4601..942e4f8 100644 +--- a/src/southbridge/amd/sb700/sm.c ++++ b/src/southbridge/amd/sb700/sm.c +@@ -63,6 +63,7 @@ static void sm_init(device_t dev) + u32 dword; + void *ioapic_base; + uint32_t power_state; ++ uint32_t enable_legacy_usb; + u32 nmi_option; + + printk(BIOS_INFO, "sm_init().\n"); +@@ -72,10 +73,23 @@ static void sm_init(device_t dev) + ioapic_base = (void *)(pci_read_config32(dev, 0x74) & (0xffffffe0)); + setup_ioapic(ioapic_base, 0); /* Don't rename IOAPIC ID. */ + ++ enable_legacy_usb = 1; ++ get_option(&enable_legacy_usb, "enable_legacy_usb"); ++ + /* 2.10 Interrupt Routing/Filtering */ +- dword = pci_read_config8(dev, 0x62); +- dword |= 3; +- pci_write_config8(dev, 0x62, dword); ++ byte = pci_read_config8(dev, 0x62); ++ if (enable_legacy_usb) ++ byte |= 0x3; ++ else ++ byte &= ~0x3; ++ pci_write_config8(dev, 0x62, byte); ++ ++ byte = pci_read_config8(dev, 0x67); ++ if (enable_legacy_usb) ++ byte |= 0x1 << 7; ++ else ++ byte &= ~(0x1 << 7); ++ pci_write_config8(dev, 0x67, byte); + + /* Delay back to back interrupts to the CPU. */ + dword = pci_read_config16(dev, 0x64); +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch new file mode 100644 index 0000000..b4be5fa --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch @@ -0,0 +1,249 @@ +From 42a116b68ea468e32bb37aa333e53eb9c552a6c7 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:57 -0600 +Subject: [PATCH 24/45] superio/winbond/w83667hg-a: Add support for W83667HG-A + +The KGPE-D16 and KCMA-D8 use a Winbond W83667HG-A SuperIO. While +the Nuvoton NCT5572D is effectively the same core, and a close +enough match to get things working initially, the W83667HG-A +has a different LDN mapping and several extra features that +require a separate support driver. + +Clone the Nuvoton NCT5572D and modify according to the W83667HG-A +datasheet. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/superio/winbond/Kconfig | 4 + + src/superio/winbond/Makefile.inc | 1 + + src/superio/winbond/w83667hg-a/Makefile.inc | 19 +++++ + src/superio/winbond/w83667hg-a/superio.c | 109 ++++++++++++++++++++++++++++ + src/superio/winbond/w83667hg-a/w83667hg-a.h | 47 ++++++++++++ + 5 files changed, 180 insertions(+) + create mode 100644 src/superio/winbond/w83667hg-a/Makefile.inc + create mode 100644 src/superio/winbond/w83667hg-a/superio.c + create mode 100644 src/superio/winbond/w83667hg-a/w83667hg-a.h + +diff --git a/src/superio/winbond/Kconfig b/src/superio/winbond/Kconfig +index ba9f479..1731a7f 100644 +--- a/src/superio/winbond/Kconfig ++++ b/src/superio/winbond/Kconfig +@@ -39,6 +39,10 @@ config SUPERIO_WINBOND_W83627UHG + bool + select SUPERIO_WINBOND_COMMON_ROMSTAGE + ++config SUPERIO_WINBOND_W83667HG_A ++ bool ++ select SUPERIO_WINBOND_COMMON_ROMSTAGE ++ + config SUPERIO_WINBOND_W83697HF + bool + select SUPERIO_WINBOND_COMMON_ROMSTAGE +diff --git a/src/superio/winbond/Makefile.inc b/src/superio/winbond/Makefile.inc +index 67927dc..ae4b283 100644 +--- a/src/superio/winbond/Makefile.inc ++++ b/src/superio/winbond/Makefile.inc +@@ -21,6 +21,7 @@ subdirs-y += w83627ehg + subdirs-y += w83627hf + subdirs-y += w83627thg + subdirs-y += w83627uhg ++subdirs-y += w83667hg-a + subdirs-y += w83697hf + subdirs-y += w83977tf + subdirs-y += wpcd376i +diff --git a/src/superio/winbond/w83667hg-a/Makefile.inc b/src/superio/winbond/w83667hg-a/Makefile.inc +new file mode 100644 +index 0000000..7665046 +--- /dev/null ++++ b/src/superio/winbond/w83667hg-a/Makefile.inc +@@ -0,0 +1,19 @@ ++## ++## This file is part of the coreboot project. ++## ++## Copyright (C) 2011 - 2012 Advanced Micro Devices, Inc. ++## Copyright (C) 2014 Felix Held <felix-coreboot@felixheld.de> ++## Copyright (C) 2015 Raptor Engineering ++## ++## This program is free software; you can redistribute it and/or modify ++## it under the terms of the GNU General Public License as published by ++## the Free Software Foundation; either version 2 of the License, or ++## (at your option) any later version. ++## ++## This program is distributed in the hope that it will be useful, ++## but WITHOUT ANY WARRANTY; without even the implied warranty of ++## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++## GNU General Public License for more details. ++## ++ ++ramstage-$(CONFIG_SUPERIO_WINBOND_W83667HG_A) += superio.c +diff --git a/src/superio/winbond/w83667hg-a/superio.c b/src/superio/winbond/w83667hg-a/superio.c +new file mode 100644 +index 0000000..b539871 +--- /dev/null ++++ b/src/superio/winbond/w83667hg-a/superio.c +@@ -0,0 +1,109 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2014 Felix Held <felix-coreboot@felixheld.de> ++ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan@alterapraxis.com> ++ * Copyright (C) 2015 Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <arch/io.h> ++#include <device/device.h> ++#include <device/pnp.h> ++#include <pc80/keyboard.h> ++#include <pc80/mc146818rtc.h> ++#include <stdlib.h> ++#include <superio/conf_mode.h> ++ ++#include "w83667hg-a.h" ++ ++#define MAINBOARD_POWER_OFF 0 ++#define MAINBOARD_POWER_ON 1 ++ ++#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL ++#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON ++#endif ++ ++static void w83667hg_a_init(struct device *dev) ++{ ++ uint8_t byte; ++ uint8_t power_status; ++ ++ if (!dev->enabled) ++ return; ++ ++ switch(dev->path.pnp.device) { ++ /* TODO: Might potentially need code for HWM or FDC etc. */ ++ case W83667HG_A_KBC: ++ pc_keyboard_init(); ++ break; ++ case W83667HG_A_ACPI: ++ /* Set power state after power fail */ ++ power_status = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; ++ get_option(&power_status, "power_on_after_fail"); ++ pnp_enter_conf_mode_8787(dev); ++ pnp_set_logical_device(dev); ++ byte = pnp_read_config(dev, 0xe4); ++ byte &= ~0x60; ++ if (power_status == 1) ++ byte |= (0x1 << 5); /* Force power on */ ++ else if (power_status == 2) ++ byte |= (0x2 << 5); /* Use last power state */ ++ pnp_write_config(dev, 0xe4, byte); ++ pnp_exit_conf_mode_aa(dev); ++ printk(BIOS_INFO, "set power %s after power fail\n", power_status ? "on" : "off"); ++ break; ++ } ++} ++ ++static struct device_operations ops = { ++ .read_resources = pnp_read_resources, ++ .set_resources = pnp_set_resources, ++ .enable_resources = pnp_enable_resources, ++ .enable = pnp_alt_enable, ++ .init = w83667hg_a_init, ++ .ops_pnp_mode = &pnp_conf_mode_8787_aa, ++}; ++ ++static struct pnp_info pnp_dev_info[] = { ++ { &ops, W83667HG_A_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x0ff8, 0}, }, ++ { &ops, W83667HG_A_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x0ff8, 0}, }, ++ { &ops, W83667HG_A_SP1, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, }, ++ { &ops, W83667HG_A_SP2, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, }, ++ { &ops, W83667HG_A_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, {0x0fff, 0}, {0x0fff, 4}, }, ++ { &ops, W83667HG_A_SPI}, ++ { &ops, W83667HG_A_WDT1}, ++ { &ops, W83667HG_A_ACPI}, ++ { &ops, W83667HG_A_HWM_TSI, PNP_IO0 | PNP_IO1 | PNP_IRQ0, {0x0ffe, 0}, {0x0ffe, 4}, }, ++ { &ops, W83667HG_A_PECI}, ++ { &ops, W83667HG_A_VID_BUSSEL}, ++ { &ops, W83667HG_A_GPIO_PP_OD}, ++ { &ops, W83667HG_A_GPIO2}, ++ { &ops, W83667HG_A_GPIO3}, ++ { &ops, W83667HG_A_GPIO4}, ++ { &ops, W83667HG_A_GPIO5}, ++ { &ops, W83667HG_A_GPIO6}, ++ { &ops, W83667HG_A_GPIO7}, ++ { &ops, W83667HG_A_GPIO8}, ++ { &ops, W83667HG_A_GPIO9}, ++}; ++ ++static void enable_dev(struct device *dev) ++{ ++ pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); ++} ++ ++struct chip_operations superio_winbond_w83667hg_a_ops = { ++ CHIP_NAME("WINBOND W83667HG-A Super I/O") ++ .enable_dev = enable_dev, ++}; +diff --git a/src/superio/winbond/w83667hg-a/w83667hg-a.h b/src/superio/winbond/w83667hg-a/w83667hg-a.h +new file mode 100644 +index 0000000..efb77b8 +--- /dev/null ++++ b/src/superio/winbond/w83667hg-a/w83667hg-a.h +@@ -0,0 +1,47 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2014 Felix Held <felix-coreboot@felixheld.de> ++ * Copyright (C) 2015 Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef SUPERIO_WINBOND_W83667HG_A ++#define SUPERIO_WINBOND_W83667HG_A ++ ++/* Logical Device Numbers (LDN). */ ++#define W83667HG_A_FDC 0x00 ++#define W83667HG_A_PP 0x01 ++#define W83667HG_A_SP1 0x02 /* Com1 */ ++#define W83667HG_A_SP2 0x03 /* Com2 */ ++#define W83667HG_A_KBC 0x05 ++#define W83667HG_A_SPI 0x06 ++#define W83667HG_A_GPIO6789_V 0x07 ++#define W83667HG_A_WDT1 0x08 ++#define W83667HG_A_GPIO2345_V 0x09 ++#define W83667HG_A_ACPI 0x0A ++#define W83667HG_A_HWM_TSI 0x0B /* HW monitor/SB-TSI/deep S5 */ ++#define W83667HG_A_PECI 0x0C ++#define W83667HG_A_VID_BUSSEL 0x0D /* VID and BUSSEL */ ++#define W83667HG_A_GPIO_PP_OD 0x0F /* GPIO Push-Pull/Open drain select */ ++ ++/* virtual LDN for GPIO */ ++#define W83667HG_A_GPIO2 ((0 << 8) | W83667HG_A_GPIO2345_V) ++#define W83667HG_A_GPIO3 ((1 << 8) | W83667HG_A_GPIO2345_V) ++#define W83667HG_A_GPIO4 ((2 << 8) | W83667HG_A_GPIO2345_V) ++#define W83667HG_A_GPIO5 ((3 << 8) | W83667HG_A_GPIO2345_V) ++#define W83667HG_A_GPIO6 ((1 << 8) | W83667HG_A_GPIO6789_V) ++#define W83667HG_A_GPIO7 ((2 << 8) | W83667HG_A_GPIO6789_V) ++#define W83667HG_A_GPIO8 ((3 << 8) | W83667HG_A_GPIO6789_V) ++#define W83667HG_A_GPIO9 ((4 << 8) | W83667HG_A_GPIO6789_V) ++ ++#endif /* SUPERIO_WINBOND_W83667HG_A */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch new file mode 100644 index 0000000..ea534fa --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch @@ -0,0 +1,109 @@ +From 35727a48c8a48f0cc1bbf8c95dd9d0d3fdafa6d9 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:57 -0600 +Subject: [PATCH 25/45] mainboard/asus/kgpe-d16: Use W83667HG-A SuperIO instead + of NCT5572D + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/Kconfig | 2 +- + src/mainboard/asus/kgpe-d16/devicetree.cb | 16 +++++++++------- + src/mainboard/asus/kgpe-d16/romstage.c | 8 ++++---- + 3 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig +index f394ca9..23c91f0 100644 +--- a/src/mainboard/asus/kgpe-d16/Kconfig ++++ b/src/mainboard/asus/kgpe-d16/Kconfig +@@ -12,7 +12,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy + select SOUTHBRIDGE_AMD_SB700 + select SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA + select SOUTHBRIDGE_AMD_SUBTYPE_SP5100 +- select SUPERIO_NUVOTON_NCT5572D ++ select SUPERIO_WINBOND_W83667HG_A + select PARALLEL_CPU_INIT + select HAVE_ROMSTAGE_CONSOLE_SPINLOCK + select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK +diff --git a/src/mainboard/asus/kgpe-d16/devicetree.cb b/src/mainboard/asus/kgpe-d16/devicetree.cb +index 96372f9..8d64ac7 100644 +--- a/src/mainboard/asus/kgpe-d16/devicetree.cb ++++ b/src/mainboard/asus/kgpe-d16/devicetree.cb +@@ -177,24 +177,27 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + device pci 14.1 on end # IDE 0x439c + device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card) + device pci 14.3 on # LPC 0x439d (SMBUS primary controller) +- chip superio/nuvoton/nct5572d # Super I/O ++ chip superio/winbond/w83667hg-a # Super I/O + device pnp 2e.0 off end # FDC; Not available on the KGPE-D16 + device pnp 2e.1 off end # LPT1; Not available on the KGPE-D16 + device pnp 2e.2 on # Com1 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end +- device pnp 2e.3 off end # IR: Not available on the KGPE-D16 ++ device pnp 2e.3 on # Com2 ++ io 0x60 = 0x2f8 ++ irq 0x70 = 3 ++ end + device pnp 2e.5 on # PS/2 keyboard & mouse + io 0x60 = 0x60 + io 0x62 = 0x64 + irq 0x70 = 1 + irq 0x72 = 12 + end +- device pnp 2e.6 off end # CIR: Not available on the KGPE-D16 +- device pnp 2e.7 off end # GIPO689 ++ device pnp 2e.6 off end # SPI: Not available on the KGPE-D16 ++ device pnp 2e.7 off end # GIPO6789 + device pnp 2e.8 off end # WDT +- device pnp 2e.9 off end # GPIO235 ++ device pnp 2e.9 off end # GPIO2345 + device pnp 2e.a on end # ACPI + device pnp 2e.b on # HW Monitor + io 0x60 = 0x290 +@@ -202,8 +205,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + irq 0x70 = 5 + end + device pnp 2e.c off end # PECI +- device pnp 2e.d off end # SUSLED +- device pnp 2e.e off end # CIRWKUP ++ device pnp 2e.d off end # VID_BUSSEL + device pnp 2e.f off end # GPIO_PP_OD + end + end +diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c +index 20ba6f2..6fb7668 100644 +--- a/src/mainboard/asus/kgpe-d16/romstage.c ++++ b/src/mainboard/asus/kgpe-d16/romstage.c +@@ -35,8 +35,8 @@ + #include "lib/delay.c" + #include <cpu/x86/lapic.h> + #include "northbridge/amd/amdfam10/reset_test.c" +-#include <superio/nuvoton/common/nuvoton.h> +-#include <superio/nuvoton/nct5572d/nct5572d.h> ++#include <superio/winbond/common/winbond.h> ++#include <superio/winbond/w83667hg-a/w83667hg-a.h> + #include <cpu/x86/bist.h> + #include <smp/spinlock.h> + // #include "northbridge/amd/amdk8/incoherent_ht.c" +@@ -46,7 +46,7 @@ + #include "northbridge/amd/amdfam10/debug.c" + #include "northbridge/amd/amdfam10/setup_resource_map.c" + +-#define SERIAL_DEV PNP_DEV(0x2e, NCT5572D_SP1) ++#define SERIAL_DEV PNP_DEV(0x2e, W83667HG_A_SP1) + + static void activate_spd_rom(const struct mem_controller *ctrl); + +@@ -393,7 +393,7 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + sb7xx_51xx_pci_port80(); + + /* Initialize early serial */ +- nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); ++ winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); + console_init(); + + /* Disable LPC legacy DMA support to prevent lockup */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch new file mode 100644 index 0000000..7e878bc --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch @@ -0,0 +1,59 @@ +From 5da709f633ca379d6f0689f99f3f2cc01110f673 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:58 -0600 +Subject: [PATCH 26/45] cpu/amd/fam10h-15h: Fix Family 15h boot hang when BSP + lift enabled + +The existing code did not allow for the second core of the BSP to +reside on an APIC ID other than 1, leading to a boot hang on Family +15h processors when APIC_ID_OFFSET was set to anything other than 0. +Furthermore, insufficient AP stack space was allocated for AP start. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/Kconfig | 2 +- + src/cpu/amd/family_10h-family_15h/init_cpus.c | 8 +++++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/cpu/amd/family_10h-family_15h/Kconfig b/src/cpu/amd/family_10h-family_15h/Kconfig +index bfb6751..2f3dfc0 100644 +--- a/src/cpu/amd/family_10h-family_15h/Kconfig ++++ b/src/cpu/amd/family_10h-family_15h/Kconfig +@@ -48,7 +48,7 @@ config DCACHE_BSP_STACK_SLUSH + + config DCACHE_AP_STACK_SIZE + hex +- default 0x400 ++ default 0x500 + + config UDELAY_IO + bool +diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c +index 5a67601..e8e81d2 100644 +--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c ++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c +@@ -356,6 +356,7 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo) + uint32_t dword; + uint8_t set_mtrrs; + uint8_t node_count; ++ uint8_t fam15_bsp_core1_apicid; + struct node_core_id id; + + /* Please refer to the calculations and explaination in cache_as_ram.inc before modifying these values */ +@@ -483,7 +484,12 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo) + if (is_fam15h()) { + /* core 1 on node 0 is special; to avoid corrupting the + * BSP do not alter MTRRs on that core */ +- if (apicid == 1) ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ fam15_bsp_core1_apicid = CONFIG_APIC_ID_OFFSET + 1; ++ else ++ fam15_bsp_core1_apicid = 1; ++ ++ if (apicid == fam15_bsp_core1_apicid) + set_mtrrs = 0; + else + set_mtrrs = !!(apicid & 0x1); +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch new file mode 100644 index 0000000..65aada7 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch @@ -0,0 +1,27 @@ +From 6c4fb7d4b666ae94c8421e4dd363674294f3f7ca Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:58 -0600 +Subject: [PATCH 27/45] southbridge/amd/sb700: Set HPET min tick value to RPR + recommendation + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/southbridge/amd/sb700/Kconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/southbridge/amd/sb700/Kconfig b/src/southbridge/amd/sb700/Kconfig +index 9a0ddb2..9a988a9 100644 +--- a/src/southbridge/amd/sb700/Kconfig ++++ b/src/southbridge/amd/sb700/Kconfig +@@ -50,4 +50,8 @@ config EHCI_BAR + hex + default 0xfef00000 + ++config HPET_MIN_TICKS ++ hex ++ default 0x14 ++ + endif # SOUTHBRIDGE_AMD_SB700 +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch new file mode 100644 index 0000000..0cb57ba --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch @@ -0,0 +1,32 @@ +From 6badc1a8783f8916d9f66026bef02781f6397dec Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:58 -0600 +Subject: [PATCH 28/45] southbridge/amd/sb700: Enable extended APIC ID when + Kconfig option set + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/southbridge/amd/sb700/sm.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c +index 942e4f8..0d017aa 100644 +--- a/src/southbridge/amd/sb700/sm.c ++++ b/src/southbridge/amd/sb700/sm.c +@@ -298,9 +298,11 @@ static void sm_init(device_t dev) + byte |= 1 << 3; + pci_write_config8(dev, 0x43, byte); + } +- //ACPI_DISABLE_TIMER_IRQ_ENHANCEMENT_FOR_8254_TIMER + byte = pci_read_config8(dev, 0xAE); +- byte |= 1 << 5; ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID)) ++ byte |= 1 << 4; ++ byte |= 1 << 5; /* ACPI_DISABLE_TIMER_IRQ_ENHANCEMENT_FOR_8254_TIMER */ ++ byte |= 1 << 6; /* Enable arbiter between APIC and PIC interrupts */ + pci_write_config8(dev, 0xAE, byte); + + /* 4.11:Programming Cycle Delay for AB and BIF Clock Gating */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch new file mode 100644 index 0000000..8b010e5 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch @@ -0,0 +1,185 @@ +From 61d7b1545c10558590ed2ac98a427318b909affc Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:59 -0600 +Subject: [PATCH 29/45] mainboard/asus/kgpe-d16: Update DSDT with new devices + and bump version + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/dsdt.asl | 123 ++++++++++++++++++++++++++--------- + 1 file changed, 94 insertions(+), 29 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/dsdt.asl b/src/mainboard/asus/kgpe-d16/dsdt.asl +index 44b6a98..702ace1 100644 +--- a/src/mainboard/asus/kgpe-d16/dsdt.asl ++++ b/src/mainboard/asus/kgpe-d16/dsdt.asl +@@ -33,7 +33,7 @@ + DefinitionBlock ( + "DSDT.AML", /* Output filename */ + "DSDT", /* Signature */ +- 0x02, /* DSDT Revision, needs to be 2 for 64bit */ ++ 0x03, /* DSDT Revision, needs to be 2 or higher for 64bit */ + "ASUS ", /* OEMID */ + "COREBOOT", /* TABLE ID */ + 0x00000001 /* OEM Revision */ +@@ -47,9 +47,8 @@ DefinitionBlock ( + Name(OSV, Ones) /* Assume nothing */ + Name(PICM, One) /* Assume APIC */ + +- /* HPET control */ +- Name (SHPB, 0xFED00000) +- Name (SHPL, 0x1000) ++ /* HPET enable */ ++ Name (HPTE, 0x1) + + /* Define power states */ + Name (\_S0, Package () { 0x00, 0x00, 0x00, 0x00 }) /* Normal operation */ +@@ -126,12 +125,13 @@ DefinitionBlock ( + /* Root of the bus hierarchy */ + Scope (\_SB) + { +- /* Top southbridge PCI device (SR5690) */ ++ /* Top southbridge PCI device (SR5690 + SP5100) */ + Device (PCI0) + { + /* BUS0 root bus */ + +- Name (_HID, EisaId ("PNP0A03")) ++ Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5690) */ ++ Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */ + Name (_ADR, 0x00180001) + Name (_UID, 0x00) + +@@ -490,6 +490,78 @@ DefinitionBlock ( + Name (_HID, EisaId ("PNP0A05")) + Name (_ADR, 0x00140003) + ++ /* Real Time Clock Device */ ++ Device(RTC0) { ++ Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */ ++ Name(BUF0, ResourceTemplate() { ++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02) ++ }) ++ Name(BUF1, ResourceTemplate() { ++ IRQNoFlags() { 8 } ++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02) ++ }) ++ Method(_CRS, 0) { ++ If(HPTE) { ++ Return(BUF0) ++ } ++ Return(BUF1) ++ } ++ } ++ ++ Device(TMR) { /* Timer */ ++ Name(_HID,EISAID("PNP0100")) /* System Timer */ ++ Name(BUF0, ResourceTemplate() { ++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04) ++ }) ++ Name(BUF1, ResourceTemplate() { ++ IRQNoFlags() { 0 } ++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04) ++ }) ++ Method(_CRS, 0) { ++ If(HPTE) { ++ Return(BUF0) ++ } ++ Return(BUF1) ++ } ++ } ++ ++ Device(SPKR) { /* Speaker */ ++ Name(_HID,EISAID("PNP0800")) /* AT style speaker */ ++ Name(_CRS, ResourceTemplate() { ++ IO(Decode16, 0x0061, 0x0061, 0, 1) ++ }) ++ } ++ ++ Device(PIC) { ++ Name(_HID,EISAID("PNP0000")) /* AT Interrupt Controller */ ++ Name(_CRS, ResourceTemplate() { ++ IRQNoFlags() { 2 } ++ IO(Decode16,0x0020, 0x0020, 0, 2) ++ IO(Decode16,0x00A0, 0x00A0, 0, 2) ++ }) ++ } ++ ++ Device(MAD) { /* 8257 DMA */ ++ Name(_HID,EISAID("PNP0200")) /* Hardware Device ID */ ++ Name(_CRS, ResourceTemplate() { ++ DMA(Compatibility,BusMaster,Transfer8){4} ++ IO(Decode16, 0x0000, 0x0000, 0x10, 0x10) ++ IO(Decode16, 0x0081, 0x0081, 0x01, 0x03) ++ IO(Decode16, 0x0087, 0x0087, 0x01, 0x01) ++ IO(Decode16, 0x0089, 0x0089, 0x01, 0x03) ++ IO(Decode16, 0x008F, 0x008F, 0x01, 0x01) ++ IO(Decode16, 0x00C0, 0x00C0, 0x10, 0x20) ++ }) /* End Name(_SB.PCI0.LpcIsaBr.MAD._CRS) */ ++ } ++ ++ Device(COPR) { ++ Name(_HID,EISAID("PNP0C04")) /* Math Coprocessor */ ++ Name(_CRS, ResourceTemplate() { ++ IO(Decode16, 0x00F0, 0x00F0, 0, 0x10) ++ IRQNoFlags(){13} ++ }) ++ } ++ + #include "../../../drivers/pc80/ps2_controller.asl" + + /* UART 1 */ +@@ -515,34 +587,27 @@ DefinitionBlock ( + }) + } + } ++ } + +- /* High Precision Event Timer */ +- Device (HPET) ++ /* High Precision Event Timer */ ++ Device (HPET) ++ { ++ Name (_HID, EisaId ("PNP0103")) ++ Name (CRS, ResourceTemplate () + { +- Name (_HID, EisaId ("PNP0103")) +- Name (CRS, ResourceTemplate () +- { +- Memory32Fixed (ReadOnly, +- 0x00000000, +- 0x00001000, +- _Y02) +- IRQNoFlags () {0} +- IRQNoFlags () {8} +- }) +- Method (_STA, 0, NotSerialized) +- { ++ Memory32Fixed(ReadOnly, 0xFED00000, 0x00000400) ++ }) ++ Method (_STA, 0) ++ { ++ If(HPTE) { + Return (0x0F) + } +- Method (_CRS, 0, NotSerialized) +- { +- CreateDWordField (CRS, \_SB.PCI0.LPC.HPET._Y02._BAS, HPT1) +- CreateDWordField (CRS, \_SB.PCI0.LPC.HPET._Y02._LEN, HPT2) +- Store (SHPB, HPT1) +- Store (SHPL, HPT2) +- Return (CRS) +- } +- ++ Return (0x0) + } ++ Method(_CRS, 0) ++ { ++ Return(CRS) ++ } + } + + /* 0:14.4 PCI Bridge */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch new file mode 100644 index 0000000..3d13fd4 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch @@ -0,0 +1,92 @@ +From 2f6df3b764bf4090a79a4bae7c4c7e7281568cf3 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:11:59 -0600 +Subject: [PATCH 30/45] mainboard/asus/kgpe-d16: Clean up legacy PIRQ table + code + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/irq_tables.c | 31 +++++++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/irq_tables.c b/src/mainboard/asus/kgpe-d16/irq_tables.c +index 029dea8..ef39db2 100644 +--- a/src/mainboard/asus/kgpe-d16/irq_tables.c ++++ b/src/mainboard/asus/kgpe-d16/irq_tables.c +@@ -2,7 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. +- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2015 Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -23,6 +23,24 @@ + + #include <cpu/amd/amdfam10_sysconf.h> + ++/* Free irqs are 3, 4, 5, 6, 7, 9, 10, 11, 12, 14, and 15 */ ++#define IRQBM ((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<14)|(1<<15)) ++ ++#define LNKA 1 ++#define LNKB 2 ++#define LNKC 3 ++#define LNKD 4 ++ ++/* ++ * For simplicity map LNK[E-H] to LNK[A-D]. ++ * This also means we are 82C596 compatible. ++ * Needs 0:11.0 0x46[4] set to 0. ++ */ ++#define LNKE 1 ++#define LNKF 2 ++#define LNKG 3 ++#define LNKH 4 ++ + static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn, + u8 link0, u16 bitmap0, u8 link1, u16 bitmap1, + u8 link2, u16 bitmap2, u8 link3, u16 bitmap3, +@@ -42,9 +60,10 @@ static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn, + pirq_info->rfu = rfu; + } + extern u8 bus_isa; +-extern u8 bus_rs780[8]; ++extern u8 bus_sr5650[14]; + extern u8 bus_sp5100[2]; +-extern unsigned long sbdn_sp5100; ++extern u32 sbdn_sp5100; ++extern u32 sbdn_sr5650; + + unsigned long write_pirq_routing_table(unsigned long addr) + { +@@ -71,6 +90,7 @@ unsigned long write_pirq_routing_table(unsigned long addr) + pirq->signature = PIRQ_SIGNATURE; + pirq->version = PIRQ_VERSION; + ++ /* Where the interrupt router resides */ + pirq->rtr_bus = bus_sp5100[0]; + pirq->rtr_devfn = PCI_DEVFN(0x14, 4); + +@@ -88,8 +108,7 @@ unsigned long write_pirq_routing_table(unsigned long addr) + + /* pci bridge */ + write_pirq_info(pirq_info, bus_sp5100[0], ((sbdn_sp5100 + 0x14) << 3) | 4, +- 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, +- 0); ++ LNKA, IRQBM, LNKB, IRQBM, LNKC, IRQBM, LNKD, IRQBM, 0, 0); + pirq_info++; + slot_num++; + +@@ -103,7 +122,7 @@ unsigned long write_pirq_routing_table(unsigned long addr) + pirq->checksum = sum; + } + +- printk(BIOS_INFO, "write_pirq_routing_table done.\n"); ++ printk(BIOS_INFO, "done.\n"); + + return (unsigned long)pirq_info; + } +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch new file mode 100644 index 0000000..5bbee0d --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch @@ -0,0 +1,65 @@ +From ccb95f573b5549fa686abbd818bfab5fadfad241 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:00 -0600 +Subject: [PATCH 31/45] mainboard/asus/kgpe-d16: Add missing IRQ route to + mptable + +The IOMMU/HT device was not routed correctly; add the proper APIC +mappting to the mptable generation code. Also clarify comments +surrounding the pin mappings. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/mptable.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/mptable.c b/src/mainboard/asus/kgpe-d16/mptable.c +index a6ed5c9..c869d31 100644 +--- a/src/mainboard/asus/kgpe-d16/mptable.c ++++ b/src/mainboard/asus/kgpe-d16/mptable.c +@@ -2,7 +2,7 @@ + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. +- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2015 Raptor Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -47,7 +47,10 @@ static void *smp_write_config_table(void *v) + + get_bus_conf(); + +- apicid_sp5100 = 0x20; ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ apicid_sp5100 = 0x0; ++ else ++ apicid_sp5100 = 0x20; + apicid_sr5650 = apicid_sp5100 + 1; + + mptable_write_buses(mc, NULL, &bus_isa); +@@ -122,13 +125,14 @@ static void *smp_write_config_table(void *v) + mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0); + + /* SR5650 devices */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((0)<<2)|(2)), apicid_sr5650, 31); /* Device 0 Function 2 (LNKA, APIC pin 31) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE, APIC pin 28) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF, APIC pin 28) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG, APIC pin 29) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */ + + dev = dev_find_slot(0, PCI_DEVFN(0x2, 0)); + if (dev && dev->enabled) { +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch new file mode 100644 index 0000000..a02f8e2 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch @@ -0,0 +1,60 @@ +From 8a89ad28a33052b3bd27faab8e0f90babd2f3599 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:01 -0600 +Subject: [PATCH 32/45] mainboard/asus/kgpe-d16: Add support for lifted BSP + APIC IDs + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/acpi_tables.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/acpi_tables.c b/src/mainboard/asus/kgpe-d16/acpi_tables.c +index 24c1724..f20e837 100644 +--- a/src/mainboard/asus/kgpe-d16/acpi_tables.c ++++ b/src/mainboard/asus/kgpe-d16/acpi_tables.c +@@ -36,7 +36,10 @@ unsigned long acpi_fill_madt(unsigned long current) + /* create all subtables for processors */ + current = acpi_create_madt_lapics(current); + +- apicid_sp5100 = 0x20; ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ apicid_sp5100 = 0x0; ++ else ++ apicid_sp5100 = 0x20; + apicid_sr5650 = apicid_sp5100 + 1; + + /* Write SB700 IOAPIC, only one */ +@@ -56,15 +59,10 @@ unsigned long acpi_fill_madt(unsigned long current) + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, 0); + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) +- current, 0, 9, 9, 0xF); +- /* 0: mean bus 0--->ISA */ +- /* 0: PIC 0 */ +- /* 2: APIC 2 */ +- /* 5 mean: 0101 --> Edge-triggered, Active high */ ++ current, 0, 9, 9, 0xf); + + /* create all subtables for processors */ +- current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0, 5, 1); +- current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 1, 5, 1); ++ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0xff, 0, 1); + /* 1: LINT1 connect to NMI */ + + return current; +@@ -77,7 +75,10 @@ unsigned long acpi_fill_ivrs_ioapic(acpi_ivrs_t* ivrs, unsigned long current) + uint32_t apicid_sp5100; + uint32_t apicid_sr5650; + +- apicid_sp5100 = 0x20; ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ apicid_sp5100 = 0x0; ++ else ++ apicid_sp5100 = 0x20; + apicid_sr5650 = apicid_sp5100 + 1; + + /* Describe NB IOAPIC */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch new file mode 100644 index 0000000..1753b05 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch @@ -0,0 +1,1160 @@ +From 5bb8df0244b9839365e292bc60c344074f17f5a4 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:01 -0600 +Subject: [PATCH 33/45] drivers/pc80: Add PS/2 mouse presence detect + +On certain Winbond SuperIO devices, when a PS/2 mouse is not +present on the auxiliary channel both channels will cease to +function if the auxiliary channel is probed while the primary +channel is active. Therefore, knowledge of mouse presence +must be gathered by coreboot during early boot, and used to +enable or disable the auxiliary PS/2 port before control is +passed to the operating system. + +Add auxiliary channel PS/2 device presence detect, and update +the Winbond W83667HG-A driver to flag the auxiliary channel as +disabled if no device was detected. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/drivers/pc80/keyboard.c | 101 +++++++++++++++++----- + src/ec/compal/ene932/ec.c | 2 +- + src/ec/google/chromeec/ec_lpc.c | 2 +- + src/ec/lenovo/h8/h8.c | 2 +- + src/ec/quanta/ene_kb3940q/ec.c | 2 +- + src/ec/quanta/it8518/ec.c | 2 +- + src/include/pc80/keyboard.h | 2 +- + src/mainboard/emulation/qemu-i440fx/mainboard.c | 2 +- + src/mainboard/emulation/qemu-q35/mainboard.c | 2 +- + src/mainboard/packardbell/ms2290/mainboard.c | 2 +- + src/mainboard/roda/rk9/mainboard.c | 2 +- + src/northbridge/via/cx700/lpc.c | 2 +- + src/northbridge/via/vx800/lpc.c | 2 +- + src/southbridge/dmp/vortex86ex/southbridge.c | 2 +- + src/southbridge/sis/sis966/lpc.c | 2 +- + src/southbridge/via/vt8237r/lpc.c | 2 +- + src/superio/fintek/f71863fg/superio.c | 2 +- + src/superio/fintek/f71869ad/superio.c | 2 +- + src/superio/fintek/f71872/superio.c | 2 +- + src/superio/fintek/f81865f/superio.c | 2 +- + src/superio/fintek/f81866d/superio.c | 2 +- + src/superio/ite/it8671f/superio.c | 2 +- + src/superio/ite/it8712f/superio.c | 2 +- + src/superio/ite/it8716f/superio.c | 2 +- + src/superio/ite/it8718f/superio.c | 2 +- + src/superio/ite/it8721f/superio.c | 2 +- + src/superio/ite/it8728f/superio.c | 2 +- + src/superio/ite/it8772f/superio.c | 2 +- + src/superio/nsc/pc87309/superio.c | 2 +- + src/superio/nsc/pc87360/superio.c | 2 +- + src/superio/nsc/pc87366/superio.c | 2 +- + src/superio/nsc/pc87417/superio.c | 2 +- + src/superio/nsc/pc97317/superio.c | 2 +- + src/superio/nuvoton/nct5572d/superio.c | 2 +- + src/superio/nuvoton/nct6779d/superio.c | 2 +- + src/superio/nuvoton/wpcm450/superio.c | 2 +- + src/superio/renesas/m3885x/superio.c | 2 +- + src/superio/smsc/dme1737/superio.c | 2 +- + src/superio/smsc/fdc37n972/fdc37n972.c | 2 +- + src/superio/smsc/kbc1100/superio.c | 2 +- + src/superio/smsc/lpc47b272/superio.c | 2 +- + src/superio/smsc/lpc47b397/superio.c | 2 +- + src/superio/smsc/lpc47m10x/superio.c | 2 +- + src/superio/smsc/lpc47m15x/superio.c | 2 +- + src/superio/smsc/lpc47n227/superio.c | 2 +- + src/superio/smsc/mec1308/superio.c | 2 +- + src/superio/smsc/sch4037/superio.c | 2 +- + src/superio/smsc/sio10n268/sio10n268.c | 2 +- + src/superio/smsc/smscsuperio/superio.c | 2 +- + src/superio/winbond/w83627dhg/superio.c | 2 +- + src/superio/winbond/w83627ehg/superio.c | 2 +- + src/superio/winbond/w83627hf/superio.c | 2 +- + src/superio/winbond/w83627thg/superio.c | 2 +- + src/superio/winbond/w83627uhg/superio.c | 2 +- + src/superio/winbond/w83667hg-a/ps2_controller.asl | 78 +++++++++++++++++ + src/superio/winbond/w83667hg-a/superio.c | 20 ++++- + src/superio/winbond/w83977tf/superio.c | 2 +- + src/superio/winbond/wpcd376i/superio.c | 2 +- + 58 files changed, 230 insertions(+), 79 deletions(-) + create mode 100644 src/superio/winbond/w83667hg-a/ps2_controller.asl + +diff --git a/src/drivers/pc80/keyboard.c b/src/drivers/pc80/keyboard.c +index 3e61a51..56b1fce 100644 +--- a/src/drivers/pc80/keyboard.c ++++ b/src/drivers/pc80/keyboard.c +@@ -1,6 +1,7 @@ + /* + * This file is part of the coreboot project. + * ++ * Copyright (C) 2015 Raptor Engineering + * Copyright (C) 2009 coresystems GmbH + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2003 Ollie Lo <ollielo@hotmail.com> +@@ -32,6 +33,8 @@ + // Keyboard Controller Commands + #define KBC_CMD_READ_COMMAND 0x20 // Read command byte + #define KBC_CMD_WRITE_COMMAND 0x60 // Write command byte ++#define KBC_CMD_AUX_ENABLE 0xA8 // Auxiliary Interface enable ++#define KBC_CMD_AUX_TEST 0xA9 // Auxiliary Interface test + #define KBC_CMD_SELF_TEST 0xAA // Controller self-test + #define KBC_CMD_KBD_TEST 0xAB // Keyboard Interface test + +@@ -106,9 +109,14 @@ static int kbc_cleanup_buffers(void) + return !!timeout; + } + +-static enum cb_err kbc_self_test(void) ++static enum cb_err kbc_self_test(uint8_t probe_aux, uint8_t *aux_probe_result) + { +- u8 self_test; ++ uint8_t self_test; ++ uint8_t byte; ++ ++ /* Set initial aux probe output value */ ++ if (aux_probe_result) ++ *aux_probe_result = 0; + + /* Clean up any junk that might have been in the KBC. + * Both input and output buffers must be empty. +@@ -154,6 +162,48 @@ static enum cb_err kbc_self_test(void) + return CB_KBD_INTERFACE_FAILURE; + } + ++ if (probe_aux) { ++ /* aux interface detect */ ++ outb(KBC_CMD_AUX_ENABLE, KBD_COMMAND); ++ if (!kbc_input_buffer_empty()) { ++ printk(BIOS_ERR, "Timeout waiting for controller during aux enable.\n"); ++ return CB_KBD_CONTROLLER_FAILURE; ++ } ++ outb(KBC_CMD_READ_COMMAND, KBD_COMMAND); ++ if (!kbc_output_buffer_full()) { ++ printk(BIOS_ERR, "Timeout waiting for controller during aux probe.\n"); ++ return CB_KBD_CONTROLLER_FAILURE; ++ } ++ ++ byte = inb(KBD_DATA); ++ if (!(byte & (0x1 << 5))) { ++ printk(BIOS_DEBUG, "PS/2 auxiliary channel detected...\n"); ++ ++ /* auxiliary interface test */ ++ outb(KBC_CMD_AUX_TEST, KBD_COMMAND); ++ ++ if (!kbc_output_buffer_full()) { ++ printk(BIOS_ERR, "Auxiliary channel probe timed out.\n"); ++ goto aux_failure; ++ } ++ ++ /* read test result, 0x00 should be returned in case of no failures */ ++ self_test = inb(KBD_DATA); ++ ++ if (self_test != 0x00) { ++ printk(BIOS_ERR, "No device detected on auxiliary channel: 0x%x\n", ++ self_test); ++ goto aux_failure; ++ } ++ ++ printk(BIOS_DEBUG, "PS/2 device detected on auxiliary channel\n"); ++ if (aux_probe_result) ++ *aux_probe_result = 1; ++ } ++ } ++ ++aux_failure: ++ + return CB_SUCCESS; + } + +@@ -187,53 +237,54 @@ static u8 send_keyboard(u8 command) + return regval; + } + +-void pc_keyboard_init(void) ++uint8_t pc_keyboard_init(uint8_t probe_aux) + { + u8 retries; + u8 regval; + enum cb_err err; ++ uint8_t aux_dev_detected; + + if (!CONFIG_DRIVERS_PS2_KEYBOARD) +- return; ++ return 0; + + if (acpi_is_wakeup_s3()) +- return; ++ return 0; + + printk(BIOS_DEBUG, "Keyboard init...\n"); + + /* Run a keyboard controller self-test */ +- err = kbc_self_test(); ++ err = kbc_self_test(probe_aux, &aux_dev_detected); + /* Ignore iterface failure as it's non-fatal. */ + if (err != CB_SUCCESS && err != CB_KBD_INTERFACE_FAILURE) +- return; ++ return 0; + + /* Enable keyboard interface - No IRQ */ + if (!kbc_input_buffer_empty()) +- return; ++ return 0; + outb(0x60, KBD_COMMAND); + if (!kbc_input_buffer_empty()) +- return; ++ return 0; + outb(0x20, KBD_DATA); /* send cmd: enable keyboard */ + if (!kbc_input_buffer_empty()) { + printk(BIOS_INFO, "Timeout while enabling keyboard\n"); +- return; ++ return 0; + } + + /* clean up any junk that might have been in the keyboard */ + if (!kbc_cleanup_buffers()) +- return; ++ return 0; + + /* reset keyboard and self test (keyboard side) */ + regval = send_keyboard(0xFF); + if (regval == KBD_REPLY_RESEND) { + /* keeps sending RESENDs, probably no keyboard. */ + printk(BIOS_INFO, "No PS/2 keyboard detected.\n"); +- return; ++ return 0; + } + + if (regval != KBD_REPLY_ACK) { + printk(BIOS_ERR, "Keyboard reset failed ACK: 0x%x\n", regval); +- return; ++ return 0; + } + + /* the reset command takes some time, so wait a little longer */ +@@ -241,14 +292,14 @@ void pc_keyboard_init(void) + + if (!kbc_output_buffer_full()) { + printk(BIOS_ERR, "Timeout waiting for keyboard after reset.\n"); +- return; ++ return 0; + } + + regval = inb(KBD_DATA); + if (regval != 0xAA) { + printk(BIOS_ERR, "Keyboard reset selftest failed: 0x%x\n", + regval); +- return; ++ return 0; + } + + /* +@@ -260,7 +311,7 @@ void pc_keyboard_init(void) + regval = send_keyboard(0xF5); + if (regval != KBD_REPLY_ACK) { + printk(BIOS_ERR, "Keyboard disable failed ACK: 0x%x\n", regval); +- return; ++ return 0; + } + + /* Set scancode command */ +@@ -268,34 +319,38 @@ void pc_keyboard_init(void) + if (regval != KBD_REPLY_ACK) { + printk(BIOS_ERR, "Keyboard set scancode cmd failed ACK: 0x%x\n", + regval); +- return; ++ return 0; + } + /* Set scancode mode 2 */ + regval = send_keyboard(0x02); + if (regval != KBD_REPLY_ACK) { + printk(BIOS_ERR, + "Keyboard set scancode mode failed ACK: 0x%x\n", regval); +- return; ++ return 0; + } + + /* All is well - enable keyboard interface */ + if (!kbc_input_buffer_empty()) +- return; ++ return 0; + outb(0x60, KBD_COMMAND); + if (!kbc_input_buffer_empty()) +- return; ++ return 0; + outb(0x65, KBD_DATA); /* send cmd: enable keyboard and IRQ 1 */ + if (!kbc_input_buffer_empty()) { + printk(BIOS_ERR, "Timeout during keyboard enable\n"); +- return; ++ return 0; + } + + /* enable the keyboard */ + regval = send_keyboard(0xF4); + if (regval != KBD_REPLY_ACK) { + printk(BIOS_ERR, "Keyboard enable failed ACK: 0x%x\n", regval); +- return; ++ return 0; + } ++ ++ printk(BIOS_DEBUG, "PS/2 keyboard initialized on primary channel\n"); ++ ++ return aux_dev_detected; + } + + /* +@@ -308,7 +363,7 @@ void set_kbc_ps2_mode(void) + enum cb_err err; + + /* Run a keyboard controller self-test */ +- err = kbc_self_test(); ++ err = kbc_self_test(0, NULL); + /* Ignore iterface failure as it's non-fatal. */ + if (err != CB_SUCCESS && err != CB_KBD_INTERFACE_FAILURE) + return; +diff --git a/src/ec/compal/ene932/ec.c b/src/ec/compal/ene932/ec.c +index d1687e9..50b8b5e 100644 +--- a/src/ec/compal/ene932/ec.c ++++ b/src/ec/compal/ene932/ec.c +@@ -133,7 +133,7 @@ static void ene932_init(struct device *dev) + return; + + printk(BIOS_DEBUG, "Compal ENE932: Initializing keyboard.\n"); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + + } + +diff --git a/src/ec/google/chromeec/ec_lpc.c b/src/ec/google/chromeec/ec_lpc.c +index 9a16906..8a04135 100644 +--- a/src/ec/google/chromeec/ec_lpc.c ++++ b/src/ec/google/chromeec/ec_lpc.c +@@ -403,7 +403,7 @@ static void lpc_ec_init(struct device *dev) + if (!dev->enabled) + return; + +- pc_keyboard_init(); ++ pc_keyboard_init(0); + google_chromeec_init(); + } + +diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c +index 3cd30bc..f0ccd48 100644 +--- a/src/ec/lenovo/h8/h8.c ++++ b/src/ec/lenovo/h8/h8.c +@@ -175,7 +175,7 @@ static void h8_smbios_strings(struct device *dev, struct smbios_type11 *t) + + static void h8_init(device_t dev) + { +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + struct device_operations h8_dev_ops = { +diff --git a/src/ec/quanta/ene_kb3940q/ec.c b/src/ec/quanta/ene_kb3940q/ec.c +index 8f23e33..a7d5bd7 100644 +--- a/src/ec/quanta/ene_kb3940q/ec.c ++++ b/src/ec/quanta/ene_kb3940q/ec.c +@@ -142,7 +142,7 @@ static void ene_kb3940q_init(struct device *dev) + return; + + printk(BIOS_DEBUG, "Quanta EnE KB3940Q: Initializing keyboard.\n"); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + + ene_kb3940q_log_events(); + } +diff --git a/src/ec/quanta/it8518/ec.c b/src/ec/quanta/it8518/ec.c +index 7388c01..dd7268a 100644 +--- a/src/ec/quanta/it8518/ec.c ++++ b/src/ec/quanta/it8518/ec.c +@@ -157,7 +157,7 @@ static void it8518_init(struct device *dev) + return; + + printk(BIOS_DEBUG, "Quanta IT8518: Initializing keyboard.\n"); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + static struct device_operations ops = { +diff --git a/src/include/pc80/keyboard.h b/src/include/pc80/keyboard.h +index 16cb959..5258d47 100644 +--- a/src/include/pc80/keyboard.h ++++ b/src/include/pc80/keyboard.h +@@ -1,7 +1,7 @@ + #ifndef PC80_KEYBOARD_H + #define PC80_KEYBOARD_H + +-void pc_keyboard_init(void); ++uint8_t pc_keyboard_init(uint8_t probe_aux); + void set_kbc_ps2_mode(void); + + #endif /* PC80_KEYBOARD_H */ +diff --git a/src/mainboard/emulation/qemu-i440fx/mainboard.c b/src/mainboard/emulation/qemu-i440fx/mainboard.c +index b2fb46c..e5fb3cb 100644 +--- a/src/mainboard/emulation/qemu-i440fx/mainboard.c ++++ b/src/mainboard/emulation/qemu-i440fx/mainboard.c +@@ -39,7 +39,7 @@ static void qemu_nb_init(device_t dev) + /* This sneaked in here, because Qemu does not + * emulate a SuperIO chip + */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + + /* setup IRQ routing */ + for (i = 0; i < 32; i++) +diff --git a/src/mainboard/emulation/qemu-q35/mainboard.c b/src/mainboard/emulation/qemu-q35/mainboard.c +index 82716c9..0000564 100644 +--- a/src/mainboard/emulation/qemu-q35/mainboard.c ++++ b/src/mainboard/emulation/qemu-q35/mainboard.c +@@ -60,7 +60,7 @@ static void qemu_nb_init(device_t dev) + /* This sneaked in here, because Qemu does not + * emulate a SuperIO chip + */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + + /* setup IRQ routing for pci slots */ + for (i = 0; i < 25; i++) +diff --git a/src/mainboard/packardbell/ms2290/mainboard.c b/src/mainboard/packardbell/ms2290/mainboard.c +index 065ca94..f964c57 100644 +--- a/src/mainboard/packardbell/ms2290/mainboard.c ++++ b/src/mainboard/packardbell/ms2290/mainboard.c +@@ -121,7 +121,7 @@ static void mainboard_enable(device_t dev) + + /* This sneaked in here, because EasyNote has no SuperIO chip. + */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + struct chip_operations mainboard_ops = { +diff --git a/src/mainboard/roda/rk9/mainboard.c b/src/mainboard/roda/rk9/mainboard.c +index a5465f9..50e9a75 100644 +--- a/src/mainboard/roda/rk9/mainboard.c ++++ b/src/mainboard/roda/rk9/mainboard.c +@@ -46,7 +46,7 @@ static void mainboard_enable(device_t dev) + + /* We have no driver for the embedded controller since the firmware + does most of the job. Hence, initialize keyboards here. */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + struct chip_operations mainboard_ops = { +diff --git a/src/northbridge/via/cx700/lpc.c b/src/northbridge/via/cx700/lpc.c +index 9262e40..e19f638 100644 +--- a/src/northbridge/via/cx700/lpc.c ++++ b/src/northbridge/via/cx700/lpc.c +@@ -285,7 +285,7 @@ static void cx700_lpc_init(struct device *dev) + isa_dma_init(); + + /* Initialize keyboard controller */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + static struct device_operations cx700_lpc_ops = { +diff --git a/src/northbridge/via/vx800/lpc.c b/src/northbridge/via/vx800/lpc.c +index 8fbb3be..1bdd7b8 100644 +--- a/src/northbridge/via/vx800/lpc.c ++++ b/src/northbridge/via/vx800/lpc.c +@@ -322,7 +322,7 @@ static void southbridge_init(struct device *dev) + setup_i8259(); // make sure interupt controller is configured before keyboard init + + /* turn on keyboard and RTC, no need to visit this reg twice */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + + printk(BIOS_DEBUG, "ps2 usb lid, you set who can wakeup system from s3 sleep\n"); + S3_ps2_kb_ms_wakeup(dev); +diff --git a/src/southbridge/dmp/vortex86ex/southbridge.c b/src/southbridge/dmp/vortex86ex/southbridge.c +index 3ef6a5d..5da7d74 100644 +--- a/src/southbridge/dmp/vortex86ex/southbridge.c ++++ b/src/southbridge/dmp/vortex86ex/southbridge.c +@@ -607,7 +607,7 @@ static void southbridge_init(struct device *dev) + retries--; + } + post_code(POST_DMP_KBD_IS_READY); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + static struct device_operations vortex_sb_ops = { +diff --git a/src/southbridge/sis/sis966/lpc.c b/src/southbridge/sis/sis966/lpc.c +index 940844b..c40df0a 100644 +--- a/src/southbridge/sis/sis966/lpc.c ++++ b/src/southbridge/sis/sis966/lpc.c +@@ -91,7 +91,7 @@ static void lpc_init(device_t dev) + int nmi_option; + + printk(BIOS_DEBUG, "LPC_INIT -------->\n"); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + + lpc_usb_legacy_init(dev); + lpc_common_init(dev); +diff --git a/src/southbridge/via/vt8237r/lpc.c b/src/southbridge/via/vt8237r/lpc.c +index b54d494..113ce93 100644 +--- a/src/southbridge/via/vt8237r/lpc.c ++++ b/src/southbridge/via/vt8237r/lpc.c +@@ -625,7 +625,7 @@ static void init_keyboard(struct device *dev) + { + u8 regval = pci_read_config8(dev, 0x51); + if (regval & 0x1) +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + + static void southbridge_init_common(struct device *dev) +diff --git a/src/superio/fintek/f71863fg/superio.c b/src/superio/fintek/f71863fg/superio.c +index 8e0a643..bb09d01 100644 +--- a/src/superio/fintek/f71863fg/superio.c ++++ b/src/superio/fintek/f71863fg/superio.c +@@ -34,7 +34,7 @@ static void f71863fg_init(struct device *dev) + /* TODO: Might potentially need code for HWM or FDC etc. */ + case F71863FG_KBC: + res0 = find_resource(dev, PNP_IDX_IO0); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/fintek/f71869ad/superio.c b/src/superio/fintek/f71869ad/superio.c +index f16c37f..8cf9008 100644 +--- a/src/superio/fintek/f71869ad/superio.c ++++ b/src/superio/fintek/f71869ad/superio.c +@@ -34,7 +34,7 @@ static void f71869ad_init(struct device *dev) + switch(dev->path.pnp.device) { + /* TODO: Might potentially need code for HWM or FDC etc. */ + case F71869AD_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case F71869AD_HWM: + f71869ad_multifunc_init(dev); +diff --git a/src/superio/fintek/f71872/superio.c b/src/superio/fintek/f71872/superio.c +index 6b4de2d..a973da8 100644 +--- a/src/superio/fintek/f71872/superio.c ++++ b/src/superio/fintek/f71872/superio.c +@@ -32,7 +32,7 @@ static void f71872_init(struct device *dev) + switch(dev->path.pnp.device) { + /* TODO: Might potentially need code for HWM or FDC etc. */ + case F71872_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/fintek/f81865f/superio.c b/src/superio/fintek/f81865f/superio.c +index 9cd5c95..fa9e23e 100644 +--- a/src/superio/fintek/f81865f/superio.c ++++ b/src/superio/fintek/f81865f/superio.c +@@ -32,7 +32,7 @@ static void f81865f_init(struct device *dev) + switch (dev->path.pnp.device) { + /* TODO: Might potentially need code for HWM or FDC etc. */ + case F81865F_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/fintek/f81866d/superio.c b/src/superio/fintek/f81866d/superio.c +index ce0e066..2a95219 100644 +--- a/src/superio/fintek/f81866d/superio.c ++++ b/src/superio/fintek/f81866d/superio.c +@@ -34,7 +34,7 @@ static void f81866d_init(struct device *dev) + switch (dev->path.pnp.device) { + /* TODO: Might potentially need extra code for serial, wdt etc. */ + case F81866D_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case F81866D_HWM: + // Fixing temp sensor read out and init Fan control +diff --git a/src/superio/ite/it8671f/superio.c b/src/superio/ite/it8671f/superio.c +index 72e31f1..907e020 100644 +--- a/src/superio/ite/it8671f/superio.c ++++ b/src/superio/ite/it8671f/superio.c +@@ -32,7 +32,7 @@ static void init(struct device *dev) + case IT8671F_PP: /* TODO. */ + break; + case IT8671F_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case IT8671F_KBCM: /* TODO. */ + break; +diff --git a/src/superio/ite/it8712f/superio.c b/src/superio/ite/it8712f/superio.c +index 02cbefc..1d87f47 100644 +--- a/src/superio/ite/it8712f/superio.c ++++ b/src/superio/ite/it8712f/superio.c +@@ -39,7 +39,7 @@ static void it8712f_init(struct device *dev) + break; + case IT8712F_KBCK: + set_kbc_ps2_mode(); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case IT8712F_KBCM: /* TODO. */ + break; +diff --git a/src/superio/ite/it8716f/superio.c b/src/superio/ite/it8716f/superio.c +index 3a9e790..469c255 100644 +--- a/src/superio/ite/it8716f/superio.c ++++ b/src/superio/ite/it8716f/superio.c +@@ -60,7 +60,7 @@ static void it8716f_init(struct device *dev) + init_ec(res0->base + EC_INDEX_PORT); + break; + case IT8716F_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/ite/it8718f/superio.c b/src/superio/ite/it8718f/superio.c +index ccef043..825fb53 100644 +--- a/src/superio/ite/it8718f/superio.c ++++ b/src/superio/ite/it8718f/superio.c +@@ -34,7 +34,7 @@ static void init(struct device *dev) + case IT8718F_EC: /* TODO. */ + break; + case IT8718F_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case IT8718F_KBCM: /* TODO. */ + break; +diff --git a/src/superio/ite/it8721f/superio.c b/src/superio/ite/it8721f/superio.c +index 4fc0562..ae052a3 100644 +--- a/src/superio/ite/it8721f/superio.c ++++ b/src/superio/ite/it8721f/superio.c +@@ -35,7 +35,7 @@ static void init(struct device *dev) + case IT8721F_EC: /* TODO. */ + break; + case IT8721F_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case IT8721F_KBCM: /* TODO. */ + break; +diff --git a/src/superio/ite/it8728f/superio.c b/src/superio/ite/it8728f/superio.c +index 4591bb1..3849d63 100644 +--- a/src/superio/ite/it8728f/superio.c ++++ b/src/superio/ite/it8728f/superio.c +@@ -38,7 +38,7 @@ static void it8728f_init(struct device *dev) + break; + case IT8728F_KBCK: + set_kbc_ps2_mode(); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/ite/it8772f/superio.c b/src/superio/ite/it8772f/superio.c +index 6c6a503..17145b8 100644 +--- a/src/superio/ite/it8772f/superio.c ++++ b/src/superio/ite/it8772f/superio.c +@@ -196,7 +196,7 @@ static void it8772f_init(struct device *dev) + case IT8772F_KBCK: + if (!conf->skip_keyboard) { + set_kbc_ps2_mode(); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + break; + case IT8772F_KBCM: +diff --git a/src/superio/nsc/pc87309/superio.c b/src/superio/nsc/pc87309/superio.c +index ecda1e7..f22566c 100644 +--- a/src/superio/nsc/pc87309/superio.c ++++ b/src/superio/nsc/pc87309/superio.c +@@ -29,7 +29,7 @@ static void init(struct device *dev) + + switch (dev->path.pnp.device) { + case PC87309_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/nsc/pc87360/superio.c b/src/superio/nsc/pc87360/superio.c +index 6b6e790..248c793 100644 +--- a/src/superio/nsc/pc87360/superio.c ++++ b/src/superio/nsc/pc87360/superio.c +@@ -31,7 +31,7 @@ static void init(struct device *dev) + + switch(dev->path.pnp.device) { + case PC87360_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/nsc/pc87366/superio.c b/src/superio/nsc/pc87366/superio.c +index f9dca21..e5c8ac2 100644 +--- a/src/superio/nsc/pc87366/superio.c ++++ b/src/superio/nsc/pc87366/superio.c +@@ -31,7 +31,7 @@ static void init(struct device *dev) + + switch(dev->path.pnp.device) { + case PC87366_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/nsc/pc87417/superio.c b/src/superio/nsc/pc87417/superio.c +index 1855db9..7a8d76f 100644 +--- a/src/superio/nsc/pc87417/superio.c ++++ b/src/superio/nsc/pc87417/superio.c +@@ -32,7 +32,7 @@ static void init(struct device *dev) + + switch(dev->path.pnp.device) { + case PC87417_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/nsc/pc97317/superio.c b/src/superio/nsc/pc97317/superio.c +index e8cf842..983c7f1 100644 +--- a/src/superio/nsc/pc97317/superio.c ++++ b/src/superio/nsc/pc97317/superio.c +@@ -33,7 +33,7 @@ static void init(struct device *dev) + pnp_set_enable(dev, 0); /* Disable keyboard */ + pnp_write_config(dev, 0xf0, 0x40); /* Set KBC clock to 8 MHz. */ + pnp_set_enable(dev, 1); /* Enable keyboard */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + default: + break; +diff --git a/src/superio/nuvoton/nct5572d/superio.c b/src/superio/nuvoton/nct5572d/superio.c +index 81a8326..6b5febd 100644 +--- a/src/superio/nuvoton/nct5572d/superio.c ++++ b/src/superio/nuvoton/nct5572d/superio.c +@@ -45,7 +45,7 @@ static void nct5572d_init(struct device *dev) + switch(dev->path.pnp.device) { + /* TODO: Might potentially need code for HWM or FDC etc. */ + case NCT5572D_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case NCT5572D_ACPI: + /* Set power state after power fail */ +diff --git a/src/superio/nuvoton/nct6779d/superio.c b/src/superio/nuvoton/nct6779d/superio.c +index 79a25b7..c16a736 100644 +--- a/src/superio/nuvoton/nct6779d/superio.c ++++ b/src/superio/nuvoton/nct6779d/superio.c +@@ -39,7 +39,7 @@ static void nct6779d_init(struct device *dev) + switch(dev->path.pnp.device) { + /* TODO: Might potentially need code for HWM or FDC etc. */ + case NCT6779D_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/nuvoton/wpcm450/superio.c b/src/superio/nuvoton/wpcm450/superio.c +index bfc3c5e..c6cb494 100644 +--- a/src/superio/nuvoton/wpcm450/superio.c ++++ b/src/superio/nuvoton/wpcm450/superio.c +@@ -31,7 +31,7 @@ static void init(struct device *dev) + + switch(dev->path.pnp.device) { + case WPCM450_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/renesas/m3885x/superio.c b/src/superio/renesas/m3885x/superio.c +index 1f30bfe..84c014c 100644 +--- a/src/superio/renesas/m3885x/superio.c ++++ b/src/superio/renesas/m3885x/superio.c +@@ -33,7 +33,7 @@ static void m3885x_init(struct device *dev) + + printk(BIOS_DEBUG, "Renesas M3885x: Initializing keyboard.\n"); + set_kbc_ps2_mode(); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + m3885_configure_multikey(); + } + +diff --git a/src/superio/smsc/dme1737/superio.c b/src/superio/smsc/dme1737/superio.c +index 23f2c7d..0e9bd4c 100644 +--- a/src/superio/smsc/dme1737/superio.c ++++ b/src/superio/smsc/dme1737/superio.c +@@ -35,7 +35,7 @@ static void dme1737_init(struct device *dev) + + switch(dev->path.pnp.device) { + case DME1737_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/fdc37n972/fdc37n972.c b/src/superio/smsc/fdc37n972/fdc37n972.c +index 0c6b517..cf94912 100644 +--- a/src/superio/smsc/fdc37n972/fdc37n972.c ++++ b/src/superio/smsc/fdc37n972/fdc37n972.c +@@ -31,7 +31,7 @@ static void init(struct device *dev) + case FDC37N972_PP: /* TODO. */ + break; + case FDC37N972_KBDC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + // [..] The rest: TODO + } +diff --git a/src/superio/smsc/kbc1100/superio.c b/src/superio/smsc/kbc1100/superio.c +index 81fb394..687691c 100644 +--- a/src/superio/smsc/kbc1100/superio.c ++++ b/src/superio/smsc/kbc1100/superio.c +@@ -68,7 +68,7 @@ static void kbc1100_init(struct device *dev) + case KBC1100_KBC: + res0 = find_resource(dev, PNP_IDX_IO0); + res1 = find_resource(dev, PNP_IDX_IO1); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/lpc47b272/superio.c b/src/superio/smsc/lpc47b272/superio.c +index 6cc4823..e8d4741 100644 +--- a/src/superio/smsc/lpc47b272/superio.c ++++ b/src/superio/smsc/lpc47b272/superio.c +@@ -46,7 +46,7 @@ static void lpc47b272_init(struct device *dev) + + switch(dev->path.pnp.device) { + case LPC47B272_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/lpc47b397/superio.c b/src/superio/smsc/lpc47b397/superio.c +index 6270d92..76164b5 100644 +--- a/src/superio/smsc/lpc47b397/superio.c ++++ b/src/superio/smsc/lpc47b397/superio.c +@@ -45,7 +45,7 @@ static void lpc47b397_init(struct device *dev) + + switch(dev->path.pnp.device) { + case LPC47B397_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/lpc47m10x/superio.c b/src/superio/smsc/lpc47m10x/superio.c +index c3c7feb..bcde524 100644 +--- a/src/superio/smsc/lpc47m10x/superio.c ++++ b/src/superio/smsc/lpc47m10x/superio.c +@@ -44,7 +44,7 @@ static void lpc47m10x_init(struct device *dev) + + switch(dev->path.pnp.device) { + case LPC47M10X2_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/lpc47m15x/superio.c b/src/superio/smsc/lpc47m15x/superio.c +index 166f383..6736621 100644 +--- a/src/superio/smsc/lpc47m15x/superio.c ++++ b/src/superio/smsc/lpc47m15x/superio.c +@@ -66,7 +66,7 @@ static void lpc47m15x_init(struct device *dev) + + switch(dev->path.pnp.device) { + case LPC47M15X_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/lpc47n227/superio.c b/src/superio/smsc/lpc47n227/superio.c +index 3885ef3..a5e33fa 100644 +--- a/src/superio/smsc/lpc47n227/superio.c ++++ b/src/superio/smsc/lpc47n227/superio.c +@@ -131,7 +131,7 @@ static void lpc47n227_init(struct device *dev) + switch (dev->path.pnp.device) { + case LPC47N227_KBDC: + printk(BIOS_DEBUG, "LPC47N227: Initializing keyboard.\n"); +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/mec1308/superio.c b/src/superio/smsc/mec1308/superio.c +index 2beeec6..aa3d012 100644 +--- a/src/superio/smsc/mec1308/superio.c ++++ b/src/superio/smsc/mec1308/superio.c +@@ -34,7 +34,7 @@ static void mec1308_init(struct device *dev) + + switch(dev->path.pnp.device) { + case MEC1308_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/sch4037/superio.c b/src/superio/smsc/sch4037/superio.c +index 0f09914..4906aa2 100644 +--- a/src/superio/smsc/sch4037/superio.c ++++ b/src/superio/smsc/sch4037/superio.c +@@ -33,7 +33,7 @@ static void sch4037_init(struct device *dev) + + switch(dev->path.pnp.device) { + case SCH4037_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/smsc/sio10n268/sio10n268.c b/src/superio/smsc/sio10n268/sio10n268.c +index 5892f0c..e0b0d99 100644 +--- a/src/superio/smsc/sio10n268/sio10n268.c ++++ b/src/superio/smsc/sio10n268/sio10n268.c +@@ -31,7 +31,7 @@ static void init(struct device *dev) + break; + case SIO10N268_KBDC: + /* TODO: This is still hardcoded. */ +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + // [..] The rest: TODO + } +diff --git a/src/superio/smsc/smscsuperio/superio.c b/src/superio/smsc/smscsuperio/superio.c +index b3238de..fec8157 100644 +--- a/src/superio/smsc/smscsuperio/superio.c ++++ b/src/superio/smsc/smscsuperio/superio.c +@@ -163,7 +163,7 @@ static void smsc_init(struct device *dev) + /* A Super I/O was found, so initialize the respective device. */ + ld = dev->path.pnp.device; + if (ld == logical_device_table[i].devs[LD_KBC]) { +- pc_keyboard_init(); ++ pc_keyboard_init(0); + } + } + +diff --git a/src/superio/winbond/w83627dhg/superio.c b/src/superio/winbond/w83627dhg/superio.c +index 10dba59..ddda25e 100644 +--- a/src/superio/winbond/w83627dhg/superio.c ++++ b/src/superio/winbond/w83627dhg/superio.c +@@ -43,7 +43,7 @@ static void w83627dhg_init(struct device *dev) + w83627dhg_enable_UR2(dev); + break; + case W83627DHG_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/winbond/w83627ehg/superio.c b/src/superio/winbond/w83627ehg/superio.c +index ea7a982..1060059 100644 +--- a/src/superio/winbond/w83627ehg/superio.c ++++ b/src/superio/winbond/w83627ehg/superio.c +@@ -85,7 +85,7 @@ static void w83627ehg_init(struct device *dev) + + switch(dev->path.pnp.device) { + case W83627EHG_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case W83627EHG_HWM: + res0 = find_resource(dev, PNP_IDX_IO0); +diff --git a/src/superio/winbond/w83627hf/superio.c b/src/superio/winbond/w83627hf/superio.c +index fe250a1..2402ae0 100644 +--- a/src/superio/winbond/w83627hf/superio.c ++++ b/src/superio/winbond/w83627hf/superio.c +@@ -92,7 +92,7 @@ static void w83627hf_init(struct device *dev) + + switch(dev->path.pnp.device) { + case W83627HF_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + case W83627HF_HWM: + res0 = find_resource(dev, PNP_IDX_IO0); +diff --git a/src/superio/winbond/w83627thg/superio.c b/src/superio/winbond/w83627thg/superio.c +index f42f948..da9bab2 100644 +--- a/src/superio/winbond/w83627thg/superio.c ++++ b/src/superio/winbond/w83627thg/superio.c +@@ -33,7 +33,7 @@ static void w83627thg_init(struct device *dev) + + switch(dev->path.pnp.device) { + case W83627THG_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/winbond/w83627uhg/superio.c b/src/superio/winbond/w83627uhg/superio.c +index 5192c32..d0e443c 100644 +--- a/src/superio/winbond/w83627uhg/superio.c ++++ b/src/superio/winbond/w83627uhg/superio.c +@@ -79,7 +79,7 @@ static void w83627uhg_init(struct device *dev) + set_uart_clock_source(dev, 0); + break; + case W83627UHG_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/winbond/w83667hg-a/ps2_controller.asl b/src/superio/winbond/w83667hg-a/ps2_controller.asl +new file mode 100644 +index 0000000..c3b5c75 +--- /dev/null ++++ b/src/superio/winbond/w83667hg-a/ps2_controller.asl +@@ -0,0 +1,78 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (c) 2013 Vladimir Serbinenko ++ * Copyright (c) 2015 Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; version 2 of ++ * the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++ /* SuperIO control port */ ++ Name (SPIO, 0x2E) ++ ++ /* SuperIO control map */ ++ OperationRegion (SPIM, SystemIO, SPIO, 0x02) ++ Field (SPIM, ByteAcc, NoLock, Preserve) { ++ SIOI, 8, ++ SIOD, 8 ++ } ++ ++ /* SuperIO control registers */ ++ IndexField (SIOI, SIOD, ByteAcc, NoLock, Preserve) { ++ Offset (0x2A), ++ CR2A, 8, /* Pin function selection */ ++ } ++ ++ Device (PS2K) // Keyboard ++ { ++ Name(_HID, EISAID("PNP0303")) ++ Name(_CID, EISAID("PNP030B")) ++ ++ Name(_CRS, ResourceTemplate() ++ { ++ IO (Decode16, 0x60, 0x60, 0x01, 0x01) ++ IO (Decode16, 0x64, 0x64, 0x01, 0x01) ++ IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1 ++ }) ++ ++ Method (_STA, 0) ++ { ++ Return (0xf) ++ } ++ } ++ ++ Device (PS2M) // Mouse ++ { ++ Name(_HID, EISAID("PNP0F13")) ++ Name(_CRS, ResourceTemplate() ++ { ++ IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12 ++ }) ++ ++ Method(_STA, 0) ++ { ++ /* Access SuperIO ACPI device */ ++ Store(0x87, SIOI) ++ Store(0x87, SIOI) ++ ++ /* Read Pin56 function select */ ++ And(CR2A, 0x2, Local0) ++ ++ /* Restore default SuperIO access */ ++ Store(0xAA, SIOI) ++ ++ if (LEqual(Local0, 0x0)) { ++ /* Mouse function selected */ ++ Return (0xf) ++ } ++ Return (0x0) ++ } ++ } +diff --git a/src/superio/winbond/w83667hg-a/superio.c b/src/superio/winbond/w83667hg-a/superio.c +index b539871..d6f2ee5 100644 +--- a/src/superio/winbond/w83667hg-a/superio.c ++++ b/src/superio/winbond/w83667hg-a/superio.c +@@ -23,6 +23,7 @@ + #include <pc80/keyboard.h> + #include <pc80/mc146818rtc.h> + #include <stdlib.h> ++#include <arch/acpi.h> + #include <superio/conf_mode.h> + + #include "w83667hg-a.h" +@@ -38,6 +39,7 @@ static void w83667hg_a_init(struct device *dev) + { + uint8_t byte; + uint8_t power_status; ++ uint8_t mouse_detected; + + if (!dev->enabled) + return; +@@ -45,7 +47,23 @@ static void w83667hg_a_init(struct device *dev) + switch(dev->path.pnp.device) { + /* TODO: Might potentially need code for HWM or FDC etc. */ + case W83667HG_A_KBC: +- pc_keyboard_init(); ++ /* Enable mouse controller */ ++ pnp_enter_conf_mode_8787(dev); ++ byte = pnp_read_config(dev, 0x2a); ++ byte &= ~(0x1 << 1); ++ pnp_write_config(dev, 0x2a, byte); ++ pnp_exit_conf_mode_aa(dev); ++ ++ mouse_detected = pc_keyboard_init(1); ++ ++ if (!mouse_detected && !acpi_is_wakeup_s3()) { ++ /* Disable mouse controller */ ++ pnp_enter_conf_mode_8787(dev); ++ byte = pnp_read_config(dev, 0x2a); ++ byte |= 0x1 << 1; ++ pnp_write_config(dev, 0x2a, byte); ++ pnp_exit_conf_mode_aa(dev); ++ } + break; + case W83667HG_A_ACPI: + /* Set power state after power fail */ +diff --git a/src/superio/winbond/w83977tf/superio.c b/src/superio/winbond/w83977tf/superio.c +index f23d7c4..b4fe594 100644 +--- a/src/superio/winbond/w83977tf/superio.c ++++ b/src/superio/winbond/w83977tf/superio.c +@@ -34,7 +34,7 @@ static void w83977tf_init(struct device *dev) + + switch(dev->path.pnp.device) { + case W83977TF_KBC: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +diff --git a/src/superio/winbond/wpcd376i/superio.c b/src/superio/winbond/wpcd376i/superio.c +index d54c4af..f2d520d 100644 +--- a/src/superio/winbond/wpcd376i/superio.c ++++ b/src/superio/winbond/wpcd376i/superio.c +@@ -45,7 +45,7 @@ static void init(device_t dev) + break; + + case WPCD376I_KBCK: +- pc_keyboard_init(); ++ pc_keyboard_init(0); + break; + } + } +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch new file mode 100644 index 0000000..a4ecef8 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch @@ -0,0 +1,27 @@ +From 6f02a70d622a6834323a960eda887074543efe8a Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:01 -0600 +Subject: [PATCH 34/45] mainboard/asus/kcma-d8: Use W83667HG-A specific PS/2 + ASL file + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/dsdt.asl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/mainboard/asus/kgpe-d16/dsdt.asl b/src/mainboard/asus/kgpe-d16/dsdt.asl +index 702ace1..5f9195a 100644 +--- a/src/mainboard/asus/kgpe-d16/dsdt.asl ++++ b/src/mainboard/asus/kgpe-d16/dsdt.asl +@@ -562,7 +562,7 @@ DefinitionBlock ( + }) + } + +- #include "../../../drivers/pc80/ps2_controller.asl" ++ #include "../../../superio/winbond/w83667hg-a/ps2_controller.asl" + + /* UART 1 */ + Device (URT1) +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch new file mode 100644 index 0000000..cbeb336 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch @@ -0,0 +1,63 @@ +From e90ac9c0e629f2f50f59203d4d91415b89354d2f Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:02 -0600 +Subject: [PATCH 35/45] nb/amd/amdmct/mct_ddr3: Save and restore SkewMemClk for + S3 resume + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 5 +++-- + src/northbridge/amd/amdmct/mct_ddr3/s3utils.c | 6 ++++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +index e7361ac..f953919 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +@@ -729,7 +729,7 @@ struct amd_s3_persistent_mct_channel_data { + uint32_t f3x5c; + uint32_t f3x60; + +- /* Family 15h-specific registers (90 dwords) */ ++ /* Family 15h-specific registers (91 dwords) */ + uint32_t f2x200; + uint32_t f2x204; + uint32_t f2x208; +@@ -785,8 +785,9 @@ struct amd_s3_persistent_mct_channel_data { + uint32_t f2x9cx0d0fc231; + uint32_t f2x9cx0d0f0_0_f_31[9]; /* [lane] */ + uint32_t f2x9cx0d0f8021; ++ uint32_t f2x9cx0d0fe00a; + +- /* TOTAL: 342 dwords */ ++ /* TOTAL: 343 dwords */ + } __attribute__((packed)); + + struct amd_s3_persistent_node_data { +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c +index ae2cca1..fe77075 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c +@@ -454,6 +454,9 @@ void copy_mct_data_to_save_variable(struct amd_s3_persistent_data* persistent_da + data->f2x9cx0d0f0_0_f_31[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0031 | (i << 8)); + + data->f2x9cx0d0f8021 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8021); ++ ++ if (channel == 1) ++ data->f2x9cx0d0fe00a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe00a); + } + + /* Stage 4 */ +@@ -796,6 +799,9 @@ void restore_mct_data_from_save_variable(struct amd_s3_persistent_data* persiste + write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0031 | (i << 8), data->f2x9cx0d0f0_0_f_31[i]); + + write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8021, data->f2x9cx0d0f8021); ++ ++ if (channel == 1) ++ write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe00a, data->f2x9cx0d0fe00a); + } + } + } +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch new file mode 100644 index 0000000..ec82f70 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch @@ -0,0 +1,66 @@ +From 3b1c5530e745b77411f3a9db1872a8592ac79bf5 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:02 -0600 +Subject: [PATCH 36/45] cpu/amd/fam10h-fam15h: Add new wait_ap_stopped function + +Under certain conditions, such as when microcode updates are +being performed, it is important to make sure all APs have +finished updates and are halted before continuing with the +boot process. + +Add a new wait_ap_stopped() function to allow for this +functionality to be added to the appropriate mainboard +romstage source files. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/init_cpus.c | 20 ++++++++++++++++++++ + src/include/cpu/amd/multicore.h | 1 + + 2 files changed, 21 insertions(+) + +diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c +index e8e81d2..e2a1bf3 100644 +--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c ++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c +@@ -299,6 +299,26 @@ void allow_all_aps_stop(u32 bsp_apicid) + lapic_write(LAPIC_MSG_REG, (bsp_apicid << 24) | F10_APSTATE_STOPPED); + } + ++static void wait_ap_stopped(u32 ap_apicid, void *gp) ++{ ++ u32 timeout; ++ timeout = wait_cpu_state(ap_apicid, F10_APSTATE_ASLEEP, F10_APSTATE_ASLEEP); ++ printk(BIOS_DEBUG, "* AP %02x", ap_apicid); ++ if (timeout) { ++ printk(BIOS_DEBUG, " timed out:%08x\n", timeout); ++ } else { ++ printk(BIOS_DEBUG, "stopped\n"); ++ } ++} ++ ++void wait_all_other_cores_stopped(u32 bsp_apicid) ++{ ++ // all aps other than core0 ++ printk(BIOS_DEBUG, "stopped ap apicid: "); ++ for_each_ap(bsp_apicid, 2, -1, wait_ap_stopped, (void *)0); ++ printk(BIOS_DEBUG, "\n"); ++} ++ + static void enable_apic_ext_id(u32 node) + { + u32 val; +diff --git a/src/include/cpu/amd/multicore.h b/src/include/cpu/amd/multicore.h +index b3a8237..0ddf866 100644 +--- a/src/include/cpu/amd/multicore.h ++++ b/src/include/cpu/amd/multicore.h +@@ -35,6 +35,7 @@ void amd_sibling_init(struct device *cpu); + void wait_all_core0_started(void); + void wait_all_other_cores_started(u32 bsp_apicid); + void wait_all_aps_started(u32 bsp_apicid); ++void wait_all_other_cores_stopped(uint32_t bsp_apicid); + void allow_all_aps_stop(u32 bsp_apicid); + #endif + u32 get_initial_apicid(void); +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch new file mode 100644 index 0000000..85df388 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch @@ -0,0 +1,34 @@ +From acb022efd422f1008e311863779cfb2395069bd6 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:03 -0600 +Subject: [PATCH 37/45] mainboard/asus/kgpe-d16: Wait for all APs to stop + before MCT setup + +Under certain conditions when the APs are still executing during +MCT setup the system can hang. This was the root cause of most +of the S3 resume failures on this platform; waiting for AP stop +before MCT setup allows for reliable S3 resume. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/romstage.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c +index 6fb7668..5df6de4 100644 +--- a/src/mainboard/asus/kgpe-d16/romstage.c ++++ b/src/mainboard/asus/kgpe-d16/romstage.c +@@ -515,6 +515,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + + post_code(0x3B); + ++ /* Wait for all APs to be stopped, otherwise ram initialization may hang */ ++ if (IS_ENABLED(CONFIG_LOGICAL_CPUS)) ++ wait_all_other_cores_stopped(bsp_apicid); ++ + /* It's the time to set ctrl in sysinfo now; */ + printk(BIOS_DEBUG, "fill_mem_ctrl() detected %d nodes\n", sysinfo->nodes); + if (is_fam15h()) +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch new file mode 100644 index 0000000..cde1ce5 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch @@ -0,0 +1,28 @@ +From 048d7a04e75fbc511838623916f4850897b29c5a Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:04 -0600 +Subject: [PATCH 38/45] cpu/amd/fam10h-15h: Add workaround for AMD Erratum 600 + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/defaults.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/cpu/amd/family_10h-family_15h/defaults.h b/src/cpu/amd/family_10h-family_15h/defaults.h +index 3618cb8..d384eb3 100644 +--- a/src/cpu/amd/family_10h-family_15h/defaults.h ++++ b/src/cpu/amd/family_10h-family_15h/defaults.h +@@ -270,6 +270,10 @@ static const struct { + ForceErrType = 0x0, + MultRetryErr = 0x0 */ + ++ /* Errata 600 */ ++ { 0, 0x150, AMD_OR_B2, AMD_PTYPE_ALL, ++ 0x00000000, 0x00000e00 }, /* HtRetryCrcDatIns = 0x4 */ ++ + /* Errata 351 + * System software should program the Link Extended Control Registers[LS2En] + * (F0x[18C:170][8]) to 0b for all links. System software should also +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch new file mode 100644 index 0000000..8e036b3 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch @@ -0,0 +1,39 @@ +From 79a5899dba0b5231c83614177e3e7287aa7167c4 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:06 -0600 +Subject: [PATCH 39/45] mainboard/asus/kgpe-d16: Reenable power LED after S3 + resume + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl b/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl +index c9bc0a9..a4d5b2a 100644 +--- a/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl ++++ b/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl +@@ -218,7 +218,7 @@ Method(\_WAK, 1) { + + /* Set up LEDs */ + /* Set power LED to steady on */ +- Store(0x3, BLNK) ++ Store(0x0, BLNK) + + /* Configure SuperIO for wake */ + /* Access SuperIO ACPI device */ +@@ -290,11 +290,6 @@ Method(\_PTS, 1) { + /* Set suspend LED to 0.25Hz toggle pulse with 50% duty cycle */ + Store(0x2, BLNK) + } +- if (LEqual(Arg0, 0x3)) /* Power state S3 requested */ +- { +- /* Set suspend LED to 0.25Hz toggle pulse with 25% duty cycle */ +- Store(0x1, BLNK) +- } + + /* Configure SuperIO for sleep */ + /* Access SuperIO ACPI device */ +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch new file mode 100644 index 0000000..0559642 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch @@ -0,0 +1,53 @@ +From 3efdfbd1def5dd2b3bd87ac9ff0bad83c2945eed Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:07 -0600 +Subject: [PATCH 40/45] cpu/amd/fam10h-fam15h: Add CMOS option to disable CPB + (core boost) + +On certain systems and CPUs Core Performance Boost (CPB) may cause +sporadic system lockups. This issue is also somewhat known on the +various proprietary BIOSes, therefore it seems to be a hardware +incompatibility when present. + +Allow the user to disable CBP if needed. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/init_cpus.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c +index e2a1bf3..c1ff240 100644 +--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c ++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c +@@ -987,6 +987,7 @@ void cpuSetAMDMSR(uint8_t node_id) + u32 platform; + uint64_t revision; + uint8_t enable_c_states; ++ uint8_t enable_cpb; + + printk(BIOS_DEBUG, "cpuSetAMDMSR "); + +@@ -1078,6 +1079,19 @@ void cpuSetAMDMSR(uint8_t node_id) + enable_c_states = 0; + #endif + ++ if (revision & AMD_FAM15_ALL) { ++ enable_cpb = 1; ++ if (get_option(&nvram, "cpu_core_boost") == CB_SUCCESS) ++ enable_cpb = !!nvram; ++ ++ if (!enable_cpb) { ++ /* Disable Core Performance Boost */ ++ msr = rdmsr(0xc0010015); ++ msr.lo |= (0x1 << 25); /* CpbDis = 1 */ ++ wrmsr(0xc0010015, msr); ++ } ++ } ++ + printk(BIOS_DEBUG, " done\n"); + } + +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch new file mode 100644 index 0000000..4df54ca --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch @@ -0,0 +1,42 @@ +From 7315434b950b3150fbaaa5c6860590c41d5cc71e Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:07 -0600 +Subject: [PATCH 41/45] mainboard/asus/kgpe-d16: Add CPB control CMOS option + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kgpe-d16/cmos.default | 1 + + src/mainboard/asus/kgpe-d16/cmos.layout | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/mainboard/asus/kgpe-d16/cmos.default b/src/mainboard/asus/kgpe-d16/cmos.default +index a05b9c3..0e7afb3 100644 +--- a/src/mainboard/asus/kgpe-d16/cmos.default ++++ b/src/mainboard/asus/kgpe-d16/cmos.default +@@ -17,6 +17,7 @@ interleave_nodes = Disable + interleave_memory_channels = Enable + cpu_c_states = Enable + cpu_cc6_state = Enable ++cpu_core_boost = Enable + sata_ahci_mode = Enable + sata_alpm = Disable + maximum_p_state_limit = 0xf +diff --git a/src/mainboard/asus/kgpe-d16/cmos.layout b/src/mainboard/asus/kgpe-d16/cmos.layout +index d1c0702..075388e 100644 +--- a/src/mainboard/asus/kgpe-d16/cmos.layout ++++ b/src/mainboard/asus/kgpe-d16/cmos.layout +@@ -48,8 +48,9 @@ entries + 476 1 e 1 l3_cache_partitioning + 477 1 e 1 ieee1394_controller + 478 1 e 1 iommu +-479 1 e 1 experimental_memory_speed_boost +-480 1 r 0 allow_spd_nvram_cache_restore ++479 1 e 1 cpu_core_boost ++480 1 e 1 experimental_memory_speed_boost ++481 1 r 0 allow_spd_nvram_cache_restore + 728 256 h 0 user_data + 984 16 h 0 check_sum + # Reserve the extended AMD configuration registers +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch new file mode 100644 index 0000000..e95630f --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch @@ -0,0 +1,131 @@ +From ed0e74f934203d11e90c227f6a2bcabd62262952 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:07 -0600 +Subject: [PATCH 42/45] cpu/amd/fam10h-15h: Set PowerStepUp/PowerStepDown on + Fam15h + +Multilink Family 15h processors were being configured with an +incorrect PowerStepUp/PowerStepDown value. Set the value +according to the BKDG, and clean up the terrible formatting +of the power_up_down() function that led to the incorrect +values being overlooked until now. + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/fidvid.c | 96 ++++++++++++++++-------------- + 1 file changed, 50 insertions(+), 46 deletions(-) + +diff --git a/src/cpu/amd/family_10h-family_15h/fidvid.c b/src/cpu/amd/family_10h-family_15h/fidvid.c +index 2edb75e..5bef7d3 100644 +--- a/src/cpu/amd/family_10h-family_15h/fidvid.c ++++ b/src/cpu/amd/family_10h-family_15h/fidvid.c +@@ -390,56 +390,60 @@ static u32 nb_clk_did(uint8_t node, uint64_t cpuRev, uint8_t procPkg) { + + + static u32 power_up_down(int node, u8 procPkg) { +- u32 dword=0; +- /* from CPU rev guide #41322 rev 3.74 June 2010 Table 26 */ +- u8 singleLinkFlag = ((procPkg == AMD_PKGTYPE_AM3_2r2) +- || (procPkg == AMD_PKGTYPE_S1gX) +- || (procPkg == AMD_PKGTYPE_ASB2)); +- +- if (singleLinkFlag) { +- /* +- * PowerStepUp=01000b - 50nS +- * PowerStepDown=01000b - 50ns +- */ +- dword |= PW_STP_UP50 | PW_STP_DN50; +- } else { +- u32 dispRefModeEn = (pci_read_config32(NODE_PCI(node,0),0x68) >> 24) & 1; +- u32 isocEn = 0; +- int j; +- for(j=0 ; (j<4) && (!isocEn) ; j++ ) { +- u8 offset; +- if (AMD_CpuFindCapability(node, j, &offset)) { +- isocEn = (pci_read_config32(NODE_PCI(node,0),offset+4) >>12) & 1; +- } +- } +- +- if (dispRefModeEn || isocEn) { +- dword |= PW_STP_UP50 | PW_STP_DN50 ; +- } else { +- /* get number of cores for PowerStepUp & PowerStepDown in server +- 1 core - 400nS - 0000b +- 2 cores - 200nS - 0010b +- 3 cores - 133nS -> 100nS - 0011b +- 4 cores - 100nS - 0011b ++ uint32_t dword=0; ++ /* from CPU rev guide #41322 rev 3.74 June 2010 Table 26 */ ++ u8 singleLinkFlag = ((procPkg == AMD_PKGTYPE_AM3_2r2) ++ || (procPkg == AMD_PKGTYPE_S1gX) ++ || (procPkg == AMD_PKGTYPE_ASB2)); ++ ++ if (singleLinkFlag) { ++ /* ++ * PowerStepUp=01000b - 50nS ++ * PowerStepDown=01000b - 50ns + */ +- switch (get_core_num_in_bsp(node)) { +- case 0: +- dword |= PW_STP_UP400 | PW_STP_DN400; +- break; +- case 1: +- case 2: +- dword |= PW_STP_UP200 | PW_STP_DN200; +- break; +- case 3: +- dword |= PW_STP_UP100 | PW_STP_DN100; +- break; +- default: ++ dword |= PW_STP_UP50 | PW_STP_DN50; ++ } else { ++ uint32_t dispRefModeEn = (pci_read_config32(NODE_PCI(node,0),0x68) >> 24) & 1; ++ uint32_t isocEn = 0; ++ int j; ++ for (j=0 ; (j<4) && (!isocEn) ; j++ ) { ++ u8 offset; ++ if (AMD_CpuFindCapability(node, j, &offset)) { ++ isocEn = (pci_read_config32(NODE_PCI(node,0),offset+4) >>12) & 1; ++ } ++ } ++ ++ if (is_fam15h()) { ++ /* Family 15h always uses 100ns for multilink processors */ + dword |= PW_STP_UP100 | PW_STP_DN100; +- break; ++ } else if (dispRefModeEn || isocEn) { ++ dword |= PW_STP_UP50 | PW_STP_DN50 ; ++ } else { ++ /* get number of cores for PowerStepUp & PowerStepDown in server ++ * 1 core - 400nS - 0000b ++ * 2 cores - 200nS - 0010b ++ * 3 cores - 133nS -> 100nS - 0011b ++ * 4 cores - 100nS - 0011b ++ */ ++ switch (get_core_num_in_bsp(node)) { ++ case 0: ++ dword |= PW_STP_UP400 | PW_STP_DN400; ++ break; ++ case 1: ++ case 2: ++ dword |= PW_STP_UP200 | PW_STP_DN200; ++ break; ++ case 3: ++ dword |= PW_STP_UP100 | PW_STP_DN100; ++ break; ++ default: ++ dword |= PW_STP_UP100 | PW_STP_DN100; ++ break; ++ } + } +- } + } +- return dword; ++ ++ return dword; + } + + static void config_clk_power_ctrl_reg0(uint8_t node, uint64_t cpuRev, uint8_t procPkg) { +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch new file mode 100644 index 0000000..27a9b98 --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch @@ -0,0 +1,3928 @@ +From 310546dc0a509f88352862a109b85bd6ee8fd3b8 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:08 -0600 +Subject: [PATCH 43/45] mainboard/asus/kcma-d8: Add copy of ASUS KGPE-D16 board + for initial support work + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kcma-d8/Kconfig | 103 ++++ + src/mainboard/asus/kcma-d8/Kconfig.name | 2 + + src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl | 367 +++++++++++++ + src/mainboard/asus/kcma-d8/acpi_tables.c | 109 ++++ + src/mainboard/asus/kcma-d8/board_info.txt | 5 + + src/mainboard/asus/kcma-d8/bootblock.c | 52 ++ + src/mainboard/asus/kcma-d8/cmos.default | 30 ++ + src/mainboard/asus/kcma-d8/cmos.layout | 155 ++++++ + src/mainboard/asus/kcma-d8/devicetree.cb | 247 +++++++++ + src/mainboard/asus/kcma-d8/dsdt.asl | 789 ++++++++++++++++++++++++++++ + src/mainboard/asus/kcma-d8/get_bus_conf.c | 121 +++++ + src/mainboard/asus/kcma-d8/irq_tables.c | 128 +++++ + src/mainboard/asus/kcma-d8/mainboard.c | 116 ++++ + src/mainboard/asus/kcma-d8/mainboard.c.orig | 116 ++++ + src/mainboard/asus/kcma-d8/mb_sysconf.h | 40 ++ + src/mainboard/asus/kcma-d8/mptable.c | 231 ++++++++ + src/mainboard/asus/kcma-d8/resourcemap.c | 550 +++++++++++++++++++ + src/mainboard/asus/kcma-d8/romstage.c | 608 +++++++++++++++++++++ + 18 files changed, 3769 insertions(+) + create mode 100644 src/mainboard/asus/kcma-d8/Kconfig + create mode 100644 src/mainboard/asus/kcma-d8/Kconfig.name + create mode 100644 src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl + create mode 100644 src/mainboard/asus/kcma-d8/acpi_tables.c + create mode 100644 src/mainboard/asus/kcma-d8/board_info.txt + create mode 100644 src/mainboard/asus/kcma-d8/bootblock.c + create mode 100644 src/mainboard/asus/kcma-d8/cmos.default + create mode 100644 src/mainboard/asus/kcma-d8/cmos.layout + create mode 100644 src/mainboard/asus/kcma-d8/devicetree.cb + create mode 100644 src/mainboard/asus/kcma-d8/dsdt.asl + create mode 100644 src/mainboard/asus/kcma-d8/get_bus_conf.c + create mode 100644 src/mainboard/asus/kcma-d8/irq_tables.c + create mode 100644 src/mainboard/asus/kcma-d8/mainboard.c + create mode 100644 src/mainboard/asus/kcma-d8/mainboard.c.orig + create mode 100644 src/mainboard/asus/kcma-d8/mb_sysconf.h + create mode 100644 src/mainboard/asus/kcma-d8/mptable.c + create mode 100644 src/mainboard/asus/kcma-d8/resourcemap.c + create mode 100644 src/mainboard/asus/kcma-d8/romstage.c + +diff --git a/src/mainboard/asus/kcma-d8/Kconfig b/src/mainboard/asus/kcma-d8/Kconfig +new file mode 100644 +index 0000000..23c91f0 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/Kconfig +@@ -0,0 +1,103 @@ ++if BOARD_ASUS_KGPE_D16 ++ ++config BOARD_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ select CPU_AMD_SOCKET_G34_NON_AGESA ++ select DIMM_DDR3 ++ select DIMM_REGISTERED ++ # select QRANK_DIMM_SUPPORT ++ select DIMM_VOLTAGE_SET_SUPPORT ++ select NORTHBRIDGE_AMD_AMDFAM10 ++ select SOUTHBRIDGE_AMD_SR5650 ++ select SOUTHBRIDGE_AMD_SB700 ++ select SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA ++ select SOUTHBRIDGE_AMD_SUBTYPE_SP5100 ++ select SUPERIO_WINBOND_W83667HG_A ++ select PARALLEL_CPU_INIT ++ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK ++ select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK ++ select HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK ++ select HAVE_HARD_RESET ++ select HAVE_OPTION_TABLE ++ select HAVE_CMOS_DEFAULT ++ select HAVE_PIRQ_TABLE ++ select HAVE_MP_TABLE ++ select HAVE_ACPI_TABLES ++ select SB_HT_CHAIN_UNITID_OFFSET_ONLY ++ select LIFT_BSP_APIC_ID ++ select BOARD_ROMSIZE_KB_2048 ++ select ENABLE_APIC_EXT_ID ++ select MMCONF_SUPPORT_DEFAULT ++ select SPI_FLASH ++ select SPI_FLASH_WINBOND ++ select HAVE_ACPI_RESUME ++ select DRIVERS_I2C_W83795 ++ select DRIVERS_ASPEED_AST2050 ++ select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG ++ ++config MAINBOARD_DIR ++ string ++ default "asus/kgpe-d16" ++ ++config BOOTBLOCK_MAINBOARD_INIT ++ string ++ default "mainboard/asus/kgpe-d16/bootblock.c" ++ ++config DCACHE_RAM_BASE ++ hex ++ default 0xc2000 ++ ++config DCACHE_RAM_SIZE ++ hex ++ default 0x1e000 ++ ++config APIC_ID_OFFSET ++ hex ++ default 0 ++ ++config MAINBOARD_PART_NUMBER ++ string ++ default "KGPE-D16" ++ ++config HW_MEM_HOLE_SIZEK ++ hex ++ default 0x100000 ++ ++config MAX_CPUS ++ int ++ default 32 ++ ++# 2 (internal) processors per G34 socket ++config MAX_PHYSICAL_CPUS ++ int ++ default 4 ++ ++config HT_CHAIN_UNITID_BASE ++ hex ++ default 0x0 ++ ++config HT_CHAIN_END_UNITID_BASE ++ hex ++ default 0x20 ++ ++config IRQ_SLOT_COUNT ++ int ++ default 13 ++ ++config SOUTHBRIDGE_AMD_SB700_SATA_PORT_COUNT_BITFIELD ++ hex ++ default 0x3f ++ ++config ONBOARD_VGA_IS_PRIMARY ++ bool ++ default y ++ ++config MAINBOARD_POWER_ON_AFTER_POWER_FAIL ++ bool ++ default y ++ ++config MAX_REBOOT_CNT ++ int ++ default 10 ++ ++endif # BOARD_ASUS_KGPE_D16 +diff --git a/src/mainboard/asus/kcma-d8/Kconfig.name b/src/mainboard/asus/kcma-d8/Kconfig.name +new file mode 100644 +index 0000000..bdfa31a +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/Kconfig.name +@@ -0,0 +1,2 @@ ++config BOARD_ASUS_KGPE_D16 ++ bool "KGPE-D16" +diff --git a/src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl b/src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl +new file mode 100644 +index 0000000..a4d5b2a +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl +@@ -0,0 +1,367 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Raptor Engineering ++ * Copyright (C) 2009 Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/* Port 80 POST card debug */ ++OperationRegion (DBG0, SystemIO, 0x80, One) ++ Field (DBG0, ByteAcc, NoLock, Preserve) { ++ DBG8, 8 ++} ++ ++/* SuperIO control port */ ++Name (SPIO, 0x2E) ++ ++/* SuperIO control map */ ++OperationRegion (SPIM, SystemIO, SPIO, 0x02) ++ Field (SPIM, ByteAcc, NoLock, Preserve) { ++ INDX, 8, ++ DATA, 8 ++} ++ ++/* SuperIO control registers */ ++IndexField (INDX, DATA, ByteAcc, NoLock, Preserve) { ++ Offset (0x07), ++ CR07, 8, /* Logical device number */ ++ Offset (0x2C), ++ CR2C, 8, /* GPIO3 multiplexed pin selection */ ++ Offset (0x30), ++ CR30, 8, /* Logical device activation control register */ ++ Offset (0xE0), ++ CRE0, 8, /* Wake control register */ ++ Offset (0xE4), ++ CRE4, 8, /* Standby power control register */ ++ Offset (0xE6), ++ CRE6, 8, /* Mouse wake event configuration register */ ++ Offset (0xF1), ++ CRF1, 8, /* GPIO3 data register */ ++ Offset (0xF3), ++ CRF3, 8, /* SUSLED mode register */ ++ Offset (0xF6), ++ CRF6, 8, /* SMI/PME event generation control register */ ++ Offset (0xF9), ++ CRF9, 8, /* ACPI PME configuration register */ ++} ++ ++/* Power Management I/O registers */ ++OperationRegion(PIOR, SystemIO, 0x00000CD6, 0x00000002) ++ Field(PIOR, ByteAcc, NoLock, Preserve) { ++ PIOI, 0x00000008, ++ PIOD, 0x00000008, ++} ++IndexField (PIOI, PIOD, ByteAcc, NoLock, Preserve) { ++ Offset(0x00), /* MiscControl */ ++ , 1, ++ T1EE, 1, ++ T2EE, 1, ++ Offset(0x01), /* MiscStatus */ ++ , 1, ++ T1E, 1, ++ T2E, 1, ++ Offset(0x04), /* SmiWakeUpEventEnable3 */ ++ , 7, ++ SSEN, 1, ++ Offset(0x07), /* SmiWakeUpEventStatus3 */ ++ , 7, ++ CSSM, 1, ++ Offset(0x10), /* AcpiEnable */ ++ , 6, ++ PWDE, 1, ++ Offset(0x1C), /* ProgramIoEnable */ ++ , 3, ++ MKME, 1, ++ IO3E, 1, ++ IO2E, 1, ++ IO1E, 1, ++ IO0E, 1, ++ Offset(0x1D), /* IOMonitorStatus */ ++ , 3, ++ MKMS, 1, ++ IO3S, 1, ++ IO2S, 1, ++ IO1S, 1, ++ IO0S,1, ++ Offset(0x20), /* AcpiPmEvtBlk */ ++ APEB, 16, ++ Offset(0x36), /* GEvtLevelConfig */ ++ , 6, ++ ELC6, 1, ++ ELC7, 1, ++ Offset(0x37), /* GPMLevelConfig0 */ ++ , 3, ++ PLC0, 1, ++ PLC1, 1, ++ PLC2, 1, ++ PLC3, 1, ++ PLC8, 1, ++ Offset(0x38), /* GPMLevelConfig1 */ ++ , 1, ++ PLC4, 1, ++ PLC5, 1, ++ , 1, ++ PLC6, 1, ++ PLC7, 1, ++ Offset(0x3B), /* PMEStatus1 */ ++ GP0S, 1, ++ GM4S, 1, ++ GM5S, 1, ++ APS, 1, ++ GM6S, 1, ++ GM7S, 1, ++ GP2S, 1, ++ STSS, 1, ++ Offset(0x55), /* SoftPciRst */ ++ SPRE, 1, ++ , 1, ++ , 1, ++ PNAT, 1, ++ PWMK, 1, ++ PWNS, 1, ++ ++ /* Offset(0x61), */ /* Options_1 */ ++ /* ,7, */ ++ /* R617,1, */ ++ ++ Offset(0x65), /* UsbPMControl */ ++ , 4, ++ URRE, 1, ++ , 2, ++ BCDL, 1, ++ Offset(0x68), /* MiscEnable68 */ ++ , 2, ++ MAPC, 1, ++ TMTE, 1, ++ , 1, ++ Offset(0x7C), /* MiscEnable7C */ ++ , 2, ++ BLNK, 2, ++ Offset(0x92), /* GEVENTIN */ ++ , 7, ++ E7IS, 1, ++ Offset(0x96), /* GPM98IN */ ++ G8IS, 1, ++ G9IS, 1, ++ Offset(0x9A), /* EnhanceControl */ ++ ,7, ++ HPDE, 1, ++ Offset(0xA8), /* PIO7654Enable */ ++ IO4E, 1, ++ IO5E, 1, ++ IO6E, 1, ++ IO7E, 1, ++ Offset(0xA9), /* PIO7654Status */ ++ IO4S, 1, ++ IO5S, 1, ++ IO6S, 1, ++ IO7S, 1, ++} ++ ++/* PM1 Event Block ++ * First word is PM1_Status, Second word is PM1_Enable ++ */ ++OperationRegion(P1EB, SystemIO, APEB, 0x04) ++ Field(P1EB, ByteAcc, NoLock, Preserve) { ++ TMST, 1, ++ , 3, ++ BMST, 1, ++ GBST, 1, ++ Offset(0x01), ++ PBST, 1, ++ , 1, ++ RTST, 1, ++ , 3, ++ PWST, 1, ++ SPWS, 1, ++ Offset(0x02), ++ TMEN, 1, ++ , 4, ++ GBEN, 1, ++ Offset(0x03), ++ PBEN, 1, ++ , 1, ++ RTEN, 1, ++ , 3, ++ PWDA, 1, ++} ++ ++/* Wake status package */ ++Name(WKST,Package() {Zero, Zero}) ++ ++/* ++ * \_WAK System Wake method ++ * ++ * Entry: ++ * Arg0=The value of the sleeping state S1=1, S2=2 ++ * ++ * Exit: ++ * Return package of 2 DWords ++ * Dword 1 - Status ++ * 0x00000000 wake succeeded ++ * 0x00000001 Wake was signaled but failed due to lack of power ++ * 0x00000002 Wake was signaled but failed due to thermal condition ++ * Dword 2 - Power Supply state ++ * if non-zero the effective S-state the power supply entered ++ */ ++Method(\_WAK, 1) { ++ Store (0x20, DBG8) ++ ++ /* Set up LEDs */ ++ /* Set power LED to steady on */ ++ Store(0x0, BLNK) ++ ++ /* Configure SuperIO for wake */ ++ /* Access SuperIO ACPI device */ ++ Store(0x87, INDX) ++ Store(0x87, INDX) ++ Store(0x0A, CR07) ++ ++ if (LEqual(Arg0, One)) /* Resuming from power state S1 */ ++ { ++ /* Deactivate the ACPI device */ ++ Store(Zero, CR30) ++ ++ /* Disable PS/2 SMI/PME events */ ++ And(CRF6, 0xCF, CRF6) ++ } ++ if (Lor(LEqual(Arg0, 0x03), LEqual(Arg0, 0x04))) /* Resuming from power state S3 or S4 */ ++ { ++ /* Disable PS/2 wake */ ++ And(CRE0, 0x1D, CRE0) ++ And(CRE6, 0x7F, CRE6) ++ } ++ ++ /* Restore default SuperIO access */ ++ Store(0xAA, INDX) ++ ++ Store (0x21, DBG8) ++ ++ /* Re-enable HPET */ ++ Store(1, HPDE) ++ ++ /* Restore PCIRST# so it resets USB */ ++ if (LEqual(Arg0, 3)){ ++ Store(1, URRE) ++ } ++ ++ /* Configure southbridge for wake */ ++ /* Arbitrarily clear PciExpWakeStatus */ ++ Store(PWST, PWST) ++ ++ Store (0x22, DBG8) ++ ++ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ ++ Return(WKST) ++} ++ ++/* ++ * \_PTS - Prepare to Sleep method ++ * ++ * Entry: ++ * Arg0=The value of the sleeping state S1=1, S2=2, etc ++ * ++ * Exit: ++ * -none- ++ * ++ * The _PTS control method is executed at the beginning of the sleep process ++ * for S1-S5. The sleeping value is passed to the _PTS control method. This ++ * control method may be executed a relatively long time before entering the ++ * sleep state and the OS may abort the operation without notification to ++ * the ACPI driver. This method cannot modify the configuration or power ++ * state of any device in the system. ++ */ ++Method(\_PTS, 1) { ++ Store (Arg0, DBG8) ++ ++ /* Set up LEDs */ ++ if (LEqual(Arg0, One)) /* Power state S1 requested */ ++ { ++ /* Set suspend LED to 0.25Hz toggle pulse with 50% duty cycle */ ++ Store(0x2, BLNK) ++ } ++ ++ /* Configure SuperIO for sleep */ ++ /* Access SuperIO ACPI device */ ++ Store(0x87, INDX) ++ Store(0x87, INDX) ++ Store(0x0A, CR07) ++ ++ /* Disable PS/2 wakeup and connect PANSW_IN to PANSW_OUT */ ++ And(CRE0, 0x1F, CRE0) ++ ++ if (LEqual(Arg0, One)) /* Power state S1 requested */ ++ { ++ /* Activate the ACPI device */ ++ Store(One, CR30) ++ ++ /* Disable SMI/PME events for: ++ * LPT ++ * FDC ++ * UART ++ */ ++ Store(0x00, CRF6) ++ ++ /* Enable PS/2 keyboard SMI/PME events */ ++ Or(CRF6, 0x10, CRF6) ++ ++ /* Enable PS/2 keyboard wake */ ++ Or(CRE0, 0x40, CRE0) ++ ++ /* Enable PS/2 mouse SMI/PME events */ ++ Or(CRF6, 0x20, CRF6) ++ ++ /* Enable PS/2 mouse wake */ ++ Or(CRE0, 0x20, CRE0) ++ } else { ++ /* Enable PS/2 keyboard wake on any keypress */ ++ Or(CRE0, 0x41, CRE0) ++ ++ /* Enable PS/2 mouse wake on any click */ ++ Or(CRE0, 0x22, CRE0) ++ Or(CRE6, 0x80, CRE6) ++ ++ if (LEqual(Arg0, 0x03)) /* Power state S3 requested */ ++ { ++ /* Set VSBGATE# to provide standby power during S3 */ ++ Or(CRE4, 0x10, CRE4) ++ } ++ } ++ ++ /* Restore default SuperIO access */ ++ Store(0xAA, INDX) ++ ++ Store (0x10, DBG8) ++ ++ /* Don't allow PCIRST# to reset USB */ ++ if (LEqual(Arg0, 3)){ ++ Store(0, URRE) ++ } ++ ++ /* Configure southbridge for sleep */ ++ /* Use bus clock for delay timebase */ ++ Store(0, BCDL) ++ /* Defer APIC interrupts until first ACPI access */ ++ Store(One, MAPC) ++ ++ /* On older chips, clear PciExpWakeDisEn */ ++ // if (LLessEqual(SBRI, 0x13)) { ++ // Store(0, PWDE) ++ // } ++ ++ Store (0x11, DBG8) ++ ++ /* Clear wake status structure. */ ++ Store(0, Index(WKST,0)) ++ Store(0, Index(WKST,1)) ++} +diff --git a/src/mainboard/asus/kcma-d8/acpi_tables.c b/src/mainboard/asus/kcma-d8/acpi_tables.c +new file mode 100644 +index 0000000..f20e837 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/acpi_tables.c +@@ -0,0 +1,109 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <string.h> ++#include <arch/acpi.h> ++#include <arch/ioapic.h> ++#include <device/pci.h> ++#include <device/pci_ids.h> ++#include <cpu/x86/msr.h> ++#include <cpu/amd/mtrr.h> ++#include <cpu/amd/amdfam10_sysconf.h> ++ ++#include "mb_sysconf.h" ++ ++unsigned long acpi_fill_madt(unsigned long current) ++{ ++ device_t dev; ++ u32 dword; ++ u32 gsi_base=0; ++ uint32_t apicid_sp5100; ++ uint32_t apicid_sr5650; ++ /* create all subtables for processors */ ++ current = acpi_create_madt_lapics(current); ++ ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ apicid_sp5100 = 0x0; ++ else ++ apicid_sp5100 = 0x20; ++ apicid_sr5650 = apicid_sp5100 + 1; ++ ++ /* Write SB700 IOAPIC, only one */ ++ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, apicid_sp5100, ++ IO_APIC_ADDR, gsi_base); ++ /* IOAPIC on rs5690 */ ++ gsi_base += 24; /* SB700 has 24 IOAPIC entries. */ ++ dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ if (dev) { ++ pci_write_config32(dev, 0xF8, 0x1); ++ dword = pci_read_config32(dev, 0xFC) & 0xfffffff0; ++ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, apicid_sr5650, ++ dword, gsi_base); ++ } ++ ++ /* bus, source, gsirq, flags */ ++ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) ++ current, 0, 0, 2, 0); ++ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) ++ current, 0, 9, 9, 0xf); ++ ++ /* create all subtables for processors */ ++ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0xff, 0, 1); ++ /* 1: LINT1 connect to NMI */ ++ ++ return current; ++} ++ ++unsigned long acpi_fill_ivrs_ioapic(acpi_ivrs_t* ivrs, unsigned long current) ++{ ++ uint8_t *p; ++ ++ uint32_t apicid_sp5100; ++ uint32_t apicid_sr5650; ++ ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ apicid_sp5100 = 0x0; ++ else ++ apicid_sp5100 = 0x20; ++ apicid_sr5650 = apicid_sp5100 + 1; ++ ++ /* Describe NB IOAPIC */ ++ p = (uint8_t *)current; ++ p[0] = 0x48; /* Entry type */ ++ p[1] = 0; /* Device */ ++ p[2] = 0; /* Bus */ ++ p[3] = 0x0; /* Data */ ++ p[4] = apicid_sr5650; /* IOAPIC ID */ ++ p[5] = 0x1; /* Device 0 Function 1 */ ++ p[6] = 0x0; /* Northbridge bus */ ++ p[7] = 0x1; /* Variety */ ++ current += 8; ++ ++ /* Describe SB IOAPIC */ ++ p = (uint8_t *)current; ++ p[0] = 0x48; /* Entry type */ ++ p[1] = 0; /* Device */ ++ p[2] = 0; /* Bus */ ++ p[3] = 0xd7; /* Data */ ++ p[4] = apicid_sp5100; /* IOAPIC ID */ ++ p[5] = 0x14 << 3; /* Device 0x14 Function 0 */ ++ p[6] = 0x0; /* Southbridge bus */ ++ p[7] = 0x1; /* Variety */ ++ current += 8; ++ ++ return current; ++} +\ No newline at end of file +diff --git a/src/mainboard/asus/kcma-d8/board_info.txt b/src/mainboard/asus/kcma-d8/board_info.txt +new file mode 100644 +index 0000000..788888e +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/board_info.txt +@@ -0,0 +1,5 @@ ++Category: server ++ROM package: PLCC-32 ++ROM protocol: LPC ++ROM socketed: y ++Flashrom support: y +\ No newline at end of file +diff --git a/src/mainboard/asus/kcma-d8/bootblock.c b/src/mainboard/asus/kcma-d8/bootblock.c +new file mode 100644 +index 0000000..6f2c0a1 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/bootblock.c +@@ -0,0 +1,52 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan@alterapraxis.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <arch/io.h> ++#include <pc80/mc146818rtc.h> ++ ++void bootblock_mainboard_init(void) ++{ ++ uint8_t recovery_enabled; ++ unsigned char addr; ++ unsigned char byte; ++ ++ bootblock_northbridge_init(); ++ bootblock_southbridge_init(); ++ ++ /* Recovery jumper is connected to SP5100 GPIO61, and clears the GPIO when placed in the Recovery position */ ++ byte = pci_io_read_config8(PCI_DEV(0, 0x14, 0), 0x56); ++ byte |= 0x1 << 4; /* Set GPIO61 to input mode */ ++ pci_io_write_config8(PCI_DEV(0, 0x14, 0), 0x56, byte); ++ recovery_enabled = (!(pci_io_read_config8(PCI_DEV(0, 0x14, 0), 0x57) & 0x1)); ++ if (recovery_enabled) { ++#if CONFIG_USE_OPTION_TABLE ++ /* Clear NVRAM checksum */ ++ for (addr = LB_CKS_RANGE_START; addr <= LB_CKS_RANGE_END; addr++) { ++ cmos_write(0x0, addr); ++ } ++ ++ /* Set fallback boot */ ++ byte = cmos_read(RTC_BOOT_BYTE); ++ byte &= 0xfc; ++ cmos_write(byte, RTC_BOOT_BYTE); ++#else ++ /* FIXME ++ * Figure out how to recover if the option table is not available ++ */ ++#endif ++ } ++} +diff --git a/src/mainboard/asus/kcma-d8/cmos.default b/src/mainboard/asus/kcma-d8/cmos.default +new file mode 100644 +index 0000000..0e7afb3 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/cmos.default +@@ -0,0 +1,30 @@ ++baud_rate = 115200 ++debug_level = Spew ++multi_core = Enable ++slow_cpu = off ++compute_unit_siblings = Enable ++iommu = Enable ++nmi = Disable ++hypertransport_speed_limit = Auto ++max_mem_clock = DDR3-1600 ++minimum_memory_voltage = 1.5V ++dimm_spd_checksum = Enforce ++ECC_memory = Enable ++ECC_redirection = Enable ++ecc_scrub_rate = 1.28us ++interleave_chip_selects = Enable ++interleave_nodes = Disable ++interleave_memory_channels = Enable ++cpu_c_states = Enable ++cpu_cc6_state = Enable ++cpu_core_boost = Enable ++sata_ahci_mode = Enable ++sata_alpm = Disable ++maximum_p_state_limit = 0xf ++probe_filter = Auto ++l3_cache_partitioning = Disable ++ieee1394_controller = Enable ++gart = Enable ++experimental_memory_speed_boost = Disable ++power_on_after_fail = On ++boot_option = Fallback +diff --git a/src/mainboard/asus/kcma-d8/cmos.layout b/src/mainboard/asus/kcma-d8/cmos.layout +new file mode 100644 +index 0000000..075388e +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/cmos.layout +@@ -0,0 +1,155 @@ ++## ++## This file is part of the coreboot project. ++## ++## Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++## Copyright (C) 2007 AMD ++## Written by Yinghai Lu <yinghailu@amd.com> for AMD. ++## ++## This program is free software; you can redistribute it and/or modify ++## it under the terms of the GNU General Public License as published by ++## the Free Software Foundation; either version 2 of the License, or ++## (at your option) any later version. ++## ++## This program is distributed in the hope that it will be useful, ++## but WITHOUT ANY WARRANTY; without even the implied warranty of ++## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++## GNU General Public License for more details. ++## ++ ++entries ++ ++0 384 r 0 reserved_memory ++384 1 e 4 boot_option ++388 4 r 0 reboot_bits ++393 3 e 5 baud_rate ++396 5 e 10 ecc_scrub_rate ++401 1 e 1 interleave_chip_selects ++402 1 e 1 interleave_nodes ++403 1 e 1 interleave_memory_channels ++404 4 e 8 max_mem_clock ++408 1 e 2 multi_core ++412 4 e 6 debug_level ++440 4 e 9 slow_cpu ++444 1 e 1 nmi ++445 1 e 1 gart ++446 2 e 3 power_on_after_fail ++456 1 e 1 ECC_memory ++457 1 e 1 ECC_redirection ++458 4 e 11 hypertransport_speed_limit ++462 2 e 12 minimum_memory_voltage ++464 1 e 2 compute_unit_siblings ++465 1 e 1 cpu_c_states ++466 1 e 1 cpu_cc6_state ++467 1 e 1 sata_ahci_mode ++468 1 e 1 sata_alpm ++469 4 h 0 maximum_p_state_limit ++473 2 e 13 dimm_spd_checksum ++475 1 e 14 probe_filter ++476 1 e 1 l3_cache_partitioning ++477 1 e 1 ieee1394_controller ++478 1 e 1 iommu ++479 1 e 1 cpu_core_boost ++480 1 e 1 experimental_memory_speed_boost ++481 1 r 0 allow_spd_nvram_cache_restore ++728 256 h 0 user_data ++984 16 h 0 check_sum ++# Reserve the extended AMD configuration registers ++1000 24 r 0 amd_reserved ++ ++ ++ ++enumerations ++ ++#ID value text ++1 0 Disable ++1 1 Enable ++2 0 Enable ++2 1 Disable ++3 0 Off ++3 1 On ++3 2 Last ++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 0 Emergency ++6 1 Alert ++6 2 Critical ++6 3 Error ++6 4 Warning ++6 5 Notice ++6 6 Information ++6 7 Debug ++6 8 Spew ++8 0 DDR3-1866 ++8 1 DDR3-1600 ++8 2 DDR3-1333 ++8 3 DDR3-1066 ++8 4 DDR3-800 ++8 5 DDR3-667 ++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% ++10 0 Disabled ++10 1 40ns ++10 2 80ns ++10 3 160ns ++10 4 320ns ++10 5 640ns ++10 6 1.28us ++10 7 2.56us ++10 8 5.12us ++10 9 10.2us ++10 10 20.5us ++10 11 41us ++10 12 81.9us ++10 13 163.8us ++10 14 327.7us ++10 15 655.4us ++10 16 1.31ms ++10 17 2.62ms ++10 18 5.24ms ++10 19 10.49ms ++10 20 20.97ms ++10 21 42ms ++10 22 84ms ++11 0 Auto ++11 1 3.2GHz ++11 2 3.0GHz ++11 3 2.8GHz ++11 4 2.6GHz ++11 5 2.4GHz ++11 6 2.2GHz ++11 7 2.0GHz ++11 8 1.8GHz ++11 9 1.6GHz ++11 10 1.4GHz ++11 11 1.2GHz ++11 12 1.0GHz ++11 13 800MHz ++11 14 600MHz ++11 15 500MHz ++12 0 1.5V ++12 1 1.35V ++12 2 1.25V ++12 3 1.15V ++13 0 Enforce ++13 1 Ignore ++13 2 Override ++14 0 Disable ++14 1 Auto ++ ++checksums ++ ++checksum 392 983 984 +diff --git a/src/mainboard/asus/kcma-d8/devicetree.cb b/src/mainboard/asus/kcma-d8/devicetree.cb +new file mode 100644 +index 0000000..8d64ac7 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/devicetree.cb +@@ -0,0 +1,247 @@ ++chip northbridge/amd/amdfam10/root_complex # Root complex ++ device cpu_cluster 0 on # (L)APIC cluster ++ chip cpu/amd/socket_F_1207 # CPU socket ++ device lapic 0 on end # Local APIC of the CPU ++ end ++ end ++ device domain 0 on # PCI domain ++ subsystemid 0x1043 0x8163 inherit ++ chip northbridge/amd/amdfam10 # Northbridge / RAM controller ++ register "maximum_memory_capacity" = "0x4000000000" # 256GB ++ device pci 18.0 on end # Link 0 == LDT 0 ++ device pci 18.0 on end # Link 1 == LDT 1 ++ device pci 18.0 on end # Link 2 == LDT 2 ++ device pci 18.0 on # Link 3 == LDT 3 [SB on link 3] ++ chip southbridge/amd/sr5650 # Primary southbridge ++ device pci 0.0 on end # HT Root Complex 0x9600 ++ device pci 0.1 on end # CLKCONFIG ++ device pci 0.2 on end # IOMMU ++ device pci 2.0 on # PCIE P2P bridge 0x9603 (GPP1 Port0) ++ # Slot # PCI E 1 / PCI E 2 ++ end ++ device pci 3.0 off end # PCIE P2P bridge 0x960b (GPP1 Port1) ++ device pci 4.0 on # PCIE P2P bridge 0x9604 (GPP3a Port0) ++ # PIKE SAS ++ end ++ device pci 5.0 off end # PCIE P2P bridge 0x9605 (GPP3a Port1) ++ device pci 6.0 off end # PCIE P2P bridge 0x9606 (GPP3a Port2) ++ device pci 7.0 off end # PCIE P2P bridge 0x9607 (GPP3a Port3) ++ device pci 8.0 off end # NB/SB Link P2P bridge ++ device pci 9.0 on # Bridge (GPP3a Port4) ++ # Onboard # NIC A ++ end ++ device pci a.0 on # Bridge (GPP3a Port5) ++ # Onboard # NIC B ++ end ++ device pci b.0 on # Bridge (GPP2 Port0) ++ # Slot # PCI E 4 ++ end ++ device pci c.0 on # Bridge (GPP2 Port1) ++ # Slot # PCI E 5 ++ end ++ device pci d.0 on # Bridge (GPP3b Port0) ++ # Slot # PCI E 3 ++ end ++ register "gpp1_configuration" = "0" # Configuration 16:0 default ++ register "gpp2_configuration" = "1" # Configuration 8:8 ++ register "gpp3a_configuration" = "2" # Configuration 4:1:1:0:0:0 ++ register "port_enable" = "0x3f1c" # Enable all ports except 0, 1, 5, 6, and 7 ++ register "pcie_settling_time" = "1000000" # Allow PIKE to be detected / configured ++ end ++ chip southbridge/amd/sb700 # Secondary southbridge ++ device pci 11.0 on end # SATA ++ device pci 12.0 on end # USB ++ device pci 12.1 on end # USB ++ device pci 12.2 on end # USB ++ device pci 13.0 on end # USB ++ device pci 13.1 on end # USB ++ device pci 13.2 on end # USB ++ device pci 14.0 on # SM ++ chip drivers/generic/generic # DIMM n-0-0-0 ++ device i2c 50 on end ++ end ++ chip drivers/generic/generic # DIMM n-0-0-1 ++ device i2c 51 on end ++ end ++ chip drivers/generic/generic # DIMM n-0-1-0 ++ device i2c 52 on end ++ end ++ chip drivers/generic/generic # DIMM n-0-1-1 ++ device i2c 53 on end ++ end ++ chip drivers/generic/generic # DIMM n-1-0-0 ++ device i2c 54 on end ++ end ++ chip drivers/generic/generic # DIMM n-1-0-1 ++ device i2c 55 on end ++ end ++ chip drivers/generic/generic # DIMM n-1-1-0 ++ device i2c 56 on end ++ end ++ chip drivers/generic/generic # DIMM n-1-1-1 ++ device i2c 57 on end ++ end ++ chip drivers/i2c/w83795 ++ register "fanin_ctl1" = "0xff" # Enable monitoring of FANIN1 - FANIN8 ++ register "fanin_ctl2" = "0x00" # Connect FANIN11 - FANIN14 to alternate functions ++ register "temp_ctl1" = "0x2a" # Enable monitoring of DTS, VSEN12, and VSEN13 ++ register "temp_ctl2" = "0x01" # Enable monitoring of TD1/TR1 ++ register "temp_dtse" = "0x03" # Enable DTS1 and DTS2 ++ register "volt_ctl1" = "0xff" # Enable monitoring of VSEN1 - VSEN8 ++ register "volt_ctl2" = "0xf7" # Enable monitoring of VSEN9 - VSEN11, 3VDD, 3VSB, and VBAT ++ register "temp1_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp1) ++ register "temp2_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp2) ++ register "temp3_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp3) ++ register "temp4_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp4) ++ register "temp5_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp5) ++ register "temp6_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp6) ++ register "temp1_source_select" = "0x00" # Use TD1/TR1 as data source for Temp1 ++ register "temp2_source_select" = "0x00" # Use TD2/TR2 as data source for Temp2 ++ register "temp3_source_select" = "0x00" # Use TD3/TR3 as data source for Temp3 ++ register "temp4_source_select" = "0x00" # Use TD4/TR4 as data source for Temp4 ++ register "temp5_source_select" = "0x00" # Use TR5 as data source for Temp5 ++ register "temp6_source_select" = "0x00" # Use TR6 as data source for Temp6 ++ register "tr1_critical_temperature" = "85" # Set TD1/TR1 critical temperature to 85°C ++ register "tr1_critical_hysteresis" = "80" # Set TD1/TR1 critical hysteresis temperature to 80°C ++ register "tr1_warning_temperature" = "70" # Set TD1/TR1 warning temperature to 70°C ++ register "tr1_warning_hysteresis" = "65" # Set TD1/TR1 warning hysteresis temperature to 65°C ++ register "dts_critical_temperature" = "85" # Set DTS (CPU) critical temperature to 85°C ++ register "dts_critical_hysteresis" = "80" # Set DTS (CPU) critical hysteresis temperature to 80°C ++ register "dts_warning_temperature" = "70" # Set DTS (CPU) warning temperature to 70°C ++ register "dts_warning_hysteresis" = "65" # Set DTS (CPU) warning hysteresis temperature to 65°C ++ register "temp1_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp2_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp3_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp4_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp5_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp6_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C ++ register "temp1_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp2_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp3_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp4_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp5_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "temp6_target_temperature" = "80" # Set Temp1 target temperature to 80°C ++ register "fan1_nonstop" = "7" # Set Fan 1 minimum speed ++ register "fan2_nonstop" = "7" # Set Fan 2 minimum speed ++ register "fan3_nonstop" = "7" # Set Fan 3 minimum speed ++ register "fan4_nonstop" = "7" # Set Fan 4 minimum speed ++ register "fan5_nonstop" = "7" # Set Fan 5 minimum speed ++ register "fan6_nonstop" = "7" # Set Fan 6 minimum speed ++ register "fan7_nonstop" = "7" # Set Fan 7 minimum speed ++ register "fan8_nonstop" = "7" # Set Fan 8 minimum speed ++ register "default_speed" = "100" # All fans to full speed on power up ++ register "fan1_duty" = "100" # Fan 1 to full speed ++ register "fan2_duty" = "100" # Fan 2 to full speed ++ register "fan3_duty" = "100" # Fan 3 to full speed ++ register "fan4_duty" = "100" # Fan 4 to full speed ++ register "fan5_duty" = "100" # Fan 5 to full speed ++ register "fan6_duty" = "100" # Fan 6 to full speed ++ register "fan7_duty" = "100" # Fan 7 to full speed ++ register "fan8_duty" = "100" # Fan 8 to full speed ++ register "vcore1_high_limit_mv" = "1500" # VCORE1 (Node 0) high limit to 1.5V ++ register "vcore1_low_limit_mv" = "900" # VCORE1 (Node 0) low limit to 0.9V ++ register "vcore2_high_limit_mv" = "1500" # VCORE2 (Node 1) high limit to 1.5V ++ register "vcore2_low_limit_mv" = "900" # VCORE2 (Node 1) low limit to 0.9V ++ register "vsen3_high_limit_mv" = "1600" # VSEN1 (Node 0 RAM voltage) high limit to 1.6V ++ register "vsen3_low_limit_mv" = "1100" # VSEN1 (Node 0 RAM voltage) low limit to 1.1V ++ register "vsen4_high_limit_mv" = "1600" # VSEN2 (Node 1 RAM voltage) high limit to 1.6V ++ register "vsen4_low_limit_mv" = "1100" # VSEN2 (Node 1 RAM voltage) low limit to 1.1V ++ register "vsen5_high_limit_mv" = "1250" # VSEN5 (Node 0 HT link voltage) high limit to 1.25V ++ register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V ++ register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V ++ register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V ++ register "vsen7_high_limit_mv" = "1250" # VSEN7 (Northbridge core voltage) high limit to 1.25V ++ register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V ++ register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V ++ register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V ++ register "vsen9_high_limit_mv" = "1250" # VSEN9 (+1.2V) high limit to 1.25V ++ register "vsen9_low_limit_mv" = "1150" # VSEN9 (+1.2V) low limit to 1.15V ++ register "vsen10_high_limit_mv" = "1150" # VSEN10 (+1.1V) high limit to 1.15V ++ register "vsen10_low_limit_mv" = "1050" # VSEN10 (+1.1V) low limit to 1.05V ++ register "vsen11_high_limit_mv" = "1625" # VSEN11 (5VSB, scaling factor ~3.2) high limit to 5.2V ++ register "vsen11_low_limit_mv" = "1500" # VSEN11 (5VSB, scaling factor ~3.2) low limit to 4.8V ++ register "vsen12_high_limit_mv" = "1083" # VSEN12 (+12V, scaling factor ~12) high limit to 13V ++ register "vsen12_low_limit_mv" = "917" # VSEN12 (+12V, scaling factor ~12) low limit to 11V ++ register "vsen13_high_limit_mv" = "1625" # VSEN13 (+5V, scaling factor ~3.2) high limit to 5.2V ++ register "vsen13_low_limit_mv" = "1500" # VSEN13 (+5V, scaling factor ~3.2) low limit to 4.8V ++ register "vdd_high_limit_mv" = "3500" # 3VDD high limit to 3.5V ++ register "vdd_low_limit_mv" = "3100" # 3VDD low limit to 3.1V ++ register "vsb_high_limit_mv" = "3500" # 3VSB high limit to 3.5V ++ register "vsb_low_limit_mv" = "3100" # 3VSB low limit to 3.1V ++ register "vbat_high_limit_mv" = "3500" # VBAT (+3V) high limit to 3.5V ++ register "vbat_low_limit_mv" = "2500" # VBAT (+3V) low limit to 2.5V ++ register "smbus_aux" = "1" # Device located on auxiliary SMBUS controller ++ device i2c 0x2f on end ++ end ++ end ++ device pci 14.1 on end # IDE 0x439c ++ device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card) ++ device pci 14.3 on # LPC 0x439d (SMBUS primary controller) ++ chip superio/winbond/w83667hg-a # Super I/O ++ device pnp 2e.0 off end # FDC; Not available on the KGPE-D16 ++ device pnp 2e.1 off end # LPT1; Not available on the KGPE-D16 ++ device pnp 2e.2 on # Com1 ++ io 0x60 = 0x3f8 ++ irq 0x70 = 4 ++ end ++ device pnp 2e.3 on # Com2 ++ io 0x60 = 0x2f8 ++ irq 0x70 = 3 ++ end ++ device pnp 2e.5 on # PS/2 keyboard & mouse ++ io 0x60 = 0x60 ++ io 0x62 = 0x64 ++ irq 0x70 = 1 ++ irq 0x72 = 12 ++ end ++ device pnp 2e.6 off end # SPI: Not available on the KGPE-D16 ++ device pnp 2e.7 off end # GIPO6789 ++ device pnp 2e.8 off end # WDT ++ device pnp 2e.9 off end # GPIO2345 ++ device pnp 2e.a on end # ACPI ++ device pnp 2e.b on # HW Monitor ++ io 0x60 = 0x290 ++ io 0x62 = 0x0000 # SB-TSI currently not implemented ++ irq 0x70 = 5 ++ end ++ device pnp 2e.c off end # PECI ++ device pnp 2e.d off end # VID_BUSSEL ++ device pnp 2e.f off end # GPIO_PP_OD ++ end ++ end ++ device pci 14.4 on # Bridge ++ device pci 1.0 on end # VGA ++ device pci 2.0 on end # FireWire ++ device pci 3.0 on # Slot ++ # Slot # PCI 0 ++ end ++ end ++ device pci 14.5 on end # USB OHCI2 0x4399 ++ end ++ end ++ device pci 18.1 on end ++ device pci 18.2 on end ++ device pci 18.3 on end ++ device pci 18.4 on end ++ device pci 18.5 on end ++ device pci 19.0 on end # Socket 0 node 1 ++ device pci 19.1 on end ++ device pci 19.2 on end ++ device pci 19.3 on end ++ device pci 19.4 on end ++ device pci 19.5 on end ++ device pci 1a.0 on end # Socket 1 node 0 ++ device pci 1a.1 on end ++ device pci 1a.2 on end ++ device pci 1a.3 on end ++ device pci 1a.4 on end ++ device pci 1a.5 on end ++ device pci 1b.0 on end # Socket 1 node 1 ++ device pci 1b.1 on end ++ device pci 1b.2 on end ++ device pci 1b.3 on end ++ device pci 1b.4 on end ++ device pci 1b.5 on end ++ end ++ end ++end +diff --git a/src/mainboard/asus/kcma-d8/dsdt.asl b/src/mainboard/asus/kcma-d8/dsdt.asl +new file mode 100644 +index 0000000..5f9195a +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/dsdt.asl +@@ -0,0 +1,789 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2005 - 2012 Advanced Micro Devices, Inc. ++ * Copyright (C) 2007-2009 coresystems GmbH ++ * Copyright (C) 2004 Nick Barker <Nick.Barker9@btinternet.com> ++ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/* ++ * WARNING: Sleep/Wake is a work in progress and is still somewhat flaky! ++ * Everything else does to the best of my knowledge... (T.P. 01/26/2015) ++ */ ++ ++/* ++ * ISA portions taken from QEMU acpi-dsdt.dsl. ++ */ ++ ++/* ++ * PCI link routing templates taken from ck804.asl and modified for this board ++ */ ++ ++DefinitionBlock ( ++ "DSDT.AML", /* Output filename */ ++ "DSDT", /* Signature */ ++ 0x03, /* DSDT Revision, needs to be 2 or higher for 64bit */ ++ "ASUS ", /* OEMID */ ++ "COREBOOT", /* TABLE ID */ ++ 0x00000001 /* OEM Revision */ ++ ) ++{ ++ #include "northbridge/amd/amdfam10/amdfam10_util.asl" ++ #include "southbridge/amd/sr5650/acpi/sr5650.asl" ++ ++ /* Some global data */ ++ Name(OSVR, 3) /* Assume nothing. WinXp = 1, Vista = 2, Linux = 3, WinCE = 4 */ ++ Name(OSV, Ones) /* Assume nothing */ ++ Name(PICM, One) /* Assume APIC */ ++ ++ /* HPET enable */ ++ Name (HPTE, 0x1) ++ ++ /* Define power states */ ++ Name (\_S0, Package () { 0x00, 0x00, 0x00, 0x00 }) /* Normal operation */ ++ Name (\_S1, Package () { 0x01, 0x01, 0x00, 0x00 }) /* Standby */ ++ Name (\_S3, Package () { 0x03, 0x03, 0x00, 0x00 }) /* Suspend to RAM */ ++ Name (\_S4, Package () { 0x04, 0x04, 0x00, 0x00 }) /* Suspend to disk */ ++ Name (\_S5, Package () { 0x05, 0x05, 0x00, 0x00 }) /* Hard power off */ ++ ++ /* The _PIC method is called by the OS to choose between interrupt ++ * routing via the i8259 interrupt controller or the APIC. ++ * ++ * _PIC is called with a parameter of 0 for i8259 configuration and ++ * with a parameter of 1 for Local Apic/IOAPIC configuration. ++ */ ++ Method (_PIC, 1, Serialized) { ++ If (Arg0) ++ { ++ \_SB.CIRQ() ++ } ++ Store (Arg0, PICM) ++ } ++ ++ /* _PR CPU0 is dynamically supplied by SSDT */ ++ /* CPU objects and _PSS entries are dynamically supplied by SSDT */ ++ ++ Scope(\_GPE) { /* Start Scope GPE */ ++ /* General event 3 */ ++ Method(_L03) { ++ /* Level-Triggered GPE */ ++ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ } ++ ++ /* General event 4 */ ++ Method(_L04) { ++ /* Level-Triggered GPE */ ++ Notify (\_SB.PCI0.PBR0, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ } ++ ++ /* Keyboard controller PME# */ ++ Method(_L08) { ++ /* Level-Triggered GPE */ ++ Notify(\_SB.PCI0.LPC.PS2K, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify(\_SB.PCI0.LPC.PS2M, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ } ++ ++ /* USB controller PME# */ ++ Method(_L0B) { ++ /* Level-Triggered GPE */ ++ Notify (\_SB.PCI0.USB0, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.USB1, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.USB2, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.USB3, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.USB4, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.USB5, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.USB6, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ } ++ ++ /* GPIO0 or GEvent8 event */ ++ Method(_L18) { ++ /* Level-Triggered GPE */ ++ Notify (\_SB.PCI0.PCE1, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.NICA, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.NICB, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.PCE4, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.PCE5, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ Notify (\_SB.PCI0.PCE3, 0x02) /* NOTIFY_DEVICE_WAKE */ ++ } ++ ++ } /* End Scope GPE */ ++ ++ /* Root of the bus hierarchy */ ++ Scope (\_SB) ++ { ++ /* Top southbridge PCI device (SR5690 + SP5100) */ ++ Device (PCI0) ++ { ++ /* BUS0 root bus */ ++ ++ Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5690) */ ++ Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */ ++ Name (_ADR, 0x00180001) ++ Name (_UID, 0x00) ++ ++ Name (HCIN, 0x00) // HC1 ++ ++ Method (_BBN, 0, NotSerialized) ++ { ++ Return (GBUS (GHCN(HCIN), GHCL(HCIN))) ++ } ++ ++ /* Operating System Capabilities Method */ ++ Method(_OSC,4) ++ { ++ /* Let OS control everything */ ++ Return (Arg3) ++ } ++ ++ External (BUSN) ++ External (MMIO) ++ External (PCIO) ++ External (SBLK) ++ External (TOM1) ++ External (HCLK) ++ External (SBDN) ++ External (HCDN) ++ External (CBST) ++ ++ /* PCI Routing Tables */ ++ Name (PR00, Package () { ++ /* PIC */ ++ /* Top southbridge device (SR5690) */ ++ /* HT Link */ ++ Package (0x04) { 0x0000FFFF, 0x00, LNKA, 0x00 }, ++ ++ /* PCI-E Slot 1 (Bridge) */ ++ Package (0x04) { 0x0002FFFF, 0x00, LNKE, 0x00 }, ++ ++ /* NIC A (Bridge) */ ++ Package (0x04) { 0x0009FFFF, 0x00, LNKF, 0x00 }, ++ ++ /* NIC B (Bridge) */ ++ Package (0x04) { 0x000AFFFF, 0x00, LNKG, 0x00 }, ++ ++ /* PCI-E Slot 4 (Bridge) */ ++ Package (0x04) { 0x000BFFFF, 0x00, LNKG, 0x00 }, ++ ++ /* PCI-E Slot 5 (Bridge) */ ++ Package (0x04) { 0x000CFFFF, 0x00, LNKG, 0x00 }, ++ ++ /* PCI-E Slot 3 (Bridge) */ ++ Package (0x04) { 0x000DFFFF, 0x00, LNKG, 0x00 }, ++ ++ /* Bottom southbridge device (SP5100) */ ++ /* SATA 0 */ ++ Package (0x04) { 0x0011FFFF, 0x00, LNKG, 0x00 }, ++ ++ /* USB 0 */ ++ Package (0x04) { 0x0012FFFF, 0x00, LNKA, 0x00 }, ++ Package (0x04) { 0x0012FFFF, 0x01, LNKB, 0x00 }, ++ Package (0x04) { 0x0012FFFF, 0x02, LNKC, 0x00 }, ++ Package (0x04) { 0x0012FFFF, 0x03, LNKD, 0x00 }, ++ ++ /* USB 1 */ ++ Package (0x04) { 0x0013FFFF, 0x00, LNKC, 0x00 }, ++ Package (0x04) { 0x0013FFFF, 0x01, LNKD, 0x00 }, ++ Package (0x04) { 0x0013FFFF, 0x02, LNKA, 0x00 }, ++ Package (0x04) { 0x0013FFFF, 0x03, LNKB, 0x00 }, ++ ++ /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */ ++ Package (0x04) { 0x0014FFFF, 0x00, LNKA, 0x00 }, ++ Package (0x04) { 0x0014FFFF, 0x01, LNKB, 0x00 }, ++ Package (0x04) { 0x0014FFFF, 0x02, LNKC, 0x00 }, ++ Package (0x04) { 0x0014FFFF, 0x03, LNKD, 0x00 }, ++ }) ++ ++ Name (AR00, Package () { ++ /* APIC */ ++ /* Top southbridge device (SR5690) */ ++ /* HT Link */ ++ Package (0x04) { 0x0000FFFF, 0x00, 0x00, 55 }, ++ ++ /* PCI-E Slot 1 (Bridge) */ ++ Package (0x04) { 0x0002FFFF, 0x00, 0x00, 52 }, ++ ++ /* NIC A (Bridge) */ ++ Package (0x04) { 0x0009FFFF, 0x00, 0x00, 53 }, ++ ++ /* NIC B (Bridge) */ ++ Package (0x04) { 0x000AFFFF, 0x00, 0x00, 54 }, ++ ++ /* PCI-E Slot 4 (Bridge) */ ++ Package (0x04) { 0x000BFFFF, 0x00, 0x00, 54 }, ++ ++ /* PCI-E Slot 5 (Bridge) */ ++ Package (0x04) { 0x000CFFFF, 0x00, 0x00, 54 }, ++ ++ /* PCI-E Slot 3 (Bridge) */ ++ Package (0x04) { 0x000DFFFF, 0x00, 0x00, 54 }, ++ ++ /* Bottom southbridge device (SP5100) */ ++ /* SATA 0 */ ++ Package (0x04) { 0x0011FFFF, 0x00, 0x00, 22 }, ++ ++ /* USB 0 */ ++ Package (0x04) { 0x0012FFFF, 0x00, 0x00, 16 }, ++ Package (0x04) { 0x0012FFFF, 0x01, 0x00, 17 }, ++ Package (0x04) { 0x0012FFFF, 0x02, 0x00, 18 }, ++ Package (0x04) { 0x0012FFFF, 0x03, 0x00, 19 }, ++ ++ /* USB 1 */ ++ Package (0x04) { 0x0013FFFF, 0x00, 0x00, 18 }, ++ Package (0x04) { 0x0013FFFF, 0x01, 0x00, 19 }, ++ Package (0x04) { 0x0013FFFF, 0x02, 0x00, 16 }, ++ Package (0x04) { 0x0013FFFF, 0x03, 0x00, 17 }, ++ ++ /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */ ++ Package (0x04) { 0x0014FFFF, 0x00, 0x00, 16 }, ++ Package (0x04) { 0x0014FFFF, 0x01, 0x00, 17 }, ++ Package (0x04) { 0x0014FFFF, 0x02, 0x00, 18 }, ++ Package (0x04) { 0x0014FFFF, 0x03, 0x00, 19 }, ++ }) ++ ++ Name (PR01, Package () { ++ /* PIC */ ++ Package (0x04) { 0x1FFFF, 0x00, LNKF, 0x00 }, ++ Package (0x04) { 0x2FFFF, 0x00, LNKE, 0x00 }, ++ Package (0x04) { 0x3FFFF, 0x00, LNKG, 0x00 }, ++ Package (0x04) { 0x3FFFF, 0x01, LNKH, 0x00 }, ++ Package (0x04) { 0x3FFFF, 0x02, LNKE, 0x00 }, ++ Package (0x04) { 0x3FFFF, 0x03, LNKF, 0x00 }, ++ }) ++ ++ Name (AR01, Package () { ++ /* APIC */ ++ Package (0x04) { 0x1FFFF, 0x00, 0x00, 21 }, ++ Package (0x04) { 0x2FFFF, 0x00, 0x00, 20 }, ++ Package (0x04) { 0x3FFFF, 0x00, 0x00, 22 }, ++ Package (0x04) { 0x3FFFF, 0x01, 0x00, 23 }, ++ Package (0x04) { 0x3FFFF, 0x02, 0x00, 20 }, ++ Package (0x04) { 0x3FFFF, 0x03, 0x00, 21 }, ++ }) ++ ++ Name (PR02, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 }, ++ }) ++ ++ Name (AR02, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 24 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 25 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 26 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 27 }, ++ }) ++ ++ Name (PR03, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKE, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKF, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKG, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKH, 0x00 }, ++ }) ++ ++ Name (AR03, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 44 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 45 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 46 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 47 }, ++ }) ++ ++ Name (PR04, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 }, ++ }) ++ ++ Name (AR04, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 48 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 49 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 50 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 51 }, ++ }) ++ ++ Name (PR05, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKH, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKE, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKF, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKG, 0x00 }, ++ }) ++ ++ Name (AR05, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 47 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 44 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 45 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 46 }, ++ }) ++ ++ Name (PR06, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 }, ++ }) ++ ++ Name (AR06, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 32 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 33 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 34 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 35 }, ++ }) ++ ++ Name (PR07, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKE, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKF, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKG, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKH, 0x00 }, ++ }) ++ ++ Name (AR07, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 36 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 37 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 38 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 39 }, ++ }) ++ ++ Name (PR08, Package () { ++ /* PIC */ ++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 }, ++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 }, ++ }) ++ ++ Name (AR08, Package () { ++ /* APIC */ ++ Package (0x04) { 0xFFFF, 0x00, 0x00, 40 }, ++ Package (0x04) { 0xFFFF, 0x01, 0x00, 41 }, ++ Package (0x04) { 0xFFFF, 0x02, 0x00, 42 }, ++ Package (0x04) { 0xFFFF, 0x03, 0x00, 43 }, ++ }) ++ ++ /* PCI Resource Tables */ ++ ++ /* PCI Resource Settings Access */ ++ Method (_CRS, 0, Serialized) ++ { ++ Name (BUF0, ResourceTemplate () ++ { ++ IO (Decode16, ++ 0x0CF8, // Address Range Minimum ++ 0x0CF8, // Address Range Maximum ++ 0x01, // Address Alignment ++ 0x08, // Address Length ++ ) ++ WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, ++ 0x0000, // Address Space Granularity ++ 0x0000, // Address Range Minimum ++ 0x0CF7, // Address Range Maximum ++ 0x0000, // Address Translation Offset ++ 0x0CF8, // Address Length ++ ,, , TypeStatic) ++ }) ++ /* Methods below use SSDT to get actual MMIO regs ++ The IO ports are from 0xd00, optionally an VGA, ++ otherwise the info from MMIO is used. ++ \_SB.GXXX(node, link) ++ */ ++ 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) ++ } ++ ++ /* PCI Routing Table Access */ ++ Method (_PRT, 0, NotSerialized) { ++ If (PICM) { ++ Return (AR00) ++ } Else { ++ Return (PR00) ++ } ++ } ++ ++ /* 0:11.0 SP5100 SATA 0 */ ++ Device(SAT0) ++ { ++ Name (_ADR, 0x00110000) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ #include "southbridge/amd/sb700/acpi/sata.asl" ++ } ++ ++ /* 0:12.0 SP5100 USB 0 */ ++ Device (USB0) ++ { ++ Name (_ADR, 0x00120000) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 0:12.1 SP5100 USB 1 */ ++ Device (USB1) ++ { ++ Name (_ADR, 0x00120001) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 0:12.2 SP5100 USB 2 */ ++ Device (USB2) ++ { ++ Name (_ADR, 0x00120002) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 0:13.0 SP5100 USB 3 */ ++ Device (USB3) ++ { ++ Name (_ADR, 0x00130000) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 0:13.1 SP5100 USB 4 */ ++ Device (USB4) ++ { ++ Name (_ADR, 0x00130001) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 0:13.2 SP5100 USB 5 */ ++ Device (USB5) ++ { ++ Name (_ADR, 0x00130002) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 0:14.1 SP5100 IDE Controller */ ++ Device (IDEC) ++ { ++ Name (_ADR, 0x00140001) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ #include "southbridge/amd/sb700/acpi/ide.asl" ++ } ++ ++ /* 0:14.3 SP5100 LPC */ ++ Device (LPC) { ++ Name (_HID, EisaId ("PNP0A05")) ++ Name (_ADR, 0x00140003) ++ ++ /* Real Time Clock Device */ ++ Device(RTC0) { ++ Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */ ++ Name(BUF0, ResourceTemplate() { ++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02) ++ }) ++ Name(BUF1, ResourceTemplate() { ++ IRQNoFlags() { 8 } ++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02) ++ }) ++ Method(_CRS, 0) { ++ If(HPTE) { ++ Return(BUF0) ++ } ++ Return(BUF1) ++ } ++ } ++ ++ Device(TMR) { /* Timer */ ++ Name(_HID,EISAID("PNP0100")) /* System Timer */ ++ Name(BUF0, ResourceTemplate() { ++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04) ++ }) ++ Name(BUF1, ResourceTemplate() { ++ IRQNoFlags() { 0 } ++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04) ++ }) ++ Method(_CRS, 0) { ++ If(HPTE) { ++ Return(BUF0) ++ } ++ Return(BUF1) ++ } ++ } ++ ++ Device(SPKR) { /* Speaker */ ++ Name(_HID,EISAID("PNP0800")) /* AT style speaker */ ++ Name(_CRS, ResourceTemplate() { ++ IO(Decode16, 0x0061, 0x0061, 0, 1) ++ }) ++ } ++ ++ Device(PIC) { ++ Name(_HID,EISAID("PNP0000")) /* AT Interrupt Controller */ ++ Name(_CRS, ResourceTemplate() { ++ IRQNoFlags() { 2 } ++ IO(Decode16,0x0020, 0x0020, 0, 2) ++ IO(Decode16,0x00A0, 0x00A0, 0, 2) ++ }) ++ } ++ ++ Device(MAD) { /* 8257 DMA */ ++ Name(_HID,EISAID("PNP0200")) /* Hardware Device ID */ ++ Name(_CRS, ResourceTemplate() { ++ DMA(Compatibility,BusMaster,Transfer8){4} ++ IO(Decode16, 0x0000, 0x0000, 0x10, 0x10) ++ IO(Decode16, 0x0081, 0x0081, 0x01, 0x03) ++ IO(Decode16, 0x0087, 0x0087, 0x01, 0x01) ++ IO(Decode16, 0x0089, 0x0089, 0x01, 0x03) ++ IO(Decode16, 0x008F, 0x008F, 0x01, 0x01) ++ IO(Decode16, 0x00C0, 0x00C0, 0x10, 0x20) ++ }) /* End Name(_SB.PCI0.LpcIsaBr.MAD._CRS) */ ++ } ++ ++ Device(COPR) { ++ Name(_HID,EISAID("PNP0C04")) /* Math Coprocessor */ ++ Name(_CRS, ResourceTemplate() { ++ IO(Decode16, 0x00F0, 0x00F0, 0, 0x10) ++ IRQNoFlags(){13} ++ }) ++ } ++ ++ #include "../../../superio/winbond/w83667hg-a/ps2_controller.asl" ++ ++ /* UART 1 */ ++ Device (URT1) ++ { ++ Name (_HID, EisaId ("PNP0501")) // "PNP0501" for UART ++ Name(_PRW, Package () {0x03, 0x04}) // Wake from S1-S4 ++ Method (_STA, 0, NotSerialized) ++ { ++ Return (0x0f) // Always enable ++ } ++ Name (_PRS, ResourceTemplate() { ++ StartDependentFn(0, 1) { ++ IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8) ++ IRQNoFlags() { 4 } ++ } EndDependentFn() ++ }) ++ Method (_CRS, 0) ++ { ++ Return(ResourceTemplate() { ++ IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8) ++ IRQNoFlags() { 4 } ++ }) ++ } ++ } ++ } ++ ++ /* High Precision Event Timer */ ++ Device (HPET) ++ { ++ Name (_HID, EisaId ("PNP0103")) ++ Name (CRS, ResourceTemplate () ++ { ++ Memory32Fixed(ReadOnly, 0xFED00000, 0x00000400) ++ }) ++ Method (_STA, 0) ++ { ++ If(HPTE) { ++ Return (0x0F) ++ } ++ Return (0x0) ++ } ++ Method(_CRS, 0) ++ { ++ Return(CRS) ++ } ++ } ++ ++ /* 0:14.4 PCI Bridge */ ++ Device (PBR0) ++ { ++ Name (_ADR, 0x00140004) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR01) ++ } Else { ++ Return (PR01) ++ } ++ } ++ Device (SLT1) ++ { ++ Name (_ADR, 0xFFFF) // _ADR: Address ++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 ++ } ++ } ++ ++ /* 0:14.5 SP5100 USB 6 */ ++ Device (USB6) ++ { ++ Name (_ADR, 0x00140005) // _ADR: Address ++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4 ++ } ++ ++ /* 2:00.0 PCIe x16 */ ++ Device (PCE1) ++ { ++ Name (_ADR, 0x00020000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR02) ++ } Else { ++ Return (PR02) ++ } ++ } ++ Device (SLT1) ++ { ++ Name (_ADR, 0xFFFF) // _ADR: Address ++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 ++ } ++ } ++ ++ /* 1:00.0 PIKE */ ++ Device (PIKE) ++ { ++ Name (_ADR, 0x00040000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR03) ++ } Else { ++ Return (PR03) ++ } ++ } ++ Device (SLT1) ++ { ++ Name (_ADR, 0xFFFF) // _ADR: Address ++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 ++ } ++ } ++ ++ /* 3:00.0 PCIe NIC A */ ++ Device (NICA) ++ { ++ Name (_ADR, 0x00090000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR04) ++ } Else { ++ Return (PR04) ++ } ++ } ++ Device (BDC1) ++ { ++ Name (_ADR, Zero) // _ADR: Address ++ } ++ } ++ ++ /* 4:00.0 PCIe NIC B */ ++ Device (NICB) ++ { ++ Name (_ADR, 0x000A0000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR05) ++ } Else { ++ Return (PR05) ++ } ++ } ++ Device (BDC2) ++ { ++ Name (_ADR, Zero) // _ADR: Address ++ } ++ } ++ ++ /* 5:00.0 PCIe x16 */ ++ Device (PCE4) ++ { ++ Name (_ADR, 0x000B0000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR06) ++ } Else { ++ Return (PR06) ++ } ++ } ++ Device (SLT1) ++ { ++ Name (_ADR, 0xFFFF) // _ADR: Address ++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 ++ } ++ } ++ ++ /* 6:00.0 PCIe x16 */ ++ Device (PCE5) ++ { ++ Name (_ADR, 0x000C0000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR07) ++ } Else { ++ Return (PR07) ++ } ++ } ++ Device (SLT1) ++ { ++ Name (_ADR, 0xFFFF) // _ADR: Address ++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 ++ } ++ } ++ ++ /* 7:00.0 PCIe x16 */ ++ Device (PCE3) ++ { ++ Name (_ADR, 0x000D0000) // _ADR: Address ++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 ++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table ++ { ++ If (PICM) { ++ Return (AR08) ++ } Else { ++ Return (PR08) ++ } ++ } ++ Device (SLT1) ++ { ++ Name (_ADR, 0xFFFF) // _ADR: Address ++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 ++ } ++ } ++ } ++ ++ Device (PWRB) { /* Start Power button device */ ++ Name(_HID, EISAID("PNP0C0C")) ++ Name(_UID, 0xAA) ++ Name(_PRW, Package () {3, 0x04}) /* wake from S1-S4 */ ++ Name(_STA, 0x0B) /* sata is invisible */ ++ } ++ } ++ ++#include "acpi/pm_ctrl.asl" ++ ++} +diff --git a/src/mainboard/asus/kcma-d8/get_bus_conf.c b/src/mainboard/asus/kcma-d8/get_bus_conf.c +new file mode 100644 +index 0000000..5ebc714 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/get_bus_conf.c +@@ -0,0 +1,121 @@ ++ /* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <device/pci.h> ++#include <device/pci_ids.h> ++#include <string.h> ++#include <stdint.h> ++#include <stdlib.h> ++#include <cpu/amd/multicore.h> ++ ++#include <cpu/amd/amdfam10_sysconf.h> ++ ++/* Global variables for MB layouts and these will be shared by irqtable mptable ++* and acpi_tables busnum is default. ++*/ ++u8 bus_isa; ++u8 bus_sr5650[14]; ++u8 bus_sp5100[2]; ++u32 apicid_sp5100; ++ ++/* ++* 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 ++*/ ++u32 pci1234x[] = { ++ 0x0000ff0, ++}; ++ ++/* ++* 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 ++*/ ++u32 hcdnx[] = { ++ 0x20202020, ++}; ++ ++ ++u32 sbdn_sr5650; ++u32 sbdn_sp5100; ++ ++extern void get_pci1234(void); ++ ++static u32 get_bus_conf_done = 0; ++ ++void get_bus_conf(void) ++{ ++ u32 apicid_base; ++ device_t dev; ++ int i; ++ ++ if (get_bus_conf_done == 1) ++ return; /* do it only once */ ++ get_bus_conf_done = 1; ++ ++ sysconf.hc_possible_num = ARRAY_SIZE(pci1234x); ++ for (i = 0; i < sysconf.hc_possible_num; i++) { ++ sysconf.pci1234[i] = pci1234x[i]; ++ sysconf.hcdn[i] = hcdnx[i]; ++ } ++ ++ get_pci1234(); ++ ++ sysconf.sbdn = (sysconf.hcdn[0] & 0xff); ++ sbdn_sr5650 = sysconf.sbdn; ++ sbdn_sp5100 = 0; ++ ++ for (i = 0; i < 2; i++) { ++ bus_sp5100[i] = 0; ++ } ++ for (i = 0; i < ARRAY_SIZE(bus_sr5650); i++) { ++ bus_sr5650[i] = 0; ++ } ++ ++ ++ bus_sr5650[0] = (sysconf.pci1234[0] >> 16) & 0xff; ++ bus_sp5100[0] = bus_sr5650[0]; ++ ++ ++ /* sp5100 */ ++ dev = dev_find_slot(bus_sp5100[0], PCI_DEVFN(sbdn_sp5100 + 0x14, 4)); ++ if (dev) { ++ bus_sp5100[1] = pci_read_config8(dev, PCI_SECONDARY_BUS); ++ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); ++ bus_isa++; ++ } ++ ++ /* sr5650 */ ++ for (i = 1; i < ARRAY_SIZE(bus_sr5650); i++) { ++ dev = dev_find_slot(bus_sr5650[0], PCI_DEVFN(sbdn_sr5650 + i, 0)); ++ if (dev) { ++ bus_sr5650[i] = pci_read_config8(dev, PCI_SECONDARY_BUS); ++ if(255 != bus_sr5650[i]) { ++ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); ++ bus_isa++; ++ } ++ } ++ } ++ ++ /* I/O APICs: APIC ID Version State Address */ ++ bus_isa = 10; ++ if (IS_ENABLED(CONFIG_LOGICAL_CPUS)) ++ apicid_base = get_apicid_base(1); ++ else ++ apicid_base = CONFIG_MAX_PHYSICAL_CPUS; ++ apicid_sp5100 = apicid_base + 0; ++} +diff --git a/src/mainboard/asus/kcma-d8/irq_tables.c b/src/mainboard/asus/kcma-d8/irq_tables.c +new file mode 100644 +index 0000000..ef39db2 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/irq_tables.c +@@ -0,0 +1,128 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <device/pci_ids.h> ++#include <device/pci.h> ++#include <string.h> ++#include <stdint.h> ++#include <arch/pirq_routing.h> ++ ++#include <cpu/amd/amdfam10_sysconf.h> ++ ++/* Free irqs are 3, 4, 5, 6, 7, 9, 10, 11, 12, 14, and 15 */ ++#define IRQBM ((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<14)|(1<<15)) ++ ++#define LNKA 1 ++#define LNKB 2 ++#define LNKC 3 ++#define LNKD 4 ++ ++/* ++ * For simplicity map LNK[E-H] to LNK[A-D]. ++ * This also means we are 82C596 compatible. ++ * Needs 0:11.0 0x46[4] set to 0. ++ */ ++#define LNKE 1 ++#define LNKF 2 ++#define LNKG 3 ++#define LNKH 4 ++ ++static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn, ++ u8 link0, u16 bitmap0, u8 link1, u16 bitmap1, ++ u8 link2, u16 bitmap2, u8 link3, u16 bitmap3, ++ u8 slot, u8 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 u8 bus_isa; ++extern u8 bus_sr5650[14]; ++extern u8 bus_sp5100[2]; ++extern u32 sbdn_sp5100; ++extern u32 sbdn_sr5650; ++ ++unsigned long write_pirq_routing_table(unsigned long addr) ++{ ++ struct irq_routing_table *pirq; ++ struct irq_info *pirq_info; ++ u32 slot_num; ++ u8 *v; ++ ++ u8 sum = 0; ++ int i; ++ ++ get_bus_conf(); /* it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c */ ++ ++ /* Align the table to be 16 byte aligned. */ ++ addr += 15; ++ addr &= ~15; ++ ++ /* This table must be between 0xf0000 & 0x100000 */ ++ printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr); ++ ++ pirq = (void *)(addr); ++ v = (u8 *) (addr); ++ ++ pirq->signature = PIRQ_SIGNATURE; ++ pirq->version = PIRQ_VERSION; ++ ++ /* Where the interrupt router resides */ ++ pirq->rtr_bus = bus_sp5100[0]; ++ pirq->rtr_devfn = PCI_DEVFN(0x14, 4); ++ ++ pirq->exclusive_irqs = 0; ++ ++ pirq->rtr_vendor = PCI_VENDOR_ID_ATI; ++ pirq->rtr_device = PCI_DEVICE_ID_ATI_SB700_PCI; ++ ++ pirq->miniport_data = 0; ++ ++ memset(pirq->rfu, 0, sizeof(pirq->rfu)); ++ ++ pirq_info = (void *)(&pirq->checksum + 1); ++ slot_num = 0; ++ ++ /* pci bridge */ ++ write_pirq_info(pirq_info, bus_sp5100[0], ((sbdn_sp5100 + 0x14) << 3) | 4, ++ LNKA, IRQBM, LNKB, IRQBM, LNKC, IRQBM, LNKD, IRQBM, 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(BIOS_INFO, "done.\n"); ++ ++ return (unsigned long)pirq_info; ++} +diff --git a/src/mainboard/asus/kcma-d8/mainboard.c b/src/mainboard/asus/kcma-d8/mainboard.c +new file mode 100644 +index 0000000..65029d4 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/mainboard.c +@@ -0,0 +1,116 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <device/device.h> ++#include <device/pci.h> ++#include <arch/io.h> ++#include <cpu/x86/msr.h> ++#include <cpu/amd/mtrr.h> ++#include <device/pci_def.h> ++#include <southbridge/amd/sb700/sb700.h> ++#include <southbridge/amd/sr5650/cmn.h> ++ ++ ++void set_pcie_reset(void); ++void set_pcie_dereset(void); ++ ++void set_pcie_reset(void) ++{ ++ device_t pcie_core_dev; ++ ++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x28282828); ++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x00000028); ++} ++ ++void set_pcie_dereset(void) ++{ ++ device_t pcie_core_dev; ++ ++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x6F6F6F6F); ++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x0000006F); ++} ++ ++/************************************************* ++* enable the dedicated function in kgpe-d16 board. ++* This function is called earlier than sr5650_enable. ++*************************************************/ ++static void mainboard_enable(device_t dev) ++{ ++ printk(BIOS_INFO, "Mainboard KGPE-D16 Enable. dev=0x%p\n", dev); ++ ++ msr_t msr, msr2; ++ ++ /* TOP_MEM: the top of DRAM below 4G */ ++ msr = rdmsr(TOP_MEM); ++ printk ++ (BIOS_INFO, "%s, TOP MEM: msr.lo = 0x%08x, msr.hi = 0x%08x\n", ++ __func__, msr.lo, msr.hi); ++ ++ /* TOP_MEM2: the top of DRAM above 4G */ ++ msr2 = rdmsr(TOP_MEM2); ++ printk ++ (BIOS_INFO, "%s, TOP MEM2: msr2.lo = 0x%08x, msr2.hi = 0x%08x\n", ++ __func__, msr2.lo, msr2.hi); ++ ++ set_pcie_dereset(); ++ /* get_ide_dma66(); */ ++} ++ ++/* override the default SATA PHY setup */ ++void sb7xx_51xx_setup_sata_phys(struct device *dev) ++{ ++ /* RPR7.6.1 Program the PHY Global Control to 0x2C00 */ ++ pci_write_config16(dev, 0x86, 0x2c00); ++ ++ /* RPR7.6.2 SATA GENI PHY ports setting */ ++ pci_write_config32(dev, 0x88, 0x01b48016); ++ pci_write_config32(dev, 0x8c, 0x01b48016); ++ pci_write_config32(dev, 0x90, 0x01b48016); ++ pci_write_config32(dev, 0x94, 0x01b48016); ++ pci_write_config32(dev, 0x98, 0x01b48016); ++ pci_write_config32(dev, 0x9c, 0x01b48016); ++ ++ /* RPR7.6.3 SATA GEN II PHY port setting for port [0~5]. */ ++ pci_write_config16(dev, 0xa0, 0xa07a); ++ pci_write_config16(dev, 0xa2, 0xa07a); ++ pci_write_config16(dev, 0xa4, 0xa07a); ++ pci_write_config16(dev, 0xa6, 0xa07a); ++ pci_write_config16(dev, 0xa8, 0xa07a); ++ pci_write_config16(dev, 0xaa, 0xa07a); ++} ++ ++/* override the default SATA port setup */ ++void sb7xx_51xx_setup_sata_port_indication(void *sata_bar5) ++{ ++ uint32_t dword; ++ ++ /* RPR7.9 Program Port Indication Registers */ ++ dword = read32(sata_bar5 + 0xf8); ++ dword &= ~(0x3f << 12); /* All ports are iSATA */ ++ dword &= ~0x3f; ++ write32(sata_bar5 + 0xf8, dword); ++ ++ dword = read32(sata_bar5 + 0xfc); ++ dword &= ~(0x1 << 20); /* No eSATA ports are present */ ++ write32(sata_bar5 + 0xfc, dword); ++} ++ ++struct chip_operations mainboard_ops = { ++ .enable_dev = mainboard_enable, ++}; +diff --git a/src/mainboard/asus/kcma-d8/mainboard.c.orig b/src/mainboard/asus/kcma-d8/mainboard.c.orig +new file mode 100644 +index 0000000..65029d4 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/mainboard.c.orig +@@ -0,0 +1,116 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <device/device.h> ++#include <device/pci.h> ++#include <arch/io.h> ++#include <cpu/x86/msr.h> ++#include <cpu/amd/mtrr.h> ++#include <device/pci_def.h> ++#include <southbridge/amd/sb700/sb700.h> ++#include <southbridge/amd/sr5650/cmn.h> ++ ++ ++void set_pcie_reset(void); ++void set_pcie_dereset(void); ++ ++void set_pcie_reset(void) ++{ ++ device_t pcie_core_dev; ++ ++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x28282828); ++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x00000028); ++} ++ ++void set_pcie_dereset(void) ++{ ++ device_t pcie_core_dev; ++ ++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x6F6F6F6F); ++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x0000006F); ++} ++ ++/************************************************* ++* enable the dedicated function in kgpe-d16 board. ++* This function is called earlier than sr5650_enable. ++*************************************************/ ++static void mainboard_enable(device_t dev) ++{ ++ printk(BIOS_INFO, "Mainboard KGPE-D16 Enable. dev=0x%p\n", dev); ++ ++ msr_t msr, msr2; ++ ++ /* TOP_MEM: the top of DRAM below 4G */ ++ msr = rdmsr(TOP_MEM); ++ printk ++ (BIOS_INFO, "%s, TOP MEM: msr.lo = 0x%08x, msr.hi = 0x%08x\n", ++ __func__, msr.lo, msr.hi); ++ ++ /* TOP_MEM2: the top of DRAM above 4G */ ++ msr2 = rdmsr(TOP_MEM2); ++ printk ++ (BIOS_INFO, "%s, TOP MEM2: msr2.lo = 0x%08x, msr2.hi = 0x%08x\n", ++ __func__, msr2.lo, msr2.hi); ++ ++ set_pcie_dereset(); ++ /* get_ide_dma66(); */ ++} ++ ++/* override the default SATA PHY setup */ ++void sb7xx_51xx_setup_sata_phys(struct device *dev) ++{ ++ /* RPR7.6.1 Program the PHY Global Control to 0x2C00 */ ++ pci_write_config16(dev, 0x86, 0x2c00); ++ ++ /* RPR7.6.2 SATA GENI PHY ports setting */ ++ pci_write_config32(dev, 0x88, 0x01b48016); ++ pci_write_config32(dev, 0x8c, 0x01b48016); ++ pci_write_config32(dev, 0x90, 0x01b48016); ++ pci_write_config32(dev, 0x94, 0x01b48016); ++ pci_write_config32(dev, 0x98, 0x01b48016); ++ pci_write_config32(dev, 0x9c, 0x01b48016); ++ ++ /* RPR7.6.3 SATA GEN II PHY port setting for port [0~5]. */ ++ pci_write_config16(dev, 0xa0, 0xa07a); ++ pci_write_config16(dev, 0xa2, 0xa07a); ++ pci_write_config16(dev, 0xa4, 0xa07a); ++ pci_write_config16(dev, 0xa6, 0xa07a); ++ pci_write_config16(dev, 0xa8, 0xa07a); ++ pci_write_config16(dev, 0xaa, 0xa07a); ++} ++ ++/* override the default SATA port setup */ ++void sb7xx_51xx_setup_sata_port_indication(void *sata_bar5) ++{ ++ uint32_t dword; ++ ++ /* RPR7.9 Program Port Indication Registers */ ++ dword = read32(sata_bar5 + 0xf8); ++ dword &= ~(0x3f << 12); /* All ports are iSATA */ ++ dword &= ~0x3f; ++ write32(sata_bar5 + 0xf8, dword); ++ ++ dword = read32(sata_bar5 + 0xfc); ++ dword &= ~(0x1 << 20); /* No eSATA ports are present */ ++ write32(sata_bar5 + 0xfc, dword); ++} ++ ++struct chip_operations mainboard_ops = { ++ .enable_dev = mainboard_enable, ++}; +diff --git a/src/mainboard/asus/kcma-d8/mb_sysconf.h b/src/mainboard/asus/kcma-d8/mb_sysconf.h +new file mode 100644 +index 0000000..7db0d9f +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/mb_sysconf.h +@@ -0,0 +1,40 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef MB_SYSCONF_H ++ ++#define MB_SYSCONF_H ++ ++struct mb_sysconf_t { ++ u8 bus_isa; ++ u8 bus_8132_0; ++ u8 bus_8132_1; ++ u8 bus_8132_2; ++ u8 bus_8111_0; ++ u8 bus_8111_1; ++ u8 bus_8132a[31][3]; ++ u8 bus_8151[31][2]; ++ ++ u32 apicid_8111; ++ u32 apicid_8132_1; ++ u32 apicid_8132_2; ++ u32 apicid_8132a[31][2]; ++ u32 sbdn3; ++ u32 sbdn3a[31]; ++ u32 sbdn5[31]; ++}; ++ ++#endif +diff --git a/src/mainboard/asus/kcma-d8/mptable.c b/src/mainboard/asus/kcma-d8/mptable.c +new file mode 100644 +index 0000000..c869d31 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/mptable.c +@@ -0,0 +1,231 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2010 Advanced Micro Devices, Inc. ++ * Copyright (C) 2015 Raptor Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <console/console.h> ++#include <arch/smp/mpspec.h> ++#include <device/pci.h> ++#include <arch/io.h> ++#include <string.h> ++#include <stdint.h> ++#include <cpu/amd/amdfam10_sysconf.h> ++ ++extern u8 bus_sr5650[14]; ++extern u8 bus_sp5100[2]; ++ ++extern u32 apicid_sp5100; ++ ++extern u32 sbdn_sr5650; ++extern u32 sbdn_sp5100; ++ ++ ++static void *smp_write_config_table(void *v) ++{ ++ struct mp_config_table *mc; ++ int bus_isa; ++ u32 apicid_sr5650; ++ device_t dev; ++ uint8_t sp5100_bus_number; ++ ++ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); ++ ++ mptable_init(mc, LOCAL_APIC_ADDR); ++ ++ smp_write_processors(mc); ++ ++ get_bus_conf(); ++ ++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0)) ++ apicid_sp5100 = 0x0; ++ else ++ apicid_sp5100 = 0x20; ++ apicid_sr5650 = apicid_sp5100 + 1; ++ ++ mptable_write_buses(mc, NULL, &bus_isa); ++ /* I/O APICs: APIC ID Version State Address */ ++ { ++ uint32_t *dword_ptr; ++ uint32_t dword; ++ uint16_t word; ++ uint8_t byte; ++ ++ sp5100_bus_number = 0; //bus_sp5100[0]; TODO: why bus_sp5100[0] use same value of bus_sr5650[0] assigned by get_pci1234(), instead of 0. ++ ++ dev = dev_find_slot(sp5100_bus_number, PCI_DEVFN(sbdn_sp5100 + 0x14, 0)); ++ if (dev) { ++ dword_ptr = (u32 *)(pci_read_config32(dev, 0x74) & 0xfffffff0); ++ smp_write_ioapic(mc, apicid_sp5100, 0x11, dword_ptr); ++ ++ /* Initialize interrupt mapping */ ++ /* USB 1 & 2 */ ++ word = pci_read_config16(dev, 0xbe); ++ word &= ~0x3f3f; ++ word |= 0x0; /* 0: INTA, ...., 7: INTH */ ++ word |= (0x1 << 3); /* 0: INTA, ...., 7: INTH */ ++ word |= (0x2 << 8); /* 0: INTA, ...., 7: INTH */ ++ word |= (0x3 << 11); /* 0: INTA, ...., 7: INTH */ ++ pci_write_config16(dev, 0xbe, word); ++ ++ /* USB 3 */ ++ byte = pci_read_config8(dev, 0x63); ++ byte &= 0xf8; ++ byte |= (0x2 << 4); /* 0: INTA, ...., 7: INTH */ ++ pci_write_config8(dev, 0x63, byte); ++ ++ dword = pci_read_config32(dev, 0xac); ++ ++ /* SATA */ ++ dword &= ~(7 << 26); ++ dword |= (0x6 << 26); /* 0: INTA, ...., 7: INTH */ ++ ++ /* Hide IDE */ ++ dword &= ~(0x00080000); ++ ++ /* dword_ptr |= 1<<22; PIC and APIC co exists */ ++ pci_write_config32(dev, 0xac, dword); ++ ++ /* ++ * 00:12.0: PROG SATA : INT F ++ * 00:13.0: INTA USB_0 ++ * 00:13.1: INTB USB_1 ++ * 00:13.2: INTC USB_2 ++ * 00:13.3: INTD USB_3 ++ * 00:13.4: INTC USB_4 ++ * 00:13.5: INTD USB2 ++ * 00:14.1: INTA IDE ++ * 00:14.2: Prog HDA : INT E ++ * 00:14.5: INTB ACI ++ * 00:14.6: INTB MCI ++ */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0, 0)); ++ if (dev) { ++ pci_write_config32(dev, 0xF8, 0x1); ++ dword_ptr = (u32 *)(pci_read_config32(dev, 0xFC) & 0xfffffff0); ++ smp_write_ioapic(mc, apicid_sr5650, 0x11, dword_ptr); ++ } ++ } ++ ++ /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ ++#define IO_LOCAL_INT(type, intr, apicid, pin) \ ++ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); ++ ++ mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0); ++ ++ /* SR5650 devices */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((0)<<2)|(2)), apicid_sr5650, 31); /* Device 0 Function 2 (LNKA, APIC pin 31) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE, APIC pin 28) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF, APIC pin 28) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG, APIC pin 29) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */ ++ ++ dev = dev_find_slot(0, PCI_DEVFN(0x2, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x2)|(0)), apicid_sr5650, 0); /* card behind dev2 */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0x4, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x4)|(0)), apicid_sr5650, 0); /* PIKE */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0x9, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x9)|(0)), apicid_sr5650, 23); /* NIC A */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0xa, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xa)|(0)), apicid_sr5650, 24); /* NIC B */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0xb, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xb)|(0)), apicid_sr5650, 0); /* card behind dev11 */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0xc, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xc)|(0)), apicid_sr5650, 0); /* card behind dev12 */ ++ } ++ dev = dev_find_slot(0, PCI_DEVFN(0xd, 0)); ++ if (dev && dev->enabled) { ++ uint8_t bus_pci = dev->link_list->secondary; ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xd)|(0)), apicid_sr5650, 0); /* card behind dev13 */ ++ } ++ ++ /* PCI interrupts are level triggered, and are ++ * associated with a specific bus/device/function tuple. ++ */ ++#define PCI_INT(bus, dev, interrupt_signal, pin) \ ++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(interrupt_signal)), apicid_sp5100, (pin)) ++ ++ /* USB1 */ ++ PCI_INT(sp5100_bus_number, 0x12, 0x0, 0x10); /* OHCI0 Port 0~2 */ ++ PCI_INT(sp5100_bus_number, 0x12, 0x1, 0x11); /* OHCI1 Port 3~5 */ ++ ++ /* USB2 */ ++ PCI_INT(sp5100_bus_number, 0x13, 0x0, 0x12); /* OHCI0 Port 6~8 */ ++ PCI_INT(sp5100_bus_number, 0x13, 0x1, 0x13); /* EHCI Port 6~11 */ ++ ++ /* USB3 */ ++ PCI_INT(sp5100_bus_number, 0x14, 0x3, 0x12); /* OHCI0 Port 12~13 */ ++ ++ /* SATA */ ++ PCI_INT(sp5100_bus_number, 0x11, 0x0, 0x16); /* 6, INTG */ ++ ++ /* PCI slots */ ++ dev = dev_find_slot(0, PCI_DEVFN(0x14, 4)); ++ if (dev && dev->enabled) { ++ u8 bus_pci = dev->link_list->secondary; ++ ++ /* PCI_SLOT 0. */ ++ PCI_INT(bus_pci, 0x1, 0x0, 0x15); ++ PCI_INT(bus_pci, 0x1, 0x1, 0x16); ++ PCI_INT(bus_pci, 0x1, 0x2, 0x17); ++ PCI_INT(bus_pci, 0x1, 0x3, 0x14); ++ ++ /* PCI_SLOT 1. */ ++ PCI_INT(bus_pci, 0x2, 0x0, 0x14); ++ PCI_INT(bus_pci, 0x2, 0x1, 0x15); ++ PCI_INT(bus_pci, 0x2, 0x2, 0x16); ++ PCI_INT(bus_pci, 0x2, 0x3, 0x17); ++ ++ /* PCI_SLOT 2. */ ++ PCI_INT(bus_pci, 0x3, 0x0, 0x16); ++ PCI_INT(bus_pci, 0x3, 0x1, 0x17); ++ PCI_INT(bus_pci, 0x3, 0x2, 0x14); ++ PCI_INT(bus_pci, 0x3, 0x3, 0x15); ++ } ++ ++ /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ ++ IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0); ++ IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1); ++ /* There is no extension information... */ ++ ++ /* Compute the checksums */ ++ return mptable_finalize(mc); ++} ++ ++unsigned long write_smp_table(unsigned long addr) ++{ ++ void *v; ++ v = smp_write_floating_table(addr, 0); ++ return (unsigned long)smp_write_config_table(v); ++} +diff --git a/src/mainboard/asus/kcma-d8/resourcemap.c b/src/mainboard/asus/kcma-d8/resourcemap.c +new file mode 100644 +index 0000000..8bcb28b +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/resourcemap.c +@@ -0,0 +1,550 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * Copyright (C) 2007 AMD ++ * Written by Yinghai Lu <yinghailu@amd.com> for AMD. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++static void setup_mb_resource_map(void) ++{ ++ static const unsigned int fam15h_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(CONFIG_CBB, CONFIG_CDB, 1, 0x44), 0x0000f8f8, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x4C), 0x0000f8f8, 0x00000001, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x54), 0x0000f8f8, 0x00000002, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x5C), 0x0000f8f8, 0x00000003, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x64), 0x0000f8f8, 0x00000004, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x6C), 0x0000f8f8, 0x00000005, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x74), 0x0000f8f8, 0x00000006, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 ++ * [31: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(CONFIG_CBB, CONFIG_CDB, 1, 0x40), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x48), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x50), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x58), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x60), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x68), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x70), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 = Link 3 ++ * [ 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(CONFIG_CBB, CONFIG_CDB, 1, 0x84), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x8C), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x94), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x9C), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA4), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xAC), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB4), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xBC), 0x00000048, 0x00000000, ++ ++ /* 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(CONFIG_CBB, CONFIG_CDB, 1, 0x80), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x88), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x90), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x98), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA0), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA8), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB0), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB8), 0x000000f0, 0x00000000, ++ ++ /* 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 = Link 3 ++ * [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(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff010, /* link 1 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 independent 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(CONFIG_CBB, CONFIG_CDB, 1, 0xC0), 0xFE000FCC, 0x00001013, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC8), 0xFE000FCC, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD0), 0xFE000FCC, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 - Link 3 ++ * [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 region i ++ */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000103, /* link 1 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000, ++ ++ }; ++ ++ static const unsigned int fam10h_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(CONFIG_CBB, CONFIG_CDB, 1, 0x44), 0x0000f8f8, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x4C), 0x0000f8f8, 0x00000001, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x54), 0x0000f8f8, 0x00000002, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x5C), 0x0000f8f8, 0x00000003, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x64), 0x0000f8f8, 0x00000004, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x6C), 0x0000f8f8, 0x00000005, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x74), 0x0000f8f8, 0x00000006, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 ++ * [31: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(CONFIG_CBB, CONFIG_CDB, 1, 0x40), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x48), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x50), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x58), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x60), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x68), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x70), 0x0000f8fc, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 = Link 3 ++ * [ 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(CONFIG_CBB, CONFIG_CDB, 1, 0x84), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x8C), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x94), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x9C), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA4), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xAC), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB4), 0x00000048, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xBC), 0x00000048, 0x00000000, ++ ++ /* 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(CONFIG_CBB, CONFIG_CDB, 1, 0x80), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x88), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x90), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x98), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA0), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA8), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB0), 0x000000f0, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB8), 0x000000f0, 0x00000000, ++ ++ /* 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 = Link 3 ++ * [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(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff110, /* link 3 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 independent 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(CONFIG_CBB, CONFIG_CDB, 1, 0xC0), 0xFE000FCC, 0x00001013, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC8), 0xFE000FCC, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD0), 0xFE000FCC, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 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 - Link 3 ++ * [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 region i ++ */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000303, /* link 3 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000, ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000, ++ ++ }; ++ ++ int max; ++ uint8_t fam15h = 0; ++ uint32_t family; ++ ++ family = cpuid_eax(0x80000001); ++ family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); ++ ++ if (family >= 0x6f) ++ /* Family 15h or later */ ++ fam15h = 1; ++ ++ if (fam15h) { ++ max = ARRAY_SIZE(fam15h_register_values); ++ setup_resource_map(fam15h_register_values, max); ++ } else { ++ max = ARRAY_SIZE(fam10h_register_values); ++ setup_resource_map(fam10h_register_values, max); ++ } ++} +diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c +new file mode 100644 +index 0000000..5df6de4 +--- /dev/null ++++ b/src/mainboard/asus/kcma-d8/romstage.c +@@ -0,0 +1,608 @@ ++/* ++ * This file is part of the coreboot project. ++ * ++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * ++ * Copyright (C) 2007 AMD ++ * Written by Yinghai Lu <yinghailu@amd.com> for AMD. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <stdint.h> ++#include <string.h> ++#include <reset.h> ++#include <device/pci_def.h> ++#include <device/pci_ids.h> ++#include <arch/io.h> ++#include <device/pnp_def.h> ++#include <cpu/x86/lapic.h> ++#include <console/console.h> ++#include <timestamp.h> ++#include <lib.h> ++#include <spd.h> ++#include <cpu/amd/model_10xxx_rev.h> ++#include <northbridge/amd/amdfam10/raminit.h> ++#include <northbridge/amd/amdfam10/amdfam10.h> ++#include "lib/delay.c" ++#include <cpu/x86/lapic.h> ++#include "northbridge/amd/amdfam10/reset_test.c" ++#include <superio/winbond/common/winbond.h> ++#include <superio/winbond/w83667hg-a/w83667hg-a.h> ++#include <cpu/x86/bist.h> ++#include <smp/spinlock.h> ++// #include "northbridge/amd/amdk8/incoherent_ht.c" ++#include <southbridge/amd/sb700/sb700.h> ++#include <southbridge/amd/sb700/smbus.h> ++#include <southbridge/amd/sr5650/sr5650.h> ++#include "northbridge/amd/amdfam10/debug.c" ++#include "northbridge/amd/amdfam10/setup_resource_map.c" ++ ++#define SERIAL_DEV PNP_DEV(0x2e, W83667HG_A_SP1) ++ ++static void activate_spd_rom(const struct mem_controller *ctrl); ++ ++static inline int spd_read_byte(unsigned device, unsigned address) ++{ ++ return do_smbus_read_byte(SMBUS_AUX_IO_BASE, device, address); ++} ++ ++#include <northbridge/amd/amdfam10/amdfam10.h> ++#include "northbridge/amd/amdfam10/raminit_sysinfo_in_ram.c" ++#include "northbridge/amd/amdfam10/pci.c" ++#include "resourcemap.c" ++#include "cpu/amd/quadcore/quadcore.c" ++ ++#include <cpu/amd/microcode.h> ++ ++#include "cpu/amd/family_10h-family_15h/init_cpus.c" ++#include "northbridge/amd/amdfam10/early_ht.c" ++ ++/* ++ * ASUS KGPE-D16 specific SPD enable/disable magic. ++ * ++ * Setting SP5100 GPIOs 59 and 60 controls an SPI mux with four settings: ++ * 0: Disabled ++ * 1: Normal SPI access ++ * 2: CPU0 SPD ++ * 3: CPU1 SPD ++ * ++ * Disable SPD access after RAM init to allow access to standard SMBus/I2C offsets ++ * which is required e.g. by lm-sensors. ++ */ ++ ++/* Relevant GPIO register information is available in the ++ * AMD SP5100 Register Reference Guide rev. 3.03, page 130 ++ */ ++static void switch_spd_mux(uint8_t channel) ++{ ++ uint8_t byte; ++ ++ byte = pci_read_config8(PCI_DEV(0, 0x14, 0), 0x54); ++ byte &= ~0xc; /* Clear SPD mux GPIOs */ ++ byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */ ++ byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */ ++ pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte); ++} ++ ++static const uint8_t spd_addr_fam15[] = { ++ // Socket 0 Node 0 ("Node 0") ++ RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, ++ // Socket 0 Node 1 ("Node 1") ++ RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, ++ // Socket 1 Node 0 ("Node 2") ++ RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, ++ // Socket 1 Node 1 ("Node 3") ++ RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, ++}; ++ ++static const uint8_t spd_addr_fam10[] = { ++ // Socket 0 Node 0 ("Node 0") ++ RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, ++ // Socket 0 Node 1 ("Node 1") ++ RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, ++ // Socket 1 Node 1 ("Node 2") ++ RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, ++ // Socket 1 Node 0 ("Node 3") ++ RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, ++}; ++ ++static void activate_spd_rom(const struct mem_controller *ctrl) { ++ struct sys_info *sysinfo = &sysinfo_car; ++ ++ printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id); ++ if (ctrl->node_id == 0) { ++ printk(BIOS_DEBUG, "enable_spd_node0()\n"); ++ switch_spd_mux(0x2); ++ } else if (ctrl->node_id == 1) { ++ printk(BIOS_DEBUG, "enable_spd_node1()\n"); ++ switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x2:0x3); ++ } else if (ctrl->node_id == 2) { ++ printk(BIOS_DEBUG, "enable_spd_node2()\n"); ++ switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x3:0x2); ++ } else if (ctrl->node_id == 3) { ++ printk(BIOS_DEBUG, "enable_spd_node3()\n"); ++ switch_spd_mux(0x3); ++ } ++} ++ ++/* Voltages are specified by index ++ * Valid indicies for this platform are: ++ * 0: 1.5V ++ * 1: 1.35V ++ * 2: 1.25V ++ * 3: 1.15V ++ */ ++static void set_ddr3_voltage(uint8_t node, uint8_t index) { ++ uint8_t byte; ++ uint8_t value = 0; ++ ++ if (index == 0) ++ value = 0x0; ++ else if (index == 1) ++ value = 0x1; ++ else if (index == 2) ++ value = 0x4; ++ else if (index == 3) ++ value = 0x5; ++ if (node == 1) ++ value <<= 1; ++ ++ /* Set GPIOs */ ++ byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd1); ++ if (node == 0) ++ byte &= ~0x5; ++ if (node == 1) ++ byte &= ~0xa; ++ byte |= value; ++ pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd1, byte); ++ ++ /* Enable GPIO output drivers */ ++ byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd0); ++ byte &= 0x0f; ++ pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd0, byte); ++ ++ printk(BIOS_DEBUG, "Node %02d DIMM voltage set to index %02x\n", node, index); ++} ++ ++void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, ++ struct DCTStatStruc *pDCTstatA) { ++ /* This mainboard allows the DIMM voltage to be set per-socket. ++ * Therefore, for each socket, iterate over all DIMMs to find the ++ * lowest supported voltage common to all DIMMs on that socket. ++ */ ++ uint8_t nvram; ++ uint8_t dimm; ++ uint8_t node; ++ uint8_t socket; ++ uint8_t allowed_voltages = 0xf; /* The mainboard VRMs allow 1.15V, 1.25V, 1.35V, and 1.5V */ ++ uint8_t socket_allowed_voltages = allowed_voltages; ++ uint32_t set_voltage = 0; ++ ++ if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS) { ++ switch (nvram) { ++ case 2: ++ allowed_voltages = 0x7; /* Allow 1.25V, 1.35V, and 1.5V */ ++ break; ++ case 1: ++ allowed_voltages = 0x3; /* Allow 1.35V and 1.5V */ ++ break; ++ case 0: ++ default: ++ allowed_voltages = 0x1; /* Allow 1.5V only */ ++ break; ++ } ++ } ++ ++ for (node = 0; node < MAX_NODES_SUPPORTED; node++) { ++ socket = node / 2; ++ struct DCTStatStruc *pDCTstat; ++ pDCTstat = pDCTstatA + node; ++ ++ /* reset socket_allowed_voltages before processing each socket */ ++ if (!(node % 2)) ++ socket_allowed_voltages = allowed_voltages; ++ ++ if (pDCTstat->NodePresent) { ++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { ++ if (pDCTstat->DIMMValid & (1 << dimm)) { ++ socket_allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm]; ++ } ++ } ++ } ++ ++ /* set voltage per socket after processing last contained node */ ++ if (pDCTstat->NodePresent && (node % 2)) { ++ /* Set voltages */ ++ if (socket_allowed_voltages & 0x8) { ++ set_voltage = 0x8; ++ set_ddr3_voltage(socket, 3); ++ } else if (socket_allowed_voltages & 0x4) { ++ set_voltage = 0x4; ++ set_ddr3_voltage(socket, 2); ++ } else if (socket_allowed_voltages & 0x2) { ++ set_voltage = 0x2; ++ set_ddr3_voltage(socket, 1); ++ } else { ++ set_voltage = 0x1; ++ set_ddr3_voltage(socket, 0); ++ } ++ ++ /* Save final DIMM voltages for MCT and SMBIOS use */ ++ if (pDCTstat->NodePresent) { ++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { ++ pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage; ++ } ++ } ++ pDCTstat = pDCTstatA + (node - 1); ++ if (pDCTstat->NodePresent) { ++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { ++ pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage; ++ } ++ } ++ } ++ } ++ ++ /* Allow the DDR supply voltages to settle */ ++ udelay(100000); ++} ++ ++static void set_peripheral_control_lines(void) { ++ uint8_t byte; ++ uint8_t nvram; ++ uint8_t enable_ieee1394; ++ ++ enable_ieee1394 = 1; ++ ++ if (get_option(&nvram, "ieee1394_controller") == CB_SUCCESS) ++ enable_ieee1394 = nvram & 0x1; ++ ++ if (enable_ieee1394) { ++ /* Enable PCICLK5 (onboard FireWire device) */ ++ outb(0x41, 0xcd6); ++ outb(0x02, 0xcd7); ++ } else { ++ /* Disable PCICLK5 (onboard FireWire device) */ ++ outb(0x41, 0xcd6); ++ outb(0x00, 0xcd7); ++ } ++ ++ /* Enable the RTC AltCentury register */ ++ outb(0x41, 0xcd6); ++ byte = inb(0xcd7); ++ byte |= 0x10; ++ outb(byte, 0xcd7); ++} ++ ++#ifdef TEST_MEMORY ++static void execute_memory_test(void) ++{ ++ /* Test DRAM functionality */ ++ uint32_t i; ++ uint32_t* dataptr; ++ printk(BIOS_DEBUG, "Writing test patterns to memory...\n"); ++ for (i=0; i < 0x1000000; i = i + 8) { ++ dataptr = (void *)(0x300000 + i); ++ *dataptr = 0x55555555; ++ dataptr = (void *)(0x300000 + i + 4); ++ *dataptr = 0xaaaaaaaa; ++ } ++ printk(BIOS_DEBUG, "Done!\n"); ++ printk(BIOS_DEBUG, "Testing memory...\n"); ++ uint32_t readback; ++ for (i=0; i < 0x1000000; i = i + 8) { ++ dataptr = (void *)(0x300000 + i); ++ readback = *dataptr; ++ if (readback != 0x55555555) ++ printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0x55555555); ++ dataptr = (void *)(0x300000 + i + 4); ++ readback = *dataptr; ++ if (readback != 0xaaaaaaaa) ++ printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0xaaaaaaaa); ++ } ++ printk(BIOS_DEBUG, "Done!\n"); ++} ++#endif ++ ++static spinlock_t printk_spinlock CAR_GLOBAL; ++ ++spinlock_t* romstage_console_lock(void) ++{ ++ return car_get_var_ptr(&printk_spinlock); ++} ++ ++void initialize_romstage_console_lock(void) ++{ ++ car_get_var(printk_spinlock) = SPIN_LOCK_UNLOCKED; ++} ++ ++static spinlock_t nvram_cbfs_spinlock CAR_GLOBAL; ++ ++spinlock_t* romstage_nvram_cbfs_lock(void) ++{ ++ return car_get_var_ptr(&nvram_cbfs_spinlock); ++} ++ ++void initialize_romstage_nvram_cbfs_lock(void) ++{ ++ car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED; ++} ++ ++static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL; ++ ++spinlock_t* romstage_microcode_cbfs_lock(void) ++{ ++ return car_get_var_ptr(µcode_cbfs_spinlock); ++} ++ ++void initialize_romstage_microcode_cbfs_lock(void) ++{ ++ car_get_var(microcode_cbfs_spinlock) = SPIN_LOCK_UNLOCKED; ++} ++ ++void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) ++{ ++ uint32_t esp; ++ __asm__ volatile ( ++ "movl %%esp, %0" ++ : "=r" (esp) ++ ); ++ ++ struct sys_info *sysinfo = &sysinfo_car; ++ ++ /* Limit the maximum HT speed to 2.6GHz to prevent lockups ++ * due to HT CPU <--> CPU wiring not being validated to 3.2GHz ++ */ ++ sysinfo->ht_link_cfg.ht_speed_limit = 2600; ++ ++ uint32_t bsp_apicid = 0, val; ++ uint8_t byte; ++ msr_t msr; ++ ++ int s3resume = acpi_is_wakeup_s3(); ++ ++ if (!cpu_init_detectedx && boot_cpu()) { ++ /* Initial timestamp */ ++ timestamp_init(timestamp_get()); ++ timestamp_add_now(TS_START_ROMSTAGE); ++ ++ /* Initialize the printk, nvram CBFS, and microcode CBFS spinlocks */ ++ initialize_romstage_console_lock(); ++ initialize_romstage_nvram_cbfs_lock(); ++ initialize_romstage_microcode_cbfs_lock(); ++ ++ /* Nothing special needs to be done to find bus 0 */ ++ /* Allow the HT devices to be found */ ++ set_bsp_node_CHtExtNodeCfgEn(); ++ enumerate_ht_chain(); ++ ++ /* SR56x0 pcie bridges block pci_locate_device() before pcie training. ++ * disable all pcie bridges on SR56x0 to work around it ++ */ ++ sr5650_disable_pcie_bridge(); ++ ++ /* Initialize southbridge */ ++ sb7xx_51xx_pci_port80(); ++ ++ /* Initialize early serial */ ++ winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); ++ console_init(); ++ ++ /* Disable LPC legacy DMA support to prevent lockup */ ++ byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0x78); ++ byte &= ~(1 << 0); ++ pci_write_config8(PCI_DEV(0, 0x14, 3), 0x78, byte); ++ } ++ ++ printk(BIOS_SPEW, "Initial stack pointer: %08x\n", esp); ++ ++ post_code(0x30); ++ ++ if (bist == 0) ++ bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo); ++ ++ post_code(0x32); ++ ++ enable_sr5650_dev8(); ++ sb7xx_51xx_lpc_init(); ++ ++ if (CONFIG_MAX_PHYSICAL_CPUS != 4) ++ printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD G34 board!\n", CONFIG_MAX_PHYSICAL_CPUS); ++ ++ /* Halt if there was a built in self test failure */ ++ report_bist_failure(bist); ++ ++ val = cpuid_eax(1); ++ printk(BIOS_DEBUG, "BSP Family_Model: %08x\n", val); ++ printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1); ++ printk(BIOS_DEBUG, "bsp_apicid = %02x\n", bsp_apicid); ++ printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx\n", cpu_init_detectedx); ++ ++ /* Setup sysinfo defaults */ ++ set_sysinfo_in_ram(0); ++ ++ update_microcode(val); ++ ++ post_code(0x33); ++ ++ cpuSetAMDMSR(0); ++ post_code(0x34); ++ ++ amd_ht_init(sysinfo); ++ amd_ht_fixup(sysinfo); ++ post_code(0x35); ++ ++ /* Setup nodes PCI space and start core 0 AP init. */ ++ finalize_node_setup(sysinfo); ++ ++ /* Setup any mainboard PCI settings etc. */ ++ setup_mb_resource_map(); ++ post_code(0x36); ++ ++ /* Wait for all the APs core0 started by finalize_node_setup. */ ++ wait_all_core0_started(); ++ ++ /* run _early_setup before soft-reset. */ ++ sr5650_early_setup(); ++ sb7xx_51xx_early_setup(); ++ ++ if (IS_ENABLED(CONFIG_LOGICAL_CPUS)) { ++ /* Core0 on each node is configured. Now setup any additional cores. */ ++ printk(BIOS_DEBUG, "start_other_cores()\n"); ++ start_other_cores(bsp_apicid); ++ post_code(0x37); ++ wait_all_other_cores_started(bsp_apicid); ++ } ++ ++ if (IS_ENABLED(CONFIG_SET_FIDVID)) { ++ msr = rdmsr(0xc0010071); ++ printk(BIOS_DEBUG, "\nBegin FIDVID MSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo); ++ ++ /* FIXME: The sb fid change may survive the warm reset and only need to be done once */ ++ enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn); ++ ++ post_code(0x39); ++ ++ #if IS_ENABLED(CONFIG_SET_FIDVID) ++ if (!warm_reset_detect(0)) { // BSP is node 0 ++ init_fidvid_bsp(bsp_apicid, sysinfo->nodes); ++ } else { ++ init_fidvid_stage2(bsp_apicid, 0); // BSP is node 0 ++ } ++ #endif ++ ++ post_code(0x3A); ++ ++ /* show final fid and vid */ ++ msr=rdmsr(0xc0010071); ++ printk(BIOS_DEBUG, "End FIDVIDMSR 0xc0010071 0x%08x 0x%08x\n", msr.hi, msr.lo); ++ } ++ ++ post_code(0x38); ++ ++ init_timer(); // Need to use TMICT to synconize FID/VID ++ ++ sr5650_htinit(); ++ ++ /* Reset for HT, FIDVID, PLL and errata changes to take effect. */ ++ if (!warm_reset_detect(0)) { ++ printk(BIOS_INFO, "...WARM RESET...\n\n\n"); ++ soft_reset(); ++ die("After soft_reset_x - shouldn't see this message!!!\n"); ++ } ++ ++ sr5650_htinit_dect_and_enable_isochronous_link(); ++ ++ /* Set default DDR memory voltage ++ * This will be overridden later during RAM initialization ++ */ ++ set_lpc_sticky_ctl(1); /* Retain LPC/IMC GPIO configuration during S3 sleep */ ++ if (!s3resume) { /* Avoid supply voltage glitches while the DIMMs are retaining data */ ++ set_ddr3_voltage(0, 0); /* Node 0 */ ++ set_ddr3_voltage(1, 0); /* Node 1 */ ++ } ++ ++ /* Set up peripheral control lines */ ++ set_peripheral_control_lines(); ++ ++ post_code(0x3B); ++ ++ /* Wait for all APs to be stopped, otherwise ram initialization may hang */ ++ if (IS_ENABLED(CONFIG_LOGICAL_CPUS)) ++ wait_all_other_cores_stopped(bsp_apicid); ++ ++ /* It's the time to set ctrl in sysinfo now; */ ++ printk(BIOS_DEBUG, "fill_mem_ctrl() detected %d nodes\n", sysinfo->nodes); ++ if (is_fam15h()) ++ fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam15); ++ else ++ fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr_fam10); ++ post_code(0x3D); ++ ++#if 0 ++ /* FIXME ++ * After the AMD K10 code has been converted to use ++ * IS_ENABLED(CONFIG_DEBUG_SMBUS) uncomment this block ++ */ ++ if (IS_ENABLED(CONFIG_DEBUG_SMBUS)) { ++ dump_spd_registers(&cpu[0]); ++ dump_smbus_registers(); ++ } ++#endif ++ ++ post_code(0x40); ++ ++ timestamp_add_now(TS_BEFORE_INITRAM); ++ printk(BIOS_DEBUG, "raminit_amdmct()\n"); ++ raminit_amdmct(sysinfo); ++ timestamp_add_now(TS_AFTER_INITRAM); ++ ++#ifdef TEST_MEMORY ++ execute_memory_test(); ++#endif ++ ++#if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT) ++ if (s3resume) ++ cbmem_initialize(); ++ else ++ cbmem_initialize_empty(); ++ post_code(0x41); ++ ++ amdmct_cbmem_store_info(sysinfo); ++#endif ++ ++ printk(BIOS_DEBUG, "disable_spd()\n"); ++ switch_spd_mux(0x1); ++ ++ sr5650_before_pci_init(); ++ sb7xx_51xx_before_pci_init(); ++ ++ /* Configure SP5100 GPIOs to match vendor settings */ ++ pci_write_config16(PCI_DEV(0, 0x14, 0), 0x50, 0x0170); ++ pci_write_config16(PCI_DEV(0, 0x14, 0), 0x54, 0x0707); ++ pci_write_config16(PCI_DEV(0, 0x14, 0), 0x56, 0x0bb0); ++ pci_write_config16(PCI_DEV(0, 0x14, 0), 0x5a, 0x0ff0); ++ ++ timestamp_add_now(TS_END_ROMSTAGE); ++ ++ post_cache_as_ram(); // BSP switch stack to ram, copy then execute LB. ++ post_code(0x43); // Should never see this post code. ++} ++ ++/** ++ * BOOL AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List) ++ * Description: ++ * This routine is called every time a non-coherent chain is processed. ++ * BUID assignment may be controlled explicitly on a non-coherent chain. Provide a ++ * swap list. The first part of the list controls the BUID assignment and the ++ * second part of the list provides the device to device linking. Device orientation ++ * can be detected automatically, or explicitly. See documentation for more details. ++ * ++ * Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially ++ * based on each device's unit count. ++ * ++ * Parameters: ++ * @param[in] node = The node on which this chain is located ++ * @param[in] link = The link on the host for this chain ++ * @param[out] List = supply a pointer to a list ++ */ ++BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List) ++{ ++ /* Force BUID to 0 */ ++ static const u8 swaplist[] = {0, 0, 0xFF, 0, 0xFF}; ++ if ((is_fam15h() && (node == 0) && (link == 1)) /* Family 15h BSP SB link */ ++ || (!is_fam15h() && (node == 0) && (link == 3))) { /* Family 10h BSP SB link */ ++ *List = swaplist; ++ return 1; ++ } ++ ++ return 0; ++} +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0044-mainboard-asus-kcma-d8-Initial-modification-for-KCMA.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0044-mainboard-asus-kcma-d8-Initial-modification-for-KCMA.patch new file mode 100644 index 0000000..a645e3d --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0044-mainboard-asus-kcma-d8-Initial-modification-for-KCMA.patch @@ -0,0 +1,156 @@ +From ebf04615b9589056c09cded45521499e8eefe8e1 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:12:08 -0600 +Subject: [PATCH 44/45] mainboard/asus/kcma-d8: Initial modification for + KCMA-D8 name strings + +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kcma-d8/Kconfig | 18 +++++++++--------- + src/mainboard/asus/kcma-d8/Kconfig.name | 4 ++-- + src/mainboard/asus/kcma-d8/mainboard.c | 2 +- + src/mainboard/asus/kcma-d8/romstage.c | 24 +++++------------------- + 4 files changed, 17 insertions(+), 31 deletions(-) + +diff --git a/src/mainboard/asus/kcma-d8/Kconfig b/src/mainboard/asus/kcma-d8/Kconfig +index 23c91f0..3c8cdcd 100644 +--- a/src/mainboard/asus/kcma-d8/Kconfig ++++ b/src/mainboard/asus/kcma-d8/Kconfig +@@ -1,8 +1,8 @@ +-if BOARD_ASUS_KGPE_D16 ++if BOARD_ASUS_KCMA_D8 + + config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y +- select CPU_AMD_SOCKET_G34_NON_AGESA ++ select CPU_AMD_SOCKET_C32_NON_AGESA + select DIMM_DDR3 + select DIMM_REGISTERED + # select QRANK_DIMM_SUPPORT +@@ -37,11 +37,11 @@ config BOARD_SPECIFIC_OPTIONS # dummy + + config MAINBOARD_DIR + string +- default "asus/kgpe-d16" ++ default "asus/kcma-d8" + + config BOOTBLOCK_MAINBOARD_INIT + string +- default "mainboard/asus/kgpe-d16/bootblock.c" ++ default "mainboard/asus/kcma-d8/bootblock.c" + + config DCACHE_RAM_BASE + hex +@@ -57,7 +57,7 @@ config APIC_ID_OFFSET + + config MAINBOARD_PART_NUMBER + string +- default "KGPE-D16" ++ default "KCMA-D8" + + config HW_MEM_HOLE_SIZEK + hex +@@ -65,12 +65,12 @@ config HW_MEM_HOLE_SIZEK + + config MAX_CPUS + int +- default 32 ++ default 16 + +-# 2 (internal) processors per G34 socket ++# 1 (internal) processor per C32 socket + config MAX_PHYSICAL_CPUS + int +- default 4 ++ default 2 + + config HT_CHAIN_UNITID_BASE + hex +@@ -100,4 +100,4 @@ config MAX_REBOOT_CNT + int + default 10 + +-endif # BOARD_ASUS_KGPE_D16 ++endif # BOARD_ASUS_KCMA_D8 +diff --git a/src/mainboard/asus/kcma-d8/Kconfig.name b/src/mainboard/asus/kcma-d8/Kconfig.name +index bdfa31a..69b63ea 100644 +--- a/src/mainboard/asus/kcma-d8/Kconfig.name ++++ b/src/mainboard/asus/kcma-d8/Kconfig.name +@@ -1,2 +1,2 @@ +-config BOARD_ASUS_KGPE_D16 +- bool "KGPE-D16" ++config BOARD_ASUS_KCMA_D8 ++ bool "KCMA-D8" +diff --git a/src/mainboard/asus/kcma-d8/mainboard.c b/src/mainboard/asus/kcma-d8/mainboard.c +index 65029d4..0219ee6 100644 +--- a/src/mainboard/asus/kcma-d8/mainboard.c ++++ b/src/mainboard/asus/kcma-d8/mainboard.c +@@ -52,7 +52,7 @@ void set_pcie_dereset(void) + *************************************************/ + static void mainboard_enable(device_t dev) + { +- printk(BIOS_INFO, "Mainboard KGPE-D16 Enable. dev=0x%p\n", dev); ++ printk(BIOS_INFO, "Mainboard KCMA-D8 initializing, dev=0x%p\n", dev); + + msr_t msr, msr2; + +diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c +index 5df6de4..0b9a2ef 100644 +--- a/src/mainboard/asus/kcma-d8/romstage.c ++++ b/src/mainboard/asus/kcma-d8/romstage.c +@@ -1,7 +1,7 @@ + /* + * This file is part of the coreboot project. + * +- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2015 Raptor Engineering + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu <yinghailu@amd.com> for AMD. +@@ -67,7 +67,7 @@ static inline int spd_read_byte(unsigned device, unsigned address) + #include "northbridge/amd/amdfam10/early_ht.c" + + /* +- * ASUS KGPE-D16 specific SPD enable/disable magic. ++ * ASUS KCMA-D8 specific SPD enable/disable magic. + * + * Setting SP5100 GPIOs 59 and 60 controls an SPI mux with four settings: + * 0: Disabled +@@ -116,22 +116,8 @@ static const uint8_t spd_addr_fam10[] = { + }; + + static void activate_spd_rom(const struct mem_controller *ctrl) { +- struct sys_info *sysinfo = &sysinfo_car; +- ++ /* Nothing needs to be done as there is no SPD mux on this board */ + printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id); +- if (ctrl->node_id == 0) { +- printk(BIOS_DEBUG, "enable_spd_node0()\n"); +- switch_spd_mux(0x2); +- } else if (ctrl->node_id == 1) { +- printk(BIOS_DEBUG, "enable_spd_node1()\n"); +- switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x2:0x3); +- } else if (ctrl->node_id == 2) { +- printk(BIOS_DEBUG, "enable_spd_node2()\n"); +- switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x3:0x2); +- } else if (ctrl->node_id == 3) { +- printk(BIOS_DEBUG, "enable_spd_node3()\n"); +- switch_spd_mux(0x3); +- } + } + + /* Voltages are specified by index +@@ -414,8 +400,8 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) + enable_sr5650_dev8(); + sb7xx_51xx_lpc_init(); + +- if (CONFIG_MAX_PHYSICAL_CPUS != 4) +- printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD G34 board!\n", CONFIG_MAX_PHYSICAL_CPUS); ++ if (CONFIG_MAX_PHYSICAL_CPUS != 2) ++ printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD C32 board!\n", CONFIG_MAX_PHYSICAL_CPUS); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); +-- +2.1.4 + diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch new file mode 100644 index 0000000..77c06ab --- /dev/null +++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch @@ -0,0 +1,575 @@ +From adf6ee421b7dd921617871905baf925cb1708646 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Tue, 24 Nov 2015 14:17:49 -0600 +Subject: [PATCH 45/45] mainboard/asus/kcma-d8: Add initial ASUS KCMA-D8 + support + +Change-Id: Idefa304a27823c741fab72ff5c2f20fed1aa5a39 +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/mainboard/asus/kcma-d8/cmos.default | 1 - + src/mainboard/asus/kcma-d8/cmos.layout | 1 - + src/mainboard/asus/kcma-d8/devicetree.cb | 46 ++++++---------- + src/mainboard/asus/kcma-d8/dsdt.asl | 92 +++++++++----------------------- + src/mainboard/asus/kcma-d8/mptable.c | 34 ++++++------ + src/mainboard/asus/kcma-d8/resourcemap.c | 8 +-- + src/mainboard/asus/kcma-d8/romstage.c | 62 ++++++--------------- + 7 files changed, 80 insertions(+), 164 deletions(-) + +diff --git a/src/mainboard/asus/kcma-d8/cmos.default b/src/mainboard/asus/kcma-d8/cmos.default +index 0e7afb3..c8edd97 100644 +--- a/src/mainboard/asus/kcma-d8/cmos.default ++++ b/src/mainboard/asus/kcma-d8/cmos.default +@@ -23,7 +23,6 @@ sata_alpm = Disable + maximum_p_state_limit = 0xf + probe_filter = Auto + l3_cache_partitioning = Disable +-ieee1394_controller = Enable + gart = Enable + experimental_memory_speed_boost = Disable + power_on_after_fail = On +diff --git a/src/mainboard/asus/kcma-d8/cmos.layout b/src/mainboard/asus/kcma-d8/cmos.layout +index 075388e..9bda1f6 100644 +--- a/src/mainboard/asus/kcma-d8/cmos.layout ++++ b/src/mainboard/asus/kcma-d8/cmos.layout +@@ -46,7 +46,6 @@ entries + 473 2 e 13 dimm_spd_checksum + 475 1 e 14 probe_filter + 476 1 e 1 l3_cache_partitioning +-477 1 e 1 ieee1394_controller + 478 1 e 1 iommu + 479 1 e 1 cpu_core_boost + 480 1 e 1 experimental_memory_speed_boost +diff --git a/src/mainboard/asus/kcma-d8/devicetree.cb b/src/mainboard/asus/kcma-d8/devicetree.cb +index 8d64ac7..1830f89 100644 +--- a/src/mainboard/asus/kcma-d8/devicetree.cb ++++ b/src/mainboard/asus/kcma-d8/devicetree.cb +@@ -7,11 +7,10 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + device domain 0 on # PCI domain + subsystemid 0x1043 0x8163 inherit + chip northbridge/amd/amdfam10 # Northbridge / RAM controller +- register "maximum_memory_capacity" = "0x4000000000" # 256GB ++ register "maximum_memory_capacity" = "0x2000000000" # 128GB + device pci 18.0 on end # Link 0 == LDT 0 + device pci 18.0 on end # Link 1 == LDT 1 +- device pci 18.0 on end # Link 2 == LDT 2 +- device pci 18.0 on # Link 3 == LDT 3 [SB on link 3] ++ device pci 18.0 on # Link 2 == LDT 2 [SB on link 2] + chip southbridge/amd/sr5650 # Primary southbridge + device pci 0.0 on end # HT Root Complex 0x9600 + device pci 0.1 on end # CLKCONFIG +@@ -36,16 +35,10 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + device pci b.0 on # Bridge (GPP2 Port0) + # Slot # PCI E 4 + end +- device pci c.0 on # Bridge (GPP2 Port1) +- # Slot # PCI E 5 +- end +- device pci d.0 on # Bridge (GPP3b Port0) +- # Slot # PCI E 3 +- end + register "gpp1_configuration" = "0" # Configuration 16:0 default + register "gpp2_configuration" = "1" # Configuration 8:8 + register "gpp3a_configuration" = "2" # Configuration 4:1:1:0:0:0 +- register "port_enable" = "0x3f1c" # Enable all ports except 0, 1, 5, 6, and 7 ++ register "port_enable" = "0x0f1c" # Enable all ports except 0, 1, 5, 6, and 7 + register "pcie_settling_time" = "1000000" # Allow PIKE to be detected / configured + end + chip southbridge/amd/sb700 # Secondary southbridge +@@ -150,7 +143,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V + register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V + register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V +- register "vsen7_high_limit_mv" = "1250" # VSEN7 (Northbridge core voltage) high limit to 1.25V ++ register "vsen7_high_limit_mv" = "1150" # VSEN7 (Northbridge core voltage) high limit to 1.15V + register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V + register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V + register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V +@@ -178,8 +171,8 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card) + device pci 14.3 on # LPC 0x439d (SMBUS primary controller) + chip superio/winbond/w83667hg-a # Super I/O +- device pnp 2e.0 off end # FDC; Not available on the KGPE-D16 +- device pnp 2e.1 off end # LPT1; Not available on the KGPE-D16 ++ device pnp 2e.0 off end # FDC; Not available on the KCMA-D8 ++ device pnp 2e.1 off end # LPT1; Not available on the KCMA-D8 + device pnp 2e.2 on # Com1 + io 0x60 = 0x3f8 + irq 0x70 = 4 +@@ -194,7 +187,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + irq 0x70 = 1 + irq 0x72 = 12 + end +- device pnp 2e.6 off end # SPI: Not available on the KGPE-D16 ++ device pnp 2e.6 off end # SPI: Not available on the KCMA-D8 + device pnp 2e.7 off end # GIPO6789 + device pnp 2e.8 off end # WDT + device pnp 2e.9 off end # GPIO2345 +@@ -210,11 +203,16 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + end + end + device pci 14.4 on # Bridge +- device pci 1.0 on end # VGA +- device pci 2.0 on end # FireWire +- device pci 3.0 on # Slot ++ device pci 1.0 on # Slot + # Slot # PCI 0 + end ++ device pci 2.0 on # Slot ++ # Slot # PCI 1 ++ end ++ device pci 3.0 on # Slot ++ # Slot # PCI 2 ++ end ++ device pci 5.0 on end # VGA + end + device pci 14.5 on end # USB OHCI2 0x4399 + end +@@ -224,24 +222,12 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + device pci 18.3 on end + device pci 18.4 on end + device pci 18.5 on end +- device pci 19.0 on end # Socket 0 node 1 ++ device pci 19.0 on end # Socket 1 node 0 + device pci 19.1 on end + device pci 19.2 on end + device pci 19.3 on end + device pci 19.4 on end + device pci 19.5 on end +- device pci 1a.0 on end # Socket 1 node 0 +- device pci 1a.1 on end +- device pci 1a.2 on end +- device pci 1a.3 on end +- device pci 1a.4 on end +- device pci 1a.5 on end +- device pci 1b.0 on end # Socket 1 node 1 +- device pci 1b.1 on end +- device pci 1b.2 on end +- device pci 1b.3 on end +- device pci 1b.4 on end +- device pci 1b.5 on end + end + end + end +diff --git a/src/mainboard/asus/kcma-d8/dsdt.asl b/src/mainboard/asus/kcma-d8/dsdt.asl +index 5f9195a..ef87d31 100644 +--- a/src/mainboard/asus/kcma-d8/dsdt.asl ++++ b/src/mainboard/asus/kcma-d8/dsdt.asl +@@ -1,7 +1,7 @@ + /* + * This file is part of the coreboot project. + * +- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering ++ * Copyright (C) 2015 Raptor Engineering + * Copyright (C) 2005 - 2012 Advanced Micro Devices, Inc. + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2004 Nick Barker <Nick.Barker9@btinternet.com> +@@ -116,8 +116,6 @@ DefinitionBlock ( + Notify (\_SB.PCI0.NICA, 0x02) /* NOTIFY_DEVICE_WAKE */ + Notify (\_SB.PCI0.NICB, 0x02) /* NOTIFY_DEVICE_WAKE */ + Notify (\_SB.PCI0.PCE4, 0x02) /* NOTIFY_DEVICE_WAKE */ +- Notify (\_SB.PCI0.PCE5, 0x02) /* NOTIFY_DEVICE_WAKE */ +- Notify (\_SB.PCI0.PCE3, 0x02) /* NOTIFY_DEVICE_WAKE */ + } + + } /* End Scope GPE */ +@@ -125,13 +123,13 @@ DefinitionBlock ( + /* Root of the bus hierarchy */ + Scope (\_SB) + { +- /* Top southbridge PCI device (SR5690 + SP5100) */ ++ /* Top southbridge PCI device (SR5670 + SP5100) */ + Device (PCI0) + { + /* BUS0 root bus */ + +- Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5690) */ +- Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */ ++ Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5670) */ ++ Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */ + Name (_ADR, 0x00180001) + Name (_UID, 0x00) + +@@ -162,7 +160,7 @@ DefinitionBlock ( + /* PCI Routing Tables */ + Name (PR00, Package () { + /* PIC */ +- /* Top southbridge device (SR5690) */ ++ /* Top southbridge device (SR5670) */ + /* HT Link */ + Package (0x04) { 0x0000FFFF, 0x00, LNKA, 0x00 }, + +@@ -178,12 +176,6 @@ DefinitionBlock ( + /* PCI-E Slot 4 (Bridge) */ + Package (0x04) { 0x000BFFFF, 0x00, LNKG, 0x00 }, + +- /* PCI-E Slot 5 (Bridge) */ +- Package (0x04) { 0x000CFFFF, 0x00, LNKG, 0x00 }, +- +- /* PCI-E Slot 3 (Bridge) */ +- Package (0x04) { 0x000DFFFF, 0x00, LNKG, 0x00 }, +- + /* Bottom southbridge device (SP5100) */ + /* SATA 0 */ + Package (0x04) { 0x0011FFFF, 0x00, LNKG, 0x00 }, +@@ -200,7 +192,7 @@ DefinitionBlock ( + Package (0x04) { 0x0013FFFF, 0x02, LNKA, 0x00 }, + Package (0x04) { 0x0013FFFF, 0x03, LNKB, 0x00 }, + +- /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */ ++ /* SMBUS / IDE / LPC / VGA / PCI Slots 0 - 2 */ + Package (0x04) { 0x0014FFFF, 0x00, LNKA, 0x00 }, + Package (0x04) { 0x0014FFFF, 0x01, LNKB, 0x00 }, + Package (0x04) { 0x0014FFFF, 0x02, LNKC, 0x00 }, +@@ -209,7 +201,7 @@ DefinitionBlock ( + + Name (AR00, Package () { + /* APIC */ +- /* Top southbridge device (SR5690) */ ++ /* Top southbridge device (SR5670) */ + /* HT Link */ + Package (0x04) { 0x0000FFFF, 0x00, 0x00, 55 }, + +@@ -225,12 +217,6 @@ DefinitionBlock ( + /* PCI-E Slot 4 (Bridge) */ + Package (0x04) { 0x000BFFFF, 0x00, 0x00, 54 }, + +- /* PCI-E Slot 5 (Bridge) */ +- Package (0x04) { 0x000CFFFF, 0x00, 0x00, 54 }, +- +- /* PCI-E Slot 3 (Bridge) */ +- Package (0x04) { 0x000DFFFF, 0x00, 0x00, 54 }, +- + /* Bottom southbridge device (SP5100) */ + /* SATA 0 */ + Package (0x04) { 0x0011FFFF, 0x00, 0x00, 22 }, +@@ -247,7 +233,7 @@ DefinitionBlock ( + Package (0x04) { 0x0013FFFF, 0x02, 0x00, 16 }, + Package (0x04) { 0x0013FFFF, 0x03, 0x00, 17 }, + +- /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */ ++ /* SMBUS / IDE / LPC / VGA / PCI Slots 0 - 2 */ + Package (0x04) { 0x0014FFFF, 0x00, 0x00, 16 }, + Package (0x04) { 0x0014FFFF, 0x01, 0x00, 17 }, + Package (0x04) { 0x0014FFFF, 0x02, 0x00, 18 }, +@@ -256,22 +242,36 @@ DefinitionBlock ( + + Name (PR01, Package () { + /* PIC */ +- Package (0x04) { 0x1FFFF, 0x00, LNKF, 0x00 }, +- Package (0x04) { 0x2FFFF, 0x00, LNKE, 0x00 }, ++ Package (0x04) { 0x1FFFF, 0x00, LNKE, 0x00 }, ++ Package (0x04) { 0x1FFFF, 0x01, LNKF, 0x00 }, ++ Package (0x04) { 0x1FFFF, 0x02, LNKG, 0x00 }, ++ Package (0x04) { 0x1FFFF, 0x03, LNKH, 0x00 }, ++ Package (0x04) { 0x2FFFF, 0x00, LNKF, 0x00 }, ++ Package (0x04) { 0x2FFFF, 0x01, LNKG, 0x00 }, ++ Package (0x04) { 0x2FFFF, 0x02, LNKH, 0x00 }, ++ Package (0x04) { 0x2FFFF, 0x03, LNKE, 0x00 }, + Package (0x04) { 0x3FFFF, 0x00, LNKG, 0x00 }, + Package (0x04) { 0x3FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x3FFFF, 0x02, LNKE, 0x00 }, + Package (0x04) { 0x3FFFF, 0x03, LNKF, 0x00 }, ++ Package (0x04) { 0x5FFFF, 0x00, LNKH, 0x00 }, + }) + + Name (AR01, Package () { + /* APIC */ +- Package (0x04) { 0x1FFFF, 0x00, 0x00, 21 }, +- Package (0x04) { 0x2FFFF, 0x00, 0x00, 20 }, ++ Package (0x04) { 0x1FFFF, 0x00, 0x00, 20 }, ++ Package (0x04) { 0x1FFFF, 0x01, 0x00, 21 }, ++ Package (0x04) { 0x1FFFF, 0x02, 0x00, 22 }, ++ Package (0x04) { 0x1FFFF, 0x03, 0x00, 23 }, ++ Package (0x04) { 0x2FFFF, 0x00, 0x00, 21 }, ++ Package (0x04) { 0x2FFFF, 0x01, 0x00, 22 }, ++ Package (0x04) { 0x2FFFF, 0x02, 0x00, 23 }, ++ Package (0x04) { 0x2FFFF, 0x03, 0x00, 20 }, + Package (0x04) { 0x3FFFF, 0x00, 0x00, 22 }, + Package (0x04) { 0x3FFFF, 0x01, 0x00, 23 }, + Package (0x04) { 0x3FFFF, 0x02, 0x00, 20 }, + Package (0x04) { 0x3FFFF, 0x03, 0x00, 21 }, ++ Package (0x04) { 0x5FFFF, 0x00, 0x00, 23 }, + }) + + Name (PR02, Package () { +@@ -734,46 +734,6 @@ DefinitionBlock ( + Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 + } + } +- +- /* 6:00.0 PCIe x16 */ +- Device (PCE5) +- { +- Name (_ADR, 0x000C0000) // _ADR: Address +- Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 +- Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table +- { +- If (PICM) { +- Return (AR07) +- } Else { +- Return (PR07) +- } +- } +- Device (SLT1) +- { +- Name (_ADR, 0xFFFF) // _ADR: Address +- Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 +- } +- } +- +- /* 7:00.0 PCIe x16 */ +- Device (PCE3) +- { +- Name (_ADR, 0x000D0000) // _ADR: Address +- Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4 +- Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table +- { +- If (PICM) { +- Return (AR08) +- } Else { +- Return (PR08) +- } +- } +- Device (SLT1) +- { +- Name (_ADR, 0xFFFF) // _ADR: Address +- Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4 +- } +- } + } + + Device (PWRB) { /* Start Power button device */ +diff --git a/src/mainboard/asus/kcma-d8/mptable.c b/src/mainboard/asus/kcma-d8/mptable.c +index c869d31..8967560 100644 +--- a/src/mainboard/asus/kcma-d8/mptable.c ++++ b/src/mainboard/asus/kcma-d8/mptable.c +@@ -132,7 +132,6 @@ static void *smp_write_config_table(void *v) + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */ +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */ + + dev = dev_find_slot(0, PCI_DEVFN(0x2, 0)); + if (dev && dev->enabled) { +@@ -164,11 +163,6 @@ static void *smp_write_config_table(void *v) + uint8_t bus_pci = dev->link_list->secondary; + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xc)|(0)), apicid_sr5650, 0); /* card behind dev12 */ + } +- dev = dev_find_slot(0, PCI_DEVFN(0xd, 0)); +- if (dev && dev->enabled) { +- uint8_t bus_pci = dev->link_list->secondary; +- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xd)|(0)), apicid_sr5650, 0); /* card behind dev13 */ +- } + + /* PCI interrupts are level triggered, and are + * associated with a specific bus/device/function tuple. +@@ -195,23 +189,29 @@ static void *smp_write_config_table(void *v) + if (dev && dev->enabled) { + u8 bus_pci = dev->link_list->secondary; + +- /* PCI_SLOT 0. */ +- PCI_INT(bus_pci, 0x1, 0x0, 0x15); +- PCI_INT(bus_pci, 0x1, 0x1, 0x16); +- PCI_INT(bus_pci, 0x1, 0x2, 0x17); +- PCI_INT(bus_pci, 0x1, 0x3, 0x14); ++ /* PCI_SLOT 0 */ ++ PCI_INT(bus_pci, 0x1, 0x0, 0x14); ++ PCI_INT(bus_pci, 0x1, 0x1, 0x15); ++ PCI_INT(bus_pci, 0x1, 0x2, 0x16); ++ PCI_INT(bus_pci, 0x1, 0x3, 0x17); + +- /* PCI_SLOT 1. */ +- PCI_INT(bus_pci, 0x2, 0x0, 0x14); +- PCI_INT(bus_pci, 0x2, 0x1, 0x15); +- PCI_INT(bus_pci, 0x2, 0x2, 0x16); +- PCI_INT(bus_pci, 0x2, 0x3, 0x17); ++ /* PCI_SLOT 1 */ ++ PCI_INT(bus_pci, 0x2, 0x0, 0x15); ++ PCI_INT(bus_pci, 0x2, 0x1, 0x16); ++ PCI_INT(bus_pci, 0x2, 0x2, 0x17); ++ PCI_INT(bus_pci, 0x2, 0x3, 0x14); + +- /* PCI_SLOT 2. */ ++ /* PCI_SLOT 2 */ + PCI_INT(bus_pci, 0x3, 0x0, 0x16); + PCI_INT(bus_pci, 0x3, 0x1, 0x17); + PCI_INT(bus_pci, 0x3, 0x2, 0x14); + PCI_INT(bus_pci, 0x3, 0x3, 0x15); ++ ++ /* VGA */ ++ PCI_INT(bus_pci, 0x5, 0x0, 0x17); ++ PCI_INT(bus_pci, 0x5, 0x1, 0x14); ++ PCI_INT(bus_pci, 0x5, 0x2, 0x15); ++ PCI_INT(bus_pci, 0x5, 0x3, 0x16); + } + + /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ +diff --git a/src/mainboard/asus/kcma-d8/resourcemap.c b/src/mainboard/asus/kcma-d8/resourcemap.c +index 8bcb28b..f7a2133 100644 +--- a/src/mainboard/asus/kcma-d8/resourcemap.c ++++ b/src/mainboard/asus/kcma-d8/resourcemap.c +@@ -196,7 +196,7 @@ static void setup_mb_resource_map(void) + * This field defines the end of PCI I/O region n + * [31:25] Reserved + */ +- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff010, /* link 1 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff020, /* link 2 of cpu 0 --> AMD SR5690 */ + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xDC), 0xFE000FC8, 0x00000000, +@@ -267,7 +267,7 @@ static void setup_mb_resource_map(void) + * [31:24] Bus Number Limit i + * This field defines the highest bus number in configuration region i + */ +- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000103, /* link 1 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000203, /* link 2 of cpu 0 --> AMD SR5690 */ + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000, +@@ -451,7 +451,7 @@ static void setup_mb_resource_map(void) + * This field defines the end of PCI I/O region n + * [31:25] Reserved + */ +- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff110, /* link 3 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff020, /* link 2 of cpu 0 --> AMD SR5690 */ + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xDC), 0xFE000FC8, 0x00000000, +@@ -522,7 +522,7 @@ static void setup_mb_resource_map(void) + * [31:24] Bus Number Limit i + * This field defines the highest bus number in configuration region i + */ +- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000303, /* link 3 of cpu 0 --> AMD SR5690 */ ++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000203, /* link 2 of cpu 0 --> AMD SR5690 */ + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000, + PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000, +diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c +index 0b9a2ef..c9e0af5 100644 +--- a/src/mainboard/asus/kcma-d8/romstage.c ++++ b/src/mainboard/asus/kcma-d8/romstage.c +@@ -96,28 +96,26 @@ static void switch_spd_mux(uint8_t channel) + static const uint8_t spd_addr_fam15[] = { + // Socket 0 Node 0 ("Node 0") + RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, +- // Socket 0 Node 1 ("Node 1") +- RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, +- // Socket 1 Node 0 ("Node 2") ++ // Socket 1 Node 0 ("Node 1") + RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, +- // Socket 1 Node 1 ("Node 3") +- RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, + }; + + static const uint8_t spd_addr_fam10[] = { + // Socket 0 Node 0 ("Node 0") + RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, +- // Socket 0 Node 1 ("Node 1") +- RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, +- // Socket 1 Node 1 ("Node 2") +- RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0, +- // Socket 1 Node 0 ("Node 3") ++ // Socket 1 Node 0 ("Node 1") + RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0, + }; + + static void activate_spd_rom(const struct mem_controller *ctrl) { +- /* Nothing needs to be done as there is no SPD mux on this board */ + printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id); ++ if (ctrl->node_id == 0) { ++ printk(BIOS_DEBUG, "enable_spd_node0()\n"); ++ switch_spd_mux(0x2); ++ } else if (ctrl->node_id == 1) { ++ printk(BIOS_DEBUG, "enable_spd_node1()\n"); ++ switch_spd_mux(0x3); ++ } + } + + /* Voltages are specified by index +@@ -189,13 +187,12 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, + } + + for (node = 0; node < MAX_NODES_SUPPORTED; node++) { +- socket = node / 2; ++ socket = node; + struct DCTStatStruc *pDCTstat; + pDCTstat = pDCTstatA + node; + + /* reset socket_allowed_voltages before processing each socket */ +- if (!(node % 2)) +- socket_allowed_voltages = allowed_voltages; ++ socket_allowed_voltages = allowed_voltages; + + if (pDCTstat->NodePresent) { + for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { +@@ -203,10 +200,7 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, + socket_allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm]; + } + } +- } + +- /* set voltage per socket after processing last contained node */ +- if (pDCTstat->NodePresent && (node % 2)) { + /* Set voltages */ + if (socket_allowed_voltages & 0x8) { + set_voltage = 0x8; +@@ -223,16 +217,8 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, + } + + /* Save final DIMM voltages for MCT and SMBIOS use */ +- if (pDCTstat->NodePresent) { +- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { +- pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage; +- } +- } +- pDCTstat = pDCTstatA + (node - 1); +- if (pDCTstat->NodePresent) { +- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { +- pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage; +- } ++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { ++ pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage; + } + } + } +@@ -243,23 +229,10 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, + + static void set_peripheral_control_lines(void) { + uint8_t byte; +- uint8_t nvram; +- uint8_t enable_ieee1394; +- +- enable_ieee1394 = 1; +- +- if (get_option(&nvram, "ieee1394_controller") == CB_SUCCESS) +- enable_ieee1394 = nvram & 0x1; + +- if (enable_ieee1394) { +- /* Enable PCICLK5 (onboard FireWire device) */ +- outb(0x41, 0xcd6); +- outb(0x02, 0xcd7); +- } else { +- /* Disable PCICLK5 (onboard FireWire device) */ +- outb(0x41, 0xcd6); +- outb(0x00, 0xcd7); +- } ++ /* Enable PCICLK5 */ ++ outb(0x41, 0xcd6); ++ outb(0x02, 0xcd7); + + /* Enable the RTC AltCentury register */ + outb(0x41, 0xcd6); +@@ -584,8 +557,7 @@ BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List) + { + /* Force BUID to 0 */ + static const u8 swaplist[] = {0, 0, 0xFF, 0, 0xFF}; +- if ((is_fam15h() && (node == 0) && (link == 1)) /* Family 15h BSP SB link */ +- || (!is_fam15h() && (node == 0) && (link == 3))) { /* Family 10h BSP SB link */ ++ if ((node == 0) && (link == 2)) { /* BSP SB link */ + *List = swaplist; + return 1; + } +-- +2.1.4 + |