ICH7 updates.
Intel ICH7 updates
- code restructuring (move ich7 out of i945)
- ACPI fixes 
- major SMI handler updates
- make sure SMBus lives where we expect it
- try to get usb debug working 


Index: src/southbridge/intel/i82801gx/i82801gx.h
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx.h	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx.h	(working copy)
@@ -21,9 +21,16 @@
 #ifndef SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H
 #define SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H
 
+/* __ROMCC__ is set by auto.c to make sure
+ * none of the stage2 data structures are included.
+ */
+#ifndef __ROMCC__
 #include "chip.h"
 extern void i82801gx_enable(device_t dev);
+#endif
 
+/* PCI Configuration Space (D31:F0): LPC */
+
 #define SERIRQ_CNTL		0x64
 
 #define GEN_PMCON_1		0xa0
@@ -58,7 +65,31 @@
 #define IDE_TIM_PRI		0x40	/* IDE timings, primary */
 #define   IDE_DECODE_ENABLE	(1 << 15)
 #define   IDE_SITRE		(1 << 14)
+#define   IDE_ISP_5_CLOCKS	(0 << 12)
+#define   IDE_ISP_4_CLOCKS	(1 << 12)
+#define   IDE_ISP_3_CLOCKS	(2 << 12)
+#define   IDE_RCT_4_CLOCKS	(0 <<  8)
+#define   IDE_RCT_3_CLOCKS	(1 <<  8)
+#define   IDE_RCT_2_CLOCKS	(2 <<  8)
+#define   IDE_RCT_1_CLOCKS	(3 <<  8)
+#define   IDE_DTE1		(1 <<  7)
+#define   IDE_PPE1		(1 <<  6)
+#define   IDE_IE1		(1 <<  5)
+#define   IDE_TIME1		(1 <<  4)
+#define   IDE_DTE0		(1 <<  3)
+#define   IDE_PPE0		(1 <<  2)
+#define   IDE_IE0		(1 <<  1)
+#define   IDE_TIME0		(1 <<  0)
 #define IDE_TIM_SEC		0x42	/* IDE timings, secondary */
+
+#define IDE_SDMA_CNT		0x48	/* Synchronous DMA control */
+#define   IDE_SSDE1		(1 <<  3)
+#define   IDE_SSDE0		(1 <<  2)
+#define   IDE_PSDE1		(1 <<  1)
+#define   IDE_PSDE0		(1 <<  0)
+
+#define IDE_SDMA_TIM		0x4a
+
 #define IDE_CONFIG		0x54	/* IDE I/O Configuration Register */
 #define   SIG_MODE_NORMAL	(0 << 16)
 #define   SIG_MODE_TRISTATE	(1 << 16)
@@ -78,12 +109,13 @@
 #define HST_EN			(1 << 0)
 
 /* SMBus I/O bits.
- * TODO: It does not matter where we put the SMBus IO base, as long as we keep
- * consistent and don't interfere with other devices. Stage2 will relocate 
- * this anyways. But it's a general problem we have not solved in the brightest
- * possible way.
+ * It does not matter where we put the SMBus I/O base, as long as we 
+ * keep it consistent and don't interfere with other devices.  Stage2
+ * will relocate this anyways.
+ * Our solution is to have SMB initialization move the I/O to SMBUS_IO_BASE
+ * again. But handling static BARs is a generic problem that should be 
+ * solved in the device allocator.
  */
-/* #define SMBUS_IO_BASE 0x1000 */
 #define SMBUS_IO_BASE		0x0400
 
 #define SMBHSTSTAT		0x0
@@ -103,4 +135,124 @@
 /* HPET, if present */
 #define HPET_ADDR		0xfed0000
 
+/* Southbridge IO BARs */
+
+/* TODO Make sure these don't get changed by stage2 */
+#define GPIOBASE		0x48
+#define DEFAULT_GPIOBASE	0x480
+
+#define PMBASE		0x40
+#define DEFAULT_PMBASE	0x500
+
+/* Root Complex Register Block */
+#define RCBA		0xf0
+#define DEFAULT_RCBA		0xfed1c000
+
+#define RCBA8(x) *((volatile u8 *)(DEFAULT_RCBA + x))
+#define RCBA16(x) *((volatile u16 *)(DEFAULT_RCBA + x))
+#define RCBA32(x) *((volatile u32 *)(DEFAULT_RCBA + x))
+
+#define VCH		0x0000	/* 32bit */
+#define VCAP1		0x0004	/* 32bit */
+#define VCAP2		0x0008	/* 32bit */
+#define PVC		0x000c	/* 16bit */
+#define PVS		0x000e	/* 16bit */
+
+#define V0CAP		0x0010	/* 32bit */
+#define V0CTL		0x0014	/* 32bit */
+#define V0STS		0x001a	/* 16bit */
+
+#define V1CAP		0x001c	/* 32bit */
+#define V1CTL		0x0020	/* 32bit */
+#define V1STS		0x0026	/* 16bit */
+
+#define RCTCL		0x0100	/* 32bit */
+#define ESD		0x0104	/* 32bit */
+#define ULD		0x0110	/* 32bit */
+#define ULBA		0x0118	/* 64bit */
+
+#define RP1D		0x0120	/* 32bit */
+#define RP1BA		0x0128	/* 64bit */
+#define RP2D		0x0130	/* 32bit */
+#define RP2BA		0x0138	/* 64bit */
+#define RP3D		0x0140	/* 32bit */
+#define RP3BA		0x0148	/* 64bit */
+#define RP4D		0x0150	/* 32bit */
+#define RP4BA		0x0158	/* 64bit */
+#define HDD		0x0160	/* 32bit */
+#define HDBA		0x0168	/* 64bit */
+#define RP5D		0x0170	/* 32bit */
+#define RP5BA		0x0178	/* 64bit */
+#define RP6D		0x0180	/* 32bit */
+#define RP6BA		0x0188	/* 64bit */
+
+#define ILCL		0x01a0	/* 32bit */
+#define LCAP		0x01a4	/* 32bit */
+#define LCTL		0x01a8	/* 16bit */
+#define LSTS		0x01aa	/* 16bit */
+
+#define RPC		0x0224	/* 32bit */
+#define RPFN		0x0238	/* 32bit */
+
+#define TRSR		0x1e00	/*  8bit */
+#define TRCR		0x1e10	/* 64bit */
+#define TWDR		0x1e18	/* 64bit */
+
+#define IOTR0		0x1e80	/* 64bit */
+#define IOTR1		0x1e88	/* 64bit */
+#define IOTR2		0x1e90	/* 64bit */
+#define IOTR3		0x1e98	/* 64bit */
+
+#define TCTL		0x3000	/*  8bit */
+
+#define D31IP		0x3100	/* 32bit */
+#define D30IP		0x3104	/* 32bit */
+#define D29IP		0x3108	/* 32bit */
+#define D28IP		0x310c	/* 32bit */
+#define D27IP		0x3110	/* 32bit */
+#define D31IR		0x3140	/* 16bit */
+#define D30IR		0x3142	/* 16bit */
+#define D29IR		0x3144	/* 16bit */
+#define D28IR		0x3146	/* 16bit */
+#define D27IR		0x3148	/* 16bit */
+#define OIC		0x31ff	/*  8bit */
+
+#define RC		0x3400	/* 32bit */
+#define HPTC		0x3404	/* 32bit */
+#define GCS		0x3410	/* 32bit */
+#define BUC		0x3414	/* 32bit */
+#define FD		0x3418	/* 32bit */
+#define CG		0x341c	/* 32bit */
+
+/* Function Disable (FD) register values.
+ * Setting a bit disables the corresponding
+ * feature.
+ * Not all features might be disabled on
+ * all chipsets. Esp. ICH-7U is picky.
+ */
+#define FD_PCIE6	(1 << 21)
+#define FD_PCIE5	(1 << 20)
+#define FD_PCIE4	(1 << 19)
+#define FD_PCIE3	(1 << 18)
+#define FD_PCIE2	(1 << 17)
+#define FD_PCIE1	(1 << 16)
+#define FD_EHCI		(1 << 15)
+#define FD_LPCB		(1 << 14)
+
+/* UHCI must be disabled from 4 downwards.
+ * If UHCI controllers get disabled, EHCI
+ * must know about it, too! */
+#define FD_UHCI4	(1 << 11)
+#define FD_UHCI34	(1 << 10) | FD_UHCI4
+#define FD_UHCI234	(1 <<  9) | FD_UHCI3
+#define FD_UHCI1234	(1 <<  8) | FD_UHCI2
+
+#define FD_INTLAN	(1 <<  7)
+#define FD_ACMOD	(1 <<  6)
+#define FD_ACAUD	(1 <<  5)
+#define FD_HDAUD	(1 <<  4)
+#define FD_SMBUS	(1 <<  3)
+#define FD_SATA		(1 <<  2)
+#define FD_PATA		(1 <<  1)
+
 #endif				/* SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H */
