epia-m support


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1655 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/arch/i386/boot/acpi.c b/src/arch/i386/boot/acpi.c
index ca9b66f7..6c837d0 100644
--- a/src/arch/i386/boot/acpi.c
+++ b/src/arch/i386/boot/acpi.c
@@ -3,6 +3,10 @@
  * written by Stefan Reinauer <stepan@openbios.org>
  * (C) 2004 SUSE LINUX AG
  */
+/* ACPI FADT, FACS, and DSDT table support added by 
+ * Nick Barker <nick.barker9@btinternet.com>, and those portions
+ * (C) Copyright 2004 Nick Barker
+ */
 
 #include <console/console.h>
 #include <string.h>
@@ -22,7 +26,15 @@
 #define OEM_ID                "LXBIOS"
 #define ASLC                  "NONE"
 
-static u8 acpi_checksum(u8 *table, u32 length)
+
+// FIX ME - define needs declaring / setting in Config files
+#define HAVE_ACPI_FADT 
+
+#ifdef HAVE_ACPI_FADT
+extern unsigned char AmlCode[];
+#endif
+
+u8 acpi_checksum(u8 *table, u32 length)
 {
 	u8 ret=0;
 	while (length--) {
@@ -43,13 +55,15 @@
 	for (i=0; i<8; i++) {
 		if(rsdt->entry[i]==0) {
 			rsdt->entry[i]=(u32)table;
+			/* fix length to stop kernel winging about invalid entries */
+			rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1));
 			/* fix checksum */
 			/* hope this won't get optimized away */
 			rsdt->header.checksum=0;
 			rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
 					rsdt->header.length);
 			
-			printk_debug("ACPI: added table %d/8\n",i+1);
+			printk_debug("ACPI: added table %d/8 Length now %d\n",i+1,rsdt->header.length);
 			return;
 		}
 	}
@@ -181,6 +195,22 @@
 	header->checksum	= acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
 }
 
+static void acpi_create_facs(acpi_facs_t *facs)
+{
+
+	memset( (void *)facs,0, sizeof(acpi_facs_t));
+
+	memcpy(facs->signature,"FACS",4);
+	facs->length = sizeof(acpi_facs_t);
+	facs->hardware_signature = 0;
+	facs->firmware_waking_vector = 0;
+	facs->global_lock = 0;
+	facs->flags = 0;
+	facs->x_firmware_waking_vector_l = 0;
+	facs->x_firmware_waking_vector_h = 0;
+	facs->version = 1;
+
+}
 static void acpi_write_rsdt(acpi_rsdt_t *rsdt)
 { 
 	acpi_header_t *header=&(rsdt->header);
@@ -222,6 +252,9 @@
 	acpi_rsdt_t *rsdt;
 	acpi_hpet_t *hpet;
 	acpi_madt_t *madt;
+	acpi_fadt_t *fadt;
+	acpi_facs_t *facs;
+	acpi_header_t *dsdt;
 	
 	/* Align ACPI tables to 16byte */
 	start   = ( start + 0x0f ) & -0x10;
@@ -244,7 +277,6 @@
 	/*
 	 * We explicitly add these tables later on:
 	 */
-#define HAVE_ACPI_HPET
 #ifdef HAVE_ACPI_HPET
 	printk_debug("ACPI:    * HPET\n");
 
@@ -263,6 +295,35 @@
 
 
 #endif
+
+#ifdef HAVE_ACPI_FADT
+
+
+	printk_debug("ACPI:     * FACS\n");
+	facs = (acpi_facs_t *) current;
+	current += sizeof(acpi_facs_t);
+	acpi_create_facs(facs);
+
+
+	dsdt = (acpi_header_t *)current;
+	current += ((acpi_header_t *)AmlCode)->length;
+	memcpy((void *)dsdt,(void *)AmlCode, ((acpi_header_t *)AmlCode)->length);
+	dsdt->checksum = 0; // don't trust intel iasl compiler to get this right
+	dsdt->checksum = acpi_checksum(dsdt,dsdt->length);
+	printk_debug("ACPI:     * DSDT @ %08x Length %x\n",dsdt,dsdt->length);
+	printk_debug("ACPI:     * FADT\n");
+
+	fadt = (acpi_fadt_t *) current;
+	current += sizeof(acpi_fadt_t);
+
+	acpi_create_fadt(fadt,facs,dsdt);
+	acpi_add_table(rsdt,fadt);
+
+
+#endif	
+
+
+
 	printk_info("ACPI: done.\n");
 	return current;
 }
diff --git a/src/arch/i386/boot/tables.c b/src/arch/i386/boot/tables.c
index 08bb7a3..18e271d 100644
--- a/src/arch/i386/boot/tables.c
+++ b/src/arch/i386/boot/tables.c
@@ -60,8 +60,13 @@
 	low_table_end = write_smp_table(low_table_end, processor_map);
 
 	/* Write ACPI tables */
-	low_table_end = write_acpi_tables(low_table_end);
-	
+	/* write them in the rom area because DSDT can be large (8K on epia-m) which
+	 * pushes linuxbios table out of first 4K if set up in low table area 
+         */
+
+	rom_table_end = write_acpi_tables(rom_table_end);
+	rom_table_end = (rom_table_end+1023) & ~1023;
+
 	/* Don't write anything in the traditional x86 BIOS data segment */
 	if (low_table_end < 0x500) {
 		low_table_end = 0x500;
diff --git a/src/arch/i386/include/arch/acpi.h b/src/arch/i386/include/arch/acpi.h
index e840d42..9c89e90 100644
--- a/src/arch/i386/include/arch/acpi.h
+++ b/src/arch/i386/include/arch/acpi.h
@@ -7,6 +7,9 @@
  * The ACPI table structs are based on the Linux kernel sources.
  * 
  */
+/* ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
+ * those parts (C) 2004 Nick Barker
+ */
 
 
 #ifndef __ASM_ACPI_H
@@ -134,7 +137,77 @@
 } __attribute__ ((packed)) acpi_madt_irqoverride_t;
 
 
+typedef struct acpi_fadt {
+	struct acpi_table_header header;
+	u32 firmware_ctrl;
+	u32 dsdt;
+	u8 res1;
+	u8 preferred_pm_profile;
+	u16 sci_int;
+	u32 smi_cmd;
+	u8 acpi_enable;
+	u8 acpi_disable;
+	u8 s4bios_req;
+	u8 pstate_cnt;
+	u32 pm1a_evt_blk;
+	u32 pm1b_evt_blk;
+	u32 pm1a_cnt_blk;
+	u32 pm1b_cnt_blk;
+	u32 pm2_cnt_blk;
+	u32 pm_tmr_blk;
+	u32 gpe0_blk;
+	u32 gpe1_blk;
+	u8 pm1_evt_len;
+	u8 pm1_cnt_len;
+	u8 pm2_cnt_len;
+	u8 pm_tmr_len;
+	u8 gpe0_blk_len;
+	u8 gpe1_blk_len;
+	u8 gpe1_base;
+	u8 cst_cnt;
+	u16 p_lvl2_lat;
+	u16 p_lvl3_lat;
+	u16 flush_size;
+	u16 flush_stride;
+	u8 duty_offset;
+	u8 duty_width;
+	u8 day_alrm;
+	u8 mon_alrm;
+	u8 century;
+	u16 iapc_boot_arch;
+	u8 res2;
+	u32 flags;
+	struct acpi_gen_regaddr reset_reg;
+	u8 reset_value;
+	u8 res3;
+	u8 res4;
+	u8 res5;
+	u32 x_firmware_ctl_l;
+	u32 x_firmware_ctl_h;
+	u32 x_dsdt_l;
+	u32 x_dsdt_h;
+	struct acpi_gen_regaddr x_pm1a_evt_blk;
+	struct acpi_gen_regaddr x_pm1b_evt_blk;
+	struct acpi_gen_regaddr x_pm1a_cnt_blk;
+	struct acpi_gen_regaddr	x_pm1b_cnt_blk;
+	struct acpi_gen_regaddr x_pm2_cnt_blk;
+	struct acpi_gen_regaddr x_pm_tmr_blk;
+	struct acpi_gen_regaddr x_gpe0_blk;
+	struct acpi_gen_regaddr x_gpe1_blk;
+} __attribute__ ((packed)) acpi_fadt_t;
 
+typedef struct acpi_facs {
+	char signature[4];
+	u32 length;
+	u32 hardware_signature;
+	u32 firmware_waking_vector;
+	u32 global_lock;
+	u32 flags;
+	u32 x_firmware_waking_vector_l;
+	u32 x_firmware_waking_vector_h;
+	u8 version;
+	u8 resv[33];
+} __attribute__ ((packed)) acpi_facs_t;
 
 
 unsigned long write_acpi_tables(unsigned long addr);
diff --git a/src/arch/i386/lib/c_start.S b/src/arch/i386/lib/c_start.S
index 602fc51..47fb645 100644
--- a/src/arch/i386/lib/c_start.S
+++ b/src/arch/i386/lib/c_start.S
@@ -116,7 +116,7 @@
 	.word	0x0000, 0x0000		/* dummy */
 	.byte	0x00, 0x00, 0x00, 0x00
 
-#if defined(CONFIG_VGABIOS) && (CONFIG_VGABIOS == 1)
+#if defined(CONFIG_LEGACY_VGABIOS) && (CONFIG_LEGACY_VGABIOS == 1)
 	// from monty:
 	/* 0x00009a00,0000ffffULL,   20h: 16-bit 64k code at 0x00000000 */
         /* 0x00009200,0000ffffULL    28h: 16-bit 64k data at 0x00000000 */
diff --git a/src/config/Options.lb b/src/config/Options.lb
index 343abda..db00c51 100644
--- a/src/config/Options.lb
+++ b/src/config/Options.lb
@@ -481,7 +481,11 @@
 	export used
 	comment "Support for legacy VGA BIOS"
 end
-
+define VGABIOS_START
+	default 0
+	export used
+	comment "Base of Legacy VGA in Rom"
+end
 ###############################################
 # SMP options
 ###############################################
diff --git a/src/cpu/p6/mtrr.c b/src/cpu/p6/mtrr.c
index 3628660..f8b33a6 100644
--- a/src/cpu/p6/mtrr.c
+++ b/src/cpu/p6/mtrr.c
@@ -45,6 +45,7 @@
 	MTRRfix4K_E0000_MSR, MTRRfix4K_E8000_MSR, MTRRfix4K_F0000_MSR, MTRRfix4K_F8000_MSR,
 };
 
+static int mtrr_count = 0;
 
 static void intel_enable_fixed_mtrr(void)
 {
@@ -79,6 +80,12 @@
 		::"memory");
 }
 
+static inline void wbinvd(void)
+{
+	asm volatile (
+		"wbinvd\n\t");
+}
+
 static inline void enable_cache(void)
 {
 	unsigned int tmp;
@@ -92,15 +99,19 @@
 }
 
 /* setting variable mtrr, comes from linux kernel source */
+/* funtion nows saves and restores state of deftype regs so that extra mtrr's can be set-up
+ * after the initial main memory mtrr's
+ */
 static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
 {
-	msr_t base, mask;
+	msr_t base, mask, def,defsave;
 
 	base.hi = basek >> 22;
 	base.lo  = basek << 10;
 
 	//printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
 
+	printk_debug("Adding mtrr #%d at %08x size %x\n",reg,base.lo,sizek<<10);
 	if (sizek < 4*1024*1024) {
 		mask.hi = ADDRESS_MASK_HIGH;
 		mask.lo = ~((sizek << 10) -1);
@@ -116,6 +127,10 @@
 	// it is recommended that we disable and enable cache when we 
 	// do this. 
 	disable_cache();
+	def = defsave = rdmsr(MTRRdefType_MSR);
+	def.lo &= 0xf300;
+	wrmsr(MTRRdefType_MSR,def);
+
 	if (sizek == 0) {
 		msr_t zero;
 		zero.lo = zero.hi = 0;
@@ -129,6 +144,8 @@
 		wrmsr (MTRRphysBase_MSR(reg), base);
 		wrmsr (MTRRphysMask_MSR(reg), mask);
 	}
+	wbinvd();
+	wrmsr(MTRRdefType_MSR,defsave);
 	enable_cache();
 }
 
@@ -262,7 +279,16 @@
 	}
 	return index;
 }
+// Externally visible function to add extra non system memory based mtrr's such
+// as AGP mtrr's - needs to be called after setup_mtrrs
 
+void add_var_mtrr(unsigned long range_startk, unsigned long range_sizek, 
+		unsigned char type)
+{
+	intel_set_var_mtrr(mtrr_count++,range_startk,range_sizek,type);
+
+}
+	
 static unsigned int range_to_mtrr(unsigned int reg, 
 	unsigned long range_startk, unsigned long range_sizek,
 	unsigned long next_range_startk)
@@ -382,6 +408,7 @@
 	}
 	/* Write the last range */
 	reg = range_to_mtrr(reg, range_startk, range_sizek, 0);
