See patch. I'm still waiting on a response from Steve just to confirm
GPLv2 on a couple files, and I'd like Yinghai to make sure those details
are correct as well (ie were you working for Tyan at the time, and is
that the right email address to use?). Other than that, it's as done as
I'm getting it. BTW, i810 will be on its way again soon, I'm trying to
get vga working first.

-Corey
This patch merges the code for the i82801ca, db, and dbm, and some parts of the i82801er (but removes no code). The i82801er uses some very different code in some places, so I'm not 100% positive that this will work the same as the old code did, the only way to really find out is try. The others all should work, but I have no hardware whatsoever, so I'll let others test. This also supports the i82801aa, which is confirmed working, and also ab, ba, and eb.

Signed-off-by: Corey Osgood <[EMAIL PROTECTED]>

Index: src/southbridge/intel/i82801xx/i82801xx_ac97.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_ac97.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_ac97.c	(revision 0)
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+#include "i82801_model_specific.h"
+
+#ifdef I82801_AC97
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	/* Write the subsystem vendor and device id */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = ac97_set_subsystem,
+};
+static struct device_operations ac97_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = 0,
+	.enable           = i82801xx_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ac97_audio_driver __pci_driver = {
+	.ops    = &ac97_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_AC97,
+};
+
+static struct pci_driver ac97_modem_driver __pci_driver = {
+	.ops    = &ac97_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_MC97,
+};
+#endif
Index: src/southbridge/intel/i82801xx/i82801xx_nic.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_nic.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_nic.c	(revision 0)
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#ifdef I82801_NIC
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801_model_specific.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 = I82801_NIC,
+};
+#endif
Index: src/southbridge/intel/i82801xx/i82801xx_pci.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_pci.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_pci.c	(revision 0)
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801_model_specific.h"
+
+static void pci_init(struct device *dev)
+{
+	uint32_t dword;
+	uint16_t word;
+
+	/* Clear system errors */
+	word = pci_read_config16(dev, 0x06);
+	word |= 0xf900; /* Clear possible errors */
+	pci_write_config16(dev, 0x06, word);
+
+	/* i82801er has this commented out, wonder why? */
+	/* 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);
+	
+	word = pci_read_config16(dev, 0x1e);
+	word |= 0xf800; /* Clear possible errors */
+	pci_write_config16(dev, 0x1e, word);
+}
+
+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 = I82801_PCI,
+};
+
Index: src/southbridge/intel/i82801xx/i82801xx_lpc.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_lpc.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_lpc.c	(revision 0)
@@ -0,0 +1,246 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2003 Linux Networx, SuSE Linux AG
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+ 
+/* from i82801dbm, needs to be fixed to support everything the i82801er does */
+
+#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 "i82801xx.h"
+#include "i82801_model_specific.h"
+
+#define NMI_OFF 0
+
+void i82801xx_enable_ioapic( struct device *dev) 
+{
+	uint32_t dword;
+	volatile uint32_t *ioapic_index = (volatile uint32_t *)0xfec00000;
+	volatile uint32_t *ioapic_data = (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); /* Delayed transaction enable */
+	dword |= (1 << 2); /* DMA collection buffer enable */
+	pci_write_config32(dev, GEN_CNTL, dword);
+	printk_debug("IOAPIC Southbridge enabled %x\n",dword);
+
+	*ioapic_index = 0;
+	*ioapic_data = (1 << 25);
+
+	*ioapic_index = 0;
+	dword = *ioapic_data;
+	printk_debug("Southbridge APIC ID = %x\n",dword);
+	if(dword != (1 << 25))
+		die("APIC Error\n");
+
+	/* TODO: From i82801ca, needed/useful on other ICH? */
+	*ioapic_index = 3;	// Select Boot Configuration register
+	*ioapic_data = 1;	// Use Processor System Bus to deliver interrupts
+}
+
+void i82801xx_enable_serial_irqs( struct device *dev)
+{
+	/* set packet length and toggle silent mode bit */
+	pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+	pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+	/* TODO: Get rid of the nasty ugly confusing bit ^^^ */
+}
+
+void i82801xx_lpc_route_dma( struct device *dev, uint8_t mask) 
+{
+        uint16_t word;
+        int i;
+        word = pci_read_config16(dev, PCI_DMA_CFG);
+        word &= 0x300;
+        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 i82801xx_rtc_init(struct device *dev)
+{//todo:needs serious improvements
+        uint8_t byte;
+        uint32_t dword;
+        int rtc_failed;
+        byte = pci_read_config8(dev, GEN_PMCON_3);
+        rtc_failed = byte & RTC_BATTERY_DEAD;
+        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 i82801xx_1f0_misc(struct device *dev)
+{
+	/* Prevent LPC disabling, enable parity errors, and SERR# (System Error) */
+	pci_write_config16(dev, PCI_COMMAND, 0x014f);
+	/* Set ACPI base address to 0x1100 (I/O space) */
+	pci_write_config32(dev, PMBASE, PM_BASE_ADDR | 1);
+	/* Enable ACPI I/O and power management */
+	pci_write_config8(dev, ACPI_CNTL, 0x10);
+	/* Set GPIO base address to 0x1180 (I/O space) */
+	pci_write_config32(dev, GPIO_BASE, GPIO_BASE_ADDR | 1);
+	/* Enable GPIO */
+	pci_write_config8(dev, GPIO_CNTL, 0x10);
+	/* Route PIRQA to IRQ11, PIRQB to IRQ3, PIRQC to IRQ5, PIRQD to IRQ10 */
+	pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B);
+	/* Route PIRQE to IRQ7. Leave PIRQF - PIRQH unrouted */
+	pci_write_config8(dev, PIRQE_ROUT, 0x07);
+	/* Enable access to the upper 128 byte bank of CMOS RAM */
+	pci_write_config8(dev, RTC_CONF, 0x04);
+	/* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB */
+	pci_write_config8(dev, COM_DEC, 0x10);
+	/* LPT decode defaults to 0x378-0x37F and 0x778-0x77F
+	 * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7 */
+	/* Enable: COMA, COMB, LPT, Floppy
+	 * Disable: Microcontroller, Super I/O, Sound, Gameport */
+	pci_write_config16(dev, LPC_EN, 0x000F);
+}
+
+static void enable_hpet(struct device *dev)
+{
+#ifdef HPET_PRESENT
+        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_ADDR | (code << 12));
+#endif
+}
+
+
+static void lpc_init(struct device *dev)
+{
+	uint8_t byte;
+	int pwr_on = -1;
+	int nmi_option;
+
+	/* IO APIC initialization */
+	i82801xx_enable_ioapic(dev);
+
+	i82801xx_enable_serial_irqs(dev);
+
+	/* TODO: Find out if this is being used/works */
+#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 if power fails\n", pwr_on?"on":"off");
+
+	/* 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 */
+	i82801xx_rtc_init(dev);
+
+	i82801xx_lpc_route_dma(dev, 0xff);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+
+	i82801xx_1f0_misc(dev);
+	/* Initialize the High Precision Event Timers, if present */
+	enable_hpet(dev);
+}
+
+static void i82801xx_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->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void i82801xx_lpc_enable_resources(device_t dev)
+{
+	pci_dev_enable_resources(dev);
+	enable_childrens_resources(dev);
+}
+
+static struct device_operations lpc_ops  = {
+	.read_resources   = i82801xx_lpc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = i82801xx_lpc_enable_resources,
+	.init             = lpc_init,
+	.scan_bus         = scan_static_bus,
+	.enable           = i82801xx_enable,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_LPC,
+};
Index: src/southbridge/intel/i82801xx/i82801xx.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx.c	(revision 0)
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ * Copyright (C) 2005 Digital Design Corporation
+ * (Written by Steven J. Magnani <[EMAIL PROTECTED]> for Digital Design Corp)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+
+void i82801xx_enable(device_t dev)
+{
+	unsigned int index = 0;
+	uint8_t bHasDisableBit = 0;
+	uint16_t cur_disable_mask, new_disable_mask;
+
+	// All 82801 devices should be on 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 any ICH, only the following devices can be disabled:
+	 *		 D31: F0, F1, F2 (ICH-ICH2), F3, F4 (ICH2), F5, F6, 
+	 *		 D29 (ICH3+): F0, F1, F2, F7, F13 */
+
+	/* TODO: this shouldn't be necessary. If the device can't be disabled, the
+	bit should be read-only, so attempting to set it should do nothing */
+	
+	if (PCI_SLOT(dev->path.u.pci.devfn) == 31) {
+    		index = PCI_FUNC(dev->path.u.pci.devfn);
+		switch (index) {
+			case 0:
+			case 1:
+/* i82801aa/ab/ba doesn't have a D29, USB is D31F2 */
+#if I82801_MODEL < I82801CA
+			case 2:
+#endif
+			case 3:
+/* i82801ba/bam has a second USB device at D31f4, not doing bam for now */
+#if I82801_MODEL == I82801BA
+			case 4:
+#endif
+			case 5:
+			case 6:
+				bHasDisableBit = 1;
+				break;
+			default:
+				break;
+		};
+		if (index == 0)
+			index = 14;		// D31:F0 bit is an exception
+	} 
+#if I82801_MODEL >= I82801CA
+	else if (PCI_SLOT(dev->path.u.pci.devfn) == 29) {
+		index = 8 + PCI_FUNC(dev->path.u.pci.devfn);
+		/* All D29 functions can be disabled and have disable bits */
+		bHasDisableBit = 1;
+	}
+#endif
+	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_i82801xx_ops = {
+	CHIP_NAME("Intel i82801 Series Southbridge")
+	.enable_dev = i82801xx_enable,
+};
Index: src/southbridge/intel/i82801xx/i82801xx_usb_ehci.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_usb_ehci.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_usb_ehci.c	(revision 0)
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+#include "i82801_model_specific.h"
+#ifdef I82801_USB_EHCI
+
+static void usb_ehci_init(struct device *dev)
+{
+	/* TODO: Is any special init really needed? */
+	uint32_t cmd;
+
+	printk_debug("EHCI: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_MASTER);
+
+	printk_debug("done.\n");
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	uint8_t access_cntl;
+	access_cntl = pci_read_config8(dev, 0x80);
+	/* Enable writes to protected registers */
+	pci_write_config8(dev, 0x80, access_cntl | 1);
+	/* Write the subsystem vendor and device id */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+	/* Restore protection */
+	pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = &usb_ehci_set_subsystem,
+};
+
+static struct device_operations usb_ehci_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = usb_ehci_init,
+	.scan_bus         = 0,
+	.enable           = i82801xx_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver usb_ehci_driver __pci_driver = {
+	.ops    = &usb_ehci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_USB_EHCI,
+};
+#endif
Index: src/southbridge/intel/i82801xx/i82801xx_reset.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_reset.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_reset.c	(revision 0)
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2002 Eric Biederman <[EMAIL PROTECTED]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <arch/io.h>
+
+void hard_reset(void)
+{
+        /* Try rebooting through port 0xcf9 */
+        outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
Index: src/southbridge/intel/i82801xx/Config.lb
===================================================================
--- src/southbridge/intel/i82801xx/Config.lb	(revision 0)
+++ src/southbridge/intel/i82801xx/Config.lb	(revision 0)
@@ -0,0 +1,30 @@
+##
+## This file is part of the LinuxBIOS project.
+##
+## Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+##
+## 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; either version 2 of the License, or
+## (at your option) any later version.
+##
+## 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
+##
+driver i82801xx.o
+driver i82801xx_usb.o
+driver i82801xx_lpc.o
+driver i82801xx_ide.o
+driver i82801xx_usb_ehci.o
+driver i82801xx_ac97.o
+driver i82801xx_nic.o
+driver i82801xx_pci.o
+driver i82801xx_sata.o
+object i82801xx_reset.o
+object i82801xx_watchdog.o
Index: src/southbridge/intel/i82801xx/i82801xx_early_smbus.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_early_smbus.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_early_smbus.c	(revision 0)
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <device/pci_ids.h>
+#include "i82801_model_specific.h"
+#include "i82801xx.h"
+#include "i82801xx_smbus.h"
+
+static void enable_smbus(void)
+{
+	device_t dev;
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, I82801_SMBUS), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("SMBUS controller not found\r\n"
+		"You've probably selected the wrong i82801 model\r\n");
+	}
+	
+	/* Set SMBus I/O base */
+	pci_write_config32(dev, SMB_BASE, SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+	/* Set SMBus enable */
+	pci_write_config8(dev, HOSTC, HST_EN);
+	/* Set SMBus I/O space enable */ 
+	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+	/* Disable interrupt generation */ 
+	outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+	/* Clear any lingering errors, so transactions can run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+	print_debug("SMBus controller enabled\r\n");
+}
+
+static inline int smbus_read_byte(unsigned device, unsigned address)
+{
+	return do_smbus_read_byte(device, address);
+}
+
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+	print_err("Unimplemented smbus_write_byte() called\r\n");
+	return;
+}
+
+static inline int smbus_write_block(unsigned device, unsigned length, unsigned cmd, 
+		 unsigned data1, unsigned data2)
+{
+	return do_smbus_write_block(device, length, cmd, data1, data2);
+}
Index: src/southbridge/intel/i82801xx/i82801xx.h
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx.h	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx.h	(revision 0)
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+/* Copyright holder left out intentionally, I don't believe there's anything 
+really copyrightable in here */
+
+#ifndef I82801XX_H
+#define I82801XX_H
+
+#ifndef __ROMCC__
+#include "chip.h"
+extern void i82801xx_enable(device_t dev);
+#endif
+
+#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 PM_BASE_ADDR    0x1100
+#define ACPI_CNTL       0x44
+#define BIOS_CNTL       0x4E
+#define GPIO_BASE       0x58
+#define GPIO_BASE_ADDR  0x1180
+#define GPIO_CNTL       0x5C
+#define PIRQA_ROUT      0x60
+#define PIRQE_ROUT      0x68
+#define COM_DEC         0xE0
+#define LPC_EN          0xE6
+#define FUNC_DIS        0xF2
+
+#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
+
+// GEN_PMCON_3 bits
+#define RTC_BATTERY_DEAD	(1 << 2)
+#define RTC_POWER_FAILED	(1 << 1)
+#define SLEEP_AFTER_POWER_FAIL	(1 << 0)
+
+// PCI Configuration Space (D31:F1)
+#define IDE_TIM_PRI		0x40	// IDE timings, primary
+#define IDE_TIM_SEC		0x42	// IDE timings, secondary
+
+// IDE_TIM bits
+#define IDE_DECODE_ENABLE	(1 << 15)
+
+// PCI Configuration Space (D31:F3)
+#define SMB_BASE	0x20
+#define HOSTC		0x40
+
+// HOSTC bits
+#define I2C_EN		(1 << 2)
+#define SMB_SMI_EN	(1 << 1)
+#define HST_EN		(1 << 0)
+
+// SMBus IO bits
+/* TODO: Does it matter where we put the SMBus IO base, as long as we keep 
+ * consistent and don't interfere with anything else? Either value works on aa*/
+//#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 
+
+#define SMBUS_TIMEOUT	(10 * 1000 * 100)
+
+//HPET, if present
+#define HPET_ADDR		0xfed0000
+
+#endif /* I82801XX_H */
Index: src/southbridge/intel/i82801xx/i82801xx_sata.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_sata.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_sata.c	(revision 0)
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+#include "i82801_model_specific.h"
+
+#ifdef I82801_SATA
+
+/* TODO: set dynamically, if the user only wants one sata channel or none at all */
+
+static void sata_init(struct device *dev)
+{
+	/* SATA configuration */
+	pci_write_config8(dev, 0x04, 0x07);
+	pci_write_config8(dev, 0x09, 0x8f);
+	
+	/* Set timmings */
+	pci_write_config16(dev, 0x40, 0x0a307);
+	pci_write_config16(dev, 0x42, 0x0a307);
+
+	/* Sync DMA */
+	pci_write_config16(dev, 0x48, 0x000f);
+	pci_write_config16(dev, 0x4a, 0x1111);
+
+	/* 66 mhz */
+	pci_write_config16(dev, 0x54, 0xf00f);
+
+	/* Combine ide - sata configuration */
+	pci_write_config8(dev, 0x90, 0x0);
+	
+	/* port 0 & 1 enable */
+	pci_write_config8(dev, 0x92, 0x33);
+	
+	/* initialize SATA  */
+	pci_write_config16(dev, 0xa0, 0x0018);
+	pci_write_config32(dev, 0xa4, 0x00000264);
+	pci_write_config16(dev, 0xa0, 0x0040);
+	pci_write_config32(dev, 0xa4, 0x00220043);
+}
+
+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           = i82801xx_enable,
+};
+
+static struct pci_driver sata_driver __pci_driver = {
+	.ops    = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_SATA,
+};
+
+/* Assuming this is for a second sata device... */
+#ifdef I82801_SATA_2
+static struct pci_driver sata_driver_nr __pci_driver = {
+	.ops    = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_SATA_2,
+};
+#endif
+#endif
Index: src/southbridge/intel/i82801xx/i82801xx_smbus.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_smbus.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_smbus.c	(revision 0)
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <smbus.h>
+#include <pci.h>
+#include <arch/io.h>
+#include "i82801_model_specific.h"
+#include "i82801xx.h"
+#include "i82801_smbus.h"
+
+static int smbus_read_byte(struct bus *bus, device_t dev, uint8_t address)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(bus->dev, 0x20);
+	
+	return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+	.read_byte  = smbus_read_byte,
+};
+
+static struct device_operations smbus_ops = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = scan_static_bus,
+	.enable           = i82801er_enable,
+	.ops_smbus_bus    = &lops_smbus_bus,
+};
+
+static struct pci_driver smbus_driver __pci_driver = {
+	.ops    = &smbus_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_SMBUS,
+};
+
Index: src/southbridge/intel/i82801xx/i82801xx_usb.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_usb.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_usb.c	(revision 0)
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+#include "i82801_model_specific.h"
+
+static void usb_init(struct device *dev)
+{
+/* TODO: Any init needed? Some ports have it, others don't */
+}
+
+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           = i82801xx_enable,
+};
+
+static struct pci_driver usb_driver_1 __pci_driver = {
+	.ops    = &usb_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_USB1,
+};
+
+#ifdef I82801_USB2
+static struct pci_driver usb_driver_2 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = I82801_USB2,
+};
+#endif
+
+#ifdef I82801_USB3
+static struct pci_driver usb_driver_3 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = I82801_USB3,
+};
+#endif
+
+#ifdef I82801_USB4
+static struct pci_driver usb_driver_4 __pci_driver = {
+        .ops    = &usb_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = I82801_USB4,
+};
+#endif
Index: src/southbridge/intel/i82801xx/i82801_model_specific.h
===================================================================
--- src/southbridge/intel/i82801xx/i82801_model_specific.h	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801_model_specific.h	(revision 0)
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* This file's purpose is to define anything that may differ between different 
+ * models within the i82801 series */
+
+#if	I82801_MODEL == I82801AA
+#define	I82801_PCI	0x2418	/* D30:F0, PCI Interface Hub */
+#define	I82801_LPC	0x2410	/* D31:F0, LPC Interface Bridge */
+#define	I82801_IDE	0x2411	/* D31:F1, IDE Controller */
+#define	I82801_USB1	0x2412	/* D31:F2, USB Controller */
+#define	I82801_SMBUS	0x2413	/* D31:F3, SMBUS Controller */
+#define	I82801_AC97	0x2415	/* D31:F5, AC'97 Audio Controller */
+#define	I82801_MC97	0x2416	/* D31:F6, AC'97 Modem Controller */
+
+#elif	I82801_MODEL == I82801AB
+#define	I82801_PCI	0x2428
+#define	I82801_LPC	0x2420
+#define	I82801_IDE	0x2421
+#define	I82801_USB1	0x2422
+#define	I82801_SMBUS	0x2423
+#define	I82801_AC97	0x2425
+#define	I82801_MC97	0x2426
+
+#elif	I82801_MODEL == I82801BA
+#define	I82801_PCI	0x244e
+#define	I82801_LPC	0x2440
+#define	I82801_IDE	0x244b
+#define	I82801_USB1	0x2442	/* D29:F0 */
+#define	I82801_USB2	0x2444	/* D29:F1 */
+#define	I82801_SMBUS	0x2443
+#define	I82801_AC97	0x2445
+#define	I82801_MC97	0x2446
+
+#elif	I82801_MODEL == I82801CA
+#define	I82801_PCI	0x244e
+#define	I82801_LPC	0x2480
+#define	I82801_IDE	0x248b
+#define	I82801_USB1	0x2482	/* D29:F0 */
+#define	I82801_USB2	0x2484	/* D29:F1 */
+#define	I82801_USB3	0x2487	/* D29:F2 */
+#define	I82801_SMBUS	0x2483
+#define	I82801_AC97	0x2485
+#define	I82801_MC97	0x2486
+
+#elif 	I82801_MODEL == I82801DB
+#define	I82801_PCI	0x244e
+#define	I82801_LPC	0x24c0
+#define	I82801_IDE	0x24cb
+#define	I82801_USB1	0x24c2
+#define	I82801_USB2	0x24c4
+#define	I82801_USB3	0x24c7
+#define	I82801_USB_EHCI	0x24cd
+#define	I82801_SMBUS	0x24c3
+#define	I82801_AC97	0x24c5
+#define	I82801_MC97	0x24c6
+
+#elif 	I82801_MODEL == I82801DBM
+#define	I82801_PCI	0x2448
+#define	I82801_LPC	0x24cc
+#define	I82801_IDE	0x24ca
+#define	I82801_USB1	0x24c2
+#define	I82801_USB2	0x24c4
+#define	I82801_USB3	0x24c7
+#define	I82801_USB_EHCI	0x24cd
+#define	I82801_SMBUS	0x24c3
+#define	I82801_AC97	0x24c5
+#define	I82801_MC97	0x24c6
+#define	I82801_NIC	0x103a
+
+#elif 	I82801_MODEL == I82801EB
+#warning "I82801EB support is experimental"
+#define	I82801_PCI	0x244e
+#define	I82801_LPC	0x24d0
+#define	I82801_IDE	0x24db
+#define	I82801_SATA	0x24d1
+#define	I82801_USB1	0x24d2
+#define	I82801_USB2	0x24d4
+#define	I82801_USB3	0x24d7
+#define	I82801_USB4	0x24de
+#define	I82801_USB_EHCI	0x24dd
+#define	I82801_SMBUS	0x24d3
+#define	I82801_AC97	0x24d5
+#define	I82801_MC97	0x24d6
+#define	I82801_NIC	0x1051
+
+#elif 	I82801_MODEL == I82801ER
+#warning "I82801ER support is experimental"
+#define	I82801_PCI	0x244e
+#define	I82801_LPC	0x24d0
+#define	I82801_IDE	0x24db
+#define	I82801_SATA	0x24df
+#define	I82801_USB1	0x24d2
+#define	I82801_USB2	0x24d4
+#define	I82801_USB3	0x24d7
+#define	I82801_USB4	0x24de
+#define	I82801_USB_EHCI	0x24dd
+#define	I82801_SMBUS	0x24d3
+#define	I82801_AC97	0x24d5
+#define	I82801_MC97	0x24d6
+#define	I82801_NIC	0x1051
+#else
+
+#error	"Unknown i82801 model passed"
+#endif
+
+#ifndef	I82801_MODEL
+#error	"Please define an i82801 model in Options.lb, \n"
+	"In the form of I82801_MODEL = I82801XX"
+#endif
Index: src/southbridge/intel/i82801xx/cmos_failover.c
===================================================================
--- src/southbridge/intel/i82801xx/cmos_failover.c	(revision 0)
+++ src/southbridge/intel/i82801xx/cmos_failover.c	(revision 0)
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+
+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);
+	}
+}
Index: src/southbridge/intel/i82801xx/chip.h
===================================================================
--- src/southbridge/intel/i82801xx/chip.h	(revision 0)
+++ src/southbridge/intel/i82801xx/chip.h	(revision 0)
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 I82801XX_CHIP_H
+#define I82801XX_CHIP_H
+
+struct southbridge_intel_i82801xx_config 
+{
+};
+
+extern struct chip_operations southbridge_intel_i82801xx_ops;
+
+#endif /* I82801XX_CHIP_H */
Index: src/southbridge/intel/i82801xx/i82801xx_smbus.h
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_smbus.h	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_smbus.h	(revision 0)
@@ -0,0 +1,176 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+
+static void smbus_delay(void)
+{
+	inb(0x80);
+}
+
+static int smbus_wait_until_ready(void)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+		smbus_delay();
+		if (--loops == 0)
+			break;
+		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	} while(byte & 1);
+	return loops?0:-1;
+}
+
+static int smbus_wait_until_done(void)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+	        smbus_delay();
+	        if (--loops == 0)
+	               break;
+	        byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	} while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
+	return loops?0:-1;
+}
+
+static int smbus_wait_until_blk_done(void)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+	        smbus_delay();
+	        if (--loops == 0)
+	               break;
+	        byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	} while((byte & (1 << 7)) == 0);
+	return loops?0:-1;
+}
+
+static int do_smbus_read_byte(unsigned device, unsigned address)
+{
+	unsigned char global_status_register;
+	unsigned char byte;
+
+	if (smbus_wait_until_ready() < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+	/* 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 + 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 the command */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done() < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+
+	global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* Ignore the In Use Status... */
+	global_status_register &= ~(3 << 5);
+
+	/* read results of transaction */
+	byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+	if (global_status_register != (1 << 1)) {
+		return SMBUS_ERROR;
+	}
+	return byte;
+}
+
+static int do_smbus_write_block(unsigned device, unsigned length, unsigned cmd, 
+		 unsigned data1, unsigned data2)
+{
+	unsigned char global_control_register;
+	unsigned char global_status_register;
+	unsigned char byte;
+	unsigned char stat;
+	int i;
+
+	/* Clear the PM timeout flags, SECOND_TO_STS */
+	outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
+	
+	if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+		return -2;
+	}
+	
+	/* Setup transaction */
+	/* Obtain ownership */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+	for(stat = 0; (stat & 0x40) == 0; ) {
+	stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+	/* Clear the done bit */
+	outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
+	/* Disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+	
+	/* Set the device I'm talking too */
+	outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
+	
+	/* Set the command address */
+	outb(cmd & 0xff, SMBUS_IO_BASE + SMBHSTCMD);
+	
+	/* Set the block length */
+	outb(length & 0xff, SMBUS_IO_BASE + SMBHSTDAT0);
+	
+	/* Try sending out the first byte of data here */
+	byte = (data1 >> (0)) & 0x0ff;
+	outb(byte, SMBUS_IO_BASE + SMBBLKDAT);
+	/* Issue a block write command */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x5 << 2) | 0x40, 
+			SMBUS_IO_BASE + SMBHSTCTL);
+
+	for(i = 0;i < length; i++) {
+		
+		/* Poll for transaction completion */
+		if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
+			return -3;
+		}
+		
+		/* Load the next byte */
+		if(i > 3)
+			byte = (data2 >> (i % 4)) & 0x0ff;
+		else
+			byte = (data1 >> (i)) & 0x0ff;
+		outb(byte, SMBUS_IO_BASE + SMBBLKDAT);
+		
+		/* Clear the done bit */
+		outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), 
+				SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+
+	print_debug("SMBUS Block complete\r\n");
+	return 0;
+}
Index: src/southbridge/intel/i82801xx/i82801xx_ide.c
===================================================================
--- src/southbridge/intel/i82801xx/i82801xx_ide.c	(revision 0)
+++ src/southbridge/intel/i82801xx/i82801xx_ide.c	(revision 0)
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan Computer)
+ * Copyright (C) 2005 Digital Design Corporation
+ * (Written by Steven J. Magnani <[EMAIL PROTECTED]> for Digital Design Corp)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "i82801xx.h"
+#include "i82801_model_specific.h"
+
+static void ide_init(struct device *dev)
+{
+	/* TODO: Needs to be tested for compatibility with ICH5(R) */
+	/* Enable ide devices so the linux ide driver will work */
+	uint16_t ideTimingConfig;
+	int enable_primary = 1;
+	int enable_secondary = 1;
+
+	ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
+	ideTimingConfig &= ~IDE_DECODE_ENABLE;
+	if (enable_primary) {
+		/* Enable primary ide interface */
+		ideTimingConfig |= IDE_DECODE_ENABLE;
+		printk_debug("IDE0 ");
+	}
+	pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
+
+	ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
+	ideTimingConfig &= ~IDE_DECODE_ENABLE;
+	if (enable_secondary) {
+		/* Enable secondary ide interface */
+		ideTimingConfig |= IDE_DECODE_ENABLE;
+		printk_debug("IDE1 ");
+	}
+	pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
+}
+
+static void ide_set_subsystem_ids(device_t dev, unsigned vendor, unsigned device)
+{
+	/* This value is also visible in usb, usb_ehci and smbus functions */
+	/* TODO: Is this ID protected like the ehci one is? */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = ide_set_subsystem_ids,
+};
+
+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           = i82801xx_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+	.ops    = &ide_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = I82801_IDE,
+};
-- 
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to