Index: src/southbridge/intel/i82801gx/i82801gx_smihandler.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_smihandler.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_smihandler.c	(working copy)
@@ -19,22 +19,24 @@
  * MA 02110-1301 USA
  */
 
+#include <types.h>
 #include <arch/io.h>
 #include <arch/romcc_io.h>
 #include <console/console.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/smm.h>
-//#include "chip.h"
+#include "i82801gx.h"
+#include "i82801gx_power.h"
 
-// Future TODO: Move to i82801gx directory
-#include "../../../northbridge/intel/i945/ich7.h"
-
 #define DEBUG_SMI
 
 #define APM_CNT		0xb2
-#define APM_STS		0xb3
+#define   CST_CONTROL	0x85 // 0x85 crashes the box
+#define   PST_CONTROL	0x80 // 0x80 crashes the box
 #define   ACPI_DISABLE	0x1e
 #define   ACPI_ENABLE	0xe1
+#define   GNVS_UPDATE   0xea
+#define APM_STS		0xb3
 
 /* I945 */
 #define SMRAM		0x9d
@@ -48,6 +50,11 @@
 #define PM1_STS		0x00
 #define PM1_EN		0x02
 #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
@@ -56,6 +63,7 @@
 #define PM2_CNT		0x20 // mobile only
 #define GPE0_STS	0x28
 #define GPE0_EN		0x2c
+#define   PME_B0_EN	(1 << 13)
 #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
@@ -84,8 +92,15 @@
 /* While we read PMBASE dynamically in case it changed, let's
  * initialize it with a sane value
  */
-static u16 pmbase = DEFAULT_PMBASE;
+u16 pmbase = DEFAULT_PMBASE;
 
+/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
+ * by coreboot.
+ */
+global_nvs_t *gnvs = (global_nvs_t *)0x0;
+void *tcg = (void *)0x0;
+void *smi1 = (void *)0x0;
+
 /**
  * @brief read and clear PM1_STS 
  * @return PM1_STS register
@@ -235,7 +250,6 @@
 	printk_debug("\n");
 }
 
-
 /* We are using PCIe accesses for now
  *  1. the chipset can do it
  *  2. we don't need to worry about how we leave 0xcf8/0xcfc behind
@@ -244,12 +258,10 @@
 
 int southbridge_io_trap_handler(int smif)
 {
-	global_nvs_t *gnvs = (global_nvs_t *)0xc00;
-
 	switch (smif) {
 	case 0x32:
 		printk_debug("OS Init\n");
-		//gnvs->smif = 0;
+		gnvs->smif = 0;
 		break;
 	default:
 		/* Not handled */
@@ -278,141 +290,337 @@
 	outb(reg8, pmbase + SMI_EN);
 }
 
-/**
- * @brief Interrupt handler for SMI#
- *
- * @param smm_revision revision of the smm state save map
- */
 