+	mtrr_count = reg;
 	printk_debug("DONE variable MTRRs\n");
 	printk_debug("Clear out the extra MTRR's\n");
 	/* Clear out the extra MTRR's */
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 785bf33..f87a590 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -679,6 +679,10 @@
 	/* if a child provides scan_bus(), for example a bridge, scan
 	 * buses behind that child */
 	for (child = bus->children; child; child = child->sibling) {
+		// make sure that we have an ops structure
+		if (!child->ops) {
+			continue;
+		}
 		if (!child->ops->scan_bus) {
 			continue;
 		}
@@ -767,17 +771,17 @@
 {
 	unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
 
-	printk_spew("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
+	printk_debug("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
 	intBits |= (1 << intNum);
 
-	printk_spew("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
+	printk_debug("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
 
 	// Write new values
 	outb((unsigned char) intBits, 0x4d0);
 	outb((unsigned char) (intBits >> 8), 0x4d1);
 
 	/* this seems like an error but is not ... */
-#if 0
+#if 1
 	if (inb(0x4d0) != (intBits & 0xf)) {
 	  printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
 		     __FUNCTION__, intBits &0xf, inb(0x4d0));
diff --git a/src/include/cpu/p6/mtrr.h b/src/include/cpu/p6/mtrr.h
index 92bf62e..b14f710 100644
--- a/src/include/cpu/p6/mtrr.h
+++ b/src/include/cpu/p6/mtrr.h
@@ -34,6 +34,7 @@
 #if !defined(ASSEMBLY)
 
 void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type);
+void add_var_mtrr(unsigned long basek, unsigned long sizek, unsigned char type);
 #if defined(INTEL_PPRO_MTRR) 
 struct mem_range;
 void setup_mtrrs(struct mem_range *mem);
diff --git a/src/mainboard/via/epia-m/Config.lb b/src/mainboard/via/epia-m/Config.lb
index ed43611..8438fcf 100644
--- a/src/mainboard/via/epia-m/Config.lb
+++ b/src/mainboard/via/epia-m/Config.lb
@@ -23,6 +23,7 @@
 uses XIP_ROM_SIZE
 uses XIP_ROM_BASE
 uses HAVE_MP_TABLE
+uses HAVE_ACPI_TABLES
 
 ## ROM_SIZE is the size of boot ROM that this board will use.
 default ROM_SIZE  = 256*1024
@@ -130,6 +131,11 @@
 driver mainboard.o
 #object reset.o
 
+if HAVE_ACPI_TABLES
+	object fadt.o
+	object dsdt.o
+end
+
 ##
 ## Romcc output
 ##
@@ -218,6 +224,14 @@
 		register "enable_keyboard" = "0"
 		register "enable_nvram" = "1"
 	end
+	southbridge ricoh/rl5c476 "rl5c476"
+	end
+	superio via/vt1211 "vt1211"
+		register "enable_com_ports" = "1"
+		register "enable_hwmon" = "1"
+		register "enable_lpt" = "1"
+		register "enable_fdc" = "1"
+	end
 end
 
 cpu p6 "cpu0"
diff --git a/src/mainboard/via/epia-m/auto.c b/src/mainboard/via/epia-m/auto.c
index 88523ed..6fbc830 100644
--- a/src/mainboard/via/epia-m/auto.c
+++ b/src/mainboard/via/epia-m/auto.c
@@ -49,7 +49,7 @@
 
 
 
-#include "northbridge/via/vt8601/raminit.c"
+#include "northbridge/via/vt8623/raminit.c"
 /*
   #include "sdram/generic_sdram.c"
 */
@@ -64,8 +64,9 @@
 	if (dev == PCI_DEV_INVALID) {
 		die("Southbridge not found!!!\n");
 	}
-	pci_write_config8(dev, 0x50, 7);
-	pci_write_config8(dev, 0x51, 0xff);
+	pci_write_config8(dev, 0x50, 0);
+	pci_write_config8(dev, 0x51, 0xfd);
+	pci_write_config8(dev, 0x94, 0xb2);
 #if 0
 	// This early setup switches IDE into compatibility mode before PCI gets 
 	// // a chance to assign I/Os
@@ -97,9 +98,15 @@
 static void main(void)
 {
 	unsigned long x;
+	device_t dev;
 	/*	init_timer();*/
 	outb(5, 0x80);
+
 	
+	pci_write_config8( 0xd*8,0x15,0x1c);
+	pci_write_config8( 0 , 0xe1, 0xdd);
+ 
+	outb(5, 0x80);	
 	enable_smbus();
 	enable_vt8235_serial();
 
diff --git a/src/mainboard/via/epia-m/fadt.c b/src/mainboard/via/epia-m/fadt.c
new file mode 100644
index 0000000..702d556
--- /dev/null
+++ b/src/mainboard/via/epia-m/fadt.c
@@ -0,0 +1,155 @@
+/*
+ * ACPI - create the Fixed ACPI Description Tables (FADT)
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <string.h>
+#include <arch/acpi.h>
+
+void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs,void *dsdt){
+	acpi_header_t *header=&(fadt->header);
+
+	memset((void *)fadt,0,sizeof(acpi_fadt_t));
+	memcpy(header->signature,"FACP",4);
+	header->length = 244;
+	header->revision = 1;
+	memcpy(header->oem_id,"LXBIOS",6);
+	memcpy(header->oem_table_id,"LXBACPI ",8);
+	memcpy(header->asl_compiler_id,"LXB",8);
+	header->asl_compiler_revision=0;
+
+	fadt->firmware_ctrl=facs;
+	fadt->dsdt= dsdt;
+	fadt->preferred_pm_profile=0;
+	fadt->sci_int=5;
+	fadt->smi_cmd = 0;
+	fadt->acpi_enable = 0;
+	fadt->acpi_disable = 0;
+	fadt->s4bios_req = 0x0;
+	fadt->pstate_cnt = 0x0;
+
+	fadt->pm1a_evt_blk = 0x400;
+	fadt->pm1b_evt_blk = 0x0;
+	fadt->pm1a_cnt_blk = 0x404;
+	fadt->pm1b_cnt_blk = 0x0;
+	fadt->pm2_cnt_blk = 0x0;
+	fadt->pm_tmr_blk = 0x408;
+	fadt->gpe0_blk = 0x420;
+	fadt->gpe1_blk = 0x0;
+
+	fadt->pm1_evt_len = 4;
+	fadt->pm1_cnt_len = 2;
+	fadt->pm2_cnt_len = 0;
+	fadt->pm_tmr_len = 4;
+	fadt->gpe0_blk_len = 4;
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+	fadt->cst_cnt = 0;
+	fadt->p_lvl2_lat = 90;
+	fadt->p_lvl3_lat = 900;
+	fadt->flush_size = 0;
+	fadt->flush_stride = 0;
+	fadt->duty_offset = 0;
+	fadt->duty_width = 1;
+	fadt->day_alrm = 125;
+	fadt->mon_alrm = 126;
+	fadt->century = 50;
+	fadt->iapc_boot_arch = 0x1;
+	fadt->flags = 0x4a5;
+
+	fadt->reset_reg.space_id = 0;
+	fadt->reset_reg.bit_width = 0;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.resv = 0;
+	fadt->reset_reg.addrl = 0x0;
+	fadt->reset_reg.addrh = 0x0;
+
+	fadt->reset_value = 0;
+	fadt->x_firmware_ctl_l = facs;
+	fadt->x_firmware_ctl_h = 0;
+	fadt->x_dsdt_l = dsdt;
+	fadt->x_dsdt_h = 0;
+
+	fadt->x_pm1a_evt_blk.space_id = 1;
+	fadt->x_pm1a_evt_blk.bit_width = 4;
+	fadt->x_pm1a_evt_blk.bit_offset = 0;
+	fadt->x_pm1a_evt_blk.resv = 0;
+	fadt->x_pm1a_evt_blk.addrl = 0x400;
+	fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+
+	fadt->x_pm1b_evt_blk.space_id = 1;
+	fadt->x_pm1b_evt_blk.bit_width = 4;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.resv = 0;
+	fadt->x_pm1b_evt_blk.addrl = 0x0;
+	fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+
+	fadt->x_pm1a_cnt_blk.space_id = 1;
+	fadt->x_pm1a_cnt_blk.bit_width = 2;
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.resv = 0;
+	fadt->x_pm1a_cnt_blk.addrl = 0x404;
+	fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+
+	fadt->x_pm1b_cnt_blk.space_id = 1;
+	fadt->x_pm1b_cnt_blk.bit_width = 2;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.resv = 0;
+	fadt->x_pm1b_cnt_blk.addrl = 0x0;
+	fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+
+	fadt->x_pm2_cnt_blk.space_id = 1;
+	fadt->x_pm2_cnt_blk.bit_width = 0;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.resv = 0;
+	fadt->x_pm2_cnt_blk.addrl = 0x0;
+	fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+
+	fadt->x_pm_tmr_blk.space_id = 1;
+	fadt->x_pm_tmr_blk.bit_width = 4;
+	fadt->x_pm_tmr_blk.bit_offset = 0;
+	fadt->x_pm_tmr_blk.resv = 0;
+	fadt->x_pm_tmr_blk.addrl = 0x408;
+	fadt->x_pm_tmr_blk.addrh = 0x0;
+
+
+	fadt->x_gpe0_blk.space_id = 1;
+	fadt->x_gpe0_blk.bit_width = 0;
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.resv = 0;
+	fadt->x_gpe0_blk.addrl = 0x420;
+	fadt->x_gpe0_blk.addrh = 0x0;
+
+
+	fadt->x_gpe1_blk.space_id = 1;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.resv = 0;
+	fadt->x_gpe1_blk.addrl = 0x0;
+	fadt->x_gpe1_blk.addrh = 0x0;
+
+	header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t));
+
+}
diff --git a/src/mainboard/via/epia-m/irq_tables.c b/src/mainboard/via/epia-m/irq_tables.c
index 894c27d..8e8aadc 100644
--- a/src/mainboard/via/epia-m/irq_tables.c
+++ b/src/mainboard/via/epia-m/irq_tables.c
@@ -1,32 +1,30 @@
 /* This file was generated by getpir.c, do not modify! 
    (but if you do, please run checkpir on it to verify)
-   Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
-
-   Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
+ * Contains the IRQ Routing Table dumped directly from your memory, which BIOS sets up
+ *
+ * Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
 */
 
 #include <arch/pirq_routing.h>
 
 const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE, /* u32 signature */
-	PIRQ_VERSION,   /* u16 version   */
-	32+16*5,        /* there can be total 5 devices on the bus */
-	0,              /* Where the interrupt router lies (bus) */
-	0x88,           /* Where the interrupt router lies (dev) */
-	0x1c20,         /* IRQs devoted exclusively to PCI usage */
-	0x1106,         /* Vendor */
-	0x8231,         /* Device */
-	0,              /* Crap (miniport) */
+	PIRQ_SIGNATURE,  /* u32 signature */
+	PIRQ_VERSION,    /* u16 version   */
+	32+16*5,	 /* there can be total 5 devices on the bus */
+	0x00,		 /* Where the interrupt router lies (bus) */
+	(0x00<<3)|0x0,   /* Where the interrupt router lies (dev) */
+	0xc20,		 /* IRQs devoted exclusively to PCI usage */
+	0,		 /* Vendor */
+	0,		 /* Device */
+	0,		 /* Crap (miniport) */
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0x5e,         /*  u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
+	0x68,         /*  u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
 	{
-		/* 8231 ethernet */
-		{0,0x90, {{0x1, 0xdeb8}, {0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}}, 0x1, 0},
-		/* 8231 internal */
-		{0,0x88, {{0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}}, 0x2, 0},
-		/* PCI slot */
-		{0,0xa0, {{0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}, {0x2, 0xdeb8}}, 0, 0},
-		{0,0x50, {{0x4, 0xdeb8}, {0x3, 0xdeb8}, {0x2, 0xdeb8}, {0x1, 0xdeb8}}, 0x3, 0},
-		{0,0x98, {{0x4, 0xdeb8}, {0x3, 0xdeb8}, {0x2, 0xdeb8}, {0x1, 0xdeb8}}, 0x4, 0},
+		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
+		{0x00,(0x14<<3)|0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0x0deb8}}, 0x1, 0x0},
+		{0x00,(0x13<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x2, 0x0},
+		{0x00,(0x0a<<3)|0x0, {{0x04, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0x0deb8}}, 0x3, 0x0},
+		{0x00,(0x0d<<3)|0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0x0deb8}}, 0x4, 0x0},
+		{0x00,(0x01<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x0, 0x0},
 	}
 };
diff --git a/src/mainboard/via/epia-m/mainboard.c b/src/mainboard/via/epia-m/mainboard.c
index 747eb3e..9597392 100644
--- a/src/mainboard/via/epia-m/mainboard.c
+++ b/src/mainboard/via/epia-m/mainboard.c
@@ -9,6 +9,9 @@
 #include <device/chip.h>
 #include "chip.h"
 
+void vga_enable_console();
+
+
 static int
 mainboard_scan_bus(device_t root, int maxbus) 
 {
@@ -19,6 +22,56 @@
 	return maxbus;
 }
 
+void vga_fixup(void) {
+        // we do this right here because:
+        // - all the hardware is working, and some VGA bioses seem to need
+        //   that
+        // - we need page 0 below for linuxbios tables.
+
+        printk_debug("INSTALL REAL-MODE IDT\n");
+        setup_realmode_idt();
+        printk_debug("DO THE VGA BIOS\n");
+        do_vgabios();
+        post_code(0x93);
+	vga_enable_console();
+
+
+}
+ 
+void write_protect_vgabios(void)
+{
+ 	device_t dev;
+ 
+ 	printk_info("write_protect_vgabios\n");
+ 	dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3123, 0);
+ 	if(dev)
+ 		pci_write_config8(dev, 0x61, 0xaa);
+ 
+}
+
+static void
+enable(struct chip *chip, enum chip_pass pass)
+{
+
+        struct mainboard_tyan_s4882_config *conf = 
+		(struct mainboard_tyan_s4882_config *)chip->chip_info;
+
+        switch (pass) {
+		default: break;
+//		case CONF_PASS_PRE_CONSOLE:
+//		case CONF_PASS_PRE_PCI:
+		case CONF_PASS_POST_PCI:		
+//                case CONF_PASS_PRE_BOOT:
+//			if (conf->fixup_scsi)
+//        			onboard_scsi_fixup();
+//			if (conf->fixup_vga)
+//				vga_fixup();
+			printk_debug("mainboard fixup pass %d done\r\n",
+					pass);
+			break;
+	}
+
+}
 static struct device_operations mainboard_operations = {
 	.read_resources   = root_dev_read_resources,
 	.set_resources    = root_dev_set_resources,
@@ -41,5 +94,6 @@
 struct chip_control mainboard_via_epia_m_control = {
 	.enumerate = enumerate, 
 	.name      = "VIA EPIA-M mainboard ",
+	.enable = enable
 };
 
diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c
index db5d831..cba7278 100644
--- a/src/northbridge/via/vt8623/northbridge.c
+++ b/src/northbridge/via/vt8623/northbridge.c
@@ -6,15 +6,16 @@
 #include <device/device.h>
 #include <device/pci.h>
 #include <device/hypertransport.h>
+#include <device/pci_ids.h>
 #include <device/chip.h>
 #include <stdlib.h>
 #include <string.h>
 #include <bitops.h>
+#include <cpu/p6/mtrr.h>
 #include "chip.h"
 #include "northbridge.h"
 
-static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
-	  				0x56, 0x57};
+static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d };
 
 struct mem_range *sizeram(void)
 {
@@ -30,8 +31,9 @@
 		return 0;
 	}
 	mem[0].basek = 0;
