[coreboot-gerrit] New patch to review for coreboot: 473061f AMD: Isolate AGESA and PI build environments for southbridge

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Sun Nov 9 23:30:21 CET 2014


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7388

-gerrit

commit 473061f52830fd71d750578a6a84293aa95156ef
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Tue Oct 21 18:22:32 2014 +0300

    AMD: Isolate AGESA and PI build environments for southbridge
    
    To backport features introduced with recent Chromebooks and/or Intel
    boards in general, heavy work on the AMD AGESA platform infrastructure
    is required. With the AGESA PI available in binary form only, community
    members have little means to verify, debug and develop for the said
    platforms.
    
    Thus it makes sense to fork the existing agesawrapper interfaces, to give
    AMD PI platforms a clean and independent sandbox. New directory layout
    reflects the separation already taken place under 3rdparty/ and vendorcode/.
    
    Change-Id: Ia730f0e45e7c1bdfc0c91e95eb6729a77773e2b9
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/mainboard/amd/olivehillplus/Kconfig            |   2 +-
 src/mainboard/amd/olivehillplus/devicetree.cb      |   4 +-
 src/mainboard/amd/olivehillplus/dsdt.asl           |  10 +-
 src/mainboard/amd/olivehillplus/mptable.c          |   2 +-
 src/mainboard/amd/olivehillplus/romstage.c         |   2 +-
 src/southbridge/amd/Kconfig                        |   1 +
 src/southbridge/amd/Makefile.inc                   |   4 +-
 src/southbridge/amd/pi/Kconfig                     |  20 +
 src/southbridge/amd/pi/Makefile.inc                |  19 +
 src/southbridge/amd/pi/avalon/Kconfig              | 237 +++++++++++
 src/southbridge/amd/pi/avalon/Makefile.inc         | 308 ++++++++++++++
 src/southbridge/amd/pi/avalon/acpi/audio.asl       |  57 +++
 src/southbridge/amd/pi/avalon/acpi/fch.asl         | 206 +++++++++
 src/southbridge/amd/pi/avalon/acpi/lpc.asl         | 108 +++++
 src/southbridge/amd/pi/avalon/acpi/pci_int.asl     | 473 +++++++++++++++++++++
 src/southbridge/amd/pi/avalon/acpi/pcie.asl        |  95 +++++
 src/southbridge/amd/pi/avalon/acpi/sleepstates.asl |  40 ++
 src/southbridge/amd/pi/avalon/acpi/smbus.asl       |  20 +
 src/southbridge/amd/pi/avalon/acpi/usb.asl         |  78 ++++
 src/southbridge/amd/pi/avalon/amd_pci_int_defs.h   |  72 ++++
 src/southbridge/amd/pi/avalon/amd_pci_int_types.h  |  33 ++
 src/southbridge/amd/pi/avalon/bootblock.c          |  67 +++
 src/southbridge/amd/pi/avalon/chip.h               |  35 ++
 src/southbridge/amd/pi/avalon/early_setup.c        | 156 +++++++
 src/southbridge/amd/pi/avalon/enable_usbdebug.c    |  63 +++
 src/southbridge/amd/pi/avalon/fadt.c               | 211 +++++++++
 src/southbridge/amd/pi/avalon/hda.c                |  51 +++
 src/southbridge/amd/pi/avalon/hudson.c             | 173 ++++++++
 src/southbridge/amd/pi/avalon/hudson.h             |  81 ++++
 src/southbridge/amd/pi/avalon/ide.c                |  48 +++
 src/southbridge/amd/pi/avalon/lpc.c                | 343 +++++++++++++++
 src/southbridge/amd/pi/avalon/pci.c                |  74 ++++
 src/southbridge/amd/pi/avalon/pci_devs.h           |  96 +++++
 src/southbridge/amd/pi/avalon/pcie.c               |  65 +++
 src/southbridge/amd/pi/avalon/reset.c              |  35 ++
 src/southbridge/amd/pi/avalon/sata.c               |  57 +++
 src/southbridge/amd/pi/avalon/sd.c                 |  69 +++
 src/southbridge/amd/pi/avalon/sm.c                 | 174 ++++++++
 src/southbridge/amd/pi/avalon/smbus.c              | 250 +++++++++++
 src/southbridge/amd/pi/avalon/smbus.h              |  76 ++++
 src/southbridge/amd/pi/avalon/smbus_spd.c          | 152 +++++++
 src/southbridge/amd/pi/avalon/smi.c                |  25 ++
 src/southbridge/amd/pi/avalon/smi.h                |  65 +++
 src/southbridge/amd/pi/avalon/smi_util.c           |  79 ++++
 src/southbridge/amd/pi/avalon/smihandler.c         | 136 ++++++
 src/southbridge/amd/pi/avalon/spi.c                | 204 +++++++++
 src/southbridge/amd/pi/avalon/usb.c                | 100 +++++
 src/vendorcode/amd/pi/00730F01/Makefile.inc        |   2 +-
 48 files changed, 4665 insertions(+), 13 deletions(-)

diff --git a/src/mainboard/amd/olivehillplus/Kconfig b/src/mainboard/amd/olivehillplus/Kconfig
index caa361a..fc1d821 100644
--- a/src/mainboard/amd/olivehillplus/Kconfig
+++ b/src/mainboard/amd/olivehillplus/Kconfig
@@ -23,7 +23,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
 	select CPU_AMD_PI_00730F01
 	select NORTHBRIDGE_AMD_PI_00730F01
-	select SOUTHBRIDGE_AMD_AGESA_AVALON
+	select SOUTHBRIDGE_AMD_PI_AVALON
 	select HAVE_OPTION_TABLE
 	select HAVE_PIRQ_TABLE
 	select HAVE_MP_TABLE
diff --git a/src/mainboard/amd/olivehillplus/devicetree.cb b/src/mainboard/amd/olivehillplus/devicetree.cb
index aec71f9..3c5e38f 100644
--- a/src/mainboard/amd/olivehillplus/devicetree.cb
+++ b/src/mainboard/amd/olivehillplus/devicetree.cb
@@ -39,7 +39,7 @@ chip northbridge/amd/pi/00730F01/root_complex
 				device pci 2.5 on  end # Edge Connector
 			end	#chip northbridge/amd/pi/00730F01
 
-			chip southbridge/amd/agesa/hudson # it is under NB/SB Link, but on the same pci bus
+			chip southbridge/amd/pi/avalon # it is under NB/SB Link, but on the same pci bus
 				device pci 10.0 on  end # XHCI HC0
 				device pci 11.0 on  end # SATA
 				device pci 12.0 on  end # USB
@@ -57,7 +57,7 @@ chip northbridge/amd/pi/00730F01/root_complex
 				device pci 14.2 on  end # HDA	0x4383
 				device pci 14.3 on  end # LPC	0x439d
 				device pci 14.7 on  end # SD
-			end	#chip southbridge/amd/hudson
+			end	#chip southbridge/amd/pi/avalon
 
 			device pci 18.0 on  end
 			device pci 18.1 on  end
diff --git a/src/mainboard/amd/olivehillplus/dsdt.asl b/src/mainboard/amd/olivehillplus/dsdt.asl
index b74dac6..56381e1 100644
--- a/src/mainboard/amd/olivehillplus/dsdt.asl
+++ b/src/mainboard/amd/olivehillplus/dsdt.asl
@@ -37,13 +37,13 @@ DefinitionBlock (
 	#include "acpi/usb_oc.asl"
 
 	/* PCI IRQ mapping for the Southbridge */
-	#include <southbridge/amd/agesa/hudson/acpi/pcie.asl>
+	#include <southbridge/amd/pi/avalon/acpi/pcie.asl>
 
 	/* Describe the processor tree (\_PR) */
 	#include <cpu/amd/pi/00730F01/acpi/cpu.asl>
 
 	/* Contains the supported sleep states for this chipset */
-	#include <southbridge/amd/agesa/hudson/acpi/sleepstates.asl>
+	#include <southbridge/amd/pi/avalon/acpi/sleepstates.asl>
 
 	/* Contains the Sleep methods (WAK, PTS, GTS, etc.) */
 	#include "acpi/sleep.asl"
@@ -68,16 +68,16 @@ DefinitionBlock (
 			#include <northbridge/amd/pi/00730F01/acpi/northbridge.asl>
 
 			/* Describe the AMD Fusion Controller Hub Southbridge */
-			#include <southbridge/amd/agesa/hudson/acpi/fch.asl>
+			#include <southbridge/amd/pi/avalon/acpi/fch.asl>
 		}
 
 		/* Describe PCI INT[A-H] for the Southbridge */
-		#include <southbridge/amd/agesa/hudson/acpi/pci_int.asl>
+		#include <southbridge/amd/pi/avalon/acpi/pci_int.asl>
 
 	} /* End \_SB scope */
 
 	/* Describe SMBUS for the Southbridge */
-	#include <southbridge/amd/agesa/hudson/acpi/smbus.asl>
+	#include <southbridge/amd/pi/avalon/acpi/smbus.asl>
 
 	/* Define the General Purpose Events for the platform */
 	#include "acpi/gpe.asl"
diff --git a/src/mainboard/amd/olivehillplus/mptable.c b/src/mainboard/amd/olivehillplus/mptable.c
index 73660e4..80ba5b5 100644
--- a/src/mainboard/amd/olivehillplus/mptable.c
+++ b/src/mainboard/amd/olivehillplus/mptable.c
@@ -27,7 +27,7 @@
 #include <cpu/amd/amdfam15.h>
 #include <arch/cpu.h>
 #include <cpu/x86/lapic.h>
-#include <southbridge/amd/agesa/hudson/hudson.h> /* pm_ioread() */
+#include <southbridge/amd/pi/avalon/hudson.h> /* pm_ioread() */
 
 u8 picr_data[0x54] = {
 	0x03,0x04,0x05,0x07,0x0B,0x0A,0x1F,0x1F,0xFA,0xF1,0x00,0x00,0x1F,0x1F,0x1F,0x1F,
diff --git a/src/mainboard/amd/olivehillplus/romstage.c b/src/mainboard/amd/olivehillplus/romstage.c
index 5230f7d..a7c825d 100644
--- a/src/mainboard/amd/olivehillplus/romstage.c
+++ b/src/mainboard/amd/olivehillplus/romstage.c
@@ -34,7 +34,7 @@
 #include <northbridge/amd/pi/agesawrapper_call.h>
 #include "cpu/x86/bist.h"
 #include "cpu/x86/lapic.h"
-#include "southbridge/amd/agesa/hudson/hudson.h"
+#include "southbridge/amd/pi/avalon/hudson.h"
 #include "cpu/amd/pi/s3_resume.h"
 
 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
diff --git a/src/southbridge/amd/Kconfig b/src/southbridge/amd/Kconfig
index 867afca..d6c7ca2 100644
--- a/src/southbridge/amd/Kconfig
+++ b/src/southbridge/amd/Kconfig
@@ -13,4 +13,5 @@ source src/southbridge/amd/sb700/Kconfig
 source src/southbridge/amd/sb800/Kconfig
 source src/southbridge/amd/cimx/Kconfig
 source src/southbridge/amd/agesa/Kconfig
+source src/southbridge/amd/pi/Kconfig
 source src/southbridge/amd/sr5650/Kconfig
diff --git a/src/southbridge/amd/Makefile.inc b/src/southbridge/amd/Makefile.inc
index 0e3f785..56c66bd 100644
--- a/src/southbridge/amd/Makefile.inc
+++ b/src/southbridge/amd/Makefile.inc
@@ -16,11 +16,11 @@ subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += cimx
 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += cimx
 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_HUDSON) += agesa
 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE) += agesa
-subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_AVALON) += agesa
+subdirs-$(CONFIG_SOUTHBRIDGE_AMD_PI_AVALON) += pi
 
 ramstage-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB700) += amd_pci_util.c
 ramstage-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += amd_pci_util.c
 ramstage-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += amd_pci_util.c
 ramstage-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_HUDSON) += amd_pci_util.c
 ramstage-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE) += amd_pci_util.c