-void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
 {
 	u8 reg8;
-	u16 pmctrl;
-	u16 pm1_sts;
-	u32 smi_sts, gpe0_sts, tco_sts;
+	u32 reg32;
+	u8 slp_typ;
+	/* FIXME: the power state on boot should be read from 
+	 * CMOS or even better from GNVS. Right now it's hard
+	 * coded at compile time.
+	 */
+	u8 s5pwr = MAINBOARD_POWER_ON_AFTER_FAIL;
 
-	pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
-	printk_spew("SMI#: pmbase = 0x%04x\n", pmbase);
+	/* First, disable further SMIs */
+	reg8 = inb(pmbase + SMI_EN);
+	reg8 &= ~SLP_SMI_EN;
+	outb(reg8, pmbase + SMI_EN);
 
-	/* We need to clear the SMI status registers, or we won't see what's
-	 * happening in the following calls.
+	/* Figure out SLP_TYP */
+	reg32 = inl(pmbase + PM1_CNT);
+	printk_spew("SMI#: SLP = 0x%08x\n", reg32);
+	slp_typ = (reg32 >> 10) & 7;
+
+	/* Next, do the deed.
 	 */
-	smi_sts = reset_smi_status();
-	dump_smi_status(smi_sts);
 
-	if (smi_sts & (1 << 21)) { // MONITOR
-		global_nvs_t *gnvs = (global_nvs_t *)0xc00;
-		int i;
-		u32 reg32;
-
-		reg32 = RCBA32(0x1e00); // TRSR - Trap Status Register
+	switch (slp_typ) {
+	case 0: printk_debug("SMI#: Entering S0 (On)\n"); break;
+	case 1: printk_debug("SMI#: Entering S1 (Assert STPCLK#)\n"); break;
+	case 5:
+		printk_debug("SMI#: Entering S3 (Suspend-To-RAM)\n");
+		/* Invalidate the cache before going to S3 */
+		wbinvd();
+		break;
+	case 6: printk_debug("SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
+	case 7:
+		printk_debug("SMI#: Entering S5 (Soft Power off)\n");
 #if 0
-		/* Comment in for some useful debug */
-		for (i=0; i<4; i++) {
-			if (reg32 & (1 << i)) {
-				printk_debug("  io trap #%d\n", i);
-			}
+		/* Set PME_B0_EN before going to S5 */
+		reg32 = inl(pmbase + GPE0_EN);
+		reg32 |= PME_B0_EN;
+		outl(reg32, pmbase + GPE0_EN);
+#endif
+		/* Should we keep the power state after a power loss?
+		 * In case the setting is "ON" or "OFF" we don't have
+		 * to do anything. But if it's "KEEP" we have to switch
+		 * to "OFF" before entering S5.
+		 */
+		if (s5pwr == MAINBOARD_POWER_KEEP) {
+			reg8 = pcie_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
+			reg8 |= 1;
+			pcie_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
 		}
-#endif
-		RCBA32(0x1e00) = reg32; // TRSR
+		break;
+	default: printk_debug("SMI#: ERROR: SLP_TYP reserved\n"); break;
+	}
 
-		reg32 = RCBA32(0x1e10);
+	/* Write back to the SLP register to cause the originally intended
+	 * event again. We need to set BIT13 (SLP_EN) though to make the 
+	 * sleep happen.
+	 */
+	outl(reg32 | SLP_EN, pmbase + PM1_CNT);
 
-		if ((reg32 & 0xfffc) != 0x808) {
-			printk_debug("  trapped io address = 0x%x\n", reg32 & 0xfffc);
-			printk_debug("  AHBE = %x\n", (reg32 >> 16) & 0xf);
-			printk_debug("  read/write: %s\n", (reg32 & (1 << 24)) ? "read" :
-				"write");
-		}
+	/* In most sleep states, the code flow of this function ends at
+	 * the line above. However, if we entered sleep state S1 and wake
+	 * up again, we will continue to execute code in this function.
+	 */
+	reg32 = inl(pmbase + PM1_CNT);
+	if (reg32 & SCI_EN) {
+		/* The OS is not an ACPI OS, so we set the state to S0 */
+		reg32 &= ~(SLP_EN | SLP_TYP);
+		outl(reg32, pmbase + PM1_CNT);
+	}
+}
 
-		if (!(reg32 & (1 << 24))) {
-			/* Write Cycle */
-			reg32 = RCBA32(0x1e18);
-			printk_debug("  iotrap written data = 0x%08x\n", reg32);
+static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
+{
+	u32 pmctrl;
+	u8 reg8;
 
-		}
+	/* Emulate B2 register as the FADT / Linux expects it */
 
-		if (gnvs->smif)
-			io_trap_handler(gnvs->smif); // call function smif
+	reg8 = inb(APM_CNT);
+	switch (reg8) {
+	case CST_CONTROL:
+		/* Calling this function seems to cause
+		 * some kind of race condition in Linux
+		 * and causes a kernel oops
+		 */
+		printk_debug("C-state control\n");
+		break;
+	case PST_CONTROL:
+		/* Calling this function seems to cause
+		 * some kind of race condition in Linux
+		 * and causes a kernel oops
+		 */
+		printk_debug("P-state control\n");
+		break;
+	case ACPI_DISABLE:
+		pmctrl = inl(pmbase + PM1_CNT);
+		pmctrl &= ~SCI_EN;
+		outl(pmctrl, pmbase + PM1_CNT);
+		printk_debug("SMI#: ACPI disabled.\n");
+		break;
+	case ACPI_ENABLE:
+		pmctrl = inl(pmbase + PM1_CNT);
+		pmctrl |= SCI_EN;
+		outl(pmctrl, pmbase + PM1_CNT);
+		printk_debug("SMI#: ACPI enabled.\n");
+		break;
+	case GNVS_UPDATE:
+		gnvs = *(global_nvs_t **)0x500;
+		tcg  = *(void **)0x504;
+		smi1 = *(void **)0x508;
+		printk_debug("SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
+		break;
+	default:
+		printk_debug("SMI#: Unknown function APM_CNT=%02x\n", reg8);
 	}
+}
 
-	if (smi_sts & (1 << 13)) { // TCO
-		tco_sts = reset_tco_status();
-		dump_tco_status(tco_sts);
+static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
+{
+	u16 pm1_sts;
 
-		if (tco_sts & (1 << 8)) { // BIOSWR
-			u8 bios_cntl;
+	pm1_sts = reset_pm1_status();
+	dump_pm1_status(pm1_sts);
+}
 
-			bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
+static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
+{
+	u32 gpe0_sts;
 
-			if (bios_cntl & 1) {
-				/* BWE is RW, so the SMI was caused by a
-				 * write to BWE, not by a write to the BIOS
-				 */
+	gpe0_sts = reset_gpe0_status();
+	dump_gpe0_status(gpe0_sts);
+}
 
-				/* This is the place where we notice someone
-				 * is trying to tinker with the BIOS. We are
-				 * trying to be nice and just ignore it. A more
-				 * resolute answer would be to power down the
-				 * box.
-				 */
-				printk_debug("Switching back to RO\n");
-				pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
-			} /* No else for now? */
-		}
+static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
+{
+	u32 reg32;
+
+	reg32 = inl(pmbase + SMI_EN);
+
+	/* Are periodic SMIs enabled? */
+	if ((reg32 & MCSMI_EN) == 0)
+		return;
+
+	printk_debug("Microcontroller SMI.\n");
+}
+
+
+
+static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
+{
+	u32 tco_sts;
+
+	tco_sts = reset_tco_status();
+
+	/* Any TCO event? */
+	if (!tco_sts)
+		return;
+
+	if (tco_sts & (1 << 8)) { // BIOSWR
+		u8 bios_cntl;
+
+		bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
+
+		if (bios_cntl & 1) {
+			/* BWE is RW, so the SMI was caused by a
+			 * write to BWE, not by a write to the BIOS
+			 */
+
+			/* This is the place where we notice someone
+			 * is trying to tinker with the BIOS. We are
+			 * trying to be nice and just ignore it. A more
+			 * resolute answer would be to power down the
+			 * box.
+			 */
+			printk_debug("Switching back to RO\n");
+			pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
+		} /* No else for now? */
+	} else if (tco_sts & (1 << 3)) { /* TIMEOUT */
+		/* Handle TCO timeout */
+		printk_debug("TCO Timeout.\n");
+	} else if (!tco_sts) {
+		dump_tco_status(tco_sts);
 	}
+}
 
-	if (smi_sts & (1 << 8)) { // PM1
-		pm1_sts = reset_pm1_status();
-		dump_pm1_status(pm1_sts);
+static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
+{
+	u32 reg32;
+
+	reg32 = inl(pmbase + SMI_EN);
+
+	/* Are periodic SMIs enabled? */
+	if ((reg32 & PERIODIC_EN) == 0)
+		return;
+
+	printk_debug("Periodic SMI.\n");
+}
+
+static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
+{
+#define IOTRAP(x) (trap_sts & (1 << x))
+	u32 trap_sts, trap_cycle;
+	u32 data, mask = 0;
+	int i;
+
+	trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
+	RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
+
+	trap_cycle = RCBA32(0x1e10);
+	for (i=16; i<20; i++) {
+		if (trap_cycle & (1 << i))
+			mask |= (0xff << ((i - 16) << 2));
 	}
 
-	if (smi_sts & (1 << 9)) { // GPE0
-		gpe0_sts = reset_gpe0_status();
-		dump_gpe0_status(gpe0_sts);
+
+	/* IOTRAP(3) SMI function call */
+	if (IOTRAP(3)) {
+		if (gnvs && gnvs->smif)
+			io_trap_handler(gnvs->smif); // call function smif
+		return;
 	}
 
-	if (smi_sts & (1 << 5)) { // APM
-		/* Emulate B2 register as the FADT / Linux expects it */
+	/* IOTRAP(2) currently unused
+	 * IOTRAP(1) currently unused */
 
-		reg8 = inb(0xb2);
-		switch (reg8) {
-		case ACPI_DISABLE:
-			pmctrl = inw(pmbase + 0x04);
-			pmctrl |= (1 << 0);
-			outw(pmctrl, pmbase + 0x04);
-			printk_debug("SMI#: ACPI disabled.\n");
-			break;
-		case ACPI_ENABLE:
-			pmctrl = inw(pmbase + 0x04);
-			pmctrl &= ~(1 << 0);
-			outw(pmctrl, pmbase + 0x04);
-			printk_debug("SMI#: ACPI enabled.\n");
-			break;
+	/* IOTRAP(0) SMIC */
+	if (IOTRAP(0)) {
+		if (!(trap_cycle & (1 << 24))) { // It's a write
+			printk_debug("SMI1 command\n");
+			data = RCBA32(0x1e18);
+			data &= mask;
+			// if (smi1)
+			// 	southbridge_smi_command(data);
+			// return;
 		}
+		// Fall through to debug
 	}
 
-	if (smi_sts & (1 << 4)) { // SLP_SMI
-		u32 reg32;
+	printk_debug("  trapped io address = 0x%x\n", trap_cycle & 0xfffc);
+	for (i=0; i < 4; i++) if(IOTRAP(i)) printk_debug("  TRAP = %d\n", i);
+	printk_debug("  AHBE = %x\n", (trap_cycle >> 16) & 0xf);
+	printk_debug("  MASK = 0x%08x\n", mask);
+	printk_debug("  read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
 
-		/* First, disable further SMIs */
-		reg8 = inb(pmbase + SMI_EN);
-		reg8 &= ~SLP_SMI_EN;
-		outb(reg8, pmbase + SMI_EN);
+	if (!(trap_cycle & (1 << 24))) {
+		/* Write Cycle */
+		data = RCBA32(0x1e18);
+		printk_debug("  iotrap written data = 0x%08x\n", data);
+	}
+#undef IOTRAP
+}
 
-		/* Next, do the deed, we should change
-		 * power on after power loss bits here
-		 * if we're going to S5
-		 */
+typedef void (*smi_handler)(unsigned int node, 
+		smm_state_save_area_t *state_save);
 
-		/* Write back to the SLP register to cause the
-		 * originally intended event again. We need to set BIT13
-		 * (SLP_EN) though to make the sleep happen.
-		 */
-		reg32 = inl(pmbase + 0x04);
-		printk_debug("SMI#: SLP = 0x%08x\n", reg32);
-		printk_debug("SMI#: Powering off.\n");
-		outl(reg32 | (1 << 13), pmbase + 0x04);
+smi_handler southbridge_smi[32] = {
+	NULL,			  //  [0] reserved
+	NULL,			  //  [1] reserved
+	NULL,			  //  [2] BIOS_STS
+	NULL,			  //  [3] LEGACY_USB_STS
+	southbridge_smi_sleep,	  //  [4] SLP_SMI_STS
+	southbridge_smi_apmc,	  //  [5] APM_STS
+	NULL,			  //  [6] SWSMI_TMR_STS
+	NULL,			  //  [7] reserved
+	southbridge_smi_pm1,	  //  [8] PM1_STS
+	southbridge_smi_gpe0,	  //  [9] GPE0_STS
+	NULL,			  // [10] GPI_STS
+	southbridge_smi_mc,	  // [11] MCSMI_STS
+	NULL,			  // [12] DEVMON_STS
+	southbridge_smi_tco,	  // [13] TCO_STS
+	southbridge_smi_periodic, // [14] PERIODIC_STS
+	NULL,			  // [15] SERIRQ_SMI_STS
+	NULL,			  // [16] SMBUS_SMI_STS
+	NULL,			  // [17] LEGACY_USB2_STS
+	NULL,			  // [18] INTEL_USB2_STS
+	NULL,			  // [19] reserved
+	NULL,			  // [20] PCI_EXP_SMI_STS
+	southbridge_smi_monitor,  // [21] MONITOR_STS
+	NULL,			  // [22] reserved
+	NULL,			  // [23] reserved
+	NULL,			  // [24] reserved
+	NULL,			  // [25] EL_SMI_STS
+	NULL,			  // [26] SPI_STS
+	NULL,			  // [27] reserved
+	NULL,			  // [28] reserved
+	NULL,			  // [29] reserved
+	NULL,			  // [30] reserved
+	NULL			  // [31] reserved 
+};
+
+/**
+ * @brief Interrupt handler for SMI#
+ *
+ * @param smm_revision revision of the smm state save map
+ */
+
+void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+{
+	int i, dump = 0;
+	u32 smi_sts;
+
+	/* Update global variable pmbase */
+	pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
+
+	/* We need to clear the SMI status registers, or we won't see what's
+	 * happening in the following calls.
+	 */
+	smi_sts = reset_smi_status();
+	
+	/* Filter all non-enabled SMI events */
+	// FIXME Double check, this clears MONITOR
+	// smi_sts &= inl(pmbase + SMI_EN);
+
+	/* Call SMI sub handler for each of the status bits */
+	for (i = 0; i < 31; i++) {
+		if (smi_sts & (1 << i)) { 
+			if (southbridge_smi[i])
+				southbridge_smi[i](node, state_save);
+			else {
+				printk_debug("SMI_STS[%d] occured, but no "
+						"handler available.\n", i);
+				dump = 1;
+			}
+		}
 	}
 
+	if(dump) {
+		dump_smi_status(smi_sts);
+	}
+
 }
Index: src/southbridge/intel/i82801gx/i82801gx_smi.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_smi.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_smi.c	(working copy)
@@ -27,11 +27,8 @@
 #include <cpu/x86/cache.h>
 #include <cpu/x86/smm.h>
 #include <string.h>
-#include "chip.h"
+#include "i82801gx.h"
 
-// Future TODO: Move to i82801gx directory
-#include "../../../northbridge/intel/i945/ich7.h"
-
 extern unsigned char smm[];
 extern unsigned int smm_len;
 
@@ -318,8 +315,12 @@
 
 void smm_init(void)
 {
+	// FIXME is this a race condition?
 	smm_relocate();
 	smm_install();
+
+	// We're done. Make sure SMIs can happen!
+	smi_set_eos();
 }
 
 void smm_lock(void)
@@ -333,3 +334,13 @@
 			D_LCK | G_SMRAME | C_BASE_SEG);
 }
 
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+	/* The GDT or coreboot table is going to live here. But a long time
+	 * after we relocated the GNVS, so this is not troublesome.
+	 */
+	*(u32 *)0x500 = (u32)gnvs;
+	*(u32 *)0x504 = (u32)tcg;
+	*(u32 *)0x508 = (u32)smi1;
+	outb(0xea, 0xb2);
+}
Index: src/southbridge/intel/i82801gx/i82801gx_sata.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_sata.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_sata.c	(working copy)
@@ -35,8 +35,10 @@
 
 	printk_debug("i82801gx_sata: initializing...\n");
 
-	if (config == NULL)
+	if (config == NULL) {
 		printk_err("i82801gx_sata: error: device not in Config.lb!\n");
+		return;
+	}
 
 	/* SATA configuration */
 
@@ -55,12 +57,15 @@
 		pci_write_config8(dev, 0x09, 0x80);
 
 		/* Set timings */
-		pci_write_config16(dev, IDE_TIM_PRI, 0x8000);
-		pci_write_config16(dev, IDE_TIM_SEC, 0xa307);
+		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+				IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
 
 		/* Sync DMA */
-		pci_write_config16(dev, 0x48, 0x0004);
-		pci_write_config16(dev, 0x4a, 0x0200);
+		pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+		pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
 
 		/* Set IDE I/O Configuration */
 		reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
@@ -84,12 +89,15 @@
 		pci_write_config8(dev, INTR_LN, 0x0a);
 
 		/* Set timings */
-		pci_write_config16(dev, IDE_TIM_PRI, 0xa307);
-		pci_write_config16(dev, IDE_TIM_SEC, 0x8000);
+		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+				IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
 
 		/* Sync DMA */
-		pci_write_config16(dev, 0x48, 0x0001);
-		pci_write_config16(dev, 0x4a, 0x0001);
+		pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+		pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
 
 		/* Set IDE I/O Configuration */
 		reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
@@ -126,12 +134,16 @@
 		pci_write_config8(dev, INTR_LN, 0xff);
 	
 		/* Set timings */
-		pci_write_config16(dev, IDE_TIM_PRI, 0xa307);
-		pci_write_config16(dev, IDE_TIM_SEC, 0xe303);
+		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+				IDE_SITRE | IDE_ISP_3_CLOCKS | 
+				IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
 	
 		/* Sync DMA */
-		pci_write_config16(dev, 0x48, 0x0005);
-		pci_write_config16(dev, 0x4a, 0x0201);
+		pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+		pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
 	
 		/* Set IDE I/O Configuration */
 		reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
Index: src/southbridge/intel/i82801gx/i82801gx_smbus.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_smbus.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_smbus.c	(working copy)
@@ -29,6 +29,19 @@
 #include "i82801gx.h"
 #include "i82801gx_smbus.h"
  
+#define SMB_BASE 0x20
+static void smbus_init(struct device *dev)
+{
+	u32 smb_base;
+
+	smb_base = pci_read_config32(dev, SMB_BASE);
+	printk_debug("Initializing SMBus device:\n");
+	printk_debug("  Old SMBUS Base Address: 0x%04x\n", smb_base);
+	pci_write_config32(dev, SMB_BASE, 0x00000401);
+	smb_base = pci_read_config32(dev, SMB_BASE);
+	printk_debug("  New SMBUS Base Address: 0x%04x\n", smb_base);
+}
+
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
 	u16 device;
@@ -65,7 +78,7 @@
 	.read_resources		= pci_dev_read_resources,
 	.set_resources		= pci_dev_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
-	.init			= 0,
+	.init			= smbus_init,
 	.scan_bus		= scan_static_bus,
 	.enable			= i82801gx_enable,
 	.ops_smbus_bus		= &lops_smbus_bus,
Index: src/southbridge/intel/i82801gx/i82801gx_usb_debug.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_usb_debug.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_usb_debug.c	(working copy)
@@ -21,16 +21,26 @@
 #define EHCI_BAR		0xFEF00000
 // These could be read from DEBUG_BASE (0:1d.7 R 0x5A 16bit)
 #define EHCI_BAR_INDEX		0x10
+
+#define EHCI_CONFIG_FLAG	0x40
+#define EHCI_PORTSC		0x44
 #define EHCI_DEBUG_OFFSET	0xA0
 
-static void set_debug_port(unsigned port)
+void set_debug_port(unsigned port)
 {
-	// Nothing for now?
+	u32 dbgctl;
+
+	printk_debug("Enabling OWNER_CNT\n");
+	dbgctl = readl(EHCI_BAR + EHCI_DEBUG_OFFSET);
+	dbgctl |= (1 << 30);
+	writel(dbgctl, EHCI_BAR + EHCI_DEBUG_OFFSET);
+
 }
 
 static void i82801gx_enable_usbdebug_direct(unsigned port)
 {
 	pci_write_config32(PCI_DEV(0, 0x1d, 7), EHCI_BAR_INDEX, EHCI_BAR);
 	pci_write_config8(PCI_DEV(0, 0x1d, 7), 0x04, 0x2); // Memory Space Enable
+	set_debug_port(port);
 }
 
Index: src/southbridge/intel/i82801gx/i82801gx_power.h
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_power.h	(revision 0)
+++ src/southbridge/intel/i82801gx/i82801gx_power.h	(revision 0)
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define MAINBOARD_POWER_OFF	0
+#define MAINBOARD_POWER_ON	1
+#define MAINBOARD_POWER_KEEP	2
+
+#ifndef MAINBOARD_POWER_ON_AFTER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON
+#endif
+
Index: src/southbridge/intel/i82801gx/i82801gx_ac97.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_ac97.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_ac97.c	(working copy)
@@ -251,6 +251,21 @@
 	}
 }
 
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	if (!vendor || !device) {
+		pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+				pci_read_config32(dev, PCI_VENDOR_ID));
+	} else {
+		pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+				((device & 0xffff) << 16) | (vendor & 0xffff));
+	}
+}
+
+static struct pci_operations ac97_pci_ops = {
+	.set_subsystem    = ac97_set_subsystem,
+};
+
 static struct device_operations ac97_audio_ops = {
 	.read_resources		= pci_dev_read_resources,
 	.set_resources		= pci_dev_set_resources,
@@ -258,6 +273,7 @@
 	.init			= ac97_audio_init,
 	.scan_bus		= 0,
 	.enable			= i82801gx_enable,
+	.ops_pci		= &ac97_pci_ops,
 };
 
 static struct device_operations ac97_modem_ops = {
@@ -267,6 +283,7 @@
 	.init			= ac97_modem_init,
 	.scan_bus		= 0,
 	.enable			= i82801gx_enable,
+	.ops_pci		= &ac97_pci_ops,
 };
 
 /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
Index: src/southbridge/intel/i82801gx/i82801gx_pci.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_pci.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_pci.c	(working copy)
@@ -81,7 +81,7 @@
 
 	command = pci_read_config16(dev, PCI_COMMAND);
 	command |= dev->command;
-#if PCI_BRIDGE_UPDATE_COMMAND
+#ifdef PCI_BRIDGE_UPDATE_COMMAND
 	/* If we write to PCI_COMMAND, on some systems 
 	 * this will cause the ROM and APICs not being visible
 	 * anymore.
Index: src/southbridge/intel/i82801gx/i82801gx_nvs.h
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_nvs.h	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_nvs.h	(working copy)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the coreboot project.
  *
- * Copyright (C) 2008 coresystems GmbH
+ * Copyright (C) 2008-2009 coresystems GmbH
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -20,44 +20,48 @@
  */
 
 typedef struct {
-	u16	osys;
-	u8	smif;
-	u8	prm0;
-	u8	prm1;
-	u8	scif;
-	u8	prm2;
-	u8	prm3;
-	u8	lckf;
-	u8	prm4;
-	u8	prm5;
-	u32	p80d;
-	u8	lids;
-	u8	pwrs;
-	u8	dbgs;
-	u8	linxs;
-	u8	rsvd;
-	u8	actt;
-	u8	psvt;
-	u8	tc1v;
-	u8	tc2v;
-	u8	tspv;
-	u8	crtt;
-	u8	dtse;
-	u8	dts1;
-	u8	dts2;
+	/* Miscellaneous */
+	u16	osys; /* 0x00 - Operating System */
+	u8	smif; /* 0x02 - SMI function call ("TRAP") */
+	u8	prm0; /* 0x03 - SMI function call parameter */
+	u8	prm1; /* 0x04 - SMI function call parameter */
+	u8	scif; /* 0x05 - SCI function call (via _L00) */
+	u8	prm2; /* 0x06 - SCI function call parameter */
+	u8	prm3; /* 0x07 - SCI function call parameter */
+	u8	lckf; /* 0x08 - Global Lock function for EC */
+	u8	prm4; /* 0x09 - Lock function parameter */
+	u8	prm5; /* 0x0a - Lock function parameter */
+	u32	p80d; /* 0x0b - Debug port (IO 0x80) value */
+	u8	lids; /* 0x0f - LID state (open = 1) */
+	u8	pwrs; /* 0x10 - Power state (AC = 1) */
+	u8	dbgs; /* 0x11 - Debug state */
+	u8	linx; /* 0x12 - Linux OS */
+	u8	dckn; /* 0x13 - PCIe docking state */
+	/* Thermal policy */
+	u8	actt; /* 0x14 - active trip point */
+	u8	psvt; /* 0x15 - passive trip point */
+	u8	tc1v; /* 0x16 - passive trip point TC1 */
+	u8	tc2v; /* 0x17 - passive trip point TC2 */
+	u8	tspv; /* 0x18 - passive trip point TSP */
+	u8	crtt; /* 0x19 - critical trip point */
+	u8	dtse; /* 0x1a - Digital Thermal Sensor enable */
+	u8	dts1; /* 0x1b - DT sensor 1 */
+	u8	dts2; /* 0x1c - DT sensor 2 */
 	u8	rsvd2;
-	u8	bnum;
-	u8	b0sc, b1sc, b2sc;
-	u8	b0ss, b1ss, b2ss;
+	/* Battery Support */
+	u8	bnum; /* 0x1e - number of batteries */
+	u8	b0sc, b1sc, b2sc; /* 0x1f-0x21 - stored capacity */
+	u8	b0ss, b1ss, b2ss; /* 0x22-0x24 - stored status */
 	u8	rsvd3[3];
-	u8	apic;
-	u8	mpen;
-	u8	bten;
-	u8	ppcm;
-	u8	pcp0;
-	u8	pcp1;
-	u8	rsvd4[4];
-	u8	natp;
+	/* Processor Identification */
+	u8	apic; /* 0x28 - APIC enabled */
+	u8	mpen; /* 0x29 - MP capable/enabled */
+	u8	pcp0; /* 0x2a - PDC CPU/CORE 0 */
+	u8	pcp1; /* 0x2b - PDC CPU/CORE 1 */
+	u8	ppcm; /* 0x2c - Max. PPC state */
+	u8	rsvd4[5];
+	/* Super I/O & CMOS config */
+	u8	natp; /* 0x32 - SIO type */
 	u8	cmap;
 	u8	cmbp;
 	u8	lptp;
@@ -67,42 +71,69 @@
 	u8	rtcf;
 	u8	util;
 	u8	acin;
-	u8	igds;
-	u8	tlst;
-	u8	cadl;
-	u8	padl;
-	u16	cste;
-	u16	pste;
-	u16	nste;
-	u16	sste;
-	u8	ndid;
-	u32	did1;
-	u32	did2;
-	u32	did3;
-	u32	did4;
-	u32	did5;
-	u8	rsvd5[0xb];
+	/* Integrated Graphics Device */
+	u8	igds; /* 0x3c - IGD state */
+	u8	tlst; /* 0x3d - Display Toggle List Pointer */
+	u8	cadl; /* 0x3e - currently attached devices */
+	u8	padl; /* 0x3f - previously attached devices */
+	u16	cste; /* 0x40 - current display state */
+	u16	nste; /* 0x42 - next display state */
+	u16	sste; /* 0x44 - set display state */
+	u8	ndid; /* 0x46 - number of device ids */
+	u32	did[5]; /* 0x47 - 5b device id 1..5 */
+	u8	rsvd5[0x9];
+	/* Backlight Control */
+	u8	blcs; /* 0x64 - Backlight Control possible */
 	u8	brtl;
 	u8	odds;
-	u8	alse;
+	u8	rsvd6[0x7];
+	/* Ambient Light Sensors*/
+	u8	alse; /* 0x6e - ALS enable */
 	u8	alaf;
 	u8	llow;
 	u8	lhih;
-	u8	rsvd6;
-	u8	emae;
+	u8	rsvd7[0x6];
+	/* EMA */
+	u8	emae; /* 0x78 - EMA enable */
 	u16	emap;
 	u16	emal;
-	u8	rsvd7;
-	u8	mefe;
-	u8	igps;
-	u8	rsvd8[2];
-	u8	tpmp;
+	u8	rsvd8[0x5];
+	/* MEF */
+	u8	mefe; /* 0x82 - MEF enable */
+	u8	rsvd9[0x9];
+	/* TPM support */
+	u8	tpmp; /* 0x8c - TPM */
 	u8	tpme;
-	u8	rsvd9[8];
-	u8	gtf0[7];
+	u8	rsvd10[8];
+	/* SATA */
+	u8	gtf0[7]; /* 0x96 - GTF task file buffer for port 0 */
+	u8	gtf1[7];
 	u8	gtf2[7];
 	u8	idem;
 	u8	idet;
-	u8	dock;
-} global_nvs_t;
+	u8	rsvd11[7];
+	/* IGD OpRegion (not implemented yet) */
+	u32	aslb; /* 0xb4 - IGD OpRegion Base Address */
+	u8	ibtt;
+	u8	ipat;
+	u8	itvf;
+	u8	itvm;
+	u8	ipsc;
+	u8	iblc;
+	u8	ibia;
+	u8	issc;
+	u8	i409;
+	u8	i509;
+	u8	i609;
+	u8	i709;
+	u8	idmm;
+	u8	idms;
+	u8	if1e;
+	u8	hvco;
+	u32	nxd[8];
+	u8	rsvd12[8];
+	/* Mainboard specific */
+	u8	dock; /* 0xf0 - Docking Status */
+	u8	rsvd13[15];
+} __attribute__((packed)) global_nvs_t;
 
Index: src/southbridge/intel/i82801gx/i82801gx_lpc.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_lpc.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_lpc.c	(working copy)
@@ -27,50 +27,15 @@
 #include <pc80/i8259.h>
 #include <arch/io.h>
 #include "i82801gx.h"
+#include "i82801gx_power.h"
 
-#include "../../../northbridge/intel/i945/ich7.h"
+#define NMI_OFF 0
 
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON  1
+#define ENABLE_ACPI_MODE_IN_COREBOOT	0
+#define TEST_SMM_FLASH_LOCKDOWN		0
 
-#ifndef MAINBOARD_POWER_ON_AFTER_FAIL
-#define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#define NMI_OFF 0
-
 typedef struct southbridge_intel_i82801gx_config config_t;
 
-/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
- * 0x00 - 0000 = Reserved
- * 0x01 - 0001 = Reserved
- * 0x02 - 0010 = Reserved
- * 0x03 - 0011 = IRQ3
- * 0x04 - 0100 = IRQ4
- * 0x05 - 0101 = IRQ5
- * 0x06 - 0110 = IRQ6
- * 0x07 - 0111 = IRQ7
- * 0x08 - 1000 = Reserved
- * 0x09 - 1001 = IRQ9
- * 0x0A - 1010 = IRQ10
- * 0x0B - 1011 = IRQ11
- * 0x0C - 1100 = IRQ12
- * 0x0D - 1101 = Reserved
- * 0x0E - 1110 = IRQ14
- * 0x0F - 1111 = IRQ15
- * PIRQ[n]_ROUT[7] - PIRQ Routing Control
- * 0x80 - The PIRQ is not routed.
- */
-
-#define PIRQA 0x03
-#define PIRQB 0x05
-#define PIRQC 0x06
-#define PIRQD 0x07
-#define PIRQE 0x09
-#define PIRQF 0x0A
-#define PIRQG 0x0B
-#define PIRQH 0x0C
-
 static void i82801gx_enable_apic(struct device *dev)
 {
 	int i;
@@ -78,7 +43,9 @@
 	volatile u32 *ioapic_index = (volatile u32 *)0xfec00000;
 	volatile u32 *ioapic_data = (volatile u32 *)0xfec00010;
 
-	/* Enable ACPI I/O and power management. */
+	/* Enable ACPI I/O and power management. 
+	 * Set SCI IRQ to IRQ9
+	 */
 	pci_write_config8(dev, ACPI_CNTL, 0x80);
 
 	*ioapic_index = 0;
@@ -109,6 +76,27 @@
 			  (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
 }
 
+/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ * PIRQ[n]_ROUT[7] - PIRQ Routing Control
+ * 0x80 - The PIRQ is not routed.
+ */
+
 static void i82801gx_pirq_init(device_t dev)
 {
 	device_t irq_dev;
@@ -180,10 +168,14 @@
 	pci_write_config32(dev, 0xb8, reg32);
 }
 
+extern u8 acpi_slp_type;
+
 static void i82801gx_power_options(device_t dev)
 {
 	u8 reg8;
-	u16 reg16;
+	u16 reg16, pmbase;
+	u32 reg32;
+	char *state;
 
 	int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
 	int nmi_option;
@@ -195,16 +187,28 @@
         get_option(&pwr_on, "power_on_after_fail");
 	reg8 = pci_read_config8(dev, GEN_PMCON_3);
 	reg8 &= 0xfe;
-	if (pwr_on) {
+	switch (pwr_on) {
+	case MAINBOARD_POWER_OFF:
+		reg8 |= 1;
+		state = "off";
+		break;
+	case MAINBOARD_POWER_ON:
 		reg8 &= ~1;
-	} else {
-		reg8 |= 1;
+		state = "on";
+		break;
+	case MAINBOARD_POWER_KEEP:
+		reg8 &= ~1;
+		state = "state keep";
+		break;
+	default:
+		state = "undefined";
 	}
+
 	reg8 |= (3 << 4);	/* avoid #S4 assertions */
 	reg8 &= ~(1 << 3);	/* minimum asssertion is 1 to 2 RTCCLK */
 
 	pci_write_config8(dev, GEN_PMCON_3, reg8);
-	printk_info("Set power %s after power failure.\n", pwr_on ? "on" : "off");
+	printk_info("Set power %s after power failure.\n", state);
 
 	/* Set up NMI on errors. */
 	reg8 = inb(0x61);
@@ -226,15 +230,27 @@
 	}
 	outb(reg8, 0x70);
 
-	// Enable CPU_SLP# and Intel Speedstep, set SMI# rate down
+	/* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
 	reg16 = pci_read_config16(dev, GEN_PMCON_1);
 	reg16 &= ~((3 << 0) | (1 << 10));
 	reg16 |= (1 << 3) | (1 << 5);
-	reg16 |= (1 << 2); // CLKRUN_EN
+	reg16 |= (1 << 2);			// CLKRUN_EN
 	pci_write_config16(dev, GEN_PMCON_1, reg16);
 
 	// Set the board's GPI routing.
 	i82801gx_gpi_routing(dev);
+
+	/* Set up power management block and determine sleep mode */
+	pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+	reg32 = inl(pmbase + 0x04); // PM1_CNT
+#if HAVE_ACPI_RESUME
+	acpi_slp_type = (((reg32 >> 10) & 7) == 5) ? 3 : 0;
+	printk_debug("PM1_CNT: 0x%08x --> acpi_sleep_type: %x\n", 
+			reg32, acpi_slp_type);
+#endif
+	reg32 |= (1 << 1); // enable C3->C0 transition on bus master
+	reg32 |= 1; // SCI_EN
+	outl(reg32, pmbase + 0x04);
 }
 
 static void i82801gx_configure_cstates(device_t dev)
@@ -273,9 +289,10 @@
 {
 	u32 reg32;
 	
-	/* Leave HPET at default address, but enable it */
+	/* Move HPET to default address 0xfed00000 and enable it */
 	reg32 = RCBA32(0x3404);
 	reg32 |= (1 << 7); // HPET Address Enable
+	reg32 &= ~(3 << 0);
 	RCBA32(0x3404) = reg32;
 }
 
@@ -467,6 +484,13 @@
 	.ops_pci		= &pci_ops,
 };
 
+/* 82801GH (ICH7 DH) */
+static const struct pci_driver ich7_dh_lpc __pci_driver = {
+	.ops	= &device_ops,
+	.vendor	= PCI_VENDOR_ID_INTEL,
+	.device	= 0x27b0,
+};
+
 /* 82801GB/GR (ICH7/ICH7R) */
 static const struct pci_driver ich7_ich7r_lpc __pci_driver = {
 	.ops	= &device_ops,
Index: src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl	(revision 4441)
+++ src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl	(working copy)
@@ -33,7 +33,8 @@
 		I2CE,	1
 	}
 
-	OperationRegion (SMBI, SystemIO, 0x500, 0x20)
+	/*
+	OperationRegion (SMBI, SystemIO, 0x400, 0x20)
 	Field (SMBI, ByteAcc, NoLock, Preserve)
 	{
 		HSTS,	8,	// Host Status
@@ -236,6 +237,7 @@
 
 		Return (0xffff)
 	}
+	*/
 
 	// Todo: Does anyone ever use these?
 	// Missing: Read / Write Word
Index: src/southbridge/intel/i82801gx/acpi/ich7_pci.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/ich7_pci.asl	(revision 4441)
+++ src/southbridge/intel/i82801gx/acpi/ich7_pci.asl	(working copy)
@@ -43,6 +43,24 @@
 		Name (_PRW, Package(){ 11, 4 })
 	}
 
+	Device (SLT6)
+	{
+		Name (_ADR, 0x00050000)
+		Name (_PRW, Package(){ 11, 4 })
+	}
+
+	Device (LANC)
+	{
+		Name (_ADR, 0x00080000)
+		Name (_PRW, Package(){ 11, 3 })
+	}
+
+	Device (LANR)
+	{
+		Name (_ADR, 0x00000000)
+		Name (_PRW, Package(){ 11, 3 })
+	}
+
 	// TODO: How many slots, where?
 
 	// PCI Interrupt Routing.
@@ -52,47 +70,7 @@
 
 	Method (_PRT)
 	{
-		If (PICM) {
-			Return (Package() {
-				// PCI Slot 1 routes FGHE
-				Package() { 0x0000ffff, 0, 0, 16}, /* Firewire */
-				Package() { 0x0000ffff, 1, 0, 22},
-				Package() { 0x0000ffff, 2, 0, 23},
-				Package() { 0x0000ffff, 3, 0, 20},
-
-				// PCI Slot 2 routes GFEH (but is EFGH now, because that actually works)
-				Package() { 0x0001ffff, 0, 0, 20},
-				Package() { 0x0001ffff, 1, 0, 21},
-				Package() { 0x0001ffff, 2, 0, 22},
-				Package() { 0x0001ffff, 3, 0, 23},
-
-				// PCI Slot 3 routes CDBA
-				Package() { 0x0002ffff, 0, 0, 18},
-				Package() { 0x0002ffff, 1, 0, 19},
-				Package() { 0x0002ffff, 2, 0, 17},
-				Package() { 0x0002ffff, 3, 0, 16}
-			})
-		} Else {
-			Return (Package() {
-				// PCI Slot 1 routes FGHE
-				Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKF, 0},
-				Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKE, 0},
-				Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKH, 0},
-				Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKG, 0},
-
-				// PCI Slot 2 routes GFEH
-				Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKG, 0},
-				Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKF, 0},
-				Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKE, 0},
-				Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKH, 0},
-
-				// PCI Slot 3 routes CDBA
-				Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKC, 0},
-				Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKD, 0},
-				Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKB, 0},
-				Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
-			})
-		}
+		Include ("acpi/ich7_pci_irqs.asl")
 	}
 
 }
