aboutsummaryrefslogtreecommitdiff
path: root/resources/libreboot/patch/coreboot
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libreboot/patch/coreboot')
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch312
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch132
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch72
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch175
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch61
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch155
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0007-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch34
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch423
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch980
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch99
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch107
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch89
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch149
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch63
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch30
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch32
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch59
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch73
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch40
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch31
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch74
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch30
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch53
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch249
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch109
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch59
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch27
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch32
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch185
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch92
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch65
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch60
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch1160
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch27
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch63
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch66
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch34
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch28
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch39
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch53
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch42
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch131
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch3928
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0044-mainboard-asus-kcma-d8-Initial-modification-for-KCMA.patch156
-rw-r--r--resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch575
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 00000000..1b8b9170
--- /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 00000000..31e47fd2
--- /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 00000000..2d49a2fc
--- /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 00000000..3f9fa8b1
--- /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 00000000..4bc79ea1
--- /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 00000000..8fc1513d
--- /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(&microcode_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 00000000..739ea611
--- /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 00000000..a5c547df
--- /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 00000000..5d50aae6
--- /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 00000000..35d0d6cf
--- /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 00000000..1c255982
--- /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 00000000..36efd720
--- /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 00000000..d9b70ca0
--- /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 00000000..5264c8fe
--- /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 00000000..dd76550b
--- /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 00000000..ab731acf
--- /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 00000000..987f0411
--- /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 00000000..7b2fdc23
--- /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 00000000..4e94f4f8
--- /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 00000000..99b8778e
--- /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 00000000..9926855d
--- /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 00000000..596cab99
--- /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 00000000..1f41eaf3
--- /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 00000000..b4be5faf
--- /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 00000000..ea534fa4
--- /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 00000000..7e878bc6
--- /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 00000000..65aada76
--- /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 00000000..0cb57baa
--- /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 00000000..8b010e55
--- /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 00000000..3d13fd46
--- /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 00000000..5bbee0dc
--- /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 00000000..a02f8e20
--- /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 00000000..1753b050
--- /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 00000000..a4ecef82
--- /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 00000000..cbeb3361
--- /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 00000000..ec82f70e
--- /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 00000000..85df388b
--- /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 00000000..cde1ce53
--- /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 00000000..8e036b3d
--- /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 00000000..05596423
--- /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 00000000..4df54cab
--- /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 00000000..e95630f2
--- /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 00000000..27a9b98b
--- /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(&microcode_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 00000000..a645e3d5
--- /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 00000000..77c06ab9
--- /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
+