-ramstage-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_AVALON) += amd_pci_util.c
+ramstage-$(CONFIG_SOUTHBRIDGE_AMD_PI_AVALON) += amd_pci_util.c
diff --git a/src/southbridge/amd/pi/Kconfig b/src/southbridge/amd/pi/Kconfig
new file mode 100644
index 0000000..a0438c8
--- /dev/null
+++ b/src/southbridge/amd/pi/Kconfig
@@ -0,0 +1,20 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2012 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+source src/southbridge/amd/pi/avalon/Kconfig
diff --git a/src/southbridge/amd/pi/Makefile.inc b/src/southbridge/amd/pi/Makefile.inc
new file mode 100644
index 0000000..b7bcc7a
--- /dev/null
+++ b/src/southbridge/amd/pi/Makefile.inc
@@ -0,0 +1,19 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2012 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+subdirs-$(CONFIG_SOUTHBRIDGE_AMD_PI_AVALON) += avalon
diff --git a/src/southbridge/amd/pi/avalon/Kconfig b/src/southbridge/amd/pi/avalon/Kconfig
new file mode 100644
index 0000000..31d4c8d
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/Kconfig
@@ -0,0 +1,237 @@
+##
+## This file is part of the coreboot project.
+##
+## 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config SOUTHBRIDGE_AMD_PI_AVALON
+	bool
+	select IOAPIC
+	select HAVE_USBDEBUG_OPTIONS
+	select HAVE_HARD_RESET
+
+if SOUTHBRIDGE_AMD_PI_AVALON
+
+config BOOTBLOCK_SOUTHBRIDGE_INIT
+	string
+	default "southbridge/amd/pi/avalon/bootblock.c"
+
+config SOUTHBRIDGE_AMD_HUDSON_SKIP_ISA_DMA_INIT
+	bool
+	default n
+
+config EHCI_BAR
+	hex
+	default 0xfef00000
+
+config HUDSON_XHCI_ENABLE
+	bool "Enable Hudson XHCI Controller"
+	default y
+	help
+	  The XHCI controller must be enabled and the XHCI firmware
+	  must be added in order to have USB 3.0 support configured
+	  by coreboot. The OS will be responsible for enabling the XHCI
+	  controller if the the XHCI firmware is available but the
+	  XHCI controller is not enabled by coreboot.
+
+config HUDSON_XHCI_FWM
+	bool "Add xhci firmware"
+	default y
+	help
+	  Add Hudson 2/3/4 XHCI Firmware to support the onboard USB 3.0
+
+config HUDSON_DISABLE_IMC
+	bool
+	default n
+
+config HUDSON_IMC_FWM
+	bool "Add IMC firmware"
+	depends on !HUDSON_DISABLE_IMC
+	default y
+        help
+	  Add Hudson 2/3/4 IMC Firmware to support the onboard fan control
+
+config HUDSON_GEC_FWM
+	bool
+	default n
+        help
+	  Add Hudson 2/3/4 GEC Firmware to support the onboard gigabit Ethernet MAC.
+	  Must be connected to a Broadcom B50610 or B50610M PHY on the motherboard.
+
+config HUDSON_PSP
+	bool
+	default y if CPU_AMD_PI_00730F01
+
+config HUDSON_XHCI_FWM_FILE
+        string "XHCI firmware path and filename"
+        default "3rdparty/southbridge/amd/avalon/xhci.bin" if SOUTHBRIDGE_AMD_PI_AVALON
+	depends on HUDSON_XHCI_FWM
+
+config HUDSON_IMC_FWM_FILE
+        string "IMC firmware path and filename"
+        default "3rdparty/southbridge/amd/avalon/imc.bin" if SOUTHBRIDGE_AMD_PI_AVALON
+	depends on HUDSON_IMC_FWM
+
+config HUDSON_GEC_FWM_FILE
+        string "GEC firmware path and filename"
+	depends on HUDSON_GEC_FWM
+
+config HUDSON_FWM
+	bool
+	default y if HUDSON_XHCI_FWM || HUDSON_IMC_FWM || HUDSON_GEC_FWM || HUDSON_PSP
+	default n
+
+if HUDSON_FWM
+
+config HUDSON_FWM_POSITION
+        hex "Hudson Firmware ROM Position"
+        default 0xFFF20000 if BOARD_ROMSIZE_KB_1024
+        default 0xFFE20000 if BOARD_ROMSIZE_KB_2048
+        default 0xFFC20000 if BOARD_ROMSIZE_KB_4096
+        default 0xFF820000 if BOARD_ROMSIZE_KB_8192
+        default 0xFF020000 if BOARD_ROMSIZE_KB_16384
+	help
+	  Hudson requires the firmware MUST be located at
+	  a specific address (ROM start address + 0x20000), otherwise
+	  xhci host Controller can not find or load the xhci firmware.
+
+	  The firmware start address is dependent on the ROM chip size.
+	  The default offset is 0x20000 from the ROM start address, namely
+	  0xFFF20000 if flash chip size is 1M
+	  0xFFE20000 if flash chip size is 2M
+	  0xFFC20000 if flash chip size is 4M
+	  0xFF820000 if flash chip size is 8M
+	  0xFF020000 if flash chip size is 16M
+endif # HUDSON_FWM
+
+config AMD_PUBKEY_FILE
+        depends on HUDSON_PSP
+        string "AMD public Key"
+        default "3rdparty/southbridge/amd/avalon/PSP/AmdPubKey.bin" if CPU_AMD_PI_00730F01
+
+choice
+	prompt "SATA Mode"
+	default HUDSON_SATA_IDE
+	help
+	  Select the mode in which SATA should be driven. NATIVE AHCI, or RAID.
+	  The default is NATIVE.
+
+config HUDSON_SATA_IDE
+	bool "NATIVE"
+	help
+	  NATIVE is the default mode and does not require a ROM.
+
+config HUDSON_SATA_RAID
+	bool "RAID"
+	help
+	  HUDSON RAID mode must have the two required ROM files.
+
+config HUDSON_SATA_AHCI
+	bool "AHCI"
+	help
+	  AHCI may work with or without AHCI ROM. It depends on the payload support.
+	  For example, seabios does not require the AHCI ROM.
+
+config HUDSON_SATA_LEGACY_IDE
+	bool "LEGACY IDE"
+	help
+	  TODO
+
+config HUDSON_SATA_IDE2AHCI
+	bool "IDE to AHCI"
+	help
+	  TODO
+
+config HUDSON_SATA_AHCI7804
+	bool "AHCI7804"
+	help
+	  AHCI ROM Required, and AMD driver required in the OS.
+
+config HUDSON_SATA_IDE2AHCI7804
+	bool "IDE to AHCI7804"
+	help
+	  AHCI ROM Required, and AMD driver required in the OS.
+
+endchoice
+
+config HUDSON_SATA_MODE
+        hex
+	depends on (HUDSON_SATA_IDE || HUDSON_SATA_RAID || HUDSON_SATA_AHCI)
+	default "0x0" if HUDSON_SATA_IDE
+	default "0x1" if HUDSON_SATA_RAID
+	default "0x2" if HUDSON_SATA_AHCI
+	default "0x3" if HUDSON_SATA_LEGACY_IDE
+	default "0x4" if HUDSON_SATA_IDE2AHCI
+	default "0x5" if HUDSON_SATA_AHCI7804
+	default "0x6" if HUDSON_SATA_IDE2AHCI7804
+
+if HUDSON_SATA_AHCI || HUDSON_SATA_AHCI7804
+config AHCI_ROM_ID
+	string "AHCI device PCI IDs"
+	default "1022,7801" if HUDSON_SATA_AHCI
+	default "1022,7804" if HUDSON_SATA_AHCI7804
+
+config HUDSON_AHCI_ROM
+	bool "Add a AHCI ROM"
+
+config AHCI_ROM_FILE
+	string "AHCI ROM path and filename"
+	depends on HUDSON_AHCI_ROM
+	default "src/southbridge/amd/pi/avalon/ahci.bin"
+endif # HUDSON_SATA_AHCI || HUDSON_SATA_AHCI7804
+
+if HUDSON_SATA_RAID
+config RAID_ROM_ID
+	string "RAID device PCI IDs"
+	default "1022,7802"
+        help
+          1022,7802 for SATA NON-RAID5 module, 1022,7803 for SATA RAID5 mode
+
+config RAID_ROM_FILE
+	string "RAID ROM path and filename"
+	depends on HUDSON_SATA_RAID
+	default "src/southbridge/amd/pi/avalon/raid.bin"
+
+config RAID_MISC_ROM_FILE
+        string "RAID Misc ROM path and filename"
+        default "src/southbridge/amd/pi/avalon/misc.bin"
+	depends on HUDSON_SATA_RAID
+
+config RAID_MISC_ROM_POSITION
+	hex "RAID Misc ROM Position"
+	default 0xFFF00000
+	depends on HUDSON_SATA_RAID
+	help
+	  The RAID ROM requires that the MISC ROM is located between the range
+	  0xFFF0_0000 to 0xFFF0_FFFF. Also, it must 1K bytes aligned.
+	  The CONFIG_ROM_SIZE must be larger than 0x100000.
+endif # HUDSON_SATA_RAID
+
+config HUDSON_LEGACY_FREE
+	bool "System is legacy free"
+	help
+	  Select y if there is no keyboard controller in the system.
+	  This sets variables in AGESA and ACPI.
+
+config AZ_PIN
+	hex
+	default 0xaa
+	help
+	  bit 1,0 - pin 0
+	  bit 3,2 - pin 1
+	  bit 5,4 - pin 2
+	  bit 7,6 - pin 3
+endif
diff --git a/src/southbridge/amd/pi/avalon/Makefile.inc b/src/southbridge/amd/pi/avalon/Makefile.inc
new file mode 100644
index 0000000..307d0bf
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/Makefile.inc
@@ -0,0 +1,308 @@
+#*****************************************************************************
+#
+# Copyright (c) 2012,        Advanced Micro Devices, Inc.
+#               2013 - 2014, Sage Electronic Engineering, LLC
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of Advanced Micro Devices, Inc. nor the names of
+#       its contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#*****************************************************************************
+
+INCLUDES += -Isrc/southbridge/amd/pi/avalon
+
+romstage-y += smbus.c smbus_spd.c
+ramstage-y += hudson.c
+ramstage-y += usb.c
+ramstage-y += lpc.c
+ramstage-y += sm.c
+ramstage-y += ide.c
+ramstage-y += sata.c
+ramstage-y += hda.c
+ramstage-y += pci.c
+ramstage-y += pcie.c
+ramstage-y += sd.c
+
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c
+ramstage-y += reset.c
+romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c
+ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c
+romstage-y += early_setup.c
+
+ramstage-$(CONFIG_SPI_FLASH) += spi.c
+ramstage-$(CONFIG_HAVE_ACPI_RESUME) += resume.c
+
+smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c smi_util.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smi_util.c
+
+# ROMSIG At ROMBASE + 0x20000:
+# +-----------+---------------+----------------+------------+
+# |0x55AA55AA |EC ROM Address |GEC ROM Address |USB3 ROM    |
+# +-----------+---------------+----------------+------------+
+# |PSPDIR ADDR|
+# +-----------+
+#
+# EC ROM should be 64K aligned.
+
+# HVB(Hardware Validated Boot) or Bypass
+CONFIG_HVB=Bypass
+
+HUDSON_FWM_POSITION=$(shell printf %u $(CONFIG_HUDSON_FWM_POSITION))
+
+#assume the cbfs header is less than 128 bytes.
+ROMSIG_SIZE=16
+ifeq ($(CONFIG_HUDSON_XHCI_FWM), y)
+HUDSON_XHCI_POSITION=$(shell echo $(HUDSON_FWM_POSITION) $(ROMSIG_SIZE) 128 \
+	| awk '{printf("%.0f", $$1 + $$2 + $$3)}')
+XHCI_FWM_SIZE=$(word 5,$(shell ls -l $(CONFIG_HUDSON_XHCI_FWM_FILE)))
+else
+HUDSON_XHCI_POSITION=0
+XHCI_FWM_SIZE=0
+endif
+
+ifeq ($(CONFIG_HUDSON_GEC_FWM), y)
+HUDSON_GEC_POSITION=$(shell echo $(HUDSON_FWM_POSITION) $(ROMSIG_SIZE) 128 \
+	$(XHCI_FWM_SIZE) 128 \
+	| awk '{printf("%.0f", $$1 + $$2 + $$3 + $$4 + $$5)}')
+GEC_FWM_SIZE=$(word 5,$(shell ls -l $(CONFIG_HUDSON_GEC_FWM_FILE)))
+else
+HUDSON_GEC_POSITION=0
+GEC_FWM_SIZE=0
+endif
+
+ifeq ($(CONFIG_HUDSON_IMC_FWM), y)
+HUDSON_IMC_POSITION_UNALIGN=$(shell echo $(HUDSON_FWM_POSITION) \
+	$(ROMSIG_SIZE) 128 $(XHCI_FWM_SIZE) 128 $(GEC_FWM_SIZE) 128 65535 \
+	| awk '{printf("%.0f", $$1 + $$2 + $$3 + $$4 + $$5 + $$6 + $$7 + $$8)}')
+HUDSON_IMC_POSITION=$(shell echo $(HUDSON_IMC_POSITION_UNALIGN) \
+	| awk '{printf("%.0f", $$1 - $$1 % 65536)}')
+else
+HUDSON_IMC_POSITION=0
+endif
+
+HUDSON_PSP_DIRECTORY_POSITION=0
+ifeq ($(CONFIG_CPU_AMD_PI_00730F01), y)
+HUDSON_PSP_DIRECTORY_POSITION=$(shell echo $(HUDSON_FWM_POSITION) 262144 |  awk '{printf("%.0f", $$1 + $$2)}')
+endif
+
+$(obj)/coreboot_hudson_romsig.bin: $(call strip_quotes, $(CONFIG_HUDSON_XHCI_FWM_FILE)) \
+			$(call strip_quotes, $(CONFIG_HUDSON_IMC_FWM_FILE)) \
+			$(call strip_quotes, $(CONFIG_HUDSON_GEC_FWM_FILE)) \
+			$(obj)/config.h
+	echo "    Hudson FW  $@"
+	for fwm in 1437226410 \
+		$(HUDSON_IMC_POSITION) \
+		$(HUDSON_GEC_POSITION) \
+		$(HUDSON_XHCI_POSITION) \
+		$(HUDSON_PSP_DIRECTORY_POSITION); do \
+		echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done > $@
+
+ifeq ($(CONFIG_HUDSON_FWM), y)
+cbfs-files-y += hudson/fwm
+hudson/fwm-file := $(obj)/coreboot_hudson_romsig.bin
+hudson/fwm-position := $(HUDSON_FWM_POSITION)
+hudson/fwm-type := raw
+endif
+
+ifeq ($(CONFIG_HUDSON_XHCI_FWM), y)
+cbfs-files-y += hudson/xhci
+hudson/xhci-file := $(call strip_quotes, $(CONFIG_HUDSON_XHCI_FWM_FILE))
+hudson/xhci-position := $(HUDSON_XHCI_POSITION)
+hudson/xhci-type := raw
+hudson/xhci-required := Hudson XHCI firmware (available in coreboot/3rdparty if enabled)
+endif
+
+ifeq ($(CONFIG_HUDSON_IMC_FWM), y)
+cbfs-files-y += hudson/imc
+hudson/imc-file := $(call strip_quotes, $(CONFIG_HUDSON_IMC_FWM_FILE))
+hudson/imc-position := $(HUDSON_IMC_POSITION)
+hudson/imc-type := raw
+hudson/imc-required := Hudson IMC Firmware (available in coreboot/3rdparty if enabled)
+endif
+
+ifeq ($(CONFIG_HUDSON_GEC_FWM), y)
+cbfs-files-y += hudson/gec
+hudson/gec-file := $(call strip_quotes, $(CONFIG_HUDSON_GEC_FWM_FILE))
+hudson/gec-position := $(HUDSON_GEC_POSITION)
+hudson/gec-type := raw
+hudson/gec-required := Hudson Gigabit Ethernet Controller Firmware (Contact your AMD representative)
+endif
+
+#ifeq ($(CONFIG_HUDSON_SATA_AHCI), y)
+ifdef CONFIG_HUDSON_AHCI_ROM
+stripped_ahci_rom_id = $(call strip_quotes,$(CONFIG_AHCI_ROM_ID))
+cbfs-files-y += pci$(stripped_ahci_rom_id).rom
+pci$(stripped_ahci_rom_id).rom-file := $(call strip_quotes,$(CONFIG_AHCI_ROM_FILE))
+pci$(stripped_ahci_rom_id).rom-type := optionrom
+pci$(stripped_ahci_rom_id).rom-required := Hudson AHCI Option ROM (Contact your AMD representative)
+#endif
+endif
+
+ifeq ($(CONFIG_HUDSON_PSP), y)
+
+# 0
+# catenate the pubkey and pspdir together to save some space.
+AMDPUBKEY_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x100)}')   #$(shell printf %u 0xFFb00100)
+AMDPUBKEY_SIZE=$(word 5,$(shell ls -l $(CONFIG_AMD_PUBKEY_FILE)))
+
+ifeq ($(CONFIG_CPU_AMD_PI_00730F01), y)
+FIRMWARE_LOCATE=$(dir $(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)))
+FIRMWARE_TYPE=
+endif
+# 1
+CONFIG_PSPBTLDR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspBootLoader$(FIRMWARE_TYPE).$(CONFIG_HVB).sbin
+PSPBTLDR_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x1000)}') #$(shell printf %u 0xFFb10000)
+PSPBTLDR_SIZE=$(word 5,$(shell ls -l $(CONFIG_PSPBTLDR_FILE)))
+cbfs-files-y += hudson/pspbtldr
+hudson/pspbtldr-file := $(CONFIG_PSPBTLDR_FILE)
+hudson/pspbtldr-position := $(PSPBTLDR_POS)
+hudson/pspbtldr-type := raw
+
+#8
+CONFIG_SMUFWM_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware$(FIRMWARE_TYPE).sbin
+SMUFWM_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0xb000)}') #$(shell printf %u 0xFFb20000)
+SMUFWM_SIZE=$(word 5,$(shell ls -l $(CONFIG_SMUFWM_FILE)))
+cbfs-files-y += hudson/smufwm
+hudson/smufwm-file := $(CONFIG_SMUFWM_FILE)
+hudson/smufwm-position := $(SMUFWM_POS)
+hudson/smufwm-type := raw
+
+#3
+CONFIG_PSPRCVR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspRecovery$(FIRMWARE_TYPE).sbin
+PSPRCVR_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x30000)}') #$(shell printf %u 0xFFBb0000)
+PSPRCVR_SIZE=$(word 5,$(shell ls -l $(CONFIG_PSPRCVR_FILE)))
+cbfs-files-y += hudson/psprcvr
+hudson/psprcvr-file := $(CONFIG_PSPRCVR_FILE)
+hudson/psprcvr-position := $(PSPRCVR_POS)
+hudson/psprcvr-type := raw
+
+# 5
+CONFIG_PUBSIGNEDKEY_FILE=$(top)/$(FIRMWARE_LOCATE)/RtmPubSigned$(FIRMWARE_TYPE).key
+PUBSIGNEDKEY_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x400)}') #$(shell printf %u 0xFFb00400)
+PUBSIGNEDKEY_SIZE=$(word 5,$(shell ls -l $(CONFIG_PUBSIGNEDKEY_FILE)))
+cbfs-files-y += hudson/pubsignedkey
+hudson/pubsignedkey-file := $(CONFIG_PUBSIGNEDKEY_FILE)
+hudson/pubsignedkey-position := $(PUBSIGNEDKEY_POS)
+hudson/pubsignedkey-type := raw
+
+# 2
+CONFIG_PSPSCUREOS_FILE=$(top)/$(FIRMWARE_LOCATE)/PspSecureOs$(FIRMWARE_TYPE).sbin
+PSPSECUREOS_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x3A000)}') #$(shell printf %u 0xFFbc0000)
+PSPSECUREOS_SIZE=$(word 5,$(shell ls -l $(CONFIG_PSPSCUREOS_FILE)))
+cbfs-files-y += hudson/pspsecureos
+hudson/pspsecureos-file := $(CONFIG_PSPSCUREOS_FILE)
+hudson/pspsecureos-position := $(PSPSECUREOS_POS)
+hudson/pspsecureos-type := raw
+
+# 4
+CONFIG_PSPNVRAM_FILE=$(top)/$(FIRMWARE_LOCATE)/PspNvram$(FIRMWARE_TYPE).bin
+PSPNVRAM_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x64000)}') #$(shell printf %u 0xFFbf0000)
+PSPNVRAM_SIZE=$(word 5,$(shell ls -l $(CONFIG_PSPNVRAM_FILE)))
+cbfs-files-y += hudson/pspnvram
+hudson/pspnvram-file := $(CONFIG_PSPNVRAM_FILE)
+hudson/pspnvram-position := $(PSPNVRAM_POS)
+hudson/pspnvram-type := raw
+
+ifeq ($(CONFIG_HVB), HVB)
+# 6
+RTM_FILE=$(objcbfs)/bootblock.bin     #The file size need to be 256 bytes aligned.
+RTM_SIZE=$(word 5,$(shell ls -l $(RTM_FILE)))
+RTM_POS=$(shell echo 4294967296 $(RTM_SIZE) | awk '{print $$1 - $$2}')
+
+# 7
+RTMSIGN_FILE=$(obj)/bootblock_sig.bin
+RTMSIGN_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x800)}') #$(shell printf %u 0xFFb00800)
+RTMSIGN_SIZE=256 #it should be hardcoded to 256, otherwise circular dependency comes up.$(word 5,$(shell ls -l $(RTMSIGN_FILE)))
+cbfs-files-y += hudson/rtmsign
+hudson/rtmsign-file := $(RTMSIGN_FILE)
+hudson/rtmsign-position := $(RTMSIGN_POS)
+hudson/rtmsign-type := raw
+endif
+
+CONFIG_SMUSCS_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuScs$(FIRMWARE_TYPE).bin
+SMUSCS_POS=$(shell echo $(HUDSON_PSP_DIRECTORY_POSITION) | awk '{printf("%.0f", $$1 + 0x6d000)}') #$(shell printf %u 0xFFC00000)
+SMUSCS_SIZE=$(word 5,$(shell ls -l $(CONFIG_SMUSCS_FILE)))
+cbfs-files-y += hudson/smuscs
+hudson/smuscs-file := $(CONFIG_SMUSCS_FILE)
+hudson/smuscs-position := $(SMUSCS_POS)
+hudson/smuscs-type := raw
+
+define output_hex
+echo $(1) | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'
+endef
+
+$(obj)/coreboot_psp_directory.bin: $(obj)/config.h $(FLETCHER) $(RTM_FILE)
+	echo "    PSPDir     $@"
+	for fwm in 0 $(AMDPUBKEY_SIZE) $(AMDPUBKEY_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done > $@_tail.tmp
+	for fwm in 1 $(PSPBTLDR_SIZE) $(PSPBTLDR_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 8 $(SMUFWM_SIZE) $(SMUFWM_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 3 $(PSPRCVR_SIZE) $(PSPRCVR_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 5 $(PUBSIGNEDKEY_SIZE) $(PUBSIGNEDKEY_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+ifeq ($(CONFIG_HVB), HVB)
+	for fwm in 6 $(RTM_SIZE) $(RTM_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 7 $(RTMSIGN_SIZE) $(RTMSIGN_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+endif
+	for fwm in 2 $(PSPSECUREOS_SIZE) $(PSPSECUREOS_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 4 $(PSPNVRAM_SIZE) $(PSPNVRAM_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 95 $(SMUSCS_SIZE) $(SMUSCS_POS) 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in 11 4294967295 0 0; do \
+	echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done >> $@_tail.tmp
+	for fwm in  1347637284 0 `ls -l $@_tail.tmp | awk '{printf("%d", $$5/16);}'` 0; do \
+		echo  $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \
+	done > $@_head.tmp
+	cat $@_head.tmp $@_tail.tmp > $@.tmp
+	$(FLETCHER) < $@.tmp > $@
+	rm $@_head.tmp $@_tail.tmp $@.tmp
+
+$(obj)/coreboot_psp_directory_combine_pubkey.bin: $(obj)/coreboot_psp_directory.bin
+	cat  $(obj)/coreboot_psp_directory.bin > $@
+	ls -l $(obj)/coreboot_psp_directory.bin | LC_ALL=C awk '{for (i=0; i<256-$$5; i++) {printf "%c", 255}}' >> $@
+	cat  $(top)/$(FIRMWARE_LOCATE)/AmdPubKey$(FIRMWARE_TYPE).bin >> $@
+
+cbfs-files-y += hudson/pspdir
+hudson/pspdir-file := $(obj)/coreboot_psp_directory_combine_pubkey.bin
+hudson/pspdir-position := $(HUDSON_PSP_DIRECTORY_POSITION)
+hudson/pspdir-type := raw
+
+endif
diff --git a/src/southbridge/amd/pi/avalon/acpi/audio.asl b/src/southbridge/amd/pi/avalon/acpi/audio.asl
new file mode 100644
index 0000000..2c25ab5
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/audio.asl
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Device(AZHD) {	/* 0:14.2 - HD Audio */
+	Name(_ADR, 0x00140002)
+	OperationRegion(AZPD, PCI_Config, 0x00, 0x100)
+		Field(AZPD, AnyAcc, NoLock, Preserve) {
+		offset (0x42),
+		NSDI, 1,
+		NSDO, 1,
+		NSEN, 1,
+		offset (0x44),
+		IPCR, 4,
+		offset (0x54),
+		PWST, 2,
+		, 6,
+		PMEB, 1,
+		, 6,
+		PMST, 1,
+		offset (0x62),
+		MMCR, 1,
+		offset (0x64),
+		MMLA, 32,
+		offset (0x68),
+		MMHA, 32,
+		offset (0x6C),
+		MMDT, 16,
+	}
+
+	Method (_INI, 0, NotSerialized)
+	{
+		If (LEqual (OSVR, 0x03))
+		{
+			Store (Zero, NSEN)
+			Store (One, NSDO)
+			Store (One, NSDI)
+		}
+	}
+} /* end AZHD */
diff --git a/src/southbridge/amd/pi/avalon/acpi/fch.asl b/src/southbridge/amd/pi/avalon/acpi/fch.asl
new file mode 100644
index 0000000..badcab0
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/fch.asl
@@ -0,0 +1,206 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* South Bridge */
+/*  _SB.PCI0 */
+
+/* Operating System Capabilities Method */
+Method(_OSC,4)
+{
+	// Create DWord-addressable fields from the Capabilities Buffer
+	CreateDWordField(Arg3,0,CDW1)
+	CreateDWordField(Arg3,4,CDW2)
+	CreateDWordField(Arg3,8,CDW3)
+
+	/* Check for proper PCI/PCIe UUID */
+	If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+	{
+		/* Let OS control everything */
+		Return (Arg3)
+	} Else {
+		Or(CDW1,4,CDW1)	// Unrecognized UUID
+		Return(Arg3)
+	}
+}
+
+/* Describe the Southbridge devices */
+
+/* 0:11.0 - SATA */
+Device(STCR) {
+	Name(_ADR, 0x00110000)
+	#include "acpi/sata.asl"
+} /* end STCR */
+
+/* 0:14.0 - SMBUS */
+Device(SBUS) {
+	Name(_ADR, 0x00140000)
+} /* end SBUS */
+
+#include "usb.asl"
+
+/* 0:14.2 - HD Audio */
+#include "audio.asl"
+
+/* 0:14.3 - LPC */
+#include "lpc.asl"
+
+/* 0:14.7 - SD Controller */
+Device(SDCN) {
+	Name(_ADR, 0x00140007)
+} /* end SDCN */
+
+#if !CONFIG_SOUTHBRIDGE_AMD_PI_YANGTZE && !CONFIG_SOUTHBRIDGE_AMD_PI_AVALON
+
+/* 0:14.4 - PCI slot 1, 2, 3 */
+Device(PIBR) {
+	Name(_ADR, 0x00140004)
+	Name(_PRW, Package() {0x18, 4})
+
+	Method(_PRT, 0) {
+		Return (PCIB)
+	}
+}
+
+/* 0:14.6 - GEC Controller */
+Device(ACMD) {
+	Name(_ADR, 0x00140006)
+} /* end Ac97modem */
+#endif
+
+Name(CRES, ResourceTemplate() {
+	/* Set the Bus number and Secondary Bus number for the PCI0 device
+	 * The Secondary bus range for PCI0 lets the system
+	 * know what bus values are allowed on the downstream
+	 * side of this PCI bus if there is a PCI-PCI bridge.
+	 * PCI busses can have 256 secondary busses which
+	 * range from [0-0xFF] but they do not need to be
+	 * sequential.
+	 */
+	WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+		0x0000,		/* address granularity */
+		0x0000,		/* range minimum */
+		0x00FF,		/* range maximum */
+		0x0000,		/* translation */
+		0x0100,		/* length */
+		,, PSB0)		/* ResourceSourceIndex, ResourceSource, DescriptorName */
+
+	IO(Decode16, 0x0CF8, 0x0CF8, 1,	8)
+
+	WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+		0x0000,		/* address granularity */
+		0x0000,		/* range minimum */
+		0x0CF7,		/* range maximum */
+		0x0000,		/* translation */
+		0x0CF8		/* length */
+	)
+	WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+		0x0000,		/* address granularity */
+		0x03B0,		/* range minimum */
+		0x03DF,		/* range maximum */
+		0x0000,		/* translation */
+		0x0030		/* length */
+	)
+
+	WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+		0x0000,		/* address granularity */
+		0x0D00,		/* range minimum */
+		0xFFFF,		/* range maximum */
+		0x0000,		/* translation */
+		0xF300		/* length */
+	)
+
+	Memory32Fixed(READONLY, 0x000A0000, 0x00020000, VGAM)	/* VGA memory space */
+	Memory32Fixed(READONLY, 0x000C0000, 0x00020000, EMM1)	/* Assume C0000-E0000 empty */
+
+	/* memory space for PCI BARs below 4GB */
+	Memory32Fixed(ReadOnly, 0x00000000, 0x00000000, MMIO)
+}) /* End Name(_SB.PCI0.CRES) */
+
+Method(_CRS, 0) {
+	/* DBGO("\\_SB\\PCI0\\_CRS\n") */
+	CreateDWordField(CRES, ^MMIO._BAS, MM1B)
+	CreateDWordField(CRES, ^MMIO._LEN, MM1L)
+
+	/*
+	 * Declare memory between TOM1 and 4GB as available
+	 * for PCI MMIO.
+	 * Use ShiftLeft to avoid 64bit constant (for XP).
+	 * This will work even if the OS does 32bit arithmetic, as
+	 * 32bit (0x00000000 - TOM1) will wrap and give the same
+	 * result as 64bit (0x100000000 - TOM1).
+	 */
+	Store(TOM1, MM1B)
+	ShiftLeft(0x10000000, 4, Local0)
+	Subtract(Local0, TOM1, Local0)
+	Store(Local0, MM1L)
+
+	Return(CRES) /* note to change the Name buffer */
+} /* end of Method(_SB.PCI0._CRS) */
+
+/*
+ *
+ *               FIRST METHOD CALLED UPON BOOT
+ *
+ *  1. If debugging, print current OS and ACPI interpreter.
+ *  2. Get PCI Interrupt routing from ACPI VSM, this
+ *     value is based on user choice in BIOS setup.
+ */
+Method(_INI, 0) {
+	/* DBGO("\\_SB\\_INI\n") */
+	/* DBGO("   DSDT.ASL code from ") */
+	/* DBGO(__DATE__) */
+	/* DBGO(" ") */
+	/* DBGO(__TIME__) */
+	/* DBGO("\n   Sleep states supported: ") */
+	/* DBGO("\n") */
+	/* DBGO("   \\_OS=") */
+	/* DBGO(\_OS) */
+	/* DBGO("\n   \\_REV=") */
+	/* DBGO(\_REV) */
+	/* DBGO("\n") */
+
+	/* Determine the OS we're running on */
+	OSFL()
+
+	/* TODO: It is unstable. */
+	//#include "acpi/AmdImc.asl" /* Hudson IMC function */
+	//ITZE() /* enable IMC Fan Control*/
+} /* End Method(_SB._INI) */
+
+Method(OSFL, 0){
+
+	if(LNotEqual(OSVR, Ones)) {Return(OSVR)}	/* OS version was already detected */
+
+	if(CondRefOf(\_OSI,Local1))
+	{
+		Store(1, OSVR)					/* Assume some form of XP */
+		if (\_OSI("Windows 2006"))		/* Vista */
+		{
+			Store(2, OSVR)
+		}
+	} else {
+		If(WCMP(\_OS,"Linux")) {
+			Store(3, OSVR)				/* Linux */
+		} Else {
+			Store(4, OSVR)				/* Gotta be WinCE */
+		}
+	}
+	Return(OSVR)
+}
diff --git a/src/southbridge/amd/pi/avalon/acpi/lpc.asl b/src/southbridge/amd/pi/avalon/acpi/lpc.asl
new file mode 100644
index 0000000..3383ac8
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/lpc.asl
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* 0:14.3 - LPC */
+Device(LIBR) {
+	Name(_ADR, 0x00140003)
+	/* Method(_INI) {
+	*	DBGO("\\_SB\\PCI0\\LpcIsaBr\\_INI\n")
+	} */ /* End Method(_SB.SBRDG._INI) */
+
+	OperationRegion(CFG,PCI_Config,0x0,0x100) // Map PCI Configuration Space
+	Field(CFG,DWordAcc,NoLock,Preserve){
+		Offset(0xA0),
+		BAR,32}		// SPI Controller Base Address Register (Index 0xA0)
+
+	Device(LDRC)	// LPC device: Resource consumption
+	{
+		Name (_HID, EISAID("PNP0C02"))  // ID for Motherboard resources
+		Name (CRS, ResourceTemplate ()  // Current Motherboard resources
+		{
+			Memory32Fixed(ReadWrite,	// Setup for fixed resource location for SPI base address
+			0x00000000,					// Address Base
+			0x00000000,					// Address Length
+			BAR0						// Descriptor Name
+			)
+		})
+
+		Method(_CRS,0,NotSerialized)
+		{
+			CreateDwordField(^CRS,^BAR0._BAS,SPIB)	// Field to hold SPI base address
+			CreateDwordField(^CRS,^BAR0._LEN,SPIL)	// Field to hold SPI address length
+			Store(BAR,SPIB)		// SPI base address mapped
+			Store(0x1000,SPIL)	// 4k space mapped
+			Return(CRS)
+		}
+	}
+
+	/* Real Time Clock Device */
+	Device(RTC0) {
+		Name(_HID, EISAID("PNP0B00"))   /* AT Real Time Clock (not PIIX4 compatible) */
+		Name(_CRS, ResourceTemplate() {
+			IRQNoFlags(){8}
+			IO(Decode16,0x0070, 0x0070, 0, 2)
+		})
+	} /* End Device(_SB.PCI0.LpcIsaBr.RTC0) */
+
+	Device(TMR) {	/* Timer */
+		Name(_HID,EISAID("PNP0100"))	/* System Timer */
+		Name(_CRS, ResourceTemplate() {
+			IRQNoFlags(){0}
+			IO(Decode16, 0x0040, 0x0040, 0, 4)
+		})
+	} /* End Device(_SB.PCI0.LpcIsaBr.TMR) */
+
+	Device(SPKR) {	/* Speaker */
+		Name(_HID,EISAID("PNP0800"))	/* AT style speaker */
+		Name(_CRS, ResourceTemplate() {
+			IO(Decode16, 0x0061, 0x0061, 0, 1)
+		})
+	} /* End Device(_SB.PCI0.LpcIsaBr.SPKR) */
+
+	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)
+		})
+	} /* End Device(_SB.PCI0.LpcIsaBr.PIC) */
+
+	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) */
+	} /* End Device(_SB.PCI0.LpcIsaBr.MAD) */
+
+	Device(COPR) {
+		Name(_HID,EISAID("PNP0C04"))	/* Math Coprocessor */
+		Name(_CRS, ResourceTemplate() {
+			IO(Decode16, 0x00F0, 0x00F0, 0, 0x10)
+			IRQNoFlags(){13}
+		})
+	} /* End Device(_SB.PCI0.LpcIsaBr.COPR) */
+	#include "acpi/superio.asl"
+} /* end LIBR */
diff --git a/src/southbridge/amd/pi/avalon/acpi/pci_int.asl b/src/southbridge/amd/pi/avalon/acpi/pci_int.asl
new file mode 100644
index 0000000..384ed61
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/pci_int.asl
@@ -0,0 +1,473 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+	/* PCIe Configuration Space for CONFIG_MMCONF_BUS_NUMBER busses */
+	OperationRegion(PCFG, SystemMemory, PCBA, PCLN) /* Each bus consumes 1MB */
+		Field(PCFG, ByteAcc, NoLock, Preserve) {
+		/* Byte offsets are computed using the following technique:
+		 * ((bus number + 1) * ((device number * 8) * 4096)) + register offset
+		 * The 8 comes from 8 functions per device, and 4096 bytes per function config space
+		*/
+		Offset(0x00088024),	/* Byte offset to SATA register 24h - Bus 0, Device 17, Function 0 */
+		STB5, 32,
+		Offset(0x00098042),	/* Byte offset to OHCI0 register 42h - Bus 0, Device 19, Function 0 */
+		PT0D, 1,
+		PT1D, 1,
+		PT2D, 1,
+		PT3D, 1,
+		PT4D, 1,
+		PT5D, 1,
+		PT6D, 1,
+		PT7D, 1,
+		PT8D, 1,
+		PT9D, 1,
+		Offset(0x000A0004),	/* Byte offset to SMBUS register 4h - Bus 0, Device 20, Function 0 */
+		SBIE, 1,
+		SBME, 1,
+		Offset(0x000A0008),	/* Byte offset to SMBUS register 8h - Bus 0, Device 20, Function 0 */
+		SBRI, 8,
+		Offset(0x000A0014),	/* Byte offset to SMBUS register 14h - Bus 0, Device 20, Function 0 */
+		SBB1, 32,
+		Offset(0x000A0078),	/* Byte offset to SMBUS register 78h - Bus 0, Device 20, Function 0 */
+		,14,
+		P92E, 1,		/* Port92 decode enable */
+	}
+
+	OperationRegion(SB5, SystemMemory, STB5, 0x1000)
+		Field(SB5, AnyAcc, NoLock, Preserve){
+		/* Port 0 */
+		Offset(0x120),		/* Port 0 Task file status */
+		P0ER, 1,
+		, 2,
+		P0DQ, 1,
+		, 3,
+		P0BY, 1,
+		Offset(0x128),		/* Port 0 Serial ATA status */
+		P0DD, 4,
+		, 4,
+		P0IS, 4,
+		Offset(0x12C),		/* Port 0 Serial ATA control */
+		P0DI, 4,
+		Offset(0x130),		/* Port 0 Serial ATA error */
+		, 16,
+		P0PR, 1,
+
+		/* Port 1 */
+		offset(0x1A0),		/* Port 1 Task file status */
+		P1ER, 1,
+		, 2,
+		P1DQ, 1,
+		, 3,
+		P1BY, 1,
+		Offset(0x1A8),		/* Port 1 Serial ATA status */
+		P1DD, 4,
+		, 4,
+		P1IS, 4,
+		Offset(0x1AC),		/* Port 1 Serial ATA control */
+		P1DI, 4,
+		Offset(0x1B0),		/* Port 1 Serial ATA error */
+		, 16,
+		P1PR, 1,
+
+		/* Port 2 */
+		Offset(0x220),		/* Port 2 Task file status */
+		P2ER, 1,
+		, 2,
+		P2DQ, 1,
+		, 3,
+		P2BY, 1,
+		Offset(0x228),		/* Port 2 Serial ATA status */
+		P2DD, 4,
+		, 4,
+		P2IS, 4,
+		Offset(0x22C),		/* Port 2 Serial ATA control */
+		P2DI, 4,
+		Offset(0x230),		/* Port 2 Serial ATA error */
+		, 16,
+		P2PR, 1,
+
+		/* Port 3 */
+		Offset(0x2A0),		/* Port 3 Task file status */
+		P3ER, 1,
+		, 2,
+		P3DQ, 1,
+		, 3,
+		P3BY, 1,
+		Offset(0x2A8),		/* Port 3 Serial ATA status */
+		P3DD, 4,
+		, 4,
+		P3IS, 4,
+		Offset(0x2AC),		/* Port 3 Serial ATA control */
+		P3DI, 4,
+		Offset(0x2B0),		/* Port 3 Serial ATA error */
+		, 16,
+		P3PR, 1,
+	}
+
+	Method(_PIC, 0x01, NotSerialized)
+	{
+		If (Arg0)
+		{
+			\_SB.CIRQ()
+		}
+		Store(Arg0, PMOD)
+	}
+
+	Method(CIRQ, 0x00, NotSerialized){
+	}
+
+	Name(IRQB, ResourceTemplate(){
+		IRQ(Level,ActiveLow,Shared){15}
+	})
+
+	Name(IRQP, ResourceTemplate(){
+		IRQ(Level,ActiveLow,Exclusive){3, 4, 5, 7, 10, 11, 12, 15}
+	})
+
+	Name(PITF, ResourceTemplate(){
+		IRQ(Level,ActiveLow,Exclusive){9}
+	})
+
+	Device(INTA) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 1)
+
+		Method(_STA, 0) {
+			if (PIRA) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTA._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKA\\_DIS\n") */
+		} /* End Method(_SB.INTA._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKA\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTA._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKA\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRA, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTA._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKA\\_SRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRA)
+		} /* End Method(_SB.INTA._SRS) */
+	} /* End Device(INTA) */
+
+	Device(INTB) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 2)
+
+		Method(_STA, 0) {
+			if (PIRB) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTB._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKB\\_DIS\n") */
+		} /* End Method(_SB.INTB._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKB\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTB._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKB\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRB, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTB._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKB\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRB)
+		} /* End Method(_SB.INTB._SRS) */
+	} /* End Device(INTB)  */
+
+	Device(INTC) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 3)
+
+		Method(_STA, 0) {
+			if (PIRC) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTC._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKC\\_DIS\n") */
+		} /* End Method(_SB.INTC._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKC\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTC._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKC\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRC, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTC._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKC\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRC)
+		} /* End Method(_SB.INTC._SRS) */
+	} /* End Device(INTC)  */
+
+	Device(INTD) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 4)
+
+		Method(_STA, 0) {
+			if (PIRD) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTD._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKD\\_DIS\n") */
+		} /* End Method(_SB.INTD._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKD\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTD._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKD\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRD, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTD._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKD\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRD)
+		} /* End Method(_SB.INTD._SRS) */
+	} /* End Device(INTD)  */
+
+	Device(INTE) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 5)
+
+		Method(_STA, 0) {
+			if (PIRE) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTE._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKE\\_DIS\n") */
+		} /* End Method(_SB.INTE._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKE\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTE._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKE\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRE, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTE._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKE\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRE)
+		} /* End Method(_SB.INTE._SRS) */
+	} /* End Device(INTE)  */
+
+	Device(INTF) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 6)
+
+		Method(_STA, 0) {
+			if (PIRF) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTF._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKF\\_DIS\n") */
+		} /* End Method(_SB.INTF._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKF\\_PRS\n") */
+			Return(PITF)
+		} /* Method(_SB.INTF._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKF\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRF, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTF._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKF\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRF)
+		} /*  End Method(_SB.INTF._SRS) */
+	} /* End Device(INTF)  */
+
+	Device(INTG) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 7)
+
+		Method(_STA, 0) {
+			if (PIRG) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTG._STA)  */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKG\\_DIS\n") */
+		} /* End Method(_SB.INTG._DIS)  */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKG\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTG._CRS)  */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKG\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRG, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTG._CRS)  */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKG\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRG)
+		} /* End Method(_SB.INTG._SRS)  */
+	} /* End Device(INTG)  */
+
+	Device(INTH) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 8)
+
+		Method(_STA, 0) {
+			if (PIRH) {
+				Return(0x0B) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTH._STA)  */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKH\\_DIS\n") */
+		} /* End Method(_SB.INTH._DIS)  */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKH\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTH._CRS)  */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKH\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRH, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTH._CRS)  */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKH\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRH)
+		} /* End Method(_SB.INTH._SRS)  */
+	} /* End Device(INTH)   */
diff --git a/src/southbridge/amd/pi/avalon/acpi/pcie.asl b/src/southbridge/amd/pi/avalon/acpi/pcie.asl
new file mode 100644
index 0000000..f130fb4
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/pcie.asl
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+	/* PCI IRQ mapping registers, C00h-C01h. */
+	OperationRegion(PRQM, SystemIO, 0x00000C00, 0x00000002)
+		Field(PRQM, ByteAcc, NoLock, Preserve) {
+		PRQI, 0x00000008,
+		PRQD, 0x00000008,  /* Offset: 1h */
+	}
+	IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) {
+		PIRA, 0x00000008,	/* Index 0 */
+		PIRB, 0x00000008,	/* Index 1 */
+		PIRC, 0x00000008,	/* Index 2 */
+		PIRD, 0x00000008,	/* Index 3 */
+		PIRE, 0x00000008,	/* Index 4 */
+		PIRF, 0x00000008,	/* Index 5 */
+		PIRG, 0x00000008,	/* Index 6 */
+		PIRH, 0x00000008,	/* Index 7 */
+	}
+
+	/* PCI Error control register */
+	OperationRegion(PERC, SystemIO, 0x00000C14, 0x00000001)
+		Field(PERC, ByteAcc, NoLock, Preserve) {
+		SENS, 0x00000001,
+		PENS, 0x00000001,
+		SENE, 0x00000001,
+		PENE, 0x00000001,
+	}
+
+	/* Client Management index/data registers */
+	OperationRegion(CMT, SystemIO, 0x00000C50, 0x00000002)
+		Field(CMT, ByteAcc, NoLock, Preserve) {
+		CMTI,	8,
+		/* Client Management Data register */
+		G64E,	1,
+		G64O,	1,
+		G32O,	2,
+		,		2,
+		GPSL,	2,
+	}
+
+	/* GPM Port register */
+	OperationRegion(GPT, SystemIO, 0x00000C52, 0x00000001)
+		Field(GPT, ByteAcc, NoLock, Preserve) {
+		GPB0,1,
+		GPB1,1,
+		GPB2,1,
+		GPB3,1,
+		GPB4,1,
+		GPB5,1,
+		GPB6,1,
+		GPB7,1,
+	}
+
+	/* Flash ROM program enable register */
+	OperationRegion(FRE, SystemIO, 0x00000C6F, 0x00000001)
+		Field(FRE, ByteAcc, NoLock, Preserve) {
+		,     0x00000006,
+		FLRE, 0x00000001,
+	}
+
+	/* PM2 index/data registers */
+	OperationRegion(PM2R, SystemIO, 0x00000CD0, 0x00000002)
+		Field(PM2R, ByteAcc, NoLock, Preserve) {
+		PM2I, 0x00000008,
+		PM2D, 0x00000008,
+	}
+
+	/* Power Management I/O registers, TODO:PMIO is quite different in SB800. */
+	OperationRegion(PIOR, SystemIO, 0x00000CD6, 0x00000002)
+		Field(PIOR, ByteAcc, NoLock, Preserve) {
+		PIOI, 0x00000008,
+		PIOD, 0x00000008,
+	}
+
+	IndexField (PIOI, PIOD, ByteAcc, NoLock, Preserve) {
+		Offset(0xEE),
+		UPWS, 3,
+	}
diff --git a/src/southbridge/amd/pi/avalon/acpi/sleepstates.asl b/src/southbridge/amd/pi/avalon/acpi/sleepstates.asl
new file mode 100644
index 0000000..f8d0bb0
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/sleepstates.asl
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Supported sleep states: */
+Name(\_S0, Package () {0x00, 0x00, 0x00, 0x00} )	/* (S0) - working state */
+
+If (LAnd(SSFG, 0x01)) {
+	Name(\_S1, Package () {0x01, 0x01, 0x00, 0x00} )	/* (S1) - sleeping w/CPU context */
+}
+If (LAnd(SSFG, 0x02)) {
+	Name(\_S2, Package () {0x02, 0x02, 0x00, 0x00} )	/* (S2) - "light" Suspend to RAM */
+}
+If (LAnd(SSFG, 0x04)) {
+	Name(\_S3, Package () {0x03, 0x03, 0x00, 0x00} )	/* (S3) - Suspend to RAM */
+}
+If (LAnd(SSFG, 0x08)) {
+	Name(\_S4, Package () {0x04, 0x04, 0x00, 0x00} )	/* (S4) - Suspend to Disk */
+}
+
+Name(\_S5, Package () {0x05, 0x05, 0x00, 0x00} )	/* (S5) - Soft Off */
+
+Name(\_SB.CSPS ,0)	/* Current Sleep State (S0, S1, S2, S3, S4, S5) */
+Name(CSMS, 0)		/* Current System State */
diff --git a/src/southbridge/amd/pi/avalon/acpi/smbus.asl b/src/southbridge/amd/pi/avalon/acpi/smbus.asl
new file mode 100644
index 0000000..11aff4a
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/smbus.asl
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* SMBus Support */
diff --git a/src/southbridge/amd/pi/avalon/acpi/usb.asl b/src/southbridge/amd/pi/avalon/acpi/usb.asl
new file mode 100644
index 0000000..647e56b
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/acpi/usb.asl
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* 0:12.0 - OHCI */
+Device(UOH1) {
+	Name(_ADR, 0x00120000)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UOH1 */
+
+/* 0:12.2 - EHCI */
+Device(UOH2) {
+	Name(_ADR, 0x00120002)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UOH2 */
+
+/* 0:13.0 - OHCI */
+Device(UOH3) {
+	Name(_ADR, 0x00130000)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UOH3 */
+
+/* 0:13.2 - EHCI */
+Device(UOH4) {
+	Name(_ADR, 0x00130002)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UOH4 */
+
+/* 0:16.0 - OHCI */
+Device(UOH5) {
+	Name(_ADR, 0x00160000)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UOH5 */
+
+/* 0:16.2 - EHCI */
+Device(UOH6) {
+	Name(_ADR, 0x00160002)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UOH5 */
+
+#if !CONFIG_SOUTHBRIDGE_AMD_PI_YANGTZE
+/* 0:14.5 - OHCI */
+Device(UEH1) {
+	Name(_ADR, 0x00140005)
+	Name(_PRW, Package() {0x0B, 3})
+} /* end UEH1 */
+#endif
+
+/* 0:10.0 - XHCI 0*/
+Device(XHC0) {
+	Name(_ADR, 0x00100000)
+	Name(_PRW, Package() {0x0B, 4})
+} /* end XHC0 */
+
+#if !CONFIG_SOUTHBRIDGE_AMD_PI_YANGTZE
+/* 0:10.1 - XHCI 1*/
+Device(XHC1) {
+	Name(_ADR, 0x00100001)
+	Name(_PRW, Package() {0x0B, 4})
+} /* end XHC1 */
+#endif
diff --git a/src/southbridge/amd/pi/avalon/amd_pci_int_defs.h b/src/southbridge/amd/pi/avalon/amd_pci_int_defs.h
new file mode 100644
index 0000000..e6bd2da
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/amd_pci_int_defs.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AMD_PCI_INT_DEFS_H
+#define AMD_PCI_INT_DEFS_H
+
+/*
+ * PIRQ and device routing - these define the index
+ * into the FCH PCI_INTR 0xC00/0xC01 interrupt
+ * routing table
+ */
+#define FCH_INT_TABLE_SIZE 0x63
+
+#define PIRQ_NC		0x1F	/* Not Used */
+#define PIRQ_A		0x00	/* INT A */
+#define PIRQ_B		0x01	/* INT B */
+#define PIRQ_C		0x02	/* INT C */
+#define PIRQ_D		0x03	/* INT D */
+#define PIRQ_E		0x04	/* INT E */
+#define PIRQ_F		0x05	/* INT F */
+#define PIRQ_G		0x06	/* INT G */
+#define PIRQ_H		0x07	/* INT H */
+#define PIRQ_MISC	0x08	/* Miscellaneous IRQ Settings - See FCH Spec */
+#define PIRQ_MISC0	0x09	/* Miscellaneous0 IRQ Settings */
+#define PIRQ_MISC1	0x0A	/* Miscellaneous1 IRQ Settings */
+#define PIRQ_MISC2	0x0B	/* Miscellaneous2 IRQ Settings */
+#define PIRQ_SIRQA	0x0C	/* Serial IRQ INTA */
+#define PIRQ_SIRQB	0x0D	/* Serial IRQ INTA */
+#define PIRQ_SIRQC	0x0E	/* Serial IRQ INTA */
+#define PIRQ_SIRQD	0x0F	/* Serial IRQ INTA */
+#define PIRQ_SCI	0x10	/* SCI IRQ */
+#define PIRQ_SMBUS	0x11	/* SMBUS	14h.0 */
+#define PIRQ_ASF	0x12	/* ASF */
+#define PIRQ_HDA	0x13	/* HDA		14h.2 */
+#define PIRQ_FC		0x14	/* FC */
+#define PIRQ_GEC	0x15	/* GEC */
+#define PIRQ_PMON	0x16	/* Performance Monitor */
+#define PIRQ_SD 	0x17	/* SD */
+#define PIRQ_IMC0	0x20	/* IMC INT0 */
+#define PIRQ_IMC1	0x21	/* IMC INT1 */
+#define PIRQ_IMC2	0x22	/* IMC INT2 */
+#define PIRQ_IMC3	0x23	/* IMC INT3 */
+#define PIRQ_IMC4	0x24	/* IMC INT4 */
+#define PIRQ_IMC5	0x25	/* IMC INT5 */
+#define PIRQ_OHCI1	0x30	/* USB OHCI	12h.0 */
+#define PIRQ_EHCI1	0x31	/* USB EHCI	12h.2 */
+#define PIRQ_OHCI2	0x32	/* USB OHCI	13h.0 */
+#define PIRQ_EHCI2	0x33	/* USB EHCI	13h.2 */
+#define PIRQ_OHCI3	0x34	/* USB OHCI	16h.0 */
+#define PIRQ_EHCI3	0x35	/* USB EHCI	16h.2 */
+#define PIRQ_OHCI4	0x36	/* USB OHCI	14h.5 */
+#define PIRQ_IDE	0x40	/* IDE		14h.1 */
+#define PIRQ_SATA	0x41	/* SATA		11h.0 */
+#define PIRQ_GPIO	0x62	/* GPIO Controller Interrupt */
+
+#endif /* AMD_PCI_INT_DEFS_H */
diff --git a/src/southbridge/amd/pi/avalon/amd_pci_int_types.h b/src/southbridge/amd/pi/avalon/amd_pci_int_types.h
new file mode 100644
index 0000000..d0fe9c8
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/amd_pci_int_types.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AMD_PCI_INT_TYPES_H
+#define AMD_PCI_INT_TYPES_H
+
+const char * intr_types[] = {
+	[0x00] = "INTA#\t", "INTB#\t", "INTC#\t", "INTD#\t", "INTE#\t", "INTF#\t", "INTG#\t", "INTH#\t",
+	[0x08] = "Misc\t", "Misc0\t", "Misc1\t", "Misc2\t", "Ser IRQ INTA", "Ser IRQ INTB", "Ser IRQ INTC", "Ser IRQ INTD",
+	[0x10] = "SCI\t", "SMBUS0\t", "ASF\t", "HDA\t", "FC\t\t", "GEC\t", "PerMon\t", "SD\t",
+	[0x20] = "IMC INT0\t", "IMC INT1\t", "IMC INT2\t", "IMC INT3\t", "IMC INT4\t", "IMC INT5\t",
+	[0x30] = "Dev18.0 INTA", "Dev18.2 INTB", "Dev19.0 INTA", "Dev19.2 INTB", "Dev22.0 INTA", "Dev22.2 INTB",
+	[0x40] = "RSVD\t", "SATA\t",
+	[0x60] = "RSVD\t", "RSVD\t", "GPIO\t",
+};
+
+#endif /* AMD_PCI_INT_TYPES_H */
diff --git a/src/southbridge/amd/pi/avalon/bootblock.c b/src/southbridge/amd/pi/avalon/bootblock.c
new file mode 100644
index 0000000..65810fa
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/bootblock.c
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <device/pci_ids.h>
+
+/*
+ * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
+ *
+ * Hardware should enable LPC ROM by pin straps. This function does not
+ * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
+ *
+ * The HUDSON power-on default is to map 512K ROM space.
+ *
+ */
+static void hudson_enable_rom(void)
+{
+	u8 reg8;
+	device_t dev;
+
+	dev = PCI_DEV(0, 0x14, 3);
+
+	/* Decode variable LPC ROM address ranges 1 and 2. */
+	reg8 = pci_read_config8(dev, 0x48);
+	reg8 |= (1 << 3) | (1 << 4);
+	pci_write_config8(dev, 0x48, reg8);
+
+	/* LPC ROM address range 1: */
+	/* Enable LPC ROM range mirroring start at 0x000e(0000). */
+	pci_write_config16(dev, 0x68, 0x000e);
+	/* Enable LPC ROM range mirroring end at 0x000f(ffff). */
+	pci_write_config16(dev, 0x6a, 0x000f);
+
+	/* LPC ROM address range 2: */
+	/*
+	 * Enable LPC ROM range start at:
+	 * 0xfff8(0000): 512KB
+	 * 0xfff0(0000): 1MB
+	 * 0xffe0(0000): 2MB
+	 * 0xffc0(0000): 4MB
+	 */
+	pci_write_config16(dev, 0x6c, 0x10000 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
+	/* Enable LPC ROM range end at 0xffff(ffff). */
+	pci_write_config16(dev, 0x6e, 0xffff);
+}
+
+static void bootblock_southbridge_init(void)
+{
+	hudson_enable_rom();
+}
diff --git a/src/southbridge/amd/pi/avalon/chip.h b/src/southbridge/amd/pi/avalon/chip.h
new file mode 100644
index 0000000..40b2480
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/chip.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVALON_CHIP_H
+#define AVALON_CHIP_H
+
+struct southbridge_amd_pi_avalon_config
+{
+	#if 1
+	u32 ide0_enable : 1;
+	u32 sata0_enable : 1;
+	u32 boot_switch_sata_ide : 1;
+	u32 hda_viddid;
+	u8  gpp_configuration;
+	u8  sd_mode;
+	#endif
+};
+
+#endif /* AVALON_CHIP_H */
diff --git a/src/southbridge/amd/pi/avalon/early_setup.c b/src/southbridge/amd/pi/avalon/early_setup.c
new file mode 100644
index 0000000..039df20
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/early_setup.c
@@ -0,0 +1,156 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _HUDSON_EARLY_SETUP_C_
+#define _HUDSON_EARLY_SETUP_C_
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <reset.h>
+#include <arch/cpu.h>
+#include <cbmem.h>
+#include "hudson.h"
+
+void hudson_pci_port80(void)
+{
+	u8 byte;
+	device_t dev;
+
+	/* P2P Bridge */
+	dev = PCI_DEV(0, 0x14, 4);
+
+	/* Chip Control: Enable subtractive decoding */
+	byte = pci_read_config8(dev, 0x40);
+	byte |= 1 << 5;
+	pci_write_config8(dev, 0x40, byte);
+
+	/* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
+	byte = pci_read_config8(dev, 0x4B);
+	byte |= 1 << 7;
+	pci_write_config8(dev, 0x4B, byte);
+
+	/* The same IO Base and IO Limit here is meaningful because we set the
+	 * bridge to be subtractive. During early setup stage, we have to make
+	 * sure that data can go through port 0x80.
+	 */
+	/* IO Base: 0xf000 */
+	byte = pci_read_config8(dev, 0x1C);
+	byte |= 0xF << 4;
+	pci_write_config8(dev, 0x1C, byte);
+
+	/* IO Limit: 0xf000 */
+	byte = pci_read_config8(dev, 0x1D);
+	byte |= 0xF << 4;
+	pci_write_config8(dev, 0x1D, byte);
+
+	/* PCI Command: Enable IO response */
+	byte = pci_read_config8(dev, 0x04);
+	byte |= 1 << 0;
+	pci_write_config8(dev, 0x04, byte);
+
+	/* LPC controller */
+	dev = PCI_DEV(0, 0x14, 3);
+
+	byte = pci_read_config8(dev, 0x4A);
+	byte &= ~(1 << 5); /* disable lpc port 80 */
+	pci_write_config8(dev, 0x4A, byte);
+}
+
+void hudson_lpc_port80(void)
+{
+	u8 byte;
+	device_t dev;
+
+	/* Enable LPC controller */
+	outb(0xEC, 0xCD6);
+	byte = inb(0xCD7);
+	byte |= 1;
+	outb(0xEC, 0xCD6);
+	outb(byte, 0xCD7);
+
+	/* Enable port 80 LPC decode in pci function 3 configuration space. */
+	dev = PCI_DEV(0, 0x14, 3);
+	byte = pci_read_config8(dev, 0x4a);
+	byte |= 1 << 5; /* enable port 80 */
+	pci_write_config8(dev, 0x4a, byte);
+}
+
+int s3_save_nvram_early(u32 dword, int size, int  nvram_pos)
+{
+	int i;
+	printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos);
+
+	for (i = 0; i<size; i++) {
+		outb(nvram_pos, BIOSRAM_INDEX);
+		outb((dword >>(8 * i)) & 0xff , BIOSRAM_DATA);
+		nvram_pos++;
+	}
+
+	return nvram_pos;
+}
+
+int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
+{
+	u32 data = *old_dword;
+	int i;
+	for (i = 0; i<size; i++) {
+		outb(nvram_pos, BIOSRAM_INDEX);
+		data &= ~(0xff << (i * 8));
+		data |= inb(BIOSRAM_DATA) << (i *8);
+		nvram_pos++;
+	}
+	*old_dword = data;
+	printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", *old_dword, size,
+		nvram_pos-size);
+	return nvram_pos;
+}
+
+#if CONFIG_HAVE_ACPI_RESUME
+int acpi_get_sleep_type(void)
+{
+	u16 tmp = inw(ACPI_PM1_CNT_BLK);
+	tmp = ((tmp & (7 << 10)) >> 10);
+	/* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */
+	return (int)tmp;
+}
+#endif
+
+#if CONFIG_HAVE_ACPI_RESUME
+int acpi_is_wakeup_early(void)
+{
+	return (acpi_get_sleep_type() == 3);
+}
+#endif
+
+unsigned long get_top_of_ram(void)
+{
+	uint32_t xdata = 0;
+	int xnvram_pos = 0xf8, xi;
+	for (xi = 0; xi<4; xi++) {
+		outb(xnvram_pos, BIOSRAM_INDEX);
+		xdata &= ~(0xff << (xi * 8));
+		xdata |= inb(BIOSRAM_DATA) << (xi *8);
+		xnvram_pos++;
+	}
+	return (unsigned long) xdata;
+}
+
+#endif
diff --git a/src/southbridge/amd/pi/avalon/enable_usbdebug.c b/src/southbridge/amd/pi/avalon/enable_usbdebug.c
new file mode 100644
index 0000000..258267e
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/enable_usbdebug.c
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+// Use simple device model for this file even in ramstage
+#define __SIMPLE_DEVICE__
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <device/pci_ehci.h>
+#include <device/pci_def.h>
+#include "hudson.h"
+
+#define DEBUGPORT_MISC_CONTROL		0x80
+
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+	if (hcd_idx==3)
+		return PCI_DEV(0, 0x16, 2);
+	else if (hcd_idx==2)
+		return PCI_DEV(0, 0x13, 2);
+	else
+		return PCI_DEV(0, 0x12, 2);
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
+{
+	u32 base_regs = pci_ehci_base_regs(dev);
+	u32 reg32;
+
+	/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
+	reg32 = read32(base_regs + DEBUGPORT_MISC_CONTROL);
+	reg32 &= ~(0xf << 28);
+	reg32 |= (port << 28);
+	reg32 |= (1 << 27); /* Enable Debug Port port number remapping. */
+	write32(base_regs + DEBUGPORT_MISC_CONTROL, reg32);
+}
+
+
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
+{
+	/* Enable all of the USB controllers */
+	outb(0xEF, PM_INDEX);
+	outb(0x7F, PM_DATA);
+
+	pci_write_config32(dev, EHCI_BAR_INDEX, base);
+	pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+}
diff --git a/src/southbridge/amd/pi/avalon/fadt.c b/src/southbridge/amd/pi/avalon/fadt.c
new file mode 100644
index 0000000..f86016a
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/fadt.c
@@ -0,0 +1,211 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * ACPI - create the Fixed ACPI Description Tables (FADT)
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include "hudson.h"
+#include "smi.h"
+
+#if CONFIG_HUDSON_LEGACY_FREE
+	#define FADT_BOOT_ARCH ACPI_FADT_LEGACY_FREE
+#else
+	#define FADT_BOOT_ARCH (ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042)
+#endif
+
+#ifndef FADT_PM_PROFILE
+	#define FADT_PM_PROFILE PM_UNSPECIFIED
+#endif
+
+/*
+ * Reference section 5.2.9 Fixed ACPI Description Table (FADT)
+ * in the ACPI 3.0b specification.
+ */
+void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
+{
+	acpi_header_t *header = &(fadt->header);
+
+	printk(BIOS_DEBUG, "pm_base: 0x%04x\n", HUDSON_ACPI_IO_BASE);
+
+	/* Prepare the header */
+	memset((void *)fadt, 0, sizeof(acpi_fadt_t));
+	memcpy(header->signature, "FACP", 4);
+	header->length = sizeof(acpi_fadt_t);
+	header->revision = ACPI_FADT_REV_ACPI_3_0;
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+	memcpy(header->asl_compiler_id, ASLC, 4);
+	header->asl_compiler_revision = 0;
+
+	fadt->firmware_ctrl = (u32) facs;
+	fadt->dsdt = (u32) dsdt;
+	fadt->model = 0;		/* reserved, should be 0 ACPI 3.0 */
+	fadt->preferred_pm_profile = FADT_PM_PROFILE;
+	fadt->sci_int = 9;		/* HUDSON - IRQ 09 – ACPI SCI */
+
+	if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
+		fadt->smi_cmd = ACPI_SMI_CTL_PORT;
+		fadt->acpi_enable = ACPI_SMI_CMD_ENABLE;
+		fadt->acpi_disable = ACPI_SMI_CMD_DISABLE;
+		fadt->s4bios_req = 0;	/* Not supported */
+		fadt->pstate_cnt = 0;	/* Not supported */
+		fadt->cst_cnt = 0;	/* Not supported */
+		outl(0x0, ACPI_PM1_CNT_BLK);	/* clear SCI_EN */
+	} else {
+		fadt->smi_cmd = 0;	/* disable system management mode */
+		fadt->acpi_enable = 0;	/* unused if SMI_CMD = 0 */
+		fadt->acpi_disable = 0;	/* unused if SMI_CMD = 0 */
+		fadt->s4bios_req = 0;	/* unused if SMI_CMD = 0 */
+		fadt->pstate_cnt = 0;	/* unused if SMI_CMD = 0 */
+		fadt->cst_cnt = 0x00;	/* unused if SMI_CMD = 0 */
+		outl(0x1, ACPI_PM1_CNT_BLK);	/* set SCI_EN */
+	}
+
+	fadt->pm1a_evt_blk = ACPI_PM_EVT_BLK;
+	fadt->pm1b_evt_blk = 0x0000;
+	fadt->pm1a_cnt_blk = ACPI_PM1_CNT_BLK;
+	fadt->pm1b_cnt_blk = 0x0000;
+	fadt->pm2_cnt_blk = 0x0000;
+	fadt->pm_tmr_blk = ACPI_PM_TMR_BLK;
+	fadt->gpe0_blk = ACPI_GPE0_BLK;
+	fadt->gpe1_blk = 0x0000;		/* No gpe1 block in hudson */
+
+	fadt->pm1_evt_len = 4;	/* 32 bits */
+	fadt->pm1_cnt_len = 2;	/* 16 bits */
+	fadt->pm2_cnt_len = 0;
+	fadt->pm_tmr_len = 4;	/* 32 bits */
+	fadt->gpe0_blk_len = 8;	/* 64 bits */
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+
+	fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
+	fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
+	fadt->flush_size = 0;	/* set to 0 if WBINVD is 1 in flags */
+	fadt->flush_stride = 0;	/* set to 0 if WBINVD is 1 in flags */
+	fadt->duty_offset = 1;	/* CLK_VAL bits 3:1 */
+	fadt->duty_width = 3;	/* CLK_VAL bits 3:1 */
+	fadt->day_alrm = 0;	/* 0x7d these have to be */
+	fadt->mon_alrm = 0;	/* 0x7e added to cmos.layout */
+	fadt->century = 0;	/* 0x7f to make rtc alarm work */
+	fadt->iapc_boot_arch = FADT_BOOT_ARCH;	/* See table 5-10 */
+	fadt->res2 = 0;		/* reserved, MUST be 0 ACPI 3.0 */
+	fadt->flags = ACPI_FADT_WBINVD | /* See table 5-10 ACPI 3.0a spec */
+				ACPI_FADT_C1_SUPPORTED |
+				ACPI_FADT_SLEEP_BUTTON |
+				ACPI_FADT_S4_RTC_WAKE |
+				ACPI_FADT_32BIT_TIMER |
+				ACPI_FADT_RESET_REGISTER |
+				ACPI_FADT_PCI_EXPRESS_WAKE |
+				ACPI_FADT_PLATFORM_CLOCK |
+				ACPI_FADT_S4_RTC_VALID |
+				ACPI_FADT_REMOTE_POWER_ON;
+
+	/* Format is from 5.2.3.1: Generic Address Structure */
+	/* reset_reg: see section 4.7.3.6 ACPI 3.0a spec */
+	/* 8 bit write of value 0x06 to 0xCF9 in IO space */
+	fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->reset_reg.bit_width = 8;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->reset_reg.addrl = 0xcf9;
+	fadt->reset_reg.addrh = 0x0;
+
+	fadt->reset_value = 6;
+
+	fadt->res3 = 0;		/* reserved, MUST be 0 ACPI 3.0 */
+	fadt->res4 = 0;		/* reserved, MUST be 0 ACPI 3.0 */
+	fadt->res5 = 0;		/* reserved, MUST be 0 ACPI 3.0 */
+
+	fadt->x_firmware_ctl_l = 0;	/* set to 0 if firmware_ctrl is used */
+	fadt->x_firmware_ctl_h = 0;
+	fadt->x_dsdt_l = (u32) dsdt;
+	fadt->x_dsdt_h = 0;
+
+	fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_evt_blk.bit_width = 32;
+	fadt->x_pm1a_evt_blk.bit_offset = 0;
+	fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
+	fadt->x_pm1a_evt_blk.addrl = ACPI_PM_EVT_BLK;
+	fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_evt_blk.bit_width = 0;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.access_size = 0;
+	fadt->x_pm1b_evt_blk.addrl = 0x0;
+	fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+
+	fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_cnt_blk.bit_width = 16;
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.access_size = 0;
+	fadt->x_pm1a_cnt_blk.addrl = ACPI_PM1_CNT_BLK;
+	fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_cnt_blk.bit_width = 0;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.access_size = 0;
+	fadt->x_pm1b_cnt_blk.addrl = 0x0;
+	fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+	/*
+	 * Note: Under this current AMD C state implementation, this is no longer
+	 *       used and should not be reported to OS.
+	 */
+	fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm2_cnt_blk.bit_width = 0;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->x_pm2_cnt_blk.addrl = 0;
+	fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+
+	fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm_tmr_blk.bit_width = 32;
+	fadt->x_pm_tmr_blk.bit_offset = 0;
+	fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_pm_tmr_blk.addrl = ACPI_PM_TMR_BLK;
+	fadt->x_pm_tmr_blk.addrh = 0x0;
+
+
+	fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + Event Enable */
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_gpe0_blk.addrl = ACPI_GPE0_BLK;
+	fadt->x_gpe0_blk.addrh = 0x0;
+
+
+	fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.access_size = 0;
+	fadt->x_gpe1_blk.addrl = 0;
+	fadt->x_gpe1_blk.addrh = 0x0;
+
+	header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t));
+}
diff --git a/src/southbridge/amd/pi/avalon/hda.c b/src/southbridge/amd/pi/avalon/hda.c
new file mode 100644
index 0000000..2e648b7
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/hda.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "hudson.h"
+
+
+static void hda_init(struct device *dev)
+{
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations hda_audio_ops = {
+	.read_resources = pci_dev_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = hda_init,
+	.scan_bus = 0,
+	.ops_pci = &lops_pci,
+};
+
+static const struct pci_driver hdaaudio_driver __pci_driver = {
+	.ops = &hda_audio_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_HDA,
+};
diff --git a/src/southbridge/amd/pi/avalon/hudson.c b/src/southbridge/amd/pi/avalon/hudson.c
new file mode 100644
index 0000000..84eaf30
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/hudson.c
@@ -0,0 +1,173 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+
+#include <arch/io.h>
+#include <arch/acpi.h>
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cbmem.h>
+#include "hudson.h"
+#include "smbus.h"
+#include "smi.h"
+
+/* Offsets from ACPI_MMIO_BASE
+ * This is defined by AGESA, but we don't include AGESA headers to avoid
+ * polluting the namesace.
+ */
+#define PM_MMIO_BASE 0xfed80300
+
+
+#if CONFIG_HAVE_ACPI_RESUME
+int acpi_get_sleep_type(void)
+{
+	u16 tmp = inw(ACPI_PM1_CNT_BLK);
+	tmp = ((tmp & (7 << 10)) >> 10);
+	/* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */
+	return (int)tmp;
+}
+#endif
+
+void backup_top_of_ram(uint64_t ramtop)
+{
+	u32 dword = (u32) ramtop;
+	int nvram_pos = 0xf8, i; /* temp */
+	/* printk(BIOS_DEBUG, "dword=%x\n", dword); */
+	for (i = 0; i<4; i++) {
+		/* printk(BIOS_DEBUG, "nvram_pos=%x, dword>>(8*i)=%x\n", nvram_pos, (dword >>(8 * i)) & 0xff); */
+		outb(nvram_pos, BIOSRAM_INDEX);
+		outb((dword >>(8 * i)) & 0xff , BIOSRAM_DATA);
+		nvram_pos++;
+	}
+}
+
+void pm_write8(u8 reg, u8 value)
+{
+	write8(PM_MMIO_BASE + reg, value);
+}
+
+u8 pm_read8(u8 reg)
+{
+	return read8(PM_MMIO_BASE + reg);
+}
+
+void pm_write16(u8 reg, u16 value)
+{
+	write16(PM_MMIO_BASE + reg, value);
+}
+
+u16 pm_read16(u16 reg)
+{
+	return read16(PM_MMIO_BASE + reg);
+}
+
+void hudson_enable(device_t dev)
+{
+	printk(BIOS_DEBUG, "hudson_enable()\n");
+	switch (dev->path.pci.devfn) {
+	case (0x14 << 3) | 7: /* 0:14.7  SD */
+		if (dev->enabled == 0) {
+			// read the VENDEV ID
+			device_t sd_dev = dev_find_slot( 0, PCI_DEVFN( 0x14, 7));
+			u32 sd_device_id = pci_read_config32( sd_dev, 0) >> 16;
+			/* turn off the SDHC controller in the PM reg */
+			u8 reg8;
+			if (sd_device_id == PCI_DEVICE_ID_AMD_HUDSON_SD) {
+				reg8 = pm_read8(0xe7);
+				reg8 &= ~(1 << 0);
+				pm_write8(0xe7, reg8);
+			}
+			else if (sd_device_id == PCI_DEVICE_ID_AMD_YANGTZE_SD) {
+				reg8 = pm_read8(0xe8);
+				reg8 &= ~(1 << 0);
+				pm_write8(0xe8, reg8);
+			}
+			/* remove device 0:14.7 from PCI space */
+			reg8 = pm_read8(0xd3);
+			reg8 &= ~(1 << 6);
+			pm_write8(0xd3, reg8);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+#if CONFIG_HAVE_ACPI_RESUME
+unsigned long get_top_of_ram(void)
+{
+	uint32_t xdata = 0;
+	int xnvram_pos = 0xf8, xi;
+	if (acpi_get_sleep_type() != 3)
+		return 0;
+	for (xi = 0; xi<4; xi++) {
+		outb(xnvram_pos, BIOSRAM_INDEX);
+		xdata &= ~(0xff << (xi * 8));
+		xdata |= inb(BIOSRAM_DATA) << (xi *8);
+		xnvram_pos++;
+	}
+	return (unsigned long) xdata;
+}
+#endif
+
+static void hudson_init_acpi_ports(void)
+{
+	/* We use some of these ports in SMM regardless of whether or not
+	 * ACPI tables are generated. Enable these ports indiscriminately.
+	 */
+
+	pm_write16(0x60, ACPI_PM_EVT_BLK);
+	pm_write16(0x62, ACPI_PM1_CNT_BLK);
+	pm_write16(0x64, ACPI_PM_TMR_BLK);
+	pm_write16(0x68, ACPI_GPE0_BLK);
+	/* CpuControl is in \_PR.CPU0, 6 bytes */
+	pm_write16(0x66, ACPI_CPU_CONTROL);
+
+	if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
+		pm_write16(0x6a, ACPI_SMI_CTL_PORT);
+		hudson_enable_acpi_cmd_smi();
+	} else {
+		pm_write16(0x6a, 0);
+	}
+
+	/* AcpiDecodeEnable, When set, SB uses the contents of the PM registers
+	 * at index 60-6B to decode ACPI I/O address. AcpiSmiEn & SmiCmdEn
+	 */
+	pm_write8(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2);
+}
+
+static void hudson_init(void *chip_info)
+{
+	hudson_init_acpi_ports();
+}
+
+static void hudson_final(void *chip_info)
+{
+}
+
+struct chip_operations southbridge_amd_pi_avalon_ops = {
+	CHIP_NAME("ATI HUDSON")
+	.enable_dev = hudson_enable,
+	.init = hudson_init,
+	.final = hudson_final
+};
diff --git a/src/southbridge/amd/pi/avalon/hudson.h b/src/southbridge/amd/pi/avalon/hudson.h
new file mode 100644
index 0000000..f67af05
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/hudson.h
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef HUDSON_H
+#define HUDSON_H
+
+#include <device/pci_ids.h>
+#include <device/device.h>
+#include "chip.h"
+
+/* Power management index/data registers */
+#define BIOSRAM_INDEX	0xcd4
+#define BIOSRAM_DATA	0xcd5
+#define PM_INDEX	0xcd6
+#define PM_DATA		0xcd7
+#define PM2_INDEX	0xcd0
+#define PM2_DATA	0xcd1
+
+#define HUDSON_ACPI_IO_BASE 0x800
+
+#define ACPI_PM_EVT_BLK		(HUDSON_ACPI_IO_BASE + 0x00) /* 4 bytes */
+#define ACPI_PM1_CNT_BLK	(HUDSON_ACPI_IO_BASE + 0x04) /* 2 bytes */
+#define ACPI_PM_TMR_BLK		(HUDSON_ACPI_IO_BASE + 0x18) /* 4 bytes */
+#define ACPI_GPE0_BLK		(HUDSON_ACPI_IO_BASE + 0x10) /* 8 bytes */
+#define ACPI_CPU_CONTROL	(HUDSON_ACPI_IO_BASE + 0x08) /* 6 bytes */
+
+#define ACPI_SMI_CTL_PORT		0xb2
+#define ACPI_SMI_CMD_CST_CONTROL	0xde
+#define ACPI_SMI_CMD_PST_CONTROL	0xad
+#define ACPI_SMI_CMD_DISABLE		0xbe
+#define ACPI_SMI_CMD_ENABLE		0xef
+#define ACPI_SMI_CMD_S4_REQ		0xc0
+
+#define REV_HUDSON_A11	0x11
+#define REV_HUDSON_A12	0x12
+
+#define SPIROM_BASE_ADDRESS_REGISTER  0xA0
+#define SPI_ROM_ENABLE                0x02
+#define SPI_BASE_ADDRESS              0xFEC10000
+
+#ifndef __SMM__
+
+void pm_write8(u8 reg, u8 value);
+u8 pm_read8(u8 reg);
+void pm_write16(u8 reg, u16 value);
+u16 pm_read16(u16 reg);
+
+#ifdef __PRE_RAM__
+void hudson_lpc_port80(void);
+void hudson_pci_port80(void);
+void hudson_clk_output_48Mhz(void);
+
+int s3_save_nvram_early(u32 dword, int size, int  nvram_pos);
+int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos);
+
+#else
+void hudson_enable(device_t dev);
+void __attribute__((weak)) hudson_setup_sata_phys(struct device *dev);
+void s3_resume_init_data(void *FchParams);
+
+#endif /* __PRE_RAM__ */
+#endif /* __SMM__ */
+
+#endif /* HUDSON_H */
diff --git a/src/southbridge/amd/pi/avalon/ide.c b/src/southbridge/amd/pi/avalon/ide.c
new file mode 100644
index 0000000..cd80f99
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/ide.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "hudson.h"
+
+static void ide_init(struct device *dev)
+{
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+	.read_resources = pci_dev_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = ide_init,
+	.scan_bus = 0,
+	.ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+	.ops = &ide_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_IDE,
+};
diff --git a/src/southbridge/amd/pi/avalon/lpc.c b/src/southbridge/amd/pi/avalon/lpc.c
new file mode 100644
index 0000000..129a615
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/lpc.c
@@ -0,0 +1,343 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pci_def.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include "hudson.h"
+
+static void lpc_init(device_t dev)
+{
+	u8 byte;
+	u32 dword;
+	device_t sm_dev;
+
+	/* Enable the LPC Controller */
+	sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+	dword = pci_read_config32(sm_dev, 0x64);
+	dword |= 1 << 20;
+	pci_write_config32(sm_dev, 0x64, dword);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+
+	/* Enable DMA transaction on the LPC bus */
+	byte = pci_read_config8(dev, 0x40);
+	byte |= (1 << 2);
+	pci_write_config8(dev, 0x40, byte);
+
+	/* Disable the timeout mechanism on LPC */
+	byte = pci_read_config8(dev, 0x48);
+	byte &= ~(1 << 7);
+	pci_write_config8(dev, 0x48, byte);
+
+	/* Disable LPC MSI Capability */
+	byte = pci_read_config8(dev, 0x78);
+	byte &= ~(1 << 1);
+	byte &= ~(1 << 0);	/* Keep the old way. i.e., when bus master/DMA cycle is going
+				   on on LPC, it holds PCI grant, so no LPC slave cycle can
+				   interrupt and visit LPC. */
+	pci_write_config8(dev, 0x78, byte);
+
+	/* bit0: Enable prefetch a cacheline (64 bytes) when Host reads code from SPI rom */
+	/* bit3: Fix SPI_CS# timing issue when running at 66M. TODO:A12. */
+	byte = pci_read_config8(dev, 0xBB);
+	byte |= 1 << 0 | 1 << 3;
+	pci_write_config8(dev, 0xBB, byte);
+
+	cmos_check_update_date(RTC_HAS_ALTCENTURY);
+
+	/* Initialize the real time clock.
+	 * The 0 argument tells cmos_init not to
+	 * update CMOS unless it is invalid.
+	 * 1 tells cmos_init to always initialize the CMOS.
+	 */
+	cmos_init(0);
+}
+
+static void hudson_lpc_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Get the normal pci resources of this device */
+	pci_dev_read_resources(dev);	/* We got one for APIC, or one more for TRAP */
+
+	/* Add an extra subtractive resource for both memory and I/O. */
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+	res->base = 0;
+	res->size = 0x1000;
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	res->base = 0xff800000;
+	res->size = 0x00800000; /* 8 MB for flash */
+	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	/* Add a memory resource for the SPI BAR. */
+	fixed_mem_resource(dev, 2, SPI_BASE_ADDRESS / 1024, 1, IORESOURCE_SUBTRACTIVE);
+
+	res = new_resource(dev, 3); /* IOAPIC */
+	res->base = IO_APIC_ADDR;
+	res->size = 0x00001000;
+	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+	compact_resources(dev);
+}
+
+static void hudson_lpc_set_resources(struct device *dev)
+{
+	struct resource *res;
+
+	/* Special case. SPI Base Address. The SpiRomEnable should STAY set. */
+	res = find_resource(dev, 2);
+	pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, res->base | SPI_ROM_ENABLE);
+
+	pci_dev_set_resources(dev);
+}
+
+/**
+ * @brief Enable resources for children devices
+ *
+ * @param dev the device whos children's resources are to be enabled
+ *
+ */
+static void hudson_lpc_enable_childrens_resources(device_t dev)
+{
+	struct bus *link;
+	u32 reg, reg_x;
+	int var_num = 0;
+	u16 reg_var[3];
+	u16 reg_size[1] =  {512};
+	u8 wiosize = pci_read_config8(dev, 0x74);
+
+	/* Be bit relaxed, tolerate that LPC region might be bigger than resource we try to fit,
+	 * do it like this for all regions < 16 bytes. If there is a resource > 16 bytes
+	 * it must be 512 bytes to be able to allocate the fresh LPC window.
+	 *
+	 * AGESA likes to enable already one LPC region in wide port base 0x64-0x65,
+	 * using DFLT_SIO_PME_BASE_ADDRESS, 512 bytes size
+	 * The code tries to check if resource can fit into this region
+	 */
+
+	reg = pci_read_config32(dev, 0x44);
+	reg_x = pci_read_config32(dev, 0x48);
+
+	/* check if ranges are free and not use them if entry is just already taken */
+	if (reg_x & (1 << 2))
+		var_num = 1;
+	/* just in case check if someone did not manually set other ranges too */
+	if (reg_x & (1 << 24))
+		var_num = 2;
+
+	if (reg_x & (1 << 25))
+		var_num = 3;
+
+	/* check AGESA region size */
+	if (wiosize & (1 << 0))
+		reg_size[0] = 16;
+
+	reg_var[2] = pci_read_config16(dev, 0x90);
+	reg_var[1] = pci_read_config16(dev, 0x66);
+	reg_var[0] = pci_read_config16(dev, 0x64);
+
+	for (link = dev->link_list; link; link = link->next) {
+		device_t child;
+		for (child = link->children; child;
+		     child = child->sibling) {
+			if (child->enabled
+			    && (child->path.type == DEVICE_PATH_PNP)) {
+				struct resource *res;
+				for (res = child->resource_list; res; res = res->next) {
+					u32 base, end;	/*  don't need long long */
+					u32 rsize, set = 0, set_x = 0;
+					if (!(res->flags & IORESOURCE_IO))
+						continue;
+					base = res->base;
+					end = resource_end(res);
+					/* find a resource size */
+					printk(BIOS_DEBUG, "hudson lpc decode:%s, base=0x%08x, end=0x%08x\n",
+					     dev_path(child), base, end);
+					switch (base) {
+					case 0x60:	/*  KB */
+					case 0x64:	/*  MS */
+						set |= (1 << 29);
+						rsize = 1;
+						break;
+					case 0x3f8:	/*  COM1 */
+						set |= (1 << 6);
+						rsize = 8;
+						break;
+					case 0x2f8:	/*  COM2 */
+						set |= (1 << 7);
+						rsize = 8;
+						break;
+					case 0x378:	/*  Parallel 1 */
+						set |= (1 << 0);
+						set |= (1 << 1); /* + 0x778 for ECP */
+						rsize = 8;
+						break;
+					case 0x3f0:	/*  FD0 */
+						set |= (1 << 26);
+						rsize = 8;
+						break;
+					case 0x220:	/*  0x220 - 0x227 */
+						set |= (1 << 8);
+						rsize = 8;
+						break;
+					case 0x228:	/*  0x228 - 0x22f */
+						set |= (1 << 9);
+						rsize = 8;
+						break;
+					case 0x238:	/*  0x238 - 0x23f */
+						set |= (1 << 10);
+						rsize = 8;
+						break;
+					case 0x300:	/*  0x300 -0x301 */
+						set |= (1 << 18);
+						rsize = 2;
+						break;
+					case 0x400:
+						set_x |= (1 << 16);
+						rsize = 0x40;
+						break;
+					case 0x480:
+						set_x |= (1 << 17);
+						rsize = 0x40;
+						break;
+					case 0x500:
+						set_x |= (1 << 18);
+						rsize = 0x40;
+						break;
+					case 0x580:
+						set_x |= (1 << 19);
+						rsize = 0x40;
+						break;
+					case 0x4700:
+						set_x |= (1 << 22);
+						rsize = 0xc;
+						break;
+					case 0xfd60:
+						set_x |= (1 << 23);
+						rsize = 16;
+						break;
+					default:
+						rsize = 0;
+						/* try AGESA allocated region in region 0 */
+						if ((var_num > 0) && ((base >=reg_var[0]) &&
+								((base + res->size) <= (reg_var[0] + reg_size[0]))))
+							rsize = reg_size[0];
+					}
+					/* check if region found and matches the enable */
+					if (res->size <= rsize) {
+						reg |= set;
+						reg_x |= set_x;
+					/* check if we can fit resource in variable range */
+					} else if ((var_num < 3) &&
+						    ((res->size <= 16) || (res->size == 512))) {
+						/* use variable ranges if pre-defined do not match */
+						switch (var_num) {
+						case 0:
+							reg_x |= (1 << 2);
+							if (res->size <= 16) {
+								wiosize |= (1 << 0);
+							}
+							break;
+						case 1:
+							reg_x |= (1 << 24);
+							if (res->size <= 16)
+								wiosize |= (1 << 2);
+							break;
+						case 2:
+							reg_x |= (1 << 25);
+							if (res->size <= 16)
+								wiosize |= (1 << 3);
+							break;
+						}
+						reg_var[var_num++] =
+						    base & 0xffff;
+					} else {
+						printk(BIOS_ERR, "cannot fit LPC decode region:%s, base=0x%08x, end=0x%08x\n",
+							dev_path(child), base, end);
+					}
+				}
+			}
+		}
+	}
+	pci_write_config32(dev, 0x44, reg);
+	pci_write_config32(dev, 0x48, reg_x);
+	/* Set WideIO for as many IOs found (fall through is on purpose) */
+	switch (var_num) {
+	case 3:
+		pci_write_config16(dev, 0x90, reg_var[2]);
+		/* fall through */
+	case 2:
+		pci_write_config16(dev, 0x66, reg_var[1]);
+		/* fall through */
+	case 1:
+		pci_write_config16(dev, 0x64, reg_var[0]);
+		break;
+	}
+	pci_write_config8(dev, 0x74, wiosize);
+}
+
+static void hudson_lpc_enable_resources(device_t dev)
+{
+	pci_dev_enable_resources(dev);
+	hudson_lpc_enable_childrens_resources(dev);
+}
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+	/* Just a dummy */
+	return current;
+}
+
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+	.read_resources = hudson_lpc_read_resources,
+	.set_resources = hudson_lpc_set_resources,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) && IS_ENABLED(CONFIG_PER_DEVICE_ACPI_TABLES)
+	.write_acpi_tables = acpi_write_hpet,
+#endif
+	.enable_resources = hudson_lpc_enable_resources,
+	.init = lpc_init,
+	.scan_bus = scan_static_bus,
+	.ops_pci = &lops_pci,
+};
+static const struct pci_driver lpc_driver __pci_driver = {
+	.ops = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_LPC,
+};
diff --git a/src/southbridge/amd/pi/avalon/pci.c b/src/southbridge/amd/pi/avalon/pci.c
new file mode 100644
index 0000000..e8836e4
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/pci.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "hudson.h"
+#include <southbridge/amd/amd_pci_util.h>
+#include <bootstate.h>
+
+static void pci_init(struct device *dev)
+{
+}
+
+/*
+ * Update the PCI devices with a valid IRQ number
+ * that is set in the mainboard PCI_IRQ structures.
+ */
+static void set_pci_irqs(void *unused)
+{
+	/* Write PCI_INTR regs 0xC00/0xC01 */
+	write_pci_int_table();
+
+	/* Write IRQs for all devicetree enabled devices */
+	write_pci_cfg_irqs();
+}
+
+/*
+ * Hook this function into the PCI state machine
+ * on entry into BS_DEV_ENABLE.
+ */
+BOOT_STATE_INIT_ENTRIES(pci_irq_update) = {
+	BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY,
+	                      set_pci_irqs, NULL),
+};
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+	.read_resources = pci_bus_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init = pci_init,
+	.scan_bus = pci_scan_bridge,
+	.reset_bus = pci_bus_reset,
+	.ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+	.ops = &pci_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_PCI,
+};
diff --git a/src/southbridge/amd/pi/avalon/pci_devs.h b/src/southbridge/amd/pi/avalon/pci_devs.h
new file mode 100644
index 0000000..2af1659
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/pci_devs.h
@@ -0,0 +1,96 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _PI_HUDSON_PCI_DEVS_H_
+#define _PI_HUDSON_PCI_DEVS_H_
+
+#define BUS0 0
+
+/* XHCI */
+#define XHCI_DEV 0x10
+#define XHCI_FUNC 0
+#define XHCI_DEVID 0x7814
+#define XHCI_DEVFN PCI_DEVFN(XHCI_DEV,XHCI_FUNC)
+
+/* SATA */
+#define SATA_DEV 0x11
+#define SATA_FUNC 0
+#define SATA_IDE_DEVID 0x7800
+#define AHCI_DEVID_MS 0x7801
+#define AHCI_DEVID_AMD 0x7804
+#define SATA_DEVFN PCI_DEVFN(SATA_DEV,SATA_FUNC)
+
+/* OHCI */
+#define OHCI1_DEV 0x12
+#define OHCI1_FUNC 0
+#define OHCI2_DEV 0x13
+#define OHCI2_FUNC 0
+#define OHCI3_DEV 0x16
+#define OHCI3_FUNC 0
+#define OHCI4_DEV 0x14
+#define OHCI4_FUNC 5
+#define OHCI_DEVID 0x7807
+#define OHCI1_DEVFN PCI_DEVFN(OHCI1_DEV,OHCI1_FUNC)
+#define OHCI2_DEVFN PCI_DEVFN(OHCI2_DEV,OHCI2_FUNC)
+#define OHCI3_DEVFN PCI_DEVFN(OHCI3_DEV,OHCI3_FUNC)
+#define OHCI4_DEVFN PCI_DEVFN(OHCI4_DEV,OHCI4_FUNC)
+
+/* EHCI */
+#define EHCI1_DEV 0x12
+#define EHCI1_FUNC 2
+#define EHCI2_DEV 0x13
+#define EHCI2_FUNC 2
+#define EHCI3_DEV 0x22
+#define EHCI3_FUNC 2
+#define EHCI_DEVID 0x7808
+#define EHCI1_DEVFN PCI_DEVFN(EHCI1_DEV,EHCI1_FUNC)
+#define EHCI2_DEVFN PCI_DEVFN(EHCI2_DEV,EHCI2_FUNC)
+#define EHCI3_DEVFN PCI_DEVFN(EHCI3_DEV,EHCI3_FUNC)
+
+/* SMBUS */
+#define SMBUS_DEV 0x14
+#define SMBUS_FUNC 0
+#define SMBUS_DEVID 0x780B
+#define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV,SMBUS_FUNC)
+
+/* HD Audio */
+#define HDA_DEV 0x14
+#define HDA_FUNC 2
+#define HDA_DEVID 0x780D
+#define HDA_DEVFN PCI_DEVFN(HDA_DEV,HDA_FUNC)
+
+/* LPC BUS */
+#define PCU_DEV 0x14
+#define LPC_FUNC 3
+#define LPC_DEVID 0x780E
+#define LPC_DEVFN PCI_DEVFN(LPC_DEV,LPC_FUNC)
+
+/* PCI Ports */
+#define SB_PCI_PORT_DEV 0x14
+#define SB_PCI_PORT_FUNC 4
+# define SB_PCI_PORT_DEVID 0x780F
+# define SB_PCI_PORT_DEVFN PCI_DEVFN(SB_PCI_PORT_DEV,SB_PCI_PORT_FUNC)
+
+/* SD Controller */
+#define SD_DEV 0x14
+#define SD_FUNC 7
+#define SD_DEVID 0x7806
+#define SD_DEVFN PCI_DEVFN(SD_DEV,SD_FUNC)
+
+#endif /* _PI_HUDSON_PCI_DEVS_H_ */
diff --git a/src/southbridge/amd/pi/avalon/pcie.c b/src/southbridge/amd/pi/avalon/pcie.c
new file mode 100644
index 0000000..ec686fc
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/pcie.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "hudson.h"
+
+static void pcie_init(struct device *dev)
+{
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+	.read_resources = pci_bus_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init = pcie_init,
+	.scan_bus = pci_scan_bridge,
+	.reset_bus = pci_bus_reset,
+	.ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pciea_driver __pci_driver = {
+	.ops = &pci_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_PCIEA,
+};
+
+static const struct pci_driver pcieb_driver __pci_driver = {
+	.ops = &pci_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_PCIEB,
+};
+static const struct pci_driver pciec_driver __pci_driver = {
+	.ops = &pci_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_PCIEC,
+};
+static const struct pci_driver pcied_driver __pci_driver = {
+	.ops = &pci_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_PCIED,
+};
diff --git a/src/southbridge/amd/pi/avalon/reset.c b/src/southbridge/amd/pi/avalon/reset.c
new file mode 100644
index 0000000..79fd79e
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/reset.c
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+// Use simple device model for this file even in ramstage
+#define __SIMPLE_DEVICE__
+
+#include <arch/io.h>
+#include <reset.h>
+
+#include <northbridge/amd/amdk8/reset_test.c>
+
+void hard_reset(void)
+{
+	set_bios_reset();
+	/* Try rebooting through port 0xcf9 */
+	/* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+	outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
+	outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
+}
diff --git a/src/southbridge/amd/pi/avalon/sata.c b/src/southbridge/amd/pi/avalon/sata.c
new file mode 100644
index 0000000..2636b74
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/sata.c
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "hudson.h"
+
+
+static void sata_init(struct device *dev)
+{
+};
+
+static struct pci_operations lops_pci = {
+	/* .set_subsystem = pci_dev_set_subsystem, */
+};
+
+static struct device_operations sata_ops = {
+	.read_resources = pci_dev_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = sata_init,
+	.scan_bus = 0,
+	.ops_pci = &lops_pci,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+	.ops = &sata_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_SATA,
+};
+
+static const struct pci_driver sata0_driver_ahci __pci_driver = {
+	.ops = &sata_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_SATA_AHCI,
+};
diff --git a/src/southbridge/amd/pi/avalon/sd.c b/src/southbridge/amd/pi/avalon/sd.c
new file mode 100644
index 0000000..4367f7a
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/sd.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "hudson.h"
+
+static void sd_init(struct device *dev)
+{
+	u32 stepping;
+
+	stepping = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xFC);
+
+	struct southbridge_amd_pi_avalon_config *sd_chip =
+		(struct southbridge_amd_pi_avalon_config *)(dev->chip_info);
+
+	if (sd_chip->sd_mode == 3) {	/* SD 3.0 mode */
+		pci_write_config32(dev, 0xA4, 0x31FEC8B2);
+		pci_write_config32(dev, 0xA8, 0x00002503);
+		pci_write_config32(dev, 0xB0, 0x02180C19);
+		pci_write_config32(dev, 0xD0, 0x0000078B);
+	}
+	else {				/* SD 2.0 mode */
+		if ((stepping & 0x0000000F) == 0) {	/* Stepping A0 */
+			pci_write_config32(dev, 0xA4, 0x31DE32B2);
+			pci_write_config32(dev, 0xB0, 0x01180C19);
+			pci_write_config32(dev, 0xD0, 0x0000058B);
+		}
+		else {					/* Stepping >= A1 */
+			pci_write_config32(dev, 0xA4, 0x31FE3FB2);
+			pci_write_config32(dev, 0xB0, 0x01180C19);
+			pci_write_config32(dev, 0xD0, 0x0000078B);
+		}
+	}
+}
+
+static struct device_operations sd_ops = {
+	.read_resources = pci_dev_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = sd_init,
+	.scan_bus = 0,
+};
+
+static const struct pci_driver sd_driver __pci_driver = {
+	.ops = &sd_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_AMD_YANGTZE_SD,
+};
diff --git a/src/southbridge/amd/pi/avalon/sm.c b/src/southbridge/amd/pi/avalon/sm.c
new file mode 100644
index 0000000..d6ca215
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/sm.c
@@ -0,0 +1,174 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/io.h>
+#include <cpu/x86/lapic.h>
+#include <arch/ioapic.h>
+#include <stdlib.h>
+#include "hudson.h"
+#include "smbus.c"
+
+#define NMI_OFF 0
+
+#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
+
+#define BIT0	(1 << 0)
+#define BIT1	(1 << 1)
+#define BIT2	(1 << 2)
+#define BIT3	(1 << 3)
+#define BIT4	(1 << 4)
+#define BIT5	(1 << 5)
+#define BIT6	(1 << 6)
+#define BIT7	(1 << 7)
+
+#define BIT8	(1 << 8 )
+#define BIT9	(1 << 9 )
+#define BIT10	(1 << 10)
+#define BIT11	(1 << 11)
+#define BIT12	(1 << 12)
+#define BIT13	(1 << 13)
+#define BIT14	(1 << 14)
+#define BIT15	(1 << 15)
+
+#define BIT16	(1 << 16)
+#define BIT17	(1 << 17)
+#define BIT18	(1 << 18)
+#define BIT19	(1 << 19)
+#define BIT20	(1 << 20)
+#define BIT21	(1 << 21)
+#define BIT22	(1 << 22)
+#define BIT23	(1 << 23)
+#define BIT24	(1 << 24)
+#define BIT25	(1 << 25)
+#define BIT26	(1 << 26)
+#define BIT27	(1 << 27)
+#define BIT28	(1 << 28)
+#define BIT29	(1 << 29)
+#define BIT30	(1 << 30)
+#define BIT31	(1 << 31)
+
+/*
+* HUDSON enables all USB controllers by default in SMBUS Control.
+* HUDSON enables SATA by default in SMBUS Control.
+*/
+
+static void sm_init(device_t dev)
+{
+	setup_ioapic(IO_APIC_ADDR, CONFIG_MAX_CPUS);
+}
+
+static int lsmbus_recv_byte(device_t dev)
+{
+	u32 device;
+	struct resource *res;
+	struct bus *pbus;
+
+	device = dev->path.i2c.device;
+	pbus = get_pbus_smbus(dev);
+
+	res = find_resource(pbus->dev, 0x90);
+
+	return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, u8 val)
+{
+	u32 device;
+	struct resource *res;
+	struct bus *pbus;
+
+	device = dev->path.i2c.device;
+	pbus = get_pbus_smbus(dev);
+
+	res = find_resource(pbus->dev, 0x90);
+
+	return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+	u32 device;
+	struct resource *res;
+	struct bus *pbus;
+
+	device = dev->path.i2c.device;
+	pbus = get_pbus_smbus(dev);
+
+	res = find_resource(pbus->dev, 0x90);
+
+	return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
+{
+	u32 device;
+	struct resource *res;
+	struct bus *pbus;
+
+	device = dev->path.i2c.device;
+	pbus = get_pbus_smbus(dev);
+
+	res = find_resource(pbus->dev, 0x90);
+
+	return do_smbus_write_byte(res->base, device, address, val);
+}
+static struct smbus_bus_operations lops_smbus_bus = {
+	.recv_byte = lsmbus_recv_byte,
+	.send_byte = lsmbus_send_byte,
+	.read_byte = lsmbus_read_byte,
+	.write_byte = lsmbus_write_byte,
+};
+
+static void hudson_sm_read_resources(device_t dev)
+{
+}
+
+static void hudson_sm_set_resources(struct device *dev)
+{
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+static struct device_operations smbus_ops = {
+	.read_resources = hudson_sm_read_resources,
+	.set_resources = hudson_sm_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = sm_init,
+	.scan_bus = scan_static_bus,
+	.ops_pci = &lops_pci,
+	.ops_smbus_bus = &lops_smbus_bus,
+};
+static const struct pci_driver smbus_driver __pci_driver = {
+	.ops = &smbus_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_SM,
+};
diff --git a/src/southbridge/amd/pi/avalon/smbus.c b/src/southbridge/amd/pi/avalon/smbus.c
new file mode 100644
index 0000000..519c85d
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smbus.c
@@ -0,0 +1,250 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _HUDSON_SMBUS_C_
+#define _HUDSON_SMBUS_C_
+
+#include <io.h>
+#include <stdint.h>
+#include "smbus.h"
+
+static int smbus_wait_until_ready(u32 smbus_io_base)
+{
+	u32 loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		u8 val;
+		val = inb(smbus_io_base + SMBHSTSTAT);
+		val &= 0x1f;
+		if (val == 0) {	/* ready now */
+			return 0;
+		}
+		outb(val, smbus_io_base + SMBHSTSTAT);
+	} while (--loops);
+	return -2;		/* time out */
+}
+
+static int smbus_wait_until_done(u32 smbus_io_base)
+{
+	u32 loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		u8 val;
+
+		val = inb(smbus_io_base + SMBHSTSTAT);
+		val &= 0x1f;	/* mask off reserved bits */
+		if (val & 0x1c) {
+			return -5;	/* error */
+		}
+		if (val == 0x02) {
+			outb(val, smbus_io_base + SMBHSTSTAT);	/* clear status */
+			return 0;
+		}
+	} while (--loops);
+	return -3;		/* timeout */
+}
+
+int do_smbus_recv_byte(u32 smbus_io_base, u32 device)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return -2;	/* not ready */
+	}
+
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+
+	byte = inb(smbus_io_base + SMBHSTCTRL);
+	byte &= 0xe3;		/* Clear [4:2] */
+	byte |= (1 << 2) | (1 << 6);	/* Byte data read/write command, start the command */
+	outb(byte, smbus_io_base + SMBHSTCTRL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return -3;	/* timeout or error */
+	}
+
+	/* read results of transaction */
+	byte = inb(smbus_io_base + SMBHSTCMD);
+
+	return byte;
+}
+
+int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return -2;	/* not ready */
+	}
+
+	/* set the command... */
+	outb(val, smbus_io_base + SMBHSTCMD);
+
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+
+	byte = inb(smbus_io_base + SMBHSTCTRL);
+	byte &= 0xe3;		/* Clear [4:2] */
+	byte |= (1 << 2) | (1 << 6);	/* Byte data read/write command, start the command */
+	outb(byte, smbus_io_base + SMBHSTCTRL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return -3;	/* timeout or error */
+	}
+
+	return 0;
+}
+
+int do_smbus_read_byte(u32 smbus_io_base, u32 device,
+			      u32 address)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return -2;	/* not ready */
+	}
+
+	/* set the command/address... */
+	outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+
+	byte = inb(smbus_io_base + SMBHSTCTRL);
+	byte &= 0xe3;		/* Clear [4:2] */
+	byte |= (1 << 3) | (1 << 6);	/* Byte data read/write command, start the command */
+	outb(byte, smbus_io_base + SMBHSTCTRL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return -3;	/* timeout or error */
+	}
+
+	/* read results of transaction */
+	byte = inb(smbus_io_base + SMBHSTDAT0);
+
+	return byte;
+}
+
+int do_smbus_write_byte(u32 smbus_io_base, u32 device,
+			       u32 address, u8 val)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return -2;	/* not ready */
+	}
+
+	/* set the command/address... */
+	outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+
+	/* output value */
+	outb(val, smbus_io_base + SMBHSTDAT0);
+
+	byte = inb(smbus_io_base + SMBHSTCTRL);
+	byte &= 0xe3;		/* Clear [4:2] */
+	byte |= (1 << 3) | (1 << 6);	/* Byte data read/write command, start the command */
+	outb(byte, smbus_io_base + SMBHSTCTRL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return -3;	/* timeout or error */
+	}
+
+	return 0;
+}
+
+void alink_ab_indx(u32 reg_space, u32 reg_addr,
+			  u32 mask, u32 val)
+{
+	u32 tmp;
+
+	outl((reg_space & 0x7) << 29 | reg_addr, AB_INDX);
+	tmp = inl(AB_DATA);
+	/* rpr 4.2
+	 * For certain revisions of the chip, the ABCFG registers,
+	 * with an address of 0x100NN (where 'N' is any hexadecimal
+	 * number), require an extra programming step.*/
+	outl(0, AB_INDX);
+
+	tmp &= ~mask;
+	tmp |= val;
+
+	/* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<29 | reg_addr); */
+	outl((reg_space & 0x7) << 29 | reg_addr, AB_INDX);	/* probably we dont have to do it again. */
+	outl(tmp, AB_DATA);
+	outl(0, AB_INDX);
+}
+
+void alink_rc_indx(u32 reg_space, u32 reg_addr, u32 port,
+			  u32 mask, u32 val)
+{
+	u32 tmp;
+
+	outl((reg_space & 0x7) << 29 | (port & 3) << 24 | reg_addr, AB_INDX);
+	tmp = inl(AB_DATA);
+	/* rpr 4.2
+	 * For certain revisions of the chip, the ABCFG registers,
+	 * with an address of 0x100NN (where 'N' is any hexadecimal
+	 * number), require an extra programming step.*/
+	outl(0, AB_INDX);
+
+	tmp &= ~mask;
+	tmp |= val;
+
+	//printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<29 | (port&3) << 24 | reg_addr);
+	outl((reg_space & 0x7) << 29 | (port & 3) << 24 | reg_addr, AB_INDX);	/* probably we dont have to do it again. */
+	outl(tmp, AB_DATA);
+	outl(0, AB_INDX);
+}
+
+/* space = 0: AX_INDXC, AX_DATAC
+ * space = 1: AX_INDXP, AX_DATAP
+ */
+void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
+			  u32 mask, u32 val)
+{
+	u32 tmp;
+
+	/* read axindc to tmp */
+	outl(space << 29 | space << 3 | 0x30, AB_INDX);
+	outl(axindc, AB_DATA);
+	outl(0, AB_INDX);
+	outl(space << 29 | space << 3 | 0x34, AB_INDX);
+	tmp = inl(AB_DATA);
+	outl(0, AB_INDX);
+
+	tmp &= ~mask;
+	tmp |= val;
+
+	/* write tmp */
+	outl(space << 29 | space << 3 | 0x30, AB_INDX);
+	outl(axindc, AB_DATA);
+	outl(0, AB_INDX);
+	outl(space << 29 | space << 3 | 0x34, AB_INDX);
+	outl(tmp, AB_DATA);
+	outl(0, AB_INDX);
+}
+#endif
diff --git a/src/southbridge/amd/pi/avalon/smbus.h b/src/southbridge/amd/pi/avalon/smbus.h
new file mode 100644
index 0000000..53cc0e6
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smbus.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef HUDSON_SMBUS_H
+#define HUDSON_SMBUS_H
+
+#include <stdint.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTRL 0x2
+#define SMBHSTCMD  0x3
+#define SMBHSTADDR 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBHSTBLKDAT 0x7
+
+#define SMBSLVCTRL 0x8
+#define SMBSLVCMD_SHADOW 0x9
+#define SMBSLVEVT 0xa
+#define SMBSLVDAT 0xc
+
+#define AX_INDXC  0
+#define AX_INDXP  2
+#define AXCFG     4
+#define ABCFG     6
+#define RC_INDXC  1
+#define RC_INDXP  3
+
+#define AB_INDX   0xCD8
+#define AB_DATA   (AB_INDX+4)
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+#define abcfg_reg(reg, mask, val)	\
+	alink_ab_indx((ABCFG), (reg), (mask), (val))
+#define axcfg_reg(reg, mask, val)	\
+	alink_ab_indx((AXCFG), (reg), (mask), (val))
+#define axindxc_reg(reg, mask, val)	\
+	alink_ax_indx((AX_INDXC), (reg), (mask), (val))
+#define axindxp_reg(reg, mask, val)		\
+	alink_ax_indx((AX_INDXP), (reg), (mask), (val))
+#define rcindxc_reg(reg, port, mask, val)	\
+	alink_rc_indx((RC_INDXC), (reg), (port), (mask), (val))
+#define rcindxp_reg(reg, port, mask, val)	\
+	alink_rc_indx((RC_INDXP), (reg), (port), (mask), (val))
+
+int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
+int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
+int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
+int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
+void alink_rc_indx(u32 reg_space, u32 reg_addr, u32 port, u32 mask, u32 val);
+void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val);
+void alink_ax_indx(u32 space /*c or p? */ , u32 axindc, u32 mask, u32 val);
+
+
+#endif
diff --git a/src/southbridge/amd/pi/avalon/smbus_spd.c b/src/southbridge/amd/pi/avalon/smbus_spd.c
new file mode 100644
index 0000000..9dfd0b5
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smbus_spd.c
@@ -0,0 +1,152 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/pci_def.h>
+#include <device/device.h>
+
+/* warning: Porting.h includes an open #pragma pack(1) */
+#include "Porting.h"
+#include "AGESA.h"
+#include "amdlib.h"
+
+#include <northbridge/amd/pi/dimmSpd.h>
+
+/*-----------------------------------------------------------------------------
+ *
+ * readSmbusByteData - read a single SPD byte from any offset
+ */
+
+static int readSmbusByteData (int iobase, int address, char *buffer, int offset)
+{
+	unsigned int status;
+	UINT64 limit;
+
+	address |= 1; // set read bit
+
+	__outbyte (iobase + 0, 0xFF);                // clear error status
+	__outbyte (iobase + 1, 0x1F);                // clear error status
+	__outbyte (iobase + 3, offset);              // offset in eeprom
+	__outbyte (iobase + 4, address);             // slave address and read bit
+	__outbyte (iobase + 2, 0x48);                // read byte command
+
+	// time limit to avoid hanging for unexpected error status (should never happen)
+	limit = __rdtsc () + 2000000000 / 10;
+	for (;;)
+	{
+		status = __inbyte (iobase);
+		if (__rdtsc () > limit) break;
+		if ((status & 2) == 0) continue;               // SMBusInterrupt not set, keep waiting
+		if ((status & 1) == 1) continue;               // HostBusy set, keep waiting
+		break;
+	}
+
+	buffer [0] = __inbyte (iobase + 5);
+	if (status == 2) status = 0;                      // check for done with no errors
+	return status;
+}
+
+/*-----------------------------------------------------------------------------
+ *
+ * readSmbusByte - read a single SPD byte from the default offset
+ *                 this function is faster function readSmbusByteData
+ */
+
+static int readSmbusByte (int iobase, int address, char *buffer)
+{
+	unsigned int status;
+	UINT64 limit;
+
+	__outbyte (iobase + 0, 0xFF);                // clear error status
+	__outbyte (iobase + 2, 0x44);                // read command
+
+	// time limit to avoid hanging for unexpected error status
+	limit = __rdtsc () + 2000000000 / 10;
+	for (;;)
+	{
+		status = __inbyte (iobase);
+		if (__rdtsc () > limit) break;
+		if ((status & 2) == 0) continue;               // SMBusInterrupt not set, keep waiting
+		if ((status & 1) == 1) continue;               // HostBusy set, keep waiting
+		break;
+	}
+
+	buffer [0] = __inbyte (iobase + 5);
+	if (status == 2) status = 0;                      // check for done with no errors
+	return status;
+}
+
+/*---------------------------------------------------------------------------
+ *
+ * readspd - Read one or more SPD bytes from a DIMM.
+ *           Start with offset zero and read sequentially.
+ *           Optimization relies on autoincrement to avoid
+ *           sending offset for every byte.
+ *          Reads 128 bytes in 7-8 ms at 400 KHz.
+ */
+
+static int readspd (int iobase, int SmbusSlaveAddress, char *buffer, int count)
+{
+	int index, error;
+
+	printk(BIOS_SPEW, "-------------READING SPD-----------\n");
+	printk(BIOS_SPEW, "iobase: 0x%08X, SmbusSlave: 0x%08X, count: %d\n",
+						iobase, SmbusSlaveAddress, count);
+
+	/* read the first byte using offset zero */
+	error = readSmbusByteData (iobase, SmbusSlaveAddress, buffer, 0);
+
+	if (error) {
+		printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n");
+		return error;
+	}
+
+	/* read the remaining bytes using auto-increment for speed */
+	for (index = 1; index < count; index++)
+	{
+		error = readSmbusByte (iobase, SmbusSlaveAddress, &buffer [index]);
+		if (error) {
+			printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n");
+			return error;
+		}
+	}
+	printk(BIOS_SPEW, "\n");
+	printk(BIOS_SPEW, "-------------FINISHED READING SPD-----------\n");
+
+	return 0;
+}
+
+static void writePmReg (int reg, int data)
+{
+	__outbyte (0xCD6, reg);
+	__outbyte (0xCD7, data);
+}
+
+static void setupFch (int ioBase)
+{
+	writePmReg (0x2D, ioBase >> 8);
+	writePmReg (0x2C, ioBase | 1);
+	__outbyte (ioBase + 0x0E, 66000000 / 400000 / 4); // set SMBus clock to 400 KHz
+}
+
+int hudson_readSpd(int spdAddress, char *buf, size_t len)
+{
+	int ioBase = 0xB00;
+	setupFch (ioBase);
+	return readspd (ioBase, spdAddress, buf, len);
+}
diff --git a/src/southbridge/amd/pi/avalon/smi.c b/src/southbridge/amd/pi/avalon/smi.c
new file mode 100644
index 0000000..1d58afe
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smi.c
@@ -0,0 +1,25 @@
+/*
+ * Utilities for SMM setup
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#include "smi.h"
+
+#include <console/console.h>
+#include <cpu/cpu.h>
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+	printk(BIOS_DEBUG, "smm_setup_structures STUB!!!\n");
+}
+
+/** Set the EOS bit and enable SMI generation from southbridge */
+void hudson_enable_smi_generation(void)
+{
+	uint32_t reg = smi_read32(SMI_REG_SMITRIG0);
+	reg &= ~SMITRG0_SMIENB;	/* Enable SMI generation */
+	reg |= SMITRG0_EOS;	/* Set EOS bit */
+	smi_write32(SMI_REG_SMITRIG0, reg);
+}
diff --git a/src/southbridge/amd/pi/avalon/smi.h b/src/southbridge/amd/pi/avalon/smi.h
new file mode 100644
index 0000000..de987a9
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smi.h
@@ -0,0 +1,65 @@
+/*
+ * Utilities for SMI handlers and SMM setup
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#ifndef _SOUTHBRIDGE_AMD_PI_HUDSON_SMI_H
+#define _SOUTHBRIDGE_AMD_PI_HUDSON_SMI_H
+
+#include <arch/io.h>
+
+/* ACPI_MMIO_BASE + 0x200 -- leave this string here so grep catches it.
+ * This is defined by AGESA, but we dpn't include AGESA headers to avoid
+ * polluting the namesace.
+ */
+#define SMI_BASE 0xfed80200
+
+#define SMI_REG_SMITRIG0	0x98
+#define SMITRG0_EOS		(1 << 28)
+#define SMITRG0_SMIENB		(1 << 31)
+
+#define SMI_REG_CONTROL0	0xa0
+
+enum smi_mode {
+	SMI_MODE_DISABLE = 0,
+	SMI_MODE_SMI = 1,
+	SMI_MODE_NMI = 2,
+	SMI_MODE_IRQ13 = 3,
+};
+
+enum smi_lvl {
+	SMI_LVL_LOW = 0,
+	SMI_LVL_HIGH = 1,
+};
+
+static inline uint32_t smi_read32(uint8_t offset)
+{
+	return read32(SMI_BASE + offset);
+}
+
+static inline void smi_write32(uint8_t offset, uint32_t value)
+{
+	write32(SMI_BASE + offset, value);
+}
+
+static inline uint16_t smi_read16(uint8_t offset)
+{
+	return read16(SMI_BASE + offset);
+}
+
+static inline void smi_write16(uint8_t offset, uint16_t value)
+{
+	write16(SMI_BASE + offset, value);
+}
+
+void hudson_configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level);
+void hudson_disable_gevent_smi(uint8_t gevent);
+void hudson_enable_acpi_cmd_smi(void);
+
+#ifndef __SMM__
+void hudson_enable_smi_generation(void);
+#endif
+
+#endif /* _SOUTHBRIDGE_AMD_PI_HUDSON_SMI_H */
diff --git a/src/southbridge/amd/pi/avalon/smi_util.c b/src/southbridge/amd/pi/avalon/smi_util.c
new file mode 100644
index 0000000..6076cd4
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smi_util.c
@@ -0,0 +1,79 @@
+/*
+ * SMM utilities used in both SMM and normal mode
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#include "smi.h"
+
+#include <console/console.h>
+
+#define HUDSON_SMI_ACPI_COMMAND		75
+
+static void configure_smi(uint8_t smi_num, uint8_t mode)
+{
+	uint8_t reg32_offset, bit_offset;
+	uint32_t reg32;
+
+	/* SMI sources range from [0:149] */
+	if (smi_num > 149) {
+		printk(BIOS_WARNING, "BUG: Invalid SMI: %u\n", smi_num);
+		return;
+	}
+
+	/* 16 sources per register, 2 bits per source; registers are 4 bytes */
+	reg32_offset = (smi_num / 16) * 4;
+	bit_offset = (smi_num % 16) * 2;
+
+	reg32 = smi_read32(SMI_REG_CONTROL0 + reg32_offset);
+	reg32 &= ~(0x3 << (bit_offset));
+	reg32 |= (mode & 0x3) << bit_offset;
+	smi_write32(SMI_REG_CONTROL0 + reg32_offset, reg32);
+}
+
+/**
+ * Configure generation of interrupts for given GEVENT pin
+ *
+ * @param gevent The GEVENT pin number. Valid values are 0 thru 23
+ * @param mode The type of event this pin should generate. Note that only
+ *	       SMI_MODE_SMI generates an SMI. SMI_MODE_DISABLE disables events.
+ * @param level SMI_LVL_LOW or SMI_LVL_HIGH
+ */
+void hudson_configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
+{
+	uint32_t reg32;
+	/* GEVENT pins range from [0:23] */
+	if (gevent > 23) {
+		printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
+		return;
+	}
+
+	/* SMI0 source is GEVENT0 and so on */
+	configure_smi(gevent, mode);
+
+	/* And set set the trigger level */
+	reg32 = smi_read32(SMI_REG_SMITRIG0);
+	reg32 &= ~(1 << gevent);
+	reg32 |= (level & 0x1) << gevent;
+	smi_write32(SMI_REG_SMITRIG0, reg32);
+}
+
+/** Disable events from given GEVENT pin */
+void hudson_disable_gevent_smi(uint8_t gevent)
+{
+	/* GEVENT pins range from [0:23] */
+	if (gevent > 23) {
+		printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
+		return;
+	}
+
+	/* SMI0 source is GEVENT0 and so on */
+	configure_smi(gevent, SMI_MODE_DISABLE);
+}
+
+/** Enable SMIs on writes to ACPI SMI command port */
+void hudson_enable_acpi_cmd_smi(void)
+{
+	configure_smi(HUDSON_SMI_ACPI_COMMAND, SMI_MODE_SMI);
+}
diff --git a/src/southbridge/amd/pi/avalon/smihandler.c b/src/southbridge/amd/pi/avalon/smihandler.c
new file mode 100644
index 0000000..e762d0b
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/smihandler.c
@@ -0,0 +1,136 @@
+/*
+ * SMI handler for Hudson southbridges
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#include "hudson.h"
+#include "smi.h"
+
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <delay.h>
+
+#define SMI_0x88_ACPI_COMMAND		(1 << 11)
+
+enum smi_source {
+	SMI_SOURCE_SCI = (1 << 0),
+	SMI_SOURCE_GPE = (1 << 1),
+	SMI_SOURCE_0x84 = (1 << 2),
+	SMI_SOURCE_0x88 = (1 << 3),
+	SMI_SOURCE_IRQ_TRAP = (1 << 4),
+	SMI_SOURCE_0x90 = (1 << 5)
+};
+
+static void hudson_apmc_smi_handler(void)
+{
+	u32 reg32;
+	const uint8_t cmd = inb(ACPI_SMI_CTL_PORT);
+
+	switch (cmd) {
+	case ACPI_SMI_CMD_ENABLE:
+		reg32 = inl(ACPI_PM1_CNT_BLK);
+		reg32 |= (1 << 0);	/* SCI_EN */
+		outl(reg32, ACPI_PM1_CNT_BLK);
+		break;
+	case ACPI_SMI_CMD_DISABLE:
+		reg32 = inl(ACPI_PM1_CNT_BLK);
+		reg32 &= ~(1 << 0);	/* clear SCI_EN */
+		outl(ACPI_PM1_CNT_BLK, reg32);
+		break;
+	}
+
+	if (mainboard_smi_apmc)
+		mainboard_smi_apmc(cmd);
+}
+
+int southbridge_io_trap_handler(int smif)
+{
+	return 0;
+}
+
+static void process_smi_sci(void)
+{
+	const uint32_t status = smi_read32(0x10);
+
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(0x10, status);
+}
+
+static void process_gpe_smi(void)
+{
+	const uint32_t status = smi_read32(0x80);
+	const uint32_t gevent_mask = (1 << 24) - 1;
+
+	/* Only Bits [23:0] indicate GEVENT SMIs. */
+	if (status & gevent_mask) {
+		/* A GEVENT SMI occured */
+		if (mainboard_smi_gpi)
+			mainboard_smi_gpi(status & gevent_mask);
+	}
+
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(0x80, status);
+}
+
+static void process_smi_0x84(void)
+{
+	const uint32_t status = smi_read32(0x84);
+
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(0x84, status);
+}
+
+static void process_smi_0x88(void)
+{
+	const uint32_t status = smi_read32(0x88);
+
+	if (status & SMI_0x88_ACPI_COMMAND) {
+		/* Command received via ACPI SMI command port */
+		hudson_apmc_smi_handler();
+	}
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(0x88, status);
+}
+
+static void process_smi_0x8c(void)
+{
+	const uint32_t status = smi_read32(0x8c);
+
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(0x8c, status);
+}
+
+static void process_smi_0x90(void)
+{
+	const uint32_t status = smi_read32(0x90);
+
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(0x90, status);
+}
+
+void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+{
+	const uint16_t smi_src = smi_read16(0x94);
+
+	if (smi_src & SMI_SOURCE_SCI)
+		process_smi_sci();
+	if (smi_src & SMI_SOURCE_GPE)
+		process_gpe_smi();
+	if (smi_src & SMI_SOURCE_0x84)
+		process_smi_0x84();
+	if (smi_src & SMI_SOURCE_0x88)
+		process_smi_0x88();
+	if (smi_src & SMI_SOURCE_IRQ_TRAP)
+		process_smi_0x8c();
+	if (smi_src & SMI_SOURCE_0x90)
+		process_smi_0x90();
+}
+
+void southbridge_smi_set_eos(void)
+{
+	uint32_t reg = smi_read32(SMI_REG_SMITRIG0);
+	reg |= SMITRG0_EOS;
+	smi_write32(SMI_REG_SMITRIG0, reg);
+}
diff --git a/src/southbridge/amd/pi/avalon/spi.c b/src/southbridge/amd/pi/avalon/spi.c
new file mode 100644
index 0000000..6a49d7e
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/spi.c
@@ -0,0 +1,204 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <spi-generic.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+
+#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM)
+#include <Proc/Fch/FchPlatform.h>
+
+static int bus_claimed = 0;
+#endif
+
+#define SPI_REG_OPCODE		0x0
+#define SPI_REG_CNTRL01		0x1
+#define SPI_REG_CNTRL02		0x2
+ #define CNTRL02_FIFO_RESET	(1 << 4)
+ #define CNTRL02_EXEC_OPCODE	(1 << 0)
+#define SPI_REG_CNTRL03		0x3
+ #define CNTRL03_SPIBUSY	(1 << 7)
+#define SPI_REG_FIFO		0xc
+#define SPI_REG_CNTRL11		0xd
+ #define CNTRL11_FIFOPTR_MASK	0x07
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_PI_YANGTZE)
+#define AMD_SB_SPI_TX_LEN	64
+#else
+#define AMD_SB_SPI_TX_LEN	8
+#endif
+
+static u32 spibar;
+
+static inline uint8_t spi_read(uint8_t reg)
+{
+	return read8(spibar + reg);
+}
+
+static inline void spi_write(uint8_t reg, uint8_t val)
+{
+	write8(spibar + reg, val);
+}
+
+static void reset_internal_fifo_pointer(void)
+{
+	uint8_t reg8;
+
+	do {
+		reg8 = spi_read(SPI_REG_CNTRL02);
+		reg8 |= CNTRL02_FIFO_RESET;
+		spi_write(SPI_REG_CNTRL02, reg8);
+	} while (spi_read(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK);
+}
+
+static void execute_command(void)
+{
+	uint8_t reg8;
+
+	reg8 = spi_read(SPI_REG_CNTRL02);
+	reg8 |= CNTRL02_EXEC_OPCODE;
+	spi_write(SPI_REG_CNTRL02, reg8);
+
+	while ((spi_read(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) &&
+	       (spi_read(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY));
+}
+
+void spi_init(void)
+{
+	device_t dev;
+
+	dev = dev_find_slot(0, PCI_DEVFN(0x14, 3));
+	spibar = pci_read_config32(dev, 0xA0) & ~0x1F;
+}
+
+unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
+{
+	return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len);
+}
+
+int spi_xfer(struct spi_slave *slave, const void *dout,
+		unsigned int bytesout, void *din, unsigned int bytesin)
+{
+	/* First byte is cmd which can not being sent through FIFO. */
+	u8 cmd = *(u8 *)dout++;
+	u8 readoffby1;
+	u8 count;
+
+	bytesout--;
+
+	/*
+	 * Check if this is a write command attempting to transfer more bytes
+	 * than the controller can handle. Iterations for writes are not
+	 * supported here because each SPI write command needs to be preceded
+	 * and followed by other SPI commands, and this sequence is controlled
+	 * by the SPI chip driver.
+	 */
+	if (bytesout > AMD_SB_SPI_TX_LEN) {
+		printk(BIOS_DEBUG, "FCH SPI: Too much to write. Does your SPI chip driver use"
+		     " spi_crop_chunk()?\n");
+		return -1;
+	}
+
+	readoffby1 = bytesout ? 0 : 1;
+
+#if CONFIG_SOUTHBRIDGE_AMD_PI_YANGTZE
+	spi_write(0x1E, 5);
+	spi_write(0x1F, bytesout); /* SpiExtRegIndx [5] - TxByteCount */
+	spi_write(0x1E, 6);
+	spi_write(0x1F, bytesin);  /* SpiExtRegIndx [6] - RxByteCount */
+#else
+	u8 readwrite = (bytesin + readoffby1) << 4 | bytesout;
+	spi_write(SPI_REG_CNTRL01, readwrite);
+#endif
+	spi_write(SPI_REG_OPCODE, cmd);
+
+	reset_internal_fifo_pointer();
+	for (count = 0; count < bytesout; count++, dout++) {
+		spi_write(SPI_REG_FIFO, *(uint8_t *)dout);
+	}
+
+	reset_internal_fifo_pointer();
+	execute_command();
+
+	reset_internal_fifo_pointer();
+	/* Skip the bytes we sent. */
+	for (count = 0; count < bytesout; count++) {
+		cmd = spi_read(SPI_REG_FIFO);
+	}
+
+	reset_internal_fifo_pointer();
+	for (count = 0; count < bytesin; count++, din++) {
+		*(uint8_t *)din = spi_read(SPI_REG_FIFO);
+	}
+
+	return 0;
+}
+int spi_claim_bus(struct spi_slave *slave)
+{
+#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM)
+
+	if (slave->rw == SPI_WRITE_FLAG) {
+		bus_claimed++;
+		if (bus_claimed == 1)
+			ImcSleep(NULL);
+	}
+#endif
+
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+#if IS_ENABLED (CONFIG_HUDSON_IMC_FWM)
+
+	if (slave->rw == SPI_WRITE_FLAG)  {
+		bus_claimed--;
+		if (bus_claimed <= 0) {
+			bus_claimed = 0;
+			ImcWakeup(NULL);
+		}
+	}
+#endif
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
+{
+	struct spi_slave *slave = malloc(sizeof(*slave));
+
+	if (!slave) {
+		return NULL;
+	}
+
+	memset(slave, 0, sizeof(*slave));
+
+	return slave;
+}
diff --git a/src/southbridge/amd/pi/avalon/usb.c b/src/southbridge/amd/pi/avalon/usb.c
new file mode 100644
index 0000000..36eff6e
--- /dev/null
+++ b/src/southbridge/amd/pi/avalon/usb.c
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pci_ehci.h>
+#include <arch/io.h>
+#include "hudson.h"
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+
+static void usb_init(struct device *dev)
+{
+}
+
+static struct device_operations usb_ops = {
+	.read_resources = pci_ehci_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = usb_init,
+	.scan_bus = 0,
+	.ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_0_driver __pci_driver = {
+	.ops = &usb_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_USB_18_0,
+};
+static const struct pci_driver usb_1_driver __pci_driver = {
+	.ops = &usb_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_USB_18_2,
+};
+
+/* the pci id of usb ctrl 0 and 1 are the same. */
+/*
+ * static const struct pci_driver usb_3_driver __pci_driver = {
+ * 	.ops = &usb_ops,
+ * 	.vendor = PCI_VENDOR_ID_AMD,
+ * 	.device = PCI_DEVICE_ID_ATI_HUDSON_USB_19_0,
+ * };
+ * static const struct pci_driver usb_4_driver __pci_driver = {
+ * 	.ops = &usb_ops,
+ * 	.vendor = PCI_VENDOR_ID_AMD,
+ * 	.device = PCI_DEVICE_ID_ATI_HUDSON_USB_19_1,
+ * };
+ */
+
+static const struct pci_driver usb_4_driver __pci_driver = {
+	.ops = &usb_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_SB900_USB_20_5,
+};
+
+/*
+static struct device_operations usb_ops2 = {
+	.read_resources = pci_ehci_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = usb_init2,
+	.scan_bus = 0,
+	.ops_pci = &lops_pci,
+};
+*/
+/*
+static const struct pci_driver usb_5_driver __pci_driver = {
+	.ops = &usb_ops2,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_ATI_HUDSON_USB_18_2,
+};
+*/
+/*
+ * static const struct pci_driver usb_5_driver __pci_driver = {
+ * 	.ops = &usb_ops2,
+ * 	.vendor = PCI_VENDOR_ID_AMD,
+ * 	.device = PCI_DEVICE_ID_ATI_HUDSON_USB_19_2,
+ * };
+ */
diff --git a/src/vendorcode/amd/pi/00730F01/Makefile.inc b/src/vendorcode/amd/pi/00730F01/Makefile.inc
index c1b87ef..72c71d4 100644
--- a/src/vendorcode/amd/pi/00730F01/Makefile.inc
+++ b/src/vendorcode/amd/pi/00730F01/Makefile.inc
@@ -47,7 +47,7 @@ AGESA_INC += -I$(AGESA_ROOT)/Proc/CPU/Feature
 AGESA_INC += -I$(AGESA_ROOT)/Proc/Fch
 AGESA_INC += -I$(AGESA_ROOT)/Proc/Fch/Common
 
-AGESA_INC += -I$(src)/southbridge/amd/agesa/hudson
+AGESA_INC += -I$(src)/southbridge/amd/pi/avalon
 
 AGESA_INC += -I$(src)/arch/x86/include
 AGESA_INC += -I$(src)/include



More information about the coreboot-gerrit mailing list