Index: src/southbridge/intel/i82801gx/acpi/globalnvs.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/globalnvs.asl	(revision 0)
+++ src/southbridge/intel/i82801gx/acpi/globalnvs.asl	(revision 0)
@@ -0,0 +1,161 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Global Variables */
+
+Name(\PICM, 0)		// IOAPIC/8259
+Name(\DSEN, 1)		// Display Output Switching Enable
+
+/* Global ACPI memory region. This region is used for passing information 
+ * between coreboot (aka "the system bios"), ACPI, and the SMI handler.
+ * Since we don't know where this will end up in memory at ACPI compile time,
+ * we have to fix it up in coreboot's ACPI creation phase.
+ */
+
+
+OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0x100)
+Field (GNVS, ByteAcc, NoLock, Preserve)
+{
+	/* Miscellaneous */
+	Offset (0x00),
+	OSYS,	16,	// 0x00 - Operating System
+	SMIF,	 8,	// 0x02 - SMI function
+	PRM0,	 8,	// 0x03 - SMI function parameter
+	PRM1,	 8,	// 0x04 - SMI function parameter
+	SCIF,	 8,	// 0x05 - SCI function
+	PRM2,	 8,	// 0x06 - SCI function parameter
+	PRM3,	 8,	// 0x07 - SCI function parameter
+	LCKF,	 8,	// 0x08 - Global Lock function for EC
+	PRM4,	 8,	// 0x09 - Lock function parameter
+	PRM5,	 8,	// 0x0a - Lock function parameter
+	P80D,	32,	// 0x0b - Debug port (IO 0x80) value
+	LIDS,	 8,	// 0x0f - LID state (open = 1)
+	PWRS,	 8,	// 0x10 - Power State (AC = 1)
+	DBGS,	 8,	// 0x11 - Debug State
+	LINX,    8,	// 0x12 - Linux OS
+	DCKN,	 8,	// 0x13 - PCIe docking state
+	/* Thermal policy */
+	Offset (0x14),
+	ACTT,	 8,	// 0x14 - active trip point
+	PSVT,	 8,	// 0x15 - passive trip point
+	TC1V,	 8,	// 0x16 - passive trip point TC1
+	TC2V,	 8,	// 0x17 - passive trip point TC2
+	TSPV,	 8,	// 0x18 - passive trip point TSP
+	CRTT,	 8,	// 0x19 - critical trip point
+	DTSE,	 8,	// 0x1a - Digital Thermal Sensor enable
+	DTS1,	 8,	// 0x1b - DT sensor 1
+	DTS2,	 8,	// 0x1c - DT sensor 2
+	/* Battery Support */
+	Offset (0x1e),
+	BNUM,	 8,	// 0x1e - number of batteries
+	B0SC,	 8,	// 0x1f - BAT0 stored capacity
+	B1SC,	 8,	// 0x20 - BAT1 stored capacity
+	B2SC,	 8,	// 0x21 - BAT2 stored capacity
+	B0SS,	 8,	// 0x22 - BAT0 stored status
+	B1SS,	 8,	// 0x23 - BAT1 stored status
+	B2SS,	 8,	// 0x24 - BAT2 stored status
+	/* Processor Identification */
+	Offset (0x28),
+	APIC,	 8,	// 0x28 - APIC Enabled by coreboot
+	MPEN,	 8,	// 0x29 - Multi Processor Enable
+	PCP0,	 8,	// 0x2a - PDC CPU/CORE 0
+	PCP1,	 8,	// 0x2b - PDC CPU/CORE 1
+	PPCM,	 8,	// 0x2c - Max. PPC state
+	/* Super I/O & CMOS config */
+	Offset (0x32),
+	NATP,	 8,	// 0x32 - ...
+	/* Integrated Graphics Device */
+	Offset (0x3c),
+	IGDS,	 8,	// 0x3c - IGD state (primary = 1)
+	TLST,	 8,	// 0x3d - Display Toggle List pointer
+	CADL,	 8,	// 0x3e - Currently Attached Devices List
+	PADL,	 8,	// 0x3f - Previously Attached Devices List
+	CSTE,	16,	// 0x40 - Current display state
+	NSTE,	16,	// 0x42 - Next display state
+	SSTE,	16,	// 0x44 - Set display state
+	Offset (0x46),
+	NDID,	 8,	// 0x46 - Number of Device IDs
+	DID1,	32,	// 0x47 - Device ID 1
+	DID2,	32,	// 0x4b - Device ID 2
+	DID3,	32,	// 0x4f - Device ID 3
+	DID4,	32,	// 0x53 - Device ID 4
+	DID5,	32,	// 0x57 - Device ID 5
+	/* Backlight Control */
+	Offset (0x64),
+	BLCS,	 8,	// 0x64 - Backlight control possible?
+	BRTL,	 8,	// 0x65 - Brightness Level
+	ODDS,	 8,	// 0x66
+	/* Ambient Light Sensors */
+	Offset (0x6e),
+	ALSE,	 8,	// 0x6e - ALS enable
+	ALAF,	 8,	// 0x6f - Ambient light adjustment factor
+	LLOW,	 8,	// 0x70 - LUX Low
+	LHIH,	 8,	// 0x71 - LUX High
+	/* EMA */
+	Offset (0x78),
+	EMAE,	 8,	// 0x78 - EMA enable
+	EMAP,	16,	// 0x79 - EMA pointer
+	EMAL,	16,	// 0x7b - EMA length
+	/* MEF */
+	Offset (0x82),
+	MEFE,	 8,	// 0x82 - MEF enable
+	/* TPM support */
+	Offset (0x8c),
+	TPMP,	 8,	// 0x8c - TPM
+	TPME,	 8,	// 0x8d - TPM enable
+	/* SATA */
+	Offset (0x96),
+	GTF0,	56,	// 0x96 - GTF task file buffer for port 0
+	GTF1,	56,	// 0x9d - GTF task file buffer for port 1
+	GTF2,	56,	// 0xa4 - GTF task file buffer for port 2
+	IDEM,	 8,	// 0xab - IDE mode (compatible / enhanced)
+	IDET,	 8,	// 0xac - IDE
+	/* IGD OpRegion */
+	Offset (0xb4),
+	ASLB,	32,	// 0xb4 - IGD OpRegion Base Address
+	IBTT,	 8,	// 0xb8 - IGD boot panel device
+	IPAT,	 8,	// 0xb9 - IGD panel type cmos option
+	ITVF,	 8,	// 0xba - IGD TV format cmos option
+	ITVM,	 8,	// 0xbb - IGD TV minor format option
+	IPSC,	 8,	// 0xbc - IGD panel scaling
+	IBLC,	 8,	// 0xbd - IGD BLC config
+	IBIA,	 8,	// 0xbe - IGD BIA config
+	ISSC,	 8,	// 0xbf - IGD SSC config
+	I409,	 8,	// 0xc0 - IGD 0409 modified settings
+	I509,	 8,	// 0xc1 - IGD 0509 modified settings
+	I609,	 8,	// 0xc2 - IGD 0609 modified settings
+	I709,	 8,	// 0xc3 - IGD 0709 modified settings
+	IDMM,	 8,	// 0xc4 - IGD DVMT Mode
+	IDMS,	 8,	// 0xc5 - IGD DVMT memory size
+	IF1E,	 8,	// 0xc6 - IGD function 1 enable
+	HVCO,	 8,	// 0xc7 - IGD HPLL VCO
+	NXD1,	32,	// 0xc8 - IGD _DGS next DID1
+	NXD2,	32,	// 0xcc - IGD _DGS next DID2
+	NXD3,	32,	// 0xd0 - IGD _DGS next DID3
+	NXD4,	32,	// 0xd4 - IGD _DGS next DID4
+	NXD5,	32,	// 0xd8 - IGD _DGS next DID5
+	NXD6,	32,	// 0xdc - IGD _DGS next DID6
+	NXD7,	32,	// 0xe0 - IGD _DGS next DID7
+	NXD8,	32,	// 0xe4 - IGD _DGS next DID8
+	/* Mainboard Specific (TODO move elsewhere) */
+	Offset (0xf0),
+	DOCK,	 8,	// 0xf0 - Docking Status
+}
Index: src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl	(revision 4441)
+++ src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl	(working copy)
@@ -68,7 +68,7 @@
 		})
 	}
 
