EPIA-M fixup


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2090 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/HOWTO/EPIA-M-howto b/HOWTO/EPIA-M-howto
new file mode 100644
index 0000000..275cc91
--- /dev/null
+++ b/HOWTO/EPIA-M-howto
@@ -0,0 +1,593 @@
+
+This HOWTO contains instructions for using LinuxBIOSv2 on the VIA EPIA-M and MII 
+mini-itx based motherboards.
+
+Version 1.0 initial write for LinuxBIOSv2 by Nick Barker
+
+Using materials and inspiration from
+- EPIA HOWTO for freebios/linuxbios by Mark Wilkinson
+- Based on the K7SEM HOWTO by Brenden Bixler,
+- which is based on the Sis 630 HOWTO by Ron Minnich.
+- Getting Started with freebios2 - a mail posting by Jay Miller
+
+Unfortunately, there is a step in this HOWTO that could be hazardous. The 
+hazards include (but are not limited to)
+	1) destroying your motherboard
+	2) hurting yourself
+	3) killing yourself
+
+Because of these hazards, you must take full responsibility if you
+decide to install LinuxBIOSv2 following these procedures. Neither the
+author of this HOWTO or any organisation or individual associated with
+the LinuxBIOSv2 project can be held responsible for any adverse consequences
+of your attempt to follow these procedures.
+
+WARNING: We assume you've built kernels, know how to open up your PC,
+and how to yank the flash part out while power is on and put in a
+different part. There is NO WARRANTY, express or implied, with this
+software. In fact, if you don't know what you're doing, and you get
+careless, you're going to end up with a nice paperweight instead of a
+motherboard, an emergency room bill, or a funeral service.
+
+			YOU HAVE BEEN WARNED.
+
+Additional information available at: http://www.linuxbios.org/
+
+Linux distribution: Most modern distributions are supported. 
+                    
+Other software notes: You MUST have 'as' version 2.9.5 or later.
+                      You MUST have 'gcc' version other than 2.96.
+                      
+			  
+Pre-requisites
+--------------
+
+Before you start there are a few things which you need to arrange:
+
+Since you are going to be re-programming the flash rom on the mainboard, and
+it is likely that you first few attempts / images will not be right, then
+you need a way of restoring a known working bios onto a board which is otherwise
+dead.
+
+Recommended: you might want to get a Bios Saviour (RD1-PL) - this is
+a handy little piggy-back flash chip that saves you destroying the original
+flash image. This howto assumes that you have this device, though other methods
+and devices exist for programming flash roms.
+
+LinuxBIOSv2 sends debugging output through the first serial port. You might want
+to arrange a null modem serial cable for connecting this serial port to a
+second computer running a terminal emulation program. I use 'microcom' which
+is simple and allows all output to be captured into a file for later analysis.
+The port is set up to use 115200 baud, 8bit, No parity, 1 stop bit.
+
+Under LinuxBIOSv2 you have a choice of 'payloads'. The payload is the program
+which LinuxBIOSv2 hands over to once it has finished initialising everything
+on the mainboard at boot time. The payload is included in the flash rom along
+with LinuxBIOSv2, and usually its function is to locate and load the operating
+system. The 2 most common payloads are FILO, for booting Linux off an IDE
+disk, and Etherboot for booting a diskless workstation accross a network.
+This howto assumes the use of FILO.  
+
+A vga bios image. LinuxBIOS2v2 uses the vga bios of the original Via BIOS to 
+initialise the vga. It is not directly downloadable, but you can capture it from
+a system running with the original bios, so you might as well capture it now:
+		dd if=/dev/mem of=/video.bios.bin \
+                   bs=1 count=65536 skip=790528
+
+
+Getting Going
+-------------
+
+The steps for loading LinuxBIOSv2 are simple:
+1) Get Linux installed on your machine.
+2) Download and install LinuxBIOSv2 sources.
+3) Understand how to flash your rom.
+4) Download, Configure and build the FILO payload
+5) Configure and build LinuxBIOSv2.
+6) Burn the LinuxBIOSv2 image to the flash.
+7) Reset the machine -- did it work?
+
+Options Once it has booted
+  i) Speeding up the boot
+ ii) Enhancing ACPI support
+iii) On EPIA-MII, booting the computer from on-board compact flash 
+
+
+Step 1) 
+	Get Linux installed on your LinuxBIOSv2 machine.
+              Don't forget to note which partition is / (/dev/hda3 etc.)
+
+
+Step 2)
+	Grab the LinuxBIOSv2 source.
+	cd to the directory you want the source tree to be.
+
+	Note: this will create a sub directory called LinuxBIOSv2 which contains
+              the LinuxBIOSv2 source code
+
+	Download the latest code for LinuxBIOSv2 from the downloads page at
+		http://www.linuxbios.org
+
+
+	having expanded the tarball, cd into the LinuxBIOSv2 directory and browse around.
+	The top level directory includes:
+
+	'src' - where all of the source files for LinuxBIOSv2 are located.
+	'targets' - where all of the platform specific configuration files
+		for each platform supported by LinuxBIOSv2 are kept, and 
+                where the build files and build process occur.
+	'util' - where various utilities required for the build process 
+		and debugging are kept.
+
+
+	Hereafter, this howto refers to directory locations relative to these directories,
+	unless an absolute pathlist is given.
+
+Step 3)
+	Whilst getting LinuxBIOSv2 going on your EPIA-M, you are almost 
+	certainly going to be re-programming the flash rom several times, and
+	there is a very high probability that at one of these stages you will
+	get a flash rom that fails to boot your mainboard into Linux.
+ 
+	Before we proceed any further, it is absolutley vital that you have
+	worked out how to program the flash chip, and how you are going to
+	get back to your original bios when things go wrong. Otherwise you 
+	will end up with a very expensive paper weight as described earlier.
+
+        You can use a professional Data I/O burner, or you can be foolhardy
+	and simply re-program the flash part of a running machine. However
+	whilst getting going a BIOS SAVIOUR RD1-PL is a very inexpensive
+	but effective device for ensuring that you always have a working
+	BIOS to hand.
+
+	The bios saviour is a little device which plugs into the flash rom
+	socket of the motherboard, and the original flash rom then plugs into
+	the bios saviour. The bios saviour includes a second flash rom chip,
+	and either of these chips can be selected as the active chip by a 
+	simple supplied electrical switch mounted on flying leads. Make
+	sure that this switch is clearly visible, so that you know which
+	chip you are booting from, and which chip you are about to re-program.
+
+	Decide which chip you are going to use for LinuxBIOSv2, and which chip
+	you are going to keep the original working bios in, and mark them 
+	clearly on this switch.
+
+        In the 'util/flash_and_burn' directory is the source for the 'flash_rom'
+	utility, which is great for re-programming the flash chips on the 
+	EPIA-M / MII. Once you have built this utility:
+
+	Make sure that it can detect both flash chips on the bios saviour:
+		with switch set to chip 1 run 'flash_rom'
+		flash rom should search through a list of known flash rom
+		device types until it finds the type of the original chip
+		from your EPIA-M, and report what it has found.
+
+		with the switch set to chip 2, run 'flash_rom' again and confirm
+		that it can 'see' the second flash chip.
+
+		If your are lucky, the actual part number of the 2 chips may
+		be different, which you can use just prior to re-programming
+		a chip to make sure you are programming the right chip.
+
+	Make sure that you can read / write and verify a flash chip:
+		with switch set to 1 (original BIOS) run
+		'flash_rom -r original.rom'
+		this should read the contents of the original bios into the
+		file original.rom
+
+		confirm that the newly read file matches the original bios
+		'flash_rom -v original.rom'
+
+ 		set the switch to 2 
+		confirm if you can that flash_rom 'sees' the second chip
+		'flash_rom' - and look for the detected device type
+
+		write the known good bios to the second chip with
+		'flash_rom -w original.bios'
+
+		verify that it has written correctly
+		'flash_rom -v original.rom'
+
+		with switch left at position 2, reboot the machine and make
+		sure that it comes up corectly. If it does then you now have
+		a working flash programming environment. If it does not, then
+		set the switch back to 1, reboot the machine, and investigate
+		further. 
+
+Step 4)
+	Download FILO from http://felixx.tsn.or.jp/~ts1/filo, and expand
+
+	In the FILO source directory, type 'make'
+
+	The first invocation of make builds the default Config file, which
+	should be edited to meet your needs. In particular look at the line:
+
+	"AUTOBOOT_FILE ...."
+
+	and make sure that it looks sensible for your setup. The line
+	AUTOBOOT_FILE "hda1:/vmlinuz root=/dev/hda2 console=ttyS0,115200" 
+	reads as:
+		- find a linux os image on device hda partion 1 called vmlinuz,
+		- load this image
+		- execute the image passing kernel command line parameters of:
+		      "root=/dev/hda2 console=ttyS0,115200" 
+
+	after editing Config, type 'make' again, and this will build the file
+	'filo.elf' which is the payload we will be using.
+
+	Copy this file to somewhere which the LinuxBIOSv2 makefile can easily 
+	find it. I just tend to keep it in the root directory though I'm sure
+	others will condem me for that practise:
+	'cp filo.elf /'
+
+	Make sure that you have compiled a kernel bzImage, and copied it to
+	the file location you identified in the FILO Config file.
+
+
+Step 5)
+	The next step is to create the build environment for the epia-m. This
+	step creates the appropriate makefiles and build directories for the
+	epia-m.
+
+	'cd targets'
+	'./buildtarget via/epia-m'
+
+	This step will create a subdirectory in the targets/via/epia-m
+	directory called epia-m, which is the build directory for LinuxBIOSv2.
+
+	The main configuration file for the epia-m is in 
+	'targets/via/epia-m/Config.lb'
+
+	If you need to make any changes to the configuration, for example you wish to
+	locate filo.elf in a place other than '/filo.elf', or during the more advanced
+	steps of this HOWTO, then these changes are made to this file.
+
+	You need to re-run the './buildtartegt via/epia-m' after any such change.
+
+	The directory 'targets/via/epia-m' contains other sample Config.lb files, any
+        of which can be copied through to Config.lb in order to become the current 
+	configuration.
+
+	Once you have your Config.lb set up to your needs, and the build environment
+	created with './buildtarget', it is time to build a rom image.
+
+	Change directory into the build directory 'targets/via/epia-m/epia-m'
+
+	The configuration as set up by the buildtarget process will create a LinuxBIOS
+        which is exactly 196608 bytes long, which is exactly 64K bytes short of what
+        needs to go into the 256K flash rom. The other 64K is for your vga bios
+	which is simply merged with the linuxbios image. The easiest way to make this 
+	happen is to edit the Makefile and change the line
+
+	     cat fallback/linuxbios.rom > linuxbios.rom
+
+        to
+
+             cat /video.bios.bin fallback/linuxbios.rom >linuxbios.rom
+
+	Note: the above order of merging the files together is critical 
+ 
+	You will need to remember to make this change every time after you have run
+        the buildtarget program.
+	
+	Type 'make', and wait for the build process to complete.
+
+	If all went well, then you should find a file 'linuxbios.rom' in your
+	current directory. Check that it is 262144 bytes long - i.e. exactly the right 
+	size for the flash rom chip in your EPIA-M / MII.
+
+
+ 
+Step 6)
+	NOTE: BE ADVISED THAT THIS STEP CAN KILL YOUR MOTHERBOARD !
+	IF YOU DO NOT HAVE A MEANS OF RECOVERING FROM FLASHING YOUR BIOS,
+	YOU MAY/WILL BE LEFT WITH A DEAD MACHINE.
+
+
+	Assuming that you are using a Bios Saviour, make sure that the switch is set
+	to the position for your LinuxBIOSv2 image.
+
+	Type 'flash_rom' to make sure it can see the flash chip, and verify its type if
+	possible.
+
+	Only once you are happy that you are about to re-programme the desired chip, type
+	'flash_rom -w linuxbios.rom', and wait the few seconds it takes to program it.
+
+	Once it has finished, verify that the chip was re-rogrammed correctly - type
+	'flash_rom -v linuxbios.rom'
+
+ 
+
+Step 7) 
+	Power cycle the machine. LinuxBIOSv2 should come up in a few seconds.
+
+	With a connection to the serial port set at 115200, you should see LinuxBIOSv2
+	come up, launch FILO, and if you have a timeout set in FILO, then it may be
+	waiting for you to confirm its boot command line.
+
+	As long as you have this command line set up correctly, and an os image in the
+	right place, then FILO should proceed to boot into your Linux os.
+
+	If you do, CONGRATULATIONS ! It WORKED ! Pat yourself on the back,
+	why not try the optional steps now ?
+
+	If you don't, time to start capturing the output of the serial port
+	and talking to the linuxbios mailing list.
+
+
+Optional steps - for use only if step 7 was successfull.
+
+OK so now we have a BIOS which boots your computer fully into the operating system, and
+depending upon your needs that may be all that you want. However LinuxBIOSv2 has a few more
+tricks up its sleeve should you find yourself hungry for more.
+
+Speeding up the boot
+--------------------
+
+Linuxbios sends its debugging output to the first serial port and, depending upon the amount of debug
+output selected, can be the limiting factor in the speed with which it boots your computer - regardless 
+of whether you have anything attached to the serial port.
+
+Linuxbios uses the notion of debug levels to control what is sent to the serial port. These levels
+range from 0 to 9 with 0 being the least verbose and 9 being the most verbose.
+
+These levels are defined in the Config.lb file described earlier. To reduce the output set:
+    option  MAXIMUM_CONSOLE_LOGLEVEL=8 
+    option  DEFAULT_CONSOLE_LOGLEVEL=8
+to lower values.
+
+Next you will have to run 'buildtarget' again to propagate the effects of the config change.
+Then edit your Makefile again to include your video bios in the final merging.
+
+Then run 'make clean' followed by 'make'.
+ 
+
+Advanced ACPI
+-------------
+
+	LinuxBIOSv2 now supports ACPI on the epia-m and epia-m II. In particular the interrupt
+	processing in Linux can be done through ACPI, and crude power management support
+	is provided. This includes software power off, and power management events from the
+	power button.
+
+	It is possible to enhance this behaviour to provide the full capabilities of the 
+	original BIOS, which includes different sleep levels and wake from these levels
+	upon certain events. This is achieved by using a 'grabbed' copy of the ACPI 
+	Differentiated System Descriptor Table or DSDT from the original BIOS.
+
+	For copyright reasons this table cannot be included with the source distribution
+	of LinuxBIOSv2.
+
+
+	You MUST have 'iasl' - Intel's ACPI Asl compiler for Unix/Linux - 
+		http://developer.intel.com/technology/iapc/acpi/downloads.htm.
+
+
+	To replace the LinuxBIOSv2 DSDT with the grabbed one from the original BIOS:
+
+		- Start the computer using the original BIOS, and make sure that you
+			have ACPI set up in the kernel that you are running
+
+		- Grab the DSDT table - 'cat /proc/acpi/dsdt >dsdt.aml'
+		- Convert to asl code - 'iasl -d dsdt.aml'          (creates dsdt.dsl)
+		- Convert it to a C hex table - 'iasl -tc dsdt.dsl' (creates dsdt.hex)
+		- Replace the file 'src/mainboard/via/epia-m/dsdt.c with dsdt.hex
+
+	Now re-build LinuxBIOSv2, re-program the flash and power cycle.
+
+	If you wish to return to the LinuxBIOSv2 DSDT, then the original file dsdt.asl can be converted
+	into a C hex file using 'iasl -tc dsdt.asl'
+
+
+
+Boot from Onboard Compact Flash (MII only)
+------------------------------------------
+
+	LinuxBIOSv2 now supports the onboard compact flash on the MII as an IDE drive,
+        and it is possible to boot directly from this drive using the following steps.
+
+	The first step is to get Filo or whatever payload you are using to recognise
+        and use this device.
+
+	In order that the pcmcia subsystem of the Linux kernel can correctly configure
+        the device later on in the boot process the CF is set up with its I/O
+	registers in a contiguous block of 16 bytes at 0x1e0 through 0x1ef. Unfortunately
+        this is not a standard IDE address which is why we need to 'fix' filo to use it.
+        (Actually it is half of the address range used by IDE4, and so we need to
+        be careful to tell the kernel not to probe that address - more on that later).
+
+	The first step is to change the filo Config file.
+	1) Comment out SUPPORT_PCI=1. This line instructs filo to search for PCI based IDE 
+           adapters only, and the CF is not attached to a PCI based IDE controller.
+	2) Add the following two lines somewhere in the Config file:
+		IDE2_CMD = 0x1e0
+		IDE2_CNTRL =0x1ec
+
+
+	The second step is to modify the file drivers/ide.c in the filo source directory.
+	Find the function 'find_ide_controller_compat' and change it to look like
+
+	static int find_ide_controller_compat(struct controller *ctrl, int index)
+	{
+		if (index >= IDE_MAX_CONTROLLERS)
+			return -1;
+	#ifdef IDE2_CMD
+		if(index == 2){
+			ctrl->cmd_base = IDE2_CMD;
+			ctrl->ctrl_base = IDE2_CNTRL;
+			return 0;
+		}
+	#endif
+		ctrl->cmd_base  = ide_base[index];
+		ctrl->ctrl_base = ide_base[index] + IDE_REG_EXTENDED_OFFSET;
+		return 0;
+	}
+	Filo will now recognise the CF as the first device on the third IDE controller 
+        (i.e. ide2), and can be referred to as 'hde'
+
+
+	The next step is to create an initrd file for your Linux kernel. What? Why?
+        The CF socket on your MII is hardwired to the PCMCIA controller and for all intents
+        and purposes it is a PCMCIA device. This means that once Linux boots it will be under
+        the control of the pcmcia manager. Now according to the pcmcia-utils documentation,
+        the pcmcia manager is intended to control and configure devices on an already
+        running system. Yet if we need the CF to be the root device, it needs to be mounted
+        very early on in the boot sequence, before the stage where pcmcia devices would normally
+        be configured. The answer is to use an initrd file to get the pcmcia manager running early
+        for the CF. If you are unfamiliar with initrd then 'man initrd' will give you more background.
+
+
+	The easiest way to create an initrd is to use the script 'mkcfinitrd' which is at the bottom
+        of this howto. This is a tailored version of the 'pcinitrd' script from the pcmcia-utils package.
+        Make sure that 'ash' is available on your system as this is the tiny shell programme used during
+        the initrd phase of booting.
+
+        It is worth mounting the initrd generated, and looking over it to make sure that
+        it contains all of the modules necessary to load and initialise the CF. It does not
+        need drivers for whatever you use in the pcmcia socket, as that can be initialised
+        later on in the boot process as before.
+
+        Finally gzip the file created, and move it alongside your kernel.
+
+	Next adjust your FILO command line to pick things up from the CF. My linux command
+	line in filo looks like:
+
+	AUTOBOOT_FILE = "hde:/vmlinuz initrd=hde:/initrd.gz root=/dev/hde console=tty0 ide4=noprobe"
+
+	The ide4=noprobe option is required to stop the kernel from probing the address used
+        by the CF. As this address is half that used as the standard address for a fifth (i.e. ide4)
+        controller, the kernel hangs whilst trying to initialise this device if this option
+        is not given.
+
+	Finally make sure that you have copied the necessary files onto your CF, and re-boot
+	your computer.
+
+
+
+******************* mkcfinitrd script **************************************
+#!/bin/sh
+#
+# Utility for constructing CF initrd for Epia-MII CF Boot
+#
+# Copyright (C) 2005 Nick Barker -- nick.barker9@btinternet.com
+#
+# Based on pcinitrd
+# Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
+
+SIZE=2400
+MODULES="pcmcia/pcmcia_core.o pcmcia/ds.o pcmcia/yenta_socket.o"
+BLK="kernel/drivers/ide/legacy/ide-cs.o"
+KERNEL=`uname -r`
+MODDIR=/lib/modules/$KERNEL
+BIN="bin/mount bin/umount sbin/insmod sbin/cardmgr"
+LIB=`ls /lib/libc.so.? | sort | tail -1`
+ETC="/etc/ld.so.cache /etc/pcmcia/config /etc/pcmcia/config.opts"
+DEV="/dev/console /dev/null /dev/ram /dev/tty1 /dev/tty2 /dev/tty3 /dev/tty4"
+MNT=/tmp/initrd.mnt
+
+# name of the initrd file to make
+TARGET=/tmp/initrd
+
+fail()
+{
+    umount $MNT
+    rmdir $MNT
+    exit 1
+}
+trap fail SIGTERM SIGINT
+
+strip_cp()
+{
+    if [ -d $3 ] ; then
+	DEST=$3/`basename $2`
+    else
+	DEST=$3
+    fi
+    strip $1 --verbose -o $DEST $2 | sed -e 's/([^ ]*)//g' || fail
+}
+
+mkdir --verbose $MNT || exit 1
+
+echo "Creating filesystem on $TARGET"
+if [ -b $TARGET ] ; then
+    rm $TARGET || fail
+fi
+
+dd if=$ROOT/dev/zero of=$TARGET bs=1k count=$SIZE
+echo "y" | mke2fs $TARGET $SIZE >/dev/null || fail
+mount --verbose -t ext2 -o loop $TARGET $MNT || fail
+
+
+rm -rf $MNT/lost+found
+echo "Creating Directories on $TARGET"
+for DIR in bin dev etc lib proc tmp mnt ; do
+    mkdir --verbose $MNT/$DIR || fail
+done
+for DIR in block misc fs net pcmcia ; do
+    mkdir --verbose $MNT/lib/$DIR || fail
+done
+
+echo "Copying Files to $TARGET"
+for F in $DEV ; do
+    cp -a --verbose /$F $MNT/dev || fail
+done
+if [ -e /dev/systty ] ; then
+    cp -a --verbose /dev/systty $MNT/dev || fail
+fi
+
+for F in $BIN ; do
+    strip_cp --strip-all /$F $MNT/bin
+done
+strip_cp --strip-all /bin/ash $MNT/bin/sh
+
+for F in $LIB ; do
+    strip_cp --strip-debug /$F $MNT/lib
+done
+cp --verbose /lib/ld-linux.so.? $MNT/lib || fail
+
+for F in $ETC ; do
+    cp --verbose /$F $MNT/etc || fail
+done
+for F in scsi network ftl ide memory serial ; do
+    touch $MNT/etc/$F ; chmod +x $MNT/etc/$F
+done
+
+for MOD in $MODULES ; do
+    strip_cp --strip-debug $MODDIR/$MOD $MNT/lib/$MOD
+done
+
+strip_cp --strip-debug $MODDIR/$BLK $MNT/lib/block/ide-cs.o
+
+echo "Creating linuxrc startup script"
+cat > $MNT/linuxrc <<- 'EOF'
+	#!/bin/sh
+	
+	mount -t proc /proc /proc
+
+	echo ""
+	echo "==== initrd: starting PCMCIA services ===="
+	echo ""
+	PC=/lib/pcmcia
+	insmod $PC/pcmcia_core.o 
+	insmod $PC/yenta_socket.o
+	insmod $PC/ds.o
+	insmod /lib/block/ide-cs.o
+	if [ "$DEBUG" != "" ] ; then V=-v ; fi
+	cardmgr $V -q -o -c /etc -m /lib -s /tmp/stab -p /tmp/pid
+	umount /proc
+	echo ""
+	
+	if [ "$DEBUG" != "" ] ; then
+	    /bin/sh < /dev/console
+	fi
+EOF
+chmod +x $MNT/linuxrc 
+
+df -P $MNT | awk '/tmp/ { printf "%dK/%dK used\n",$3,$2 }'
+umount $VERBOSE $MNT
+rmdir $MNT
+echo "Finished $TARGET"
+echo "Now gzip $TARGET to create final initrd.gz"
+exit 0
+
+*************************** end mkcfinitrd ***********************************
\ No newline at end of file
diff --git a/src/arch/i386/lib/cpu.c b/src/arch/i386/lib/cpu.c
index 628bb79..11ccee2 100644
--- a/src/arch/i386/lib/cpu.c
+++ b/src/arch/i386/lib/cpu.c
@@ -234,11 +234,13 @@
 	// Check that we haven't been passed bad information as the result of a race 
 	// (i.e. BSP timed out while waiting for us to load secondary_stack)
 