-	mem[0].sizek = 65536;
-	idx = 1;
+	mem[0].sizek = 0xa0000 >>10; // first 640k
+	mem[1].basek = 0xc0000 >>10; // leave a hole for vga
+	idx = 2;
 	while(idx < sizeof(mem)/sizeof(mem[0])) {
 		mem[idx].basek = 0;
 		mem[idx].sizek = 0;
@@ -53,8 +55,8 @@
 				ramregs[i]);
 	}
 	
-	printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
-	mem[0].sizek = rambits*8*1024;
+	printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024);
+	mem[1].sizek = rambits*16*1024 - 32768 - (0xc0000 >> 10);
 #if 1
 	for(i = 0; i < idx; i++) {
 		printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
@@ -78,18 +80,65 @@
  * Apparently these registers govern some sort of bus master behavior.
  */
 static void random_fixup() {
-	device_t pcidev = dev_find_slot(0, 0);
+	device_t pcidev0 = dev_find_slot(0, 0);
+	device_t pcidev1,pcidev2;
+	unsigned long fb;
+	unsigned char c;
 
-	printk_spew("VT8623 random fixup ...\n");
-	if (pcidev) {
-		pci_write_config8(pcidev, 0x70, 0xc0);
-		pci_write_config8(pcidev, 0x71, 0x88);
-		pci_write_config8(pcidev, 0x72, 0xec);
-		pci_write_config8(pcidev, 0x73, 0x0c);
-		pci_write_config8(pcidev, 0x74, 0x0e);
-		pci_write_config8(pcidev, 0x75, 0x81);
-		pci_write_config8(pcidev, 0x76, 0x52);
+	printk_debug("VT8623 random fixup ...\n");
+	if (pcidev0) {
+		pci_write_config8(pcidev0, 0x0d, 0x08);
+		pci_write_config8(pcidev0, 0x70, 0x82);
+		pci_write_config8(pcidev0, 0x71, 0xc8);
+		pci_write_config8(pcidev0, 0x72, 0x0);
+		pci_write_config8(pcidev0, 0x73, 0x01);
+		pci_write_config8(pcidev0, 0x74, 0x01);
+		pci_write_config8(pcidev0, 0x75, 0x08);
+		pci_write_config8(pcidev0, 0x76, 0x52);
+		pci_write_config8(pcidev0, 0x13, 0xd0);
+		pci_write_config8(pcidev0, 0x84, 0x80);
+		pci_write_config16(pcidev0,0x80, 0x610f);
+		pci_write_config32(pcidev0,0x88, 0x02);
 	}
+	printk_debug("VT8623 AGP random fixup ...\n");
+	pcidev1 = dev_find_device(PCI_VENDOR_ID_VIA,0xb091,0);
+	if( pcidev1) {
+		pci_write_config8(pcidev1,0x3e,0x0c);
+		pci_write_config8(pcidev1,0x40,0x83);
+		pci_write_config8(pcidev1,0x41,0xc5);
+		pci_write_config8(pcidev1,0x43,0x44);
+		pci_write_config8(pcidev1,0x44,0x34);
+		pci_write_config8(pcidev1,0x83,0x02);
+	}
+	printk_debug("VGA random fixup ...\n");
+	pcidev2 = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
+	if( pcidev2 ){
+		pci_write_config8(pcidev2,0x04,0x07);
+		pci_write_config8(pcidev2,0x0d,0x20);
+	}
+	// fixup GART and framebuffer addresses properly
+	// first set up frame buffer properly
+	fb = pci_read_config32(pcidev2,0x10);  // base address of framebuffer
+	printk_debug("Frame buffer at %8x\n",fb);
+	c = pci_read_config8(pcidev0,0xe1) & 0xf0;    // size of vga
+	c |= fb>>28;  // upper nibble of frame buffer address
+	pci_write_config8(pcidev0,0xe1,c);
+	c = (fb>>20) | 1; // enable framebuffer
+	pci_write_config8(pcidev0,0xe0,c);
+	pci_write_config8(pcidev0,0xe2,0x42); // 'cos award does
+
+	
+}
+static void set_vga_mtrrs(void)
+{
+	device_t pcidev = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
+	unsigned long fb;
+
+	add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
+	fb = pci_read_config32(pcidev,0x10); // get the fb address
+	add_var_mtrr( fb>>10, 8192, MTRR_TYPE_WRCOMB);
+	
+
 }
 
 static void northbridge_init(struct chip *chip, enum chip_pass pass)
@@ -103,10 +152,11 @@
 		break;
 		
 	case CONF_PASS_POST_PCI:
+		random_fixup();
 		break;
 		
 	case CONF_PASS_PRE_BOOT:
-		random_fixup();
+		set_vga_mtrrs();
 		break;
 		
 	default:
diff --git a/src/northbridge/via/vt8623/raminit.c b/src/northbridge/via/vt8623/raminit.c
index f7c0a10..10086a0 100644
--- a/src/northbridge/via/vt8623/raminit.c
+++ b/src/northbridge/via/vt8623/raminit.c
@@ -47,16 +47,17 @@
 #define DIMM_CL2 0
 #endif
 
-void dimms_read(unsigned long x) 
+
+
+
+
+void dimm_read(unsigned long x) 
 {
-	uint8_t c;
 	unsigned long eax; 
 	volatile unsigned long y;
 	eax =  x;
-	for(c = 0; c < 6; c++) {
-		y = * (volatile unsigned long *) eax;
-		eax += 0x10000000;
-	}
+	y = * (volatile unsigned long *) eax;
+
 }
 
 void dimms_write(int x) 
@@ -88,7 +89,7 @@
 void
 dumpnorth(device_t north) 
 {
-	uint8_t r, c;
+	uint16_t r, c;
 	for(r = 0; r < 256; r += 16) {
 		print_debug_hex8(r);
 		print_debug(":");
@@ -106,7 +107,7 @@
 	uint8_t c, r;
 
 	print_err("vt8623 init starting\r\n");
-	north = pci_locate_device(PCI_ID(0x1106, 0x8623), 0);
+	north = pci_locate_device(PCI_ID(0x1106, 0x3123), 0);
 	north = 0;
 	print_debug_hex32(north);
 	print_debug(" is the north\n");
@@ -118,66 +119,57 @@
 	/* All we are doing now is setting initial known-good values that will
 	 * be revised later as we read SPD
 	 */	
-	// memory clk enable. We are not using ECC
-	pci_write_config8(north,0x78, 0x01);
-	print_debug_hex8(pci_read_config8(north, 0x78));
-	// dram control, see the book. 
-#if DIMM_PC133
-	pci_write_config8(north,0x68, 0x52);
-#else
-	pci_write_config8(north,0x68, 0x42);
-#endif
-	// dram control, see the book. 
-	pci_write_config8(north,0x6B, 0x0c);
-	// Initial setting, 256MB in each bank, will be rewritten later.
-	pci_write_config8(north,0x5A, 0x20);
-	print_debug_hex8(pci_read_config8(north, 0x5a));
-	pci_write_config8(north,0x5B, 0x40);
-	pci_write_config8(north,0x5C, 0x60);
-	pci_write_config8(north,0x5D, 0x80);
-	pci_write_config8(north,0x5E, 0xA0);
-	pci_write_config8(north,0x5F, 0xC0);
-	// It seems we have to take care of these 2 registers as if 
-	// they are bank 6 and 7.
-	pci_write_config8(north,0x56, 0xC0);
-	pci_write_config8(north,0x57, 0xC0);
+
+	pci_write_config8(north,0x75,0x08);
+
+	/* since we only support epia-m at the moment, only ddr is supported */
+	/* setup cpu */
+	pci_write_config8(north,0x50,0xc8);
+	pci_write_config8(north,0x51,0xde);
+	pci_write_config8(north,0x52,0xcf);
+	pci_write_config8(north,0x53,0x88);
+	pci_write_config8(north,0x55,0x07);
+
+	/* DRAM MA Map Type */
+	pci_write_config8(north,0x58,0xe0);
+
+	/* DRAM bank 0 - 3 size = 512M */
+	pci_write_config8(north,0x5a,0x10);
+	pci_write_config8(north,0x5b,0x10);
+	pci_write_config8(north,0x5c,0x10);
+	pci_write_config8(north,0x5d,0x10);
+
+	/* set DRAM timing for all banks */
+	pci_write_config8(north,0x64,0xe6);
+
+	/* set DRAM type to DDR */
+	pci_write_config8(north,0x60,0x02);
+
+
+	/* DRAM arbitration timer */
+	pci_write_config8(north,0x65,0x32);
+	pci_write_config8(north,0x66,0x01);
+	pci_write_config8(north,0x68,0x59);
+
+
+	/* DRAM Frequency */
+	pci_write_config8(north,0x54,0xe0);
+	pci_write_config8(north,0x69,0x2d);
+
+	/* Enable CKE */
+	pci_write_config8(north,0x6b,0x10);
 	
-	// SDRAM in all banks
-	pci_write_config8(north,0x60, 0x3F);
-	// DRAM timing. I'm suspicious of this
-	// This is for all banks, 64 is 0,1.  65 is 2,3. 66 is 4,5.
-	// ras precharge 4T, RAS pulse 5T
-	// cas2 is 0xd6, cas3 is 0xe6
-	// we're also backing off write pulse width to 2T, so result is 0xee
-#if DIMM_CL2
-	pci_write_config8(north,0x64, 0xd4);
-	pci_write_config8(north,0x65, 0xd4);
-	pci_write_config8(north,0x66, 0xd4);
-#else // CL=3
-	pci_write_config8(north,0x64, 0xe4);
-	pci_write_config8(north,0x65, 0xe4);
-	pci_write_config8(north,0x66, 0xe4);
-#endif
+	/* Disable DRAM refresh */
+	pci_write_config8(north,0x6a,0x0);
 
-	// dram frequency select.
-	// enable 4K pages for 64M dram. 
-#if DIMM_PC133
-	pci_write_config8(north,0x69, 0x3c);
-#else
-	pci_write_config8(north,0x69, 0xac);
-#endif
+	/* set heavy drive */
+	pci_write_config8(north,0x6d,0x44);
 
-	/* IMPORTANT -- disable refresh counter */
-	// refresh counter, disabled.
-	pci_write_config8(north,0x6A, 0x00);
-	
 
-	// clkenable configuration. kevinh FIXME - add precharge
-	pci_write_config8(north,0x6C, 0x00);
-	// dram read latch delay of 1 ns, MD drive 8 mA,
-	// high drive strength on MA[2:	13], we#, cas#, ras#
-	// As per Cindy Lee, set to 0x37, not 0x57
-	pci_write_config8(north,0x6D, 0x7f);
+	pci_write_config8(north,0x61,0xff);
+
+
+
 }
 
 /* slot is the dram slot. Return size of side0 in lower 16-bit,
@@ -291,104 +283,87 @@
 	};
 	device_t north = 0;
 	uint32_t size, base, slot, ma;
-	/* begin to initialize*/
-	// I forget why we need this, but we do
-	dimms_write(0xa55a5aa5);
 	
-	/* set NOP*/
-	pci_write_config8(north,0x6C, 0x01);
-	print_debug("NOP\r\n");
-	/* wait 200us*/
-	// You need to do the memory reference. That causes the nop cycle. 
-	dimms_read(0);
-	udelay(400);
-	print_debug("PRECHARGE\r\n");
-	/* set precharge */
-	pci_write_config8(north,0x6C, 0x02);
-	print_debug("DUMMY READS\r\n");
-	/* dummy reads*/
-	dimms_read(0);
-	udelay(200);
-	print_debug("CBR\r\n");
-	/* set CBR*/
-	pci_write_config8(north,0x6C, 0x04);
-	
-	/* do 8 reads and wait >100us between each - from via*/
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	dimms_read(0);
-	udelay(200);
-	print_debug("MRS\r\n");
-	/* set MRS*/
-	pci_write_config8(north,0x6c, 0x03);
-#if DIMM_CL2
-	dimms_read(0x150);
-#else // CL=3
-	dimms_read(0x1d0);
-#endif
-	udelay(200);
-	print_debug("NORMAL\r\n");
-	/* set to normal mode */
-	pci_write_config8(north,0x6C, 0x08);
-	
-	dimms_write(0x55aa55aa);
-	dimms_read(0);
-	udelay(200);
-	print_debug("set ref. rate\r\n");
-	// Set the refresh rate. 
-#if DIMM_PC133
-	pci_write_config8(north,0x6A, 0x86);
-#else
-	pci_write_config8(north,0x6A, 0x65);
-#endif
-	print_debug("enable multi-page open\r\n");
-	// enable multi-page open
-	pci_write_config8(north,0x6B, 0x0d);
-	
-	base = 0;
-	for(slot = 0; slot < 4; slot++) {
-		size = spd_module_size(slot);
-		/* side 0 */
-		base += size & 0xffff;
-		pci_write_config8(north, ramregs[2*slot], base);
-		/* side 1 */
-		base += size >> 16;
-		if (base > 0xff)
-			base = 0xff;
-		pci_write_config8(north, ramregs[2*slot + 1], base);
 
-		if (!size)
-			continue;
+	/* NOP command enable */
+	pci_write_config8(north,0x6b,0x01);
 
-		/* Calculate the value of MA mapping type register,
-		 * based on size of SDRAM chips. */
-		size = (size & 0xffff) << (3 + 3);
-			/* convert module size to be in Mbits */
-		size /= spd_num_chips(slot);
-		print_debug_hex16(size);
-		print_debug(" is the chip size\r\n");
-		if (size < 64)
-			ma = 0;
-		if (size < 256)
-			ma = 8;
-		else
-			ma = 0xe;
-		print_debug_hex16(ma);
-		print_debug(" is the MA type\r\n");
-		set_ma_mapping(north, slot, ma);
-	}
-	print_err("vt8623 done\r\n");
+	/* read a double word from any addree of the dimm */
+	dimm_read(0x1f000);
+	udelay(200);
+
+	/* All bank precharge Command Enable */
+	pci_write_config8(north,0x6b,0x02);
+	dimm_read(0x1f000);
+
+	/* MSR Enable */
+	pci_write_config8(north,0x6b,0x03);
+	dimm_read(0x2000);
+
+	dimm_read(0x800);
+
+	/* All banks precharge Command Enable */
+	pci_write_config8(north,0x6b,0x02);
+	dimm_read(0x1f200);
+
+	/* CBR Cycle Enable */
+	pci_write_config8(north,0x6b,0x04);
+
+	/* Read 8 times */
+	dimm_read(0x1f300);
+	udelay(100);
+	dimm_read(0x1f400);
+	udelay(100);
+	dimm_read(0x1f500);
+	udelay(100);
+	dimm_read(0x1f600);
+	udelay(100);
+	dimm_read(0x1f700);
+	udelay(100);
+	dimm_read(0x1f800);
+	udelay(100);
+	dimm_read(0x1f900);
+	udelay(100);
+	dimm_read(0x1fa00);
+	udelay(100);
+
+	/* MSR Enable */
+	pci_write_config8(north,0x6b,0x03);
+
+	/* 0x150 if CAS Latency 2 or 0x350 CAS Latency 2.5 */
+	dimm_read(0x350);
+
+	/* Normal SDRAM Mode */
+	pci_write_config8(north,0x6b,0x58 );
+
+
+	/* Set the refresh rate */
+	pci_write_config8(north,0x6a,0x43);
+	pci_write_config8(north,0x67,0x22);
+
+	/* pci */
+	pci_write_config8(north,0x70,0x82);
+	pci_write_config8(north,0x73,0x01);
+	pci_write_config8(north,0x76,0x50);
+
+
+	pci_write_config8(north,0x71,0xc8);
+	
+
+	/* graphics aperture base */
+	pci_write_config8(north,0x13,0xd0);
+
+	//pci_write_config8(north,0x56,0x10);
+	//pci_write_config8(north,0x57,0x10);
+
+	pci_write_config8(north,0xe0,0x80);
+	pci_write_config8(north,0xe1,0xdf);
+	pci_write_config8(north,0xe2,0x42);
+
+	pci_write_config8(north,0xa8,0x04);
+	pci_write_config8(north,0xac,0x2f);
+	pci_write_config8(north,0xae,0x04);
+
+        print_err("vt8623 done\r\n");
 	dumpnorth(north);
 }
diff --git a/src/pc80/Config.lb b/src/pc80/Config.lb
index 1261abf..fb00418 100644
--- a/src/pc80/Config.lb
+++ b/src/pc80/Config.lb
@@ -3,7 +3,7 @@
 
 object mc146818rtc.o
 object isa-dma.o
-#object i8259.o CONFIG_I8259
+object i8259.o 
 #object udelay_timer2.o CONFIG_UDELAY_TIMER2
 #object beep.o CONFIG_BEEP
 #object vga_load_regs.o VIDEO_CONSOLE
diff --git a/src/pc80/keyboard.c b/src/pc80/keyboard.c
index d293f71..331f5ab 100644
--- a/src/pc80/keyboard.c
+++ b/src/pc80/keyboard.c
@@ -5,7 +5,7 @@
 
 /* much better keyboard init courtesy ollie@sis.com.tw 
    TODO: Typematic Setting, the keyboard is too slow for me */
-static void pc_keyboard_init(struct pc_keyboard *keyboard)
+void pc_keyboard_init(struct pc_keyboard *keyboard)
 {
 	volatile unsigned char regval;
 
diff --git a/src/pc80/vgabios.c b/src/pc80/vgabios.c
index c83498e..a6806d3 100644
--- a/src/pc80/vgabios.c
+++ b/src/pc80/vgabios.c
@@ -1,8 +1,10 @@
-#include <pci.h>
-#include <pci_ids.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
 #undef __KERNEL__
 #include <arch/io.h>
-#include <printk.h>
+//#include <printk.h>
 #include <string.h>
 #include "vgachip.h"
 
@@ -121,6 +123,8 @@
 		"    mov  %ax, %es          \n"
 		"    mov  %ax, %fs          \n"
 		"    mov  %ax, %gs          \n"
+		"    mov  $0x40, %ax          \n"
+		"    mov  %ax, %ds          \n"
 		"    mov %cx, %ax	\n"
 		" .byte 0x9a, 0x03, 0, 0, 0xc0  \n"
 		" movb $0x55, %al\noutb %al, $0x80\n"
@@ -151,10 +155,99 @@
 __asm__ (".text\n""real_mode_switch_end:\n");
 extern char real_mode_switch_end[];
 
+/* call vga bios int 10 function 0x4f14 to enable main console 
+   epia-m does not always autosence the main console so forcing it on is good !! */
+ 
+void vga_enable_console()
+{
+	__asm__ __volatile__ (
+		// paranoia -- does ecx get saved? not sure. This is 
+		// the easiest safe thing to do.
+		"	pushal\n"
+		/* save the stack */
+		"	mov %esp, __stack\n"
+
+		/*  This configures CS properly for real mode. */
+		"	ljmp $0x28, $__vga_ec_16bit\n"
+		"__vga_ec_16bit:                 \n"
+		".code16                      \n"
+		/* 16 bit code from here on... */
+
+		/* Load the segment registers w/ properly configured segment
+		 * descriptors.  They will retain these configurations (limits,
+		 * writability, etc.) once protected mode is turned off. */
+		"	mov  $0x30, %ax         \n"
+		"	mov  %ax, %ds          \n"
+		"	mov  %ax, %es          \n"
+		"	mov  %ax, %fs          \n"
+		"	mov  %ax, %gs          \n"
+		"	mov  %ax, %ss          \n"
+
+		/* Turn off protection (bit 0 in CR0) */
+		"	movl %cr0, %eax        \n"
+		"	andl $0xFFFFFFFE, %eax  \n"
+		"	movl %eax, %cr0        \n"
+
+		/* Now really going into real mode */
+		"	ljmp $0,  $__vga_ec_real \n"
+		"__vga_ec_real:                  \n"
+
+		// put the stack at the end of page zero. 
+		// that way we can easily share it between real and protected, 
+		// since the 16-bit ESP at segment 0 will work for any case. 
+		/* Setup a stack */
+		"    mov  $0x0, %ax       \n"
+		"    mov  %ax, %ss          \n"
+		"    movl  $0x1000, %eax       \n"
+		"    movl  %eax, %esp          \n"
+		/* debugging for RGM */
+		"    mov $0x11, %al	\n"
+		" outb	%al, $0x80\n"
+
+		/* Dump zeros in the other segregs */
+		"    xor  %ax, %ax          \n"
+		"    mov  %ax, %ds          \n"
+		"    mov  %ax, %es          \n"
+		"    mov  %ax, %fs          \n"
+		"    mov  %ax, %gs          \n"
+		/* ask bios to enable main console */
+		/* set up for int 10 call - values found from X server bios call routines */
+		"    movw $0x4f14,%ax    \n"
+		"    movw $0x8003,%bx     \n"
+		"    movw $1, %cx          \n"
+		"    movw $0, %dx          \n"
+		"    movw $0, %di          \n"
+		"  .byte 0xcd, 0x10             \n"
+		" movb $0x55, %al\noutb %al, $0x80\n"
+		/* if we got here, just about done. 
+		 * Need to get back to protected mode */
+		"movl	%cr0, %eax\n"
+		//       "andl	$0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
+		//	"orl	$0x60000001, %eax\n" /* CD, NW, PE = 1 */
+		"orl	$0x0000001, %eax\n" /* PE = 1 */
+		"movl	%eax, %cr0\n"
+		/* Now that we are in protected mode jump to a 32 bit code segment. */
+		"data32	ljmp	$0x10, $vga_ec_restart\n"
+		"vga_ec_restart:\n"
+		".code32\n"
+		"    movw $0x18, %ax          \n"
+		"    mov  %ax, %ds          \n"
+		"    mov  %ax, %es          \n"
+		"    mov  %ax, %fs          \n"
+		"    mov  %ax, %gs          \n"
+		"    mov  %ax, %ss          \n"
+		".globl vga__ec_exit\n"
+		"vga_ec_exit:\n"
+		"    mov  __stack, %esp\n"
+		"    popal\n"
+		);
+}
+
+
 void
 do_vgabios(void)
 {
-	struct pci_dev *dev;
+	device_t dev;
 	unsigned long busdevfn;
 	unsigned int rom = 0;
 	unsigned char *buf;
@@ -162,17 +255,17 @@
 	int i;
 	
 	for (i=0x400; i<0x500; i++) {
-		printk_debug("%02x%c", *(unsigned char *)i,
-			     i%16==15 ? '\n' : ' ');
+		//printk_debug("%02x%c", *(unsigned char *)i,
+		//	     i%16==15 ? '\n' : ' ');
 		*(unsigned char *) i = 0;
 	}
 
-	for (i=0x400; i<0x500; i++) {
+/*	for (i=0x400; i<0x500; i++) {
 		printk_debug("%02x%c", *(unsigned char *)i,
 			     i%16==15 ? '\n' : ' ');
 	}
-
-	dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
+*/
+	dev = dev_find_class(PCI_CLASS_DISPLAY_VGA<<8 , 0);
 
 	if (! dev) {
 		printk_debug("NO VGA FOUND\n");
@@ -184,7 +277,7 @@
 	// Use VGA BIOS blob at specified address
 	rom = VGABIOS_START;
 #else
-	pci_read_config32(dev, PCI_ROM_ADDRESS, &rom);
+	rom = pci_read_config32(dev, PCI_ROM_ADDRESS);
 	// paranoia
 	rom = 0xf0000000;
 	pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
@@ -193,12 +286,28 @@
 	buf = (unsigned char *) rom;
 	if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
 		memcpy((void *) 0xc0000, buf, size);
+
+#define VGABIOS_WRITE_PROTECT 1
+#ifdef VGABIOS_WRITE_PROTECT
+		write_protect_vgabios();
+#endif
+
+	  	for(i = 0; i < 16; i++)
+	    		printk_debug("0x%x ", buf[i]);
+	  	// check signature again
+		buf = (unsigned char *) 0xc0000;
+		if (buf[0]==0x55 && buf[1]==0xAA) {
+			busdevfn = (dev->bus->secondary << 8) | dev->path.u.pci.devfn;
+			printk_debug("bus/devfn = %#x\n", busdevfn);
+
+		    	real_mode_switch_call_vga(busdevfn);
+			//for( i = 0 ; i < 0x500; i++){
+			//	printk_debug("%02x%c",*(unsigned char *)i,
+			//		i%16 == 15 ? '\n':' ');
+			//}
+		} else
+			printk_debug("Failed to copy VGA BIOS to 0xc0000\n");
 		
-		for(i = 0; i < 16; i++)
-			printk_debug("0x%x ", buf[i]);
-		// check signature here later!
-		busdevfn = (dev->bus->secondary << 8) | dev->devfn;
-		real_mode_switch_call_vga(busdevfn);
 	} else 
 		printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
 #ifndef VGABIOS_START
@@ -253,6 +362,10 @@
 	__asm__ __volatile__ (
 		".code16\n"
 		"callbiosint16:\n"
+		" push %ds \n"
+		" push %es \n"
+		" push %fs \n"
+		" push %gs \n"
 		// clean up the int #. To save space we put it in the lower
 		// byte. But the top 24 bits are junk. 
 		"andl $0xff, %eax\n"
@@ -277,8 +390,8 @@
 		"    mov  %ax, %ss          \n"
 		"	call	biosint	\n"
 		// back to real mode ...
-		"    ljmp $0x28, $__rms_16bit\n"
-		"__rms_16bit:                 \n"
+		"    ljmp $0x28, $__rms_16bit2\n"
+		"__rms_16bit2:                 \n"
 		".code16                      \n" /* 16 bit code from here on... */
 		
 		/* Load the segment registers w/ properly configured segment
@@ -297,8 +410,8 @@
 		"    movl %eax, %cr0        \n"
 		
 		/* Now really going into real mode */
-		"    ljmp $0,  $__rms_real \n"
-		"__rms_real:                  \n"
+		"    ljmp $0,  $__rms_real2 \n"
+		"__rms_real2:                  \n"
 		
 		/* Setup a stack */
 		"    mov  $0x0, %ax       \n"
@@ -311,10 +424,16 @@
 		"    mov  %ax, %es          \n"
 		"    mov  %ax, %fs          \n"
 		"    mov  %ax, %gs          \n"
+		"    mov  $0x40, %ax        \n"
+		"    mov  %ax, %ds          \n"
 		// pop the INT # that you pushed earlier
 		"   popl	%eax\n"
-		" 	popal\n"
-		"	iret\n"
+		"   pop %gs \n"
+		"   pop %fs \n"
+		"   pop %es \n"
+		"   pop %ds \n"
+		"   popal\n"
+		"   iret\n"
 		".code32\n"
 		);
 }
@@ -336,12 +455,26 @@
         unsigned long *peax,
         unsigned long *pflags
         );
+int
+handleint21(
+        unsigned long *pedi,
+        unsigned long *pesi,
+        unsigned long *pebp,
+        unsigned long *pesp,
+        unsigned long *pebx,
+        unsigned long *pedx,
+        unsigned long *pecx,
+        unsigned long *peax,
+        unsigned long *pflags
+        );
 
 extern void vga_exit(void);
 
 int
 biosint(
 	unsigned long intnumber,
+	unsigned long gsfs,
+	unsigned long dses,
 	unsigned long edi, 
 	unsigned long esi,
 	unsigned long ebp, 
@@ -393,8 +526,12 @@
 		eax = 64 * 1024;
 		ret = 0;
 		break;
+	case 0x15:
+		ret=handleint21( &edi, &esi, &ebp, &esp, 
+				&ebx, &edx, &ecx, &eax, &flags);
+		break;
 	default:
-		printk_info(__FUNCTION__ ": Unsupport int #0x%x\n", 
+		printk_info("BIOSINT: Unsupport int #0x%x\n", 
 			    intnumber);
 		break;
 	}
@@ -491,7 +628,7 @@
 	unsigned short devid, vendorid, devfn;
 	short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
 	unsigned char bus;
-	struct pci_dev *dev;
+	device_t dev;
 	
 	switch(func) {
 	case  CHECK:
@@ -505,7 +642,7 @@
 		vendorid = *pedx;
 		devindex = *pesi;
 		dev = 0;
-		while ((dev = pci_find_device(vendorid, devid, dev))) {
+		while ((dev = dev_find_device(vendorid, devid, dev))) {
 			if (devindex <= 0)
 				break;
 			devindex--;
@@ -516,7 +653,7 @@
 			// busnum is an unsigned char;
 			// devfn is an int, so we mask it off. 
 			busdevfn = (dev->bus->secondary << 8)
-				| (dev->devfn & 0xff);
+				| (dev->path.u.pci.devfn & 0xff);
 			printk_debug("0x%x: return 0x%x\n", func, busdevfn);
 			*pebx = busdevfn;
 			retval = 0;
@@ -541,7 +678,7 @@
 		devfn = *pebx & 0xff;
 		bus = *pebx >> 8;
 		reg = *pedi;
-		dev = pci_find_slot(bus, devfn);
+		dev = dev_find_slot(bus, devfn);
 		if (! dev) {
 			printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
 			// idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
@@ -563,15 +700,15 @@
 			break;
 		case WRITECONFBYTE:
 			byte = *pecx;
-			write_config8(dev, reg, byte);
+			pci_write_config8(dev, reg, byte);
 			break;
 		case WRITECONFWORD:
 			word = *pecx;
-			write_config16(dev, reg, word);
+			pci_write_config16(dev, reg, word);
 			break;
 		case WRITECONFDWORD:
-			word = *pecx;
-			write_config32(dev, reg, dword);
+			dword = *pecx;
+			pci_write_config32(dev, reg, dword);
 			break;
 		}
 		
@@ -590,31 +727,46 @@
 	return retval;
 } 
 
-static void vga_init(struct chip *chip, enum chip_pass pass)
-{
 
-	struct pc80_vgabios_config *conf = 
-		(struct pc80_vgabios_config *)chip->chip_info;
-	
-	switch (pass) {
-	case CONF_PASS_PRE_BOOT:
-		
+
+int handleint21( unsigned long *edi, unsigned long *esi, unsigned long *ebp,
+			  unsigned long *esp, unsigned long *ebx, unsigned long *edx,
+			  unsigned long *ecx, unsigned long *eax, unsigned long *flags)
+{
+int res=-1;
+	switch(*eax&0xffff)
+	{
+	case 0x5f19:
 		break;
-		
-	default:
-		/* nothing yet */
+	case 0x5f18:
+		*eax=0x5f;
+		*ebx=0x545; // MCLK = 133, 32M frame buffer, 256 M main memory
+		// *ebx = 0x515;  // MCLK = 133, 32M frame buffer, 128 M main memory
+		*ecx=0x060;
+		res=0;
+		break;
+	case 0x5f00:
+		*eax = 0x8600;
+		break;
+	case 0x5f01:
+		*eax = 0x5f;
+		*ecx = (*ecx & 0xffffff00 ) | 2; // panel type =  2 = 1024 * 768
+		res = 0;
+		break;
+	case 0x5f02:
+		*eax=0x5f;
+		*ebx= (*ebx & 0xffff0000) | 2;
+		*ecx= (*ecx & 0xffff0000) | 0x401;  // PAL + crt only 
+		*edx= (*edx & 0xffff0000) | 0;  // TV Layout - default
+		res=0;
+		break;
+	case 0x5f0f:
+		*eax=0x860f;
+		//*ebx=0;
+		//*ecx=0;
+		//*edx=0;
+		//res=0;
 		break;
 	}
+	return res;
 }
-
-static void enumerate(struct chip *chip)
-{
-	/* don't really need to do anything */
-
-}
-
-struct chip_control southbridge_via_vt8231_control = {
-	.enumerate = enumerate,
-	.enable    = vga_init,
-	.name      = "Legacy VGA bios"
-};
diff --git a/src/southbridge/ricoh/rl5c476/Config.lb b/src/southbridge/ricoh/rl5c476/Config.lb
new file mode 100644
index 0000000..05c7739
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object rl5c476.o
diff --git a/src/southbridge/ricoh/rl5c476/chip.h b/src/southbridge/ricoh/rl5c476/chip.h
new file mode 100644
index 0000000..d951a8a
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/chip.h
@@ -0,0 +1,10 @@
+#ifndef _SOUTHBRIDGE_RICOH_RL5C476
+#define _SOUTHBRIDGE_RICOH_RL5C476
+
+extern struct chip_control southbridge_ricoh_rl5c476_control;
+
+struct southbridge_ricoh_rl5c476_config {
+	int num;
+};
+
+#endif /* _SOUTHBRIDGE_RL5C476 */
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.c b/src/southbridge/ricoh/rl5c476/rl5c476.c
new file mode 100644
index 0000000..c6cb55c
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.c
@@ -0,0 +1,255 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <device/chip.h>
+#include <console/console.h>
+#include "rl5c476.h"
+#include "chip.h"
+
+static void udelay(int i){
+	for(; i > 0 ; i--)
+		inb(0x80);
+
+}
+
+static void
+dump_south(void)
+{
+	device_t dev0;
+	dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
+	dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev0);
+	int i,j;
+	
+	for(i = 0; i < 256; i += 16) {
+		printk_debug("0x%x: ", i);
+		for(j = 0; j < 16; j++) {
+			printk_debug("%02x ", pci_read_config8(dev0, i+j));
+		}
+		printk_debug("\n");
+	}
+	printk_debug("Card32\n");
+	for(i = 0 ; i < 256 ; i+=16){
+		printk_debug("0x%x: ",i);
+		for(j = 0 ; j < 16 ; j++){
+			printk_debug(" %02x",*(unsigned char *)(0x80000000+i+j));
+		}
+		printk_debug("\n");
+	}
+	printk_debug("Card16\n");
+	for(i = 0; i < 256; i += 16) {
+		printk_debug("0x%x: ", i);
+		for(j = 0; j < 16; j++) {
+			printk_debug("%02x ", *(unsigned char *)(0x80000800+ i+j));
+		}
+		printk_debug("\n");
+	}
+	printk_debug("CF Config\n");
+	for(i = 0 ; i < 256 ; i+=16){
+		printk_debug("0x%x: ",i);
+		for(j=0 ; j < 16 ; j++){
+			printk_debug("%02x ",*(unsigned char *)(0x81000200 + i + j));
+		}
+		printk_debug("\n");
+	}
+}
+
+
+static void rl5c476_init(struct southbridge_rl5c476_config *conf)
+{
+	//unsigned char enables;
+	device_t dev;
+	pc16reg_t *pc16;
+	int i;
+
+	printk_debug("rl5c476 init\n");
+	/* cardbus controller function 1 for CF Socket */
+	dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
+
+	if (!dev ){
+		// probably an epia-m rather than mii
+		printk_debug("No rl5c476 found\n");
+		return;
+	}	
+
+	/* setup pci header manually because 'pci_device.c' doesn't know how to handle
+         * pci to cardbus bridges - (header type 2 I think)
+	 */
+
+
+	/* initialize function zero - pcmcia socket so it behaves itself */
+	/* FIXME - statically put control memory at 0xe0000000 for now
+	 * one day the pci_device allocator might do this */
+	pci_write_config32(dev,0x10,0xe0000000);
+	pci_write_config8(dev,0x0d,0x20);
+	pci_write_config8(dev,0x19,0x02);
+	pci_write_config8(dev,0x1a,0x02);
+	pci_write_config8(dev,0x1b,0x20);
+	//pci_write_config8(dev,0x3c,0);
+	pci_write_config8(dev,0x82,0x00a0);
+	pci_write_config16(dev,0x04,0x07);
+
+	
+	/* get second function - i.e. compact flash socket */
+	dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev);
+
+
+	/* FIXME - control structure statically declared at 0xe0008000 for now */
+	pci_write_config32(dev,0x10,0xe0008000);
+	pci_write_config8(dev,0x0d,0x20);
+	pci_write_config8(dev,0x19,0x03);
+	pci_write_config8(dev,0x1a,0x03);
+	pci_write_config8(dev,0x1b,0x20);
+
+	//pci_write_config8(dev,0x3c,0x0);
+	pci_write_config16(dev,0x3e,0x0780);
+	pci_write_config16(dev,0x82,0x00a0);
+
+	pci_write_config16(dev,0x04,0x07);
+
+
+	/* pick up where 16 bit card control structure is */
+	pc16 = (pc16reg_t *)(0xe0008800);
+
+	/* disable memory and io windows and turn off socket power */
+	pc16->pwctrl = 0;
+
+	/* disable irq lines */
+	pc16->igctrl = 0;
+
+	/* disable memory and I/O windows */
+	pc16->awinen = 0;
+
+	/* reset card, configure for I/O and set IRQ line */
+	pc16->igctrl = 0x69;
+
+
+	// set io window 0 for 1e8 - 1ef
+	pc16->iostl0 = 0xe8;
+	pc16->iosth0 = 1;
+
+	pc16->iospl0 = 0xef;
+	pc16->iosph0 = 1;
+
+	// add io offset of 8 so that CF card will decode 0x1e8 as 0x1f0 i.e. the first byte of
+	// a 16 byte aligned, 16 byte window etc
+	pc16->ioffl0 = 0x8;
+	pc16->ioffh0 = 0;
+
+	// set io window 1 for 3ed - 3ee
+	pc16->iostl1 = 0xed;
+	pc16->iosth1 = 3;
+
+	pc16->iospl1 = 0xee;
+	pc16->iosph1 = 3;
+
+	pc16->ioffl1 = 0x0;
+	pc16->ioffh1 = 0;
+
+
+	// FIXME statically declare CF config window at 0xe1000000
+	pc16->smstl0 = 0;
+	pc16->smsth0 = 0;
+	pc16->smspl0 = 0;
+	pc16->smsph0 = 0x80;
+	pc16->moffl0 = 0;
+	pc16->moffh0 = 0x40;
+	pc16->smpga0 = 0xe1;
+
+	// set I/O width for Auto Data width
+	pc16->ioctrl = 0x22;
+
+
+	// enable I/O window 0 and 1
+	pc16->awinen = 0xc1;
+
+
+	pc16->miscc1 = 1;
+
+	// apply power and enable outputs
+	pc16->pwctrl = 0xb0;
+	
+
+	// delay could be optimised, but this works
+	udelay(100000);
+	
+	pc16->igctrl = 0x69;
+
+	unsigned char *cptr;
+	cptr = (unsigned char *)(0xe1000200);
+	printk_debug("CF Config = %x\n",*cptr);
+
+	// FIX Me 16 bit CF always have first config byte at 0x200 into Config structure,
+        // but CF+ May Not according to spec - should locate through reading tuple data,
+        // but this will do for now !!!
+
+
+	// set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io
+	// windows of the bridge set up above to map those bytes into the 
+	// addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
+	*cptr = 0x41;
+
+
+}
+
+static void southbridge_init(struct chip *chip, enum chip_pass pass)
+{
+
+	struct southbridge_rl5c476_config *conf = 
+		(struct southbridge_rl5c476_config *)chip->chip_info;
+
+	switch (pass) {
+	case CONF_PASS_PRE_PCI:
+		//rl5c476_pci_enable(conf);
+		break;
+		
+	case CONF_PASS_POST_PCI:
+		rl5c476_init(conf);
+
+		break;
+
+	case CONF_PASS_PRE_BOOT:
+		//dump_south();
+		break;
+		
+	default:
+		/* nothing yet */
+		break;
+	}
+}
+
+static void enumerate(struct chip *chip)
+{
+	extern struct device_operations default_pci_ops_bus;
+	chip_enumerate(chip);
+	chip->dev->ops = &default_pci_ops_bus;
+}
+
+struct chip_control southbridge_ricoh_rl5c476_control = {
+	.enumerate = enumerate,
+	.enable    = southbridge_init,
+	.name      = "RICOH RL5C476"
+};
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.h b/src/southbridge/ricoh/rl5c476/rl5c476.h
new file mode 100644
index 0000000..c2da0de
--- /dev/null
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.h
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* rl5c476 routines and defines*/
+
+
+typedef unsigned char u8;
+
+
+/* the 16 bit control structure for ricoh cardbus bridge */
+typedef struct pc16reg  {
+	u8 idrevs;
+	u8 ifstat;
+	u8 pwctrl;
+	u8 igctrl;
+	u8 cschg;
+	u8 cscint;
+	u8 awinen;
+	u8 ioctrl;
+	u8 iostl0;
+	u8 iosth0;
+	u8 iospl0;
+	u8 iosph0;
+	u8 iostl1;
+	u8 iosth1;
+	u8 iospl1;
+	u8 iosph1;
+	u8 smstl0;
+	u8 smsth0;
+	u8 smspl0;
+	u8 smsph0;
+	u8 moffl0;
+	u8 moffh0;
+	u8 cdgenc;
+	u8 resv1;
+	u8 smstl1;
+	u8 smsth1;
+	u8 smspl1;
+	u8 smsph1;
+	u8 moffl1;
+	u8 moffh1;
+	u8 glctrl;
+	u8 atctrl;
+	u8 smstl2;
+	u8 smsth2;
+	u8 smspl2;
+	u8 smsph2;
+	u8 moffl2;
+	u8 moffh2;
+	u8 resv2;
+	u8 resv3;
+	u8 smstl3;
+	u8 smsth3;
+	u8 smspl3;
+	u8 smsph3;
+	u8 moffl3;
+	u8 moffh3;
+	u8 resv4;
+	u8 miscc1;
+	u8 smstl4;
+	u8 smsth4;
+	u8 smspl4;
+	u8 smsph4;
+	u8 moffl4;
+	u8 moffh4;
+	u8 ioffl0;
+	u8 ioffh0;
+	u8 ioffl1;
+	u8 ioffh1;
+	u8 gpio;
+	u8 resv5;
+	u8 resv6;
+	u8 resv7;
+	u8 resv8;
+	u8 resv9;
+	u8 smpga0;
+} __attribute__ ((packed)) pc16reg_t;
+
+	
+
diff --git a/src/southbridge/via/vt8235/vt8235.c b/src/southbridge/via/vt8235/vt8235.c
index ca5ab32..fc4c6a6 100644
--- a/src/southbridge/via/vt8235/vt8235.c
+++ b/src/southbridge/via/vt8235/vt8235.c
@@ -9,6 +9,8 @@
 #include "vt8235.h"
 #include "chip.h"
 
+void rtc_init(int i);
+
 void pc_keyboard_init(void);
 
 void hard_reset(void) 
@@ -23,67 +25,78 @@
 	/* Base 8235 controller */
 	device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
 	/* USB controller 1 */
-	device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
+	device_t dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
 	/* USB controller 2 */
-	device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2);
+	device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev1);
+	/* USB controller 2 */
+	device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, 
+	PCI_DEVICE_ID_VIA_82C586_2, dev2);
 	
-	/* enable USB1 */
-	if(dev2) {
-		if (enable) {
-			pci_write_config8(dev2, 0x3c, 0x05);
-			pci_write_config8(dev2, 0x04, 0x07);
-		} else {
-			pci_write_config8(dev2, 0x3c, 0x00);
-			pci_write_config8(dev2, 0x04, 0x00);
+	if(enable){
+        	if(dev0) {
+	    		regval = pci_read_config8(dev0, 0x50);
+	    		regval &= ~(0x36);
+	    		pci_write_config8(dev0, 0x50, regval);
 		}
-	}
-	
-	if(dev0) {
-		regval = pci_read_config8(dev0, 0x50);
-		if (enable) 
-			regval &= ~(0x10);    
-		else
-			regval |= 0x10;    	      
-		pci_write_config8(dev0, 0x50, regval);
-	}
-	
-	/* enable USB2 */
-	if(dev3) {
-		if (enable) {
-			pci_write_config8(dev3, 0x3c, 0x05);
-			pci_write_config8(dev3, 0x04, 0x07);
-		} else {
-			pci_write_config8(dev3, 0x3c, 0x00);
-			pci_write_config8(dev3, 0x04, 0x00);
+
+		/* enable USB1 */
+		if(dev1) {
+	    		pci_write_config8(dev1, 0x04, 0x07);
 		}
-	}
-	
-	if(dev0) {
-		regval = pci_read_config8(dev0, 0x50);
-		if (enable) 
-			regval &= ~(0x20);    
-		else
-			regval |= 0x20;    
-		pci_write_config8(dev0, 0x50, regval);
+
+		/* enable USB2 */
+		if(dev2) {
+	    		pci_write_config8(dev2, 0x04, 0x07);
+		}
+
+		/* enable USB3 */
+		if(dev3) {
+	    		pci_write_config8(dev3, 0x04, 0x07);
+		}
+
+	}else{
+        	if(dev0) {
+	    		regval = pci_read_config8(dev0, 0x50);
+	    		regval |= 0x36;    
+	    		pci_write_config8(dev0, 0x50, regval);
+		}
+
+		/* disable USB1 */
+		if(dev1) {
+	    		pci_write_config8(dev1, 0x3c, 0x00);
+	    		pci_write_config8(dev1, 0x04, 0x00);
+		}
+
+		/* disable USB2 */
+		if(dev2) {
+	    		pci_write_config8(dev2, 0x3c, 0x00);
+	    		pci_write_config8(dev2, 0x04, 0x00);
+		}
+
+		/* disable USB3 */
+		if(dev3) {
+	    		pci_write_config8(dev3, 0x3c, 0x00);
+	    		pci_write_config8(dev3, 0x04, 0x00);
+		}
 	}
 }
 
 static void keyboard_on(void)
 {
 	unsigned char regval;
-	
+
 	/* Base 8235 controller */
-	device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
-	
-	/* kevinh/Ispiri - update entire function to use 
-	   new pci_write_config8 */
+	device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \
+						PCI_DEVICE_ID_VIA_8235, 0);
 
 	if (dev0) {
 		regval = pci_read_config8(dev0, 0x51);
-		regval |= 0x0f; 
+//		regval |= 0x0f; 
+		/* !!!FIX let's try this */
+		regval |= 0x1d; 
 		pci_write_config8(dev0, 0x51, regval);
 	}
-	init_pc_keyboard(0x60, 0x64, 0);
+	pc_keyboard_init();
 }
 
 static void nvram_on(void)
@@ -152,16 +165,43 @@
  */
 void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]);
 
+/* taken some liberties - changed irq structures to pins numbers so that it is easier to
+ * change PCI irq assignments without having to change each PCI function individually
+ */
 
-static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 };
-static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 };
-static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
+/* pciIrqs contains the irqs assigned for PCI pins A-D */
+/* setting will depend on motherboard as irqs can be quite scarce */
+/* e.g on EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia socket */
+/* may want another - for now only claim 3 interupts for PCI, leaving at least one spare */
+/* for CF.  */
+/* On EPIA-M one could allocated all four irqs to different numbers since there are no cardbus */
+/* devices */
 