-	Device (FWHD)		// Firmware Hub
+	Device (FWH)		// Firmware Hub
 	{
 		Name (_HID, EISAID("INT0800"))
 		Name (_CRS, ResourceTemplate()
@@ -80,7 +80,7 @@
 	Device (HPET)
 	{
 		Name (_HID, EISAID("PNP0103"))
-		Name (_CID, EISAID("PNP0C01"))
+		Name (_CID, 0x010CD041)
 
 		Name(BUF0, ResourceTemplate()
 		{
@@ -92,19 +92,33 @@
 			If (HPTE) {
 				// Note: Ancient versions of Windows don't want
 				// to see the HPET in order to work right
-				// Return (0xb)	// Enable and don't show device
-
-				Return (0xf)	// Enable and show device
+				If (LGreaterEqual(OSYS, 2001)) {
+					Return (0xf)	// Enable and show device
+				} Else {
+					Return (0xb)	// Enable and don't show device
+				}
 			}
 
 			Return (0x0)	// Not enabled, don't show.
 		}
 
-		Method (_CRS, 0, Serialized)
+		Method (_CRS, 0, Serialized) // Current resources
 		{
-			// Here we could do crazy stuff like move the HPET. Why
-			// should we?
+			If (HPTE) {
+				CreateDWordField(BUF0, \_SB.PCI0.LPCB.HPET.FED0._BAS, HPT0)
+				If (Lequal(HPAS, 1)) {
+					Store(0xfed01000, HPT0)
+				}
 
+				If (Lequal(HPAS, 2)) {
+					Store(0xfed02000, HPT0)
+				}
+
+				If (Lequal(HPAS, 3)) {
+					Store(0xfed03000, HPT0)
+				}
+			}
+
 			Return (BUF0)
 		}
 	}
@@ -130,7 +144,7 @@
 			IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
 			IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
 			IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
-			IO (Decode16, 0x4d0, 0x4b0, 0x01, 0x02)
+			IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
 			IRQNoFlags () { 2 }
 		})
 	}