+#if CONFIG_SMP  || CONFIG_IOPIC 
 	if (cpu->path.u.apic.apic_id != lapicid()) {
 		printk_err("CPU #%d Initialization FAILED: APIC ID mismatch (%u != %u)\n",
 				   info->index, cpu->path.u.apic.apic_id, lapicid());
 		// return without setting initialized flag
 	} else {
+#endif
 		/* Find what type of cpu we are dealing with */
 		identify_cpu(cpu);
 		printk_debug("CPU: vendor %s device %x\n",
@@ -255,8 +257,10 @@
 		}
 
 		printk_info("CPU #%d Initialized\n", info->index);
-	}
+#if CONFIG_SMP  || CONFIG_IOPIC 
 
+	}
+#endif
 	return;
 }
 
diff --git a/src/cpu/via/model_centaur/model_centaur_init.c b/src/cpu/via/model_centaur/model_centaur_init.c
index b76b065..33f10a8 100644
--- a/src/cpu/via/model_centaur/model_centaur_init.c
+++ b/src/cpu/via/model_centaur/model_centaur_init.c
@@ -15,6 +15,7 @@
 {
 	/* Turn on caching if we haven't already */
 	x86_enable_cache();
+	x86_setup_mtrrs(36);
 	x86_mtrr_check();
 
 	/* Enable the local cpu apics */
@@ -28,6 +29,13 @@
 #warning "FIXME - need correct cpu id here for VIA C3"
 static struct cpu_device_id cpu_table[] = {
 	{ X86_VENDOR_CENTAUR, 0x0670 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0671 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0672 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0673 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0674 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0675 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0676 },		// VIA C3 Samual 2
+	{ X86_VENDOR_CENTAUR, 0x0677 },		// VIA C3 Samual 2
 	{ X86_VENDOR_CENTAUR, 0x0678 },		// VIA C3 Ezra
 	{ X86_VENDOR_CENTAUR, 0x0680 },		// VIA C3 Ezra-T
 	{ X86_VENDOR_CENTAUR, 0x0698 },		// VIA C3 Nehemiah
diff --git a/src/devices/cardbus_device.c b/src/devices/cardbus_device.c
index 4c92d91..5b03d28 100644
--- a/src/devices/cardbus_device.c
+++ b/src/devices/cardbus_device.c
@@ -74,7 +74,14 @@
 	resource_t moving_base, moving_limit, moving;
 	unsigned long type;
 	uint16_t ctl;
-	
+	unsigned long index;	
+
+	/* See if needs a card control registers base address */
+
+	pci_get_resource(dev, PCI_BASE_ADDRESS_0);
+
+	compact_resources(dev);
+
 	/* See which bridge I/O resources are implemented */
 	moving_base  = pci_moving_config32(dev, PCI_CB_IO_BASE_0);
 	moving_limit = pci_moving_config32(dev, PCI_CB_IO_LIMIT_0);
diff --git a/src/include/device/cardbus.h b/src/include/device/cardbus.h
index 38aa41c..07cc46a 100644
--- a/src/include/device/cardbus.h
+++ b/src/include/device/cardbus.h
@@ -6,6 +6,7 @@
 unsigned int cardbus_scan_bus(struct bus *bus, 
 	unsigned min_devfn, unsigned max_devfn, unsigned int max);
 unsigned int cardbus_scan_bridge(device_t dev, unsigned int max);
+void cardbus_enable_resources(device_t dev);
 
 extern struct device_operations default_cardbus_ops_bus;
 
diff --git a/src/mainboard/via/epia-m/Config.lb b/src/mainboard/via/epia-m/Config.lb
index decbd0e..6dc4b3d 100644
--- a/src/mainboard/via/epia-m/Config.lb
+++ b/src/mainboard/via/epia-m/Config.lb
@@ -45,6 +45,7 @@
 driver mainboard.o
 if HAVE_PIRQ_TABLE object irq_tables.o end
 #object reset.o
+object vgabios.o
 
 if HAVE_ACPI_TABLES
 	object fadt.o
@@ -133,11 +134,6 @@
 chip northbridge/via/vt8623
 	device pci_domain 0 on
 		chip southbridge/via/vt8235
-			register "enable_usb" = "0"
-			register "enable_native_ide" = "0"
-			register "enable_com_ports" = "1"
-			register "enable_keyboard" = "0"
-			register "enable_nvram" = "1"
 
 			device pci 10.0 on end # USB 1.1
 			device pci 10.1 on end # USB 1.1
@@ -151,7 +147,7 @@
 						irq 0x70 = 6
 						drq 0x74 = 2
 					end
-					device pnp 2e.1 off	# Parallel Port
+					device pnp 2e.1 on	# Parallel Port
 						io 0x60 = 0x378
 						irq 0x70 = 7
 						drq 0x74 = 3
@@ -178,10 +174,16 @@
 			device pci 12.0 on end  # Ethernet
 		end
 #		This is on the EPIA MII, not the M.
-#		chip southbridge/ricoh/rl5c476
-#		end
+		chip southbridge/ricoh/rl5c476
+			register "enable_cf" = "1"
+			device pci 0a.0 on end
+			device pci 0a.1 on end	
+		end
 	end
 
-	chip cpu/via/model_centaur 
+	device apic_cluster 0 on
+		chip cpu/via/model_centaur
+			device apic 0 on  end 
+		end
 	end
 end
diff --git a/src/mainboard/via/epia-m/Options.lb b/src/mainboard/via/epia-m/Options.lb
index 4184236..6c3193e 100644
--- a/src/mainboard/via/epia-m/Options.lb
+++ b/src/mainboard/via/epia-m/Options.lb
@@ -36,6 +36,8 @@
 uses MAXIMUM_CONSOLE_LOGLEVEL
 uses CONFIG_CONSOLE_SERIAL8250
 uses CONFIG_UDELAY_TSC
+uses CONFIG_PCI_ROM_RUN
+uses CONFIG_CONSOLE_VGA
 
 ## ROM_SIZE is the size of boot ROM that this board will use.
 default ROM_SIZE  = 256*1024
@@ -43,6 +45,8 @@
 ###
 ### Build options
 ###
+default CONFIG_PCI_ROM_RUN=0
+default CONFIG_CONSOLE_VGA=0
 
 ##
 ## Build code for the fallback boot
@@ -70,6 +74,13 @@
 default HAVE_PIRQ_TABLE=1
 default IRQ_SLOT_COUNT=5
 
+
+##
+## Build code to load acpi tables
+##
+default HAVE_ACPI_TABLES=1
+
+
 ##
 ## Build code to export a CMOS option table
 ##
diff --git a/src/mainboard/via/epia-m/auto.c b/src/mainboard/via/epia-m/auto.c
index 7d08de8..c69b7bf 100644
--- a/src/mainboard/via/epia-m/auto.c
+++ b/src/mainboard/via/epia-m/auto.c
@@ -68,7 +68,7 @@
 		die("Southbridge not found!!!\n");
 	}
 	pci_write_config8(dev, 0x50, 0x80);
-	pci_write_config8(dev, 0x51, 0x1F);
+	pci_write_config8(dev, 0x51, 0x1f);
 #if 0
 	// This early setup switches IDE into compatibility mode before PCI gets 
 	// // a chance to assign I/Os
@@ -141,14 +141,8 @@
 
 	print_debug(" Enabling shadow ram\r\n");
 	enable_shadow_ram();
-	/*
-	  memreset_setup();
-	  this is way more generic than we need.
-	  sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
-	*/
-	sdram_set_registers((const struct mem_controller *) 0);
-	sdram_set_spd_registers((const struct mem_controller *) 0);
-	sdram_enable(0, (const struct mem_controller *) 0);
+
+	ddr_ram_setup((const struct mem_controller *)0);
 	
 	/* Check all of memory */
 #if 0
diff --git a/src/mainboard/via/epia-m/dsdt.asl b/src/mainboard/via/epia-m/dsdt.asl
new file mode 100644
index 0000000..2fcb77e
--- /dev/null
+++ b/src/mainboard/via/epia-m/dsdt.asl
@@ -0,0 +1,256 @@
+/*
+ * Minimalist ACPI DSDT table for EPIA-M / MII
+ * (C) Copyright 2004 Nick Barker <Nick.Barker9@btinternet.com>
+ *
+ * 
+ */
+
+DefinitionBlock ("DSDT.aml", "DSDT", 1, "LXBIOS", "LXB-DSDT", 1)
+{
+	/*  
+	 * Define the main processor
+	 */
+	Scope (\_PR)
+	{
+		Processor (\_PR.CPU0, 0x00, 0x00000410, 0x06) {}
+	}
+
+	/* For now only define 2 power states:
+	 *  - S0 which is fully on
+	 *  - S5 which is soft off
+	 * any others would involve declaring the wake up methods
+	 */
+	Name (\_S0, Package () {0x00, 0x00, 0x00, 0x00 })
+	Name (\_S5, Package () {0x02, 0x02, 0x00, 0x00 })
+
+	/* Root of the bus hierarchy */
+	Scope (\_SB)
+    	{
+		/* Define how interrupt Link A is plumbed in */ 
+		Device (LNKA)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x01)
+			/* Status - always return ready */
+			Method (_STA, 0, NotSerialized)
+			{
+				Return (0x0B)
+ 			}
+			/* Current Resources - return irq set up in BIOS */  
+			Method (_CRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+				{
+					IRQ (Level, ActiveLow, Shared) {5}
+				})
+				Return (BUFF)
+                	}
+			/* Possible Resources - return the range of irqs
+ 			 * we are using for PCI - only here to keep Linux ACPI
+			 * happy 
+			 */
+			Method (_PRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+                    		{
+					IRQ (Level, ActiveLow, Shared) {5,9,10}
+                    		})
+                    		Return (BUFF)
+                	}
+			/* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+			 * assignments as long as the CRS and STA functions 
+			 * return good values
+			 */
+			Method (_SRS, 1, NotSerialized ) {}
+			/* Disable - dummy function to keep Linux ACPI happy */
+			Method (_DIS, 0, NotSerialized ) {}
+ 
+		} // End of LNKA 
+
+		/* Define how interrupt Link B is plumbed in */ 
+		Device (LNKB)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x02)
+			/* Status - always return ready */
+			Method (_STA, 0, NotSerialized)
+			{
+				Return (0x0B)
+ 			}
+			/* Current Resources - return irq set up in BIOS */  
+			Method (_CRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+				{
+					IRQ (Level, ActiveLow, Shared) {9}
+				})
+				Return (BUFF)
+                	}
+			/* Possible Resources - return the range of irqs
+			 * we are using for PCI - only here to keep Linux ACPI
+			 * happy 
+			 */
+			Method (_PRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+                    		{
+					IRQ (Level, ActiveLow, Shared) {5,9,10}
+                    		})
+                    		Return (BUFF)
+                	}
+			/* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+			 * assignments as long as the CRS and STA functions 
+			 * return good values
+			 */
+			Method (_SRS, 1, NotSerialized ) {}
+			/* Disable - dummy function to keep Linux ACPI happy */
+			Method (_DIS, 0, NotSerialized ) {}
+ 
+		} // End of LNKB
+
+		/* Define how interrupt Link C is plumbed in */ 
+		Device (LNKC)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x03)
+			/* Status - always return ready */
+			Method (_STA, 0, NotSerialized)
+			{
+				Return (0x0B)
+ 			}
+			/* Current Resources - return irq set up in BIOS */  
+			Method (_CRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+				{
+					IRQ (Level, ActiveLow, Shared) {9}
+				})
+				Return (BUFF)
+                	}
+			/* Possible Resources - return the range of irqs
+			 * we are using for PCI - only here to keep Linux ACPI
+			 * happy 
+			 */
+			Method (_PRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+                    		{
+					IRQ (Level, ActiveLow, Shared) {5,9,10}
+                    		})
+                    		Return (BUFF)
+                	}
+			/* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+			 * assignments as long as the CRS and STA functions 
+			 * return good values
+			 */
+			Method (_SRS, 1, NotSerialized ) {}
+			/* Disable - dummy function to keep Linux ACPI happy */
+			Method (_DIS, 0, NotSerialized ) {}
+ 
+		} // End of LNKC
+
+		/* Define how interrupt Link D is plumbed in */ 
+		Device (LNKD)
+		{
+			Name (_HID, EisaId ("PNP0C0F"))
+			Name (_UID, 0x04)
+			/* Status - always return ready */
+			Method (_STA, 0, NotSerialized)
+			{
+				Return (0x0B)
+ 			}
+			/* Current Resources - return irq set up in BIOS */  
+			Method (_CRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+				{
+					IRQ (Level, ActiveLow, Shared) {5}
+				})
+				Return (BUFF)
+                	}
+			/* Possible Resources - return the range of irqs
+			 * we are using for PCI - only here to keep Linux ACPI
+			 * happy 
+			 */
+			Method (_PRS, 0, NotSerialized)
+			{
+				Name (BUFF, ResourceTemplate ()
+                    		{
+					IRQ (Level, ActiveLow, Shared) {5,9,10}
+                    		})
+                    		Return (BUFF)
+                	}
+			/* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+			 * assignments as long as the CRS and STA functions 
+			 * return good values
+			 */
+			Method (_SRS, 1, NotSerialized ) {}
+			/* Disable - dummy function to keep Linux ACPI happy */
+			Method (_DIS, 0, NotSerialized ) {}
+ 
+		} // End of LNKD 
+
+ 
+		/* top PCI device */
+		Device (PCI0)
+		{
+			Name (_HID, EisaId ("PNP0A03"))
+			Name (_ADR, 0x00)
+			Name (_UID, 0x00)
+			Name (_BBN, 0x00)
+
+			/* PCI Routing Table */
+			Name (_PRT, Package () {
+				Package () {0x000AFFFF, 0x00, LNKD, 0x00}, // Cardbus Link D
+				Package () {0x000AFFFF, 0x01, LNKA, 0x00}, // Cardbus Link A 
+				Package () {0x000AFFFF, 0x02, LNKB, 0x00}, // Cardbus Link B
+				Package () {0x000AFFFF, 0x03, LNKC, 0x00}, // Cardbus Link C
+
+				Package () {0x000DFFFF, 0x00, LNKB, 0x00}, // Firewire Link B
+				Package () {0x000DFFFF, 0x01, LNKC, 0x00}, // Firewire Link C
+				Package () {0x000DFFFF, 0x02, LNKD, 0x00}, // Firewire Linc D
+				Package () {0x000DFFFF, 0x03, LNKA, 0x00}, // Firewire Link A
+
+				Package () {0x0010FFFF, 0x00, LNKA, 0x00}, // USB Link A
+				Package () {0x0010FFFF, 0x01, LNKB, 0x00}, // USB Link B
+				Package () {0x0010FFFF, 0x02, LNKC, 0x00}, // USB Link C
+				Package () {0x0010FFFF, 0x03, LNKD, 0x00}, // USB Link D
+
+				Package () {0x0011FFFF, 0x00, LNKA, 0x00}, // vt8623 Link A
+				Package () {0x0011FFFF, 0x01, LNKB, 0x00}, // vt8623 Link B
+				Package () {0x0011FFFF, 0x02, LNKC, 0x00}, // vt8623 Link C
+				Package () {0x0011FFFF, 0x03, LNKD, 0x00}, // vt8623 Link D
+
+				Package () {0x0012FFFF, 0x00, LNKA, 0x00}, // LAN Link A 
+				Package () {0x0012FFFF, 0x01, LNKB, 0x00}, // LAN Link B
+				Package () {0x0012FFFF, 0x02, LNKC, 0x00}, // LAN Link C
+				Package () {0x0012FFFF, 0x03, LNKD, 0x00}, // LAN Link D
+
+				Package () {0x0013FFFF, 0x00, LNKA, 0x00}, // Riser slot LinkA 
+				Package () {0x0013FFFF, 0x01, LNKB, 0x00}, // Riser slot LinkB
+				Package () {0x0013FFFF, 0x02, LNKC, 0x00}, // Riser slot LinkC
+				Package () {0x0013FFFF, 0x03, LNKD, 0x00}, // Riser slot LinkD
+
+				Package () {0x0014FFFF, 0x00, LNKB, 0x00}, // Slot 1, Link B
+				Package () {0x0014FFFF, 0x01, LNKC, 0x00}, // Slot 1, Link C
+				Package () {0x0014FFFF, 0x02, LNKD, 0x00}, // Slot 1, Link D
+				Package () {0x0014FFFF, 0x03, LNKA, 0x00}, // Slot 1, Link A
+                
+				Package () {0x0001FFFF, 0x00, LNKA, 0x00}, // VGA Link A
+				Package () {0x0001FFFF, 0x01, LNKB, 0x00}, // VGA Link B
+				Package () {0x0001FFFF, 0x02, LNKC, 0x00}, // VGA Link C
+				Package () {0x0001FFFF, 0x03, LNKD, 0x00} // VGA Link D
+
+            		})
+
+
+		} // End of PCI0
+
+	} // End of _SB
+
+} // End of Definition Block
+
diff --git a/src/mainboard/via/epia-m/dsdt.c b/src/mainboard/via/epia-m/dsdt.c
new file mode 100644
index 0000000..62b0f3d
--- /dev/null
+++ b/src/mainboard/via/epia-m/dsdt.c
@@ -0,0 +1,142 @@
+/*
+ * 
+ * Intel ACPI Component Architecture
+ * ASL Optimizing Compiler / AML Disassembler version 20040715 [Aug 16 2004]
+ * Copyright (C) 2000 - 2004 Intel Corporation
+ * Supports ACPI Specification Revision 2.0c
+ * 
+ * Compilation of "dsdt.asl" - Thu Oct 27 09:25:57 2005
+ * 
+ * C source code output
+ *
+ */
+unsigned char AmlCode[] = 
+{
+    0x44,0x53,0x44,0x54,0xF0,0x03,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x01,0x11,0x4C,0x58,0x42,0x49,0x4F,0x53,  /* 00000008    "..LXBIOS" */
+    0x4C,0x58,0x42,0x2D,0x44,0x53,0x44,0x54,  /* 00000010    "LXB-DSDT" */
+    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
+    0x15,0x07,0x04,0x20,0x10,0x12,0x5F,0x50,  /* 00000020    "... .._P" */
+    0x52,0x5F,0x5B,0x83,0x0B,0x43,0x50,0x55,  /* 00000028    "R_[..CPU" */
+    0x30,0x00,0x10,0x04,0x00,0x00,0x06,0x08,  /* 00000030    "0......." */
+    0x5F,0x53,0x30,0x5F,0x12,0x06,0x04,0x00,  /* 00000038    "_S0_...." */
+    0x00,0x00,0x00,0x08,0x5F,0x53,0x35,0x5F,  /* 00000040    "...._S5_" */
+    0x12,0x08,0x04,0x0A,0x02,0x0A,0x02,0x00,  /* 00000048    "........" */
+    0x00,0x10,0x4E,0x39,0x5F,0x53,0x42,0x5F,  /* 00000050    "..N9_SB_" */
+    0x5B,0x82,0x44,0x06,0x4C,0x4E,0x4B,0x41,  /* 00000058    "[.D.LNKA" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000060    "._HID.A." */
+    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,  /* 00000068    "..._UID." */
+    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000070    ".._STA.." */
+    0x0A,0x0B,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000078    "...._CRS" */
+    0x00,0x08,0x42,0x55,0x46,0x46,0x11,0x09,  /* 00000080    "..BUFF.." */
+    0x0A,0x06,0x23,0x20,0x00,0x18,0x79,0x00,  /* 00000088    "..# ..y." */
+    0xA4,0x42,0x55,0x46,0x46,0x14,0x1A,0x5F,  /* 00000090    ".BUFF.._" */
+    0x50,0x52,0x53,0x00,0x08,0x42,0x55,0x46,  /* 00000098    "PRS..BUF" */
+    0x46,0x11,0x09,0x0A,0x06,0x23,0x20,0x06,  /* 000000A0    "F....# ." */
+    0x18,0x79,0x00,0xA4,0x42,0x55,0x46,0x46,  /* 000000A8    ".y..BUFF" */
+    0x14,0x06,0x5F,0x53,0x52,0x53,0x01,0x14,  /* 000000B0    ".._SRS.." */
+    0x06,0x5F,0x44,0x49,0x53,0x00,0x5B,0x82,  /* 000000B8    "._DIS.[." */
+    0x45,0x06,0x4C,0x4E,0x4B,0x42,0x08,0x5F,  /* 000000C0    "E.LNKB._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000000C8    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,  /* 000000D0    "._UID..." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 000000D8    "._STA..." */
+    0x0B,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 000000E0    "..._CRS." */
+    0x08,0x42,0x55,0x46,0x46,0x11,0x09,0x0A,  /* 000000E8    ".BUFF..." */
+    0x06,0x23,0x00,0x02,0x18,0x79,0x00,0xA4,  /* 000000F0    ".#...y.." */
+    0x42,0x55,0x46,0x46,0x14,0x1A,0x5F,0x50,  /* 000000F8    "BUFF.._P" */
+    0x52,0x53,0x00,0x08,0x42,0x55,0x46,0x46,  /* 00000100    "RS..BUFF" */
+    0x11,0x09,0x0A,0x06,0x23,0x20,0x06,0x18,  /* 00000108    "....# .." */
+    0x79,0x00,0xA4,0x42,0x55,0x46,0x46,0x14,  /* 00000110    "y..BUFF." */
+    0x06,0x5F,0x53,0x52,0x53,0x01,0x14,0x06,  /* 00000118    "._SRS..." */
+    0x5F,0x44,0x49,0x53,0x00,0x5B,0x82,0x45,  /* 00000120    "_DIS.[.E" */
+    0x06,0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,  /* 00000128    ".LNKC._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000130    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x0A,0x03,0x14,0x09,  /* 00000138    "_UID...." */
+    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0B,  /* 00000140    "_STA...." */
+    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000148    ".._CRS.." */
+    0x42,0x55,0x46,0x46,0x11,0x09,0x0A,0x06,  /* 00000150    "BUFF...." */
+    0x23,0x00,0x02,0x18,0x79,0x00,0xA4,0x42,  /* 00000158    "#...y..B" */
+    0x55,0x46,0x46,0x14,0x1A,0x5F,0x50,0x52,  /* 00000160    "UFF.._PR" */
+    0x53,0x00,0x08,0x42,0x55,0x46,0x46,0x11,  /* 00000168    "S..BUFF." */
+    0x09,0x0A,0x06,0x23,0x20,0x06,0x18,0x79,  /* 00000170    "...# ..y" */
+    0x00,0xA4,0x42,0x55,0x46,0x46,0x14,0x06,  /* 00000178    "..BUFF.." */
+    0x5F,0x53,0x52,0x53,0x01,0x14,0x06,0x5F,  /* 00000180    "_SRS..._" */
+    0x44,0x49,0x53,0x00,0x5B,0x82,0x45,0x06,  /* 00000188    "DIS.[.E." */
+    0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,0x49,  /* 00000190    "LNKD._HI" */
+    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 00000198    "D.A...._" */
+    0x55,0x49,0x44,0x0A,0x04,0x14,0x09,0x5F,  /* 000001A0    "UID...._" */
+    0x53,0x54,0x41,0x00,0xA4,0x0A,0x0B,0x14,  /* 000001A8    "STA....." */
+    0x1A,0x5F,0x43,0x52,0x53,0x00,0x08,0x42,  /* 000001B0    "._CRS..B" */
+    0x55,0x46,0x46,0x11,0x09,0x0A,0x06,0x23,  /* 000001B8    "UFF....#" */
+    0x20,0x00,0x18,0x79,0x00,0xA4,0x42,0x55,  /* 000001C0    " ..y..BU" */
+    0x46,0x46,0x14,0x1A,0x5F,0x50,0x52,0x53,  /* 000001C8    "FF.._PRS" */
+    0x00,0x08,0x42,0x55,0x46,0x46,0x11,0x09,  /* 000001D0    "..BUFF.." */
+    0x0A,0x06,0x23,0x20,0x06,0x18,0x79,0x00,  /* 000001D8    "..# ..y." */
+    0xA4,0x42,0x55,0x46,0x46,0x14,0x06,0x5F,  /* 000001E0    ".BUFF.._" */
+    0x53,0x52,0x53,0x01,0x14,0x06,0x5F,0x44,  /* 000001E8    "SRS..._D" */
+    0x49,0x53,0x00,0x5B,0x82,0x4B,0x1F,0x50,  /* 000001F0    "IS.[.K.P" */
+    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000001F8    "CI0._HID" */
+    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x41,  /* 00000200    ".A...._A" */
+    0x44,0x52,0x00,0x08,0x5F,0x55,0x49,0x44,  /* 00000208    "DR.._UID" */
+    0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x08,  /* 00000210    ".._BBN.." */
+    0x5F,0x50,0x52,0x54,0x12,0x43,0x1D,0x20,  /* 00000218    "_PRT.C. " */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000220    "........" */
+    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000228    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C,  /* 00000230    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000238    "NKA....." */
+    0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000240    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000248    "KB......" */
+    0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000250    ".....LNK" */
+    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000258    "C......." */
+    0x0D,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000260    "...LNKB." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 00000268    "........" */
+    0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,  /* 00000270    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,  /* 00000278    "........" */
+    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000280    "LNKD...." */
+    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C,  /* 00000288    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 00000290    "NKA....." */
+    0xFF,0xFF,0x10,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000298    ".....LNK" */
+    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000002A0    "A......." */
+    0x10,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 000002A8    "...LNKB." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x10,0x00,  /* 000002B0    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000002B8    "..LNKC.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x10,0x00,0x0A,  /* 000002C0    "........" */
+    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 000002C8    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x11,0x00,0x00,0x4C,  /* 000002D0    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 000002D8    "NKA....." */
+    0xFF,0xFF,0x11,0x00,0x01,0x4C,0x4E,0x4B,  /* 000002E0    ".....LNK" */
+    0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000002E8    "B......." */
+    0x11,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,  /* 000002F0    "....LNKC" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x11,  /* 000002F8    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000300    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x12,0x00,  /* 00000308    "........" */
+    0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000310    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x12,0x00,0x01,0x4C,  /* 00000318    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,  /* 00000320    "NKB....." */
+    0xFF,0xFF,0x12,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000328    "......LN" */
+    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000330    "KC......" */
+    0xFF,0x12,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000338    ".....LNK" */
+    0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000340    "D......." */
+    0x13,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000348    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x13,0x00,  /* 00000350    "........" */
+    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000358    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x13,0x00,0x0A,0x02,  /* 00000360    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 00000368    "LNKC...." */
+    0x0C,0xFF,0xFF,0x13,0x00,0x0A,0x03,0x4C,  /* 00000370    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 00000378    "NKD....." */
+    0xFF,0xFF,0x14,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000380    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000388    "B......." */
+    0x14,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000390    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x14,0x00,  /* 00000398    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000003A0    "..LNKD.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x14,0x00,0x0A,  /* 000003A8    "........" */
+    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 000003B0    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 000003B8    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 000003C0    "NKA....." */
+    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 000003C8    ".....LNK" */
+    0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000003D0    "B......." */
+    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,  /* 000003D8    "....LNKC" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 000003E0    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,  /* 000003E8    "...LNKD." */
+
+};
diff --git a/src/mainboard/via/epia-m/fadt.c b/src/mainboard/via/epia-m/fadt.c
index 3d9873e..702d556 100644
--- a/src/mainboard/via/epia-m/fadt.c
+++ b/src/mainboard/via/epia-m/fadt.c
@@ -15,8 +15,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
 
