summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/src/hcl/index.texi2
-rw-r--r--docs/src/hcl/kcma-d8.texi96
-rw-r--r--docs/src/install/index.texi14
-rw-r--r--docs/src/install/kcma-d8.texi50
-rw-r--r--docs/src/release.texi9
-rw-r--r--resources/libreboot/config/grub/kcma-d8/architecture1
-rw-r--r--resources/libreboot/config/grub/kcma-d8/cbrevision1
-rw-r--r--resources/libreboot/config/grub/kcma-d8/config604
-rw-r--r--resources/libreboot/config/grub/kcma-d8/vbootrevision1
-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
-rwxr-xr-xresources/scripts/helpers/build/roms/withgrub_helper4
-rw-r--r--resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/blobs.list52
-rw-r--r--resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs.list323
-rw-r--r--resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs_notes15
58 files changed, 11623 insertions, 2 deletions
diff --git a/docs/src/hcl/index.texi b/docs/src/hcl/index.texi
index d5bbbc6..087f832 100644
--- a/docs/src/hcl/index.texi
+++ b/docs/src/hcl/index.texi
@@ -67,6 +67,8 @@ Libreboot supports the following systems in this release:
@itemize
@item
@uref{ga-g41m-es2l.html,Gigabyte Gigabyte GA-G41M-ES2L motherboard}
+@item
+@uref{kcma-d8.html,ASUS KCMA-D8 motherboard}
@end itemize
@node Servers/workstations AMD x86
diff --git a/docs/src/hcl/kcma-d8.texi b/docs/src/hcl/kcma-d8.texi
new file mode 100644
index 0000000..2b54dc4
--- /dev/null
+++ b/docs/src/hcl/kcma-d8.texi
@@ -0,0 +1,96 @@
+\input texinfo
+@documentencoding UTF-8
+
+@ifnottex
+@paragraphindent 0
+@end ifnottex
+@titlepage
+@title ASUS KCMA-D8 server/workstation board
+@end titlepage
+
+@node Top
+@top ASUS KCMA-D8 server/workstation board
+
+@menu
+* ASUS KCMA-D8 server/workstation board::
+* Board status compatibility::
+* Form factor::
+* IPMI iKVM module add-on::
+* Flash chips::
+* Native graphics initialization::
+* Current issues::
+@end menu
+
+@node ASUS kcma-d8 server/workstation board
+@chapter ASUS kcma-d8 server/workstation board
+@anchor{#asus-kcma-d8-serverworkstation-board}
+This is a server board using AMD hardware (Fam10h @strong{and Fam15h} CPUs available). It can also be used for building a high-powered workstation. Powered by libreboot. The coreboot port was done by Timothy Pearson of @uref{https://raptorengineeringinc.com/,Raptor Engineering Inc.} and, working with Timothy (and sponsoring the work) merged into libreboot.
+
+@strong{NOTE: This board is unsupported in libreboot 20150518. To use it in libreboot, for now, you must build for it from source using the libreboot git repository.}
+
+Flashing instructions can be found at @uref{../install/index.html#flashrom,../install/index.html#flashrom} - note that external flashing is required (e.g. BBB), if the proprietary (ASUS) firmware is currently installed. If you already have libreboot, by default it is possible to re-flash using software running in GNU/Linux on the kcma-d8, without using external hardware.
+
+@uref{index.html,Back to previous index}.
+
+@node Board status compatibility
+@chapter Board status (compatibility)
+@anchor{#board-status-compatibility}
+See @uref{https://raptorengineeringinc.com/coreboot/kcma-d8-status.php,https://raptorengineeringinc.com/coreboot/kcma-d8-status.php}.
+
+@node Form factor
+@chapter Form factor
+@anchor{#form-factor}
+These boards use the SSI EEB 3.61 form factor; make sure that your case supports this. This form factor is similar to E-ATX in that the size is identical, but the position of the screws are different.
+
+@node IPMI iKVM module add-on
+@chapter IPMI iKVM module add-on
+@anchor{#ipmi-ikvm-module-add-on}
+Don't use it. It uses proprietary firmware and adds a backdoor (remote out-of-band management chip, similar to the @uref{http://libreboot.org/faq/#intelme,Intel Management Engine}. Fortunately, the firmware is unsigned (possibly to replace) and physically separate from the mainboard since it's on the add-on module, which you don't have to install.
+
+@node Flash chips
+@chapter Flash chips
+@anchor{#flash-chips}
+2MiB flash chips are included by default, on these boards. It's on a P-DIP 8 slot (SPI chip). The flash chip can be upgraded to higher sizes: 4MiB, 8MiB or 16MiB. With at least 8MiB, you could feasibly fit a compressed linux+initramfs image (BusyBox+Linux system) into CBFS and boot that, loading it into memory.
+
+Libreboot has configs for 2, 4, 8 and 16 MiB flash chip sizes (default flash chip is 2MiB).
+
+@strong{DO NOT hot-swap the chip with your bare hands. Use a P-DIP 8 chip extractor. These can be found online. See @uref{http://www.coreboot.org/Developer_Manual/Tools#Chip_removal_tools,http://www.coreboot.org/Developer_Manual/Tools#Chip_removal_tools}}
+
+@node Native graphics initialization
+@chapter Native graphics initialization
+@anchor{#native-graphics-initialization}
+Only text-mode is known to work, but linux(kernel) can initialize the framebuffer display (if it has KMS - kernel mode setting).
+
+@node Current issues
+@chapter Current issues
+@anchor{#current-issues}
+@itemize
+@item
+RDIMM memory modules untested, according to tpearson (they'll probably work)
+@item
+LRDIMM memory modules are currently incompatible
+@item
+SAS (via PIKE 2008 module) requires non-free option ROM (and SeaBIOS) to boot from it (theoretically possible to replace, but you can put a kernel in CBFS or on SATA and use that to boot GNU, which can be on a SAS drive. The linux kernel can use those SAS drives (via PIKE module) without an option ROM).
+@item
+IPMI iKVM module (optional add-on card) uses proprietary firmware. Since it's for remote out-of-band management, it's theoretically a backdoor similar to the Intel Management Engine. Fortunately, unlike the ME, this firmware is unsigned which means that a free replacement is theoretically possible. For now, the libreboot project recommends not installing the module. @uref{https://github.com/facebook/openbmc,This project} might be interesting to derive from, for those who want to work on a free replacement. In practise, out-of-band management isn't very useful anyway (or at the very least, it's not a major inconvenience to not have it).
+@item
+Graphics: only text-mode works. See @ref{#graphics,#graphics}
+@end itemize
+
+@menu
+* Hardware specifications::
+@end menu
+
+Check ASUS website for specs
+
+Copyright © 2015 Francis Rowe <info@@gluglug.org.uk>@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at @uref{../resources/licenses/gfdl-1.3.txt,gfdl-1.3.txt}
+
+Updated versions of the license (when available) can be found at @uref{https://www.gnu.org/licenses/licenses.html,https://www.gnu.org/licenses/licenses.html}
+
+UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+@bye
diff --git a/docs/src/install/index.texi b/docs/src/install/index.texi
index 9b7ddfb..994bbf4 100644
--- a/docs/src/install/index.texi
+++ b/docs/src/install/index.texi
@@ -61,6 +61,8 @@ This section relates to installing libreboot on supported targets.
@item
@uref{kgpe-d16.html,KGPE-D16 (needed if running the proprietary firmware, or to unbrick)}
@item
+@uref{kcma-d8.html,KCMA-D8 (needed if running the proprietary firmware, or to unbrick)}
+@item
@uref{x60_unbrick.html,ThinkPad X60: Recovery guide}
@item
@uref{x60tablet_unbrick.html,ThinkPad X60 Tablet: Recovery guide}
@@ -128,6 +130,7 @@ Look at the @ref{#rom,list of ROM images} to see which image is compatible with
* Are you currently running the original proprietary firmware?::
* ASUS KFSN4-DRE?::
* ASUS KGPE-D16?::
+* ASUS KCMA-D8?::
* Are you currently running libreboot or coreboot?::
* MAC address on GM45 X200/R400/T400/T500::
* Flash chip size::
@@ -167,6 +170,17 @@ If you already have coreboot or libreboot installed, without write protection on
Do check the HCL entry: @uref{../hcl/kgpe-d16.html,../hcl/kgpe-d16.html}
+@node ASUS KCMA-D8?
+@section ASUS KCMA-D8?
+@anchor{#asus-kcma-d8}
+If you have the proprietary BIOS, you need to flash libreboot externally. See @uref{kcma-d8.html,kcma-d8.html}.
+
+If you already have coreboot or libreboot installed, without write protection on the flash chip, then you can do it in software (otherwise, see link above).
+
+@strong{DO NOT hot-swap the chip with your bare hands. Use a PDIP-8 chip extractor. These can be found online. See @uref{http://www.coreboot.org/Developer_Manual/Tools#Chip_removal_tools,http://www.coreboot.org/Developer_Manual/Tools#Chip_removal_tools}}
+
+Do check the HCL entry: @uref{../hcl/kcma-d8.html,../hcl/kcma-d8.html}
+
@node Are you currently running libreboot or coreboot?
@section Are you currently running libreboot (or coreboot)?
@anchor{#are-you-currently-running-libreboot-or-coreboot}
diff --git a/docs/src/install/kcma-d8.texi b/docs/src/install/kcma-d8.texi
new file mode 100644
index 0000000..f2fe528
--- /dev/null
+++ b/docs/src/install/kcma-d8.texi
@@ -0,0 +1,50 @@
+\input texinfo
+@documentencoding UTF-8
+
+@ifnottex
+@paragraphindent 0
+@end ifnottex
+@titlepage
+@title KCMA-D8 external flashing instructions
+@end titlepage
+
+@node Top
+@top KCMA-D8 external flashing instructions
+
+@menu
+* KCMA-D8 external flashing instructions::
+* KCMA-D8 boards and full systems with libreboot preinstalled::
+* External programmer::
+@end menu
+
+@node KCMA-D8 external flashing instructions
+@chapter KCMA-D8 external flashing instructions
+@anchor{#kcma-d8-external-flashing-instructions}
+Initial flashing instructions for KCMA-D8.
+
+This guide is for those who want libreboot on their ASUS KCMA-D8 motherboard, while they still have the proprietary ASUS BIOS present. This guide can also be followed (adapted) if you brick you board, to know how to recover.
+
+For more general information about this board, refer to @uref{../hcl/kcma-d8.html,../hcl/kcma-d8.html}.
+
+TODO: show photos here, and other info.
+
+@uref{index.html,Back to main index}
+
+@node External programmer
+@chapter External programmer
+@anchor{#external-programmer}
+Refer to @uref{bbb_setup.html,bbb_setup.html} for a guide on how to set up an external SPI programmer.
+
+The flash chip is in a PDIP 8 socket (SPI flash chip) on the motherboard, which you take out and then re-flash with libreboot, using the programmer. @strong{DO NOT} remove the chip with your hands. Use a chip extractor tool.
+
+Copyright © 2016 Francis Rowe <info@@gluglug.org.uk>@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at @uref{../resources/licenses/gfdl-1.3.txt,gfdl-1.3.txt}
+
+Updated versions of the license (when available) can be found at @uref{https://www.gnu.org/licenses/licenses.html,https://www.gnu.org/licenses/licenses.html}
+
+UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+@bye
diff --git a/docs/src/release.texi b/docs/src/release.texi
index c4b5ce2..95c89b4 100644
--- a/docs/src/release.texi
+++ b/docs/src/release.texi
@@ -83,6 +83,15 @@ Check notes in @strong{@emph{hcl/kgpe-d16.html}}
@end itemize
@item
+@strong{ASUS KCMA-D8 desktop/workstation board}
+@itemize
+@item
+Check notes in @strong{@emph{hcl/kcma-d8.html}}
+@item
+@strong{NOTE: not in libreboot 20150518. Only in git, for now.}
+@end itemize
+
+@item
@strong{ThinkPad X60/X60s}
@itemize
@item
diff --git a/resources/libreboot/config/grub/kcma-d8/architecture b/resources/libreboot/config/grub/kcma-d8/architecture
new file mode 100644
index 0000000..5a9a476
--- /dev/null
+++ b/resources/libreboot/config/grub/kcma-d8/architecture
@@ -0,0 +1 @@
+i386
diff --git a/resources/libreboot/config/grub/kcma-d8/cbrevision b/resources/libreboot/config/grub/kcma-d8/cbrevision
new file mode 100644
index 0000000..832f0cc
--- /dev/null
+++ b/resources/libreboot/config/grub/kcma-d8/cbrevision
@@ -0,0 +1 @@
+369b561315ca68d0cdedc38208105a513c7139b5
diff --git a/resources/libreboot/config/grub/kcma-d8/config b/resources/libreboot/config/grub/kcma-d8/config
new file mode 100644
index 0000000..b98f981
--- /dev/null
+++ b/resources/libreboot/config/grub/kcma-d8/config
@@ -0,0 +1,604 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# coreboot configuration
+#
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_CBFS_PREFIX="fallback"
+# CONFIG_MULTIPLE_CBFS_INSTANCES is not set
+CONFIG_COMPILER_GCC=y
+# CONFIG_COMPILER_LLVM_CLANG is not set
+# CONFIG_ANY_TOOLCHAIN is not set
+# CONFIG_CCACHE is not set
+# CONFIG_FMD_GENPARSER is not set
+# CONFIG_SCONFIG_GENPARSER is not set
+# CONFIG_USE_OPTION_TABLE is not set
+# CONFIG_UNCOMPRESSED_RAMSTAGE is not set
+CONFIG_COMPRESS_RAMSTAGE=y
+CONFIG_INCLUDE_CONFIG_FILE=y
+CONFIG_EARLY_CBMEM_INIT=y
+# CONFIG_COLLECT_TIMESTAMPS is not set
+CONFIG_HAS_PRECBMEM_TIMESTAMP_REGION=y
+# CONFIG_USE_BLOBS is not set
+# CONFIG_COVERAGE is not set
+# CONFIG_RELOCATABLE_MODULES is not set
+# CONFIG_RELOCATABLE_RAMSTAGE is not set
+CONFIG_FLASHMAP_OFFSET=0
+CONFIG_BOOTBLOCK_SIMPLE=y
+# CONFIG_BOOTBLOCK_NORMAL is not set
+CONFIG_BOOTBLOCK_CUSTOM=y
+CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c"
+# CONFIG_UPDATE_IMAGE is not set
+# CONFIG_GENERIC_GPIO_LIB is not set
+# CONFIG_BOARD_ID_AUTO is not set
+# CONFIG_BOARD_ID_MANUAL is not set
+# CONFIG_RAM_CODE_SUPPORT is not set
+# CONFIG_BOOTSPLASH_IMAGE is not set
+# CONFIG_ACPI_SATA_GENERATOR is not set
+
+#
+# Mainboard
+#
+# CONFIG_VENDOR_A_TREND is not set
+# CONFIG_VENDOR_AAEON is not set
+# CONFIG_VENDOR_ABIT is not set
+# CONFIG_VENDOR_ADLINK is not set
+# CONFIG_VENDOR_ADVANSUS is not set
+# CONFIG_VENDOR_AMD is not set
+# CONFIG_VENDOR_AOPEN is not set
+# CONFIG_VENDOR_APPLE is not set
+# CONFIG_VENDOR_ARTECGROUP is not set
+# CONFIG_VENDOR_ASROCK is not set
+CONFIG_VENDOR_ASUS=y
+# CONFIG_VENDOR_AVALUE is not set
+# CONFIG_VENDOR_AZZA is not set
+# CONFIG_VENDOR_BACHMANN is not set
+# CONFIG_VENDOR_BAP is not set
+# CONFIG_VENDOR_BCOM is not set
+# CONFIG_VENDOR_BIFFEROS is not set
+# CONFIG_VENDOR_BIOSTAR is not set
+# CONFIG_VENDOR_BROADCOM is not set
+# CONFIG_VENDOR_COMPAQ is not set
+# CONFIG_VENDOR_CUBIETECH is not set
+# CONFIG_VENDOR_DIGITALLOGIC is not set
+# CONFIG_VENDOR_DMP is not set
+# CONFIG_VENDOR_ECS is not set
+# CONFIG_VENDOR_EMULATION is not set
+# CONFIG_VENDOR_ESD is not set
+# CONFIG_VENDOR_GETAC is not set
+# CONFIG_VENDOR_GIGABYTE is not set
+# CONFIG_VENDOR_GIZMOSPHERE is not set
+# CONFIG_VENDOR_GOOGLE is not set
+# CONFIG_VENDOR_HP is not set
+# CONFIG_VENDOR_IBASE is not set
+# CONFIG_VENDOR_IEI is not set
+# CONFIG_VENDOR_INTEL is not set
+# CONFIG_VENDOR_IWAVE is not set
+# CONFIG_VENDOR_IWILL is not set
+# CONFIG_VENDOR_JETWAY is not set
+# CONFIG_VENDOR_KONTRON is not set
+# CONFIG_VENDOR_LANNER is not set
+# CONFIG_VENDOR_LENOVO is not set
+# CONFIG_VENDOR_LINUTOP is not set
+# CONFIG_VENDOR_LIPPERT is not set
+# CONFIG_VENDOR_MITAC is not set
+# CONFIG_VENDOR_MSI is not set
+# CONFIG_VENDOR_NEC is not set
+# CONFIG_VENDOR_NOKIA is not set
+# CONFIG_VENDOR_NVIDIA is not set
+# CONFIG_VENDOR_PACKARDBELL is not set
+# CONFIG_VENDOR_PCENGINES is not set
+# CONFIG_VENDOR_RCA is not set
+# CONFIG_VENDOR_RODA is not set
+# CONFIG_VENDOR_SAMSUNG is not set
+# CONFIG_VENDOR_SIEMENS is not set
+# CONFIG_VENDOR_SOYO is not set
+# CONFIG_VENDOR_SUNW is not set
+# CONFIG_VENDOR_SUPERMICRO is not set
+# CONFIG_VENDOR_TECHNEXION is not set
+# CONFIG_VENDOR_THOMSON is not set
+# CONFIG_VENDOR_TI is not set
+# CONFIG_VENDOR_TRAVERSE is not set
+# CONFIG_VENDOR_TYAN is not set
+# CONFIG_VENDOR_VIA is not set
+# CONFIG_VENDOR_WINENT is not set
+# CONFIG_VENDOR_WYSE is not set
+CONFIG_BOARD_SPECIFIC_OPTIONS=y
+CONFIG_MAINBOARD_DIR="asus/kcma-d8"
+CONFIG_MAINBOARD_PART_NUMBER="KCMA-D8"
+CONFIG_IRQ_SLOT_COUNT=13
+CONFIG_MAINBOARD_VENDOR="ASUS"
+CONFIG_APIC_ID_OFFSET=0
+CONFIG_HW_MEM_HOLE_SIZEK=0x100000
+CONFIG_MAX_CPUS=16
+CONFIG_MAX_PHYSICAL_CPUS=2
+# CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC is not set
+CONFIG_HT_CHAIN_END_UNITID_BASE=0x20
+CONFIG_HT_CHAIN_UNITID_BASE=0x0
+CONFIG_ONBOARD_VGA_IS_PRIMARY=y
+# CONFIG_VGA_BIOS is not set
+# CONFIG_UDELAY_IO is not set
+CONFIG_MAINBOARD_SERIAL_NUMBER="123456789"
+CONFIG_DCACHE_RAM_BASE=0xc2000
+CONFIG_DCACHE_RAM_SIZE=0x1e000
+CONFIG_MMCONF_BASE_ADDRESS=0xc0000000
+CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="ASUS"
+# CONFIG_BOARD_ASUS_A8N_E is not set
+# CONFIG_BOARD_ASUS_A8N_SLI is not set
+# CONFIG_BOARD_ASUS_A8V_E_DELUXE is not set
+# CONFIG_BOARD_ASUS_A8V_E_SE is not set
+# CONFIG_BOARD_ASUS_DSBF is not set
+# CONFIG_BOARD_ASUS_F2A85_M is not set
+# CONFIG_BOARD_ASUS_F2A85_M_LE is not set
+# CONFIG_BOARD_ASUS_K8V_X is not set
+CONFIG_BOARD_ASUS_KCMA_D8=y
+# CONFIG_BOARD_ASUS_KFSN4_DRE is not set
+# CONFIG_BOARD_ASUS_KFSN4_DRE_K8 is not set
+# CONFIG_BOARD_ASUS_KGPE_D16 is not set
+# CONFIG_BOARD_ASUS_M2N_E is not set
+# CONFIG_BOARD_ASUS_M2V_MX_SE is not set
+# CONFIG_BOARD_ASUS_M2V is not set
+# CONFIG_BOARD_ASUS_M4A78_EM is not set
+# CONFIG_BOARD_ASUS_M4A785M is not set
+# CONFIG_BOARD_ASUS_M4A785TM is not set
+# CONFIG_BOARD_ASUS_M5A88_V is not set
+# CONFIG_BOARD_ASUS_MEW_AM is not set
+# CONFIG_BOARD_ASUS_MEW_VM is not set
+# CONFIG_BOARD_ASUS_P2B_D is not set
+# CONFIG_BOARD_ASUS_P2B_DS is not set
+# CONFIG_BOARD_ASUS_P2B_F is not set
+# CONFIG_BOARD_ASUS_P2B_LS is not set
+# CONFIG_BOARD_ASUS_P2B is not set
+# CONFIG_BOARD_ASUS_P3B_F is not set
+CONFIG_AGP_APERTURE_SIZE=0x4000000
+CONFIG_BOOTBLOCK_MAINBOARD_INIT="mainboard/asus/kcma-d8/bootblock.c"
+CONFIG_SOUTHBRIDGE_AMD_SB700_SATA_PORT_COUNT_BITFIELD=0x3f
+CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL=y
+CONFIG_MAX_REBOOT_CNT=10
+CONFIG_UART_FOR_CONSOLE=0
+CONFIG_ID_SECTION_OFFSET=0x80
+# CONFIG_BOARD_EMULATION_QEMU_ARMV7 is not set
+# CONFIG_BOARD_EMULATION_QEMU_X86_I440FX is not set
+# CONFIG_BOARD_EMULATION_QEMU_X86_Q35 is not set
+# CONFIG_BOARD_EMULATION_QEMU_UCB_RISCV is not set
+# CONFIG_BOARD_EMULATION_SPIKE_UCB_RISCV is not set
+CONFIG_RAMTOP=0x400000
+CONFIG_CACHE_ROM_SIZE_OVERRIDE=0
+CONFIG_CBFS_SIZE=0x200000
+CONFIG_POST_DEVICE=y
+CONFIG_USBDEBUG_HCD_INDEX=0
+CONFIG_BOOT_MEDIA_SPI_BUS=0
+CONFIG_TTYS0_LCS=3
+CONFIG_UDELAY_LAPIC_FIXED_FSB=200
+CONFIG_CPU_ADDR_BITS=48
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
+CONFIG_USBDEBUG=y
+CONFIG_MAINBOARD_VERSION="1.0"
+# CONFIG_DRIVERS_PS2_KEYBOARD is not set
+CONFIG_BOARD_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set
+CONFIG_COREBOOT_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set
+CONFIG_COREBOOT_ROMSIZE_KB=2048
+CONFIG_ROM_SIZE=0x200000
+# CONFIG_SYSTEM_TYPE_LAPTOP is not set
+
+#
+# Chipset
+#
+
+#
+# SoC
+#
+# CONFIG_SOC_BROADCOM_CYGNUS is not set
+CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/amd/amdfam10/bootblock.c"
+CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/amd/sb700/bootblock.c"
+CONFIG_TTYS0_BASE=0x3f8
+CONFIG_EHCI_BAR=0xfef00000
+CONFIG_HEAP_SIZE=0xc0000
+# CONFIG_SOC_MARVELL_BG4CD is not set
+# CONFIG_SOC_MEDIATEK_MT8173 is not set
+# CONFIG_SOC_NVIDIA_TEGRA124 is not set
+# CONFIG_SOC_NVIDIA_TEGRA132 is not set
+# CONFIG_SOC_NVIDIA_TEGRA210 is not set
+# CONFIG_SOC_QC_IPQ806X is not set
+# CONFIG_SOC_ROCKCHIP_RK3288 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set
+# CONFIG_SOC_UCB_RISCV is not set
+
+#
+# CPU
+#
+# CONFIG_CPU_ALLWINNER_A10 is not set
+CONFIG_DCACHE_BSP_STACK_SIZE=0x4000
+CONFIG_DCACHE_BSP_STACK_SLUSH=0x4000
+CONFIG_DCACHE_AP_STACK_SIZE=0x500
+CONFIG_CPU_SOCKET_TYPE=0x14
+# CONFIG_EXT_RT_TBL_SUPPORT is not set
+CONFIG_CBB=0x0
+CONFIG_CDB=0x18
+CONFIG_XIP_ROM_SIZE=0x80000
+CONFIG_CPU_AMD_SOCKET_C32_NON_AGESA=y
+CONFIG_DIMM_SUPPORT=0x0005
+CONFIG_LIFT_BSP_APIC_ID=y
+CONFIG_SET_FIDVID=y
+CONFIG_SET_FIDVID_DEBUG=y
+# CONFIG_SET_FIDVID_CORE0_ONLY is not set
+CONFIG_SET_FIDVID_STORE_AP_APICID_AT_FIRST=y
+CONFIG_CPU_AMD_MODEL_10XXX=y
+CONFIG_USE_LARGE_DCACHE=y
+CONFIG_NUM_IPI_STARTS=1
+CONFIG_SET_FIDVID_CORE_RANGE=0
+# CONFIG_CPU_AMD_AGESA is not set
+CONFIG_S3_DATA_POS=0x0
+CONFIG_S3_DATA_SIZE=32768
+# CONFIG_CPU_AMD_PI is not set
+# CONFIG_EXT_CONF_SUPPORT is not set
+# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set
+CONFIG_SSE2=y
+# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set
+# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set
+# CONFIG_CPU_TI_AM335X is not set
+CONFIG_PARALLEL_CPU_INIT=y
+CONFIG_UDELAY_LAPIC=y
+# CONFIG_LAPIC_MONOTONIC_TIMER is not set
+# CONFIG_UDELAY_TSC is not set
+# CONFIG_UDELAY_TIMER2 is not set
+# CONFIG_TSC_CALIBRATE_WITH_IO is not set
+CONFIG_TSC_SYNC_LFENCE=y
+# CONFIG_TSC_SYNC_MFENCE is not set
+CONFIG_LOGICAL_CPUS=y
+# CONFIG_SMM_TSEG is not set
+# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set
+# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set
+CONFIG_X86_AMD_FIXED_MTRRS=y
+# CONFIG_PLATFORM_USES_FSP1_0 is not set
+# CONFIG_PARALLEL_MP is not set
+# CONFIG_BACKUP_DEFAULT_SMM_REGION is not set
+# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set
+CONFIG_CACHE_AS_RAM=y
+CONFIG_SMP=y
+CONFIG_AP_SIPI_VECTOR=0xfffff000
+CONFIG_SSE=y
+CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y
+# CONFIG_USES_MICROCODE_HEADER_FILES is not set
+# CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set
+# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set
+CONFIG_CPU_MICROCODE_CBFS_NONE=y
+CONFIG_CPU_MICROCODE_MULTIPLE_FILES=y
+
+#
+# Northbridge
+#
+# CONFIG_NORTHBRIDGE_AMD_AGESA is not set
+CONFIG_MMCONF_BUS_NUMBER=256
+CONFIG_NORTHBRIDGE_AMD_AMDFAM10=y
+CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY=y
+# CONFIG_HT_CHAIN_DISTRIBUTE is not set
+# CONFIG_DIMM_FBDIMM is not set
+# CONFIG_DIMM_DDR2 is not set
+CONFIG_DIMM_DDR3=y
+CONFIG_DIMM_REGISTERED=y
+CONFIG_DIMM_VOLTAGE_SET_SUPPORT=y
+# CONFIG_SVI_HIGH_FREQ is not set
+
+#
+# HyperTransport setup
+#
+# CONFIG_LIMIT_HT_DOWN_WIDTH_8 is not set
+CONFIG_LIMIT_HT_DOWN_WIDTH_16=y
+# CONFIG_LIMIT_HT_UP_WIDTH_8 is not set
+CONFIG_LIMIT_HT_UP_WIDTH_16=y
+# CONFIG_AMD_NB_CIMX is not set
+# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set
+CONFIG_VIDEO_MB=0
+# CONFIG_NORTHBRIDGE_AMD_PI is not set
+CONFIG_RAMBASE=0x100000
+CONFIG_HPET_ADDRESS=0xfed00000
+CONFIG_HPET_MIN_TICKS=0x14
+CONFIG_MAX_PIRQ_LINKS=4
+
+#
+# Southbridge
+#
+# CONFIG_AMD_SB_CIMX is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set
+CONFIG_SOUTHBRIDGE_AMD_SB700=y
+CONFIG_SOUTHBRIDGE_SPECIFIC_OPTIONS=y
+CONFIG_SOUTHBRIDGE_AMD_SUBTYPE_SP5100=y
+# CONFIG_SOUTHBRIDGE_AMD_SB700_SKIP_ISA_DMA_INIT is not set
+CONFIG_SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA=y
+CONFIG_SOUTHBRIDGE_AMD_SR5650=y
+# CONFIG_SOUTHBRIDGE_INTEL_COMMON is not set
+
+#
+# Super I/O
+#
+CONFIG_SUPERIO_WINBOND_COMMON_ROMSTAGE=y
+CONFIG_SUPERIO_WINBOND_W83667HG_A=y
+
+#
+# Embedded Controllers
+#
+# CONFIG_MAINBOARD_HAS_CHROMEOS is not set
+# CONFIG_UEFI_2_4_BINDING is not set
+# CONFIG_ARCH_ARM is not set
+# CONFIG_ARCH_BOOTBLOCK_ARM is not set
+# CONFIG_ARCH_VERSTAGE_ARM is not set
+# CONFIG_ARCH_ROMSTAGE_ARM is not set
+# CONFIG_ARCH_RAMSTAGE_ARM is not set
+# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set
+# CONFIG_ARCH_VERSTAGE_ARMV4 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set
+# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set
+# CONFIG_ARCH_VERSTAGE_ARMV7 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set
+# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set
+# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set
+# CONFIG_ARM_LPAE is not set
+# CONFIG_ARCH_ARM64 is not set
+# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set
+# CONFIG_ARCH_VERSTAGE_ARM64 is not set
+# CONFIG_ARCH_ROMSTAGE_ARM64 is not set
+# CONFIG_ARCH_RAMSTAGE_ARM64 is not set
+# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set
+# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set
+# CONFIG_ARM64_A53_ERRATUM_843419 is not set
+# CONFIG_ARCH_MIPS is not set
+# CONFIG_ARCH_BOOTBLOCK_MIPS is not set
+# CONFIG_ARCH_VERSTAGE_MIPS is not set
+# CONFIG_ARCH_ROMSTAGE_MIPS is not set
+# CONFIG_ARCH_RAMSTAGE_MIPS is not set
+# CONFIG_ARCH_RISCV is not set
+# CONFIG_ARCH_BOOTBLOCK_RISCV is not set
+# CONFIG_ARCH_VERSTAGE_RISCV is not set
+# CONFIG_ARCH_ROMSTAGE_RISCV is not set
+# CONFIG_ARCH_RAMSTAGE_RISCV is not set
+CONFIG_ARCH_X86=y
+CONFIG_ARCH_BOOTBLOCK_X86_32=y
+CONFIG_ARCH_VERSTAGE_X86_32=y
+CONFIG_ARCH_ROMSTAGE_X86_32=y
+CONFIG_ARCH_RAMSTAGE_X86_32=y
+# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set
+# CONFIG_ARCH_VERSTAGE_X86_64 is not set
+# CONFIG_ARCH_ROMSTAGE_X86_64 is not set
+# CONFIG_ARCH_RAMSTAGE_X86_64 is not set
+# CONFIG_AP_IN_SIPI_WAIT is not set
+# CONFIG_SIPI_VECTOR_IN_ROM is not set
+# CONFIG_ROMCC is not set
+# CONFIG_LATE_CBMEM_INIT is not set
+CONFIG_PC80_SYSTEM=y
+CONFIG_HAVE_CMOS_DEFAULT=y
+CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default"
+CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y
+# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set
+# CONFIG_COMPILE_IN_DSDT is not set
+
+#
+# Devices
+#
+# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT is not set
+CONFIG_NATIVE_VGA_INIT_USE_EDID=y
+CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG=y
+# CONFIG_VGA_ROM_RUN is not set
+# CONFIG_ON_DEVICE_ROM_RUN is not set
+# CONFIG_PCI_OPTION_ROM_RUN_REALMODE is not set
+# CONFIG_PCI_OPTION_ROM_RUN_YABEL is not set
+# CONFIG_MULTIPLE_VGA_ADAPTERS is not set
+CONFIG_SMBUS_HAS_AUX_CHANNELS=y
+# CONFIG_SPD_CACHE is not set
+CONFIG_PCI=y
+CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT=y
+CONFIG_PCIX_PLUGIN_SUPPORT=y
+CONFIG_PCIEXP_PLUGIN_SUPPORT=y
+CONFIG_CARDBUS_PLUGIN_SUPPORT=y
+# CONFIG_AZALIA_PLUGIN_SUPPORT is not set
+CONFIG_PCIEXP_COMMON_CLOCK=y
+CONFIG_PCIEXP_ASPM=y
+CONFIG_PCIEXP_CLK_PM=y
+# CONFIG_EARLY_PCI_BRIDGE is not set
+CONFIG_PCIEXP_L1_SUB_STATE=y
+CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
+CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
+# CONFIG_PXE_ROM is not set
+# CONFIG_SOFTWARE_I2C is not set
+
+#
+# Generic Drivers
+#
+# CONFIG_DRIVERS_AS3722_RTC is not set
+CONFIG_DRIVERS_ASPEED_AST_COMMON=y
+CONFIG_DEVICE_SPECIFIC_OPTIONS=y
+CONFIG_DRIVERS_ASPEED_AST2050=y
+# CONFIG_ELOG is not set
+# CONFIG_GIC is not set
+# CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set
+# CONFIG_DRIVERS_I2C_RTD2132 is not set
+CONFIG_DRIVERS_I2C_W83795=y
+# CONFIG_INTEL_DP is not set
+# CONFIG_INTEL_DDI is not set
+# CONFIG_INTEL_EDID is not set
+# CONFIG_INTEL_INT15 is not set
+# CONFIG_INTEL_GMA_ACPI is not set
+# CONFIG_DRIVER_INTEL_I210 is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_DRIVERS_LENOVO_WACOM is not set
+# CONFIG_DRIVER_MAXIM_MAX77686 is not set
+# CONFIG_DRIVER_PARADE_PS8625 is not set
+CONFIG_DRIVERS_MC146818=y
+# CONFIG_MAINBOARD_HAS_LPC_TPM is not set
+# CONFIG_DRIVERS_RICOH_RCE822 is not set
+# CONFIG_DRIVERS_SIL_3114 is not set
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_ATOMIC_SEQUENCING=y
+CONFIG_SPI_FLASH_MEMORY_MAPPED=y
+# CONFIG_SPI_FLASH_NO_FAST_READ is not set
+CONFIG_SPI_FLASH_ADESTO=y
+CONFIG_SPI_FLASH_AMIC=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set
+# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set
+# CONFIG_DRIVER_TI_TPS65090 is not set
+# CONFIG_DRIVERS_TI_TPS65913 is not set
+# CONFIG_DRIVERS_TI_TPS65913_RTC is not set
+CONFIG_DRIVERS_UART=y
+CONFIG_DRIVERS_UART_8250IO=y
+# CONFIG_NO_UART_ON_SUPERIO is not set
+# CONFIG_DRIVERS_UART_8250MEM is not set
+# CONFIG_DRIVERS_UART_8250MEM_32 is not set
+# CONFIG_HAVE_UART_SPECIAL is not set
+# CONFIG_DRIVERS_UART_OXPCIE is not set
+# CONFIG_DRIVERS_UART_PL011 is not set
+CONFIG_HAVE_USBDEBUG=y
+CONFIG_HAVE_USBDEBUG_OPTIONS=y
+CONFIG_USBDEBUG_IN_ROMSTAGE=y
+CONFIG_USBDEBUG_DEFAULT_PORT=0
+CONFIG_USBDEBUG_DONGLE_STD=y
+# CONFIG_USBDEBUG_DONGLE_BEAGLEBONE is not set
+# CONFIG_USBDEBUG_DONGLE_BEAGLEBONE_BLACK is not set
+# CONFIG_USBDEBUG_DONGLE_FTDI_FT232H is not set
+CONFIG_USBDEBUG_OPTIONAL_HUB_PORT=0
+# CONFIG_DRIVER_XPOWERS_AXP209 is not set
+CONFIG_RTC=y
+# CONFIG_TPM is not set
+CONFIG_STACK_SIZE=0x1000
+CONFIG_MMCONF_SUPPORT_DEFAULT=y
+CONFIG_MMCONF_SUPPORT=y
+# CONFIG_BOOTMODE_STRAPS is not set
+
+#
+# Console
+#
+CONFIG_SQUELCH_EARLY_SMP=y
+CONFIG_CONSOLE_SERIAL=y
+
+#
+# I/O mapped, 8250-compatible
+#
+
+#
+# Serial port base address = 0x3f8
+#
+CONFIG_CONSOLE_SERIAL_115200=y
+# CONFIG_CONSOLE_SERIAL_57600 is not set
+# CONFIG_CONSOLE_SERIAL_38400 is not set
+# CONFIG_CONSOLE_SERIAL_19200 is not set
+# CONFIG_CONSOLE_SERIAL_9600 is not set
+CONFIG_TTYS0_BAUD=115200
+# CONFIG_SPKMODEM is not set
+CONFIG_CONSOLE_USB=y
+# CONFIG_CONSOLE_NE2K is not set
+CONFIG_CONSOLE_CBMEM=y
+CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set
+# CONFIG_NO_POST is not set
+# CONFIG_CMOS_POST is not set
+# CONFIG_CONSOLE_POST is not set
+CONFIG_POST_DEVICE_NONE=y
+# CONFIG_POST_DEVICE_LPC is not set
+# CONFIG_POST_DEVICE_PCI_PCIE is not set
+CONFIG_POST_IO=y
+CONFIG_POST_IO_PORT=0x80
+# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set
+CONFIG_HAVE_ACPI_RESUME=y
+CONFIG_HAVE_HARD_RESET=y
+CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK=y
+CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK=y
+CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK=y
+CONFIG_HAVE_MONOTONIC_TIMER=y
+# CONFIG_GENERIC_UDELAY is not set
+# CONFIG_TIMER_QUEUE is not set
+CONFIG_HAVE_OPTION_TABLE=y
+# CONFIG_PIRQ_ROUTE is not set
+# CONFIG_HAVE_SMI_HANDLER is not set
+CONFIG_PCI_IO_CFG_EXT=y
+CONFIG_IOAPIC=y
+# CONFIG_USE_WATCHDOG_ON_BOOT is not set
+CONFIG_VGA=y
+# CONFIG_GFXUMA is not set
+CONFIG_HAVE_ACPI_TABLES=y
+CONFIG_HAVE_MP_TABLE=y
+CONFIG_HAVE_PIRQ_TABLE=y
+# CONFIG_COMMON_FADT is not set
+
+#
+# System tables
+#
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_SMBIOS_TABLES=y
+CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="KCMA-D8"
+
+#
+# Payload
+#
+# CONFIG_PAYLOAD_NONE is not set
+CONFIG_PAYLOAD_ELF=y
+# CONFIG_PAYLOAD_FILO is not set
+# CONFIG_PAYLOAD_GRUB2 is not set
+# CONFIG_PAYLOAD_SEABIOS is not set
+# CONFIG_PAYLOAD_LINUX is not set
+# CONFIG_PAYLOAD_TIANOCORE is not set
+CONFIG_PAYLOAD_FILE="grub.elf"
+# CONFIG_SEABIOS_STABLE is not set
+# CONFIG_SEABIOS_MASTER is not set
+CONFIG_COMPRESSED_PAYLOAD_LZMA=y
+
+#
+# Debugging
+#
+# CONFIG_GDB_STUB is not set
+# CONFIG_FATAL_ASSERTS is not set
+# CONFIG_DEBUG_CBFS is not set
+CONFIG_HAVE_DEBUG_RAM_SETUP=y
+# CONFIG_DEBUG_RAM_SETUP is not set
+CONFIG_HAVE_DEBUG_CAR=y
+# CONFIG_DEBUG_CAR is not set
+# CONFIG_DEBUG_PIRQ is not set
+CONFIG_HAVE_DEBUG_SMBUS=y
+# CONFIG_DEBUG_SMBUS is not set
+# CONFIG_DEBUG_MALLOC is not set
+# CONFIG_DEBUG_ACPI is not set
+# CONFIG_DEBUG_SPI_FLASH is not set
+# CONFIG_DEBUG_USBDEBUG is not set
+# CONFIG_TRACE is not set
+CONFIG_ENABLE_APIC_EXT_ID=y
+CONFIG_WARNINGS_ARE_ERRORS=y
+CONFIG_IASL_WARNINGS_ARE_ERRORS=y
+# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set
+# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set
+# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set
+# CONFIG_REG_SCRIPT is not set
diff --git a/resources/libreboot/config/grub/kcma-d8/vbootrevision b/resources/libreboot/config/grub/kcma-d8/vbootrevision
new file mode 100644
index 0000000..074840e
--- /dev/null
+++ b/resources/libreboot/config/grub/kcma-d8/vbootrevision
@@ -0,0 +1 @@
+d6723ed12b429834c2627c009aab58f0db20ce73
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch
new file mode 100644
index 0000000..1b8b917
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0001-southbridge-amd-sr5650-Add-MCFG-ACPI-table-support.patch
@@ -0,0 +1,312 @@
+From 00b7f63bd7bd400d9fdf92974c5e295b30ba1d2f Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Fri, 14 Aug 2015 15:20:42 -0500
+Subject: [PATCH 01/45] southbridge/amd/sr5650: Add MCFG ACPI table support
+
+Change-Id: I0c4ba74ddcc727cd92b848d5d3240e6f9f392101
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdfam10/northbridge.c | 22 +++---
+ src/southbridge/amd/rs780/rs780.c | 11 +++
+ src/southbridge/amd/rs780/rs780.h | 1 +
+ src/southbridge/amd/sb700/lpc.c | 6 --
+ src/southbridge/amd/sb800/lpc.c | 7 +-
+ src/southbridge/amd/sr5650/Kconfig | 9 +++
+ src/southbridge/amd/sr5650/ht.c | 107 ++++++++++++++++++++++++++++-
+ src/southbridge/amd/sr5650/sr5650.c | 18 +++++
+ 8 files changed, 156 insertions(+), 25 deletions(-)
+
+diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c
+index c8bf8fa..b376171 100644
+--- a/src/northbridge/amd/amdfam10/northbridge.c
++++ b/src/northbridge/amd/amdfam10/northbridge.c
+@@ -737,16 +737,18 @@ static void amdfam10_domain_read_resources(device_t dev)
+
+ pci_domain_read_resources(dev);
+
+-#if CONFIG_MMCONF_SUPPORT
+- struct resource *res = new_resource(dev, 0xc0010058);
+- res->base = CONFIG_MMCONF_BASE_ADDRESS;
+- res->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256;
+- res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
+- IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+-
+- /* Reserve lower DRAM region to force PCI MMIO region to correct location above 0xefffffff */
+- ram_resource(dev, 7, 0, rdmsr(TOP_MEM).lo >> 10);
+-#endif
++ if (IS_ENABLED(CONFIG_MMCONF_SUPPORT) && !IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
++ struct resource *res = new_resource(dev, 0xc0010058);
++ res->base = CONFIG_MMCONF_BASE_ADDRESS;
++ res->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256;
++ res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
++ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
++ }
++
++ if (IS_ENABLED(CONFIG_MMCONF_SUPPORT)) {
++ /* Reserve lower DRAM region to force PCI MMIO region to correct location above 0xefffffff */
++ ram_resource(dev, 7, 0, rdmsr(TOP_MEM).lo >> 10);
++ }
+
+ if (is_fam15h()) {
+ enable_cc6 = 0;
+diff --git a/src/southbridge/amd/rs780/rs780.c b/src/southbridge/amd/rs780/rs780.c
+index c82a629..0d482ae 100644
+--- a/src/southbridge/amd/rs780/rs780.c
++++ b/src/southbridge/amd/rs780/rs780.c
+@@ -349,6 +349,17 @@ void rs780_enable(device_t dev)
+ }
+ }
+
++#if !IS_ENABLED(CONFIG_AMD_SB_CIMX)
++unsigned long acpi_fill_mcfg(unsigned long current)
++{
++ /* FIXME
++ * Leave table blank until proper contents
++ * are determined.
++ */
++ return current;
++}
++#endif
++
+ struct chip_operations southbridge_amd_rs780_ops = {
+ CHIP_NAME("ATI RS780")
+ .enable_dev = rs780_enable,
+diff --git a/src/southbridge/amd/rs780/rs780.h b/src/southbridge/amd/rs780/rs780.h
+index 341de0d..abc601f 100644
+--- a/src/southbridge/amd/rs780/rs780.h
++++ b/src/southbridge/amd/rs780/rs780.h
+@@ -17,6 +17,7 @@
+ #define __RS780_H__
+
+ #include <stdint.h>
++#include <arch/acpi.h>
+ #include <device/pci_ids.h>
+ #include "chip.h"
+ #include "rev.h"
+diff --git a/src/southbridge/amd/sb700/lpc.c b/src/southbridge/amd/sb700/lpc.c
+index a71fe1f..78933fa 100644
+--- a/src/southbridge/amd/sb700/lpc.c
++++ b/src/southbridge/amd/sb700/lpc.c
+@@ -30,12 +30,6 @@
+ #include <cpu/amd/powernow.h>
+ #include "sb700.h"
+
+-unsigned long acpi_fill_mcfg(unsigned long current)
+-{
+- /* Just a dummy */
+- return current;
+-}
+-
+ static void lpc_init(device_t dev)
+ {
+ u8 byte;
+diff --git a/src/southbridge/amd/sb800/lpc.c b/src/southbridge/amd/sb800/lpc.c
+index 756a0c4..18d4471 100644
+--- a/src/southbridge/amd/sb800/lpc.c
++++ b/src/southbridge/amd/sb800/lpc.c
+@@ -2,6 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -25,12 +26,6 @@
+ #include <arch/acpi.h>
+ #include "sb800.h"
+
+-unsigned long acpi_fill_mcfg(unsigned long current)
+-{
+- /* Just a dummy */
+- return current;
+-}
+-
+ static void lpc_init(device_t dev)
+ {
+ u8 byte;
+diff --git a/src/southbridge/amd/sr5650/Kconfig b/src/southbridge/amd/sr5650/Kconfig
+index 29017c6..f2d12ff 100644
+--- a/src/southbridge/amd/sr5650/Kconfig
++++ b/src/southbridge/amd/sr5650/Kconfig
+@@ -15,3 +15,12 @@
+
+ config SOUTHBRIDGE_AMD_SR5650
+ bool
++
++if SOUTHBRIDGE_AMD_SR5650
++config EXT_CONF_SUPPORT
++ bool "Enable PCI-E MMCONFIG support"
++ default n
++ help
++ Select to enable PCI-E MMCONFIG support on the SR5650.
++
++endif
+diff --git a/src/southbridge/amd/sr5650/ht.c b/src/southbridge/amd/sr5650/ht.c
+index 6119985..e74d36b 100644
+--- a/src/southbridge/amd/sr5650/ht.c
++++ b/src/southbridge/amd/sr5650/ht.c
+@@ -20,7 +20,9 @@
+ #include <device/pci_ids.h>
+ #include <device/pci_ops.h>
+ #include <arch/ioapic.h>
++#include <lib.h>
+ #include "sr5650.h"
++#include "cmn.h"
+
+ /* Table 6-6 Recommended Interrupt Routing Configuration */
+ typedef struct _apic_device_info {
+@@ -154,11 +156,29 @@ static void pcie_init(struct device *dev)
+
+ static void sr5690_read_resource(struct device *dev)
+ {
++ struct resource *res;
++
++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
++ printk(BIOS_DEBUG,"%s: %s\n", __func__, dev_path(dev));
++ set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 1 << 3); /* Hide BAR3 */
++ }
++
+ pci_dev_read_resources(dev);
+
+ /* rpr6.2.(1). Write the Base Address Register (BAR) */
+- pci_write_config32(dev, 0xF8, 0x1); /* set IOAPIC's index as 1 and make sure no one changes it. */
+- pci_get_resource(dev, 0xFC); /* APIC located in sr5690 */
++ pci_write_config32(dev, 0xf8, 0x1); /* Set IOAPIC's index to 1 and make sure no one changes it */
++ pci_get_resource(dev, 0xfc); /* APIC located in sr5690 */
++
++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
++ res = new_resource(dev, 0x1c); /* PCIe MCFG space */
++ res->base = EXT_CONF_BASE_ADDRESS;
++ res->size = CONFIG_MMCONF_BUS_NUMBER * 1024 * 1024; /* Each bus needs 1M */
++ res->align = log2(res->size);
++ res->gran = log2(res->size);
++ res->limit = 0xffffffffffffffffULL; /* 64-bit location allowed */
++ res->flags = IORESOURCE_FIXED | IORESOURCE_MEM | IORESOURCE_PCI64
++ | IORESOURCE_ASSIGNED | IORESOURCE_RESERVE | IORESOURCE_BRIDGE;
++ }
+
+ compact_resources(dev);
+ }
+@@ -166,7 +186,88 @@ static void sr5690_read_resource(struct device *dev)
+ /* If IOAPIC's index changes, we should replace the pci_dev_set_resource(). */
+ static void sr5690_set_resources(struct device *dev)
+ {
+- pci_write_config32(dev, 0xF8, 0x1); /* set IOAPIC's index as 1 and make sure no one changes it. */
++ pci_write_config32(dev, 0xf8, 0x1); /* Set IOAPIC's index to 1 and make sure no one changes it */
++
++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
++ uint32_t reg;
++ device_t amd_ht_cfg_dev;
++ device_t amd_addr_map_dev;
++ resource_t res_base;
++ resource_t res_end;
++ uint32_t base;
++ uint32_t limit;
++ struct resource *res;
++
++ printk(BIOS_DEBUG,"%s %s\n", dev_path(dev), __func__);
++
++ res = probe_resource(dev, 0x1c);
++ if (res) {
++ /* Find requisite AMD CPU devices */
++ amd_ht_cfg_dev = dev_find_slot(0, PCI_DEVFN(0x18, 0));
++ amd_addr_map_dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
++
++ if (!amd_ht_cfg_dev || !amd_addr_map_dev) {
++ printk(BIOS_WARNING, "%s: %s Unable to locate CPU control devices\n", __func__, dev_path(dev));
++ }
++ else {
++ /* Set up MMCONFIG bus range */
++ set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 0 << 3); /* Make BAR3 visible */
++ set_nbcfg_enable_bits(dev, 0x7c, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register */
++ set_nbcfg_enable_bits(dev, 0x84, 7 << 16, 0 << 16); /* Program bus range = 255 busses */
++ pci_write_config32(dev, 0x1c, res->base);
++
++ /* Enable MMCONFIG decoding. */
++ set_htiu_enable_bits(dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */
++ set_nbcfg_enable_bits(dev, 0x7c, 1 << 30, 0 << 30); /* Disable writes to the BAR3 register */
++ set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 1 << 3); /* Hide BAR3 */
++
++ /* Set up nonposted resource in MMIO space */
++ res_base = res->base; /* Get the base address */
++ res_end = resource_end(res); /* Get the limit (rounded up) */
++ printk(BIOS_DEBUG, "%s: %s[0x1c] base = %0llx limit = %0llx\n", __func__, dev_path(dev), res_base, res_end);
++
++ /* Locate an unused MMIO resource */
++ for (reg = 0xb8; reg >= 0x80; reg -= 8) {
++ base = pci_read_config32(amd_addr_map_dev, reg);
++ limit = pci_read_config32(amd_addr_map_dev, reg + 4);
++ if (!(base & 0x3))
++ break; /* Unused resource found */
++ }
++
++ /* If an unused MMIO resource was available, set up the mapping */
++ if (!(base & 0x3)) {
++ uint32_t sblk;
++
++ /* Remember this resource has been stored. */
++ res->flags |= IORESOURCE_STORED;
++ report_resource_stored(dev, res, " <mmconfig>");
++
++ /* Get SBLink value (HyperTransport I/O Hub Link ID). */
++ sblk = (pci_read_config32(amd_ht_cfg_dev, 0x64) >> 8) & 0x3;
++
++ /* Calculate the MMIO mapping base */
++ base &= 0x000000f0;
++ base |= ((res_base >> 8) & 0xffffff00);
++ base |= 3;
++
++ /* Calculate the MMIO mapping limit */
++ limit &= 0x00000048;
++ limit |= ((res_end >> 8) & 0xffffff00);
++ limit |= (sblk << 4);
++ limit |= (1 << 7);
++
++ /* Configure and enable MMIO mapping */
++ printk(BIOS_INFO, "%s: %s <- index %x base %04x limit %04x\n", __func__, dev_path(amd_addr_map_dev), reg, base, limit);
++ pci_write_config32(amd_addr_map_dev, reg + 4, limit);
++ pci_write_config32(amd_addr_map_dev, reg, base);
++ }
++ else {
++ printk(BIOS_WARNING, "%s: %s No free MMIO resources available\n", __func__, dev_path(dev));
++ }
++ }
++ }
++ }
++
+ pci_dev_set_resources(dev);
+ }
+
+diff --git a/src/southbridge/amd/sr5650/sr5650.c b/src/southbridge/amd/sr5650/sr5650.c
+index 07b4a02..54f0071 100644
+--- a/src/southbridge/amd/sr5650/sr5650.c
++++ b/src/southbridge/amd/sr5650/sr5650.c
+@@ -796,6 +796,24 @@ static void add_ivrs_device_entries(struct device *parent, struct device *dev, i
+ free(root_level);
+ }
+
++unsigned long acpi_fill_mcfg(unsigned long current)
++{
++ struct resource *res;
++ resource_t mmconf_base = EXT_CONF_BASE_ADDRESS;
++
++ if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
++ device_t dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ /* Report MMCONF base */
++ res = probe_resource(dev, 0x1c);
++ if (res)
++ mmconf_base = res->base;
++
++ current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, mmconf_base, 0x0, 0x0, 0x1f);
++ }
++
++ return current;
++}
++
+ static unsigned long acpi_fill_ivrs(acpi_ivrs_t* ivrs, unsigned long current)
+ {
+ uint8_t *p;
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch
new file mode 100644
index 0000000..31e47fd
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0002-src-console-Add-x86-romstage-spinlock-option-and-pri.patch
@@ -0,0 +1,132 @@
+From 964824b31218e5e63c2b52a11491e1b44692eb83 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Mon, 18 May 2015 16:04:10 -0500
+Subject: [PATCH 02/45] src/console: Add x86 romstage spinlock option and
+ printk spinlock support
+
+This paves the way for AP printk spinlock on AMD platforms
+
+Change-Id: Ice42a0d3177736bf6e1bc601092e413601866f20
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/Kconfig | 4 ++++
+ src/arch/x86/include/arch/smp/spinlock.h | 11 ++++++++++-
+ src/console/printk.c | 15 +++++++++++++++
+ src/cpu/amd/car/post_cache_as_ram.c | 4 ++++
+ 4 files changed, 33 insertions(+), 1 deletion(-)
+
+diff --git a/src/Kconfig b/src/Kconfig
+index 8439a00..b8da62a 100644
+--- a/src/Kconfig
++++ b/src/Kconfig
+@@ -468,6 +468,10 @@ config HAVE_HARD_RESET
+ This variable specifies whether a given board has a hard_reset
+ function, no matter if it's provided by board code or chipset code.
+
++config HAVE_ROMSTAGE_CONSOLE_SPINLOCK
++ bool
++ default n
++
+ config HAVE_MONOTONIC_TIMER
+ def_bool n
+ help
+diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h
+index 32be2f2..74e532c 100644
+--- a/src/arch/x86/include/arch/smp/spinlock.h
++++ b/src/arch/x86/include/arch/smp/spinlock.h
+@@ -1,7 +1,7 @@
+ #ifndef ARCH_SMP_SPINLOCK_H
+ #define ARCH_SMP_SPINLOCK_H
+
+-#ifndef __PRE_RAM__
++#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+
+ /*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+@@ -11,9 +11,18 @@ typedef struct {
+ volatile unsigned int lock;
+ } spinlock_t;
+
++#ifdef __PRE_RAM__
++spinlock_t *romstage_console_lock(void);
++void initialize_romstage_console_lock(void);
++#endif
+
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
++
++#ifndef __PRE_RAM__
+ #define DECLARE_SPIN_LOCK(x) static spinlock_t x = SPIN_LOCK_UNLOCKED;
++#else
++#define DECLARE_SPIN_LOCK(x)
++#endif
+
+ /*
+ * Simple spin lock operations. There are two variants, one clears IRQ's
+diff --git a/src/console/printk.c b/src/console/printk.c
+index aab7ff5..99f90a8 100644
+--- a/src/console/printk.c
++++ b/src/console/printk.c
+@@ -2,6 +2,7 @@
+ * blatantly copied from linux/kernel/printk.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ */
+
+@@ -13,7 +14,9 @@
+ #include <stddef.h>
+ #include <trace.h>
+
++#if (!defined(__PRE_RAM__) && IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)) || !IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+ DECLARE_SPIN_LOCK(console_lock)
++#endif
+
+ void do_putchar(unsigned char byte)
+ {
+@@ -39,7 +42,13 @@ int do_printk(int msg_level, const char *fmt, ...)
+ #endif
+
+ DISABLE_TRACE;
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
++ spin_lock(romstage_console_lock());
++#endif
++#else
+ spin_lock(&console_lock);
++#endif
+
+ va_start(args, fmt);
+ i = vtxprintf(wrap_putchar, fmt, args, NULL);
+@@ -47,7 +56,13 @@ int do_printk(int msg_level, const char *fmt, ...)
+
+ console_tx_flush();
+
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
++ spin_unlock(romstage_console_lock());
++#endif
++#else
+ spin_unlock(&console_lock);
++#endif
+ ENABLE_TRACE;
+
+ return i;
+diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c
+index fb09cd4..8c5757e 100644
+--- a/src/cpu/amd/car/post_cache_as_ram.c
++++ b/src/cpu/amd/car/post_cache_as_ram.c
+@@ -76,6 +76,10 @@ static void prepare_ramstage_region(void *resume_backup_memory)
+ memset_((void*)0, 0, CONFIG_RAMTOP - backup_top);
+ }
+
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
++ initialize_romstage_console_lock();
++#endif
++
+ print_car_debug(" Done\n");
+ }
+
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch
new file mode 100644
index 0000000..2d49a2f
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0003-mainboard-asus-kgpe-d16-Enable-romstage-spinlocks.patch
@@ -0,0 +1,72 @@
+From 013c91f9f6699cfefcda0d0745db7bd999d7cdb5 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Thu, 5 Nov 2015 13:16:55 -0600
+Subject: [PATCH 03/45] mainboard/asus/kgpe-d16: Enable romstage spinlocks
+
+Change-Id: Iac1adbeacdcded7faff2443b78a491cbb8a90fe8
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/Kconfig | 1 +
+ src/mainboard/asus/kgpe-d16/romstage.c | 20 +++++++++++++++-----
+ 2 files changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig
+index c4f3962..67b43ca 100644
+--- a/src/mainboard/asus/kgpe-d16/Kconfig
++++ b/src/mainboard/asus/kgpe-d16/Kconfig
+@@ -14,6 +14,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ select SOUTHBRIDGE_AMD_SUBTYPE_SP5100
+ select SUPERIO_NUVOTON_NCT5572D
+ select PARALLEL_CPU_INIT
++ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK
+ select HAVE_HARD_RESET
+ select HAVE_OPTION_TABLE
+ select HAVE_CMOS_DEFAULT
+diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
+index df76ab4..13eacd2 100644
+--- a/src/mainboard/asus/kgpe-d16/romstage.c
++++ b/src/mainboard/asus/kgpe-d16/romstage.c
+@@ -312,6 +312,18 @@ static void execute_memory_test(void)
+ }
+ #endif
+
++static spinlock_t printk_spinlock CAR_GLOBAL;
++
++spinlock_t* romstage_console_lock(void)
++{
++ return car_get_var_ptr(&printk_spinlock);
++}
++
++void initialize_romstage_console_lock(void)
++{
++ car_get_var(printk_spinlock) = SPIN_LOCK_UNLOCKED;
++}
++
+ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ {
+ uint32_t esp;
+@@ -338,6 +350,9 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ timestamp_init(timestamp_get());
+ timestamp_add_now(TS_START_ROMSTAGE);
+
++ /* Initialize the printk spinlock */
++ initialize_romstage_console_lock();
++
+ /* Nothing special needs to be done to find bus 0 */
+ /* Allow the HT devices to be found */
+ set_bsp_node_CHtExtNodeCfgEn();
+@@ -407,11 +422,6 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ post_code(0x36);
+
+ /* Wait for all the APs core0 started by finalize_node_setup. */
+- /* FIXME: A bunch of cores are going to start output to serial at once.
+- * It would be nice to fix up prink spinlocks for ROM XIP mode.
+- * I think it could be done by putting the spinlock flag in the cache
+- * of the BSP located right after sysinfo.
+- */
+ wait_all_core0_started();
+
+ /* run _early_setup before soft-reset. */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch
new file mode 100644
index 0000000..3f9fa8b
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0004-drivers-pc80-Add-optional-spinlock-for-nvram-CBFS-ac.patch
@@ -0,0 +1,175 @@
+From cac177b845bea4469b7e7c4345f90d02eb11ce5a Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Fri, 28 Aug 2015 19:52:05 -0500
+Subject: [PATCH 04/45] drivers/pc80: Add optional spinlock for nvram CBFS
+ access
+
+When enabling the IOMMU on certain systems dmesg is spammed with I/O page faults like the following:
+AMD-Vi: Event logged [IO_PAGE_FAULT device=00:14.0 domain=0x000a address=0x000000fdf9103300 flags=0x0030]
+
+Decoding the faulting address:
+0x000000fdf9103300
+ fdf91x Hypertransport system management region
+ 33 SysMgtCmd (System Management Command) = 0x33
+ 3 Base Command Type = 0x3: STPCLK (Stop Clock request)
+ 3 SMAF (System Management Action Field) = [3:1] = 0x1
+ 1 Signal State Bit Map = [0] = 0x1
+
+Therefore, the error appears to be triggered by an upstream C1E request.
+
+This was eventually traced to concurrent access to the SP5100's SPI Flash controller by
+multiple APs during startup. Calls to the nvram read functions get_option and read_option
+call CBFS functions, which in turn make near-simultaneous requests to the SPI Flash
+controller, thus placing the SP5100 in an invalid state. This limitation is not documented
+in any public AMD errata, and was only discovered through considerable debugging effort.
+
+Change-Id: I4e61b1ab767b1b7958ac7c1cf20eee41d2261bef
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/Kconfig | 4 +++
+ src/arch/x86/include/arch/smp/spinlock.h | 4 ++-
+ src/cpu/amd/car/post_cache_as_ram.c | 3 +++
+ src/drivers/pc80/mc146818rtc.c | 43 ++++++++++++++++++++++++++++++--
+ 4 files changed, 51 insertions(+), 3 deletions(-)
+
+diff --git a/src/Kconfig b/src/Kconfig
+index b8da62a..5c38b7e 100644
+--- a/src/Kconfig
++++ b/src/Kconfig
+@@ -472,6 +472,10 @@ config HAVE_ROMSTAGE_CONSOLE_SPINLOCK
+ bool
+ default n
+
++config HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
++ bool
++ default n
++
+ config HAVE_MONOTONIC_TIMER
+ def_bool n
+ help
+diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h
+index 74e532c..057d9e3 100644
+--- a/src/arch/x86/include/arch/smp/spinlock.h
++++ b/src/arch/x86/include/arch/smp/spinlock.h
+@@ -1,7 +1,7 @@
+ #ifndef ARCH_SMP_SPINLOCK_H
+ #define ARCH_SMP_SPINLOCK_H
+
+-#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
++#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
+
+ /*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+@@ -14,6 +14,8 @@ typedef struct {
+ #ifdef __PRE_RAM__
+ spinlock_t *romstage_console_lock(void);
+ void initialize_romstage_console_lock(void);
++spinlock_t* romstage_nvram_cbfs_lock(void);
++void initialize_romstage_nvram_cbfs_lock(void);
+ #endif
+
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
+diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c
+index 8c5757e..435fdcb 100644
+--- a/src/cpu/amd/car/post_cache_as_ram.c
++++ b/src/cpu/amd/car/post_cache_as_ram.c
+@@ -79,6 +79,9 @@ static void prepare_ramstage_region(void *resume_backup_memory)
+ #if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
+ initialize_romstage_console_lock();
+ #endif
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ initialize_romstage_nvram_cbfs_lock();
++#endif
+
+ print_car_debug(" Done\n");
+ }
+diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c
+index 0c95265..0afc12b 100644
+--- a/src/drivers/pc80/mc146818rtc.c
++++ b/src/drivers/pc80/mc146818rtc.c
+@@ -2,6 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 The Chromium OS Authors. All rights reserved.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -33,6 +34,11 @@
+ #define LB_CKS_LOC 0
+ #endif
+
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++#include <smp/spinlock.h>
++#endif
++#endif
+
+ static void cmos_reset_date(void)
+ {
+@@ -204,6 +210,12 @@ enum cb_err get_option(void *dest, const char *name)
+ if (!IS_ENABLED(CONFIG_USE_OPTION_TABLE))
+ return CB_CMOS_OTABLE_DISABLED;
+
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ spin_lock(romstage_nvram_cbfs_lock());
++#endif
++#endif
++
+ /* Figure out how long name is */
+ namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
+
+@@ -213,6 +225,11 @@ enum cb_err get_option(void *dest, const char *name)
+ if (!ct) {
+ printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. "
+ "Options are disabled\n");
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ spin_unlock(romstage_nvram_cbfs_lock());
++#endif
++#endif
+ return CB_CMOS_LAYOUT_NOT_FOUND;
+ }
+ ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length);
+@@ -225,13 +242,35 @@ enum cb_err get_option(void *dest, const char *name)
+ }
+ if (!found) {
+ printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name);
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ spin_unlock(romstage_nvram_cbfs_lock());
++#endif
++#endif
+ return CB_CMOS_OPTION_NOT_FOUND;
+ }
+
+- if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS)
++ if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS) {
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ spin_unlock(romstage_nvram_cbfs_lock());
++#endif
++#endif
+ return CB_CMOS_ACCESS_ERROR;
+- if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC))
++ }
++ if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC)) {
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ spin_unlock(romstage_nvram_cbfs_lock());
++#endif
++#endif
+ return CB_CMOS_CHECKSUM_INVALID;
++ }
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++ spin_unlock(romstage_nvram_cbfs_lock());
++#endif
++#endif
+ return CB_SUCCESS;
+ }
+
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch
new file mode 100644
index 0000000..4bc79ea
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0005-mainboard-asus-kgpe-d16-Enable-CBFS-spinlocks.patch
@@ -0,0 +1,61 @@
+From 0c194e790a3b6550afc298beaeeb4a537fae4bfb Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Fri, 28 Aug 2015 20:02:45 -0500
+Subject: [PATCH 05/45] mainboard/asus/kgpe-d16: Enable CBFS spinlocks
+
+Change-Id: I8f6226d3e74ac5c7f29f708128a7502ced1287bf
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/Kconfig | 1 +
+ src/mainboard/asus/kgpe-d16/romstage.c | 15 ++++++++++++++-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig
+index 67b43ca..49dd37b 100644
+--- a/src/mainboard/asus/kgpe-d16/Kconfig
++++ b/src/mainboard/asus/kgpe-d16/Kconfig
+@@ -15,6 +15,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ select SUPERIO_NUVOTON_NCT5572D
+ select PARALLEL_CPU_INIT
+ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK
++ select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
+ select HAVE_HARD_RESET
+ select HAVE_OPTION_TABLE
+ select HAVE_CMOS_DEFAULT
+diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
+index 13eacd2..f9af195 100644
+--- a/src/mainboard/asus/kgpe-d16/romstage.c
++++ b/src/mainboard/asus/kgpe-d16/romstage.c
+@@ -324,6 +324,18 @@ void initialize_romstage_console_lock(void)
+ car_get_var(printk_spinlock) = SPIN_LOCK_UNLOCKED;
+ }
+
++static spinlock_t nvram_cbfs_spinlock CAR_GLOBAL;
++
++spinlock_t* romstage_nvram_cbfs_lock(void)
++{
++ return car_get_var_ptr(&nvram_cbfs_spinlock);
++}
++
++void initialize_romstage_nvram_cbfs_lock(void)
++{
++ car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED;
++}
++
+ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ {
+ uint32_t esp;
+@@ -350,8 +362,9 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ timestamp_init(timestamp_get());
+ timestamp_add_now(TS_START_ROMSTAGE);
+
+- /* Initialize the printk spinlock */
++ /* Initialize the printk and nvram CBFS spinlocks */
+ initialize_romstage_console_lock();
++ initialize_romstage_nvram_cbfs_lock();
+
+ /* Nothing special needs to be done to find bus 0 */
+ /* Allow the HT devices to be found */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch
new file mode 100644
index 0000000..8fc1513
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0006-cpu-amd-microcode-Introduce-CBFS-access-spinlock-to-.patch
@@ -0,0 +1,155 @@
+From 1c25371e5826f756af16314bccd8dcc106deae71 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Fri, 28 Aug 2015 20:48:17 -0500
+Subject: [PATCH 06/45] cpu/amd/microcode: Introduce CBFS access spinlock to
+ avoid IOMMU failure
+
+Change-Id: Ib7e8cb171f44833167053ca98a85cca23021dfba
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/Kconfig | 4 ++++
+ src/arch/x86/include/arch/smp/spinlock.h | 7 ++++++-
+ src/cpu/amd/microcode/microcode.c | 24 +++++++++++++++++++++++-
+ src/mainboard/asus/kgpe-d16/Kconfig | 1 +
+ src/mainboard/asus/kgpe-d16/romstage.c | 15 ++++++++++++++-
+ 5 files changed, 48 insertions(+), 3 deletions(-)
+
+diff --git a/src/Kconfig b/src/Kconfig
+index 5c38b7e..ca29a16 100644
+--- a/src/Kconfig
++++ b/src/Kconfig
+@@ -476,6 +476,10 @@ config HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
+ bool
+ default n
+
++config HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK
++ bool
++ default n
++
+ config HAVE_MONOTONIC_TIMER
+ def_bool n
+ help
+diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h
+index 057d9e3..39a81d2 100644
+--- a/src/arch/x86/include/arch/smp/spinlock.h
++++ b/src/arch/x86/include/arch/smp/spinlock.h
+@@ -1,7 +1,10 @@
+ #ifndef ARCH_SMP_SPINLOCK_H
+ #define ARCH_SMP_SPINLOCK_H
+
+-#if !defined(__PRE_RAM__) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
++#if !defined(__PRE_RAM__) \
++ || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK) \
++ || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK) \
++ || IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
+
+ /*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+@@ -16,6 +19,8 @@ spinlock_t *romstage_console_lock(void);
+ void initialize_romstage_console_lock(void);
+ spinlock_t* romstage_nvram_cbfs_lock(void);
+ void initialize_romstage_nvram_cbfs_lock(void);
++spinlock_t* romstage_microcode_cbfs_lock(void);
++void initialize_romstage_microcode_cbfs_lock(void);
+ #endif
+
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
+diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c
+index 37d395a..5f3280c 100644
+--- a/src/cpu/amd/microcode/microcode.c
++++ b/src/cpu/amd/microcode/microcode.c
+@@ -21,6 +21,12 @@
+ #include <cbfs.h>
+ #include <arch/io.h>
+
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
++#include <smp/spinlock.h>
++#endif
++#endif
++
+ #define UCODE_DEBUG(fmt, args...) \
+ do { printk(BIOS_DEBUG, "[microcode] "fmt, ##args); } while(0)
+
+@@ -197,14 +203,30 @@ void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id)
+ return;
+ }
+
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
++ spin_lock(romstage_microcode_cbfs_lock());
++#endif
++#endif
++
+ ucode = cbfs_boot_map_with_leak(microcode_cbfs_file[i],
+ CBFS_TYPE_MICROCODE, &ucode_len);
+ if (!ucode) {
+ UCODE_DEBUG("microcode file not found. Skipping updates.\n");
+-
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
++ spin_unlock(romstage_microcode_cbfs_lock());
++#endif
++#endif
+ return;
+ }
+
+ amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id);
++
++#ifdef __PRE_RAM__
++#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK)
++ spin_unlock(romstage_microcode_cbfs_lock());
++#endif
++#endif
+ }
+ }
+diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig
+index 49dd37b..f394ca9 100644
+--- a/src/mainboard/asus/kgpe-d16/Kconfig
++++ b/src/mainboard/asus/kgpe-d16/Kconfig
+@@ -16,6 +16,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ select PARALLEL_CPU_INIT
+ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK
+ select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
++ select HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK
+ select HAVE_HARD_RESET
+ select HAVE_OPTION_TABLE
+ select HAVE_CMOS_DEFAULT
+diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
+index f9af195..09de4b5 100644
+--- a/src/mainboard/asus/kgpe-d16/romstage.c
++++ b/src/mainboard/asus/kgpe-d16/romstage.c
+@@ -336,6 +336,18 @@ void initialize_romstage_nvram_cbfs_lock(void)
+ car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED;
+ }
+
++static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL;
++
++spinlock_t* romstage_microcode_cbfs_lock(void)
++{
++ return car_get_var_ptr(&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 0000000..739ea61
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0007-cpu-amd-car-Initialize-entire-CAR-space-instead-of-o.patch
@@ -0,0 +1,34 @@
+From b1f7214a611061ebe1b4441999880a9b93f7e9bc Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Thu, 4 Jun 2015 00:07:05 -0500
+Subject: [PATCH 07/45] cpu/amd/car: Initialize entire CAR space instead of
+ only half
+
+Change-Id: If2b6c875e523f595e662d5d62322c3c3f96ccb4a
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/car/cache_as_ram.inc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cpu/amd/car/cache_as_ram.inc b/src/cpu/amd/car/cache_as_ram.inc
+index 5305603..d532bb4 100644
+--- a/src/cpu/amd/car/cache_as_ram.inc
++++ b/src/cpu/amd/car/cache_as_ram.inc
+@@ -474,12 +474,12 @@ fam10_end_part1:
+ /* Read the range with lodsl. */
+ cld
+ movl $CacheBase, %esi
+- movl $(CacheSize >> 2), %ecx
++ movl $CacheSize, %ecx
+ rep lodsl
+
+ /* Clear the range. */
+ movl $CacheBase, %edi
+- movl $(CacheSize >> 2), %ecx
++ movl $CacheSize, %ecx
+ xorl %eax, %eax
+ rep stosl
+
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch
new file mode 100644
index 0000000..a5c547d
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0008-northbridge-amd-amdfam10-Update-DRAM-speed-limits-fo.patch
@@ -0,0 +1,423 @@
+From 4d620e5796f863926d6926d85326091847970974 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:47 -0600
+Subject: [PATCH 08/45] northbridge/amd/amdfam10: Update DRAM speed limits for
+ C32 sockets
+
+The existing code applied G34-specific speed limits to all socket
+types. Update G34 and C32 specific speed limits to be in line with
+BKDG recommendations.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdfam10/raminit_amdmct.c | 346 +++++++++++++++++++-------
+ 1 file changed, 259 insertions(+), 87 deletions(-)
+
+diff --git a/src/northbridge/amd/amdfam10/raminit_amdmct.c b/src/northbridge/amd/amdfam10/raminit_amdmct.c
+index a40c5a1..1407631 100644
+--- a/src/northbridge/amd/amdfam10/raminit_amdmct.c
++++ b/src/northbridge/amd/amdfam10/raminit_amdmct.c
+@@ -180,141 +180,313 @@ static uint16_t mct_MaxLoadFreq(uint8_t count, uint8_t highest_rank_count, uint8
+ }
+
+ if (is_fam15h()) {
+- if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
+- /* Fam15h BKDG Rev. 3.14 Table 27 */
+- if (voltage & 0x4) {
+- /* 1.25V */
+- if (count > 1) {
+- if (highest_rank_count > 1) {
+- /* Limit to DDR3-1066 */
+- if (freq > 533) {
+- freq = 533;
+- printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ if (CONFIG_CPU_SOCKET_TYPE == 0x15) {
++ /* Socket G34 */
++ if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
++ /* Fam15h BKDG Rev. 3.14 Table 27 */
++ if (voltage & 0x4) {
++ /* 1.25V */
++ if (count > 1) {
++ if (highest_rank_count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
+ }
+ } else {
+ /* Limit to DDR3-1333 */
+ if (freq > 666) {
+ freq = 666;
++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else if (voltage & 0x2) {
++ /* 1.35V */
++ if (count > 1) {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
+ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+ }
++ } else {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
+ }
+- } else {
+- /* Limit to DDR3-1333 */
+- if (freq > 666) {
+- freq = 666;
+- printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ } else if (voltage & 0x1) {
++ /* 1.50V */
++ if (count > 1) {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1866 */
++ if (freq > 933) {
++ freq = 933;
++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage));
++ }
+ }
+ }
+- } else if (voltage & 0x2) {
+- /* 1.35V */
+- if (count > 1) {
+- /* Limit to DDR3-1333 */
+- if (freq > 666) {
+- freq = 666;
+- printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+- }
+- } else {
+- /* Limit to DDR3-1600 */
+- if (freq > 800) {
+- freq = 800;
+- printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ } else {
++ /* Fam15h BKDG Rev. 3.14 Table 26 */
++ if (voltage & 0x4) {
++ /* 1.25V */
++ if (count > 1) {
++ if (highest_rank_count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
+ }
+- }
+- } else if (voltage & 0x1) {
+- /* 1.50V */
+- if (count > 1) {
+- /* Limit to DDR3-1600 */
+- if (freq > 800) {
+- freq = 800;
+- printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ } else if (voltage & 0x2) {
++ /* 1.35V */
++ if (MaxDimmsInstallable > 1) {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
+ }
+- } else {
+- /* Limit to DDR3-1866 */
+- if (freq > 933) {
+- freq = 933;
+- printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage));
++ } else if (voltage & 0x1) {
++ if (MaxDimmsInstallable == 1) {
++ if (count > 1) {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1866 */
++ if (freq > 933) {
++ freq = 933;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else {
++ if (count > 1) {
++ if (highest_rank_count > 1) {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
+ }
+ }
+ }
+- } else {
+- /* Fam15h BKDG Rev. 3.14 Table 26 */
+- if (voltage & 0x4) {
+- /* 1.25V */
+- if (count > 1) {
+- if (highest_rank_count > 1) {
+- /* Limit to DDR3-1066 */
+- if (freq > 533) {
+- freq = 533;
+- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ } else if (CONFIG_CPU_SOCKET_TYPE == 0x14) {
++ /* Socket C32 */
++ if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
++ /* Fam15h BKDG Rev. 3.14 Table 30 */
++ if (voltage & 0x4) {
++ /* 1.25V */
++ if (count > 1) {
++ if (highest_rank_count > 2) {
++ /* Limit to DDR3-800 */
++ if (freq > 400) {
++ freq = 400;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
+ }
+ } else {
+ /* Limit to DDR3-1333 */
+ if (freq > 666) {
+ freq = 666;
+- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+ }
+ }
+- } else {
+- /* Limit to DDR3-1333 */
+- if (freq > 666) {
+- freq = 666;
+- printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+- }
+- }
+- } else if (voltage & 0x2) {
+- /* 1.35V */
+- if (MaxDimmsInstallable > 1) {
+- /* Limit to DDR3-1333 */
+- if (freq > 666) {
+- freq = 666;
+- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+- }
+- } else {
+- /* Limit to DDR3-1600 */
+- if (freq > 800) {
+- freq = 800;
+- printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
+- }
+- }
+- } else if (voltage & 0x1) {
+- if (MaxDimmsInstallable == 1) {
++ } else if (voltage & 0x2) {
++ /* 1.35V */
+ if (count > 1) {
++ if (highest_rank_count > 2) {
++ /* Limit to DDR3-800 */
++ if (freq > 400) {
++ freq = 400;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else if (highest_rank_count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else {
+ /* Limit to DDR3-1600 */
+ if (freq > 800) {
+ freq = 800;
+- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
+- }
+- } else {
+- /* Limit to DDR3-1866 */
+- if (freq > 933) {
+- freq = 933;
+- printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1866\n", __func__, voltage_index_to_mv(voltage));
++ printk(BIOS_DEBUG, "%s: 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
+ }
+ }
+- } else {
++ } else if (voltage & 0x1) {
++ /* 1.50V */
+ if (count > 1) {
+- if (highest_rank_count > 1) {
++ if (highest_rank_count > 2) {
++ /* Limit to DDR3-800 */
++ if (freq > 400) {
++ freq = 400;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-800\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else if (highest_rank_count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
+ /* Limit to DDR3-1333 */
+ if (freq > 666) {
+ freq = 666;
+- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else {
++ if (highest_rank_count > 2) {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+ }
+ } else {
+ /* Limit to DDR3-1600 */
+ if (freq > 800) {
+ freq = 800;
+- printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ printk(BIOS_DEBUG, "%s: More than 1 registered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ }
++ }
++ } else {
++ /* Fam15h BKDG Rev. 3.14 Table 29 */
++ if (voltage & 0x4) {
++ /* 1.25V */
++ if (count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else if (voltage & 0x2) {
++ if (count > 1) {
++ if (highest_rank_count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
+ }
+ }
+ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else if (voltage & 0x1) {
++ if (MaxDimmsInstallable == 1) {
+ /* Limit to DDR3-1600 */
+ if (freq > 800) {
+ freq = 800;
+ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
+ }
++ } else {
++ if (count > 1) {
++ if (highest_rank_count > 1) {
++ /* Limit to DDR3-1066 */
++ if (freq > 533) {
++ freq = 533;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1066\n", __func__, voltage_index_to_mv(voltage));
++ }
++ } else {
++ /* Limit to DDR3-1333 */
++ if (freq > 666) {
++ freq = 666;
++ printk(BIOS_DEBUG, "%s: More than 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1333\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
++ } else {
++ /* Limit to DDR3-1600 */
++ if (freq > 800) {
++ freq = 800;
++ printk(BIOS_DEBUG, "%s: 1 unbuffered DIMM on %dmV channel; limiting to DDR3-1600\n", __func__, voltage_index_to_mv(voltage));
++ }
++ }
+ }
+ }
+ }
++ } else {
++ /* TODO
++ * Other socket support unimplemented
++ */
+ }
+ } else {
+ if (IS_ENABLED(CONFIG_DIMM_REGISTERED) && registered) {
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch
new file mode 100644
index 0000000..5d50aae
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0009-northbridge-amd-amdmct-Add-termination-and-timing-va.patch
@@ -0,0 +1,980 @@
+From 864c5d310f3a833e1317053c1d9886ac6e95a56e Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:47 -0600
+Subject: [PATCH 09/45] northbridge/amd/amdmct: Add termination and timing
+ values for C32 sockets
+
+The existing MCT initialization code was largely missing C32 socket-
+specific configuration data. Add C32 socket-specific timing and ODT
+values as specified in the BKDG.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 543 ++++++++++++++++++++++++++-
+ src/northbridge/amd/amdmct/mct_ddr3/mctrci.c | 58 +++
+ src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 254 +++++++++++++
+ 3 files changed, 851 insertions(+), 4 deletions(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+index cb83fe1..ac5220e 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+@@ -1092,6 +1092,152 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++
++ if (rank_count_dimm0 == 4) {
++ calibration_code &= ~(0xff << 16);
++ calibration_code |= 0x22 << 16;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++
++ if ((rank_count_dimm0 == 4) || (rank_count_dimm1 == 4)) {
++ calibration_code &= ~(0xff << 16);
++ calibration_code |= 0x22 << 16;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x10222222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x20222222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ calibration_code = 0x30222222;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++ /* TODO
++ * LRDIMM support unimplemented
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */
++ if (MaxDimmsInstallable == 1) {
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00112222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x10112222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x20112222;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ calibration_code = 0x30112222;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x10222222;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x20222222;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x30222222;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ calibration_code = 0x30222222;
++ else
++ calibration_code = 0x30112222;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -1116,11 +1262,165 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
+ uint8_t rank_count_dimm0;
+ uint8_t rank_count_dimm1;
+
+- if (package_type == PT_GR) {
+- /* Socket G34 */
++ if (package_type == PT_GR) {
++ /* Socket G34 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */
++ if (MaxDimmsInstallable == 1) {
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ calibration_code = 0x00000000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x003c3c3c;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x003a3a3a;
++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
++ /* DDR3-1600 - DDR3-1866 */
++ calibration_code = 0x00393939;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ calibration_code = 0x00000000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x00393c39;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00373a37;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ calibration_code = 0x00363936;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ calibration_code = 0x00000000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x003a3c3a;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00383a38;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ calibration_code = 0x00353935;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++ /* TODO
++ * LRDIMM support unimplemented
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x00383837;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00363635;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00353533;
++ else
++ calibration_code = 0x00003533;
++ } else if (MemClkFreq == 0x16) {
++ /* DDR3-1866 */
++ calibration_code = 0x00333330;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00000000;
++ else
++ calibration_code = 0x003b0000;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x00383837;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00363635;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if (rank_count_dimm0 == 1)
++ calibration_code = 0x00353533;
++ else
++ calibration_code = 0x00003533;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (MemClkFreq == 0x4) {
++ /* DDR3-667 */
++ calibration_code = 0x00390039;
++ } else if (MemClkFreq == 0x6) {
++ /* DDR3-800 */
++ calibration_code = 0x00390039;
++ } else if (MemClkFreq == 0xa) {
++ /* DDR3-1066 */
++ calibration_code = 0x003a3a3a;
++ } else if (MemClkFreq == 0xe) {
++ /* DDR3-1333 */
++ calibration_code = 0x00003939;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ calibration_code = 0x00003738;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
+ if (pDCTstat->Status & (1 << SB_Registered)) {
+ /* RDIMM */
+- /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */
+ if (MaxDimmsInstallable == 1) {
+ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
+ /* DDR3-667 - DDR3-800 */
+@@ -1179,7 +1479,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC
+ */
+ } else {
+ /* UDIMM */
+- /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */
+ if (MaxDimmsInstallable == 1) {
+ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
+
+@@ -1357,6 +1657,69 @@ static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dc
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */
++ slow_access = 0;
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 78 */
++ slow_access = 0;
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
++ || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) {
++ /* DDR3-667 - DDR3-1333 */
++ slow_access = 0;
++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
++ /* DDR3-1600 - DDR3-1866 */
++ if (rank_count_dimm0 == 1)
++ slow_access = 0;
++ else
++ slow_access = 1;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
++ || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) {
++ /* DDR3-667 - DDR3-1333 */
++ slow_access = 0;
++ } else if (MemClkFreq == 0x12) {
++ /* DDR3-1600 */
++ if (rank_count_dimm0 == 1)
++ slow_access = 0;
++ else
++ slow_access = 1;
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)
++ || (MemClkFreq == 0xa)) {
++ /* DDR3-667 - DDR3-1066 */
++ slow_access = 0;
++ } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) {
++ /* DDR3-1333 - DDR3-1600 */
++ slow_access = 1;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -1466,6 +1829,92 @@ static uint8_t fam15h_odt_tristate_enable_code(struct DCTStatStruc *pDCTstat, ui
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ odt_tristate_code = 0xe;
++ else
++ odt_tristate_code = 0xa;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm1 == 1)
++ odt_tristate_code = 0xd;
++ else
++ odt_tristate_code = 0x5;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0xc;
++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 >= 2))
++ odt_tristate_code = 0x4;
++ else if ((rank_count_dimm0 >= 2) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0x8;
++ else
++ odt_tristate_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++
++ /* TODO
++ * Implement LRDIMM support
++ * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ odt_tristate_code = 0xe;
++ else
++ odt_tristate_code = 0xa;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ odt_tristate_code = 0xd;
++ else
++ odt_tristate_code = 0x5;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0xc;
++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2))
++ odt_tristate_code = 0x4;
++ else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1))
++ odt_tristate_code = 0x8;
++ else
++ odt_tristate_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -1575,6 +2024,92 @@ static uint8_t fam15h_cs_tristate_enable_code(struct DCTStatStruc *pDCTstat, uin
+ */
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (pDCTstat->Status & (1 << SB_Registered)) {
++ /* RDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 < 4)
++ cs_tristate_code = 0xfc;
++ else
++ cs_tristate_code = 0xcc;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm1 < 4)
++ cs_tristate_code = 0xf3;
++ else
++ cs_tristate_code = 0x33;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ cs_tristate_code = 0xf0;
++ else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4))
++ cs_tristate_code = 0x30;
++ else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4))
++ cs_tristate_code = 0xc0;
++ else
++ cs_tristate_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
++ /* LRDIMM */
++
++ /* TODO
++ * Implement LRDIMM support
++ * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108
++ */
++ } else {
++ /* UDIMM */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ cs_tristate_code = 0xfe;
++ else
++ cs_tristate_code = 0xfc;
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if (rank_count_dimm0 == 1)
++ cs_tristate_code = 0xfb;
++ else
++ cs_tristate_code = 0xf3;
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1))
++ cs_tristate_code = 0xfa;
++ else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2))
++ cs_tristate_code = 0xf2;
++ else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1))
++ cs_tristate_code = 0xf8;
++ else
++ cs_tristate_code = 0xf0;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
+index 4455391..f5d488a 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
+@@ -77,6 +77,51 @@ static uint8_t fam15h_rdimm_rc2_ibt_code(struct DCTStatStruc *pDCTstat, uint8_t
+ * 3 DIMM/channel support unimplemented
+ */
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32 */
++ /* Fam15h BKDG Rev. 3.14 section 2.10.5.7.1.2.1 Table 86 */
++ if (MaxDimmsInstallable == 1) {
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ control_code = 0x1;
++ } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) {
++ /* DDR3-1066 - DDR3-1333 */
++ if (num_registers == 1) {
++ control_code = 0x0;
++ } else {
++ control_code = 0x1;
++ }
++ } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
++ /* DDR3-1600 - DDR3-1866 */
++ control_code = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ if (dimm_count == 1) {
++ /* 1 DIMM detected */
++ if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ control_code = 0x1;
++ } else if ((MemClkFreq >= 0xa) && (MemClkFreq <= 0x12)) {
++ /* DDR3-1066 - DDR3-1600 */
++ if (num_registers == 1) {
++ control_code = 0x0;
++ } else {
++ control_code = 0x1;
++ }
++ }
++ } else if (dimm_count == 2) {
++ /* 2 DIMMs detected */
++ if (num_registers == 1) {
++ control_code = 0x1;
++ } else {
++ control_code = 0x8;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
+ } else {
+ /* TODO
+ * Other socket support unimplemented
+@@ -166,6 +211,13 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
+ val = 0x4;
+ }
+ }
++ else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (MaxDimmsInstallable == 2) {
++ if (Dimms > 1)
++ val = 0x4;
++ }
++ }
+ }
+ } else if (CtrlWordNum == 3) {
+ val = (pDCTstat->CtrlWrd3 >> (DimmNum << 2)) & 0xff;
+@@ -183,6 +235,12 @@ static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
+ val = 0x0;
+ }
+ }
++ else if (package_type == PT_C3) {
++ /* Socket C32 */
++ if (MaxDimmsInstallable == 2) {
++ val = 0x0;
++ }
++ }
+ }
+ } else if (CtrlWordNum == 9) {
+ val = 0xd; /* DBA1, DBA0, DA3 = 0 */
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+index 143290f..822d813 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+@@ -117,6 +117,67 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d
+ term = 0x2;
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 60 */
++ if (MaxDimmsInstallable == 1) {
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)
++ || (frequency_index == 0xa) || (frequency_index == 0xe)) {
++ /* DDR3-667 - DDR3-1333 */
++ if (rank_count < 3)
++ term = 0x0;
++ else
++ term = 0x2;
++ } else {
++ /* DDR3-1600 */
++ term = 0x0;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ if ((number_of_dimms == 1) && ((rank_count_dimm0 < 4)
++ && (rank_count_dimm1 < 4)))
++ term = 0x0;
++ else
++ term = 0x2;
++ } else if (frequency_index == 0xa) {
++ /* DDR3-1066 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x0;
++ else
++ term = 0x2;
++ } else {
++ term = 0x1;
++ }
++ } else if (frequency_index == 0xe) {
++ /* DDR3-1333 */
++ term = 0x2;
++ } else {
++ /* DDR3-1600 */
++ if (number_of_dimms == 1)
++ term = 0x0;
++ else
++ term = 0x1;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ rank_count_dimm2 = pDCTstat->DimmRanks[(2 * 2) + dct];
++
++ if ((frequency_index == 0xa) || (frequency_index == 0xe)) {
++ /* DDR3-1066 - DDR3-1333 */
++ if (rank_count_dimm2 < 4)
++ term = 0x1;
++ else
++ term = 0x2;
++ } else if (frequency_index == 0x12) {
++ /* DDR3-1600 */
++ term = 0x1;
++ } else {
++ term = 0x2;
++ }
++ }
+ } else {
+ /* TODO
+ * Other sockets unimplemented
+@@ -151,6 +212,33 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d
+ term = 0x2;
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 59 */
++ if (MaxDimmsInstallable == 1) {
++ term = 0x0;
++ } else if (MaxDimmsInstallable == 2) {
++ if ((number_of_dimms == 2) && (frequency_index == 0x12)) {
++ term = 0x1;
++ } else if (number_of_dimms == 1) {
++ term = 0x0;
++ } else {
++ term = 0x2;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ if (number_of_dimms == 1) {
++ if (frequency_index <= 0xa) {
++ term = 0x2;
++ } else {
++ if (rank_count < 3) {
++ term = 0x1;
++ } else {
++ term = 0x2;
++ }
++ }
++ } else if (number_of_dimms == 2) {
++ term = 0x2;
++ }
++ }
+ } else {
+ /* TODO
+ * Other sockets unimplemented
+@@ -302,6 +390,125 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t
+ * 3 DIMM/channel support unimplemented
+ */
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 60 */
++ if (MaxDimmsInstallable == 1) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ if (rank_count_dimm0 < 4) {
++ term = 0x2;
++ } else {
++ if (!rank)
++ term = 0x2;
++ else
++ term = 0x0;
++ }
++ } else if (frequency_index == 0xa) {
++ /* DDR3-1066 */
++ term = 0x1;
++ } else if (frequency_index == 0xe) {
++ /* DDR3-1333 */
++ if (rank_count_dimm0 < 4) {
++ term = 0x1;
++ } else {
++ if (!rank)
++ term = 0x3;
++ else
++ term = 0x0;
++ }
++ } else {
++ term = 0x3;
++ }
++ } else if (MaxDimmsInstallable == 2) {
++ rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
++ rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
++
++ if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
++ /* DDR3-667 - DDR3-800 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x2;
++ else if (rank)
++ term = 0x0;
++ else
++ term = 0x2;
++ } else {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
++ term = 0x3;
++ } else {
++ if (rank_count_dimm0 == 4) {
++ if (rank_count_dimm1 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ } else if (rank_count_dimm1 == 4) {
++ if (rank_count_dimm0 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ }
++ if (rank)
++ term = 0x0;
++ }
++ }
++ } else if (frequency_index == 0xa) {
++ /* DDR3-1066 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x1;
++ else if (rank)
++ term = 0x0;
++ else
++ term = 0x1;
++ } else {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
++ term = 0x3;
++ } else {
++ if (rank_count_dimm0 == 4) {
++ if (rank_count_dimm1 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ } else if (rank_count_dimm1 == 4) {
++ if (rank_count_dimm0 == 1)
++ term = 0x5;
++ else
++ term = 0x1;
++ }
++ if (rank)
++ term = 0x0;
++ }
++ }
++ } else if (frequency_index == 0xe) {
++ /* DDR3-1333 */
++ if (number_of_dimms == 1) {
++ if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
++ term = 0x1;
++ else if (rank)
++ term = 0x0;
++ else
++ term = 0x3;
++ } else {
++ term = 0x5;
++ }
++ } else {
++ /* DDR3-1600 */
++ if (number_of_dimms == 1)
++ term = 0x3;
++ else
++ term = 0x4;
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ /* TODO
++ * 3 DIMM/channel support unimplemented
++ */
++ }
++ } else {
++ /* TODO
++ * Other sockets unimplemented
++ */
+ }
+ } else {
+ /* UDIMM */
+@@ -352,6 +559,53 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t
+ }
+ }
+ }
++ } else if (package_type == PT_C3) {
++ /* Socket C32: Fam15h BKDG v3.14 Table 62 */
++ if (MaxDimmsInstallable == 1) {
++ if ((frequency_index == 0x4) || (frequency_index == 0x6))
++ term = 0x2;
++ else if ((frequency_index == 0xa) || (frequency_index == 0xe))
++ term = 0x1;
++ else
++ term = 0x3;
++ }
++ if (MaxDimmsInstallable == 2) {
++ if (number_of_dimms == 1) {
++ if (frequency_index <= 0x6) {
++ term = 0x2;
++ } else if (frequency_index <= 0xe) {
++ term = 0x1;
++ } else {
++ term = 0x3;
++ }
++ } else {
++ if (frequency_index <= 0xa) {
++ term = 0x3;
++ } else if (frequency_index <= 0xe) {
++ term = 0x5;
++ } else {
++ term = 0x4;
++ }
++ }
++ } else if (MaxDimmsInstallable == 3) {
++ if (number_of_dimms == 1) {
++ term = 0x0;
++ } else if (number_of_dimms == 2) {
++ if (frequency_index <= 0xa) {
++ if (rank == 1) {
++ term = 0x0;
++ } else {
++ term = 0x3;
++ }
++ } else if (frequency_index <= 0xe) {
++ if (rank == 1) {
++ term = 0x0;
++ } else {
++ term = 0x5;
++ }
++ }
++ }
++ }
+ } else {
+ /* TODO
+ * Other sockets unimplemented
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch
new file mode 100644
index 0000000..35d0d6c
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0010-cpu-amd-family_10h-family_15h-Set-LDT-tristate-corre.patch
@@ -0,0 +1,99 @@
+From c4669801294d56534e4ac4de3ab71de39afe90d8 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:47 -0600
+Subject: [PATCH 10/45] cpu/amd/family_10h-family_15h: Set LDT tristate
+ correctly on C32 sockets
+
+The existing code unconditionally cleared the LDT tristate enable bit,
+which was incorrect for C32 sockets. Update the code to be in line
+with the BKDG recommendations.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/defaults.h | 19 -------------
+ src/cpu/amd/family_10h-family_15h/init_cpus.c | 39 +++++++++++++++++++++++++++
+ 2 files changed, 39 insertions(+), 19 deletions(-)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/defaults.h b/src/cpu/amd/family_10h-family_15h/defaults.h
+index 57c0518..3618cb8 100644
+--- a/src/cpu/amd/family_10h-family_15h/defaults.h
++++ b/src/cpu/amd/family_10h-family_15h/defaults.h
+@@ -260,25 +260,6 @@ static const struct {
+ { 0, 0xE4, AMD_FAM10_ALL, AMD_PTYPE_ALL,
+ 0x00002000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
+
+- /* FIXME
+- * Non-C32 packages only
+- */
+- { 0, 0x84, AMD_FAM15_ALL, AMD_PTYPE_ALL,
+- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
+-
+- { 0, 0xA4, AMD_FAM15_ALL, AMD_PTYPE_ALL,
+- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
+-
+- { 0, 0xC4, AMD_FAM15_ALL, AMD_PTYPE_ALL,
+- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
+-
+- { 0, 0xE4, AMD_FAM15_ALL, AMD_PTYPE_ALL,
+- 0x00000000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
+-
+- /* FIXME
+- * C32 package is not supported at this time
+- */
+-
+ /* Link Global Retry Control Register */
+ { 0, 0x150, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
+ 0x00073900, 0x00073f70 }, /* TotalRetryAttempts = 0x7,
+diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+index bf1862b..1794072 100644
+--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c
++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+@@ -1095,6 +1095,45 @@ static void cpuSetAMDPCI(u8 node)
+ }
+ }
+
++ if (is_fam15h()) {
++ if (CONFIG_CPU_SOCKET_TYPE == 0x14) {
++ /* Socket C32 */
++ dword = pci_read_config32(NODE_PCI(node, 0), 0x84);
++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */
++ pci_write_config32(NODE_PCI(node, 0), 0x84, dword);
++
++ dword = pci_read_config32(NODE_PCI(node, 0), 0xa4);
++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */
++ pci_write_config32(NODE_PCI(node, 0), 0xa4, dword);
++
++ dword = pci_read_config32(NODE_PCI(node, 0), 0xc4);
++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */
++ pci_write_config32(NODE_PCI(node, 0), 0xc4, dword);
++
++ dword = pci_read_config32(NODE_PCI(node, 0), 0xe4);
++ dword |= 0x1 << 13; /* LdtStopTriEn = 1 */
++ pci_write_config32(NODE_PCI(node, 0), 0xe4, dword);
++ }
++ else {
++ /* Other socket (G34, etc.) */
++ dword = pci_read_config32(NODE_PCI(node, 0), 0x84);
++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */
++ pci_write_config32(NODE_PCI(node, 0), 0x84, dword);
++
++ dword = pci_read_config32(NODE_PCI(node, 0), 0xa4);
++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */
++ pci_write_config32(NODE_PCI(node, 0), 0xa4, dword);
++
++ dword = pci_read_config32(NODE_PCI(node, 0), 0xc4);
++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */
++ pci_write_config32(NODE_PCI(node, 0), 0xc4, dword);
++
++ dword = pci_read_config32(NODE_PCI(node, 0), 0xe4);
++ dword &= ~(0x1 << 13); /* LdtStopTriEn = 0 */
++ pci_write_config32(NODE_PCI(node, 0), 0xe4, dword);
++ }
++ }
++
+ #ifdef DEBUG_HT_SETUP
+ /* Dump link settings */
+ for (i = 0; i < 4; i++) {
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch
new file mode 100644
index 0000000..1c25598
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0011-cpu-amd-family_10h-family_15h-Move-CBMEM-storage-out.patch
@@ -0,0 +1,107 @@
+From 908455aa41424aefbb328fd8c826be2e2b344ce6 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:48 -0600
+Subject: [PATCH 11/45] cpu/amd/family_10h-family_15h: Move CBMEM storage out
+ of CC6 save region
+
+The existing CBMEM TOM calculations did not account for the CC6 save region
+(when enabled); this resulted in CBMEM storage being placed on top of the
+CC6 save region, which resulted in corrupt CBMEM data and a boot hang.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/ram_calc.c | 51 +++++++++++++++++++++++++++-
+ src/cpu/amd/family_10h-family_15h/ram_calc.h | 1 +
+ 2 files changed, 51 insertions(+), 1 deletion(-)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.c b/src/cpu/amd/family_10h-family_15h/ram_calc.c
+index 9ac2c99..4fe997e 100644
+--- a/src/cpu/amd/family_10h-family_15h/ram_calc.c
++++ b/src/cpu/amd/family_10h-family_15h/ram_calc.c
+@@ -18,11 +18,30 @@
+ #include <cpu/x86/msr.h>
+ #include <cpu/amd/mtrr.h>
+
++#include <arch/io.h>
++#include <device/device.h>
++#include <device/pci.h>
++
+ #include <cbmem.h>
+
+ #include "ram_calc.h"
+
+ #if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
++static inline uint8_t is_fam15h(void)
++{
++ uint8_t fam15h = 0;
++ uint32_t family;
++
++ family = cpuid_eax(0x80000001);
++ family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
++
++ if (family >= 0x6f)
++ /* Family 15h or later */
++ fam15h = 1;
++
++ return fam15h;
++}
++
+ uint64_t get_uma_memory_size(uint64_t topmem)
+ {
+ uint64_t uma_size = 0;
+@@ -41,10 +60,40 @@ uint64_t get_uma_memory_size(uint64_t topmem)
+ return uma_size;
+ }
+
++uint64_t get_cc6_memory_size()
++{
++ uint8_t enable_cc6;
++
++ uint64_t cc6_size = 0;
++
++ if (is_fam15h()) {
++ enable_cc6 = 0;
++
++#ifdef __PRE_RAM__
++ if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18))
++ enable_cc6 = 1;
++#else
++ device_t dct_dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
++ if (pci_read_config32(dct_dev, 0x118) & (0x1 << 18))
++ enable_cc6 = 1;
++#endif
++
++ if (enable_cc6) {
++ /* Preserve the maximum possible CC6 save region
++ * This needs to be kept in sync with
++ * amdfam10_domain_read_resources() in northbridge.c
++ */
++ cc6_size = 0x8000000;
++ }
++ }
++
++ return cc6_size;
++}
++
+ void *cbmem_top(void)
+ {
+ uint32_t topmem = rdmsr(TOP_MEM).lo;
+
+- return (void *) topmem - get_uma_memory_size(topmem);
++ return (void *) topmem - get_uma_memory_size(topmem) - get_cc6_memory_size();
+ }
+ #endif
+diff --git a/src/cpu/amd/family_10h-family_15h/ram_calc.h b/src/cpu/amd/family_10h-family_15h/ram_calc.h
+index 8cfc199..0bb4cac 100644
+--- a/src/cpu/amd/family_10h-family_15h/ram_calc.h
++++ b/src/cpu/amd/family_10h-family_15h/ram_calc.h
+@@ -17,5 +17,6 @@
+ #define _AMD_MODEL_10XXX_RAM_CALC_H_
+
+ uint64_t get_uma_memory_size(uint64_t topmem);
++uint64_t get_cc6_memory_size(void);
+
+ #endif
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch
new file mode 100644
index 0000000..36efd72
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0012-northbridge-amd-amdmct-mct_ddr3-Enable-fast-refresh-.patch
@@ -0,0 +1,89 @@
+From 2eb03f516b6555636282713527bf9f2e672bf97b Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:50 -0600
+Subject: [PATCH 12/45] northbridge/amd/amdmct/mct_ddr3: Enable fast refresh on
+ ETR devices
+
+When an Extended Temperature Range DIMM is installed on a channel
+the refresh rate should be increased per the BKDG recommendations
+to allow correct operation at higher temperature ranges.
+
+Set fast refresh on a channel if an ETR DIMM is installed on that
+channel.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 12 +++++++++++-
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 5 +++--
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+index ac5220e..beb71f9 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+@@ -3993,6 +3993,7 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
+ u32 DramTimingLo, DramTimingHi;
+ u8 tCK16x;
+ u16 Twtr;
++ uint8_t Etr[2];
+ u8 LDIMM;
+ u8 MTB16x;
+ u8 byte;
+@@ -4011,6 +4012,8 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
+ Trc = 0;
+ Twr = 0;
+ Twtr = 0;
++ for (i=0; i < 2; i++)
++ Etr[i] = 0;
+ for (i=0; i < 4; i++)
+ Trfc[i] = 0;
+ Tfaw = 0;
+@@ -4077,6 +4080,10 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
+ val *= MTB16x;
+ if (Tfaw < val)
+ Tfaw = val;
++
++ /* Determine if the DIMMs on this channel support 95°C ETR */
++ if (pDCTstat->spd_data.spd_bytes[dct + i][SPD_Thermal] & 0x1)
++ Etr[dct] = 1;
+ } /* Dimm Present */
+ }
+
+@@ -4248,7 +4255,10 @@ static void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
+ dev = pDCTstat->dev_dct;
+
+ dword = Get_NB32_DCT(dev, dct, 0x8c); /* DRAM Timing High */
+- val = 2; /* Tref = 7.8us */
++ if (Etr[dct])
++ val = 3; /* Tref = 3.9us */
++ else
++ val = 2; /* Tref = 7.8us */
+ dword &= ~(0x3 << 16);
+ dword |= (val & 0x3) << 16;
+ Set_NB32_DCT(dev, dct, 0x8c, dword); /* DRAM Timing High */
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+index 5f72ff3..e7361ac 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+@@ -217,8 +217,8 @@
+ #define SPD_CASHigh 15
+ #define SPD_tAAmin 16
+
+-#define SPD_DEVATTRIB 22
+-#define SPD_EDCTYPE 11
++#define SPD_DEVATTRIB 22
++#define SPD_EDCTYPE 11
+ #define JED_ADRCPAR 0x04
+
+ #define SPD_tWRmin 17
+@@ -232,6 +232,7 @@
+ #define SPD_tRTPmin 27
+ #define SPD_Upper_tFAW 28
+ #define SPD_tFAWmin 29
++#define SPD_Thermal 31
+
+ #define SPD_RefRawCard 62
+ #define SPD_AddressMirror 63
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch
new file mode 100644
index 0000000..d9b70ca
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0013-nb-amd-mct_ddr3-Update-drive-strength-configuration.patch
@@ -0,0 +1,149 @@
+From cebd4b26e543f7284ee6fa48531315bc6d40523d Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:50 -0600
+Subject: [PATCH 13/45] nb/amd/mct_ddr3: Update drive strength configuration
+
+The existing drive strength calibration code did not strictly
+follow the BKDG-defined setup process. Bring the calibration
+code in line with the BKDG recommendations.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 49 +++++++++++++++++++----------
+ 1 file changed, 32 insertions(+), 17 deletions(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+index beb71f9..9724008 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+@@ -6828,7 +6828,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
+ /* Program TxPreP/TxPreN for data lanes (Stage 1) */
+ for (index = 0; index < 0x9; index++) {
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8));
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8), dword);
+ }
+@@ -6841,13 +6841,13 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
+ /* Program TxPreP/TxPreN for data lanes (Stage 2) */
+ for (index = 0; index < 0x9; index++) {
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8));
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8), dword);
+ }
+ for (index = 0; index < 0x9; index++) {
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8));
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8), dword);
+ }
+@@ -6859,15 +6859,15 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
+
+ /* Program TxPreP/TxPreN for command/address lines (Stage 1) */
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002, dword);
+
+@@ -6878,31 +6878,31 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
+
+ /* Program TxPreP/TxPreN for command/address lines (Stage 2) */
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= tx_pre;
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102, dword);
+
+@@ -6913,7 +6913,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
+
+ /* Program TxPreP/TxPreN for command/address lines (Stage 3) */
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002, dword);
+
+@@ -6924,17 +6924,32 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
+
+ /* Program TxPreP/TxPreN for clock lines */
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102, dword);
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202);
+- dword &= ~(0xfff);
++ dword &= ~(0xffff);
+ dword |= (0x8000 | tx_pre);
+ Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202, dword);
++
++ /* Be extra safe and wait for the predriver calibration to be applied
++ * to the hardware. The BKDG does not require this, but it does take
++ * some time for the data to propagate, so it's probably a good idea.
++ */
++ uint8_t predriver_cal_pending = 1;
++ printk(BIOS_DEBUG, "Waiting for predriver calibration to be applied...");
++ while (predriver_cal_pending) {
++ predriver_cal_pending = 0;
++ for (index = 0; index < 0x9; index++) {
++ if (Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)) & 0x8000)
++ predriver_cal_pending = 1;
++ }
++ }
++ printk(BIOS_DEBUG, "done!\n");
+ } else {
+ dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00);
+ dword = 0;
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch
new file mode 100644
index 0000000..5264c8f
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0014-nb-amd-mct_ddr3-Add-additional-verbose-level-debug-s.patch
@@ -0,0 +1,63 @@
+From 99fae7d439a9eaac33ce4a4f7e9a78696dfd3547 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:52 -0600
+Subject: [PATCH 14/45] nb/amd/mct_ddr3: Add additional verbose-level debug
+ statements
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c | 10 ++++++++--
+ src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c | 2 ++
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
+index 4cc87de..22e9836 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
+@@ -1428,8 +1428,9 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat,
+
+ if (check_antiphase == 0) {
+ /* Check for early abort before analyzing per-nibble status */
+- dword = Get_NB32_DCT(dev, dct, 0x264) & 0x1ffffff;
+- if (dword != 0) {
++ dword = Get_NB32_DCT(dev, dct, 0x264);
++ if ((dword & 0x1ffffff) != 0) {
++ print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 162 early abort: F2x264 ", dword, 6);
+ dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 0; /* Fail */
+ continue;
+ }
+@@ -1439,6 +1440,7 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat,
+ * Record pass / fail status
+ */
+ dword = Get_NB32_DCT(dev, dct, 0x268) & 0x3ffff;
++ print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 163 read results: F2x268 ", dword, 6);
+ if (dword & (0x3 << (lane * 2)))
+ dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 0; /* Fail */
+ else
+@@ -1737,6 +1739,10 @@ static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat,
+ printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc_D_Fam15 Receiver %d lane %d initial phy delay %04x: iterating from %04x to %04x\n", Receiver, lane, initial_phy_phase_delay[lane], rx_en_offset, 0x3ff);
+ #endif
+ for (current_phy_phase_delay[lane] = rx_en_offset; current_phy_phase_delay[lane] < 0x3ff; current_phy_phase_delay[lane] += ren_step) {
++#if DQS_TRAIN_DEBUG > 0
++ printk(BIOS_DEBUG, "%s: Receiver %d lane %d current phy delay: %04x\n", __func__, Receiver, lane, current_phy_phase_delay[lane]);
++#endif
++
+ /* 2.10.5.8.3 (4 A) */
+ write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg);
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
+index 1c756ab..d316d27 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
+@@ -228,6 +228,8 @@ static uint16_t fam15_receiver_enable_training_seed(struct DCTStatStruc *pDCTsta
+ }
+ }
+
++ printk(BIOS_DEBUG, "%s: using seed: %04x\n", __func__, seed);
++
+ return seed;
+ }
+
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch
new file mode 100644
index 0000000..dd76550
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0015-nb-amd-mct_ddr3-Properly-set-MR0-WR-value.patch
@@ -0,0 +1,30 @@
+From 5f5614ca862cecec27a3cf1fe843a4c30cbde69b Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:52 -0600
+Subject: [PATCH 15/45] nb/amd/mct_ddr3: Properly set MR0 WR value
+
+The existing code accidentally truncated the MSB from the MR0
+WR value. While this probably had a minimal effect in reality,
+it should be configured correctly for maximal system stability.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+index 822d813..bcf6031 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+@@ -967,7 +967,7 @@ static u32 mct_MR0(struct MCTStatStruc *pMCTstat,
+
+ /* Load data into MRS word */
+ ret |= (ppd & 0x1) << 12;
+- ret |= (wr_ap & 0x3) << 9;
++ ret |= (wr_ap & 0x7) << 9;
+ ret |= (dll_reset & 0x1) << 8;
+ ret |= (test_mode & 0x1) << 7;
+ ret |= ((cas_latency & 0xe) >> 1) << 4;
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch
new file mode 100644
index 0000000..ab731ac
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0016-nb-amd-mct_ddr3-Fix-RDIMM-training-failure-on-Fam15h.patch
@@ -0,0 +1,32 @@
+From 2888ba1b3ac0056183b05a37e6f24018a00339fa Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:52 -0600
+Subject: [PATCH 16/45] nb/amd/mct_ddr3: Fix RDIMM training failure on Fam15h
+
+Certain registered DIMMs failed training due to an error
+likely introduced during historical rebase. Ensure that
+the SubMemclkRegDly bit is set according to BKDG
+recommendations on Family 15 processors.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mctproc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
+index cf13b40..fc62afb 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
+@@ -66,6 +66,9 @@ u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat,
+ misc2 |= ((cs_mux_67 & 0x1) << 27);
+ misc2 &= ~(0x1 << 26); /* CsMux45 = cs_mux_45 */
+ misc2 |= ((cs_mux_45 & 0x1) << 26);
++
++ if (pDCTstat->Status & (1 << SB_Registered))
++ misc2 |= 1 << SubMemclkRegDly;
+ } else if (pDCTstat->LogicalCPUID & (AMD_DR_Dx | AMD_DR_Cx)) {
+ if (pDCTstat->Status & (1 << SB_Registered)) {
+ misc2 |= 1 << SubMemclkRegDly;
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch
new file mode 100644
index 0000000..987f041
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0017-cpu-amd-fam10h-fam15h-Correctly-create-APIC-ID-on-si.patch
@@ -0,0 +1,59 @@
+From eb9dc9e1f48f8f6bdb7e97a2d0ec4b5db93db0e0 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:53 -0600
+Subject: [PATCH 17/45] cpu/amd/fam10h-fam15h: Correctly create APIC ID on
+ single node systems
+
+The existing code generated an incorrect boot APIC ID from node and
+core number for single node packages, leading to a boot failure when
+the second node was installed.
+
+Properly generate the boot APIC ID from node and core number.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/init_cpus.c | 6 +++++-
+ src/northbridge/amd/amdfam10/northbridge.c | 4 +++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+index 1794072..5a67601 100644
+--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c
++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+@@ -127,13 +127,17 @@ uint32_t get_boot_apic_id(uint8_t node, uint32_t core) {
+ }
+ } else {
+ if (fam15h) {
+- ap_apicid = (node * (siblings + 1)) + core;
++ ap_apicid = 0;
++ ap_apicid |= (node & 0x7) << 4; /* Node ID */
++ ap_apicid |= core & 0xf; /* Core ID */
+ } else {
+ ap_apicid = node * (nb_cfg_54 ? (siblings + 1) : 1) +
+ core * (nb_cfg_54 ? 1 : 64);
+ }
+ }
+
++ printk(BIOS_DEBUG, "%s: using %d as APIC ID for node %d, core %d\n", __func__, ap_apicid, node, core);
++
+ return ap_apicid;
+ }
+
+diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c
+index b376171..35d0925 100644
+--- a/src/northbridge/amd/amdfam10/northbridge.c
++++ b/src/northbridge/amd/amdfam10/northbridge.c
+@@ -1636,7 +1636,9 @@ static void cpu_bus_scan(device_t dev)
+ }
+ } else {
+ if (fam15h) {
+- apic_id = (i * (siblings + 1)) + j;
++ apic_id = 0;
++ apic_id |= (i & 0x7) << 4; /* Node ID */
++ apic_id |= j & 0xf; /* Core ID */
+ } else {
+ apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ?
+ }
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch
new file mode 100644
index 0000000..7b2fdc2
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0018-nb-amdmct-mct_ddr3-Enable-mainboard-voltage-set.patch
@@ -0,0 +1,73 @@
+From 7c59896199f78e3b7ededce1a9c2eb9a9bfa795d Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:53 -0600
+Subject: [PATCH 18/45] nb/amdmct/mct_ddr3: Enable mainboard voltage set
+
+The existing code used an incorrect macro name to check for mainboard
+DRAM voltage set support, and as a result no voltages were actually
+set. Furthermore, the existing code did not contain a centralized
+voltage assumption for boards that did not have a DIMM voltage set
+implementation.
+
+Use the correct macro name to test for boards with voltage set
+implementation, and provide a basic fallback to 1.5V operation
+for boards without a voltage set implementation.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+index 9724008..e1c0d4f 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+@@ -254,6 +254,10 @@ static uint8_t dct_ddr_voltage_index(struct DCTStatStruc *pDCTstat, uint8_t dct)
+ uint8_t dimm;
+ uint8_t ddr_voltage_index = 0;
+
++ /* If no DIMMs are present on this DCT, report 1.5V operation and skip checking the hardware */
++ if (pDCTstat->DIMMValidDCT[dct] == 0)
++ return 0x1;
++
+ /* Find current DDR supply voltage for this DCT */
+ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+ if (pDCTstat->DIMMValidDCT[dct] & (1 << dimm))
+@@ -2409,6 +2413,7 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
+ */
+ u8 Node, NodesWmem;
+ u32 node_sys_base;
++ uint8_t dimm;
+ uint8_t nvram;
+ uint8_t enable_cc6;
+ uint8_t allow_config_restore;
+@@ -2498,10 +2503,25 @@ restartinit:
+ nvram = 0;
+ set_option("allow_spd_nvram_cache_restore", &nvram);
+
+-#if IS_ENABLED(DIMM_VOLTAGE_SET_SUPPORT)
++#if IS_ENABLED(CONFIG_DIMM_VOLTAGE_SET_SUPPORT)
+ printk(BIOS_DEBUG, "%s: DIMMSetVoltage\n", __func__);
+ DIMMSetVoltages(pMCTstat, pDCTstatA); /* Set the DIMM voltages (mainboard specific) */
+ #endif
++ if (!IS_ENABLED(CONFIG_DIMM_VOLTAGE_SET_SUPPORT)) {
++ /* Assume 1.5V operation */
++ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
++ struct DCTStatStruc *pDCTstat;
++ pDCTstat = pDCTstatA + Node;
++
++ if (!pDCTstat->NodePresent)
++ continue;
++
++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
++ if (pDCTstat->DIMMValid & (1 << dimm))
++ pDCTstat->DimmConfiguredVoltage[dimm] = 0x1;
++ }
++ }
++ }
+
+ /* If DIMM configuration has not changed since last boot restore training values */
+ allow_config_restore = 1;
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch
new file mode 100644
index 0000000..4e94f4f
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0019-mainboard-asus-kgpe-d16-Move-memory-test-before-IMD-.patch
@@ -0,0 +1,40 @@
+From b4b1b5269981dd559ef30efea8025e76e8c0a7ba Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:54 -0600
+Subject: [PATCH 19/45] mainboard/asus/kgpe-d16: Move memory test before IMD
+ setup
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/romstage.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
+index 09de4b5..20ba6f2 100644
+--- a/src/mainboard/asus/kgpe-d16/romstage.c
++++ b/src/mainboard/asus/kgpe-d16/romstage.c
+@@ -541,6 +541,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ raminit_amdmct(sysinfo);
+ timestamp_add_now(TS_AFTER_INITRAM);
+
++#ifdef TEST_MEMORY
++ execute_memory_test();
++#endif
++
+ #if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
+ if (s3resume)
+ cbmem_initialize();
+@@ -565,10 +569,6 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+
+ timestamp_add_now(TS_END_ROMSTAGE);
+
+-#ifdef TEST_MEMORY
+- execute_memory_test();
+-#endif
+-
+ post_cache_as_ram(); // BSP switch stack to ram, copy then execute LB.
+ post_code(0x43); // Should never see this post code.
+ }
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch
new file mode 100644
index 0000000..99b8778
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0020-mainboard-asus-kgpe-d16-Enable-ASUS-MIO-audio-option.patch
@@ -0,0 +1,31 @@
+From 4484fa77860f3595a4c0fd634bcd8648c3f12764 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:55 -0600
+Subject: [PATCH 20/45] mainboard/asus/kgpe-d16: Enable ASUS MIO audio option
+
+The KGPE-D16 supports an optional MIO audio card, which connects
+to the on-board HDA interface of the SP5100.
+
+Enable the HDA interface for use with the MIO card.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/devicetree.cb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/devicetree.cb b/src/mainboard/asus/kgpe-d16/devicetree.cb
+index 014a35f..96372f9 100644
+--- a/src/mainboard/asus/kgpe-d16/devicetree.cb
++++ b/src/mainboard/asus/kgpe-d16/devicetree.cb
+@@ -175,7 +175,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ end
+ end
+ device pci 14.1 on end # IDE 0x439c
+- device pci 14.2 off end # HDA 0x4383 (KGPE-D16 omits audio option)
++ device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card)
+ device pci 14.3 on # LPC 0x439d (SMBUS primary controller)
+ chip superio/nuvoton/nct5572d # Super I/O
+ device pnp 2e.0 off end # FDC; Not available on the KGPE-D16
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch
new file mode 100644
index 0000000..9926855
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0021-mainboard-asus-kgpe-d16-Use-stock-PS-2-ACPI-ASL-file.patch
@@ -0,0 +1,74 @@
+From bd28638ec8e08636346d8fe2d276267dc0a06a1c Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:55 -0600
+Subject: [PATCH 21/45] mainboard/asus/kgpe-d16: Use stock PS/2 ACPI ASL file
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/dsdt.asl | 43 +++---------------------------------
+ 1 file changed, 3 insertions(+), 40 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/dsdt.asl b/src/mainboard/asus/kgpe-d16/dsdt.asl
+index 8445eb3..44b6a98 100644
+--- a/src/mainboard/asus/kgpe-d16/dsdt.asl
++++ b/src/mainboard/asus/kgpe-d16/dsdt.asl
+@@ -92,8 +92,8 @@ DefinitionBlock (
+ /* Keyboard controller PME# */
+ Method(_L08) {
+ /* Level-Triggered GPE */
+- Notify(\_SB.PCI0.LPC.KBD, 0x02) /* NOTIFY_DEVICE_WAKE */
+- Notify(\_SB.PCI0.LPC.MOU, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify(\_SB.PCI0.LPC.PS2K, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify(\_SB.PCI0.LPC.PS2M, 0x02) /* NOTIFY_DEVICE_WAKE */
+ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */
+ }
+
+@@ -490,44 +490,7 @@ DefinitionBlock (
+ Name (_HID, EisaId ("PNP0A05"))
+ Name (_ADR, 0x00140003)
+
+- /* PS/2 keyboard (seems to be important for WinXP install) */
+- Device (KBD)
+- {
+- Name (_HID, EisaId ("PNP0303"))
+- Name (_CID, EisaId ("PNP030B"))
+- Method (_STA, 0, NotSerialized)
+- {
+- Return (0x0f)
+- }
+- Method (_CRS, 0, Serialized)
+- {
+- Name (TMP, ResourceTemplate () {
+- IO (Decode16, 0x0060, 0x0060, 0x01, 0x01)
+- IO (Decode16, 0x0064, 0x0064, 0x01, 0x01)
+- IRQNoFlags () {1}
+- })
+- Return (TMP)
+- }
+- }
+-
+- /* PS/2 mouse */
+- Device (MOU)
+- {
+- Name (_HID, EisaId ("PNP0F03"))
+- Name (_CID, EisaId ("PNP0F13"))
+- Method (_STA, 0, NotSerialized)
+- {
+- Return (0x0f)
+- }
+- Method (_CRS, 0, Serialized)
+- {
+- Name (TMP, ResourceTemplate () {
+- IRQNoFlags () {12}
+- })
+- Return (TMP)
+- }
+- }
+-
++ #include "../../../drivers/pc80/ps2_controller.asl"
+
+ /* UART 1 */
+ Device (URT1)
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch
new file mode 100644
index 0000000..596cab9
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0022-southbridge-amd-sb700-Add-missing-DMA-setup-step-fro.patch
@@ -0,0 +1,30 @@
+From c104a49921424687b0aacea660582ea3c027024a Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:56 -0600
+Subject: [PATCH 22/45] southbridge/amd/sb700: Add missing DMA setup step from
+ AMD RRG
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/southbridge/amd/sb700/early_setup.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/southbridge/amd/sb700/early_setup.c b/src/southbridge/amd/sb700/early_setup.c
+index 06c6c77..544447e 100644
+--- a/src/southbridge/amd/sb700/early_setup.c
++++ b/src/southbridge/amd/sb700/early_setup.c
+@@ -420,6 +420,11 @@ static void sb700_devices_por_init(void)
+ /* Legacy DMA Prefetch Enhancement, CIM masked it. */
+ /* pci_write_config8(dev, 0x43, 0x1); */
+
++ /* Enable DMA verify bugfix */
++ byte = pci_read_config8(dev, 0x67);
++ byte |= 0x1 << 1;
++ pci_write_config8(dev, 0x67, byte);
++
+ /* Disabling Legacy USB Fast SMI# */
+ byte = pci_read_config8(dev, 0x62);
+ byte |= 0x24;
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch
new file mode 100644
index 0000000..1f41eaf
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0023-southbridge-amd-sb700-Add-CMOS-option-to-disable-leg.patch
@@ -0,0 +1,53 @@
+From 01f84b46b749454f6c93c3273fac65be780a128b Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:56 -0600
+Subject: [PATCH 23/45] southbridge/amd/sb700: Add CMOS option to disable
+ legacy USB support
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/southbridge/amd/sb700/sm.c | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c
+index 04f4601..942e4f8 100644
+--- a/src/southbridge/amd/sb700/sm.c
++++ b/src/southbridge/amd/sb700/sm.c
+@@ -63,6 +63,7 @@ static void sm_init(device_t dev)
+ u32 dword;
+ void *ioapic_base;
+ uint32_t power_state;
++ uint32_t enable_legacy_usb;
+ u32 nmi_option;
+
+ printk(BIOS_INFO, "sm_init().\n");
+@@ -72,10 +73,23 @@ static void sm_init(device_t dev)
+ ioapic_base = (void *)(pci_read_config32(dev, 0x74) & (0xffffffe0));
+ setup_ioapic(ioapic_base, 0); /* Don't rename IOAPIC ID. */
+
++ enable_legacy_usb = 1;
++ get_option(&enable_legacy_usb, "enable_legacy_usb");
++
+ /* 2.10 Interrupt Routing/Filtering */
+- dword = pci_read_config8(dev, 0x62);
+- dword |= 3;
+- pci_write_config8(dev, 0x62, dword);
++ byte = pci_read_config8(dev, 0x62);
++ if (enable_legacy_usb)
++ byte |= 0x3;
++ else
++ byte &= ~0x3;
++ pci_write_config8(dev, 0x62, byte);
++
++ byte = pci_read_config8(dev, 0x67);
++ if (enable_legacy_usb)
++ byte |= 0x1 << 7;
++ else
++ byte &= ~(0x1 << 7);
++ pci_write_config8(dev, 0x67, byte);
+
+ /* Delay back to back interrupts to the CPU. */
+ dword = pci_read_config16(dev, 0x64);
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch
new file mode 100644
index 0000000..b4be5fa
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0024-superio-winbond-w83667hg-a-Add-support-for-W83667HG-.patch
@@ -0,0 +1,249 @@
+From 42a116b68ea468e32bb37aa333e53eb9c552a6c7 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:57 -0600
+Subject: [PATCH 24/45] superio/winbond/w83667hg-a: Add support for W83667HG-A
+
+The KGPE-D16 and KCMA-D8 use a Winbond W83667HG-A SuperIO. While
+the Nuvoton NCT5572D is effectively the same core, and a close
+enough match to get things working initially, the W83667HG-A
+has a different LDN mapping and several extra features that
+require a separate support driver.
+
+Clone the Nuvoton NCT5572D and modify according to the W83667HG-A
+datasheet.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/superio/winbond/Kconfig | 4 +
+ src/superio/winbond/Makefile.inc | 1 +
+ src/superio/winbond/w83667hg-a/Makefile.inc | 19 +++++
+ src/superio/winbond/w83667hg-a/superio.c | 109 ++++++++++++++++++++++++++++
+ src/superio/winbond/w83667hg-a/w83667hg-a.h | 47 ++++++++++++
+ 5 files changed, 180 insertions(+)
+ create mode 100644 src/superio/winbond/w83667hg-a/Makefile.inc
+ create mode 100644 src/superio/winbond/w83667hg-a/superio.c
+ create mode 100644 src/superio/winbond/w83667hg-a/w83667hg-a.h
+
+diff --git a/src/superio/winbond/Kconfig b/src/superio/winbond/Kconfig
+index ba9f479..1731a7f 100644
+--- a/src/superio/winbond/Kconfig
++++ b/src/superio/winbond/Kconfig
+@@ -39,6 +39,10 @@ config SUPERIO_WINBOND_W83627UHG
+ bool
+ select SUPERIO_WINBOND_COMMON_ROMSTAGE
+
++config SUPERIO_WINBOND_W83667HG_A
++ bool
++ select SUPERIO_WINBOND_COMMON_ROMSTAGE
++
+ config SUPERIO_WINBOND_W83697HF
+ bool
+ select SUPERIO_WINBOND_COMMON_ROMSTAGE
+diff --git a/src/superio/winbond/Makefile.inc b/src/superio/winbond/Makefile.inc
+index 67927dc..ae4b283 100644
+--- a/src/superio/winbond/Makefile.inc
++++ b/src/superio/winbond/Makefile.inc
+@@ -21,6 +21,7 @@ subdirs-y += w83627ehg
+ subdirs-y += w83627hf
+ subdirs-y += w83627thg
+ subdirs-y += w83627uhg
++subdirs-y += w83667hg-a
+ subdirs-y += w83697hf
+ subdirs-y += w83977tf
+ subdirs-y += wpcd376i
+diff --git a/src/superio/winbond/w83667hg-a/Makefile.inc b/src/superio/winbond/w83667hg-a/Makefile.inc
+new file mode 100644
+index 0000000..7665046
+--- /dev/null
++++ b/src/superio/winbond/w83667hg-a/Makefile.inc
+@@ -0,0 +1,19 @@
++##
++## This file is part of the coreboot project.
++##
++## Copyright (C) 2011 - 2012 Advanced Micro Devices, Inc.
++## Copyright (C) 2014 Felix Held <felix-coreboot@felixheld.de>
++## Copyright (C) 2015 Raptor Engineering
++##
++## This program is free software; you can redistribute it and/or modify
++## it under the terms of the GNU General Public License as published by
++## the Free Software Foundation; either version 2 of the License, or
++## (at your option) any later version.
++##
++## This program is distributed in the hope that it will be useful,
++## but WITHOUT ANY WARRANTY; without even the implied warranty of
++## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++## GNU General Public License for more details.
++##
++
++ramstage-$(CONFIG_SUPERIO_WINBOND_W83667HG_A) += superio.c
+diff --git a/src/superio/winbond/w83667hg-a/superio.c b/src/superio/winbond/w83667hg-a/superio.c
+new file mode 100644
+index 0000000..b539871
+--- /dev/null
++++ b/src/superio/winbond/w83667hg-a/superio.c
+@@ -0,0 +1,109 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2014 Felix Held <felix-coreboot@felixheld.de>
++ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan@alterapraxis.com>
++ * Copyright (C) 2015 Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <arch/io.h>
++#include <device/device.h>
++#include <device/pnp.h>
++#include <pc80/keyboard.h>
++#include <pc80/mc146818rtc.h>
++#include <stdlib.h>
++#include <superio/conf_mode.h>
++
++#include "w83667hg-a.h"
++
++#define MAINBOARD_POWER_OFF 0
++#define MAINBOARD_POWER_ON 1
++
++#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
++#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
++#endif
++
++static void w83667hg_a_init(struct device *dev)
++{
++ uint8_t byte;
++ uint8_t power_status;
++
++ if (!dev->enabled)
++ return;
++
++ switch(dev->path.pnp.device) {
++ /* TODO: Might potentially need code for HWM or FDC etc. */
++ case W83667HG_A_KBC:
++ pc_keyboard_init();
++ break;
++ case W83667HG_A_ACPI:
++ /* Set power state after power fail */
++ power_status = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
++ get_option(&power_status, "power_on_after_fail");
++ pnp_enter_conf_mode_8787(dev);
++ pnp_set_logical_device(dev);
++ byte = pnp_read_config(dev, 0xe4);
++ byte &= ~0x60;
++ if (power_status == 1)
++ byte |= (0x1 << 5); /* Force power on */
++ else if (power_status == 2)
++ byte |= (0x2 << 5); /* Use last power state */
++ pnp_write_config(dev, 0xe4, byte);
++ pnp_exit_conf_mode_aa(dev);
++ printk(BIOS_INFO, "set power %s after power fail\n", power_status ? "on" : "off");
++ break;
++ }
++}
++
++static struct device_operations ops = {
++ .read_resources = pnp_read_resources,
++ .set_resources = pnp_set_resources,
++ .enable_resources = pnp_enable_resources,
++ .enable = pnp_alt_enable,
++ .init = w83667hg_a_init,
++ .ops_pnp_mode = &pnp_conf_mode_8787_aa,
++};
++
++static struct pnp_info pnp_dev_info[] = {
++ { &ops, W83667HG_A_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x0ff8, 0}, },
++ { &ops, W83667HG_A_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x0ff8, 0}, },
++ { &ops, W83667HG_A_SP1, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, },
++ { &ops, W83667HG_A_SP2, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, },
++ { &ops, W83667HG_A_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, {0x0fff, 0}, {0x0fff, 4}, },
++ { &ops, W83667HG_A_SPI},
++ { &ops, W83667HG_A_WDT1},
++ { &ops, W83667HG_A_ACPI},
++ { &ops, W83667HG_A_HWM_TSI, PNP_IO0 | PNP_IO1 | PNP_IRQ0, {0x0ffe, 0}, {0x0ffe, 4}, },
++ { &ops, W83667HG_A_PECI},
++ { &ops, W83667HG_A_VID_BUSSEL},
++ { &ops, W83667HG_A_GPIO_PP_OD},
++ { &ops, W83667HG_A_GPIO2},
++ { &ops, W83667HG_A_GPIO3},
++ { &ops, W83667HG_A_GPIO4},
++ { &ops, W83667HG_A_GPIO5},
++ { &ops, W83667HG_A_GPIO6},
++ { &ops, W83667HG_A_GPIO7},
++ { &ops, W83667HG_A_GPIO8},
++ { &ops, W83667HG_A_GPIO9},
++};
++
++static void enable_dev(struct device *dev)
++{
++ pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
++}
++
++struct chip_operations superio_winbond_w83667hg_a_ops = {
++ CHIP_NAME("WINBOND W83667HG-A Super I/O")
++ .enable_dev = enable_dev,
++};
+diff --git a/src/superio/winbond/w83667hg-a/w83667hg-a.h b/src/superio/winbond/w83667hg-a/w83667hg-a.h
+new file mode 100644
+index 0000000..efb77b8
+--- /dev/null
++++ b/src/superio/winbond/w83667hg-a/w83667hg-a.h
+@@ -0,0 +1,47 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2014 Felix Held <felix-coreboot@felixheld.de>
++ * Copyright (C) 2015 Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef SUPERIO_WINBOND_W83667HG_A
++#define SUPERIO_WINBOND_W83667HG_A
++
++/* Logical Device Numbers (LDN). */
++#define W83667HG_A_FDC 0x00
++#define W83667HG_A_PP 0x01
++#define W83667HG_A_SP1 0x02 /* Com1 */
++#define W83667HG_A_SP2 0x03 /* Com2 */
++#define W83667HG_A_KBC 0x05
++#define W83667HG_A_SPI 0x06
++#define W83667HG_A_GPIO6789_V 0x07
++#define W83667HG_A_WDT1 0x08
++#define W83667HG_A_GPIO2345_V 0x09
++#define W83667HG_A_ACPI 0x0A
++#define W83667HG_A_HWM_TSI 0x0B /* HW monitor/SB-TSI/deep S5 */
++#define W83667HG_A_PECI 0x0C
++#define W83667HG_A_VID_BUSSEL 0x0D /* VID and BUSSEL */
++#define W83667HG_A_GPIO_PP_OD 0x0F /* GPIO Push-Pull/Open drain select */
++
++/* virtual LDN for GPIO */
++#define W83667HG_A_GPIO2 ((0 << 8) | W83667HG_A_GPIO2345_V)
++#define W83667HG_A_GPIO3 ((1 << 8) | W83667HG_A_GPIO2345_V)
++#define W83667HG_A_GPIO4 ((2 << 8) | W83667HG_A_GPIO2345_V)
++#define W83667HG_A_GPIO5 ((3 << 8) | W83667HG_A_GPIO2345_V)
++#define W83667HG_A_GPIO6 ((1 << 8) | W83667HG_A_GPIO6789_V)
++#define W83667HG_A_GPIO7 ((2 << 8) | W83667HG_A_GPIO6789_V)
++#define W83667HG_A_GPIO8 ((3 << 8) | W83667HG_A_GPIO6789_V)
++#define W83667HG_A_GPIO9 ((4 << 8) | W83667HG_A_GPIO6789_V)
++
++#endif /* SUPERIO_WINBOND_W83667HG_A */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch
new file mode 100644
index 0000000..ea534fa
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0025-mainboard-asus-kgpe-d16-Use-W83667HG-A-SuperIO-inste.patch
@@ -0,0 +1,109 @@
+From 35727a48c8a48f0cc1bbf8c95dd9d0d3fdafa6d9 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:57 -0600
+Subject: [PATCH 25/45] mainboard/asus/kgpe-d16: Use W83667HG-A SuperIO instead
+ of NCT5572D
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/Kconfig | 2 +-
+ src/mainboard/asus/kgpe-d16/devicetree.cb | 16 +++++++++-------
+ src/mainboard/asus/kgpe-d16/romstage.c | 8 ++++----
+ 3 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/Kconfig b/src/mainboard/asus/kgpe-d16/Kconfig
+index f394ca9..23c91f0 100644
+--- a/src/mainboard/asus/kgpe-d16/Kconfig
++++ b/src/mainboard/asus/kgpe-d16/Kconfig
+@@ -12,7 +12,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ select SOUTHBRIDGE_AMD_SB700
+ select SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA
+ select SOUTHBRIDGE_AMD_SUBTYPE_SP5100
+- select SUPERIO_NUVOTON_NCT5572D
++ select SUPERIO_WINBOND_W83667HG_A
+ select PARALLEL_CPU_INIT
+ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK
+ select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
+diff --git a/src/mainboard/asus/kgpe-d16/devicetree.cb b/src/mainboard/asus/kgpe-d16/devicetree.cb
+index 96372f9..8d64ac7 100644
+--- a/src/mainboard/asus/kgpe-d16/devicetree.cb
++++ b/src/mainboard/asus/kgpe-d16/devicetree.cb
+@@ -177,24 +177,27 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ device pci 14.1 on end # IDE 0x439c
+ device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card)
+ device pci 14.3 on # LPC 0x439d (SMBUS primary controller)
+- chip superio/nuvoton/nct5572d # Super I/O
++ chip superio/winbond/w83667hg-a # Super I/O
+ device pnp 2e.0 off end # FDC; Not available on the KGPE-D16
+ device pnp 2e.1 off end # LPT1; Not available on the KGPE-D16
+ device pnp 2e.2 on # Com1
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+ end
+- device pnp 2e.3 off end # IR: Not available on the KGPE-D16
++ device pnp 2e.3 on # Com2
++ io 0x60 = 0x2f8
++ irq 0x70 = 3
++ end
+ device pnp 2e.5 on # PS/2 keyboard & mouse
+ io 0x60 = 0x60
+ io 0x62 = 0x64
+ irq 0x70 = 1
+ irq 0x72 = 12
+ end
+- device pnp 2e.6 off end # CIR: Not available on the KGPE-D16
+- device pnp 2e.7 off end # GIPO689
++ device pnp 2e.6 off end # SPI: Not available on the KGPE-D16
++ device pnp 2e.7 off end # GIPO6789
+ device pnp 2e.8 off end # WDT
+- device pnp 2e.9 off end # GPIO235
++ device pnp 2e.9 off end # GPIO2345
+ device pnp 2e.a on end # ACPI
+ device pnp 2e.b on # HW Monitor
+ io 0x60 = 0x290
+@@ -202,8 +205,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ irq 0x70 = 5
+ end
+ device pnp 2e.c off end # PECI
+- device pnp 2e.d off end # SUSLED
+- device pnp 2e.e off end # CIRWKUP
++ device pnp 2e.d off end # VID_BUSSEL
+ device pnp 2e.f off end # GPIO_PP_OD
+ end
+ end
+diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
+index 20ba6f2..6fb7668 100644
+--- a/src/mainboard/asus/kgpe-d16/romstage.c
++++ b/src/mainboard/asus/kgpe-d16/romstage.c
+@@ -35,8 +35,8 @@
+ #include "lib/delay.c"
+ #include <cpu/x86/lapic.h>
+ #include "northbridge/amd/amdfam10/reset_test.c"
+-#include <superio/nuvoton/common/nuvoton.h>
+-#include <superio/nuvoton/nct5572d/nct5572d.h>
++#include <superio/winbond/common/winbond.h>
++#include <superio/winbond/w83667hg-a/w83667hg-a.h>
+ #include <cpu/x86/bist.h>
+ #include <smp/spinlock.h>
+ // #include "northbridge/amd/amdk8/incoherent_ht.c"
+@@ -46,7 +46,7 @@
+ #include "northbridge/amd/amdfam10/debug.c"
+ #include "northbridge/amd/amdfam10/setup_resource_map.c"
+
+-#define SERIAL_DEV PNP_DEV(0x2e, NCT5572D_SP1)
++#define SERIAL_DEV PNP_DEV(0x2e, W83667HG_A_SP1)
+
+ static void activate_spd_rom(const struct mem_controller *ctrl);
+
+@@ -393,7 +393,7 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ sb7xx_51xx_pci_port80();
+
+ /* Initialize early serial */
+- nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
++ winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
+ console_init();
+
+ /* Disable LPC legacy DMA support to prevent lockup */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch
new file mode 100644
index 0000000..7e878bc
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0026-cpu-amd-fam10h-15h-Fix-Family-15h-boot-hang-when-BSP.patch
@@ -0,0 +1,59 @@
+From 5da709f633ca379d6f0689f99f3f2cc01110f673 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:58 -0600
+Subject: [PATCH 26/45] cpu/amd/fam10h-15h: Fix Family 15h boot hang when BSP
+ lift enabled
+
+The existing code did not allow for the second core of the BSP to
+reside on an APIC ID other than 1, leading to a boot hang on Family
+15h processors when APIC_ID_OFFSET was set to anything other than 0.
+Furthermore, insufficient AP stack space was allocated for AP start.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/Kconfig | 2 +-
+ src/cpu/amd/family_10h-family_15h/init_cpus.c | 8 +++++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/Kconfig b/src/cpu/amd/family_10h-family_15h/Kconfig
+index bfb6751..2f3dfc0 100644
+--- a/src/cpu/amd/family_10h-family_15h/Kconfig
++++ b/src/cpu/amd/family_10h-family_15h/Kconfig
+@@ -48,7 +48,7 @@ config DCACHE_BSP_STACK_SLUSH
+
+ config DCACHE_AP_STACK_SIZE
+ hex
+- default 0x400
++ default 0x500
+
+ config UDELAY_IO
+ bool
+diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+index 5a67601..e8e81d2 100644
+--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c
++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+@@ -356,6 +356,7 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
+ uint32_t dword;
+ uint8_t set_mtrrs;
+ uint8_t node_count;
++ uint8_t fam15_bsp_core1_apicid;
+ struct node_core_id id;
+
+ /* Please refer to the calculations and explaination in cache_as_ram.inc before modifying these values */
+@@ -483,7 +484,12 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
+ if (is_fam15h()) {
+ /* core 1 on node 0 is special; to avoid corrupting the
+ * BSP do not alter MTRRs on that core */
+- if (apicid == 1)
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ fam15_bsp_core1_apicid = CONFIG_APIC_ID_OFFSET + 1;
++ else
++ fam15_bsp_core1_apicid = 1;
++
++ if (apicid == fam15_bsp_core1_apicid)
+ set_mtrrs = 0;
+ else
+ set_mtrrs = !!(apicid & 0x1);
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch
new file mode 100644
index 0000000..65aada7
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0027-southbridge-amd-sb700-Set-HPET-min-tick-value-to-RPR.patch
@@ -0,0 +1,27 @@
+From 6c4fb7d4b666ae94c8421e4dd363674294f3f7ca Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:58 -0600
+Subject: [PATCH 27/45] southbridge/amd/sb700: Set HPET min tick value to RPR
+ recommendation
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/southbridge/amd/sb700/Kconfig | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/southbridge/amd/sb700/Kconfig b/src/southbridge/amd/sb700/Kconfig
+index 9a0ddb2..9a988a9 100644
+--- a/src/southbridge/amd/sb700/Kconfig
++++ b/src/southbridge/amd/sb700/Kconfig
+@@ -50,4 +50,8 @@ config EHCI_BAR
+ hex
+ default 0xfef00000
+
++config HPET_MIN_TICKS
++ hex
++ default 0x14
++
+ endif # SOUTHBRIDGE_AMD_SB700
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch
new file mode 100644
index 0000000..0cb57ba
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0028-southbridge-amd-sb700-Enable-extended-APIC-ID-when-K.patch
@@ -0,0 +1,32 @@
+From 6badc1a8783f8916d9f66026bef02781f6397dec Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:58 -0600
+Subject: [PATCH 28/45] southbridge/amd/sb700: Enable extended APIC ID when
+ Kconfig option set
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/southbridge/amd/sb700/sm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c
+index 942e4f8..0d017aa 100644
+--- a/src/southbridge/amd/sb700/sm.c
++++ b/src/southbridge/amd/sb700/sm.c
+@@ -298,9 +298,11 @@ static void sm_init(device_t dev)
+ byte |= 1 << 3;
+ pci_write_config8(dev, 0x43, byte);
+ }
+- //ACPI_DISABLE_TIMER_IRQ_ENHANCEMENT_FOR_8254_TIMER
+ byte = pci_read_config8(dev, 0xAE);
+- byte |= 1 << 5;
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID))
++ byte |= 1 << 4;
++ byte |= 1 << 5; /* ACPI_DISABLE_TIMER_IRQ_ENHANCEMENT_FOR_8254_TIMER */
++ byte |= 1 << 6; /* Enable arbiter between APIC and PIC interrupts */
+ pci_write_config8(dev, 0xAE, byte);
+
+ /* 4.11:Programming Cycle Delay for AB and BIF Clock Gating */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch
new file mode 100644
index 0000000..8b010e5
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0029-mainboard-asus-kgpe-d16-Update-DSDT-with-new-devices.patch
@@ -0,0 +1,185 @@
+From 61d7b1545c10558590ed2ac98a427318b909affc Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:59 -0600
+Subject: [PATCH 29/45] mainboard/asus/kgpe-d16: Update DSDT with new devices
+ and bump version
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/dsdt.asl | 123 ++++++++++++++++++++++++++---------
+ 1 file changed, 94 insertions(+), 29 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/dsdt.asl b/src/mainboard/asus/kgpe-d16/dsdt.asl
+index 44b6a98..702ace1 100644
+--- a/src/mainboard/asus/kgpe-d16/dsdt.asl
++++ b/src/mainboard/asus/kgpe-d16/dsdt.asl
+@@ -33,7 +33,7 @@
+ DefinitionBlock (
+ "DSDT.AML", /* Output filename */
+ "DSDT", /* Signature */
+- 0x02, /* DSDT Revision, needs to be 2 for 64bit */
++ 0x03, /* DSDT Revision, needs to be 2 or higher for 64bit */
+ "ASUS ", /* OEMID */
+ "COREBOOT", /* TABLE ID */
+ 0x00000001 /* OEM Revision */
+@@ -47,9 +47,8 @@ DefinitionBlock (
+ Name(OSV, Ones) /* Assume nothing */
+ Name(PICM, One) /* Assume APIC */
+
+- /* HPET control */
+- Name (SHPB, 0xFED00000)
+- Name (SHPL, 0x1000)
++ /* HPET enable */
++ Name (HPTE, 0x1)
+
+ /* Define power states */
+ Name (\_S0, Package () { 0x00, 0x00, 0x00, 0x00 }) /* Normal operation */
+@@ -126,12 +125,13 @@ DefinitionBlock (
+ /* Root of the bus hierarchy */
+ Scope (\_SB)
+ {
+- /* Top southbridge PCI device (SR5690) */
++ /* Top southbridge PCI device (SR5690 + SP5100) */
+ Device (PCI0)
+ {
+ /* BUS0 root bus */
+
+- Name (_HID, EisaId ("PNP0A03"))
++ Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5690) */
++ Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */
+ Name (_ADR, 0x00180001)
+ Name (_UID, 0x00)
+
+@@ -490,6 +490,78 @@ DefinitionBlock (
+ Name (_HID, EisaId ("PNP0A05"))
+ Name (_ADR, 0x00140003)
+
++ /* Real Time Clock Device */
++ Device(RTC0) {
++ Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */
++ Name(BUF0, ResourceTemplate() {
++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02)
++ })
++ Name(BUF1, ResourceTemplate() {
++ IRQNoFlags() { 8 }
++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02)
++ })
++ Method(_CRS, 0) {
++ If(HPTE) {
++ Return(BUF0)
++ }
++ Return(BUF1)
++ }
++ }
++
++ Device(TMR) { /* Timer */
++ Name(_HID,EISAID("PNP0100")) /* System Timer */
++ Name(BUF0, ResourceTemplate() {
++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04)
++ })
++ Name(BUF1, ResourceTemplate() {
++ IRQNoFlags() { 0 }
++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04)
++ })
++ Method(_CRS, 0) {
++ If(HPTE) {
++ Return(BUF0)
++ }
++ Return(BUF1)
++ }
++ }
++
++ Device(SPKR) { /* Speaker */
++ Name(_HID,EISAID("PNP0800")) /* AT style speaker */
++ Name(_CRS, ResourceTemplate() {
++ IO(Decode16, 0x0061, 0x0061, 0, 1)
++ })
++ }
++
++ Device(PIC) {
++ Name(_HID,EISAID("PNP0000")) /* AT Interrupt Controller */
++ Name(_CRS, ResourceTemplate() {
++ IRQNoFlags() { 2 }
++ IO(Decode16,0x0020, 0x0020, 0, 2)
++ IO(Decode16,0x00A0, 0x00A0, 0, 2)
++ })
++ }
++
++ Device(MAD) { /* 8257 DMA */
++ Name(_HID,EISAID("PNP0200")) /* Hardware Device ID */
++ Name(_CRS, ResourceTemplate() {
++ DMA(Compatibility,BusMaster,Transfer8){4}
++ IO(Decode16, 0x0000, 0x0000, 0x10, 0x10)
++ IO(Decode16, 0x0081, 0x0081, 0x01, 0x03)
++ IO(Decode16, 0x0087, 0x0087, 0x01, 0x01)
++ IO(Decode16, 0x0089, 0x0089, 0x01, 0x03)
++ IO(Decode16, 0x008F, 0x008F, 0x01, 0x01)
++ IO(Decode16, 0x00C0, 0x00C0, 0x10, 0x20)
++ }) /* End Name(_SB.PCI0.LpcIsaBr.MAD._CRS) */
++ }
++
++ Device(COPR) {
++ Name(_HID,EISAID("PNP0C04")) /* Math Coprocessor */
++ Name(_CRS, ResourceTemplate() {
++ IO(Decode16, 0x00F0, 0x00F0, 0, 0x10)
++ IRQNoFlags(){13}
++ })
++ }
++
+ #include "../../../drivers/pc80/ps2_controller.asl"
+
+ /* UART 1 */
+@@ -515,34 +587,27 @@ DefinitionBlock (
+ })
+ }
+ }
++ }
+
+- /* High Precision Event Timer */
+- Device (HPET)
++ /* High Precision Event Timer */
++ Device (HPET)
++ {
++ Name (_HID, EisaId ("PNP0103"))
++ Name (CRS, ResourceTemplate ()
+ {
+- Name (_HID, EisaId ("PNP0103"))
+- Name (CRS, ResourceTemplate ()
+- {
+- Memory32Fixed (ReadOnly,
+- 0x00000000,
+- 0x00001000,
+- _Y02)
+- IRQNoFlags () {0}
+- IRQNoFlags () {8}
+- })
+- Method (_STA, 0, NotSerialized)
+- {
++ Memory32Fixed(ReadOnly, 0xFED00000, 0x00000400)
++ })
++ Method (_STA, 0)
++ {
++ If(HPTE) {
+ Return (0x0F)
+ }
+- Method (_CRS, 0, NotSerialized)
+- {
+- CreateDWordField (CRS, \_SB.PCI0.LPC.HPET._Y02._BAS, HPT1)
+- CreateDWordField (CRS, \_SB.PCI0.LPC.HPET._Y02._LEN, HPT2)
+- Store (SHPB, HPT1)
+- Store (SHPL, HPT2)
+- Return (CRS)
+- }
+-
++ Return (0x0)
+ }
++ Method(_CRS, 0)
++ {
++ Return(CRS)
++ }
+ }
+
+ /* 0:14.4 PCI Bridge */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch
new file mode 100644
index 0000000..3d13fd4
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0030-mainboard-asus-kgpe-d16-Clean-up-legacy-PIRQ-table-c.patch
@@ -0,0 +1,92 @@
+From 2f6df3b764bf4090a79a4bae7c4c7e7281568cf3 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:11:59 -0600
+Subject: [PATCH 30/45] mainboard/asus/kgpe-d16: Clean up legacy PIRQ table
+ code
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/irq_tables.c | 31 +++++++++++++++++++++++++------
+ 1 file changed, 25 insertions(+), 6 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/irq_tables.c b/src/mainboard/asus/kgpe-d16/irq_tables.c
+index 029dea8..ef39db2 100644
+--- a/src/mainboard/asus/kgpe-d16/irq_tables.c
++++ b/src/mainboard/asus/kgpe-d16/irq_tables.c
+@@ -2,7 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2015 Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -23,6 +23,24 @@
+
+ #include <cpu/amd/amdfam10_sysconf.h>
+
++/* Free irqs are 3, 4, 5, 6, 7, 9, 10, 11, 12, 14, and 15 */
++#define IRQBM ((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<14)|(1<<15))
++
++#define LNKA 1
++#define LNKB 2
++#define LNKC 3
++#define LNKD 4
++
++/*
++ * For simplicity map LNK[E-H] to LNK[A-D].
++ * This also means we are 82C596 compatible.
++ * Needs 0:11.0 0x46[4] set to 0.
++ */
++#define LNKE 1
++#define LNKF 2
++#define LNKG 3
++#define LNKH 4
++
+ static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn,
+ u8 link0, u16 bitmap0, u8 link1, u16 bitmap1,
+ u8 link2, u16 bitmap2, u8 link3, u16 bitmap3,
+@@ -42,9 +60,10 @@ static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn,
+ pirq_info->rfu = rfu;
+ }
+ extern u8 bus_isa;
+-extern u8 bus_rs780[8];
++extern u8 bus_sr5650[14];
+ extern u8 bus_sp5100[2];
+-extern unsigned long sbdn_sp5100;
++extern u32 sbdn_sp5100;
++extern u32 sbdn_sr5650;
+
+ unsigned long write_pirq_routing_table(unsigned long addr)
+ {
+@@ -71,6 +90,7 @@ unsigned long write_pirq_routing_table(unsigned long addr)
+ pirq->signature = PIRQ_SIGNATURE;
+ pirq->version = PIRQ_VERSION;
+
++ /* Where the interrupt router resides */
+ pirq->rtr_bus = bus_sp5100[0];
+ pirq->rtr_devfn = PCI_DEVFN(0x14, 4);
+
+@@ -88,8 +108,7 @@ unsigned long write_pirq_routing_table(unsigned long addr)
+
+ /* pci bridge */
+ write_pirq_info(pirq_info, bus_sp5100[0], ((sbdn_sp5100 + 0x14) << 3) | 4,
+- 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0,
+- 0);
++ LNKA, IRQBM, LNKB, IRQBM, LNKC, IRQBM, LNKD, IRQBM, 0, 0);
+ pirq_info++;
+ slot_num++;
+
+@@ -103,7 +122,7 @@ unsigned long write_pirq_routing_table(unsigned long addr)
+ pirq->checksum = sum;
+ }
+
+- printk(BIOS_INFO, "write_pirq_routing_table done.\n");
++ printk(BIOS_INFO, "done.\n");
+
+ return (unsigned long)pirq_info;
+ }
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch
new file mode 100644
index 0000000..5bbee0d
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0031-mainboard-asus-kgpe-d16-Add-missing-IRQ-route-to-mpt.patch
@@ -0,0 +1,65 @@
+From ccb95f573b5549fa686abbd818bfab5fadfad241 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:00 -0600
+Subject: [PATCH 31/45] mainboard/asus/kgpe-d16: Add missing IRQ route to
+ mptable
+
+The IOMMU/HT device was not routed correctly; add the proper APIC
+mappting to the mptable generation code. Also clarify comments
+surrounding the pin mappings.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/mptable.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/mptable.c b/src/mainboard/asus/kgpe-d16/mptable.c
+index a6ed5c9..c869d31 100644
+--- a/src/mainboard/asus/kgpe-d16/mptable.c
++++ b/src/mainboard/asus/kgpe-d16/mptable.c
+@@ -2,7 +2,7 @@
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2015 Raptor Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -47,7 +47,10 @@ static void *smp_write_config_table(void *v)
+
+ get_bus_conf();
+
+- apicid_sp5100 = 0x20;
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ apicid_sp5100 = 0x0;
++ else
++ apicid_sp5100 = 0x20;
+ apicid_sr5650 = apicid_sp5100 + 1;
+
+ mptable_write_buses(mc, NULL, &bus_isa);
+@@ -122,13 +125,14 @@ static void *smp_write_config_table(void *v)
+ mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0);
+
+ /* SR5650 devices */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((0)<<2)|(2)), apicid_sr5650, 31); /* Device 0 Function 2 (LNKA, APIC pin 31) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE, APIC pin 28) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF, APIC pin 28) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG, APIC pin 29) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */
+
+ dev = dev_find_slot(0, PCI_DEVFN(0x2, 0));
+ if (dev && dev->enabled) {
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch
new file mode 100644
index 0000000..a02f8e2
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0032-mainboard-asus-kgpe-d16-Add-support-for-lifted-BSP-A.patch
@@ -0,0 +1,60 @@
+From 8a89ad28a33052b3bd27faab8e0f90babd2f3599 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:01 -0600
+Subject: [PATCH 32/45] mainboard/asus/kgpe-d16: Add support for lifted BSP
+ APIC IDs
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/acpi_tables.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/acpi_tables.c b/src/mainboard/asus/kgpe-d16/acpi_tables.c
+index 24c1724..f20e837 100644
+--- a/src/mainboard/asus/kgpe-d16/acpi_tables.c
++++ b/src/mainboard/asus/kgpe-d16/acpi_tables.c
+@@ -36,7 +36,10 @@ unsigned long acpi_fill_madt(unsigned long current)
+ /* create all subtables for processors */
+ current = acpi_create_madt_lapics(current);
+
+- apicid_sp5100 = 0x20;
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ apicid_sp5100 = 0x0;
++ else
++ apicid_sp5100 = 0x20;
+ apicid_sr5650 = apicid_sp5100 + 1;
+
+ /* Write SB700 IOAPIC, only one */
+@@ -56,15 +59,10 @@ unsigned long acpi_fill_madt(unsigned long current)
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 0, 2, 0);
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+- current, 0, 9, 9, 0xF);
+- /* 0: mean bus 0--->ISA */
+- /* 0: PIC 0 */
+- /* 2: APIC 2 */
+- /* 5 mean: 0101 --> Edge-triggered, Active high */
++ current, 0, 9, 9, 0xf);
+
+ /* create all subtables for processors */
+- current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0, 5, 1);
+- current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 1, 5, 1);
++ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0xff, 0, 1);
+ /* 1: LINT1 connect to NMI */
+
+ return current;
+@@ -77,7 +75,10 @@ unsigned long acpi_fill_ivrs_ioapic(acpi_ivrs_t* ivrs, unsigned long current)
+ uint32_t apicid_sp5100;
+ uint32_t apicid_sr5650;
+
+- apicid_sp5100 = 0x20;
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ apicid_sp5100 = 0x0;
++ else
++ apicid_sp5100 = 0x20;
+ apicid_sr5650 = apicid_sp5100 + 1;
+
+ /* Describe NB IOAPIC */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch
new file mode 100644
index 0000000..1753b05
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0033-drivers-pc80-Add-PS-2-mouse-presence-detect.patch
@@ -0,0 +1,1160 @@
+From 5bb8df0244b9839365e292bc60c344074f17f5a4 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:01 -0600
+Subject: [PATCH 33/45] drivers/pc80: Add PS/2 mouse presence detect
+
+On certain Winbond SuperIO devices, when a PS/2 mouse is not
+present on the auxiliary channel both channels will cease to
+function if the auxiliary channel is probed while the primary
+channel is active. Therefore, knowledge of mouse presence
+must be gathered by coreboot during early boot, and used to
+enable or disable the auxiliary PS/2 port before control is
+passed to the operating system.
+
+Add auxiliary channel PS/2 device presence detect, and update
+the Winbond W83667HG-A driver to flag the auxiliary channel as
+disabled if no device was detected.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/drivers/pc80/keyboard.c | 101 +++++++++++++++++-----
+ src/ec/compal/ene932/ec.c | 2 +-
+ src/ec/google/chromeec/ec_lpc.c | 2 +-
+ src/ec/lenovo/h8/h8.c | 2 +-
+ src/ec/quanta/ene_kb3940q/ec.c | 2 +-
+ src/ec/quanta/it8518/ec.c | 2 +-
+ src/include/pc80/keyboard.h | 2 +-
+ src/mainboard/emulation/qemu-i440fx/mainboard.c | 2 +-
+ src/mainboard/emulation/qemu-q35/mainboard.c | 2 +-
+ src/mainboard/packardbell/ms2290/mainboard.c | 2 +-
+ src/mainboard/roda/rk9/mainboard.c | 2 +-
+ src/northbridge/via/cx700/lpc.c | 2 +-
+ src/northbridge/via/vx800/lpc.c | 2 +-
+ src/southbridge/dmp/vortex86ex/southbridge.c | 2 +-
+ src/southbridge/sis/sis966/lpc.c | 2 +-
+ src/southbridge/via/vt8237r/lpc.c | 2 +-
+ src/superio/fintek/f71863fg/superio.c | 2 +-
+ src/superio/fintek/f71869ad/superio.c | 2 +-
+ src/superio/fintek/f71872/superio.c | 2 +-
+ src/superio/fintek/f81865f/superio.c | 2 +-
+ src/superio/fintek/f81866d/superio.c | 2 +-
+ src/superio/ite/it8671f/superio.c | 2 +-
+ src/superio/ite/it8712f/superio.c | 2 +-
+ src/superio/ite/it8716f/superio.c | 2 +-
+ src/superio/ite/it8718f/superio.c | 2 +-
+ src/superio/ite/it8721f/superio.c | 2 +-
+ src/superio/ite/it8728f/superio.c | 2 +-
+ src/superio/ite/it8772f/superio.c | 2 +-
+ src/superio/nsc/pc87309/superio.c | 2 +-
+ src/superio/nsc/pc87360/superio.c | 2 +-
+ src/superio/nsc/pc87366/superio.c | 2 +-
+ src/superio/nsc/pc87417/superio.c | 2 +-
+ src/superio/nsc/pc97317/superio.c | 2 +-
+ src/superio/nuvoton/nct5572d/superio.c | 2 +-
+ src/superio/nuvoton/nct6779d/superio.c | 2 +-
+ src/superio/nuvoton/wpcm450/superio.c | 2 +-
+ src/superio/renesas/m3885x/superio.c | 2 +-
+ src/superio/smsc/dme1737/superio.c | 2 +-
+ src/superio/smsc/fdc37n972/fdc37n972.c | 2 +-
+ src/superio/smsc/kbc1100/superio.c | 2 +-
+ src/superio/smsc/lpc47b272/superio.c | 2 +-
+ src/superio/smsc/lpc47b397/superio.c | 2 +-
+ src/superio/smsc/lpc47m10x/superio.c | 2 +-
+ src/superio/smsc/lpc47m15x/superio.c | 2 +-
+ src/superio/smsc/lpc47n227/superio.c | 2 +-
+ src/superio/smsc/mec1308/superio.c | 2 +-
+ src/superio/smsc/sch4037/superio.c | 2 +-
+ src/superio/smsc/sio10n268/sio10n268.c | 2 +-
+ src/superio/smsc/smscsuperio/superio.c | 2 +-
+ src/superio/winbond/w83627dhg/superio.c | 2 +-
+ src/superio/winbond/w83627ehg/superio.c | 2 +-
+ src/superio/winbond/w83627hf/superio.c | 2 +-
+ src/superio/winbond/w83627thg/superio.c | 2 +-
+ src/superio/winbond/w83627uhg/superio.c | 2 +-
+ src/superio/winbond/w83667hg-a/ps2_controller.asl | 78 +++++++++++++++++
+ src/superio/winbond/w83667hg-a/superio.c | 20 ++++-
+ src/superio/winbond/w83977tf/superio.c | 2 +-
+ src/superio/winbond/wpcd376i/superio.c | 2 +-
+ 58 files changed, 230 insertions(+), 79 deletions(-)
+ create mode 100644 src/superio/winbond/w83667hg-a/ps2_controller.asl
+
+diff --git a/src/drivers/pc80/keyboard.c b/src/drivers/pc80/keyboard.c
+index 3e61a51..56b1fce 100644
+--- a/src/drivers/pc80/keyboard.c
++++ b/src/drivers/pc80/keyboard.c
+@@ -1,6 +1,7 @@
+ /*
+ * This file is part of the coreboot project.
+ *
++ * Copyright (C) 2015 Raptor Engineering
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2003 Ollie Lo <ollielo@hotmail.com>
+@@ -32,6 +33,8 @@
+ // Keyboard Controller Commands
+ #define KBC_CMD_READ_COMMAND 0x20 // Read command byte
+ #define KBC_CMD_WRITE_COMMAND 0x60 // Write command byte
++#define KBC_CMD_AUX_ENABLE 0xA8 // Auxiliary Interface enable
++#define KBC_CMD_AUX_TEST 0xA9 // Auxiliary Interface test
+ #define KBC_CMD_SELF_TEST 0xAA // Controller self-test
+ #define KBC_CMD_KBD_TEST 0xAB // Keyboard Interface test
+
+@@ -106,9 +109,14 @@ static int kbc_cleanup_buffers(void)
+ return !!timeout;
+ }
+
+-static enum cb_err kbc_self_test(void)
++static enum cb_err kbc_self_test(uint8_t probe_aux, uint8_t *aux_probe_result)
+ {
+- u8 self_test;
++ uint8_t self_test;
++ uint8_t byte;
++
++ /* Set initial aux probe output value */
++ if (aux_probe_result)
++ *aux_probe_result = 0;
+
+ /* Clean up any junk that might have been in the KBC.
+ * Both input and output buffers must be empty.
+@@ -154,6 +162,48 @@ static enum cb_err kbc_self_test(void)
+ return CB_KBD_INTERFACE_FAILURE;
+ }
+
++ if (probe_aux) {
++ /* aux interface detect */
++ outb(KBC_CMD_AUX_ENABLE, KBD_COMMAND);
++ if (!kbc_input_buffer_empty()) {
++ printk(BIOS_ERR, "Timeout waiting for controller during aux enable.\n");
++ return CB_KBD_CONTROLLER_FAILURE;
++ }
++ outb(KBC_CMD_READ_COMMAND, KBD_COMMAND);
++ if (!kbc_output_buffer_full()) {
++ printk(BIOS_ERR, "Timeout waiting for controller during aux probe.\n");
++ return CB_KBD_CONTROLLER_FAILURE;
++ }
++
++ byte = inb(KBD_DATA);
++ if (!(byte & (0x1 << 5))) {
++ printk(BIOS_DEBUG, "PS/2 auxiliary channel detected...\n");
++
++ /* auxiliary interface test */
++ outb(KBC_CMD_AUX_TEST, KBD_COMMAND);
++
++ if (!kbc_output_buffer_full()) {
++ printk(BIOS_ERR, "Auxiliary channel probe timed out.\n");
++ goto aux_failure;
++ }
++
++ /* read test result, 0x00 should be returned in case of no failures */
++ self_test = inb(KBD_DATA);
++
++ if (self_test != 0x00) {
++ printk(BIOS_ERR, "No device detected on auxiliary channel: 0x%x\n",
++ self_test);
++ goto aux_failure;
++ }
++
++ printk(BIOS_DEBUG, "PS/2 device detected on auxiliary channel\n");
++ if (aux_probe_result)
++ *aux_probe_result = 1;
++ }
++ }
++
++aux_failure:
++
+ return CB_SUCCESS;
+ }
+
+@@ -187,53 +237,54 @@ static u8 send_keyboard(u8 command)
+ return regval;
+ }
+
+-void pc_keyboard_init(void)
++uint8_t pc_keyboard_init(uint8_t probe_aux)
+ {
+ u8 retries;
+ u8 regval;
+ enum cb_err err;
++ uint8_t aux_dev_detected;
+
+ if (!CONFIG_DRIVERS_PS2_KEYBOARD)
+- return;
++ return 0;
+
+ if (acpi_is_wakeup_s3())
+- return;
++ return 0;
+
+ printk(BIOS_DEBUG, "Keyboard init...\n");
+
+ /* Run a keyboard controller self-test */
+- err = kbc_self_test();
++ err = kbc_self_test(probe_aux, &aux_dev_detected);
+ /* Ignore iterface failure as it's non-fatal. */
+ if (err != CB_SUCCESS && err != CB_KBD_INTERFACE_FAILURE)
+- return;
++ return 0;
+
+ /* Enable keyboard interface - No IRQ */
+ if (!kbc_input_buffer_empty())
+- return;
++ return 0;
+ outb(0x60, KBD_COMMAND);
+ if (!kbc_input_buffer_empty())
+- return;
++ return 0;
+ outb(0x20, KBD_DATA); /* send cmd: enable keyboard */
+ if (!kbc_input_buffer_empty()) {
+ printk(BIOS_INFO, "Timeout while enabling keyboard\n");
+- return;
++ return 0;
+ }
+
+ /* clean up any junk that might have been in the keyboard */
+ if (!kbc_cleanup_buffers())
+- return;
++ return 0;
+
+ /* reset keyboard and self test (keyboard side) */
+ regval = send_keyboard(0xFF);
+ if (regval == KBD_REPLY_RESEND) {
+ /* keeps sending RESENDs, probably no keyboard. */
+ printk(BIOS_INFO, "No PS/2 keyboard detected.\n");
+- return;
++ return 0;
+ }
+
+ if (regval != KBD_REPLY_ACK) {
+ printk(BIOS_ERR, "Keyboard reset failed ACK: 0x%x\n", regval);
+- return;
++ return 0;
+ }
+
+ /* the reset command takes some time, so wait a little longer */
+@@ -241,14 +292,14 @@ void pc_keyboard_init(void)
+
+ if (!kbc_output_buffer_full()) {
+ printk(BIOS_ERR, "Timeout waiting for keyboard after reset.\n");
+- return;
++ return 0;
+ }
+
+ regval = inb(KBD_DATA);
+ if (regval != 0xAA) {
+ printk(BIOS_ERR, "Keyboard reset selftest failed: 0x%x\n",
+ regval);
+- return;
++ return 0;
+ }
+
+ /*
+@@ -260,7 +311,7 @@ void pc_keyboard_init(void)
+ regval = send_keyboard(0xF5);
+ if (regval != KBD_REPLY_ACK) {
+ printk(BIOS_ERR, "Keyboard disable failed ACK: 0x%x\n", regval);
+- return;
++ return 0;
+ }
+
+ /* Set scancode command */
+@@ -268,34 +319,38 @@ void pc_keyboard_init(void)
+ if (regval != KBD_REPLY_ACK) {
+ printk(BIOS_ERR, "Keyboard set scancode cmd failed ACK: 0x%x\n",
+ regval);
+- return;
++ return 0;
+ }
+ /* Set scancode mode 2 */
+ regval = send_keyboard(0x02);
+ if (regval != KBD_REPLY_ACK) {
+ printk(BIOS_ERR,
+ "Keyboard set scancode mode failed ACK: 0x%x\n", regval);
+- return;
++ return 0;
+ }
+
+ /* All is well - enable keyboard interface */
+ if (!kbc_input_buffer_empty())
+- return;
++ return 0;
+ outb(0x60, KBD_COMMAND);
+ if (!kbc_input_buffer_empty())
+- return;
++ return 0;
+ outb(0x65, KBD_DATA); /* send cmd: enable keyboard and IRQ 1 */
+ if (!kbc_input_buffer_empty()) {
+ printk(BIOS_ERR, "Timeout during keyboard enable\n");
+- return;
++ return 0;
+ }
+
+ /* enable the keyboard */
+ regval = send_keyboard(0xF4);
+ if (regval != KBD_REPLY_ACK) {
+ printk(BIOS_ERR, "Keyboard enable failed ACK: 0x%x\n", regval);
+- return;
++ return 0;
+ }
++
++ printk(BIOS_DEBUG, "PS/2 keyboard initialized on primary channel\n");
++
++ return aux_dev_detected;
+ }
+
+ /*
+@@ -308,7 +363,7 @@ void set_kbc_ps2_mode(void)
+ enum cb_err err;
+
+ /* Run a keyboard controller self-test */
+- err = kbc_self_test();
++ err = kbc_self_test(0, NULL);
+ /* Ignore iterface failure as it's non-fatal. */
+ if (err != CB_SUCCESS && err != CB_KBD_INTERFACE_FAILURE)
+ return;
+diff --git a/src/ec/compal/ene932/ec.c b/src/ec/compal/ene932/ec.c
+index d1687e9..50b8b5e 100644
+--- a/src/ec/compal/ene932/ec.c
++++ b/src/ec/compal/ene932/ec.c
+@@ -133,7 +133,7 @@ static void ene932_init(struct device *dev)
+ return;
+
+ printk(BIOS_DEBUG, "Compal ENE932: Initializing keyboard.\n");
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+
+ }
+
+diff --git a/src/ec/google/chromeec/ec_lpc.c b/src/ec/google/chromeec/ec_lpc.c
+index 9a16906..8a04135 100644
+--- a/src/ec/google/chromeec/ec_lpc.c
++++ b/src/ec/google/chromeec/ec_lpc.c
+@@ -403,7 +403,7 @@ static void lpc_ec_init(struct device *dev)
+ if (!dev->enabled)
+ return;
+
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ google_chromeec_init();
+ }
+
+diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c
+index 3cd30bc..f0ccd48 100644
+--- a/src/ec/lenovo/h8/h8.c
++++ b/src/ec/lenovo/h8/h8.c
+@@ -175,7 +175,7 @@ static void h8_smbios_strings(struct device *dev, struct smbios_type11 *t)
+
+ static void h8_init(device_t dev)
+ {
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ struct device_operations h8_dev_ops = {
+diff --git a/src/ec/quanta/ene_kb3940q/ec.c b/src/ec/quanta/ene_kb3940q/ec.c
+index 8f23e33..a7d5bd7 100644
+--- a/src/ec/quanta/ene_kb3940q/ec.c
++++ b/src/ec/quanta/ene_kb3940q/ec.c
+@@ -142,7 +142,7 @@ static void ene_kb3940q_init(struct device *dev)
+ return;
+
+ printk(BIOS_DEBUG, "Quanta EnE KB3940Q: Initializing keyboard.\n");
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+
+ ene_kb3940q_log_events();
+ }
+diff --git a/src/ec/quanta/it8518/ec.c b/src/ec/quanta/it8518/ec.c
+index 7388c01..dd7268a 100644
+--- a/src/ec/quanta/it8518/ec.c
++++ b/src/ec/quanta/it8518/ec.c
+@@ -157,7 +157,7 @@ static void it8518_init(struct device *dev)
+ return;
+
+ printk(BIOS_DEBUG, "Quanta IT8518: Initializing keyboard.\n");
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ static struct device_operations ops = {
+diff --git a/src/include/pc80/keyboard.h b/src/include/pc80/keyboard.h
+index 16cb959..5258d47 100644
+--- a/src/include/pc80/keyboard.h
++++ b/src/include/pc80/keyboard.h
+@@ -1,7 +1,7 @@
+ #ifndef PC80_KEYBOARD_H
+ #define PC80_KEYBOARD_H
+
+-void pc_keyboard_init(void);
++uint8_t pc_keyboard_init(uint8_t probe_aux);
+ void set_kbc_ps2_mode(void);
+
+ #endif /* PC80_KEYBOARD_H */
+diff --git a/src/mainboard/emulation/qemu-i440fx/mainboard.c b/src/mainboard/emulation/qemu-i440fx/mainboard.c
+index b2fb46c..e5fb3cb 100644
+--- a/src/mainboard/emulation/qemu-i440fx/mainboard.c
++++ b/src/mainboard/emulation/qemu-i440fx/mainboard.c
+@@ -39,7 +39,7 @@ static void qemu_nb_init(device_t dev)
+ /* This sneaked in here, because Qemu does not
+ * emulate a SuperIO chip
+ */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+
+ /* setup IRQ routing */
+ for (i = 0; i < 32; i++)
+diff --git a/src/mainboard/emulation/qemu-q35/mainboard.c b/src/mainboard/emulation/qemu-q35/mainboard.c
+index 82716c9..0000564 100644
+--- a/src/mainboard/emulation/qemu-q35/mainboard.c
++++ b/src/mainboard/emulation/qemu-q35/mainboard.c
+@@ -60,7 +60,7 @@ static void qemu_nb_init(device_t dev)
+ /* This sneaked in here, because Qemu does not
+ * emulate a SuperIO chip
+ */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+
+ /* setup IRQ routing for pci slots */
+ for (i = 0; i < 25; i++)
+diff --git a/src/mainboard/packardbell/ms2290/mainboard.c b/src/mainboard/packardbell/ms2290/mainboard.c
+index 065ca94..f964c57 100644
+--- a/src/mainboard/packardbell/ms2290/mainboard.c
++++ b/src/mainboard/packardbell/ms2290/mainboard.c
+@@ -121,7 +121,7 @@ static void mainboard_enable(device_t dev)
+
+ /* This sneaked in here, because EasyNote has no SuperIO chip.
+ */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ struct chip_operations mainboard_ops = {
+diff --git a/src/mainboard/roda/rk9/mainboard.c b/src/mainboard/roda/rk9/mainboard.c
+index a5465f9..50e9a75 100644
+--- a/src/mainboard/roda/rk9/mainboard.c
++++ b/src/mainboard/roda/rk9/mainboard.c
+@@ -46,7 +46,7 @@ static void mainboard_enable(device_t dev)
+
+ /* We have no driver for the embedded controller since the firmware
+ does most of the job. Hence, initialize keyboards here. */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ struct chip_operations mainboard_ops = {
+diff --git a/src/northbridge/via/cx700/lpc.c b/src/northbridge/via/cx700/lpc.c
+index 9262e40..e19f638 100644
+--- a/src/northbridge/via/cx700/lpc.c
++++ b/src/northbridge/via/cx700/lpc.c
+@@ -285,7 +285,7 @@ static void cx700_lpc_init(struct device *dev)
+ isa_dma_init();
+
+ /* Initialize keyboard controller */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ static struct device_operations cx700_lpc_ops = {
+diff --git a/src/northbridge/via/vx800/lpc.c b/src/northbridge/via/vx800/lpc.c
+index 8fbb3be..1bdd7b8 100644
+--- a/src/northbridge/via/vx800/lpc.c
++++ b/src/northbridge/via/vx800/lpc.c
+@@ -322,7 +322,7 @@ static void southbridge_init(struct device *dev)
+ setup_i8259(); // make sure interupt controller is configured before keyboard init
+
+ /* turn on keyboard and RTC, no need to visit this reg twice */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+
+ printk(BIOS_DEBUG, "ps2 usb lid, you set who can wakeup system from s3 sleep\n");
+ S3_ps2_kb_ms_wakeup(dev);
+diff --git a/src/southbridge/dmp/vortex86ex/southbridge.c b/src/southbridge/dmp/vortex86ex/southbridge.c
+index 3ef6a5d..5da7d74 100644
+--- a/src/southbridge/dmp/vortex86ex/southbridge.c
++++ b/src/southbridge/dmp/vortex86ex/southbridge.c
+@@ -607,7 +607,7 @@ static void southbridge_init(struct device *dev)
+ retries--;
+ }
+ post_code(POST_DMP_KBD_IS_READY);
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ static struct device_operations vortex_sb_ops = {
+diff --git a/src/southbridge/sis/sis966/lpc.c b/src/southbridge/sis/sis966/lpc.c
+index 940844b..c40df0a 100644
+--- a/src/southbridge/sis/sis966/lpc.c
++++ b/src/southbridge/sis/sis966/lpc.c
+@@ -91,7 +91,7 @@ static void lpc_init(device_t dev)
+ int nmi_option;
+
+ printk(BIOS_DEBUG, "LPC_INIT -------->\n");
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+
+ lpc_usb_legacy_init(dev);
+ lpc_common_init(dev);
+diff --git a/src/southbridge/via/vt8237r/lpc.c b/src/southbridge/via/vt8237r/lpc.c
+index b54d494..113ce93 100644
+--- a/src/southbridge/via/vt8237r/lpc.c
++++ b/src/southbridge/via/vt8237r/lpc.c
+@@ -625,7 +625,7 @@ static void init_keyboard(struct device *dev)
+ {
+ u8 regval = pci_read_config8(dev, 0x51);
+ if (regval & 0x1)
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+
+ static void southbridge_init_common(struct device *dev)
+diff --git a/src/superio/fintek/f71863fg/superio.c b/src/superio/fintek/f71863fg/superio.c
+index 8e0a643..bb09d01 100644
+--- a/src/superio/fintek/f71863fg/superio.c
++++ b/src/superio/fintek/f71863fg/superio.c
+@@ -34,7 +34,7 @@ static void f71863fg_init(struct device *dev)
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case F71863FG_KBC:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/fintek/f71869ad/superio.c b/src/superio/fintek/f71869ad/superio.c
+index f16c37f..8cf9008 100644
+--- a/src/superio/fintek/f71869ad/superio.c
++++ b/src/superio/fintek/f71869ad/superio.c
+@@ -34,7 +34,7 @@ static void f71869ad_init(struct device *dev)
+ switch(dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case F71869AD_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case F71869AD_HWM:
+ f71869ad_multifunc_init(dev);
+diff --git a/src/superio/fintek/f71872/superio.c b/src/superio/fintek/f71872/superio.c
+index 6b4de2d..a973da8 100644
+--- a/src/superio/fintek/f71872/superio.c
++++ b/src/superio/fintek/f71872/superio.c
+@@ -32,7 +32,7 @@ static void f71872_init(struct device *dev)
+ switch(dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case F71872_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/fintek/f81865f/superio.c b/src/superio/fintek/f81865f/superio.c
+index 9cd5c95..fa9e23e 100644
+--- a/src/superio/fintek/f81865f/superio.c
++++ b/src/superio/fintek/f81865f/superio.c
+@@ -32,7 +32,7 @@ static void f81865f_init(struct device *dev)
+ switch (dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case F81865F_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/fintek/f81866d/superio.c b/src/superio/fintek/f81866d/superio.c
+index ce0e066..2a95219 100644
+--- a/src/superio/fintek/f81866d/superio.c
++++ b/src/superio/fintek/f81866d/superio.c
+@@ -34,7 +34,7 @@ static void f81866d_init(struct device *dev)
+ switch (dev->path.pnp.device) {
+ /* TODO: Might potentially need extra code for serial, wdt etc. */
+ case F81866D_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case F81866D_HWM:
+ // Fixing temp sensor read out and init Fan control
+diff --git a/src/superio/ite/it8671f/superio.c b/src/superio/ite/it8671f/superio.c
+index 72e31f1..907e020 100644
+--- a/src/superio/ite/it8671f/superio.c
++++ b/src/superio/ite/it8671f/superio.c
+@@ -32,7 +32,7 @@ static void init(struct device *dev)
+ case IT8671F_PP: /* TODO. */
+ break;
+ case IT8671F_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case IT8671F_KBCM: /* TODO. */
+ break;
+diff --git a/src/superio/ite/it8712f/superio.c b/src/superio/ite/it8712f/superio.c
+index 02cbefc..1d87f47 100644
+--- a/src/superio/ite/it8712f/superio.c
++++ b/src/superio/ite/it8712f/superio.c
+@@ -39,7 +39,7 @@ static void it8712f_init(struct device *dev)
+ break;
+ case IT8712F_KBCK:
+ set_kbc_ps2_mode();
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case IT8712F_KBCM: /* TODO. */
+ break;
+diff --git a/src/superio/ite/it8716f/superio.c b/src/superio/ite/it8716f/superio.c
+index 3a9e790..469c255 100644
+--- a/src/superio/ite/it8716f/superio.c
++++ b/src/superio/ite/it8716f/superio.c
+@@ -60,7 +60,7 @@ static void it8716f_init(struct device *dev)
+ init_ec(res0->base + EC_INDEX_PORT);
+ break;
+ case IT8716F_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/ite/it8718f/superio.c b/src/superio/ite/it8718f/superio.c
+index ccef043..825fb53 100644
+--- a/src/superio/ite/it8718f/superio.c
++++ b/src/superio/ite/it8718f/superio.c
+@@ -34,7 +34,7 @@ static void init(struct device *dev)
+ case IT8718F_EC: /* TODO. */
+ break;
+ case IT8718F_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case IT8718F_KBCM: /* TODO. */
+ break;
+diff --git a/src/superio/ite/it8721f/superio.c b/src/superio/ite/it8721f/superio.c
+index 4fc0562..ae052a3 100644
+--- a/src/superio/ite/it8721f/superio.c
++++ b/src/superio/ite/it8721f/superio.c
+@@ -35,7 +35,7 @@ static void init(struct device *dev)
+ case IT8721F_EC: /* TODO. */
+ break;
+ case IT8721F_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case IT8721F_KBCM: /* TODO. */
+ break;
+diff --git a/src/superio/ite/it8728f/superio.c b/src/superio/ite/it8728f/superio.c
+index 4591bb1..3849d63 100644
+--- a/src/superio/ite/it8728f/superio.c
++++ b/src/superio/ite/it8728f/superio.c
+@@ -38,7 +38,7 @@ static void it8728f_init(struct device *dev)
+ break;
+ case IT8728F_KBCK:
+ set_kbc_ps2_mode();
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/ite/it8772f/superio.c b/src/superio/ite/it8772f/superio.c
+index 6c6a503..17145b8 100644
+--- a/src/superio/ite/it8772f/superio.c
++++ b/src/superio/ite/it8772f/superio.c
+@@ -196,7 +196,7 @@ static void it8772f_init(struct device *dev)
+ case IT8772F_KBCK:
+ if (!conf->skip_keyboard) {
+ set_kbc_ps2_mode();
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+ break;
+ case IT8772F_KBCM:
+diff --git a/src/superio/nsc/pc87309/superio.c b/src/superio/nsc/pc87309/superio.c
+index ecda1e7..f22566c 100644
+--- a/src/superio/nsc/pc87309/superio.c
++++ b/src/superio/nsc/pc87309/superio.c
+@@ -29,7 +29,7 @@ static void init(struct device *dev)
+
+ switch (dev->path.pnp.device) {
+ case PC87309_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/nsc/pc87360/superio.c b/src/superio/nsc/pc87360/superio.c
+index 6b6e790..248c793 100644
+--- a/src/superio/nsc/pc87360/superio.c
++++ b/src/superio/nsc/pc87360/superio.c
+@@ -31,7 +31,7 @@ static void init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case PC87360_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/nsc/pc87366/superio.c b/src/superio/nsc/pc87366/superio.c
+index f9dca21..e5c8ac2 100644
+--- a/src/superio/nsc/pc87366/superio.c
++++ b/src/superio/nsc/pc87366/superio.c
+@@ -31,7 +31,7 @@ static void init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case PC87366_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/nsc/pc87417/superio.c b/src/superio/nsc/pc87417/superio.c
+index 1855db9..7a8d76f 100644
+--- a/src/superio/nsc/pc87417/superio.c
++++ b/src/superio/nsc/pc87417/superio.c
+@@ -32,7 +32,7 @@ static void init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case PC87417_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/nsc/pc97317/superio.c b/src/superio/nsc/pc97317/superio.c
+index e8cf842..983c7f1 100644
+--- a/src/superio/nsc/pc97317/superio.c
++++ b/src/superio/nsc/pc97317/superio.c
+@@ -33,7 +33,7 @@ static void init(struct device *dev)
+ pnp_set_enable(dev, 0); /* Disable keyboard */
+ pnp_write_config(dev, 0xf0, 0x40); /* Set KBC clock to 8 MHz. */
+ pnp_set_enable(dev, 1); /* Enable keyboard */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ default:
+ break;
+diff --git a/src/superio/nuvoton/nct5572d/superio.c b/src/superio/nuvoton/nct5572d/superio.c
+index 81a8326..6b5febd 100644
+--- a/src/superio/nuvoton/nct5572d/superio.c
++++ b/src/superio/nuvoton/nct5572d/superio.c
+@@ -45,7 +45,7 @@ static void nct5572d_init(struct device *dev)
+ switch(dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case NCT5572D_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case NCT5572D_ACPI:
+ /* Set power state after power fail */
+diff --git a/src/superio/nuvoton/nct6779d/superio.c b/src/superio/nuvoton/nct6779d/superio.c
+index 79a25b7..c16a736 100644
+--- a/src/superio/nuvoton/nct6779d/superio.c
++++ b/src/superio/nuvoton/nct6779d/superio.c
+@@ -39,7 +39,7 @@ static void nct6779d_init(struct device *dev)
+ switch(dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case NCT6779D_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/nuvoton/wpcm450/superio.c b/src/superio/nuvoton/wpcm450/superio.c
+index bfc3c5e..c6cb494 100644
+--- a/src/superio/nuvoton/wpcm450/superio.c
++++ b/src/superio/nuvoton/wpcm450/superio.c
+@@ -31,7 +31,7 @@ static void init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case WPCM450_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/renesas/m3885x/superio.c b/src/superio/renesas/m3885x/superio.c
+index 1f30bfe..84c014c 100644
+--- a/src/superio/renesas/m3885x/superio.c
++++ b/src/superio/renesas/m3885x/superio.c
+@@ -33,7 +33,7 @@ static void m3885x_init(struct device *dev)
+
+ printk(BIOS_DEBUG, "Renesas M3885x: Initializing keyboard.\n");
+ set_kbc_ps2_mode();
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ m3885_configure_multikey();
+ }
+
+diff --git a/src/superio/smsc/dme1737/superio.c b/src/superio/smsc/dme1737/superio.c
+index 23f2c7d..0e9bd4c 100644
+--- a/src/superio/smsc/dme1737/superio.c
++++ b/src/superio/smsc/dme1737/superio.c
+@@ -35,7 +35,7 @@ static void dme1737_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case DME1737_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/fdc37n972/fdc37n972.c b/src/superio/smsc/fdc37n972/fdc37n972.c
+index 0c6b517..cf94912 100644
+--- a/src/superio/smsc/fdc37n972/fdc37n972.c
++++ b/src/superio/smsc/fdc37n972/fdc37n972.c
+@@ -31,7 +31,7 @@ static void init(struct device *dev)
+ case FDC37N972_PP: /* TODO. */
+ break;
+ case FDC37N972_KBDC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ // [..] The rest: TODO
+ }
+diff --git a/src/superio/smsc/kbc1100/superio.c b/src/superio/smsc/kbc1100/superio.c
+index 81fb394..687691c 100644
+--- a/src/superio/smsc/kbc1100/superio.c
++++ b/src/superio/smsc/kbc1100/superio.c
+@@ -68,7 +68,7 @@ static void kbc1100_init(struct device *dev)
+ case KBC1100_KBC:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+ res1 = find_resource(dev, PNP_IDX_IO1);
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/lpc47b272/superio.c b/src/superio/smsc/lpc47b272/superio.c
+index 6cc4823..e8d4741 100644
+--- a/src/superio/smsc/lpc47b272/superio.c
++++ b/src/superio/smsc/lpc47b272/superio.c
+@@ -46,7 +46,7 @@ static void lpc47b272_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case LPC47B272_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/lpc47b397/superio.c b/src/superio/smsc/lpc47b397/superio.c
+index 6270d92..76164b5 100644
+--- a/src/superio/smsc/lpc47b397/superio.c
++++ b/src/superio/smsc/lpc47b397/superio.c
+@@ -45,7 +45,7 @@ static void lpc47b397_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case LPC47B397_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/lpc47m10x/superio.c b/src/superio/smsc/lpc47m10x/superio.c
+index c3c7feb..bcde524 100644
+--- a/src/superio/smsc/lpc47m10x/superio.c
++++ b/src/superio/smsc/lpc47m10x/superio.c
+@@ -44,7 +44,7 @@ static void lpc47m10x_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case LPC47M10X2_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/lpc47m15x/superio.c b/src/superio/smsc/lpc47m15x/superio.c
+index 166f383..6736621 100644
+--- a/src/superio/smsc/lpc47m15x/superio.c
++++ b/src/superio/smsc/lpc47m15x/superio.c
+@@ -66,7 +66,7 @@ static void lpc47m15x_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case LPC47M15X_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/lpc47n227/superio.c b/src/superio/smsc/lpc47n227/superio.c
+index 3885ef3..a5e33fa 100644
+--- a/src/superio/smsc/lpc47n227/superio.c
++++ b/src/superio/smsc/lpc47n227/superio.c
+@@ -131,7 +131,7 @@ static void lpc47n227_init(struct device *dev)
+ switch (dev->path.pnp.device) {
+ case LPC47N227_KBDC:
+ printk(BIOS_DEBUG, "LPC47N227: Initializing keyboard.\n");
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/mec1308/superio.c b/src/superio/smsc/mec1308/superio.c
+index 2beeec6..aa3d012 100644
+--- a/src/superio/smsc/mec1308/superio.c
++++ b/src/superio/smsc/mec1308/superio.c
+@@ -34,7 +34,7 @@ static void mec1308_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case MEC1308_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/sch4037/superio.c b/src/superio/smsc/sch4037/superio.c
+index 0f09914..4906aa2 100644
+--- a/src/superio/smsc/sch4037/superio.c
++++ b/src/superio/smsc/sch4037/superio.c
+@@ -33,7 +33,7 @@ static void sch4037_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case SCH4037_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/smsc/sio10n268/sio10n268.c b/src/superio/smsc/sio10n268/sio10n268.c
+index 5892f0c..e0b0d99 100644
+--- a/src/superio/smsc/sio10n268/sio10n268.c
++++ b/src/superio/smsc/sio10n268/sio10n268.c
+@@ -31,7 +31,7 @@ static void init(struct device *dev)
+ break;
+ case SIO10N268_KBDC:
+ /* TODO: This is still hardcoded. */
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ // [..] The rest: TODO
+ }
+diff --git a/src/superio/smsc/smscsuperio/superio.c b/src/superio/smsc/smscsuperio/superio.c
+index b3238de..fec8157 100644
+--- a/src/superio/smsc/smscsuperio/superio.c
++++ b/src/superio/smsc/smscsuperio/superio.c
+@@ -163,7 +163,7 @@ static void smsc_init(struct device *dev)
+ /* A Super I/O was found, so initialize the respective device. */
+ ld = dev->path.pnp.device;
+ if (ld == logical_device_table[i].devs[LD_KBC]) {
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ }
+ }
+
+diff --git a/src/superio/winbond/w83627dhg/superio.c b/src/superio/winbond/w83627dhg/superio.c
+index 10dba59..ddda25e 100644
+--- a/src/superio/winbond/w83627dhg/superio.c
++++ b/src/superio/winbond/w83627dhg/superio.c
+@@ -43,7 +43,7 @@ static void w83627dhg_init(struct device *dev)
+ w83627dhg_enable_UR2(dev);
+ break;
+ case W83627DHG_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/winbond/w83627ehg/superio.c b/src/superio/winbond/w83627ehg/superio.c
+index ea7a982..1060059 100644
+--- a/src/superio/winbond/w83627ehg/superio.c
++++ b/src/superio/winbond/w83627ehg/superio.c
+@@ -85,7 +85,7 @@ static void w83627ehg_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case W83627EHG_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case W83627EHG_HWM:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+diff --git a/src/superio/winbond/w83627hf/superio.c b/src/superio/winbond/w83627hf/superio.c
+index fe250a1..2402ae0 100644
+--- a/src/superio/winbond/w83627hf/superio.c
++++ b/src/superio/winbond/w83627hf/superio.c
+@@ -92,7 +92,7 @@ static void w83627hf_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case W83627HF_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ case W83627HF_HWM:
+ res0 = find_resource(dev, PNP_IDX_IO0);
+diff --git a/src/superio/winbond/w83627thg/superio.c b/src/superio/winbond/w83627thg/superio.c
+index f42f948..da9bab2 100644
+--- a/src/superio/winbond/w83627thg/superio.c
++++ b/src/superio/winbond/w83627thg/superio.c
+@@ -33,7 +33,7 @@ static void w83627thg_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case W83627THG_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/winbond/w83627uhg/superio.c b/src/superio/winbond/w83627uhg/superio.c
+index 5192c32..d0e443c 100644
+--- a/src/superio/winbond/w83627uhg/superio.c
++++ b/src/superio/winbond/w83627uhg/superio.c
+@@ -79,7 +79,7 @@ static void w83627uhg_init(struct device *dev)
+ set_uart_clock_source(dev, 0);
+ break;
+ case W83627UHG_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/winbond/w83667hg-a/ps2_controller.asl b/src/superio/winbond/w83667hg-a/ps2_controller.asl
+new file mode 100644
+index 0000000..c3b5c75
+--- /dev/null
++++ b/src/superio/winbond/w83667hg-a/ps2_controller.asl
+@@ -0,0 +1,78 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (c) 2013 Vladimir Serbinenko
++ * Copyright (c) 2015 Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; version 2 of
++ * the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++ /* SuperIO control port */
++ Name (SPIO, 0x2E)
++
++ /* SuperIO control map */
++ OperationRegion (SPIM, SystemIO, SPIO, 0x02)
++ Field (SPIM, ByteAcc, NoLock, Preserve) {
++ SIOI, 8,
++ SIOD, 8
++ }
++
++ /* SuperIO control registers */
++ IndexField (SIOI, SIOD, ByteAcc, NoLock, Preserve) {
++ Offset (0x2A),
++ CR2A, 8, /* Pin function selection */
++ }
++
++ Device (PS2K) // Keyboard
++ {
++ Name(_HID, EISAID("PNP0303"))
++ Name(_CID, EISAID("PNP030B"))
++
++ Name(_CRS, ResourceTemplate()
++ {
++ IO (Decode16, 0x60, 0x60, 0x01, 0x01)
++ IO (Decode16, 0x64, 0x64, 0x01, 0x01)
++ IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1
++ })
++
++ Method (_STA, 0)
++ {
++ Return (0xf)
++ }
++ }
++
++ Device (PS2M) // Mouse
++ {
++ Name(_HID, EISAID("PNP0F13"))
++ Name(_CRS, ResourceTemplate()
++ {
++ IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12
++ })
++
++ Method(_STA, 0)
++ {
++ /* Access SuperIO ACPI device */
++ Store(0x87, SIOI)
++ Store(0x87, SIOI)
++
++ /* Read Pin56 function select */
++ And(CR2A, 0x2, Local0)
++
++ /* Restore default SuperIO access */
++ Store(0xAA, SIOI)
++
++ if (LEqual(Local0, 0x0)) {
++ /* Mouse function selected */
++ Return (0xf)
++ }
++ Return (0x0)
++ }
++ }
+diff --git a/src/superio/winbond/w83667hg-a/superio.c b/src/superio/winbond/w83667hg-a/superio.c
+index b539871..d6f2ee5 100644
+--- a/src/superio/winbond/w83667hg-a/superio.c
++++ b/src/superio/winbond/w83667hg-a/superio.c
+@@ -23,6 +23,7 @@
+ #include <pc80/keyboard.h>
+ #include <pc80/mc146818rtc.h>
+ #include <stdlib.h>
++#include <arch/acpi.h>
+ #include <superio/conf_mode.h>
+
+ #include "w83667hg-a.h"
+@@ -38,6 +39,7 @@ static void w83667hg_a_init(struct device *dev)
+ {
+ uint8_t byte;
+ uint8_t power_status;
++ uint8_t mouse_detected;
+
+ if (!dev->enabled)
+ return;
+@@ -45,7 +47,23 @@ static void w83667hg_a_init(struct device *dev)
+ switch(dev->path.pnp.device) {
+ /* TODO: Might potentially need code for HWM or FDC etc. */
+ case W83667HG_A_KBC:
+- pc_keyboard_init();
++ /* Enable mouse controller */
++ pnp_enter_conf_mode_8787(dev);
++ byte = pnp_read_config(dev, 0x2a);
++ byte &= ~(0x1 << 1);
++ pnp_write_config(dev, 0x2a, byte);
++ pnp_exit_conf_mode_aa(dev);
++
++ mouse_detected = pc_keyboard_init(1);
++
++ if (!mouse_detected && !acpi_is_wakeup_s3()) {
++ /* Disable mouse controller */
++ pnp_enter_conf_mode_8787(dev);
++ byte = pnp_read_config(dev, 0x2a);
++ byte |= 0x1 << 1;
++ pnp_write_config(dev, 0x2a, byte);
++ pnp_exit_conf_mode_aa(dev);
++ }
+ break;
+ case W83667HG_A_ACPI:
+ /* Set power state after power fail */
+diff --git a/src/superio/winbond/w83977tf/superio.c b/src/superio/winbond/w83977tf/superio.c
+index f23d7c4..b4fe594 100644
+--- a/src/superio/winbond/w83977tf/superio.c
++++ b/src/superio/winbond/w83977tf/superio.c
+@@ -34,7 +34,7 @@ static void w83977tf_init(struct device *dev)
+
+ switch(dev->path.pnp.device) {
+ case W83977TF_KBC:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+diff --git a/src/superio/winbond/wpcd376i/superio.c b/src/superio/winbond/wpcd376i/superio.c
+index d54c4af..f2d520d 100644
+--- a/src/superio/winbond/wpcd376i/superio.c
++++ b/src/superio/winbond/wpcd376i/superio.c
+@@ -45,7 +45,7 @@ static void init(device_t dev)
+ break;
+
+ case WPCD376I_KBCK:
+- pc_keyboard_init();
++ pc_keyboard_init(0);
+ break;
+ }
+ }
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch
new file mode 100644
index 0000000..a4ecef8
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0034-mainboard-asus-kcma-d8-Use-W83667HG-A-specific-PS-2-.patch
@@ -0,0 +1,27 @@
+From 6f02a70d622a6834323a960eda887074543efe8a Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:01 -0600
+Subject: [PATCH 34/45] mainboard/asus/kcma-d8: Use W83667HG-A specific PS/2
+ ASL file
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/dsdt.asl | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/dsdt.asl b/src/mainboard/asus/kgpe-d16/dsdt.asl
+index 702ace1..5f9195a 100644
+--- a/src/mainboard/asus/kgpe-d16/dsdt.asl
++++ b/src/mainboard/asus/kgpe-d16/dsdt.asl
+@@ -562,7 +562,7 @@ DefinitionBlock (
+ })
+ }
+
+- #include "../../../drivers/pc80/ps2_controller.asl"
++ #include "../../../superio/winbond/w83667hg-a/ps2_controller.asl"
+
+ /* UART 1 */
+ Device (URT1)
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch
new file mode 100644
index 0000000..cbeb336
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0035-nb-amd-amdmct-mct_ddr3-Save-and-restore-SkewMemClk-f.patch
@@ -0,0 +1,63 @@
+From e90ac9c0e629f2f50f59203d4d91415b89354d2f Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:02 -0600
+Subject: [PATCH 35/45] nb/amd/amdmct/mct_ddr3: Save and restore SkewMemClk for
+ S3 resume
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 5 +++--
+ src/northbridge/amd/amdmct/mct_ddr3/s3utils.c | 6 ++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+index e7361ac..f953919 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+@@ -729,7 +729,7 @@ struct amd_s3_persistent_mct_channel_data {
+ uint32_t f3x5c;
+ uint32_t f3x60;
+
+- /* Family 15h-specific registers (90 dwords) */
++ /* Family 15h-specific registers (91 dwords) */
+ uint32_t f2x200;
+ uint32_t f2x204;
+ uint32_t f2x208;
+@@ -785,8 +785,9 @@ struct amd_s3_persistent_mct_channel_data {
+ uint32_t f2x9cx0d0fc231;
+ uint32_t f2x9cx0d0f0_0_f_31[9]; /* [lane] */
+ uint32_t f2x9cx0d0f8021;
++ uint32_t f2x9cx0d0fe00a;
+
+- /* TOTAL: 342 dwords */
++ /* TOTAL: 343 dwords */
+ } __attribute__((packed));
+
+ struct amd_s3_persistent_node_data {
+diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
+index ae2cca1..fe77075 100644
+--- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
++++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
+@@ -454,6 +454,9 @@ void copy_mct_data_to_save_variable(struct amd_s3_persistent_data* persistent_da
+ data->f2x9cx0d0f0_0_f_31[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0031 | (i << 8));
+
+ data->f2x9cx0d0f8021 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8021);
++
++ if (channel == 1)
++ data->f2x9cx0d0fe00a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe00a);
+ }
+
+ /* Stage 4 */
+@@ -796,6 +799,9 @@ void restore_mct_data_from_save_variable(struct amd_s3_persistent_data* persiste
+ write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0031 | (i << 8), data->f2x9cx0d0f0_0_f_31[i]);
+
+ write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8021, data->f2x9cx0d0f8021);
++
++ if (channel == 1)
++ write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe00a, data->f2x9cx0d0fe00a);
+ }
+ }
+ }
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch
new file mode 100644
index 0000000..ec82f70
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0036-cpu-amd-fam10h-fam15h-Add-new-wait_ap_stopped-functi.patch
@@ -0,0 +1,66 @@
+From 3b1c5530e745b77411f3a9db1872a8592ac79bf5 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:02 -0600
+Subject: [PATCH 36/45] cpu/amd/fam10h-fam15h: Add new wait_ap_stopped function
+
+Under certain conditions, such as when microcode updates are
+being performed, it is important to make sure all APs have
+finished updates and are halted before continuing with the
+boot process.
+
+Add a new wait_ap_stopped() function to allow for this
+functionality to be added to the appropriate mainboard
+romstage source files.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/init_cpus.c | 20 ++++++++++++++++++++
+ src/include/cpu/amd/multicore.h | 1 +
+ 2 files changed, 21 insertions(+)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+index e8e81d2..e2a1bf3 100644
+--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c
++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+@@ -299,6 +299,26 @@ void allow_all_aps_stop(u32 bsp_apicid)
+ lapic_write(LAPIC_MSG_REG, (bsp_apicid << 24) | F10_APSTATE_STOPPED);
+ }
+
++static void wait_ap_stopped(u32 ap_apicid, void *gp)
++{
++ u32 timeout;
++ timeout = wait_cpu_state(ap_apicid, F10_APSTATE_ASLEEP, F10_APSTATE_ASLEEP);
++ printk(BIOS_DEBUG, "* AP %02x", ap_apicid);
++ if (timeout) {
++ printk(BIOS_DEBUG, " timed out:%08x\n", timeout);
++ } else {
++ printk(BIOS_DEBUG, "stopped\n");
++ }
++}
++
++void wait_all_other_cores_stopped(u32 bsp_apicid)
++{
++ // all aps other than core0
++ printk(BIOS_DEBUG, "stopped ap apicid: ");
++ for_each_ap(bsp_apicid, 2, -1, wait_ap_stopped, (void *)0);
++ printk(BIOS_DEBUG, "\n");
++}
++
+ static void enable_apic_ext_id(u32 node)
+ {
+ u32 val;
+diff --git a/src/include/cpu/amd/multicore.h b/src/include/cpu/amd/multicore.h
+index b3a8237..0ddf866 100644
+--- a/src/include/cpu/amd/multicore.h
++++ b/src/include/cpu/amd/multicore.h
+@@ -35,6 +35,7 @@ void amd_sibling_init(struct device *cpu);
+ void wait_all_core0_started(void);
+ void wait_all_other_cores_started(u32 bsp_apicid);
+ void wait_all_aps_started(u32 bsp_apicid);
++void wait_all_other_cores_stopped(uint32_t bsp_apicid);
+ void allow_all_aps_stop(u32 bsp_apicid);
+ #endif
+ u32 get_initial_apicid(void);
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch
new file mode 100644
index 0000000..85df388
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0037-mainboard-asus-kgpe-d16-Wait-for-all-APs-to-stop-bef.patch
@@ -0,0 +1,34 @@
+From acb022efd422f1008e311863779cfb2395069bd6 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:03 -0600
+Subject: [PATCH 37/45] mainboard/asus/kgpe-d16: Wait for all APs to stop
+ before MCT setup
+
+Under certain conditions when the APs are still executing during
+MCT setup the system can hang. This was the root cause of most
+of the S3 resume failures on this platform; waiting for AP stop
+before MCT setup allows for reliable S3 resume.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/romstage.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c
+index 6fb7668..5df6de4 100644
+--- a/src/mainboard/asus/kgpe-d16/romstage.c
++++ b/src/mainboard/asus/kgpe-d16/romstage.c
+@@ -515,6 +515,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+
+ post_code(0x3B);
+
++ /* Wait for all APs to be stopped, otherwise ram initialization may hang */
++ if (IS_ENABLED(CONFIG_LOGICAL_CPUS))
++ wait_all_other_cores_stopped(bsp_apicid);
++
+ /* It's the time to set ctrl in sysinfo now; */
+ printk(BIOS_DEBUG, "fill_mem_ctrl() detected %d nodes\n", sysinfo->nodes);
+ if (is_fam15h())
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch
new file mode 100644
index 0000000..cde1ce5
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0038-cpu-amd-fam10h-15h-Add-workaround-for-AMD-Erratum-60.patch
@@ -0,0 +1,28 @@
+From 048d7a04e75fbc511838623916f4850897b29c5a Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:04 -0600
+Subject: [PATCH 38/45] cpu/amd/fam10h-15h: Add workaround for AMD Erratum 600
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/defaults.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/defaults.h b/src/cpu/amd/family_10h-family_15h/defaults.h
+index 3618cb8..d384eb3 100644
+--- a/src/cpu/amd/family_10h-family_15h/defaults.h
++++ b/src/cpu/amd/family_10h-family_15h/defaults.h
+@@ -270,6 +270,10 @@ static const struct {
+ ForceErrType = 0x0,
+ MultRetryErr = 0x0 */
+
++ /* Errata 600 */
++ { 0, 0x150, AMD_OR_B2, AMD_PTYPE_ALL,
++ 0x00000000, 0x00000e00 }, /* HtRetryCrcDatIns = 0x4 */
++
+ /* Errata 351
+ * System software should program the Link Extended Control Registers[LS2En]
+ * (F0x[18C:170][8]) to 0b for all links. System software should also
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch
new file mode 100644
index 0000000..8e036b3
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0039-mainboard-asus-kgpe-d16-Reenable-power-LED-after-S3-.patch
@@ -0,0 +1,39 @@
+From 79a5899dba0b5231c83614177e3e7287aa7167c4 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:06 -0600
+Subject: [PATCH 39/45] mainboard/asus/kgpe-d16: Reenable power LED after S3
+ resume
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl b/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl
+index c9bc0a9..a4d5b2a 100644
+--- a/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl
++++ b/src/mainboard/asus/kgpe-d16/acpi/pm_ctrl.asl
+@@ -218,7 +218,7 @@ Method(\_WAK, 1) {
+
+ /* Set up LEDs */
+ /* Set power LED to steady on */
+- Store(0x3, BLNK)
++ Store(0x0, BLNK)
+
+ /* Configure SuperIO for wake */
+ /* Access SuperIO ACPI device */
+@@ -290,11 +290,6 @@ Method(\_PTS, 1) {
+ /* Set suspend LED to 0.25Hz toggle pulse with 50% duty cycle */
+ Store(0x2, BLNK)
+ }
+- if (LEqual(Arg0, 0x3)) /* Power state S3 requested */
+- {
+- /* Set suspend LED to 0.25Hz toggle pulse with 25% duty cycle */
+- Store(0x1, BLNK)
+- }
+
+ /* Configure SuperIO for sleep */
+ /* Access SuperIO ACPI device */
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch
new file mode 100644
index 0000000..0559642
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0040-cpu-amd-fam10h-fam15h-Add-CMOS-option-to-disable-CPB.patch
@@ -0,0 +1,53 @@
+From 3efdfbd1def5dd2b3bd87ac9ff0bad83c2945eed Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:07 -0600
+Subject: [PATCH 40/45] cpu/amd/fam10h-fam15h: Add CMOS option to disable CPB
+ (core boost)
+
+On certain systems and CPUs Core Performance Boost (CPB) may cause
+sporadic system lockups. This issue is also somewhat known on the
+various proprietary BIOSes, therefore it seems to be a hardware
+incompatibility when present.
+
+Allow the user to disable CBP if needed.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/init_cpus.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+index e2a1bf3..c1ff240 100644
+--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c
++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c
+@@ -987,6 +987,7 @@ void cpuSetAMDMSR(uint8_t node_id)
+ u32 platform;
+ uint64_t revision;
+ uint8_t enable_c_states;
++ uint8_t enable_cpb;
+
+ printk(BIOS_DEBUG, "cpuSetAMDMSR ");
+
+@@ -1078,6 +1079,19 @@ void cpuSetAMDMSR(uint8_t node_id)
+ enable_c_states = 0;
+ #endif
+
++ if (revision & AMD_FAM15_ALL) {
++ enable_cpb = 1;
++ if (get_option(&nvram, "cpu_core_boost") == CB_SUCCESS)
++ enable_cpb = !!nvram;
++
++ if (!enable_cpb) {
++ /* Disable Core Performance Boost */
++ msr = rdmsr(0xc0010015);
++ msr.lo |= (0x1 << 25); /* CpbDis = 1 */
++ wrmsr(0xc0010015, msr);
++ }
++ }
++
+ printk(BIOS_DEBUG, " done\n");
+ }
+
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch
new file mode 100644
index 0000000..4df54ca
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0041-mainboard-asus-kgpe-d16-Add-CPB-control-CMOS-option.patch
@@ -0,0 +1,42 @@
+From 7315434b950b3150fbaaa5c6860590c41d5cc71e Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:07 -0600
+Subject: [PATCH 41/45] mainboard/asus/kgpe-d16: Add CPB control CMOS option
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kgpe-d16/cmos.default | 1 +
+ src/mainboard/asus/kgpe-d16/cmos.layout | 5 +++--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/mainboard/asus/kgpe-d16/cmos.default b/src/mainboard/asus/kgpe-d16/cmos.default
+index a05b9c3..0e7afb3 100644
+--- a/src/mainboard/asus/kgpe-d16/cmos.default
++++ b/src/mainboard/asus/kgpe-d16/cmos.default
+@@ -17,6 +17,7 @@ interleave_nodes = Disable
+ interleave_memory_channels = Enable
+ cpu_c_states = Enable
+ cpu_cc6_state = Enable
++cpu_core_boost = Enable
+ sata_ahci_mode = Enable
+ sata_alpm = Disable
+ maximum_p_state_limit = 0xf
+diff --git a/src/mainboard/asus/kgpe-d16/cmos.layout b/src/mainboard/asus/kgpe-d16/cmos.layout
+index d1c0702..075388e 100644
+--- a/src/mainboard/asus/kgpe-d16/cmos.layout
++++ b/src/mainboard/asus/kgpe-d16/cmos.layout
+@@ -48,8 +48,9 @@ entries
+ 476 1 e 1 l3_cache_partitioning
+ 477 1 e 1 ieee1394_controller
+ 478 1 e 1 iommu
+-479 1 e 1 experimental_memory_speed_boost
+-480 1 r 0 allow_spd_nvram_cache_restore
++479 1 e 1 cpu_core_boost
++480 1 e 1 experimental_memory_speed_boost
++481 1 r 0 allow_spd_nvram_cache_restore
+ 728 256 h 0 user_data
+ 984 16 h 0 check_sum
+ # Reserve the extended AMD configuration registers
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch
new file mode 100644
index 0000000..e95630f
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0042-cpu-amd-fam10h-15h-Set-PowerStepUp-PowerStepDown-on-.patch
@@ -0,0 +1,131 @@
+From ed0e74f934203d11e90c227f6a2bcabd62262952 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:07 -0600
+Subject: [PATCH 42/45] cpu/amd/fam10h-15h: Set PowerStepUp/PowerStepDown on
+ Fam15h
+
+Multilink Family 15h processors were being configured with an
+incorrect PowerStepUp/PowerStepDown value. Set the value
+according to the BKDG, and clean up the terrible formatting
+of the power_up_down() function that led to the incorrect
+values being overlooked until now.
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/cpu/amd/family_10h-family_15h/fidvid.c | 96 ++++++++++++++++--------------
+ 1 file changed, 50 insertions(+), 46 deletions(-)
+
+diff --git a/src/cpu/amd/family_10h-family_15h/fidvid.c b/src/cpu/amd/family_10h-family_15h/fidvid.c
+index 2edb75e..5bef7d3 100644
+--- a/src/cpu/amd/family_10h-family_15h/fidvid.c
++++ b/src/cpu/amd/family_10h-family_15h/fidvid.c
+@@ -390,56 +390,60 @@ static u32 nb_clk_did(uint8_t node, uint64_t cpuRev, uint8_t procPkg) {
+
+
+ static u32 power_up_down(int node, u8 procPkg) {
+- u32 dword=0;
+- /* from CPU rev guide #41322 rev 3.74 June 2010 Table 26 */
+- u8 singleLinkFlag = ((procPkg == AMD_PKGTYPE_AM3_2r2)
+- || (procPkg == AMD_PKGTYPE_S1gX)
+- || (procPkg == AMD_PKGTYPE_ASB2));
+-
+- if (singleLinkFlag) {
+- /*
+- * PowerStepUp=01000b - 50nS
+- * PowerStepDown=01000b - 50ns
+- */
+- dword |= PW_STP_UP50 | PW_STP_DN50;
+- } else {
+- u32 dispRefModeEn = (pci_read_config32(NODE_PCI(node,0),0x68) >> 24) & 1;
+- u32 isocEn = 0;
+- int j;
+- for(j=0 ; (j<4) && (!isocEn) ; j++ ) {
+- u8 offset;
+- if (AMD_CpuFindCapability(node, j, &offset)) {
+- isocEn = (pci_read_config32(NODE_PCI(node,0),offset+4) >>12) & 1;
+- }
+- }
+-
+- if (dispRefModeEn || isocEn) {
+- dword |= PW_STP_UP50 | PW_STP_DN50 ;
+- } else {
+- /* get number of cores for PowerStepUp & PowerStepDown in server
+- 1 core - 400nS - 0000b
+- 2 cores - 200nS - 0010b
+- 3 cores - 133nS -> 100nS - 0011b
+- 4 cores - 100nS - 0011b
++ uint32_t dword=0;
++ /* from CPU rev guide #41322 rev 3.74 June 2010 Table 26 */
++ u8 singleLinkFlag = ((procPkg == AMD_PKGTYPE_AM3_2r2)
++ || (procPkg == AMD_PKGTYPE_S1gX)
++ || (procPkg == AMD_PKGTYPE_ASB2));
++
++ if (singleLinkFlag) {
++ /*
++ * PowerStepUp=01000b - 50nS
++ * PowerStepDown=01000b - 50ns
+ */
+- switch (get_core_num_in_bsp(node)) {
+- case 0:
+- dword |= PW_STP_UP400 | PW_STP_DN400;
+- break;
+- case 1:
+- case 2:
+- dword |= PW_STP_UP200 | PW_STP_DN200;
+- break;
+- case 3:
+- dword |= PW_STP_UP100 | PW_STP_DN100;
+- break;
+- default:
++ dword |= PW_STP_UP50 | PW_STP_DN50;
++ } else {
++ uint32_t dispRefModeEn = (pci_read_config32(NODE_PCI(node,0),0x68) >> 24) & 1;
++ uint32_t isocEn = 0;
++ int j;
++ for (j=0 ; (j<4) && (!isocEn) ; j++ ) {
++ u8 offset;
++ if (AMD_CpuFindCapability(node, j, &offset)) {
++ isocEn = (pci_read_config32(NODE_PCI(node,0),offset+4) >>12) & 1;
++ }
++ }
++
++ if (is_fam15h()) {
++ /* Family 15h always uses 100ns for multilink processors */
+ dword |= PW_STP_UP100 | PW_STP_DN100;
+- break;
++ } else if (dispRefModeEn || isocEn) {
++ dword |= PW_STP_UP50 | PW_STP_DN50 ;
++ } else {
++ /* get number of cores for PowerStepUp & PowerStepDown in server
++ * 1 core - 400nS - 0000b
++ * 2 cores - 200nS - 0010b
++ * 3 cores - 133nS -> 100nS - 0011b
++ * 4 cores - 100nS - 0011b
++ */
++ switch (get_core_num_in_bsp(node)) {
++ case 0:
++ dword |= PW_STP_UP400 | PW_STP_DN400;
++ break;
++ case 1:
++ case 2:
++ dword |= PW_STP_UP200 | PW_STP_DN200;
++ break;
++ case 3:
++ dword |= PW_STP_UP100 | PW_STP_DN100;
++ break;
++ default:
++ dword |= PW_STP_UP100 | PW_STP_DN100;
++ break;
++ }
+ }
+- }
+ }
+- return dword;
++
++ return dword;
+ }
+
+ static void config_clk_power_ctrl_reg0(uint8_t node, uint64_t cpuRev, uint8_t procPkg) {
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch
new file mode 100644
index 0000000..27a9b98
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0043-mainboard-asus-kcma-d8-Add-copy-of-ASUS-KGPE-D16-boa.patch
@@ -0,0 +1,3928 @@
+From 310546dc0a509f88352862a109b85bd6ee8fd3b8 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:08 -0600
+Subject: [PATCH 43/45] mainboard/asus/kcma-d8: Add copy of ASUS KGPE-D16 board
+ for initial support work
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kcma-d8/Kconfig | 103 ++++
+ src/mainboard/asus/kcma-d8/Kconfig.name | 2 +
+ src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl | 367 +++++++++++++
+ src/mainboard/asus/kcma-d8/acpi_tables.c | 109 ++++
+ src/mainboard/asus/kcma-d8/board_info.txt | 5 +
+ src/mainboard/asus/kcma-d8/bootblock.c | 52 ++
+ src/mainboard/asus/kcma-d8/cmos.default | 30 ++
+ src/mainboard/asus/kcma-d8/cmos.layout | 155 ++++++
+ src/mainboard/asus/kcma-d8/devicetree.cb | 247 +++++++++
+ src/mainboard/asus/kcma-d8/dsdt.asl | 789 ++++++++++++++++++++++++++++
+ src/mainboard/asus/kcma-d8/get_bus_conf.c | 121 +++++
+ src/mainboard/asus/kcma-d8/irq_tables.c | 128 +++++
+ src/mainboard/asus/kcma-d8/mainboard.c | 116 ++++
+ src/mainboard/asus/kcma-d8/mainboard.c.orig | 116 ++++
+ src/mainboard/asus/kcma-d8/mb_sysconf.h | 40 ++
+ src/mainboard/asus/kcma-d8/mptable.c | 231 ++++++++
+ src/mainboard/asus/kcma-d8/resourcemap.c | 550 +++++++++++++++++++
+ src/mainboard/asus/kcma-d8/romstage.c | 608 +++++++++++++++++++++
+ 18 files changed, 3769 insertions(+)
+ create mode 100644 src/mainboard/asus/kcma-d8/Kconfig
+ create mode 100644 src/mainboard/asus/kcma-d8/Kconfig.name
+ create mode 100644 src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl
+ create mode 100644 src/mainboard/asus/kcma-d8/acpi_tables.c
+ create mode 100644 src/mainboard/asus/kcma-d8/board_info.txt
+ create mode 100644 src/mainboard/asus/kcma-d8/bootblock.c
+ create mode 100644 src/mainboard/asus/kcma-d8/cmos.default
+ create mode 100644 src/mainboard/asus/kcma-d8/cmos.layout
+ create mode 100644 src/mainboard/asus/kcma-d8/devicetree.cb
+ create mode 100644 src/mainboard/asus/kcma-d8/dsdt.asl
+ create mode 100644 src/mainboard/asus/kcma-d8/get_bus_conf.c
+ create mode 100644 src/mainboard/asus/kcma-d8/irq_tables.c
+ create mode 100644 src/mainboard/asus/kcma-d8/mainboard.c
+ create mode 100644 src/mainboard/asus/kcma-d8/mainboard.c.orig
+ create mode 100644 src/mainboard/asus/kcma-d8/mb_sysconf.h
+ create mode 100644 src/mainboard/asus/kcma-d8/mptable.c
+ create mode 100644 src/mainboard/asus/kcma-d8/resourcemap.c
+ create mode 100644 src/mainboard/asus/kcma-d8/romstage.c
+
+diff --git a/src/mainboard/asus/kcma-d8/Kconfig b/src/mainboard/asus/kcma-d8/Kconfig
+new file mode 100644
+index 0000000..23c91f0
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/Kconfig
+@@ -0,0 +1,103 @@
++if BOARD_ASUS_KGPE_D16
++
++config BOARD_SPECIFIC_OPTIONS # dummy
++ def_bool y
++ select CPU_AMD_SOCKET_G34_NON_AGESA
++ select DIMM_DDR3
++ select DIMM_REGISTERED
++ # select QRANK_DIMM_SUPPORT
++ select DIMM_VOLTAGE_SET_SUPPORT
++ select NORTHBRIDGE_AMD_AMDFAM10
++ select SOUTHBRIDGE_AMD_SR5650
++ select SOUTHBRIDGE_AMD_SB700
++ select SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA
++ select SOUTHBRIDGE_AMD_SUBTYPE_SP5100
++ select SUPERIO_WINBOND_W83667HG_A
++ select PARALLEL_CPU_INIT
++ select HAVE_ROMSTAGE_CONSOLE_SPINLOCK
++ select HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK
++ select HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK
++ select HAVE_HARD_RESET
++ select HAVE_OPTION_TABLE
++ select HAVE_CMOS_DEFAULT
++ select HAVE_PIRQ_TABLE
++ select HAVE_MP_TABLE
++ select HAVE_ACPI_TABLES
++ select SB_HT_CHAIN_UNITID_OFFSET_ONLY
++ select LIFT_BSP_APIC_ID
++ select BOARD_ROMSIZE_KB_2048
++ select ENABLE_APIC_EXT_ID
++ select MMCONF_SUPPORT_DEFAULT
++ select SPI_FLASH
++ select SPI_FLASH_WINBOND
++ select HAVE_ACPI_RESUME
++ select DRIVERS_I2C_W83795
++ select DRIVERS_ASPEED_AST2050
++ select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG
++
++config MAINBOARD_DIR
++ string
++ default "asus/kgpe-d16"
++
++config BOOTBLOCK_MAINBOARD_INIT
++ string
++ default "mainboard/asus/kgpe-d16/bootblock.c"
++
++config DCACHE_RAM_BASE
++ hex
++ default 0xc2000
++
++config DCACHE_RAM_SIZE
++ hex
++ default 0x1e000
++
++config APIC_ID_OFFSET
++ hex
++ default 0
++
++config MAINBOARD_PART_NUMBER
++ string
++ default "KGPE-D16"
++
++config HW_MEM_HOLE_SIZEK
++ hex
++ default 0x100000
++
++config MAX_CPUS
++ int
++ default 32
++
++# 2 (internal) processors per G34 socket
++config MAX_PHYSICAL_CPUS
++ int
++ default 4
++
++config HT_CHAIN_UNITID_BASE
++ hex
++ default 0x0
++
++config HT_CHAIN_END_UNITID_BASE
++ hex
++ default 0x20
++
++config IRQ_SLOT_COUNT
++ int
++ default 13
++
++config SOUTHBRIDGE_AMD_SB700_SATA_PORT_COUNT_BITFIELD
++ hex
++ default 0x3f
++
++config ONBOARD_VGA_IS_PRIMARY
++ bool
++ default y
++
++config MAINBOARD_POWER_ON_AFTER_POWER_FAIL
++ bool
++ default y
++
++config MAX_REBOOT_CNT
++ int
++ default 10
++
++endif # BOARD_ASUS_KGPE_D16
+diff --git a/src/mainboard/asus/kcma-d8/Kconfig.name b/src/mainboard/asus/kcma-d8/Kconfig.name
+new file mode 100644
+index 0000000..bdfa31a
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/Kconfig.name
+@@ -0,0 +1,2 @@
++config BOARD_ASUS_KGPE_D16
++ bool "KGPE-D16"
+diff --git a/src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl b/src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl
+new file mode 100644
+index 0000000..a4d5b2a
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/acpi/pm_ctrl.asl
+@@ -0,0 +1,367 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Raptor Engineering
++ * Copyright (C) 2009 Advanced Micro Devices, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++/* Port 80 POST card debug */
++OperationRegion (DBG0, SystemIO, 0x80, One)
++ Field (DBG0, ByteAcc, NoLock, Preserve) {
++ DBG8, 8
++}
++
++/* SuperIO control port */
++Name (SPIO, 0x2E)
++
++/* SuperIO control map */
++OperationRegion (SPIM, SystemIO, SPIO, 0x02)
++ Field (SPIM, ByteAcc, NoLock, Preserve) {
++ INDX, 8,
++ DATA, 8
++}
++
++/* SuperIO control registers */
++IndexField (INDX, DATA, ByteAcc, NoLock, Preserve) {
++ Offset (0x07),
++ CR07, 8, /* Logical device number */
++ Offset (0x2C),
++ CR2C, 8, /* GPIO3 multiplexed pin selection */
++ Offset (0x30),
++ CR30, 8, /* Logical device activation control register */
++ Offset (0xE0),
++ CRE0, 8, /* Wake control register */
++ Offset (0xE4),
++ CRE4, 8, /* Standby power control register */
++ Offset (0xE6),
++ CRE6, 8, /* Mouse wake event configuration register */
++ Offset (0xF1),
++ CRF1, 8, /* GPIO3 data register */
++ Offset (0xF3),
++ CRF3, 8, /* SUSLED mode register */
++ Offset (0xF6),
++ CRF6, 8, /* SMI/PME event generation control register */
++ Offset (0xF9),
++ CRF9, 8, /* ACPI PME configuration register */
++}
++
++/* Power Management I/O registers */
++OperationRegion(PIOR, SystemIO, 0x00000CD6, 0x00000002)
++ Field(PIOR, ByteAcc, NoLock, Preserve) {
++ PIOI, 0x00000008,
++ PIOD, 0x00000008,
++}
++IndexField (PIOI, PIOD, ByteAcc, NoLock, Preserve) {
++ Offset(0x00), /* MiscControl */
++ , 1,
++ T1EE, 1,
++ T2EE, 1,
++ Offset(0x01), /* MiscStatus */
++ , 1,
++ T1E, 1,
++ T2E, 1,
++ Offset(0x04), /* SmiWakeUpEventEnable3 */
++ , 7,
++ SSEN, 1,
++ Offset(0x07), /* SmiWakeUpEventStatus3 */
++ , 7,
++ CSSM, 1,
++ Offset(0x10), /* AcpiEnable */
++ , 6,
++ PWDE, 1,
++ Offset(0x1C), /* ProgramIoEnable */
++ , 3,
++ MKME, 1,
++ IO3E, 1,
++ IO2E, 1,
++ IO1E, 1,
++ IO0E, 1,
++ Offset(0x1D), /* IOMonitorStatus */
++ , 3,
++ MKMS, 1,
++ IO3S, 1,
++ IO2S, 1,
++ IO1S, 1,
++ IO0S,1,
++ Offset(0x20), /* AcpiPmEvtBlk */
++ APEB, 16,
++ Offset(0x36), /* GEvtLevelConfig */
++ , 6,
++ ELC6, 1,
++ ELC7, 1,
++ Offset(0x37), /* GPMLevelConfig0 */
++ , 3,
++ PLC0, 1,
++ PLC1, 1,
++ PLC2, 1,
++ PLC3, 1,
++ PLC8, 1,
++ Offset(0x38), /* GPMLevelConfig1 */
++ , 1,
++ PLC4, 1,
++ PLC5, 1,
++ , 1,
++ PLC6, 1,
++ PLC7, 1,
++ Offset(0x3B), /* PMEStatus1 */
++ GP0S, 1,
++ GM4S, 1,
++ GM5S, 1,
++ APS, 1,
++ GM6S, 1,
++ GM7S, 1,
++ GP2S, 1,
++ STSS, 1,
++ Offset(0x55), /* SoftPciRst */
++ SPRE, 1,
++ , 1,
++ , 1,
++ PNAT, 1,
++ PWMK, 1,
++ PWNS, 1,
++
++ /* Offset(0x61), */ /* Options_1 */
++ /* ,7, */
++ /* R617,1, */
++
++ Offset(0x65), /* UsbPMControl */
++ , 4,
++ URRE, 1,
++ , 2,
++ BCDL, 1,
++ Offset(0x68), /* MiscEnable68 */
++ , 2,
++ MAPC, 1,
++ TMTE, 1,
++ , 1,
++ Offset(0x7C), /* MiscEnable7C */
++ , 2,
++ BLNK, 2,
++ Offset(0x92), /* GEVENTIN */
++ , 7,
++ E7IS, 1,
++ Offset(0x96), /* GPM98IN */
++ G8IS, 1,
++ G9IS, 1,
++ Offset(0x9A), /* EnhanceControl */
++ ,7,
++ HPDE, 1,
++ Offset(0xA8), /* PIO7654Enable */
++ IO4E, 1,
++ IO5E, 1,
++ IO6E, 1,
++ IO7E, 1,
++ Offset(0xA9), /* PIO7654Status */
++ IO4S, 1,
++ IO5S, 1,
++ IO6S, 1,
++ IO7S, 1,
++}
++
++/* PM1 Event Block
++ * First word is PM1_Status, Second word is PM1_Enable
++ */
++OperationRegion(P1EB, SystemIO, APEB, 0x04)
++ Field(P1EB, ByteAcc, NoLock, Preserve) {
++ TMST, 1,
++ , 3,
++ BMST, 1,
++ GBST, 1,
++ Offset(0x01),
++ PBST, 1,
++ , 1,
++ RTST, 1,
++ , 3,
++ PWST, 1,
++ SPWS, 1,
++ Offset(0x02),
++ TMEN, 1,
++ , 4,
++ GBEN, 1,
++ Offset(0x03),
++ PBEN, 1,
++ , 1,
++ RTEN, 1,
++ , 3,
++ PWDA, 1,
++}
++
++/* Wake status package */
++Name(WKST,Package() {Zero, Zero})
++
++/*
++ * \_WAK System Wake method
++ *
++ * Entry:
++ * Arg0=The value of the sleeping state S1=1, S2=2
++ *
++ * Exit:
++ * Return package of 2 DWords
++ * Dword 1 - Status
++ * 0x00000000 wake succeeded
++ * 0x00000001 Wake was signaled but failed due to lack of power
++ * 0x00000002 Wake was signaled but failed due to thermal condition
++ * Dword 2 - Power Supply state
++ * if non-zero the effective S-state the power supply entered
++ */
++Method(\_WAK, 1) {
++ Store (0x20, DBG8)
++
++ /* Set up LEDs */
++ /* Set power LED to steady on */
++ Store(0x0, BLNK)
++
++ /* Configure SuperIO for wake */
++ /* Access SuperIO ACPI device */
++ Store(0x87, INDX)
++ Store(0x87, INDX)
++ Store(0x0A, CR07)
++
++ if (LEqual(Arg0, One)) /* Resuming from power state S1 */
++ {
++ /* Deactivate the ACPI device */
++ Store(Zero, CR30)
++
++ /* Disable PS/2 SMI/PME events */
++ And(CRF6, 0xCF, CRF6)
++ }
++ if (Lor(LEqual(Arg0, 0x03), LEqual(Arg0, 0x04))) /* Resuming from power state S3 or S4 */
++ {
++ /* Disable PS/2 wake */
++ And(CRE0, 0x1D, CRE0)
++ And(CRE6, 0x7F, CRE6)
++ }
++
++ /* Restore default SuperIO access */
++ Store(0xAA, INDX)
++
++ Store (0x21, DBG8)
++
++ /* Re-enable HPET */
++ Store(1, HPDE)
++
++ /* Restore PCIRST# so it resets USB */
++ if (LEqual(Arg0, 3)){
++ Store(1, URRE)
++ }
++
++ /* Configure southbridge for wake */
++ /* Arbitrarily clear PciExpWakeStatus */
++ Store(PWST, PWST)
++
++ Store (0x22, DBG8)
++
++ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */
++
++ Return(WKST)
++}
++
++/*
++ * \_PTS - Prepare to Sleep method
++ *
++ * Entry:
++ * Arg0=The value of the sleeping state S1=1, S2=2, etc
++ *
++ * Exit:
++ * -none-
++ *
++ * The _PTS control method is executed at the beginning of the sleep process
++ * for S1-S5. The sleeping value is passed to the _PTS control method. This
++ * control method may be executed a relatively long time before entering the
++ * sleep state and the OS may abort the operation without notification to
++ * the ACPI driver. This method cannot modify the configuration or power
++ * state of any device in the system.
++ */
++Method(\_PTS, 1) {
++ Store (Arg0, DBG8)
++
++ /* Set up LEDs */
++ if (LEqual(Arg0, One)) /* Power state S1 requested */
++ {
++ /* Set suspend LED to 0.25Hz toggle pulse with 50% duty cycle */
++ Store(0x2, BLNK)
++ }
++
++ /* Configure SuperIO for sleep */
++ /* Access SuperIO ACPI device */
++ Store(0x87, INDX)
++ Store(0x87, INDX)
++ Store(0x0A, CR07)
++
++ /* Disable PS/2 wakeup and connect PANSW_IN to PANSW_OUT */
++ And(CRE0, 0x1F, CRE0)
++
++ if (LEqual(Arg0, One)) /* Power state S1 requested */
++ {
++ /* Activate the ACPI device */
++ Store(One, CR30)
++
++ /* Disable SMI/PME events for:
++ * LPT
++ * FDC
++ * UART
++ */
++ Store(0x00, CRF6)
++
++ /* Enable PS/2 keyboard SMI/PME events */
++ Or(CRF6, 0x10, CRF6)
++
++ /* Enable PS/2 keyboard wake */
++ Or(CRE0, 0x40, CRE0)
++
++ /* Enable PS/2 mouse SMI/PME events */
++ Or(CRF6, 0x20, CRF6)
++
++ /* Enable PS/2 mouse wake */
++ Or(CRE0, 0x20, CRE0)
++ } else {
++ /* Enable PS/2 keyboard wake on any keypress */
++ Or(CRE0, 0x41, CRE0)
++
++ /* Enable PS/2 mouse wake on any click */
++ Or(CRE0, 0x22, CRE0)
++ Or(CRE6, 0x80, CRE6)
++
++ if (LEqual(Arg0, 0x03)) /* Power state S3 requested */
++ {
++ /* Set VSBGATE# to provide standby power during S3 */
++ Or(CRE4, 0x10, CRE4)
++ }
++ }
++
++ /* Restore default SuperIO access */
++ Store(0xAA, INDX)
++
++ Store (0x10, DBG8)
++
++ /* Don't allow PCIRST# to reset USB */
++ if (LEqual(Arg0, 3)){
++ Store(0, URRE)
++ }
++
++ /* Configure southbridge for sleep */
++ /* Use bus clock for delay timebase */
++ Store(0, BCDL)
++ /* Defer APIC interrupts until first ACPI access */
++ Store(One, MAPC)
++
++ /* On older chips, clear PciExpWakeDisEn */
++ // if (LLessEqual(SBRI, 0x13)) {
++ // Store(0, PWDE)
++ // }
++
++ Store (0x11, DBG8)
++
++ /* Clear wake status structure. */
++ Store(0, Index(WKST,0))
++ Store(0, Index(WKST,1))
++}
+diff --git a/src/mainboard/asus/kcma-d8/acpi_tables.c b/src/mainboard/asus/kcma-d8/acpi_tables.c
+new file mode 100644
+index 0000000..f20e837
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/acpi_tables.c
+@@ -0,0 +1,109 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <string.h>
++#include <arch/acpi.h>
++#include <arch/ioapic.h>
++#include <device/pci.h>
++#include <device/pci_ids.h>
++#include <cpu/x86/msr.h>
++#include <cpu/amd/mtrr.h>
++#include <cpu/amd/amdfam10_sysconf.h>
++
++#include "mb_sysconf.h"
++
++unsigned long acpi_fill_madt(unsigned long current)
++{
++ device_t dev;
++ u32 dword;
++ u32 gsi_base=0;
++ uint32_t apicid_sp5100;
++ uint32_t apicid_sr5650;
++ /* create all subtables for processors */
++ current = acpi_create_madt_lapics(current);
++
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ apicid_sp5100 = 0x0;
++ else
++ apicid_sp5100 = 0x20;
++ apicid_sr5650 = apicid_sp5100 + 1;
++
++ /* Write SB700 IOAPIC, only one */
++ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, apicid_sp5100,
++ IO_APIC_ADDR, gsi_base);
++ /* IOAPIC on rs5690 */
++ gsi_base += 24; /* SB700 has 24 IOAPIC entries. */
++ dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ if (dev) {
++ pci_write_config32(dev, 0xF8, 0x1);
++ dword = pci_read_config32(dev, 0xFC) & 0xfffffff0;
++ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, apicid_sr5650,
++ dword, gsi_base);
++ }
++
++ /* bus, source, gsirq, flags */
++ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
++ current, 0, 0, 2, 0);
++ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
++ current, 0, 9, 9, 0xf);
++
++ /* create all subtables for processors */
++ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0xff, 0, 1);
++ /* 1: LINT1 connect to NMI */
++
++ return current;
++}
++
++unsigned long acpi_fill_ivrs_ioapic(acpi_ivrs_t* ivrs, unsigned long current)
++{
++ uint8_t *p;
++
++ uint32_t apicid_sp5100;
++ uint32_t apicid_sr5650;
++
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ apicid_sp5100 = 0x0;
++ else
++ apicid_sp5100 = 0x20;
++ apicid_sr5650 = apicid_sp5100 + 1;
++
++ /* Describe NB IOAPIC */
++ p = (uint8_t *)current;
++ p[0] = 0x48; /* Entry type */
++ p[1] = 0; /* Device */
++ p[2] = 0; /* Bus */
++ p[3] = 0x0; /* Data */
++ p[4] = apicid_sr5650; /* IOAPIC ID */
++ p[5] = 0x1; /* Device 0 Function 1 */
++ p[6] = 0x0; /* Northbridge bus */
++ p[7] = 0x1; /* Variety */
++ current += 8;
++
++ /* Describe SB IOAPIC */
++ p = (uint8_t *)current;
++ p[0] = 0x48; /* Entry type */
++ p[1] = 0; /* Device */
++ p[2] = 0; /* Bus */
++ p[3] = 0xd7; /* Data */
++ p[4] = apicid_sp5100; /* IOAPIC ID */
++ p[5] = 0x14 << 3; /* Device 0x14 Function 0 */
++ p[6] = 0x0; /* Southbridge bus */
++ p[7] = 0x1; /* Variety */
++ current += 8;
++
++ return current;
++}
+\ No newline at end of file
+diff --git a/src/mainboard/asus/kcma-d8/board_info.txt b/src/mainboard/asus/kcma-d8/board_info.txt
+new file mode 100644
+index 0000000..788888e
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/board_info.txt
+@@ -0,0 +1,5 @@
++Category: server
++ROM package: PLCC-32
++ROM protocol: LPC
++ROM socketed: y
++Flashrom support: y
+\ No newline at end of file
+diff --git a/src/mainboard/asus/kcma-d8/bootblock.c b/src/mainboard/asus/kcma-d8/bootblock.c
+new file mode 100644
+index 0000000..6f2c0a1
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/bootblock.c
+@@ -0,0 +1,52 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan@alterapraxis.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <arch/io.h>
++#include <pc80/mc146818rtc.h>
++
++void bootblock_mainboard_init(void)
++{
++ uint8_t recovery_enabled;
++ unsigned char addr;
++ unsigned char byte;
++
++ bootblock_northbridge_init();
++ bootblock_southbridge_init();
++
++ /* Recovery jumper is connected to SP5100 GPIO61, and clears the GPIO when placed in the Recovery position */
++ byte = pci_io_read_config8(PCI_DEV(0, 0x14, 0), 0x56);
++ byte |= 0x1 << 4; /* Set GPIO61 to input mode */
++ pci_io_write_config8(PCI_DEV(0, 0x14, 0), 0x56, byte);
++ recovery_enabled = (!(pci_io_read_config8(PCI_DEV(0, 0x14, 0), 0x57) & 0x1));
++ if (recovery_enabled) {
++#if CONFIG_USE_OPTION_TABLE
++ /* Clear NVRAM checksum */
++ for (addr = LB_CKS_RANGE_START; addr <= LB_CKS_RANGE_END; addr++) {
++ cmos_write(0x0, addr);
++ }
++
++ /* Set fallback boot */
++ byte = cmos_read(RTC_BOOT_BYTE);
++ byte &= 0xfc;
++ cmos_write(byte, RTC_BOOT_BYTE);
++#else
++ /* FIXME
++ * Figure out how to recover if the option table is not available
++ */
++#endif
++ }
++}
+diff --git a/src/mainboard/asus/kcma-d8/cmos.default b/src/mainboard/asus/kcma-d8/cmos.default
+new file mode 100644
+index 0000000..0e7afb3
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/cmos.default
+@@ -0,0 +1,30 @@
++baud_rate = 115200
++debug_level = Spew
++multi_core = Enable
++slow_cpu = off
++compute_unit_siblings = Enable
++iommu = Enable
++nmi = Disable
++hypertransport_speed_limit = Auto
++max_mem_clock = DDR3-1600
++minimum_memory_voltage = 1.5V
++dimm_spd_checksum = Enforce
++ECC_memory = Enable
++ECC_redirection = Enable
++ecc_scrub_rate = 1.28us
++interleave_chip_selects = Enable
++interleave_nodes = Disable
++interleave_memory_channels = Enable
++cpu_c_states = Enable
++cpu_cc6_state = Enable
++cpu_core_boost = Enable
++sata_ahci_mode = Enable
++sata_alpm = Disable
++maximum_p_state_limit = 0xf
++probe_filter = Auto
++l3_cache_partitioning = Disable
++ieee1394_controller = Enable
++gart = Enable
++experimental_memory_speed_boost = Disable
++power_on_after_fail = On
++boot_option = Fallback
+diff --git a/src/mainboard/asus/kcma-d8/cmos.layout b/src/mainboard/asus/kcma-d8/cmos.layout
+new file mode 100644
+index 0000000..075388e
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/cmos.layout
+@@ -0,0 +1,155 @@
++##
++## This file is part of the coreboot project.
++##
++## Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++## Copyright (C) 2007 AMD
++## Written by Yinghai Lu <yinghailu@amd.com> for AMD.
++##
++## This program is free software; you can redistribute it and/or modify
++## it under the terms of the GNU General Public License as published by
++## the Free Software Foundation; either version 2 of the License, or
++## (at your option) any later version.
++##
++## This program is distributed in the hope that it will be useful,
++## but WITHOUT ANY WARRANTY; without even the implied warranty of
++## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++## GNU General Public License for more details.
++##
++
++entries
++
++0 384 r 0 reserved_memory
++384 1 e 4 boot_option
++388 4 r 0 reboot_bits
++393 3 e 5 baud_rate
++396 5 e 10 ecc_scrub_rate
++401 1 e 1 interleave_chip_selects
++402 1 e 1 interleave_nodes
++403 1 e 1 interleave_memory_channels
++404 4 e 8 max_mem_clock
++408 1 e 2 multi_core
++412 4 e 6 debug_level
++440 4 e 9 slow_cpu
++444 1 e 1 nmi
++445 1 e 1 gart
++446 2 e 3 power_on_after_fail
++456 1 e 1 ECC_memory
++457 1 e 1 ECC_redirection
++458 4 e 11 hypertransport_speed_limit
++462 2 e 12 minimum_memory_voltage
++464 1 e 2 compute_unit_siblings
++465 1 e 1 cpu_c_states
++466 1 e 1 cpu_cc6_state
++467 1 e 1 sata_ahci_mode
++468 1 e 1 sata_alpm
++469 4 h 0 maximum_p_state_limit
++473 2 e 13 dimm_spd_checksum
++475 1 e 14 probe_filter
++476 1 e 1 l3_cache_partitioning
++477 1 e 1 ieee1394_controller
++478 1 e 1 iommu
++479 1 e 1 cpu_core_boost
++480 1 e 1 experimental_memory_speed_boost
++481 1 r 0 allow_spd_nvram_cache_restore
++728 256 h 0 user_data
++984 16 h 0 check_sum
++# Reserve the extended AMD configuration registers
++1000 24 r 0 amd_reserved
++
++
++
++enumerations
++
++#ID value text
++1 0 Disable
++1 1 Enable
++2 0 Enable
++2 1 Disable
++3 0 Off
++3 1 On
++3 2 Last
++4 0 Fallback
++4 1 Normal
++5 0 115200
++5 1 57600
++5 2 38400
++5 3 19200
++5 4 9600
++5 5 4800
++5 6 2400
++5 7 1200
++6 0 Emergency
++6 1 Alert
++6 2 Critical
++6 3 Error
++6 4 Warning
++6 5 Notice
++6 6 Information
++6 7 Debug
++6 8 Spew
++8 0 DDR3-1866
++8 1 DDR3-1600
++8 2 DDR3-1333
++8 3 DDR3-1066
++8 4 DDR3-800
++8 5 DDR3-667
++9 0 off
++9 1 87.5%
++9 2 75.0%
++9 3 62.5%
++9 4 50.0%
++9 5 37.5%
++9 6 25.0%
++9 7 12.5%
++10 0 Disabled
++10 1 40ns
++10 2 80ns
++10 3 160ns
++10 4 320ns
++10 5 640ns
++10 6 1.28us
++10 7 2.56us
++10 8 5.12us
++10 9 10.2us
++10 10 20.5us
++10 11 41us
++10 12 81.9us
++10 13 163.8us
++10 14 327.7us
++10 15 655.4us
++10 16 1.31ms
++10 17 2.62ms
++10 18 5.24ms
++10 19 10.49ms
++10 20 20.97ms
++10 21 42ms
++10 22 84ms
++11 0 Auto
++11 1 3.2GHz
++11 2 3.0GHz
++11 3 2.8GHz
++11 4 2.6GHz
++11 5 2.4GHz
++11 6 2.2GHz
++11 7 2.0GHz
++11 8 1.8GHz
++11 9 1.6GHz
++11 10 1.4GHz
++11 11 1.2GHz
++11 12 1.0GHz
++11 13 800MHz
++11 14 600MHz
++11 15 500MHz
++12 0 1.5V
++12 1 1.35V
++12 2 1.25V
++12 3 1.15V
++13 0 Enforce
++13 1 Ignore
++13 2 Override
++14 0 Disable
++14 1 Auto
++
++checksums
++
++checksum 392 983 984
+diff --git a/src/mainboard/asus/kcma-d8/devicetree.cb b/src/mainboard/asus/kcma-d8/devicetree.cb
+new file mode 100644
+index 0000000..8d64ac7
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/devicetree.cb
+@@ -0,0 +1,247 @@
++chip northbridge/amd/amdfam10/root_complex # Root complex
++ device cpu_cluster 0 on # (L)APIC cluster
++ chip cpu/amd/socket_F_1207 # CPU socket
++ device lapic 0 on end # Local APIC of the CPU
++ end
++ end
++ device domain 0 on # PCI domain
++ subsystemid 0x1043 0x8163 inherit
++ chip northbridge/amd/amdfam10 # Northbridge / RAM controller
++ register "maximum_memory_capacity" = "0x4000000000" # 256GB
++ device pci 18.0 on end # Link 0 == LDT 0
++ device pci 18.0 on end # Link 1 == LDT 1
++ device pci 18.0 on end # Link 2 == LDT 2
++ device pci 18.0 on # Link 3 == LDT 3 [SB on link 3]
++ chip southbridge/amd/sr5650 # Primary southbridge
++ device pci 0.0 on end # HT Root Complex 0x9600
++ device pci 0.1 on end # CLKCONFIG
++ device pci 0.2 on end # IOMMU
++ device pci 2.0 on # PCIE P2P bridge 0x9603 (GPP1 Port0)
++ # Slot # PCI E 1 / PCI E 2
++ end
++ device pci 3.0 off end # PCIE P2P bridge 0x960b (GPP1 Port1)
++ device pci 4.0 on # PCIE P2P bridge 0x9604 (GPP3a Port0)
++ # PIKE SAS
++ end
++ device pci 5.0 off end # PCIE P2P bridge 0x9605 (GPP3a Port1)
++ device pci 6.0 off end # PCIE P2P bridge 0x9606 (GPP3a Port2)
++ device pci 7.0 off end # PCIE P2P bridge 0x9607 (GPP3a Port3)
++ device pci 8.0 off end # NB/SB Link P2P bridge
++ device pci 9.0 on # Bridge (GPP3a Port4)
++ # Onboard # NIC A
++ end
++ device pci a.0 on # Bridge (GPP3a Port5)
++ # Onboard # NIC B
++ end
++ device pci b.0 on # Bridge (GPP2 Port0)
++ # Slot # PCI E 4
++ end
++ device pci c.0 on # Bridge (GPP2 Port1)
++ # Slot # PCI E 5
++ end
++ device pci d.0 on # Bridge (GPP3b Port0)
++ # Slot # PCI E 3
++ end
++ register "gpp1_configuration" = "0" # Configuration 16:0 default
++ register "gpp2_configuration" = "1" # Configuration 8:8
++ register "gpp3a_configuration" = "2" # Configuration 4:1:1:0:0:0
++ register "port_enable" = "0x3f1c" # Enable all ports except 0, 1, 5, 6, and 7
++ register "pcie_settling_time" = "1000000" # Allow PIKE to be detected / configured
++ end
++ chip southbridge/amd/sb700 # Secondary southbridge
++ device pci 11.0 on end # SATA
++ device pci 12.0 on end # USB
++ device pci 12.1 on end # USB
++ device pci 12.2 on end # USB
++ device pci 13.0 on end # USB
++ device pci 13.1 on end # USB
++ device pci 13.2 on end # USB
++ device pci 14.0 on # SM
++ chip drivers/generic/generic # DIMM n-0-0-0
++ device i2c 50 on end
++ end
++ chip drivers/generic/generic # DIMM n-0-0-1
++ device i2c 51 on end
++ end
++ chip drivers/generic/generic # DIMM n-0-1-0
++ device i2c 52 on end
++ end
++ chip drivers/generic/generic # DIMM n-0-1-1
++ device i2c 53 on end
++ end
++ chip drivers/generic/generic # DIMM n-1-0-0
++ device i2c 54 on end
++ end
++ chip drivers/generic/generic # DIMM n-1-0-1
++ device i2c 55 on end
++ end
++ chip drivers/generic/generic # DIMM n-1-1-0
++ device i2c 56 on end
++ end
++ chip drivers/generic/generic # DIMM n-1-1-1
++ device i2c 57 on end
++ end
++ chip drivers/i2c/w83795
++ register "fanin_ctl1" = "0xff" # Enable monitoring of FANIN1 - FANIN8
++ register "fanin_ctl2" = "0x00" # Connect FANIN11 - FANIN14 to alternate functions
++ register "temp_ctl1" = "0x2a" # Enable monitoring of DTS, VSEN12, and VSEN13
++ register "temp_ctl2" = "0x01" # Enable monitoring of TD1/TR1
++ register "temp_dtse" = "0x03" # Enable DTS1 and DTS2
++ register "volt_ctl1" = "0xff" # Enable monitoring of VSEN1 - VSEN8
++ register "volt_ctl2" = "0xf7" # Enable monitoring of VSEN9 - VSEN11, 3VDD, 3VSB, and VBAT
++ register "temp1_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp1)
++ register "temp2_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp2)
++ register "temp3_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp3)
++ register "temp4_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp4)
++ register "temp5_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp5)
++ register "temp6_fan_select" = "0x00" # All fans to manual mode (no dependence on Temp6)
++ register "temp1_source_select" = "0x00" # Use TD1/TR1 as data source for Temp1
++ register "temp2_source_select" = "0x00" # Use TD2/TR2 as data source for Temp2
++ register "temp3_source_select" = "0x00" # Use TD3/TR3 as data source for Temp3
++ register "temp4_source_select" = "0x00" # Use TD4/TR4 as data source for Temp4
++ register "temp5_source_select" = "0x00" # Use TR5 as data source for Temp5
++ register "temp6_source_select" = "0x00" # Use TR6 as data source for Temp6
++ register "tr1_critical_temperature" = "85" # Set TD1/TR1 critical temperature to 85°C
++ register "tr1_critical_hysteresis" = "80" # Set TD1/TR1 critical hysteresis temperature to 80°C
++ register "tr1_warning_temperature" = "70" # Set TD1/TR1 warning temperature to 70°C
++ register "tr1_warning_hysteresis" = "65" # Set TD1/TR1 warning hysteresis temperature to 65°C
++ register "dts_critical_temperature" = "85" # Set DTS (CPU) critical temperature to 85°C
++ register "dts_critical_hysteresis" = "80" # Set DTS (CPU) critical hysteresis temperature to 80°C
++ register "dts_warning_temperature" = "70" # Set DTS (CPU) warning temperature to 70°C
++ register "dts_warning_hysteresis" = "65" # Set DTS (CPU) warning hysteresis temperature to 65°C
++ register "temp1_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C
++ register "temp2_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C
++ register "temp3_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C
++ register "temp4_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C
++ register "temp5_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C
++ register "temp6_critical_temperature" = "80" # Set Temp1 critical temperature to 80°C
++ register "temp1_target_temperature" = "80" # Set Temp1 target temperature to 80°C
++ register "temp2_target_temperature" = "80" # Set Temp1 target temperature to 80°C
++ register "temp3_target_temperature" = "80" # Set Temp1 target temperature to 80°C
++ register "temp4_target_temperature" = "80" # Set Temp1 target temperature to 80°C
++ register "temp5_target_temperature" = "80" # Set Temp1 target temperature to 80°C
++ register "temp6_target_temperature" = "80" # Set Temp1 target temperature to 80°C
++ register "fan1_nonstop" = "7" # Set Fan 1 minimum speed
++ register "fan2_nonstop" = "7" # Set Fan 2 minimum speed
++ register "fan3_nonstop" = "7" # Set Fan 3 minimum speed
++ register "fan4_nonstop" = "7" # Set Fan 4 minimum speed
++ register "fan5_nonstop" = "7" # Set Fan 5 minimum speed
++ register "fan6_nonstop" = "7" # Set Fan 6 minimum speed
++ register "fan7_nonstop" = "7" # Set Fan 7 minimum speed
++ register "fan8_nonstop" = "7" # Set Fan 8 minimum speed
++ register "default_speed" = "100" # All fans to full speed on power up
++ register "fan1_duty" = "100" # Fan 1 to full speed
++ register "fan2_duty" = "100" # Fan 2 to full speed
++ register "fan3_duty" = "100" # Fan 3 to full speed
++ register "fan4_duty" = "100" # Fan 4 to full speed
++ register "fan5_duty" = "100" # Fan 5 to full speed
++ register "fan6_duty" = "100" # Fan 6 to full speed
++ register "fan7_duty" = "100" # Fan 7 to full speed
++ register "fan8_duty" = "100" # Fan 8 to full speed
++ register "vcore1_high_limit_mv" = "1500" # VCORE1 (Node 0) high limit to 1.5V
++ register "vcore1_low_limit_mv" = "900" # VCORE1 (Node 0) low limit to 0.9V
++ register "vcore2_high_limit_mv" = "1500" # VCORE2 (Node 1) high limit to 1.5V
++ register "vcore2_low_limit_mv" = "900" # VCORE2 (Node 1) low limit to 0.9V
++ register "vsen3_high_limit_mv" = "1600" # VSEN1 (Node 0 RAM voltage) high limit to 1.6V
++ register "vsen3_low_limit_mv" = "1100" # VSEN1 (Node 0 RAM voltage) low limit to 1.1V
++ register "vsen4_high_limit_mv" = "1600" # VSEN2 (Node 1 RAM voltage) high limit to 1.6V
++ register "vsen4_low_limit_mv" = "1100" # VSEN2 (Node 1 RAM voltage) low limit to 1.1V
++ register "vsen5_high_limit_mv" = "1250" # VSEN5 (Node 0 HT link voltage) high limit to 1.25V
++ register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V
++ register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V
++ register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V
++ register "vsen7_high_limit_mv" = "1250" # VSEN7 (Northbridge core voltage) high limit to 1.25V
++ register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V
++ register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V
++ register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V
++ register "vsen9_high_limit_mv" = "1250" # VSEN9 (+1.2V) high limit to 1.25V
++ register "vsen9_low_limit_mv" = "1150" # VSEN9 (+1.2V) low limit to 1.15V
++ register "vsen10_high_limit_mv" = "1150" # VSEN10 (+1.1V) high limit to 1.15V
++ register "vsen10_low_limit_mv" = "1050" # VSEN10 (+1.1V) low limit to 1.05V
++ register "vsen11_high_limit_mv" = "1625" # VSEN11 (5VSB, scaling factor ~3.2) high limit to 5.2V
++ register "vsen11_low_limit_mv" = "1500" # VSEN11 (5VSB, scaling factor ~3.2) low limit to 4.8V
++ register "vsen12_high_limit_mv" = "1083" # VSEN12 (+12V, scaling factor ~12) high limit to 13V
++ register "vsen12_low_limit_mv" = "917" # VSEN12 (+12V, scaling factor ~12) low limit to 11V
++ register "vsen13_high_limit_mv" = "1625" # VSEN13 (+5V, scaling factor ~3.2) high limit to 5.2V
++ register "vsen13_low_limit_mv" = "1500" # VSEN13 (+5V, scaling factor ~3.2) low limit to 4.8V
++ register "vdd_high_limit_mv" = "3500" # 3VDD high limit to 3.5V
++ register "vdd_low_limit_mv" = "3100" # 3VDD low limit to 3.1V
++ register "vsb_high_limit_mv" = "3500" # 3VSB high limit to 3.5V
++ register "vsb_low_limit_mv" = "3100" # 3VSB low limit to 3.1V
++ register "vbat_high_limit_mv" = "3500" # VBAT (+3V) high limit to 3.5V
++ register "vbat_low_limit_mv" = "2500" # VBAT (+3V) low limit to 2.5V
++ register "smbus_aux" = "1" # Device located on auxiliary SMBUS controller
++ device i2c 0x2f on end
++ end
++ end
++ device pci 14.1 on end # IDE 0x439c
++ device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card)
++ device pci 14.3 on # LPC 0x439d (SMBUS primary controller)
++ chip superio/winbond/w83667hg-a # Super I/O
++ device pnp 2e.0 off end # FDC; Not available on the KGPE-D16
++ device pnp 2e.1 off end # LPT1; Not available on the KGPE-D16
++ device pnp 2e.2 on # Com1
++ io 0x60 = 0x3f8
++ irq 0x70 = 4
++ end
++ device pnp 2e.3 on # Com2
++ io 0x60 = 0x2f8
++ irq 0x70 = 3
++ end
++ device pnp 2e.5 on # PS/2 keyboard & mouse
++ io 0x60 = 0x60
++ io 0x62 = 0x64
++ irq 0x70 = 1
++ irq 0x72 = 12
++ end
++ device pnp 2e.6 off end # SPI: Not available on the KGPE-D16
++ device pnp 2e.7 off end # GIPO6789
++ device pnp 2e.8 off end # WDT
++ device pnp 2e.9 off end # GPIO2345
++ device pnp 2e.a on end # ACPI
++ device pnp 2e.b on # HW Monitor
++ io 0x60 = 0x290
++ io 0x62 = 0x0000 # SB-TSI currently not implemented
++ irq 0x70 = 5
++ end
++ device pnp 2e.c off end # PECI
++ device pnp 2e.d off end # VID_BUSSEL
++ device pnp 2e.f off end # GPIO_PP_OD
++ end
++ end
++ device pci 14.4 on # Bridge
++ device pci 1.0 on end # VGA
++ device pci 2.0 on end # FireWire
++ device pci 3.0 on # Slot
++ # Slot # PCI 0
++ end
++ end
++ device pci 14.5 on end # USB OHCI2 0x4399
++ end
++ end
++ device pci 18.1 on end
++ device pci 18.2 on end
++ device pci 18.3 on end
++ device pci 18.4 on end
++ device pci 18.5 on end
++ device pci 19.0 on end # Socket 0 node 1
++ device pci 19.1 on end
++ device pci 19.2 on end
++ device pci 19.3 on end
++ device pci 19.4 on end
++ device pci 19.5 on end
++ device pci 1a.0 on end # Socket 1 node 0
++ device pci 1a.1 on end
++ device pci 1a.2 on end
++ device pci 1a.3 on end
++ device pci 1a.4 on end
++ device pci 1a.5 on end
++ device pci 1b.0 on end # Socket 1 node 1
++ device pci 1b.1 on end
++ device pci 1b.2 on end
++ device pci 1b.3 on end
++ device pci 1b.4 on end
++ device pci 1b.5 on end
++ end
++ end
++end
+diff --git a/src/mainboard/asus/kcma-d8/dsdt.asl b/src/mainboard/asus/kcma-d8/dsdt.asl
+new file mode 100644
+index 0000000..5f9195a
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/dsdt.asl
+@@ -0,0 +1,789 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2005 - 2012 Advanced Micro Devices, Inc.
++ * Copyright (C) 2007-2009 coresystems GmbH
++ * Copyright (C) 2004 Nick Barker <Nick.Barker9@btinternet.com>
++ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++/*
++ * WARNING: Sleep/Wake is a work in progress and is still somewhat flaky!
++ * Everything else does to the best of my knowledge... (T.P. 01/26/2015)
++ */
++
++/*
++ * ISA portions taken from QEMU acpi-dsdt.dsl.
++ */
++
++/*
++ * PCI link routing templates taken from ck804.asl and modified for this board
++ */
++
++DefinitionBlock (
++ "DSDT.AML", /* Output filename */
++ "DSDT", /* Signature */
++ 0x03, /* DSDT Revision, needs to be 2 or higher for 64bit */
++ "ASUS ", /* OEMID */
++ "COREBOOT", /* TABLE ID */
++ 0x00000001 /* OEM Revision */
++ )
++{
++ #include "northbridge/amd/amdfam10/amdfam10_util.asl"
++ #include "southbridge/amd/sr5650/acpi/sr5650.asl"
++
++ /* Some global data */
++ Name(OSVR, 3) /* Assume nothing. WinXp = 1, Vista = 2, Linux = 3, WinCE = 4 */
++ Name(OSV, Ones) /* Assume nothing */
++ Name(PICM, One) /* Assume APIC */
++
++ /* HPET enable */
++ Name (HPTE, 0x1)
++
++ /* Define power states */
++ Name (\_S0, Package () { 0x00, 0x00, 0x00, 0x00 }) /* Normal operation */
++ Name (\_S1, Package () { 0x01, 0x01, 0x00, 0x00 }) /* Standby */
++ Name (\_S3, Package () { 0x03, 0x03, 0x00, 0x00 }) /* Suspend to RAM */
++ Name (\_S4, Package () { 0x04, 0x04, 0x00, 0x00 }) /* Suspend to disk */
++ Name (\_S5, Package () { 0x05, 0x05, 0x00, 0x00 }) /* Hard power off */
++
++ /* The _PIC method is called by the OS to choose between interrupt
++ * routing via the i8259 interrupt controller or the APIC.
++ *
++ * _PIC is called with a parameter of 0 for i8259 configuration and
++ * with a parameter of 1 for Local Apic/IOAPIC configuration.
++ */
++ Method (_PIC, 1, Serialized) {
++ If (Arg0)
++ {
++ \_SB.CIRQ()
++ }
++ Store (Arg0, PICM)
++ }
++
++ /* _PR CPU0 is dynamically supplied by SSDT */
++ /* CPU objects and _PSS entries are dynamically supplied by SSDT */
++
++ Scope(\_GPE) { /* Start Scope GPE */
++ /* General event 3 */
++ Method(_L03) {
++ /* Level-Triggered GPE */
++ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */
++ }
++
++ /* General event 4 */
++ Method(_L04) {
++ /* Level-Triggered GPE */
++ Notify (\_SB.PCI0.PBR0, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */
++ }
++
++ /* Keyboard controller PME# */
++ Method(_L08) {
++ /* Level-Triggered GPE */
++ Notify(\_SB.PCI0.LPC.PS2K, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify(\_SB.PCI0.LPC.PS2M, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */
++ }
++
++ /* USB controller PME# */
++ Method(_L0B) {
++ /* Level-Triggered GPE */
++ Notify (\_SB.PCI0.USB0, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.USB1, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.USB2, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.USB3, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.USB4, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.USB5, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.USB6, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */
++ }
++
++ /* GPIO0 or GEvent8 event */
++ Method(_L18) {
++ /* Level-Triggered GPE */
++ Notify (\_SB.PCI0.PCE1, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.NICA, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.NICB, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.PCE4, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.PCE5, 0x02) /* NOTIFY_DEVICE_WAKE */
++ Notify (\_SB.PCI0.PCE3, 0x02) /* NOTIFY_DEVICE_WAKE */
++ }
++
++ } /* End Scope GPE */
++
++ /* Root of the bus hierarchy */
++ Scope (\_SB)
++ {
++ /* Top southbridge PCI device (SR5690 + SP5100) */
++ Device (PCI0)
++ {
++ /* BUS0 root bus */
++
++ Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5690) */
++ Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */
++ Name (_ADR, 0x00180001)
++ Name (_UID, 0x00)
++
++ Name (HCIN, 0x00) // HC1
++
++ Method (_BBN, 0, NotSerialized)
++ {
++ Return (GBUS (GHCN(HCIN), GHCL(HCIN)))
++ }
++
++ /* Operating System Capabilities Method */
++ Method(_OSC,4)
++ {
++ /* Let OS control everything */
++ Return (Arg3)
++ }
++
++ External (BUSN)
++ External (MMIO)
++ External (PCIO)
++ External (SBLK)
++ External (TOM1)
++ External (HCLK)
++ External (SBDN)
++ External (HCDN)
++ External (CBST)
++
++ /* PCI Routing Tables */
++ Name (PR00, Package () {
++ /* PIC */
++ /* Top southbridge device (SR5690) */
++ /* HT Link */
++ Package (0x04) { 0x0000FFFF, 0x00, LNKA, 0x00 },
++
++ /* PCI-E Slot 1 (Bridge) */
++ Package (0x04) { 0x0002FFFF, 0x00, LNKE, 0x00 },
++
++ /* NIC A (Bridge) */
++ Package (0x04) { 0x0009FFFF, 0x00, LNKF, 0x00 },
++
++ /* NIC B (Bridge) */
++ Package (0x04) { 0x000AFFFF, 0x00, LNKG, 0x00 },
++
++ /* PCI-E Slot 4 (Bridge) */
++ Package (0x04) { 0x000BFFFF, 0x00, LNKG, 0x00 },
++
++ /* PCI-E Slot 5 (Bridge) */
++ Package (0x04) { 0x000CFFFF, 0x00, LNKG, 0x00 },
++
++ /* PCI-E Slot 3 (Bridge) */
++ Package (0x04) { 0x000DFFFF, 0x00, LNKG, 0x00 },
++
++ /* Bottom southbridge device (SP5100) */
++ /* SATA 0 */
++ Package (0x04) { 0x0011FFFF, 0x00, LNKG, 0x00 },
++
++ /* USB 0 */
++ Package (0x04) { 0x0012FFFF, 0x00, LNKA, 0x00 },
++ Package (0x04) { 0x0012FFFF, 0x01, LNKB, 0x00 },
++ Package (0x04) { 0x0012FFFF, 0x02, LNKC, 0x00 },
++ Package (0x04) { 0x0012FFFF, 0x03, LNKD, 0x00 },
++
++ /* USB 1 */
++ Package (0x04) { 0x0013FFFF, 0x00, LNKC, 0x00 },
++ Package (0x04) { 0x0013FFFF, 0x01, LNKD, 0x00 },
++ Package (0x04) { 0x0013FFFF, 0x02, LNKA, 0x00 },
++ Package (0x04) { 0x0013FFFF, 0x03, LNKB, 0x00 },
++
++ /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */
++ Package (0x04) { 0x0014FFFF, 0x00, LNKA, 0x00 },
++ Package (0x04) { 0x0014FFFF, 0x01, LNKB, 0x00 },
++ Package (0x04) { 0x0014FFFF, 0x02, LNKC, 0x00 },
++ Package (0x04) { 0x0014FFFF, 0x03, LNKD, 0x00 },
++ })
++
++ Name (AR00, Package () {
++ /* APIC */
++ /* Top southbridge device (SR5690) */
++ /* HT Link */
++ Package (0x04) { 0x0000FFFF, 0x00, 0x00, 55 },
++
++ /* PCI-E Slot 1 (Bridge) */
++ Package (0x04) { 0x0002FFFF, 0x00, 0x00, 52 },
++
++ /* NIC A (Bridge) */
++ Package (0x04) { 0x0009FFFF, 0x00, 0x00, 53 },
++
++ /* NIC B (Bridge) */
++ Package (0x04) { 0x000AFFFF, 0x00, 0x00, 54 },
++
++ /* PCI-E Slot 4 (Bridge) */
++ Package (0x04) { 0x000BFFFF, 0x00, 0x00, 54 },
++
++ /* PCI-E Slot 5 (Bridge) */
++ Package (0x04) { 0x000CFFFF, 0x00, 0x00, 54 },
++
++ /* PCI-E Slot 3 (Bridge) */
++ Package (0x04) { 0x000DFFFF, 0x00, 0x00, 54 },
++
++ /* Bottom southbridge device (SP5100) */
++ /* SATA 0 */
++ Package (0x04) { 0x0011FFFF, 0x00, 0x00, 22 },
++
++ /* USB 0 */
++ Package (0x04) { 0x0012FFFF, 0x00, 0x00, 16 },
++ Package (0x04) { 0x0012FFFF, 0x01, 0x00, 17 },
++ Package (0x04) { 0x0012FFFF, 0x02, 0x00, 18 },
++ Package (0x04) { 0x0012FFFF, 0x03, 0x00, 19 },
++
++ /* USB 1 */
++ Package (0x04) { 0x0013FFFF, 0x00, 0x00, 18 },
++ Package (0x04) { 0x0013FFFF, 0x01, 0x00, 19 },
++ Package (0x04) { 0x0013FFFF, 0x02, 0x00, 16 },
++ Package (0x04) { 0x0013FFFF, 0x03, 0x00, 17 },
++
++ /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */
++ Package (0x04) { 0x0014FFFF, 0x00, 0x00, 16 },
++ Package (0x04) { 0x0014FFFF, 0x01, 0x00, 17 },
++ Package (0x04) { 0x0014FFFF, 0x02, 0x00, 18 },
++ Package (0x04) { 0x0014FFFF, 0x03, 0x00, 19 },
++ })
++
++ Name (PR01, Package () {
++ /* PIC */
++ Package (0x04) { 0x1FFFF, 0x00, LNKF, 0x00 },
++ Package (0x04) { 0x2FFFF, 0x00, LNKE, 0x00 },
++ Package (0x04) { 0x3FFFF, 0x00, LNKG, 0x00 },
++ Package (0x04) { 0x3FFFF, 0x01, LNKH, 0x00 },
++ Package (0x04) { 0x3FFFF, 0x02, LNKE, 0x00 },
++ Package (0x04) { 0x3FFFF, 0x03, LNKF, 0x00 },
++ })
++
++ Name (AR01, Package () {
++ /* APIC */
++ Package (0x04) { 0x1FFFF, 0x00, 0x00, 21 },
++ Package (0x04) { 0x2FFFF, 0x00, 0x00, 20 },
++ Package (0x04) { 0x3FFFF, 0x00, 0x00, 22 },
++ Package (0x04) { 0x3FFFF, 0x01, 0x00, 23 },
++ Package (0x04) { 0x3FFFF, 0x02, 0x00, 20 },
++ Package (0x04) { 0x3FFFF, 0x03, 0x00, 21 },
++ })
++
++ Name (PR02, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 },
++ })
++
++ Name (AR02, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 24 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 25 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 26 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 27 },
++ })
++
++ Name (PR03, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKE, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKF, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKG, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKH, 0x00 },
++ })
++
++ Name (AR03, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 44 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 45 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 46 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 47 },
++ })
++
++ Name (PR04, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 },
++ })
++
++ Name (AR04, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 48 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 49 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 50 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 51 },
++ })
++
++ Name (PR05, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKH, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKE, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKF, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKG, 0x00 },
++ })
++
++ Name (AR05, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 47 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 44 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 45 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 46 },
++ })
++
++ Name (PR06, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 },
++ })
++
++ Name (AR06, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 32 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 33 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 34 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 35 },
++ })
++
++ Name (PR07, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKE, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKF, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKG, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKH, 0x00 },
++ })
++
++ Name (AR07, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 36 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 37 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 38 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 39 },
++ })
++
++ Name (PR08, Package () {
++ /* PIC */
++ Package (0x04) { 0xFFFF, 0x00, LNKA, 0x00 },
++ Package (0x04) { 0xFFFF, 0x01, LNKB, 0x00 },
++ Package (0x04) { 0xFFFF, 0x02, LNKC, 0x00 },
++ Package (0x04) { 0xFFFF, 0x03, LNKD, 0x00 },
++ })
++
++ Name (AR08, Package () {
++ /* APIC */
++ Package (0x04) { 0xFFFF, 0x00, 0x00, 40 },
++ Package (0x04) { 0xFFFF, 0x01, 0x00, 41 },
++ Package (0x04) { 0xFFFF, 0x02, 0x00, 42 },
++ Package (0x04) { 0xFFFF, 0x03, 0x00, 43 },
++ })
++
++ /* PCI Resource Tables */
++
++ /* PCI Resource Settings Access */
++ Method (_CRS, 0, Serialized)
++ {
++ Name (BUF0, ResourceTemplate ()
++ {
++ IO (Decode16,
++ 0x0CF8, // Address Range Minimum
++ 0x0CF8, // Address Range Maximum
++ 0x01, // Address Alignment
++ 0x08, // Address Length
++ )
++ WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
++ 0x0000, // Address Space Granularity
++ 0x0000, // Address Range Minimum
++ 0x0CF7, // Address Range Maximum
++ 0x0000, // Address Translation Offset
++ 0x0CF8, // Address Length
++ ,, , TypeStatic)
++ })
++ /* Methods below use SSDT to get actual MMIO regs
++ The IO ports are from 0xd00, optionally an VGA,
++ otherwise the info from MMIO is used.
++ \_SB.GXXX(node, link)
++ */
++ Concatenate (\_SB.GMEM (0x00, \_SB.PCI0.SBLK), BUF0, Local1)
++ Concatenate (\_SB.GIOR (0x00, \_SB.PCI0.SBLK), Local1, Local2)
++ Concatenate (\_SB.GWBN (0x00, \_SB.PCI0.SBLK), Local2, Local3)
++ Return (Local3)
++ }
++
++ /* PCI Routing Table Access */
++ Method (_PRT, 0, NotSerialized) {
++ If (PICM) {
++ Return (AR00)
++ } Else {
++ Return (PR00)
++ }
++ }
++
++ /* 0:11.0 SP5100 SATA 0 */
++ Device(SAT0)
++ {
++ Name (_ADR, 0x00110000) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ #include "southbridge/amd/sb700/acpi/sata.asl"
++ }
++
++ /* 0:12.0 SP5100 USB 0 */
++ Device (USB0)
++ {
++ Name (_ADR, 0x00120000) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 0:12.1 SP5100 USB 1 */
++ Device (USB1)
++ {
++ Name (_ADR, 0x00120001) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 0:12.2 SP5100 USB 2 */
++ Device (USB2)
++ {
++ Name (_ADR, 0x00120002) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 0:13.0 SP5100 USB 3 */
++ Device (USB3)
++ {
++ Name (_ADR, 0x00130000) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 0:13.1 SP5100 USB 4 */
++ Device (USB4)
++ {
++ Name (_ADR, 0x00130001) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 0:13.2 SP5100 USB 5 */
++ Device (USB5)
++ {
++ Name (_ADR, 0x00130002) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 0:14.1 SP5100 IDE Controller */
++ Device (IDEC)
++ {
++ Name (_ADR, 0x00140001) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ #include "southbridge/amd/sb700/acpi/ide.asl"
++ }
++
++ /* 0:14.3 SP5100 LPC */
++ Device (LPC) {
++ Name (_HID, EisaId ("PNP0A05"))
++ Name (_ADR, 0x00140003)
++
++ /* Real Time Clock Device */
++ Device(RTC0) {
++ Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */
++ Name(BUF0, ResourceTemplate() {
++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02)
++ })
++ Name(BUF1, ResourceTemplate() {
++ IRQNoFlags() { 8 }
++ IO(Decode16, 0x0070, 0x0070, 0x01, 0x02)
++ })
++ Method(_CRS, 0) {
++ If(HPTE) {
++ Return(BUF0)
++ }
++ Return(BUF1)
++ }
++ }
++
++ Device(TMR) { /* Timer */
++ Name(_HID,EISAID("PNP0100")) /* System Timer */
++ Name(BUF0, ResourceTemplate() {
++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04)
++ })
++ Name(BUF1, ResourceTemplate() {
++ IRQNoFlags() { 0 }
++ IO(Decode16, 0x0040, 0x0040, 0x01, 0x04)
++ })
++ Method(_CRS, 0) {
++ If(HPTE) {
++ Return(BUF0)
++ }
++ Return(BUF1)
++ }
++ }
++
++ Device(SPKR) { /* Speaker */
++ Name(_HID,EISAID("PNP0800")) /* AT style speaker */
++ Name(_CRS, ResourceTemplate() {
++ IO(Decode16, 0x0061, 0x0061, 0, 1)
++ })
++ }
++
++ Device(PIC) {
++ Name(_HID,EISAID("PNP0000")) /* AT Interrupt Controller */
++ Name(_CRS, ResourceTemplate() {
++ IRQNoFlags() { 2 }
++ IO(Decode16,0x0020, 0x0020, 0, 2)
++ IO(Decode16,0x00A0, 0x00A0, 0, 2)
++ })
++ }
++
++ Device(MAD) { /* 8257 DMA */
++ Name(_HID,EISAID("PNP0200")) /* Hardware Device ID */
++ Name(_CRS, ResourceTemplate() {
++ DMA(Compatibility,BusMaster,Transfer8){4}
++ IO(Decode16, 0x0000, 0x0000, 0x10, 0x10)
++ IO(Decode16, 0x0081, 0x0081, 0x01, 0x03)
++ IO(Decode16, 0x0087, 0x0087, 0x01, 0x01)
++ IO(Decode16, 0x0089, 0x0089, 0x01, 0x03)
++ IO(Decode16, 0x008F, 0x008F, 0x01, 0x01)
++ IO(Decode16, 0x00C0, 0x00C0, 0x10, 0x20)
++ }) /* End Name(_SB.PCI0.LpcIsaBr.MAD._CRS) */
++ }
++
++ Device(COPR) {
++ Name(_HID,EISAID("PNP0C04")) /* Math Coprocessor */
++ Name(_CRS, ResourceTemplate() {
++ IO(Decode16, 0x00F0, 0x00F0, 0, 0x10)
++ IRQNoFlags(){13}
++ })
++ }
++
++ #include "../../../superio/winbond/w83667hg-a/ps2_controller.asl"
++
++ /* UART 1 */
++ Device (URT1)
++ {
++ Name (_HID, EisaId ("PNP0501")) // "PNP0501" for UART
++ Name(_PRW, Package () {0x03, 0x04}) // Wake from S1-S4
++ Method (_STA, 0, NotSerialized)
++ {
++ Return (0x0f) // Always enable
++ }
++ Name (_PRS, ResourceTemplate() {
++ StartDependentFn(0, 1) {
++ IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8)
++ IRQNoFlags() { 4 }
++ } EndDependentFn()
++ })
++ Method (_CRS, 0)
++ {
++ Return(ResourceTemplate() {
++ IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8)
++ IRQNoFlags() { 4 }
++ })
++ }
++ }
++ }
++
++ /* High Precision Event Timer */
++ Device (HPET)
++ {
++ Name (_HID, EisaId ("PNP0103"))
++ Name (CRS, ResourceTemplate ()
++ {
++ Memory32Fixed(ReadOnly, 0xFED00000, 0x00000400)
++ })
++ Method (_STA, 0)
++ {
++ If(HPTE) {
++ Return (0x0F)
++ }
++ Return (0x0)
++ }
++ Method(_CRS, 0)
++ {
++ Return(CRS)
++ }
++ }
++
++ /* 0:14.4 PCI Bridge */
++ Device (PBR0)
++ {
++ Name (_ADR, 0x00140004) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR01)
++ } Else {
++ Return (PR01)
++ }
++ }
++ Device (SLT1)
++ {
++ Name (_ADR, 0xFFFF) // _ADR: Address
++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
++ }
++ }
++
++ /* 0:14.5 SP5100 USB 6 */
++ Device (USB6)
++ {
++ Name (_ADR, 0x00140005) // _ADR: Address
++ Name(_PRW, Package () {0x05, 0x04}) // Wake from S1-S4
++ }
++
++ /* 2:00.0 PCIe x16 */
++ Device (PCE1)
++ {
++ Name (_ADR, 0x00020000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR02)
++ } Else {
++ Return (PR02)
++ }
++ }
++ Device (SLT1)
++ {
++ Name (_ADR, 0xFFFF) // _ADR: Address
++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
++ }
++ }
++
++ /* 1:00.0 PIKE */
++ Device (PIKE)
++ {
++ Name (_ADR, 0x00040000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR03)
++ } Else {
++ Return (PR03)
++ }
++ }
++ Device (SLT1)
++ {
++ Name (_ADR, 0xFFFF) // _ADR: Address
++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
++ }
++ }
++
++ /* 3:00.0 PCIe NIC A */
++ Device (NICA)
++ {
++ Name (_ADR, 0x00090000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR04)
++ } Else {
++ Return (PR04)
++ }
++ }
++ Device (BDC1)
++ {
++ Name (_ADR, Zero) // _ADR: Address
++ }
++ }
++
++ /* 4:00.0 PCIe NIC B */
++ Device (NICB)
++ {
++ Name (_ADR, 0x000A0000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR05)
++ } Else {
++ Return (PR05)
++ }
++ }
++ Device (BDC2)
++ {
++ Name (_ADR, Zero) // _ADR: Address
++ }
++ }
++
++ /* 5:00.0 PCIe x16 */
++ Device (PCE4)
++ {
++ Name (_ADR, 0x000B0000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR06)
++ } Else {
++ Return (PR06)
++ }
++ }
++ Device (SLT1)
++ {
++ Name (_ADR, 0xFFFF) // _ADR: Address
++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
++ }
++ }
++
++ /* 6:00.0 PCIe x16 */
++ Device (PCE5)
++ {
++ Name (_ADR, 0x000C0000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR07)
++ } Else {
++ Return (PR07)
++ }
++ }
++ Device (SLT1)
++ {
++ Name (_ADR, 0xFFFF) // _ADR: Address
++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
++ }
++ }
++
++ /* 7:00.0 PCIe x16 */
++ Device (PCE3)
++ {
++ Name (_ADR, 0x000D0000) // _ADR: Address
++ Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
++ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
++ {
++ If (PICM) {
++ Return (AR08)
++ } Else {
++ Return (PR08)
++ }
++ }
++ Device (SLT1)
++ {
++ Name (_ADR, 0xFFFF) // _ADR: Address
++ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
++ }
++ }
++ }
++
++ Device (PWRB) { /* Start Power button device */
++ Name(_HID, EISAID("PNP0C0C"))
++ Name(_UID, 0xAA)
++ Name(_PRW, Package () {3, 0x04}) /* wake from S1-S4 */
++ Name(_STA, 0x0B) /* sata is invisible */
++ }
++ }
++
++#include "acpi/pm_ctrl.asl"
++
++}
+diff --git a/src/mainboard/asus/kcma-d8/get_bus_conf.c b/src/mainboard/asus/kcma-d8/get_bus_conf.c
+new file mode 100644
+index 0000000..5ebc714
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/get_bus_conf.c
+@@ -0,0 +1,121 @@
++ /*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <device/pci.h>
++#include <device/pci_ids.h>
++#include <string.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <cpu/amd/multicore.h>
++
++#include <cpu/amd/amdfam10_sysconf.h>
++
++/* Global variables for MB layouts and these will be shared by irqtable mptable
++* and acpi_tables busnum is default.
++*/
++u8 bus_isa;
++u8 bus_sr5650[14];
++u8 bus_sp5100[2];
++u32 apicid_sp5100;
++
++/*
++* Here you only need to set value in pci1234 for HT-IO that could be installed or not
++* You may need to preset pci1234 for HTIO board,
++* please refer to src/northbridge/amd/amdk8/get_sblk_pci1234.c for detail
++*/
++u32 pci1234x[] = {
++ 0x0000ff0,
++};
++
++/*
++* HT Chain device num, actually it is unit id base of every ht device in chain,
++* assume every chain only have 4 ht device at most
++*/
++u32 hcdnx[] = {
++ 0x20202020,
++};
++
++
++u32 sbdn_sr5650;
++u32 sbdn_sp5100;
++
++extern void get_pci1234(void);
++
++static u32 get_bus_conf_done = 0;
++
++void get_bus_conf(void)
++{
++ u32 apicid_base;
++ device_t dev;
++ int i;
++
++ if (get_bus_conf_done == 1)
++ return; /* do it only once */
++ get_bus_conf_done = 1;
++
++ sysconf.hc_possible_num = ARRAY_SIZE(pci1234x);
++ for (i = 0; i < sysconf.hc_possible_num; i++) {
++ sysconf.pci1234[i] = pci1234x[i];
++ sysconf.hcdn[i] = hcdnx[i];
++ }
++
++ get_pci1234();
++
++ sysconf.sbdn = (sysconf.hcdn[0] & 0xff);
++ sbdn_sr5650 = sysconf.sbdn;
++ sbdn_sp5100 = 0;
++
++ for (i = 0; i < 2; i++) {
++ bus_sp5100[i] = 0;
++ }
++ for (i = 0; i < ARRAY_SIZE(bus_sr5650); i++) {
++ bus_sr5650[i] = 0;
++ }
++
++
++ bus_sr5650[0] = (sysconf.pci1234[0] >> 16) & 0xff;
++ bus_sp5100[0] = bus_sr5650[0];
++
++
++ /* sp5100 */
++ dev = dev_find_slot(bus_sp5100[0], PCI_DEVFN(sbdn_sp5100 + 0x14, 4));
++ if (dev) {
++ bus_sp5100[1] = pci_read_config8(dev, PCI_SECONDARY_BUS);
++ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
++ bus_isa++;
++ }
++
++ /* sr5650 */
++ for (i = 1; i < ARRAY_SIZE(bus_sr5650); i++) {
++ dev = dev_find_slot(bus_sr5650[0], PCI_DEVFN(sbdn_sr5650 + i, 0));
++ if (dev) {
++ bus_sr5650[i] = pci_read_config8(dev, PCI_SECONDARY_BUS);
++ if(255 != bus_sr5650[i]) {
++ bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
++ bus_isa++;
++ }
++ }
++ }
++
++ /* I/O APICs: APIC ID Version State Address */
++ bus_isa = 10;
++ if (IS_ENABLED(CONFIG_LOGICAL_CPUS))
++ apicid_base = get_apicid_base(1);
++ else
++ apicid_base = CONFIG_MAX_PHYSICAL_CPUS;
++ apicid_sp5100 = apicid_base + 0;
++}
+diff --git a/src/mainboard/asus/kcma-d8/irq_tables.c b/src/mainboard/asus/kcma-d8/irq_tables.c
+new file mode 100644
+index 0000000..ef39db2
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/irq_tables.c
+@@ -0,0 +1,128 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <device/pci_ids.h>
++#include <device/pci.h>
++#include <string.h>
++#include <stdint.h>
++#include <arch/pirq_routing.h>
++
++#include <cpu/amd/amdfam10_sysconf.h>
++
++/* Free irqs are 3, 4, 5, 6, 7, 9, 10, 11, 12, 14, and 15 */
++#define IRQBM ((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<14)|(1<<15))
++
++#define LNKA 1
++#define LNKB 2
++#define LNKC 3
++#define LNKD 4
++
++/*
++ * For simplicity map LNK[E-H] to LNK[A-D].
++ * This also means we are 82C596 compatible.
++ * Needs 0:11.0 0x46[4] set to 0.
++ */
++#define LNKE 1
++#define LNKF 2
++#define LNKG 3
++#define LNKH 4
++
++static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn,
++ u8 link0, u16 bitmap0, u8 link1, u16 bitmap1,
++ u8 link2, u16 bitmap2, u8 link3, u16 bitmap3,
++ u8 slot, u8 rfu)
++{
++ pirq_info->bus = bus;
++ pirq_info->devfn = devfn;
++ pirq_info->irq[0].link = link0;
++ pirq_info->irq[0].bitmap = bitmap0;
++ pirq_info->irq[1].link = link1;
++ pirq_info->irq[1].bitmap = bitmap1;
++ pirq_info->irq[2].link = link2;
++ pirq_info->irq[2].bitmap = bitmap2;
++ pirq_info->irq[3].link = link3;
++ pirq_info->irq[3].bitmap = bitmap3;
++ pirq_info->slot = slot;
++ pirq_info->rfu = rfu;
++}
++extern u8 bus_isa;
++extern u8 bus_sr5650[14];
++extern u8 bus_sp5100[2];
++extern u32 sbdn_sp5100;
++extern u32 sbdn_sr5650;
++
++unsigned long write_pirq_routing_table(unsigned long addr)
++{
++ struct irq_routing_table *pirq;
++ struct irq_info *pirq_info;
++ u32 slot_num;
++ u8 *v;
++
++ u8 sum = 0;
++ int i;
++
++ get_bus_conf(); /* it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c */
++
++ /* Align the table to be 16 byte aligned. */
++ addr += 15;
++ addr &= ~15;
++
++ /* This table must be between 0xf0000 & 0x100000 */
++ printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr);
++
++ pirq = (void *)(addr);
++ v = (u8 *) (addr);
++
++ pirq->signature = PIRQ_SIGNATURE;
++ pirq->version = PIRQ_VERSION;
++
++ /* Where the interrupt router resides */
++ pirq->rtr_bus = bus_sp5100[0];
++ pirq->rtr_devfn = PCI_DEVFN(0x14, 4);
++
++ pirq->exclusive_irqs = 0;
++
++ pirq->rtr_vendor = PCI_VENDOR_ID_ATI;
++ pirq->rtr_device = PCI_DEVICE_ID_ATI_SB700_PCI;
++
++ pirq->miniport_data = 0;
++
++ memset(pirq->rfu, 0, sizeof(pirq->rfu));
++
++ pirq_info = (void *)(&pirq->checksum + 1);
++ slot_num = 0;
++
++ /* pci bridge */
++ write_pirq_info(pirq_info, bus_sp5100[0], ((sbdn_sp5100 + 0x14) << 3) | 4,
++ LNKA, IRQBM, LNKB, IRQBM, LNKC, IRQBM, LNKD, IRQBM, 0, 0);
++ pirq_info++;
++ slot_num++;
++
++ pirq->size = 32 + 16 * slot_num;
++
++ for (i = 0; i < pirq->size; i++)
++ sum += v[i];
++
++ sum = pirq->checksum - sum;
++ if (sum != pirq->checksum) {
++ pirq->checksum = sum;
++ }
++
++ printk(BIOS_INFO, "done.\n");
++
++ return (unsigned long)pirq_info;
++}
+diff --git a/src/mainboard/asus/kcma-d8/mainboard.c b/src/mainboard/asus/kcma-d8/mainboard.c
+new file mode 100644
+index 0000000..65029d4
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/mainboard.c
+@@ -0,0 +1,116 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <device/device.h>
++#include <device/pci.h>
++#include <arch/io.h>
++#include <cpu/x86/msr.h>
++#include <cpu/amd/mtrr.h>
++#include <device/pci_def.h>
++#include <southbridge/amd/sb700/sb700.h>
++#include <southbridge/amd/sr5650/cmn.h>
++
++
++void set_pcie_reset(void);
++void set_pcie_dereset(void);
++
++void set_pcie_reset(void)
++{
++ device_t pcie_core_dev;
++
++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x28282828);
++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x00000028);
++}
++
++void set_pcie_dereset(void)
++{
++ device_t pcie_core_dev;
++
++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x6F6F6F6F);
++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x0000006F);
++}
++
++/*************************************************
++* enable the dedicated function in kgpe-d16 board.
++* This function is called earlier than sr5650_enable.
++*************************************************/
++static void mainboard_enable(device_t dev)
++{
++ printk(BIOS_INFO, "Mainboard KGPE-D16 Enable. dev=0x%p\n", dev);
++
++ msr_t msr, msr2;
++
++ /* TOP_MEM: the top of DRAM below 4G */
++ msr = rdmsr(TOP_MEM);
++ printk
++ (BIOS_INFO, "%s, TOP MEM: msr.lo = 0x%08x, msr.hi = 0x%08x\n",
++ __func__, msr.lo, msr.hi);
++
++ /* TOP_MEM2: the top of DRAM above 4G */
++ msr2 = rdmsr(TOP_MEM2);
++ printk
++ (BIOS_INFO, "%s, TOP MEM2: msr2.lo = 0x%08x, msr2.hi = 0x%08x\n",
++ __func__, msr2.lo, msr2.hi);
++
++ set_pcie_dereset();
++ /* get_ide_dma66(); */
++}
++
++/* override the default SATA PHY setup */
++void sb7xx_51xx_setup_sata_phys(struct device *dev)
++{
++ /* RPR7.6.1 Program the PHY Global Control to 0x2C00 */
++ pci_write_config16(dev, 0x86, 0x2c00);
++
++ /* RPR7.6.2 SATA GENI PHY ports setting */
++ pci_write_config32(dev, 0x88, 0x01b48016);
++ pci_write_config32(dev, 0x8c, 0x01b48016);
++ pci_write_config32(dev, 0x90, 0x01b48016);
++ pci_write_config32(dev, 0x94, 0x01b48016);
++ pci_write_config32(dev, 0x98, 0x01b48016);
++ pci_write_config32(dev, 0x9c, 0x01b48016);
++
++ /* RPR7.6.3 SATA GEN II PHY port setting for port [0~5]. */
++ pci_write_config16(dev, 0xa0, 0xa07a);
++ pci_write_config16(dev, 0xa2, 0xa07a);
++ pci_write_config16(dev, 0xa4, 0xa07a);
++ pci_write_config16(dev, 0xa6, 0xa07a);
++ pci_write_config16(dev, 0xa8, 0xa07a);
++ pci_write_config16(dev, 0xaa, 0xa07a);
++}
++
++/* override the default SATA port setup */
++void sb7xx_51xx_setup_sata_port_indication(void *sata_bar5)
++{
++ uint32_t dword;
++
++ /* RPR7.9 Program Port Indication Registers */
++ dword = read32(sata_bar5 + 0xf8);
++ dword &= ~(0x3f << 12); /* All ports are iSATA */
++ dword &= ~0x3f;
++ write32(sata_bar5 + 0xf8, dword);
++
++ dword = read32(sata_bar5 + 0xfc);
++ dword &= ~(0x1 << 20); /* No eSATA ports are present */
++ write32(sata_bar5 + 0xfc, dword);
++}
++
++struct chip_operations mainboard_ops = {
++ .enable_dev = mainboard_enable,
++};
+diff --git a/src/mainboard/asus/kcma-d8/mainboard.c.orig b/src/mainboard/asus/kcma-d8/mainboard.c.orig
+new file mode 100644
+index 0000000..65029d4
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/mainboard.c.orig
+@@ -0,0 +1,116 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <device/device.h>
++#include <device/pci.h>
++#include <arch/io.h>
++#include <cpu/x86/msr.h>
++#include <cpu/amd/mtrr.h>
++#include <device/pci_def.h>
++#include <southbridge/amd/sb700/sb700.h>
++#include <southbridge/amd/sr5650/cmn.h>
++
++
++void set_pcie_reset(void);
++void set_pcie_dereset(void);
++
++void set_pcie_reset(void)
++{
++ device_t pcie_core_dev;
++
++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x28282828);
++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x00000028);
++}
++
++void set_pcie_dereset(void)
++{
++ device_t pcie_core_dev;
++
++ pcie_core_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ set_htiu_enable_bits(pcie_core_dev, 0xA8, 0xFFFFFFFF, 0x6F6F6F6F);
++ set_htiu_enable_bits(pcie_core_dev, 0xA9, 0x000000FF, 0x0000006F);
++}
++
++/*************************************************
++* enable the dedicated function in kgpe-d16 board.
++* This function is called earlier than sr5650_enable.
++*************************************************/
++static void mainboard_enable(device_t dev)
++{
++ printk(BIOS_INFO, "Mainboard KGPE-D16 Enable. dev=0x%p\n", dev);
++
++ msr_t msr, msr2;
++
++ /* TOP_MEM: the top of DRAM below 4G */
++ msr = rdmsr(TOP_MEM);
++ printk
++ (BIOS_INFO, "%s, TOP MEM: msr.lo = 0x%08x, msr.hi = 0x%08x\n",
++ __func__, msr.lo, msr.hi);
++
++ /* TOP_MEM2: the top of DRAM above 4G */
++ msr2 = rdmsr(TOP_MEM2);
++ printk
++ (BIOS_INFO, "%s, TOP MEM2: msr2.lo = 0x%08x, msr2.hi = 0x%08x\n",
++ __func__, msr2.lo, msr2.hi);
++
++ set_pcie_dereset();
++ /* get_ide_dma66(); */
++}
++
++/* override the default SATA PHY setup */
++void sb7xx_51xx_setup_sata_phys(struct device *dev)
++{
++ /* RPR7.6.1 Program the PHY Global Control to 0x2C00 */
++ pci_write_config16(dev, 0x86, 0x2c00);
++
++ /* RPR7.6.2 SATA GENI PHY ports setting */
++ pci_write_config32(dev, 0x88, 0x01b48016);
++ pci_write_config32(dev, 0x8c, 0x01b48016);
++ pci_write_config32(dev, 0x90, 0x01b48016);
++ pci_write_config32(dev, 0x94, 0x01b48016);
++ pci_write_config32(dev, 0x98, 0x01b48016);
++ pci_write_config32(dev, 0x9c, 0x01b48016);
++
++ /* RPR7.6.3 SATA GEN II PHY port setting for port [0~5]. */
++ pci_write_config16(dev, 0xa0, 0xa07a);
++ pci_write_config16(dev, 0xa2, 0xa07a);
++ pci_write_config16(dev, 0xa4, 0xa07a);
++ pci_write_config16(dev, 0xa6, 0xa07a);
++ pci_write_config16(dev, 0xa8, 0xa07a);
++ pci_write_config16(dev, 0xaa, 0xa07a);
++}
++
++/* override the default SATA port setup */
++void sb7xx_51xx_setup_sata_port_indication(void *sata_bar5)
++{
++ uint32_t dword;
++
++ /* RPR7.9 Program Port Indication Registers */
++ dword = read32(sata_bar5 + 0xf8);
++ dword &= ~(0x3f << 12); /* All ports are iSATA */
++ dword &= ~0x3f;
++ write32(sata_bar5 + 0xf8, dword);
++
++ dword = read32(sata_bar5 + 0xfc);
++ dword &= ~(0x1 << 20); /* No eSATA ports are present */
++ write32(sata_bar5 + 0xfc, dword);
++}
++
++struct chip_operations mainboard_ops = {
++ .enable_dev = mainboard_enable,
++};
+diff --git a/src/mainboard/asus/kcma-d8/mb_sysconf.h b/src/mainboard/asus/kcma-d8/mb_sysconf.h
+new file mode 100644
+index 0000000..7db0d9f
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/mb_sysconf.h
+@@ -0,0 +1,40 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef MB_SYSCONF_H
++
++#define MB_SYSCONF_H
++
++struct mb_sysconf_t {
++ u8 bus_isa;
++ u8 bus_8132_0;
++ u8 bus_8132_1;
++ u8 bus_8132_2;
++ u8 bus_8111_0;
++ u8 bus_8111_1;
++ u8 bus_8132a[31][3];
++ u8 bus_8151[31][2];
++
++ u32 apicid_8111;
++ u32 apicid_8132_1;
++ u32 apicid_8132_2;
++ u32 apicid_8132a[31][2];
++ u32 sbdn3;
++ u32 sbdn3a[31];
++ u32 sbdn5[31];
++};
++
++#endif
+diff --git a/src/mainboard/asus/kcma-d8/mptable.c b/src/mainboard/asus/kcma-d8/mptable.c
+new file mode 100644
+index 0000000..c869d31
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/mptable.c
+@@ -0,0 +1,231 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2010 Advanced Micro Devices, Inc.
++ * Copyright (C) 2015 Raptor Engineering
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <console/console.h>
++#include <arch/smp/mpspec.h>
++#include <device/pci.h>
++#include <arch/io.h>
++#include <string.h>
++#include <stdint.h>
++#include <cpu/amd/amdfam10_sysconf.h>
++
++extern u8 bus_sr5650[14];
++extern u8 bus_sp5100[2];
++
++extern u32 apicid_sp5100;
++
++extern u32 sbdn_sr5650;
++extern u32 sbdn_sp5100;
++
++
++static void *smp_write_config_table(void *v)
++{
++ struct mp_config_table *mc;
++ int bus_isa;
++ u32 apicid_sr5650;
++ device_t dev;
++ uint8_t sp5100_bus_number;
++
++ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
++
++ mptable_init(mc, LOCAL_APIC_ADDR);
++
++ smp_write_processors(mc);
++
++ get_bus_conf();
++
++ if (IS_ENABLED(CONFIG_ENABLE_APIC_EXT_ID) && (CONFIG_APIC_ID_OFFSET > 0))
++ apicid_sp5100 = 0x0;
++ else
++ apicid_sp5100 = 0x20;
++ apicid_sr5650 = apicid_sp5100 + 1;
++
++ mptable_write_buses(mc, NULL, &bus_isa);
++ /* I/O APICs: APIC ID Version State Address */
++ {
++ uint32_t *dword_ptr;
++ uint32_t dword;
++ uint16_t word;
++ uint8_t byte;
++
++ sp5100_bus_number = 0; //bus_sp5100[0]; TODO: why bus_sp5100[0] use same value of bus_sr5650[0] assigned by get_pci1234(), instead of 0.
++
++ dev = dev_find_slot(sp5100_bus_number, PCI_DEVFN(sbdn_sp5100 + 0x14, 0));
++ if (dev) {
++ dword_ptr = (u32 *)(pci_read_config32(dev, 0x74) & 0xfffffff0);
++ smp_write_ioapic(mc, apicid_sp5100, 0x11, dword_ptr);
++
++ /* Initialize interrupt mapping */
++ /* USB 1 & 2 */
++ word = pci_read_config16(dev, 0xbe);
++ word &= ~0x3f3f;
++ word |= 0x0; /* 0: INTA, ...., 7: INTH */
++ word |= (0x1 << 3); /* 0: INTA, ...., 7: INTH */
++ word |= (0x2 << 8); /* 0: INTA, ...., 7: INTH */
++ word |= (0x3 << 11); /* 0: INTA, ...., 7: INTH */
++ pci_write_config16(dev, 0xbe, word);
++
++ /* USB 3 */
++ byte = pci_read_config8(dev, 0x63);
++ byte &= 0xf8;
++ byte |= (0x2 << 4); /* 0: INTA, ...., 7: INTH */
++ pci_write_config8(dev, 0x63, byte);
++
++ dword = pci_read_config32(dev, 0xac);
++
++ /* SATA */
++ dword &= ~(7 << 26);
++ dword |= (0x6 << 26); /* 0: INTA, ...., 7: INTH */
++
++ /* Hide IDE */
++ dword &= ~(0x00080000);
++
++ /* dword_ptr |= 1<<22; PIC and APIC co exists */
++ pci_write_config32(dev, 0xac, dword);
++
++ /*
++ * 00:12.0: PROG SATA : INT F
++ * 00:13.0: INTA USB_0
++ * 00:13.1: INTB USB_1
++ * 00:13.2: INTC USB_2
++ * 00:13.3: INTD USB_3
++ * 00:13.4: INTC USB_4
++ * 00:13.5: INTD USB2
++ * 00:14.1: INTA IDE
++ * 00:14.2: Prog HDA : INT E
++ * 00:14.5: INTB ACI
++ * 00:14.6: INTB MCI
++ */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0, 0));
++ if (dev) {
++ pci_write_config32(dev, 0xF8, 0x1);
++ dword_ptr = (u32 *)(pci_read_config32(dev, 0xFC) & 0xfffffff0);
++ smp_write_ioapic(mc, apicid_sr5650, 0x11, dword_ptr);
++ }
++ }
++
++ /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
++#define IO_LOCAL_INT(type, intr, apicid, pin) \
++ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin));
++
++ mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0);
++
++ /* SR5650 devices */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((0)<<2)|(2)), apicid_sr5650, 31); /* Device 0 Function 2 (LNKA, APIC pin 31) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((2)<<2)|(0)), apicid_sr5650, 28); /* Device 2 (LNKE, APIC pin 28) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((4)<<2)|(0)), apicid_sr5650, 28); /* Device 4 (LNKF, APIC pin 28) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((9)<<2)|(0)), apicid_sr5650, 29); /* Device 9 (LNKG, APIC pin 29) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */
++
++ dev = dev_find_slot(0, PCI_DEVFN(0x2, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x2)|(0)), apicid_sr5650, 0); /* card behind dev2 */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0x4, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x4)|(0)), apicid_sr5650, 0); /* PIKE */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0x9, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0x9)|(0)), apicid_sr5650, 23); /* NIC A */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0xa, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xa)|(0)), apicid_sr5650, 24); /* NIC B */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0xb, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xb)|(0)), apicid_sr5650, 0); /* card behind dev11 */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0xc, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xc)|(0)), apicid_sr5650, 0); /* card behind dev12 */
++ }
++ dev = dev_find_slot(0, PCI_DEVFN(0xd, 0));
++ if (dev && dev->enabled) {
++ uint8_t bus_pci = dev->link_list->secondary;
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xd)|(0)), apicid_sr5650, 0); /* card behind dev13 */
++ }
++
++ /* PCI interrupts are level triggered, and are
++ * associated with a specific bus/device/function tuple.
++ */
++#define PCI_INT(bus, dev, interrupt_signal, pin) \
++ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(interrupt_signal)), apicid_sp5100, (pin))
++
++ /* USB1 */
++ PCI_INT(sp5100_bus_number, 0x12, 0x0, 0x10); /* OHCI0 Port 0~2 */
++ PCI_INT(sp5100_bus_number, 0x12, 0x1, 0x11); /* OHCI1 Port 3~5 */
++
++ /* USB2 */
++ PCI_INT(sp5100_bus_number, 0x13, 0x0, 0x12); /* OHCI0 Port 6~8 */
++ PCI_INT(sp5100_bus_number, 0x13, 0x1, 0x13); /* EHCI Port 6~11 */
++
++ /* USB3 */
++ PCI_INT(sp5100_bus_number, 0x14, 0x3, 0x12); /* OHCI0 Port 12~13 */
++
++ /* SATA */
++ PCI_INT(sp5100_bus_number, 0x11, 0x0, 0x16); /* 6, INTG */
++
++ /* PCI slots */
++ dev = dev_find_slot(0, PCI_DEVFN(0x14, 4));
++ if (dev && dev->enabled) {
++ u8 bus_pci = dev->link_list->secondary;
++
++ /* PCI_SLOT 0. */
++ PCI_INT(bus_pci, 0x1, 0x0, 0x15);
++ PCI_INT(bus_pci, 0x1, 0x1, 0x16);
++ PCI_INT(bus_pci, 0x1, 0x2, 0x17);
++ PCI_INT(bus_pci, 0x1, 0x3, 0x14);
++
++ /* PCI_SLOT 1. */
++ PCI_INT(bus_pci, 0x2, 0x0, 0x14);
++ PCI_INT(bus_pci, 0x2, 0x1, 0x15);
++ PCI_INT(bus_pci, 0x2, 0x2, 0x16);
++ PCI_INT(bus_pci, 0x2, 0x3, 0x17);
++
++ /* PCI_SLOT 2. */
++ PCI_INT(bus_pci, 0x3, 0x0, 0x16);
++ PCI_INT(bus_pci, 0x3, 0x1, 0x17);
++ PCI_INT(bus_pci, 0x3, 0x2, 0x14);
++ PCI_INT(bus_pci, 0x3, 0x3, 0x15);
++ }
++
++ /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
++ IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0);
++ IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1);
++ /* There is no extension information... */
++
++ /* Compute the checksums */
++ return mptable_finalize(mc);
++}
++
++unsigned long write_smp_table(unsigned long addr)
++{
++ void *v;
++ v = smp_write_floating_table(addr, 0);
++ return (unsigned long)smp_write_config_table(v);
++}
+diff --git a/src/mainboard/asus/kcma-d8/resourcemap.c b/src/mainboard/asus/kcma-d8/resourcemap.c
+new file mode 100644
+index 0000000..8bcb28b
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/resourcemap.c
+@@ -0,0 +1,550 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ *
++ * Copyright (C) 2007 AMD
++ * Written by Yinghai Lu <yinghailu@amd.com> for AMD.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++static void setup_mb_resource_map(void)
++{
++ static const unsigned int fam15h_register_values[] = {
++ /* Careful set limit registers before base registers which contain the enables */
++ /* DRAM Limit i Registers
++ * F1:0x44 i = 0
++ * F1:0x4C i = 1
++ * F1:0x54 i = 2
++ * F1:0x5C i = 3
++ * F1:0x64 i = 4
++ * F1:0x6C i = 5
++ * F1:0x74 i = 6
++ * F1:0x7C i = 7
++ * [ 2: 0] Destination Node ID
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 7: 3] Reserved
++ * [10: 8] Interleave select
++ * specifies the values of A[14:12] to use with interleave enable.
++ * [15:11] Reserved
++ * [31:16] DRAM Limit Address i Bits 39-24
++ * This field defines the upper address bits of a 40 bit address
++ * that define the end of the DRAM region.
++ */
++ // PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x44), 0x0000f8f8, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x4C), 0x0000f8f8, 0x00000001,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x54), 0x0000f8f8, 0x00000002,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x5C), 0x0000f8f8, 0x00000003,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x64), 0x0000f8f8, 0x00000004,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x6C), 0x0000f8f8, 0x00000005,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x74), 0x0000f8f8, 0x00000006,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x7C), 0x0000f8f8, 0x00000007,
++
++ /* DRAM Base i Registers
++ * F1:0x40 i = 0
++ * F1:0x48 i = 1
++ * F1:0x50 i = 2
++ * F1:0x58 i = 3
++ * F1:0x60 i = 4
++ * F1:0x68 i = 5
++ * F1:0x70 i = 6
++ * F1:0x78 i = 7
++ * [ 0: 0] Read Enable
++ * 0 = Reads Disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes Disabled
++ * 1 = Writes Enabled
++ * [ 7: 2] Reserved
++ * [10: 8] Interleave Enable
++ * 000 = No interleave
++ * 001 = Interleave on A[12] (2 nodes)
++ * 010 = reserved
++ * 011 = Interleave on A[12] and A[14] (4 nodes)
++ * 100 = reserved
++ * 101 = reserved
++ * 110 = reserved
++ * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
++ * [15:11] Reserved
++ * [31:16] DRAM Base Address i Bits 39-24
++ * This field defines the upper address bits of a 40-bit address
++ * that define the start of the DRAM region.
++ */
++ // PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x40), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x48), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x50), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x58), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x60), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x68), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x70), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x78), 0x0000f8fc, 0x00000000,
++
++ /* Memory-Mapped I/O Limit i Registers
++ * F1:0x84 i = 0
++ * F1:0x8C i = 1
++ * F1:0x94 i = 2
++ * F1:0x9C i = 3
++ * F1:0xA4 i = 4
++ * F1:0xAC i = 5
++ * F1:0xB4 i = 6
++ * F1:0xBC i = 7
++ * [ 2: 0] Destination Node ID
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 3: 3] Reserved
++ * [ 5: 4] Destination Link ID
++ * 00 = Link 0
++ * 01 = Link 1
++ * 10 = Link 2
++ * 11 = Link 3
++ * [ 6: 6] Reserved
++ * [ 7: 7] Non-Posted
++ * 0 = CPU writes may be posted
++ * 1 = CPU writes must be non-posted
++ * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
++ * This field defines the upp adddress bits of a 40-bit address that
++ * defines the end of a memory-mapped I/O region n
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x84), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x8C), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x94), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x9C), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA4), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xAC), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB4), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xBC), 0x00000048, 0x00000000,
++
++ /* Memory-Mapped I/O Base i Registers
++ * F1:0x80 i = 0
++ * F1:0x88 i = 1
++ * F1:0x90 i = 2
++ * F1:0x98 i = 3
++ * F1:0xA0 i = 4
++ * F1:0xA8 i = 5
++ * F1:0xB0 i = 6
++ * F1:0xB8 i = 7
++ * [ 0: 0] Read Enable
++ * 0 = Reads disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes disabled
++ * 1 = Writes Enabled
++ * [ 2: 2] Cpu Disable
++ * 0 = Cpu can use this I/O range
++ * 1 = Cpu requests do not use this I/O range
++ * [ 3: 3] Lock
++ * 0 = base/limit registers i are read/write
++ * 1 = base/limit registers i are read-only
++ * [ 7: 4] Reserved
++ * [31: 8] Memory-Mapped I/O Base Address i (39-16)
++ * This field defines the upper address bits of a 40bit address
++ * that defines the start of memory-mapped I/O region i
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x80), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x88), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x90), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x98), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA0), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA8), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB0), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB8), 0x000000f0, 0x00000000,
++
++ /* PCI I/O Limit i Registers
++ * F1:0xC4 i = 0
++ * F1:0xCC i = 1
++ * F1:0xD4 i = 2
++ * F1:0xDC i = 3
++ * [ 2: 0] Destination Node ID
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 3: 3] Reserved
++ * [ 5: 4] Destination Link ID
++ * 00 = Link 0
++ * 01 = Link 1
++ * 10 = Link 2
++ * 11 = Link 3
++ * [11: 6] Reserved
++ * [24:12] PCI I/O Limit Address i
++ * This field defines the end of PCI I/O region n
++ * [31:25] Reserved
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff010, /* link 1 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xDC), 0xFE000FC8, 0x00000000,
++
++ /* PCI I/O Base i Registers
++ * F1:0xC0 i = 0
++ * F1:0xC8 i = 1
++ * F1:0xD0 i = 2
++ * F1:0xD8 i = 3
++ * [ 0: 0] Read Enable
++ * 0 = Reads Disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes Disabled
++ * 1 = Writes Enabled
++ * [ 3: 2] Reserved
++ * [ 4: 4] VGA Enable
++ * 0 = VGA matches Disabled
++ * 1 = matches all address < 64K and where A[9:0] is in the
++ * range 3B0-3BB or 3C0-3DF independent of the base & limit registers
++ * [ 5: 5] ISA Enable
++ * 0 = ISA matches Disabled
++ * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
++ * from matching agains this base/limit pair
++ * [11: 6] Reserved
++ * [24:12] PCI I/O Base i
++ * This field defines the start of PCI I/O region n
++ * [31:25] Reserved
++ */
++// PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC0), 0xFE000FCC, 0x00001013,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC8), 0xFE000FCC, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD0), 0xFE000FCC, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD8), 0xFE000FCC, 0x00000000,
++
++ /* Config Base and Limit i Registers
++ * F1:0xE0 i = 0
++ * F1:0xE4 i = 1
++ * F1:0xE8 i = 2
++ * F1:0xEC i = 3
++ * [ 0: 0] Read Enable
++ * 0 = Reads Disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes Disabled
++ * 1 = Writes Enabled
++ * [ 2: 2] Device Number Compare Enable
++ * 0 = The ranges are based on bus number
++ * 1 = The ranges are ranges of devices on bus 0
++ * [ 3: 3] Reserved
++ * [ 6: 4] Destination Node
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 7: 7] Reserved
++ * [ 9: 8] Destination Link
++ * 00 = Link 0
++ * 01 = Link 1
++ * 10 = Link 2
++ * 11 - Link 3
++ * [15:10] Reserved
++ * [23:16] Bus Number Base i
++ * This field defines the lowest bus number in configuration region i
++ * [31:24] Bus Number Limit i
++ * This field defines the highest bus number in configuration region i
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000103, /* link 1 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000,
++
++ };
++
++ static const unsigned int fam10h_register_values[] = {
++ /* Careful set limit registers before base registers which contain the enables */
++ /* DRAM Limit i Registers
++ * F1:0x44 i = 0
++ * F1:0x4C i = 1
++ * F1:0x54 i = 2
++ * F1:0x5C i = 3
++ * F1:0x64 i = 4
++ * F1:0x6C i = 5
++ * F1:0x74 i = 6
++ * F1:0x7C i = 7
++ * [ 2: 0] Destination Node ID
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 7: 3] Reserved
++ * [10: 8] Interleave select
++ * specifies the values of A[14:12] to use with interleave enable.
++ * [15:11] Reserved
++ * [31:16] DRAM Limit Address i Bits 39-24
++ * This field defines the upper address bits of a 40 bit address
++ * that define the end of the DRAM region.
++ */
++ // PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x44), 0x0000f8f8, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x4C), 0x0000f8f8, 0x00000001,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x54), 0x0000f8f8, 0x00000002,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x5C), 0x0000f8f8, 0x00000003,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x64), 0x0000f8f8, 0x00000004,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x6C), 0x0000f8f8, 0x00000005,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x74), 0x0000f8f8, 0x00000006,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x7C), 0x0000f8f8, 0x00000007,
++
++ /* DRAM Base i Registers
++ * F1:0x40 i = 0
++ * F1:0x48 i = 1
++ * F1:0x50 i = 2
++ * F1:0x58 i = 3
++ * F1:0x60 i = 4
++ * F1:0x68 i = 5
++ * F1:0x70 i = 6
++ * F1:0x78 i = 7
++ * [ 0: 0] Read Enable
++ * 0 = Reads Disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes Disabled
++ * 1 = Writes Enabled
++ * [ 7: 2] Reserved
++ * [10: 8] Interleave Enable
++ * 000 = No interleave
++ * 001 = Interleave on A[12] (2 nodes)
++ * 010 = reserved
++ * 011 = Interleave on A[12] and A[14] (4 nodes)
++ * 100 = reserved
++ * 101 = reserved
++ * 110 = reserved
++ * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
++ * [15:11] Reserved
++ * [31:16] DRAM Base Address i Bits 39-24
++ * This field defines the upper address bits of a 40-bit address
++ * that define the start of the DRAM region.
++ */
++ // PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x40), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x48), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x50), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x58), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x60), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x68), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x70), 0x0000f8fc, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x78), 0x0000f8fc, 0x00000000,
++
++ /* Memory-Mapped I/O Limit i Registers
++ * F1:0x84 i = 0
++ * F1:0x8C i = 1
++ * F1:0x94 i = 2
++ * F1:0x9C i = 3
++ * F1:0xA4 i = 4
++ * F1:0xAC i = 5
++ * F1:0xB4 i = 6
++ * F1:0xBC i = 7
++ * [ 2: 0] Destination Node ID
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 3: 3] Reserved
++ * [ 5: 4] Destination Link ID
++ * 00 = Link 0
++ * 01 = Link 1
++ * 10 = Link 2
++ * 11 = Link 3
++ * [ 6: 6] Reserved
++ * [ 7: 7] Non-Posted
++ * 0 = CPU writes may be posted
++ * 1 = CPU writes must be non-posted
++ * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
++ * This field defines the upp adddress bits of a 40-bit address that
++ * defines the end of a memory-mapped I/O region n
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x84), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x8C), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x94), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x9C), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA4), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xAC), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB4), 0x00000048, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xBC), 0x00000048, 0x00000000,
++
++ /* Memory-Mapped I/O Base i Registers
++ * F1:0x80 i = 0
++ * F1:0x88 i = 1
++ * F1:0x90 i = 2
++ * F1:0x98 i = 3
++ * F1:0xA0 i = 4
++ * F1:0xA8 i = 5
++ * F1:0xB0 i = 6
++ * F1:0xB8 i = 7
++ * [ 0: 0] Read Enable
++ * 0 = Reads disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes disabled
++ * 1 = Writes Enabled
++ * [ 2: 2] Cpu Disable
++ * 0 = Cpu can use this I/O range
++ * 1 = Cpu requests do not use this I/O range
++ * [ 3: 3] Lock
++ * 0 = base/limit registers i are read/write
++ * 1 = base/limit registers i are read-only
++ * [ 7: 4] Reserved
++ * [31: 8] Memory-Mapped I/O Base Address i (39-16)
++ * This field defines the upper address bits of a 40bit address
++ * that defines the start of memory-mapped I/O region i
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x80), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x88), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x90), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0x98), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA0), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xA8), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB0), 0x000000f0, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xB8), 0x000000f0, 0x00000000,
++
++ /* PCI I/O Limit i Registers
++ * F1:0xC4 i = 0
++ * F1:0xCC i = 1
++ * F1:0xD4 i = 2
++ * F1:0xDC i = 3
++ * [ 2: 0] Destination Node ID
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 3: 3] Reserved
++ * [ 5: 4] Destination Link ID
++ * 00 = Link 0
++ * 01 = Link 1
++ * 10 = Link 2
++ * 11 = Link 3
++ * [11: 6] Reserved
++ * [24:12] PCI I/O Limit Address i
++ * This field defines the end of PCI I/O region n
++ * [31:25] Reserved
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff110, /* link 3 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xDC), 0xFE000FC8, 0x00000000,
++
++ /* PCI I/O Base i Registers
++ * F1:0xC0 i = 0
++ * F1:0xC8 i = 1
++ * F1:0xD0 i = 2
++ * F1:0xD8 i = 3
++ * [ 0: 0] Read Enable
++ * 0 = Reads Disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes Disabled
++ * 1 = Writes Enabled
++ * [ 3: 2] Reserved
++ * [ 4: 4] VGA Enable
++ * 0 = VGA matches Disabled
++ * 1 = matches all address < 64K and where A[9:0] is in the
++ * range 3B0-3BB or 3C0-3DF independent of the base & limit registers
++ * [ 5: 5] ISA Enable
++ * 0 = ISA matches Disabled
++ * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
++ * from matching agains this base/limit pair
++ * [11: 6] Reserved
++ * [24:12] PCI I/O Base i
++ * This field defines the start of PCI I/O region n
++ * [31:25] Reserved
++ */
++// PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC0), 0xFE000FCC, 0x00001013,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC8), 0xFE000FCC, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD0), 0xFE000FCC, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD8), 0xFE000FCC, 0x00000000,
++
++ /* Config Base and Limit i Registers
++ * F1:0xE0 i = 0
++ * F1:0xE4 i = 1
++ * F1:0xE8 i = 2
++ * F1:0xEC i = 3
++ * [ 0: 0] Read Enable
++ * 0 = Reads Disabled
++ * 1 = Reads Enabled
++ * [ 1: 1] Write Enable
++ * 0 = Writes Disabled
++ * 1 = Writes Enabled
++ * [ 2: 2] Device Number Compare Enable
++ * 0 = The ranges are based on bus number
++ * 1 = The ranges are ranges of devices on bus 0
++ * [ 3: 3] Reserved
++ * [ 6: 4] Destination Node
++ * 000 = Node 0
++ * 001 = Node 1
++ * 010 = Node 2
++ * 011 = Node 3
++ * 100 = Node 4
++ * 101 = Node 5
++ * 110 = Node 6
++ * 111 = Node 7
++ * [ 7: 7] Reserved
++ * [ 9: 8] Destination Link
++ * 00 = Link 0
++ * 01 = Link 1
++ * 10 = Link 2
++ * 11 - Link 3
++ * [15:10] Reserved
++ * [23:16] Bus Number Base i
++ * This field defines the lowest bus number in configuration region i
++ * [31:24] Bus Number Limit i
++ * This field defines the highest bus number in configuration region i
++ */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000303, /* link 3 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000,
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000,
++
++ };
++
++ int max;
++ uint8_t fam15h = 0;
++ uint32_t family;
++
++ family = cpuid_eax(0x80000001);
++ family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
++
++ if (family >= 0x6f)
++ /* Family 15h or later */
++ fam15h = 1;
++
++ if (fam15h) {
++ max = ARRAY_SIZE(fam15h_register_values);
++ setup_resource_map(fam15h_register_values, max);
++ } else {
++ max = ARRAY_SIZE(fam10h_register_values);
++ setup_resource_map(fam10h_register_values, max);
++ }
++}
+diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c
+new file mode 100644
+index 0000000..5df6de4
+--- /dev/null
++++ b/src/mainboard/asus/kcma-d8/romstage.c
+@@ -0,0 +1,608 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ *
++ * Copyright (C) 2007 AMD
++ * Written by Yinghai Lu <yinghailu@amd.com> for AMD.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <stdint.h>
++#include <string.h>
++#include <reset.h>
++#include <device/pci_def.h>
++#include <device/pci_ids.h>
++#include <arch/io.h>
++#include <device/pnp_def.h>
++#include <cpu/x86/lapic.h>
++#include <console/console.h>
++#include <timestamp.h>
++#include <lib.h>
++#include <spd.h>
++#include <cpu/amd/model_10xxx_rev.h>
++#include <northbridge/amd/amdfam10/raminit.h>
++#include <northbridge/amd/amdfam10/amdfam10.h>
++#include "lib/delay.c"
++#include <cpu/x86/lapic.h>
++#include "northbridge/amd/amdfam10/reset_test.c"
++#include <superio/winbond/common/winbond.h>
++#include <superio/winbond/w83667hg-a/w83667hg-a.h>
++#include <cpu/x86/bist.h>
++#include <smp/spinlock.h>
++// #include "northbridge/amd/amdk8/incoherent_ht.c"
++#include <southbridge/amd/sb700/sb700.h>
++#include <southbridge/amd/sb700/smbus.h>
++#include <southbridge/amd/sr5650/sr5650.h>
++#include "northbridge/amd/amdfam10/debug.c"
++#include "northbridge/amd/amdfam10/setup_resource_map.c"
++
++#define SERIAL_DEV PNP_DEV(0x2e, W83667HG_A_SP1)
++
++static void activate_spd_rom(const struct mem_controller *ctrl);
++
++static inline int spd_read_byte(unsigned device, unsigned address)
++{
++ return do_smbus_read_byte(SMBUS_AUX_IO_BASE, device, address);
++}
++
++#include <northbridge/amd/amdfam10/amdfam10.h>
++#include "northbridge/amd/amdfam10/raminit_sysinfo_in_ram.c"
++#include "northbridge/amd/amdfam10/pci.c"
++#include "resourcemap.c"
++#include "cpu/amd/quadcore/quadcore.c"
++
++#include <cpu/amd/microcode.h>
++
++#include "cpu/amd/family_10h-family_15h/init_cpus.c"
++#include "northbridge/amd/amdfam10/early_ht.c"
++
++/*
++ * ASUS KGPE-D16 specific SPD enable/disable magic.
++ *
++ * Setting SP5100 GPIOs 59 and 60 controls an SPI mux with four settings:
++ * 0: Disabled
++ * 1: Normal SPI access
++ * 2: CPU0 SPD
++ * 3: CPU1 SPD
++ *
++ * Disable SPD access after RAM init to allow access to standard SMBus/I2C offsets
++ * which is required e.g. by lm-sensors.
++ */
++
++/* Relevant GPIO register information is available in the
++ * AMD SP5100 Register Reference Guide rev. 3.03, page 130
++ */
++static void switch_spd_mux(uint8_t channel)
++{
++ uint8_t byte;
++
++ byte = pci_read_config8(PCI_DEV(0, 0x14, 0), 0x54);
++ byte &= ~0xc; /* Clear SPD mux GPIOs */
++ byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */
++ byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */
++ pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte);
++}
++
++static const uint8_t spd_addr_fam15[] = {
++ // Socket 0 Node 0 ("Node 0")
++ RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
++ // Socket 0 Node 1 ("Node 1")
++ RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
++ // Socket 1 Node 0 ("Node 2")
++ RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
++ // Socket 1 Node 1 ("Node 3")
++ RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
++};
++
++static const uint8_t spd_addr_fam10[] = {
++ // Socket 0 Node 0 ("Node 0")
++ RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
++ // Socket 0 Node 1 ("Node 1")
++ RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
++ // Socket 1 Node 1 ("Node 2")
++ RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
++ // Socket 1 Node 0 ("Node 3")
++ RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
++};
++
++static void activate_spd_rom(const struct mem_controller *ctrl) {
++ struct sys_info *sysinfo = &sysinfo_car;
++
++ printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id);
++ if (ctrl->node_id == 0) {
++ printk(BIOS_DEBUG, "enable_spd_node0()\n");
++ switch_spd_mux(0x2);
++ } else if (ctrl->node_id == 1) {
++ printk(BIOS_DEBUG, "enable_spd_node1()\n");
++ switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x2:0x3);
++ } else if (ctrl->node_id == 2) {
++ printk(BIOS_DEBUG, "enable_spd_node2()\n");
++ switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x3:0x2);
++ } else if (ctrl->node_id == 3) {
++ printk(BIOS_DEBUG, "enable_spd_node3()\n");
++ switch_spd_mux(0x3);
++ }
++}
++
++/* Voltages are specified by index
++ * Valid indicies for this platform are:
++ * 0: 1.5V
++ * 1: 1.35V
++ * 2: 1.25V
++ * 3: 1.15V
++ */
++static void set_ddr3_voltage(uint8_t node, uint8_t index) {
++ uint8_t byte;
++ uint8_t value = 0;
++
++ if (index == 0)
++ value = 0x0;
++ else if (index == 1)
++ value = 0x1;
++ else if (index == 2)
++ value = 0x4;
++ else if (index == 3)
++ value = 0x5;
++ if (node == 1)
++ value <<= 1;
++
++ /* Set GPIOs */
++ byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd1);
++ if (node == 0)
++ byte &= ~0x5;
++ if (node == 1)
++ byte &= ~0xa;
++ byte |= value;
++ pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd1, byte);
++
++ /* Enable GPIO output drivers */
++ byte = pci_read_config8(PCI_DEV(0, 0x14, 3), 0xd0);
++ byte &= 0x0f;
++ pci_write_config8(PCI_DEV(0, 0x14, 3), 0xd0, byte);
++
++ printk(BIOS_DEBUG, "Node %02d DIMM voltage set to index %02x\n", node, index);
++}
++
++void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
++ struct DCTStatStruc *pDCTstatA) {
++ /* This mainboard allows the DIMM voltage to be set per-socket.
++ * Therefore, for each socket, iterate over all DIMMs to find the
++ * lowest supported voltage common to all DIMMs on that socket.
++ */
++ uint8_t nvram;
++ uint8_t dimm;
++ uint8_t node;
++ uint8_t socket;
++ uint8_t allowed_voltages = 0xf; /* The mainboard VRMs allow 1.15V, 1.25V, 1.35V, and 1.5V */
++ uint8_t socket_allowed_voltages = allowed_voltages;
++ uint32_t set_voltage = 0;
++
++ if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS) {
++ switch (nvram) {
++ case 2:
++ allowed_voltages = 0x7; /* Allow 1.25V, 1.35V, and 1.5V */
++ break;
++ case 1:
++ allowed_voltages = 0x3; /* Allow 1.35V and 1.5V */
++ break;
++ case 0:
++ default:
++ allowed_voltages = 0x1; /* Allow 1.5V only */
++ break;
++ }
++ }
++
++ for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
++ socket = node / 2;
++ struct DCTStatStruc *pDCTstat;
++ pDCTstat = pDCTstatA + node;
++
++ /* reset socket_allowed_voltages before processing each socket */
++ if (!(node % 2))
++ socket_allowed_voltages = allowed_voltages;
++
++ if (pDCTstat->NodePresent) {
++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
++ if (pDCTstat->DIMMValid & (1 << dimm)) {
++ socket_allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm];
++ }
++ }
++ }
++
++ /* set voltage per socket after processing last contained node */
++ if (pDCTstat->NodePresent && (node % 2)) {
++ /* Set voltages */
++ if (socket_allowed_voltages & 0x8) {
++ set_voltage = 0x8;
++ set_ddr3_voltage(socket, 3);
++ } else if (socket_allowed_voltages & 0x4) {
++ set_voltage = 0x4;
++ set_ddr3_voltage(socket, 2);
++ } else if (socket_allowed_voltages & 0x2) {
++ set_voltage = 0x2;
++ set_ddr3_voltage(socket, 1);
++ } else {
++ set_voltage = 0x1;
++ set_ddr3_voltage(socket, 0);
++ }
++
++ /* Save final DIMM voltages for MCT and SMBIOS use */
++ if (pDCTstat->NodePresent) {
++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
++ pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
++ }
++ }
++ pDCTstat = pDCTstatA + (node - 1);
++ if (pDCTstat->NodePresent) {
++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
++ pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
++ }
++ }
++ }
++ }
++
++ /* Allow the DDR supply voltages to settle */
++ udelay(100000);
++}
++
++static void set_peripheral_control_lines(void) {
++ uint8_t byte;
++ uint8_t nvram;
++ uint8_t enable_ieee1394;
++
++ enable_ieee1394 = 1;
++
++ if (get_option(&nvram, "ieee1394_controller") == CB_SUCCESS)
++ enable_ieee1394 = nvram & 0x1;
++
++ if (enable_ieee1394) {
++ /* Enable PCICLK5 (onboard FireWire device) */
++ outb(0x41, 0xcd6);
++ outb(0x02, 0xcd7);
++ } else {
++ /* Disable PCICLK5 (onboard FireWire device) */
++ outb(0x41, 0xcd6);
++ outb(0x00, 0xcd7);
++ }
++
++ /* Enable the RTC AltCentury register */
++ outb(0x41, 0xcd6);
++ byte = inb(0xcd7);
++ byte |= 0x10;
++ outb(byte, 0xcd7);
++}
++
++#ifdef TEST_MEMORY
++static void execute_memory_test(void)
++{
++ /* Test DRAM functionality */
++ uint32_t i;
++ uint32_t* dataptr;
++ printk(BIOS_DEBUG, "Writing test patterns to memory...\n");
++ for (i=0; i < 0x1000000; i = i + 8) {
++ dataptr = (void *)(0x300000 + i);
++ *dataptr = 0x55555555;
++ dataptr = (void *)(0x300000 + i + 4);
++ *dataptr = 0xaaaaaaaa;
++ }
++ printk(BIOS_DEBUG, "Done!\n");
++ printk(BIOS_DEBUG, "Testing memory...\n");
++ uint32_t readback;
++ for (i=0; i < 0x1000000; i = i + 8) {
++ dataptr = (void *)(0x300000 + i);
++ readback = *dataptr;
++ if (readback != 0x55555555)
++ printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0x55555555);
++ dataptr = (void *)(0x300000 + i + 4);
++ readback = *dataptr;
++ if (readback != 0xaaaaaaaa)
++ printk(BIOS_DEBUG, "%p: INCORRECT VALUE %08x (should have been %08x)\n", dataptr, readback, 0xaaaaaaaa);
++ }
++ printk(BIOS_DEBUG, "Done!\n");
++}
++#endif
++
++static spinlock_t printk_spinlock CAR_GLOBAL;
++
++spinlock_t* romstage_console_lock(void)
++{
++ return car_get_var_ptr(&printk_spinlock);
++}
++
++void initialize_romstage_console_lock(void)
++{
++ car_get_var(printk_spinlock) = SPIN_LOCK_UNLOCKED;
++}
++
++static spinlock_t nvram_cbfs_spinlock CAR_GLOBAL;
++
++spinlock_t* romstage_nvram_cbfs_lock(void)
++{
++ return car_get_var_ptr(&nvram_cbfs_spinlock);
++}
++
++void initialize_romstage_nvram_cbfs_lock(void)
++{
++ car_get_var(nvram_cbfs_spinlock) = SPIN_LOCK_UNLOCKED;
++}
++
++static spinlock_t microcode_cbfs_spinlock CAR_GLOBAL;
++
++spinlock_t* romstage_microcode_cbfs_lock(void)
++{
++ return car_get_var_ptr(&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 0000000..a645e3d
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0044-mainboard-asus-kcma-d8-Initial-modification-for-KCMA.patch
@@ -0,0 +1,156 @@
+From ebf04615b9589056c09cded45521499e8eefe8e1 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:12:08 -0600
+Subject: [PATCH 44/45] mainboard/asus/kcma-d8: Initial modification for
+ KCMA-D8 name strings
+
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kcma-d8/Kconfig | 18 +++++++++---------
+ src/mainboard/asus/kcma-d8/Kconfig.name | 4 ++--
+ src/mainboard/asus/kcma-d8/mainboard.c | 2 +-
+ src/mainboard/asus/kcma-d8/romstage.c | 24 +++++-------------------
+ 4 files changed, 17 insertions(+), 31 deletions(-)
+
+diff --git a/src/mainboard/asus/kcma-d8/Kconfig b/src/mainboard/asus/kcma-d8/Kconfig
+index 23c91f0..3c8cdcd 100644
+--- a/src/mainboard/asus/kcma-d8/Kconfig
++++ b/src/mainboard/asus/kcma-d8/Kconfig
+@@ -1,8 +1,8 @@
+-if BOARD_ASUS_KGPE_D16
++if BOARD_ASUS_KCMA_D8
+
+ config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+- select CPU_AMD_SOCKET_G34_NON_AGESA
++ select CPU_AMD_SOCKET_C32_NON_AGESA
+ select DIMM_DDR3
+ select DIMM_REGISTERED
+ # select QRANK_DIMM_SUPPORT
+@@ -37,11 +37,11 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+
+ config MAINBOARD_DIR
+ string
+- default "asus/kgpe-d16"
++ default "asus/kcma-d8"
+
+ config BOOTBLOCK_MAINBOARD_INIT
+ string
+- default "mainboard/asus/kgpe-d16/bootblock.c"
++ default "mainboard/asus/kcma-d8/bootblock.c"
+
+ config DCACHE_RAM_BASE
+ hex
+@@ -57,7 +57,7 @@ config APIC_ID_OFFSET
+
+ config MAINBOARD_PART_NUMBER
+ string
+- default "KGPE-D16"
++ default "KCMA-D8"
+
+ config HW_MEM_HOLE_SIZEK
+ hex
+@@ -65,12 +65,12 @@ config HW_MEM_HOLE_SIZEK
+
+ config MAX_CPUS
+ int
+- default 32
++ default 16
+
+-# 2 (internal) processors per G34 socket
++# 1 (internal) processor per C32 socket
+ config MAX_PHYSICAL_CPUS
+ int
+- default 4
++ default 2
+
+ config HT_CHAIN_UNITID_BASE
+ hex
+@@ -100,4 +100,4 @@ config MAX_REBOOT_CNT
+ int
+ default 10
+
+-endif # BOARD_ASUS_KGPE_D16
++endif # BOARD_ASUS_KCMA_D8
+diff --git a/src/mainboard/asus/kcma-d8/Kconfig.name b/src/mainboard/asus/kcma-d8/Kconfig.name
+index bdfa31a..69b63ea 100644
+--- a/src/mainboard/asus/kcma-d8/Kconfig.name
++++ b/src/mainboard/asus/kcma-d8/Kconfig.name
+@@ -1,2 +1,2 @@
+-config BOARD_ASUS_KGPE_D16
+- bool "KGPE-D16"
++config BOARD_ASUS_KCMA_D8
++ bool "KCMA-D8"
+diff --git a/src/mainboard/asus/kcma-d8/mainboard.c b/src/mainboard/asus/kcma-d8/mainboard.c
+index 65029d4..0219ee6 100644
+--- a/src/mainboard/asus/kcma-d8/mainboard.c
++++ b/src/mainboard/asus/kcma-d8/mainboard.c
+@@ -52,7 +52,7 @@ void set_pcie_dereset(void)
+ *************************************************/
+ static void mainboard_enable(device_t dev)
+ {
+- printk(BIOS_INFO, "Mainboard KGPE-D16 Enable. dev=0x%p\n", dev);
++ printk(BIOS_INFO, "Mainboard KCMA-D8 initializing, dev=0x%p\n", dev);
+
+ msr_t msr, msr2;
+
+diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c
+index 5df6de4..0b9a2ef 100644
+--- a/src/mainboard/asus/kcma-d8/romstage.c
++++ b/src/mainboard/asus/kcma-d8/romstage.c
+@@ -1,7 +1,7 @@
+ /*
+ * This file is part of the coreboot project.
+ *
+- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2015 Raptor Engineering
+ *
+ * Copyright (C) 2007 AMD
+ * Written by Yinghai Lu <yinghailu@amd.com> for AMD.
+@@ -67,7 +67,7 @@ static inline int spd_read_byte(unsigned device, unsigned address)
+ #include "northbridge/amd/amdfam10/early_ht.c"
+
+ /*
+- * ASUS KGPE-D16 specific SPD enable/disable magic.
++ * ASUS KCMA-D8 specific SPD enable/disable magic.
+ *
+ * Setting SP5100 GPIOs 59 and 60 controls an SPI mux with four settings:
+ * 0: Disabled
+@@ -116,22 +116,8 @@ static const uint8_t spd_addr_fam10[] = {
+ };
+
+ static void activate_spd_rom(const struct mem_controller *ctrl) {
+- struct sys_info *sysinfo = &sysinfo_car;
+-
++ /* Nothing needs to be done as there is no SPD mux on this board */
+ printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id);
+- if (ctrl->node_id == 0) {
+- printk(BIOS_DEBUG, "enable_spd_node0()\n");
+- switch_spd_mux(0x2);
+- } else if (ctrl->node_id == 1) {
+- printk(BIOS_DEBUG, "enable_spd_node1()\n");
+- switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x2:0x3);
+- } else if (ctrl->node_id == 2) {
+- printk(BIOS_DEBUG, "enable_spd_node2()\n");
+- switch_spd_mux((is_fam15h() || (sysinfo->nodes <= 2))?0x3:0x2);
+- } else if (ctrl->node_id == 3) {
+- printk(BIOS_DEBUG, "enable_spd_node3()\n");
+- switch_spd_mux(0x3);
+- }
+ }
+
+ /* Voltages are specified by index
+@@ -414,8 +400,8 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
+ enable_sr5650_dev8();
+ sb7xx_51xx_lpc_init();
+
+- if (CONFIG_MAX_PHYSICAL_CPUS != 4)
+- printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD G34 board!\n", CONFIG_MAX_PHYSICAL_CPUS);
++ if (CONFIG_MAX_PHYSICAL_CPUS != 2)
++ printk(BIOS_WARNING, "CONFIG_MAX_PHYSICAL_CPUS is %d, but this is a dual socket AMD C32 board!\n", CONFIG_MAX_PHYSICAL_CPUS);
+
+ /* Halt if there was a built in self test failure */
+ report_bist_failure(bist);
+--
+2.1.4
+
diff --git a/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch
new file mode 100644
index 0000000..77c06ab
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/grub/kcma-d8/0045-mainboard-asus-kcma-d8-Add-initial-ASUS-KCMA-D8-supp.patch
@@ -0,0 +1,575 @@
+From adf6ee421b7dd921617871905baf925cb1708646 Mon Sep 17 00:00:00 2001
+From: Timothy Pearson <tpearson@raptorengineeringinc.com>
+Date: Tue, 24 Nov 2015 14:17:49 -0600
+Subject: [PATCH 45/45] mainboard/asus/kcma-d8: Add initial ASUS KCMA-D8
+ support
+
+Change-Id: Idefa304a27823c741fab72ff5c2f20fed1aa5a39
+Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
+---
+ src/mainboard/asus/kcma-d8/cmos.default | 1 -
+ src/mainboard/asus/kcma-d8/cmos.layout | 1 -
+ src/mainboard/asus/kcma-d8/devicetree.cb | 46 ++++++----------
+ src/mainboard/asus/kcma-d8/dsdt.asl | 92 +++++++++-----------------------
+ src/mainboard/asus/kcma-d8/mptable.c | 34 ++++++------
+ src/mainboard/asus/kcma-d8/resourcemap.c | 8 +--
+ src/mainboard/asus/kcma-d8/romstage.c | 62 ++++++---------------
+ 7 files changed, 80 insertions(+), 164 deletions(-)
+
+diff --git a/src/mainboard/asus/kcma-d8/cmos.default b/src/mainboard/asus/kcma-d8/cmos.default
+index 0e7afb3..c8edd97 100644
+--- a/src/mainboard/asus/kcma-d8/cmos.default
++++ b/src/mainboard/asus/kcma-d8/cmos.default
+@@ -23,7 +23,6 @@ sata_alpm = Disable
+ maximum_p_state_limit = 0xf
+ probe_filter = Auto
+ l3_cache_partitioning = Disable
+-ieee1394_controller = Enable
+ gart = Enable
+ experimental_memory_speed_boost = Disable
+ power_on_after_fail = On
+diff --git a/src/mainboard/asus/kcma-d8/cmos.layout b/src/mainboard/asus/kcma-d8/cmos.layout
+index 075388e..9bda1f6 100644
+--- a/src/mainboard/asus/kcma-d8/cmos.layout
++++ b/src/mainboard/asus/kcma-d8/cmos.layout
+@@ -46,7 +46,6 @@ entries
+ 473 2 e 13 dimm_spd_checksum
+ 475 1 e 14 probe_filter
+ 476 1 e 1 l3_cache_partitioning
+-477 1 e 1 ieee1394_controller
+ 478 1 e 1 iommu
+ 479 1 e 1 cpu_core_boost
+ 480 1 e 1 experimental_memory_speed_boost
+diff --git a/src/mainboard/asus/kcma-d8/devicetree.cb b/src/mainboard/asus/kcma-d8/devicetree.cb
+index 8d64ac7..1830f89 100644
+--- a/src/mainboard/asus/kcma-d8/devicetree.cb
++++ b/src/mainboard/asus/kcma-d8/devicetree.cb
+@@ -7,11 +7,10 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ device domain 0 on # PCI domain
+ subsystemid 0x1043 0x8163 inherit
+ chip northbridge/amd/amdfam10 # Northbridge / RAM controller
+- register "maximum_memory_capacity" = "0x4000000000" # 256GB
++ register "maximum_memory_capacity" = "0x2000000000" # 128GB
+ device pci 18.0 on end # Link 0 == LDT 0
+ device pci 18.0 on end # Link 1 == LDT 1
+- device pci 18.0 on end # Link 2 == LDT 2
+- device pci 18.0 on # Link 3 == LDT 3 [SB on link 3]
++ device pci 18.0 on # Link 2 == LDT 2 [SB on link 2]
+ chip southbridge/amd/sr5650 # Primary southbridge
+ device pci 0.0 on end # HT Root Complex 0x9600
+ device pci 0.1 on end # CLKCONFIG
+@@ -36,16 +35,10 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ device pci b.0 on # Bridge (GPP2 Port0)
+ # Slot # PCI E 4
+ end
+- device pci c.0 on # Bridge (GPP2 Port1)
+- # Slot # PCI E 5
+- end
+- device pci d.0 on # Bridge (GPP3b Port0)
+- # Slot # PCI E 3
+- end
+ register "gpp1_configuration" = "0" # Configuration 16:0 default
+ register "gpp2_configuration" = "1" # Configuration 8:8
+ register "gpp3a_configuration" = "2" # Configuration 4:1:1:0:0:0
+- register "port_enable" = "0x3f1c" # Enable all ports except 0, 1, 5, 6, and 7
++ register "port_enable" = "0x0f1c" # Enable all ports except 0, 1, 5, 6, and 7
+ register "pcie_settling_time" = "1000000" # Allow PIKE to be detected / configured
+ end
+ chip southbridge/amd/sb700 # Secondary southbridge
+@@ -150,7 +143,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ register "vsen5_low_limit_mv" = "1150" # VSEN5 (Node 0 HT link voltage) low limit to 1.15V
+ register "vsen6_high_limit_mv" = "1250" # VSEN6 (Node 1 HT link voltage) high limit to 1.25V
+ register "vsen6_low_limit_mv" = "1150" # VSEN6 (Node 1 HT link voltage) low limit to 1.15V
+- register "vsen7_high_limit_mv" = "1250" # VSEN7 (Northbridge core voltage) high limit to 1.25V
++ register "vsen7_high_limit_mv" = "1150" # VSEN7 (Northbridge core voltage) high limit to 1.15V
+ register "vsen7_low_limit_mv" = "1050" # VSEN7 (Northbridge core voltage) low limit to 1.05V
+ register "vsen8_high_limit_mv" = "1900" # VSEN8 (+1.8V) high limit to 1.9V
+ register "vsen8_low_limit_mv" = "1700" # VSEN8 (+1.8V) low limit to 1.7V
+@@ -178,8 +171,8 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ device pci 14.2 on end # HDA 0x4383 (ASUS MIO add-on card)
+ device pci 14.3 on # LPC 0x439d (SMBUS primary controller)
+ chip superio/winbond/w83667hg-a # Super I/O
+- device pnp 2e.0 off end # FDC; Not available on the KGPE-D16
+- device pnp 2e.1 off end # LPT1; Not available on the KGPE-D16
++ device pnp 2e.0 off end # FDC; Not available on the KCMA-D8
++ device pnp 2e.1 off end # LPT1; Not available on the KCMA-D8
+ device pnp 2e.2 on # Com1
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+@@ -194,7 +187,7 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ irq 0x70 = 1
+ irq 0x72 = 12
+ end
+- device pnp 2e.6 off end # SPI: Not available on the KGPE-D16
++ device pnp 2e.6 off end # SPI: Not available on the KCMA-D8
+ device pnp 2e.7 off end # GIPO6789
+ device pnp 2e.8 off end # WDT
+ device pnp 2e.9 off end # GPIO2345
+@@ -210,11 +203,16 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ end
+ end
+ device pci 14.4 on # Bridge
+- device pci 1.0 on end # VGA
+- device pci 2.0 on end # FireWire
+- device pci 3.0 on # Slot
++ device pci 1.0 on # Slot
+ # Slot # PCI 0
+ end
++ device pci 2.0 on # Slot
++ # Slot # PCI 1
++ end
++ device pci 3.0 on # Slot
++ # Slot # PCI 2
++ end
++ device pci 5.0 on end # VGA
+ end
+ device pci 14.5 on end # USB OHCI2 0x4399
+ end
+@@ -224,24 +222,12 @@ chip northbridge/amd/amdfam10/root_complex # Root complex
+ device pci 18.3 on end
+ device pci 18.4 on end
+ device pci 18.5 on end
+- device pci 19.0 on end # Socket 0 node 1
++ device pci 19.0 on end # Socket 1 node 0
+ device pci 19.1 on end
+ device pci 19.2 on end
+ device pci 19.3 on end
+ device pci 19.4 on end
+ device pci 19.5 on end
+- device pci 1a.0 on end # Socket 1 node 0
+- device pci 1a.1 on end
+- device pci 1a.2 on end
+- device pci 1a.3 on end
+- device pci 1a.4 on end
+- device pci 1a.5 on end
+- device pci 1b.0 on end # Socket 1 node 1
+- device pci 1b.1 on end
+- device pci 1b.2 on end
+- device pci 1b.3 on end
+- device pci 1b.4 on end
+- device pci 1b.5 on end
+ end
+ end
+ end
+diff --git a/src/mainboard/asus/kcma-d8/dsdt.asl b/src/mainboard/asus/kcma-d8/dsdt.asl
+index 5f9195a..ef87d31 100644
+--- a/src/mainboard/asus/kcma-d8/dsdt.asl
++++ b/src/mainboard/asus/kcma-d8/dsdt.asl
+@@ -1,7 +1,7 @@
+ /*
+ * This file is part of the coreboot project.
+ *
+- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
++ * Copyright (C) 2015 Raptor Engineering
+ * Copyright (C) 2005 - 2012 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2004 Nick Barker <Nick.Barker9@btinternet.com>
+@@ -116,8 +116,6 @@ DefinitionBlock (
+ Notify (\_SB.PCI0.NICA, 0x02) /* NOTIFY_DEVICE_WAKE */
+ Notify (\_SB.PCI0.NICB, 0x02) /* NOTIFY_DEVICE_WAKE */
+ Notify (\_SB.PCI0.PCE4, 0x02) /* NOTIFY_DEVICE_WAKE */
+- Notify (\_SB.PCI0.PCE5, 0x02) /* NOTIFY_DEVICE_WAKE */
+- Notify (\_SB.PCI0.PCE3, 0x02) /* NOTIFY_DEVICE_WAKE */
+ }
+
+ } /* End Scope GPE */
+@@ -125,13 +123,13 @@ DefinitionBlock (
+ /* Root of the bus hierarchy */
+ Scope (\_SB)
+ {
+- /* Top southbridge PCI device (SR5690 + SP5100) */
++ /* Top southbridge PCI device (SR5670 + SP5100) */
+ Device (PCI0)
+ {
+ /* BUS0 root bus */
+
+- Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5690) */
+- Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */
++ Name (_HID, EisaId ("PNP0A08")) /* PCI-e root bus (SR5670) */
++ Name (_CID, EisaId ("PNP0A03")) /* PCI root bus (SP5100) */
+ Name (_ADR, 0x00180001)
+ Name (_UID, 0x00)
+
+@@ -162,7 +160,7 @@ DefinitionBlock (
+ /* PCI Routing Tables */
+ Name (PR00, Package () {
+ /* PIC */
+- /* Top southbridge device (SR5690) */
++ /* Top southbridge device (SR5670) */
+ /* HT Link */
+ Package (0x04) { 0x0000FFFF, 0x00, LNKA, 0x00 },
+
+@@ -178,12 +176,6 @@ DefinitionBlock (
+ /* PCI-E Slot 4 (Bridge) */
+ Package (0x04) { 0x000BFFFF, 0x00, LNKG, 0x00 },
+
+- /* PCI-E Slot 5 (Bridge) */
+- Package (0x04) { 0x000CFFFF, 0x00, LNKG, 0x00 },
+-
+- /* PCI-E Slot 3 (Bridge) */
+- Package (0x04) { 0x000DFFFF, 0x00, LNKG, 0x00 },
+-
+ /* Bottom southbridge device (SP5100) */
+ /* SATA 0 */
+ Package (0x04) { 0x0011FFFF, 0x00, LNKG, 0x00 },
+@@ -200,7 +192,7 @@ DefinitionBlock (
+ Package (0x04) { 0x0013FFFF, 0x02, LNKA, 0x00 },
+ Package (0x04) { 0x0013FFFF, 0x03, LNKB, 0x00 },
+
+- /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */
++ /* SMBUS / IDE / LPC / VGA / PCI Slots 0 - 2 */
+ Package (0x04) { 0x0014FFFF, 0x00, LNKA, 0x00 },
+ Package (0x04) { 0x0014FFFF, 0x01, LNKB, 0x00 },
+ Package (0x04) { 0x0014FFFF, 0x02, LNKC, 0x00 },
+@@ -209,7 +201,7 @@ DefinitionBlock (
+
+ Name (AR00, Package () {
+ /* APIC */
+- /* Top southbridge device (SR5690) */
++ /* Top southbridge device (SR5670) */
+ /* HT Link */
+ Package (0x04) { 0x0000FFFF, 0x00, 0x00, 55 },
+
+@@ -225,12 +217,6 @@ DefinitionBlock (
+ /* PCI-E Slot 4 (Bridge) */
+ Package (0x04) { 0x000BFFFF, 0x00, 0x00, 54 },
+
+- /* PCI-E Slot 5 (Bridge) */
+- Package (0x04) { 0x000CFFFF, 0x00, 0x00, 54 },
+-
+- /* PCI-E Slot 3 (Bridge) */
+- Package (0x04) { 0x000DFFFF, 0x00, 0x00, 54 },
+-
+ /* Bottom southbridge device (SP5100) */
+ /* SATA 0 */
+ Package (0x04) { 0x0011FFFF, 0x00, 0x00, 22 },
+@@ -247,7 +233,7 @@ DefinitionBlock (
+ Package (0x04) { 0x0013FFFF, 0x02, 0x00, 16 },
+ Package (0x04) { 0x0013FFFF, 0x03, 0x00, 17 },
+
+- /* SMBUS / IDE / LPC / VGA / FireWire / PCI Slot 0 */
++ /* SMBUS / IDE / LPC / VGA / PCI Slots 0 - 2 */
+ Package (0x04) { 0x0014FFFF, 0x00, 0x00, 16 },
+ Package (0x04) { 0x0014FFFF, 0x01, 0x00, 17 },
+ Package (0x04) { 0x0014FFFF, 0x02, 0x00, 18 },
+@@ -256,22 +242,36 @@ DefinitionBlock (
+
+ Name (PR01, Package () {
+ /* PIC */
+- Package (0x04) { 0x1FFFF, 0x00, LNKF, 0x00 },
+- Package (0x04) { 0x2FFFF, 0x00, LNKE, 0x00 },
++ Package (0x04) { 0x1FFFF, 0x00, LNKE, 0x00 },
++ Package (0x04) { 0x1FFFF, 0x01, LNKF, 0x00 },
++ Package (0x04) { 0x1FFFF, 0x02, LNKG, 0x00 },
++ Package (0x04) { 0x1FFFF, 0x03, LNKH, 0x00 },
++ Package (0x04) { 0x2FFFF, 0x00, LNKF, 0x00 },
++ Package (0x04) { 0x2FFFF, 0x01, LNKG, 0x00 },
++ Package (0x04) { 0x2FFFF, 0x02, LNKH, 0x00 },
++ Package (0x04) { 0x2FFFF, 0x03, LNKE, 0x00 },
+ Package (0x04) { 0x3FFFF, 0x00, LNKG, 0x00 },
+ Package (0x04) { 0x3FFFF, 0x01, LNKH, 0x00 },
+ Package (0x04) { 0x3FFFF, 0x02, LNKE, 0x00 },
+ Package (0x04) { 0x3FFFF, 0x03, LNKF, 0x00 },
++ Package (0x04) { 0x5FFFF, 0x00, LNKH, 0x00 },
+ })
+
+ Name (AR01, Package () {
+ /* APIC */
+- Package (0x04) { 0x1FFFF, 0x00, 0x00, 21 },
+- Package (0x04) { 0x2FFFF, 0x00, 0x00, 20 },
++ Package (0x04) { 0x1FFFF, 0x00, 0x00, 20 },
++ Package (0x04) { 0x1FFFF, 0x01, 0x00, 21 },
++ Package (0x04) { 0x1FFFF, 0x02, 0x00, 22 },
++ Package (0x04) { 0x1FFFF, 0x03, 0x00, 23 },
++ Package (0x04) { 0x2FFFF, 0x00, 0x00, 21 },
++ Package (0x04) { 0x2FFFF, 0x01, 0x00, 22 },
++ Package (0x04) { 0x2FFFF, 0x02, 0x00, 23 },
++ Package (0x04) { 0x2FFFF, 0x03, 0x00, 20 },
+ Package (0x04) { 0x3FFFF, 0x00, 0x00, 22 },
+ Package (0x04) { 0x3FFFF, 0x01, 0x00, 23 },
+ Package (0x04) { 0x3FFFF, 0x02, 0x00, 20 },
+ Package (0x04) { 0x3FFFF, 0x03, 0x00, 21 },
++ Package (0x04) { 0x5FFFF, 0x00, 0x00, 23 },
+ })
+
+ Name (PR02, Package () {
+@@ -734,46 +734,6 @@ DefinitionBlock (
+ Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
+ }
+ }
+-
+- /* 6:00.0 PCIe x16 */
+- Device (PCE5)
+- {
+- Name (_ADR, 0x000C0000) // _ADR: Address
+- Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
+- Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
+- {
+- If (PICM) {
+- Return (AR07)
+- } Else {
+- Return (PR07)
+- }
+- }
+- Device (SLT1)
+- {
+- Name (_ADR, 0xFFFF) // _ADR: Address
+- Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
+- }
+- }
+-
+- /* 7:00.0 PCIe x16 */
+- Device (PCE3)
+- {
+- Name (_ADR, 0x000D0000) // _ADR: Address
+- Name(_PRW, Package () {0x11, 0x04}) // Wake from S1-S4
+- Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
+- {
+- If (PICM) {
+- Return (AR08)
+- } Else {
+- Return (PR08)
+- }
+- }
+- Device (SLT1)
+- {
+- Name (_ADR, 0xFFFF) // _ADR: Address
+- Name(_PRW, Package () {0x0B, 0x04}) // Wake from S1-S4
+- }
+- }
+ }
+
+ Device (PWRB) { /* Start Power button device */
+diff --git a/src/mainboard/asus/kcma-d8/mptable.c b/src/mainboard/asus/kcma-d8/mptable.c
+index c869d31..8967560 100644
+--- a/src/mainboard/asus/kcma-d8/mptable.c
++++ b/src/mainboard/asus/kcma-d8/mptable.c
+@@ -132,7 +132,6 @@ static void *smp_write_config_table(void *v)
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((10)<<2)|(0)), apicid_sr5650, 30); /* Device 10 (LNKG, APIC pin 30) */
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((11)<<2)|(0)), apicid_sr5650, 30); /* Device 11 (LNKG, APIC pin 30) */
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((12)<<2)|(0)), apicid_sr5650, 30); /* Device 12 (LNKG, APIC pin 30) */
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 30); /* Device 13 (LNKG, APIC pin 30)) */
+
+ dev = dev_find_slot(0, PCI_DEVFN(0x2, 0));
+ if (dev && dev->enabled) {
+@@ -164,11 +163,6 @@ static void *smp_write_config_table(void *v)
+ uint8_t bus_pci = dev->link_list->secondary;
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xc)|(0)), apicid_sr5650, 0); /* card behind dev12 */
+ }
+- dev = dev_find_slot(0, PCI_DEVFN(0xd, 0));
+- if (dev && dev->enabled) {
+- uint8_t bus_pci = dev->link_list->secondary;
+- smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_pci, (((0)<<0xd)|(0)), apicid_sr5650, 0); /* card behind dev13 */
+- }
+
+ /* PCI interrupts are level triggered, and are
+ * associated with a specific bus/device/function tuple.
+@@ -195,23 +189,29 @@ static void *smp_write_config_table(void *v)
+ if (dev && dev->enabled) {
+ u8 bus_pci = dev->link_list->secondary;
+
+- /* PCI_SLOT 0. */
+- PCI_INT(bus_pci, 0x1, 0x0, 0x15);
+- PCI_INT(bus_pci, 0x1, 0x1, 0x16);
+- PCI_INT(bus_pci, 0x1, 0x2, 0x17);
+- PCI_INT(bus_pci, 0x1, 0x3, 0x14);
++ /* PCI_SLOT 0 */
++ PCI_INT(bus_pci, 0x1, 0x0, 0x14);
++ PCI_INT(bus_pci, 0x1, 0x1, 0x15);
++ PCI_INT(bus_pci, 0x1, 0x2, 0x16);
++ PCI_INT(bus_pci, 0x1, 0x3, 0x17);
+
+- /* PCI_SLOT 1. */
+- PCI_INT(bus_pci, 0x2, 0x0, 0x14);
+- PCI_INT(bus_pci, 0x2, 0x1, 0x15);
+- PCI_INT(bus_pci, 0x2, 0x2, 0x16);
+- PCI_INT(bus_pci, 0x2, 0x3, 0x17);
++ /* PCI_SLOT 1 */
++ PCI_INT(bus_pci, 0x2, 0x0, 0x15);
++ PCI_INT(bus_pci, 0x2, 0x1, 0x16);
++ PCI_INT(bus_pci, 0x2, 0x2, 0x17);
++ PCI_INT(bus_pci, 0x2, 0x3, 0x14);
+
+- /* PCI_SLOT 2. */
++ /* PCI_SLOT 2 */
+ PCI_INT(bus_pci, 0x3, 0x0, 0x16);
+ PCI_INT(bus_pci, 0x3, 0x1, 0x17);
+ PCI_INT(bus_pci, 0x3, 0x2, 0x14);
+ PCI_INT(bus_pci, 0x3, 0x3, 0x15);
++
++ /* VGA */
++ PCI_INT(bus_pci, 0x5, 0x0, 0x17);
++ PCI_INT(bus_pci, 0x5, 0x1, 0x14);
++ PCI_INT(bus_pci, 0x5, 0x2, 0x15);
++ PCI_INT(bus_pci, 0x5, 0x3, 0x16);
+ }
+
+ /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
+diff --git a/src/mainboard/asus/kcma-d8/resourcemap.c b/src/mainboard/asus/kcma-d8/resourcemap.c
+index 8bcb28b..f7a2133 100644
+--- a/src/mainboard/asus/kcma-d8/resourcemap.c
++++ b/src/mainboard/asus/kcma-d8/resourcemap.c
+@@ -196,7 +196,7 @@ static void setup_mb_resource_map(void)
+ * This field defines the end of PCI I/O region n
+ * [31:25] Reserved
+ */
+- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff010, /* link 1 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff020, /* link 2 of cpu 0 --> AMD SR5690 */
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xDC), 0xFE000FC8, 0x00000000,
+@@ -267,7 +267,7 @@ static void setup_mb_resource_map(void)
+ * [31:24] Bus Number Limit i
+ * This field defines the highest bus number in configuration region i
+ */
+- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000103, /* link 1 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000203, /* link 2 of cpu 0 --> AMD SR5690 */
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000,
+@@ -451,7 +451,7 @@ static void setup_mb_resource_map(void)
+ * This field defines the end of PCI I/O region n
+ * [31:25] Reserved
+ */
+- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff110, /* link 3 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xC4), 0xFE000FC8, 0x00fff020, /* link 2 of cpu 0 --> AMD SR5690 */
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xCC), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xD4), 0xFE000FC8, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xDC), 0xFE000FC8, 0x00000000,
+@@ -522,7 +522,7 @@ static void setup_mb_resource_map(void)
+ * [31:24] Bus Number Limit i
+ * This field defines the highest bus number in configuration region i
+ */
+- PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000303, /* link 3 of cpu 0 --> AMD SR5690 */
++ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE0), 0x0000FC88, 0x05000203, /* link 2 of cpu 0 --> AMD SR5690 */
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE4), 0x0000FC88, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xE8), 0x0000FC88, 0x00000000,
+ PCI_ADDR(CONFIG_CBB, CONFIG_CDB, 1, 0xEC), 0x0000FC88, 0x00000000,
+diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c
+index 0b9a2ef..c9e0af5 100644
+--- a/src/mainboard/asus/kcma-d8/romstage.c
++++ b/src/mainboard/asus/kcma-d8/romstage.c
+@@ -96,28 +96,26 @@ static void switch_spd_mux(uint8_t channel)
+ static const uint8_t spd_addr_fam15[] = {
+ // Socket 0 Node 0 ("Node 0")
+ RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
+- // Socket 0 Node 1 ("Node 1")
+- RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
+- // Socket 1 Node 0 ("Node 2")
++ // Socket 1 Node 0 ("Node 1")
+ RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
+- // Socket 1 Node 1 ("Node 3")
+- RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
+ };
+
+ static const uint8_t spd_addr_fam10[] = {
+ // Socket 0 Node 0 ("Node 0")
+ RC00, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
+- // Socket 0 Node 1 ("Node 1")
+- RC00, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
+- // Socket 1 Node 1 ("Node 2")
+- RC01, DIMM4, DIMM5, 0, 0, DIMM6, DIMM7, 0, 0,
+- // Socket 1 Node 0 ("Node 3")
++ // Socket 1 Node 0 ("Node 1")
+ RC01, DIMM0, DIMM1, 0, 0, DIMM2, DIMM3, 0, 0,
+ };
+
+ static void activate_spd_rom(const struct mem_controller *ctrl) {
+- /* Nothing needs to be done as there is no SPD mux on this board */
+ printk(BIOS_DEBUG, "activate_spd_rom() for node %02x\n", ctrl->node_id);
++ if (ctrl->node_id == 0) {
++ printk(BIOS_DEBUG, "enable_spd_node0()\n");
++ switch_spd_mux(0x2);
++ } else if (ctrl->node_id == 1) {
++ printk(BIOS_DEBUG, "enable_spd_node1()\n");
++ switch_spd_mux(0x3);
++ }
+ }
+
+ /* Voltages are specified by index
+@@ -189,13 +187,12 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
+ }
+
+ for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
+- socket = node / 2;
++ socket = node;
+ struct DCTStatStruc *pDCTstat;
+ pDCTstat = pDCTstatA + node;
+
+ /* reset socket_allowed_voltages before processing each socket */
+- if (!(node % 2))
+- socket_allowed_voltages = allowed_voltages;
++ socket_allowed_voltages = allowed_voltages;
+
+ if (pDCTstat->NodePresent) {
+ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+@@ -203,10 +200,7 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
+ socket_allowed_voltages &= pDCTstat->DimmSupportedVoltages[dimm];
+ }
+ }
+- }
+
+- /* set voltage per socket after processing last contained node */
+- if (pDCTstat->NodePresent && (node % 2)) {
+ /* Set voltages */
+ if (socket_allowed_voltages & 0x8) {
+ set_voltage = 0x8;
+@@ -223,16 +217,8 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
+ }
+
+ /* Save final DIMM voltages for MCT and SMBIOS use */
+- if (pDCTstat->NodePresent) {
+- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+- pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
+- }
+- }
+- pDCTstat = pDCTstatA + (node - 1);
+- if (pDCTstat->NodePresent) {
+- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
+- pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
+- }
++ for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
++ pDCTstat->DimmConfiguredVoltage[dimm] = set_voltage;
+ }
+ }
+ }
+@@ -243,23 +229,10 @@ void DIMMSetVoltages(struct MCTStatStruc *pMCTstat,
+
+ static void set_peripheral_control_lines(void) {
+ uint8_t byte;
+- uint8_t nvram;
+- uint8_t enable_ieee1394;
+-
+- enable_ieee1394 = 1;
+-
+- if (get_option(&nvram, "ieee1394_controller") == CB_SUCCESS)
+- enable_ieee1394 = nvram & 0x1;
+
+- if (enable_ieee1394) {
+- /* Enable PCICLK5 (onboard FireWire device) */
+- outb(0x41, 0xcd6);
+- outb(0x02, 0xcd7);
+- } else {
+- /* Disable PCICLK5 (onboard FireWire device) */
+- outb(0x41, 0xcd6);
+- outb(0x00, 0xcd7);
+- }
++ /* Enable PCICLK5 */
++ outb(0x41, 0xcd6);
++ outb(0x02, 0xcd7);
+
+ /* Enable the RTC AltCentury register */
+ outb(0x41, 0xcd6);
+@@ -584,8 +557,7 @@ BOOL AMD_CB_ManualBUIDSwapList (u8 node, u8 link, const u8 **List)
+ {
+ /* Force BUID to 0 */
+ static const u8 swaplist[] = {0, 0, 0xFF, 0, 0xFF};
+- if ((is_fam15h() && (node == 0) && (link == 1)) /* Family 15h BSP SB link */
+- || (!is_fam15h() && (node == 0) && (link == 3))) { /* Family 10h BSP SB link */
++ if ((node == 0) && (link == 2)) { /* BSP SB link */
+ *List = swaplist;
+ return 1;
+ }
+--
+2.1.4
+
diff --git a/resources/scripts/helpers/build/roms/withgrub_helper b/resources/scripts/helpers/build/roms/withgrub_helper
index b3584d3..f39bc91 100755
--- a/resources/scripts/helpers/build/roms/withgrub_helper
+++ b/resources/scripts/helpers/build/roms/withgrub_helper
@@ -76,9 +76,9 @@ do
continue
fi
fi
- if [ "${boardtarget}" = "kgpe-d16" ] || [ "${boardtarget}" = "ga-g41m-es2l" ]; then
+ if [ "${boardtarget}" = "kgpe-d16" ] || [ "${boardtarget}" = "ga-g41m-es2l" ] || [ "${boardtarget}" = "kcma-d8" ]; then
if [ "${romtype}" = "vesafb" ]; then
- printf "Only text-mode is reported to work on KGPE-D16 and ga-g41m-es2l\n"
+ printf "Only text-mode is reported to work on KGPE-D16, KCMA-D8 and ga-g41m-es2l\n"
printf "TODO: get tpearson to fix it\n"
continue
fi
diff --git a/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/blobs.list b/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/blobs.list
new file mode 100644
index 0000000..a8a9a96
--- /dev/null
+++ b/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/blobs.list
@@ -0,0 +1,52 @@
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c7.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c6.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c8.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000d9.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/RevE/F10MicrocodePatch010000bf.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrMicrocodePatch06000624_Enc.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrMicrocodePatch0600050D_Enc.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/OR/F15OrMicrocodePatch06000425.c
+src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600110F_Enc.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c7.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c6.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c8.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c4.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/RevE/F10MicrocodePatch010000bf.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/F14MicrocodePatch0500000B.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/F14MicrocodePatch0500001A.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c6.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c8.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c4.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevE/F10MicrocodePatch010000bf.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/F12MicrocodePatch03000002.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/F12MicrocodePatch0300000f.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/F12MicrocodePatch0300000e.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000c7.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000085.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch010000b6.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000098.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevC/F10MicrocodePatch01000086.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c4.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/RevD/F10MicrocodePatch010000c5.c
+src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbId7001MicrocodePatch.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/F14MicrocodePatch05000029.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x14/F14MicrocodePatch05000119.c
+src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbSmuFirmware.h
+src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbSmuFirmware.h
+src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSmuFirmwareKB.h
+src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbInitTN/GnbSmuFirmwareTN.h
+src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/excel925.h
+src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbSamuPatchKB.h
+src/vendorcode/amd/cimx/rd890/HotplugFirmware.h
+src/cpu/dmp/vortex86ex/dmp_kbd_fw_part1.inc
+src/vendorcode/amd/agesa/f14/Proc/GNB/PCIe/Family/0x14/F14PcieAlibSsdt.h
+src/vendorcode/amd/agesa/f12/Proc/GNB/PCIe/Family/LN/F12PcieAlibSsdt.h
+src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/AlibSsdtKB.h
+src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbInitTN/PcieAlibSsdtTNFM2.h
+src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbInitTN/PcieAlibSsdtTNFS1.h
diff --git a/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs.list b/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs.list
new file mode 100644
index 0000000..ef2eb70
--- /dev/null
+++ b/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs.list
@@ -0,0 +1,323 @@
+payloads/libpayload/curses/pdcurses-backend/pdcdisp.c
+payloads/libpayload/curses/tinycurses.c
+payloads/libpayload/drivers/keyboard.c
+payloads/libpayload/drivers/usb/usbmsc.c
+payloads/libpayload/tests/cbfs-x86-test.c
+payloads/nvramcui/payload.sh
+src/cpu/allwinner/a10/raminit.c
+src/cpu/amd/geode_gx2/Kconfig
+src/cpu/amd/geode_lx/cpureginit.c
+src/cpu/amd/geode_lx/Kconfig
+src/cpu/amd/model_fxx/model_fxx_update_microcode.c
+src/cpu/amd/model_fxx/powernow_acpi.c
+src/cpu/intel/haswell/acpi.c
+src/cpu/intel/microcode/microcode.c
+src/cpu/intel/model_2065x/acpi.c
+src/cpu/intel/model_206ax/acpi.c
+src/cpu/Kconfig
+src/cpu/via/nano/update_ucode.c
+src/device/dram/spd_cache.c
+src/device/Kconfig
+src/device/oprom/yabel/interrupt.c
+src/drivers/pc80/mc146818rtc.c
+src/drivers/pc80/vga/vga_palette.c
+src/Kconfig
+src/lib/coreboot_table.c
+src/lib/jpeg.c
+src/mainboard/advansus/a785e-i/mptable.c
+src/mainboard/amd/bimini_fam10/mptable.c
+src/mainboard/amd/dinar/buildOpts.c
+src/mainboard/amd/dinar/Kconfig
+src/mainboard/amd/inagua/Kconfig
+src/mainboard/amd/olivehill/mptable.c
+src/mainboard/amd/olivehillplus/mptable.c
+src/mainboard/amd/parmer/mptable.c
+src/mainboard/amd/persimmon/Kconfig
+src/mainboard/amd/serengeti_cheetah_fam10/get_bus_conf.c
+src/mainboard/amd/south_station/Kconfig
+src/mainboard/amd/south_station/mptable.c
+src/mainboard/amd/thatcher/mptable.c
+src/mainboard/amd/torpedo/Kconfig
+src/mainboard/amd/torpedo/mptable.c
+src/mainboard/amd/union_station/Kconfig
+src/mainboard/amd/union_station/mptable.c
+src/mainboard/asrock/e350m1/mptable.c
+src/mainboard/asrock/imb-a180/mptable.c
+src/mainboard/asus/f2a85-m/mptable.c
+src/mainboard/asus/m5a88-v/mptable.c
+src/mainboard/avalue/eax-785e/mptable.c
+src/mainboard/gigabyte/ga-b75m-d3h/romstage.c
+src/mainboard/gizmosphere/gizmo2/Micron_MT41J128M16JT.spd.hex
+src/mainboard/gizmosphere/gizmo/mptable.c
+src/mainboard/google/bolt/romstage.c
+src/mainboard/google/butterfly/hda_verb.c
+src/mainboard/google/butterfly/mainboard.c
+src/mainboard/google/falco/romstage.c
+src/mainboard/google/link/hda_verb.c
+src/mainboard/google/link/i915.c
+src/mainboard/google/link/romstage.c
+src/mainboard/google/panther/lan.c
+src/mainboard/google/peach_pit/mainboard.c
+src/mainboard/google/peppy/romstage.c
+src/mainboard/google/rambi/romstage.c
+src/mainboard/google/samus/romstage.c
+src/mainboard/google/slippy/romstage.c
+src/mainboard/hp/dl165_g6_fam10/get_bus_conf.c
+src/mainboard/hp/pavilion_m6_1035dx/mptable.c
+src/mainboard/ibase/mb899/cmos.layout
+src/mainboard/ibase/mb899/superio_hwm.c
+src/mainboard/intel/minnowmax/Kconfig
+src/mainboard/intel/wtm2/i915.c
+src/mainboard/jetway/nf81-t56n-lf/Kconfig
+src/mainboard/kontron/986lcd-m/cmos.layout
+src/mainboard/kontron/986lcd-m/mainboard.c
+src/mainboard/lenovo/g505s/mptable.c
+src/mainboard/lippert/frontrunner-af/Kconfig
+src/mainboard/lippert/frontrunner-af/mptable.c
+src/mainboard/lippert/toucan-af/Kconfig
+src/mainboard/lippert/toucan-af/mptable.c
+src/mainboard/msi/ms9652_fam10/get_bus_conf.c
+src/mainboard/packardbell/ms2290/mainboard.c
+src/mainboard/samsung/lumpy/romstage.c
+src/mainboard/siemens/sitemp_g1p1/cmos.layout
+src/mainboard/supermicro/h8dmr_fam10/get_bus_conf.c
+src/mainboard/supermicro/h8qgi/buildOpts.c
+src/mainboard/supermicro/h8qme_fam10/get_bus_conf.c
+src/mainboard/supermicro/h8scm/buildOpts.c
+src/mainboard/tyan/s2912_fam10/get_bus_conf.c
+src/mainboard/tyan/s8226/buildOpts.c
+src/northbridge/amd/agesa/common/common.c
+src/northbridge/amd/amdk8/acpi.c
+src/northbridge/amd/amdk8/coherent_ht.c
+src/northbridge/amd/amdk8/raminit_test.c
+src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c
+src/northbridge/amd/amdmct/mct/mctardk3.c
+src/northbridge/amd/amdmct/mct/mctardk4.c
+src/northbridge/amd/amdmct/mct/mcttmrl.c
+src/northbridge/amd/gx2/pll_reset.c
+src/northbridge/amd/pi/00730F01/Kconfig
+src/northbridge/intel/gm45/raminit_rcomp_calibration.c
+src/northbridge/intel/gm45/raminit_read_write_training.c
+src/northbridge/intel/haswell/Kconfig
+src/northbridge/intel/haswell/raminit.c
+src/northbridge/intel/i82830/vga.c
+src/northbridge/intel/i945/raminit.c
+src/northbridge/intel/nehalem/gma.c
+src/northbridge/intel/nehalem/raminit.c
+src/northbridge/intel/sandybridge/gma.c
+src/northbridge/intel/sandybridge/Kconfig
+src/northbridge/intel/sandybridge/raminit.c
+src/northbridge/via/cx700/raminit.c
+src/northbridge/via/vx800/ide.c
+src/northbridge/via/vx800/uma_ram_setting.c
+src/northbridge/via/vx900/sata.c
+src/soc/intel/baytrail/acpi.c
+src/soc/intel/baytrail/Kconfig
+src/soc/intel/baytrail/romstage/raminit.c
+src/soc/intel/broadwell/acpi.c
+src/soc/intel/broadwell/Kconfig
+src/soc/intel/broadwell/romstage/raminit.c
+src/soc/intel/fsp_baytrail/acpi.c
+src/soc/intel/fsp_baytrail/fsp/Kconfig
+src/soc/intel/fsp_baytrail/Kconfig
+src/soc/qualcomm/ipq806x/Kconfig
+src/soc/samsung/exynos5250/clock.c
+src/soc/samsung/exynos5420/clock.c
+src/southbridge/amd/agesa/hudson/Kconfig
+src/southbridge/amd/cimx/sb800/Kconfig
+src/southbridge/intel/bd82x6x/Kconfig
+src/southbridge/intel/i82801ix/dmi_setup.c
+src/southbridge/intel/ibexpeak/Kconfig
+src/southbridge/intel/lynxpoint/Kconfig
+src/southbridge/intel/sch/Kconfig
+src/southbridge/sis/sis966/early_smbus.c
+src/southbridge/sis/sis966/ide.c
+src/southbridge/sis/sis966/sata.c
+src/southbridge/sis/sis966/usb2.c
+src/southbridge/sis/sis966/usb.c
+src/superio/via/vt1211/vt1211.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10Dmi.c
+src/vendorcode/amd/agesa/f10/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c
+src/vendorcode/amd/agesa/f10/Proc/Mem/Main/muc.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/cpuF10Dmi.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuF12Dmi.c
+src/vendorcode/amd/agesa/f12/Proc/CPU/Family/0x12/cpuF12WheaInitDataTables.c
+src/vendorcode/amd/agesa/f12/Proc/Fch/Hwm/Family/Hudson2/Hudson2HwmLateService.c
+src/vendorcode/amd/agesa/f12/Proc/GNB/Gfx/Family/LN/F12GfxServices.c
+src/vendorcode/amd/agesa/f12/Proc/Mem/Main/muc.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/cpuF10Dmi.c
+src/vendorcode/amd/agesa/f14/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c
+src/vendorcode/amd/agesa/f14/Proc/Mem/Main/muc.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/cpuF10Dmi.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x10/cpuF10WheaInitDataTables.c
+src/vendorcode/amd/agesa/f15/Proc/CPU/Family/0x15/cpuF15WheaInitDataTables.c
+src/vendorcode/amd/agesa/f15/Proc/Mem/Main/muc.c
+src/vendorcode/amd/agesa/f15/Proc/Mem/Ps/OR/mpor3.c
+src/vendorcode/amd/agesa/f15/Proc/Mem/Tech/DDR3/mtlrdimm3.c
+src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/cpuF15WheaInitDataTables.c
+src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbInitTN/GfxIntegratedInfoTableTN.c
+src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbInitTN/GfxLibTN.c
+src/vendorcode/amd/agesa/f15tn/Proc/Mem/Main/muc.c
+src/vendorcode/amd/agesa/f15tn/Proc/Mem/Ps/TN/mptn3.c
+src/vendorcode/amd/agesa/f15tn/Proc/Mem/Tech/DDR3/mtlrdimm3.c
+src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/cpuF16WheaInitDataTables.c
+src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c
+src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GnbF1TableKB.c
+src/vendorcode/amd/agesa/f16kb/Proc/Mem/Main/muc.c
+src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/KB/mpkb3.c
+src/vendorcode/amd/cimx/sb800/SATA.c
+src/vendorcode/google/chromeos/build-snow
+util/amdtools/example_input/lspci-cb-48G-667MHz-18.2-20090909e
+util/amdtools/example_input/lspci-prop-48G-667MHz-18.2
+util/cbfstool/linux_trampoline.c
+util/ifdtool/ifdtool.c
+util/kconfig/zconf.hash.c_shipped
+util/kconfig/zconf.lex.c_shipped
+util/kconfig/zconf.tab.c_shipped
+util/nvramtool/accessors/layout-bin.c
+util/romcc/do_tests.sh
+util/romcc/tests/include/linux_console.h
+util/romcc/tests/linux_console.h
+util/romcc/tests/linux_test5.c
+util/romcc/tests/raminit_test6.c
+util/romcc/tests/raminit_test7.c
+util/romcc/tests/simple_test14.c
+util/romcc/tests/simple_test30.c
+util/romcc/tests/simple_test38.c
+util/romcc/tests/simple_test39.c
+util/romcc/tests/simple_test54.c
+util/romcc/tests/simple_test59.c
+util/romcc/tests/simple_test72.c
+util/romcc/tests/simple_test73.c
+util/sconfig/lex.yy.c_shipped
+util/sconfig/sconfig.tab.c_shipped
+util/superiotool/fintek.c
+util/superiotool/ite.c
+util/superiotool/smsc.c
+util/superiotool/winbond.c
+src/mainboard/google/slippy/Micron_4KTF25664HZ.spd.hex
+src/mainboard/google/falco/Micron_4KTF25664HZ.spd.hex
+src/mainboard/google/peppy/Micron_4KTF25664HZ.spd.hex
+src/mainboard/google/link/micron_4Gb_1600_1.35v_x16.spd.hex
+src/mainboard/google/rambi/spd/micron_1GiB_dimm_MT41K128M16JT-125.spd.hex
+src/mainboard/google/rambi/spd/micron_2GiB_dimm_MT41K256M16HA-125.spd.hex
+src/mainboard/google/bolt/micron_4Gb_1600_1.35v_x16.spd.hex
+src/mainboard/google/link/samsung_4Gb_1600_1.35v_x16.spd.hex
+src/mainboard/google/link/elpida_4Gb_1600_x16.spd.hex
+src/mainboard/google/slippy/Hynix_HMT425S6AFR6A.spd.hex
+src/mainboard/google/falco/Hynix_HMT425S6AFR6A.spd.hex
+src/mainboard/google/falco/Elpida_EDJ4216EFBG.spd.hex
+src/mainboard/google/rambi/spd/hynix_1GiB_dimm_H5TC2G63FFR-PBA.spd.hex
+src/mainboard/google/rambi/spd/hynix_2GiB_dimm_H5TC4G63AFR-PBA.spd.hex
+src/mainboard/google/bolt/samsung_4Gb_1600_1.35v_x16.spd.hex
+src/mainboard/google/bolt/elpida_4Gb_1600_x16.spd.hex
+src/mainboard/google/peppy/Hynix_HMT425S6AFR6A.spd.hex
+src/mainboard/google/peppy/Elpida_EDJ4216EFBG.spd.hex
+src/mainboard/google/falco/Samsung_M471B5674QH0.spd.hex
+src/mainboard/google/samus/spd/empty.spd.hex
+src/mainboard/google/samus/spd/elpida_4.spd.hex
+src/mainboard/google/samus/spd/hynix_4.spd.hex
+src/mainboard/google/samus/spd/elpida_16.spd.hex
+src/mainboard/google/samus/spd/hynix_8.spd.hex
+src/mainboard/google/samus/spd/hynix_16.spd.hex
+src/mainboard/google/samus/spd/samsung_8.spd.hex
+src/mainboard/google/samus/spd/elpida_8.spd.hex
+src/mainboard/google/samus/spd/samsung_4.spd.hex
+src/mainboard/google/auron/spd/Micron_4KTF25664HZ.spd.hex
+src/mainboard/google/auron/spd/Elpida_EDJ4216EFBG.spd.hex
+src/mainboard/google/auron/spd/Hynix_HMT425S6AFR6A.spd.hex
+src/mainboard/google/glados/spd/samsung_dimm_K4E6E304EE-EGCF.spd.hex
+src/mainboard/google/auron/spd/empty.spd.hex
+src/mainboard/google/cyan/spd/hynix_2GiB_dimm_HMT425S6CFR6A_H5TC4G63CFR.spd.hex
+src/mainboard/google/cyan/spd/samsung_2GiB_dimm_K4B4G1646Q-HYK0.spd.hex
+src/mainboard/google/cyan/spd/hynix_2GiB_dimm_H5TC4G63AFR-PBA.spd.hex
+src/mainboard/google/glados/spd/hynix_dimm_H9CCNNNBLTALAR.spd.hex
+src/mainboard/google/glados/spd/empty.spd.hex
+src/mainboard/google/glados/spd/hynix_dimm_H9CCNNN8JTBLAR.spd.hex
+src/mainboard/intel/sklrvp/spd/empty.spd.hex
+src/mainboard/intel/sklrvp/spd/rvp3.spd.hex
+src/mainboard/intel/kunimitsu/spd/empty.spd.hex
+src/mainboard/intel/kunimitsu/spd/samsung_dimm_K4E8E304EE-EGCE.spd.hex
+src/mainboard/intel/strago/spd/hynix_2GiB_dimm_HMT425S6CFR6A_H5TC4G63CFR.spd.hex
+src/mainboard/intel/strago/spd/samsung_2GiB_dimm_K4B4G1646Q-HYK0.spd.hex
+src/mainboard/intel/strago/spd/hynix_2GiB_dimm_H5TC4G63AFR-PBA.spd.hex
+src/mainboard/intel/kunimitsu/spd/hynix_dimm_H9CCNNNBLTALAR-NUD-2G-1866.spd.hex
+src/mainboard/intel/kunimitsu/spd/samsung_dimm_K4E8E304EE-EGCF-1G-1866.spd.hex
+src/mainboard/intel/kunimitsu/spd/samsung_dimm_K4E6E304EE-EGCF-2G-1866.spd.hex
+src/mainboard/intel/kunimitsu/spd/hynix_dimm_H9CCNNN8JTALAR-NUD-1G-1866.spd.hex
+src/mainboard/bap/ode_e20XX/BAP_Q7.spd.hex
+src/northbridge/intel/nehalem/raminit_tables.c
+src/northbridge/intel/sandybridge/raminit_patterns.h
+src/southbridge/nvidia/mcp55/early_setup_ss.h
+src/southbridge/nvidia/ck804/early_setup_ss.h
+src/southbridge/sis/sis966/early_setup_ss.h
+util/crossgcc/patches/binutils-2.25_riscv.patch
+src/southbridge/amd/pi/hudson/Kconfig
+src/drivers/xgi/common/vb_setmode.c
+src/drivers/xgi/common/vb_table.h
+src/drivers/xgi/common/XGI_main.h
+src/mainboard/siemens/mc_tcu3/romstage.c
+src/mainboard/siemens/mc_tcu3/lcd_panel.c
+src/mainboard/siemens/mc_tcu3/modhwinfo.c
+src/mainboard/pcengines/apu1/Kconfig
+src/mainboard/asus/kfsn4-dre/get_bus_conf.c
+src/mainboard/google/samus/spd/spd.c
+src/mainboard/hp/abm/mptable.c
+src/northbridge/amd/pi/00630F01/Kconfig
+src/cpu/amd/microcode/microcode.c
+src/lib/tlcl_structures.h
+util/rockchip/make_idb.py
+util/autoport/readme.md
+util/bimgtool/bimgtool.c
+util/cbfstool/fmd_parser.c_shipped
+util/cbfstool/fmd_scanner.c_shipped
+Documentation/CorebootBuildingGuide.tex
+Documentation/hypertransport.svg
+Documentation/codeflow.svg
+src/soc/broadcom/cygnus/ddr_init.c
+src/soc/broadcom/cygnus/ddr_init_table.c
+src/soc/qualcomm/ipq806x/lcc.c
+src/soc/intel/braswell/acpi.c
+src/soc/intel/braswell/Kconfig
+src/vendorcode/amd/pi/Kconfig
+src/drivers/intel/fsp1_1/Kconfig
+src/drivers/intel/fsp1_1/fsp_gop.c
+src/drivers/i2c/ww_ring/ww_ring_programs.c
+src/mainboard/google/auron/spd/spd.c
+src/mainboard/google/jecht/lan.c
+src/mainboard/gigabyte/ga-b75m-d3v/romstage.c
+src/mainboard/amd/lamar/Kconfig
+payloads/external/GRUB2/Kconfig
+payloads/external/FILO/Kconfig
+payloads/external/SeaBIOS/Kconfig
+src/soc/intel/skylake/Kconfig
+src/soc/intel/braswell/gpio.c
+src/soc/nvidia/tegra210/Kconfig
+src/soc/nvidia/tegra210/mtc.c
+src/southbridge/intel/common/firmware/Kconfig
+src/mainboard/google/cyan/spd/spd.c
+src/mainboard/google/cyan/Kconfig
+src/mainboard/google/glados/spd/spd.c
+src/mainboard/intel/sklrvp/spd/spd.c
+src/mainboard/intel/kunimitsu/spd/spd.c
+src/mainboard/intel/strago/spd/spd.c
+src/mainboard/intel/strago/Kconfig
+src/mainboard/amd/bettong/mptable.c
+src/northbridge/amd/pi/00660F01/Kconfig
+util/crossgcc/patches/gcc-5.2.0_riscv.patch
+util/xcompile/xcompile
+src/northbridge/intel/sandybridge/raminit_mrc.c
+src/northbridge/intel/fsp_rangeley/fsp/Kconfig
+src/drivers/intel/fsp1_1/car.c
+src/mainboard/intel/mohonpeak/Kconfig
+src/mainboard/apple/macbookair4_2/early_southbridge.c
+src/cpu/intel/fsp_model_406dx/acpi.c
+src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
+src/drivers/aspeed/common/ast_dram_tables.h
+src/drivers/aspeed/common/ast_tables.h
+src/mainboard/intel/cougar_canyon2/Kconfig
+src/cpu/amd/family_10h-family_15h/processor_name.c
+src/cpu/amd/family_10h-family_15h/init_cpus.c
+src/cpu/intel/fsp_model_206ax/acpi.c
+src/northbridge/intel/pineview/raminit.c
diff --git a/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs_notes b/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs_notes
new file mode 100644
index 0000000..551da4a
--- /dev/null
+++ b/resources/utilities/coreboot-libre/blobs/coreboot/369b561315ca68d0cdedc38208105a513c7139b5/nonblobs_notes
@@ -0,0 +1,15 @@
+.spd.hex files - serial presence detect. These are not blobs
+see JEDEC standard or https://en.wikipedia.org/wiki/Serial_presence_detect
+These are added to the nonblobs file
+
+src/northbridge/intel/nehalem/raminit_tables.c"
+src/northbridge/intel/sandybridge/raminit_patterns.h
+These are used by native raminit for the relevant platforms, and are not blobs
+
+"src/southbridge/nvidia/mcp55/early_setup_ss.h" \
+"src/southbridge/nvidia/ck804/early_setup_ss.h" \
+"src/southbridge/sis/sis966/early_setup_ss.h"
+not blobs
+
+The text in this file is CC-BY-SA 4.0 or higher. All contributions to it must
+be made under the same license.