@@ -145,7 +159,7 @@
 		})
 	}
 
-	Device(MISC)	// Various other devices
+	Device(LDRC)	// LPC device: Resource consumption
 	{
 		Name (_HID, EISAID("PNP0C02"))
 		Name (_UID, 2)
@@ -153,18 +167,18 @@
 		{
 			IO (Decode16, 0x2e, 0x2e, 0x1, 0x02)		// First SuperIO
 			IO (Decode16, 0x4e, 0x4e, 0x1, 0x02)		// Second SuperIO
-			IO (Decode16, 0x61, 0x61, 0x1, 0x1)		// NMI Status
-			IO (Decode16, 0x63, 0x63, 0x1, 0x1)		// CPU Reserved
-			IO (Decode16, 0x65, 0x65, 0x1, 0x1)		// CPU Reserved
-			IO (Decode16, 0x67, 0x67, 0x1, 0x1)		// CPU Reserved
-			IO (Decode16, 0x80, 0x80, 0x1, 0x1)		// Port 80 Post
-			IO (Decode16, 0x92, 0x92, 0x1, 0x1)		// CPU Reserved
+			IO (Decode16, 0x61, 0x61, 0x1, 0x01)		// NMI Status
+			IO (Decode16, 0x63, 0x63, 0x1, 0x01)		// CPU Reserved
+			IO (Decode16, 0x65, 0x65, 0x1, 0x01)		// CPU Reserved
+			IO (Decode16, 0x67, 0x67, 0x1, 0x01)		// CPU Reserved
+			IO (Decode16, 0x80, 0x80, 0x1, 0x01)		// Port 80 Post
+			IO (Decode16, 0x92, 0x92, 0x1, 0x01)		// CPU Reserved
 			IO (Decode16, 0xb2, 0xb2, 0x1, 0x02)		// SWSMI
-			IO (Decode16, 0x680, 0x680, 0x1, 0x70)		// IO ???
+			// IO (Decode16, 0x680, 0x680, 0x1, 0x70)	// IO ???
 			IO (Decode16, 0x800, 0x800, 0x1, 0x10)		// ACPI I/O trap
 			IO (Decode16, 0x0500, 0x0500, 0x1, 0x80)	// ICH7-M ACPI
-			IO (Decode16, 0x1180, 0x1180, 0x1, 0x40)	// ICH7-M GPIO
-			IO (Decode16, 0x1640, 0x1640, 0x1, 0x10)	// IO ???
+			IO (Decode16, 0x0480, 0x0480, 0x1, 0x40)	// ICH7-M GPIO
+			// IO (Decode16, 0x1640, 0x1640, 0x1, 0x10)	// IO ???
 		})
 	}
 