diff --git a/src/mainboard/via/epia-m/failover.c b/src/mainboard/via/epia-m/failover.c
index bdcb9ea..35317fc 100644
--- a/src/mainboard/via/epia-m/failover.c
+++ b/src/mainboard/via/epia-m/failover.c
@@ -8,6 +8,7 @@
 
 static unsigned long main(unsigned long bist)
 {
+#if 0
 	/* This is the primary cpu how should I boot? */
 	if (do_normal_boot()) {
 		goto normal_image;
@@ -28,5 +29,6 @@
 		: /* clobbers */
 		);
  fallback_image:
+#endif
 	return bist;
 }
diff --git a/src/mainboard/via/epia-m/mainboard.c b/src/mainboard/via/epia-m/mainboard.c
index 9eb7b37..26e5916 100644
--- a/src/mainboard/via/epia-m/mainboard.c
+++ b/src/mainboard/via/epia-m/mainboard.c
@@ -25,7 +25,7 @@
 
 }
  
-static void write_protect_vgabios(void)
+void write_protect_vgabios(void)
 {
  	device_t dev;
  
diff --git a/src/mainboard/via/epia-m/vgabios.c b/src/mainboard/via/epia-m/vgabios.c
new file mode 100644
index 0000000..67620ea
--- /dev/null
+++ b/src/mainboard/via/epia-m/vgabios.c
@@ -0,0 +1,861 @@
+#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 <string.h>
+#include "vgachip.h"
+
+/* vgabios.c. Derived from: */
+
+/*------------------------------------------------------------ -*- C -*-
+ *  2 Kernel Monte a.k.a. Linux loading Linux on x86
+ *
+ *  Erik Arjan Hendriks <hendriks@lanl.gov>
+ *
+ *  This version is a derivative of the original two kernel monte
+ *  which is (C) 2000 Scyld.
+ *
+ *  Copyright (C) 2000 Scyld Computing Corporation
+ *
+ *  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.
+ *
+ * Portions related to the alpha architecture are:
+ *
+ *  Copyright(C) 2001 University of California.  LA-CC Number 01-67.
+ *  This software has been authored by an employee or employees of the
+ *  University of California, operator of the Los Alamos National
+ *  Laboratory under Contract No.  W-7405-ENG-36 with the U.S.
+ *  Department of Energy.  The U.S. Government has rights to use,
+ *  reproduce, and distribute this software. If the software is
+ *  modified to produce derivative works, such modified software should
+ *  be clearly marked, so as not to confuse it with the version
+ *  available from LANL.
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by
+ *  reference to http://www.gnu.org/licenses/gpl.html.
+ *
+ *  This software is provided by the author(s) "as is" and any express
+ *  or implied warranties, including, but not limited to, the implied
+ *  warranties of merchantability and fitness for a particular purpose
+ *  are disclaimed.  In no event shall the author(s) be liable for any
+ *  direct, indirect, incidental, special, exemplary, or consequential
+ *  damages (including, but not limited to, procurement of substitute
+ *  goods or services; loss of use, data, or profits; or business
+ *  interruption) however caused and on any theory of liability,
+ *  whether in contract, strict liability, or tort (including
+ *  negligence or otherwise) arising in any way out of the use of this
+ *  software, even if advised of the possibility of such damage.
+ *
+ *  $Id: vgabios.c,v 1.5 2004/10/06 17:33:52 rminnich Exp $
+ *--------------------------------------------------------------------*/
+
+/* Modified to be a self sufficient plug in so that it can be used 
+   without reliance on other parts of core Linuxbios 
+   (C) 2005 Nick.Barker9@btinternet.com
+
+  Used initially for epia-m where there are problems getting the bios
+  emulator to successfully run this bios.
+*/
+
+/* Declare a temporary global descriptor table - necessary because the
+   Core part of the bios no longer sets up any 16 bit segments */
+__asm__ (
+	/* pointer to original gdt */
+	"gdtarg:			\n\t"
+	".word	gdt_limit	\n\t"
+	".long	gdt			\n\t"		
+
+	/* compute the table limit */
+	"__mygdt_limit = __mygdt_end - __mygdt - 1	\n\t"
+
+	"__mygdtaddr:			\n\t"
+	".word	__mygdt_limit	\n\t"
+	".long	__mygdt			\n\t"		
+
+
+	"__mygdt: 				\n\t"
+	/* selgdt 0, unused */
+	".word	0x0000, 0x0000	\n\t"
+	".byte	0x00, 0x00, 0x00, 0x00	\n\t"
+
+	/* selgdt 8, unused */
+	".word	0x0000, 0x0000			\n\t"
+	".byte	0x00, 0x00, 0x00, 0x00	\n\t"
+
+	/* selgdt 0x10, flat code segment */
+	".word	0xffff, 0x0000			\n\t"		
+	".byte	0x00, 0x9b, 0xcf, 0x00	\n\t"	
+
+	/* selgdt 0x18, flat data segment */
+	".word	0xffff, 0x0000			\n\t"		
+	".byte	0x00, 0x93, 0xcf, 0x00	\n\t"
+
+	/* selgdt 0x20, unused */
+	".word	0x0000, 0x0000			\n\t"
+	".byte	0x00, 0x00, 0x00, 0x00	\n\t"
+
+        /*selgdt 0x28 16-bit 64k code at 0x00000000 */
+	".word 0xffff, 0x0000			\n\t"
+	".byte 0, 0x9a, 0, 0			\n\t"
+
+	/* selgdt 0x30 16-bit 64k data at 0x00000000 */
+	".word 0xffff, 0x0000			\n\t"
+	".byte 0, 0x92, 0, 0			\n\t"
+
+	"__mygdt_end:					\n\t"
+);
+
+/* Declare a pointer to where our idt is going to be i.e. at mem zero */
+__asm__ (
+	"__myidt:	\n"
+	"    .word 1023	\n"
+	"    .long 0 \n"
+	"    .word 0 \n"
+);
+
+/* The address arguments to this function are PHYSICAL ADDRESSES */ 
+static void real_mode_switch_call_vga(unsigned long devfn)
+{
+	__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"
+		"	jmp 1f\n"
+		"__stack: .long 0\n"
+		"1:\n"
+		/* get devfn into %ecx */
+		"	movl    %esp, %ebp\n"
+		"	movl    8(%ebp), %ecx\n"
+		/* load 'our' gdt */
+		"   lgdt %cs:__mygdtaddr		\n\t"
+
+		/*  This configures CS properly for real mode. */
+		"	ljmp $0x28, $__rms_16bit\n"
+		"__rms_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,  $__rms_real \n"
+		"__rms_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"
+
+		/* Load our 16 it idt */
+		"    xor  %ax, %ax          \n"
+		"    mov  %ax, %ds          \n"
+		"    lidt __myidt            \n"
+
+
+		/* Dump zeros in the other segregs */
+		"    mov  %ax, %es          \n"
+		"    mov  %ax, %fs          \n"
+		"    mov  %ax, %gs          \n"
+		"    mov  $0x40, %ax          \n"
+		"    mov  %ax, %ds          \n"
+		"    mov %cx, %ax	\n"
+		/* go run the code */
+		" .byte 0x9a, 0x03, 0, 0, 0xc0  \n"
+
+		/* if we got here, just about done. 
+		 * Need to get back to protected mode */
+		"movl	%cr0, %eax\n"
+		"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, $vgarestart\n"
+		"vgarestart:\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"
+
+		/* restore proper gdt and idt */
+		"	 lgdt %cs:gdtarg			\n"
+		"    lidt idtarg            \n"
+		".globl vga_exit\n"
+		"vga_exit:\n"
+		"    mov  __stack, %esp\n"
+		"    popal\n"
+		);
+}
+
+__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"
+
+		/* load 'our' gdt */
+		"   lgdt %cs:__mygdtaddr		\n\t"
+
+		/*  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"
+
+		/* Load our 16 it idt */
+		"    xor  %ax, %ax          \n"
+		"    mov  %ax, %ds          \n"
+		"    lidt __myidt            \n"
+
+		/* Dump zeros in the other segregs */
+		"    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"
+		"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"
+
+
+		/* restore proper gdt and idt */
+		"	 lgdt %cs:gdtarg			\n"
+		"    lidt idtarg            \n"
+		".globl vga__ec_exit\n"
+		"vga_ec_exit:\n"
+		"    mov  __stack, %esp\n"
+		"    popal\n"
+		);
+}
+
+
+void
+do_vgabios(void)
+{
+	device_t dev;
+	unsigned long busdevfn;
+	unsigned int rom = 0;
+	unsigned char *buf;
+	unsigned int size = 64*1024;
+	int i;
+	
+	/* clear vga bios data area */
+	for (i=0x400; i<0x500; i++) {
+		*(unsigned char *) i = 0;
+	}
+
+	dev = dev_find_class(PCI_CLASS_DISPLAY_VGA<<8 , 0);
+
+	if (! dev) {
+		printk_debug("NO VGA FOUND\n");
+		return;
+	}
+	printk_debug("found VGA: vid=%x, did=%x\n", dev->vendor, dev->device);
+	
+	/* declare rom address here - keep any config data out of the way of core LXB stuff */
+
+	rom = 0xfffc0000;
+	pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
+	printk_debug("rom base, size: %x\n", rom);
+
+	buf = (unsigned char *) rom;
+	if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
+		memcpy((void *) 0xc0000, buf, size);
+
+		write_protect_vgabios();  // in northbridge
+
+	  	// 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);
+		} else
+			printk_debug("Failed to copy VGA BIOS to 0xc0000\n");
+		
+	} else 
+		printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
+	
+	pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
+
+}
+
+
+// we had hoped to avoid this. 
+// this is a stub IDT only. It's main purpose is to ignore calls 
+// to the BIOS. 
+// no longer. Dammit. We have to respond to these.
+struct realidt {
+	unsigned short offset, cs;
+}; 
+
+// from a handy writeup that andrey found.
+
+// handler. 
+// There are some assumptions we can make here. 
+// First, the Top Of Stack (TOS) is located on the top of page zero. 
+// we can share this stack between real and protected mode. 
+// that simplifies a lot of things ...
+// we'll just push all the registers on the stack as longwords, 
+// and pop to protected mode. 
+// second, since this only ever runs as part of linuxbios, 
+// we know all the segment register values -- so we don't save any.
+// keep the handler that calls things small. It can do a call to 
+// more complex code in linuxbios itself. This helps a lot as we don't
+// have to do address fixup in this little stub, and calls are absolute
+// so the handler is relocatable.
+void handler(void) {
+	__asm__ __volatile__ ( 
+		".code16\n"
+		"idthandle:\n"
+		"	pushal\n"
+		"	movb $0, %al\n"
+		"	ljmp $0, $callbiosint16\n"
+		"end_idthandle:\n"
+		".code32\n"
+		);
+
+}
+
+void debughandler(void) {
+	__asm__ __volatile__ ( 
+		".code16\n"
+		"debughandle:\n"
+		"   pushw %cx  \n"
+		"   movw  $250, %cx \n"
+		"dbh1:         \n"
+		"	loop dbh1  \n"
+		"   popw %cx   \n"
+		"	iret \n"
+		"end_debughandle:\n"
+		".code32\n"
+		);
+
+}
+
+// Calling conventions. The first C function is called with this stuff
+// on the stack. They look like value parameters, but note that if you
+// modify them they will go back to the INTx function modified. 
+// the C function will call the biosint function with these as
+// REFERENCE parameters. In this way, we can easily get 
+// returns back to the INTx caller (i.e. vgabios)
+void callbiosint(void) {
+	__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"
+		// this push does two things:
+		// - put the INT # on the stack as a parameter
+		// - provides us with a temp for the %cr0 mods.
+		"pushl	%eax\n"
+		"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    $0x00000001, %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, $biosprotect\n"
+		"biosprotect:\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"
+		"   lidt idtarg         \n"
+		"	call	biosint	\n"
+		// back to real mode ...
+		"    ljmp $0x28, $__rms_16bit2\n"
+		"__rms_16bit2:                 \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,  $__rms_real2 \n"
+		"__rms_real2:                  \n"
+		
+		/* Setup a stack */
+		"    mov  $0x0, %ax       \n"
+		"    mov  %ax, %ss          \n"
+		/* ebugging for RGM */
+		"    mov $0x11, %al      \n"
+		" outb  %al, $0x80\n"
+		"    xor  %ax, %ax          \n"
+		"    mov  %ax, %ds          \n"
+		"    lidt __myidt           \n"
+		"    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"
+		"   pop %gs \n"
+		"   pop %fs \n"
+		"   pop %es \n"
+		"   pop %ds \n"
+		"   popal\n"
+		"   iret\n"
+		".code32\n"
+		);
+}
+
+
+enum {
+	PCIBIOS = 0x1a, 
+	MEMSIZE = 0x12
+};
+int
+pcibios(
+        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
+        );
+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, 
+	unsigned long esp, 
+	unsigned long ebx, 
+	unsigned long edx, 
+	unsigned long ecx, 
+	unsigned long eax, 
+	unsigned long cs_ip,
+	unsigned short stackflags
+	) {
+	unsigned long ip; 
+	unsigned long cs; 
+	unsigned long flags;
+	int ret = -1;
+	
+	ip = cs_ip & 0xffff;
+	cs = cs_ip >> 16;
+	flags = stackflags;
+	
+	printk_debug("biosint: # 0x%lx, eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n", 
+		     intnumber, eax, ebx, ecx, edx);
+	printk_debug("biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n", ebp, esp, edi, esi);
+	printk_debug("biosint: ip 0x%x cs 0x%x flags 0x%x\n", ip, cs, flags);
+	// cases in a good compiler are just as good as your own tables. 
+	switch (intnumber) {
+	case 0 ... 15:
+		// These are not BIOS service, but the CPU-generated exceptions
+		printk_info("biosint: Oops, exception %u\n", intnumber);
+		if (esp < 0x1000) {
+			printk_debug("Stack contents: ");
+			while (esp < 0x1000) {
+				printk_debug("0x%04x ", *(unsigned short *) esp);
+				esp += 2;
+			}
+			printk_debug("\n");
+		}
+		printk_debug("biosint: Bailing out\n");
+		// "longjmp"
+		vga_exit();
+		break;
+		
+	case PCIBIOS:
+		ret = pcibios( &edi, &esi, &ebp, &esp, 
+			       &ebx, &edx, &ecx, &eax, &flags);
+		break;
+	case MEMSIZE: 
+		// who cares. 
+		eax = 64 * 1024;
+		ret = 0;
+		break;
+	case 0x15:
+		ret=handleint21( &edi, &esi, &ebp, &esp, 
+				&ebx, &edx, &ecx, &eax, &flags);
+		break;
+	default:
+		printk_info("BIOSINT: Unsupport int #0x%x\n", 
+			    intnumber);
+		break;
+	}
+	if (ret)
+		flags |= 1; // carry flags
+	else
+		flags &= ~1;
+	stackflags = flags;
+	return ret;
+} 
+
+
+void setup_realmode_idt(void) 
+{
+	extern unsigned char idthandle, end_idthandle;
+	extern unsigned char debughandle, end_debughandle;
+
+	int i;
+	struct realidt *idts = (struct realidt *) 0;
+	int codesize = &end_idthandle - &idthandle;
+	unsigned char *intbyte, *codeptr;
+	
+	// for each int, we create a customized little handler
+	// that just pushes %ax, puts the int # in %al, 
+	// then calls the common interrupt handler. 
+	// this necessitated because intel didn't know much about 
+	// architecture when they did the 8086 (it shows)
+	// (hmm do they know anymore even now :-)
+	// obviously you can see I don't really care about memory 
+	// efficiency. If I did I would probe back through the stack
+	// and get it that way. But that's really disgusting.
+	for (i = 0; i < 256; i++) {
+		idts[i].cs = 0;
+		codeptr = (char*) 4096 + i * codesize;
+		idts[i].offset = (unsigned) codeptr;
+		memcpy(codeptr, &idthandle, codesize);
+		intbyte = codeptr + 3;
+		*intbyte = i;
+	}
+	
+	// fixed entry points
+	
+	// VGA BIOSes tend to hardcode f000:f065 as the previous handler of
+	// int10. 
+	// calling convention here is the same as INTs, we can reuse
+	// the int entry code.
+	codeptr = (char*) 0xff065;
+	memcpy(codeptr, &idthandle, codesize);
+	intbyte = codeptr + 3;
+	*intbyte = 0x42; /* int42 is the relocated int10 */
+
+	/* debug handler - useful to set a programmable delay between instructions if the TF bit is set upon
+           call to real mode */
+	idts[1].cs = 0;
+	idts[1].offset = 16384;
+	memcpy(16384, &debughandle, &end_debughandle - &debughandle);
+
+	
+}
+
+
+
+enum {
+	CHECK = 0xb001,
+	FINDDEV = 0xb102,
+	READCONFBYTE = 0xb108,
+	READCONFWORD = 0xb109,
+	READCONFDWORD = 0xb10a,
+	WRITECONFBYTE = 0xb10b,
+	WRITECONFWORD = 0xb10c,
+	WRITECONFDWORD = 0xb10d
+};
+
+// errors go in AH. Just set these up so that word assigns
+// will work. KISS. 
+enum {
+	PCIBIOS_NODEV = 0x8600,
+	PCIBIOS_BADREG = 0x8700
+};
+
+int
+pcibios(
+	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
+	) {
+	unsigned long edi = *pedi;
+	unsigned long esi = *pesi;
+	unsigned long ebp = *pebp;
+	unsigned long esp = *pesp;
+	unsigned long ebx = *pebx;
+	unsigned long edx = *pedx;
+	unsigned long ecx = *pecx;
+	unsigned long eax = *peax;
+	unsigned long flags = *pflags;
+	unsigned short func = (unsigned short) eax;
+	int retval = 0;
+	unsigned short devid, vendorid, devfn;
+	short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
+	unsigned char bus;
+	device_t dev;
+	
+	switch(func) {
+	case  CHECK:
+		*pedx = 0x4350;
+		*pecx = 0x2049;
+		retval = 0;
+		break;
+	case FINDDEV:
+	{
+		devid = *pecx;
+		vendorid = *pedx;
+		devindex = *pesi;
+		dev = 0;
+		while ((dev = dev_find_device(vendorid, devid, dev))) {
+			if (devindex <= 0)
+				break;
+			devindex--;
+		}
+		if (dev) {
+			unsigned short busdevfn;
+			*peax = 0;
+			// busnum is an unsigned char;
+			// devfn is an int, so we mask it off. 
+			busdevfn = (dev->bus->secondary << 8)
+				| (dev->path.u.pci.devfn & 0xff);
+			printk_debug("0x%x: return 0x%x\n", func, busdevfn);
+			*pebx = busdevfn;
+			retval = 0;
+		} else {
+			*peax = PCIBIOS_NODEV;
+			retval = -1;
+		}
+	}
+	break;
+	case READCONFDWORD:
+	case READCONFWORD:
+	case READCONFBYTE:
+	case WRITECONFDWORD:
+	case WRITECONFWORD:
+	case WRITECONFBYTE:
+	{
+		unsigned long dword;
+		unsigned short word;
+		unsigned char byte;
+		unsigned char reg;
+		
+		devfn = *pebx & 0xff;
+		bus = *pebx >> 8;
+		reg = *pedi;
+		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!
+			*peax = PCIBIOS_BADREG;
+			retval = -1;
+		}
+		switch(func) {
+		case READCONFBYTE:
+			byte = pci_read_config8(dev, reg);
+			*pecx = byte;
+			break;
+		case READCONFWORD:
+			word = pci_read_config16(dev, reg);
+			*pecx = word;
+			break;
+		case READCONFDWORD:
+			dword = pci_read_config32(dev, reg);
+			*pecx = dword;
+			break;
+		case WRITECONFBYTE:
+			byte = *pecx;
+			pci_write_config8(dev, reg, byte);
+			break;
+		case WRITECONFWORD:
+			word = *pecx;
+			pci_write_config16(dev, reg, word);
+			break;
+		case WRITECONFDWORD:
+			dword = *pecx;
+			pci_write_config32(dev, reg, dword);
+			break;
+		}
+		
+		if (retval) 
+			retval = PCIBIOS_BADREG;
+		printk_debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n", func, bus, devfn, reg, *pecx);
+		*peax = 0;
+		retval = 0;
+	}
+	break;
+	default:
+		printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n",  func);
+		break;
+	}
+	
+	return retval;
+} 
+
+
+
+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;
+	case 0x5f18:
+		*eax=0x5f;
+		*ebx=0x545; // MCLK = 133, 32M frame buffer, 256 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;
+		break;
+	}
+	return res;
+}
diff --git a/src/mainboard/via/epia-m/vgachip.h b/src/mainboard/via/epia-m/vgachip.h
new file mode 100644
index 0000000..d43788c
--- /dev/null
+++ b/src/mainboard/via/epia-m/vgachip.h
@@ -0,0 +1,10 @@
+#ifndef _PC80_VGABIOS
+#define _PC80_VGABIOS
+
+extern struct chip_control pc80_vgabios_control;
+
+struct pc80_vgabios_config {
+	int nothing;
+};
+
+#endif /* _PC80_VGABIOS */
diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c
index bfaaeac..7143c35 100644
--- a/src/northbridge/via/vt8623/northbridge.c
+++ b/src/northbridge/via/vt8623/northbridge.c
@@ -10,6 +10,7 @@
 #include <bitops.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
 #include "chip.h"
 #include "northbridge.h"
 