+
+static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 10 };
+
+static const unsigned char usbPins[4] =      { 'A','B','C','D'};
+static const unsigned char enetPins[4] =     { 'A','B','C','D'};
+static const unsigned char slotPins[4] =     { 'B','C','D','A'};
+static const unsigned char firewirePins[4] = { 'B','C','D','A'};
+static const unsigned char vt8235Pins[4] =   { 'A','B','C','D'};
+static const unsigned char vgaPins[4] =      { 'A','B','C','D'};
+static const unsigned char cbPins[4] =       { 'A','B','C','D'};
+static const unsigned char riserPins[4] =    { 'A','B','C','D'};
 /*
 	Our IDSEL mappings are as follows
 	PCI slot is AD31          (device 15) (00:14.0)
 	Southbridge is AD28       (device 12) (00:11.0)
 */
+static unsigned char *pin_to_irq(const unsigned char *pin)
+{
+	static unsigned char Irqs[4];
+	int i;
+	for (i = 0 ; i < 4 ; i++)
+		Irqs[i] = pciIrqs[ pin[i] - 'A' ];
+
+	return Irqs;
+}
 static void pci_routing_fixup(void)
 {
 	device_t dev;
@@ -177,23 +217,47 @@
 		   PINTC = IRQ10
 		   PINTD = IRQ12
 		*/
-		pci_write_config8(dev, 0x55, 0xb0);
-		pci_write_config8(dev, 0x56, 0xa5);
-		pci_write_config8(dev, 0x57, 0xc0);
+		pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
+		pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
+		pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
+
 	}
 