@@ -194,12 +208,19 @@
 	Device (PS2K)		// Keyboard
 	{
 		Name(_HID, EISAID("PNP0303"))
+		Name(_CID, EISAID("PNP030B"))
+
 		Name(_CRS, ResourceTemplate()
 		{
 			IO (Decode16, 0x60, 0x60, 0x01, 0x01)
 			IO (Decode16, 0x64, 0x64, 0x01, 0x01)
 			IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1
 		})
+
+		Method (_STA, 0)
+		{
+			Return (0xf)
+		}
 	}
 
 	Device (PS2M)		// Mouse
@@ -209,5 +230,36 @@
 		{
 			IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12
 		})
+
+		Method(_STA, 0)
+		{
+			Return (0xf)
+		}
 	}
+
+	Device (FDC0)		// Floppy controller
+	{
+		Name (_HID, EisaId ("PNP0700"))
+		Method (_STA, 0, NotSerialized)
+		{
+			Return (0x0f) // FIXME
+		}
+
+		Name(_CRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
+			IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
+			IRQNoFlags () {6}
+			DMA (Compatibility, NotBusMaster, Transfer8) {2}
+		})
+
+		Name(_PRS, ResourceTemplate()
+		{
+			IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
+			IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
+			IRQNoFlags () {6}
+			DMA (Compatibility, NotBusMaster, Transfer8) {2}
+		})
+
+	}
 }