@@ -19,6 +20,18 @@
  * slower than normal, ethernet drops packets).
  * Apparently these registers govern some sort of bus master behavior.
  */
+static void dump_dev(device_t dev)
+{
+	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(dev, i+j));
+		}
+		printk_debug("\n");
+	}
+}
 static void northbridge_init(device_t dev) 
 {
 	device_t fb_dev;
@@ -44,21 +57,25 @@
 		/* Fixup GART and framebuffer addresses properly.
 		 * First setup frame buffer properly.
 		 */
-		fb = pci_read_config32(dev, 0x10);       /* Base addres of framebuffer */
+		//fb = pci_read_config32(dev, 0x10);       /* Base addres of framebuffer */
+		fb = 0xd0000000;
 		printk_debug("Frame buffer at %8x\n",fb);
 
 		c = pci_read_config8(dev, 0xe1) & 0xf0;  /* size of vga */
 		c |= fb>>28;  /* upper nibble of frame buffer address */
+		c = 0xdd;
 		pci_write_config8(dev, 0xe1, c);
-		c = (fb>>20) | 1;                        /* enable framebuffer */
+		c = 0x81;                                /* enable framebuffer */
 		pci_write_config8(dev, 0xe0, c);
 		pci_write_config8(dev, 0xe2, 0x42);      /* 'cos award does */
 	}
