This does the following:

cd coreboot/src/southbridge
svn mv i82801ca i82801cx
svn mv i82801dbm i82801dx
svn mv i82801er i82801ex
svn copy i82801xx i82801bx
svn mv i82801xx i82801ax

Plus, fixing up the filenames in these directories and the romstage.c and
Kconfig files of the mainboards using those drivers.
Plus, switching the thomson ip1000 and rca rm4100 to the i82801dx driver.

There's a lot more to be done, like 
- adding device IDs for the ICH3 and newer drivers that have been kept in
  i82801xx so far
- drop the additional parts support from the ax and bx drivers.


Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
Acked-by: Joseph Smith <joe@settoplinux.org>




git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5167 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/southbridge/intel/i82801dx/Kconfig b/src/southbridge/intel/i82801dx/Kconfig
new file mode 100644
index 0000000..6a35691
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/Kconfig
@@ -0,0 +1,2 @@
+config SOUTHBRIDGE_INTEL_I82801DX
+	bool
diff --git a/src/southbridge/intel/i82801dx/Makefile.inc b/src/southbridge/intel/i82801dx/Makefile.inc
new file mode 100644
index 0000000..7167e1d
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/Makefile.inc
@@ -0,0 +1,9 @@
+driver-y += i82801dx.o
+driver-y += i82801dx_usb.o
+driver-y += i82801dx_lpc.o
+driver-y += i82801dx_ide.o
+driver-y += i82801dx_usb2.o
+driver-y += i82801dx_ac97.o
+#driver-y += i82801dx_nic.o
+#driver-y += i82801dx_pci.o
+obj-y += i82801dx_reset.o
diff --git a/src/southbridge/intel/i82801dx/chip.h b/src/southbridge/intel/i82801dx/chip.h
new file mode 100644
index 0000000..fdbb7d2
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/chip.h
@@ -0,0 +1,27 @@
+#ifndef I82801DX_CHIP_H
+#define I82801DX_CHIP_H
+
+struct southbridge_intel_i82801dx_config 
+{
+	int enable_usb;
+	int enable_native_ide;
+	/**
+	 * Interrupt Routing configuration
+	 * If bit7 is 1, the interrupt is disabled.
+	 */
+	uint8_t pirqa_routing;
+	uint8_t pirqb_routing;
+	uint8_t pirqc_routing;
+	uint8_t pirqd_routing;
+	uint8_t pirqe_routing;
+	uint8_t pirqf_routing;
+	uint8_t pirqg_routing;
+	uint8_t pirqh_routing;
+
+	uint8_t ide0_enable;
+	uint8_t ide1_enable;
+};
+
+extern struct chip_operations southbridge_intel_i82801dx_ops;
+
+#endif /* I82801DBM_CHIP_H */
diff --git a/src/southbridge/intel/i82801dx/cmos_failover.c b/src/southbridge/intel/i82801dx/cmos_failover.c
new file mode 100644
index 0000000..4821fad
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/cmos_failover.c
@@ -0,0 +1,16 @@
+//kind of cmos_err for ich5
+#define RTC_FAILED    (1 <<2)
+#define GEN_PMCON_3     0xa4
+static void check_cmos_failed(void) 
+{
+
+                uint8_t byte;
+                byte = pci_read_config8(PCI_DEV(0,0x1f,0),GEN_PMCON_3);
+                if( byte & RTC_FAILED){
+//clear bit 1 and bit 2
+                        byte = cmos_read(RTC_BOOT_BYTE);
+                        byte &= 0x0c;
+                        byte |= CONFIG_MAX_REBOOT_CNT << 4;
+                        cmos_write(byte, RTC_BOOT_BYTE);
+                }
+}
diff --git a/src/southbridge/intel/i82801dx/i82801dx.c b/src/southbridge/intel/i82801dx/i82801dx.c
new file mode 100644
index 0000000..abfd8c2
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx.c
@@ -0,0 +1,65 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801dx.h"
+
+void i82801dx_enable(device_t dev)
+{
+	unsigned int index = 0;
+	uint8_t bHasDisableBit = 0;
+	uint16_t cur_disable_mask, new_disable_mask;
+
+//	all 82801dbm devices are in bus 0
+	unsigned int devfn = PCI_DEVFN(0x1f, 0); // lpc
+	device_t lpc_dev = dev_find_slot(0, devfn); // 0
+	if (!lpc_dev)
+		return;
+
+	// Calculate disable bit position for specified device:function
+	// NOTE: For ICH-4, only the following devices can be disabled:
+	//		 D31: F0, F1, F3, F5, F6, 
+	//		 D29: F0, F1, F2, F7
+
+    if (PCI_SLOT(dev->path.pci.devfn) == 31) {
+    	index = PCI_FUNC(dev->path.pci.devfn);
+
+		switch (index) {
+			case 0:
+			case 1:
+			case 3:
+			case 5:
+			case 6:
+				bHasDisableBit = 1;
+				break;
+			
+			default:
+				break;
+		};
+		
+		if (index == 0)
+			index = 14;		// D31:F0 bit is an exception
+
+    } else if (PCI_SLOT(dev->path.pci.devfn) == 29) {
+    	index = 8 + PCI_FUNC(dev->path.pci.devfn);
+
+		if ((PCI_FUNC(dev->path.pci.devfn) < 3) || (PCI_FUNC(dev->path.pci.devfn) == 7))
+			bHasDisableBit = 1;
+    }
+
+	if (bHasDisableBit) {
+		cur_disable_mask = pci_read_config16(lpc_dev, FUNC_DIS);
+		new_disable_mask = cur_disable_mask & ~(1<<index); 		// enable it
+		if (!dev->enabled) {
+			new_disable_mask |= (1<<index);  // disable it
+		}
+		if (new_disable_mask != cur_disable_mask) {
+			pci_write_config16(lpc_dev, FUNC_DIS, new_disable_mask);
+		}
+	}
+}
+
+struct chip_operations southbridge_intel_i82801dx_ops = {
+	CHIP_NAME("Intel ICH4/ICH4-M (82801Dx) Series Southbridge")
+	.enable_dev = i82801dx_enable,
+};
diff --git a/src/southbridge/intel/i82801dx/i82801dx.h b/src/southbridge/intel/i82801dx/i82801dx.h
new file mode 100644
index 0000000..d4e1aa0
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx.h
@@ -0,0 +1,163 @@
+/* the problem: we have 82801dbm support in fb1, and 82801er in fb2. 
+ * fb1 code is what we want, fb2 structure is needed however. 
+ * so we need to get fb1 code for 82801dbm into fb2 structure. 
+ */
+/* What I did: took the 80801er stuff from fb2, verify it against the 
+ * db stuff in fb1, and made sure it was right.
+ */
+
+#ifndef I82801DX_H
+#define I82801DX_H
+
+#if !defined( __ROMCC__ ) && !defined(__PRE_RAM__)
+#include "chip.h"
+extern void i82801dx_enable(device_t dev);
+#endif
+
+#define MAINBOARD_POWER_OFF	0
+#define MAINBOARD_POWER_ON	1
+#define MAINBOARD_POWER_KEEP	2
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+/*
+000 = Non-combined. P0 is primary master. P1 is secondary master.
+001 = Non-combined. P0 is secondary master. P1 is primary master.
+100 = Combined. P0 is primary master. P1 is primary slave. IDE is secondary; Primary IDE channel
+disabled.
+101 = Combined. P0 is primary slave. P1 is primary master. IDE is secondary.
+110 = Combined. IDE is primary. P0 is secondary master. P1 is secondary slave; Secondary IDE
+channel disabled.
+111 = Combined. IDE is primary. P0 is secondary slave. P1 is secondary master.
+*/
+
+#define PCI_DMA_CFG     0x90
+#define SERIRQ_CNTL     0x64
+#define GEN_CNTL        0xd0
+#define GEN_STS         0xd4
+#define RTC_CONF        0xd8
+#define GEN_PMCON_3     0xa4
+
+#define PCICMD          0x04
+#define PMBASE          0x40
+#define   PMBASE_ADDR	0x0400
+#define ACPI_CNTL       0x44
+#define BIOS_CNTL       0x4E
+#define GPIO_BASE       0x58
+#define GPIO_CNTL       0x5C
+#define PIRQA_ROUT      0x60
+#define PIRQE_ROUT      0x68
+#define COM_DEC         0xE0
+#define LPC_EN          0xE6
+#define FUNC_DIS        0xF2
+
+/* 1e f0 244e */
+
+#define CMD             0x04
+#define SBUS_NUM        0x19
+#define SUB_BUS_NUM     0x1A
+#define SMLT            0x1B
+#define IOBASE          0x1C
+#define IOLIM           0x1D
+#define MEMBASE         0x20
+#define MEMLIM          0x22
+#define CNF             0x50
+#define MTT             0x70
+#define PCI_MAST_STS    0x82
+
+#define RTC_FAILED      (1 <<2)
+
+
+#define SMBUS_IO_BASE 0x1000
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL  0x2
+#define SMBHSTCMD  0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT  0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL  0xf 
+
+/* 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)
+
+#define PM1_STS		0x00
+#define   WAK_STS	(1 << 15)
+#define   PCIEXPWAK_STS	(1 << 14)
+#define   PRBTNOR_STS	(1 << 11)
+#define   RTC_STS	(1 << 10)
+#define   PWRBTN_STS	(1 << 8)
+#define   GBL_STS	(1 << 5)
+#define   BM_STS	(1 << 4)
+#define   TMROF_STS	(1 << 0)
+#define PM1_EN		0x02
+#define   PCIEXPWAK_DIS	(1 << 14)
+#define   RTC_EN	(1 << 10)
+#define   PWRBTN_EN	(1 << 8)
+#define   GBL_EN	(1 << 5)
+#define   TMROF_EN	(1 << 0)
+#define PM1_CNT		0x04
+#define   SLP_EN	(1 << 13)
+#define   SLP_TYP	(7 << 10)
+#define   GBL_RLS	(1 << 2)
+#define   BM_RLD	(1 << 1)
+#define   SCI_EN	(1 << 0)
+#define PM1_TMR		0x08
+#define PROC_CNT	0x10
+#define LV2		0x14
+#define LV3		0x15
+#define LV4		0x16
+#define PM2_CNT		0x20 // mobile only
+#define GPE0_STS	0x28
+#define   PME_B0_STS	(1 << 13)
+#define   USB3_STS	(1 << 12)
+#define   PME_STS	(1 << 11)
+#define   BATLOW_STS	(1 << 10)
+#define   GST_STS	(1 << 9)
+#define   RI_STS	(1 << 8)
+#define   SMB_WAK_STS	(1 << 7)
+#define   TCOSCI_STS	(1 << 6)
+#define   AC97_STS	(1 << 5)
+#define   USB2_STS	(1 << 4)
+#define   USB1_STS	(1 << 3)
+#define   SWGPE_STS	(1 << 2)
+#define   HOT_PLUG_STS	(1 << 1)
+#define   THRM_STS	(1 << 0)
+#define GPE0_EN		0x2c
+#define   PME_B0_EN	(1 << 13)
+#define   PME_EN	(1 << 11)
+#define SMI_EN		0x30
+#define   EL_SMI_EN	 (1 << 25) // Intel Quick Resume Technology
+#define   INTEL_USB2_EN	 (1 << 18) // Intel-Specific USB2 SMI logic
+#define   LEGACY_USB2_EN (1 << 17) // Legacy USB2 SMI logic
+#define   PERIODIC_EN	 (1 << 14) // SMI on PERIODIC_STS in SMI_STS
+#define   TCO_EN	 (1 << 13) // Enable TCO Logic (BIOSWE et al)
+#define   MCSMI_EN	 (1 << 11) // Trap microcontroller range access
+#define   BIOS_RLS	 (1 <<  7) // asserts SCI on bit set
+#define   SWSMI_TMR_EN	 (1 <<  6) // start software smi timer on bit set
+#define   APMC_EN	 (1 <<  5) // Writes to APM_CNT cause SMI#
+#define   SLP_SMI_EN	 (1 <<  4) // Write to SLP_EN in PM1_CNT asserts SMI#
+#define   LEGACY_USB_EN  (1 <<  3) // Legacy USB circuit SMI logic
+#define   BIOS_EN	 (1 <<  2) // Assert SMI# on setting GBL_RLS bit
+#define   EOS		 (1 <<  1) // End of SMI (deassert SMI#)
+#define   GBL_SMI_EN	 (1 <<  0) // SMI# generation at all?
+#define SMI_STS		0x34
+#define ALT_GP_SMI_EN	0x38
+#define ALT_GP_SMI_STS	0x3a
+#define GPE_CNTL	0x42
+#define DEVACT_STS	0x44
+#define SS_CNT		0x50
+#define C3_RES		0x54
+
+#define TCOBASE		0x60 /* TCO Base Address Register */
+#define TCO1_CNT	0x08 /* TCO1 Control Register */
+
+#endif /* I82801DX_H */
diff --git a/src/southbridge/intel/i82801dx/i82801dx_ac97.c b/src/southbridge/intel/i82801dx/i82801dx_ac97.c
new file mode 100644
index 0000000..7524498
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_ac97.c
@@ -0,0 +1,41 @@
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+
+static struct device_operations ac97audio_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.enable           = i82801dx_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static const struct pci_driver ac97audio_driver __pci_driver = {
+	.ops    = &ac97audio_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_AC97_AUDIO,
+};
+
+
+static struct device_operations ac97modem_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.enable           = i82801dx_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static const struct pci_driver ac97modem_driver __pci_driver = {
+	.ops    = &ac97modem_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_AC97_MODEM,
+};
diff --git a/src/southbridge/intel/i82801dx/i82801dx_early_smbus.c b/src/southbridge/intel/i82801dx/i82801dx_early_smbus.c
new file mode 100644
index 0000000..0a0ff91
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_early_smbus.c
@@ -0,0 +1,180 @@
+
+//#define SMBUS_IO_BASE 0x1000
+//#define SMBUS_IO_BASE 0x0f00
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL  0x2
+#define SMBHSTCMD  0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT  0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL  0xf 
+
+/* 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)
+
+static void enable_smbus(void)
+{
+	device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+	print_debug("SMBus controller enabled\r\n");
+	/* set smbus iobase */
+	pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+	/* Set smbus enable */
+	pci_write_config8(dev, 0x40, 0x01);
+	/* Set smbus iospace enable */ 
+	pci_write_config16(dev, 0x4, 0x01);
+	/* Disable interrupt generation */ 
+	outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+
+static inline void smbus_delay(void)
+{
+	outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_active(void)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned char val;
+		smbus_delay();
+		val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+		if ((val & 1)) {
+			break;
+		}
+	} while(--loops);
+	return loops?0:-4;
+}
+
+static int smbus_wait_until_ready(void)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned char val;
+		smbus_delay();
+		val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+		if ((val & 1) == 0) {
+			break;
+		}
+		if(loops == (SMBUS_TIMEOUT / 2)) {
+			outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), 
+				SMBUS_IO_BASE + SMBHSTSTAT);
+		}
+	} while(--loops);
+	return loops?0:-2;
+}
+
+static int smbus_wait_until_done(void)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned char val;
+		smbus_delay();
+		
+		val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+		if ( (val & 1) == 0) {
+			break;
+		}
+		if ((val & ~((1<<6)|(1<<0)) ) != 0 ) {
+			break;
+		}
+	} while(--loops);
+	return loops?0:-3;
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+	unsigned char global_control_register;
+	unsigned char global_status_register;
+	unsigned char byte;
+
+	/*print_err("smbus_read_byte\r\n");*/
+	if (smbus_wait_until_ready() < 0) {
+		print_err_hex8(-2);
+		return -2;
+	}
+	
+	/* setup transaction */
+	/* disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+	/* set the command/address... */
+	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	/* set up for a byte data read */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2<<2), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* clear the data byte...*/
+	outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+	/* start a byte read, with interrupts disabled */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+	/* poll for it to start */
+	if (smbus_wait_until_active() < 0) {
+		print_err_hex8(-4);
+		return -4;
+	}
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done() < 0) {
+		print_err_hex8(-3);
+		return -3;
+	}
+
+	global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1<<6); /* Ignore the In Use Status... */
+
+	/* read results of transaction */
+	byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+	if (global_status_register != 2) {
+		print_err_hex8(-1);
+		return -1;
+	}
+/*
+        print_err("smbus_read_byte: ");
+	print_err_hex32(device); print_err(" ad "); print_err_hex32(address);
+	print_err("value "); print_err_hex8(byte); print_err("\r\n");
+ */
+	return byte;
+}
+#if 0
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+	if (smbus_wait_until_ready() < 0) {
+		return;
+	}
+
+	/* by LYH */
+	outb(0x37,SMBUS_IO_BASE + SMBHSTSTAT);
+	/* set the device I'm talking too */
+	outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR);
+
+	/* data to send */
+	outb(val, SMBUS_IO_BASE + SMBHSTDAT);
+
+	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+
+	/* start the command */
+	outb(0xa, SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* poll for transaction completion */
+	smbus_wait_until_done();
+	return;
+}
+#endif
diff --git a/src/southbridge/intel/i82801dx/i82801dx_ide.c b/src/southbridge/intel/i82801dx/i82801dx_ide.c
new file mode 100644
index 0000000..bb35107
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_ide.c
@@ -0,0 +1,53 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+
+static void ide_init(struct device *dev)
+{
+#if ICH5_SATA_ADDRESS_MAP<=1
+	/* Enable ide devices so the linux ide driver will work */
+	uint16_t word;
+	uint8_t byte;
+	int enable_a=1, enable_b=1;
+
+
+	word = pci_read_config16(dev, 0x40);
+	word &= ~((1 << 15));
+	if (enable_a) {
+		/* Enable first ide interface */
+		word |= (1<<15);
+		printk_debug("IDE0 ");
+	}
+	pci_write_config16(dev, 0x40, word);
+
+        word = pci_read_config16(dev, 0x42);
+        word &= ~((1 << 15));
+        if (enable_b) {
+                /* Enable secondary ide interface */
+                word |= (1<<15);
+                printk_debug("IDE1 ");
+        }
+        pci_write_config16(dev, 0x42, word);
+#endif
+
+}
+
+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,
+	.enable           = i82801dx_enable,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+	.ops    = &ide_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_IDE,
+};
+
diff --git a/src/southbridge/intel/i82801dx/i82801dx_lpc.c b/src/southbridge/intel/i82801dx/i82801dx_lpc.c
new file mode 100644
index 0000000..59225d2
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_lpc.c
@@ -0,0 +1,226 @@
+/*
+ * (C) 2003 Linux Networx, SuSE Linux AG
+ * (C) 2004 Tyan Computer
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include "i82801dx.h"
+
+
+
+#define NMI_OFF 0
+
+void i82801dx_enable_ioapic( struct device *dev) 
+{
+        uint32_t dword;
+        volatile uint32_t *ioapic_sba = (volatile uint32_t *)0xfec00000;
+        volatile uint32_t *ioapic_sbd = (volatile uint32_t *)0xfec00010;
+
+        dword = pci_read_config32(dev, GEN_CNTL);
+        dword |= (3 << 7); /* enable ioapic */
+        dword |= (1 <<13); /* coprocessor error enable */
+        dword |= (1 << 1); /* delay transaction enable */
+        dword |= (1 << 2); /* DMA collection buf enable */
+        pci_write_config32(dev, GEN_CNTL, dword);
+        printk_debug("ioapic southbridge enabled %x\n",dword);
+        *ioapic_sba=0;
+        *ioapic_sbd=(2<<24);
+        //lyh *ioapic_sba=3;
+        //lyh *ioapic_sbd=1;    
+        *ioapic_sba=0;
+        dword=*ioapic_sbd;
+        printk_debug("Southbridge apic id = %x\n",dword);
+        if(dword!=(2<<24))
+                die("");
+        //lyh *ioapic_sba=3;
+        //lyh dword=*ioapic_sbd;
+        //lyh printk_debug("Southbridge apic DT = %x\n",dword);
+        //lyh if(dword!=1)
+        //lyh   die("");
+
+
+}
+void i82801dx_enable_serial_irqs( struct device *dev)
+{
+        pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
+}
+void i82801dx_lpc_route_dma( struct device *dev, uint8_t mask) 
+{
+        uint16_t word;
+        int i;
+        word = pci_read_config16(dev, PCI_DMA_CFG);
+        word &= ((1 << 10) - (1 << 8));
+        for(i = 0; i < 8; i++) {
+                if (i == 4)
+                        continue;
+                word |= ((mask & (1 << i))? 3:1) << (i*2);
+        }
+        pci_write_config16(dev, PCI_DMA_CFG, word);
+}
+void i82801dx_rtc_init(struct device *dev)
+{
+        uint8_t byte;
+        uint32_t dword;
+        int rtc_failed;
+        byte = pci_read_config8(dev, GEN_PMCON_3);
+        rtc_failed = byte & RTC_FAILED;
+        if (rtc_failed) {
+                byte &= ~(1 << 1); /* preserve the power fail state */
+                pci_write_config8(dev, GEN_PMCON_3, byte);
+        }
+        dword = pci_read_config32(dev, GEN_STS);
+        rtc_failed |= dword & (1 << 2);
+        rtc_init(rtc_failed);
+}
+
+
+void i82801dx_1f0_misc(struct device *dev)
+{
+        pci_write_config16(dev, PCICMD, 0x014f);
+        pci_write_config32(dev, PMBASE, 0x00001001);
+        pci_write_config8(dev, ACPI_CNTL, 0x10);
+        pci_write_config32(dev, GPIO_BASE, 0x00001181);
+        pci_write_config8(dev, GPIO_CNTL, 0x10);
+        pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B);
+        pci_write_config8(dev, PIRQE_ROUT, 0x07);
+        pci_write_config8(dev, RTC_CONF, 0x04);
+        pci_write_config8(dev, COM_DEC, 0x10);  //lyh E0->
+        pci_write_config16(dev, LPC_EN, 0x000F);  //LYH 000D->
+}
+
+static void enable_hpet(struct device *dev)
+{
+	const unsigned long hpet_address = 0xfed0000;
+
+        uint32_t dword;
+	uint32_t code = (0 & 0x3);
+        
+        dword = pci_read_config32(dev, GEN_CNTL);
+        dword |= (1 << 17); /* enable hpet */
+	/*Bits [16:15]Memory Address Range
+	00 FED0_0000h - FED0_03FFh
+	01 FED0_1000h - FED0_13FFh
+	10 FED0_2000h - FED0_23FFh
+	11 FED0_3000h - FED0_33FFh*/
+
+        dword &= ~(3 << 15); /* clear it */
+	dword |= (code<<15);
+
+	printk_debug("enabling HPET @0x%x\n", hpet_address | (code <<12) );
+}
+
+static void lpc_init(struct device *dev)
+{
+	uint8_t byte;
+	int pwr_on=-1;
+	int nmi_option;
+
+	/* IO APIC initialization */
+	i82801dx_enable_ioapic(dev);
+
+	i82801dx_enable_serial_irqs(dev);
+
+#ifdef SUSPICIOUS_LOOKING_CODE	
+	// The ICH-4 datasheet does not mention this configuration register. 
+	// This code may have been inherited (incorrectly) from code for the AMD 766 southbridge,
+	// which *does* support this functionality.
+
+	/* posted memory write enable */
+	byte = pci_read_config8(dev, 0x46);
+	pci_write_config8(dev, 0x46, byte | (1<<0)); 
+#endif
+
+	/* power after power fail */
+	        /* FIXME this doesn't work! */
+        /* Which state do we want to goto after g3 (power restored)?
+         * 0 == S0 Full On
+         * 1 == S5 Soft Off
+         */
+        pci_write_config8(dev, GEN_PMCON_3, pwr_on?0:1);
+        printk_info("set power %s after power fail\n", pwr_on?"on":"off");
+#if 0
+	/* Enable Error reporting */
+	/* Set up sync flood detected */
+	byte = pci_read_config8(dev, 0x47);
+	byte |= (1 << 1);
+	pci_write_config8(dev, 0x47, byte);
+#endif
+
+	/* Set up NMI on errors */
+    byte = inb(0x61);
+    byte &= ~(1 << 3); /* IOCHK# NMI Enable */
+    byte &= ~(1 << 2); /* PCI SERR# Enable */
+    outb(byte, 0x61);
+    byte = inb(0x70);
+	nmi_option = NMI_OFF;
+	get_option(&nmi_option, "nmi");
+	if (nmi_option) {			
+        byte &= ~(1 << 7); /* set NMI */
+        outb(byte, 0x70);
+	}
+	
+	/* Initialize the real time clock */
+	i82801dx_rtc_init(dev);
+
+	i82801dx_lpc_route_dma(dev, 0xff);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+
+	i82801dx_1f0_misc(dev);
+	/* Initialize the High Precision Event Timers */
+	enable_hpet(dev);
+}
+
+static void i82801dx_lpc_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Get the normal PCI resources of this device. */
+	pci_dev_read_resources(dev);
+
+	/* 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;
+}
+
+static void i82801dx_lpc_enable_resources(device_t dev)
+{
+	pci_dev_enable_resources(dev);
+	enable_childrens_resources(dev);
+}
+
+static struct device_operations lpc_ops  = {
+	.read_resources   = i82801dx_lpc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = i82801dx_lpc_enable_resources,
+	.init             = lpc_init,
+	.scan_bus         = scan_static_bus,
+	.enable           = i82801dx_enable,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_LPC,
+};
diff --git a/src/southbridge/intel/i82801dx/i82801dx_nic.c b/src/southbridge/intel/i82801dx/i82801dx_nic.c
new file mode 100644
index 0000000..6221ba488
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_nic.c
@@ -0,0 +1,21 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+
+static struct device_operations nic_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static const struct pci_driver nic_driver __pci_driver = {
+	.ops    = &nic_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x103a,
+};
diff --git a/src/southbridge/intel/i82801dx/i82801dx_pci.c b/src/southbridge/intel/i82801dx/i82801dx_pci.c
new file mode 100644
index 0000000..0c88bf2
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_pci.c
@@ -0,0 +1,33 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void pci_init(struct device *dev)
+{
+	/* Enable pci error detecting */
+	uint32_t dword;
+	/* System error enable */
+	dword = pci_read_config32(dev, 0x04);
+	dword |= (1<<8); /* SERR# Enable */
+	dword |= (1<<6); /* Parity Error Response */
+	pci_write_config32(dev, 0x04, dword);
+
+}
+
+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,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_PCI,
+};
+
diff --git a/src/southbridge/intel/i82801dx/i82801dx_reset.c b/src/southbridge/intel/i82801dx/i82801dx_reset.c
new file mode 100644
index 0000000..3d7a4b7
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_reset.c
@@ -0,0 +1,7 @@
+#include <arch/io.h>
+
+void hard_reset(void)
+{
+        /* Try rebooting through port 0xcf9 */
+        outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
diff --git a/src/southbridge/intel/i82801dx/i82801dx_sata.c b/src/southbridge/intel/i82801dx/i82801dx_sata.c
new file mode 100644
index 0000000..22c6cd7
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_sata.c
@@ -0,0 +1,75 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void sata_init(struct device *dev)
+{
+
+        uint16_t word;
+        uint8_t byte;
+	int enable_c=1, enable_d=1;
+	//	int i;
+                
+        //Enable Serial ATA port
+        byte = pci_read_config8(dev,0x90);
+        byte &= 0xf8;
+        byte |= ICH5_SATA_ADDRESS_MAP & 7;
+        pci_write_config8(dev,0x90,byte);
+
+//        for(i=0;i<10;i++) {
+		word = pci_read_config16(dev,0x92);
+                word &= 0xfffc;
+//                if( (word & 0x0003) == 0x0003) break;
+                word |= 0x0003; // enable P0/P1 
+                pci_write_config16(dev,0x92,word);
+//        }
+
+//        for(i=0;i<10;i++) {
+              /* enable ide0 */
+		word = pci_read_config16(dev, 0x40);
+        	word &= ~(1 << 15);
+                if(enable_c==0) {
+//                     	if( (word & 0x8000) == 0x0000) break;
+                       	word |= 0x0000;
+                }
+                else {
+//                       	if( (word & 0x8000) == 0x8000) break;
+                       	word |= 0x8000;
+                }
+                pci_write_config16(dev, 0x40, word);
+//	}
+                /* enable ide1 */
+//        for(i=0;i<10;i++) {
+              	word = pci_read_config16(dev, 0x42);
+                word &= ~(1 << 15);
+                if(enable_d==0) {
+//                       	if( (word & 0x8000) == 0x0000) break;
+                       	word |= 0x0000;
+                }
+                else {
+//                       	if( (word & 0x8000) == 0x8000) break;
+                       	word |= 0x8000;
+                }
+                pci_write_config16(dev, 0x42, word);
+//        }
+
+}
+
+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,
+	.enable           = i82801dx_enable,
+};
+
+static const struct pci_driver stat_driver __pci_driver = {
+	.ops    = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_SATA,
+};
+
diff --git a/src/southbridge/intel/i82801dx/i82801dx_smbus.c b/src/southbridge/intel/i82801dx/i82801dx_smbus.c
new file mode 100644
index 0000000..e56a67c
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_smbus.c
@@ -0,0 +1,95 @@
+#include "i82801dx.h"
+#include <smbus.h>
+#include <pci.h>
+#include <arch/io.h>
+
+#define PM_BUS 0
+#define PM_DEVFN PCI_DEVFN(0x1f,3)
+
+#if 0
+#define SMBUS_IO_BASE 0x1000
+#define SMBHSTSTAT 0
+#define SMBHSTCTL  2
+#define SMBHSTCMD  3
+#define SMBHSTADD  4
+#define SMBHSTDAT0 5
+#define SMBHSTDAT1 6
+#define SMBBLKDAT  7
+#endif
+
+void smbus_enable(void)
+{
+	unsigned char byte;
+	/* iobase addr */
+	pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x20, SMBUS_IO_BASE | 1);
+	/* smbus enable */
+	pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0x40,  1);
+	/* iospace enable */
+	pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
+
+        /* Disable interrupt generation */
+        outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+}
+
+void smbus_setup(void)
+{
+	outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static void smbus_wait_until_ready(void)
+{
+	while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
+		/* nop */
+	}
+}
+
+static void smbus_wait_until_done(void)
+{
+	unsigned char byte;
+	do {
+		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+	while((byte &1) == 1);
+	while( (byte & ~1) == 0) {
+		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+}
+
+int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
+{
+	unsigned char host_status_register;
+	unsigned char byte;
+
+	smbus_wait_until_ready();
+
+	/* setup transaction */
+	/* disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
+	/* set the command/address... */
+	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	/* set up for a byte data read */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* clear the data byte...*/
+	outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+	/* start the command */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* poll for transaction completion */
+	smbus_wait_until_done();
+
+	host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* read results of transaction */
+	byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+	*result = byte;
+	return host_status_register != 0x02;
+}
diff --git a/src/southbridge/intel/i82801dx/i82801dx_usb.c b/src/southbridge/intel/i82801dx/i82801dx_usb.c
new file mode 100644
index 0000000..2e60193
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_usb.c
@@ -0,0 +1,49 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void usb_init(struct device *dev)
+{
+
+
+#if 0
+	uint32_t cmd;
+	printk_debug("USB: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
+		PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
+
+
+	printk_debug("done.\n");
+#endif
+
+}
+
+static struct device_operations usb_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = usb_init,
+	.scan_bus         = 0,
+	.enable           = i82801dx_enable,
+};
+
+static const struct pci_driver usb_driver_1 __pci_driver = {
+	.ops    = &usb_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_USB1,
+};
+static const struct pci_driver usb_driver_2 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_USB2,
+};
+static const struct pci_driver usb_driver_3 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_USB3,
+};
diff --git a/src/southbridge/intel/i82801dx/i82801dx_usb2.c b/src/southbridge/intel/i82801dx/i82801dx_usb2.c
new file mode 100644
index 0000000..ca13e92
--- /dev/null
+++ b/src/southbridge/intel/i82801dx/i82801dx_usb2.c
@@ -0,0 +1,40 @@
+//2003 Copywright Tyan
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void usb2_init(struct device *dev)
+{
+
+
+#if 0  
+  uint32_t cmd;
+	printk_debug("USB: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
+		PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
+
+
+	printk_debug("done.\n");
+#endif
+}
+
+static struct device_operations usb2_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = usb2_init,
+	.scan_bus         = 0,
+	.enable           = i82801dx_enable,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+	.ops    = &usb2_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801DBM_EHCI,
+};