-	// Standard southbridge components
-	printk_info("setting southbridge\n");
-	pci_assign_irqs(0, 0x11, southbridgeIrqs);
+
+
+	// firewire built into southbridge
+	printk_info("setting firewire\n");
+	pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins) );
+
+	// Standard usb components
+	printk_info("setting usb\n");
+	pci_assign_irqs(0, 0x10, pin_to_irq(usbPins) );
+
+	// VT8235 + sound hardware
+	printk_info("setting vt8235\n");
+	pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins) );
 
 	// Ethernet built into southbridge
 	printk_info("setting ethernet\n");
-	pci_assign_irqs(0, 0x12, enetIrqs);
+	pci_assign_irqs(0, 0x12, pin_to_irq(enetPins) );
+
+	// VGA
+	printk_info("setting vga\n");
+	pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins) );
 
 	// PCI slot
 	printk_info("setting pci slot\n");
-	pci_assign_irqs(0, 0x14, slotIrqs);
-	printk_info("%s: DONE\n", __FUNCTION__);
+	pci_assign_irqs(0, 0x14, pin_to_irq(slotPins) );
+
+	// Cardbus slot 
+	printk_info("setting cardbus slot\n");
+	pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins) );
+
+	// Via 2 slot riser card 2nd slot
+	printk_info("setting riser slot\n");
+	pci_assign_irqs(0, 0x13, pin_to_irq(riserPins) );
+
+
 }
 
 