+	//dump_dev(dev);
 }
 
+static void nullfunc(){}
 
 static struct device_operations northbridge_operations = {
-	.read_resources   = pci_dev_read_resources,
+	.read_resources   = nullfunc,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
 	.init             = northbridge_init
@@ -80,10 +97,11 @@
 	pci_write_config8(dev, 0x43, 0x44);
 	pci_write_config8(dev, 0x44, 0x34);
 	pci_write_config8(dev, 0x83, 0x02);
+	//dump_dev(dev);
 }
 
 static struct device_operations agp_operations = {
-	.read_resources   = pci_bus_read_resources,
+	.read_resources   = nullfunc,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_bus_enable_resources,
 	.init             = agp_init,
@@ -100,12 +118,64 @@
 static void vga_init(device_t dev)
 {
 //	unsigned long fb;
+	msr_t clocks1,clocks2,instructions,setup;
 
 	printk_debug("VGA random fixup ...\n");
 	pci_write_config8(dev, 0x04, 0x07);
 	pci_write_config8(dev, 0x0d, 0x20);
+	pci_write_config32(dev,0x10,0xd8000008);
+	pci_write_config32(dev,0x14,0xdc000000);
+
+	//dump_dev(dev);
 	
-	/* Set the vga mtrrs - disable for the moment */
+	// set up performnce counters for debugging vga init sequence
+	//setup.lo = 0x1c0; // count instructions
+	//wrmsr(0x187,setup);
+	//instructions.hi = 0;
+	//instructions.lo = 0;
+	//wrmsr(0xc2,instructions);
+	//clocks1 = rdmsr(0x10);
+
+	
+#if 0
+	/* code to make vga init go through the emulator - as of yet this does not workfor the epia-m */
+	dev->on_mainboard=1;
+	dev->rom_address = (void *)0xfffc0000;
+
+	pci_dev_init(dev);
+	
+	call_bios_interrupt(0x10,0x4f1f,0x8003,1,0);
+	
+	//clocks2 = rdmsr(0x10);
+	//instructions = rdmsr(0xc2);
+	
+	printk_debug("Clocks 1 = %08x:%08x\n",clocks1.hi,clocks1.lo);
+	printk_debug("Clocks 2 = %08x:%08x\n",clocks2.hi,clocks2.lo);
+	printk_debug("Instructions = %08x:%08x\n",instructions.hi,instructions.lo);
+
+#else
+
+	/* code to make vga init run in real mode - does work but against the current Linuxbios philosophy */
+	printk_debug("INSTALL REAL-MODE IDT\n");
+        setup_realmode_idt();
+        printk_debug("DO THE VGA BIOS\n");
+        do_vgabios();
+
+	//clocks2 = rdmsr(0x10);
+	//instructions = rdmsr(0xc2);
+	
+	//printk_debug("Clocks 1 = %08x:%08x\n",clocks1.hi,clocks1.lo);
+	//printk_debug("Clocks 2 = %08x:%08x\n",clocks2.hi,clocks2.lo);
+	//printk_debug("Instructions = %08x:%08x\n",instructions.hi,instructions.lo);
+
+        vga_enable_console();
+	
+#endif
+
+
+	pci_write_config32(dev,0x30,0);
+
+	/* Set the vga mtrrs - disable for the moment as the add_var_mtrr function has vapourised */
 #if 0
 	add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
 	fb = pci_read_config32(dev,0x10); // get the fb address
@@ -113,8 +183,17 @@
 #endif
 }
 
+static void vga_read_resources(device_t dev)
+{
+
+	dev->rom_address = (void *)0xfffc0000;
+	dev->on_mainboard=1;
+	pci_dev_read_resources(dev);
+
+}
+
 static struct device_operations vga_operations = {
-	.read_resources   = pci_dev_read_resources,
+	.read_resources   = vga_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
 	.init             = vga_init,
diff --git a/src/northbridge/via/vt8623/raminit.c b/src/northbridge/via/vt8623/raminit.c
index 7371e09..7501932 100644
--- a/src/northbridge/via/vt8623/raminit.c
+++ b/src/northbridge/via/vt8623/raminit.c
@@ -1,90 +1,49 @@
+/*
+ * (C) Copyright 2005 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* 
+  Automatically detect and set up ddr dram on the CLE266 chipset.
+  Assumes DDR memory, though chipset also supports SDRAM
+  Assumes at least 266Mhz memory as no attempt is made to clock
+  the chipset down if slower memory is installed.
+  So far tested on:
+	256 Mb 266Mhz 1 Bank (i.e. single sided)
+	256 Mb 266Mhz 2 Bank (i.e. double sided)
+	512 Mb 266Mhz 2 Bank (i.e. double sided)
+*/
+/* ported and enhanced from assembler level code in Linuxbios v1 */
+
 #include <cpu/x86/mtrr.h>
 #include "raminit.h"
 
-/*
-This software and ancillary information (herein called SOFTWARE )
-called LinuxBIOS          is made available under the terms described
-here.  The SOFTWARE has been approved for release with associated
-LA-CC Number 00-34   .  Unless otherwise indicated, this SOFTWARE has
-been authored by an employee or employees of the University of
-California, operator of the Los Alamos National Laboratory under
-Contract No. W-7405-ENG-36 with the U.S. Department of Energy.  The
-U.S. Government has rights to use, reproduce, and distribute this
-SOFTWARE.  The public may copy, distribute, prepare derivative works
-and publicly display this SOFTWARE without charge, provided that this
-Notice and any statement of authorship are reproduced on all copies.
-Neither the Government nor the University makes any warranty, express 
-or implied, or assumes any liability or responsibility for the use of
-this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
-such modified SOFTWARE should be clearly marked, so as not to confuse
-it with the version available from LANL.
- */
-/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
- * rminnich@lanl.gov
- */
-/*
- * 11/26/02 - kevinh@ispiri.com - The existing comments implied that
- * this didn't work yet.  Therefore, I've updated it so that it works
- * correctly - at least on my VIA epia motherboard.  64MB DIMM in slot 0.
- */
-
-/* Added automatic detection of first equipped bank and its MA mapping type.
- * (Rest of configuration is done in C)
- * 5/19/03 by SONE Takeshi <ts1@tsn.or.jp>
- */
-/* converted to C 9/2003 Ron Minnich */
-
-/* Set to 1 if your DIMMs are PC133 Note that I'm assuming CPU's FSB
- * frequency is 133MHz. If your CPU runs at another bus speed, you
- * might need to change some of register values.
- */
-#ifndef DIMM_PC133
-#define DIMM_PC133 0
-#endif
-
-// Set to 1 if your DIMMs are CL=2
-#ifndef DIMM_CL2
-#define DIMM_CL2 0
-#endif
 
 
-
-
-
-void dimm_read(unsigned long x) 
+void dimm_read(unsigned long bank,unsigned long x) 
 {
-	unsigned long eax; 
+	//unsigned long eax; 
 	volatile unsigned long y;
-	eax =  x;
-	y = * (volatile unsigned long *) eax;
+	//eax =  x;
+	y = * (volatile unsigned long *) (x+ bank) ;
 
 }
 
-void dimms_write(int x) 
-{
-	uint8_t c;
-	unsigned long eax = x;
-	for(c = 0; c < 6; c++) {
-		*(volatile unsigned long *) eax = 0;
-		eax += 0x10000000;
-	}
-}
-
-
-
-#ifdef DEBUG_SETNORTHB
-void setnorthb(device_t north, uint8_t reg, uint8_t val) 
-{
-	print_debug("setnorth: reg ");
-	print_debug_hex8(reg);
-	print_debug(" to ");
-	print_debug_hex8(val);
-	print_debug("\r\n");
-	pci_write_config8(north, reg, val);
-}
-#else
-#define setnorthb pci_write_config8
-#endif
 
 void
 dumpnorth(device_t north) 
@@ -100,47 +59,242 @@
 		print_debug("\r\n");
   }
 }
