Index: src/southbridge/intel/i82801aa/i82801aa_ide.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_ide.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_ide.c	(revision 0)
@@ -0,0 +1,48 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801aa.h"
+
+
+static void ide_init(struct device *dev)
+{
+	/* 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 first 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 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           = i82801aa_enable,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+	.ops    = &ide_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x2411,
+};
Index: src/southbridge/intel/i82801aa/i82801aa_reset.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_reset.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_reset.c	(revision 0)
@@ -0,0 +1,8 @@
+#include <arch/io.h>
+
+void i82801aa_hard_reset(void)
+{
+        /* Try rebooting through port 0xcf9 */
+        // Hard reset without power cycle
+        outb(0xe, 0xcf9);
+}
Index: src/southbridge/intel/i82801aa/Config.lb
===================================================================
--- src/southbridge/intel/i82801aa/Config.lb	(revision 0)
+++ src/southbridge/intel/i82801aa/Config.lb	(revision 0)
@@ -0,0 +1,16 @@
+uses CONFIG_IDE
+
+config chip.h
+driver i82801aa.o
+
+driver i82801aa_usb.o
+
+driver i82801aa_lpc.o
+
+if CONFIG_IDE
+	driver i82801aa_ide.o
+end
+
+driver i82801aa_ac97.o
+driver i82801aa_pci.o
+object i82801aa_reset.o
Index: src/southbridge/intel/i82801aa/i82801aa_ac97.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_ac97.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_ac97.c	(revision 0)
@@ -0,0 +1,41 @@
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801aa.h"
+
+
+static struct device_operations ac97audio_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.enable           = i82801aa_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static struct pci_driver ac97audio_driver __pci_driver = {
+	.ops    = &ac97audio_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801CA_AC97_AUDIO,
+};
+
+
+static struct device_operations ac97modem_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.enable           = i82801aa_enable,
+	.init             = 0,
+	.scan_bus         = 0,
+};
+
+static struct pci_driver ac97modem_driver __pci_driver = {
+	.ops    = &ac97modem_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x2415,
+};
Index: src/southbridge/intel/i82801aa/i82801aa_early_smbus.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_early_smbus.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_early_smbus.c	(revision 0)
@@ -0,0 +1,138 @@
+#include <device/pci_ids.h>
+#include "i82801aa.h"
+
+static void enable_smbus(void)
+{
+	device_t dev;
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, 0x2413), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("SMBUS controller not found\r\n");
+	}
+	
+	print_debug("SMBus controller enabled\r\n");
+	/* set smbus iobase */
+	pci_write_config32(dev, SMB_BASE, SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+	/* Set smbus enable */
+	pci_write_config8(dev, HOSTC, HST_EN);
+	/* Set smbus iospace enable */ 
+	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+	/* Disable interrupt generation */ 
+	outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+
+static inline void smbus_delay(void)
+{
+	inb(0x80);
+}
+
+// See http://openbios.org/pipermail/linuxbios/2004-September/009077.html
+// for a description of this function.
+static int smbus_wait_until_active(void)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned char val;
+		smbus_delay();
+		val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+		if ((val & 1)) {
+			break;
+		}
+	} while (--loops);
+	return loops ? 0 : -4;
+}
+
+static int smbus_wait_until_ready(void)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned char val;
+		smbus_delay();
+		val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+		// !HOST_BUSY?
+		if ((val & 1) == 0) {
+			break;
+		}
+		if(loops == (SMBUS_TIMEOUT / 2)) {
+			// Clear status flags
+			outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), 
+				SMBUS_IO_BASE + SMBHSTSTAT);
+		}
+	} while(--loops);
+	return loops?0:-2;
+}
+
+static int smbus_wait_until_done(void)
+{
+	unsigned long loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		unsigned char val;
+		smbus_delay();
+		
+		val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+		// !HOST_BUSY?
+		if ( (val & 1) == 0) {
+			break;
+		}
+		// BYTE_DONE or SUCCESS or error?
+		if ((val & ~((1<<6)|(1<<0)) ) != 0 ) {
+			break;
+		}
+	} while(--loops);
+	return loops?0:-3;
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+	unsigned char global_control_register;
+	unsigned char global_status_register;
+	unsigned char byte;
+
+	if (smbus_wait_until_ready() < 0) {
+		return -2;
+	}
+	
+	/* setup transaction */
+	/* disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
+	/* set to read from the specified device  */
+	outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+	/* set the command/address... */
+	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	/* set up for a byte data read */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2<<2), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* clear the data byte...*/
+	outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+	/* start a byte read, with interrupts disabled */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+	/* poll for it to start */
+	if (smbus_wait_until_active() < 0) {
+		return -4;
+	}
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done() < 0) {
+		return -3;
+	}
+
+	global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1<<6); /* Ignore the In Use Status... */
+
+	/* read results of transaction */
+	byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+	// SUCCESS?
+	if (global_status_register != 2) {
+		return -1;
+	}
+	return byte;
+}
Index: src/southbridge/intel/i82801aa/i82801aa.h
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa.h	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa.h	(revision 0)
@@ -0,0 +1,78 @@
+#ifndef I82801AA_H
+#define I82801AA_H
+
+#ifndef __ROMCC__
+#include "chip.h"
+extern void i82801aa_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 PMBASE          0x40
+#define ACPI_CNTL       0x44
+#define BIOS_CNTL       0x4E
+#define GPIO_BASE       0x58
+#define GPIO_CNTL       0x5C
+#define PIRQA_ROUT      0x60
+#define PIRQE_ROUT      0x68
+#define COM_DEC         0xE0
+#define LPC_EN          0xE6
+#define FUNC_DIS        0xF2
+
+// GEN_PMCON_3 bits
+#define RTC_BATTERY_DEAD		(1<<2)
+#define RTC_POWER_FAILED		(1<<1)
+#define SLEEP_AFTER_POWER_FAIL	(1<<0)
+
+/********************************************************************/
+/*							IDE Controller                          */
+/********************************************************************/
+
+// 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)
+
+/********************************************************************/
+/*								SMBus                               */
+/********************************************************************/
+
+// 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)
+
+#define SMBUS_IO_BASE 0x1000
+
+// I/O registers (relative to SMBUS_IO_BASE)
+#define SMBHSTSTAT		0
+#define SMBHSTCTL		2
+#define SMBHSTCMD		3
+#define SMBXMITADD		4
+#define SMBHSTDAT0		5
+#define SMBHSTDAT1		6
+#define SMBBLKDAT		7
+#define SMBTRNSADD		9
+#define SMBSLVDATA		10
+#define SMLINK_PIN_CTL	14
+#define SMBUS_PIN_CTL	15 
+
+/* Between 1-10 seconds, We should never timeout normally 
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000)
+
+#endif /* I82801AA_H */
Index: src/southbridge/intel/i82801aa/i82801aa_smbus.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_smbus.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_smbus.c	(revision 0)
@@ -0,0 +1,83 @@
+#include <smbus.h>
+#include <pci.h>
+#include <arch/io.h>
+#include "i82801aa.h"
+
+#define PM_BUS 0
+#define PM_DEVFN PCI_DEVFN(0x1f,3)
+
+void smbus_enable(void)
+{
+	/* iobase addr */
+	pcibios_write_config_dword(PM_BUS, PM_DEVFN, SMB_BASE, 
+							   SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+	/* smbus enable */
+	pcibios_write_config_byte(PM_BUS, PM_DEVFN, HOSTC, HST_EN);
+	/* iospace enable */
+	pcibios_write_config_word(PM_BUS, PM_DEVFN, PCI_COMMAND, PCI_COMMAND_IO);
+
+    /* Disable interrupt generation */
+    outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+}
+
+static void smbus_wait_until_ready(void)
+{
+	// Loop while HOST_BUSY
+	while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
+		/* nop */
+	}
+}
+
+static void smbus_wait_until_done(void)
+{
+	unsigned char byte;
+	
+	// Loop while HOST_BUSY
+	do {
+		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+	while((byte &1) == 1);
+	
+	// Wait for SUCCESS or error or BYTE_DONE
+	while( (byte & ~1) == 0) {
+		byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+}
+
+int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
+{
+	unsigned char host_status_register;
+	unsigned char byte;
+
+	smbus_wait_until_ready();
+
+	/* setup transaction */
+	/* disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+	/* set to read from the specified device  */
+	outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
+	/* set the command/address... */
+	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	/* set up for a byte data read */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* clear the data byte...*/
+	outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+	/* start the command */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+
+	/* poll for transaction completion */
+	smbus_wait_until_done();
+
+	host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+	/* read results of transaction */
+	byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+	*result = byte;
+	return host_status_register != 0x02;		// return true if !SUCCESS
+}
Index: src/southbridge/intel/i82801aa/i82801aa_usb.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_usb.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_usb.c	(revision 0)
@@ -0,0 +1,39 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801aa.h"
+
+static void usb_init(struct device *dev)
+{
+
+#if 0
+	uint32_t cmd;
+	printk_debug("USB: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
+		PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
+
+
+	printk_debug("done.\n");
+#endif
+
+}
+
+static struct device_operations usb_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = usb_init,
+	.scan_bus         = 0,
+	.enable           = i82801aa_enable,
+};
+
+static struct pci_driver usb_driver_1 __pci_driver = {
+	.ops    = &usb_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x2412,
+};
+
Index: src/southbridge/intel/i82801aa/chip.h
===================================================================
--- src/southbridge/intel/i82801aa/chip.h	(revision 0)
+++ src/southbridge/intel/i82801aa/chip.h	(revision 0)
@@ -0,0 +1,9 @@
+#ifndef I82801AA_CHIP_H
+#define I82801AA_CHIP_H
+
+struct southbridge_intel_i82801aa_config 
+{
+};
+extern struct chip_operations southbridge_intel_i82801aa_ops;
+
+#endif /* I82801AA_CHIP_H */
Index: src/southbridge/intel/i82801aa/i82801aa_pci.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_pci.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_pci.c	(revision 0)
@@ -0,0 +1,30 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801aa.h"
+
+static void pci_init(struct device *dev)
+{
+	// NOTE: the original (v1) 'CA code set these in the bridge register (0x3E-3F)
+	/* Enable pci error detecting */
+	uint32_t dword = pci_read_config32(dev, PCI_COMMAND);
+	dword |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+	pci_write_config32(dev, PCI_COMMAND, dword);
+}
+
+static struct device_operations pci_ops  = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init             = pci_init,
+	.scan_bus         = pci_scan_bridge,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x2418,
+};
+
Index: src/southbridge/intel/i82801aa/cmos_failover.c
===================================================================
--- src/southbridge/intel/i82801aa/cmos_failover.c	(revision 0)
+++ src/southbridge/intel/i82801aa/cmos_failover.c	(revision 0)
@@ -0,0 +1,20 @@
+//kind of cmos_err for ich3
+//todo: check if present on ich/ich0
+
+#include "i82801aa.h"
+
+static void check_cmos_failed(void) 
+{
+#if HAVE_OPTION_TABLE
+	uint8_t byte = pci_read_config8(PCI_DEV(0,0x1f,0),GEN_PMCON_3);
+
+	if( byte & RTC_BATTERY_DEAD) {
+		// Set boot_option and last_boot to 'Fallback',
+		// clear reboot_bits
+        byte = cmos_read(RTC_BOOT_BYTE);
+        byte &= 0x0c;
+        byte |= MAX_REBOOT_CNT << 4;
+        cmos_write(byte, RTC_BOOT_BYTE);
+    }
+#endif
+}
Index: src/southbridge/intel/i82801aa/i82801aa_lpc.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa_lpc.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa_lpc.c	(revision 0)
@@ -0,0 +1,240 @@
+/*
+ * (C) 2003 Linux Networx, SuSE Linux AG
+ * (C) 2004 Tyan Computer
+ * (c) 2005 Digital Design Corporation
+ */
+#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 "i82801aa.h"
+
+#define NMI_OFF 0
+
+#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON  1
+
+
+void i82801aa_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 & disable SMBus interrupts */
+    dword |= (1 <<13); /* coprocessor error enable */
+    dword |= (1 << 1); /* delay transaction enable */
+    dword |= (1 << 2); /* DMA collection buf enable */
+    pci_write_config32(dev, GEN_CNTL, dword);
+    printk_debug("ioapic southbridge enabled %x\n",dword);
+        
+    // Must program the APIC's ID before using it
+
+    *ioapic_index = 0;		// Select APIC ID register
+    *ioapic_data = (2<<24);
+        
+    // Hang if the ID didn't take (chip not present?)
+    *ioapic_index = 0;
+    dword = *ioapic_data;
+    printk_debug("Southbridge apic id = %x\n", (dword>>24) & 0xF);
+    if(dword != (2<<24))
+		die("");
+
+	*ioapic_index = 3;		// Select Boot Configuration register
+	*ioapic_data = 1;		// Use Processor System Bus to deliver interrupts
+}
+
+// This is how interrupts are received from the Super I/O chip
+void i82801aa_enable_serial_irqs( struct device *dev)
+{
+	// Recognize serial IRQs, continuous mode, frame size 21, 4 clock start frame pulse width
+    pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
+}
+
+//----------------------------------------------------------------------------------
+// Function:    	i82801aa_lpc_route_dma
+// Parameters:  	dev
+//					mask - identifies whether each channel should be used for PCI DMA
+//						   (bit = 0) or LPC DMA (bit = 1). The LSb controls channel 0.
+//						   Channel 4 is not used (reserved). 
+// Return Value:	None
+// Description: 	Route all DMA channels to either PCI or LPC.
+//
+void i82801aa_lpc_route_dma( struct device *dev, uint8_t mask) 
+{
+    uint16_t dmaConfig;
+    int channelIndex;
+
+    dmaConfig = pci_read_config16(dev, PCI_DMA_CFG);
+    dmaConfig &= 0x300;				// Preserve reserved bits
+    for(channelIndex = 0; channelIndex < 8; channelIndex++) {
+    	if (channelIndex == 4)
+        	continue;		// Register doesn't support channel 4
+        dmaConfig |= ((mask & (1 << channelIndex))? 3:1) << (channelIndex*2);
+    }
+    pci_write_config16(dev, PCI_DMA_CFG, dmaConfig);
+}
+
+void i82801aa_rtc_init(struct device *dev)
+{
+    uint32_t dword;
+    int rtc_failed;
+	int pwr_on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+    uint8_t pmcon3 = pci_read_config8(dev, GEN_PMCON_3);
+
+    rtc_failed = pmcon3 & RTC_BATTERY_DEAD;
+    if (rtc_failed) {
+    	// Clear the RTC_BATTERY_DEAD bit, but preserve
+        // the RTC_POWER_FAILED, G3 state, and reserved bits
+		// NOTE: RTC_BATTERY_DEAD and RTC_POWER_FAILED are "write-1-clear" bits
+        pmcon3 &= ~RTC_POWER_FAILED;
+    }
+
+    get_option(&pwr_on, "power_on_after_fail");
+	pmcon3 &= ~SLEEP_AFTER_POWER_FAIL;
+	if (!pwr_on) {
+		pmcon3 |= SLEEP_AFTER_POWER_FAIL;
+	}
+	pci_write_config8(dev, GEN_PMCON_3, pmcon3);
+	printk_info("set power %s after power fail\n", 
+				 pwr_on ? "on" : "off");
+
+    // See if the Safe Mode jumper is set
+    dword = pci_read_config32(dev, GEN_STS);
+    rtc_failed |= dword & (1 << 2);
+        
+    rtc_init(rtc_failed);
+}
+
+
+void i82801aa_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, 0x00001101);
+        
+    // 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, 0x00001181);
+        
+    // 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 lpc_init(struct device *dev)
+{
+	uint8_t byte;
+	int pwr_on=-1;
+	int nmi_option;
+
+	/* IO APIC initialization */
+	i82801aa_enable_ioapic(dev);
+
+	i82801aa_enable_serial_irqs(dev);
+	
+	/* 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
+         */
+    byte = pci_read_config8(dev, GEN_PMCON_3);
+    if (pwr_on)
+    	byte &= ~1;		// Return to S0 (boot) after power is re-applied
+    else
+    	byte |= 1;		// Return to S5
+    pci_write_config8(dev, GEN_PMCON_3, byte);
+    printk_info("set power %s after power fail\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 */
+	i82801aa_rtc_init(dev);
+
+	i82801aa_lpc_route_dma(dev, 0xff);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+
+	i82801aa_1f0_misc(dev);
+}
+
+static void i82801aa_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_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void i82801aa_lpc_enable_resources(device_t dev)
+{
+	pci_dev_enable_resources(dev);
+	enable_childrens_resources(dev);
+}
+
+static struct device_operations lpc_ops  = {
+	.read_resources   = i82801aa_lpc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = i82801aa_lpc_enable_resources,
+	.init             = lpc_init,
+	.scan_bus         = scan_static_bus,
+	.enable           = 0,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x2410,
+};
Index: src/southbridge/intel/i82801aa/i82801aa.c
===================================================================
--- src/southbridge/intel/i82801aa/i82801aa.c	(revision 0)
+++ src/southbridge/intel/i82801aa/i82801aa.c	(revision 0)
@@ -0,0 +1,56 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <assert.h>
+#include "i82801aa.h"
+
+/* TODO: Check all of this against datasheets/hardware. 
+ * I've only changed the names for now */
+
+void i82801aa_enable(device_t dev)
+{
+	unsigned int index = 0;
+	uint8_t bHasDisableBit = 0;
+	uint16_t cur_disable_mask, new_disable_mask;
+
+//	all 82801ca devices are in bus 0
+	unsigned int devfn = PCI_DEVFN(0x1f, 0); // lpc
+	device_t lpc_dev = dev_find_slot(0, devfn); // 0
+	if (!lpc_dev)
+		return;
+
+	// Calculate disable bit position for specified device:function
+	// NOTE: For ICH-3, only the following devices can be disabled:
+	//		 D31:F1, D31:F3, D31:F5, D31:F6, 
+	//		 D29:F0, D29:F1, D29:F2
+
+    if (PCI_SLOT(dev->path.u.pci.devfn) == 31) {
+    	index = PCI_FUNC(dev->path.u.pci.devfn);
+
+		if ((index == 1) || (index == 3) || (index == 5) || (index == 6))
+			bHasDisableBit = 1;
+
+    } else if (PCI_SLOT(dev->path.u.pci.devfn) == 29) {
+    	index = 8 + PCI_FUNC(dev->path.u.pci.devfn);
+
+		if (PCI_FUNC(dev->path.u.pci.devfn) < 3)
+			bHasDisableBit = 1;
+    }
+
+	if (bHasDisableBit) {
+		cur_disable_mask = pci_read_config16(lpc_dev, FUNC_DIS);
+		new_disable_mask = cur_disable_mask & ~(1<<index); 		// enable it
+		if (!dev->enabled) {
+			new_disable_mask |= (1<<index);  // disable it
+		}
+		if (new_disable_mask != cur_disable_mask) {
+			pci_write_config16(lpc_dev, FUNC_DIS, new_disable_mask);
+		}
+	}
+}
+
+struct chip_operations southbridge_intel_i82801aa_ops = {
+	CHIP_NAME("Intel 82801AA Southbridge")
+	.enable_dev = i82801aa_enable,
+};
Index: src/mainboard/asus/mew-vm/Config.lb
===================================================================
--- src/mainboard/asus/mew-vm/Config.lb	(revision 0)
+++ src/mainboard/asus/mew-vm/Config.lb	(revision 0)
@@ -0,0 +1,164 @@
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default CONFIG_ROM_PAYLOAD_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=65536
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+
+#if HAVE_PIRQ_TABLE object irq_tables.o end
+#object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc" 
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -E -mcpu=p2 -O -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc 
+	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc    -mcpu=p2 -O -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc 
+	ldscript /cpu/x86/16bit/reset16.lds 
+else
+	mainboardinit cpu/x86/32bit/reset32.inc 
+	ldscript /cpu/x86/32bit/reset32.lds 
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/i810
+	device pci_domain 0 on 
+		chip southbridge/intel/i82801aa # Southbridge
+			device pci 1e.0 on end # PCI Bridge
+			device pci 1f.0 on  # ISA/LPC Bridge
+				chip superio/smsc/lpc47b272 # Super I/O
+					device pnp 2e.0 on end # Floppy
+					device pnp 2e.3 off end # Parallel port
+					device pnp 2e.4 on # COM1
+						io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.5 on end # COM2
+					device pnp 2e.4 on end # Power mgmt.
+					#device pnp 2e.5 on end # Mouse
+					device pnp 2e.7 on # Keyboard & Mouse?
+						io 0x60 = 0x60
+						io 0x62 = 0x64
+						irq 0x70 = 1
+						irq 0x72 = 12 # ???
+					end
+				end
+			end
+			device pci 1f.1 on end # IDE
+			device pci 1f.2 on end # USB
+			device pci 1f.3 on end # SMBus
+			device pci 1f.5 off end # AC'97
+			device pci 1f.6 off end # AC97 Modem
+		end
+		device pci 0.0 on end # Host bridge
+		device pci 1.0 on end # PCI bridge  TODO: AGP bridge?
+		
+	end
+	chip cpu/intel/socket_PGA370
+	end
+end
+
Index: src/mainboard/asus/mew-vm/debug.c
===================================================================
--- src/mainboard/asus/mew-vm/debug.c	(revision 0)
+++ src/mainboard/asus/mew-vm/debug.c	(revision 0)
@@ -0,0 +1,66 @@
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
Index: src/mainboard/asus/mew-vm/Options.lb
===================================================================
--- src/mainboard/asus/mew-vm/Options.lb	(revision 0)
+++ src/mainboard/asus/mew-vm/Options.lb	(revision 0)
@@ -0,0 +1,160 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses HAVE_OPTION_TABLE
+uses USE_OPTION_TABLE
+uses CONFIG_ROM_PAYLOAD
+uses IRQ_SLOT_COUNT
+uses MAINBOARD
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PART_NUMBER
+uses LINUXBIOS_EXTRA_VERSION
+uses ARCH
+uses FALLBACK_SIZE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_PAYLOAD_START
+uses CONFIG_COMPRESSED_PAYLOAD_LZMA
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses _RAMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses HAVE_MP_TABLE
+uses CROSS_COMPILE
+uses CC
+uses HOSTCC
+uses OBJCOPY
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses CONFIG_UDELAY_TSC
+uses CONFIG_IDE
+
+## ROM_SIZE is the size of boot ROM that this board will use.
+default ROM_SIZE  = 512*1024
+
+###
+### Build options
+###
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT = 1
+
+##
+## no MP table
+##
+default HAVE_MP_TABLE = 0
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET = 0
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE = 0
+default IRQ_SLOT_COUNT = 4
+#object irq_tables.o
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE = 0
+
+## IDE Support
+default CONFIG_IDE = 1
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+default FALLBACK_SIZE = 131072
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 16K heap
+##
+default HEAP_SIZE=0x4000
+
+##
+## Only use the option table in a normal image
+##
+#default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+default USE_OPTION_TABLE = 0
+
+default _RAMBASE = 0x00004000
+
+default CONFIG_ROM_PAYLOAD     = 1
+
+##
+## The default compiler
+##
+default CROSS_COMPILE=""
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=9
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=9
+
+default CONFIG_UDELAY_TSC=1
+end
+
Index: src/mainboard/asus/mew-vm/failover.c
===================================================================
--- src/mainboard/asus/mew-vm/failover.c	(revision 0)
+++ src/mainboard/asus/mew-vm/failover.c	(revision 0)
@@ -0,0 +1,32 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include "arch/romcc_io.h"
+#include "pc80/mc146818rtc_early.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* This is the primary cpu how should I boot? */
+	if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
Index: src/mainboard/asus/mew-vm/auto.c
===================================================================
--- src/mainboard/asus/mew-vm/auto.c	(revision 0)
+++ src/mainboard/asus/mew-vm/auto.c	(revision 0)
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com>
+ *
+ * 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
+ */
+
+#define ASSEMBLY 1
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <arch/hlt.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/i82801aa/i82801aa_early_smbus.c"
+#include "superio/smsc/lpc47b272/lpc47b272_early_serial.c"
+#include "northbridge/intel/i810/raminit.h"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "cpu/x86/bist.h"
+
+#define SERIAL_DEV PNP_DEV(0x2e, LPC47B272_SP1)
+
+void udelay(int usecs) 
+{
+	int i;
+	for(i = 0; i < usecs; i++)
+		outb(i&0xff, 0x80);
+}
+
+#include "debug.c"
+#include "lib/delay.c"
+
+#include "northbridge/intel/i810/raminit.c"
+#include "northbridge/intel/i810/debug.c"
+#include "sdram/generic_sdram.c"
+
+static void main(unsigned long bist)
+{
+	static const struct mem_controller memctrl[] = {
+		{
+		 .d0 = PCI_DEV(0, 0, 0),
+		 .channel0 = {
+			      (0xa << 3) | 0,
+			      (0xa << 3) | 1,
+			      },
+		 }
+	};
+	
+	if (bist == 0) {
+		early_mtrr_init();
+	}
+	
+	enable_smbus();
+	
+	lpc47b272_enable_serial(SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+	report_bist_failure(bist);
+
+	//enable_shadow_ram();
+
+	//dump_spd_registers(&memctrl[0]);
+
+	/* sdram_initialize runs out of registers */
+	//sdram_initialize(sizeof(memctrl) / sizeof(memctrl[0]), memctrl);
+	
+	sdram_set_registers(memctrl);
+	sdram_set_spd_registers(memctrl);
+	sdram_enable(0, memctrl);
+
+	/* Check whether RAM is working.
+	 *
+	 * Do _not_ check the area from 640 KB - 1 MB, as that's not really
+	 * RAM, but rather reserved for various other things:
+	 *
+	 *  - 640 KB - 768 KB: Video Buffer Area
+	 *  - 768 KB - 896 KB: Expansion Area
+	 *  - 896 KB - 960 KB: Extended System BIOS Area
+	 *  - 960 KB - 1 MB:   Memory (BIOS Area) - System BIOS Area
+	 *
+	 * Trying to check these areas will fail.
+	 */
+	/* TODO: This is currently hardcoded to check 64 MB. */
+	ram_check(0x00000000, 0x0009ffff);	/* 0 - 640 KB */
+	ram_check(0x00100000, 0x007c0000);	/* 1 MB - 64 MB */
+}
Index: src/mainboard/asus/mew-vm/chip.h
===================================================================
--- src/mainboard/asus/mew-vm/chip.h	(revision 0)
+++ src/mainboard/asus/mew-vm/chip.h	(revision 0)
@@ -0,0 +1,5 @@
+extern struct chip_operations mainboard_asus_mew_vm_ops;
+
+struct mainboard_asus_mew_vm_config {
+	int nothing;
+};
Index: src/mainboard/asus/mew-vm/cmos.layout
===================================================================
--- src/mainboard/asus/mew-vm/cmos.layout	(revision 0)
+++ src/mainboard/asus/mew-vm/cmos.layout	(revision 0)
@@ -0,0 +1,74 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+1008         16      h       0        check_sum
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 1007 1008
+
+
Index: src/mainboard/asus/mew-vm/mainboard.c
===================================================================
--- src/mainboard/asus/mew-vm/mainboard.c	(revision 0)
+++ src/mainboard/asus/mew-vm/mainboard.c	(revision 0)
@@ -0,0 +1,7 @@
+#include <device/device.h>
+#include "chip.h"
+
+struct chip_operations mainboard_asus_mew_vm_ops = {
+	CHIP_NAME("ASUS MEW-VM Mainboard")
+};
+
Index: src/northbridge/intel/i810/Config.lb
===================================================================
--- src/northbridge/intel/i810/Config.lb	(revision 0)
+++ src/northbridge/intel/i810/Config.lb	(revision 0)
@@ -0,0 +1,22 @@
+##
+## This file is part of the LinuxBIOS project.
+##
+## Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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
+##
+
+config chip.h
+object northbridge.o
Index: src/northbridge/intel/i810/raminit.c
===================================================================
--- src/northbridge/intel/i810/raminit.c	(revision 0)
+++ src/northbridge/intel/i810/raminit.c	(revision 0)
@@ -0,0 +1,323 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com>
+ *
+ * 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 <spd.h>
+#include <sdram_mode.h>
+#include <delay.h>
+#include "i810.h"
+
+/*-----------------------------------------------------------------------------
+Macros and definitions.
+-----------------------------------------------------------------------------*/
+
+/* Uncomment this to enable debugging output. */
+#define DEBUG_RAM_SETUP 1
+
+/* Debugging macros. */
+#if defined(DEBUG_RAM_SETUP)
+#define PRINT_DEBUG(x)		print_debug(x)
+#define PRINT_DEBUG_HEX8(x)	print_debug_hex8(x)
+#define PRINT_DEBUG_HEX16(x)	print_debug_hex16(x)
+#define PRINT_DEBUG_HEX32(x)	print_debug_hex32(x)
+#define DUMPNORTH()		dump_pci_device(PCI_DEV(0, 0, 0))
+#else
+#define PRINT_DEBUG(x)
+#define PRINT_DEBUG_HEX8(x)
+#define PRINT_DEBUG_HEX16(x)
+#define PRINT_DEBUG_HEX32(x)
+#define DUMPNORTH()
+#endif
+
+/* DRAMT[7:5] - SDRAM Mode Select (SMS). */
+#define RAM_COMMAND_SELF_REFRESH 0x0 /* IE disable refresh */
+#define RAM_COMMAND_NORMAL	 0x1 /* Slow/normal refresh, 15.6us/11.7us for 100/133MHz */
+#define RAM_COMMAND_NORMAL_FR	 0x2 /* Fast refresh, 7.8us/5.85us for 100/133MHz */
+#define RAM_COMMAND_NOP		 0x4
+#define RAM_COMMAND_PRECHARGE	 0x5
+#define RAM_COMMAND_MRS		 0x6
+#define RAM_COMMAND_CBR		 0x7
+
+/*-----------------------------------------------------------------------------
+SDRAM configuration functions.
+-----------------------------------------------------------------------------*/
+
+/**
+ * Send the specified RAM command to all DIMMs.
+ *
+ * @param Memory controller
+ * @param TODO
+ * @param TODO
+ */
+static void do_ram_command(const struct mem_controller *ctrl,
+			   uint32_t command, uint32_t addr_offset)
+{
+	int i;
+	uint8_t reg;
+
+	/* TODO: Support for multiple DIMMs. */
+
+	/* Configure the RAM command. */
+	reg = pci_read_config8(ctrl->d0, DRAMT);
+	reg &= 0x1f;		/* Clear bits 7-5. */
+	reg |= command << 5;
+	pci_write_config8(ctrl->d0, DRAMT, reg);
+
+	/* RAM_COMMAND_NORMAL affects only the memory controller and
+	   doesn't need to be "sent" to the DIMMs. */
+	/* if (command == RAM_COMMAND_NORMAL) return; */
+
+	PRINT_DEBUG("    Sending RAM command 0x");
+	PRINT_DEBUG_HEX8(reg);
+	PRINT_DEBUG(" to 0x");
+	PRINT_DEBUG_HEX32(0 + addr_offset); // FIXME
+	PRINT_DEBUG("\r\n");
+
+	/* Read from (DIMM start address + addr_offset). */
+	read32(0 + addr_offset); // FIXME
+}
+
+/*-----------------------------------------------------------------------------
+DIMM-independant configuration functions.
+-----------------------------------------------------------------------------*/
+static const uint8_t translate_size[] = {
+	/* Plug in the value of byte 31, out pops the right northbridge value! */
+	/* Value for northbridge/8MB is 0xff for invalid spd bytes or non-supported sizes */
+	0xff,	// invalid, byte 31 == 0x0
+	0xff,	// 4/0,16
+	0x01,	// 8/0,16
+	0xff,	// 8/4
+	0x04,	// 16/0,16
+	0xff,	// 16/4
+	0x05,	// 16/8
+	0xff,
+	0x07,	// 32/0,32
+	0xff,	// 32/4
+	0xff,	// 32/8
+	0xff,
+	0x08,	// 32/16
+	0xff, 0xff, 0xff,
+	0x0a,	// 64/0,64 (1 << 4)
+	0xff,	// 64/4
+	0xff,	// 64/8
+	0xff,
+	0xff,	// 64/16 (1 << 4)|(1 << 2)
+	0xff, 0xff, 0xff,
+	0x0b,	// 64/32 (1 << 4)|(1 << 3)
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0x0d,	// 128/0,128 (1 << 5)
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff,
+	0x0e,	//128/64 (1 << 5)|(1 << 4)
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 
+	0x0f,	//256/0,256
+};
+
+static void spd_set_dram_size(const struct mem_controller *ctrl)
+{
+	int i, dual_sided, drp, dimm_size;
+	drp = 0x00;
+	
+	/* TODO: fix this up for i815, needs to use RPS2 for slots 2,3 */
+	for(i = 0; i < 2; i++)
+	{
+		/* First check if a DIMM is actually present */
+		if(smbus_read_byte(ctrl->channel0[i], 2) == 4)
+		{
+			print_debug("Found DIMM in slot ");
+			print_debug_hex8(i);
+			print_debug("\r\n");
+			
+			dimm_size = smbus_read_byte(ctrl->channel0[i], 31);			
+			
+			print_debug("DIMM is 0x");
+			print_debug_hex8(dimm_size);
+			print_debug(" in units of 4MB\r\n");
+
+			/* Send the dimm size to a scratch register, so we can use it later */
+			/* We're going to store it in units of 8MB */
+			/* Is 0xf0 actually a scratch register? */
+			/* All signs point to no, but there should be some on the southbridge */
+			//pci_write_config8(ctrl->d0, 0xf0 + i, dimm_size >> 1);
+
+			/* Set the values for a single sided dimm */
+			/* Much better way to do this: table 
+			   (dimm_size = translate_size[dimm_size]) */
+			
+			#if 0 //old way
+			/* 8MB */
+			if(dimm_size == 0x2) dimm_size = 0x1;
+			/* 16MB */
+			else if(dimm_size == 0x4) dimm_size = 0x4;
+			/* 32MB */
+			else if(dimm_size == 0x8) dimm_size = 0x7;
+			/* 64 MB */
+			else if(dimm_size == 0x10) dimm_size = 0xa;
+			/* 128 MB */
+			else if(dimm_size == 0x20) dimm_size = 0xd;
+			else print_debug("Ram Size not supported\r\n");
+			#endif
+			
+			//new way!
+			dimm_size = translate_size[dimm_size];
+			
+			print_debug("After translation, dimm_size is 0x");
+			print_debug_hex8(dimm_size);
+			print_debug("\r\n");
+			
+			/* If the dimm is dual-sided, the value is +2 */
+			/* Still assuming symetric banks, will fix later */
+			if(smbus_read_byte(ctrl->channel0[i], 127) & 0xf0 == 0xf0)
+			{
+				print_debug("DIMM is dual-sided\r\n");
+				dimm_size += 2;
+				/* Also double up the size in the scratch reg */
+				//pci_write_config8(ctrl->d0, 0xf0 + i, 
+					//(pci_read_config8(ctrl->d0, 0xf0 + i) * 2));
+			}
+		} 
+		else
+		{
+			print_debug("No DIMM found in slot ");
+			print_debug_hex8(i);
+			print_debug("\r\n");
+
+			/* If there's no dimm in the slot, set the value to 0 */
+			dimm_size = 0x00;
+			//pci_write_config8(ctrl->d0, 0xf0 + i, 0x0);
+		}	
+		
+		/* Put in dimm_size to reflect the current dimm */
+		drp |= dimm_size << (i * 4);
+	}
+
+	print_debug("DRP calculated to 0x");
+	print_debug_hex8(drp);
+	print_debug("\r\n");
+
+	pci_write_config8(ctrl->d0, DRP, drp);		
+}
+
+static void set_spd_timing(const struct mem_controller *ctrl)
+{
+/* Table 14. Programmable SDRAM Timing Parameters
+                         Parameter          DRAMT Bit Values (SCLKs)
+            RAS# Precharge (SRP)               0            2,3
+            RAS# to CAS# Delay (SRCD)          1            2,3
+            CAS# Latency (CL)                  2            2,3
+            DRAM Cycle Time (DCT)              4         Tras = 5,6
+                                                         Trc = 7,8
+*/
+}
+
+
+/*-----------------------------------------------------------------------------
+Public interface.
+-----------------------------------------------------------------------------*/
+
+/**
+ * TODO.
+ *
+ * @param Memory controller
+ */
+static void sdram_set_registers(const struct mem_controller *ctrl)
+{
+	/* TODO */
+	pci_write_config8(ctrl->d0, GMCHCFG, 0x60);
+	/* TODO */
+	pci_write_config8(ctrl->d0, PAM, 0x00);
+	/* TODO */
+	pci_write_config8(ctrl->d0, DRAMT, 0x08);
+	/* TODO */
+	//pci_write_config8(ctrl->d0, SMRAM, 0x00);
+	/* TODO */
+	pci_write_config8(ctrl->d0, MISSC2, 0x06);
+	
+	/* TODO - Undocumented on i810 */
+	//pci_write_config8(ctrl->d0, 0x81, 0xf8);
+	/* TODO */
+	//pci_write_config8(ctrl->d0, 0x82, 0x1f);
+	
+	/* TODO: This needs to be set according to the dram tech (x8, x16, or x32) */
+	pci_write_config16(ctrl->d0, BUFF_SC, 0x1149);	
+}
+
+/**
+ * TODO.
+ *
+ * @param Memory controller
+ */
+static void sdram_set_spd_registers(const struct mem_controller *ctrl)
+{
+	spd_set_dram_size(ctrl);
+
+	//set_spd_timing(ctrl);
+	
+	//set_buffer_strength(ctrl);
+}
+
+/**
+ * Enable SDRAM.
+ *
+ * @param Number of controllers
+ * @param Memory controller
+ */
+static void sdram_enable(int controllers, const struct mem_controller *ctrl)
+{
+	int i;
+
+	/* TODO: Use a delay here? Needed? */
+	mdelay(200);
+
+	/* TODO: How long should the delays be? Fix later. */
+
+	/* 1. Apply NOP. */
+	PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n");
+	do_ram_command(ctrl, RAM_COMMAND_NOP, 0);
+	udelay(400);
+
+	/* 2. Precharge all. Wait tRP. */
+	PRINT_DEBUG("RAM Enable 2: Precharge all\r\n");
+	do_ram_command(ctrl, RAM_COMMAND_PRECHARGE, 0);
+	udelay(400);
+
+	/* 3. Perform 8 refresh cycles. Wait tRC each time. */
+	PRINT_DEBUG("RAM Enable 3: CBR\r\n");
+	do_ram_command(ctrl, RAM_COMMAND_CBR, 0);
+	for (i = 0; i < 8; i++) {
+		read32(0);
+		udelay(100);
+	}
+
+	/* 4. Mode register set. Wait two memory cycles. */
+	PRINT_DEBUG("RAM Enable 4: Mode register set\r\n");
+	do_ram_command(ctrl, RAM_COMMAND_MRS, 0x1d0);
+	
+	udelay(200);
+
+	/* 5. Normal operation (enables refresh) */
+	PRINT_DEBUG("RAM Enable 5: Normal operation\r\n");
+	do_ram_command(ctrl, RAM_COMMAND_NORMAL, 0);
+	udelay(100);
+
+	PRINT_DEBUG("Northbridge following SDRAM init:\r\n");
+	DUMPNORTH();
+}
Index: src/northbridge/intel/i810/debug.c
===================================================================
--- src/northbridge/intel/i810/debug.c	(revision 0)
+++ src/northbridge/intel/i810/debug.c	(revision 0)
@@ -0,0 +1,91 @@
+
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+#if 0  /* Enable this if you have 2 memory channels */
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+#endif		
+	}
+}
+
+#if 0
+void dump_spd_registers(void)
+{
+	unsigned device;
+	device = SMBUS_MEM_DEVICE_START;
+	printk_debug("\n");
+	while(device <= SMBUS_MEM_DEVICE_END) {
+		int status = 0;
+		int i;
+		printk_debug("dimm %02x", device);
+		for(i = 0; (i < 256) && (status == 0); i++) {
+			unsigned char byte;
+			if ((i % 20) == 0) {
+				printk_debug("\n%3d: ", i);
+			}
+			status = smbus_read_byte(device, i, &byte);
+			if (status != 0) {
+				printk_debug("bad device\n");
+				continue;
+			}
+			printk_debug("%02x ", byte);
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		printk_debug("\n");
+	}
+}
+#endif
Index: src/northbridge/intel/i810/i810.h
===================================================================
--- src/northbridge/intel/i810/i810.h	(revision 0)
+++ src/northbridge/intel/i810/i810.h	(revision 0)
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2006 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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
+ */
+
+/*
+ * Datasheet:
+ *   - Name: Intel 440BX AGPset: 82443BX Host Bridge/Controller
+ *   - URL: http://www.intel.com/design/chipsets/datashts/290633.htm
+ *   - PDF: http://www.intel.com/design/chipsets/datashts/29063301.pdf
+ *   - Order Number: 290633-001
+ */
+
+/*
+ * Host-to-PCI Bridge Registers.
+ * The values in parenthesis are the default values as per datasheet.
+ * Any addresses between 0x00 and 0xff not listed below are either
+ * Reserved or Intel Reserved and should not be touched.
+ */
+#define VID	0x00 /* Vendor Identification (0x8086). */
+#define DID	0x02 /* Device Identification (0x7190/0x7192). */
+#define PCICMD	0x04 /* PCI Command Register (0x006). */
+#define PCISTS	0x06 /* PCI Status Register (0x0210/0x0200). */
+#define RID	0x08 /* Revision Identification (0x00/0x01/0x02). */
+#define SUBC	0x0a /* Sub-Class Code (0x00). */
+#define BCC	0x0b /* Base Class Code (0x06). */
+#define MLT	0x0d /* Master Latency Timer (0x00). */
+#define HDR	0x0e /* Header Type (0x00). */
+#define SVID	0x2c /* Subsystem Vendor Identification (0x0000). */
+#define SID	0x2e /* Subsystem Identification (0x0000). */
+#define CAPPTR	0x34 /* Capabilities Pointer (0xa0/0x00). */
+/* TODO: Descriptions */
+#define GMCHCFG	0x50
+
+/* i815 has this reg re-mapped to another function */
+#ifndef MODEL_815
+#define PAM	0x51
+#endif
+
+#define DRP	0x52
+#define DRAMT	0x53
+#define FDHC	0x58
+#define SMRAM	0x70 /* System Management RAM Control (0x02). */
+#define MISSC	0x72
+#define MISSC2	0x80
+#define BUFF_SC	0x92
+
+/* Used by i815, but not i810 */
+#ifdef MODEL_815
+#define APBASE	0x10
+#define DRP2	0x54
+#define PAM	0x59
+#define CAPID	0x88
+#define BUFF_SC2 0x94
+#define ACAPID	0xa0
+#define AGPSTAT	0xa4
+#define AGPCMD	0xa8
+#define AGPCTRL	0xb0
+#define APSIZE	0xb4
+#define ATTBASE	0xb8
+#define AMTT	0xbc
+#define LPTT	0xbd
+#define MCHCFG	0xbe
+#define ERRCMD	0xcb
+#endif
Index: src/northbridge/intel/i810/northbridge.c
===================================================================
--- src/northbridge/intel/i810/northbridge.c	(revision 0)
+++ src/northbridge/intel/i810/northbridge.c	(revision 0)
@@ -0,0 +1,202 @@
+#include <console/console.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bitops.h>
+#include "chip.h"
+#include "northbridge.h"
+#include "i810.h"
+
+static void northbridge_init(device_t dev) 
+{
+	printk_spew("Northbridge Init\n");
+}
+
+static struct device_operations northbridge_operations = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = northbridge_init,
+	.enable           = 0,
+	.ops_pci          = 0,
+};
+
+static struct pci_driver northbridge_driver __pci_driver = {
+	.ops = &northbridge_operations,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x7120,
+};
+
+/* Table which returns the ram size in MB when fed the DRP[7:4] or [3:0] value */
+/* Please note this does the _opposite_ of the translate_size[] in raminit.c,
+   which takes values from spd (ie in 4MB) and translates them to values for DRP */
+/* Note that 2 is a value which the DRP should never be programmed to */
+static int translate_size[] = {
+/* DRP	0  1 (2) 3   4   5   6   7   8   9   A   B   C    D    E    F */
+/* MB */0, 8, 0, 16, 16, 24, 32, 32, 48, 64, 64, 96, 128, 128, 192, 256,
+};
+
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
+{
+        struct resource *resource;
+        unsigned reg;
+
+        /* Initialize the system wide io space constraints */
+        resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+        resource->limit = 0xffffUL;
+        resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+        /* Initialize the system wide memory resources constraints */
+        resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+        resource->limit = 0xffffffffULL;
+        resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void ram_resource(device_t dev, unsigned long index,
+        unsigned long basek, unsigned long sizek)
+{
+        struct resource *resource;
+
+        if (!sizek) {
+                return;
+        }
+        resource = new_resource(dev, index);
+        resource->base  = ((resource_t)basek) << 10;
+        resource->size  = ((resource_t)sizek) << 10;
+        resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+                IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+static void tolm_test(void *gp, struct device *dev, struct resource *new)
+{
+	struct resource **best_p = gp;
+	struct resource *best;
+	best = *best_p;
+	if (!best || (best->base > new->base)) {
+		best = new;
+	}
+	*best_p = best;
+}
+
+static uint32_t find_pci_tolm(struct bus *bus)
+{
+	struct resource *min;
+	uint32_t tolm;
+	min = 0;
+	search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
+	tolm = 0xffffffffUL;
+	if (min && tolm > min->base) {
+		tolm = min->base;
+	}
+	return tolm;
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+	device_t mc_dev;
+        uint32_t pci_tolm;
+
+        pci_tolm = find_pci_tolm(&dev->link[0]);
+	mc_dev = dev->link[0].children;
+
+	if (mc_dev) {
+		/* Figure out which areas are/should be occupied by RAM.
+		 * This is all computed in kilobytes and converted to/from
+		 * the memory controller right at the edges.
+		 * Having different variables in different units is
+		 * too confusing to get right.  Kilobytes are good up to
+		 * 4 Terabytes of RAM...
+		 */
+		unsigned long tomk, tolmk;
+		int idx;
+		int drp_value;
+
+		/* Get the value of the total memory, which we stored in scratch 
+		 * in raminit.c. The units are ticks of 8MB, i.e. 1 means 8MB.
+		 */
+		
+		/*First get the value for DIMM 0 */
+		drp_value = pci_read_config8(mc_dev, DRP) & 0xf; 
+		/* Translate it to MB and add to tomk */
+		tomk = (unsigned long)(translate_size[drp_value]);
+		/* Now do the same for DIMM 1 */
+		drp_value = pci_read_config8(mc_dev, DRP) >> 4;
+		tomk += (unsigned long)(translate_size[drp_value]);
+
+		printk_debug("Setting RAM size to %d MB\n", tomk);
+
+		/* Convert tomk from MB to KB */
+		tomk = tomk << 10;		
+
+		/* Compute the top of Low memory */
+		tolmk = pci_tolm >> 10;
+		if (tolmk >= tomk) {
+			/* The PCI hole does does not overlap the memory.
+			 */
+			tolmk = tomk;
+		}
+
+		/* Report the memory regions */
+		idx = 10;
+		ram_resource(dev, idx++, 0, 640);
+		// ram_resource(dev, idx++, 768, tolmk - 768);
+		ram_resource(dev, idx++, 1024, tolmk - 1024);
+	}
+	assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+        max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+        return max;
+}
+
+static struct device_operations pci_domain_ops = {
+        .read_resources   = pci_domain_read_resources,
+        .set_resources    = pci_domain_set_resources,
+        .enable_resources = enable_childrens_resources,
+        .init             = 0,
+        .scan_bus         = pci_domain_scan_bus,
+};  
+
+static void cpu_bus_init(device_t dev)
+{
+        initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+        .read_resources   = cpu_bus_noop,
+        .set_resources    = cpu_bus_noop,
+        .enable_resources = cpu_bus_noop,
+        .init             = cpu_bus_init,
+        .scan_bus         = 0,
+};
+
+static void enable_dev(struct device *dev)
+{
+        struct device_path path;
+
+        /* Set the operations if it is a special bus type */
+        if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+                dev->ops = &pci_domain_ops;
+		pci_set_method(dev);
+        }
+        else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+                dev->ops = &cpu_bus_ops;
+        }
+}
+
+struct chip_operations northbridge_intel_i810_ops = {
+	CHIP_NAME("Intel i810/i815 Northbridge")
+	.enable_dev = enable_dev,
+};
Index: src/northbridge/intel/i810/raminit.h
===================================================================
--- src/northbridge/intel/i810/raminit.h	(revision 0)
+++ src/northbridge/intel/i810/raminit.h	(revision 0)
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com>
+ *
+ * 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 RAMINIT_H
+#define RAMINIT_H
+
+/* The i810 supports max 2 dual-sided DIMMs. */
+#define DIMM_SOCKETS	2
+
+struct mem_controller {
+	device_t d0;
+	uint16_t channel0[DIMM_SOCKETS];
+};
+
+#endif				/* RAMINIT_H */
Index: src/northbridge/intel/i810/chip.h
===================================================================
--- src/northbridge/intel/i810/chip.h	(revision 0)
+++ src/northbridge/intel/i810/chip.h	(revision 0)
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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
+ */
+
+struct northbridge_intel_i810_config
+{
+};
+
+extern struct chip_operations northbridge_intel_i810_ops;
Index: src/northbridge/intel/i810/northbridge.h
===================================================================
--- src/northbridge/intel/i810/northbridge.h	(revision 0)
+++ src/northbridge/intel/i810/northbridge.h	(revision 0)
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey@slightlyhackish.com>
+ *
+ * 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 NORTHBRIDGE_INTEL_I810_H
+#define NORTHBRIDGE_INTEL_I810_H
+
+extern unsigned int i810_scan_root_bus(device_t root, unsigned int max);
+
+#endif				/* NORTHBRIDGE_INTEL_I810_H */
Index: targets/asus/mew-vm/Config.lb
===================================================================
--- targets/asus/mew-vm/Config.lb	(revision 0)
+++ targets/asus/mew-vm/Config.lb	(revision 0)
@@ -0,0 +1,31 @@
+# Config file for asus mew-vm board
+# This will make a target directory of ./mew-vm
+
+target mew-vm
+mainboard asus/mew-vm
+
+option ROM_SIZE=512*1024
+
+romimage "normal"
+	option USE_FALLBACK_IMAGE=0
+	option ROM_IMAGE_SIZE=0x10000
+	option LINUXBIOS_EXTRA_VERSION=".0Normal"
+#	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
+#	payload ../../../../tg3--ide_disk.zelf	
+#	payload ../../../../../lnxieepro100.ebi
+#	payload /etc/hosts
+	payload /home/amp/linuxbios/filo-0.5/filo-ide.elf
+end
+
+romimage "fallback" 
+	option USE_FALLBACK_IMAGE=1
+	option ROM_IMAGE_SIZE=0x10000
+	option LINUXBIOS_EXTRA_VERSION=".0Fallback"
+#	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
+#	payload ../../../../tg3--ide_disk.zelf	
+#	payload ../../../../../lnxieepro100.ebia
+#	payload /etc/hosts
+	payload /home/amp/linuxbios/filo-0.5/filo-ide.elf
+end
+
+buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
