summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzbao <fishbaozi@gmail.com>2012-07-13 18:47:03 +0800
committerPatrick Georgi <patrick@georgi-clan.de>2012-07-14 16:29:52 +0200
commit246e84bc0d04e3e670ca815eca32bcfa3be7e2c2 (patch)
tree10aadb7c1812235e2572d528a91f339d758f217d
parent22b7a55a4db9d9bfa69113a8e25e86f21ce8ab6e (diff)
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@amd.com> Signed-off-by: zbao <fishbaozi@gmail.com> Reviewed-on: http://review.coreboot.org/1157 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
-rw-r--r--src/southbridge/amd/Kconfig1
-rw-r--r--src/southbridge/amd/Makefile.inc3
-rw-r--r--src/southbridge/amd/agesa/Kconfig20
-rw-r--r--src/southbridge/amd/agesa/Makefile.inc19
-rw-r--r--src/southbridge/amd/agesa/hudson/Kconfig208
-rw-r--r--src/southbridge/amd/agesa/hudson/Makefile.inc34
-rw-r--r--src/southbridge/amd/agesa/hudson/bootblock.c68
-rw-r--r--src/southbridge/amd/agesa/hudson/chip.h36
-rw-r--r--src/southbridge/amd/agesa/hudson/early_setup.c112
-rw-r--r--src/southbridge/amd/agesa/hudson/enable_usbdebug.c52
-rw-r--r--src/southbridge/amd/agesa/hudson/fadt.c186
-rw-r--r--src/southbridge/amd/agesa/hudson/hda.c51
-rw-r--r--src/southbridge/amd/agesa/hudson/hudson.c122
-rw-r--r--src/southbridge/amd/agesa/hudson/hudson.h75
-rw-r--r--src/southbridge/amd/agesa/hudson/hudson_fwm.py64
-rw-r--r--src/southbridge/amd/agesa/hudson/ide.c48
-rw-r--r--src/southbridge/amd/agesa/hudson/lpc.c148
-rw-r--r--src/southbridge/amd/agesa/hudson/pci.c49
-rw-r--r--src/southbridge/amd/agesa/hudson/pcie.c65
-rw-r--r--src/southbridge/amd/agesa/hudson/reset.c33
-rw-r--r--src/southbridge/amd/agesa/hudson/sata.c51
-rw-r--r--src/southbridge/amd/agesa/hudson/sm.c174
-rw-r--r--src/southbridge/amd/agesa/hudson/smbus.c253
-rw-r--r--src/southbridge/amd/agesa/hudson/smbus.h76
-rw-r--r--src/southbridge/amd/agesa/hudson/spi.c218
-rw-r--r--src/southbridge/amd/agesa/hudson/spi.h43
-rw-r--r--src/southbridge/amd/agesa/hudson/usb.c124
27 files changed, 2332 insertions, 1 deletions
diff --git a/src/southbridge/amd/Kconfig b/src/southbridge/amd/Kconfig
index 1b997aefd6..867afcaf8b 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 9bc58cd358..970971518a 100644
--- a/src/southbridge/amd/Makefile.inc
+++ b/src/southbridge/amd/Makefile.inc
@@ -14,6 +14,7 @@ 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)
@@ -21,7 +22,7 @@ ifeq ($(CONFIG_CPU_AMD_AGESA), y)
$(obj)/s3.rom:
echo " S3 NVRAM 0xffff0000 (S3 storage area)"
# force C locale, so cygwin awk doesn't try to interpret the 0xff below as UTF-8 (or worse)
- LC_ALL=C awk 'BEGIN {for (i=0; i<20480; i++) {printf "%c", 255}}' > $@.tmp
+ LC_ALL=C 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 0000000000..29e00a68fa
--- /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 0000000000..72e62ac7f2
--- /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 0000000000..5b2904232a
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/Kconfig
@@ -0,0 +1,208 @@
+##
+## 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 "3rdparty/amd/hudson/xhci.bin"
+ depends on HUDSON_XHCI_FWM
+
+config HUDSON_IMC_FWM_FILE
+ string "IMC firmware path and filename"
+ default "3rdparty/amd/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_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 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 0000000000..19ffae18fd
--- /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 0000000000..1d0be0ae70
--- /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 0000000000..7732f6d2fe
--- /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 0000000000..8cf380bdf6
--- /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 0000000000..c558a2698a
--- /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 0000000000..ee0334cc5a
--- /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 0000000000..fcd9f7f0ec
--- /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 0000000000..ce450429fa
--- /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 0000000000..28faea49fb
--- /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, TODO: Is it 0xFE00? */
+#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 0000000000..ad60b3b4e4
--- /dev/null
+++ b/src/southbridge/amd/agesa/hudson/hudson_fwm.py
@@ -0,0 +1,64 @@
+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
+
+ if not os.path.exists(xhci_name):
+ print "XHCI firmware %s does not exist\n" % xhci_name
+ sys.exit(1)
+ if not os.path.exists(imc_name):
+ print "IMC firmware %s does not exist\n" % imc_name
+ sys.exit(1)
+
+ 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)
+
+ fwm_content = open(xhci_name).read()
+ f.write(fwm_content)
+
+ 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 0000000000..44dcfe05ac
--- /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 0000000000..4dd6083b1e
--- /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 0000000000..492e195c65
--- /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 0000000000..feb99144b5
--- /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 0000000000..32ee66b4b5
--- /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 0000000000..ce3d96b90d
--- /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 0000000000..36742aa31c
--- /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 0000000000..9db936c31f
--- /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 0000000000..fce8e96572
--- /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 0000000000..ad8b6d4f44
--- /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 0000000000..657ce4e2f4
--- /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 0000000000..0d3ba9ea2c
--- /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,
+ * };
+ */