+void print_val(char *str, int val)
+{
+	print_debug(str);
+	print_debug_hex8(val);
+}
 
-static void sdram_set_registers(const struct mem_controller *ctrl) 
+static void ddr_ram_setup(const struct mem_controller *ctrl) 
 {
 	device_t north = (device_t) 0;
-	uint8_t c, r;
+	uint8_t b, c, bank;
+	uint16_t i,j;
+	unsigned long bank_address;
 
 	print_err("vt8623 init starting\r\n");
 	north = pci_locate_device(PCI_ID(0x1106, 0x3123), 0);
 	north = 0;
-	print_debug_hex32(north);
-	print_debug(" is the north\r\n");
-	print_debug_hex16(pci_read_config16(north, 0));
-	print_debug(" ");
-	print_debug_hex16(pci_read_config16(north, 2));
-	print_debug("\r\n");
 	
-	/* All we are doing now is setting initial known-good values that will
-	 * be revised later as we read SPD
-	 */	
 
 	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);
+	pci_write_config8(north,0x55,0x04);
 
-	/* DRAM MA Map Type */
-	pci_write_config8(north,0x58,0xe0);
+/*
+    DRAM MA Map Type  Device 0  Offset 58
 
-	/* 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);
+    Determine memory addressing based on the module's memory technology and
+    arrangement.  See Table 4-9 of Intel's 82443GX datasheet for details.
+
+    Bank 1/0 MA map type   58[7-5]
+    Bank 1/0 command rate  58[4]
+    Bank 3/2 MA map type   58[3-1]
+    Bank 3/2 command rate  58[0]
+
+
+    Read SPD byte 17, Number of banks on SDRAM device.
+*/
+	c = 0;
+	b = smbus_read_byte(0xa0,17);
+	print_val("Detecting Memory\r\nNumber of Banks ",b);
+
+	if( b != 2 ){            // not 16 Mb type
+	
+/*
+    Read SPD byte 3, Number of row addresses.
+*/
+		b = smbus_read_byte(0xa0,3);
+		print_val("\r\nNumber of Rows ",b);
+		if( b >= 0x0d ){	// not 64/128Mb (rows <=12)
+
+/*
+    Read SPD byte 13, Primary DRAM width.
+*/
+			b = smbus_read_byte(0xa0,13);
+			print_val("\r\nPriamry DRAM width",b);
+			if( b != 4 )   // mot 64/128Mb (x4)
+				c = 0x80;  // 256Mb
+		}
+
+/*
+    64/128Mb chip
+
+    Read SPD byte 4, Number of column addresses.
+*/		
+		b = smbus_read_byte(0xa0,4);
+		print_val("\r\nNo Columns ",b);
+		if( b == 10 || b == 11 ) c |= 0x60;   // 10/11 bit col addr
+		if( b == 9 ) c |= 0x40;           // 9 bit col addr
+		if( b == 8 ) c |= 0x20;           // 8 bit col addr
+
+	}
+	print_val("\r\nMA type ",c);
+	pci_write_config8(north,0x58,c);
+
+/*
+    DRAM bank size.  See 4.3.1 pg 35
+
+    5a->5d  set to end address for each bank.  1 bit == 16MB
+    5a = bank 0
+    5b = bank 0 + b1
+    5c = bank 0 + b1 + b2
+    5d = bank 0 + b1 + b2 + b3
+*/
+
+// Read SPD byte 31 Module bank density
+	c = 0;
+	b = smbus_read_byte(0xa0,31);
+	if( b & 0x02 ) c = 0x80;         // 2GB
+	else if( b & 0x01) c = 0x40;     // 1GB
+	else if( b & 0x80) c = 0x20;     // 512Mb
+	else if( b & 0x40) c = 0x10;     // 256Mb 
+	else if( b & 0x20) c = 0x08;     // 128Mb
+	else if( b & 0x10) c = 0x04;     // 64Mb
+	else if( b & 0x08) c = 0x02;     // 32Mb
+	else if( b & 0x04) c = 0x01;     // 16Mb / 4Gb
+	else c = 0x01;                   // Error, use default
+
+
+	print_val("\r\nBank 0 (*16 Mb) ",c);
+
+	// set bank zero size
+	pci_write_config8(north,0x5a,c);
+	// SPD byte 5  # of physical banks
+	b = smbus_read_byte(0xa0,5);
+
+	print_val("\r\nNo Physical Banks ",b);
+	if( b == 2)
+		c <<=1;
+
+	print_val("\r\nTotal Memory (*16 Mb) ",c);
+	// set banks 1,2,3
+	pci_write_config8(north,0x5b,c);
+	pci_write_config8(north,0x5c,c);
+	pci_write_config8(north,0x5d,c);
+
+
+	/* Read SPD byte 18 CAS Latency */
+	b = smbus_read_byte(0xa0,18);
+	print_debug("\r\nCAS Supported ");
+	if(b & 0x04)
+		print_debug("2 ");
+	if(b & 0x08)
+		print_debug("2.5 ");
+	if(b & 0x10)
+		print_debug("3");
+	print_val("\r\nCycle time at CL X     (nS)",smbus_read_byte(0xa0,9));
+	print_val("\r\nCycle time at CL X-0.5 (nS)",smbus_read_byte(0xa0,23));
+	print_val("\r\nCycle time at CL X-1   (nS)",smbus_read_byte(0xa0,25));
+	
+
+	if( b & 0x10 ){             // DDR offering optional CAS 3
+		print_debug("\r\nStarting at CAS 3");
+		c = 0x30;
+		/* see if we can better it */
+		if( b & 0x08 ){     // DDR mandatory CAS 2.5
+			if( smbus_read_byte(0xa0,23) <= 0x75 ){ // we can manage 133Mhz at CAS 2.5
+				print_debug("\r\nWe can do CAS 2.5");
+				c = 0x20;
+			}
+		}
+		if( b & 0x04 ){     // DDR mandatory CAS 2
+			if( smbus_read_byte(0xa0,25) <= 0x75 ){ // we can manage 133Mhz at CAS 2
+				print_debug("\r\nWe can do CAS 2");
+				c = 0x10;
+			}
+		}
+	}else{                     // no optional CAS values just 2 & 2.5
+		print_debug("\r\nStarting at CAS 2.5");
+		c = 0x20;          // assume CAS 2.5
+		if( b & 0x04){      // Should always happen
+			if( smbus_read_byte(0xa0,23) <= 0x75){ // we can manage 133Mhz at CAS 2
+				print_debug("\r\nWe can do CAS 2");
+				c = 0x10;
+			}
+		}
+	}
+
+
+
+/*
+    DRAM Timing  Device 0  Offset 64
+
+    Row pre-charge  64[7]
+    RAS Pulse width 64[6]
+    CAS Latency     64[5,4]
+
+         SDR  DDR
+      00  1T   -
+      01  2T   2T
+      10  3T   2.5T
+      11  -    3T
+
+    RAS/CAS delay   64[2]
+    Bank Interleave 64[1,0]
+
+
+    Determine row pre-charge time (tRP)
+
+    T    nS    SPD*4   SPD
+    1T   7.5   0x1e
+    2T   15    0x3c
+    3T   22.5  0x5a
+    4T   30            0x1e
+    5T   37.5          0x25 .5?
+    6T   45            0x2d
+
+
+    Read SPD byte 27, min row pre-charge time.
+*/
+
+	b = smbus_read_byte(0xa0,27);
+	print_val("\r\ntRP ",b);
+	if( b > 0x3c )           // set tRP = 3T
+		c |= 0x80;
+
+
+/*
+    Determine RAS to CAS delay (tRCD)
+
+    Read SPD byte 29, min row pre-charge time.
+*/
+
+	b = smbus_read_byte(0xa0,29);
+	print_val("\r\ntRCD ",b);
+	if( b > 0x3c )           // set tRCD = 3T
+		c |= 0x04;
+
+/*
+    Determine RAS pulse width (tRAS)
+
+
+    Read SPD byte 30, device min active to pre-charge time.
+*/
+
+	b = smbus_read_byte(0xa0,30);
+	print_val("\r\ntRAS ",b);
+	if( b > 0x25 )           // set tRAS = 6T
+		c |= 0x40;
+
+
+/*
+    Determine bank interleave
+
+    Read SPD byte 17, Number of banks on SDRAM device.
+*/
+	b = smbus_read_byte(0xa0,17);
+	if( b == 4) c |= 0x02;
+	else if (b == 2) c |= 0x01;
+
 
 	/* set DRAM timing for all banks */
-	pci_write_config8(north,0x64,0xe6);
+	pci_write_config8(north,0x64,c);
 
 	/* set DRAM type to DDR */
 	pci_write_config8(north,0x60,0x02);
@@ -148,198 +302,284 @@
 
 	/* DRAM arbitration timer */
 	pci_write_config8(north,0x65,0x32);
-	pci_write_config8(north,0x66,0x01);
-	pci_write_config8(north,0x68,0x59);
 
 
-	/* DRAM Frequency */
+/*
+    CPU Frequency  Device 0 Offset 54
+
+    CPU Frequency          54[7,6]  bootstraps at 0xc0 (133Mhz)
+    DRAM burst length = 8  54[5]
+*/
 	pci_write_config8(north,0x54,0xe0);
+
+
+/*
+    DRAM Clock  Device 0 Offset 69
+
+    DRAM/CPU speed      69[7,6]  (leave at default 00 == CPU)
+    Controller que > 2  69[5]
+    Controller que != 4 69[4]
+    DRAM 8k page size   69[3]
+    DRAM 4k page size   69[2]
+    Multiple page mode  69[0]
+*/
+
 	pci_write_config8(north,0x69,0x2d);
 
+	/* Delay >= 100ns after DRAM Frequency adjust, See 4.1.1.3 pg 15 */
+	udelay(200);
+
+
 	/* Enable CKE */
 	pci_write_config8(north,0x6b,0x10);
-	
+	udelay(200);
+
 	/* Disable DRAM refresh */
 	pci_write_config8(north,0x6a,0x0);
 
-	/* set heavy drive */
-	pci_write_config8(north,0x6d,0x44);
 
+	/* Set drive for 1 bank DDR  (Table 4.4.2, pg 40) */
+	pci_write_config8(north,0x6d,0x044);
+	pci_write_config8(north,0x67,0x3a);
+
+	b = smbus_read_byte(0xa0,5); // SPD byte 5  # of physical banks
+	if( b > 1) {
+                // Increase drive control when there is more than 1 physical bank
+		pci_write_config8(north,0x6c,0x84);   // Drive control: MA, DQS, MD/CKE
+		pci_write_config8(north,0x6d,0x55);   // DC: Early clock select, DQM, CS#, MD
+	}
+	/* place frame buffer on last bank */
+	if( !b) b++;     // make sure at least 1 bank reported
+	pci_write_config8(north,0xe3,b-1);
+
+	for( bank = 0 , bank_address=0; bank < b ; bank++){
+/*
+    DDR init described in Via BIOS Porting Guide.  Pg 28 (4.2.3.1)
+*/
+
+
+		/* NOP command enable */
+		pci_write_config8(north,0x6b,0x11);
+
+		/* read a double word from any address of the dimm */
+		dimm_read(bank_address,0x1f000);
+		//udelay(200);
+
+		/* All bank precharge Command Enable */
+		pci_write_config8(north,0x6b,0x12);
+		dimm_read(bank_address,0x1f000);
+
+
+		/* MSR Enable */
+		pci_write_config8(north,0x6b,0x13);
+		dimm_read(bank_address,0x2000);
+		udelay(1);
+		dimm_read(bank_address,0x800);
+		udelay(1);
+
+		/* All banks precharge Command Enable */
+		pci_write_config8(north,0x6b,0x12);
+		dimm_read(bank_address,0x1f200);
+
+		/* CBR Cycle Enable */
+		pci_write_config8(north,0x6b,0x14);
+
+		/* Read 8 times */
+		dimm_read(bank_address,0x1f300);
+		udelay(100);
+		dimm_read(bank_address,0x1f400);
+		udelay(100);
+		dimm_read(bank_address,0x1f500);
+		udelay(100);
+		dimm_read(bank_address,0x1f600);
+		udelay(100);
+		dimm_read(bank_address,0x1f700);
+		udelay(100);
+		dimm_read(bank_address,0x1f800);
+		udelay(100);
+		dimm_read(bank_address,0x1f900);
+		udelay(100);
+		dimm_read(bank_address,0x1fa00);
+		udelay(100);
+
+		/* MSR Enable */
+		pci_write_config8(north,0x6b,0x13);
+
+/* 
+    Mode Register Definition
+    with adjustement so that address calculation is correct - 64 bit technology, therefore
+    a0-a2 refer to byte within a 64 bit long word, and a3 is the first address line presented
+    to DIMM as a row or column address.
+
+    MR[9-7]   CAS Latency
+    MR[6]     Burst Type 0 = sequential, 1 = interleaved
+    MR[5-3]   burst length 001 = 2, 010 = 4, 011 = 8, others reserved
+    MR[0-2]   dont care 
+
+    CAS Latency 
+    000       reserved
+    001       reserved
+    010       2
+    011       3
+    100       reserved
+    101       1.5
+    110       2.5
+    111       reserved
+
+    CAS 2     0101011000 = 0x158
+    CAS 2.5   1101011000 = 0x358
+    CAS 3     0111011000 = 0x1d8
+
+*/
+		c = pci_read_config8(north,0x64);
+		if( (c & 0x30) == 0x10 )
+			dimm_read(bank_address,0x150);
+		else if((c & 0x30) == 0x20 )
+			dimm_read(bank_address,0x350);
+		else
+			dimm_read(bank_address,0x1d0);
+
+		//dimm_read(bank_address,0x350);
+
+		/* Normal SDRAM Mode */
+		pci_write_config8(north,0x6b,0x58 );
+
+
+		bank_address = pci_read_config8(north,0x5a+bank) * 0x1000000;
+	} // end of for each bank
+
+	/* Adjust DQS (data strobe output delay). See 4.2.3.2 pg 29 */
+	pci_write_config8(north,0x66,0x41);
+
+	/* determine low bond */
+	if( b == 2)
+		bank_address = pci_read_config8(north,0x5a) * 0x1000000;
+	else
+		bank_address = 0;
+
+	for(i = 0 ; i < 0x0ff; i++){
+		c = i ^ (i>>1);			// convert to gray code
+		pci_write_config8(north,0x68,c);
+		// clear
+		*(volatile unsigned long*)(0x4000) = 0;
+		*(volatile unsigned long*)(0x4100+bank_address) = 0;
+		*(volatile unsigned long*)(0x4200) = 0;
+		*(volatile unsigned long*)(0x4300+bank_address) = 0;
+		*(volatile unsigned long*)(0x4400) = 0;
+		*(volatile unsigned long*)(0x4500+bank_address) = 0;
+
+
+		// fill
+		*(volatile unsigned long*)(0x4000) = 0x12345678;
+		*(volatile unsigned long*)(0x4100+bank_address) = 0x81234567;
+		*(volatile unsigned long*)(0x4200) = 0x78123456;
+		*(volatile unsigned long*)(0x4300+bank_address) = 0x67812345;
+		*(volatile unsigned long*)(0x4400) = 0x56781234;
+		*(volatile unsigned long*)(0x4500+bank_address) = 0x45678123;
+
+			// verify
+		if( *(volatile unsigned long*)(0x4000) != 0x12345678)
+			continue;
+
+		if( *(volatile unsigned long*)(0x4100+bank_address) != 0x81234567)
+			continue;
+
+		if( *(volatile unsigned long*)(0x4200) != 0x78123456)
+			continue;
+
+		if( *(volatile unsigned long*)(0x4300+bank_address) != 0x67812345)
+			continue;
+
+		if( *(volatile unsigned long*)(0x4400) != 0x56781234)
+			continue;
+
+		if( *(volatile unsigned long*)(0x4500+bank_address) != 0x45678123)
+			continue;
+
+		// if everything verified then found low bond
+		break;
+		
+	}
+	print_val("\r\nLow Bond ",i);	
+	if( i < 0xff ){ 
+		c = i++;
+		for(  ; i <0xff ; i++){
+ 			pci_write_config8(north,0x68,i ^ (i>>1) );
+
+			// clear
+			*(volatile unsigned long*)(0x8000) = 0;
+			*(volatile unsigned long*)(0x8100+bank_address) = 0;
+			*(volatile unsigned long*)(0x8200) = 0x0;
+			*(volatile unsigned long*)(0x8300+bank_address) = 0;
+			*(volatile unsigned long*)(0x8400) = 0x0;
+			*(volatile unsigned long*)(0x8500+bank_address) = 0;
+
+			// fill
+			*(volatile unsigned long*)(0x8000) = 0x12345678;
+			*(volatile unsigned long*)(0x8100+bank_address) = 0x81234567;
+			*(volatile unsigned long*)(0x8200) = 0x78123456;
+			*(volatile unsigned long*)(0x8300+bank_address) = 0x67812345;
+			*(volatile unsigned long*)(0x8400) = 0x56781234;
+			*(volatile unsigned long*)(0x8500+bank_address) = 0x45678123;
+
+			// verify
+			if( *(volatile unsigned long*)(0x8000) != 0x12345678)
+				break;
+
+			if( *(volatile unsigned long*)(0x8100+bank_address) != 0x81234567)
+				break;
+
+			if( *(volatile unsigned long*)(0x8200) != 0x78123456)
+				break;
+
+			if( *(volatile unsigned long*)(0x8300+bank_address) != 0x67812345)
+				break;
+
+			if( *(volatile unsigned long*)(0x8400) != 0x56781234)
+				break;
+
+			if( *(volatile unsigned long*)(0x8500+bank_address) != 0x45678123)
+				break;
+
+		}
+		print_val("  High Bond",i);
+		c = ((i - c)<<1)/3 +c;
+		print_val("  Setting DQS delay",c);
+		c = c ^ (c>>1);		// convert to gray code
+		pci_write_config8(north,0x68,c);
+		pci_write_config8(north,0x68,0x42);
+	}else{
+		print_debug("Unable to determine low bond - Setting default\r\n");
+		pci_write_config8(north,0x68,0x59);
+	}
+
+
+	pci_write_config8(north,0x66,0x01);
+	pci_write_config8(north,0x55,0x07);
+
+
+
+/*
+    DRAM refresh rate  Device 0 Offset 6a
+
+    Units of 16 DRAM clock cycles.  (See 4.4.1 pg 39)
+
+    Rx69 (DRAM freq)  Rx58 (chip tech)  Rx6a
+
+    133Mhz            64/128Mb          0x86
+    133Mhz            256/512Mb         0x43
+    100Mhz            64/128Mb          0x65
+    100Mhz            256/512Mb         0x32
+*/
+
+	b = pci_read_config8(north,0x58);
+	if( b < 0x80 )   // 256 tech
+		pci_write_config8(north,0x6a,0x86);
+	else
+		pci_write_config8(north,0x6a,0x43);
 
 	pci_write_config8(north,0x61,0xff);
