new intel io hub.


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1634 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/southbridge/intel/i82801dbm/Config.lb b/src/southbridge/intel/i82801dbm/Config.lb
new file mode 100644
index 0000000..e7024bd
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/Config.lb
@@ -0,0 +1,11 @@
+config i82801dbm.h
+driver i82801dbm.o
+driver i82801dbm_usb.o
+driver i82801dbm_lpc.o
+driver i82801dbm_ide.o
+driver i82801dbm_sata.o
+driver i82801dbm_usb2.o
+driver i82801dbm_ac97.o
+#driver i82801dbm_nic.o
+#driver i82801dbm_pci.o
+object i82801dbm_reset.o
diff --git a/src/southbridge/intel/i82801dbm/cmos_failover.c b/src/southbridge/intel/i82801dbm/cmos_failover.c
new file mode 100644
index 0000000..9702313
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/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 |= MAX_REBOOT_CNT << 4;
+                        cmos_write(byte, RTC_BOOT_BYTE);
+                }
+}
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm.c b/src/southbridge/intel/i82801dbm/i82801dbm.c
new file mode 100644
index 0000000..d89a309
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm.c
@@ -0,0 +1,57 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/chip.h>
+#include "i82801dbm.h"
+
+void i82801dbm_enable(device_t dev)
+{
+	device_t lpc_dev;
+	unsigned int index;
+	uint16_t reg_old, reg;
+
+//	all 82801dbm device ares in bus 0
+	unsigned int devfn;
+	devfn = PCI_DEVFN(0x1f, 0); // lpc
+	lpc_dev = dev_find_slot(0, devfn); // 0
+	if (!lpc_dev ) {
+		return;
+	}
+#if 0
+	if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) ||
+	    (lpc_dev->device != PCI_DEVICE_ID_INTEL_82801ER_1F0)) {
+		uint32_t id;
+		id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
+		if (id != (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_82801ER_1F0 << 16))) {
+			return;
+		}
+	}
+#endif
+
+	index = (dev->path.u.pci.devfn & 7);
+        if((dev->path.u.pci.devfn & ~0x7)==devfn) { // D=0x1f
+                if(index==0){   //1f0   
+                        index = 14;
+                } 
+        } else { // D=0x1d
+                index += 8;
+        }
+
+	reg_old = pci_read_config16(lpc_dev, FUNC_DIS);
+	reg = reg_old;
+	reg &= ~(1<<index); // enable it
+	if (!dev->enabled) {
+		reg |= (1<<index);  // disable it
+	}
+	if (reg != reg_old) {
+		pci_write_config16(lpc_dev, FUNC_DIS, reg);
+	}
+	reg = pci_read_config16(lpc_dev, FUNC_DIS);
+
+}
+
+struct chip_control southbridge_intel_i82801dbm_control = {
+	.name       = "Intel 82801dbm Southbridge",
+	.enable_dev = i82801dbm_enable,
+};
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm.h b/src/southbridge/intel/i82801dbm/i82801dbm.h
new file mode 100644
index 0000000..85dce4ec
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm.h
@@ -0,0 +1,81 @@
+#ifndef I82801ER_H
+#define I82801ER_H
+
+struct southbridge_intel_i82801er_config 
+{
+};
+struct chip_control;
+extern struct chip_control southbridge_intel_i82801er_control;
+
+extern void i82801er_enable(device_t dev);
+
+/*
+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 ICH5_SATA_ADDRESS_MAP 0
+
+
+#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 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)
+
+#endif /* I82801ER_H */
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_ac97.c b/src/southbridge/intel/i82801dbm/i82801dbm_ac97.c
new file mode 100644
index 0000000..091f4d6
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_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 "i82801dbm.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           = i82801dbm_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static struct pci_driver ac97audio_driver __pci_driver = {
+	.ops    = &ac97audio_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F5,
+};
+
+
+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           = i82801dbm_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static struct pci_driver ac97modem_driver __pci_driver = {
+	.ops    = &ac97modem_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F6,
+};
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c b/src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c
new file mode 100644
index 0000000..ed014f1
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c
@@ -0,0 +1,156 @@
+
+//#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;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d3), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("SMBUS controller not found\r\n");
+	}
+	
+	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_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;
+
+	if (smbus_wait_until_ready() < 0) {
+		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 transaction completion */
+	if (smbus_wait_until_done() < 0) {
+		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) {
+		return -1;
+	}
+	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/i82801dbm/i82801dbm_ide.c b/src/southbridge/intel/i82801dbm/i82801dbm_ide.c
new file mode 100644
index 0000000..487fe9f
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_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 "i82801dbm.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_a) {
+                /* 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           = i82801dbm_enable,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+	.ops    = &ide_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F1,
+};
+
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_lpc.c b/src/southbridge/intel/i82801dbm/i82801dbm_lpc.c
new file mode 100644
index 0000000..7256610
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_lpc.c
@@ -0,0 +1,219 @@
+/*
+ * (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 <device/chip.h>
+#include <pc80/mc146818rtc.h>
+#include "i82801dbm.h"
+
+void isa_dma_init(void); /* from /pc80/isa-dma.c */
+
+#define NMI_OFF 0
+
+void i82801dbm_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))
+                for(;;);
+        //lyh *ioapic_sba=3;
+        //lyh dword=*ioapic_sbd;
+        //lyh printk_debug("Southbridge apic DT = %x\n",dword);
+        //lyh if(dword!=1)
+        //lyh   for(;;);
+
+
+}
+void i82801dbm_enable_serial_irqs( struct device *dev)
+{
+        pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
+}
+void i82801dbm_lpc_route_dma( struct device *dev, uint8_t mask) 
+{
+        uint16_t word;
+        int i;
+        word = pci_read_config8(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 i82801dbm_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 i82801dbm_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 */
+	i82801dbm_enable_ioapic(dev);
+
+	i82801dbm_enable_serial_irqs(dev);
+	
+	/* posted memory write enable */
+	byte = pci_read_config8(dev, 0x46);
+	pci_write_config8(dev, 0x46, byte | (1<<0)); 
+
+	/* 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 = pci_read_config8(dev, 0x61);
+	byte |= (1 << 3); /* IOCHK# NMI Enable */
+	byte |= (1 << 6); /* PCI SERR# Enable */
+	pci_write_config8(dev, 0x61, byte);
+	byte = pci_read_config8(dev, 0x70);
+	nmi_option = NMI_OFF;
+	get_option(&nmi_option, "nmi");
+	if (nmi_option) {			
+		byte |= (1 << 7); /* set NMI */
+		pci_write_config8(dev, 0x70, byte);
+	}
+	
+	/* Initialize the real time clock */
+	i82801dbm_rtc_init(dev);
+
+	i82801dbm_lpc_route_dma(dev, 0xff);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+
+	i82801dbm_1f0_misc(dev);
+	/* Initialize the High Precision Event Timers */
+	enable_hpet(dev);
+}
+
+static void i82801dbm_lpc_read_resources(device_t dev)
+{
+	unsigned int reg;
+
+	/* Get the normal pci resources of this device */
+	pci_dev_read_resources(dev);
+
+	/* Find my place in the resource list */
+	reg = dev->resources;
+
+	/* Add an extra subtractive resource for both memory and I/O */
+	dev->resource[reg].base  = 0;
+	dev->resource[reg].size  = 0;
+	dev->resource[reg].align = 0;
+	dev->resource[reg].gran  = 0;
+	dev->resource[reg].limit = 0;
+	dev->resource[reg].flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+	dev->resource[reg].index = 0;
+	reg++;
+	
+	dev->resource[reg].base  = 0;
+	dev->resource[reg].size  = 0;
+	dev->resource[reg].align = 0;
+	dev->resource[reg].gran  = 0;
+	dev->resource[reg].limit = 0;
+	dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+	dev->resource[reg].index = 0;
+	reg++;
+	
+	dev->resources = reg;
+}
+
+static struct device_operations lpc_ops  = {
+	.read_resources   = i82801dbm_lpc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = lpc_init,
+	.scan_bus         = scan_static_bus,
+	.enable           = i82801dbm_enable,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F0,
+};
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_nic.c b/src/southbridge/intel/i82801dbm/i82801dbm_nic.c
new file mode 100644
index 0000000..5b9c976
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_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 "i82801dbm.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 struct pci_driver nic_driver __pci_driver = {
+	.ops    = &nic_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x1051,
+};
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_pci.c b/src/southbridge/intel/i82801dbm/i82801dbm_pci.c
new file mode 100644
index 0000000..20fb1d2
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_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 "i82801dbm.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 struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1E0,
+};
+
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_reset.c b/src/southbridge/intel/i82801dbm/i82801dbm_reset.c
new file mode 100644
index 0000000..3d7a4b7
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_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/i82801dbm/i82801dbm_sata.c b/src/southbridge/intel/i82801dbm/i82801dbm_sata.c
new file mode 100644
index 0000000..2bc287f
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_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 "i82801dbm.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           = i82801dbm_enable,
+};
+
+static struct pci_driver stat_driver __pci_driver = {
+	.ops    = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F2_R,
+};
+
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_smbus.c b/src/southbridge/intel/i82801dbm/i82801dbm_smbus.c
new file mode 100644
index 0000000..fd06871
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_smbus.c
@@ -0,0 +1,92 @@
+#include <smbus.h>
+#include <pci.h>
+#include <arch/io.h>
+
+#define PM_BUS 0
+#define PM_DEVFN PCI_DEVFN(0x1f,3)
+
+#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
+
+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/i82801dbm/i82801dbm_usb.c b/src/southbridge/intel/i82801dbm/i82801dbm_usb.c
new file mode 100644
index 0000000..b810f59
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_usb.c
@@ -0,0 +1,54 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dbm.h"
+
+static void usb_init(struct device *dev)
+{
+	uint32_t cmd;
+
+#if 0
+	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           = i82801dbm_enable,
+};
+
+static struct pci_driver usb_driver_1 __pci_driver = {
+	.ops    = &usb_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1D0,
+};
+static struct pci_driver usb_driver_2 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_82801ER_1D1,
+};
+static struct pci_driver usb_driver_3 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_82801ER_1D2,
+};
+static struct pci_driver usb_driver_4 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_82801ER_1D3,
+};
+
diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_usb2.c b/src/southbridge/intel/i82801dbm/i82801dbm_usb2.c
new file mode 100644
index 0000000..5b7465d
--- /dev/null
+++ b/src/southbridge/intel/i82801dbm/i82801dbm_usb2.c
@@ -0,0 +1,39 @@
+//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 "i82801dbm.h"
+
+static void usb2_init(struct device *dev)
+{
+	uint32_t cmd;
+
+#if 0
+	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           = i82801dbm_enable,
+};
+
+static struct pci_driver usb2_driver __pci_driver = {
+	.ops    = &usb2_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1D7,
+};