@@ -213,13 +277,76 @@
 	}
 }
 
+void set_led(void)
+{
+
+	// set power led to steady now that lxbios has virtually done its job
+	device_t dev0;
+	dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,0);
+
+	pci_write_config8(dev0,0x94,0xb0);
+
+}
+
+/* set up the power management capabilities directly into ACPI mode */
+/* this avoids having to handle any System Management Interrupts (SMI's) which I can't */
+/* figure out how to do !!!! */ 
+
+void setup_pm(device_t dev0)
+{
+
+	// Set gen config 0
+	pci_write_config8(dev0,0x80,0x20);
+
+	// Set ACPI base address to IO 0x4000
+	pci_write_config16(dev0, 0x88, 0x0401);
+	
+	// set ACPI irq to 5
+	pci_write_config8(dev0,0x82,0x55);
+
+	// primary interupt channel
+	pci_write_config16(dev0,0x84,0x30f2);
+
+	// throttle / stop clock control
+	pci_write_config8(dev0,0x8d,0x18);
+
+	pci_write_config8(dev0,0x93,0x88);
+	//pci_write_config8(dev0,0x94,0xb0);
+	pci_write_config8(dev0,0x95,0xc0);
+	pci_write_config8(dev0,0x98,0);
+	pci_write_config8(dev0,0x99,0xea);
+	pci_write_config8(dev0,0xe4,0x14);
+	pci_write_config8(dev0,0xe5,0x08);
+
+
+	// Enable ACPI access (and setup like award)
+	pci_write_config8(dev0, 0x81, 0x84);
+
+	outw(0xffff,0x400);
+	outw(0xffff,0x420);
+	outw(0xffff,0x428);
+	outl(0xffffffff,0x430);
+	
+	outw(0x0,0x424);
+	outw(0x0,0x42a);
+	outw(0x1,0x42c);
+	outl(0x0,0x434);
+	outl(0x01,0x438);
+	outb(0x0,0x442);
+	outl(0xffff7fff,0x448);
+	outw(0x001,0x404);
+
+
+}
+
 static void vt8235_init(struct southbridge_via_vt8235_config *conf)
 {
 	unsigned char enables;
 	device_t dev0;
 	device_t dev1;
-	device_t devpwr;
-	
+	//device_t devpwr;
+	//int i;
+
 	// to do: use the pcibios_find function here, instead of 
 	// hard coding the devfn. 
 	// done - kevinh/Ispiri
@@ -243,6 +370,7 @@
 	// IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI 
 	// interrupts can be properly marked as level triggered.
 	enables = pci_read_config8(dev0, 0x40);
+	enables |= 0x45;
 	pci_write_config8(dev0, 0x40, enables);
 	
 	// Set 0x42 to 0xf0 to match Award bios
@@ -250,6 +378,17 @@
 	enables |= 0xf0;
 	pci_write_config8(dev0, 0x42, enables);
 	
+
+	/* Set 0x58 to 0x03 to match Award */
+	pci_write_config8(dev0, 0x58, 0x03);
+
+	/* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
+	enables = pci_read_config8(dev0, 0x4f);
+	enables |= 0x08;
+	pci_write_config8(dev0, 0x4f, enables);
+
+
+
 	// Set bit 3 of 0x4a, to match award (dummy pci request)
 	enables = pci_read_config8(dev0, 0x4a);
 	enables |= 0x08;
@@ -271,67 +410,23 @@
 	}
 	
 	
-	// enable com1 and com2. 
-	if (conf->enable_com_ports) {
-		enables = pci_read_config8(dev0, 0x6e);
-		
-		/* 0x80 is enable com port b, 0x10 is to make it com2, 0x8
-		 * is enable com port a as com1 kevinh/Ispiri - Old code
-		 * thought 0x01 would make it com1, that was wrong enables =
-		 * 0x80 | 0x10 | 0x8 ; pci_write_config8(dev0, 0x6e,
-		 * enables); // note: this is also a redo of some port of
-		 * assembly, but we want everything up.
-		 */
-		
-		/* set com1 to 115 kbaud not clear how to do this yet.
-		 * forget it; done in assembly.
-		 */
+	/* enable serial irq */
+	pci_write_config8(dev0,0x52,0x9);
 
-	}
-	// enable IDE, since Linux won't do it.
-	// First do some more things to devfn (17,0)
-	// note: this should already be cleared, according to the book. 
-	enables = pci_read_config8(dev0, 0x50);
-	printk_debug("IDE enable in reg. 50 is 0x%x\n", enables);
-	enables &= ~8; // need manifest constant here!
-	printk_debug("set IDE reg. 50 to 0x%x\n", enables);
-	pci_write_config8(dev0, 0x50, enables);
-	
-	// set default interrupt values (IDE)
-	enables = pci_read_config8(dev0, 0x4c);
-	printk_debug("IRQs in reg. 4c are 0x%x\n", enables & 0xf);
-	// clear out whatever was there. 
-	enables &= ~0xf;
-	enables |= 4;
-	printk_debug("setting reg. 4c to 0x%x\n", enables);
-	pci_write_config8(dev0, 0x4c, enables);
-	
-	// set up the serial port interrupts. 
-	// com2 to 3, com1 to 4
-	pci_write_config8(dev0, 0x46, 0x04);
-	pci_write_config8(dev0, 0x47, 0x03);
-	pci_write_config8(dev0, 0x6e, 0x98);
-	//
+	/* dma */
+	pci_write_config8(dev0, 0x53, 0x00);
+
+	/* Use compatability mode - per award bios */
+	pci_write_config32(dev1, 0x10, 0x0);
+	pci_write_config32(dev1, 0x14, 0x0);
+	pci_write_config32(dev1, 0x18, 0x0);
+	pci_write_config32(dev1, 0x1c, 0x0);
+
+
 	// Power management setup