-
-
-
-}
-
-/* slot is the dram slot. Return size of side0 in lower 16-bit,
- * side1 in upper 16-bit, in units of 8MB */
-static unsigned long 
-spd_module_size(unsigned char slot) 
-{ 
-	/* for all the DRAMS, see if they are there and get the size of each
-	 * module. This is just a very early first cut at sizing.
-	 */
-	/* we may run out of registers ... */
-	unsigned int banks, rows, cols, reg;
-	unsigned int value = 0;
-	unsigned int module = ((0x50 + slot) << 1) + 1;
-	/* is the module there? if byte 2 is not 4, then we'll assume it 
-	 * is useless. 
-	 */
-	print_info("Slot "); 
-	print_info_hex8(slot); 
-	if (smbus_read_byte(module, 2) != 4) {
-		print_info(" is empty\r\n");
-		return 0;
-	}
-	print_info(" is SDRAM ");
-	
-	banks = smbus_read_byte(module, 17);
-	/* we're going to assume symmetric banks. Sorry. */
-	cols = smbus_read_byte(module, 4)  & 0xf;
-	rows = smbus_read_byte(module, 3)  & 0xf;
-	/* grand total. You have rows+cols addressing, * times of banks, times
-	 * width of data in bytes */
-	/* Width is assumed to be 64 bits == 8 bytes */
-	value = (1 << (cols + rows)) * banks * 8;
-	print_info_hex32(value);
-	print_info(" bytes ");
-	/* Return in 8MB units */
-	value >>= 23;
-
-	/* We should have single or double side */
-	if (smbus_read_byte(module, 5) == 2) {
-		print_info("x2");
-		value = (value << 16) | value;
-	}
-	print_info("\r\n");
-	return value;
-
-}
-
-static int
-spd_num_chips(unsigned char slot) 
-{ 
-	unsigned int module = ((0x50 + slot) << 1) + 1;
-	unsigned int width;
-
-	width = smbus_read_byte(module, 13);
-	if (width == 0)
-		width = 8;
-	return 64 / width;
-}
-
-static void sdram_set_spd_registers(const struct mem_controller *ctrl)
-{
-#define T133 7
-	unsigned char Trp = 1, Tras = 1, casl = 2, val;
-	unsigned char timing = 0xe4;
-	/* read Trp */
-	val = smbus_read_byte(0xa0, 27);
-	if (val < 2*T133)
-		Trp = 1;
-	val = smbus_read_byte(0xa0, 30);
-	if (val < 5*T133)
-		Tras = 0;
-	val = smbus_read_byte(0xa0, 18);
-	if (val < 8)
-		casl = 1;
-	if (val < 4)
-		casl = 0;
-	
-	val = (Trp << 7) | (Tras << 6) | (casl << 4) | 4;
-	
-	print_debug_hex8(val); print_debug(" is the computed timing\r\n");
-	/* don't set it. Experience shows that this screwy chipset should just
-	 * be run with the most conservative timing.
-	 * pci_write_config8(0, 0x64, val);
-	 */
-}
-
-static void set_ma_mapping(device_t north, int slot, int type)
-{
-    unsigned char reg, val;
-    int shift;
-
-    reg = 0x58 + slot/2;
-    if (slot%2 >= 1)
-        shift = 0;
-    else
-        shift = 4;
-
-    val = pci_read_config8(north, reg);
-    val &= ~(0xf << shift);
-    val |= type << shift;
-    pci_write_config8(north, reg, val);
-}
-
-
-static void sdram_enable(int controllers, const struct mem_controller *ctrl) 
-{
-	unsigned char i;
-	static const uint8_t ramregs[] = {
-		0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x56, 0x57
-	};
-	device_t north = 0;
-	uint32_t size, base, slot, ma;
-	
-
-	/* NOP command enable */
-	pci_write_config8(north,0x6b,0x01);
-
-	/* 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_write_config8(north,0x67,0x22);
 
 	/* pci */
 	pci_write_config8(north,0x70,0x82);
@@ -351,14 +591,18 @@
 	
 
 	/* 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,0xe1,0xdf);
+	//pci_write_config8(north,0xe2,0x42);
+	pci_write_config8(north,0xe0,0x00);
 
-	pci_write_config8(north,0xe0,0x80);
-	pci_write_config8(north,0xe1,0xdf);
-	pci_write_config8(north,0xe2,0x42);
+	pci_write_config8(north,0x84,0x80);
+	pci_write_config16(north,0x80,0x610f);
+	pci_write_config32(north,0x88,0x00000002);
+
+
 
 	pci_write_config8(north,0xa8,0x04);
 	pci_write_config8(north,0xac,0x2f);
@@ -366,4 +610,18 @@
 
         print_err("vt8623 done\r\n");
 	dumpnorth(north);
+
+	print_err("AGP\r\n");
+	north = pci_locate_device(PCI_ID(0x1106, 0xb091), 0);
+	pci_write_config32(north,0x20,0xddf0dc00);
+	pci_write_config32(north,0x24,0xdbf0d800);
+	pci_write_config8(north,0x3e,0x0c);
+	//dumpnorth(north);
+
+	//print_err("VGA\n");
+	//north = pci_locate_device(PCI_ID(0x1106, 0x3122), 0);
+	//pci_write_config32(north,0x10,0xd8000008);
+	//pci_write_config32(north,0x14,0xdc000000);
+	//dumpnorth(north);
+
 }
diff --git a/src/southbridge/ricoh/rl5c476/chip.h b/src/southbridge/ricoh/rl5c476/chip.h
index 5d7a2e3..c4cd9d7 100644
--- a/src/southbridge/ricoh/rl5c476/chip.h
+++ b/src/southbridge/ricoh/rl5c476/chip.h
@@ -1,10 +1,11 @@
 #ifndef _SOUTHBRIDGE_RICOH_RL5C476
 #define _SOUTHBRIDGE_RICOH_RL5C476
 
-extern struct chip_operations southbridge_ricoh_rl5c476_control;
+extern struct chip_operations southbridge_ricoh_rl5c476_ops;
 
 struct southbridge_ricoh_rl5c476_config {
-	int num;
+	int enable_cf;
+	
 };
 
 #endif /* _SOUTHBRIDGE_RL5C476 */
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.c b/src/southbridge/ricoh/rl5c476/rl5c476.c
index ede34b6..8495c3f 100644
--- a/src/southbridge/ricoh/rl5c476/rl5c476.c
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.c
@@ -14,10 +14,11 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
-
+/* (C) Copyright 2005 Nick Barker <nick.barker@btinternet.com
+   brought into line with the current architecture of LinuxBios */ 
 
 
 #include <arch/io.h>
@@ -26,194 +27,174 @@
 #include <device/pci_ops.h>
 #include <device/pci_ids.h>
 #include <console/console.h>
+#include <device/cardbus.h>
 #include "rl5c476.h"
 #include "chip.h"
 
+static int enable_cf_boot = 0;
+static unsigned int cf_base;
+
 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(device_t dev)
 {
 	//unsigned char enables;
 	pc16reg_t *pc16;
-	int i;
 
-#error "FIXME implement carbus bridge support"
-#error "FIXME this code is close to a but the conversion needs more work"
+	unsigned char *base;
+
 	/* cardbus controller function 1 for CF Socket */
 	printk_debug("rl5c476 init\n");
 
-	/* setup pci header manually because 'pci_device.c' doesn't know how to handle
-         * pci to cardbus bridges - (header type 2 I think)
-	 */
+	printk_debug("CF Base = %0x\n",cf_base);
 
-
-	/* 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);
+	/* misc control register */
 	pci_write_config16(dev,0x82,0x00a0);
 
-	pci_write_config16(dev,0x04,0x07);
+	/* set up second slot as compact flash port if asked to do so */
+	if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){ 
+
+		/* make sure isa interrupts are enabled */
+		pci_write_config16(dev,0x3e,0x0780);
+
+		/* pick up where 16 bit card control structure is (0x800 bytes into config structure) */
+		base = (unsigned char *)pci_read_config32(dev,0x10);
+		pc16 = (pc16reg_t *)(base + 0x800);
+
+		/* 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 1e0 - 1ef
+ 		/* note this now sets CF up on a contiguous I/O window of 16 bytes, 0x1e0 to 0x1ef
+                   Be warned that this is not a standard IDE address as automatically detected by the likes
+                   of Filo, and would need patching to recognise these addresses as an IDE drive */
+		/* an earlier version of this driver set up 2 io windows to emulate the expected addresses
+                   for IDE2, however the pcmcia package within Linux then could not re-initiailse the
+                   device as it tried to take control of it. So I belive it is easier to patch Filo or the like
+                   to pick up this drive rather than playing silly games as the kernel tries to boot.
+		*/
+		pc16->iostl0 = 0xe0;
+		pc16->iosth0 = 1;
+
+		pc16->iospl0 = 0xef;
+		pc16->iosph0 = 1;
+
+		pc16->ioffl0 = 0;
+		pc16->ioffh0 = 0;
+
+		// clear window 1
+		pc16->iostl1 = 0;
+		pc16->iosth1 = 0;
+
+		pc16->iospl1 = 0;
+		pc16->iosph1 = 0;
+
+		pc16->ioffl1 = 0x0;
+		pc16->ioffh1 = 0;
 
 
-	/* 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 up CF config window
+		pc16->smpga0 = cf_base>>24;
+		pc16->smsth0 = (cf_base>>20)&0x0f;
+		pc16->smstl0 = (cf_base>>12)&0xff;
+		pc16->smsph0 = ((cf_base>>20)&0x0f) | 0x80;
+		pc16->smspl0 = (cf_base>>12)&0xff;
+		pc16->moffl0 = 0;
+		pc16->moffh0 = 0x40;
 
 
-	// 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;
+		// set I/O width for Auto Data width
+		pc16->ioctrl = 0x22;
 
 
-	// 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;
 
 
-	// enable I/O window 0 and 1
-	pc16->awinen = 0xc1;
+		pc16->miscc1 = 1;
 
-
-	pc16->miscc1 = 1;
-
-	// apply power and enable outputs
-	pc16->pwctrl = 0xb0;
+		// apply power and enable outputs
+		pc16->pwctrl = 0xb0;
 	
 
-	// delay could be optimised, but this works
-	udelay(100000);
+		// 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 !!!
+		pc16->igctrl = 0x69;
 
 
-	// 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;
+		// 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 !!!
+		unsigned char *cptr;
+		cptr = (unsigned char *)(cf_base + 0x200);
+		printk_debug("CF Config = %x\n",*cptr);
 
+		// 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;
+	}
+
+}
+
+void rl5c476_read_resources(device_t dev)
+{
+
+	struct resource *resource;
+
+   	 /* for cf socket we need an extra memory window for the control structure of the cf itself */
+	if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){ 
+		resource = new_resource(dev,1);    /* fake index as it isn't in pci config space */
+		resource->flags |= IORESOURCE_MEM ;
+		resource->size = 0x1000;
+		resource->align = resource->gran = 12;
+		resource->limit= 0xffff0000;
+		//compute_allocate_resource(&dev->link[0],resource,resource->flags,resource->flags);
+	}
+	cardbus_read_resources(dev);
+
+}
+
+void rl5c476_set_resources(device_t dev)
+{
+
+	struct resource *resource;
+	printk_debug("%s In set resources \n",dev_path(dev));
+	if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){
+		resource = find_resource(dev,1);
+		if( !(resource->flags & IORESOURCE_STORED) ){
+			resource->flags |= IORESOURCE_STORED ;
+			compute_allocate_resource(&dev->link[0],resource,resource->flags,resource->flags);
+			printk_debug("%s 1 ==> %x\n",dev_path(dev),resource->base); 
+			cf_base = resource->base;
+		}
+	}
+
+	pci_dev_set_resources(dev);
 
 }
 
 static struct device_operations ricoh_rl5c476_ops = {
-	.read_resources   = pci_bus_read_resources,
-	.set_resources    = pci_dev_set_resources,
-	.enable_resources = pci_bus_enable_resources,
-	.inti             = rl5c476_init,
-	.scan_bus         = pci_scan_bridge,
+	.read_resources   = rl5c476_read_resources,
+	.set_resources    = rl5c476_set_resources,
+	.enable_resources = cardbus_enable_resources,
+	.init             = rl5c476_init,
+	.scan_bus         = cardbus_scan_bridge,
 };
 
 static struct pci_driver ricoh_rl5c476_driver __pci_driver = {
@@ -222,7 +203,15 @@
 	.device = PCI_DEVICE_ID_RICOH_RL5C476,
 };
 
