[coreboot] New patch to review for coreboot: 09c7b60 AGESA F15 wrapper for Hudson.

Zheng Bao (zheng.bao@amd.com) gerrit at coreboot.org
Mon Jul 2 06:45:04 CEST 2012


Zheng Bao (zheng.bao at amd.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1157

-gerrit

commit 09c7b60b01ebe9abbdf5bbdd7649c02306281c54
Author: zbao <fishbaozi at gmail.com>
Date:   Mon Jul 2 14:19:20 2012 +0800

    AGESA F15 wrapper for Hudson.
    
    Hudson code has been integrated from CIMx to AGESA. This patch is about the wrapper.
    
    Change-Id: I63d951982140b82a3a77a97eb3d55fc75fc0caa3
    Signed-off-by: Zheng Bao <zheng.bao at amd.com>
    Signed-off-by: zbao <fishbaozi at gmail.com>
---
 src/southbridge/amd/Kconfig                        |    1 +
 src/southbridge/amd/Makefile.inc                   |    3 +-
 src/southbridge/amd/agesa/Kconfig                  |   20 ++
 src/southbridge/amd/agesa/Makefile.inc             |   19 ++
 src/southbridge/amd/agesa/hudson/Kconfig           |  216 +++++++++++++++++
 src/southbridge/amd/agesa/hudson/Makefile.inc      |   34 +++
 src/southbridge/amd/agesa/hudson/bootblock.c       |   68 ++++++
 src/southbridge/amd/agesa/hudson/chip.h            |   36 +++
 src/southbridge/amd/agesa/hudson/early_setup.c     |  112 +++++++++
 src/southbridge/amd/agesa/hudson/enable_usbdebug.c |   52 ++++
 src/southbridge/amd/agesa/hudson/fadt.c            |  186 ++++++++++++++
 src/southbridge/amd/agesa/hudson/hda.c             |   51 ++++
 src/southbridge/amd/agesa/hudson/hudson.c          |  122 ++++++++++
 src/southbridge/amd/agesa/hudson/hudson.h          |   75 ++++++
 src/southbridge/amd/agesa/hudson/hudson_fwm.py     |   58 +++++
 src/southbridge/amd/agesa/hudson/ide.c             |   48 ++++
 src/southbridge/amd/agesa/hudson/lpc.c             |  148 ++++++++++++
 src/southbridge/amd/agesa/hudson/pci.c             |   49 ++++
 src/southbridge/amd/agesa/hudson/pcie.c            |   65 +++++
 src/southbridge/amd/agesa/hudson/reset.c           |   33 +++
 src/southbridge/amd/agesa/hudson/sata.c            |   51 ++++
 src/southbridge/amd/agesa/hudson/sm.c              |  174 ++++++++++++++
 src/southbridge/amd/agesa/hudson/smbus.c           |  253 ++++++++++++++++++++
 src/southbridge/amd/agesa/hudson/smbus.h           |   76 ++++++
 src/southbridge/amd/agesa/hudson/spi.c             |  218 +++++++++++++++++
 src/southbridge/amd/agesa/hudson/spi.h             |   43 ++++
 src/southbridge/amd/agesa/hudson/usb.c             |  124 ++++++++++
 27 files changed, 2334 insertions(+), 1 deletions(-)

diff --git a/src/southbridge/amd/Kconfig b/src/southbridge/amd/Kconfig
index 1b997ae..867afca 100644
--- a/src/southbridge/amd/Kconfig
+++ b/src/southbridge/amd/Kconfig
@@ -12,4 +12,5 @@ source src/southbridge/amd/rs780/Kconfig
 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/sr5650/Kconfig
diff --git a/src/southbridge/amd/Makefile.inc b/src/southbridge/amd/Makefile.inc
index d7b5645..740e862 100644
--- a/src/southbridge/amd/Makefile.inc
+++ b/src/southbridge/amd/Makefile.inc
@@ -14,13 +14,14 @@ subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CS5536) += cs5536
 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB700) += cimx
 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += cimx
 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += cimx
+subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_HUDSON) += agesa
 
 ifeq ($(CONFIG_HAVE_ACPI_RESUME), y)
 ifeq ($(CONFIG_CPU_AMD_AGESA), y)
 
 $(obj)/s3.rom:
 	echo "    S3 NVRAM   0xffff0000 (S3 storage area)"
-	awk 'BEGIN {for (i=0; i<20480; i++) {printf "%c", 255}}' > $@.tmp
+	awk 'BEGIN {for (i=0; i<32768; i++) {printf "%c", 255}}' > $@.tmp
 	mv $@.tmp $@
 
 cbfs-files-y += s3nv