+	setup_pm(dev0);
+	
 	//
-	// Set ACPI base address to IO 0x4000
-	//pci_write_config32(devpwr, 0x48, 0x4001);
-	
-	// Enable ACPI access (and setup like award)
-	//pci_write_config8(devpwr, 0x41, 0x84);
-	
-	// Set hardware monitor base address to IO 0x6000
-	//pci_write_config32(devpwr, 0x70, 0x6001);
-	
-	// Enable hardware monitor (and setup like award)
-	//pci_write_config8(devpwr, 0x74, 0x01);
-	
-	// set IO base address to 0x5000
-	//pci_write_config32(devpwr, 0x90, 0x5001);
-	
-	// Enable SMBus 
-	//pci_write_config8(devpwr, 0xd2, 0x01);
-	
 	//
 	// IDE setup
 	//
@@ -422,6 +517,8 @@
 	
 	// Start the rtc
 	rtc_init(0);
+
+
 }
 
 static void southbridge_init(struct chip *chip, enum chip_pass pass)
@@ -436,12 +533,23 @@
 		break;
 		
 	case CONF_PASS_POST_PCI:
+		/* initialise the PIC - particularly so that VGA bios init code 
+                   doesn't get nasty unknown interupt vectors when it tries to establish 
+                   its interrupts. */
+		setup_i8259();
 		vt8235_init(conf);
 		pci_routing_fixup();
+		usb_on(1);
+		keyboard_on();
+		vga_fixup();
+
+
+
 		break;
 
 	case CONF_PASS_PRE_BOOT:
 		dump_south();
+		set_led();
 		break;
 		
 	default:
diff --git a/src/southbridge/via/vt8235/vt8235_early_smbus.c b/src/southbridge/via/vt8235/vt8235_early_smbus.c
index 79b73df..26beea9 100644
--- a/src/southbridge/via/vt8235/vt8235_early_smbus.c
+++ b/src/southbridge/via/vt8235/vt8235_early_smbus.c
@@ -29,35 +29,64 @@
 {
 	device_t dev;
 	unsigned char c;
+	int i;
 	/* Power management controller */
-	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235), 0);
+		dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235), 0);
 	
 	if (dev == PCI_DEV_INVALID) {
 		die("SMBUS controller not found\r\n");
-	}
-	
+	}		
+	pci_write_config8(dev, 0xd2, (0x4 << 1 ));
+
 	// set IO base address to SMBUS_IO_BASE
-	pci_write_config32(dev, 0x90, SMBUS_IO_BASE|1);
+	pci_write_config16(dev, 0xd0, SMBUS_IO_BASE);
 	
 	// Enable SMBus 
 	pci_write_config8(dev, 0xd2, (0x4 << 1)|1);
 	
+	// Enable RTC
+	pci_write_config8(dev,0x51,0x04);
+
 	/* make it work for I/O ...
 	 */
-	pci_write_config8(dev, 4, 1);
+	pci_write_config16(dev, 4, 1);
+	
+
+	/* tell the world we're alive - make power led flash during bios execution */
+	pci_write_config8(dev,0x94,0xb2);
+
+
+	/* FIX for half baud rate problem */
+	/* let clocks and the like settle */
+	/* as yet arbitrary count - 1000 is too little 5000 works */
+	for(i = 0 ; i < 5000 ; i++)
+		outb(0x80,0x80);
+
+	/* southbridge doesn't seem to like to do much untill after this delay, so set up 
+         * the flashing power LED again */
+	pci_write_config8(dev,0x94,0xb2);
 
 /* The VT1211 serial port needs 48 mhz clock, on power up it is getting
    only 24 mhz, there is some mysterious device on the smbus that can
    fix this...this code below does it. */
 	outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT); 
+	outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+	outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+	outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+	for( ;;) {
+		c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
+		if ((c & 1) == 0)
+			break;
+	}
 	outb(0x7f, SMBUS_IO_BASE+SMBHSTDAT0); 
 	outb(0x83, SMBUS_IO_BASE+SMBHSTCMD);
-        outb(CLOCK_SLAVE_ADDRESS<<1, SMBUS_IO_BASE+SMBXMITADD);
+        outb(CLOCK_SLAVE_ADDRESS<<1 , SMBUS_IO_BASE+SMBXMITADD);
         outb(8 | I2C_TRANS_CMD, SMBUS_IO_BASE+SMBHSTCTL);
 
+        	
 	for (;;) {
 		c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
-		if (c & 1 == 0)
+		if ((c & 1) == 0)
 			break;
 	}
 }
@@ -173,8 +202,9 @@
 	
 	/* SMBUS Wait Ready */
 	for ( i = 0; i < 0xFFFF; i++ )