-struct chip_operations southbridge_ricoh_rl5c476_control = {
+void southbridge_init(device_t dev)
+{
+
+	struct southbridge_ricoh_rl5c476_config *conf = dev->chip_info;
+	enable_cf_boot = conf->enable_cf;
+
+}
+
+struct chip_operations southbridge_ricoh_rl5c476_ops = {
 	CHIP_NAME("RICOH RL5C476")
-	.enable    = southbridge_init,
+	.enable_dev    = southbridge_init,
 };
diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.h b/src/southbridge/ricoh/rl5c476/rl5c476.h
index 0ded3d5..c2da0de 100644
--- a/src/southbridge/ricoh/rl5c476/rl5c476.h
+++ b/src/southbridge/ricoh/rl5c476/rl5c476.h
@@ -14,8 +14,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
  /* rl5c476 routines and defines*/
diff --git a/src/southbridge/via/vt8235/vt8235.c b/src/southbridge/via/vt8235/vt8235.c
index ea649a4..e6287ec 100644
--- a/src/southbridge/via/vt8235/vt8235.c
+++ b/src/southbridge/via/vt8235/vt8235.c
@@ -10,7 +10,7 @@
 /*
  * Base VT8235.
  */
-static device_t lpc_dev;
+static int enabled = 0;
 
 void hard_reset(void) 
 {
@@ -22,18 +22,15 @@
 	unsigned char regval;
 
 	regval = pci_read_config8(dev, 0x51);
-//	regval |= 0x0f; 
-	/* !!!FIX let's try this */
-	regval |= 0x1d; 
+	regval |= 0x05; 
+	regval &= 0xfd;
 	pci_write_config8(dev, 0x51, regval);
 
 	init_pc_keyboard(0x60, 0x64, 0);
 }
 
-void dump_south(void)
+void dump_south(device_t dev0)
 {
-	device_t dev0;
-	dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
 	int i,j;
 	
 	for(i = 0; i < 256; i += 16) {
@@ -45,23 +42,53 @@
 	}
 }
 
-void set_led(struct device *dev)
+void set_led()
 {
 	// set power led to steady now that lxbios has virtually done its job
+	device_t dev;
+	dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
 	pci_write_config8(dev, 0x94, 0xb0);
 }
 
+
 static void vt8235_enable(struct device *dev)
 {
 	struct southbridge_via_vt8235_config *conf = dev->chip_info;
+	unsigned char regval;
+	unsigned short vendor,model;
 
-	printk_debug("In vt8235_enable.\n");
-	if (!lpc_dev) {
-		lpc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
-				PCI_DEVICE_ID_VIA_8235, 0);
-		if (conf->enable_keyboard)
-			keyboard_on(lpc_dev);
-	}
+
+	vendor = pci_read_config16(dev,0);
+	model = pci_read_config16(dev,0x2);
+
+	printk_debug("In vt8235_enable %04x %04x.\n",vendor,model);
+	
+	/* if this is not the southbridge itself just return */
+	/* this is necessary because USB devices are slot 10, whereas this device is slot 11 
+	  therefore usb devices get called first during the bus scan */
+
+	if( (vendor != PCI_VENDOR_ID_VIA) || (model != PCI_DEVICE_ID_VIA_8235))
+		return;
+
+	printk_debug("Initialising Devices\n");
+
+
+	setup_i8259();   // make sure interupt controller is configured before keyboard init 
+
+	/* enable RTC and ethernet */
+	regval = pci_read_config8(dev, 0x51);
+	regval |= 0x18; 
+	pci_write_config8(dev, 0x51, regval);
+
+	/* turn on keyboard */
+	keyboard_on(dev);
+
+	/* enable USB 1.1 & USB 2.0 -redundant really since we've already been there - see note above*/
+   	regval = pci_read_config8(dev, 0x50);
+	regval &= ~(0x36);
+	pci_write_config8(dev, 0x50, regval);
+
+
 }
 
 struct chip_operations southbridge_via_vt8235_ops = {
diff --git a/src/southbridge/via/vt8235/vt8235.h b/src/southbridge/via/vt8235/vt8235.h
index c8e79fc..f071371 100644
--- a/src/southbridge/via/vt8235/vt8235.h
+++ b/src/southbridge/via/vt8235/vt8235.h
@@ -17,8 +17,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
  /* winbond access routines and defines*/
diff --git a/src/southbridge/via/vt8235/vt8235_ide.c b/src/southbridge/via/vt8235/vt8235_ide.c
index 1775203..fedda9c 100644
--- a/src/southbridge/via/vt8235/vt8235_ide.c
+++ b/src/southbridge/via/vt8235/vt8235_ide.c
@@ -13,7 +13,7 @@
 
 	printk_info("Enabling VIA IDE.\n");
 
-	if (!conf->enable_native_ide) {
+	/*if (!conf->enable_native_ide) { */
 		/*
 		 * Run the IDE controller in 'compatiblity mode - i.e. don't
 		 * use PCI interrupts.  Using PCI ints confuses linux for some
@@ -28,7 +28,7 @@
 		enables = pci_read_config8(dev, 0x42);
 		printk_debug("enables in reg 0x42 read back as 0x%x\n",
 				enables);
-	}
+	/* } */
 	
 	enables = pci_read_config8(dev, 0x40);
 	printk_debug("enables in reg 0x40 0x%x\n", enables);
diff --git a/src/southbridge/via/vt8235/vt8235_lpc.c b/src/southbridge/via/vt8235/vt8235_lpc.c
index 4a3c683..3e22094 100644
--- a/src/southbridge/via/vt8235/vt8235_lpc.c
+++ b/src/southbridge/via/vt8235/vt8235_lpc.c
@@ -10,21 +10,30 @@
 #include "vt8235.h"
 #include "chip.h"
 
-/*
- * 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
- * 
- * 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
- */
+/* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
+   This is how the Award bios sets it up too.
+   epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
+   make sure that ACPI dsdt is changed to suit.
 
-static const unsigned char pciIrqs[4] = { 11 , 5, 10 , 12 };
+	IRQ 0 = timer
+	IRQ 1 = keyboard
+	IRQ 2 = cascade
+	IRQ 3 = COM 2
+	IRQ 4 = COM 1
+	IRQ 5 = available for PCI interrupts
+	IRQ 6 = floppy or availbale for PCI if floppy controller disabled
+        IRQ 7 = LPT or available if LPT port disabled
+	IRQ 8 = rtc
+	IRQ 9 = available for PCI interrupts
+	IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
+	IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
+	IRQ 12 = PS2 mouse (hardwired to 12)
+	IRQ 13 = legacy FPU interrupt
+	IRQ 14 = IDE controller 1
+	IRQ 15 = IDE controller 2
+
+*/
+static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
 
 static const unsigned char usbPins[4] =      { 'A','B','C','D'};
 static const unsigned char enetPins[4] =     { 'A','B','C','D'};
@@ -32,14 +41,9 @@
 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 cbPins[4] =       { 'D','A','B','C'};
 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)
 {
@@ -54,19 +58,12 @@
 static void pci_routing_fixup(struct device *dev)
 {
 	printk_info("%s: dev is %p\n", __FUNCTION__, dev);
-	if (dev) {
-		/* initialize PCI interupts - these assignments depend
-		   on the PCB routing of PINTA-D 
 
-		   PINTA = IRQ11
-		   PINTB = IRQ5
-		   PINTC = IRQ10
-		   PINTD = IRQ12
-		*/
-		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);
-	}
+	/* set up PCI IRQ routing */
+	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);
+
 
 	// firewire built into southbridge
 	printk_info("setting firewire\n");
@@ -201,12 +198,6 @@
 	// Set 0x58 to 0x03 to match Award
 	pci_write_config8(dev, 0x58, 0x03);
 	
-	// enable the ethernet/RTC
-	if (dev) {
-		enables = pci_read_config8(dev, 0x51);
-		enables |= 0x18; 
-		pci_write_config8(dev, 0x51, enables);
-	}
 	
 	/* enable serial irq */
 	pci_write_config8(dev, 0x52, 0x9);
@@ -224,6 +215,36 @@
 	rtc_init(0);
 }
 
+/* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
+   device has a resource to set - so set a dummy one */
+void vt8235_read_resources(device_t dev)
+{
+
+	struct resource *resource;
+	pci_dev_read_resources(dev);
+	resource = new_resource(dev, 1);
+	resource->flags |= IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO | IORESOURCE_STORED;
+	resource->size = 2;
+	resource->base = 0x2e;
+
+}
+void vt8235_set_resources(device_t dev)
+{
+	struct resource *resource;
+	//resource = find_resource(dev,1);
+	//resource->flags |= IORESOURCE_STORED;
+	pci_dev_set_resources(dev);
+}
+
+void vt8235_enable_resources(device_t dev)
+{
+	/* vt8235 is not a pci bridge and has no resources of its own (other than standard PC i/o addresses)
+           however it does control the isa bus and so we need to manually call enable childrens resources on that bus */
+	pci_dev_enable_resources(dev);
+	enable_childrens_resources(dev);
+
+}
+	
 static void southbridge_init(struct device *dev)
 {
 	vt8235_init(dev);
@@ -231,9 +252,9 @@
 }
 
 static struct device_operations vt8235_lpc_ops = {
-	.read_resources   = pci_dev_read_resources,
-	.set_resources    = pci_dev_set_resources,
-	.enable_resources = pci_dev_enable_resources,
+	.read_resources   = vt8235_read_resources,
+	.set_resources    = vt8235_set_resources,
+	.enable_resources = vt8235_enable_resources,
 	.init             = &southbridge_init,
 	.scan_bus         = scan_static_bus,
 };
diff --git a/src/southbridge/via/vt8235/vt8235_usb.c b/src/southbridge/via/vt8235/vt8235_usb.c
index 24c6a17..8142c53 100644
--- a/src/southbridge/via/vt8235/vt8235_usb.c
+++ b/src/southbridge/via/vt8235/vt8235_usb.c
@@ -5,11 +5,14 @@
 #include <device/pci_ids.h>
 #include "vt8235.h"
 
+/* really nothing to do here, both usb 1.1 & 2.0 are normal PCI devices and so get resources allocated
+   properly. They are part of the southbridge and are enabled in the chip enable function for the southbridge */
+
 static void usb_init(struct device *dev)
 {
 	printk_debug("Configuring VIA USB 1.1\n");
 
-	pci_write_config8(dev, 0x04, 0x07);
+	/* pci_write_config8(dev, 0x04, 0x07); */
 
 	/*
 	 * To disable; though do we need to do this?
@@ -25,6 +28,7 @@
 	 */
 }
 
+/*
 static struct device_operations usb_ops = {
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
@@ -39,3 +43,4 @@
 	.vendor = PCI_VENDOR_ID_VIA,
 	.device = PCI_DEVICE_ID_VIA_82C586_2,
 };
+*/
\ No newline at end of file
diff --git a/src/superio/via/vt1211/vt1211.c b/src/superio/via/vt1211/vt1211.c
index 30d9592..47a1ba4 100644
--- a/src/superio/via/vt1211/vt1211.c
+++ b/src/superio/via/vt1211/vt1211.c
@@ -14,8 +14,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
  /* vt1211 routines and defines*/
@@ -58,6 +58,25 @@
 	outb(0xaa, dev->path.u.pnp.port);
 }
 
+static void vt1211_set_iobase(device_t dev, unsigned index, unsigned iobase)
+{
+
+	switch (dev->path.u.pnp.device) {
+		case VT1211_FDC:
+		case VT1211_PP:
+		case VT1211_SP1:
+		case VT1211_SP2:
+			pnp_write_config(dev, index + 0, (iobase >> 2) & 0xff);
+			break;
+		case VT1211_HWM:
+		default:
+			pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
+			pnp_write_config(dev, index + 1, iobase & 0xff);
+			break;
+	}
+	
+}
+
 static void init_hwm(unsigned long base)
 {
 	int i;
@@ -79,6 +98,9 @@
 	}
 
 	switch (dev->path.u.pnp.device) {
+	case VT1211_FDC:
+	case VT1211_PP:
+		break;
 	case VT1211_SP1:
 		res0 = find_resource(dev, PNP_IDX_IO0);
 		init_uart8250(res0->base, &conf->com1);
@@ -95,24 +117,12 @@
 		printk_info("vt1211 asked to initialise unknown device!\n");
 	}
 	
-	/* 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();
-
- 	// Activate the vt1211 hardware monitor
-	start_conf_pnp(0x0b);
-	write_pnp(0x60,0xec); 
-	write_pnp(0x30,1);
-	end_conf_pnp(); */
 
 }
 
 void vt1211_pnp_enable_resources(device_t dev)
 {
+	printk_debug("%s - enabling\n",dev_path(dev));
 	pnp_enter_ext_func_mode(dev);
 	pnp_enable_resources(dev);
 	pnp_exit_ext_func_mode(dev);
@@ -120,8 +130,54 @@
 
 void vt1211_pnp_set_resources(struct device *dev)
 {
+	int i;
+	struct resource *resource;
+
+#if CONFIG_CONSOLE_SERIAL8250 == 1
+	if( dev->path.u.pnp.device == 2 ){
+		for( i = 0 ; i < dev->resources; i++){
+			resource = &dev->resource[i];
+			resource->flags |= IORESOURCE_STORED;
+			report_resource_stored(dev, resource, "");	
+		}
+		return;
+	}
+#endif
 	pnp_enter_ext_func_mode(dev);
-	pnp_set_resources(dev);
+	/* Select the device */
+	pnp_set_logical_device(dev);
+
+	/* Paranoia says I should disable the device here... */
+	for(i = 0; i < dev->resources; i++) {
+		resource = &dev->resource[i];
+		if (!(resource->flags & IORESOURCE_ASSIGNED)) {
+			printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
+				dev_path(dev), dev->resource->index,
+				resource_type(resource),
+				resource->size);
+			continue;
+		}
+
+		/* Now store the resource */
+		if (resource->flags & IORESOURCE_IO) {
+			vt1211_set_iobase(dev, resource->index, resource->base);
+		}
+		else if (resource->flags & IORESOURCE_DRQ) {
+			pnp_set_drq(dev, resource->index, resource->base);
+		}
+		else if (resource->flags  & IORESOURCE_IRQ) {
+			pnp_set_irq(dev, resource->index, resource->base);
+		}
+		else {
+			printk_err("ERROR: %s %02x unknown resource type\n",
+				dev_path(dev), resource->index);
+			return;
+		}
+		resource->flags |= IORESOURCE_STORED;
+
+		report_resource_stored(dev, resource, "");	
+	}
+
 	pnp_exit_ext_func_mode(dev);
 }
 
@@ -148,7 +204,7 @@
 	{ &ops, VT1211_PP,  PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
 	{ &ops, VT1211_SP1, PNP_IO0 | PNP_IRQ0,            { 0x07f8, 0}, },
 	{ &ops, VT1211_SP2, PNP_IO0 | PNP_IRQ0,            { 0x07f8, 0}, },
-	{ &ops, VT1211_HWM, PNP_IO0 , { 0xfff8, 0 }, },
+	{ &ops, VT1211_HWM, PNP_IO0 , { 0xff00, 0 }, },
 };
 
 static void enable_dev(struct device *dev)
diff --git a/targets/via/epia-m/Config.lb b/targets/via/epia-m/Config.lb
index baf066e..1d20481 100644
--- a/targets/via/epia-m/Config.lb
+++ b/targets/via/epia-m/Config.lb
@@ -18,7 +18,7 @@
 ### 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=0x30000
 
 ## LinuxBIOS C code runs at this location in RAM
 option _RAMBASE=0x00004000
@@ -30,26 +30,32 @@
 ###
 
 #
-# Via EPIA-M
+# EPIA-M
 #
-romimage "normal"
-	option USE_FALLBACK_IMAGE=0
-	option ROM_IMAGE_SIZE=0x10000
-	option LINUXBIOS_EXTRA_VERSION=".0Normal"
+#romimage "normal"
+#	option USE_FALLBACK_IMAGE=0
+#	option ROM_IMAGE_SIZE=0xc000
+#	option ROM_SECTION_OFFSET=0x10000
+#	option ROM_SECTION_SIZE=0x18000
+#	option XIP_ROM_BASE=0xfffd0000
+#	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 ../../../payloads/filo.elf
-end
+#	payload /filo.elf
+#end
 
 romimage "fallback" 
 	option USE_FALLBACK_IMAGE=1
 	option ROM_IMAGE_SIZE=0x10000
+	option ROM_SECTION_OFFSET=0x10000
+	option ROM_SECTION_SIZE=0x30000
+#	option XIP_ROM_BASE=0xfffe0000
 	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.ebi
-	payload ../../../payloads/filo.elf
+	payload /filo.elf
 end
 
-buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
+buildrom ./linuxbios.rom ROM_SIZE  "fallback"