diff --git a/src/southbridge/amd/agesa/Kconfig b/src/southbridge/amd/agesa/Kconfig
new file mode 100644
index 0000000..29e00a6
--- /dev/null
+++ b/src/southbridge/amd/agesa/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/agesa/hudson/Kconfig
diff --git a/src/southbridge/amd/agesa/Makefile.inc b/src/southbridge/amd/agesa/Makefile.inc
new file mode 100644
index 0000000..72e62ac
--- /dev/null
+++ b/src/southbridge/amd/agesa/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_AGESA_HUDSON) += hudson
diff --git a/src/southbridge/amd/agesa/hudson/Kconfig b/src/southbridge/amd/agesa/hudson/Kconfig
new file mode 100644
index 0000000..3168aec
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/Kconfig
@@ -0,0 +1,216 @@
+##
+## 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_AGESA_HUDSON
+	bool
+	select IOAPIC
+	select HAVE_USBDEBUG
+	select TINY_BOOTBLOCK
+
+config BOOTBLOCK_SOUTHBRIDGE_INIT
+	string
+	default "southbridge/amd/agesa/hudson/bootblock.c"
+	depends on SOUTHBRIDGE_AMD_AGESA_HUDSON
+
+config SOUTHBRIDGE_AMD_HUDSON_SKIP_ISA_DMA_INIT
+	bool
+	default n
+	depends on SOUTHBRIDGE_AMD_AGESA_HUDSON
+
+config EHCI_BAR
+	hex
+	default 0xfef00000 if SOUTHBRIDGE_AMD_AGESA_HUDSON
+
+config EHCI_DEBUG_OFFSET
+	hex
+	default 0xe0 if SOUTHBRIDGE_AMD_AGESA_HUDSON
+
+
+if SOUTHBRIDGE_AMD_AGESA_HUDSON
+
+config HUDSON_XHCI_FWM
+	bool "Add xhci firmware"
+	default y
+        help
+	  Add Hudson 2/3/4 XHCI Firmware to support the onboard usb3.0
+	  Please contact AMD to obtain the related firmware
+
+config HUDSON_IMC_FWM
+	bool "Add imc firmware"
+	default y
+        help
+	  Add Hudson 2/3/4 IMC Firmware to support the onboard fan control
+	  Please contact AMD to obtain the related firmware
+
+config HUDSON_GEC_FWM
+	bool "Add gec firmware"
+	default n
+        help
+	  Add Hudson 2/3/4 GEC Firmware
+	  Please contact AMD to obtain the related firmware
+
+config HUDSON_XHCI_FWM_FILE
+        string "XHCI firmware path and filename"
+        default "src/southbridge/amd/agesa/hudson/xhci.bin"
+	depends on HUDSON_XHCI_FWM
+
+config HUDSON_IMC_FWM_FILE
+        string "IMC firmware path and filename"
+        default "src/southbridge/amd/agesa/hudson/imc.bin"
+	depends on HUDSON_IMC_FWM
+
+config HUDSON_GEC_FWM_FILE
+        string "GEC firmware path and filename"
+        default "src/southbridge/amd/agesa/hudson/gec.bin"
+	depends on HUDSON_GEC_FWM
+
+config HUDSON_FWM
+	bool
+	default y if HUDSON_XHCI_FWM || HUDSON_IMC_FWM || HUDSON_GEC_FWM
+	default n if !HUDSON_XHCI_FWM && !HUDSON_IMC_FWM && !HUDSON_GEC_FWM
+
+if HUDSON_FWM
+config HUDSON_FWM_FILE
+        string "Hudson firmware (with ROMSIG header) path and filename"
+        default "src/southbridge/amd/agesa/hudson/hudson.bin"
+
+config HUDSON_FWM_POSITION
+        hex "Hudwon Firmware rom Position"
+        #default 0xFFF20000 if COREBOOT_ROMSIZE_KB_1024
+        #default 0xFFE20000 if COREBOOT_ROMSIZE_KB_2048
+        #default 0xFFC20000 if COREBOOT_ROMSIZE_KB_4096
+        #default 0xFF820000 if COREBOOT_ROMSIZE_KB_8192
+        #default 0xFF020000 if COREBOOT_ROMSIZE_KB_16384
+        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 to 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
+
+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/agesa/hudson/ahci.bin"
+endif
+
+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/agesa/hudson/raid.bin"
+
+config RAID_MISC_ROM_FILE
+        string "RAID Misc ROM path and filename"
+        default "src/southbridge/amd/agesa/hudson/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 larger than 0x100000.
+endif
+
+endif
diff --git a/src/southbridge/amd/agesa/hudson/Makefile.inc b/src/southbridge/amd/agesa/hudson/Makefile.inc
new file mode 100644
index 0000000..19ffae1
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/Makefile.inc
@@ -0,0 +1,34 @@
+driver-y += hudson.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += sm.c
+driver-y += ide.c
+driver-y += sata.c
+driver-y += hda.c
+driver-y += pci.c
+driver-y += pcie.c
+ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
+ramstage-y += reset.c
+romstage-y += enable_usbdebug.c
+romstage-y += early_setup.c
+
+ramstage-$(CONFIG_HAVE_ACPI_RESUME) += spi.c
+
+$(obj)/hudson.bin:
+	python $(src)/southbridge/amd/agesa/hudson/hudson_fwm.py $(CONFIG_HUDSON_FWM_POSITION) $@ $(CONFIG_HUDSON_XHCI_FWM_FILE) $(CONFIG_HUDSON_IMC_FWM_FILE) ""
+
+ifeq ($(CONFIG_HUDSON_FWM), y)
+cbfs-files-y += hudson/fwm
+hudson/fwm-file := $(obj)/hudson.bin
+hudson/fwm-position := $(CONFIG_HUDSON_FWM_POSITION)
+hudson/fwm-type := raw
+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
+#endif
+endif
diff --git a/src/southbridge/amd/agesa/hudson/bootblock.c b/src/southbridge/amd/agesa/hudson/bootblock.c
new file mode 100644
index 0000000..1d0be0a
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/bootblock.c
@@ -0,0 +1,68 @@
+/*
+ * 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 <arch/romcc_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/agesa/hudson/chip.h b/src/southbridge/amd/agesa/hudson/chip.h
new file mode 100644
index 0000000..7732f6d
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/chip.h
@@ -0,0 +1,36 @@
+/*
+ * 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_CHIP_H
+#define HUDSON_CHIP_H
+
+struct southbridge_amd_agesa_hudson_config
+{
+	#if 1
+	u32 ide0_enable : 1;
+	u32 sata0_enable : 1;
+	u32 boot_switch_sata_ide : 1;
+	u32 hda_viddid;
+	u8  gpp_configuration;
+	#endif
+};
+struct chip_operations;
+extern struct chip_operations southbridge_amd_agesa_hudson_ops;
+
+#endif /* HUDSON_CHIP_H */
diff --git a/src/southbridge/amd/agesa/hudson/early_setup.c b/src/southbridge/amd/agesa/hudson/early_setup.c
new file mode 100644
index 0000000..8cf380b
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/early_setup.c
@@ -0,0 +1,112 @@
+/*
+ * 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>		/* inl, outl */
+#include <arch/romcc_io.h>	/* device_t */
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <reset.h>
+#include <arch/cpu.h>
+#include <cbmem.h>
+#include "hudson.h"
+
+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);//pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
+	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 == 1
+int acpi_get_sleep_type(void)
+{
+	u16 tmp = inw(PM1_CNT_BLK_ADDRESS);
+	tmp = ((tmp & (7 << 10)) >> 10);
+	/* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */
+	return (int)tmp;
+}
+#endif
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+int acpi_is_wakeup_early(void)
+{
+	return (acpi_get_sleep_type() == 3);
+}
+#endif
+
+struct cbmem_entry *get_cbmem_toc(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 (struct cbmem_entry *) xdata;
+}
+
+#endif
diff --git a/src/southbridge/amd/agesa/hudson/enable_usbdebug.c b/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
new file mode 100644
index 0000000..c558a26
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
@@ -0,0 +1,52 @@
+/*
+ * 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 <arch/romcc_io.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "hudson.h"
+
+#ifndef HUDSON_DEVN_BASE
+#define HUDSON_DEVN_BASE 0
+#endif
+
+#define EHCI_EOR		(CONFIG_EHCI_BAR + 0x20)
+#define DEBUGPORT_MISC_CONTROL	(EHCI_EOR + 0x80)
+
+void set_debug_port(unsigned int port)
+{
+	u32 reg32;
+
+	/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
+	reg32 = read32(DEBUGPORT_MISC_CONTROL);
+	reg32 &= ~(0xf << 28);
+	reg32 |= (port << 28);
+	reg32 |= (1 << 27); /* Enable Debug Port port number remapping. */
+	write32(DEBUGPORT_MISC_CONTROL, reg32);
+}
+
+
+void enable_usbdebug(unsigned int port)
+{
+	pci_write_config32(PCI_DEV(0, HUDSON_DEVN_BASE + 0x13, 5),
+			   EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+	pci_write_config8(PCI_DEV(0, HUDSON_DEVN_BASE + 0x13, 5), 0x04, 0x2);	/* mem space enabe */
+	set_debug_port(port);
+}
diff --git a/src/southbridge/amd/agesa/hudson/fadt.c b/src/southbridge/amd/agesa/hudson/fadt.c
new file mode 100644
index 0000000..ee0334c
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/fadt.c
@@ -0,0 +1,186 @@
+/*
+ * 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"
+
+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 = 244;
+	header->revision = 3;
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, "COREBOOT", 8);
+	memcpy(header->asl_compiler_id, ASLC, 4);
+	header->asl_compiler_revision = 0;
+
+	fadt->firmware_ctrl = (u32) facs;
+	fadt->dsdt = (u32) dsdt;
+	/* 3=Workstation,4=Enterprise Server, 7=Performance Server */
+	fadt->preferred_pm_profile = 0x03;
+	fadt->sci_int = 9;
+	/* disable system management mode by setting to 0: */
+	fadt->smi_cmd = 0;
+	fadt->acpi_enable = 0xf0;
+	fadt->acpi_disable = 0xf1;
+	fadt->s4bios_req = 0x0;
+	fadt->pstate_cnt = 0xe2;
+
+	pm_iowrite(0x60, ACPI_PM_EVT_BLK & 0xFF);
+	pm_iowrite(0x61, ACPI_PM_EVT_BLK >> 8);
+	pm_iowrite(0x62, ACPI_PM1_CNT_BLK & 0xFF);
+	pm_iowrite(0x63, ACPI_PM1_CNT_BLK >> 8);
+	pm_iowrite(0x64, ACPI_PM_TMR_BLK & 0xFF);
+	pm_iowrite(0x65, ACPI_PM_TMR_BLK >> 8);
+	pm_iowrite(0x68, ACPI_GPE0_BLK & 0xFF);
+	pm_iowrite(0x69, ACPI_GPE0_BLK >> 8);
+
+	/* CpuControl is in \_PR.CPU0, 6 bytes */
+	pm_iowrite(0x66, ACPI_CPU_CONTROL & 0xFF);
+	pm_iowrite(0x67, ACPI_CPU_CONTROL >> 8);
+
+	pm_iowrite(0x6A, 0);	/* AcpiSmiCmdLo */
+	pm_iowrite(0x6B, 0);	/* AcpiSmiCmdHi */
+
+	pm_iowrite(0x6C, ACPI_PMA_CNT_BLK & 0xFF);
+	pm_iowrite(0x6D, ACPI_PMA_CNT_BLK >> 8);
+
+	pm_iowrite(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2); /* AcpiDecodeEnable, When set, SB uses
+					* the contents of the PM registers at
+					* index 60-6B to decode ACPI I/O address.
+					* AcpiSmiEn & SmiCmdEn*/
+	/* RTC_En_En, TMR_En_En, GBL_EN_EN */
+	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 = ACPI_PMA_CNT_BLK;
+	fadt->pm_tmr_blk = ACPI_PM_TMR_BLK;
+	fadt->gpe0_blk = ACPI_GPE0_BLK;
+	fadt->gpe1_blk = 0x0000;	/* we dont have gpe1 block, do we? */
+
+	fadt->pm1_evt_len = 4;
+	fadt->pm1_cnt_len = 2;
+	fadt->pm2_cnt_len = 1;
+	fadt->pm_tmr_len = 4;
+	fadt->gpe0_blk_len = 8;
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+
+	fadt->cst_cnt = 0xe3;
+	fadt->p_lvl2_lat = 101;
+	fadt->p_lvl3_lat = 1001;
+	fadt->flush_size = 0;
+	fadt->flush_stride = 0;
+	fadt->duty_offset = 1;
+	fadt->duty_width = 3;
+	fadt->day_alrm = 0;	/* 0x7d these have to be */
+	fadt->mon_alrm = 0;	/* 0x7e added to cmos.layout */
+	fadt->century = 0;	/* 0x7f to make rtc alrm work */
+	fadt->iapc_boot_arch = 0x3;	/* See table 5-11 */
+	fadt->flags = 0x0001c1a5 | 1 << 10;/* 0x25; */
+
+	fadt->res2 = 0;
+
+	fadt->reset_reg.space_id = 1;
+	fadt->reset_reg.bit_width = 8;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.resv = 0;
+	fadt->reset_reg.addrl = 0xcf9;
+	fadt->reset_reg.addrh = 0x0;
+
+	fadt->reset_value = 6;
+	fadt->x_firmware_ctl_l = (u32) facs;
+	fadt->x_firmware_ctl_h = 0;
+	fadt->x_dsdt_l = (u32) dsdt;
+	fadt->x_dsdt_h = 0;
+
+	fadt->x_pm1a_evt_blk.space_id = 1;
+	fadt->x_pm1a_evt_blk.bit_width = 32;
+	fadt->x_pm1a_evt_blk.bit_offset = 0;
+	fadt->x_pm1a_evt_blk.resv = 0;
+	fadt->x_pm1a_evt_blk.addrl = ACPI_PM_EVT_BLK;
+	fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_evt_blk.space_id = 1;
+	fadt->x_pm1b_evt_blk.bit_width = 4;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.resv = 0;
+	fadt->x_pm1b_evt_blk.addrl = 0x0;
+	fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1a_cnt_blk.space_id = 1;
+	fadt->x_pm1a_cnt_blk.bit_width = 16;
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.resv = 0;
+	fadt->x_pm1a_cnt_blk.addrl = ACPI_PM1_CNT_BLK;
+	fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_cnt_blk.space_id = 1;
+	fadt->x_pm1b_cnt_blk.bit_width = 2;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.resv = 0;
+	fadt->x_pm1b_cnt_blk.addrl = 0x0;
+	fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm2_cnt_blk.space_id = 1;
+	fadt->x_pm2_cnt_blk.bit_width = 0;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.resv = 0;
+	fadt->x_pm2_cnt_blk.addrl = ACPI_PMA_CNT_BLK;
+	fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm_tmr_blk.space_id = 1;
+	fadt->x_pm_tmr_blk.bit_width = 32;
+	fadt->x_pm_tmr_blk.bit_offset = 0;
+	fadt->x_pm_tmr_blk.resv = 0;
+	fadt->x_pm_tmr_blk.addrl = ACPI_PM_TMR_BLK;
+	fadt->x_pm_tmr_blk.addrh = 0x0;
+
+	fadt->x_gpe0_blk.space_id = 1;
+	fadt->x_gpe0_blk.bit_width = 32;
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.resv = 0;
+	fadt->x_gpe0_blk.addrl = ACPI_GPE0_BLK;
+	fadt->x_gpe0_blk.addrh = 0x0;
+
+	fadt->x_gpe1_blk.space_id = 1;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.resv = 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/agesa/hudson/hda.c b/src/southbridge/amd/agesa/hudson/hda.c
new file mode 100644
index 0000000..fcd9f7f
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/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/agesa/hudson/hudson.c b/src/southbridge/amd/agesa/hudson/hudson.c
new file mode 100644
index 0000000..ce45042
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/hudson.c
@@ -0,0 +1,122 @@
+/*
+ * 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"
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+int acpi_get_sleep_type(void)
+{
+	u16 tmp = inw(PM1_CNT_BLK_ADDRESS);
+	tmp = ((tmp & (7 << 10)) >> 10);
+	/* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */
+	return (int)tmp;
+}
+#endif
+
+void set_cbmem_toc(struct cbmem_entry *toc)
+{
+	u32 dword = (u32) toc;
+	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 set_sm_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val)
+{
+	u32 reg_old, reg;
+	reg = reg_old = pci_read_config32(sm_dev, reg_pos);
+	reg &= ~mask;
+	reg |= val;
+	if (reg != reg_old) {
+		pci_write_config32(sm_dev, reg_pos, reg);
+	}
+}
+
+static void pmio_write_index(u16 port_base, u8 reg, u8 value)
+{
+	outb(reg, port_base);
+	outb(value, port_base + 1);
+}
+
+static u8 pmio_read_index(u16 port_base, u8 reg)
+{
+	outb(reg, port_base);
+	return inb(port_base + 1);
+}
+
+void pm_iowrite(u8 reg, u8 value)
+{
+	pmio_write_index(PM_INDEX, reg, value);
+}
+
+u8 pm_ioread(u8 reg)
+{
+	return pmio_read_index(PM_INDEX, reg);
+}
+
+void pm2_iowrite(u8 reg, u8 value)
+{
+	pmio_write_index(PM2_INDEX, reg, value);
+}
+
+u8 pm2_ioread(u8 reg)
+{
+	return pmio_read_index(PM2_INDEX, reg);
+}
+
+
+void hudson_enable(device_t dev)
+{
+	printk(BIOS_DEBUG, "sb800_enable()\n");
+}
+
+struct cbmem_entry *get_cbmem_toc(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 (struct cbmem_entry *) xdata;
+}
+
+
+struct chip_operations southbridge_amd_agesa_hudson_ops = {
+	CHIP_NAME("ATI HUDSON")
+	.enable_dev = hudson_enable,
+};
diff --git a/src/southbridge/amd/agesa/hudson/hudson.h b/src/southbridge/amd/agesa/hudson/hudson.h
new file mode 100644
index 0000000..da69de0
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/hudson.h
@@ -0,0 +1,75 @@
+/*
+ * 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_H
+#define HUDSON_H
+
+#include <device/pci_ids.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_PMA_CNT_BLK	(HUDSON_ACPI_IO_BASE + 0x0F) /* 1 byte */
+#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 */
+
+void pm_iowrite(u8 reg, u8 value);
+u8 pm_ioread(u8 reg);
+void pm2_iowrite(u8 reg, u8 value);
+u8 pm2_ioread(u8 reg);
+void set_sm_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val);
+
+#define REV_HUDSON_A11	0x11
+#define REV_HUDSON_A12	0x12
+
+#define PM1_EVT_BLK_ADDRESS                     0x800                           //      AcpiPm1EvtBlkAddr;
+#define PM1_CNT_BLK_ADDRESS                     0x804                           //      AcpiPm1CntBlkAddr;
+#define PM1_TMR_BLK_ADDRESS                     0x808                           //      AcpiPmTmrBlkAddr;
+#define CPU_CNT_BLK_ADDRESS                     0x810                           //      CpuControlBlkAddr;
+#define GPE0_BLK_ADDRESS                        0x820                           //  AcpiGpe0BlkAddr;
+#define SMI_CMD_PORT                            0xB0                            //      SmiCmdPortAddr;
+#define ACPI_PMA_CNT_BLK_ADDRESS        0xFE00                          //      AcpiPmaCntBlkAddr;
+
+#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);
+
+int acpi_is_wakeup_early(void);
+
+#else
+void hudson_enable(device_t dev);
+void __attribute__((weak)) hudson_setup_sata_phys(struct device *dev);
+#endif
+
+#endif /* HUDSON_H */
diff --git a/src/southbridge/amd/agesa/hudson/hudson_fwm.py b/src/southbridge/amd/agesa/hudson/hudson_fwm.py
new file mode 100644
index 0000000..c5875da
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/hudson_fwm.py
@@ -0,0 +1,58 @@
+import sys, os, re
+import struct
+from Queue import Queue
+
+def main(start_addr, file_name, xhci_name, imc_name, gec_name):
+	fwm_sig		= 0x55AA55AA # Hudson-2/3/4 firmware signature
+	fwm_header_len	= 0x10       # 55AA55AA, imc_off, gec_off, xhci_off
+
+	f = open(file_name, "w")
+	print "write to file " + file_name
+
+	imc_offset	= 0x10000 # 64K Bytes offset, hardcoded
+	imc_addr	= start_addr + imc_offset; #startaddr + 0x10000
+	gec_offset	= 0 #TODO
+	gec_addr	= 0 #TODO
+	xhci_addr	= start_addr + fwm_header_len #ROMSIG take 0x10 bytes
+
+	format="I" # one unsigned integer
+	data=struct.pack(format, fwm_sig)
+	f.write(data)
+	data=struct.pack(format, imc_addr)
+	f.write(data)
+	data=struct.pack(format, gec_addr)
+	f.write(data)
+	data=struct.pack(format, xhci_addr)
+	f.write(data)
+
+	if os.path.exists(xhci_name):
+		fwm_content = open(xhci_name).read()
+		f.write(fwm_content)
+	if os.path.exists(imc_name):
+		imc_content = open(imc_name).read()
+		f.seek(0)
+		f.seek(imc_offset)
+		f.write(imc_content)
+#	if os.path.exists(gec_name):
+#		gec_conent = open(gec_name).read()
+#		f.seek(0)
+#		f.seek(gec_offset)
+#		f.write(gec_content)
+
+	f.close()
+	print "done\n"
+
+
+if __name__ == '__main__':
+	if (len(sys.argv) < 6):
+		print "\nUsage: %s <rom_addr> <rom_file> <xhci_rom> <imc_rom> <gec_rom>\n" % sys.argv[0]
+		print "Example: %s 0xFFF20000 hudson.bin xhci.bin imc.bin gec.bin\n" % sys.argv[0]
+		sys.exit(1)
+	rom_addr = int(sys.argv[1], 16)
+	rom_file = sys.argv[2]
+	xhci_file = sys.argv[3]
+	imc_file = sys.argv[4]
+	gec_file = sys.argv[5]
+	print "%x %s %s %s %s" % (rom_addr, rom_file, xhci_file, imc_file, gec_file)
+
+	main(rom_addr, rom_file, xhci_file, imc_file, gec_file)
diff --git a/src/southbridge/amd/agesa/hudson/ide.c b/src/southbridge/amd/agesa/hudson/ide.c
new file mode 100644
index 0000000..44dcfe0
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/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/agesa/hudson/lpc.c b/src/southbridge/amd/agesa/hudson/lpc.c
new file mode 100644
index 0000000..4dd6083
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/lpc.c
@@ -0,0 +1,148 @@
+/*
+ * 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/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.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);
+}
+
+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 */
+
+	pci_get_resource(dev, 0xA0); /* SPI ROM base address */
+
+	/* 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;
+
+	//res = new_resource(dev, 3); /* IOAPIC */
+	//res->base = 0xfec00000;
+	//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;
+
+	pci_dev_set_resources(dev);
+
+	/* Specical case. SPI Base Address. The SpiRomEnable should be set. */
+	res = find_resource(dev, 0xA0);
+	pci_write_config32(dev, 0xA0, res->base | 1 << 1);
+
+}
+
+/**
+ * @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)
+{
+	printk(BIOS_DEBUG, "hudson_lpc_enable_childrens_resources\n");
+
+}
+
+static void hudson_lpc_enable_resources(device_t dev)
+{
+	pci_dev_enable_resources(dev);
+	hudson_lpc_enable_childrens_resources(dev);
+}
+
+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,
+	.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/agesa/hudson/pci.c b/src/southbridge/amd/agesa/hudson/pci.c
new file mode 100644
index 0000000..492e195
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/pci.c
@@ -0,0 +1,49 @@
+/*
+ * 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 pci_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 = 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/agesa/hudson/pcie.c b/src/southbridge/amd/agesa/hudson/pcie.c
new file mode 100644
index 0000000..feb9914
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/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/agesa/hudson/reset.c b/src/southbridge/amd/agesa/hudson/reset.c
new file mode 100644
index 0000000..32ee66b
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/reset.c
@@ -0,0 +1,33 @@
+/*
+ * 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 <reset.h>
+#include <arch/io.h>
+#include <arch/romcc_io.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/agesa/hudson/sata.c b/src/southbridge/amd/agesa/hudson/sata.c
new file mode 100644
index 0000000..ce3d96b
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/sata.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 <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,
+};
diff --git a/src/southbridge/amd/agesa/hudson/sm.c b/src/southbridge/amd/agesa/hudson/sm.c
new file mode 100644
index 0000000..36742aa
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/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 <bitops.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)
+{
+}
+
+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/agesa/hudson/smbus.c b/src/southbridge/amd/agesa/hudson/smbus.c
new file mode 100644
index 0000000..9db936c
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/smbus.c
@@ -0,0 +1,253 @@
+/*
+ * 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  _SB800_SMBUS_C_
+#define  _SB800_SMBUS_C_
+
+#include "smbus.h"
+
+static inline void smbus_delay(void)
+{
+	outb(inb(0x80), 0x80);
+}
+
+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/agesa/hudson/smbus.h b/src/southbridge/amd/agesa/hudson/smbus.h
new file mode 100644
index 0000000..fce8e96
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/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 SB800_SMBUS_H
+#define SB800_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/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c
new file mode 100644
index 0000000..ad8b6d4
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/spi.c
@@ -0,0 +1,218 @@
+/*
+ * 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 <console/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include "spi.h"
+
+void execute_command(volatile u8 * spi_address)
+{
+	*(spi_address + 2) |= 1;
+}
+
+void wait4command_complete(volatile u8 * spi_address)
+{
+//	while (*(spi_address + 2) & 1)
+	while ((*(spi_address + 2) & 1) && (*(spi_address + 3) & 0x80))
+		printk(BIOS_DEBUG, "wait4CommandComplete\n");
+}
+
+void reset_internal_fifo_pointer(volatile u8 * spi_address)
+{
+	u8 val;
+
+	do {
+		*(spi_address + 2) |= 0x10;
+		val = *(spi_address + 0xd);
+	} while (val & 0x7);
+}
+
+u8 read_spi_status(volatile u8 * spi_address)
+{
+	u8 val;
+	*spi_address = 0x05;
+	*(spi_address + 1) = 0x21;
+	reset_internal_fifo_pointer(spi_address);
+	*(spi_address + 0xC) = 0x0;	/* dummy */
+	reset_internal_fifo_pointer(spi_address);
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	reset_internal_fifo_pointer(spi_address);
+	val = *(spi_address + 0xC);
+	val = *(spi_address + 0xC);
+	val = *(spi_address + 0xC);
+	return val;
+}
+
+void wait4flashpart_ready(volatile u8 * spi_address)
+{
+	while (read_spi_status(spi_address) & 1) ;
+}
+
+void write_spi_status(volatile u8 * spi_address, u8 status)
+{
+	*spi_address = 0x50;	/* EWSR */
+	*(spi_address + 1) = 0;	/* RxByte=TxByte=0 */
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+
+	*spi_address = 0x01;	/* WRSR */
+	*(spi_address + 1) = 0x01;
+	reset_internal_fifo_pointer(spi_address);
+	*(spi_address + 0xC) = status;
+	reset_internal_fifo_pointer(spi_address);
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	wait4flashpart_ready(spi_address);
+
+	read_spi_status(spi_address);
+}
+
+void read_spi_id(volatile u8 * spi_address)
+{
+	u8 mid = 0, did = 0;
+	*spi_address = 0x90;
+	*(spi_address + 1) = 0x23;	/* RxByte=2, TxByte=3 */
+	reset_internal_fifo_pointer(spi_address);
+	*(spi_address + 0xC) = 0;
+	*(spi_address + 0xC) = 0;
+	*(spi_address + 0xC) = 0;
+	reset_internal_fifo_pointer(spi_address);
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	reset_internal_fifo_pointer(spi_address);
+	mid = *(spi_address + 0xC);
+	printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
+	mid = *(spi_address + 0xC);
+	printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
+	mid = *(spi_address + 0xC);
+	printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
+
+	mid = *(spi_address + 0xC);
+	did = *(spi_address + 0xC);
+	printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
+}
+
+void spi_write_enable(volatile u8 * spi_address)
+{
+	*spi_address = 0x06;	/* Write Enable */
+	*(spi_address + 1) = 0x0;	/* RxByte=0, TxByte=0 */
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+}
+
+void spi_write_disable(volatile u8 * spi_address)
+{
+	*spi_address = 0x04;	/* Write Enable */
+	*(spi_address + 1) = 0x0;	/* RxByte=0, TxByte=0 */
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+}
+
+void sector_erase_spi(volatile u8 * spi_address, u32 address)
+{
+	spi_write_enable(spi_address);
+	*spi_address = 0x20;
+	*(spi_address + 1) = 0x03;	/* RxByte=0, TxByte=3 */
+
+	reset_internal_fifo_pointer(spi_address);
+	*(spi_address + 0xC) = (address >> 16) & 0xFF;
+	*(spi_address + 0xC) = (address >> 8) & 0xFF;
+	*(spi_address + 0xC) = (address >> 0) & 0xFF;
+	reset_internal_fifo_pointer(spi_address);
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	wait4flashpart_ready(spi_address);
+}
+
+void chip_erase_spi(volatile u8 * spi_address)
+{
+	spi_write_enable(spi_address);
+	*spi_address = 0xC7;
+	*(spi_address + 1) = 0x00;
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	wait4flashpart_ready(spi_address);
+}
+
+void byte_program(volatile u8 * spi_address, u32 address, u32 data)
+{
+	spi_write_enable(spi_address);
+	*spi_address = 0x02;
+	*(spi_address + 1) = 0x0 << 4 | 4;
+	reset_internal_fifo_pointer(spi_address);
+	*(spi_address + 0xC) = (address >> 16) & 0xFF;
+	*(spi_address + 0xC) = (address >> 8) & 0xFF;
+	*(spi_address + 0xC) = (address >> 0) & 0xFF;
+	*(spi_address + 0xC) = data & 0xFF;
+	reset_internal_fifo_pointer(spi_address);
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	wait4flashpart_ready(spi_address);
+}
+
+void dword_noneAAI_program(volatile u8 * spi_address, u32 address, u32 data)
+{
+	u8 i;
+	/*
+	 * printk(BIOS_SPEW, "%s: addr=%x, data=%x\n", __func__, address, data);
+	 */
+	for (i = 0; i < 4; i++) {
+		spi_write_enable(spi_address);
+		*spi_address = 0x02;
+		*(spi_address + 1) = 0x0 << 4 | 4;
+		reset_internal_fifo_pointer(spi_address);
+		*(spi_address + 0xC) = (address >> 16) & 0xFF;
+		*(spi_address + 0xC) = (address >> 8) & 0xFF;
+		*(spi_address + 0xC) = (address >> 0) & 0xFF;
+		*(spi_address + 0xC) = data & 0xFF;
+		data >>= 8;
+		address++;
+		reset_internal_fifo_pointer(spi_address);
+		execute_command(spi_address);
+		wait4command_complete(spi_address);
+		wait4flashpart_ready(spi_address);
+	}
+}
+
+void dword_program(volatile u8 * spi_address, u32 address, u32 data)
+{
+	spi_write_enable(spi_address);
+	*spi_address = 0x02;
+	*(spi_address + 1) = 0x0 << 4 | 7;
+	reset_internal_fifo_pointer(spi_address);
+	*(spi_address + 0xC) = (address >> 16) & 0xFF;
+	*(spi_address + 0xC) = (address >> 8) & 0xFF;
+	*(spi_address + 0xC) = (address >> 0) & 0xFF;
+	*(spi_address + 0xC) = data & 0xFF;
+	*(spi_address + 0xC) = (data >> 8) & 0xFF;
+	*(spi_address + 0xC) = (data >> 16) & 0xFF;
+	*(spi_address + 0xC) = (data >> 24) & 0xFF;
+	reset_internal_fifo_pointer(spi_address);
+	execute_command(spi_address);
+	wait4command_complete(spi_address);
+	wait4flashpart_ready(spi_address);
+}
+
+void direct_byte_program(volatile u8 * spi_address, volatile u32 * address, u32 data)
+{
+	spi_write_enable(spi_address);
+	*address = data;
+	wait4flashpart_ready(spi_address);
+}
diff --git a/src/southbridge/amd/agesa/hudson/spi.h b/src/southbridge/amd/agesa/hudson/spi.h
new file mode 100644
index 0000000..657ce4e
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/spi.h
@@ -0,0 +1,43 @@
+/*
+ *****************************************************************************
+ *
+ * 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
+ * ***************************************************************************
+ *
+ */
+
+#ifndef _HUDSON_CIMX_SPI_H_
+#define _HUDSON_CIMX_SPI_H_
+
+void execute_command(volatile u8 * spi_address);
+void wait4command_complete(volatile u8 * spi_address);
+void reset_internal_fifo_pointer(volatile u8 * spi_address);
+u8 read_spi_status(volatile u8 * spi_address);
+void wait4flashpart_ready(volatile u8 * spi_address);
+void write_spi_status(volatile u8 * spi_address, u8 status);
+void read_spi_id(volatile u8 * spi_address);
+void spi_write_enable(volatile u8 * spi_address);
+void spi_write_disable(volatile u8 * spi_address);
+void sector_erase_spi(volatile u8 * spi_address, u32 address);
+void chip_erase_spi(volatile u8 * spi_address);
+void byte_program(volatile u8 * spi_address, u32 address, u32 data);
+void dword_noneAAI_program(volatile u8 * spi_address, u32 address, u32 data);
+void dword_program(volatile u8 * spi_address, u32 address, u32 data);
+void direct_byte_program(volatile u8 * spi_address, volatile u32 * address, u32 data);
+
+#endif
diff --git a/src/southbridge/amd/agesa/hudson/usb.c b/src/southbridge/amd/agesa/hudson/usb.c
new file mode 100644
index 0000000..0d3ba9e
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/usb.c
@@ -0,0 +1,124 @@
+/*
+ * 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 <usbdebug.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 void usb_set_resources(struct device *dev)
+{
+#if CONFIG_USBDEBUG
+	struct resource *res;
+	u32 base;
+	u32 old_debug;
+
+	old_debug = get_ehci_debug();
+	set_ehci_debug(0);
+#endif
+	pci_dev_set_resources(dev);
+
+#if CONFIG_USBDEBUG
+	res = find_resource(dev, 0x10);
+	set_ehci_debug(old_debug);
+	if (!res)
+		return;
+	base = res->base;
+	set_ehci_base(base);
+	report_resource_stored(dev, res, "");
+#endif
+
+}
+
+static struct device_operations usb_ops = {
+	.read_resources = pci_dev_read_resources,
+	.set_resources = usb_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_dev_read_resources,
+	.set_resources = usb_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,
+ * };
+ */




More information about the coreboot mailing list