Index: src/southbridge/intel/i82801gx/acpi/ich7.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/ich7.asl	(revision 4441)
+++ src/southbridge/intel/i82801gx/acpi/ich7.asl	(working copy)
@@ -92,7 +92,8 @@
 		Offset(0x38),	// GPIO Level 2
 		, 5,
 		GP37, 1,	// PATA_PWR_EN
-		, 2,
+		GP38, 1,	// Battery / Power (?)
+		GP39, 1,	// ??
 		GL05, 8,
 		GL06, 8,
 		GL07, 8
@@ -100,7 +101,7 @@
 
 
 	// ICH7 Root Complex Register Block. Memory Mapped through RCBA)
-	OperationRegion(RCRB, SystemMemory, 0xfff1000, 0x4000)
+	OperationRegion(RCRB, SystemMemory, 0xfed1c000, 0x4000)
 	Field(RCRB, DWordAcc, Lock, Preserve)
 	{
 		Offset(0x0000), // Backbone
@@ -111,12 +112,22 @@
 		, 5,
 		HPTE, 1,	// Address Enable
 		Offset(0x3418), // FD (Function Disable)
-		, 1,
+		, 1,		// Reserved
 		PATD, 1,	// PATA disable
 		SATD, 1,	// SATA disable
 		SMBD, 1,	// SMBUS disable
 		HDAD, 1,	// Azalia disable
-		, 11,		// ... FIXME
+		A97D, 1,	// AC'97 disable
+		M97D, 1,	// AC'97 disable
+		ILND, 1,	// Internal LAN disable
+		US1D, 1,	// UHCI #1 disable
+		US2D, 1,	// UHCI #2 disable
+		US3D, 1,	// UHCI #3 disable
+		US4D, 1,	// UHCI #4 disable
+		, 2,		// Reserved
+		LPBD, 1,	// LPC bridge disable
+		EHCD, 1,	// EHCI disable
+		Offset(0x341a), // FD Root Ports
 		RP1D, 1,	// Root Port 1 disable
 		RP2D, 1,	// Root Port 2 disable
 		RP3D, 1,	// Root Port 3 disable
@@ -139,6 +150,9 @@
 // PCI Bridge
 Include ("../../../southbridge/intel/i82801gx/acpi/ich7_pci.asl")
 
+// AC97 Audio and Modem
+Include ("../../../southbridge/intel/i82801gx/acpi/ich7_ac97.asl")
+
 // LPC Bridge
 Include ("../../../southbridge/intel/i82801gx/acpi/ich7_lpc.asl")
 
Index: src/southbridge/intel/i82801gx/acpi/ich7_audio.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/ich7_audio.asl	(revision 4441)
+++ src/southbridge/intel/i82801gx/acpi/ich7_audio.asl	(working copy)
@@ -27,6 +27,10 @@
 {
 	Name (_ADR, 0x001b0000)
 
-	Name (_PRW, Package(){ 13, 4 })
+	// Power Resources for Wake
+	Name (_PRW, Package(){ 
+		5,  // Bit 5 of GPE
+		4   // Can wake from S4 state.
+	})
 }
 
Index: src/southbridge/intel/i82801gx/acpi/sleepstates.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/sleepstates.asl	(revision 0)
+++ src/southbridge/intel/i82801gx/acpi/sleepstates.asl	(revision 0)
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Name(\_S0, Package(4){0x0,0x0,0,0})
+Name(\_S1, Package(4){0x1,0x0,0,0})
+Name(\_S3, Package(4){0x5,0x0,0,0})
+Name(\_S4, Package(4){0x6,0x0,0,0})
+Name(\_S5, Package(4){0x7,0x0,0,0})
+
Index: src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl
===================================================================
--- src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl	(revision 0)
+++ src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl	(revision 0)
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Intel i82801G AC'97 Audio and Modem */
+
+// Intel AC'97 Audio 0:1e.2
+
+Device (AUD0)
+{
+	Name (_ADR, 0x001e0002)
+}
+
+// Intel AC'97 Modem 0:1e.3
+
+Device (MODM)
+{
+	Name (_ADR, 0x001e0003)
+	
+	Name (_PRW, Package(){ 5, 4 })
+}
+
+
Index: src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c
===================================================================
--- src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c	(revision 4441)
+++ src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c	(working copy)
@@ -31,7 +31,7 @@
 static void usb_ehci_init(struct device *dev)
 {
 	struct resource *res;
-	u8 *base;
+	u32 base;
 	u32 reg32;
 	u8 reg8;
 
@@ -52,9 +52,9 @@
 
 	/* Clear any pending port changes */
 	res = find_resource(dev, 0x10);
-	base =(u8 *)res->base;
-	reg32 = readl(base + 0x24) | (1 << 2);
-	writel(base + 0x24, reg32);
+	base = res->base;
+	reg32 = readl((u8 *)base + 0x24) | (1 << 2);
+	writel(reg32, (u8 *)base + 0x24);
 
 	/* workaround */
 	reg8 = pci_read_config8(dev, 0x84);
@@ -115,7 +115,7 @@
 
 static struct device_operations usb_ehci_ops = {
 	.read_resources		= pci_dev_read_resources,
-	.set_resources		= pci_dev_set_resources,
+	.set_resources		= usb_ehci_set_resources,
 	.enable_resources	= pci_dev_enable_resources,
 	.init			= usb_ehci_init,
 	.scan_bus		= 0,