-		if ( ((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0 )
+		if ( ((sts = (inb(SMBUS_IO_BASE) & 0x1f)) & 0x01) == 0 )
 			break;
+	
 	if ((sts & ~3) != 0) {
 		smbus_print_error(sts);
 		return 0;
diff --git a/src/superio/via/vt1211/Config.lb b/src/superio/via/vt1211/Config.lb
new file mode 100644
index 0000000..a1dfde0
--- /dev/null
+++ b/src/superio/via/vt1211/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object vt1211.o
diff --git a/src/superio/via/vt1211/chip.h b/src/superio/via/vt1211/chip.h
new file mode 100644
index 0000000..76a5a5b
--- /dev/null
+++ b/src/superio/via/vt1211/chip.h
@@ -0,0 +1,19 @@
+#ifndef _SUPERIO_VIA_VT1211
+#define _SUPERIO_VIA_VT1211
+
+extern struct chip_control superio_via_vt1211_control;
+
+struct superio_via_vt1211_config {
+	/* PCI function enables */
+	/* i.e. so that pci scan bus will find them. */
+	/* I am putting in IDE as an example but obviously this needs
+	 * to be more complete!
+	 */
+	/* enables of functions of devices */
+	int enable_com_ports;
+	int enable_fdc;
+	int enable_lpt;
+	int enable_hwmon;
+};
+
+#endif /* _SUPERIO_VIA_VT1211 */
diff --git a/src/superio/via/vt1211/vt1211.c b/src/superio/via/vt1211/vt1211.c
new file mode 100644
index 0000000..26d9356
--- /dev/null
+++ b/src/superio/via/vt1211/vt1211.c
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* vt1211 routines and defines*/
+
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <device/chip.h>
+#include <console/console.h>
+#include "vt1211.h"
+#include "chip.h"
+
+
+static unsigned char vt1211hwmonitorinits[]={
+ 0x10,0x3, 0x11,0x10, 0x12,0xd, 0x13,0x7f,
+ 0x14,0x21, 0x15,0x81, 0x16,0xbd, 0x17,0x8a,
+ 0x18,0x0, 0x19,0x0, 0x1a,0x0, 0x1b,0x0,
+ 0x1d,0xff, 0x1e,0x0, 0x1f,0x73, 0x20,0x67,
+ 0x21,0xc1, 0x22,0xca, 0x23,0x74, 0x24,0xc2,
+ 0x25,0xc7, 0x26,0xc9, 0x27,0x7f, 0x29,0x0,
+ 0x2a,0x0, 0x2b,0xff, 0x2c,0x0, 0x2d,0xff,
+ 0x2e,0x0, 0x2f,0xff, 0x30,0x0, 0x31,0xff,
+ 0x32,0x0, 0x33,0xff, 0x34,0x0, 0x39,0xff,
+ 0x3a,0x0, 0x3b,0xff, 0x3c,0xff, 0x3d,0xff,
+ 0x3e,0x0, 0x3f,0xb0, 0x43,0xff, 0x44,0xff,
+ 0x46,0xff, 0x47,0x50, 0x4a,0x3, 0x4b,0xc0,
+ 0x4c,0x0, 0x4d,0x0, 0x4e,0xf, 0x5d,0x77,
+ 0x5c,0x0, 0x5f,0x33, 0x40,0x1};
+
+static void start_conf_pnp(int dev)
+{
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	outb(7,0x2e);
+	outb(dev,0x2f);
+}
+static void write_pnp(int reg, int val)
+{
+	outb(reg,0x2e);
+	outb(val,0x2f);
+}
+static void end_conf_pnp()
+{
+	outb(0xaa,0x2e);
+}
+
+static void vt1211_init(struct superio_via_vt1211_config *conf)
+{
+
+	int i;
+ 	// Activate the vt1211 hardware monitor
+	if(conf->enable_hwmon){
+		start_conf_pnp(0x0b);
+		write_pnp(0x60,0xec); 
+		write_pnp(0x30,1);
+		end_conf_pnp();
+
+	 	// initialize vt1211 hardware monitor registers, which are at 0xECXX
+ 		for(i=0;i<sizeof(vt1211hwmonitorinits);i+=2)
+ 			outb(vt1211hwmonitorinits[i+1],0xec00+vt1211hwmonitorinits[i]);
+	}
+	if( conf->enable_fdc){
+		// activate FDC
+		start_conf_pnp(0); // fdc is device 0
+		write_pnp(0x60,0xfc); // io address
+		write_pnp(0x70,0x06); // interupt
+		write_pnp(0x74,0x02); // dma
+		write_pnp(0x30,0x01); // activate it
+		end_conf_pnp();
+	}	
+
+	if( conf->enable_com_ports ){
+		// activate com2
+		start_conf_pnp(3);
+		write_pnp(0x60,0xbe);
+		write_pnp(0x70,0x3);
+		write_pnp(0xf0,0x02);
+		write_pnp(0x30,0x01);
+		end_conf_pnp();
+	}
+
+	if( conf->enable_lpt ){
+		// activate lpt
+		start_conf_pnp(1);
+		write_pnp(0x60,0xde);
+		write_pnp(0x70,0x07);
+		write_pnp(0x74,0x3);
+		write_pnp(0x30,0x01);
+		end_conf_pnp();
+	}
+
+}
+
+static void superio_init(struct chip *chip, enum chip_pass pass)
+{
+
+	struct superio_via_vt1211_config *conf = 
+		(struct superio_via_vt1211_config *)chip->chip_info;
+
+	switch (pass) {
+	case CONF_PASS_PRE_PCI:
+		break;
+		
+	case CONF_PASS_POST_PCI:
+		vt1211_init(conf);
+		break;
+
+	case CONF_PASS_PRE_BOOT:
+		break;
+		
+	default:
+		/* nothing yet */
+		break;
+	}
+}
+
+static void enumerate(struct chip *chip)
+{
+	extern struct device_operations default_pci_ops_bus;
+	chip_enumerate(chip);
+	chip->dev->ops = &default_pci_ops_bus;
+}
+
+struct chip_control superio_via_vt1211_control = {
+	.enumerate = enumerate,
+	.enable    = superio_init,
+	.name      = "VIA vt1211"
+};
diff --git a/src/superio/via/vt1211/vt1211.h b/src/superio/via/vt1211/vt1211.h
new file mode 100644
index 0000000..0d3d620
--- /dev/null
+++ b/src/superio/via/vt1211/vt1211.h
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* vt1211 routines and defines*/
+
diff --git a/targets/via/epia-m/Config.etherboot.lb b/targets/via/epia-m/Config.etherboot.lb
new file mode 100644
index 0000000..b19858d
--- /dev/null
+++ b/targets/via/epia-m/Config.etherboot.lb
@@ -0,0 +1,107 @@
+# Sample config file for EPIA-M
+# This will make a target directory of ./epia-m
+
+loadoptions
+
+target epia-m
+
+uses ARCH
+uses CONFIG_COMPRESS
+uses CONFIG_IOAPIC
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses CONFIG_UDELAY_TSC
+uses CPU_FIXUP
+uses FALLBACK_SIZE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses HAVE_HARD_RESET
+uses i586
+uses i686
+uses INTEL_PPRO_MTRR
+uses HEAP_SIZE
+uses IRQ_SLOT_COUNT
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses CONFIG_SMP
+uses CONFIG_MAX_CPUS
+uses MEMORY_HOLE
+uses PAYLOAD_SIZE
+uses _RAMBASE
+uses _ROMBASE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_OFFSET
+uses ROM_SECTION_SIZE
+uses ROM_SIZE
+uses STACK_SIZE
+uses USE_FALLBACK_IMAGE
+uses USE_OPTION_TABLE
+uses HAVE_OPTION_TABLE
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses  DEFAULT_CONSOLE_LOGLEVEL
+uses  CONFIG_CONSOLE_SERIAL8250
+uses MAINBOARD
+uses CONFIG_CHIP_CONFIGURE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses LINUXBIOS_EXTRA_VERSION
+uses TTYS0_BAUD
+
+option TTYS0_BAUD=19200
+
+option CONFIG_CHIP_CONFIGURE=1
+
+option  MAXIMUM_CONSOLE_LOGLEVEL=7
+option  DEFAULT_CONSOLE_LOGLEVEL=7
+option  CONFIG_CONSOLE_SERIAL8250=1
+
+option CPU_FIXUP=1
+option CONFIG_UDELAY_TSC=0
+option i686=1
+option i586=1
+option INTEL_PPRO_MTRR=1
+option ROM_SIZE=256*1024
+
+option HAVE_OPTION_TABLE=1
+option CONFIG_ROM_STREAM=1
+option HAVE_FALLBACK_BOOT=1
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+option FALLBACK_SIZE=131072
+
+## LinuxBIOS C code runs at this location in RAM
+option _RAMBASE=0x00004000
+
+#
+###
+### Compute the start location and size size of
+### The linuxBIOS bootloader.
+###
+
+#
+# Arima hdama
+romimage "normal"
+	option USE_FALLBACK_IMAGE=0
+	option ROM_IMAGE_SIZE=0x10000
+	option LINUXBIOS_EXTRA_VERSION=".0Normal"
+	mainboard via/epia-m
+#	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
+#	payload ../../../../tg3--ide_disk.zelf	
+	payload ../../../../../lnxieepro100.ebi
+end
+
+romimage "fallback" 
+	option USE_FALLBACK_IMAGE=1
+	option ROM_IMAGE_SIZE=0x10000
+	option LINUXBIOS_EXTRA_VERSION=".0Fallback"
+	mainboard via/epia-m
+#	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
+#	payload ../../../../tg3--ide_disk.zelf	
+	payload ../../../../../lnxieepro100.ebi
+end
+
+buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
diff --git a/targets/via/epia-m/Config.lb b/targets/via/epia-m/Config.lb
index b19858d..ca87c7b 100644
--- a/targets/via/epia-m/Config.lb
+++ b/targets/via/epia-m/Config.lb
@@ -46,32 +46,33 @@
 uses XIP_ROM_SIZE
 uses XIP_ROM_BASE
 uses LINUXBIOS_EXTRA_VERSION
-uses TTYS0_BAUD
-
-option TTYS0_BAUD=19200
-
+uses HAVE_ACPI_TABLES
+uses CONFIG_LEGACY_VGABIOS
+uses VGABIOS_START
+uses VGABIOS_START
 option CONFIG_CHIP_CONFIGURE=1
 
-option  MAXIMUM_CONSOLE_LOGLEVEL=7
-option  DEFAULT_CONSOLE_LOGLEVEL=7
+option  MAXIMUM_CONSOLE_LOGLEVEL=8
+option  DEFAULT_CONSOLE_LOGLEVEL=8
 option  CONFIG_CONSOLE_SERIAL8250=1
-
+option HAVE_ACPI_TABLES=1
 option CPU_FIXUP=1
 option CONFIG_UDELAY_TSC=0
 option i686=1
 option i586=1
 option INTEL_PPRO_MTRR=1
 option ROM_SIZE=256*1024
-
+option CONFIG_LEGACY_VGABIOS=1
 option HAVE_OPTION_TABLE=1
 option CONFIG_ROM_STREAM=1
 option HAVE_FALLBACK_BOOT=1
 
+option VGABIOS_START=0xfffc0000
 ###
 ### Compute the location and size of where this firmware image
 ### (linuxBIOS plus bootloader) will live in the boot rom chip.
 ###
-option FALLBACK_SIZE=131072
+option FALLBACK_SIZE=0x18000
 
 ## LinuxBIOS C code runs at this location in RAM
 option _RAMBASE=0x00004000
@@ -86,22 +87,26 @@
 # Arima hdama
 romimage "normal"
 	option USE_FALLBACK_IMAGE=0
-	option ROM_IMAGE_SIZE=0x10000
+	option ROM_IMAGE_SIZE=0xc000
+	option ROM_SECTION_OFFSET=0x10000
+	option ROM_SECTION_SIZE=0x18000
 	option LINUXBIOS_EXTRA_VERSION=".0Normal"
 	mainboard via/epia-m
 #	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
 #	payload ../../../../tg3--ide_disk.zelf	
-	payload ../../../../../lnxieepro100.ebi
+#	payload ../../../../../lnxieepro100.ebi
+	payload /filo.elf
 end
 
 romimage "fallback" 
 	option USE_FALLBACK_IMAGE=1
-	option ROM_IMAGE_SIZE=0x10000
+	option ROM_IMAGE_SIZE=0xc000
 	option LINUXBIOS_EXTRA_VERSION=".0Fallback"
 	mainboard via/epia-m
 #	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
 #	payload ../../../../tg3--ide_disk.zelf	
-	payload ../../../../../lnxieepro100.ebi
+#	payload ../../../../../lnxieepro100.ebi
+	payload /filo.elf
 end
 
 buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
diff --git a/targets/via/epia-m/Config.vga.filo b/targets/via/epia-m/Config.vga.filo
new file mode 100644
index 0000000..ca87c7b
--- /dev/null
+++ b/targets/via/epia-m/Config.vga.filo
@@ -0,0 +1,112 @@
+# Sample config file for EPIA-M
+# This will make a target directory of ./epia-m
+
+loadoptions
+
+target epia-m
+
+uses ARCH
+uses CONFIG_COMPRESS
+uses CONFIG_IOAPIC
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses CONFIG_UDELAY_TSC
+uses CPU_FIXUP
+uses FALLBACK_SIZE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses HAVE_HARD_RESET
+uses i586
+uses i686
+uses INTEL_PPRO_MTRR
+uses HEAP_SIZE
+uses IRQ_SLOT_COUNT
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses CONFIG_SMP
+uses CONFIG_MAX_CPUS
+uses MEMORY_HOLE
+uses PAYLOAD_SIZE
+uses _RAMBASE
+uses _ROMBASE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_OFFSET
+uses ROM_SECTION_SIZE
+uses ROM_SIZE
+uses STACK_SIZE
+uses USE_FALLBACK_IMAGE
+uses USE_OPTION_TABLE
+uses HAVE_OPTION_TABLE
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses  DEFAULT_CONSOLE_LOGLEVEL
+uses  CONFIG_CONSOLE_SERIAL8250
+uses MAINBOARD
+uses CONFIG_CHIP_CONFIGURE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses LINUXBIOS_EXTRA_VERSION
+uses HAVE_ACPI_TABLES
+uses CONFIG_LEGACY_VGABIOS
+uses VGABIOS_START
+uses VGABIOS_START
+option CONFIG_CHIP_CONFIGURE=1
+
+option  MAXIMUM_CONSOLE_LOGLEVEL=8
+option  DEFAULT_CONSOLE_LOGLEVEL=8
+option  CONFIG_CONSOLE_SERIAL8250=1
+option HAVE_ACPI_TABLES=1
+option CPU_FIXUP=1
+option CONFIG_UDELAY_TSC=0
+option i686=1
+option i586=1
+option INTEL_PPRO_MTRR=1
+option ROM_SIZE=256*1024
+option CONFIG_LEGACY_VGABIOS=1
+option HAVE_OPTION_TABLE=1
+option CONFIG_ROM_STREAM=1
+option HAVE_FALLBACK_BOOT=1
+
+option VGABIOS_START=0xfffc0000
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+option FALLBACK_SIZE=0x18000
+
+## LinuxBIOS C code runs at this location in RAM
+option _RAMBASE=0x00004000
+
+#
+###
+### Compute the start location and size size of
+### The linuxBIOS bootloader.
+###
+
+#
+# Arima hdama
+romimage "normal"
+	option USE_FALLBACK_IMAGE=0
+	option ROM_IMAGE_SIZE=0xc000
+	option ROM_SECTION_OFFSET=0x10000
+	option ROM_SECTION_SIZE=0x18000
+	option LINUXBIOS_EXTRA_VERSION=".0Normal"
+	mainboard via/epia-m
+#	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
+#	payload ../../../../tg3--ide_disk.zelf	
+#	payload ../../../../../lnxieepro100.ebi
+	payload /filo.elf
+end
+
+romimage "fallback" 
+	option USE_FALLBACK_IMAGE=1
+	option ROM_IMAGE_SIZE=0xc000
+	option LINUXBIOS_EXTRA_VERSION=".0Fallback"
+	mainboard via/epia-m
+#	payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
+#	payload ../../../../tg3--ide_disk.zelf	
+#	payload ../../../../../lnxieepro100.ebi
+	payload /filo.elf
+end
+
+buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
diff --git a/util/resetcf/resetcf.c b/util/resetcf/resetcf.c
new file mode 100644
index 0000000..1977f7d
--- /dev/null
+++ b/util/resetcf/resetcf.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <unistd.h>
+#include <sys/mman.h>
+
+main(int argc, char *argv[])
+{
+  int i;
+  volatile unsigned char *cp;
+  int fd;
+  void *v;
+  off_t nvram;
+  size_t length = 0x1000;
+
+  fd = open("/proc/bus/pci/00/0a.1",O_RDONLY);
+  lseek(fd,0x10,0);
+  read(fd,&nvram,sizeof(nvram));
+  close(fd);
+  //printf("Star %x\n",nvram);
+
+  if((fd = open("/dev/mem",O_RDWR)) != -1)
+    {
+      v = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED,fd,nvram);
+      fprintf(stderr, "mmap returns %p\n", v);
+      
+      if ( v == (void *) -1)
+	{
+	  perror("mmap");
+	  exit(1);
+	}
+    } else {
+      perror("open /dev/mem");
+      exit(1);
+    }
+  
+    for( i = 0x836 ; i < 0x840 ; i++){
+	*(unsigned char *)(v+i) = 0;
+    }
+   
+  
+}