eric patch
        1. x86_setup_mtrr take address bit.
        2. generic ht, pcix, pcie beidge...
        3. scan bus and reset_bus
        4. ht read ctrl to decide if the ht chain
           is ready
        5. Intel e7520 and e7525 support
        6. new ich5r support
        7. intel sb 6300 support.

yhlu patch
	1. split x86_setup_mtrrs to fixed and var
	2. if (resource->flags & IORESOURCE_FIXED ) return; in device.c pick_largest_resource
	3. in_conherent.c K8_SCAN_PCI_BUS


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1982 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/config/Options.lb b/src/config/Options.lb
index 92104a0..13a531b 100644
--- a/src/config/Options.lb
+++ b/src/config/Options.lb
@@ -576,6 +576,42 @@
 	comment "Default command line when autobooting"
 end
 
+define USE_WATCHDOG_ON_BOOT
+	default 0
+	export always
+	comment "Use the watchdog on booting"
+end
+
+###############################################
+# Plugin Device support options
+###############################################
+
+define CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT
+	default 1
+	export always
+	comment "Enable support for plugin Hypertransport busses"
+end
+define CONFIG_AGP_PLUGIN_SUPPORT
+	default 1
+	export always
+	comment "Enable support for plugin AGP busses"
+end
+define CONFIG_CARDBUS_PLUGIN_SUPPORT
+	default 1
+	export always
+	comment "Enable support cardbus plugin cards"
+end
+define CONFIG_PCIX_PLUGIN_SUPPORT
+	default 1
+	export always
+	comment "Enable support for plugin PCI-X busses"
+end
+define CONFIG_PCIEXP_PLUGIN_SUPPORT
+	default 1
+	export always
+	comment "Enable support for plugin PCI-E busses"
+end
+
 ###############################################
 # IRQ options
 ###############################################
@@ -709,21 +745,6 @@
 	export used
 	comment "Have hard reset"
 end
-define HARD_RESET_BUS
-	default 1
-	export always
-	comment "Bus number of southbridge device doing reset"
-end
-define HARD_RESET_DEVICE
-	default 5
-	export always
-	comment "Device number of southbridge device doing reset"
-end
-define HARD_RESET_FUNCTION
-	default 0
-	export always
-	comment "Function number of southbridge device doing reset"
-end
 define MEMORY_HOLE
 	default none
 	export used
diff --git a/src/cpu/amd/car/cache_as_ram_post.c b/src/cpu/amd/car/cache_as_ram_post.c
index 66ca9fd..6a129b2 100644
--- a/src/cpu/amd/car/cache_as_ram_post.c
+++ b/src/cpu/amd/car/cache_as_ram_post.c
@@ -1,4 +1,5 @@
 /* by yhlu 6.2005 */
+/* be warned, this file will be used other cores and core0/node0 */
         __asm__ volatile (
 	/* 
 	FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
diff --git a/src/cpu/amd/model_fxx/model_fxx_init.c b/src/cpu/amd/model_fxx/model_fxx_init.c
index b75025b..3c526e7 100644
--- a/src/cpu/amd/model_fxx/model_fxx_init.c
+++ b/src/cpu/amd/model_fxx/model_fxx_init.c
@@ -192,6 +192,7 @@
 	/* If ecc support is not enabled don't touch memory */
 	dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
 	if (!(dcl & DCL_DimmEccEn)) {
+		printk_debug("ECC Disabled\n");
 		return;
 	}
 
@@ -226,7 +227,9 @@
 	disable_lapic();
 
 	/* Walk through 2M chunks and zero them */
-	for(basek = begink; basek < endk; basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
+	for(basek = begink; basek < endk; 
+		basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) 
+	{
 		unsigned long limitk;
 		unsigned long size;
 		void *addr;
@@ -255,12 +258,13 @@
 		}
 		size = (limitk - basek) << 10;
 		addr = map_2M_page(basek >> 11);
-		addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
 		if (addr == MAPPING_ERROR) {
+			printk_err("Cannot map page: %x\n", basek >> 11);
 			continue;
 		}
 
 		/* clear memory 2M (limitk - basek) */
+		addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
 		clear_memory(addr, size);
 	}
 	/* Restore the normal state */
@@ -319,19 +323,16 @@
 		}	
 		wrmsr(NB_CFG_MSR, msr);
 	}
-// AMD_D0_SUPPORT	
+	
+	/* Erratum 97 ... */
 	if (!is_cpu_pre_c0() && is_cpu_pre_d0()) {
-		/* D0 later don't need it */
-		/* Erratum 97 ... */
 		msr = rdmsr_amd(DC_CFG_MSR);
 		msr.lo |= 1 << 3;
 		wrmsr_amd(DC_CFG_MSR, msr);
-	}
-		
-//AMD_D0_SUPPORT
-	if(is_cpu_pre_d0()) {
-		/*D0 later don't need it */
-		/* Erratum 94 ... */
+	}	
+	
+	/* Erratum 94 ... */
+	if (is_cpu_pre_d0()) {
 		msr = rdmsr_amd(IC_CFG_MSR);
 		msr.lo |= 1 << 11;
 		wrmsr_amd(IC_CFG_MSR, msr);
@@ -339,37 +340,51 @@
 
 	/* Erratum 91 prefetch miss is handled in the kernel */
 
-//AMD_D0_SUPPORT
+	/* Erratum 106 ... */
+	msr = rdmsr_amd(LS_CFG_MSR);
+	msr.lo |= 1 << 25;
+	wrmsr_amd(LS_CFG_MSR, msr);
+
+	/* Erratum 107 ... */
+	msr = rdmsr_amd(BU_CFG_MSR);
+	msr.hi |= 1 << (43 - 32);
+	wrmsr_amd(BU_CFG_MSR, msr);
+
 	if(is_cpu_d0()) {
 		/* Erratum 110 ...*/
 		msr = rdmsr_amd(CPU_ID_HYPER_EXT_FEATURES);
 		msr.hi |=1;
 		wrmsr_amd(CPU_ID_HYPER_EXT_FEATURES, msr);
-	}
+ 	}
 
-//AMD_E0_SUPPORT
-	if(!is_cpu_pre_e0()) {
-                /* Erratum 110 ...*/
+	if (!is_cpu_pre_e0()) {
+		/* Erratum 110 ... */
                 msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
                 msr.hi |=1;
                 wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
 	}
+
+	/* Erratum 122 */
+	msr = rdmsr(HWCR_MSR);
+	msr.lo |= 1 << 6;
+	wrmsr(HWCR_MSR, msr);
+	
 }
 
 void model_fxx_init(device_t dev)
 {
 	unsigned long i;
 	msr_t msr;
-#if CONFIG_LOGICAL_CPUS==1
+#if CONFIG_LOGICAL_CPUS
 	struct node_core_id id;
-        unsigned siblings;
+	unsigned siblings;
 	id.coreid=0;
 #else
 	unsigned nodeid;
 #endif
 
 	/* Turn on caching if we haven't already */
-	x86_enable_cache(); 
+	x86_enable_cache();
 	amd_setup_mtrrs();
 	x86_mtrr_check();
 
@@ -386,11 +401,12 @@
 	
 	enable_cache();
 
-#if CONFIG_LOGICAL_CPUS==1
-//AMD_DUAL_CORE_SUPPORT
+	/* Enable the local cpu apics */
+	setup_lapic();
+
+#if CONFIG_LOGICAL_CPUS == 1
         siblings = cpuid_ecx(0x80000008) & 0xff;
 
-//	id = get_node_core_id((!is_cpu_pre_e0())? read_nb_cfg_54():0);
 	id = get_node_core_id(read_nb_cfg_54()); // pre e0 nb_cfg_54 can not be set
 
        	if(siblings>0) {
@@ -407,24 +423,24 @@
                	wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
 	} 
         
+
 	/* Is this a bad location?  In particular can another node prefecth
 	 * data from this node before we have initialized it?
 	 */
-	if(id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core0
+	if (id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core 0
 #else
-	/* For now there is a 1-1 mapping between node_id and cpu_id */
-	nodeid = lapicid() & 0x7;
+	/* Is this a bad location?  In particular can another node prefecth
+	 * data from this node before we have initialized it?
+	 */
+	nodeid = lapicid() & 0xf;
 	init_ecc_memory(nodeid);
 #endif
-	
-	/* Enable the local cpu apics */
-	setup_lapic();
 
 #if CONFIG_LOGICAL_CPUS==1
-//AMD_DUAL_CORE_SUPPORT
         /* Start up my cpu siblings */
 //	if(id.coreid==0)  amd_sibling_init(dev); // Don't need core1 is already be put in the CPU BUS in bus_cpu_scan
 #endif
+
 }
 
 static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/amd/model_fxx/model_fxx_msr.h b/src/cpu/amd/model_fxx/model_fxx_msr.h
index c8d57be..b4795cb 100644
--- a/src/cpu/amd/model_fxx/model_fxx_msr.h
+++ b/src/cpu/amd/model_fxx/model_fxx_msr.h
@@ -3,6 +3,7 @@
 
 #define HWCR_MSR			0xC0010015
 #define NB_CFG_MSR			0xC001001f
+#define LS_CFG_MSR                      0xC0011020
 #define IC_CFG_MSR			0xC0011021
 #define DC_CFG_MSR			0xC0011022
 #define BU_CFG_MSR			0xC0011023
diff --git a/src/cpu/amd/mtrr/amd_mtrr.c b/src/cpu/amd/mtrr/amd_mtrr.c
index de4ed98..e57bb3b 100644
--- a/src/cpu/amd/mtrr/amd_mtrr.c
+++ b/src/cpu/amd/mtrr/amd_mtrr.c
@@ -96,26 +96,32 @@
 		return;
 	}
 	printk_debug("Setting fixed MTRRs(%d-%d) Type: WB, RdMEM, WrMEM\n",
-		     start_mtrr, last_mtrr);
+		start_mtrr, last_mtrr);
 	set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM);
 	
 }
 
+extern void enable_fixed_mtrr(void);
+
 void amd_setup_mtrrs(void)
 {
+	unsigned long address_bits;
 	struct mem_state state;
 	unsigned long i;
 	msr_t msr;
 
+
 	/* Enable the access to AMD RdDram and WrDram extension bits */
+	disable_cache();
 	msr = rdmsr(SYSCFG_MSR);
 	msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
 	wrmsr(SYSCFG_MSR, msr);
+	enable_cache();
 
 	printk_debug("\n");
 	/* Initialized the fixed_mtrrs to uncached */
 	printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n", 
-		     0, NUM_FIXED_RANGES);
+		0, NUM_FIXED_RANGES);
 	set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
 
 	/* Except for the PCI MMIO hole just before 4GB there are no
@@ -127,6 +133,7 @@
 		IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
 		set_fixed_mtrr_resource, &state);
 	printk_debug("DONE fixed MTRRs\n");
+
 	if (state.mmio_basek > state.tomk) {
 		state.mmio_basek = state.tomk;
 	}
@@ -164,10 +171,17 @@
 	msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
 	wrmsr(SYSCFG_MSR, msr);
 
+	enable_fixed_mtrr();
+
 	enable_cache();
 
+	/* FIXME we should probably query the cpu for this
+	 * but so far this is all any recent AMD cpu has supported.
+	 */
+	address_bits = 40;
+
 	/* Now that I have mapped what is memory and what is not
 	 * Setup the mtrrs so we can cache the memory.
 	 */
-	x86_setup_mtrrs();
+	x86_setup_var_mtrrs(address_bits);
 }
diff --git a/src/cpu/intel/model_f0x/model_f0x_init.c b/src/cpu/intel/model_f0x/model_f0x_init.c
index 55504a1..474d025 100644
--- a/src/cpu/intel/model_f0x/model_f0x_init.c
+++ b/src/cpu/intel/model_f0x/model_f0x_init.c
@@ -30,7 +30,7 @@
 {
 	/* Turn on caching if we haven't already */
 	x86_enable_cache();
-	x86_setup_mtrrs();
+	x86_setup_mtrrs(36);
 	x86_mtrr_check();
 	
 	/* Update the microcode */
diff --git a/src/cpu/intel/model_f1x/model_f1x_init.c b/src/cpu/intel/model_f1x/model_f1x_init.c
index 53cee4f..42dff1e 100644
--- a/src/cpu/intel/model_f1x/model_f1x_init.c
+++ b/src/cpu/intel/model_f1x/model_f1x_init.c
@@ -30,7 +30,7 @@
 {
 	/* Turn on caching if we haven't already */
 	x86_enable_cache();
-	x86_setup_mtrrs();
+	x86_setup_mtrrs(36);
 	x86_mtrr_check();
 	
 	/* Update the microcode */
diff --git a/src/cpu/intel/model_f2x/model_f2x_init.c b/src/cpu/intel/model_f2x/model_f2x_init.c
index 4f69d81..f019ea4 100644
--- a/src/cpu/intel/model_f2x/model_f2x_init.c
+++ b/src/cpu/intel/model_f2x/model_f2x_init.c
@@ -34,7 +34,7 @@
 {
 	/* Turn on caching if we haven't already */
 	x86_enable_cache();
-	x86_setup_mtrrs();
+	x86_setup_mtrrs(36);
 	x86_mtrr_check();
 	
 	/* Update the microcode */
diff --git a/src/cpu/intel/model_f3x/model_f3x_init.c b/src/cpu/intel/model_f3x/model_f3x_init.c
index a89e7d1..20b8518 100644
--- a/src/cpu/intel/model_f3x/model_f3x_init.c
+++ b/src/cpu/intel/model_f3x/model_f3x_init.c
@@ -31,7 +31,7 @@
 {
 	/* Turn on caching if we haven't already */
 	x86_enable_cache();
-	x86_setup_mtrrs();
+	x86_setup_mtrrs(36);
 	x86_mtrr_check();
 	
 	/* Update the microcode */
diff --git a/src/cpu/intel/model_f4x/Config.lb b/src/cpu/intel/model_f4x/Config.lb
new file mode 100644
index 0000000..66f6ceb
--- /dev/null
+++ b/src/cpu/intel/model_f4x/Config.lb
@@ -0,0 +1,12 @@
+uses HAVE_MOVNTI
+default HAVE_MOVNTI=1
+dir /cpu/x86/tsc
+dir /cpu/x86/mtrr
+dir /cpu/x86/fpu
+dir /cpu/x86/mmx
+dir /cpu/x86/sse
+dir /cpu/x86/lapic
+dir /cpu/x86/cache
+dir /cpu/intel/microcode
+dir /cpu/intel/hyperthreading
+driver model_f4x_init.o
diff --git a/src/cpu/intel/model_f4x/microcode_MBDF410D.h b/src/cpu/intel/model_f4x/microcode_MBDF410D.h
new file mode 100644
index 0000000..9266ce5
--- /dev/null
+++ b/src/cpu/intel/model_f4x/microcode_MBDF410D.h
@@ -0,0 +1,1024 @@
+0x00000001, /* Header Version	*/

+0x0000000d, /* Patch ID		*/

+0x11032004, /* DATE		*/

+0x00000f41, /* CPUID		*/

+0xa3430d74, /* Checksum		*/

+0x00000001, /* Loader Version	*/

+0x000000bd, /* Platform ID	*/

+0x00000fd0, /* Data size	*/

+0x00001000, /* Total size	*/

+0x00000000, /* reserved		*/

+0x00000000, /* reserved		*/

+0x00000000, /* reserved		*/

+0x23869663,

+0x00e8d132,

+0xc1efa329,

+0x20662968,

+0xb833cad6,

+0x78012780,

+0x0971cf44,

+0xda1410ae,

+0xece61219,

+0x5ec0a10c,

+0x5a1c529c,

+0x9b5e4fac,

+0x35fee068,

+0x24bb3539,

+0xa6c23421,

+0x0309a01d,

+0x80331c7b,

+0x960d5da2,

+0x56d31115,

+0xdaadb98b,

+0x8d5c0ca8,

+0xc1fc4f86,

+0xef6ee956,

+0x512c9483,

+0x08a9c125,

+0x03b95162,

+0x6499668c,

+0x25e15127,

+0xfb4f0f0b,

+0x10d1b2c3,

+0x542be728,

+0xa0f11cc9,

+0xa5bc6bd2,

+0xf3b7cc86,

+0xe4a91466,

+0x41eceee1,

+0x5beb249b,

+0x6ab82791,

+0x2c5a86ac,

+0x90c2865d,

+0x4702c4a5,

+0xbddad5f1,

+0xb2e224fb,

+0x0ffb50d3,

+0x13c6933c,

+0xc573b9df,

+0x908510f6,

+0xca6f3a9e,

+0x2049f489,

+0xe20b8848,

+0xfd659d6e,

+0xc9afd397,

+0x1432aa70,

+0x62c3e20c,

+0xee6dda59,

+0xe8601135,

+0xa9e30f8e,

+0x691b59e5,

+0x0446816b,

+0xd63a3f0c,

+0x5d1b9d99,

+0xfe8d9637,

+0xee61a0a4,

+0xeeae5aa0,

+0x709d78e6,

+0x5468e7fb,

+0x7e0f2dc3,

+0x632591e1,

+0x990864bb,

+0x413a220b,

+0x5285bdcd,

+0xb7323fa6,

+0xfe0098ce,

+0xd05d24b2,

+0x51ee2e1e,

+0x0078c207,

+0x9d1e1514,

+0x1be23c59,

+0xa80398e4,

+0xe0fa94c8,

+0x2b2f841e,

+0x21144f67,

+0x0a6a1413,

+0xfa30499a,

+0xba49558e,

+0x1607d767,

+0xebd70987,

+0x00cb016d,

+0xac1de18a,

+0xfcde8566,

+0x23f51d05,

+0xb7368509,

+0x9b1947fd,

+0x0d0d3c22,

+0xfbeab67d,

+0xfc963120,

+0x0aeae56b,

+0x0dbe2aeb,

+0x6d4ba825,

+0xab4b8dae,

+0x23bbe7a0,

+0x53d38f2e,

+0x6ee7bed3,

+0x39869966,

+0x8e36076d,

+0x410dca57,

+0x133c4861,

+0xcc2920d0,

+0xb1cfc172,

+0xd3c2e94b,

+0x8cdb7550,

+0xcb14be86,

+0x1c72bb42,

+0x469a6066,

+0x912f65eb,

+0x173ac7b9,

+0xfa02afca,

+0x23fc44f2,

+0xbbf0c89f,

+0xa018ba5f,

+0x950654d1,

+0x1b6d7652,

+0xb2a04767,

+0x86630316,

+0xff3fd7b3,

+0x9c9b3aba,

+0xb7d6115b,

+0x7c7a354c,

+0x1761b195,

+0xc54b49dd,

+0x2e0f5f20,

+0xaf1e90b2,

+0x07056032,

+0x46ccdd94,

+0xcc751ec5,

+0x4774af8a,

+0x24a3dba1,

+0xa388bccc,

+0xacd1c25a,

+0x4ee406c1,

+0x9861931a,

+0x5bae36e2,

+0xafc6e087,

+0x8d36cd1b,

+0x25f894d1,

+0xd749fdaa,

+0x3cef917d,

+0xb85440c2,

+0x4d22a2bf,

+0x19703ee4,

+0xa5fd9e1e,

+0x76062779,

+0x14031f62,

+0x6e309271,

+0x55476f65,

+0xb4fd2411,

+0x554882db,

+0xee9d4d38,

+0x57faf730,

+0x730e0285,

+0xb882d382,

+0xc156852d,

+0xf2db8f7a,

+0xea52f3e4,

+0x323430d1,

+0x51ea5fe9,

+0x0929d601,

+0x8e6740cf,

+0x69c456e1,

+0xd9e2f5c1,

+0x0124bf3b,

+0x0220f415,

+0xfbe91365,

+0x2bc82d06,

+0x0a31f25c,

+0xbeaf32af,

+0x3c2175b7,

+0xe8f67a0e,

+0x177bb8fa,

+0x33b86eb3,

+0x3ba0e579,

+0x368fc48b,

+0xe6665da8,

+0x688bfd43,

+0x48448000,

+0xc5c99d34,

+0xab99cfeb,

+0x1ce9c58d,

+0x773ae448,

+0x3534d849,

+0x6d86470f,

+0x306db8d0,

+0x550c15ff,

+0x7a2c439a,

+0xe6f1b78f,

+0x0bf4cdd7,

+0xfbcab3d7,

+0x402e87ec,

+0xf4ee5874,

+0xc03c70d9,

+0x3b9ed9e6,

+0x04ef67e0,

+0xd04ae924,

+0xf6845607,

+0x5e58c954,

+0xc2fdf283,

+0xc558ae4e,

+0x8300ece1,

+0x7bbaea80,

+0xc5d0b0f1,

+0xfc9e8004,

+0xfcea494a,

+0x04f4eb47,

+0x129f505d,

+0xccbae019,

+0x59c0616f,

+0xaaba53a8,

+0x19d8a002,

+0x361fb171,

+0x00c4aee2,

+0x6bb0dfb0,

+0xc03d6b9a,

+0xabaed6fb,

+0xa23c48fe,

+0x50866e98,

+0xbb499854,

+0xb5730aad,

+0xbe89d93c,

+0xe6d35886,

+0x7ae05c20,

+0xc2708cbd,

+0xf8f18059,

+0xf492c48e,

+0x14121e3d,

+0x9e9dc5a7,

+0xafa3ef3a,

+0x17535114,

+0x08296547,

+0xe1ab5d3c,

+0x2e51d954,

+0x0e6953db,

+0xde0ea136,

+0xd1f37944,

+0x3074f7ed,

+0x3b196093,

+0x0efb3b56,

+0x3b904c2c,

+0xcef179ee,

+0xc854e7f5,

+0x48aa28ce,

+0x1c0cb17e,

+0xae4236b2,

+0x87c5dc18,

+0x7832ec05,

+0xc4212949,

+0xca5a40d2,

+0x8e8f431d,

+0x328df52b,

+0xe4dd2524,

+0x7b8ae78a,

+0x17ba24a3,

+0x25eb59d5,

+0x1a341b63,

+0x45f1e3f2,

+0x0e2d9cf8,

+0xa66c17e8,

+0x515bc934,

+0xfea866d3,

+0xd149deac,

+0x740a7cf5,

+0x2f47375b,

+0xa5fdd0c4,

+0xd8965720,

+0x4ecefd2f,

+0x1916443a,

+0x984995a9,

+0x7b919733,

+0x80f02747,

+0x30fe0d17,

+0x65a68843,

+0xdb0931ad,

+0x0929b113,

+0x1bd4cc0c,

+0x7b2f63fd,

+0x6238656c,

+0x8a1badab,

+0x6565a869,

+0xca48cce2,

+0x7ff6bdc3,

+0x772305d4,

+0x376639d3,

+0x56ed9f11,

+0x75e17cef,

+0x7dffbcf4,

+0xfbafb077,

+0x932aed24,

+0x8b04ebf4,

+0x768ac85f,

+0xb54a99f9,

+0xd4fdf692,

+0x43b09d0a,

+0x32d81423,

+0xcb2a74e6,

+0x59f40d29,

+0x6392b933,

+0x7a3bc72c,

+0xfa647af0,

+0x2c28e15f,

+0xa724e1b0,

+0x6174f8f6,

+0x651672ab,

+0xd8eb376a,

+0x61d18571,

+0xa9bab242,

+0x2ba20ac2,

+0x332c20a9,

+0x21e71331,

+0x7ba9dbe4,

+0x1e61e44d,

+0x07ee9579,

+0xd1846f7a,

+0xca29125b,

+0x11958b89,

+0xb6fe5a2b,

+0x249991b4,

+0x5f28c005,

+0x0b909d87,

+0x673159ab,

+0xf25d3b1a,

+0x2a7f0d31,

+0x2e741145,

+0x60c1525d,

+0x7a2996a7,

+0x5051ead4,

+0xb9473e57,

+0x7c5f9d0e,

+0x51584719,

+0xa25c2246,

+0xceec4103,

+0x813e68be,

+0xabf2eed8,

+0x4fb4988f,

+0x678fba46,

+0x801b82e1,

+0x7fc428dc,

+0xa30bf423,

+0xd1dc03db,

+0x65d1f1fb,

+0xfea39d25,

+0x7b8cfad4,

+0x7eda42af,

+0x4c7cb670,

+0x1ac54e69,

+0x6ecd00ae,

+0x2ff34b4e,

+0x0f7c1999,

+0x14713cb0,

+0x3942aea8,

+0x07832b5c,

+0x5cd3fa0c,

+0x918b4916,

+0xe9420e66,

+0x8bd0f43c,

+0x28e79a91,

+0x999c89a3,

+0x59da832c,

+0x3dd8cb18,

+0x67deb7fe,

+0xa4f503bb,

+0x77f8114f,

+0xe732a72b,

+0x7e8b8835,

+0x10192856,

+0x54da048f,

+0x8ea0f6cd,

+0x722ba57f,

+0x133ad6fc,

+0x7d486fb3,

+0x27764f83,

+0x8c0dff5f,

+0x9f137e77,

+0x5d6b4057,

+0xeef4eee0,

+0xb0e0e900,

+0xf37b72f1,

+0xec1b84f5,

+0x0a454136,

+0xc23a91a3,

+0x0ab3bae8,

+0x715496f9,

+0xc1082181,

+0xccf9217f,

+0x5213635d,

+0x2e29ab5b,

+0xb4574eef,

+0x2bc2fea8,

+0x1ee67ef8,

+0xd567c2b8,

+0xfc19ef2c,

+0xe19af740,

+0x28a28944,

+0x836be662,

+0xb0080f12,

+0xd6f61914,

+0x33c85c03,

+0x326e680f,

+0x87b45aa5,

+0xad7c015b,

+0x63e312a9,

+0x65fb08cf,

+0x5fca6d27,

+0x7b57bef5,

+0x466fa276,

+0x56c21f72,

+0x38fb8f1d,

+0xc1966d08,

+0x15d4c28b,

+0xeec1eade,

+0x905f5218,

+0x5be29b59,

+0xb64aa150,

+0xc8994548,

+0xe4bfb038,

+0xd63e54cf,

+0x98469c03,

+0xb28e3b7b,

+0xf852cae3,

+0xc76b8b09,

+0x16810021,

+0x8ea0bfec,

+0xdfc083e5,

+0x884c8453,

+0x908a80f2,

+0xb6d91870,

+0x56ad6422,

+0x05174668,

+0x380d8035,

+0xeef37603,

+0x38ff195e,

+0x44898288,

+0xb300620f,

+0xa814ec47,

+0xa58d3007,

+0x7d4536f5,

+0x2dfc2f4d,

+0xfa2ae308,

+0x24d4799f,

+0x1423df15,

+0x82dc572b,

+0xa3141ca3,

+0xa1210bb1,

+0xb7eecdc4,

+0x5d9ac524,

+0xb8f4b3fb,

+0x6cd8f8a8,

+0x0e745c45,

+0xb0041dbe,

+0x6ee22101,

+0xc9fb746b,

+0x69909b4d,

+0x9e63a31c,

+0xbc627065,

+0x6b24225b,

+0x1d2b80b1,

+0x4c08e46b,

+0x1f78a68c,

+0x75bc0a34,

+0x74d23ab8,

+0xb16d2786,

+0xfbb6fa5f,

+0xc9bbf303,

+0x69ebae66,

+0xcfa4bf29,

+0xaa69d19e,

+0x5d965c81,

+0x7cebac23,

+0x030b7aca,

+0x7983efba,

+0x03babdb7,

+0xd9d7a8bb,

+0xa939d7e1,

+0x6913d42f,

+0xfce3f3b5,

+0xb9d2a26b,

+0x32e614b2,

+0xbbb00851,

+0x4313ca42,

+0xe17a6d39,

+0x5b9f0631,

+0x90569ece,

+0xf980f983,

+0x13eb7233,

+0xc8da9166,

+0x60dbe5fc,

+0x4621997a,

+0xccd2a527,

+0x061180aa,

+0xa92467da,

+0x3dc79eef,

+0x39f31e91,

+0x9e45191c,

+0x7dcba672,

+0xfc23a8b8,

+0x1a773f6a,

+0x6fc6fa46,

+0x46b50e14,

+0x514bd261,

+0xe6cc3574,

+0x5a88dea2,

+0x9121d758,

+0x7f39e3bf,

+0x9ab043b6,

+0xc1007d0c,

+0xc3c3ff8e,

+0x08411386,

+0x0bd529d7,

+0xcaa9a1d8,

+0x27b19be2,

+0x95703f7e,

+0x44ab493a,

+0xcf1fc404,

+0x3f34062d,

+0xa56d454b,

+0x9464f996,

+0x1346eadf,

+0xdd6e6895,

+0x27b5ba10,

+0xb84c1d0c,

+0x5fa57ca4,

+0xad052de8,

+0xf5b4a3ae,

+0x6a61144d,

+0x48c00092,

+0x4897fad0,

+0x90b7b116,

+0xcdf29b2c,

+0xa41aac9a,

+0x147d09f7,

+0xebf3615d,

+0xb3ddf0b0,

+0xc8edc675,

+0x43cbf71b,

+0xfa0a0b5c,

+0xe0b63692,

+0x6c5870a9,

+0xe0b37be9,

+0xb16acc39,

+0xc55aed8c,

+0xd34fb041,

+0x24735885,

+0x0fff6e94,

+0x834181e8,

+0x56671872,

+0xb3f2e29b,

+0xfa383cd3,

+0xe585e5b6,

+0xa40cb894,

+0x1fe8376a,

+0xf794c60a,

+0xa3efdb18,

+0x0df1f1b4,

+0x54230798,

+0xd2a8ba49,

+0x349ce466,

+0xcbff13b4,

+0x71a63418,

+0x728ae615,

+0xf7c4f811,

+0x0dd072d8,

+0x9aa6fac7,

+0xa44210d0,

+0x2a1a85bf,

+0x1e18a8c6,

+0xbe2bb680,

+0xfed00f0e,

+0x2acc1b4b,

+0x4f049f6f,

+0x6f5aeec1,

+0x2db8f7b4,

+0xd61041a2,

+0x5cc7c861,

+0xb6ed3676,

+0x02aef566,

+0x2b6d41c8,

+0xaba9296e,

+0xf7b032cd,

+0xc290e538,

+0x584ad0f9,

+0x95289bc7,

+0x49b428b8,

+0x84bb41d4,

+0xdf0fcf91,

+0x9bd712a9,

+0xc6f730e1,

+0xe28b78d4,

+0x45b0480d,

+0x29d344bf,

+0xcd0101bb,

+0x18561b59,

+0xcfa84f65,

+0x76e798eb,

+0xac73f8af,

+0x71fe2488,

+0x207dd75d,

+0x198130e5,

+0x3604d44d,

+0xd895dc9b,

+0xf55fe7e2,

+0x4fed2e51,

+0xf434e20a,

+0x7c3204e8,

+0x4d653a59,

+0x6652a556,

+0x8713f1e2,

+0xa69dea42,

+0x2fd0ee37,

+0xe7617993,

+0xc0791c80,

+0x57e14435,

+0x87fcad6e,

+0x96505f56,

+0x838e7a38,

+0x78b228ab,

+0x84411d16,

+0x0b4e1d87,

+0x21f17d96,

+0x72021b3c,

+0xe69f4784,

+0x324fb9b4,

+0x041c7459,

+0x500ffe39,

+0x6e561c0f,

+0xadaf6fd7,

+0x0c91509f,

+0x8be04594,

+0x6a5ead5a,

+0x313c9f9d,

+0xe4754919,

+0x63d7cebc,

+0x02d0ad32,

+0x2dc3cdb7,

+0xd9b2e421,

+0xa1ad018c,

+0xd954f545,

+0x9f3871b2,

+0xf8a9a4a9,

+0x4cdc558d,

+0x300c9685,

+0x639f4b78,

+0x2181680d,

+0xb96442d6,

+0x7821a1a2,

+0x174a9e5b,

+0x79320590,

+0xf580c60c,

+0xba8539ce,

+0x59905669,

+0xc6f39c94,

+0xb57cc9bf,

+0xc2f7ad76,

+0x8d9ebc2d,

+0x6c33e47f,

+0x29294c84,

+0x49a2bef6,

+0x8aa6f79b,

+0x809f0eb5,

+0x3691aa7f,

+0xcf4b0e8f,

+0xec44f802,

+0x16bf83a7,

+0x82c00d36,

+0xa99071b1,

+0xe3815c76,

+0xc0835331,

+0xc794c55f,

+0x041b44af,

+0x2fa75171,

+0x985bd852,

+0xc4391e66,

+0x7bf08eaf,

+0x2b826882,

+0xfb8834dc,

+0x9128681e,

+0x6a2cb9ef,

+0x6d1d20f9,

+0x9f90ee4d,

+0xc48c3ee3,

+0xdd063585,

+0x82454044,

+0xf7077f1a,

+0x47e6e556,

+0xd803f7dd,

+0x98f67f71,

+0x9089e4ac,

+0xe7f09610,

+0xa9e3f93b,

+0x420c1550,

+0xc01f7710,

+0x0905da5e,

+0x02d71f99,

+0xbf36b473,

+0x50a96e32,

+0x2dedb8b9,

+0x9e3051a2,

+0x84c023c4,

+0xd43073b1,

+0x74f23fbb,

+0xd42a4487,

+0x266dfc42,

+0x6be0acdf,

+0xa986294c,

+0x3ee65aa8,

+0x19c1cf4f,

+0x2fdf8308,

+0xa6a64910,

+0xc3fa82e8,

+0x2943c8b8,

+0xf1a60b7b,

+0x4cc9ea04,

+0x3cc95270,

+0x054a8d2b,

+0xae7a4525,

+0x2e2abb62,

+0x24b9522b,

+0xb95a6668,

+0xad8c237d,

+0x1ea73bf8,

+0xff33f0d6,

+0x772a16a3,

+0xfefabdc4,

+0xb181234c,

+0xab59fb47,

+0x96f2c987,

+0xff0d4f54,

+0x6e938aba,

+0x727e6266,

+0xea0d851f,

+0x2ced3474,

+0x8c2e7718,

+0xa576c375,

+0xc97addeb,

+0x2f46a635,

+0xdb669986,

+0xa4333f93,

+0x7042c2c6,

+0x419fda5f,

+0x95b8aa3f,

+0x6ad05dc8,

+0x8b90655a,

+0xd8c77947,

+0x20508480,

+0xfa3cdf6b,

+0xdbb44af2,

+0x235941d0,

+0x3154c107,

+0x566bc32a,

+0x426fb2cd,

+0xd2010afa,

+0xe2775abe,

+0x6f543a20,

+0x2c626450,

+0x34f193f4,

+0x37ac5908,

+0x58a7eca6,

+0xc4859881,

+0x183393ff,

+0xab9abed9,

+0xde947d21,

+0xffec2b7d,

+0xb21b8788,

+0xb527117f,

+0x199dffe5,

+0xd7ebe4e6,

+0xc89a72b0,

+0x91cc3042,

+0x91bd3463,

+0x736e6f4f,

+0x0cc208bc,

+0x029f21cb,

+0x3f204418,

+0x050db787,

+0x71b56562,

+0xaf07f08f,

+0xaca4701f,

+0x88d4f2f8,

+0xf98fe016,

+0xb47672c6,

+0xed601c94,

+0x285db8b8,

+0x28a81c19,

+0x9e2763ce,

+0xe39741c0,

+0xcd9fce6d,

+0xe9917796,

+0xfdd3ebaf,

+0x99dcb253,

+0xe9aa0db4,

+0x3a65c0b0,

+0xb39c61fb,

+0x1f413c5e,

+0x60576c8c,

+0x48d6df34,

+0x0cbca786,

+0x4caff4b7,

+0x8473e181,

+0x36eed747,

+0x82f486af,

+0x79f02eed,

+0xab6886ed,

+0x06aef911,

+0xad42a654,

+0x5471c813,

+0xc8bbe710,

+0xfc65fd97,

+0x60f467af,

+0xf56b71d8,

+0xc1d6f193,

+0x3a1c42bf,

+0x46ce3b78,

+0x39472626,

+0x04dc137e,

+0xb48dc9dd,

+0xdfd27741,

+0x4718e5a2,

+0x00ba4728,

+0x855b661f,

+0x6d98577f,

+0xc3b48131,

+0x2b0384c1,

+0x8af572fe,

+0x760aa4e3,

+0x2f5b53fb,

+0xb9234297,

+0x401b47f5,

+0x44237cc0,

+0x2f7205f4,

+0x19b63c6e,

+0x7c375e6b,

+0x152c42d8,

+0x603731c7,

+0xc67601fb,

+0xa5d4826c,

+0x9068966f,

+0x864fe2f9,

+0xb37311d9,

+0xe6e4a34a,

+0xd46ee161,

+0xecd76c4a,

+0x90d0328a,

+0x4865b540,

+0xd2e13982,

+0x7e3925f4,

+0xc850a518,

+0x63bffcce,

+0x7cdb918f,

+0xcd8786d3,

+0xcf83df01,

+0x27122e50,

+0x0f014b76,

+0xde1485d7,

+0xa6ff496f,

+0xed0812f7,

+0x34efe965,

+0x12a63465,

+0xb83d9f77,

+0x040efa2e,

+0x4ac576d1,

+0x185430dd,

+0xb4271745,

+0x9bb58be2,

+0x7f55d4bb,

+0xca7dae0b,

+0x0bfe5147,

+0x4a9ade45,

+0x20bdc545,

+0xdf66689d,

+0x22e29493,

+0x31763c1f,

+0x2d021cd2,

+0x06286428,

+0xc7bba5d4,

+0x6bc42a0e,

+0x1c987082,

+0xd6c6c2f9,

+0x2c1ecdd0,

+0x84946249,

+0x42c1c41b,

+0x6d949e60,

+0x9dbb1571,

+0xf6b1df68,

+0x0705ae1a,

+0xa1ec5add,

+0x7e94d7c8,

+0x7d4d451d,

+0xd53c13d4,

+0x0204877b,

+0x0f0e44e0,

+0xdf25570f,

+0xd2a9adaf,

+0x556aeacf,

+0x2f985a30,

+0x706c42c6,

+0x2d5a76a5,

+0xdc428213,

+0xdf2864a2,

+0x0f6788a9,

+0xc764d3a6,

+0x9211d0ca,

+0x59e3f5cc,

+0xd31fd5b6,

+0xfa8b535b,

+0x2cac74bb,

+0xc43f36b2,

+0xf83b5bac,

+0x96c255bf,

+0x45915993,

+0x657d751a,

+0x9b86b994,

+0xddab62fd,

+0x1b6ac108,

+0x559073c9,

+0xe60a0bda,

+0xd65df6de,

+0x41f7e5d4,

+0x825a5701,

+0x377307b6,

+0x08176ce6,

+0x7a8a2c4a,

+0xd7ecb869,

+0x02710179,

+0x75e7517c,

+0xdfaf2c82,

+0x67590275,

+0x6ad621af,

+0xaedaa35c,

+0xfa8fbee3,

+0x9e5dda5f,

+0x09f571fa,

+0xe358dbfe,

+0x1b3300f1,

+0x05567c6b,

+0x5a9d335f,

+0x215114f8,

+0xd5744f0a,

+0x78ecc142,

+0x9b5f60b8,

+0x30f8fed2,

+0x5c013696,

+0x675c84de,

+0xdb50bbcc,

+0x7c504a4e,

+0x3ffc5fda,

+0x24b2c30a,

+0xac00d64a,

+0x97832b52,

+0xb34d9975,

+0x93c6cb4e,

+0x471bfcae,

+0xaabbb6d8,

+0x0bc6a5e5,

+0x6875c630,

+0xf4cce30c,

+0xdab0d64b,

+0x29aba8b9,

+0xe34b3cde,

+0x8654e470,

+0x2c5041f7,

+0xdcf5eff9,

+0x26a88f84,

+0x9d374761,

+0xefa60ac4,

+0xdf0d0fd3,

+0x72e37e59,

+0xa76d26e1,

+0x3ffe2408,

+0x13ecf42d,

+0x46de7cba,

+0x43330219,

+0xc2536a31,

+0xa69c4729,

+0x114990f8,

+0x3f08ed00,

+0xeaa05cae,

+0x08f06e57,

+0x30f4a62f,

+0x963a7557,

+0x631fb75f,

+0x1344a74b,

+0x1e80cef5,

+0x8a4f86dd,

+0x0f7f1c62,

+0xfe9f5809,

+0x710d86de,

+0x8939283d,

+0x19403076,

+0x26ce286b,

+0x6baaf798,

+0xbc1d2808,

+0xea980728,

+0x72288979,

+0x7c92be68,

+0x0a7af91b,

+0x7bb8059b,

+0xe7eca99c,

+0xd3a8819f,

+0xb9182916,

+0x0c48ba1e,

+0xb6aaf63b,

+0x10a740a6,

+0x0aa2e4e7,

+0x0bf27e94,

+0x6d266f86,

diff --git a/src/cpu/intel/model_f4x/model_f4x_init.c b/src/cpu/intel/model_f4x/model_f4x_init.c
new file mode 100644
index 0000000..6496386
--- /dev/null
+++ b/src/cpu/intel/model_f4x/model_f4x_init.c
@@ -0,0 +1,58 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/intel/hyperthreading.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/mtrr.h>
+
+static uint32_t microcode_updates[] = {
+	/* WARNING - Intel has a new data structure that has variable length
+	 * microcode update lengths.  They are encoded in int 8 and 9.  A
+	 * dummy header of nulls must terminate the list.
+	 */
+	
+#include "microcode_MBDF410D.h"
+	/*  Dummy terminator  */
+        0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0,
+};
+
+
+static void model_f4x_init(device_t cpu)
+{
+	/* Turn on caching if we haven't already */
+	x86_enable_cache();
+	x86_setup_mtrrs(36);
+	x86_mtrr_check();
+	
+	/* Update the microcode */
+	intel_update_microcode(microcode_updates);
+
+	/* Enable the local cpu apics */
+	setup_lapic();
+
+	/* Start up my cpu siblings */
+	intel_sibling_init(cpu);
+};
+
+static struct device_operations cpu_dev_ops = {
+	.init = model_f4x_init,
+};
+static struct cpu_device_id cpu_table[] = {
+	{ X86_VENDOR_INTEL, 0x0f41 }, /* Xeon */
+	{ 0, 0 },
+};
+
+static struct cpu_driver model_f4x __cpu_driver = {
+	.ops      = &cpu_dev_ops,
+	.id_table = cpu_table,
+};
diff --git a/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb b/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb
index 0b79433..2637c86 100644
--- a/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb
+++ b/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb
@@ -1,3 +1,4 @@
 config chip.h
 object socket_mPGA604_800Mhz.o
 dir /cpu/intel/model_f3x
+dir /cpu/intel/model_f4x
diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c
index c435b2e..105f7c4 100644
--- a/src/cpu/x86/mtrr/earlymtrr.c
+++ b/src/cpu/x86/mtrr/earlymtrr.c
@@ -37,8 +37,8 @@
 	wrmsr(MTRRphysMask_MSR(reg), zero);
 }
 
-static void set_var_mtrr(unsigned reg, unsigned base, unsigned size,
-			 unsigned type)
+static void set_var_mtrr(
+	unsigned reg, unsigned base, unsigned size, unsigned type)
 
 {
 	/* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
@@ -76,7 +76,7 @@
 	msr.lo = 0;
 	msr.hi = 0;
 	unsigned long msr_nr;
-	for (msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) {
+	for(msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) {
 		wrmsr(msr_nr, msr);
 	}
 
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index 59f9ca1..1226713 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -22,9 +22,14 @@
  *
  * Reference: Intel Architecture Software Developer's Manual, Volume 3: System Programming
  */
+
 /*
-	2005.1 yhlu add NC support to spare mtrrs for 64G memory stored
+        2005.1 yhlu add NC support to spare mtrrs for 64G memory above installed
+	2005.6 Eric add address bit in x86_setup_mtrrs
+	2005.6 yhlu split x86_setup_var_mtrrs and x86_setup_fixed_mtrrs,
+		for AMD, it will not use x86_setup_fixed_mtrrs
 */
+
 #include <stddef.h>
 #include <console/console.h>
 #include <device/device.h>
@@ -32,19 +37,6 @@
 #include <cpu/x86/mtrr.h>
 #include <cpu/x86/cache.h>
 
-#warning "FIXME I do not properly handle address more than 36 physical address bits"
-
-//#define k8 0
-#define k8 1
-
-#if k8
-# define ADDRESS_BITS 40
-#else
-# define ADDRESS_BITS 36
-#endif
-#define ADDRESS_BITS_HIGH (ADDRESS_BITS - 32)
-#define ADDRESS_MASK_HIGH ((1u << ADDRESS_BITS_HIGH) - 1)
-
 static unsigned int mtrr_msr[] = {
 	MTRRfix64K_00000_MSR, MTRRfix16K_80000_MSR, MTRRfix16K_A0000_MSR,
 	MTRRfix4K_C0000_MSR, MTRRfix4K_C8000_MSR, MTRRfix4K_D0000_MSR, MTRRfix4K_D8000_MSR,
@@ -52,7 +44,7 @@
 };
 
 
-static void enable_fixed_mtrr(void)
+void enable_fixed_mtrr(void)
 {
 	msr_t msr;
 
@@ -71,21 +63,26 @@
 }
 
 /* setting variable mtrr, comes from linux kernel source */
-static void set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
+static void set_var_mtrr(
+	unsigned int reg, unsigned long basek, unsigned long sizek, 
+	unsigned char type, unsigned address_bits)
 {
 	msr_t base, mask;
+	unsigned address_mask_high;
+
+	address_mask_high = ((1u << (address_bits - 32u)) - 1u);
 
 	base.hi = basek >> 22;
 	base.lo  = basek << 10;
 
-       //printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
+	printk_spew("ADDRESS_MASK_HIGH=%#x\n", address_mask_high);
 
 	if (sizek < 4*1024*1024) {
-		mask.hi = ADDRESS_MASK_HIGH;
+		mask.hi = address_mask_high;
 		mask.lo = ~((sizek << 10) -1);
 	}
 	else {
-		mask.hi = ADDRESS_MASK_HIGH & (~((sizek >> 22) -1));
+		mask.hi = address_mask_high & (~((sizek >> 22) -1));
 		mask.lo = 0;
 	}
 
@@ -219,7 +216,7 @@
 
 static unsigned int range_to_mtrr(unsigned int reg, 
 	unsigned long range_startk, unsigned long range_sizek,
-	unsigned long next_range_startk, unsigned char type)
+	unsigned long next_range_startk, unsigned char type, unsigned address_bits)
 {
 	if (!range_sizek || (reg >= BIOS_MTRRS)) {
 		return reg;
@@ -235,11 +232,11 @@
 		}
 		sizek = 1 << align;
 		printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type %s\n",
-			reg, range_startk >>10, sizek >> 10, 
-			(type==MTRR_TYPE_UNCACHEABLE) ? "NC" :
-			    ((type==MTRR_TYPE_WRBACK) ? "WB" : "Other")
+			reg, range_startk >>10, sizek >> 10,
+			(type==MTRR_TYPE_UNCACHEABLE)?"UC":
+			    ((type==MTRR_TYPE_WRBACK)?"WB":"Other")
 			);
-		set_var_mtrr(reg++, range_startk, sizek, type);
+		set_var_mtrr(reg++, range_startk, sizek, type, address_bits);
 		range_startk += sizek;
 		range_sizek -= sizek;
 		if (reg >= BIOS_MTRRS)
@@ -279,6 +276,7 @@
 	unsigned long range_startk, range_sizek;
 	unsigned int reg;
 	unsigned long hole_startk, hole_sizek;
+	unsigned address_bits;
 };
 
 void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res)
@@ -300,47 +298,68 @@
 	}
 	/* Write the range mtrrs */
 	if (state->range_sizek != 0) {
-		if(state->hole_sizek == 0) {
-			// we need to put that on to hole.
-	                unsigned long endk = basek + sizek;
+		if (state->hole_sizek == 0) {
+			/* We need to put that on to hole */
+			unsigned long endk = basek + sizek;
 			state->hole_startk = state->range_startk + state->range_sizek;
-			state->hole_sizek = basek - state->hole_startk;
-	                state->range_sizek = endk - state->range_startk;
+			state->hole_sizek  = basek - state->hole_startk;
+			state->range_sizek = endk - state->range_startk;
 			return;
 		}
-		state->reg = range_to_mtrr(state->reg, state->range_startk, state->range_sizek, basek, MTRR_TYPE_WRBACK);
-		state->reg = range_to_mtrr(state->reg, state->hole_startk, state->hole_sizek, basek, MTRR_TYPE_UNCACHEABLE);
+		state->reg = range_to_mtrr(state->reg, state->range_startk, 
+			state->range_sizek, basek, MTRR_TYPE_WRBACK, state->address_bits);
+		state->reg = range_to_mtrr(state->reg, state->hole_startk, 
+			state->hole_sizek, basek,  MTRR_TYPE_UNCACHEABLE, state->address_bits);
 		state->range_startk = 0;
 		state->range_sizek = 0;
                 state->hole_startk = 0;
                 state->hole_sizek = 0;
 	}
-	/* Allocate an msr */
+	/* Allocate an msr */  
+	printk_spew(" Allocate an msr - basek = %d, sizek = %d,\n", basek, sizek);
 	state->range_startk = basek;
 	state->range_sizek  = sizek;
 }
 
-void x86_setup_mtrrs(void)
+void x86_setup_fixed_mtrrs(void)
+{
+        /* Try this the simple way of incrementally adding together
+         * mtrrs.  If this doesn't work out we can get smart again 
+         * and clear out the mtrrs.
+         */
+        struct var_mtrr_state var_state;
+
+        printk_debug("\n");
+        /* Initialized the fixed_mtrrs to uncached */
+        printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n",
+	        0, NUM_FIXED_RANGES);
+        set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
+
+        /* Now see which of the fixed mtrrs cover ram.
+                 */
+        search_global_resources(
+		IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
+		set_fixed_mtrr_resource, NULL);
+        printk_debug("DONE fixed MTRRs\n");
+
+        /* enable fixed MTRR */
+        printk_spew("call enable_fixed_mtrr()\n");
+        enable_fixed_mtrr();
+
+}
+void x86_setup_var_mtrrs(unsigned address_bits)
+/* this routine needs to know how many address bits a given processor
+ * supports.  CPUs get grumpy when you set too many bits in 
+ * their mtrr registers :(  I would generically call cpuid here
+ * and find out how many physically supported but some cpus are
+ * buggy, and report more bits then they actually support.
+ */
 {
 	/* Try this the simple way of incrementally adding together
 	 * mtrrs.  If this doesn't work out we can get smart again 
 	 * and clear out the mtrrs.
 	 */
 	struct var_mtrr_state var_state;
-#if !k8
-	printk_debug("\n");
-	/* Initialized the fixed_mtrrs to uncached */
-	printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n", 
-		0, NUM_FIXED_RANGES);
-	set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
-
-	/* Now see which of the fixed mtrrs cover ram.
-	 */
-	search_global_resources(
-		IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
-		set_fixed_mtrr_resource, NULL);
-	printk_debug("DONE fixed MTRRs\n");
-#endif
 
 	/* Cache as many memory areas as possible */
 	/* FIXME is there an algorithm for computing the optimal set of mtrrs? 
@@ -351,28 +370,35 @@
 	var_state.hole_startk = 0;
 	var_state.hole_sizek = 0;
 	var_state.reg = 0;
+	var_state.address_bits = address_bits;
 	search_global_resources(
 		IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
 		set_var_mtrr_resource, &var_state);
 
 	/* Write the last range */
-	var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk, var_state.range_sizek, 0, MTRR_TYPE_WRBACK);
-	var_state.reg = range_to_mtrr(var_state.reg, var_state.hole_startk, var_state.hole_sizek, 0, MTRR_TYPE_UNCACHEABLE);
+	var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk, 
+		var_state.range_sizek, 0, MTRR_TYPE_WRBACK, var_state.address_bits);
+	var_state.reg = range_to_mtrr(var_state.reg, var_state.hole_startk,
+		var_state.hole_sizek,  0, MTRR_TYPE_UNCACHEABLE, var_state.address_bits);
 	printk_debug("DONE variable MTRRs\n");
 	printk_debug("Clear out the extra MTRR's\n");
 	/* Clear out the extra MTRR's */
 	while(var_state.reg < MTRRS) {
-		set_var_mtrr(var_state.reg++, 0, 0, 0);
+		set_var_mtrr(var_state.reg++, 0, 0, 0, var_state.address_bits);
 	}
-	/* enable fixed MTRR */
-	printk_spew("call enable_fixed_mtrr()\n");
-	enable_fixed_mtrr();
 	printk_spew("call enable_var_mtrr()\n");
 	enable_var_mtrr();
 	printk_spew("Leave %s\n", __FUNCTION__);
 	post_code(0x6A);
 }
 
+void x86_setup_mtrrs(unsigned address_bits)
+{
+	x86_setup_fixed_mtrrs();
+	x86_setup_var_mtrrs(address_bits);
+}
+
+
 int x86_mtrr_check(void)
 {
 	/* Only Pentium Pro and later have MTRR */
diff --git a/src/devices/Config.lb b/src/devices/Config.lb
index 8de8d4a..6ba7472 100644
--- a/src/devices/Config.lb
+++ b/src/devices/Config.lb
@@ -3,8 +3,12 @@
 object root_device.o
 object device_util.o
 object pci_device.o
-object pnp_device.o
 object hypertransport.o
+object pcix_device.o
+object pciexp_device.o
+object agp_device.o
+object cardbus_device.o
+object pnp_device.o
 object pci_ops.o
 object smbus_ops.o
 
diff --git a/src/devices/agp_device.c b/src/devices/agp_device.c
new file mode 100644
index 0000000..27ae36e
--- /dev/null
+++ b/src/devices/agp_device.c
@@ -0,0 +1,54 @@
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/agp.h>
+
+static void agp_tune_dev(device_t dev)
+{
+	unsigned cap;
+	cap = pci_find_capability(dev, PCI_CAP_ID_AGP);
+	if (!cap) {
+		return;
+	}
+	/* The OS is responsible for AGP tuning so do nothing here */
+}
+
+unsigned int agp_scan_bus(struct bus *bus,
+	unsigned min_devfn, unsigned max_devfn, unsigned int max)
+{
+	device_t child;
+	max = pci_scan_bus(bus, min_devfn, max_devfn, max);
+	for(child = bus->children; child; child = child->sibling) {
+		if (	(child->path.u.pci.devfn < min_devfn) ||
+			(child->path.u.pci.devfn > max_devfn))
+		{
+			continue;
+		}
+		agp_tune_dev(child);
+	}
+	return max;
+}
+
+unsigned int agp_scan_bridge(device_t dev, unsigned int max)
+{
+	return do_pci_scan_bridge(dev, max, agp_scan_bus);
+}
+
+/** Default device operations for AGP bridges */
+static struct pci_operations agp_bus_ops_pci = {
+	.set_subsystem = 0,
+};
+
+struct device_operations default_agp_ops_bus = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init		  = 0,
+	.scan_bus	  = agp_scan_bridge,
+	.enable           = 0,
+	.reset_bus        = pci_bus_reset,
+	.ops_pci          = &agp_bus_ops_pci,
+};
diff --git a/src/devices/device.c b/src/devices/device.c
index d2c435f..303a669 100644
--- a/src/devices/device.c
+++ b/src/devices/device.c
@@ -58,7 +58,7 @@
 	spin_lock(&dev_lock);	
 
 	/* Find the last child of our parent */
-	for (child = parent->children; child && child->sibling; ) {
+	for(child = parent->children; child && child->sibling; ) {
 		child = child->sibling;
 	}
 
@@ -70,7 +70,7 @@
 	memcpy(&dev->path, path, sizeof(*path));
 
 	/* Initialize the back pointers in the link fields */
-	for (link = 0; link < MAX_LINKS; link++) {
+	for(link = 0; link < MAX_LINKS; link++) {
 		dev->link[link].dev  = dev;
 		dev->link[link].link = link;
 	}
@@ -119,10 +119,10 @@
 	struct device *curdev;
 
 	printk_spew("%s read_resources bus %d link: %d\n",
-		    dev_path(bus->dev), bus->secondary, bus->link);
+		dev_path(bus->dev), bus->secondary, bus->link);
 
 	/* Walk through all of the devices and find which resources they need. */
-	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
+	for(curdev = bus->children; curdev; curdev = curdev->sibling) {
 		unsigned links;
 		int i;
 		if (curdev->have_resources) {
@@ -140,7 +140,7 @@
 		curdev->have_resources = 1;
 		/* Read in subtractive resources behind the current device */
 		links = 0;
-		for (i = 0; i < curdev->resources; i++) {
+		for(i = 0; i < curdev->resources; i++) {
 			struct resource *resource;
 			unsigned link;
 			resource = &curdev->resource[i];
@@ -149,18 +149,17 @@
 			link = IOINDEX_SUBTRACTIVE_LINK(resource->index);
 			if (link > MAX_LINKS) {
 				printk_err("%s subtractive index on link: %d\n",
-					   dev_path(curdev), link);
+					dev_path(curdev), link);
 				continue;
 			}
 			if (!(links & (1 << link))) {
 				links |= (1 << link);
-				read_resources(&curdev->link[resource->index]);
-				
+				read_resources(&curdev->link[link]);
 			}
 		}
 	}
 	printk_spew("%s read_resources bus %d link: %d done\n",
-		    dev_path(bus->dev), bus->secondary, bus->link);
+		dev_path(bus->dev), bus->secondary, bus->link);
 }
 
 struct pick_largest_state {
@@ -181,6 +180,7 @@
 		state->seen_last = 1;
 		return;
 	}
+	if (resource->flags & IORESOURCE_FIXED ) return; //skip it 
 	if (last && (
 		    (last->align < resource->align) ||
 		    ((last->align == resource->align) &&
@@ -191,9 +191,10 @@
 		return;
 	}
 	if (!state->result || 
-	    (state->result->align < resource->align) ||
-	    ((state->result->align == resource->align) &&
-	     (state->result->size < resource->size))) {
+		(state->result->align < resource->align) ||
+		((state->result->align == resource->align) &&
+			(state->result->size < resource->size)))
+	{
 		state->result_dev = dev;
 		state->result = resource;
 	}    
@@ -258,10 +259,10 @@
 	base = bridge->base;
 
 	printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d\n", 
-		    dev_path(bus->dev),
-		    (bridge->flags & IORESOURCE_IO)? "io":
-		    (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
-		    base, bridge->size, bridge->align, bridge->gran);
+		dev_path(bus->dev),
+		(bridge->flags & IORESOURCE_IO)? "io":
+		(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
+		base, bridge->size, bridge->align, bridge->gran);
 
 	/* We want different minimum alignments for different kinds of
 	 * resources.  These minimums are not device type specific
@@ -283,7 +284,7 @@
 	/* Walk through all the devices on the current bus and 
 	 * compute the addresses.
 	 */
-	while ((dev = largest_resource(bus, &resource, type_mask, type))) {
+	while((dev = largest_resource(bus, &resource, type_mask, type))) {
 		resource_t size;
 		/* Do NOT I repeat do not ignore resources which have zero size.
 		 * If they need to be ignored dev->read_resources should not even
@@ -301,9 +302,11 @@
 		if (align < min_align) {
 			align = min_align;
 		}
+
 		if (resource->flags & IORESOURCE_FIXED) {
 			continue;
 		}
+
 		/* Propogate the resource limit to the bridge register */
 		if (bridge->limit > resource->limit) {
 			bridge->limit = resource->limit;
@@ -338,13 +341,14 @@
 			resource->flags &= ~IORESOURCE_STORED;
 			base += size;
 			
-			printk_spew("%s %02x *  [0x%08Lx - 0x%08Lx] %s\n",
-				    dev_path(dev),
-				    resource->index, 
-				    resource->base, 
-				    resource->base + resource->size - 1,
-				    (resource->flags & IORESOURCE_IO)? "io":
-				    (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
+			printk_spew(
+				"%s %02x *  [0x%08Lx - 0x%08Lx] %s\n",
+				dev_path(dev),
+				resource->index, 
+				resource->base, 
+				resource->base + resource->size - 1,
+				(resource->flags & IORESOURCE_IO)? "io":
+				(resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
 		}
 	}
 	/* A pci bridge resource does not need to be a power
@@ -356,15 +360,16 @@
 	bridge->size = round(base, bridge->gran) - bridge->base;
 
 	printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d done\n", 
-		     dev_path(bus->dev),
-		     (bridge->flags & IORESOURCE_IO)? "io":
-		     (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
-		     base, bridge->size, bridge->align, bridge->gran);
+		dev_path(bus->dev),
+		(bridge->flags & IORESOURCE_IO)? "io":
+		(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
+		base, bridge->size, bridge->align, bridge->gran);
 
 
 }
 
 #if CONFIG_CONSOLE_VGA == 1
+
 device_t vga_pri = 0;
 static void allocate_vga_resource(void)
 {
@@ -377,10 +382,11 @@
 	bus = 0;
 	vga = 0;
 	vga_onboard = 0;
-	for (dev = all_devices; dev; dev = dev->next) {
+	for(dev = all_devices; dev; dev = dev->next) {
 		if (!dev->enabled) continue;
 		if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
-		    ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) {
+			((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) 
+		{
 			if (!vga) {
 				if (dev->on_mainboard) {
 					vga_onboard = dev;
@@ -398,14 +404,15 @@
 	}
 	
 	if (vga) {
-		// vga is first add on card or the only onboard vga
+		/* vga is first add on card or the only onboard vga */
 		printk_debug("Allocating VGA resource %s\n", dev_path(vga));
+		/* All legacy VGA cards have MEM & I/O space registers */
 		vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
 		vga_pri = vga;
 		bus = vga->bus;
 	}
 	/* Now walk up the bridges setting the VGA enable */
-	while (bus) {
+	while(bus) {
 		printk_debug("Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
 			     dev_path(bus->dev));
 		bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
@@ -435,7 +442,7 @@
 	printk_spew("%s assign_resources, bus %d link: %d\n", 
 		dev_path(bus->dev), bus->secondary, bus->link);
 
-	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
+	for(curdev = bus->children; curdev; curdev = curdev->sibling) {
 		if (!curdev->enabled || !curdev->resources) {
 			continue;
 		}
@@ -480,6 +487,70 @@
 	dev->ops->enable_resources(dev);
 }
 
+/** 
+ * @brief Reset all of the devices a bus
+ *
+ * Reset all of the devices on a bus and clear the bus's reset_needed flag.
+ *
+ * @param bus pointer to the bus structure
+ *
+ * @return 1 if the bus was successfully reset, 0 otherwise.
+ *
+ */
+int reset_bus(struct bus *bus)
+{
+	device_t dev;
+	if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus)
+	{
+		bus->dev->ops->reset_bus(bus);
+		bus->reset_needed = 0;
+		return 1;
+	}
+	return 0;
+}
+
+/** 
+ * @brief Scan for devices on a bus.
+ *
+ * If there are bridges on the bus, recursively scan the buses behind the bridges.
+ * If the setting up and tuning of the bus causes a reset to be required, 
+ * reset the bus and scan it again.
+ *
+ * @param bus pointer to the bus device
+ * @param max current bus number
+ *
+ * @return The maximum bus number found, after scanning all subordinate busses
+ */
+unsigned int scan_bus(device_t bus, unsigned int max)
+{
+	unsigned int new_max;
+	int do_scan_bus;
+	if (	!bus ||
+		!bus->enabled ||
+		!bus->ops ||
+		!bus->ops->scan_bus)
+	{
+		return max;
+	}
+	do_scan_bus = 1;
+	while(do_scan_bus) {
+		int link;
+		new_max = bus->ops->scan_bus(bus, max);
+		do_scan_bus = 0;
+		for(link = 0; link < bus->links; link++) {
+			if (bus->link[link].reset_needed) {
+				if (reset_bus(&bus->link[link])) {
+					do_scan_bus = 1;
+				} else {
+					bus->bus->reset_needed = 1;
+				}
+			}
+		}
+	}
+	return new_max;
+}
+
+
 /**
  * @brief Determine the existence of devices and extend the device tree.
  *
@@ -515,7 +586,7 @@
 		printk_err("dev_root missing scan_bus operation");
 		return;
 	}
-	subordinate = root->ops->scan_bus(root, 0);
+	subordinate = scan_bus(root, 0);
 	printk_info("done\n");
 }
 
@@ -613,18 +684,19 @@
 	struct device *dev;
 
 	printk_info("Initializing devices...\n");
-
-        for (dev = all_devices; dev; dev = dev->next) {
-                if (dev->enabled && !dev->initialized &&
-                        dev->ops && dev->ops->init)
-                {
-			if(dev->path.type == DEVICE_PATH_I2C)
-				printk_debug("smbus: %s[%d]->",  dev_path(dev->bus->dev), dev->bus->link );
-                        printk_debug("%s init\n", dev_path(dev));
-                        dev->initialized = 1;
-                        dev->ops->init(dev);
-                }
-        }
+	for(dev = all_devices; dev; dev = dev->next) {
+		if (dev->enabled && !dev->initialized && 
+			dev->ops && dev->ops->init) 
+		{
+			if (dev->path.type == DEVICE_PATH_I2C) {
+ 				printk_debug("smbus: %s[%d]->",
+					dev_path(dev->bus->dev), dev->bus->link);
+			}
+			printk_debug("%s init\n", dev_path(dev));
+			dev->initialized = 1;
+			dev->ops->init(dev);
+		}
+	}
 	printk_info("Devices initialized\n");
 }
 
diff --git a/src/devices/device_util.c b/src/devices/device_util.c
index a19a878..fa2adae 100644
--- a/src/devices/device_util.c
+++ b/src/devices/device_util.c
@@ -16,7 +16,7 @@
 device_t find_dev_path(struct bus *parent, struct device_path *path)
 {
 	device_t child;
-	for (child = parent->children; child; child = child->sibling) {
+	for(child = parent->children; child; child = child->sibling) {
 		if (path_eq(path, &child->path)) {
 			break;
 		}
@@ -178,6 +178,14 @@
 	return buffer;
 }
 
+const char *bus_path(struct bus *bus)
+{
+	static char buffer[BUS_PATH_MAX];
+	sprintf(buffer, "%s,%d",
+		dev_path(bus->dev), bus->link);
+	return buffer;
+}
+
 int path_eq(struct device_path *path1, struct device_path *path2)
 {
 	int equal = 0;
@@ -390,12 +398,30 @@
 }
 
 /**
+ * @brief return the resource type of a resource
+ * @param resource the resource type to decode.
+ */
+const char *resource_type(struct resource *resource)
+{
+	static char buffer[RESOURCE_TYPE_MAX];
+	sprintf(buffer, "%s%s%s%s",
+		((resource->flags & IORESOURCE_READONLY)? "ro": ""),
+		((resource->flags & IORESOURCE_PREFETCH)? "pref":""),
+		((resource->flags == 0)? "unused":
+	 	(resource->flags & IORESOURCE_IO)? "io":
+		(resource->flags & IORESOURCE_DRQ)? "drq":
+		(resource->flags & IORESOURCE_IRQ)? "irq":
+		(resource->flags & IORESOURCE_MEM)? "mem":"??????"),
+		((resource->flags & IORESOURCE_PCI64)?"64":""));
+	return buffer;
+}
+
+/**
  * @brief print the resource that was just stored.
  * @param dev the device the stored resorce lives on
  * @param resource the resource that was just stored.
  */
-void report_resource_stored(device_t dev, struct resource *resource,
-			    const char *comment)
+void report_resource_stored(device_t dev, struct resource *resource, const char *comment)
 {
 	if (resource->flags & IORESOURCE_STORED) {
 		unsigned char buf[10];
@@ -407,18 +433,12 @@
 			sprintf(buf, "bus %d ", dev->link[0].secondary);
 		}
 		printk_debug(
-			"%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s%s\n",
+			"%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s\n",
 			dev_path(dev),
 			resource->index,
 			base, end,
 			buf,
-			(resource->flags & IORESOURCE_PREFETCH) ? "pref" : "",
-			(resource->flags & IORESOURCE_IO)? "io":
-			(resource->flags & IORESOURCE_DRQ)? "drq":
-			(resource->flags & IORESOURCE_IRQ)? "irq":
-			(resource->flags & IORESOURCE_READONLY)? "rom":
-			(resource->flags & IORESOURCE_MEM)? "mem":
-			"????",
+			resource_type(resource),
 			comment);
 	}
 }
@@ -473,3 +493,29 @@
 		}
 	}
 }
+
+void dev_set_enabled(device_t dev, int enable)
+{
+	if (dev->enabled == enable) {
+		return;
+	}
+	dev->enabled = enable;
+	if (dev->ops && dev->ops->enable) {
+		dev->ops->enable(dev);
+	}
+	else if (dev->chip_ops && dev->chip_ops->enable_dev) {
+		dev->chip_ops->enable_dev(dev);
+	}
+}
+
+void disable_children(struct bus *bus)
+{
+	device_t child;
+	for(child = bus->children; child; child = child->sibling) {
+		int link;
+		for(link = 0; link < child->links; link++) {
+			disable_children(&child->link[link]);
+		}
+		dev_set_enabled(child, 0);
+	}
+}
diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c
index 80c621e..a30c8f6 100644
--- a/src/devices/hypertransport.c
+++ b/src/devices/hypertransport.c
@@ -9,7 +9,7 @@
 #include <part/fallback_boot.h>
 
 #define OPT_HT_LINK 0
-
+        
 #if OPT_HT_LINK == 1
 #include "../northbridge/amd/amdk8/cpu_rev.c"
 #endif
@@ -19,17 +19,37 @@
 	device_t first, last;
 	first = *old_devices;
 	last = first;
+	/* Extract the chain of devices to (first through last)
+	 * for the next hypertransport device.
+	 */
 	while(last && last->sibling && 
 		(last->sibling->path.type == DEVICE_PATH_PCI) &&
-		(last->sibling->path.u.pci.devfn > last->path.u.pci.devfn)) {
+		(last->sibling->path.u.pci.devfn > last->path.u.pci.devfn)) 
+	{
 		last = last->sibling;
 	}
 	if (first) {
+		device_t child;
+		/* Unlink the chain from the list of old devices */
 		*old_devices = last->sibling;
 		last->sibling = 0;
+
+		/* Now add the device to the list of devices on the bus.
+		 */
+		/* Find the last child of our parent */
+		for(child = first->bus->children; child && child->sibling; ) {
+			child = child->sibling;
+		}
+		/* Place the chain on the list of children of their parent. */
+		if (child) {
+			child->sibling = first;
+		} else {
+			first->bus->children = first;
+		}
 	}
 	return first;
 }
+
 #if OPT_HT_LINK == 1
 static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
 {
@@ -43,30 +63,37 @@
 	if ((dev->vendor == PCI_VENDOR_ID_AMD) &&
 		(dev->device == PCI_DEVICE_ID_AMD_8131_PCIX)) {
 		freq_cap &= ~(1 << HT_FREQ_800Mhz);
-	} else
+	}
 	/* AMD 8151 Errata 23 */
 	if ((dev->vendor == PCI_VENDOR_ID_AMD) &&
 		(dev->device == PCI_DEVICE_ID_AMD_8151_SYSCTRL)) {
 		freq_cap &= ~(1 << HT_FREQ_800Mhz);
-	} else
+	}
 	/* AMD K8 Unsupported 1Ghz? */
 	if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) {
+#if K8_HT_FREQ_1G_SUPPORT == 1  
 		if (is_cpu_pre_e0()) 
+#endif
+		{
 			freq_cap &= ~(1 << HT_FREQ_1000Mhz);
+		}
+
 	}
 	return freq_cap;
 }
+#endif
 
-struct prev_link {
+struct ht_link {
 	struct device *dev;
 	unsigned pos;
-	unsigned char config_off, freq_off, freq_cap_off;
+	unsigned char ctrl_off, config_off, freq_off, freq_cap_off;
 };
 
-static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
+static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos)
 {
 	static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
 	static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
+	struct ht_link cur[1];
 	unsigned present_width_cap,    upstream_width_cap;
 	unsigned present_freq_cap,     upstream_freq_cap;
 	unsigned ln_present_width_in,  ln_upstream_width_in; 
@@ -78,13 +105,30 @@
 
 	/* Set the hypertransport link width and frequency */
 	reset_needed = 0;
-	linkb_to_host = (pci_read_config16(dev, pos + PCI_CAP_FLAGS) >> 10) & 1;
-
+	/* See which side of the device our previous write to 
+	 * set the unitid came from.
+	 */
+	cur->dev = dev;
+	cur->pos = pos;
+	linkb_to_host = (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1;
+	if (!linkb_to_host) {
+		cur->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL0;
+		cur->config_off   = PCI_HT_CAP_SLAVE_WIDTH0;
+		cur->freq_off     = PCI_HT_CAP_SLAVE_FREQ0;
+		cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
+	}
+	else {
+		cur->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL1;
+		cur->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
+		cur->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
+		cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
+	}
+#if OPT_HT_LINK == 1
 	/* Read the capabilities */
-	present_freq_cap   = ht_read_freq_cap(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ_CAP1: PCI_HT_CAP_SLAVE_FREQ_CAP0));
+	present_freq_cap   = ht_read_freq_cap(cur->dev, cur->pos + cur->freq_cap_off);
 	upstream_freq_cap  = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off);
-	present_width_cap  = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0));
-        upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
+	present_width_cap  = pci_read_config8(cur->dev, cur->pos + cur->config_off);
+	upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
 	
 	/* Calculate the highest useable frequency */
 	freq = log2(present_freq_cap & upstream_freq_cap);
@@ -107,87 +151,130 @@
 	present_width  |= pow2_to_link_width[ln_upstream_width_out];
 
 	/* Set the current device */
-	old_freq = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0));
+	old_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off);
+	old_freq &= 0x0f;
 	if (freq != old_freq) {
-		pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0), freq);
+		unsigned new_freq;
+		pci_write_config8(cur->dev, cur->pos + cur->freq_off, freq);
 		reset_needed = 1;
 		printk_spew("HyperT FreqP old %x new %x\n",old_freq,freq);
+		new_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off);
+		new_freq &= 0x0f;
+		if (new_freq != freq) {
+			printk_err("%s Hypertransport frequency would not set wanted: %x got: %x\n",
+				dev_path(dev), freq, new_freq);
+		}
 	}
-	old_width = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1);
+	old_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1);
 	if (present_width != old_width) {
-		pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1, present_width);
+		unsigned new_width;
+		pci_write_config8(cur->dev, cur->pos + cur->config_off + 1,
+			present_width);
 		reset_needed = 1;
 		printk_spew("HyperT widthP old %x new %x\n",old_width, present_width);
+		new_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1);
+		if (new_width != present_width) {
+			printk_err("%s Hypertransport width would not set wanted: %x got: %x\n",
+				dev_path(dev), present_width, new_width);
+		}
 	}
 
 	/* Set the upstream device */
 	old_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off);
 	old_freq &= 0x0f;
 	if (freq != old_freq) {
+		unsigned new_freq;
 		pci_write_config8(prev->dev, prev->pos + prev->freq_off, freq);
 		reset_needed = 1;
 		printk_spew("HyperT freqU old %x new %x\n", old_freq, freq);
+		new_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off);
+		new_freq &= 0x0f;
+		if (new_freq != freq) {
+			printk_err("%s Hypertransport frequency would not set wanted: %x got: %x\n",
+				dev_path(prev->dev), freq, new_freq);
+		}
 	}
 	old_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1);
 	if (upstream_width != old_width) {
+		unsigned new_width;
 		pci_write_config8(prev->dev, prev->pos + prev->config_off + 1, upstream_width);
 		reset_needed = 1;
 		printk_spew("HyperT widthU old %x new %x\n", old_width, upstream_width);
+		new_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1);
+		if (new_width != upstream_width) {
+			printk_err("%s Hypertransport width would not set wanted: %x got: %x\n",
+				dev_path(prev->dev), upstream_width, new_width);
+		}
 	}
+#endif
 	
-	/* Remember the current link as the previous link */
-	prev->dev = dev;
-	prev->pos = pos;
-        if(linkb_to_host) {
-	        prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH0;
-	        prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ0;
-	        prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
-        }
-        else {
-	        prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
-	        prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
-        	prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
-        }
+	/* Remember the current link as the previous link,
+	 * But look at the other offsets.
+	 */
+	prev->dev = cur->dev;
+	prev->pos = cur->pos;
+	if (cur->ctrl_off == PCI_HT_CAP_SLAVE_CTRL0) {
+		prev->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL1;
+		prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
+		prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
+		prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
+	} else {
+		prev->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL0;
+		prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH0;
+		prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ0;
+		prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
+	}
 
 	return reset_needed;
 		
 }
-#endif
 
 static unsigned ht_lookup_slave_capability(struct device *dev)
 {
 	unsigned pos;
 	pos = 0;
-	switch(dev->hdr_type & 0x7f) {
-	case PCI_HEADER_TYPE_NORMAL:
-	case PCI_HEADER_TYPE_BRIDGE:
-		pos = PCI_CAPABILITY_LIST;
-		break;
-	}
-	if (pos > PCI_CAP_LIST_NEXT) {
-		pos = pci_read_config8(dev, pos);
-	}
-	while(pos != 0) {   /* loop through the linked list */
-		uint8_t cap;
-		cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
-		printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
-		if (cap == PCI_CAP_ID_HT) {
+	do {
+		pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos);
+		if (pos) {
 			unsigned flags;
 			flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
-			printk_spew("flags: 0x%04x\n", (unsigned)flags);
+			printk_spew("flags: 0x%04x\n", flags);
 			if ((flags >> 13) == 0) {
-				/* Entry is a Slave secondary, success...*/
+				/* Entry is a Slave secondary, success... */
 				break;
 			}
 		}
-		pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
-	}
+	} while(pos);
 	return pos;
 }
 
 static void ht_collapse_early_enumeration(struct bus *bus)
 {
 	unsigned int devfn;
+	struct ht_link prev;
+	unsigned ctrl;
+
+	/* Initialize the hypertransport enumeration state */
+	prev.dev = bus->dev;
+	prev.pos = bus->cap;
+	prev.ctrl_off     = PCI_HT_CAP_HOST_CTRL;
+	prev.config_off   = PCI_HT_CAP_HOST_WIDTH;
+	prev.freq_off     = PCI_HT_CAP_HOST_FREQ;
+	prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
+
+	/* Wait until the link initialization is complete */
+	do {
+		ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off);
+		/* Is this the end of the hypertransport chain */
+		if (ctrl & (1 << 6)) {
+			return;
+		}
+		/* Has the link failed? */
+		if (ctrl & (1 << 4)) {
+			return;
+		}
+	} while((ctrl & (1 << 5)) == 0);
+
 
 	/* Spin through the devices and collapse any early
 	 * hypertransport enumeration.
@@ -200,21 +287,10 @@
 		dummy.path.type        = DEVICE_PATH_PCI;
 		dummy.path.u.pci.devfn = devfn;
 		id = pci_read_config32(&dummy, PCI_VENDOR_ID);
-		if (id == 0xffffffff || id == 0x00000000 || 
-			id == 0x0000ffff || id == 0xffff0000) {
+		if (	(id == 0xffffffff) || (id == 0x00000000) || 
+			(id == 0x0000ffff) || (id == 0xffff0000)) {
 			continue;
 		}
-
-#if 0
-#if CK804_DEVN_BASE==0		
-                //CK804 workaround: 
-                // CK804 UnitID changes not use
-                if(id == 0x005e10de) {
-                        break;
-                }
-#endif
-#endif
-
 		dummy.vendor = id & 0xffff;
 		dummy.device = (id >> 16) & 0xffff;
 		dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE);
@@ -232,15 +308,13 @@
 	}
 }
 
-unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
+unsigned int hypertransport_scan_chain(struct bus *bus, 
+	unsigned min_devfn, unsigned max_devfn, unsigned int max)
 {
-	unsigned next_unitid, last_unitid, previous_unitid;
-	device_t old_devices, dev, func, *chain_last;
+	unsigned next_unitid, last_unitid;
+	device_t old_devices, dev, func;
 	unsigned min_unitid = 1;
-#if OPT_HT_LINK == 1
-	int reset_needed;
-	struct prev_link prev;
-#endif
+	struct ht_link prev;
 
 	/* Restore the hypertransport chain to it's unitialized state */
 	ht_collapse_early_enumeration(bus);
@@ -248,71 +322,48 @@
 	/* See which static device nodes I have */
 	old_devices = bus->children;
 	bus->children = 0;
-	chain_last = &bus->children;
 
 	/* Initialize the hypertransport enumeration state */
-#if OPT_HT_LINK == 1
-	reset_needed = 0;
 	prev.dev = bus->dev;
 	prev.pos = bus->cap;
+	prev.ctrl_off     = PCI_HT_CAP_HOST_CTRL;
 	prev.config_off   = PCI_HT_CAP_HOST_WIDTH;
 	prev.freq_off     = PCI_HT_CAP_HOST_FREQ;
 	prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
-#endif
 	
 	/* If present assign unitid to a hypertransport chain */
 	last_unitid = min_unitid -1;
 	next_unitid = min_unitid;
 	do {
-		uint32_t id, class;
-		uint8_t hdr_type;
-		unsigned pos;
+		uint8_t pos;
 		uint16_t flags;
 		unsigned count, static_count;
+		unsigned ctrl;
 
-		previous_unitid = last_unitid;
 		last_unitid = next_unitid;
 
-		/* Get setup the device_structure */
+		/* Wait until the link initialization is complete */
+		do {
+			ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off);
+			/* Is this the end of the hypertransport chain?
+			 * Has the link failed?
+			 * If so further scanning is pointless.
+			 */
+			if (ctrl & ((1 << 6) | (1 << 4))) {
+				goto end_of_chain;
+			}
+		} while((ctrl & (1 << 5)) == 0);
+		
+
+		/* Get and setup the device_structure */
 		dev = ht_scan_get_devs(&old_devices);
 
-		if (!dev) {
-			struct device dummy;
-			dummy.bus              = bus;
-			dummy.path.type        = DEVICE_PATH_PCI;
-			dummy.path.u.pci.devfn = 0;
-			id = pci_read_config32(&dummy, PCI_VENDOR_ID);
-			/* If the chain is fully enumerated quit */
-			if (id == 0xffffffff || id == 0x00000000 ||
-				id == 0x0000ffff || id == 0xffff0000) {
-				break;
-			}
-			dev = alloc_dev(bus, &dummy.path);
-		}
-		else {
-			/* Add this device to the pci bus chain */
-			*chain_last = dev;
-			/* Run the magice enable sequence for the device */
-			if (dev->chip_ops && dev->chip_ops->enable_dev) {
-				dev->chip_ops->enable_dev(dev);
-			}
-			/* Now read the vendor and device id */
-			id = pci_read_config32(dev, PCI_VENDOR_ID);
-
-			/* If the chain is fully enumerated quit */
-			if (id == 0xffffffff || id == 0x00000000 ||
-				id == 0x0000ffff || id == 0xffff0000) {
-	                               if (dev->enabled) {
-        	                               printk_info("Disabling static device: %s\n",
-                	                               dev_path(dev));
-                        	               dev->enabled = 0;
-                               	}
-				break;
-			}
-		}
-		/* Update the device chain tail */
-		for(func = dev; func; func = func->sibling) {
-			chain_last = &func->sibling;
+		/* See if a device is present and setup the
+		 * device structure.
+		 */
+		dev = pci_probe_dev(dev, bus, 0);
+		if (!dev || !dev->enabled) {
+			break;
 		}
 
 		/* Find the hypertransport link capability */
@@ -323,20 +374,29 @@
 			break;
 		}
 		
-
 		/* Update the Unitid of the current device */
 		flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
+        
+		/* If the devices has a unitid set and is at devfn 0 we are done. 
+		 * This can happen with shadow hypertransport devices,
+		 * or if we have reached the bottom of a
+		 * hypertransport device chain.
+		 */
+		if (flags & 0x1f) {
+			break;
+		}
+
 		flags &= ~0x1f; /* mask out base Unit ID */
 #if CK804_DEVN_BASE==0  
-	        if(id == 0x005e10de) {
-			next_unitid = 0;
-		} 
-		else {
+               if((dev->vendor == 0x10de) && (dev->device == 0x005e)) {
+                       next_unitid = 0;
+               } 
+               else {
 #endif
-			flags |= next_unitid & 0x1f;
-			pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
+                       flags |= next_unitid & 0x1f;
+                       pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
 #if CK804_DEVN_BASE==0 
-		}
+               }
 #endif
 
 		/* Update the Unitd id in the device structure */
@@ -347,17 +407,6 @@
 				- (dev->path.u.pci.devfn >> 3) + 1;
 		}
 
-                /* Read the rest of the pci configuration information */
-                hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
-                class = pci_read_config32(dev, PCI_CLASS_REVISION);
-
-                /* Store the interesting information in the device structure */
-                dev->vendor = id & 0xffff;
-                dev->device = (id >> 16) & 0xffff;
-                dev->hdr_type = hdr_type;
-                /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
-                dev->class = class >> 8;
-
 		/* Compute the number of unitids consumed */
 		count = (flags >> 5) & 0x1f; /* get unit count */
 		printk_spew("%s count: %04x static_count: %04x\n", 
@@ -369,36 +418,83 @@
 		/* Update the Unitid of the next device */
 		next_unitid += count;
 
-#if OPT_HT_LINK == 1
 		/* Setup the hypetransport link */
-		reset_needed |= ht_setup_link(&prev, dev, pos);
-#endif
+		bus->reset_needed |= ht_setup_link(&prev, dev, pos);
 
 		printk_debug("%s [%04x/%04x] %s next_unitid: %04x\n",
 			dev_path(dev),
 			dev->vendor, dev->device, 
 			(dev->enabled? "enabled": "disabled"), next_unitid);
+
 #if CK804_DEVN_BASE==0 
-	 	if(id == 0x005e10de) {
-			break; // CK804 can not change unitid, so it only can be alone in the link
-		}
+		if ((dev->vendor == 0x10de) && (dev->device == 0x005e)) {
+                      break; // CK804 can not change unitid, so it only can be alone in the link
+                }
 #endif
 
-	} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
-
+	} while((last_unitid != next_unitid) && (next_unitid <= (max_devfn >> 3)));
+ end_of_chain:
 #if OPT_HT_LINK == 1
-#if HAVE_HARD_RESET == 1
-	if(reset_needed) {
+	if(bus->reset_needed) {
 		printk_info("HyperT reset needed\n");
-		hard_reset();
 	}
 	else {
 		printk_debug("HyperT reset not needed\n");
 	}
 #endif
-#endif
 	if (next_unitid > 0x1f) {
 		next_unitid = 0x1f;
 	}
-	return pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max);
+
+	/* Die if any leftover Static devices are are found.  
+	 * There's probably a problem in the Config.lb.
+	 */
+	if(old_devices) {
+		device_t left;
+		for(left = old_devices; left; left = left->sibling) {
+			printk_debug("%s\n", dev_path(left));
+		}
+		die("Left over static devices.  Check your Config.lb\n");
+	}
+	
+	/* Now that nothing is overlapping it is safe to scan the
+	 * children. 
+	 */
+	max = pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max);
+	return max; 
 }
+
+/**
+ * @brief Scan a PCI bridge and the buses behind the bridge.
+ *
+ * Determine the existence of buses behind the bridge. Set up the bridge
+ * according to the result of the scan.
+ *
+ * This function is the default scan_bus() method for PCI bridge devices.
+ *
+ * @param dev pointer to the bridge device
+ * @param max the highest bus number assgined up to now
+ *
+ * @return The maximum bus number found, after scanning all subordinate busses
+ */
+unsigned int ht_scan_bridge(struct device *dev, unsigned int max)
+{
+	return do_pci_scan_bridge(dev, max, hypertransport_scan_chain);
+}
+
+
+/** Default device operations for hypertransport bridges */
+static struct pci_operations ht_bus_ops_pci = {
+	.set_subsystem = 0,
+};
+
+struct device_operations default_ht_ops_bus = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init		  = 0,
+	.scan_bus	  = ht_scan_bridge,
+	.enable           = 0,
+	.reset_bus        = pci_bus_reset,
+	.ops_pci          = &ht_bus_ops_pci,
+};
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index 3f9a1ca..f3f53f0 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -21,8 +21,23 @@
 #include <part/hard_reset.h>
 #include <part/fallback_boot.h>
 #include <delay.h>
+#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
+#include <device/hypertransport.h>
+#endif
+#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
+#include <device/pcix.h>
+#endif
+#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
+#include <device/pciexp.h>
+#endif
+#if CONFGI_AGP_PLUGIN_SUPPORT == 1
+#include <device/agp.h>
+#endif
+#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
+#include <device/cardbus.h>
+#endif
 
-static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
+uint8_t pci_moving_config8(struct device *dev, unsigned reg)
 {
 	uint8_t value, ones, zeroes;
 	value = pci_read_config8(dev, reg);
@@ -38,7 +53,7 @@
 	return ones ^ zeroes;
 }
 
-static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
+uint16_t pci_moving_config16(struct device *dev, unsigned reg)
 {
 	uint16_t value, ones, zeroes;
 	value = pci_read_config16(dev, reg);
@@ -54,7 +69,7 @@
 	return ones ^ zeroes;
 }
 
-static uint32_t pci_moving_config32(struct device *dev, unsigned reg)
+uint32_t pci_moving_config32(struct device *dev, unsigned reg)
 {
 	uint32_t value, ones, zeroes;
 	value = pci_read_config32(dev, reg);
@@ -70,29 +85,53 @@
 	return ones ^ zeroes;
 }
 
-unsigned pci_find_capability(device_t dev, unsigned cap)
+unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
 {
 	unsigned pos;
+	unsigned status;
+	unsigned reps = 48;
 	pos = 0;
+	status = pci_read_config16(dev, PCI_STATUS);
+	if (!(status & PCI_STATUS_CAP_LIST)) {
+		return 0;
+	}
 	switch(dev->hdr_type & 0x7f) {
 	case PCI_HEADER_TYPE_NORMAL:
 	case PCI_HEADER_TYPE_BRIDGE:
 		pos = PCI_CAPABILITY_LIST;
 		break;
+	case PCI_HEADER_TYPE_CARDBUS:
+		pos = PCI_CB_CAPABILITY_LIST;
+		break;
+	default:
+		return 0;
 	}
-	if (pos > PCI_CAP_LIST_NEXT) {
-		pos = pci_read_config8(dev, pos);
-	}
-	while (pos != 0) {   /* loop through the linked list */
+	pos = pci_read_config8(dev, pos);
+	while(reps-- && (pos >= 0x40)) {   /* loop through the linked list */
 		int this_cap;
+		pos &= ~3;
 		this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
-		if (this_cap == cap) {
+		printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
+		if (this_cap == 0xff) {
+			break;
+		}
+		if (!last && (this_cap == cap)) {
 			return pos;
 		}
+		if (last == pos) {
+			last = 0;
+		}
+		pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
 	}
 	return 0;
 }
 
+unsigned pci_find_capability(device_t dev, unsigned cap)
+{
+	return pci_find_next_capability(dev, cap, 0);
+
+}
+
 /** Given a device and register, read the size of the BAR for that register. 
  * @param dev       Pointer to the device structure
  * @param resource  Pointer to the resource structure
@@ -118,7 +157,7 @@
 
 	/* If it is a 64bit resource look at the high half as well */
 	if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
-	    ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
+		((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
 	{
 		/* Find the high bits that move */
 		moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32;
@@ -134,7 +173,7 @@
 	if (moving) {
 		resource->size = 1;
 		resource->align = resource->gran = 0;
-		while (!(moving & resource->size)) {
+		while(!(moving & resource->size)) {
 			resource->size <<= 1;
 			resource->align += 1;
 			resource->gran  += 1;
@@ -154,17 +193,20 @@
 	 */
 	if (moving == 0) {
 		if (value != 0) {
-			printk_debug("%s register %02x(%08x), read-only ignoring it\n",
-				     dev_path(dev), index, value);
+			printk_debug(
+				"%s register %02x(%08x), read-only ignoring it\n",
+				dev_path(dev), index, value);
 		}
 		resource->flags = 0;
-	} else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
+	}
+	else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
 		/* An I/O mapped base address */
 		attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
 		resource->flags |= IORESOURCE_IO;
 		/* I don't want to deal with 32bit I/O resources */
 		resource->limit = 0xffff;
-	} else {
+	} 
+	else {
 		/* A Memory mapped base address */
 		attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
 		resource->flags |= IORESOURCE_MEM;
@@ -175,14 +217,17 @@
 		if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
 			/* 32bit limit */
 			resource->limit = 0xffffffffUL;
-		} else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
+		}
+		else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
 			/* 1MB limit */
 			resource->limit = 0x000fffffUL;
-		} else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
+		}
+		else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
 			/* 64bit limit */
 			resource->limit = 0xffffffffffffffffULL;
 			resource->flags |= IORESOURCE_PCI64;
-		} else {
+		}
+		else {
 			/* Invalid value */
 			resource->flags = 0;
 		}
@@ -194,18 +239,15 @@
 #if 0
 	if (resource->flags) {
 		printk_debug("%s %02x ->",
-			     dev_path(dev), resource->index);
+			dev_path(dev), resource->index);
 		printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
-			     value, zeroes, ones, attr);
+			value, zeroes, ones, attr);
 		printk_debug(
-			"%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ",
+			"%s %02x -> size: 0x%08Lx max: 0x%08Lx %s\n ",
 			dev_path(dev),
 			resource->index,
 			resource->size,	resource->limit,
-			(resource->flags == 0) ? "unused":
-			(resource->flags & IORESOURCE_IO)? "io":
-			(resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem",
-			(resource->flags & IORESOURCE_PCI64)?"64":"");
+			resource_type(resource));
 	}
 #endif
 
@@ -272,32 +314,32 @@
 		resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY |
 			IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 	}  
+
+	compact_resources(dev);
 }
 
 /** Read the base address registers for a given device. 
  * @param dev Pointer to the dev structure
  * @param howmany How many registers to read (6 for device, 2 for bridge)
  */
-static void pci_read_bases(struct device *dev, unsigned int howmany, unsigned long rom)
+static void pci_read_bases(struct device *dev, unsigned int howmany)
 {
 	unsigned long index;
 
-	for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
+	for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
 		struct resource *resource;
 		resource = pci_get_resource(dev, index);
 		index += (resource->flags & IORESOURCE_PCI64)?8:4;
 	}
-	if (rom)
-		pci_get_rom_resource(dev, rom);
 
 	compact_resources(dev);
 }
 
 static void pci_set_resource(struct device *dev, struct resource *resource);
 
-static void pci_record_bridge_resource( struct device *dev, resource_t moving,
-					unsigned index, unsigned long mask,
-					unsigned long type)
+static void pci_record_bridge_resource(
+	struct device *dev, resource_t moving,
+	unsigned index, unsigned long mask, unsigned long type)
 {
 	/* Initiliaze the constraints on the current bus */
 	struct resource *resource;
@@ -346,8 +388,10 @@
 	moving = moving_base & moving_limit;
 
 	/* Initialize the io space constraints on the current bus */
-	pci_record_bridge_resource(dev, moving, PCI_IO_BASE,
-				   IORESOURCE_IO, IORESOURCE_IO);
+	pci_record_bridge_resource(
+		dev, moving, PCI_IO_BASE, 
+		IORESOURCE_IO, IORESOURCE_IO);
+
 
 	/* See if the bridge prefmem resources are implemented */
 	moving_base =  ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
@@ -358,9 +402,11 @@
 	
 	moving = moving_base & moving_limit;
 	/* Initiliaze the prefetchable memory constraints on the current bus */
-	pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE, 
-				   IORESOURCE_MEM | IORESOURCE_PREFETCH,
-				   IORESOURCE_MEM | IORESOURCE_PREFETCH);
+	pci_record_bridge_resource(
+		dev, moving, PCI_PREF_MEMORY_BASE, 
+		IORESOURCE_MEM | IORESOURCE_PREFETCH,
+		IORESOURCE_MEM | IORESOURCE_PREFETCH);
+	
 
 	/* See if the bridge mem resources are implemented */
 	moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
@@ -369,26 +415,25 @@
 	moving = moving_base & moving_limit;
 
 	/* Initialize the memory resources on the current bus */
-	pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE, 
-				   IORESOURCE_MEM | IORESOURCE_PREFETCH,
-				   IORESOURCE_MEM);
+	pci_record_bridge_resource(
+		dev, moving, PCI_MEMORY_BASE, 
+		IORESOURCE_MEM | IORESOURCE_PREFETCH,
+		IORESOURCE_MEM);
 
 	compact_resources(dev);
 }
 
 void pci_dev_read_resources(struct device *dev)
 {
-	uint32_t addr;
-
-	pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
+	pci_read_bases(dev, 6);
+	pci_get_rom_resource(dev, PCI_ROM_ADDRESS);
 }
 
 void pci_bus_read_resources(struct device *dev)
 {
-	uint32_t addr;
-
 	pci_bridge_read_bases(dev);
-	pci_read_bases(dev, 2,  PCI_ROM_ADDRESS1);
+	pci_read_bases(dev, 2);
+	pci_get_rom_resource(dev, PCI_ROM_ADDRESS1);
 }
 
 static void pci_set_resource(struct device *dev, struct resource *resource)
@@ -397,8 +442,10 @@
 
 	/* Make certain the resource has actually been set */
 	if (!(resource->flags & IORESOURCE_ASSIGNED)) {
-		printk_err("ERROR: %s %02x not allocated\n",
-			dev_path(dev), resource->index);
+		printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
+			dev_path(dev), resource->index,
+			resource_type(resource),
+			resource->size);
 		return;
 	}
 
@@ -497,10 +544,10 @@
 
 	last = &dev->resource[dev->resources];
 
-	for (resource = &dev->resource[0]; resource < last; resource++) {
+	for(resource = &dev->resource[0]; resource < last; resource++) {
 		pci_set_resource(dev, resource);
 	}
-	for (link = 0; link < dev->links; link++) {
+	for(link = 0; link < dev->links; link++) {
 		struct bus *bus;
 		bus = &dev->link[link];
 		if (bus->children) {
@@ -551,14 +598,10 @@
 void pci_bus_enable_resources(struct device *dev)
 {
 	uint16_t ctrl;
-
-#if CONFIG_CONSOLE_VGA == 1
 	/* enable IO in command register if there is VGA card
 	 * connected with (even it does not claim IO resource) */
 	if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
 		dev->command |= PCI_COMMAND_IO;
-#endif
-
 	ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
 	ctrl |= dev->link[0].bridge_ctrl;
 	ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
@@ -570,15 +613,27 @@
 	enable_childrens_resources(dev);
 }
 
+void pci_bus_reset(struct bus *bus)
+{
+	unsigned ctl;
+	ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL);
+	ctl |= PCI_BRIDGE_CTL_BUS_RESET;
+	pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
+	mdelay(10);
+	ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+	pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
+	delay(1);
+}
+
 void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
 {
 	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
 		((device & 0xffff) << 16) | (vendor & 0xffff));
 }
 
-#if CONFIG_PCI_ROM_RUN == 1
 void pci_dev_init(struct device *dev)
 {
+#if CONFIG_PCI_ROM_RUN == 1
 	struct rom_header *rom, *ram;
 
 	rom = pci_rom_probe(dev);
@@ -589,8 +644,8 @@
 		return;
 
 	run_bios(dev, ram);
-}
 #endif
+}
 
 /** Default device operation for PCI devices */
 static struct pci_operations pci_dev_ops_pci = {
@@ -601,11 +656,7 @@
 	.read_resources   = pci_dev_read_resources,
 	.set_resources    = pci_dev_set_resources,
 	.enable_resources = pci_dev_enable_resources,
-#if CONFIG_PCI_ROM_RUN == 1
 	.init		  = pci_dev_init,
-#else
-	.init		  = 0,
-#endif
 	.scan_bus	  = 0,
 	.enable           = 0,
 	.ops_pci          = &pci_dev_ops_pci,
@@ -623,10 +674,79 @@
 	.init		  = 0,
 	.scan_bus	  = pci_scan_bridge,
 	.enable           = 0,
+	.reset_bus        = pci_bus_reset,
 	.ops_pci          = &pci_bus_ops_pci,
 };
 
 /**
+ * @brief Detect the type of downstream bridge
+ *
+ * This function is a heuristic to detect which type
+ * of bus is downstream of a pci to pci bridge.  This
+ * functions by looking for various capability blocks
+ * to figure out the type of downstream bridge.  PCI-X
+ * PCI-E, and Hypertransport all seem to have appropriate
+ * capabilities.
+ * 
+ * When only a PCI-Express capability is found the type
+ * is examined to see which type of bridge we have.
+ *
+ * @param dev
+ * 
+ * @return appropriate bridge operations
+ */
+static struct device_operations *get_pci_bridge_ops(device_t dev)
+{
+	unsigned pos;
+
+#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
+	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	if (pos) {
+		printk_debug("%s subbordinate bus PCI-X\n", dev_path(dev));
+		return &default_pcix_ops_bus;
+	}
+#endif
+#if CONFIG_AGP_PLUGIN_SUPPORT == 1
+	/* How do I detect an PCI to AGP bridge? */
+#endif
+#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
+	pos = 0;
+	while((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) {
+		unsigned flags;
+		flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
+		if ((flags >> 13) == 1) {
+			/* Host or Secondary Interface */
+			printk_debug("%s subbordinate bus Hypertransport\n", 
+				dev_path(dev));
+			return &default_ht_ops_bus;
+		}
+	}
+#endif
+#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
+	pos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
+	if (pos) {
+		unsigned flags;
+		flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS);
+		switch((flags & PCI_EXP_FLAGS_TYPE) >> 4) {
+		case PCI_EXP_TYPE_ROOT_PORT:
+		case PCI_EXP_TYPE_UPSTREAM:
+		case PCI_EXP_TYPE_DOWNSTREAM:
+			printk_debug("%s subbordinate bus PCI Express\n", 
+				dev_path(dev));
+			return &default_pciexp_ops_bus;
+		case PCI_EXP_TYPE_PCI_BRIDGE:
+			printk_debug("%s subbordinate PCI\n", 
+				dev_path(dev));
+			return &default_pci_ops_bus;
+		default:
+			break;
+		}
+	}
+#endif
+	return &default_pci_ops_bus;
+}
+
+/**
  * @brief Set up PCI device operation
  *
  *
@@ -644,12 +764,12 @@
 	/* Look through the list of setup drivers and find one for
 	 * this pci device 
 	 */
-	for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
+	for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
 		if ((driver->vendor == dev->vendor) &&
-		    (driver->device == dev->device)) 
+			(driver->device == dev->device)) 
 		{
 			dev->ops = driver->ops;
-			printk_debug("%s [%04x/%04x] %sops\n", 
+			printk_spew("%s [%04x/%04x] %sops\n", 
 				dev_path(dev),
 				driver->vendor, driver->device,
 				(driver->ops->scan_bus?"bus ":""));
@@ -667,8 +787,13 @@
 	case PCI_HEADER_TYPE_BRIDGE:
 		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 			goto bad;
-		dev->ops = &default_pci_ops_bus;
+		dev->ops = get_pci_bridge_ops(dev);
 		break;
+#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
+	case PCI_HEADER_TYPE_CARDBUS:
+		dev->ops = &default_cardbus_ops_bus;
+		break;
+#endif
 	default:
 	bad:
 		if (dev->enabled) {
@@ -682,6 +807,8 @@
 	return;
 }
 
+
+
 /**
  * @brief See if we have already allocated a device structure for a given devfn.
  *
@@ -702,7 +829,7 @@
 	for(; *list; list = &(*list)->sibling) {
 		if ((*list)->path.type != DEVICE_PATH_PCI) {
 			printk_err("child %s not a pci device\n",
-				   dev_path(*list));
+				dev_path(*list));
 			continue;
 		}
 		if ((*list)->path.u.pci.devfn == devfn) {
@@ -713,15 +840,15 @@
 			break;
 		}
 	}
-	/* Just like alloc_dev add the device to the list of device on the bus.
-	 * When the list of devices was formed we removed all of the parents
-	 * children, and now we are interleaving static and dynamic devices in
+	/* Just like alloc_dev add the device to the  list of device on the bus.  
+	 * When the list of devices was formed we removed all of the parents 
+	 * children, and now we are interleaving static and dynamic devices in 
 	 * order on the bus.
 	 */
 	if (dev) {
 		device_t child;
 		/* Find the last child of our parent */
-		for (child = dev->bus->children; child && child->sibling; ) {
+		for(child = dev->bus->children; child && child->sibling; ) {
 			child = child->sibling;
 		}
 		/* Place the device on the list of children of it's parent. */
@@ -738,9 +865,128 @@
 /** 
  * @brief Scan a PCI bus.
  *
+ * Determine the existence of a given PCI device.
+ *
+ * @param bus pointer to the bus structure
+ * @param devfn to look at
+ *
+ * @return The device structure for hte device (if found)
+ *         or the NULL if no device is found.
+ */
+device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
+{
+	uint32_t id, class;
+	uint8_t hdr_type;
+
+	/* Detect if a device is present */
+	if (!dev) {
+		struct device dummy;
+		dummy.bus              = bus;
+		dummy.path.type        = DEVICE_PATH_PCI;
+		dummy.path.u.pci.devfn = devfn;
+		id = pci_read_config32(&dummy, PCI_VENDOR_ID);
+		/* Have we found somthing?
+		 * Some broken boards return 0 if a slot is empty.
+		 */
+		if (	(id == 0xffffffff) || (id == 0x00000000) ||
+			(id == 0x0000ffff) || (id == 0xffff0000))
+		{
+			printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
+			return NULL;
+		}
+		dev = alloc_dev(bus, &dummy.path);
+	}
+	else {
+		/* Enable/disable the device.  Once we have
+		 * found the device specific operations this
+		 * operations we will disable the device with
+		 * those as well.
+		 * 
+		 * This is geared toward devices that have subfunctions
+		 * that do not show up by default.
+		 * 
+		 * If a device is a stuff option on the motherboard
+		 * it may be absent and enable_dev must cope.
+		 * 
+		 */
+		/* Run the magice enable sequence for the device */
+		if (dev->chip_ops && dev->chip_ops->enable_dev) {
+			dev->chip_ops->enable_dev(dev);
+		}
+		/* Now read the vendor and device id */
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		
+		
+		/* If the device does not have a pci id disable it.
+		 * Possibly this is because we have already disabled
+		 * the device.  But this also handles optional devices
+		 * that may not always show up.
+		 */
+		/* If the chain is fully enumerated quit */
+		if (	(id == 0xffffffff) || (id == 0x00000000) ||
+			(id == 0x0000ffff) || (id == 0xffff0000)) 
+		{
+			if (dev->enabled) {
+				printk_info("Disabling static device: %s\n",
+					dev_path(dev));
+				dev->enabled = 0;
+			}
+			return dev;
+		}
+	}
+	/* Read the rest of the pci configuration information */
+	hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
+	class = pci_read_config32(dev, PCI_CLASS_REVISION);
+	
+	/* Store the interesting information in the device structure */
+	dev->vendor = id & 0xffff;
+	dev->device = (id >> 16) & 0xffff;
+	dev->hdr_type = hdr_type;
+	/* class code, the upper 3 bytes of PCI_CLASS_REVISION */
+	dev->class = class >> 8;
+	
+
+	/* Architectural/System devices always need to
+	 * be bus masters.
+	 */
+	if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
+		dev->command |= PCI_COMMAND_MASTER;
+	}
+	/* Look at the vendor and device id, or at least the 
+	 * header type and class and figure out which set of
+	 * configuration methods to use.  Unless we already
+	 * have some pci ops.
+	 */
+	set_pci_ops(dev);
+
+	/* Now run the magic enable/disable sequence for the device */
+	if (dev->ops && dev->ops->enable) {
+		dev->ops->enable(dev);
+	}
+	
+
+	/* Display the device and error if we don't have some pci operations
+	 * for it.
+	 */
+	printk_debug("%s [%04x/%04x] %s%s\n",
+		dev_path(dev),
+		dev->vendor, dev->device, 
+		dev->enabled?"enabled": "disabled",
+		dev->ops?"" : " No operations"
+		);
+
+	return dev;
+}
+
+/** 
+ * @brief Scan a PCI bus.
+ *
  * Determine the existence of devices and bridges on a PCI bus. If there are
  * bridges on the bus, recursively scan the buses behind the bridges.
  *
+ * This function is the default scan_bus() method for the root device
+ * 'dev_root'.
+ *
  * @param bus pointer to the bus structure
  * @param min_devfn minimum devfn to look at in the scan usually 0x00
  * @param max_devfn maximum devfn to look at in the scan usually 0xff
@@ -748,11 +994,11 @@
  *
  * @return The maximum bus number found, after scanning all subordinate busses
  */
-unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn,
-			  unsigned int max)
+unsigned int pci_scan_bus(struct bus *bus,
+	unsigned min_devfn, unsigned max_devfn,
+	unsigned int max)
 {
 	unsigned int devfn;
-	device_t dev;
 	device_t old_devices;
 	device_t child;
 
@@ -762,141 +1008,49 @@
 	bus->children = 0;
 
 	post_code(0x24);
-
 	/* probe all devices/functions on this bus with some optimization for
 	 * non-existence and single funcion devices
 	 */
 	for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
-		uint32_t id, class;
-		uint8_t hdr_type;
+		device_t dev;
 
 		/* First thing setup the device structure */
 		dev = pci_scan_get_dev(&old_devices, devfn);
-	
-		/* Detect if a device is present */
-		if (!dev) {
-			struct device dummy;
-			dummy.bus              = bus;
-			dummy.path.type        = DEVICE_PATH_PCI;
-			dummy.path.u.pci.devfn = devfn;
-			id = pci_read_config32(&dummy, PCI_VENDOR_ID);
-			/* some broken boards return 0 if a slot is empty: */
-			if ((id == 0xffffffff) || (id == 0x00000000) || 
-			    (id == 0x0000ffff) || (id == 0xffff0000))
-			{
-				printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
-				if (PCI_FUNC(devfn) == 0x00) {
-					/* if this is a function 0 device and 
-					 * it is not present,
-					 * skip to next device 
-					 */
-					devfn += 0x07;
-				}
-				/* This function in a multi function device is
-				 * not present, skip to the next function.
-				 */
-				continue;
-			}
-			dev = alloc_dev(bus, &dummy.path);
-		}
-		else {
-			/* Enable/disable the device.  Once we have
-			 * found the device specific operations this
-			 * operations we will disable the device with
-			 * those as well.
-			 * 
-			 * This is geared toward devices that have subfunctions
-			 * that do not show up by default.
-			 * 
-			 * If a device is a stuff option on the motherboard
-			 * it may be absent and enable_dev must cope.
-			 * 
-			 */
-			if (dev->chip_ops && dev->chip_ops->enable_dev) 
-			{
-				dev->chip_ops->enable_dev(dev);
-			}
-			/* Now read the vendor and device id */
-			id = pci_read_config32(dev, PCI_VENDOR_ID);
-			
-			/* If the device does not have a pci id disable it.
-			 * Possibly this is because we have already disabled
-			 * the device.  But this also handles optional devices
-			 * that may not always show up.
-			 */
-			if (id == 0xffffffff || id == 0x00000000 ||
-			    id == 0x0000ffff || id == 0xffff0000) 
-			{
-				if (dev->enabled) {
-					printk_info("Disabling static device: %s\n",
-						dev_path(dev));
-					dev->enabled = 0;
-				}
-				continue;
-			}
-		}
-		/* Read the rest of the pci configuration information */
-		hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
-		class = pci_read_config32(dev, PCI_CLASS_REVISION);
 
-		/* Store the interesting information in the device structure */
-		dev->vendor = id & 0xffff;
-		dev->device = (id >> 16) & 0xffff;
-		dev->hdr_type = hdr_type;
-		/* class code, the upper 3 bytes of PCI_CLASS_REVISION */
-		dev->class = class >> 8;
-
-		/* Architectural/System devices always need to
-		 * be bus masters.
+		/* See if a device is present and setup the device
+		 * structure.
 		 */
-		if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
-			dev->command |= PCI_COMMAND_MASTER;
-		}
+		dev = pci_probe_dev(dev, bus, devfn); 
 
-		/* Look at the vendor and device id, or at least the 
-		 * header type and class and figure out which set of
-		 * configuration methods to use.  Unless we already
-		 * have some pci ops.
+		/* if this is not a multi function device, 
+		 * or the device is not present don't waste
+		 * time probing another function. 
+		 * Skip to next device. 
 		 */
-		set_pci_ops(dev);
-		/* Error if we don't have some pci operations for it */
-		if (!dev->ops) {
-			printk_err("%s No device operations\n",
-				dev_path(dev));
-			continue;
-		}
-
-		/* Now run the magic enable/disable sequence for the device */
-		if (dev->ops && dev->ops->enable) {
-			dev->ops->enable(dev);
-		}
-
-		printk_debug("%s [%04x/%04x] %s\n", 
-			dev_path(dev),
-			dev->vendor, dev->device, 
-			dev->enabled?"enabled": "disabled");
-
-		if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
-			/* if this is not a multi function device, 
-			 * don't waste time probing another function. 
-			 * Skip to next device. 
-			 */
+		if ((PCI_FUNC(devfn) == 0x00) && 
+			(!dev || (dev->enabled && ((dev->hdr_type & 0x80) != 0x80))))
+		{
 			devfn += 0x07;
 		}
 	}
 	post_code(0x25);
 
+	/* Die if any leftover Static devices are are found.  
+	 * There's probably a problem in the Config.lb.
+	*/
+	if(old_devices) {
+		device_t left;
+		for(left = old_devices; left; left = left->sibling) {
+			printk_debug("%s\n", dev_path(left));
+		}
+		die("Left over static devices.  Check your Config.lb\n");
+	}
+
 	/* For all children that implement scan_bus (i.e. bridges)
 	 * scan the bus behind that child.
 	 */
-	for (child = bus->children; child; child = child->sibling) {
-		if (!child->enabled ||
-		    !child->ops || 
-		    !child->ops->scan_bus) 
-		{
-			continue;
-		}
-		max = child->ops->scan_bus(child, max);
+	for(child = bus->children; child; child = child->sibling) {
+		max = scan_bus(child, max);
 	}
 
 	/*
@@ -911,6 +1065,7 @@
 	return max;
 }
 
+
 /**
  * @brief Scan a PCI bridge and the buses behind the bridge.
  *
@@ -924,7 +1079,9 @@
  *
  * @return The maximum bus number found, after scanning all subordinate busses
  */
-unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
+unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max, 
+	unsigned int (*do_scan_bus)(struct bus *bus, 
+		unsigned min_devfn, unsigned max_devfn, unsigned int max))
 {
 	struct bus *bus;
 	uint32_t buses;
@@ -960,14 +1117,14 @@
 	 */
 	buses &= 0xff000000;
 	buses |= (((unsigned int) (dev->bus->secondary) << 0) |
-		  ((unsigned int) (bus->secondary) << 8) |
-		  ((unsigned int) (bus->subordinate) << 16));
+		((unsigned int) (bus->secondary) << 8) |
+		((unsigned int) (bus->subordinate) << 16));
 	pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
 
 	/* Now we can scan all subordinate buses 
 	 * i.e. the bus behind the bridge.
 	 */
-	max = pci_scan_bus(bus, 0x00, 0xff, max);
+	max = do_scan_bus(bus, 0x00, 0xff, max);
 
 	/* We know the number of buses behind this bridge. Set the subordinate
 	 * bus number to its real value.
@@ -977,11 +1134,29 @@
 		((unsigned int) (bus->subordinate) << 16);
 	pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
 	pci_write_config16(dev, PCI_COMMAND, cr);
-
+	
 	printk_spew("%s returns max %d\n", __func__, max);
 	return max;
 }
 
+/**
+ * @brief Scan a PCI bridge and the buses behind the bridge.
+ *
+ * Determine the existence of buses behind the bridge. Set up the bridge
+ * according to the result of the scan.
+ *
+ * This function is the default scan_bus() method for PCI bridge devices.
+ *
+ * @param dev pointer to the bridge device
+ * @param max the highest bus number assgined up to now
+ *
+ * @return The maximum bus number found, after scanning all subordinate busses
+ */
+unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
+{
+	return do_pci_scan_bridge(dev, max, pci_scan_bus);
+}
+
 /*
     Tell the EISA int controller this int must be level triggered
     THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
@@ -1026,7 +1201,8 @@
 
     -kevinh@ispiri.com
 */
-void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4])
+void pci_assign_irqs(unsigned bus, unsigned slot,
+	const unsigned char pIntAtoD[4])
 {
 	unsigned functNum;
 	device_t pdev;
diff --git a/src/devices/pciexp_device.c b/src/devices/pciexp_device.c
new file mode 100644
index 0000000..5422a8e
--- /dev/null
+++ b/src/devices/pciexp_device.c
@@ -0,0 +1,60 @@
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pciexp.h>
+
+
+static void pciexp_tune_dev(device_t dev)
+{
+	unsigned cap;
+
+	cap = pci_find_capability(dev, PCI_CAP_ID_PCIE);
+	if (!cap) {
+		/* error... */
+		return;
+	}
+	printk_debug("PCIEXP: tunning %s\n", dev_path(dev));
+#warning "IMPLEMENT PCI EXPRESS TUNING"
+}
+
+unsigned int pciexp_scan_bus(struct bus *bus, 
+	unsigned min_devfn, unsigned max_devfn, 
+	unsigned int max)
+{
+	device_t child;
+	max = pci_scan_bus(bus, min_devfn, max_devfn, max);
+	for(child = bus->children; child; child = child->sibling) {
+		if (	(child->path.u.pci.devfn < min_devfn) ||
+			(child->path.u.pci.devfn > max_devfn))
+		{
+			continue;
+		}
+		pciexp_tune_dev(child);
+	}
+	return max;
+}
+
+
+unsigned int pciexp_scan_bridge(device_t dev, unsigned int max)
+{
+	return do_pci_scan_bridge(dev, max, pciexp_scan_bus);
+}
+
+/** Default device operations for PCI Express bridges */
+static struct pci_operations pciexp_bus_ops_pci = {
+	.set_subsystem = 0,
+};
+
+struct device_operations default_pciexp_ops_bus = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init		  = 0,
+	.scan_bus	  = pciexp_scan_bridge,
+	.enable           = 0,
+	.reset_bus        = pci_bus_reset,
+	.ops_pci          = &pciexp_bus_ops_pci,
+};
diff --git a/src/devices/pcix_device.c b/src/devices/pcix_device.c
new file mode 100644
index 0000000..8915e56
--- /dev/null
+++ b/src/devices/pcix_device.c
@@ -0,0 +1,140 @@
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pcix.h>
+
+
+static void pcix_tune_dev(device_t dev)
+{
+	unsigned cap;
+	unsigned status, orig_cmd, cmd;
+	unsigned max_read, max_tran;
+
+	if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
+		return;
+	}
+	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	if (!cap) {
+		return;
+	}
+	printk_debug("%s PCI-X tuning\n", dev_path(dev));
+	status = pci_read_config32(dev, cap + PCI_X_STATUS);
+	orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
+
+	max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
+	max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
+	if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
+		cmd &= ~PCI_X_CMD_MAX_READ;
+		cmd |= max_read << 2;
+	}
+	if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
+		cmd &= ~PCI_X_CMD_MAX_SPLIT;
+		cmd |= max_tran << 4;
+	}
+	/* Don't attempt to handle PCI-X errors */
+	cmd &= ~PCI_X_CMD_DPERR_E;
+	/* Enable Relaxed Ordering */
+	cmd |= PCI_X_CMD_ERO;
+	if (orig_cmd != cmd) {
+		pci_write_config16(dev, cap + PCI_X_CMD, cmd);
+	}
+}
+
+unsigned int pcix_scan_bus(struct bus *bus,
+	unsigned min_devfn, unsigned max_devfn, unsigned int max)
+{
+	device_t child;
+	max = pci_scan_bus(bus, min_devfn, max_devfn, max);
+	for(child = bus->children; child; child = child->sibling) {
+		if (	(child->path.u.pci.devfn < min_devfn) ||
+			(child->path.u.pci.devfn > max_devfn))
+		{
+			continue;
+		}
+		pcix_tune_dev(child);
+	}
+	return max;
+}
+
+const char *pcix_speed(unsigned sstatus)
+{
+	static const char conventional[] = "Conventional PCI";
+	static const char pcix_66mhz[] = "66MHz PCI-X";
+	static const char pcix_100mhz[] = "100MHz PCI-X";
+	static const char pcix_133mhz[] = "133MHz PCI-X";
+	static const char pcix_266mhz[] = "266MHz PCI-X";
+	static const char pcix_533mhz[] = "533MHZ PCI-X";
+	static const char unknown[] = "Unknown";
+		
+	const char *result;
+	result = unknown;
+	switch(PCI_X_SSTATUS_MFREQ(sstatus)) {
+	case PCI_X_SSTATUS_CONVENTIONAL_PCI:	
+		result = conventional; 
+		break;
+	case PCI_X_SSTATUS_MODE1_66MHZ:
+		result = pcix_66mhz;
+		break;
+	case PCI_X_SSTATUS_MODE1_100MHZ:
+		result = pcix_100mhz;
+		break;
+		
+	case PCI_X_SSTATUS_MODE1_133MHZ:
+		result = pcix_133mhz;
+		break;
+		
+	case PCI_X_SSTATUS_MODE2_266MHZ_REF_66MHZ:
+	case PCI_X_SSTATUS_MODE2_266MHZ_REF_100MHZ:
+	case PCI_X_SSTATUS_MODE2_266MHZ_REF_133MHZ:
+		result = pcix_266mhz;
+		break;
+		
+	case PCI_X_SSTATUS_MODE2_533MHZ_REF_66MHZ:
+	case PCI_X_SSTATUS_MODE2_533MHZ_REF_100MHZ:
+	case PCI_X_SSTATUS_MODE2_533MHZ_REF_133MHZ:
+		result = pcix_533mhz;
+		break;
+	}
+	return result;
+}
+
+unsigned int pcix_scan_bridge(device_t dev, unsigned int max)
+{
+	unsigned pos;
+	unsigned sstatus;
+
+	/* Find the PCI-X capability */
+	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	sstatus = pci_read_config16(dev, pos + PCI_X_SEC_STATUS);
+
+	if (PCI_X_SSTATUS_MFREQ(sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
+		max = do_pci_scan_bridge(dev, max, pci_scan_bus);
+	} else {
+		max = do_pci_scan_bridge(dev, max, pcix_scan_bus);
+	}
+
+	/* Print the PCI-X bus speed */
+	printk_debug("PCI: %02x: %s\n", dev->link[0].secondary, pcix_speed(sstatus));
+
+	return max;
+}
+
+
+/** Default device operations for PCI-X bridges */
+static struct pci_operations pcix_bus_ops_pci = {
+	.set_subsystem = 0,
+};
+
+struct device_operations default_pcix_ops_bus = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init		  = 0,
+	.scan_bus	  = pcix_scan_bridge,
+	.enable           = 0,
+	.reset_bus        = pci_bus_reset,
+	.ops_pci          = &pcix_bus_ops_pci,
+};
diff --git a/src/devices/pnp_device.c b/src/devices/pnp_device.c
index cde571f..13f12ee 100644
--- a/src/devices/pnp_device.c
+++ b/src/devices/pnp_device.c
@@ -68,8 +68,10 @@
 static void pnp_set_resource(device_t dev, struct resource *resource)
 {
 	if (!(resource->flags & IORESOURCE_ASSIGNED)) {
-		printk_err("ERROR: %s %02x not allocated\n",
-			dev_path(dev), resource->index);
+		printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
+			dev_path(dev), resource->index,
+			resource_type(resource),
+			resource->size);
 		return;
 	}
 
diff --git a/src/devices/root_device.c b/src/devices/root_device.c
index 2bb4f0a..3e559ea 100644
--- a/src/devices/root_device.c
+++ b/src/devices/root_device.c
@@ -1,6 +1,7 @@
 #include <console/console.h>
 #include <device/device.h>
 #include <device/pci.h>
+#include <part/hard_reset.h>
 
 /** 
  * Read the resources for the root device,
@@ -35,8 +36,9 @@
 }
 
 /**
- * @brief Write the resources for the root device
+ * @brief Write the resources for every device
  *
+ * Write the resources for the root device,
  * and every device under it which are all of the devices.
  * @param root Pointer to the device structure for the system root device
  */
@@ -45,10 +47,10 @@
 	struct bus *bus;
 
 	bus = &root->link[0];
-	compute_allocate_resource(bus, &root->resource[0],
-				  IORESOURCE_IO, IORESOURCE_IO);
-	compute_allocate_resource(bus, &root->resource[1],
-				  IORESOURCE_MEM, IORESOURCE_MEM);
+	compute_allocate_resource(bus,
+		&root->resource[0], IORESOURCE_IO, IORESOURCE_IO);
+	compute_allocate_resource(bus, 
+		&root->resource[1], IORESOURCE_MEM, IORESOURCE_MEM);
 	assign_resources(bus);
 }
 
@@ -57,9 +59,9 @@
  *
  * The enumeration of certain buses is purely static. The existence of
  * devices on those buses can be completely determined at compile time
- * and is specified in the config file. Typical exapmles are the 'PNP'
- * devices on a legacy ISA/LPC bus. There is no need of probing of any
- * kind, the only thing we have to do is to walk through the bus and
+ * and is specified in the config file. Typical examples are the 'PNP' 
+ * devices on a legacy ISA/LPC bus. There is no need of probing of any kind, 
+ * the only thing we have to do is to walk through the bus and 
  * enable or disable devices as indicated in the config file.
  *
  * On the other hand, some devices are virtual and their existence is
@@ -70,47 +72,50 @@
  * This function is the default scan_bus() method for the root device and
  * LPC bridges.
  *
- * @param root Pointer to the root device which the static buses are attached
+ * @param bus Pointer to the device structure which the static buses are attached
  * @param max  Maximum bus number currently used before scanning.
- * @return Largest bus number used after scanning.
+ * @return Largest bus number used.
  */
 static int smbus_max = 0;
-unsigned int scan_static_bus(device_t root, unsigned int max)
+unsigned int scan_static_bus(device_t bus, unsigned int max)
 {
 	device_t child;
 	unsigned link;
 
-	printk_spew("%s for %s\n", __func__, dev_path(root));
+	printk_spew("%s for %s\n", __func__, dev_path(bus));
 
-	for (link = 0; link < root->links; link++) {
-                /* for smbus bus enumerate */
-                child = root->link[link].children;
-                if(child && child->path.type == DEVICE_PATH_I2C) {
-                        root->link[link].secondary = ++smbus_max;
-                }
-		for (child = root->link[link].children; child; child = child->sibling) {
+	for(link = 0; link < bus->links; link++) {
+		/* for smbus bus enumerate */
+		child = bus->link[link].children;
+		if(child && child->path.type == DEVICE_PATH_I2C) {
+			bus->link[link].secondary = ++smbus_max;
+		}
+		for(child = bus->link[link].children; child; child = child->sibling) {
 			if (child->chip_ops && child->chip_ops->enable_dev) {
 				child->chip_ops->enable_dev(child);
 			}
 			if (child->ops && child->ops->enable) {
 				child->ops->enable(child);
 			}
-			if (child->path.type == DEVICE_PATH_I2C)	
-				printk_debug("smbus: %s[%d]->",  dev_path(child->bus->dev), child->bus->link );
-			printk_debug("%s %s\n", dev_path(child),
-				     child->enabled?"enabled": "disabled");
+ 			if (child->path.type == DEVICE_PATH_I2C) {
+ 				printk_debug("smbus: %s[%d]->",  
+					dev_path(child->bus->dev), child->bus->link );
+			}
+			printk_debug("%s %s\n",
+				dev_path(child),
+				child->enabled?"enabled": "disabled");
 		}
 	}
-	for (link = 0; link < root->links; link++) {
-		for (child = root->link[link].children; child; child = child->sibling) {
+	for(link = 0; link < bus->links; link++) {
+		for(child = bus->link[link].children; child; child = child->sibling) {
 			if (!child->ops || !child->ops->scan_bus)
 				continue;
 			printk_spew("%s scanning...\n", dev_path(child));
-			max = child->ops->scan_bus(child, max);
+			max = scan_bus(child, max);
 		}
 	}
 
-	printk_spew("%s for  %s done\n", __func__, dev_path(root));
+	printk_spew("%s for %s done\n", __func__, dev_path(bus));
 
 	return max;
 }
@@ -120,7 +125,7 @@
  *
  * @param dev the device whos children's resources are to be enabled
  *
- * This function is call by the global enable_resources() indirectly via the
+ * This function is called by the global enable_resource() indirectly via the
  * device_operation::enable_resources() method of devices.
  *
  * Indirect mutual recursion:
@@ -131,9 +136,9 @@
 void enable_childrens_resources(device_t dev)
 {
 	unsigned link;
-	for (link = 0; link < dev->links; link++) {
+	for(link = 0; link < dev->links; link++) {
 		device_t child;
-		for (child = dev->link[link].children; child; child = child->sibling) {
+		for(child = dev->link[link].children; child; child = child->sibling) {
 			enable_resources(child);
 		}
 	}
@@ -161,6 +166,12 @@
 {
 }
 
+void root_dev_reset(struct bus *bus)
+{
+	printk_info("Reseting board...\n");
+	hard_reset();
+}
+
 /**
  * @brief Default device operation for root device
  *
@@ -174,6 +185,7 @@
 	.enable_resources = root_dev_enable_resources,
 	.init             = root_dev_init,
 	.scan_bus         = root_dev_scan_bus,
+	.reset_bus        = root_dev_reset,
 };
 
 /**
diff --git a/src/drivers/generic/debug/debug_dev.c b/src/drivers/generic/debug/debug_dev.c
index d5f9e62..49d442a 100644
--- a/src/drivers/generic/debug/debug_dev.c
+++ b/src/drivers/generic/debug/debug_dev.c
@@ -268,6 +268,9 @@
 	case 7:
 		print_tsc();
 		break;
+	case 8: 
+		hard_reset();
+		break;
 	}
 }
 
diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h
index 3d229d2..51c0b51 100644
--- a/src/include/cpu/x86/mtrr.h
+++ b/src/include/cpu/x86/mtrr.h
@@ -34,7 +34,9 @@
 
 #if !defined(__ROMCC__) && !defined (ASSEMBLY)
 
-void x86_setup_mtrrs(void);
+
+void x86_setup_var_mtrrs(unsigned address_bits);
+void x86_setup_mtrrs(unsigned address_bits);
 int x86_mtrr_check(void);
 
 #endif /* __ROMCC__ */
diff --git a/src/include/device/agp.h b/src/include/device/agp.h
new file mode 100644
index 0000000..073858a
--- /dev/null
+++ b/src/include/device/agp.h
@@ -0,0 +1,12 @@
+#ifndef DEVICE_AGP_H
+#define DEVICE_AGP_H
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+unsigned int agp_scan_bus(struct bus *bus, 
+	unsigned min_devfn, unsigned max_devfn, unsigned int max);
+unsigned int agp_scan_bridge(device_t dev, unsigned int max);
+
+extern struct device_operations default_agp_ops_bus;
+
+
+#endif /* DEVICE_AGP_H */
diff --git a/src/include/device/cardbus.h b/src/include/device/cardbus.h
new file mode 100644
index 0000000..38aa41c
--- /dev/null
+++ b/src/include/device/cardbus.h
@@ -0,0 +1,12 @@
+#ifndef DEVICE_CARDBUS_H
+#define DEVICE_CARDBUS_H
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+void cardbus_read_resources(device_t dev);
+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);
+
+extern struct device_operations default_cardbus_ops_bus;
+
+#endif /* DEVICE_CARDBUS_H */
diff --git a/src/include/device/device.h b/src/include/device/device.h
index be93f55..aff5616 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -26,6 +26,8 @@
 #define CHIP_NAME(X)
 #endif
 
+struct bus;
+
 struct device_operations {
 	void (*read_resources)(device_t dev);
 	void (*set_resources)(device_t dev);
@@ -34,6 +36,7 @@
 	unsigned int (*scan_bus)(device_t bus, unsigned int max);
 	void (*enable)(device_t dev);
 	void (*set_link)(device_t dev, unsigned int link);
+	void (*reset_bus)(struct bus *bus);
 	const struct pci_operations *ops_pci;
 	const struct smbus_bus_operations *ops_smbus_bus;
 	const struct pci_bus_operations *ops_pci_bus;
@@ -48,6 +51,8 @@
 	unsigned char	secondary; 	/* secondary bus number */
 	unsigned char	subordinate;	/* max subordinate bus number */
 	unsigned char   cap;		/* PCi capability offset */
+	unsigned	reset_needed : 1;
+	unsigned	disable_relaxed_ordering : 1;
 };
 
 #define MAX_RESOURCES 12
@@ -81,7 +86,8 @@
 	unsigned int resources;
 
 	/* link are (down sream) buses attached to the device, usually a leaf
-	 * device with no child have 0 bus attached and a bridge has 1 bus */
+	 * device with no children have 0 buses attached and a bridge has 1 bus 
+	 */
 	struct bus link[MAX_LINKS];
 	/* number of buses attached to the device */
 	unsigned int links;
@@ -101,8 +107,11 @@
 extern void dev_configure(void);
 extern void dev_enable(void);
 extern void dev_initialize(void);
+extern void dev_optimize(void);
 
 /* Generic device helper functions */
+extern int reset_bus(struct bus *bus);
+extern unsigned int scan_bus(struct device *bus, unsigned int max);
 extern void compute_allocate_resource(struct bus *bus, struct resource *bridge,
 	unsigned long type_mask, unsigned long type);
 extern void assign_resources(struct bus *bus);
@@ -110,6 +119,9 @@
 extern void enumerate_static_device(void);
 extern void enumerate_static_devices(void);
 extern const char *dev_path(device_t dev);
+const char *bus_path(struct bus *bus);
+extern void dev_set_enabled(device_t dev, int enable);
+extern void disable_children(struct bus *bus);
 
 /* Helper functions */
 device_t find_dev_path(struct bus *parent, struct device_path *path);
@@ -134,5 +146,4 @@
 extern void root_dev_enable_resources(device_t dev);
 extern unsigned int root_dev_scan_bus(device_t root, unsigned int max);
 extern void root_dev_init(device_t dev);
-
 #endif /* DEVICE_H */
diff --git a/src/include/device/hypertransport.h b/src/include/device/hypertransport.h
index 410495c..f04d0ec 100644
--- a/src/include/device/hypertransport.h
+++ b/src/include/device/hypertransport.h
@@ -3,7 +3,10 @@
 
 #include <device/hypertransport_def.h>
 
-unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max);
+unsigned int hypertransport_scan_chain(struct bus *bus, 
+	unsigned min_devfn, unsigned max_devfn, unsigned int max);
+unsigned int ht_scan_bridge(struct device *dev, unsigned int max);
+extern struct device_operations default_ht_ops_bus;
 
 #define HT_IO_HOST_ALIGN 4096
 #define HT_MEM_HOST_ALIGN (1024*1024)
diff --git a/src/include/device/path.h b/src/include/device/path.h
index f55827b..cfac751 100644
--- a/src/include/device/path.h
+++ b/src/include/device/path.h
@@ -72,6 +72,7 @@
 
 
 #define DEVICE_PATH_MAX 30
+#define BUS_PATH_MAX (DEVICE_PATH_MAX+10)
 
 extern int path_eq(struct device_path *path1, struct device_path *path2);
 
diff --git a/src/include/device/pci.h b/src/include/device/pci.h
index d359a96..2daa1ca 100644
--- a/src/include/device/pci.h
+++ b/src/include/device/pci.h
@@ -50,16 +50,26 @@
 extern struct pci_driver epci_drivers[];
 
 
-struct device_operations default_pci_ops_dev;
-struct device_operations default_pci_ops_bus;
+extern struct device_operations default_pci_ops_dev;
+extern struct device_operations default_pci_ops_bus;
 
 void pci_dev_read_resources(device_t dev);
 void pci_bus_read_resources(device_t dev);
 void pci_dev_set_resources(device_t dev);
 void pci_dev_enable_resources(device_t dev);
 void pci_bus_enable_resources(device_t dev);
+void pci_bus_reset(struct bus *bus);
+device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn);
+unsigned int do_pci_scan_bridge(device_t bus, unsigned int max,
+	unsigned int (*do_scan_bus)(struct bus *bus, 
+		unsigned min_devfn, unsigned max_devfn, unsigned int max));
 unsigned int pci_scan_bridge(device_t bus, unsigned int max);
 unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn, unsigned int max);
+uint8_t pci_moving_config8(struct device *dev, unsigned reg);
+uint16_t pci_moving_config16(struct device *dev, unsigned reg);
+uint32_t pci_moving_config32(struct device *dev, unsigned reg);
+unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last);
+unsigned pci_find_capability(device_t dev, unsigned cap);
 struct resource *pci_get_resource(struct device *dev, unsigned long index);
 void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device);
 
diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h
index dc2176ba..6fb7ebd 100644
--- a/src/include/device/pci_def.h
+++ b/src/include/device/pci_def.h
@@ -181,15 +181,20 @@
 #define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
 #define  PCI_CAP_ID_PCIX	0x07	/* PCIX  */
 #define  PCI_CAP_ID_HT          0x08	/* Hypertransport */
+#define  PCI_CAP_ID_SHPC 	0x0C	/* PCI Standard Hot-Plug Controller */
 #define  PCI_CAP_ID_PCIE	0x10	/* PCI Express */
+#define  PCI_CAP_ID_MSIX	0x11	/* MSI-X */
 #define PCI_CAP_LIST_NEXT	1	/* Next capability in the list */
 #define PCI_CAP_FLAGS		2	/* Capability defined flags (16 bits) */
 
 /* Hypertransport Registers */
 #define PCI_HT_CAP_SIZEOF	   4
+#define PCI_HT_CAP_HOST_CTRL       4	/* Host link control */ 
 #define PCI_HT_CAP_HOST_WIDTH	   6	/* width value & capability  */
 #define PCI_HT_CAP_HOST_FREQ	   0x09	/* Host frequency */
 #define PCI_HT_CAP_HOST_FREQ_CAP   0x0a	/* Host Frequency capability  */
+#define PCI_HT_CAP_SLAVE_CTRL0	   4	/* link control */
+#define PCI_HT_CAP_SLAVE_CTRL1	   8	/* link control to */
 #define PCI_HT_CAP_SLAVE_WIDTH0	   6	/* width value & capability  */
 #define PCI_HT_CAP_SLAVE_WIDTH1	   0x0a	/* width value & capability  to */
 #define PCI_HT_CAP_SLAVE_FREQ0	   0x0d	/* Slave frequency from */
@@ -199,6 +204,7 @@
 
 /* Power Management Registers */
 
+#define PCI_PM_PMC              2       /* PM Capabilities Register */
 #define  PCI_PM_CAP_VER_MASK	0x0007	/* Version */
 #define  PCI_PM_CAP_PME_CLOCK	0x0008	/* PME clock required */
 #define  PCI_PM_CAP_AUX_POWER	0x0010	/* Auxilliary power support */
@@ -260,6 +266,191 @@
 #define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
+#define PCI_MSI_MASK_BIT	16	/* Mask bits register */
+
+/* CompactPCI Hotswap Register */
+
+#define PCI_CHSWP_CSR		2	/* Control and Status Register */
+#define  PCI_CHSWP_DHA		0x01	/* Device Hiding Arm */
+#define  PCI_CHSWP_EIM		0x02	/* ENUM# Signal Mask */
+#define  PCI_CHSWP_PIE		0x04	/* Pending Insert or Extract */
+#define  PCI_CHSWP_LOO		0x08	/* LED On / Off */
+#define  PCI_CHSWP_PI		0x30	/* Programming Interface */
+#define  PCI_CHSWP_EXT		0x40	/* ENUM# status - extraction */
+#define  PCI_CHSWP_INS		0x80	/* ENUM# status - insertion */
+
+/* PCI-X registers */
+
+#define PCI_X_CMD		2	/* Modes & Features */
+#define  PCI_X_CMD_DPERR_E	0x0001	/* Data Parity Error Recovery Enable */
+#define  PCI_X_CMD_ERO		0x0002	/* Enable Relaxed Ordering */
+#define  PCI_X_CMD_MAX_READ	0x000c	/* Max Memory Read Byte Count */
+#define  PCI_X_CMD_MAX_SPLIT	0x0070	/* Max Outstanding Split Transactions */
+#define  PCI_X_CMD_VERSION(x) 	(((x) >> 12) & 3) /* Version */
+#define PCI_X_STATUS		4	/* PCI-X capabilities */
+#define  PCI_X_STATUS_DEVFN	0x000000ff	/* A copy of devfn */
+#define  PCI_X_STATUS_BUS	0x0000ff00	/* A copy of bus nr */
+#define  PCI_X_STATUS_64BIT	0x00010000	/* 64-bit device */
+#define  PCI_X_STATUS_133MHZ	0x00020000	/* 133 MHz capable */
+#define  PCI_X_STATUS_SPL_DISC	0x00040000	/* Split Completion Discarded */
+#define  PCI_X_STATUS_UNX_SPL	0x00080000	/* Unexpected Split Completion */
+#define  PCI_X_STATUS_COMPLEX	0x00100000	/* Device Complexity */
+#define  PCI_X_STATUS_MAX_READ	0x00600000	/* Designed Max Memory Read Count */
+#define  PCI_X_STATUS_MAX_SPLIT	0x03800000	/* Designed Max Outstanding Split Transactions */
+#define  PCI_X_STATUS_MAX_CUM	0x1c000000	/* Designed Max Cumulative Read Size */
+#define  PCI_X_STATUS_SPL_ERR	0x20000000	/* Rcvd Split Completion Error Msg */
+#define  PCI_X_STATUS_266MHZ	0x40000000	/* 266 MHz capable */
+#define  PCI_X_STATUS_533MHZ	0x80000000	/* 533 MHz capable */
+
+/* PCI-X bridge registers */
+#define PCI_X_SEC_STATUS	2	/* Secondary status */
+#define  PCI_X_SSTATUS_64BIT	0x0001	/* The bus behind the bridge is 64bits wide */
+#define  PCI_X_SSTATUS_133MHZ	0x0002	/* The bus behind the bridge is 133Mhz Capable */
+#define  PCI_X_SSTATUS_SPL_DISC 0x0004	/* Split Completion Discarded */
+#define  PCI_X_SSTATUS_UNX_SPL	0x0008	/* Unexpected Split Completion */
+#define  PCI_X_SSTATUS_SPL_OVR	0x0010	/* Split Completion Overrun */
+#define  PCI_X_SSTATUS_SPL_DLY	0x0020	/* Split Completion Delayed */
+#define  PCI_X_SSTATUS_MFREQ(x) (((x) & 0x03c0) >> 6)	/* PCI-X mode and frequency */
+#define   PCI_X_SSTATUS_CONVENTIONAL_PCI	0x0
+#define   PCI_X_SSTATUS_MODE1_66MHZ	0x1
+#define   PCI_X_SSTATUS_MODE1_100MHZ	0x2
+#define   PCI_X_SSTATUS_MODE1_133MHZ	0x3
+#define   PCI_X_SSTATUS_MODE2_266MHZ_REF_66MHZ	0x9
+#define   PCI_X_SSTATUS_MODE2_266MHZ_REF_100MHZ	0xa
+#define   PCI_X_SSTATUS_MODE2_266MHZ_REF_133MHZ	0xb
+#define   PCI_X_SSTATUS_MODE2_533MHZ_REF_66MHZ	0xd
+#define   PCI_X_SSTATUS_MODE2_533MHZ_REF_100MHZ	0xe
+#define   PCI_X_SSTATUS_MODE2_533MHZ_REF_133MHZ	0xf
+#define  PCI_X_SSTATUS_VERSION(x)	(((x) >> 12) & 3) /* Version */
+#define  PCI_X_SSTATUS_266MHZ	0x4000	/* The bus behind the bridge is 266Mhz Capable */
+#define  PCI_X_SSTAUTS_533MHZ	0x8000	/* The bus behind the bridge is 533Mhz Capable */
+
+/* PCI Express capability registers */
+
+#define PCI_EXP_FLAGS		2	/* Capabilities register */
+#define PCI_EXP_FLAGS_VERS	0x000f	/* Capability version */
+#define PCI_EXP_FLAGS_TYPE	0x00f0	/* Device/Port type */
+#define  PCI_EXP_TYPE_ENDPOINT	0x0	/* Express Endpoint */
+#define  PCI_EXP_TYPE_LEG_END	0x1	/* Legacy Endpoint */
+#define  PCI_EXP_TYPE_ROOT_PORT 0x4	/* Root Port */
+#define  PCI_EXP_TYPE_UPSTREAM	0x5	/* Upstream Port */
+#define  PCI_EXP_TYPE_DOWNSTREAM 0x6	/* Downstream Port */
+#define  PCI_EXP_TYPE_PCI_BRIDGE 0x7	/* PCI/PCI-X Bridge */
+#define PCI_EXP_FLAGS_SLOT	0x0100	/* Slot implemented */
+#define PCI_EXP_FLAGS_IRQ	0x3e00	/* Interrupt message number */
+#define PCI_EXP_DEVCAP		4	/* Device capabilities */
+#define  PCI_EXP_DEVCAP_PAYLOAD	0x07	/* Max_Payload_Size */
+#define  PCI_EXP_DEVCAP_PHANTOM	0x18	/* Phantom functions */
+#define  PCI_EXP_DEVCAP_EXT_TAG	0x20	/* Extended tags */
+#define  PCI_EXP_DEVCAP_L0S	0x1c0	/* L0s Acceptable Latency */
+#define  PCI_EXP_DEVCAP_L1	0xe00	/* L1 Acceptable Latency */
+#define  PCI_EXP_DEVCAP_ATN_BUT	0x1000	/* Attention Button Present */
+#define  PCI_EXP_DEVCAP_ATN_IND	0x2000	/* Attention Indicator Present */
+#define  PCI_EXP_DEVCAP_PWR_IND	0x4000	/* Power Indicator Present */
+#define  PCI_EXP_DEVCAP_PWR_VAL	0x3fc0000 /* Slot Power Limit Value */
+#define  PCI_EXP_DEVCAP_PWR_SCL	0xc000000 /* Slot Power Limit Scale */
+#define PCI_EXP_DEVCTL		8	/* Device Control */
+#define  PCI_EXP_DEVCTL_CERE	0x0001	/* Correctable Error Reporting En. */
+#define  PCI_EXP_DEVCTL_NFERE	0x0002	/* Non-Fatal Error Reporting Enable */
+#define  PCI_EXP_DEVCTL_FERE	0x0004	/* Fatal Error Reporting Enable */
+#define  PCI_EXP_DEVCTL_URRE	0x0008	/* Unsupported Request Reporting En. */
+#define  PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
+#define  PCI_EXP_DEVCTL_PAYLOAD	0x00e0	/* Max_Payload_Size */
+#define  PCI_EXP_DEVCTL_EXT_TAG	0x0100	/* Extended Tag Field Enable */
+#define  PCI_EXP_DEVCTL_PHANTOM	0x0200	/* Phantom Functions Enable */
+#define  PCI_EXP_DEVCTL_AUX_PME	0x0400	/* Auxiliary Power PM Enable */
+#define  PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800  /* Enable No Snoop */
+#define  PCI_EXP_DEVCTL_READRQ	0x7000	/* Max_Read_Request_Size */
+#define PCI_EXP_DEVSTA		10	/* Device Status */
+#define  PCI_EXP_DEVSTA_CED	0x01	/* Correctable Error Detected */
+#define  PCI_EXP_DEVSTA_NFED	0x02	/* Non-Fatal Error Detected */
+#define  PCI_EXP_DEVSTA_FED	0x04	/* Fatal Error Detected */
+#define  PCI_EXP_DEVSTA_URD	0x08	/* Unsupported Request Detected */
+#define  PCI_EXP_DEVSTA_AUXPD	0x10	/* AUX Power Detected */
+#define  PCI_EXP_DEVSTA_TRPND	0x20	/* Transactions Pending */
+#define PCI_EXP_LNKCAP		12	/* Link Capabilities */
+#define PCI_EXP_LNKCTL		16	/* Link Control */
+#define PCI_EXP_LNKSTA		18	/* Link Status */
+#define PCI_EXP_SLTCAP		20	/* Slot Capabilities */
+#define PCI_EXP_SLTCTL		24	/* Slot Control */
+#define PCI_EXP_SLTSTA		26	/* Slot Status */
+#define PCI_EXP_RTCTL		28	/* Root Control */
+#define  PCI_EXP_RTCTL_SECEE	0x01	/* System Error on Correctable Error */
+#define  PCI_EXP_RTCTL_SENFEE	0x02	/* System Error on Non-Fatal Error */
+#define  PCI_EXP_RTCTL_SEFEE	0x04	/* System Error on Fatal Error */
+#define  PCI_EXP_RTCTL_PMEIE	0x08	/* PME Interrupt Enable */
+#define  PCI_EXP_RTCTL_CRSSVE	0x10	/* CRS Software Visibility Enable */
+#define PCI_EXP_RTCAP		30	/* Root Capabilities */
+#define PCI_EXP_RTSTA		32	/* Root Status */
+
+/* Extended Capabilities (PCI-X 2.0 and Express) */
+#define PCI_EXT_CAP_ID(header)		(header & 0x0000ffff)
+#define PCI_EXT_CAP_VER(header)		((header >> 16) & 0xf)
+#define PCI_EXT_CAP_NEXT(header)	((header >> 20) & 0xffc)
+
+#define PCI_EXT_CAP_ID_ERR	1
+#define PCI_EXT_CAP_ID_VC	2
+#define PCI_EXT_CAP_ID_DSN	3
+#define PCI_EXT_CAP_ID_PWR	4
+
+/* Advanced Error Reporting */
+#define PCI_ERR_UNCOR_STATUS	4	/* Uncorrectable Error Status */
+#define  PCI_ERR_UNC_TRAIN	0x00000001	/* Training */
+#define  PCI_ERR_UNC_DLP	0x00000010	/* Data Link Protocol */
+#define  PCI_ERR_UNC_POISON_TLP	0x00001000	/* Poisoned TLP */
+#define  PCI_ERR_UNC_FCP	0x00002000	/* Flow Control Protocol */
+#define  PCI_ERR_UNC_COMP_TIME	0x00004000	/* Completion Timeout */
+#define  PCI_ERR_UNC_COMP_ABORT	0x00008000	/* Completer Abort */
+#define  PCI_ERR_UNC_UNX_COMP	0x00010000	/* Unexpected Completion */
+#define  PCI_ERR_UNC_RX_OVER	0x00020000	/* Receiver Overflow */
+#define  PCI_ERR_UNC_MALF_TLP	0x00040000	/* Malformed TLP */
+#define  PCI_ERR_UNC_ECRC	0x00080000	/* ECRC Error Status */
+#define  PCI_ERR_UNC_UNSUP	0x00100000	/* Unsupported Request */
+#define PCI_ERR_UNCOR_MASK	8	/* Uncorrectable Error Mask */
+	/* Same bits as above */
+#define PCI_ERR_UNCOR_SEVER	12	/* Uncorrectable Error Severity */
+	/* Same bits as above */
+#define PCI_ERR_COR_STATUS	16	/* Correctable Error Status */
+#define  PCI_ERR_COR_RCVR	0x00000001	/* Receiver Error Status */
+#define  PCI_ERR_COR_BAD_TLP	0x00000040	/* Bad TLP Status */
+#define  PCI_ERR_COR_BAD_DLLP	0x00000080	/* Bad DLLP Status */
+#define  PCI_ERR_COR_REP_ROLL	0x00000100	/* REPLAY_NUM Rollover */
+#define  PCI_ERR_COR_REP_TIMER	0x00001000	/* Replay Timer Timeout */
+#define PCI_ERR_COR_MASK	20	/* Correctable Error Mask */
+	/* Same bits as above */
+#define PCI_ERR_CAP		24	/* Advanced Error Capabilities */
+#define  PCI_ERR_CAP_FEP(x)	((x) & 31)	/* First Error Pointer */
+#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
+#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
+#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
+#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
+#define PCI_ERR_HEADER_LOG	28	/* Header Log Register (16 bytes) */
+#define PCI_ERR_ROOT_COMMAND	44	/* Root Error Command */
+#define PCI_ERR_ROOT_STATUS	48
+#define PCI_ERR_ROOT_COR_SRC	52
+#define PCI_ERR_ROOT_SRC	54
+
+/* Virtual Channel */
+#define PCI_VC_PORT_REG1	4
+#define PCI_VC_PORT_REG2	8
+#define PCI_VC_PORT_CTRL	12
+#define PCI_VC_PORT_STATUS	14
+#define PCI_VC_RES_CAP		16
+#define PCI_VC_RES_CTRL		20
+#define PCI_VC_RES_STATUS	26
+
+/* Power Budgeting */
+#define PCI_PWR_DSR		4	/* Data Select Register */
+#define PCI_PWR_DATA		8	/* Data Register */
+#define  PCI_PWR_DATA_BASE(x)	((x) & 0xff)	    /* Base Power */
+#define  PCI_PWR_DATA_SCALE(x)	(((x) >> 8) & 3)    /* Data Scale */
+#define  PCI_PWR_DATA_PM_SUB(x)	(((x) >> 10) & 7)   /* PM Sub State */
+#define  PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
+#define  PCI_PWR_DATA_TYPE(x)	(((x) >> 15) & 7)   /* Type */
+#define  PCI_PWR_DATA_RAIL(x)	(((x) >> 18) & 7)   /* Power Rail */
+#define PCI_PWR_CAP		12	/* Capability */
+#define  PCI_PWR_CAP_BUDGET(x)	((x) & 1)	/* Included in system budget */
+
 
 /*
  * The PCI interface treats multi-function devices as independent
diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h
index c0ccdd0..7dba234 100644
--- a/src/include/device/pci_ids.h
+++ b/src/include/device/pci_ids.h
@@ -137,12 +137,14 @@
 #define PCI_DEVICE_ID_COMPAQ_SMART2P	0xae10
 #define PCI_DEVICE_ID_COMPAQ_NETEL100	0xae32
 #define PCI_DEVICE_ID_COMPAQ_NETEL10	0xae34
+#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33
 #define PCI_DEVICE_ID_COMPAQ_NETFLEX3I	0xae35
 #define PCI_DEVICE_ID_COMPAQ_NETEL100D	0xae40
 #define PCI_DEVICE_ID_COMPAQ_NETEL100PI	0xae43
 #define PCI_DEVICE_ID_COMPAQ_NETEL100I	0xb011
 #define PCI_DEVICE_ID_COMPAQ_CISS	0xb060
 #define PCI_DEVICE_ID_COMPAQ_CISSB	0xb178
+#define PCI_DEVICE_ID_COMPAQ_CISSC	0x46
 #define PCI_DEVICE_ID_COMPAQ_THUNDER	0xf130
 #define PCI_DEVICE_ID_COMPAQ_NETFLEX3B	0xf150
 
@@ -165,6 +167,7 @@
 #define PCI_DEVICE_ID_LSI_53C1010_33	0x0020
 #define PCI_DEVICE_ID_LSI_53C1010_66	0x0021
 #define PCI_DEVICE_ID_LSI_53C1030	0x0030
+#define PCI_DEVICE_ID_LSI_1030_53C1035	0x0032
 #define PCI_DEVICE_ID_LSI_53C1035	0x0040
 #define PCI_DEVICE_ID_NCR_53C875J	0x008f
 #define PCI_DEVICE_ID_LSI_FC909		0x0621
@@ -172,9 +175,21 @@
 #define PCI_DEVICE_ID_LSI_FC929_LAN	0x0623
 #define PCI_DEVICE_ID_LSI_FC919		0x0624
 #define PCI_DEVICE_ID_LSI_FC919_LAN	0x0625
+#define PCI_DEVICE_ID_LSI_FC929X	0x0626
+#define PCI_DEVICE_ID_LSI_FC939X	0x0642
+#define PCI_DEVICE_ID_LSI_FC949X	0x0640
+#define PCI_DEVICE_ID_LSI_FC919X	0x0628
 #define PCI_DEVICE_ID_NCR_YELLOWFIN	0x0701
 #define PCI_DEVICE_ID_LSI_61C102	0x0901
 #define PCI_DEVICE_ID_LSI_63C815	0x1000
+#define PCI_DEVICE_ID_LSI_SAS1064	0x0050
+#define PCI_DEVICE_ID_LSI_SAS1066	0x005E
+#define PCI_DEVICE_ID_LSI_SAS1068	0x0054
+#define PCI_DEVICE_ID_LSI_SAS1064A	0x005C
+#define PCI_DEVICE_ID_LSI_SAS1064E	0x0056
+#define PCI_DEVICE_ID_LSI_SAS1066E	0x005A
+#define PCI_DEVICE_ID_LSI_SAS1068E	0x0058
+#define PCI_DEVICE_ID_LSI_SAS1078	0x0060
 
 #define PCI_VENDOR_ID_ATI		0x1002
 /* Mach64 */
@@ -901,6 +916,33 @@
 #define PCI_DEVICE_ID_NVIDIA_UTNT2		0x0029
 #define PCI_DEVICE_ID_NVIDIA_VTNT2		0x002C
 #define PCI_DEVICE_ID_NVIDIA_UVTNT2		0x002D
+#define PCI_DEVICE_ID_NVIDIA_CK804_LPC          0x0050
+#define PCI_DEVICE_ID_NVIDIA_CK804_PRO          0x0051
+#define PCI_DEVICE_ID_NVIDIA_CK804_ISA          0x0051
+#define PCI_DEVICE_ID_NVIDIA_CK804_SMB          0x0052
+#define PCI_DEVICE_ID_NVIDIA_CK804_SM           0x0052
+#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI         0x0052
+#define PCI_DEVICE_ID_NVIDIA_CK804_IDE          0x0053
+#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0        0x0054
+#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1        0x0055
+#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1        0x0055
+#define PCI_DEVICE_ID_NVIDIA_CK804_ENET         0x0056
+#define PCI_DEVICE_ID_NVIDIA_CK804_NIC          0x0056
+#define PCI_DEVICE_ID_NVIDIA_CK804_ENET2        0x0057
+#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE   0x0057
+#define PCI_DEVICE_ID_NVIDIA_CK804_MODEM        0x0058
+#define PCI_DEVICE_ID_NVIDIA_CK804_MCI          0x0058
+#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO        0x0059
+#define PCI_DEVICE_ID_NVIDIA_CK804_ACI          0x0059
+#define PCI_DEVICE_ID_NVIDIA_CK804_USB          0x005A
+#define PCI_DEVICE_ID_NVIDIA_CK804_USB2         0x005B
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCI          0x005C
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE         0x005D
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E        0x005D
+#define PCI_DEVICE_ID_NVIDIA_CK804_MEM          0x005E
+#define PCI_DEVICE_ID_NVIDIA_CK804_HT           0x005E
+#define PCI_DEVICE_ID_NVIDIA_CK804_TRIM         0x005f
+#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE        0x00d3
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR	0x0100
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR	0x0101
@@ -919,23 +961,6 @@
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2		0x0202
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC		0x0203
 
-#define PCI_DEVICE_ID_NVIDIA_CK804_HT           0x005e
-#define PCI_DEVICE_ID_NVIDIA_CK804_LPC          0x0050
-#define PCI_DEVICE_ID_NVIDIA_CK804_PRO          0x0051
-#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE        0x00d3
-#define PCI_DEVICE_ID_NVIDIA_CK804_SM           0x0052
-#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI         0x0052
-#define PCI_DEVICE_ID_NVIDIA_CK804_USB          0x005a
-#define PCI_DEVICE_ID_NVIDIA_CK804_USB2         0x005b
-#define PCI_DEVICE_ID_NVIDIA_CK804_NIC          0x0056
-#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE   0x0057
-#define PCI_DEVICE_ID_NVIDIA_CK804_ACI          0x0059
-#define PCI_DEVICE_ID_NVIDIA_CK804_MCI          0x0058
-#define PCI_DEVICE_ID_NVIDIA_CK804_IDE          0x0053
-#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0        0x0054
-#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1        0x0055
-#define PCI_DEVICE_ID_NVIDIA_CK804_PCI          0x005c
-#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E        0x005d
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_8849		0x8849
@@ -1812,7 +1837,9 @@
 #define PCI_DEVICE_ID_INTEL_6300ESB_USB2 0x25aa
 #define PCI_DEVICE_ID_INTEL_6300ESB_USB3 0x25ad
 #define PCI_DEVICE_ID_INTEL_6300ESB_SATA 0x25a3
+#define PCI_DEVICE_ID_INTEL_6300ESB_SATA_R 0x25b0
 #define PCI_DEVICE_ID_INTEL_6300ESB_PIC1 0x25ac
+#define PCI_DEVICE_ID_INTEL_6300ESB_BRIDGE1C 0x25ae
 #define PCI_DEVICE_ID_INTEL_80310	0x530d
 #define PCI_DEVICE_ID_INTEL_82810_MC1	0x7120
 #define PCI_DEVICE_ID_INTEL_82810_IG1	0x7121
diff --git a/src/include/device/pciexp.h b/src/include/device/pciexp.h
new file mode 100644
index 0000000..9ea662d
--- /dev/null
+++ b/src/include/device/pciexp.h
@@ -0,0 +1,11 @@
+#ifndef DEVICE_PCIEXP_H
+#define DEVICE_PCIEXP_H
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+unsigned int pciexp_scan_bus(struct bus *bus, 
+	unsigned min_devfn, unsigned max_devfn, unsigned int max);
+unsigned int pciexp_scan_bridge(device_t dev, unsigned int max);
+
+extern struct device_operations default_pciexp_ops_bus;
+
+#endif /* DEVICE_PCIEXP_H */
diff --git a/src/include/device/pcix.h b/src/include/device/pcix.h
new file mode 100644
index 0000000..8bf1935
--- /dev/null
+++ b/src/include/device/pcix.h
@@ -0,0 +1,12 @@
+#ifndef DEVICE_PCIX_H
+#define DEVICE_PCIX_H
+/* (c) 2005 Linux Networx GPL see COPYING for details */
+
+unsigned int pcix_scan_bus(struct bus *bus, 
+	unsigned min_devfn, unsigned max_devfn, unsigned int max);
+unsigned int pcix_scan_bridge(device_t dev, unsigned int max);
+const char *pcix_speed(unsigned sstatus);
+
+extern struct device_operations default_pcix_ops_bus;
+
+#endif /* DEVICE_PCIX_H */
diff --git a/src/include/device/resource.h b/src/include/device/resource.h
index a5c7f0a..902cf68 100644
--- a/src/include/device/resource.h
+++ b/src/include/device/resource.h
@@ -98,4 +98,7 @@
 	unsigned long type_mask, unsigned long type,
 	resource_search_t search, void *gp);
 
+#define RESOURCE_TYPE_MAX 20
+extern const char *resource_type(struct resource *resource);
+
 #endif /* RESOURCE_H */
diff --git a/src/include/part/fallback_boot.h b/src/include/part/fallback_boot.h
index 7d6e790..17db5c6 100644
--- a/src/include/part/fallback_boot.h
+++ b/src/include/part/fallback_boot.h
@@ -4,11 +4,13 @@
 #ifndef ASSEMBLY
 
 #if HAVE_FALLBACK_BOOT == 1
-void boot_successful(void);
+void set_boot_successful(void);
 #else
-#define boot_successful()
+#define set_boot_successful()
 #endif
 
+void boot_successful(void);
+
 #endif /* ASSEMBLY */
 
 #define RTC_BOOT_BYTE	48
diff --git a/src/include/part/watchdog.h b/src/include/part/watchdog.h
new file mode 100644
index 0000000..4374f30
--- /dev/null
+++ b/src/include/part/watchdog.h
@@ -0,0 +1,10 @@
+#ifndef PART_WATCHDOG_H
+#define PART_WATCHDOG_H
+
+#if USE_WATCHDOG_ON_BOOT == 1
+void watchdog_off(void);
+#else
+#define watchdog_off()
+#endif
+
+#endif /* PART_WATCHDOG_H */
diff --git a/src/lib/Config.lb b/src/lib/Config.lb
index 32566d2..3a1baf6 100644
--- a/src/lib/Config.lb
+++ b/src/lib/Config.lb
@@ -9,9 +9,7 @@
 object memmove.o
 object malloc.o
 object delay.o
-if HAVE_FALLBACK_BOOT
-	object fallback_boot.o
-end
+object fallback_boot.o
 object compute_ip_checksum.o
 object version.o
 # Force version.o to recompile every time
diff --git a/src/lib/clog2.c b/src/lib/clog2.c
index 41e2af9..b9b1731 100644
--- a/src/lib/clog2.c
+++ b/src/lib/clog2.c
@@ -4,16 +4,19 @@
 #include <console/console.h>
 #endif
 
+/* Assume 8 bits per byte */
+#define CHAR_BIT 8
+
 unsigned long log2(unsigned long x)
 {
         // assume 8 bits per byte.
-        unsigned long i = 1 << (sizeof(x)*8 - 1);
-        unsigned long pow = sizeof(x) * 8 - 1;
+        unsigned long i = 1ULL << (sizeof(x)* CHAR_BIT - 1ULL);
+        unsigned long pow = sizeof(x) * CHAR_BIT - 1ULL;
 
         if (! x) {
 #ifdef DEBUG_LOG2
                 printk_warning("%s called with invalid parameter of 0\n",
-			__FUNCTION__);
+			__func__);
 #endif
                 return -1;
         }
diff --git a/src/lib/fallback_boot.c b/src/lib/fallback_boot.c
index fe34e08..9e892dd 100644
--- a/src/lib/fallback_boot.c
+++ b/src/lib/fallback_boot.c
@@ -1,9 +1,12 @@
 #include <console/console.h>
 #include <part/fallback_boot.h>
+#include <part/watchdog.h>
 #include <pc80/mc146818rtc.h>
 #include <arch/io.h>
 
-void boot_successful(void)
+
+#if HAVE_FALLBACK_BOOT == 1
+void set_boot_successful(void)
 {
 	/* Remember I succesfully booted by setting
 	 * the initial boot direction
@@ -23,3 +26,13 @@
 		byte &= 0x0f;
 	outb(byte, RTC_PORT(1));
 }
+#endif
+
+void boot_successful(void)
+{
+	/* Remember this was a successful boot */
+	set_boot_successful();
+
+	/* turn off the boot watchdog */
+	watchdog_off();
+}
diff --git a/src/mainboard/Iwill/DK8S2/Config.lb b/src/mainboard/Iwill/DK8S2/Config.lb
index 661cadc..22c589f 100644
--- a/src/mainboard/Iwill/DK8S2/Config.lb
+++ b/src/mainboard/Iwill/DK8S2/Config.lb
@@ -45,6 +45,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
 
 ## ATI Rage XL framebuffering graphics driver
 dir /drivers/ati/ragexl
@@ -129,7 +130,7 @@
 dir /pc80
 config chip.h
 
-# config for arima/hdama
+# config for Iwill/DK8S2
 chip northbridge/amd/amdk8/root_complex
 	device pci_domain 0 on
 		chip northbridge/amd/amdk8
@@ -189,7 +190,7 @@
 					end
 					device pci 1.1 on end
 					device pci 1.2 on end
-					device pci 1.3 on end 
+					device pci 1.3 on end
 					device pci 1.5 off end
 					device pci 1.6 off end
 				end
@@ -208,7 +209,7 @@
 			device pci 19.2 on end
 			device pci 19.3 on end
 		end
-	end 
+	end
 	device apic_cluster 0 on
 		chip cpu/amd/socket_940
 			device apic 0 on end
diff --git a/src/mainboard/Iwill/DK8S2/Options.lb b/src/mainboard/Iwill/DK8S2/Options.lb
index d7b694d..5cb440f 100644
--- a/src/mainboard/Iwill/DK8S2/Options.lb
+++ b/src/mainboard/Iwill/DK8S2/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -76,13 +73,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/Iwill/DK8S2/reset.c b/src/mainboard/Iwill/DK8S2/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/Iwill/DK8S2/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/Iwill/DK8X/Config.lb b/src/mainboard/Iwill/DK8X/Config.lb
index d8fc0cb..59f3828 100644
--- a/src/mainboard/Iwill/DK8X/Config.lb
+++ b/src/mainboard/Iwill/DK8X/Config.lb
@@ -45,6 +45,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
 
 ##
 ## Romcc output
diff --git a/src/mainboard/Iwill/DK8X/Options.lb b/src/mainboard/Iwill/DK8X/Options.lb
index 0f413f0..6265e72 100644
--- a/src/mainboard/Iwill/DK8X/Options.lb
+++ b/src/mainboard/Iwill/DK8X/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -76,13 +73,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/Iwill/DK8X/reset.c b/src/mainboard/Iwill/DK8X/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/Iwill/DK8X/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/amd/quartet/Config.lb b/src/mainboard/amd/quartet/Config.lb
index 2d818d4..5adaf35 100644
--- a/src/mainboard/amd/quartet/Config.lb
+++ b/src/mainboard/amd/quartet/Config.lb
@@ -41,6 +41,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
 
 ##
 ## Romcc output
diff --git a/src/mainboard/amd/quartet/Options.lb b/src/mainboard/amd/quartet/Options.lb
index 7e2dc48..f1013ea 100644
--- a/src/mainboard/amd/quartet/Options.lb
+++ b/src/mainboard/amd/quartet/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -75,13 +72,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/amd/quartet/reset.c b/src/mainboard/amd/quartet/reset.c
new file mode 100644
index 0000000..6395818
--- /dev/null
+++ b/src/mainboard/amd/quartet/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 2);
+}
diff --git a/src/mainboard/amd/serenade/Config.lb b/src/mainboard/amd/serenade/Config.lb
index 4fdc235..deac98b 100644
--- a/src/mainboard/amd/serenade/Config.lb
+++ b/src/mainboard/amd/serenade/Config.lb
@@ -41,6 +41,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
 
 ##
 ## Romcc output
diff --git a/src/mainboard/amd/serenade/Options.lb b/src/mainboard/amd/serenade/Options.lb
index fedc518..a26f270 100644
--- a/src/mainboard/amd/serenade/Options.lb
+++ b/src/mainboard/amd/serenade/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -74,13 +71,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/amd/serenade/reset.c b/src/mainboard/amd/serenade/reset.c
new file mode 100644
index 0000000..6395818
--- /dev/null
+++ b/src/mainboard/amd/serenade/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 2);
+}
diff --git a/src/mainboard/amd/solo/Config.lb b/src/mainboard/amd/solo/Config.lb
index fdf3c1c..6feb8b1 100644
--- a/src/mainboard/amd/solo/Config.lb
+++ b/src/mainboard/amd/solo/Config.lb
@@ -42,6 +42,7 @@
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
 if HAVE_ACPI_TABLES object acpi_tables.o end
+object reset.o
 
 ##
 ## Romcc output
diff --git a/src/mainboard/amd/solo/Options.lb b/src/mainboard/amd/solo/Options.lb
index 4261144..87a2ceb 100644
--- a/src/mainboard/amd/solo/Options.lb
+++ b/src/mainboard/amd/solo/Options.lb
@@ -4,9 +4,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -76,13 +73,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/amd/solo/reset.c b/src/mainboard/amd/solo/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/amd/solo/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/arima/hdama/Config.lb b/src/mainboard/arima/hdama/Config.lb
index a9df17b..0b04d51 100644
--- a/src/mainboard/arima/hdama/Config.lb
+++ b/src/mainboard/arima/hdama/Config.lb
@@ -29,7 +29,7 @@
 ## XIP_ROM_SIZE must be a power of 2.
 ## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
 ##
-default XIP_ROM_SIZE=65536
+default XIP_ROM_SIZE=131072
 default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
 
 ##
@@ -45,13 +45,13 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 
 ##
 ## Romcc output
 ##
 makerule ./failover.E
-	depends "$(MAINBOARD)/failover.c ./romcc" 
+	depends "$(MAINBOARD)/failover.c ./romcc"
 	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
 end
 
@@ -60,11 +60,11 @@
 	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
 end
 
-makerule ./auto.E 
-	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+makerule ./auto.E
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc"
 	action	"./romcc -E -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
 end
-makerule ./auto.inc 
+makerule ./auto.inc
 	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
 	action	"./romcc    -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
 end
@@ -129,61 +129,122 @@
 
 # config for arima/hdama
 chip northbridge/amd/amdk8/root_complex
-	device apic_cluster 0 on
-		chip cpu/amd/socket_940
-			device apic 0 on end
-		end
-		chip cpu/amd/socket_940
-			device apic 1 on end
-		end
-	end
 	device pci_domain 0 on
 		chip northbridge/amd/amdk8
 			device pci 18.0 on #  northbridge 
 				#  devices on link 0, link 0 == LDT 0 
 				chip southbridge/amd/amd8131
 					# the on/off keyword is mandatory
-					device pci 0.0 on end	# PCIX bridge
+					device pci 0.0 on	# PCIX bridge
+						## On board NIC A
+						#chip drivers/generic/generic
+						#	device pci 3.0 on	
+						#		irq 0 = 0x13
+						#	end
+						#end
+						## On board NIC B
+						#chip drivers/generic/generic
+						#	device pci 4.0 on
+						#		irq 0 = 0x13
+						#	end
+						#end
+						## PCI Slot 3
+						#chip drivers/generic/generic
+						#	device pci 1.0 on
+						#		irq 0 = 0x11
+						#		irq 1 = 0x12
+						#		irq 2 = 0x13
+						#		irq 3 = 0x10
+						#	end
+						#end 
+						## PCI Slot 4
+						#chip drivers/generic/generic
+						#	device pci 2.0 on
+						#		irq 0 = 0x12
+						#		irq 1 = 0x13
+						#		irq 2 = 0x10
+						#		irq 3 = 0x11
+						#	end
+						#end 
+					end
 					device pci 0.1 on end	# IOAPIC
-					device pci 1.0 on end	# PCIX bridge
-					device pci 1.1 on end	# IOAPIC 
+					device pci 1.0 on 	# PCIX bridge
+						## PCI Slot 1
+						#chip drivers/generic/generic
+						#	device pci 1.0 on
+						#		irq 0 = 0x11
+						#		irq 1 = 0x12
+						#		irq 2 = 0x13
+						#		irq 3 = 0x10
+						#	end
+						#end
+						## PCI Slot 2
+						#chip drivers/generic/generic
+						#	device pci 2.0 on
+						#		irq 0 = 0x12
+						#		irq 1 = 0x13
+						#		irq 2 = 0x10
+						#		irq 3 = 0x11
+						#	end
+						#end 
+					end
+					device pci 1.1 on end	# IOAPIC
 				end
 				chip southbridge/amd/amd8111
 					# this "device pci 0.0" is the parent of the next one
 					# PCI bridge
 					device pci 0.0 on
-						device pci 0.0 on  end # USB0
-						device pci 0.1 on  end # USB1
-						device pci 0.2 off end # USB 2.0
-						device pci 1.0 off end # LAN
+						device pci 0.0 on  end	# USB0
+						device pci 0.1 on  end	# USB1
+						device pci 0.2 off end	# USB 2.0
+						device pci 1.0 off end	# LAN
 						chip drivers/pci/onboard
 							device pci 6.0 on end # ATI Rage XL
 							register "rom_address" = "0xfff80000"
 						end
+						## PCI Slot 5 (correct?)
+						#chip drivers/generic/generic
+						#	device pci 5.0 on
+						#		irq 0 = 0x11
+						#		irq 1 = 0x12
+						#		irq 2 = 0x13
+						#		irq 3 = 0x10
+						#	end
+						#end 
+						## PCI Slot 6 (correct?)
+						#chip drivers/generic/generic
+						#	device pci 4.0 on
+						#		irq 0 = 0x10
+						#		irq 1 = 0x11
+						#		irq 2 = 0x12
+						#		irq 3 = 0x13
+						#	end
+						#end 
+
 					end
 					# LPC bridge
 					device pci 1.0 on
 						chip superio/NSC/pc87360
-							device	pnp 2e.0 off	# Floppy 
+							device	pnp 2e.0 off  # Floppy 
 								 io 0x60 = 0x3f0
 								irq 0x70 = 6
 								drq 0x74 = 2
 							end
-							device pnp 2e.1 off	# Parallel Port
+							device pnp 2e.1 off  # Parallel Port
 								 io 0x60 = 0x378
 								irq 0x70 = 7
 							end
-							device pnp 2e.2 off	# Com 2
+							device pnp 2e.2 off # Com 2
 								 io 0x60 = 0x2f8
 								irq 0x70 = 3
 							end
-							device pnp 2e.3 on	# Com 1
+							device pnp 2e.3 on  # Com 1
 								 io 0x60 = 0x3f8
 								irq 0x70 = 4
 							end
 							device pnp 2e.4 off end # SWC
 							device pnp 2e.5 off end # Mouse
-							device pnp 2e.6 on	# Keyboard
+							device pnp 2e.6 on  # Keyboard
 								 io 0x60 = 0x60
 								 io 0x62 = 0x64
 								irq 0x70 = 1
@@ -239,7 +300,7 @@
 					register "ide0_enable" = "1"
 					register "ide1_enable" = "1"
 				end
-			end # device pci 18.0 
+			end #  device pci 18.0 
 			
 			device pci 18.0 on end # LDT1
 			device pci 18.0 on end # LDT2
@@ -255,6 +316,14 @@
 			device pci 19.2 on end
 			device pci 19.3 on end
 		end
+	end 
+	device apic_cluster 0 on
+		chip cpu/amd/socket_940
+			device apic 0 on end
+		end
+		chip cpu/amd/socket_940
+			device apic 1 on end
+		end
 	end
 end
 
diff --git a/src/mainboard/arima/hdama/Options.lb b/src/mainboard/arima/hdama/Options.lb
index 773d698..9d70f5b 100644
--- a/src/mainboard/arima/hdama/Options.lb
+++ b/src/mainboard/arima/hdama/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -80,13 +77,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/arima/hdama/auto.c b/src/mainboard/arima/hdama/auto.c
index b4d9553..7790b3e 100644
--- a/src/mainboard/arima/hdama/auto.c
+++ b/src/mainboard/arima/hdama/auto.c
@@ -11,6 +11,7 @@
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
+#include "northbridge/amd/amdk8/cpu_rev.c"
 #include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
@@ -18,28 +19,59 @@
 #include "lib/delay.c"
 #include "cpu/x86/lapic/boot_cpu.c"
 #include "northbridge/amd/amdk8/reset_test.c"
-#include "northbridge/amd/amdk8/debug.c"
-#include "northbridge/amd/amdk8/cpu_rev.c"
 #include "superio/NSC/pc87360/pc87360_early_serial.c"
 #include "cpu/amd/mtrr/amd_earlymtrr.c"
 #include "cpu/x86/bist.h"
 
 #define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+	unsigned reg;
+
+	for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+		unsigned config_map;
+		config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+		if ((config_map & 3) != 3) {
+			continue;
+		}
+		if ((((config_map >> 4) & 7) == node) &&
+			(((config_map >> 8) & 3) == link)) 
+		{
+			return (config_map >> 16) & 0xff;
+		}
+	}
+	return 0;
+}
+
 static void hard_reset(void)
 {
-	set_bios_reset();
+	device_t dev;
 
+	/* Find the device */
+	dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
+	
 	/* enable cf9 */
-	pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+	pci_write_config8(dev, 0x41, 0xf1);
+
 	/* reset */
+	set_bios_reset();
 	outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+	device_t dev;
+	
+	/* Find the device */
+	dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
+
+	/* Reset */
 	set_bios_reset();
-	pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+	pci_write_config8(dev, 0x47, 1);
 }
 
 /*
@@ -128,6 +160,7 @@
 #include "northbridge/amd/amdk8/coherent_ht.c"
 #include "sdram/generic_sdram.c"
 #include "northbridge/amd/amdk8/resourcemap.c"
+#include "debug.c"
 
 #define FIRST_CPU  1
 #define SECOND_CPU 1
@@ -160,13 +193,14 @@
 	};
 
 	int needs_reset;
-	unsigned nodeid;
 	if (bist == 0) {
+		unsigned nodeid;
 		/* Skip this if there was a built in self test failure */
 		amd_early_mtrr_init();
 		enable_lapic();
 		init_timer();
 		nodeid = lapicid() & 0xf;
+
 		/* Has this cpu already booted? */
 		if (cpu_init_detected(nodeid)) {
 			asm volatile ("jmp __cpu_reset");
@@ -191,13 +225,12 @@
 		print_info("ht reset -\r\n");
 		soft_reset();
 	}
-
 #if 0
 	print_pci_devices();
 #endif
 	enable_smbus();
 #if 0
-	dump_spd_registers(&cpu[0]);
+	dump_spd_registers(sizeof(cpu)/sizeof(cpu[0]), cpu);
 #endif
 
 	memreset_setup();
@@ -205,6 +238,8 @@
 
 #if 0
 	dump_pci_devices();
+#endif
+#if 0
 	dump_pci_device(PCI_DEV(0, 0x18, 2));
 #endif
 
diff --git a/src/mainboard/arima/hdama/debug.c b/src/mainboard/arima/hdama/debug.c
new file mode 100644
index 0000000..55c6264
--- /dev/null
+++ b/src/mainboard/arima/hdama/debug.c
@@ -0,0 +1,143 @@
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+static void dump_spd_registers(int controllers, const struct mem_controller *ctrl)
+{
+	int n;
+	for(n = 0; n < controllers; n++) {
+		int i;
+		print_debug("\r\n");
+		activate_spd_rom(&ctrl[n]);
+		for(i = 0; i < 4; i++) {
+			unsigned device;
+			device = ctrl[n].channel0[i];
+			if (device) {
+				int j;
+				print_debug("dimm: "); 
+				print_debug_hex8(n);
+				print_debug_char('.');
+				print_debug_hex8(i); 
+				print_debug(".0: ");
+				print_debug_hex8(device);
+				for(j = 0; j < 256; j++) {
+					int status;
+					unsigned char byte;
+					if ((j & 0xf) == 0) {
+						print_debug("\r\n");
+						print_debug_hex8(j);
+						print_debug(": ");
+					}
+					status = spd_read_byte(device, j);
+					if (status < 0) {
+						print_debug("bad device\r\n");
+						break;
+					}
+#if 0
+					byte = status & 0xff;
+					print_debug_hex8(byte);
+#else
+					print_debug_hex8(status & 0xff);
+#endif
+					print_debug_char(' ');
+				}
+				print_debug("\r\n");
+			}
+			device = ctrl[n].channel1[i];
+			if (device) {
+				int j;
+				print_debug("dimm: "); 
+				print_debug_hex8(n);
+				print_debug_char('.');
+				print_debug_hex8(i); 
+				print_debug(".1: ");
+				print_debug_hex8(device);
+				for(j = 0; j < 256; j++) {
+					int status;
+					unsigned char byte;
+					if ((j & 0xf) == 0) {
+						print_debug("\r\n");
+						print_debug_hex8(j);
+						print_debug(": ");
+					}
+					status = spd_read_byte(device, j);
+					if (status < 0) {
+						print_debug("bad device\r\n");
+						break;
+					}
+#if 0
+					byte = status & 0xff;
+					print_debug_hex8(byte);
+#else
+					print_debug_hex8(status & 0xff);
+#endif
+					print_debug_char(' ');
+				}
+				print_debug("\r\n");
+			}
+		}
+	}
+}
diff --git a/src/mainboard/arima/hdama/mptable.c b/src/mainboard/arima/hdama/mptable.c
index 9287b73..ef32251 100644
--- a/src/mainboard/arima/hdama/mptable.c
+++ b/src/mainboard/arima/hdama/mptable.c
@@ -4,6 +4,40 @@
 #include <string.h>
 #include <stdint.h>
 
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+	device_t dev;
+	unsigned reg;
+
+	dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+	if (!dev) {
+		return 0;
+	}
+	for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+		uint32_t config_map;
+		unsigned dst_node;
+		unsigned dst_link;
+		unsigned bus_base;
+		config_map = pci_read_config32(dev, reg);
+		if ((config_map & 3) != 3) {
+			continue;
+		}
+		dst_node = (config_map >> 4) & 7;
+		dst_link = (config_map >> 8) & 3;
+		bus_base = (config_map >> 16) & 0xff;
+#if 0				
+		printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+			dst_node, dst_link, bus_base,
+			reg, config_map);
+#endif
+		if ((dst_node == node) && (dst_link == link)) 
+		{
+			return bus_base;
+		}
+	}
+	return 0;
+}
+
 void *smp_write_config_table(void *v)
 {
 	static const char sig[4] = "PCMP";
@@ -12,6 +46,7 @@
 	struct mp_config_table *mc;
 	unsigned char bus_num;
 	unsigned char bus_isa;
+	unsigned char bus_chain_0;
 	unsigned char bus_8131_1;
 	unsigned char bus_8131_2;
 	unsigned char bus_8111_1;
@@ -38,8 +73,15 @@
 	{
 		device_t dev;
 
+		/* HT chain 0 */
+		bus_chain_0 = node_link_to_bus(0, 0);
+		if (bus_chain_0 == 0) {
+			printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+			bus_chain_0 = 1;
+		}
+
 		/* 8111 */
-		dev = dev_find_slot(1, PCI_DEVFN(0x03,0));
+		dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
 		if (dev) {
 			bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
@@ -52,7 +94,7 @@
 			bus_isa = 5;
 		}
 		/* 8131-1 */
-		dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
+		dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
 		if (dev) {
 			bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 
@@ -63,7 +105,7 @@
 			bus_8131_1 = 2;
 		}
 		/* 8131-2 */
-		dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
+		dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
 		if (dev) {
 			bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 
@@ -87,7 +129,7 @@
 		device_t dev;
 		struct resource *res;
 		/* 8131 apic 3 */
-		dev = dev_find_slot(1, PCI_DEVFN(0x01,1));
+		dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,1));
 		if (dev) {
 			res = find_resource(dev, PCI_BASE_ADDRESS_0);
 			if (res) {
@@ -95,7 +137,7 @@
 			}
 		}
 		/* 8131 apic 4 */
-		dev = dev_find_slot(1, PCI_DEVFN(0x02,1));
+		dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,1));
 		if (dev) {
 			res = find_resource(dev, PCI_BASE_ADDRESS_0);
 			if (res) {
diff --git a/src/mainboard/arima/hdama/reset.c b/src/mainboard/arima/hdama/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/arima/hdama/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/emulation/qemu-i386/Options.lb b/src/mainboard/emulation/qemu-i386/Options.lb
index 9047dc6..d12a1c3 100644
--- a/src/mainboard/emulation/qemu-i386/Options.lb
+++ b/src/mainboard/emulation/qemu-i386/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -73,13 +70,6 @@
 default HAVE_HARD_RESET=0
 
 ##
-## Funky hard reset implementation
-## 
-# default HARD_RESET_BUS=1
-# default HARD_RESET_DEVICE=4
-# default HARD_RESET_FUNCTION=0
- 
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=0
diff --git a/src/mainboard/ibm/e325/Config.lb b/src/mainboard/ibm/e325/Config.lb
index 604a82d..1633c8f 100644
--- a/src/mainboard/ibm/e325/Config.lb
+++ b/src/mainboard/ibm/e325/Config.lb
@@ -45,6 +45,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
 
 ##
 ## Romcc output
diff --git a/src/mainboard/ibm/e325/Options.lb b/src/mainboard/ibm/e325/Options.lb
index 9bad5956..a1b21fd 100644
--- a/src/mainboard/ibm/e325/Options.lb
+++ b/src/mainboard/ibm/e325/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -75,13 +72,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/ibm/e325/reset.c b/src/mainboard/ibm/e325/reset.c
new file mode 100644
index 0000000..7f58d01
--- /dev/null
+++ b/src/mainboard/ibm/e325/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 1);
+}
diff --git a/src/mainboard/intel/jarrell/Config.lb b/src/mainboard/intel/jarrell/Config.lb
new file mode 100644
index 0000000..adca342
--- /dev/null
+++ b/src/mainboard/intel/jarrell/Config.lb
@@ -0,0 +1,213 @@
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=131072
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc" 
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc 
+	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc    -mcpu=p4 -fno-simplify-phi -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc
+	ldscript /cpu/x86/16bit/reset16.lds
+else
+	mainboardinit cpu/x86/32bit/reset32.inc
+	ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/E7520
+	device pci_domain 0 on 
+		device pci 00.0 on end
+		device pci 00.1 on end
+		device pci 01.0 on end
+		device pci 02.0 on 
+			chip southbridge/intel/pxhd # pxhd1
+				device pci 00.0 on end
+				device pci 00.1 on end
+				device pci 00.2 on
+					chip drivers/generic/generic
+						device pci 04.0 on end
+						device pci 04.1 on end
+					end
+				end
+				device pci 00.3 on end
+			end
+		end
+		device pci 06.0 on end
+		chip southbridge/intel/ich5r # ich5r
+			device pci 1d.0 on end
+			device pci 1d.1 on end
+			device pci 1d.2 on end
+			device pci 1d.3 off end
+			device pci 1d.7 on end
+			device pci 1e.0 on
+				chip drivers/ati/ragexl
+					device pci 0c.0 on end
+				end
+			end
+			device pci 1f.0 on 
+				chip superio/NSC/pc87427
+					device pnp 2e.0 off end
+					device pnp 2e.2 on
+#						 io 0x60 = 0x2f8
+#						irq 0x70 = 3
+						 io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.3 on
+#						 io 0x60 = 0x3f8
+#						irq 0x70 = 4
+						 io 0x60 = 0x2f8
+						irq 0x70 = 3
+					end
+					device pnp 2e.4 off end
+					device pnp 2e.5 off end
+					device pnp 2e.6 on
+						 io 0x60 = 0x60
+						 io 0x62 = 0x64
+						irq 0x70 = 1
+					end
+					device pnp 2e.7 off end
+					device pnp 2e.9 off end
+					device pnp 2e.a off end
+					device pnp 2e.f on end
+					device pnp 2e.10 off end
+					device pnp 2e.14 off end
+				end
+			end
+			device pci 1f.1 on end
+			device pci 1f.2 off end
+			device pci 1f.3 on end 
+			device pci 1f.5 off end
+			device pci 1f.6 off end
+			register "gpio[40]" = "ICH5R_GPIO_USE_AS_GPIO"
+			register "gpio[48]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_OUTPUT | ICH5R_GPIO_LVL_LOW"
+			register "gpio[41]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_INPUT"
+		end
+	end
+	device apic_cluster 0 on
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu 0
+			device apic 0 on end
+		end
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu 1
+			device apic 6 on end
+		end
+	end
+end
diff --git a/src/mainboard/intel/jarrell/Options.lb b/src/mainboard/intel/jarrell/Options.lb
new file mode 100644
index 0000000..a7a5c72
--- /dev/null
+++ b/src/mainboard/intel/jarrell/Options.lb
@@ -0,0 +1,242 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_BTEXT
+uses CC
+uses HOSTCC
+uses CROSS_COMPILE
+uses OBJCOPY
+uses MAX_REBOOT_CNT
+uses USE_WATCHDOG_ON_BOOT
+
+
+###
+### Build options
+###
+
+##
+## Because we do the stutter start we need more attempts
+##
+default MAX_REBOOT_CNT=8
+
+##
+## Use the watchdog to break out of a lockup condition
+##
+default USE_WATCHDOG_ON_BOOT=1
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=2097152
+
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Delay timer options
+## Use timer2
+## 
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=9
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=4
+default CONFIG_LOGICAL_CPUS=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="SE7520JR22D"
+default MAINBOARD_VENDOR=     "Intel"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x8086
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x1079
+#default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x3437
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+default FALLBACK_SIZE=131072
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM=1
+
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+##
+## Don't enable the btext console
+##
+default  CONFIG_CONSOLE_BTEXT=0
+
+
+### End Options.lb
+end
diff --git a/src/mainboard/intel/jarrell/auto.c b/src/mainboard/intel/jarrell/auto.c
new file mode 100644
index 0000000..7e9cd99
--- /dev/null
+++ b/src/mainboard/intel/jarrell/auto.c
@@ -0,0 +1,150 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/ich5r/ich5r_early_smbus.c"
+#include "northbridge/intel/E7520/raminit.h"
+#include "superio/NSC/pc87427/pc87427.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "power_reset_check.c"
+#include "jarrell_fixups.c"
+#include "superio/NSC/pc87427/pc87427_early_init.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP2)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, PC87427_SP1)
+
+#define DEVPRES_CONFIG  (DEVPRES_D1F0 | DEVPRES_D2F0 | DEVPRES_D6F0)
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+/* Beta values:         0x00090800 */
+/* Silver values:       0x000a0900 */
+#define RECVENA_CONFIG  0x000a090a
+#define RECVENB_CONFIG  0x000a090a
+#define DIMM_MAP_LOGICAL 0x0124
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7520/raminit.c"
+#include "sdram/generic_sdram.c"
+#include "debug.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+			.channel0 = { (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, 0 },
+			.channel1 = { (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, 0 },
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	pc87427_disable_dev(CONSOLE_SERIAL_DEV);
+	pc87427_disable_dev(HIDDEN_SERIAL_DEV);
+	pc87427_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+        /* Enable Serial 2 lines instead of GPIO */
+        outb(0x2c, 0x2e);
+        outb((inb(0x2f) & (~1<<1)), 0x2f);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+	report_bist_failure(bist);
+
+	pc87427_enable_dev(PC87427_GPIO_DEV, SIO_GPIO_BASE);
+
+	pc87427_enable_dev(PC87427_XBUS_DEV, SIO_XBUS_BASE);
+	xbus_cfg(PC87427_XBUS_DEV);
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing ich5?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	print_pci_devices();
+#endif
+	enable_smbus();
+#if 0
+//	dump_spd_registers(&cpu[0]);
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+	power_down_reset_check();
+//	dump_ipmi_registers();
+	mainboard_set_e7520_leds();	
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+	ich5_watchdog_on();
+#if 0
+	dump_pci_devices();
+#endif
+#if 0
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+	dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+	ram_check(0x00100000, 0x01000000);
+	/* check the first 1M in the 3rd Gig */
+	ram_check(0x30100000, 0x31000000);
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#endif
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/intel/jarrell/chip.h b/src/mainboard/intel/jarrell/chip.h
new file mode 100644
index 0000000..7cc5909
--- /dev/null
+++ b/src/mainboard/intel/jarrell/chip.h
@@ -0,0 +1,5 @@
+struct chip_operations mainboard_intel_jarrell_ops;
+
+struct mainboard_intel_jarrell_config {
+	int nothing;
+};
diff --git a/src/mainboard/intel/jarrell/cmos.layout b/src/mainboard/intel/jarrell/cmos.layout
new file mode 100644
index 0000000..71387a2
--- /dev/null
+++ b/src/mainboard/intel/jarrell/cmos.layout
@@ -0,0 +1,82 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          376       r       0        reserved_memory
+376	     1       e       1        power_up_watchdog
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       2        hyper_threading
+397          1       e       1        pxhd_bus_speed_100
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/intel/jarrell/debug.c b/src/mainboard/intel/jarrell/debug.c
new file mode 100644
index 0000000..5546421
--- /dev/null
+++ b/src/mainboard/intel/jarrell/debug.c
@@ -0,0 +1,330 @@
+#define SMBUS_MEM_DEVICE_START 0x50
+#define SMBUS_MEM_DEVICE_END 0x57
+#define SMBUS_MEM_DEVICE_INC 1
+
+static void print_reg(unsigned char index)
+{
+        unsigned char data;
+                                                                                
+        outb(index, 0x2e);
+        data = inb(0x2f);
+	print_debug("0x");
+	print_debug_hex8(index);
+	print_debug(": 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+        return;
+}
+        
+static void xbus_en(void)
+{
+        /* select the XBUS function in the SIO */
+        outb(0x07, 0x2e);
+        outb(0x0f, 0x2f);
+        outb(0x30, 0x2e);
+        outb(0x01, 0x2f);
+	return;
+}
+                                                                        
+static void setup_func(unsigned char func)
+{
+        /* select the function in the SIO */
+        outb(0x07, 0x2e);
+        outb(func, 0x2f);
+        /* print out the regs */
+        print_reg(0x30);
+        print_reg(0x60);
+        print_reg(0x61);
+        print_reg(0x62);
+        print_reg(0x63);
+        print_reg(0x70);
+        print_reg(0x71);
+        print_reg(0x74);
+        print_reg(0x75);
+        return;
+}
+                                                                                
+static void siodump(void)
+{
+        int i;
+        unsigned char data;
+       
+	 print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
+        for (i=0x10; i<=0x2d; i++) {
+                print_reg((unsigned char)i);
+        }
+#if 0                                                                         
+        print_debug("\r\n*** XBUS REGISTERS ***\r\n");
+        setup_func(0x0f);
+        for (i=0xf0; i<=0xff; i++) {
+                print_reg((unsigned char)i);
+        }
+                                                                                
+        print_debug("\r\n***  SERIAL 1 CONFIG REGISTERS ***\r\n");
+        setup_func(0x03);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  SERIAL 2 CONFIG REGISTERS ***\r\n");
+        setup_func(0x02);
+        print_reg(0xf0);
+
+#endif
+        print_debug("\r\n***  GPIO REGISTERS ***\r\n");
+        setup_func(0x07);
+        for (i=0xf0; i<=0xf8; i++) {
+                print_reg((unsigned char)i);
+        }
+        print_debug("\r\n***  GPIO VALUES ***\r\n");
+        data = inb(0x68a);
+	print_debug("\r\nGPDO 4: 0x");
+	print_debug_hex8(data);
+        data = inb(0x68b);
+	print_debug("\r\nGPDI 4: 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+	
+#if 0                                                                                
+                                                                                
+        print_debug("\r\n***  WATCHDOG TIMER REGISTERS ***\r\n");
+        setup_func(0x0a);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  FAN CONTROL REGISTERS ***\r\n");
+        setup_func(0x09);
+        print_reg(0xf0);
+        print_reg(0xf1);
+
+        print_debug("\r\n***  RTC REGISTERS ***\r\n");
+        setup_func(0x10);
+        print_reg(0xf0);
+        print_reg(0xf1);
+        print_reg(0xf3);
+        print_reg(0xf6);
+        print_reg(0xf7);
+        print_reg(0xfe);
+        print_reg(0xff);
+                                                                                
+        print_debug("\r\n***  HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
+        setup_func(0x14);
+        print_reg(0xf0);
+#endif                                                                           
+        return;
+}
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_bar14(unsigned dev)
+{
+	int i;
+	unsigned long bar;
+	
+	print_debug("BAR 14 Dump\r\n");
+	
+	bar = pci_read_config32(dev, 0x14);
+	for(i = 0; i <= 0x300; i+=4) {
+#if 0		
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+#endif		
+		if((i%4)==0) {
+		print_debug("\r\n");
+		print_debug_hex16(i);
+		print_debug_char(' ');
+		}
+		print_debug_hex32(read32(bar + i));
+		print_debug_char(' ');
+	}
+	print_debug("\r\n");
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+#if 0
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+	}
+}
+#endif
+
+void dump_spd_registers(void)
+{
+        unsigned device;
+        device = SMBUS_MEM_DEVICE_START;
+        while(device <= SMBUS_MEM_DEVICE_END) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("dimm ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 256) ; i++) {
+	                unsigned char byte;
+                        if ((i % 16) == 0) {
+				print_debug("\r\n");
+				print_debug_hex8(i);
+				print_debug(": ");
+                        }
+			status = smbus_read_byte(device, i);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}
+
+void dump_ipmi_registers(void)
+{
+        unsigned device;
+        device = 0x42;
+        while(device <= 0x42) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("ipmi ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 8) ; i++) {
+	                unsigned char byte;
+			status = smbus_read_byte(device, 2);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}	
diff --git a/src/mainboard/intel/jarrell/failover.c b/src/mainboard/intel/jarrell/failover.c
new file mode 100644
index 0000000..5029d98
--- /dev/null
+++ b/src/mainboard/intel/jarrell/failover.c
@@ -0,0 +1,46 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "pc80/mc146818rtc_early.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* Did just the cpu reset? */
+	if (memory_initialized()) {
+	 	if (last_boot_normal()) {
+			goto normal_image;
+		} else {
+			goto cpu_reset;
+		}
+	}
+
+	/* This is the primary cpu how should I boot? */
+	else if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
diff --git a/src/mainboard/intel/jarrell/irq_tables.c b/src/mainboard/intel/jarrell/irq_tables.c
new file mode 100644
index 0000000..75071c1
--- /dev/null
+++ b/src/mainboard/intel/jarrell/irq_tables.c
@@ -0,0 +1,37 @@
+/* PCI: Interrupt Routing Table found at 0x40114180 size = 320 */
+
+#include <arch/pirq_routing.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+	0x52495024, /* u32 signature */
+	0x0100,     /* u16 version   */
+	320,        /* u16 Table size 32+(16*devices)  */
+	0x00,       /* u8 Bus 0 */
+	0xf8,       /* u8 Device 1, Function 0 */
+	0x0000,     /* u16 reserve IRQ for PCI */
+	0x8086,     /* u16 Vendor */
+	0x24d0,     /* Device ID */
+	0x00000000, /* u32 miniport_data */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0x38,   /*  u8 checksum - mod 256 checksum must give zero */
+	{  /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  */
+	    {0x00, 0x08, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, 0xf8, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, 0xe8, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00,  0x00},
+	    {0x02, 0x20, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x03, 0x28, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, 0x60, {{0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x02, 0x08, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}}, 0x04,  0x00},
+	    {0x02, 0x10, {{0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}, {0x60, 0xdcf8}}, 0x05,  0x00},
+	    {0x02, 0x18, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0xdcf8}}, 0x06,  0x00},
+	    {0x03, 0x08, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}}, 0x01,  0x00},
+	    {0x03, 0x10, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x61, 0xdcf8}}, 0x02,  0x00},
+	    {0x03, 0x18, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}}, 0x03,  0x00},
+	    {0x00, 0x10, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, 0x18, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, 0x20, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, 0x28, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, 0x30, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, 0x38, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00,  0x00}
+	}
+};
diff --git a/src/mainboard/intel/jarrell/jarrell_fixups.c b/src/mainboard/intel/jarrell/jarrell_fixups.c
new file mode 100644
index 0000000..d8c694b
--- /dev/null
+++ b/src/mainboard/intel/jarrell/jarrell_fixups.c
@@ -0,0 +1,123 @@
+#include <arch/romcc_io.h>
+
+static void mch_reset(void)
+{
+        device_t dev;
+        unsigned long value, base;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+        if (dev != PCI_DEV_INVALID) {
+                /* I/O space is always enables */
+
+                /* Set gpio base */
+                pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
+                base = ICH5_GPIOBASE;
+
+                /* Enable GPIO Bar */
+                value = pci_read_config32(dev, 0x5c);
+                value |= 0x10;
+                pci_write_config32(dev, 0x5c, value);
+
+		/* Set GPIO 19 mux to IO usage */
+		value = inl(base);
+		value |= (1 <<19);
+		outl(value, base);
+		
+                /* Pull GPIO 19 low */
+                value = inl(base + 0x0c);
+                value &= ~(1 << 19);
+                outl(value, base + 0x0c);
+        }
+        return;
+}
+
+
+
+static void mainboard_set_e7520_pll(unsigned bits)
+{
+	uint16_t gpio_index;
+	uint8_t data;
+	device_t dev;
+
+	/* currently only handle the Jarrell/PC87427 case */
+	dev = PC87427_GPIO_DEV;
+		
+
+	pnp_set_logical_device(dev);
+	gpio_index = pnp_read_iobase(dev, 0x60);
+
+	/* select SIO GPIO port 4, pin 2 */
+	pnp_write_config(dev, PC87427_GPSEL, ((pnp_read_config(dev, PC87427_GPSEL) & 0x88) | 0x42));
+	/* set to push-pull, enable output */
+	pnp_write_config(dev, PC87427_GPCFG1, 0x03);
+
+	/* select SIO GPIO port 4, pin 4 */
+	pnp_write_config(dev, PC87427_GPSEL, ((pnp_read_config(dev, PC87427_GPSEL) & 0x88) | 0x44));
+	/* set to push-pull, enable output */
+	pnp_write_config(dev, PC87427_GPCFG1, 0x03);
+
+	/* set gpio 42,44 signal levels */
+	data = inb(gpio_index + PC87427_GPDO_4);
+	if ((data & 0x14) == (0xff & (((bits&2)?0:1)<<4 | ((bits&1)?0:1)<<2))) {
+		print_debug("set_pllsel: correct settings detected!\r\n");
+		return; /* settings already configured */
+	} else {
+		outb((data & 0xeb) | ((bits&2)?0:1)<<4 | ((bits&1)?0:1)<<2, gpio_index + PC87427_GPDO_4);
+		/* reset */
+		print_debug("set_pllsel: settings adjusted, now resetting...\r\n");
+	//	hard_reset(); /* should activate a PCI_RST, which should reset MCH, but it doesn't seem to work ???? */
+//		mch_reset();
+		full_reset();
+	}
+	return; 
+}
+
+
+static void mainboard_set_e7520_leds(void)
+{
+	uint8_t cnt;
+	uint8_t data;
+	device_t dev;
+
+	/* currently only handle the Jarrell/PC87427 case */
+	dev = PC87427_GPIO_DEV;
+		
+	pnp_set_logical_device(dev);
+
+	/* enable */
+	outb(0x30, 0x2e);
+	outb(0x01, 0x2f);
+	outb(0x2d, 0x2e);
+	outb(0x01, 0x2f);
+
+	/* Set auto mode for dimm leds and post */
+	outb(0xf0,0x2e);
+	outb(0x70,0x2f);	
+	outb(0xf4,0x2e);
+	outb(0x30,0x2f);	
+	outb(0xf5,0x2e);
+	outb(0x88,0x2f);	
+	outb(0xf6,0x2e);
+	outb(0x00,0x2f);	
+	outb(0xf7,0x2e);
+	outb(0x90,0x2f);	
+	outb(0xf8,0x2e);
+	outb(0x00,0x2f);	
+
+	/* Turn the leds off */
+	outb(0x00,0x88);
+	outb(0x00,0x90);
+
+	/* Disable the ports */
+	outb(0xf5,0x2e);
+	outb(0x00,0x2f);	
+	outb(0xf7,0x2e);
+	outb(0x00,0x2f);	
+	outb(0xf4,0x2e);
+	outb(0x00,0x2f);	
+	
+	return; 
+}
+
+
+
+
diff --git a/src/mainboard/intel/jarrell/mainboard.c b/src/mainboard/intel/jarrell/mainboard.c
new file mode 100644
index 0000000..9b25e0a
--- /dev/null
+++ b/src/mainboard/intel/jarrell/mainboard.c
@@ -0,0 +1,13 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include <arch/io.h>
+#include "chip.h"
+
+struct chip_operations mainboard_intel_e7520_ops = {
+	CHIP_NAME("Intel Jarell mainboard ")
+};
+
diff --git a/src/mainboard/intel/jarrell/microcode_updates.c b/src/mainboard/intel/jarrell/microcode_updates.c
new file mode 100644
index 0000000..54daab0
--- /dev/null
+++ b/src/mainboard/intel/jarrell/microcode_updates.c
@@ -0,0 +1,1563 @@
+/* WARNING - Intel has a new data structure that has variable length
+ * microcode update lengths.  They are encoded in int 8 and 9.  A
+ * dummy header of nulls must terminate the list.
+ */
+
+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {
+	/*
+           Copyright  Intel Corporation, 1995, 96, 97, 98, 99, 2000.
+           These microcode updates are distributed for the sole purpose of
+           installation in the BIOS or Operating System of computer systems
+           which include an Intel P6 family microprocessor sold or distributed
+           to or by you.  You are authorized to copy and install this material
+           on such systems.  You are not authorized to use this material for
+           any other purpose.
+        */
+
+	/*  M1DF340E.TXT - Noconoa D-0  */
+	
+
+	0x00000001, /* Header Version	*/
+	0x0000000e, /* Patch ID		*/
+	0x05042004, /* DATE		*/
+	0x00000f34, /* CPUID		*/
+	0x9b18561d, /* Checksum		*/
+	0x00000001, /* Loader Version	*/
+	0x0000001d, /* Platform ID	*/
+	0x000017d0, /* Data size	*/
+	0x00001800, /* Total size	*/
+	0x00000000, /* reserved		*/
+	0x00000000, /* reserved		*/
+	0x00000000, /* reserved		*/
+	0x9fbf327a,
+	0x2b41b451,
+	0xb0a79cab,
+	0x6b62b8fd,
+	0xc953d679,
+	0x1e462145,
+	0x59d96ae5,
+	0xb90dfc00,
+	0x4f6bd233,
+	0xa8dda234,
+	0xb96b5eb7,
+	0x588fc98f,
+	0xdd59a87c,
+	0xb038ad4c,
+	0x338af84c,
+	0x44842e0d,
+	0x2e664aa6,
+	0xd46497b7,
+	0xddbcd376,
+	0xd86dd62a,
+	0x27ceec6e,
+	0xb089ff2e,
+	0xfc549965,
+	0x556f5b78,
+	0xa8c4732c,
+	0x0969180d,
+	0x14a346e8,
+	0x561a91b3,
+	0x1cd21cde,
+	0xd09d06bc,
+	0x3a4cae91,
+	0x5d23fa54,
+	0x43747e8d,
+	0x19ff0547,
+	0xdae0e17a,
+	0xc16bab85,
+	0x2364fea6,
+	0x8508f3c6,
+	0x598ca70f,
+	0x72fb0579,
+	0x24c28f46,
+	0xed19ad6b,
+	0xcd6206fe,
+	0xe3d091e8,
+	0xb7f1f9f1,
+	0x501c1c77,
+	0x5fdda272,
+	0xbdc8301b,
+	0x64b200ea,
+	0xb8460b09,
+	0x26d125ea,
+	0x03e27414,
+	0x3d023f17,
+	0x0b0520c8,
+	0x74fba5c6,
+	0xc3d761de,
+	0x672cf9fa,
+	0x4c000ff0,
+	0x0a8bbda4,
+	0x5dd7b3b1,
+	0x439e12f1,
+	0x235444bb,
+	0xa7513c27,
+	0x8ce97fbf,
+	0xb41f857c,
+	0x6e71fd9d,
+	0xd11f2fe3,
+	0x5d92f44d,
+	0x4b06f5fa,
+	0x7695eed0,
+	0x3aa045e8,
+	0x9ce894d4,
+	0x02a1723a,
+	0xa4d9e99e,
+	0x0ca6f5ec,
+	0x1df8ee10,
+	0x82d9b0a9,
+	0xb7fceca0,
+	0x0eebfe97,
+	0xda2e8c7b,
+	0xf9ffdf4b,
+	0xb6c84538,
+	0xb7eee9d7,
+	0x89f8e993,
+	0x7d51dbf8,
+	0xc75f6389,
+	0xd2e76e6c,
+	0x60fdc275,
+	0x6758a029,
+	0x9d463f02,
+	0x40069261,
+	0x55ebc0b5,
+	0xa90d5bb2,
+	0x33a3d807,
+	0xa6e603c8,
+	0x4b0e2505,
+	0xd28eb45d,
+	0xeab8055b,
+	0x97439c5f,
+	0xb3ccb9dd,
+	0xb33f1bb5,
+	0xd34e6009,
+	0x946e7d07,
+	0x68908cea,
+	0x435581e5,
+	0xb2ceee79,
+	0x112df532,
+	0xd7d079f5,
+	0xbcb997f9,
+	0xdc3c7807,
+	0x5c6b4af9,
+	0x3f919e49,
+	0x62a597b9,
+	0x20e4fc37,
+	0x4241bc5c,
+	0x66636de1,
+	0x2a0f3988,
+	0x62281e5f,
+	0x9d19500a,
+	0x9f349dbf,
+	0x9b16869d,
+	0x0299fec1,
+	0xa013cf08,
+	0x36e47a83,
+	0x8cf78105,
+	0xa92a7080,
+	0xece3a363,
+	0x01361d90,
+	0x1555e2b4,
+	0x9ec1207c,
+	0x93f5f638,
+	0x1854d4e4,
+	0xa5768108,
+	0xe6b867bc,
+	0xec91c0a3,
+	0xb42c40b9,
+	0x7a543ed2,
+	0xbe080c40,
+	0x72edfcda,
+	0xd2ddde37,
+	0x1e1f1563,
+	0xd24ca500,
+	0x761df139,
+	0xc9e79091,
+	0xab44cdcb,
+	0x16c204d7,
+	0x5d4ff67b,
+	0x8651ea63,
+	0x09d8dc41,
+	0x643cddcf,
+	0x5709c4b7,
+	0x04384755,
+	0x30e52749,
+	0x1329aac2,
+	0x7bf64fad,
+	0x5d3e6b49,
+	0x515aa075,
+	0xfe7e7f8d,
+	0x5461d781,
+	0x0547b8b2,
+	0xa71b89c7,
+	0x30f03604,
+	0xe37970a5,
+	0x169e27f9,
+	0x1024e384,
+	0x62198879,
+	0xd689b295,
+	0xa5a340c0,
+	0x8460b084,
+	0x86a301c4,
+	0x2e589fca,
+	0xf4687ad0,
+	0x8d4b4c7d,
+	0x0d9635e6,
+	0x91aac10f,
+	0xcff70e8b,
+	0x904c0678,
+	0x56237892,
+	0x4d8eefc5,
+	0xdd1b74d2,
+	0x6405fb4b,
+	0x8b15cc77,
+	0x83f3fca3,
+	0x1ad9724c,
+	0xbccceb84,
+	0x18bb629d,
+	0x5ae70712,
+	0x6ca076d8,
+	0xa231c82b,
+	0x6a60573f,
+	0x9046baf1,
+	0x7e08ade7,
+	0xd949e10a,
+	0xfc5a396f,
+	0x9cb8eaaa,
+	0x4e050c89,
+	0x751b8672,
+	0x0e0d565a,
+	0x837787e8,
+	0xdb01db4e,
+	0xb41d9bb5,
+	0x41e4ce55,
+	0xfe1700ae,
+	0x89e70c4f,
+	0x05f007b9,
+	0x105a311e,
+	0xa8793ba4,
+	0xa7572e49,
+	0xaf72e942,
+	0x59f5c594,
+	0x583f872b,
+	0x9041d9de,
+	0x72f628bd,
+	0x8bb19420,
+	0x957eca65,
+	0x1b3bd477,
+	0x581c475a,
+	0x9a87bbbc,
+	0x2fa9cca5,
+	0x6115e020,
+	0xd44f74ef,
+	0x37ea131f,
+	0x3f07b084,
+	0x543aca7a,
+	0xe91d50c6,
+	0xc9139700,
+	0xcd0182ac,
+	0xe09514f7,
+	0xfe01038e,
+	0x7c97be09,
+	0xbc79c28b,
+	0x18aea71f,
+	0xd6776f66,
+	0xc020822a,
+	0xd7fc90ac,
+	0x382cd812,
+	0x60c49263,
+	0xb279295a,
+	0x69eb4399,
+	0x8e32fd5e,
+	0xfe739807,
+	0x1495d3e5,
+	0xbf025c3f,
+	0x190920d3,
+	0x1680dbaf,
+	0x1eda0681,
+	0x93bac657,
+	0x0e18680c,
+	0x2e5d85f6,
+	0x100fa070,
+	0x171e7931,
+	0x79f779fa,
+	0x8723130d,
+	0x222c2d90,
+	0xbffd0448,
+	0x31e7a11e,
+	0x15952725,
+	0x0a0d6880,
+	0x2045bb27,
+	0x65903721,
+	0x009adfcf,
+	0xc5b6017a,
+	0x98920c52,
+	0x960b5e3f,
+	0x5bc23253,
+	0x0c299c66,
+	0xd0ac9e6e,
+	0xf7735ce5,
+	0xa4e70ec1,
+	0x0b0dac09,
+	0x7a5a9bfa,
+	0x06001d88,
+	0x316f6221,
+	0x7fe9aeb1,
+	0x22543edc,
+	0xf8b94fde,
+	0x392bf047,
+	0xb0f1bc2c,
+	0x984d8795,
+	0xa8db0148,
+	0xc42addb0,
+	0x9883a82c,
+	0xe8676a43,
+	0x95f5ccf7,
+	0x06afe12c,
+	0x756a1b33,
+	0x1519091b,
+	0x61c5ccd2,
+	0xf3288b41,
+	0x7d33e180,
+	0x76cc5a24,
+	0xd1a18aa4,
+	0xa353a07c,
+	0x4e173b6b,
+	0x3ad5b70c,
+	0x6440b4c9,
+	0x37979ae9,
+	0x0c517fc6,
+	0xc8252fb3,
+	0x21a33062,
+	0xe21e8070,
+	0xa3e8fe61,
+	0xb8e22e6e,
+	0xd6f2fd79,
+	0xc9185337,
+	0xd8ef8db8,
+	0x952e6ac3,
+	0x2ba27d5a,
+	0xe4b502d7,
+	0xc720f8f4,
+	0x5601e451,
+	0x2dabcbf3,
+	0x06d6bf4e,
+	0x580e0ec5,
+	0x42099aa9,
+	0x288a795a,
+	0x09d59ae5,
+	0xc56311bf,
+	0xc9a0be28,
+	0x82ab89e4,
+	0x63a6b7de,
+	0xb654846e,
+	0x53fa8bbc,
+	0x766e12b2,
+	0xa7a5de15,
+	0x951a8fe8,
+	0xa638273b,
+	0x78ce2cc7,
+	0x1cff0475,
+	0x53318a42,
+	0x1a30f362,
+	0x55d14483,
+	0xf19b2f8e,
+	0x66a791b8,
+	0xf454cc9b,
+	0xc688da27,
+	0x8877ee5d,
+	0x7c66e45e,
+	0x8fa7945b,
+	0x9eb7942f,
+	0xdedf49b4,
+	0x22ae7a86,
+	0xd2eaf279,
+	0x5f7547a2,
+	0x13872ebf,
+	0x70ebb737,
+	0x9e433f1c,
+	0x40987dc1,
+	0x9321c994,
+	0x832871b0,
+	0x77e8ebad,
+	0x0a2853a2,
+	0x75460864,
+	0x4028c1f7,
+	0x066fb1db,
+	0x6a8a47dd,
+	0x8ec0f102,
+	0x3d9502bb,
+	0x38e3b20b,
+	0x1d24cebb,
+	0xcd316180,
+	0x2e39fcaa,
+	0xd68dff5b,
+	0x1b8d3990,
+	0xce9715b9,
+	0xcb3ef0d4,
+	0xc87865ec,
+	0x6eb72a87,
+	0xf02302f8,
+	0x9d06420c,
+	0x013ada55,
+	0x482dc805,
+	0x469d83e4,
+	0x4f64348b,
+	0xb320168a,
+	0x736063a3,
+	0xa44e2034,
+	0x14cf72d6,
+	0x7758468f,
+	0xdc130a50,
+	0xcd3a98d1,
+	0xc7d3ec32,
+	0x6008c722,
+	0x7729faf1,
+	0xca184989,
+	0xcdfbfe93,
+	0x140df767,
+	0xeab2b859,
+	0xef388f9e,
+	0xcfad00e8,
+	0xb3edb3f2,
+	0xd9bf19b3,
+	0x7a988c4f,
+	0xc9478520,
+	0xb0120f5a,
+	0x6a2639aa,
+	0x8a8f628f,
+	0x446a7769,
+	0xc02ae4de,
+	0x0869bd59,
+	0xef8ccf75,
+	0x46670a06,
+	0xea9aeb5a,
+	0x16162088,
+	0x22b7f89e,
+	0x54f46cae,
+	0xf401a8fe,
+	0xeb80ce25,
+	0xfd811c6a,
+	0x95714e43,
+	0x6369cc4a,
+	0x091d595a,
+	0x0ed23abc,
+	0x8a5b0807,
+	0x8f6d34b4,
+	0x5f6048fe,
+	0x03bfcc6d,
+	0x54a49828,
+	0x36e096a4,
+	0x1dfe968e,
+	0x826336c0,
+	0xfb2453dd,
+	0xab618401,
+	0x7c0a4e4a,
+	0xab852bb5,
+	0xd1182cab,
+	0x54688e26,
+	0xf8bc5226,
+	0x92e39ae8,
+	0x4969458d,
+	0xb5e9e4e0,
+	0x1cc35776,
+	0x066a5f0e,
+	0xa0f944bd,
+	0xe6c4db63,
+	0x1c171fd6,
+	0x36bdf158,
+	0x75c65c25,
+	0x4200bb72,
+	0x4616777f,
+	0xbc70b23c,
+	0x4546dda2,
+	0x7fa13471,
+	0xe4db3be2,
+	0x0e1eb25a,
+	0xf0253cc3,
+	0xcaef50f5,
+	0xaa67a3f1,
+	0x6fabd333,
+	0xe3e3686e,
+	0xe4398405,
+	0x18334de1,
+	0xbb8eedef,
+	0xbdfe0fd4,
+	0x635a8be2,
+	0x502d965f,
+	0x41308946,
+	0x1e5ae64d,
+	0xbeb7ff7a,
+	0xc33a7af0,
+	0x8d5a19a6,
+	0x77547cd0,
+	0x8c98d59f,
+	0x2daeb33e,
+	0x2bace475,
+	0x265cd5f1,
+	0x4f95e4c4,
+	0x7f4dbce2,
+	0xebb65b1b,
+	0xb4a7740b,
+	0x82bcbfed,
+	0x7670d288,
+	0xbc69ee8f,
+	0x0a073dbf,
+	0x320f0800,
+	0xfa581147,
+	0x13989462,
+	0x45a6b4a3,
+	0x8a651db1,
+	0xa35444d4,
+	0xbf230bac,
+	0xb313dbe4,
+	0xbe09cd73,
+	0x13c228a2,
+	0x85241e58,
+	0xeb9e5fc7,
+	0xf07df2c7,
+	0x5afc6231,
+	0x88f06beb,
+	0xee11a03c,
+	0xf48b6388,
+	0x67a1bb4e,
+	0x4ab92ac0,
+	0x5b29973d,
+	0xf59ff86c,
+	0x1206dedc,
+	0x999ccb7a,
+	0x629c3310,
+	0x5b3e217f,
+	0x92354d19,
+	0xc57f1f99,
+	0x80652554,
+	0x8c44b1ad,
+	0xfba863cd,
+	0x1a499196,
+	0xe6ecddb4,
+	0x66d53c7d,
+	0x81f63062,
+	0x5f6a6cf8,
+	0xd493e938,
+	0xa3e9fe77,
+	0xbc4f2d8a,
+	0x733fb762,
+	0xa05280d2,
+	0x6005f547,
+	0x6cf17c67,
+	0x5a69d045,
+	0x414383a5,
+	0xb16f5425,
+	0x6ce49c82,
+	0x331ed575,
+	0x12f830ce,
+	0x63bc960a,
+	0x38a05f7d,
+	0xda50d724,
+	0xfc2e58a1,
+	0x763ac7d3,
+	0x3dd8abdf,
+	0xcafc7a77,
+	0x80ebae62,
+	0xf2d70ca4,
+	0xcf9a6db7,
+	0xfffda692,
+	0x264713c1,
+	0x8a1bd6a0,
+	0x13711bad,
+	0x4a7ca477,
+	0x4d07231a,
+	0x521210a7,
+	0xaea41847,
+	0x2197f6cf,
+	0x5bbee70c,
+	0xbe5aae01,
+	0x10e53ed6,
+	0x7f00a280,
+	0x96d72d54,
+	0xa5ae6425,
+	0xc721855b,
+	0xc2a8a0dc,
+	0x60b56433,
+	0xd945cc76,
+	0x18a092f8,
+	0x552020f4,
+	0xe46528da,
+	0xe4cca6c4,
+	0xf4b00110,
+	0x714a91de,
+	0x10e19450,
+	0xcd57f7f8,
+	0x7ddcd6ee,
+	0xbf3489b8,
+	0xd77c098a,
+	0x72152d71,
+	0x81ab14d4,
+	0xd97cfe8a,
+	0x4953c6ba,
+	0x0853017a,
+	0x9a64b325,
+	0x1645516f,
+	0xd5ece3a9,
+	0xab76d41b,
+	0xb64936d6,
+	0x7162d5d7,
+	0x344a0ae3,
+	0x7d180b8a,
+	0xd8eb3b6c,
+	0xfe39169e,
+	0x0e32b004,
+	0xb1b6ef0f,
+	0x4efc612f,
+	0x3ed51902,
+	0x7ab26840,
+	0x3f593b3b,
+	0x00ec59e4,
+	0x9ac2db9a,
+	0x6c42f681,
+	0x9b5dec47,
+	0x1bd6c7b4,
+	0xd9f0fe7c,
+	0x9660dac2,
+	0x1d2a5d0f,
+	0x569465a0,
+	0x15780587,
+	0xff71e10c,
+	0xe42c2a6d,
+	0x2a2fc9b7,
+	0xd873f66b,
+	0x0ace2492,
+	0x3b32947a,
+	0xb432db31,
+	0x23c33b9e,
+	0x6698e729,
+	0x094d8174,
+	0xf0d17bcf,
+	0x456706b7,
+	0x12ae6c75,
+	0xaed5319b,
+	0xa874a599,
+	0x8fb6643b,
+	0xabd58c0c,
+	0xc50e83e7,
+	0x7a558c8b,
+	0x4e11c7e6,
+	0x1552bcb1,
+	0xd408589f,
+	0x679fc9a7,
+	0x47c0800d,
+	0xb1f7afbe,
+	0x109fe2b9,
+	0xb54361b9,
+	0xea21d805,
+	0x461cd956,
+	0xc191f1b4,
+	0x949eb6a6,
+	0x16aedf85,
+	0x1020f31e,
+	0xfde8914a,
+	0x12e27158,
+	0xb418a938,
+	0x655c23ac,
+	0xf3909c7c,
+	0x421a309c,
+	0xf16d522f,
+	0x65f120a2,
+	0x51ccd73c,
+	0xf1913c82,
+	0x25dfd7a9,
+	0x62caad88,
+	0x76fc1229,
+	0xecf5a837,
+	0x85282036,
+	0x89f74447,
+	0xe5d8e2d3,
+	0x66375e99,
+	0x792b58a2,
+	0x85094329,
+	0x1b6cd378,
+	0x2cb27a8b,
+	0xdbda0f3b,
+	0x4e8f6f83,
+	0xde3626ac,
+	0x19bd8301,
+	0x30129851,
+	0x5ea607ef,
+	0x5421188c,
+	0xb7fd392e,
+	0x286dfb6e,
+	0x5be2d96d,
+	0xfe4606cc,
+	0x13266bd0,
+	0x22512e73,
+	0x7fe7d929,
+	0xa4e42e7e,
+	0xeeba5488,
+	0xf69949cb,
+	0x772ae500,
+	0x044f68b6,
+	0xcaa790f7,
+	0x653d862b,
+	0xdab1dca2,
+	0x617fae01,
+	0x58fcbcdd,
+	0xb94cbd50,
+	0x4deb82eb,
+	0xf3aea152,
+	0xa39e0413,
+	0xb51f95a9,
+	0xbeeb2054,
+	0xda3a5a26,
+	0xc53dd642,
+	0xa01fe6d0,
+	0xf60cecfd,
+	0x514b4044,
+	0x74ca621a,
+	0x530b6b6a,
+	0x7415aad3,
+	0xe89d6436,
+	0xe616ffe2,
+	0x9daa5272,
+	0x25391d23,
+	0xfb28424e,
+	0x1364802c,
+	0xe060f84d,
+	0x0ae2f131,
+	0x6ce62b10,
+	0x39937124,
+	0xa3aaca72,
+	0x0816c8c2,
+	0x11e8f5d1,
+	0xd95fdf39,
+	0xc2cd550b,
+	0x9190a02f,
+	0xe8c20598,
+	0xdbf56feb,
+	0x9caf355b,
+	0x9bd648a7,
+	0xde575e2e,
+	0xb5b45019,
+	0x9f390f47,
+	0x9b4e7412,
+	0x13066ce2,
+	0xfa475b46,
+	0xfeec8697,
+	0x8e0e56a6,
+	0xfa6f6aef,
+	0x57f6dc81,
+	0x5d2316f1,
+	0xe28e1249,
+	0xcd22f97a,
+	0x947ff08d,
+	0x1124a7c2,
+	0x8dbcfd6e,
+	0x8da10ea5,
+	0x9962e5e5,
+	0x847516b4,
+	0x65e725bc,
+	0xaacaf361,
+	0xacd16e3c,
+	0x972a3137,
+	0x0e4a4ad6,
+	0x983a5779,
+	0x9588efa8,
+	0x3e320974,
+	0x33437ea5,
+	0x6e0211cd,
+	0x8071a615,
+	0x6f372d73,
+	0x43880814,
+	0x975c105f,
+	0x7e571853,
+	0xf6254581,
+	0x28afacf3,
+	0x9bb1937c,
+	0x3a3f584a,
+	0xa54f46b8,
+	0xc23014a9,
+	0x71b8f1d0,
+	0xa4e997d3,
+	0xc823c95a,
+	0xfc9c7180,
+	0x6c08eaff,
+	0x6667f1fd,
+	0x2b3852c6,
+	0x05ca73d6,
+	0x074d88b7,
+	0xb9bccd0f,
+	0xa9287294,
+	0x6ef285b7,
+	0x4d8ea775,
+	0x51080197,
+	0x8516571c,
+	0xc50d7bc6,
+	0x38f29672,
+	0x417e0842,
+	0xd8caea6e,
+	0xadd9841e,
+	0x4874471b,
+	0x32714ada,
+	0x3a736227,
+	0xbec8a741,
+	0x93ffa4f7,
+	0xc6a65f24,
+	0xad353a96,
+	0x37f7abe3,
+	0x83002f1e,
+	0x5344eb50,
+	0x1933be53,
+	0x3d4aafd5,
+	0x44686e7c,
+	0xcb3c0c04,
+	0x3126c38e,
+	0x062eb627,
+	0xabba5dc8,
+	0x26a8ec35,
+	0x751d4863,
+	0x23caa099,
+	0x032c8c08,
+	0xf2428467,
+	0x580242e1,
+	0x2f1e8114,
+	0x177793cb,
+	0x2bc1a8a8,
+	0x3a95b194,
+	0xe6f65760,
+	0x0b1cede5,
+	0x93f08f46,
+	0xbabbf998,
+	0x73fc1072,
+	0x53217830,
+	0xf336109c,
+	0x00018216,
+	0x4fb6470a,
+	0xc715b776,
+	0x3f312e0e,
+	0x6a9a0cbe,
+	0xe719d8bb,
+	0x5b434e50,
+	0xbe5bc12f,
+	0x05fec000,
+	0x21b2478a,
+	0x7efa9d65,
+	0x4b7d2ce1,
+	0x4cdb4f14,
+	0x1a41a5c4,
+	0x424d94f3,
+	0xf364aa6e,
+	0xe003899b,
+	0x2284d34e,
+	0xc235c39c,
+	0xd0e54c8d,
+	0x969ed32e,
+	0xadca1e41,
+	0x1cf5dd48,
+	0xfeaee739,
+	0x8aa95f56,
+	0x79123691,
+	0xa8d5e6df,
+	0x14941574,
+	0xa002f08e,
+	0x81125113,
+	0x835eac03,
+	0x23e1df47,
+	0x5f3856fe,
+	0xf5bc6869,
+	0xce6f65f1,
+	0xf8f88627,
+	0xb0a74080,
+	0xc2c67512,
+	0x47510b62,
+	0x757a8619,
+	0xd358a6cf,
+	0xefd36be3,
+	0x0d8e6ebe,
+	0xe244e367,
+	0xdaf5202b,
+	0x9da43b72,
+	0x799510b2,
+	0x7aba0824,
+	0xc9375579,
+	0x430b0595,
+	0x49aeff96,
+	0x471a76a4,
+	0x6d902adb,
+	0xcd87aab5,
+	0x7767a00d,
+	0x5960ca6e,
+	0x4f8ef870,
+	0x309fa8bf,
+	0x46d14c6b,
+	0xd75ceaf2,
+	0x59d42f82,
+	0xd282a8bc,
+	0x52639643,
+	0xd7cf10ce,
+	0x943a78f5,
+	0xc69e88e3,
+	0x10eeeba0,
+	0xcafc5c65,
+	0xff74b46a,
+	0xf79f4d9c,
+	0x2630e51a,
+	0x7e2214b4,
+	0x880f701b,
+	0xd93cce83,
+	0xc3c79a30,
+	0xa0a02241,
+	0x33b91b39,
+	0x11fcc620,
+	0xc9ba6612,
+	0xe7443db4,
+	0x3cc12aa5,
+	0x157f6b71,
+	0x5c24d7b8,
+	0x19236745,
+	0x9db789d6,
+	0x5c2d0dfd,
+	0xea6d256f,
+	0x6d7b3e15,
+	0xe7334d29,
+	0xf6997706,
+	0x30aefa11,
+	0x75b11c2f,
+	0x66d9f586,
+	0x16c2c53e,
+	0x537a5647,
+	0xb49df107,
+	0xf502f5c2,
+	0x8a6417a1,
+	0xa1ff6fed,
+	0xdd7a388c,
+	0x484bc008,
+	0x96aeb4df,
+	0x7e5da879,
+	0x39ba7899,
+	0x945096f4,
+	0xaca0677a,
+	0x3aab6837,
+	0x693eb6ae,
+	0xd2769858,
+	0xf8c3a848,
+	0x3d416f0d,
+	0xc827d5b8,
+	0x634a0142,
+	0x95307840,
+	0x38598312,
+	0xebd78517,
+	0x9759f546,
+	0x96cae151,
+	0x41cbbc4a,
+	0xd8414d28,
+	0x0109dae8,
+	0xfcaa2c27,
+	0x0d4fe4eb,
+	0x4347492e,
+	0x3c16415e,
+	0xe491356a,
+	0x61b4e63f,
+	0x00ede80d,
+	0xe1fcdfe5,
+	0xfa4652e8,
+	0x1fc3ba51,
+	0x88951c66,
+	0x9a692f49,
+	0xe18779f7,
+	0xb4139fe4,
+	0x8d9eaa67,
+	0x53543af7,
+	0x528fbc3d,
+	0x18db3cc7,
+	0x56c5f946,
+	0xe70a19b3,
+	0x13fceeee,
+	0x73b311c8,
+	0xbed6fe39,
+	0xd92e42e7,
+	0xee11ab04,
+	0x20e4eec8,
+	0xca96264f,
+	0x948e9472,
+	0x609ca9b0,
+	0xa08c2aad,
+	0xfd2504f9,
+	0x36cf63ae,
+	0xe0734470,
+	0x652751e7,
+	0x642273d0,
+	0x9823fbe7,
+	0x6824fe6a,
+	0xe80ac838,
+	0x18846710,
+	0xfec2c7aa,
+	0xd80a48b4,
+	0xa66fe74c,
+	0x3f30c5dc,
+	0x227433b1,
+	0x83c4d631,
+	0x706c636a,
+	0x138b0fad,
+	0xe56524c0,
+	0xb2ac11f9,
+	0xad1799ce,
+	0x7ad15722,
+	0x1f163bb9,
+	0xd94d13e6,
+	0xba486e31,
+	0x4147dc40,
+	0xf294535b,
+	0xf3795177,
+	0x6cc4c80e,
+	0xce535635,
+	0xaa7227f5,
+	0xf08a7bf1,
+	0x04abff71,
+	0xc9fa751c,
+	0xf507bee7,
+	0x36461342,
+	0x257fdb9c,
+	0x8e7e5088,
+	0x82c48383,
+	0xbca8a03a,
+	0x981b4944,
+	0x82761269,
+	0x304b3d32,
+	0xf3e469b2,
+	0x3a26b2af,
+	0xccbbba89,
+	0xc28a2b71,
+	0xa69cef0d,
+	0xbcb33016,
+	0x5b682012,
+	0xfcdf7e05,
+	0x0b0ba583,
+	0x499ca677,
+	0x4fba9f8e,
+	0x7b76bc65,
+	0x2fc75e51,
+	0xc15ddfe9,
+	0x861d4c9c,
+	0xb8a93900,
+	0x92bd9e86,
+	0x5ff6d34f,
+	0x2709acde,
+	0x4e297037,
+	0x0e1d5d01,
+	0xf17f9166,
+	0x4444d54c,
+	0xea9aa934,
+	0xb5a8ab82,
+	0x501c04e6,
+	0xe7c53a5e,
+	0xb3af5520,
+	0x6fa0a711,
+	0xd10ae8c8,
+	0xbca08561,
+	0xdef0f8dc,
+	0x2b00a8da,
+	0x194cfec5,
+	0x53cced19,
+	0xd882fd4c,
+	0xd2a1f062,
+	0xbd9c92ab,
+	0x11faa9c4,
+	0x6b81821f,
+	0xd50e6f83,
+	0x9e6a865e,
+	0x6af4288a,
+	0xc7474730,
+	0xa3ee94f6,
+	0x53f3a99d,
+	0xfe59024c,
+	0x93372281,
+	0x02abbc57,
+	0x97fc1888,
+	0xbc99a04c,
+	0xd8f811a7,
+	0x4687ef67,
+	0xd28b56de,
+	0x70c55613,
+	0xbbad7b20,
+	0xd8ef8c62,
+	0xcbd82566,
+	0x4b42df32,
+	0x08ec3009,
+	0x75815b67,
+	0x72bacd00,
+	0xab7f376a,
+	0x42eafc17,
+	0x4044abef,
+	0xdd3e7e25,
+	0xc6a85884,
+	0x072e2f0c,
+	0x68b1f04b,
+	0xe406c8aa,
+	0x882f5d33,
+	0xaa29b242,
+	0xe5623462,
+	0xc83e4127,
+	0x4a7052bc,
+	0x0a28ad40,
+	0x754b0cc7,
+	0x2aad9413,
+	0x6b529f22,
+	0x07ddc99b,
+	0x9cd5e160,
+	0x7ff454c5,
+	0x7ab0fa49,
+	0x330dc0f7,
+	0x35f7c492,
+	0xfa234caf,
+	0xebd6def4,
+	0xea7d0b21,
+	0x5bf95b14,
+	0x0df1a519,
+	0x2ec447ac,
+	0xd6e80c4c,
+	0xc6cba5ff,
+	0x74424b66,
+	0x994f29ff,
+	0x133beb2e,
+	0xbf4a6652,
+	0x4308b5da,
+	0x11fe0718,
+	0xca296045,
+	0x949be826,
+	0x6e2c3fb8,
+	0xb850aa5c,
+	0x33f58121,
+	0x694d49c0,
+	0x90e404d8,
+	0x7704a82f,
+	0x4c55d386,
+	0xeb7593e2,
+	0x1550ecf0,
+	0x9755c436,
+	0x00e2bd8c,
+	0x819b4cb6,
+	0x57047356,
+	0xca7f96bb,
+	0xd21846d3,
+	0xe75c8b6b,
+	0x7c64db6a,
+	0x66807671,
+	0x42afbdac,
+	0x898a62a1,
+	0x352b4728,
+	0xa01ab76a,
+	0x3ecaa8ad,
+	0x857e137f,
+	0x7425aa2c,
+	0x59820cd5,
+	0x6cabe70e,
+	0xdf2b5075,
+	0x80d9ace0,
+	0x87a585a2,
+	0xa8aa2961,
+	0xc78ae53d,
+	0xad2fe51a,
+	0x12fc4d3b,
+	0xc2586e62,
+	0x3f9af3c1,
+	0x31aaca0e,
+	0x90de6dfa,
+	0xe8423a5d,
+	0x3473b38f,
+	0xb306a21c,
+	0x25c329db,
+	0xa63f49ce,
+	0xd64d55a5,
+	0xf22cd1fa,
+	0x5bb1371f,
+	0xa9548a1e,
+	0xb7e2103f,
+	0xfafd86f1,
+	0x04f18888,
+	0xef929aed,
+	0xc7f32159,
+	0x187d353c,
+	0xace75d6e,
+	0x7c8a9d00,
+	0xedc5203e,
+	0x4f8ad5e8,
+	0x270a3740,
+	0x136db4c5,
+	0x4d745554,
+	0xe834508e,
+	0x1e7971ec,
+	0x52af33bd,
+	0xc6be41f2,
+	0x06bf9120,
+	0x56c34b9f,
+	0x27dda918,
+	0xa873d58d,
+	0xaba2b6d2,
+	0x46ee0a64,
+	0xf71e6893,
+	0x6dadbe93,
+	0xc2dd2fc3,
+	0xe07ef64c,
+	0x2a17ea62,
+	0x918e4d24,
+	0x226ee1fd,
+	0x98b6f003,
+	0x75dfe5ba,
+	0xb9783d6e,
+	0x2847a098,
+	0x3b5f8fed,
+	0x4a264321,
+	0xf0989f25,
+	0xea2896e7,
+	0x62830aaf,
+	0x7ebb47eb,
+	0x7b990fc2,
+	0xcfe59d2c,
+	0xdf7b0cec,
+	0xee2bb918,
+	0x2e107193,
+	0x2ffcc92b,
+	0x56c8d7fb,
+	0x6d9596a2,
+	0xdbade8c2,
+	0x96bbd09c,
+	0x3be88ddb,
+	0x25788736,
+	0xf42e08aa,
+	0x2ace1c30,
+	0x04b3283b,
+	0x42abff1c,
+	0x9109f92e,
+	0xf44f974c,
+	0x69de015b,
+	0xcb5be1a3,
+	0x42006ec8,
+	0xf9f7bbae,
+	0x0e498747,
+	0xe64f42e5,
+	0xbdd9769a,
+	0xbfefe3ed,
+	0x1cf0b302,
+	0x304b38bb,
+	0x6fe98e02,
+	0x198560f0,
+	0x5f323a6b,
+	0x32d80d5b,
+	0xa02926cf,
+	0x749673f7,
+	0xdc5b89eb,
+	0xd7e59060,
+	0x08f0c0c8,
+	0x05f2b242,
+	0x41c621b9,
+	0x0f9d75e4,
+	0xc10fb771,
+	0x723e2009,
+	0x609c716a,
+	0xc1a4321c,
+	0x2a585c54,
+	0x512a2333,
+	0x9b83b957,
+	0xaa789a88,
+	0xf77108d3,
+	0x9d5dff9c,
+	0x3516bf33,
+	0x2553ec5e,
+	0x5b9cd3fc,
+	0xc4c8576c,
+	0xf49a4004,
+	0xbc0e4aa0,
+	0x23dd6368,
+	0x41ed272f,
+	0x2665d6de,
+	0x51ef3bc7,
+	0x5a7bbe62,
+	0x11711c5a,
+	0xd750fbb8,
+	0xfe0b186c,
+	0x1cacecb5,
+	0x4c3e6cff,
+	0xa9166568,
+	0x5c28eae4,
+	0x916df88f,
+	0x3581d00f,
+	0xfa85b4c6,
+	0xade872df,
+	0xbd2d75c7,
+	0x35a17396,
+	0xbe2f15ec,
+	0x2ed3dc19,
+	0xfc8ccfb4,
+	0xd72224ca,
+	0x5b467c42,
+	0x05740237,
+	0xc90cc5af,
+	0x7ee94bb7,
+	0x341ce345,
+	0xf6d5c608,
+	0x54395b3e,
+	0x86671dc1,
+	0xa012736f,
+	0xece35f7e,
+	0x98b029cf,
+	0xc3bac321,
+	0xa83bb90f,
+	0x4e98f460,
+	0x172ad9d0,
+	0x0ddf428b,
+	0xc732c52e,
+	0x751bb0b1,
+	0x7e635e70,
+	0xcf083db0,
+	0xf7665ffb,
+	0xd10b7314,
+	0x0a0915c2,
+	0x9b708e96,
+	0xdd6641dc,
+	0xd3c5503f,
+	0x99fcad3c,
+	0x7f7cdac4,
+	0xacf81c45,
+	0xbb9ac1aa,
+	0x9edba02a,
+	0xd2674351,
+	0x655d6e1a,
+	0x316eb98b,
+	0xef0da1b0,
+	0x230268a6,
+	0xa3d15e0c,
+	0x1af0fe7a,
+	0x545a1440,
+	0x58ebb256,
+	0x3004ba86,
+	0x5625f280,
+	0x31fba6e9,
+	0x0d816494,
+	0x26c6f165,
+	0xe871e8de,
+	0xe1d7f6d4,
+	0x023760f2,
+	0x440f27af,
+	0x728ba35f,
+	0x17ce346a,
+	0x3a11f0d1,
+	0x6207d713,
+	0x20f84bc8,
+	0xd6bbd3c5,
+	0x54e23e98,
+	0x4d55a3f4,
+	0x0bcb2af5,
+	0xd669176e,
+	0x587e3dfc,
+	0x76c2cb8f,
+	0xf76cf120,
+	0x4d5802b4,
+	0x5c14c2f2,
+	0x75343fec,
+	0xdd66b18c,
+	0xc71afb83,
+	0x98443a88,
+	0xdefbb711,
+	0xfdb0d451,
+	0x26c463d8,
+	0xbeb59073,
+	0xea637d70,
+	0x75ac392c,
+	0x8911a2c2,
+	0xea8a08c4,
+	0xb17c6b41,
+	0x95187ba1,
+	0xca82b4e0,
+	0x47b9b7c5,
+	0xd07c16f8,
+	0x0b008289,
+	0x1638d750,
+	0x1c67341e,
+	0x3d1c7fcd,
+	0x773a6217,
+	0x402ce582,
+	0xb391379f,
+	0x5f329458,
+	0x7df3edc8,
+	0x939cb659,
+	0x54cec0df,
+	0x32a63ce6,
+	0x5473cd21,
+	0x5399ca04,
+	0xd48fec8d,
+	0x184a35dd,
+	0x0259889e,
+	0xf5de1e03,
+	0xf637e932,
+	0xdac59987,
+	0x3482e9ef,
+	0xc4b0d39c,
+	0xc1703b84,
+	0x82783cc5,
+	0x609005de,
+	0xa6f4b2ec,
+	0x2cfd9aee,
+	0xeeba8f38,
+	0x4f1bd205,
+	0xa1f30232,
+	0x79587a9a,
+	0x9032d2a0,
+	0x3f2a3667,
+	0x0be30687,
+	0xab67f3b2,
+	0x5e7952bd,
+	0x1055730a,
+	0x7326e2ef,
+	0x4e90bafe,
+	0x40098ae4,
+	0xbc8b3245,
+	0xac40eacf,
+	0x990d0b6a,
+	0xcc285b9d,
+	0x1f84b128,
+	0x3d3baa7e,
+	0xa25b70c3,
+	0x24ad4c19,
+	0xea67f99e,
+	0x0692f3a5,
+	0x282a5acd,
+	0x507aa6fe,
+	0xb73af27f,
+	0x915227cc,
+	0xe3c0fb17,
+	0x234d8772,
+	0x5038947d,
+	0xa6770fb2,
+	0x0cbe5619,
+	0x62310604,
+	0x577f3820,
+	0xa0f465d0,
+	0xd58e64e3,
+	0xf9c7c1a0,
+	0x02366336,
+	0x7514c9ff,
+	0xc80e7468,
+	0x31c55e4c,
+	0x64f2ee36,
+	0x65308077,
+	0xcc8f7a9c,
+	0xd5afe99c,
+	0xa3d2f848,
+	0xbe343aed,
+	0xc9e5d1d9,
+	0x7689df57,
+	0x436efdb9,
+	0x02fe9c78,
+	0xbf44d386,
+	0xd1a7f051,
+	0x688f8e40,
+	0xbfc35d3f,
+	0x8e9ccf1d,
+	0x265725ce,
+	0x7b541f84,
+	0x04b7534a,
+	0x537689b7,
+	0xf0196afd,
+	0xa1c53118,
+	0xdd4b8f2f,
+	0x27a4542d,
+	0x148fc97f,
+	0xcbb1fe8e,
+	0xb0f0e359,
+	0x619182d1,
+	0x7fe52e97,
+	0x02112644,
+	0xde85b69d,
+	0x6ae60743,
+	0xc3957d75,
+	0x55ec9f1c,
+	0xdf5569a7,
+	0xff211f65,
+	0x9f191bb7,
+	0x27b4ed8e,
+	0x3d6b7584,
+	0x1eb61acd,
+	0x5ab3edfe,
+	0xb7746746,
+	0xe202812e,
+	0xc3a6dad6,
+	0x6eadbc54,
+	0xaaf3dbe5,
+	0x0d5d1241,
+	0x573db0ba,
+	0x6acb9a75,
+	0x355f4aad,
+	0xb7af5481,
+	0xd6895cc1,
+	0x9a3576ae,
+	0x0a4ce960,
+	0xea88e6c0,
+	0xf9777f8c,
+	0xf5586085,
+	0x96aa74a0,
+	0x6ba5f631,
+	0x98e69a66,
+	0xa27317f5,
+	0x7a62af6e,
+	0x7c640f8c,
+	0x40bdba17,
+	0xc3e35f92,
+	0x257c9a1c,
+	0x6ae2ba67,
+	0xd53319a8,
+	0x82ae2cff,
+	0x2b2e2602,
+	0x325499f0,
+	0x56415add,
+	0x2f76d62a,
+	0x13a4fea9,
+	0x82292dfc,
+	0x3452de2e,
+	0x21bc5307,
+	0xe8dc18ad,
+	0xa1cfbcfc,
+	0xa61f387b,
+	0xfd781889,
+	0x98e6417a,
+	0x12df4516,
+	0xb4946c67,
+	0x0cecea65,
+	0x04f28274,
+	0x9df23422,
+	0xb4dc8368,
+	0x8e2010e2,
+	0x4c304228,
+	0x99918a5a,
+	0x44cb62e4,
+	0xe5d3f6f9,
+	0xd45ab4f1,
+	0x15956307,
+	0x9243a7d6,
+	0x0c3ee4ca,
+	0xbfbc5d1b,
+	0x880c3c65,
+	0xe9a1e5f7,
+	0x6573caae,
+	0x2d971582,
+	0x2931af83,
+	0xfbab4eef,
+	0x9b954125,
+	0x16e305b1,
+	0xa2aad029,
+	0x0c4c4162,
+	0x2d29f41e,
+	0xd045716c,
+	0x836fd651,
+	0xb8aa8f3a,
+	0x6f884795,
+	0x98199e25,
+	0xecc70aec,
+	0xf85e31c4,
+	0x0f06b850,
+/*  Dummy terminator  */
+        0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0,
+};
+
+
diff --git a/src/mainboard/intel/jarrell/mptable.c b/src/mainboard/intel/jarrell/mptable.c
new file mode 100644
index 0000000..0773219
--- /dev/null
+++ b/src/mainboard/intel/jarrell/mptable.c
@@ -0,0 +1,293 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "LNXI    ";
+	static const char productid[12] = "SE7520JR20  ";
+	struct mp_config_table *mc;
+	unsigned char bus_num;
+	unsigned char bus_isa;
+	unsigned char bus_pxhd_1;
+	unsigned char bus_pxhd_2;
+	unsigned char bus_pxhd_3 = 0;
+	unsigned char bus_pxhd_4 = 0;
+	unsigned char bus_pxhd_x;
+	unsigned char bus_ich5r_1;
+	unsigned int bus_pxhd_id;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* initially just the header */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* not yet computed */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet... */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+	
+	{
+		device_t dev;
+
+		/* ich5r */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
+		if (dev) {
+			bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_isa++;
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1f.0, using defaults\n");
+
+			bus_ich5r_1 = 4;
+			bus_isa = 5;
+		}
+		/* pxhd-1 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x0,0));
+		if (dev) {
+			bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n");
+
+			bus_pxhd_1 = 2;
+		}
+		/* pxhd-2 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,2));
+		if (dev) {
+			bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
+
+			bus_pxhd_2 = 3;
+		}
+		/* test for active riser with 2nd pxh device */
+		dev = dev_find_slot(0, PCI_DEVFN(0x06,0));
+                if (dev) {
+			bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
+			if(bus_pxhd_id == 0x35998086) {
+				bus_pxhd_x = pci_read_config8(dev, PCI_SECONDARY_BUS);
+				/* pxhd-3 */
+				dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x0,0));
+				if (dev) {
+					bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
+					if(bus_pxhd_id == 0x03298086) {
+					    bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+					}
+				}
+				/* pxhd-4 */
+				dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,2));
+				if (dev) {
+					bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
+                                        if(bus_pxhd_id == 0x032a8086) {
+					    bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+					}
+				}
+			}
+		}
+	}
+	
+	/* define bus and isa numbers */
+	for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+		smp_write_bus(mc, bus_num, "PCI	  ");
+	}
+	smp_write_bus(mc, bus_isa, "ISA	  ");
+
+	/* IOAPIC handling */
+
+	smp_write_ioapic(mc, 8, 0x20, 0xfec00000);
+	{
+		struct resource *res;
+		device_t dev;
+		/* pxhd apic 3 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,1));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x09, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n");
+		}
+		/* pxhd apic 4 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,3));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x0a, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n");
+		}
+		/* pxhd apic 5 */
+		if(bus_pxhd_3) { /* Active riser pxhd */
+			dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,1));
+			if (dev) {
+				res = find_resource(dev, PCI_BASE_ADDRESS_0);
+				if (res) {
+					smp_write_ioapic(mc, 0x0b, 0x20, res->base);
+				}
+			}
+			else {
+				printk_debug("ERROR - could not find IOAPIC PCI %d:00.1\n",bus_pxhd_x);
+			}
+		}
+		/* pxhd apic 6 */
+		if(bus_pxhd_4) { /* active riser pxhd */
+			dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,3));
+			if (dev) {
+				res = find_resource(dev, PCI_BASE_ADDRESS_0);
+				if (res) {
+					smp_write_ioapic(mc, 0x0c, 0x20, res->base);
+				}
+			}
+			else {
+				printk_debug("ERROR - could not find IOAPIC PCI %d:00.3\n",bus_pxhd_x);
+			}
+		}
+	}
+
+	
+	/* ISA backward compatibility interrupts  */
+	smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x00, 0x08, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x01, 0x08, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x00, 0x08, 0x02);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x03, 0x08, 0x03);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x04, 0x08, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x06, 0x08, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x08, 0x08, 0x08);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x09, 0x08, 0x09);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x0c, 0x08, 0x0c);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x0d, 0x08, 0x0d);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x0e, 0x08, 0x0e);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x0f, 0x08, 0x0f);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0a, 0x08, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0b, 0x08, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0a, 0x08, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x07, 0x08, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0b, 0x08, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x05, 0x08, 0x17);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0b, 0x08, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x07, 0x08, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0b, 0x08, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_isa, 0x0a, 0x08, 0x10);
+
+	/* Standard local interrupt assignments */
+	smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x00, MP_APIC_ALL, 0x00);
+	smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_isa, 0x00, MP_APIC_ALL, 0x01);
+
+
+#warning "FIXME verify I have the irqs handled for all of the risers"
+	/* 2:3.0 PCI Slot 1 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_1, (3<<2)|0, 0x9, 0x0);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_1, (3<<2)|1, 0x9, 0x3);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_1, (3<<2)|2, 0x9, 0x5);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_1, (3<<2)|3, 0x9, 0x4);
+
+
+	/* 3:7.0 PCI Slot 2 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_2, (7<<2)|0, 0xa, 0x4);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_2, (7<<2)|1, 0xa, 0x3);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_2, (7<<2)|2, 0xa, 0x2);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_2, (7<<2)|3, 0xa, 0x1);
+
+	/* PCI Slot 3 (if active riser) */
+	if(bus_pxhd_3) {
+		smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+	                bus_pxhd_3, (1<<2)|0, 0xb, 0x0);
+	}
+
+	/* PCI Slot 4 (if active riser) */
+	if(bus_pxhd_4) {
+		smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+	                bus_pxhd_4, (1<<2)|0, 0xc, 0x0);
+	}
+
+	/* Onboard SCSI 0 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_1, (5<<2)|0, 0x9, 0x2);
+
+	/* Onboard SCSI 1 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_1, (5<<2)|1, 0x9, 0x1);
+
+	/* Onboard NIC 0 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_2, (4<<2)|0, 0xa, 0x6);
+
+	/* Onboard NIC 1 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		bus_pxhd_2, (4<<2)|1, 0xa, 0x7);
+
+	/* Onboard VGA */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
+		 bus_ich5r_1, (12<<2)|0, 0x8, 0x11);
+
+	/* There is no extension information... */
+
+	/* Compute the checksums */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+	printk_debug("Wrote the mp table end at: %p - %p\n",
+		mc, smp_next_mpe_entry(mc));
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
+
diff --git a/src/mainboard/intel/jarrell/power_reset_check.c b/src/mainboard/intel/jarrell/power_reset_check.c
new file mode 100644
index 0000000..e9008a4
--- /dev/null
+++ b/src/mainboard/intel/jarrell/power_reset_check.c
@@ -0,0 +1,12 @@
+
+static void power_down_reset_check(void)
+{
+	uint8_t cmos;
+
+	cmos=cmos_read(RTC_BOOT_BYTE)>>4 ;
+	print_debug("Boot byte = ");
+	print_debug_hex8(cmos);
+	print_debug("\r\n");
+
+	if((cmos>2)&&(cmos&1))  full_reset();
+}
diff --git a/src/mainboard/intel/jarrell/reset.c b/src/mainboard/intel/jarrell/reset.c
new file mode 100644
index 0000000..874bfc4
--- /dev/null
+++ b/src/mainboard/intel/jarrell/reset.c
@@ -0,0 +1,40 @@
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#ifndef __ROMCC__
+#include <device/device.h>
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+#define PCI_DEV_INVALID 0
+
+static inline device_t pci_locate_device(unsigned pci_id, device_t from)
+{
+	return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
+}
+#endif
+
+void soft_reset(void)
+{
+        outb(0x04, 0xcf9);
+}
+void hard_reset(void)
+{
+        outb(0x02, 0xcf9);
+        outb(0x06, 0xcf9);
+}
+void full_reset(void)
+{
+	device_t dev;
+	/* Enable power on after power fail... */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0);
+	if (dev != PCI_DEV_INVALID) {
+		unsigned byte;
+		byte = pci_read_config8(dev, 0xa4);
+		byte &= 0xfe;
+		pci_write_config8(dev, 0xa4, byte);
+		
+	}
+        outb(0x0e, 0xcf9);
+}
+
+
diff --git a/src/mainboard/intel/jarrell/watchdog.c b/src/mainboard/intel/jarrell/watchdog.c
new file mode 100644
index 0000000..29e8ba3
--- /dev/null
+++ b/src/mainboard/intel/jarrell/watchdog.c
@@ -0,0 +1,138 @@
+#include <device/pnp_def.h>
+
+#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
+#define NSC_WDBASE 0x600
+#define ICH5_WDBASE 0x400
+#define ICH5_GPIOBASE 0x500
+
+static void disable_sio_watchdog(device_t dev)
+{
+	/* FIXME move me somewhere more appropriate */
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 1);
+	pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
+	/* disable the sio watchdog */
+	outb(0, NSC_WDBASE + 0);
+	pnp_set_enable(dev, 0);
+}
+
+static void disable_ich5_watchdog(void)
+{
+	/* FIXME move me somewhere more appropriate */
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ICH5_WDBASE + 0x60;
+	
+	/* Set bit 11 in TCO1_CNT */
+	value = inw(base + 0x08);
+	value |= 1 << 11;
+	outw(value, base + 0x08);
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+}
+
+static void disable_jarell_frb3(void)
+{
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 0);
+	pci_write_config16(dev, 0x04, value);
+
+	/* Set gpio base */
+	pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
+	base = ICH5_GPIOBASE;
+
+	/* Enable GPIO Bar */
+	value = pci_read_config32(dev, 0x5c);
+	value |= 0x10;
+	pci_write_config32(dev, 0x5c, value);
+
+	/* Configure GPIO 48 and 40 as GPIO */
+	value = inl(base + 0x30);
+	value |= (1 << 16) | ( 1 << 8);
+	outl(value, base + 0x30);
+
+	/* Configure GPIO 48 as Output */
+	value = inl(base + 0x34);
+	value &= ~(1 << 16);
+	outl(value, base + 0x34);
+
+	/* Toggle GPIO 48 high to low */
+	value = inl(base + 0x38);
+	value |= (1 << 16);
+	outl(value, base + 0x38);
+	value &= ~(1 << 16);
+	outl(value, base + 0x38);
+				  
+}
+
+static void disable_watchdogs(void)
+{
+	disable_sio_watchdog(NSC_WD_DEV);
+	disable_ich5_watchdog();
+	disable_jarell_frb3();
+	print_debug("Watchdogs disabled\r\n");
+}
+
+static void ich5_watchdog_on(void)
+{
+	device_t dev;
+	unsigned long value, base;
+	unsigned char byte;
+
+	/* check cmos options */
+	byte = cmos_read(RTC_BOOT_BYTE-1);
+	if(!(byte & 1)) return; /* no boot watchdog */
+	byte = cmos_read(RTC_BOOT_BYTE);
+	if(!(byte & 2)) return; /* fallback so ignore */
+
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ICH5_WDBASE + 0x60;
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+
+	/* set the time value 1 cnt = .6 sec */
+	outw(0x0010, base + 0x01);
+	/* reload the timer with the value */
+	outw(0x0001, base + 0x00);
+
+	/* clear bit 11 in TCO1_CNT to start watchdog */
+	value = inw(base + 0x08);
+	value &= ~(1 << 11);
+	outw(value, base + 0x08);	
+
+	print_debug("Watchdog ICH5 enabled\r\n");
+}
diff --git a/src/mainboard/island/aruma/Config.lb b/src/mainboard/island/aruma/Config.lb
index f45862d..b05eb49 100644
--- a/src/mainboard/island/aruma/Config.lb
+++ b/src/mainboard/island/aruma/Config.lb
@@ -46,6 +46,7 @@
  object fadt.o
  object dsdt.o
 end
+object reset.o
 
 
 ##
diff --git a/src/mainboard/island/aruma/Options.lb b/src/mainboard/island/aruma/Options.lb
index fc9489a..87ff134 100644
--- a/src/mainboard/island/aruma/Options.lb
+++ b/src/mainboard/island/aruma/Options.lb
@@ -4,9 +4,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -82,13 +79,6 @@
 default HAVE_HARD_RESET=0
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/island/aruma/reset.c b/src/mainboard/island/aruma/reset.c
new file mode 100644
index 0000000..7f58d01
--- /dev/null
+++ b/src/mainboard/island/aruma/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 1);
+}
diff --git a/src/mainboard/newisys/khepri/Config.lb b/src/mainboard/newisys/khepri/Config.lb
index 947180d..506ae64 100644
--- a/src/mainboard/newisys/khepri/Config.lb
+++ b/src/mainboard/newisys/khepri/Config.lb
@@ -45,6 +45,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
 
 dir /drivers/trident/blade3d
 
diff --git a/src/mainboard/newisys/khepri/Options.lb b/src/mainboard/newisys/khepri/Options.lb
index d80f0c3..37733ac 100644
--- a/src/mainboard/newisys/khepri/Options.lb
+++ b/src/mainboard/newisys/khepri/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -74,13 +71,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/newisys/khepri/reset.c b/src/mainboard/newisys/khepri/reset.c
new file mode 100644
index 0000000..6395818
--- /dev/null
+++ b/src/mainboard/newisys/khepri/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 2);
+}
diff --git a/src/mainboard/supermicro/x6dai_g/Config.lb b/src/mainboard/supermicro/x6dai_g/Config.lb
new file mode 100644
index 0000000..8d4ada5
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/Config.lb
@@ -0,0 +1,198 @@
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can be cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=131072
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc" 
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc 
+	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc    -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc
+	ldscript /cpu/x86/16bit/reset16.lds
+else
+	mainboardinit cpu/x86/32bit/reset32.inc
+	ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/E7525 # mch
+	device pci_domain 0 on
+		chip southbridge/intel/esb6300  # esb6300 
+			register "pirq_a_d" = "0x0b0a0a05"
+			register "pirq_e_h" = "0x0a0b0c80"
+		
+			device pci 1c.0 on end
+		
+			device pci 1d.0 on end
+			device pci 1d.1 on end
+			device pci 1d.4 on end
+			device pci 1d.5 on end
+			device pci 1d.7 on end
+		
+			device pci 1e.0 on end
+		
+			device pci 1f.0 on 
+				chip superio/winbond/w83627hf
+					device pnp 2e.0 off end
+					device pnp 2e.1 off end
+					device pnp 2e.2 on
+						 io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.3 on
+						 io 0x60 = 0x2f8
+						irq 0x70 = 3
+					end
+					device pnp 2e.4 off end
+					device pnp 2e.5 off end
+					device pnp 2e.6 off end
+					device pnp 2e.7 off end
+					device pnp 2e.9 off end
+					device pnp 2e.a on  end
+					device pnp 2e.b off end
+					device pnp 2e.f off end
+					device pnp 2e.10 off end
+					device pnp 2e.14 off end
+				end
+			end
+			device pci 1f.1 on end
+			device pci 1f.2 on end
+			device pci 1f.3 on end
+			device pci 1f.5 off end
+			device pci 1f.6 on end
+		end
+		device pci 00.0 on end
+		device pci 00.1 on end 
+		device pci 00.2 on end
+		device pci 02.0 on end
+		device pci 03.0 on end
+		device pci 04.0 on end
+		device pci 08.0 on end
+	end
+	device apic_cluster 0 on
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu0
+			device apic 0 on end
+		end
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu1
+			device apic 6 on end
+		end
+	end
+end
+
diff --git a/src/mainboard/supermicro/x6dai_g/Options.lb b/src/mainboard/supermicro/x6dai_g/Options.lb
new file mode 100644
index 0000000..822e31f
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/Options.lb
@@ -0,0 +1,229 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_BTEXT
+uses CC
+uses HOSTCC
+uses CROSS_COMPILE
+uses OBJCOPY
+
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=1048576
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Delay timer options
+## Use timer2
+## 
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=16
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=4
+default CONFIG_LOGICAL_CPUS=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="X6DAI"
+default MAINBOARD_VENDOR=     "Supermicro"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6780
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+default FALLBACK_SIZE=131072
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM=1
+
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+##
+## Don't enable the btext console
+##
+default  CONFIG_CONSOLE_BTEXT=0
+
+
+### End Options.lb
+end
+
diff --git a/src/mainboard/supermicro/x6dai_g/auto.c b/src/mainboard/supermicro/x6dai_g/auto.c
new file mode 100644
index 0000000..f148a8c
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/auto.c
@@ -0,0 +1,139 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/esb6300/esb6300_early_smbus.c"
+#include "northbridge/intel/E7525/raminit.h"
+#include "superio/winbond/w83627hf/w83627hf.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "debug.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "superio/winbond/w83627hf/w83627hf_early_init.c"
+#include "northbridge/intel/E7525/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, W83627HF_SP2)
+
+#define DEVPRES_CONFIG  ( \
+	DEVPRES_D1F0 | \
+	DEVPRES_D2F0 | \
+	DEVPRES_D3F0 | \
+	DEVPRES_D4F0 | \
+	DEVPRES_D6F0 | \
+	0 )
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+#define RECVENA_CONFIG  0x0808090a
+#define RECVENB_CONFIG  0x0808090a
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7525/raminit.c"
+#include "sdram/generic_sdram.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+			.channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, },
+			.channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, },
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
+	w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing 6300ESB?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	display_cpuid_update_microcode();
+#endif
+#if 0
+	print_pci_devices();
+#endif
+#if 1
+	enable_smbus();
+#endif
+#if 0
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+#if 1
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+//	dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+	ram_check(0x00100000, 0x01000000);
+	/* check the first 1M in the 3rd Gig */
+	ram_check(0x30100000, 0x31000000);
+#endif
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/supermicro/x6dai_g/chip.h b/src/mainboard/supermicro/x6dai_g/chip.h
new file mode 100644
index 0000000..02f1518
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/chip.h
@@ -0,0 +1,5 @@
+struct chip_operations mainboard_supermicro_x6dai_g_ops;
+
+struct mainboard_supermicro_x6dai_g_config {
+	int nothing;
+};
diff --git a/src/mainboard/supermicro/x6dai_g/cmos.layout b/src/mainboard/supermicro/x6dai_g/cmos.layout
new file mode 100644
index 0000000..6f3cd18
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/cmos.layout
@@ -0,0 +1,80 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       2        hyper_threading
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/supermicro/x6dai_g/debug.c b/src/mainboard/supermicro/x6dai_g/debug.c
new file mode 100644
index 0000000..5546421
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/debug.c
@@ -0,0 +1,330 @@
+#define SMBUS_MEM_DEVICE_START 0x50
+#define SMBUS_MEM_DEVICE_END 0x57
+#define SMBUS_MEM_DEVICE_INC 1
+
+static void print_reg(unsigned char index)
+{
+        unsigned char data;
+                                                                                
+        outb(index, 0x2e);
+        data = inb(0x2f);
+	print_debug("0x");
+	print_debug_hex8(index);
+	print_debug(": 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+        return;
+}
+        
+static void xbus_en(void)
+{
+        /* select the XBUS function in the SIO */
+        outb(0x07, 0x2e);
+        outb(0x0f, 0x2f);
+        outb(0x30, 0x2e);
+        outb(0x01, 0x2f);
+	return;
+}
+                                                                        
+static void setup_func(unsigned char func)
+{
+        /* select the function in the SIO */
+        outb(0x07, 0x2e);
+        outb(func, 0x2f);
+        /* print out the regs */
+        print_reg(0x30);
+        print_reg(0x60);
+        print_reg(0x61);
+        print_reg(0x62);
+        print_reg(0x63);
+        print_reg(0x70);
+        print_reg(0x71);
+        print_reg(0x74);
+        print_reg(0x75);
+        return;
+}
+                                                                                
+static void siodump(void)
+{
+        int i;
+        unsigned char data;
+       
+	 print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
+        for (i=0x10; i<=0x2d; i++) {
+                print_reg((unsigned char)i);
+        }
+#if 0                                                                         
+        print_debug("\r\n*** XBUS REGISTERS ***\r\n");
+        setup_func(0x0f);
+        for (i=0xf0; i<=0xff; i++) {
+                print_reg((unsigned char)i);
+        }
+                                                                                
+        print_debug("\r\n***  SERIAL 1 CONFIG REGISTERS ***\r\n");
+        setup_func(0x03);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  SERIAL 2 CONFIG REGISTERS ***\r\n");
+        setup_func(0x02);
+        print_reg(0xf0);
+
+#endif
+        print_debug("\r\n***  GPIO REGISTERS ***\r\n");
+        setup_func(0x07);
+        for (i=0xf0; i<=0xf8; i++) {
+                print_reg((unsigned char)i);
+        }
+        print_debug("\r\n***  GPIO VALUES ***\r\n");
+        data = inb(0x68a);
+	print_debug("\r\nGPDO 4: 0x");
+	print_debug_hex8(data);
+        data = inb(0x68b);
+	print_debug("\r\nGPDI 4: 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+	
+#if 0                                                                                
+                                                                                
+        print_debug("\r\n***  WATCHDOG TIMER REGISTERS ***\r\n");
+        setup_func(0x0a);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  FAN CONTROL REGISTERS ***\r\n");
+        setup_func(0x09);
+        print_reg(0xf0);
+        print_reg(0xf1);
+
+        print_debug("\r\n***  RTC REGISTERS ***\r\n");
+        setup_func(0x10);
+        print_reg(0xf0);
+        print_reg(0xf1);
+        print_reg(0xf3);
+        print_reg(0xf6);
+        print_reg(0xf7);
+        print_reg(0xfe);
+        print_reg(0xff);
+                                                                                
+        print_debug("\r\n***  HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
+        setup_func(0x14);
+        print_reg(0xf0);
+#endif                                                                           
+        return;
+}
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_bar14(unsigned dev)
+{
+	int i;
+	unsigned long bar;
+	
+	print_debug("BAR 14 Dump\r\n");
+	
+	bar = pci_read_config32(dev, 0x14);
+	for(i = 0; i <= 0x300; i+=4) {
+#if 0		
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+#endif		
+		if((i%4)==0) {
+		print_debug("\r\n");
+		print_debug_hex16(i);
+		print_debug_char(' ');
+		}
+		print_debug_hex32(read32(bar + i));
+		print_debug_char(' ');
+	}
+	print_debug("\r\n");
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+#if 0
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+	}
+}
+#endif
+
+void dump_spd_registers(void)
+{
+        unsigned device;
+        device = SMBUS_MEM_DEVICE_START;
+        while(device <= SMBUS_MEM_DEVICE_END) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("dimm ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 256) ; i++) {
+	                unsigned char byte;
+                        if ((i % 16) == 0) {
+				print_debug("\r\n");
+				print_debug_hex8(i);
+				print_debug(": ");
+                        }
+			status = smbus_read_byte(device, i);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}
+
+void dump_ipmi_registers(void)
+{
+        unsigned device;
+        device = 0x42;
+        while(device <= 0x42) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("ipmi ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 8) ; i++) {
+	                unsigned char byte;
+			status = smbus_read_byte(device, 2);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}	
diff --git a/src/mainboard/supermicro/x6dai_g/failover.c b/src/mainboard/supermicro/x6dai_g/failover.c
new file mode 100644
index 0000000..1a4a88e
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/failover.c
@@ -0,0 +1,46 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "pc80/mc146818rtc_early.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/intel/E7525/memory_initialized.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* Did just the cpu reset? */
+	if (memory_initialized()) {
+	 	if (last_boot_normal()) {
+			goto normal_image;
+		} else {
+			goto cpu_reset;
+		}
+	}
+
+	/* This is the primary cpu how should I boot? */
+	else if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
diff --git a/src/mainboard/supermicro/x6dai_g/irq_tables.c b/src/mainboard/supermicro/x6dai_g/irq_tables.c
new file mode 100644
index 0000000..c34a722
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/irq_tables.c
@@ -0,0 +1,34 @@
+/* PCI: Interrupt Routing Table found at 0x40163ed0 size = 272 */
+
+#include <arch/pirq_routing.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+	0x52495024, /* u32 signature */
+	0x0100,     /* u16 version   */
+	272,        /* u16 Table size 32+(16*devices)  */
+	0x00,       /* u8 Bus 0 */
+	0xf8,       /* u8 Device 1, Function 0 */
+	0x0000,     /* u16 reserve IRQ for PCI */
+	0x8086,     /* u16 Vendor */
+	0x122e,     /* Device ID */
+	0x00000000, /* u32 miniport_data */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0x78,   /*  u8 checksum - mod 256 checksum must give zero */
+	{  /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  */
+	    {0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00,  0x00},
+	    {0x00, 0x10, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00,  0x00},
+	    {0x01, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x04,  0x00},
+	    {0x00, 0x20, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00,  0x00},
+	    {0x02, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x06,  0x00},
+	    {0x00, 0xe0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00,  0x00},
+	    {0x04, 0x08, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x01,  0x00},
+	    {0x04, 0x10, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x07,  0x00},
+	    {0x04, 0x18, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x02,  0x00},
+	    {0x00, 0xf0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00,  0x00},
+	    {0x05, 0x40, {{0x68, 0x1ef8}, {0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}}, 0x03,  0x00},
+	    {0x05, 0x18, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x08,  0x00},
+	    {0x05, 0x10, {{0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}, {0x68, 0x1ef8}}, 0x05,  0x00},
+	    {0x00, 0xf8, {{0x62, 0x1ef8}, {0x61, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00,  0x00},
+	    {0x00, 0xe8, {{0x60, 0x1ef8}, {0x63, 0x1ef8}, {0x00, 0xdef8}, {0x6b, 0x1ef8}}, 0x00,  0x00}
+	}
+};
diff --git a/src/mainboard/supermicro/x6dai_g/mainboard.c b/src/mainboard/supermicro/x6dai_g/mainboard.c
new file mode 100644
index 0000000..bf74198
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include "chip.h"
+
+struct chip_operations supermicro_x6dai_g_ops = {
+	CHIP_NAME("Supermicro X6DAI_G mainboard ")
+};
+
diff --git a/src/mainboard/supermicro/x6dai_g/mptable.c b/src/mainboard/supermicro/x6dai_g/mptable.c
new file mode 100644
index 0000000..9d793c4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/mptable.c
@@ -0,0 +1,142 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "LNXI    ";
+	static const char productid[12] = "X6DAI-G     ";
+	struct mp_config_table *mc;
+	unsigned char bus_num;
+	unsigned char bus_isa;
+	unsigned char bus_6300;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* initially just the header */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* not yet computed */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet... */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+	
+	{
+		device_t dev;
+
+		/* southbridge */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
+		if (dev) {
+			bus_6300 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_isa++;
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n");
+			bus_6300 = 5;
+			bus_isa = 6;
+		}
+	}
+	
+	/* define bus and isa numbers */
+	for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+		smp_write_bus(mc, bus_num, "PCI	  ");
+	}
+	smp_write_bus(mc, bus_isa, "ISA	  ");
+
+	/* IOAPIC handling */
+
+	smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
+	smp_write_ioapic(mc, 3, 0x20, 0xfec10000);
+
+	/* ISA backward compatibility interrupts  */
+	smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x01, 0x02, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x02);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x03, 0x02, 0x03);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x04, 0x02, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x06, 0x02, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x07, 0x02, 0x07);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x08, 0x02, 0x08);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x09, 0x02, 0x09);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x77, 0x02, 0x17);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x75, 0x02, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0c, 0x02, 0x0c);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0d, 0x02, 0x0d);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0e, 0x02, 0x0e);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0f, 0x02, 0x0f);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7c, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7d, 0x02, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7d, 0x02, 0x11);
+	/* Slot 1 function 0 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		4, 0x04, 0x03, 0x00);
+	/* Slot 2 function 0 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		4, 0x0c, 0x03, 0x01);
+	/* Slot 3 function 0 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_6300, 0x20, 0x02, 0x14);
+	/* Slot 4 function 0 */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_6300, 0x08, 0x02, 0x15);
+	/* On board NIC */
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_6300, 0x0c, 0x02, 0x16);
+
+	/* Standard local interrupt assignments */
+//	smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+//		bus_isa, 0x00, MP_APIC_ALL, 0x00);
+	smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x01);
+
+	/* There is no extension information... */
+
+	/* Compute the checksums */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+	printk_debug("Wrote the mp table end at: %p - %p\n",
+		mc, smp_next_mpe_entry(mc));
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
+
diff --git a/src/mainboard/supermicro/x6dai_g/reset.c b/src/mainboard/supermicro/x6dai_g/reset.c
new file mode 100644
index 0000000..1d7f5a3
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/reset.c
@@ -0,0 +1,40 @@
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#ifndef __ROMCC__
+#include <device/device.h>
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+#define PCI_DEV_INVALID 0
+
+static inline device_t pci_locate_device(unsigned pci_id, device_t from)
+{
+	return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
+}
+#endif
+
+void soft_reset(void)
+{
+        outb(0x04, 0xcf9);
+}
+void hard_reset(void)
+{
+        outb(0x02, 0xcf9);
+        outb(0x06, 0xcf9);
+}
+void full_reset(void)
+{
+	device_t dev;
+	/* Enable power on after power fail... */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_6300ESB_ISA), 0);
+	if (dev != PCI_DEV_INVALID) {
+		unsigned byte;
+		byte = pci_read_config8(dev, 0xa4);
+		byte &= 0xfe;
+		pci_write_config8(dev, 0xa4, byte);
+		
+	}
+        outb(0x0e, 0xcf9);
+}
+
+
diff --git a/src/mainboard/supermicro/x6dai_g/watchdog.c b/src/mainboard/supermicro/x6dai_g/watchdog.c
new file mode 100644
index 0000000..465ba4c
--- /dev/null
+++ b/src/mainboard/supermicro/x6dai_g/watchdog.c
@@ -0,0 +1,42 @@
+#include <device/pnp_def.h>
+
+#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
+#define NSC_WDBASE 0x600
+#define ICH5_WDBASE 0x400
+#define ICH5_GPIOBASE 0x500
+
+static void disable_esb6300_watchdog(void)
+{
+	/* FIXME move me somewhere more appropriate */
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing 6300ESB?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ICH5_WDBASE + 0x60;
+	
+	/* Set bit 11 in TCO1_CNT */
+	value = inw(base + 0x08);
+	value |= 1 << 11;
+	outw(value, base + 0x08);
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+}
+
+static void disable_watchdogs(void)
+{
+	disable_esb6300_watchdog();
+	print_debug("Watchdogs disabled\r\n");
+}
+
diff --git a/src/mainboard/supermicro/x6dhe_g/Config.lb b/src/mainboard/supermicro/x6dhe_g/Config.lb
new file mode 100644
index 0000000..672da82
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/Config.lb
@@ -0,0 +1,220 @@
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of LinuxBIOS will start in the boot rom
+##
+default _ROMBASE	=( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can be cached to speed up linuxBIOS.
+## execution speed.
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+default XIP_ROM_SIZE=131072
+default XIP_ROM_BASE= ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+makerule ./auto.inc 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc    -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc 
+	ldscript /cpu/x86/16bit/reset16.lds 
+else
+	mainboardinit cpu/x86/32bit/reset32.inc 
+	ldscript /cpu/x86/32bit/reset32.lds 
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/E7520  # MCH
+	chip drivers/generic/debug  # DEBUGGING
+		device pnp 00.0 on end
+		device pnp 00.1 off end
+		device pnp 00.2 off end
+		device pnp 00.3 off end
+	end
+	device pci_domain 0 on
+		chip southbridge/intel/esb6300	# ESB6300
+			register "pirq_a_d" = "0x0b070a05"
+			register "pirq_e_h" = "0x0a808080"
+
+			device pci 1c.0 on 
+				chip drivers/generic/generic 
+					device pci 01.0 on end	# onboard gige1
+					device pci 02.0 on end 	# onboard gige2
+				end
+			end
+
+			# USB ports
+			device pci 1d.0 on end
+			device pci 1d.1 on end
+			device pci 1d.4 on end	# Southbridge Watchdog timer
+			device pci 1d.5 on end	# Southbridge I/O apic1
+			device pci 1d.7 on end
+
+			# VGA / PCI 32-bit
+			device pci 1e.0 on 
+				chip drivers/generic/generic
+					device pci 01.0 on end 
+				end
+			end
+
+
+			device pci 1f.0 on 	# ISA bridge
+				chip superio/winbond/w83627hf
+					device pnp 2e.0 off end
+					device pnp 2e.2 on 
+						 io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.3 on
+						 io 0x60 = 0x2f8
+						irq 0x70 = 3
+					end
+					device pnp 2e.4 off end
+					device pnp 2e.5 off end
+					device pnp 2e.6 off end
+					device pnp 2e.7 off end
+					device pnp 2e.9 off end
+					device pnp 2e.a on end
+					device pnp 2e.b off end
+				end
+			end
+			device pci 1f.1 on end
+			device pci 1f.2 off end
+			device pci 1f.3	on end		# SMBus
+			device pci 1f.5 off end
+			device pci 1f.6 off end
+		end
+
+		device pci 00.0	on end	# Northbridge
+		device pci 00.1	on end  # Northbridge Error reporting
+		device pci 01.0 on end
+		device pci 02.0 on 
+			chip southbridge/intel/pxhd	# PXHD 6700 
+				device pci 00.0 on end   # bridge 
+				device pci 00.1 on end   # I/O apic
+				device pci 00.2 on end   # bridge
+				device pci 00.3 on end   # I/O apic
+			end
+		end
+#	 	device register "intrline" = "0x00070105" 
+		device 	pci 04.0 on end	
+		device 	pci 06.0 on end	
+	end
+
+	device apic_cluster 0 on
+		chip cpu/intel/socket_mPGA604_800Mhz  	# CPU 0
+			device apic 0 on end
+		end
+		chip cpu/intel/socket_mPGA604_800Mhz 	# CPU 1
+			device apic 6 on end
+		end
+	end
+end
diff --git a/src/mainboard/supermicro/x6dhe_g/Options.lb b/src/mainboard/supermicro/x6dhe_g/Options.lb
new file mode 100644
index 0000000..d09effc
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/Options.lb
@@ -0,0 +1,229 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_BTEXT
+uses CC
+uses HOSTCC
+uses CROSS_COMPILE
+uses OBJCOPY
+
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=1048576
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Delay timer options
+## Use timer2
+## 
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=16
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=4
+default CONFIG_LOGICAL_CPUS=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="X6DHE_g"
+default MAINBOARD_VENDOR=     "Supermicro"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6080
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+default FALLBACK_SIZE=131072
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM=1
+
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+##
+## Don't enable the btext console
+##
+default  CONFIG_CONSOLE_BTEXT=0
+
+
+### End Options.lb
+end
+
diff --git a/src/mainboard/supermicro/x6dhe_g/auto.c b/src/mainboard/supermicro/x6dhe_g/auto.c
new file mode 100644
index 0000000..be5affc
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/auto.c
@@ -0,0 +1,167 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/esb6300/esb6300_early_smbus.c"
+#include "northbridge/intel/E7520/raminit.h"
+#include "superio/winbond/w83627hf/w83627hf.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "debug.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "x6dhe_g_fixups.c"
+#include "superio/winbond/w83627hf/w83627hf_early_init.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, W83627HF_SP2)
+
+#define DEVPRES_CONFIG  ( \
+	DEVPRES_D1F0 | \
+	DEVPRES_D2F0 | \
+	DEVPRES_D3F0 | \
+	DEVPRES_D4F0 | \
+	DEVPRES_D6F0 | \
+	0 )
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+#define RECVENA_CONFIG  0x0808090a
+#define RECVENB_CONFIG  0x0808090a
+
+//void udelay(int usecs)
+//{
+//        int i;
+//        for(i = 0; i < usecs; i++)
+//                outb(i&0xff, 0x80);
+//}
+
+#if 0
+static void hard_reset(void)
+{
+	/* enable cf9 */
+	pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+	/* reset */
+	outb(0x0e, 0x0cf9);
+}
+#endif
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7520/raminit.c"
+#include "sdram/generic_sdram.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+			.channel0 = {(0xa<<3)|0, (0xa<<3)|1, (0xa<<3)|2, (0xa<<3)|3, },
+			.channel1 = {(0xa<<3)|4, (0xa<<3)|5, (0xa<<3)|6, (0xa<<3)|7, },
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
+	w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+//	report_bist_failure(bist);
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing esb6300?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	display_cpuid_update_microcode();
+#endif
+#if 0
+	print_pci_devices();
+#endif
+#if 1
+	enable_smbus();
+#endif
+#if 0
+//	dump_spd_registers(&cpu[0]);
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+//	dump_ipmi_registers();
+//	mainboard_set_e7520_leds();	
+//	memreset_setup();
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+#if 0
+	dump_pci_devices();
+#endif
+#if 0
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+	dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+	ram_check(0x00100000, 0x01000000);
+	/* check the first 1M in the 3rd Gig */
+	ram_check(0x30100000, 0x31000000);
+#endif
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/supermicro/x6dhe_g/chip.h b/src/mainboard/supermicro/x6dhe_g/chip.h
new file mode 100644
index 0000000..f8ba112
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/chip.h
@@ -0,0 +1,5 @@
+struct chip_operations mainboard_supermicro_x6dhe_g_ops;
+
+struct mainboard_supermicro_x6dhe_g_config {
+	int nothing;
+};
diff --git a/src/mainboard/supermicro/x6dhe_g/cmos.layout b/src/mainboard/supermicro/x6dhe_g/cmos.layout
new file mode 100644
index 0000000..6f3cd18
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/cmos.layout
@@ -0,0 +1,80 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       2        hyper_threading
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g/debug.c b/src/mainboard/supermicro/x6dhe_g/debug.c
new file mode 100644
index 0000000..5546421
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/debug.c
@@ -0,0 +1,330 @@
+#define SMBUS_MEM_DEVICE_START 0x50
+#define SMBUS_MEM_DEVICE_END 0x57
+#define SMBUS_MEM_DEVICE_INC 1
+
+static void print_reg(unsigned char index)
+{
+        unsigned char data;
+                                                                                
+        outb(index, 0x2e);
+        data = inb(0x2f);
+	print_debug("0x");
+	print_debug_hex8(index);
+	print_debug(": 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+        return;
+}
+        
+static void xbus_en(void)
+{
+        /* select the XBUS function in the SIO */
+        outb(0x07, 0x2e);
+        outb(0x0f, 0x2f);
+        outb(0x30, 0x2e);
+        outb(0x01, 0x2f);
+	return;
+}
+                                                                        
+static void setup_func(unsigned char func)
+{
+        /* select the function in the SIO */
+        outb(0x07, 0x2e);
+        outb(func, 0x2f);
+        /* print out the regs */
+        print_reg(0x30);
+        print_reg(0x60);
+        print_reg(0x61);
+        print_reg(0x62);
+        print_reg(0x63);
+        print_reg(0x70);
+        print_reg(0x71);
+        print_reg(0x74);
+        print_reg(0x75);
+        return;
+}
+                                                                                
+static void siodump(void)
+{
+        int i;
+        unsigned char data;
+       
+	 print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
+        for (i=0x10; i<=0x2d; i++) {
+                print_reg((unsigned char)i);
+        }
+#if 0                                                                         
+        print_debug("\r\n*** XBUS REGISTERS ***\r\n");
+        setup_func(0x0f);
+        for (i=0xf0; i<=0xff; i++) {
+                print_reg((unsigned char)i);
+        }
+                                                                                
+        print_debug("\r\n***  SERIAL 1 CONFIG REGISTERS ***\r\n");
+        setup_func(0x03);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  SERIAL 2 CONFIG REGISTERS ***\r\n");
+        setup_func(0x02);
+        print_reg(0xf0);
+
+#endif
+        print_debug("\r\n***  GPIO REGISTERS ***\r\n");
+        setup_func(0x07);
+        for (i=0xf0; i<=0xf8; i++) {
+                print_reg((unsigned char)i);
+        }
+        print_debug("\r\n***  GPIO VALUES ***\r\n");
+        data = inb(0x68a);
+	print_debug("\r\nGPDO 4: 0x");
+	print_debug_hex8(data);
+        data = inb(0x68b);
+	print_debug("\r\nGPDI 4: 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+	
+#if 0                                                                                
+                                                                                
+        print_debug("\r\n***  WATCHDOG TIMER REGISTERS ***\r\n");
+        setup_func(0x0a);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  FAN CONTROL REGISTERS ***\r\n");
+        setup_func(0x09);
+        print_reg(0xf0);
+        print_reg(0xf1);
+
+        print_debug("\r\n***  RTC REGISTERS ***\r\n");
+        setup_func(0x10);
+        print_reg(0xf0);
+        print_reg(0xf1);
+        print_reg(0xf3);
+        print_reg(0xf6);
+        print_reg(0xf7);
+        print_reg(0xfe);
+        print_reg(0xff);
+                                                                                
+        print_debug("\r\n***  HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
+        setup_func(0x14);
+        print_reg(0xf0);
+#endif                                                                           
+        return;
+}
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_bar14(unsigned dev)
+{
+	int i;
+	unsigned long bar;
+	
+	print_debug("BAR 14 Dump\r\n");
+	
+	bar = pci_read_config32(dev, 0x14);
+	for(i = 0; i <= 0x300; i+=4) {
+#if 0		
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+#endif		
+		if((i%4)==0) {
+		print_debug("\r\n");
+		print_debug_hex16(i);
+		print_debug_char(' ');
+		}
+		print_debug_hex32(read32(bar + i));
+		print_debug_char(' ');
+	}
+	print_debug("\r\n");
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+#if 0
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+	}
+}
+#endif
+
+void dump_spd_registers(void)
+{
+        unsigned device;
+        device = SMBUS_MEM_DEVICE_START;
+        while(device <= SMBUS_MEM_DEVICE_END) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("dimm ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 256) ; i++) {
+	                unsigned char byte;
+                        if ((i % 16) == 0) {
+				print_debug("\r\n");
+				print_debug_hex8(i);
+				print_debug(": ");
+                        }
+			status = smbus_read_byte(device, i);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}
+
+void dump_ipmi_registers(void)
+{
+        unsigned device;
+        device = 0x42;
+        while(device <= 0x42) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("ipmi ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 8) ; i++) {
+	                unsigned char byte;
+			status = smbus_read_byte(device, 2);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}	
diff --git a/src/mainboard/supermicro/x6dhe_g/failover.c b/src/mainboard/supermicro/x6dhe_g/failover.c
new file mode 100644
index 0000000..5029d98
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/failover.c
@@ -0,0 +1,46 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "pc80/mc146818rtc_early.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* Did just the cpu reset? */
+	if (memory_initialized()) {
+	 	if (last_boot_normal()) {
+			goto normal_image;
+		} else {
+			goto cpu_reset;
+		}
+	}
+
+	/* This is the primary cpu how should I boot? */
+	else if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
diff --git a/src/mainboard/supermicro/x6dhe_g/irq_tables.c b/src/mainboard/supermicro/x6dhe_g/irq_tables.c
new file mode 100644
index 0000000..0851fbe
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/irq_tables.c
@@ -0,0 +1,34 @@
+/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */
+
+#include <arch/pirq_routing.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+	0x52495024, /* u32 signature */
+	0x0100,     /* u16 version   */
+	272,        /* u16 Table size 32+(15*devices)  */
+	0x00,       /* u8 Bus 0 */
+	0xf8,       /* u8 Device 1, Function 0 */
+	0x0000,     /* u16 reserve IRQ for PCI */
+	0x8086,     /* u16 Vendor */
+	0x25a1,     /* Device ID */
+	0x00000000, /* u32 miniport_data */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0xc4,   /*  u8 checksum - mod 256 checksum must give zero */
+	{  /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  */
+	    {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06,  0x00},
+	    {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07,  0x00}
+	}
+};
diff --git a/src/mainboard/supermicro/x6dhe_g/mainboard.c b/src/mainboard/supermicro/x6dhe_g/mainboard.c
new file mode 100644
index 0000000..6cb224f
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include "chip.h"
+
+struct chip_operations supermicro_x6dhe_g_ops = {
+    CHIP_NAME("Supermicro X6DHE_G mainboard")
+};
+
diff --git a/src/mainboard/supermicro/x6dhe_g/microcode_updates.c b/src/mainboard/supermicro/x6dhe_g/microcode_updates.c
new file mode 100644
index 0000000..b2e72ab
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/microcode_updates.c
@@ -0,0 +1,1563 @@
+/* WARNING - Intel has a new data structure that has variable length

+ * microcode update lengths.  They are encoded in int 8 and 9.  A

+ * dummy header of nulls must terminate the list.

+ */

+                                                                                

+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {

+        /*

+           Copyright  Intel Corporation, 1995, 96, 97, 98, 99, 2000.

+           These microcode updates are distributed for the sole purpose of

+           installation in the BIOS or Operating System of computer systems

+           which include an Intel P6 family microprocessor sold or distributed

+           to or by you.  You are authorized to copy and install this material

+           on such systems.  You are not authorized to use this material for

+           any other purpose.

+        */

+                                                                                

+        /*  M1DF3413.TXT - Noconoa D-0  */

+                                                                                

+        0x00000001, /* Header Version   */

+        0x00000013, /* Patch ID         */

+        0x07302004, /* DATE             */

+        0x00000f34, /* CPUID            */

+        0x95f183f0, /* Checksum         */

+        0x00000001, /* Loader Version   */

+        0x0000001d, /* Platform ID      */

+        0x000017d0, /* Data size        */

+        0x00001800, /* Total size       */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+ 

+	0x9fbf327a,

+	0x2b41b451,

+	0xb2abaca8,

+	0x6b62b8e0,

+	0x0af32c41,

+	0x12ca6048,

+	0x5bd55ae6,

+	0xb90dfc1d,

+	0x565fe2b2,

+	0x326b1718,

+	0x61f3a40d,

+	0xceb53db3,

+	0x14fb5261,

+	0xbb23b6c3,

+	0x9d7c0466,

+	0xde90a25e,

+	0x9450e9bb,

+	0x497bd6e4,

+	0x97d1041a,

+	0x1831013f,

+	0x6e6fa37e,

+	0x0b5c1d03,

+	0x5eae4db2,

+	0xc029d9e3,

+	0x5373bca3,

+	0xe15fccca,

+	0x39043db0,

+	0xaeb0ea0c,

+	0x62b4e391,

+	0x0b280c6b,

+	0x279eb9d3,

+	0x98d95ada,

+	0xc1cb45a7,

+	0x06917bda,

+	0xdde8aafa,

+	0xdff9d15c,

+	0xd07f8f0a,

+	0x192bcf9d,

+	0xf77de31f,

+	0xadf8be55,

+	0x3f7a5d95,

+	0x0e2140b6,

+	0xf0c75eec,

+	0x3254876a,

+	0x684a1698,

+	0x4ad0cca7,

+	0x6d705304,

+	0xf957d91b,

+	0xe8bb864a,

+	0x440d636c,

+	0xaf4d7d06,

+	0x12680ecf,

+	0x5d0f9e53,

+	0x60148a5d,

+	0x81008364,

+	0x243a8aed,

+	0xd55976de,

+	0xd6a84520,

+	0x932d4b77,

+	0xe67e5f19,

+	0x7dba0e47,

+	0xfee3b153,

+	0x46b6a20c,

+	0x2594e6f6,

+	0x210cab0f,

+	0xf6e47d5d,

+	0xe38276e4,

+	0x90fc2728,

+	0x9faefa11,

+	0xc972217c,

+	0xc8d079dd,

+	0x5f7dc338,

+	0x106f7b7b,

+	0xd04c0a1c,

+	0x0eca300e,

+	0x1ddae8a6,

+	0x6e7fd42e,

+	0xa56c514d,

+	0x56a4e255,

+	0x975ea2bf,

+	0x0eaa78cc,

+	0x0c3e284f,

+	0xbacb6c71,

+	0x1645006f,

+	0xe9a2b955,

+	0x0677c019,

+	0x24b33da0,

+	0x62f200fa,

+	0x234238c4,

+	0x81d5ad79,

+	0x9f754bc9,

+	0xeffd5016,

+	0x041b2cc2,

+	0x2f020bc7,

+	0x4fcd68b8,

+	0x22c3579c,

+	0x4804a114,

+	0xc42db3ea,

+	0x7cde8141,

+	0x47e167c8,

+	0x01aa38cc,

+	0x74a5c25e,

+	0xe0c48d67,

+	0x562365ad,

+	0x38321e57,

+	0x0395885a,

+	0x6888323e,

+	0xd6fc518f,

+	0x1854b64c,

+	0x06a58476,

+	0x3662f898,

+	0xe2bcdaee,

+	0x84c40693,

+	0xef09d374,

+	0x353cc799,

+	0x742223d4,

+	0x05b3c99b,

+	0x0c51ee45,

+	0xd145824a,

+	0xac30806c,

+	0x2ed70c0d,

+	0x71ae10ff,

+	0xbf491854,

+	0x3e1f03b4,

+	0x76bfd6cd,

+	0x1449aa8a,

+	0xf954d3fb,

+	0xf8c7c940,

+	0x70233f85,

+	0x0729e257,

+	0x10bb8936,

+	0xc35bb5b5,

+	0x95d78b5c,

+	0xcc1ba443,

+	0x6f507126,

+	0xa607cfd0,

+	0xce22f2f3,

+	0x5134ed8c,

+	0xec8d2f06,

+	0xa92413d5,

+	0xb973f431,

+	0x16e136dd,

+	0xf7d41bed,

+	0x01b002fe,

+	0x646ed771,

+	0x76ea3d26,

+	0x5024af20,

+	0x84270f51,

+	0x9b3d7820,

+	0x2454a2c6,

+	0xc1f072ed,

+	0x155e864f,

+	0x4c39a6e5,

+	0x928206e5,

+	0x9d1685f5,

+	0x45542ee7,

+	0x1fd27d9e,

+	0x5f2dd9ff,

+	0x222005eb,

+	0x354e8a55,

+	0x1f0de29a,

+	0xb86dc696,

+	0x9eafafad,

+	0x191b197e,

+	0x0e0900e1,

+	0xe0ac42bb,

+	0x3143236f,

+	0x44177def,

+	0x05259274,

+	0xb21af44a,

+	0x6ddee4df,

+	0xc7b56255,

+	0xb6b1d39d,

+	0x218f9070,

+	0x96545a42,

+	0x98cc2d4a,

+	0xb21bac9e,

+	0x83e12d44,

+	0x2ef4fb39,

+	0xbc03528f,

+	0x9485af58,

+	0xd9f1e6ab,

+	0xde7607e6,

+	0x3b398733,

+	0x9cd9b1a9,

+	0xabd77984,

+	0xcce18826,

+	0x701c5c21,

+	0xe6591cbf,

+	0x07a9b9e1,

+	0x69459c90,

+	0xe0cdcad6,

+	0xc4c6c4b6,

+	0x12748024,

+	0x4a33c567,

+	0x7d26a37e,

+	0xcae163bf,

+	0xeb7547fa,

+	0xccc6a01c,

+	0x3cb8abb8,

+	0x64aa67b2,

+	0x51ddf6de,

+	0xbfe1b905,

+	0x50923949,

+	0xacfa43af,

+	0x1fdb5a44,

+	0x091533cb,

+	0x7c92e5dc,

+	0x1c5d0d3e,

+	0x195271f5,

+	0x96e73a4a,

+	0xe1b11968,

+	0xb42906f2,

+	0x5a2940b3,

+	0x611283e9,

+	0x65829161,

+	0x5d1357b7,

+	0x019428ad,

+	0x836c5c3c,

+	0xc0e5e169,

+	0xd360e424,

+	0x257a9d69,

+	0xdca09040,

+	0x85f1c060,

+	0xae7cae79,

+	0xa5ddcfd6,

+	0xdba8f68e,

+	0xd98df596,

+	0xe6e3cd51,

+	0xcfb2be8f,

+	0x368fe6cd,

+	0x58486b75,

+	0x791f1a48,

+	0xf81a61f2,

+	0x58a38155,

+	0x30a86547,

+	0xd7fb2db1,

+	0x300e0b1d,

+	0x3f838461,

+	0xf278805a,

+	0x49529931,

+	0x601d5649,

+	0xe500ba1a,

+	0xc4f78965,

+	0xe10ed02d,

+	0x1f777ebd,

+	0x2db1d17d,

+	0x48a22e6a,

+	0x5a14b738,

+	0xdcf899e0,

+	0xc845bd04,

+	0xd04a52b9,

+	0xf2f19b06,

+	0xdb5ba97a,

+	0xf05605ff,

+	0xc787b72c,

+	0x9f197770,

+	0x87b31150,

+	0x3ff00d57,

+	0x89d1dcb3,

+	0x07528ff4,

+	0x4105fcef,

+	0xb087de2e,

+	0x3bd333a5,

+	0x84a094f4,

+	0x9ab8fb97,

+	0xc9bba063,

+	0x664c52e5,

+	0x27fd05e4,

+	0x3f0e491d,

+	0xab8f4b9a,

+	0x344a0249,

+	0x727dd74f,

+	0x29587211,

+	0xbba262b9,

+	0x319ecbb3,

+	0xec54b023,

+	0xd0fa096d,

+	0x3d223f23,

+	0x0b6013e7,

+	0x513e045b,

+	0xcb1edf15,

+	0xfd44bb25,

+	0x023eb973,

+	0x3f55dac6,

+	0xc2df6514,

+	0x68589880,

+	0x4556878e,

+	0x86f6acfb,

+	0xbcd23f0b,

+	0x32c417c1,

+	0x45f3bb56,

+	0xbe60872b,

+	0x09457cc0,

+	0x2e18b62d,

+	0x065f54d1,

+	0xae3b4a20,

+	0x265b10ae,

+	0xb7547a1d,

+	0x5a9481a9,

+	0xd477ed02,

+	0x601ed0fc,

+	0x9a43257e,

+	0xc9922b72,

+	0xa2a696ae,

+	0xe9d6c37b,

+	0xfab8bdf9,

+	0x1deb34dc,

+	0xaa6bb090,

+	0xbdc3b72f,

+	0xecb3b010,

+	0xe64376e7,

+	0x40356095,

+	0x928b5047,

+	0xbd271c09,

+	0xfd806f61,

+	0x0821e090,

+	0x6afb3588,

+	0xd10e91ea,

+	0xbbc7fedd,

+	0xb1ac6d33,

+	0x07788e4b,

+	0xa10f8013,

+	0x4f8efd9d,

+	0xe5d8728d,

+	0x017f3e82,

+	0xf09ec7eb,

+	0x6bfd7906,

+	0xbcefcb44,

+	0x76699ad5,

+	0x1b976522,

+	0xa55b3dbd,

+	0x88bb33e2,

+	0x98ac5b7f,

+	0x61ac4c8b,

+	0xfd948f3d,

+	0xee610413,

+	0xc77c5035,

+	0x662825a9,

+	0x0009fcba,

+	0x3450fd88,

+	0xeb391fef,

+	0x6949960d,

+	0x1ccb13c3,

+	0x21dac5a6,

+	0x6bcc6b37,

+	0x37ad77a5,

+	0xf71d58b1,

+	0x84ed440d,

+	0xe606b699,

+	0xe43067a4,

+	0x21d5b8b3,

+	0xe11f83e2,

+	0xa0cc6585,

+	0x40eb6d16,

+	0xc5a6879f,

+	0xbd333fd5,

+	0xb44acab4,

+	0x68c016fc,

+	0xfbcd3cfc,

+	0xadf76e42,

+	0xc520e516,

+	0x7468cb61,

+	0x585c0d52,

+	0xea83cefe,

+	0x615d7760,

+	0x89c9b8fd,

+	0x367c355a,

+	0x409371a2,

+	0x7edb38a7,

+	0xca86d263,

+	0xda18250d,

+	0x26e1ed8b,

+	0x02fefede,

+	0x704cb5c8,

+	0x52cbe1eb,

+	0x9cdbc71a,

+	0xa0637560,

+	0xe31f03ca,

+	0x2b78969b,

+	0x803d5866,

+	0xec52d984,

+	0xd8df8bdb,

+	0x6cb1d5e8,

+	0x7b9aec01,

+	0xf7d39401,

+	0xdd04c6ae,

+	0x0e5ca4eb,

+	0x12b593c8,

+	0x38f6d4e5,

+	0x13a91268,

+	0x60c8251b,

+	0xa136cf9a,

+	0xda070cdd,

+	0x6142408c,

+	0xc28065dd,

+	0x50b73718,

+	0x36074eee,

+	0xc7b20fcb,

+	0x18d29f9b,

+	0xe97eb966,

+	0xe6936bcc,

+	0x1c9188ea,

+	0x7cff40e2,

+	0xee791ac8,

+	0xb099a323,

+	0x571d69b7,

+	0x22c1f7d0,

+	0x0b9662ee,

+	0x76e45cb9,

+	0xbd0d7020,

+	0x7794bd95,

+	0x1b0fe51a,

+	0xda2754ef,

+	0x7f3ad7a9,

+	0x58f627d3,

+	0x211670a3,

+	0xc7471b81,

+	0x495a93ac,

+	0xaad4f030,

+	0xa76614c8,

+	0xd63dba3c,

+	0x9c4f729c,

+	0x6e831cfb,

+	0xa6105c75,

+	0x95c62188,

+	0x723ef45d,

+	0xf59f2dd1,

+	0x5825283d,

+	0x768d8a86,

+	0x070d02ac,

+	0xfdbcbd73,

+	0x0d479795,

+	0x797aa7f7,

+	0x6c9e468b,

+	0xa961571d,

+	0xc7127ef0,

+	0x4b0442e7,

+	0xd99a9e87,

+	0x6c876cba,

+	0xe4f9f814,

+	0x120eeb8d,

+	0x4bbb9c8e,

+	0x22c0a29e,

+	0xff681fcc,

+	0x26777226,

+	0x6339e667,

+	0x2402333e,

+	0x2bf66a17,

+	0x63806e6c,

+	0x98416b75,

+	0x791b3e91,

+	0x79c09cd7,

+	0x0c157436,

+	0x6d99157c,

+	0xc8990984,

+	0xaf7d2ae4,

+	0xfe3ee7d9,

+	0xb7676de0,

+	0x9df8722e,

+	0x08462a7e,

+	0x99032839,

+	0xd726ff95,

+	0x5c1c78e8,

+	0x4ef1b747,

+	0x4e257ba7,

+	0xa83ad5f3,

+	0x523b3809,

+	0xc2ce4f19,

+	0xabfadaa5,

+	0x370b005c,

+	0x2d6a02e1,

+	0xbf6ee428,

+	0xfd84be50,

+	0xb79801b3,

+	0x488ad789,

+	0x65a87bda,

+	0x59f0fd6a,

+	0xa4106878,

+	0xdbadd916,

+	0x1f86f200,

+	0xefb7fc72,

+	0x26d4d47f,

+	0xf7892efc,

+	0x41f50167,

+	0xc6a28f9e,

+	0xffd4a8e0,

+	0xa00e4ea0,

+	0x8183f648,

+	0x030faa4c,

+	0x26c1715f,

+	0x322c9ea3,

+	0x5d60d054,

+	0x413470cb,

+	0x3d131892,

+	0x22f2ae86,

+	0x9f1c96b6,

+	0x015563f4,

+	0x3a5625ba,

+	0xcb95b598,

+	0xf0685fb9,

+	0x158af5ec,

+	0xfc01a406,

+	0x01841d19,

+	0x210b7e73,

+	0x19a416a1,

+	0xed254c44,

+	0x5bd51335,

+	0xb8905dc9,

+	0x9e52f38c,

+	0xef5d7dd0,

+	0x1516f6bb,

+	0xf13bb426,

+	0x9ee6d6cb,

+	0x28bde0a6,

+	0x766b655e,

+	0xaf2e0e52,

+	0xdec60f49,

+	0x254a0959,

+	0xb009d431,

+	0x2f6d3533,

+	0x0a074afc,

+	0xcd3d3a72,

+	0x52aa4fce,

+	0x16c4507d,

+	0x2f842898,

+	0xb087e98b,

+	0x68b41826,

+	0xd4adc5c9,

+	0x53b3e498,

+	0x2dff7b03,

+	0xda931e65,

+	0xf1d66edd,

+	0x2beb7555,

+	0x97b3f152,

+	0x035676f8,

+	0xca9c7cf6,

+	0x57992a53,

+	0x578a1004,

+	0x458e23c8,

+	0x2a2494bf,

+	0xa92c549b,

+	0x2ca46deb,

+	0xcd907478,

+	0x93baaeb5,

+	0xa70af4c6,

+	0x9767d5b8,

+	0x9874bcee,

+	0xb0413973,

+	0x9bfef4f7,

+	0x7fbed607,

+	0x2a255991,

+	0xa5e3109d,

+	0x90f09fef,

+	0xb7a3d468,

+	0x6db437aa,

+	0xe8dad585,

+	0xfbc19cbc,

+	0x34cacc6f,

+	0x6c5cc449,

+	0xcc6dc144,

+	0x70c6aaa0,

+	0x183bc459,

+	0x490ea5a8,

+	0xddf105bf,

+	0x3429facf,

+	0x79020f72,

+	0xd2de786d,

+	0xb776f3ed,

+	0x553e3da7,

+	0xaecff099,

+	0x2b471ce1,

+	0xe3a72af9,

+	0x04c9b2bf,

+	0xe84d9702,

+	0xec7cd831,

+	0xda66c6c1,

+	0x451b207c,

+	0x68243bc3,

+	0xb3012b1e,

+	0x1855c026,

+	0x1addac14,

+	0xc73834a2,

+	0xea91596d,

+	0x08f0d135,

+	0xc6021aa0,

+	0xc5d1726b,

+	0xc21d1f0b,

+	0x92b7c740,

+	0x9f024526,

+	0x6c91df6c,

+	0xfec85435,

+	0x3d5a9150,

+	0x93249836,

+	0x2ec5e71f,

+	0x23e96579,

+	0x81ce78d6,

+	0x49e45ccf,

+	0x4d5e9c78,

+	0x2a2cdfab,

+	0x148e1833,

+	0xa3fab11b,

+	0xd0ceb7e9,

+	0x4789b634,

+	0x147fc687,

+	0x48f4f59c,

+	0x21eea4e3,

+	0x411dfb7d,

+	0x033fe075,

+	0x57c9e07d,

+	0xb09edf4e,

+	0x9db83f5f,

+	0x6ef1343a,

+	0x64a68315,

+	0x300e34c3,

+	0x72ac2766,

+	0x640271a4,

+	0x0a282b82,

+	0xcaf1ec1b,

+	0x7d4849f9,

+	0x108c5eaa,

+	0xfaa96613,

+	0x0476639b,

+	0x70ee8371,

+	0x9db599ba,

+	0x85158d5f,

+	0x02912911,

+	0xe6fec86a,

+	0xcf3036f3,

+	0xccdd49a0,

+	0xe650b3cd,

+	0xf5429ef0,

+	0x411e4690,

+	0xa526e30b,

+	0x275822af,

+	0x91e12d05,

+	0x958881aa,

+	0xabf76cc4,

+	0x06e794a9,

+	0xa97d1577,

+	0x0188613c,

+	0x17c96558,

+	0x96c31832,

+	0x5696b201,

+	0x03e3dad2,

+	0xbe44d0ba,

+	0x4d552a6c,

+	0xe9fafb48,

+	0x4968ad28,

+	0xf109edce,

+	0xd1534f30,

+	0xc2d8b9e8,

+	0x66e911d7,

+	0xd67a594b,

+	0x4492b2b4,

+	0xeb86848d,

+	0x4106979b,

+	0x0f75039f,

+	0xf5f3ee2c,

+	0x04baf613,

+	0x00c6fd60,

+	0x32ebe198,

+	0xc7f129eb,

+	0x7cac0839,

+	0x57a1fde4,

+	0x2da04cfc,

+	0x93179aa5,

+	0xf3f4d2d9,

+	0xd8d2528a,

+	0x5fdd42af,

+	0xd08c7bdb,

+	0x53acd639,

+	0xe37aab85,

+	0x2d55b5a2,

+	0x7bc96248,

+	0x2fb42401,

+	0x2ff99915,

+	0x2be3b5ea,

+	0xf0ff9bdd,

+	0x1b6bbaa3,

+	0x83a13de0,

+	0x4503fc83,

+	0x08c24640,

+	0x2463a2b2,

+	0x2e264872,

+	0xc451a29d,

+	0xbfd2e09c,

+	0x15bcb009,

+	0x69102223,

+	0x4c8581e9,

+	0x4ec94cf0,

+	0x75017d7b,

+	0x0e5d8cf1,

+	0x50b9ca97,

+	0x55df1100,

+	0x245162e0,

+	0x0df18bca,

+	0x00776990,

+	0xf6790a03,

+	0x599ef43e,

+	0xe8bf7afb,

+	0xea141ddc,

+	0xad1a54b2,

+	0x55f767f8,

+	0xb661981c,

+	0xe1650342,

+	0x365adc95,

+	0xbb44e3a0,

+	0xa064fea1,

+	0x3516bf27,

+	0xfd40a414,

+	0x53f9a9e6,

+	0x2071a5ee,

+	0x56ca2713,

+	0x7afdd07a,

+	0xd62b7f6e,

+	0xe9dac904,

+	0xca212105,

+	0xb9d6e3de,

+	0x6af5033f,

+	0x34d9049b,

+	0xc51ec095,

+	0xe5eddb9d,

+	0x122b5c6a,

+	0x9f562e58,

+	0x20ec8986,

+	0x760857f2,

+	0x8d8aadb3,

+	0xbc8f0807,

+	0x0f79eae7,

+	0xbfa6bfa8,

+	0x28151aeb,

+	0xbe4b4d4b,

+	0xc65d58b0,

+	0xcf99ba1b,

+	0xc1049197,

+	0xe36d8c87,

+	0x548b7676,

+	0xbe7bb2c4,

+	0x77923781,

+	0x5fbd631e,

+	0x770e5a41,

+	0xd2f2948a,

+	0x074f5428,

+	0xc7a1562e,

+	0xf55618c6,

+	0x8bf8a3d1,

+	0x837ed4a8,

+	0xe42e0298,

+	0xd3754b0c,

+	0xbaa24c25,

+	0x793ac973,

+	0x814e66ec,

+	0xa4154fa9,

+	0x3e0e65ca,

+	0x5a783bd5,

+	0x2bb37f6c,

+	0xb3c2526e,

+	0x34c9a28a,

+	0x6c8b4795,

+	0x64605fa8,

+	0x2e6aae2e,

+	0xd9b28f27,

+	0x6a9a200b,

+	0x3acd1e3a,

+	0xce9a4a6c,

+	0xd2a0bd14,

+	0x700f2003,

+	0x501cbef7,

+	0x4068b05e,

+	0xa24c4580,

+	0x4da75506,

+	0x500b9b0f,

+	0x22e3a600,

+	0x7bec4e94,

+	0x8f0958e2,

+	0x42129a1e,

+	0xb46d8dc5,

+	0x29f8851c,

+	0x83fb38bd,

+	0x17b0de15,

+	0x15340d20,

+	0x74f00fde,

+	0x6c646b32,

+	0x905897c4,

+	0x4d8ed991,

+	0x3cf91fd5,

+	0x0ee02ddf,

+	0xec069ce6,

+	0x0b977683,

+	0xa0bf31f6,

+	0xa1d135a9,

+	0xa882d1db,

+	0xa731a63a,

+	0x48e211f1,

+	0xf3d89e99,

+	0xf982e6ea,

+	0x23dde303,

+	0x7f1ff8da,

+	0xdc8c6414,

+	0x806f432e,

+	0xd047bc02,

+	0x671bacff,

+	0xd40ba2a8,

+	0xe3666685,

+	0x31265f9f,

+	0x3931a952,

+	0x62f35606,

+	0xc48f0c5e,

+	0xfd107640,

+	0xf636da24,

+	0xb8f5c3b0,

+	0x1c91e88f,

+	0xed9dd432,

+	0x2b85fa5d,

+	0x8b15d2ac,

+	0x1e06cf24,

+	0x1def6e9c,

+	0xfae9175f,

+	0x03ac6f02,

+	0x37318c87,

+	0xbc0b1ce5,

+	0xa0640cab,

+	0x6cc20a3c,

+	0x1c7b2524,

+	0x4685dacc,

+	0xeab8bb31,

+	0x8063b5d0,

+	0x79817d52,

+	0x211b1972,

+	0xd7bfc987,

+	0xab9128dc,

+	0x150d9b36,

+	0x6a5838ab,

+	0x9a0a304d,

+	0x2e43c331,

+	0x84f2c4b8,

+	0x435146c1,

+	0xed64a280,

+	0x553ecb4c,

+	0x5c800db2,

+	0xeef4df95,

+	0x5dcf2c37,

+	0x70755ddf,

+	0x4274737b,

+	0xe610350e,

+	0xd97a5997,

+	0x7af5edce,

+	0xfd18ba0c,

+	0xb7587cd8,

+	0xfa5e42d6,

+	0x76bde9eb,

+	0xec41eead,

+	0x604d2423,

+	0xb4adbcf9,

+	0xce728fa3,

+	0x02361c31,

+	0x02fab64d,

+	0x00316b1c,

+	0x562f9aa4,

+	0x71f85790,

+	0x9cb6d464,

+	0x32949ebf,

+	0x434fc23d,

+	0xee7fac51,

+	0xda5cc63a,

+	0x17e616b4,

+	0xcd1bd1bc,

+	0x14638cae,

+	0xd31808fa,

+	0xb16e0727,

+	0xfdda2b0f,

+	0xbc11c678,

+	0xfe79dc6e,

+	0xe26eefb4,

+	0x9a78de16,

+	0xb68f2df2,

+	0xd47da234,

+	0xbdff28a4,

+	0x937bb1f4,

+	0x0786dd46,

+	0xbd1160f5,

+	0xf77b070c,

+	0x72b7c51e,

+	0xcbb3a371,

+	0x5e50e904,

+	0x00fbc379,

+	0x680757dd,

+	0xd38193f7,

+	0x93113e25,

+	0x7b258da7,

+	0x991aaa09,

+	0xab1415be,

+	0xa3740774,

+	0x370b72e5,

+	0x2fc643f4,

+	0x3916d70e,

+	0xea2838d3,

+	0xe4840c42,

+	0xd18e6959,

+	0x69a270ee,

+	0xee4a494e,

+	0x0329799b,

+	0x07480357,

+	0x0260c46f,

+	0x7b75346e,

+	0x787234f4,

+	0xe0adf25b,

+	0xba85cacf,

+	0xb5724eb1,

+	0xfde2c080,

+	0x2b6bb492,

+	0xd2f70545,

+	0x9ca97510,

+	0x4034c18f,

+	0x616bcb12,

+	0x5667f52a,

+	0xe2f6bfce,

+	0x1f25969e,

+	0x569eaab7,

+	0x27ad8196,

+	0x2d30a6d0,

+	0x96d6c10a,

+	0xcb9f024f,

+	0x3d7941ef,

+	0xf7a76bc5,

+	0xe9a701d4,

+	0xd53293a3,

+	0x252cf5df,

+	0xaf9172f6,

+	0xd090c809,

+	0xb1a17387,

+	0x045a0987,

+	0x92d9ffd9,

+	0xb30c449c,

+	0x2180ff58,

+	0x2929f7de,

+	0x3f91766e,

+	0x9f488e3d,

+	0x05dd6734,

+	0x82482f5b,

+	0x01da3ca2,

+	0x42f33408,

+	0xf8e3ba89,

+	0x750ac2ff,

+	0x39f11551,

+	0x71087971,

+	0x368fa634,

+	0xefda0572,

+	0x14b8f750,

+	0xe5768705,

+	0x71c168e2,

+	0x8c012c63,

+	0x12ad74ce,

+	0x841c17ea,

+	0xe6f44176,

+	0x36cf2557,

+	0x14760a6d,

+	0x4bb3b7c2,

+	0x14d1437d,

+	0xbe673210,

+	0x4d6ba9f5,

+	0xe68abbf9,

+	0xc311908d,

+	0x46b63956,

+	0xac2c9fb3,

+	0xab769ce8,

+	0xa29d7040,

+	0xec3d67e3,

+	0xdef311de,

+	0x52a53b14,

+	0xca924769,

+	0xf35d1514,

+	0x524b0471,

+	0xc0d08591,

+	0x454fc34c,

+	0xca719639,

+	0x9af2f230,

+	0xa023a821,

+	0x3d6539ba,

+	0x90d0d7a2,

+	0xc65fc56e,

+	0x4eb2aa19,

+	0xeba3b0e7,

+	0x1bb5b33e,

+	0xab8c68c2,

+	0x0f1793d3,

+	0xdcf176e9,

+	0x1b7bbba0,

+	0x96170a27,

+	0x1955452d,

+	0x42e88c71,

+	0x48cad4b3,

+	0xdcc36042,

+	0x90619951,

+	0x7566bc7c,

+	0xe14ba224,

+	0xc24ad73d,

+	0xdb04144d,

+	0xd9792727,

+	0x11150943,

+	0xe45f0c57,

+	0xb87d184e,

+	0x3cf13243,

+	0x2010d95c,

+	0x84c347c1,

+	0x6d0f2461,

+	0xb5c41194,

+	0xde7ccb2e,

+	0xb929ecb0,

+	0x51fbd8f7,

+	0x45dc65fb,

+	0x6902d2c0,

+	0xb940814f,

+	0xf339e083,

+	0x6f370d56,

+	0xcaf5638e,

+	0xe8a3cb83,

+	0xacf414b6,

+	0xe61095a1,

+	0x99b4cde4,

+	0x55112fed,

+	0x606b9d53,

+	0x5a05974a,

+	0xa4c7db34,

+	0xdc92469b,

+	0xf9280621,

+	0xe7b1ef95,

+	0xc0fc5be8,

+	0x74a1da09,

+	0xa92a4b7f,

+	0x3d65d75e,

+	0xe3804335,

+	0x1ff49e19,

+	0x71da8170,

+	0xac69069b,

+	0x04aae3d5,

+	0xc0ef4b46,

+	0x091a3482,

+	0x8356c7ae,

+	0x32ecb208,

+	0x900c89ed,

+	0x2a206ff5,

+	0x7eed5032,

+	0x5b55b25d,

+	0xf98d6df2,

+	0xf52bc8a9,

+	0x1aa2f5fe,

+	0x1d33c0bf,

+	0x3cd34e89,

+	0x9a0da4ae,

+	0x1c205917,

+	0x7ca784cd,

+	0xf7dda662,

+	0xad97f3ff,

+	0x525c53ec,

+	0x024f11ff,

+	0x32c3ae5b,

+	0xbf372800,

+	0x8ff15f4d,

+	0x7605d019,

+	0x0dae7740,

+	0x5f5dd0ef,

+	0x0f6c37d0,

+	0xee6fa91e,

+	0xb9f51051,

+	0x39a9f0d1,

+	0x22bf03fb,

+	0x485a0922,

+	0x7384b30e,

+	0x85ba7f16,

+	0xb1f0a524,

+	0x7e9c5113,

+	0x240d9306,

+	0x1ca7b0ea,

+	0x18a0d114,

+	0x76b64213,

+	0x31212cc0,

+	0xc9dca5c3,

+	0x69f2ae52,

+	0x545caa7c,

+	0xfb2ff045,

+	0x3f3a1af5,

+	0xe75b6913,

+	0x775a1c79,

+	0x4627e25f,

+	0x90a14b97,

+	0x06456383,

+	0x3d52cf69,

+	0xfb2492c3,

+	0x39f25a22,

+	0x81f68c55,

+	0x87b14e15,

+	0x0920af5d,

+	0xe2585678,

+	0x0671e46d,

+	0xb77ddb67,

+	0x3948c4b3,

+	0x122dddef,

+	0xd0726172,

+	0xd3302234,

+	0x58bab4e4,

+	0x195ac247,

+	0x082459f0,

+	0x18a2566d,

+	0xbf56078d,

+	0x116ed409,

+	0x5ccc0f80,

+	0xbae0b4ca,

+	0x21a6325d,

+	0x7e1f0c40,

+	0x595326d4,

+	0x518b2244,

+	0x8ab3cdb7,

+	0xbe6b4835,

+	0xfc39f8ac,

+	0x63b167aa,

+	0x194f070d,

+	0xed3d0416,

+	0xae16758a,

+	0xb9bb6bbf,

+	0x477d9c85,

+	0x9808c304,

+	0xe1d8cec4,

+	0x7ee22e17,

+	0x0a7a9d7f,

+	0xcc98173a,

+	0x5f78dc21,

+	0x364bc95e,

+	0xb54608d9,

+	0x5d4d70ea,

+	0x083a7f79,

+	0x59ffbd73,

+	0x4f3e9eaf,

+	0x68755ad4,

+	0xab254689,

+	0x11bf09a8,

+	0xbbc40098,

+	0x969ca3eb,

+	0x30eee9d2,

+	0xe35bc37e,

+	0xcb2d678f,

+	0x7846876b,

+	0xf0d28ae7,

+	0xc092fbb2,

+	0x321b344a,

+	0xcc5ee81b,

+	0xd2afa00f,

+	0xfeccd86a,

+	0x6e5e55c2,

+	0x2b5543ea,

+	0x810e4009,

+	0xea2d8e20,

+	0x6acae3b9,

+	0x3828e15e,

+	0xe1e4821c,

+	0xf429da70,

+	0x35f6565c,

+	0x64b1baa8,

+	0x350e9583,

+	0xd2522d4f,

+	0x5e28a3f1,

+	0x949ff0aa,

+	0x3c1b5694,

+	0x146dde1f,

+	0x6f3430e1,

+	0x71c077b7,

+	0x4d145924,

+	0xe431cd28,

+	0xb315cfde,

+	0xa0365a4a,

+	0x473de1aa,

+	0xcbe4e999,

+	0x319906e9,

+	0xad0fea9c,

+	0x89e4e72d,

+	0x9dbba94d,

+	0xd395c1c5,

+	0xa1fff11a,

+	0x8447e120,

+	0xe5c59100,

+	0xa07cb778,

+	0x8f30a039,

+	0xed78facb,

+	0x86de9373,

+	0x550c4889,

+	0xce71e3a8,

+	0x06167b3a,

+	0x5abdd9a3,

+	0xc8a9e48d,

+	0xe3312905,

+	0x7a63a146,

+	0xc0f19763,

+	0xda0cf9db,

+	0x1d708306,

+	0x0e41f0ba,

+	0x4c7939fe,

+	0x768e48c2,

+	0xe925fd31,

+	0x309e7870,

+	0xfc261b87,

+	0xc897b2de,

+	0x6c714792,

+	0x41c7fbac,

+	0x57d0b3c3,

+	0x4fa82a55,

+	0xd56b4a87,

+	0x81e5cabc,

+	0xb260cb7b,

+	0x520927ab,

+	0x20d0ab46,

+	0xc9f92ddf,

+	0x81f4a21d,

+	0xfc5a0ca2,

+	0x95d16aad,

+	0xe54d7847,

+	0x6080cc07,

+	0x0df73f7e,

+	0xaa8d5187,

+	0x97a0bc12,

+	0xb22c5e68,

+	0x0954d7dc,

+	0x3368ab5a,

+	0xd12541df,

+	0x58119260,

+	0xe5b0e1df,

+	0x25027fa4,

+	0x5780425d,

+	0x29bb8791,

+	0x4100b7a9,

+	0x076b3519,

+	0x15e0ebb4,

+	0xe5fb9273,

+	0x6dbf07e7,

+	0x1f82bddd,

+	0x03691b6b,

+	0xbacef28c,

+	0x9909ed5a,

+	0x98886793,

+	0x544f9a82,

+	0x9d9749d0,

+	0x38441606,

+	0xc4a9f4d2,

+	0x6ce2bcf1,

+	0x1c7c3abd,

+	0x62c621f1,

+	0x871ee1e4,

+	0xa83930ce,

+	0xbe1ee459,

+	0xd61f1ca4,

+	0x8c4450e5,

+	0x98031ca9,

+	0xe52f54e2,

+	0xd0c4c737,

+	0x76074160,

+	0xbf050c3b,

+	0x2603af14,

+	0x43cbb0bc,

+	0xc631b9e8,

+	0x26030719,

+	0x993f570c,

+	0xdda34038,

+	0xe34a9793,

+	0x337a124c,

+	0x2aa8af16,

+	0xf80d7473,

+	0xf01d9397,

+	0x68e1afb9,

+	0x0eb37ad2,

+	0xf71969f9,

+	0xdf020552,

+	0x75aa9b30,

+	0xffa210cf,

+	0x543c414f,

+	0xa1e3faec,

+	0x40891d7e,

+	0x6b48a6c5,

+	0xec09a1a0,

+	0x97a31f2a,

+	0x5a6be2d7,

+	0xd06e492b,

+	0xc54290af,

+	0xcb524021,

+	0x420e8c4d,

+	0xfb135c17,

+	0x2bfc8adb,

+	0x9f0cfb46,

+	0x564db712,

+	0x7a97a227,

+	0x8bb98daf,

+	0xdd0d6180,

+	0x3d28b9e3,

+	0xe505050f,

+	0x19a9868e,

+	0x7bf5685f,

+	0x35d698c4,

+	0xce7e1de3,

+	0x360a64af,

+	0x25a1f022,

+	0xe26c1d04,

+	0x5b3fb364,

+	0x932f25f7,

+	0x9a2aa00d,

+	0xc50fb773,

+	0xec45ea3a,

+	0x22ddf8e4,

+	0xafb6a6c8,

+	0x876d04f7,

+	0xd9c86c3c,

+	0xd54bee2d,

+	0xf4e28199,

+	0xc3456776,

+	0x04c3107b,

+	0xbf914e9d,

+	0x23fefaa5,

+	0x0931a133,

+	0x41467758,

+	0x8ec49707,

+	0x5ed48709,

+	0xd11c2de8,

+	0xb687a0b9,

+	0xdc908383,

+	0xd8037ff3,

+	0xd4311a9f,

+	0xd00aeb6a,

+	0xfe54df3b,

+	0x9c51ce4d,

+	0x36956408,

+	0xcd28ef09,

+	0xc68932b0,

+	0x7c31e782,

+	0x28b4723c,

+	0xededacc2,

+	0x6ddbac6b,

+	0x775a7fc1,

+	0x6909906f,

+	0xa774123c,

+	0xf63145ad,

+	0x287b191e,

+	0x59d79300,

+	0xbf76a2fc,

+	0xfbaf9207,

+	0x2fe5b7f6,

+	0xebe7c103,

+	0x71ac0a8d,

+	0x2028c3c7,

+	0xd2cb4917,

+	0xd74a4ee4,

+	0xfce405d8,

+	0xad83fd0f,

+	0x8f9ec3da,

+	0xaab2301c,

+	0xc6f1339f,

+	0xc652bced,

+	0xe378b272,

+	0x18e1ff34,

+	0x9ec778b6,

+	0xce1a3883,

+	0x7c5e5eaf,

+	0xd16ec37a,

+	0xa69e45f4,

+	0xc36cd4aa,

+	0x045b391f,

+	0x5a2a08f1,

+	0x4dd8d53e,

+	0xd64796ec,

+	0x4476fc28,

+	0x18dbaa50,

+	0x00fb2407,

+	0x177db915,

+	0x5969758b,

+	0x3030964a,

+	0x81d6485b,

+	0x7d2e12b0,

+	0x624d6c5f,

+	0x0746bbc0,

+	0xe669d150,

+	0x0465eef7,

+	0x09764011,

+	0x551995e4,

+	0x8422dedf,

+	0x0ca56194,

+	0x293eab2e,

+	0xf20a137a,

+	0x55117fc2,

+	0xbc5431af,

+	0x064751fa,

+	0xc0dafdb2,

+	0x6c3b1d4f,

+	0xeac335b3,

+	0x71173afc,

+	0x31c84b7c,

+	0xfef2b4ab,

+	0x59ca5fa2,

+	0x664c8b4e,

+	0x7dfd560b,

+	0xdb0daff3,

+	0x51f87bfa,

+	0x58015d2e,

+	0x67a827b4,

+	0x62cebc1a,

+	0x24b37298,

+	0x75b589be,

+	0x874f1800,

+	0x277b795c,

+	0xf762489e,

+	0x87d00752,

+	0x9be45ed1,

+	0x296ec120,

+	0x61162480,

+	0x792e8a2c,

+	0x3b631590,

+	0xe33ba0cf,

+	0x542ac23c,

+	0xe1e8cffa,

+	0xfc084cd8,

+	0xc115ad31,

+	0x71559928,

+	0x791f1e33,

+	0x662ed92b,

+	0x7222c76d,

+	0x02dcd566,

+	0x8db9b4d4,

+	0xa5f344c8,

+	0x15806b12,

+	0x81e572f7,

+	0x3b3fbe25,

+	0x2133b413,

+	0x2d68a367,

+	0x356f6ce7,

+	0xcd6dfed1,

+	0xd8b3a26e,

+	0xe9d328da,

+	0x127425ab,

+	0x83a60aac,

+	0x8cc26190,

+	0x7f87ab26,

+	0x56faab5f,

+	0x76d0feaa,

+	0x4b25dd10,

+	0x4f6286ea,

+	0x79298d06,

+	0x8002bf83,

+	0x2977c85e,

+	0xd3b3d19a,

+	0xa92bf132,

+	0xa280efd8,

+	0x83f7ad6e,

+	0x748969c7,

+	0x25ff411d,

+	0x3854d3a8,

+	0x55746aa2,

+	0x00db5c54,

+	0x36949e0d,

+	0x40402ab6,

+	0x1a720211,

+	0xe02ce823,

+	0x4ac104a2,

+	0x214d2e4b,

+	0x267e5c83,

+	0x38a3a483,

+	0xd1da1f67,

+	0x0c68db2c,

+	0xd7035d63,

+	0xa29393bb,

+	0xa5743519,

+	0xcb97c84e,

+	0xa853974f,

+	0x147360a0,

+	0x2df9b3f4,

+	0x0aff129e,

+	0x177d687f,

+	0x87eff911,

+	0x6c60b354,

+	0x6c356c38,

+	0x7d480965,

+	0xbb06a193,

+	0x25b0568e,

+	0x6fd6da9a,

+	0x82b64f14,

+	0x3d267a78,

+	0xf100b6a7,

+	0x32c74539,

+	0x6042e152,

+	0x4548276e,

+	0xa3a32b70,

+	0xf029fe15,

+	0xa9b8bd2f,

+	0x5618eee4,

+	0x9815a5f0,

+	0x89fb2850,

+	0xa9261b26,

+	0xded9e505,

+	0x37e9d749,

+	0xdc4aeb78,

+	0x9e634f7a,

+	0xcf638d2d,

+	0x6b679f92,

+	0x2b64911d,

+	0xe6d1312f,

+	0x88b3e76a,

+	0x56311f62,

+	0x00916de7,

+	0x39d0bc61,

+	0x8ac09356,

+	0x47abcfce,

+	0x324cb73e,

+	0xfadcd0a8,

+	0x2f2fbca8,

+	0x945eda22,

+	0xba23cab1,

+	0xf9fb4212,

+	0x1fa71d45,

+	0x867a034e,

+	0x3bee5db1,

+	0xf54adced,

+	0x6633ba77,

+	0xe1eb4f1e,

+	0x97ef01f6,

+	0x57fd3b32,

+	0x5234d80d,

+	0xe8ee95f3,

+	0x5dc990bf,

+	0xaba833e1,

+/*  Dummy terminator  */

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+};

+                                                                                

+

diff --git a/src/mainboard/supermicro/x6dhe_g/mptable.c b/src/mainboard/supermicro/x6dhe_g/mptable.c
new file mode 100644
index 0000000..6a28498
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/mptable.c
@@ -0,0 +1,202 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "LNXI    ";
+	static const char productid[12] = "X6DHE       ";
+	struct mp_config_table *mc;
+	unsigned char bus_num;
+	unsigned char bus_isa;
+	unsigned char bus_pxhd_1;
+	unsigned char bus_pxhd_2;
+	unsigned char bus_esb6300_1;
+	unsigned char bus_esb6300_2;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* initially just the header */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* not yet computed */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet... */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+	
+	{
+		device_t dev;
+
+		/* esb6300_2 */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1c,0));
+		if (dev) {
+			bus_esb6300_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1c.0, using defaults\n");
+
+			bus_esb6300_2 = 6;
+		}
+		/* esb6300_1 */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
+		if (dev) {
+			bus_esb6300_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_isa++;
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n");
+
+			bus_esb6300_1 = 7;
+			bus_isa = 8;
+		}
+		/* pxhd-1 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x0,0));
+		if (dev) {
+			bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n");
+
+			bus_pxhd_1 = 2;
+		}
+		/* pxhd-2 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,2));
+		if (dev) {
+			bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
+
+			bus_pxhd_2 = 3;
+		}
+	}
+	
+	/* define bus and isa numbers */
+	for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+		smp_write_bus(mc, bus_num, "PCI	  ");
+	}
+	smp_write_bus(mc, bus_isa, "ISA	  ");
+
+	/* IOAPIC handling */
+
+	smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
+	smp_write_ioapic(mc, 3, 0x20, 0xfec10000);
+	{
+	    	struct resource *res;
+		device_t dev;
+		/* PXHd apic 4 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,1));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x04, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n");
+			printk_debug("DEBUG: Dev= %p\n", dev);
+		}
+		/* PXHd apic 5 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,3));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x05, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n");
+			printk_debug("DEBUG: Dev= %p\n", dev);
+		}
+	}
+
+	
+	/* ISA backward compatibility interrupts  */
+	smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x01, 0x02, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x02);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x03, 0x02, 0x03);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x04, 0x02, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x06, 0x02, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, // added
+		bus_isa, 0x07, 0x02, 0x07);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x08, 0x02, 0x08);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x09, 0x02, 0x09);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x77, 0x02, 0x17);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x75, 0x02, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0c, 0x02, 0x0c);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0d, 0x02, 0x0d);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0e, 0x02, 0x0e);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0f, 0x02, 0x0f);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7c, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7d, 0x02, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		0x03, 0x08, 0x05, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		0x03, 0x08, 0x05, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_1, 0x04, 0x03, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_1, 0x08, 0x03, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_2, 0x04, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_2, 0x08, 0x02, 0x14);
+	
+	/* Standard local interrupt assignments */
+	smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x00);
+	smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x01);
+
+#warning "FIXME verify I have the irqs handled for all of the risers"
+
+	/* Compute the checksums */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+	printk_debug("Wrote the mp table end at: %p - %p\n",
+		mc, smp_next_mpe_entry(mc));
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
+
diff --git a/src/mainboard/supermicro/x6dhe_g/reset.c b/src/mainboard/supermicro/x6dhe_g/reset.c
new file mode 100644
index 0000000..874bfc4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/reset.c
@@ -0,0 +1,40 @@
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#ifndef __ROMCC__
+#include <device/device.h>
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+#define PCI_DEV_INVALID 0
+
+static inline device_t pci_locate_device(unsigned pci_id, device_t from)
+{
+	return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
+}
+#endif
+
+void soft_reset(void)
+{
+        outb(0x04, 0xcf9);
+}
+void hard_reset(void)
+{
+        outb(0x02, 0xcf9);
+        outb(0x06, 0xcf9);
+}
+void full_reset(void)
+{
+	device_t dev;
+	/* Enable power on after power fail... */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0);
+	if (dev != PCI_DEV_INVALID) {
+		unsigned byte;
+		byte = pci_read_config8(dev, 0xa4);
+		byte &= 0xfe;
+		pci_write_config8(dev, 0xa4, byte);
+		
+	}
+        outb(0x0e, 0xcf9);
+}
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g/watchdog.c b/src/mainboard/supermicro/x6dhe_g/watchdog.c
new file mode 100644
index 0000000..3904a7d
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/watchdog.c
@@ -0,0 +1,99 @@
+#include <device/pnp_def.h>
+
+#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
+#define NSC_WDBASE 0x600
+#define ESB6300_WDBASE 0x400
+#define ESB6300_GPIOBASE 0x500
+
+static void disable_sio_watchdog(device_t dev)
+{
+#if 0
+	/* FIXME move me somewhere more appropriate */
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 1);
+	pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
+	/* disable the sio watchdog */
+	outb(0, NSC_WDBASE + 0);
+	pnp_set_enable(dev, 0);
+#endif
+}
+
+static void disable_esb6300_watchdog(void)
+{
+	/* FIXME move me somewhere more appropriate */
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing esb6300?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ESB6300_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ESB6300_WDBASE + 0x60;
+	
+	/* Set bit 11 in TCO1_CNT */
+	value = inw(base + 0x08);
+	value |= 1 << 11;
+	outw(value, base + 0x08);
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+}
+
+static void disable_jarell_frb3(void)
+{
+#if 0
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing esb6300?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 0);
+	pci_write_config16(dev, 0x04, value);
+
+	/* Set gpio base */
+	pci_write_config32(dev, 0x58, ESB6300_GPIOBASE | 1);
+	base = ESB6300_GPIOBASE;
+
+	/* Enable GPIO Bar */
+	value = pci_read_config32(dev, 0x5c);
+	value |= 0x10;
+	pci_write_config32(dev, 0x5c, value);
+
+	/* Configure GPIO 48 and 40 as GPIO */
+	value = inl(base + 0x30);
+	value |= (1 << 16) | ( 1 << 8);
+	outl(value, base + 0x30);
+
+	/* Configure GPIO 48 as Output */
+	value = inl(base + 0x34);
+	value &= ~(1 << 16);
+	outl(value, base + 0x34);
+
+	/* Toggle GPIO 48 high to low */
+	value = inl(base + 0x38);
+	value |= (1 << 16);
+	outl(value, base + 0x38);
+	value &= ~(1 << 16);
+	outl(value, base + 0x38);
+#endif				  
+}
+
+static void disable_watchdogs(void)
+{
+//	disable_sio_watchdog(NSC_WD_DEV);
+	disable_esb6300_watchdog();
+//	disable_jarell_frb3();
+	print_debug("Watchdogs disabled\r\n");
+}
+
diff --git a/src/mainboard/supermicro/x6dhe_g/x6dhe_g_fixups.c b/src/mainboard/supermicro/x6dhe_g/x6dhe_g_fixups.c
new file mode 100644
index 0000000..82c070b
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g/x6dhe_g_fixups.c
@@ -0,0 +1,23 @@
+#include <arch/romcc_io.h>
+
+static void mch_reset(void)
+{
+        return;
+}
+
+
+
+static void mainboard_set_e7520_pll(unsigned bits)
+{
+	return; 
+}
+
+
+static void mainboard_set_e7520_leds(void)
+{
+	return; 
+}
+
+
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/Config.lb b/src/mainboard/supermicro/x6dhe_g2/Config.lb
new file mode 100644
index 0000000..65a9900
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/Config.lb
@@ -0,0 +1,220 @@
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of LinuxBIOS will start in the boot rom
+##
+default _ROMBASE	=( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can be cached to speed up linuxBIOS.
+## execution speed.
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+default XIP_ROM_SIZE=131072
+default XIP_ROM_BASE= ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+makerule ./auto.inc 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc    -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc 
+	ldscript /cpu/x86/16bit/reset16.lds 
+else
+	mainboardinit cpu/x86/32bit/reset32.inc 
+	ldscript /cpu/x86/32bit/reset32.lds 
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/E7520  # MCH
+	chip drivers/generic/debug  # DEBUGGING
+		device pnp 00.0 off end
+		device pnp 00.1 off end
+		device pnp 00.2 off end
+		device pnp 00.3 off end
+	end
+	device pci_domain 0 on
+		chip southbridge/intel/ich5r	# ICH5R 
+			register "pirq_a_d" = "0x0b070a05"
+			register "pirq_e_h" = "0x0a808080"
+
+			device pci 1c.0 on 
+				chip drivers/generic/generic 
+					device pci 01.0 on end	# onboard gige1
+					device pci 02.0 on end 	# onboard gige2
+				end
+			end
+
+			# USB ports
+			device pci 1d.0 on end
+			device pci 1d.1 on end
+			device pci 1d.4 on end	# Southbridge Watchdog timer
+			device pci 1d.5 on end	# Southbridge I/O apic1
+			device pci 1d.7 on end
+
+			# VGA / PCI 32-bit
+			device pci 1e.0 on 
+				chip drivers/generic/generic
+					device pci 01.0 on end 
+				end
+			end
+
+
+			device pci 1f.0 on 	# ISA bridge
+				chip superio/NSC/pc87427
+					device pnp 2e.0 off end
+					device pnp 2e.2 on 
+						 io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.3 on
+						 io 0x60 = 0x2f8
+						irq 0x70 = 3
+					end
+					device pnp 2e.4 off end
+					device pnp 2e.5 off end
+					device pnp 2e.6 off end
+					device pnp 2e.7 off end
+					device pnp 2e.9 off end
+					device pnp 2e.a on end
+					device pnp 2e.b off end
+				end
+			end
+			device pci 1f.1 on end
+			device pci 1f.2 on end
+			device pci 1f.3	on end		# SMBus
+			device pci 1f.5 off end
+			device pci 1f.6 off end
+		end
+
+		device pci 00.0	on end	# Northbridge
+		device pci 00.1	on end  # Northbridge Error reporting
+		device pci 01.0 on end
+		device pci 02.0 on 
+			chip southbridge/intel/pxhd	# PXHD 6700 
+				device pci 00.0 on end   # bridge 
+				device pci 00.1 on end   # I/O apic
+				device pci 00.2 on end   # bridge
+				device pci 00.3 on end   # I/O apic
+			end
+		end
+#	 	device register "intrline" = "0x00070105" 
+		device 	pci 04.0 on end	
+		device 	pci 06.0 on end	
+	end
+
+	device apic_cluster 0 on
+		chip cpu/intel/socket_mPGA604_800Mhz  	# CPU 0
+			device apic 0 on end
+		end
+		chip cpu/intel/socket_mPGA604_800Mhz 	# CPU 1
+			device apic 6 on end
+		end
+	end
+end
diff --git a/src/mainboard/supermicro/x6dhe_g2/Options.lb b/src/mainboard/supermicro/x6dhe_g2/Options.lb
new file mode 100644
index 0000000..d09effc
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/Options.lb
@@ -0,0 +1,229 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_BTEXT
+uses CC
+uses HOSTCC
+uses CROSS_COMPILE
+uses OBJCOPY
+
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=1048576
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Delay timer options
+## Use timer2
+## 
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=16
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=4
+default CONFIG_LOGICAL_CPUS=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="X6DHE_g"
+default MAINBOARD_VENDOR=     "Supermicro"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6080
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+default FALLBACK_SIZE=131072
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM=1
+
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+##
+## Don't enable the btext console
+##
+default  CONFIG_CONSOLE_BTEXT=0
+
+
+### End Options.lb
+end
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/auto.c b/src/mainboard/supermicro/x6dhe_g2/auto.c
new file mode 100644
index 0000000..978356c
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/auto.c
@@ -0,0 +1,168 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/ich5r/ich5r_early_smbus.c"
+#include "northbridge/intel/E7520/raminit.h"
+#include "superio/NSC/pc87427/pc87427.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "debug.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "x6dhe_g2_fixups.c"
+#include "superio/NSC/pc87427/pc87427_early_init.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP1)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, PC87427_SP2)
+
+#define DEVPRES_CONFIG  ( \
+	DEVPRES_D1F0 | \
+	DEVPRES_D2F0 | \
+	DEVPRES_D3F0 | \
+	DEVPRES_D4F0 | \
+	DEVPRES_D6F0 | \
+	0 )
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+#define RECVENA_CONFIG  0x0708090a
+#define RECVENB_CONFIG  0x0708090a
+
+//void udelay(int usecs)
+//{
+//        int i;
+//        for(i = 0; i < usecs; i++)
+//                outb(i&0xff, 0x80);
+//}
+
+#if 0
+static void hard_reset(void)
+{
+	/* enable cf9 */
+	pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+	/* reset */
+	outb(0x0e, 0x0cf9);
+}
+#endif
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7520/raminit.c"
+#include "sdram/generic_sdram.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+		    	.channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, },
+			.channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, },
+
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
+	pc87427_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+//	report_bist_failure(bist);
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing ich5r?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	display_cpuid_update_microcode();
+#endif
+#if 0
+	print_pci_devices();
+#endif
+#if 1
+	enable_smbus();
+#endif
+#if 0
+//	dump_spd_registers(&cpu[0]);
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+//	dump_ipmi_registers();
+//	mainboard_set_e7520_leds();	
+//	memreset_setup();
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+#if 0
+	dump_pci_devices();
+#endif
+#if 1
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+	//dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+	ram_check(0x00100000, 0x01000000);
+	/* check the first 1M in the 3rd Gig */
+	ram_check(0x30100000, 0x31000000);
+#endif
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/supermicro/x6dhe_g2/auto.updated.c b/src/mainboard/supermicro/x6dhe_g2/auto.updated.c
new file mode 100644
index 0000000..b4966a7
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/auto.updated.c
@@ -0,0 +1,168 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/esb6300/esb6300_early_smbus.c"
+#include "northbridge/intel/E7520/raminit.h"
+#include "superio/winbond/w83627hf/w83627hf.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "debug.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "x6dhe_g_fixups.c"
+#include "superio/winbond/w83627hf/w83627hf_early_init.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, W83627HF_SP2)
+
+#define DEVPRES_CONFIG  ( \
+	DEVPRES_D1F0 | \
+	DEVPRES_D2F0 | \
+	DEVPRES_D3F0 | \
+	DEVPRES_D4F0 | \
+	DEVPRES_D6F0 | \
+	0 )
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+#define RECVENA_CONFIG  0x0708090a
+#define RECVENB_CONFIG  0x0708090a
+
+//void udelay(int usecs)
+//{
+//        int i;
+//        for(i = 0; i < usecs; i++)
+//                outb(i&0xff, 0x80);
+//}
+
+#if 0
+static void hard_reset(void)
+{
+	/* enable cf9 */
+	pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+	/* reset */
+	outb(0x0e, 0x0cf9);
+}
+#endif
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7520/raminit.c"
+#include "sdram/generic_sdram.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+		    	.channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, },
+			.channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, },
+
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
+	w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+//	report_bist_failure(bist);
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing esb6300?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	display_cpuid_update_microcode();
+#endif
+#if 0
+	print_pci_devices();
+#endif
+#if 1
+	enable_smbus();
+#endif
+#if 0
+//	dump_spd_registers(&cpu[0]);
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+//	dump_ipmi_registers();
+//	mainboard_set_e7520_leds();	
+//	memreset_setup();
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+#if 0
+	dump_pci_devices();
+#endif
+#if 1
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+	//dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+	ram_check(0x00100000, 0x01000000);
+	/* check the first 1M in the 3rd Gig */
+	ram_check(0x30100000, 0x31000000);
+#endif
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/supermicro/x6dhe_g2/chip.h b/src/mainboard/supermicro/x6dhe_g2/chip.h
new file mode 100644
index 0000000..ff86e23
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/chip.h
@@ -0,0 +1,5 @@
+struct chip_operations mainboard_supermicro_x6dhe_g2_ops;
+
+struct mainboard_supermicro_x6dhe_g2_config {
+	int nothing;
+};
diff --git a/src/mainboard/supermicro/x6dhe_g2/cmos.layout b/src/mainboard/supermicro/x6dhe_g2/cmos.layout
new file mode 100644
index 0000000..6f3cd18
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/cmos.layout
@@ -0,0 +1,80 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       2        hyper_threading
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/debug.c b/src/mainboard/supermicro/x6dhe_g2/debug.c
new file mode 100644
index 0000000..5546421
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/debug.c
@@ -0,0 +1,330 @@
+#define SMBUS_MEM_DEVICE_START 0x50
+#define SMBUS_MEM_DEVICE_END 0x57
+#define SMBUS_MEM_DEVICE_INC 1
+
+static void print_reg(unsigned char index)
+{
+        unsigned char data;
+                                                                                
+        outb(index, 0x2e);
+        data = inb(0x2f);
+	print_debug("0x");
+	print_debug_hex8(index);
+	print_debug(": 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+        return;
+}
+        
+static void xbus_en(void)
+{
+        /* select the XBUS function in the SIO */
+        outb(0x07, 0x2e);
+        outb(0x0f, 0x2f);
+        outb(0x30, 0x2e);
+        outb(0x01, 0x2f);
+	return;
+}
+                                                                        
+static void setup_func(unsigned char func)
+{
+        /* select the function in the SIO */
+        outb(0x07, 0x2e);
+        outb(func, 0x2f);
+        /* print out the regs */
+        print_reg(0x30);
+        print_reg(0x60);
+        print_reg(0x61);
+        print_reg(0x62);
+        print_reg(0x63);
+        print_reg(0x70);
+        print_reg(0x71);
+        print_reg(0x74);
+        print_reg(0x75);
+        return;
+}
+                                                                                
+static void siodump(void)
+{
+        int i;
+        unsigned char data;
+       
+	 print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
+        for (i=0x10; i<=0x2d; i++) {
+                print_reg((unsigned char)i);
+        }
+#if 0                                                                         
+        print_debug("\r\n*** XBUS REGISTERS ***\r\n");
+        setup_func(0x0f);
+        for (i=0xf0; i<=0xff; i++) {
+                print_reg((unsigned char)i);
+        }
+                                                                                
+        print_debug("\r\n***  SERIAL 1 CONFIG REGISTERS ***\r\n");
+        setup_func(0x03);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  SERIAL 2 CONFIG REGISTERS ***\r\n");
+        setup_func(0x02);
+        print_reg(0xf0);
+
+#endif
+        print_debug("\r\n***  GPIO REGISTERS ***\r\n");
+        setup_func(0x07);
+        for (i=0xf0; i<=0xf8; i++) {
+                print_reg((unsigned char)i);
+        }
+        print_debug("\r\n***  GPIO VALUES ***\r\n");
+        data = inb(0x68a);
+	print_debug("\r\nGPDO 4: 0x");
+	print_debug_hex8(data);
+        data = inb(0x68b);
+	print_debug("\r\nGPDI 4: 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+	
+#if 0                                                                                
+                                                                                
+        print_debug("\r\n***  WATCHDOG TIMER REGISTERS ***\r\n");
+        setup_func(0x0a);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  FAN CONTROL REGISTERS ***\r\n");
+        setup_func(0x09);
+        print_reg(0xf0);
+        print_reg(0xf1);
+
+        print_debug("\r\n***  RTC REGISTERS ***\r\n");
+        setup_func(0x10);
+        print_reg(0xf0);
+        print_reg(0xf1);
+        print_reg(0xf3);
+        print_reg(0xf6);
+        print_reg(0xf7);
+        print_reg(0xfe);
+        print_reg(0xff);
+                                                                                
+        print_debug("\r\n***  HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
+        setup_func(0x14);
+        print_reg(0xf0);
+#endif                                                                           
+        return;
+}
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_bar14(unsigned dev)
+{
+	int i;
+	unsigned long bar;
+	
+	print_debug("BAR 14 Dump\r\n");
+	
+	bar = pci_read_config32(dev, 0x14);
+	for(i = 0; i <= 0x300; i+=4) {
+#if 0		
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+#endif		
+		if((i%4)==0) {
+		print_debug("\r\n");
+		print_debug_hex16(i);
+		print_debug_char(' ');
+		}
+		print_debug_hex32(read32(bar + i));
+		print_debug_char(' ');
+	}
+	print_debug("\r\n");
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+#if 0
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+	}
+}
+#endif
+
+void dump_spd_registers(void)
+{
+        unsigned device;
+        device = SMBUS_MEM_DEVICE_START;
+        while(device <= SMBUS_MEM_DEVICE_END) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("dimm ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 256) ; i++) {
+	                unsigned char byte;
+                        if ((i % 16) == 0) {
+				print_debug("\r\n");
+				print_debug_hex8(i);
+				print_debug(": ");
+                        }
+			status = smbus_read_byte(device, i);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}
+
+void dump_ipmi_registers(void)
+{
+        unsigned device;
+        device = 0x42;
+        while(device <= 0x42) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("ipmi ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 8) ; i++) {
+	                unsigned char byte;
+			status = smbus_read_byte(device, 2);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}	
diff --git a/src/mainboard/supermicro/x6dhe_g2/failover.c b/src/mainboard/supermicro/x6dhe_g2/failover.c
new file mode 100644
index 0000000..5029d98
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/failover.c
@@ -0,0 +1,46 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "pc80/mc146818rtc_early.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* Did just the cpu reset? */
+	if (memory_initialized()) {
+	 	if (last_boot_normal()) {
+			goto normal_image;
+		} else {
+			goto cpu_reset;
+		}
+	}
+
+	/* This is the primary cpu how should I boot? */
+	else if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
diff --git a/src/mainboard/supermicro/x6dhe_g2/irq_tables.c b/src/mainboard/supermicro/x6dhe_g2/irq_tables.c
new file mode 100644
index 0000000..0851fbe
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/irq_tables.c
@@ -0,0 +1,34 @@
+/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */
+
+#include <arch/pirq_routing.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+	0x52495024, /* u32 signature */
+	0x0100,     /* u16 version   */
+	272,        /* u16 Table size 32+(15*devices)  */
+	0x00,       /* u8 Bus 0 */
+	0xf8,       /* u8 Device 1, Function 0 */
+	0x0000,     /* u16 reserve IRQ for PCI */
+	0x8086,     /* u16 Vendor */
+	0x25a1,     /* Device ID */
+	0x00000000, /* u32 miniport_data */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0xc4,   /*  u8 checksum - mod 256 checksum must give zero */
+	{  /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  */
+	    {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06,  0x00},
+	    {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07,  0x00}
+	}
+};
diff --git a/src/mainboard/supermicro/x6dhe_g2/mainboard.c b/src/mainboard/supermicro/x6dhe_g2/mainboard.c
new file mode 100644
index 0000000..dcdb6f6
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include "chip.h"
+
+struct chip_operations supermicro_x6dhe_g2_ops = {
+    CHIP_NAME("Supermicro X6DHE_G2 mainboard")
+};
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/microcode_updates.c b/src/mainboard/supermicro/x6dhe_g2/microcode_updates.c
new file mode 100644
index 0000000..b2e72ab
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/microcode_updates.c
@@ -0,0 +1,1563 @@
+/* WARNING - Intel has a new data structure that has variable length

+ * microcode update lengths.  They are encoded in int 8 and 9.  A

+ * dummy header of nulls must terminate the list.

+ */

+                                                                                

+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {

+        /*

+           Copyright  Intel Corporation, 1995, 96, 97, 98, 99, 2000.

+           These microcode updates are distributed for the sole purpose of

+           installation in the BIOS or Operating System of computer systems

+           which include an Intel P6 family microprocessor sold or distributed

+           to or by you.  You are authorized to copy and install this material

+           on such systems.  You are not authorized to use this material for

+           any other purpose.

+        */

+                                                                                

+        /*  M1DF3413.TXT - Noconoa D-0  */

+                                                                                

+        0x00000001, /* Header Version   */

+        0x00000013, /* Patch ID         */

+        0x07302004, /* DATE             */

+        0x00000f34, /* CPUID            */

+        0x95f183f0, /* Checksum         */

+        0x00000001, /* Loader Version   */

+        0x0000001d, /* Platform ID      */

+        0x000017d0, /* Data size        */

+        0x00001800, /* Total size       */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+ 

+	0x9fbf327a,

+	0x2b41b451,

+	0xb2abaca8,

+	0x6b62b8e0,

+	0x0af32c41,

+	0x12ca6048,

+	0x5bd55ae6,

+	0xb90dfc1d,

+	0x565fe2b2,

+	0x326b1718,

+	0x61f3a40d,

+	0xceb53db3,

+	0x14fb5261,

+	0xbb23b6c3,

+	0x9d7c0466,

+	0xde90a25e,

+	0x9450e9bb,

+	0x497bd6e4,

+	0x97d1041a,

+	0x1831013f,

+	0x6e6fa37e,

+	0x0b5c1d03,

+	0x5eae4db2,

+	0xc029d9e3,

+	0x5373bca3,

+	0xe15fccca,

+	0x39043db0,

+	0xaeb0ea0c,

+	0x62b4e391,

+	0x0b280c6b,

+	0x279eb9d3,

+	0x98d95ada,

+	0xc1cb45a7,

+	0x06917bda,

+	0xdde8aafa,

+	0xdff9d15c,

+	0xd07f8f0a,

+	0x192bcf9d,

+	0xf77de31f,

+	0xadf8be55,

+	0x3f7a5d95,

+	0x0e2140b6,

+	0xf0c75eec,

+	0x3254876a,

+	0x684a1698,

+	0x4ad0cca7,

+	0x6d705304,

+	0xf957d91b,

+	0xe8bb864a,

+	0x440d636c,

+	0xaf4d7d06,

+	0x12680ecf,

+	0x5d0f9e53,

+	0x60148a5d,

+	0x81008364,

+	0x243a8aed,

+	0xd55976de,

+	0xd6a84520,

+	0x932d4b77,

+	0xe67e5f19,

+	0x7dba0e47,

+	0xfee3b153,

+	0x46b6a20c,

+	0x2594e6f6,

+	0x210cab0f,

+	0xf6e47d5d,

+	0xe38276e4,

+	0x90fc2728,

+	0x9faefa11,

+	0xc972217c,

+	0xc8d079dd,

+	0x5f7dc338,

+	0x106f7b7b,

+	0xd04c0a1c,

+	0x0eca300e,

+	0x1ddae8a6,

+	0x6e7fd42e,

+	0xa56c514d,

+	0x56a4e255,

+	0x975ea2bf,

+	0x0eaa78cc,

+	0x0c3e284f,

+	0xbacb6c71,

+	0x1645006f,

+	0xe9a2b955,

+	0x0677c019,

+	0x24b33da0,

+	0x62f200fa,

+	0x234238c4,

+	0x81d5ad79,

+	0x9f754bc9,

+	0xeffd5016,

+	0x041b2cc2,

+	0x2f020bc7,

+	0x4fcd68b8,

+	0x22c3579c,

+	0x4804a114,

+	0xc42db3ea,

+	0x7cde8141,

+	0x47e167c8,

+	0x01aa38cc,

+	0x74a5c25e,

+	0xe0c48d67,

+	0x562365ad,

+	0x38321e57,

+	0x0395885a,

+	0x6888323e,

+	0xd6fc518f,

+	0x1854b64c,

+	0x06a58476,

+	0x3662f898,

+	0xe2bcdaee,

+	0x84c40693,

+	0xef09d374,

+	0x353cc799,

+	0x742223d4,

+	0x05b3c99b,

+	0x0c51ee45,

+	0xd145824a,

+	0xac30806c,

+	0x2ed70c0d,

+	0x71ae10ff,

+	0xbf491854,

+	0x3e1f03b4,

+	0x76bfd6cd,

+	0x1449aa8a,

+	0xf954d3fb,

+	0xf8c7c940,

+	0x70233f85,

+	0x0729e257,

+	0x10bb8936,

+	0xc35bb5b5,

+	0x95d78b5c,

+	0xcc1ba443,

+	0x6f507126,

+	0xa607cfd0,

+	0xce22f2f3,

+	0x5134ed8c,

+	0xec8d2f06,

+	0xa92413d5,

+	0xb973f431,

+	0x16e136dd,

+	0xf7d41bed,

+	0x01b002fe,

+	0x646ed771,

+	0x76ea3d26,

+	0x5024af20,

+	0x84270f51,

+	0x9b3d7820,

+	0x2454a2c6,

+	0xc1f072ed,

+	0x155e864f,

+	0x4c39a6e5,

+	0x928206e5,

+	0x9d1685f5,

+	0x45542ee7,

+	0x1fd27d9e,

+	0x5f2dd9ff,

+	0x222005eb,

+	0x354e8a55,

+	0x1f0de29a,

+	0xb86dc696,

+	0x9eafafad,

+	0x191b197e,

+	0x0e0900e1,

+	0xe0ac42bb,

+	0x3143236f,

+	0x44177def,

+	0x05259274,

+	0xb21af44a,

+	0x6ddee4df,

+	0xc7b56255,

+	0xb6b1d39d,

+	0x218f9070,

+	0x96545a42,

+	0x98cc2d4a,

+	0xb21bac9e,

+	0x83e12d44,

+	0x2ef4fb39,

+	0xbc03528f,

+	0x9485af58,

+	0xd9f1e6ab,

+	0xde7607e6,

+	0x3b398733,

+	0x9cd9b1a9,

+	0xabd77984,

+	0xcce18826,

+	0x701c5c21,

+	0xe6591cbf,

+	0x07a9b9e1,

+	0x69459c90,

+	0xe0cdcad6,

+	0xc4c6c4b6,

+	0x12748024,

+	0x4a33c567,

+	0x7d26a37e,

+	0xcae163bf,

+	0xeb7547fa,

+	0xccc6a01c,

+	0x3cb8abb8,

+	0x64aa67b2,

+	0x51ddf6de,

+	0xbfe1b905,

+	0x50923949,

+	0xacfa43af,

+	0x1fdb5a44,

+	0x091533cb,

+	0x7c92e5dc,

+	0x1c5d0d3e,

+	0x195271f5,

+	0x96e73a4a,

+	0xe1b11968,

+	0xb42906f2,

+	0x5a2940b3,

+	0x611283e9,

+	0x65829161,

+	0x5d1357b7,

+	0x019428ad,

+	0x836c5c3c,

+	0xc0e5e169,

+	0xd360e424,

+	0x257a9d69,

+	0xdca09040,

+	0x85f1c060,

+	0xae7cae79,

+	0xa5ddcfd6,

+	0xdba8f68e,

+	0xd98df596,

+	0xe6e3cd51,

+	0xcfb2be8f,

+	0x368fe6cd,

+	0x58486b75,

+	0x791f1a48,

+	0xf81a61f2,

+	0x58a38155,

+	0x30a86547,

+	0xd7fb2db1,

+	0x300e0b1d,

+	0x3f838461,

+	0xf278805a,

+	0x49529931,

+	0x601d5649,

+	0xe500ba1a,

+	0xc4f78965,

+	0xe10ed02d,

+	0x1f777ebd,

+	0x2db1d17d,

+	0x48a22e6a,

+	0x5a14b738,

+	0xdcf899e0,

+	0xc845bd04,

+	0xd04a52b9,

+	0xf2f19b06,

+	0xdb5ba97a,

+	0xf05605ff,

+	0xc787b72c,

+	0x9f197770,

+	0x87b31150,

+	0x3ff00d57,

+	0x89d1dcb3,

+	0x07528ff4,

+	0x4105fcef,

+	0xb087de2e,

+	0x3bd333a5,

+	0x84a094f4,

+	0x9ab8fb97,

+	0xc9bba063,

+	0x664c52e5,

+	0x27fd05e4,

+	0x3f0e491d,

+	0xab8f4b9a,

+	0x344a0249,

+	0x727dd74f,

+	0x29587211,

+	0xbba262b9,

+	0x319ecbb3,

+	0xec54b023,

+	0xd0fa096d,

+	0x3d223f23,

+	0x0b6013e7,

+	0x513e045b,

+	0xcb1edf15,

+	0xfd44bb25,

+	0x023eb973,

+	0x3f55dac6,

+	0xc2df6514,

+	0x68589880,

+	0x4556878e,

+	0x86f6acfb,

+	0xbcd23f0b,

+	0x32c417c1,

+	0x45f3bb56,

+	0xbe60872b,

+	0x09457cc0,

+	0x2e18b62d,

+	0x065f54d1,

+	0xae3b4a20,

+	0x265b10ae,

+	0xb7547a1d,

+	0x5a9481a9,

+	0xd477ed02,

+	0x601ed0fc,

+	0x9a43257e,

+	0xc9922b72,

+	0xa2a696ae,

+	0xe9d6c37b,

+	0xfab8bdf9,

+	0x1deb34dc,

+	0xaa6bb090,

+	0xbdc3b72f,

+	0xecb3b010,

+	0xe64376e7,

+	0x40356095,

+	0x928b5047,

+	0xbd271c09,

+	0xfd806f61,

+	0x0821e090,

+	0x6afb3588,

+	0xd10e91ea,

+	0xbbc7fedd,

+	0xb1ac6d33,

+	0x07788e4b,

+	0xa10f8013,

+	0x4f8efd9d,

+	0xe5d8728d,

+	0x017f3e82,

+	0xf09ec7eb,

+	0x6bfd7906,

+	0xbcefcb44,

+	0x76699ad5,

+	0x1b976522,

+	0xa55b3dbd,

+	0x88bb33e2,

+	0x98ac5b7f,

+	0x61ac4c8b,

+	0xfd948f3d,

+	0xee610413,

+	0xc77c5035,

+	0x662825a9,

+	0x0009fcba,

+	0x3450fd88,

+	0xeb391fef,

+	0x6949960d,

+	0x1ccb13c3,

+	0x21dac5a6,

+	0x6bcc6b37,

+	0x37ad77a5,

+	0xf71d58b1,

+	0x84ed440d,

+	0xe606b699,

+	0xe43067a4,

+	0x21d5b8b3,

+	0xe11f83e2,

+	0xa0cc6585,

+	0x40eb6d16,

+	0xc5a6879f,

+	0xbd333fd5,

+	0xb44acab4,

+	0x68c016fc,

+	0xfbcd3cfc,

+	0xadf76e42,

+	0xc520e516,

+	0x7468cb61,

+	0x585c0d52,

+	0xea83cefe,

+	0x615d7760,

+	0x89c9b8fd,

+	0x367c355a,

+	0x409371a2,

+	0x7edb38a7,

+	0xca86d263,

+	0xda18250d,

+	0x26e1ed8b,

+	0x02fefede,

+	0x704cb5c8,

+	0x52cbe1eb,

+	0x9cdbc71a,

+	0xa0637560,

+	0xe31f03ca,

+	0x2b78969b,

+	0x803d5866,

+	0xec52d984,

+	0xd8df8bdb,

+	0x6cb1d5e8,

+	0x7b9aec01,

+	0xf7d39401,

+	0xdd04c6ae,

+	0x0e5ca4eb,

+	0x12b593c8,

+	0x38f6d4e5,

+	0x13a91268,

+	0x60c8251b,

+	0xa136cf9a,

+	0xda070cdd,

+	0x6142408c,

+	0xc28065dd,

+	0x50b73718,

+	0x36074eee,

+	0xc7b20fcb,

+	0x18d29f9b,

+	0xe97eb966,

+	0xe6936bcc,

+	0x1c9188ea,

+	0x7cff40e2,

+	0xee791ac8,

+	0xb099a323,

+	0x571d69b7,

+	0x22c1f7d0,

+	0x0b9662ee,

+	0x76e45cb9,

+	0xbd0d7020,

+	0x7794bd95,

+	0x1b0fe51a,

+	0xda2754ef,

+	0x7f3ad7a9,

+	0x58f627d3,

+	0x211670a3,

+	0xc7471b81,

+	0x495a93ac,

+	0xaad4f030,

+	0xa76614c8,

+	0xd63dba3c,

+	0x9c4f729c,

+	0x6e831cfb,

+	0xa6105c75,

+	0x95c62188,

+	0x723ef45d,

+	0xf59f2dd1,

+	0x5825283d,

+	0x768d8a86,

+	0x070d02ac,

+	0xfdbcbd73,

+	0x0d479795,

+	0x797aa7f7,

+	0x6c9e468b,

+	0xa961571d,

+	0xc7127ef0,

+	0x4b0442e7,

+	0xd99a9e87,

+	0x6c876cba,

+	0xe4f9f814,

+	0x120eeb8d,

+	0x4bbb9c8e,

+	0x22c0a29e,

+	0xff681fcc,

+	0x26777226,

+	0x6339e667,

+	0x2402333e,

+	0x2bf66a17,

+	0x63806e6c,

+	0x98416b75,

+	0x791b3e91,

+	0x79c09cd7,

+	0x0c157436,

+	0x6d99157c,

+	0xc8990984,

+	0xaf7d2ae4,

+	0xfe3ee7d9,

+	0xb7676de0,

+	0x9df8722e,

+	0x08462a7e,

+	0x99032839,

+	0xd726ff95,

+	0x5c1c78e8,

+	0x4ef1b747,

+	0x4e257ba7,

+	0xa83ad5f3,

+	0x523b3809,

+	0xc2ce4f19,

+	0xabfadaa5,

+	0x370b005c,

+	0x2d6a02e1,

+	0xbf6ee428,

+	0xfd84be50,

+	0xb79801b3,

+	0x488ad789,

+	0x65a87bda,

+	0x59f0fd6a,

+	0xa4106878,

+	0xdbadd916,

+	0x1f86f200,

+	0xefb7fc72,

+	0x26d4d47f,

+	0xf7892efc,

+	0x41f50167,

+	0xc6a28f9e,

+	0xffd4a8e0,

+	0xa00e4ea0,

+	0x8183f648,

+	0x030faa4c,

+	0x26c1715f,

+	0x322c9ea3,

+	0x5d60d054,

+	0x413470cb,

+	0x3d131892,

+	0x22f2ae86,

+	0x9f1c96b6,

+	0x015563f4,

+	0x3a5625ba,

+	0xcb95b598,

+	0xf0685fb9,

+	0x158af5ec,

+	0xfc01a406,

+	0x01841d19,

+	0x210b7e73,

+	0x19a416a1,

+	0xed254c44,

+	0x5bd51335,

+	0xb8905dc9,

+	0x9e52f38c,

+	0xef5d7dd0,

+	0x1516f6bb,

+	0xf13bb426,

+	0x9ee6d6cb,

+	0x28bde0a6,

+	0x766b655e,

+	0xaf2e0e52,

+	0xdec60f49,

+	0x254a0959,

+	0xb009d431,

+	0x2f6d3533,

+	0x0a074afc,

+	0xcd3d3a72,

+	0x52aa4fce,

+	0x16c4507d,

+	0x2f842898,

+	0xb087e98b,

+	0x68b41826,

+	0xd4adc5c9,

+	0x53b3e498,

+	0x2dff7b03,

+	0xda931e65,

+	0xf1d66edd,

+	0x2beb7555,

+	0x97b3f152,

+	0x035676f8,

+	0xca9c7cf6,

+	0x57992a53,

+	0x578a1004,

+	0x458e23c8,

+	0x2a2494bf,

+	0xa92c549b,

+	0x2ca46deb,

+	0xcd907478,

+	0x93baaeb5,

+	0xa70af4c6,

+	0x9767d5b8,

+	0x9874bcee,

+	0xb0413973,

+	0x9bfef4f7,

+	0x7fbed607,

+	0x2a255991,

+	0xa5e3109d,

+	0x90f09fef,

+	0xb7a3d468,

+	0x6db437aa,

+	0xe8dad585,

+	0xfbc19cbc,

+	0x34cacc6f,

+	0x6c5cc449,

+	0xcc6dc144,

+	0x70c6aaa0,

+	0x183bc459,

+	0x490ea5a8,

+	0xddf105bf,

+	0x3429facf,

+	0x79020f72,

+	0xd2de786d,

+	0xb776f3ed,

+	0x553e3da7,

+	0xaecff099,

+	0x2b471ce1,

+	0xe3a72af9,

+	0x04c9b2bf,

+	0xe84d9702,

+	0xec7cd831,

+	0xda66c6c1,

+	0x451b207c,

+	0x68243bc3,

+	0xb3012b1e,

+	0x1855c026,

+	0x1addac14,

+	0xc73834a2,

+	0xea91596d,

+	0x08f0d135,

+	0xc6021aa0,

+	0xc5d1726b,

+	0xc21d1f0b,

+	0x92b7c740,

+	0x9f024526,

+	0x6c91df6c,

+	0xfec85435,

+	0x3d5a9150,

+	0x93249836,

+	0x2ec5e71f,

+	0x23e96579,

+	0x81ce78d6,

+	0x49e45ccf,

+	0x4d5e9c78,

+	0x2a2cdfab,

+	0x148e1833,

+	0xa3fab11b,

+	0xd0ceb7e9,

+	0x4789b634,

+	0x147fc687,

+	0x48f4f59c,

+	0x21eea4e3,

+	0x411dfb7d,

+	0x033fe075,

+	0x57c9e07d,

+	0xb09edf4e,

+	0x9db83f5f,

+	0x6ef1343a,

+	0x64a68315,

+	0x300e34c3,

+	0x72ac2766,

+	0x640271a4,

+	0x0a282b82,

+	0xcaf1ec1b,

+	0x7d4849f9,

+	0x108c5eaa,

+	0xfaa96613,

+	0x0476639b,

+	0x70ee8371,

+	0x9db599ba,

+	0x85158d5f,

+	0x02912911,

+	0xe6fec86a,

+	0xcf3036f3,

+	0xccdd49a0,

+	0xe650b3cd,

+	0xf5429ef0,

+	0x411e4690,

+	0xa526e30b,

+	0x275822af,

+	0x91e12d05,

+	0x958881aa,

+	0xabf76cc4,

+	0x06e794a9,

+	0xa97d1577,

+	0x0188613c,

+	0x17c96558,

+	0x96c31832,

+	0x5696b201,

+	0x03e3dad2,

+	0xbe44d0ba,

+	0x4d552a6c,

+	0xe9fafb48,

+	0x4968ad28,

+	0xf109edce,

+	0xd1534f30,

+	0xc2d8b9e8,

+	0x66e911d7,

+	0xd67a594b,

+	0x4492b2b4,

+	0xeb86848d,

+	0x4106979b,

+	0x0f75039f,

+	0xf5f3ee2c,

+	0x04baf613,

+	0x00c6fd60,

+	0x32ebe198,

+	0xc7f129eb,

+	0x7cac0839,

+	0x57a1fde4,

+	0x2da04cfc,

+	0x93179aa5,

+	0xf3f4d2d9,

+	0xd8d2528a,

+	0x5fdd42af,

+	0xd08c7bdb,

+	0x53acd639,

+	0xe37aab85,

+	0x2d55b5a2,

+	0x7bc96248,

+	0x2fb42401,

+	0x2ff99915,

+	0x2be3b5ea,

+	0xf0ff9bdd,

+	0x1b6bbaa3,

+	0x83a13de0,

+	0x4503fc83,

+	0x08c24640,

+	0x2463a2b2,

+	0x2e264872,

+	0xc451a29d,

+	0xbfd2e09c,

+	0x15bcb009,

+	0x69102223,

+	0x4c8581e9,

+	0x4ec94cf0,

+	0x75017d7b,

+	0x0e5d8cf1,

+	0x50b9ca97,

+	0x55df1100,

+	0x245162e0,

+	0x0df18bca,

+	0x00776990,

+	0xf6790a03,

+	0x599ef43e,

+	0xe8bf7afb,

+	0xea141ddc,

+	0xad1a54b2,

+	0x55f767f8,

+	0xb661981c,

+	0xe1650342,

+	0x365adc95,

+	0xbb44e3a0,

+	0xa064fea1,

+	0x3516bf27,

+	0xfd40a414,

+	0x53f9a9e6,

+	0x2071a5ee,

+	0x56ca2713,

+	0x7afdd07a,

+	0xd62b7f6e,

+	0xe9dac904,

+	0xca212105,

+	0xb9d6e3de,

+	0x6af5033f,

+	0x34d9049b,

+	0xc51ec095,

+	0xe5eddb9d,

+	0x122b5c6a,

+	0x9f562e58,

+	0x20ec8986,

+	0x760857f2,

+	0x8d8aadb3,

+	0xbc8f0807,

+	0x0f79eae7,

+	0xbfa6bfa8,

+	0x28151aeb,

+	0xbe4b4d4b,

+	0xc65d58b0,

+	0xcf99ba1b,

+	0xc1049197,

+	0xe36d8c87,

+	0x548b7676,

+	0xbe7bb2c4,

+	0x77923781,

+	0x5fbd631e,

+	0x770e5a41,

+	0xd2f2948a,

+	0x074f5428,

+	0xc7a1562e,

+	0xf55618c6,

+	0x8bf8a3d1,

+	0x837ed4a8,

+	0xe42e0298,

+	0xd3754b0c,

+	0xbaa24c25,

+	0x793ac973,

+	0x814e66ec,

+	0xa4154fa9,

+	0x3e0e65ca,

+	0x5a783bd5,

+	0x2bb37f6c,

+	0xb3c2526e,

+	0x34c9a28a,

+	0x6c8b4795,

+	0x64605fa8,

+	0x2e6aae2e,

+	0xd9b28f27,

+	0x6a9a200b,

+	0x3acd1e3a,

+	0xce9a4a6c,

+	0xd2a0bd14,

+	0x700f2003,

+	0x501cbef7,

+	0x4068b05e,

+	0xa24c4580,

+	0x4da75506,

+	0x500b9b0f,

+	0x22e3a600,

+	0x7bec4e94,

+	0x8f0958e2,

+	0x42129a1e,

+	0xb46d8dc5,

+	0x29f8851c,

+	0x83fb38bd,

+	0x17b0de15,

+	0x15340d20,

+	0x74f00fde,

+	0x6c646b32,

+	0x905897c4,

+	0x4d8ed991,

+	0x3cf91fd5,

+	0x0ee02ddf,

+	0xec069ce6,

+	0x0b977683,

+	0xa0bf31f6,

+	0xa1d135a9,

+	0xa882d1db,

+	0xa731a63a,

+	0x48e211f1,

+	0xf3d89e99,

+	0xf982e6ea,

+	0x23dde303,

+	0x7f1ff8da,

+	0xdc8c6414,

+	0x806f432e,

+	0xd047bc02,

+	0x671bacff,

+	0xd40ba2a8,

+	0xe3666685,

+	0x31265f9f,

+	0x3931a952,

+	0x62f35606,

+	0xc48f0c5e,

+	0xfd107640,

+	0xf636da24,

+	0xb8f5c3b0,

+	0x1c91e88f,

+	0xed9dd432,

+	0x2b85fa5d,

+	0x8b15d2ac,

+	0x1e06cf24,

+	0x1def6e9c,

+	0xfae9175f,

+	0x03ac6f02,

+	0x37318c87,

+	0xbc0b1ce5,

+	0xa0640cab,

+	0x6cc20a3c,

+	0x1c7b2524,

+	0x4685dacc,

+	0xeab8bb31,

+	0x8063b5d0,

+	0x79817d52,

+	0x211b1972,

+	0xd7bfc987,

+	0xab9128dc,

+	0x150d9b36,

+	0x6a5838ab,

+	0x9a0a304d,

+	0x2e43c331,

+	0x84f2c4b8,

+	0x435146c1,

+	0xed64a280,

+	0x553ecb4c,

+	0x5c800db2,

+	0xeef4df95,

+	0x5dcf2c37,

+	0x70755ddf,

+	0x4274737b,

+	0xe610350e,

+	0xd97a5997,

+	0x7af5edce,

+	0xfd18ba0c,

+	0xb7587cd8,

+	0xfa5e42d6,

+	0x76bde9eb,

+	0xec41eead,

+	0x604d2423,

+	0xb4adbcf9,

+	0xce728fa3,

+	0x02361c31,

+	0x02fab64d,

+	0x00316b1c,

+	0x562f9aa4,

+	0x71f85790,

+	0x9cb6d464,

+	0x32949ebf,

+	0x434fc23d,

+	0xee7fac51,

+	0xda5cc63a,

+	0x17e616b4,

+	0xcd1bd1bc,

+	0x14638cae,

+	0xd31808fa,

+	0xb16e0727,

+	0xfdda2b0f,

+	0xbc11c678,

+	0xfe79dc6e,

+	0xe26eefb4,

+	0x9a78de16,

+	0xb68f2df2,

+	0xd47da234,

+	0xbdff28a4,

+	0x937bb1f4,

+	0x0786dd46,

+	0xbd1160f5,

+	0xf77b070c,

+	0x72b7c51e,

+	0xcbb3a371,

+	0x5e50e904,

+	0x00fbc379,

+	0x680757dd,

+	0xd38193f7,

+	0x93113e25,

+	0x7b258da7,

+	0x991aaa09,

+	0xab1415be,

+	0xa3740774,

+	0x370b72e5,

+	0x2fc643f4,

+	0x3916d70e,

+	0xea2838d3,

+	0xe4840c42,

+	0xd18e6959,

+	0x69a270ee,

+	0xee4a494e,

+	0x0329799b,

+	0x07480357,

+	0x0260c46f,

+	0x7b75346e,

+	0x787234f4,

+	0xe0adf25b,

+	0xba85cacf,

+	0xb5724eb1,

+	0xfde2c080,

+	0x2b6bb492,

+	0xd2f70545,

+	0x9ca97510,

+	0x4034c18f,

+	0x616bcb12,

+	0x5667f52a,

+	0xe2f6bfce,

+	0x1f25969e,

+	0x569eaab7,

+	0x27ad8196,

+	0x2d30a6d0,

+	0x96d6c10a,

+	0xcb9f024f,

+	0x3d7941ef,

+	0xf7a76bc5,

+	0xe9a701d4,

+	0xd53293a3,

+	0x252cf5df,

+	0xaf9172f6,

+	0xd090c809,

+	0xb1a17387,

+	0x045a0987,

+	0x92d9ffd9,

+	0xb30c449c,

+	0x2180ff58,

+	0x2929f7de,

+	0x3f91766e,

+	0x9f488e3d,

+	0x05dd6734,

+	0x82482f5b,

+	0x01da3ca2,

+	0x42f33408,

+	0xf8e3ba89,

+	0x750ac2ff,

+	0x39f11551,

+	0x71087971,

+	0x368fa634,

+	0xefda0572,

+	0x14b8f750,

+	0xe5768705,

+	0x71c168e2,

+	0x8c012c63,

+	0x12ad74ce,

+	0x841c17ea,

+	0xe6f44176,

+	0x36cf2557,

+	0x14760a6d,

+	0x4bb3b7c2,

+	0x14d1437d,

+	0xbe673210,

+	0x4d6ba9f5,

+	0xe68abbf9,

+	0xc311908d,

+	0x46b63956,

+	0xac2c9fb3,

+	0xab769ce8,

+	0xa29d7040,

+	0xec3d67e3,

+	0xdef311de,

+	0x52a53b14,

+	0xca924769,

+	0xf35d1514,

+	0x524b0471,

+	0xc0d08591,

+	0x454fc34c,

+	0xca719639,

+	0x9af2f230,

+	0xa023a821,

+	0x3d6539ba,

+	0x90d0d7a2,

+	0xc65fc56e,

+	0x4eb2aa19,

+	0xeba3b0e7,

+	0x1bb5b33e,

+	0xab8c68c2,

+	0x0f1793d3,

+	0xdcf176e9,

+	0x1b7bbba0,

+	0x96170a27,

+	0x1955452d,

+	0x42e88c71,

+	0x48cad4b3,

+	0xdcc36042,

+	0x90619951,

+	0x7566bc7c,

+	0xe14ba224,

+	0xc24ad73d,

+	0xdb04144d,

+	0xd9792727,

+	0x11150943,

+	0xe45f0c57,

+	0xb87d184e,

+	0x3cf13243,

+	0x2010d95c,

+	0x84c347c1,

+	0x6d0f2461,

+	0xb5c41194,

+	0xde7ccb2e,

+	0xb929ecb0,

+	0x51fbd8f7,

+	0x45dc65fb,

+	0x6902d2c0,

+	0xb940814f,

+	0xf339e083,

+	0x6f370d56,

+	0xcaf5638e,

+	0xe8a3cb83,

+	0xacf414b6,

+	0xe61095a1,

+	0x99b4cde4,

+	0x55112fed,

+	0x606b9d53,

+	0x5a05974a,

+	0xa4c7db34,

+	0xdc92469b,

+	0xf9280621,

+	0xe7b1ef95,

+	0xc0fc5be8,

+	0x74a1da09,

+	0xa92a4b7f,

+	0x3d65d75e,

+	0xe3804335,

+	0x1ff49e19,

+	0x71da8170,

+	0xac69069b,

+	0x04aae3d5,

+	0xc0ef4b46,

+	0x091a3482,

+	0x8356c7ae,

+	0x32ecb208,

+	0x900c89ed,

+	0x2a206ff5,

+	0x7eed5032,

+	0x5b55b25d,

+	0xf98d6df2,

+	0xf52bc8a9,

+	0x1aa2f5fe,

+	0x1d33c0bf,

+	0x3cd34e89,

+	0x9a0da4ae,

+	0x1c205917,

+	0x7ca784cd,

+	0xf7dda662,

+	0xad97f3ff,

+	0x525c53ec,

+	0x024f11ff,

+	0x32c3ae5b,

+	0xbf372800,

+	0x8ff15f4d,

+	0x7605d019,

+	0x0dae7740,

+	0x5f5dd0ef,

+	0x0f6c37d0,

+	0xee6fa91e,

+	0xb9f51051,

+	0x39a9f0d1,

+	0x22bf03fb,

+	0x485a0922,

+	0x7384b30e,

+	0x85ba7f16,

+	0xb1f0a524,

+	0x7e9c5113,

+	0x240d9306,

+	0x1ca7b0ea,

+	0x18a0d114,

+	0x76b64213,

+	0x31212cc0,

+	0xc9dca5c3,

+	0x69f2ae52,

+	0x545caa7c,

+	0xfb2ff045,

+	0x3f3a1af5,

+	0xe75b6913,

+	0x775a1c79,

+	0x4627e25f,

+	0x90a14b97,

+	0x06456383,

+	0x3d52cf69,

+	0xfb2492c3,

+	0x39f25a22,

+	0x81f68c55,

+	0x87b14e15,

+	0x0920af5d,

+	0xe2585678,

+	0x0671e46d,

+	0xb77ddb67,

+	0x3948c4b3,

+	0x122dddef,

+	0xd0726172,

+	0xd3302234,

+	0x58bab4e4,

+	0x195ac247,

+	0x082459f0,

+	0x18a2566d,

+	0xbf56078d,

+	0x116ed409,

+	0x5ccc0f80,

+	0xbae0b4ca,

+	0x21a6325d,

+	0x7e1f0c40,

+	0x595326d4,

+	0x518b2244,

+	0x8ab3cdb7,

+	0xbe6b4835,

+	0xfc39f8ac,

+	0x63b167aa,

+	0x194f070d,

+	0xed3d0416,

+	0xae16758a,

+	0xb9bb6bbf,

+	0x477d9c85,

+	0x9808c304,

+	0xe1d8cec4,

+	0x7ee22e17,

+	0x0a7a9d7f,

+	0xcc98173a,

+	0x5f78dc21,

+	0x364bc95e,

+	0xb54608d9,

+	0x5d4d70ea,

+	0x083a7f79,

+	0x59ffbd73,

+	0x4f3e9eaf,

+	0x68755ad4,

+	0xab254689,

+	0x11bf09a8,

+	0xbbc40098,

+	0x969ca3eb,

+	0x30eee9d2,

+	0xe35bc37e,

+	0xcb2d678f,

+	0x7846876b,

+	0xf0d28ae7,

+	0xc092fbb2,

+	0x321b344a,

+	0xcc5ee81b,

+	0xd2afa00f,

+	0xfeccd86a,

+	0x6e5e55c2,

+	0x2b5543ea,

+	0x810e4009,

+	0xea2d8e20,

+	0x6acae3b9,

+	0x3828e15e,

+	0xe1e4821c,

+	0xf429da70,

+	0x35f6565c,

+	0x64b1baa8,

+	0x350e9583,

+	0xd2522d4f,

+	0x5e28a3f1,

+	0x949ff0aa,

+	0x3c1b5694,

+	0x146dde1f,

+	0x6f3430e1,

+	0x71c077b7,

+	0x4d145924,

+	0xe431cd28,

+	0xb315cfde,

+	0xa0365a4a,

+	0x473de1aa,

+	0xcbe4e999,

+	0x319906e9,

+	0xad0fea9c,

+	0x89e4e72d,

+	0x9dbba94d,

+	0xd395c1c5,

+	0xa1fff11a,

+	0x8447e120,

+	0xe5c59100,

+	0xa07cb778,

+	0x8f30a039,

+	0xed78facb,

+	0x86de9373,

+	0x550c4889,

+	0xce71e3a8,

+	0x06167b3a,

+	0x5abdd9a3,

+	0xc8a9e48d,

+	0xe3312905,

+	0x7a63a146,

+	0xc0f19763,

+	0xda0cf9db,

+	0x1d708306,

+	0x0e41f0ba,

+	0x4c7939fe,

+	0x768e48c2,

+	0xe925fd31,

+	0x309e7870,

+	0xfc261b87,

+	0xc897b2de,

+	0x6c714792,

+	0x41c7fbac,

+	0x57d0b3c3,

+	0x4fa82a55,

+	0xd56b4a87,

+	0x81e5cabc,

+	0xb260cb7b,

+	0x520927ab,

+	0x20d0ab46,

+	0xc9f92ddf,

+	0x81f4a21d,

+	0xfc5a0ca2,

+	0x95d16aad,

+	0xe54d7847,

+	0x6080cc07,

+	0x0df73f7e,

+	0xaa8d5187,

+	0x97a0bc12,

+	0xb22c5e68,

+	0x0954d7dc,

+	0x3368ab5a,

+	0xd12541df,

+	0x58119260,

+	0xe5b0e1df,

+	0x25027fa4,

+	0x5780425d,

+	0x29bb8791,

+	0x4100b7a9,

+	0x076b3519,

+	0x15e0ebb4,

+	0xe5fb9273,

+	0x6dbf07e7,

+	0x1f82bddd,

+	0x03691b6b,

+	0xbacef28c,

+	0x9909ed5a,

+	0x98886793,

+	0x544f9a82,

+	0x9d9749d0,

+	0x38441606,

+	0xc4a9f4d2,

+	0x6ce2bcf1,

+	0x1c7c3abd,

+	0x62c621f1,

+	0x871ee1e4,

+	0xa83930ce,

+	0xbe1ee459,

+	0xd61f1ca4,

+	0x8c4450e5,

+	0x98031ca9,

+	0xe52f54e2,

+	0xd0c4c737,

+	0x76074160,

+	0xbf050c3b,

+	0x2603af14,

+	0x43cbb0bc,

+	0xc631b9e8,

+	0x26030719,

+	0x993f570c,

+	0xdda34038,

+	0xe34a9793,

+	0x337a124c,

+	0x2aa8af16,

+	0xf80d7473,

+	0xf01d9397,

+	0x68e1afb9,

+	0x0eb37ad2,

+	0xf71969f9,

+	0xdf020552,

+	0x75aa9b30,

+	0xffa210cf,

+	0x543c414f,

+	0xa1e3faec,

+	0x40891d7e,

+	0x6b48a6c5,

+	0xec09a1a0,

+	0x97a31f2a,

+	0x5a6be2d7,

+	0xd06e492b,

+	0xc54290af,

+	0xcb524021,

+	0x420e8c4d,

+	0xfb135c17,

+	0x2bfc8adb,

+	0x9f0cfb46,

+	0x564db712,

+	0x7a97a227,

+	0x8bb98daf,

+	0xdd0d6180,

+	0x3d28b9e3,

+	0xe505050f,

+	0x19a9868e,

+	0x7bf5685f,

+	0x35d698c4,

+	0xce7e1de3,

+	0x360a64af,

+	0x25a1f022,

+	0xe26c1d04,

+	0x5b3fb364,

+	0x932f25f7,

+	0x9a2aa00d,

+	0xc50fb773,

+	0xec45ea3a,

+	0x22ddf8e4,

+	0xafb6a6c8,

+	0x876d04f7,

+	0xd9c86c3c,

+	0xd54bee2d,

+	0xf4e28199,

+	0xc3456776,

+	0x04c3107b,

+	0xbf914e9d,

+	0x23fefaa5,

+	0x0931a133,

+	0x41467758,

+	0x8ec49707,

+	0x5ed48709,

+	0xd11c2de8,

+	0xb687a0b9,

+	0xdc908383,

+	0xd8037ff3,

+	0xd4311a9f,

+	0xd00aeb6a,

+	0xfe54df3b,

+	0x9c51ce4d,

+	0x36956408,

+	0xcd28ef09,

+	0xc68932b0,

+	0x7c31e782,

+	0x28b4723c,

+	0xededacc2,

+	0x6ddbac6b,

+	0x775a7fc1,

+	0x6909906f,

+	0xa774123c,

+	0xf63145ad,

+	0x287b191e,

+	0x59d79300,

+	0xbf76a2fc,

+	0xfbaf9207,

+	0x2fe5b7f6,

+	0xebe7c103,

+	0x71ac0a8d,

+	0x2028c3c7,

+	0xd2cb4917,

+	0xd74a4ee4,

+	0xfce405d8,

+	0xad83fd0f,

+	0x8f9ec3da,

+	0xaab2301c,

+	0xc6f1339f,

+	0xc652bced,

+	0xe378b272,

+	0x18e1ff34,

+	0x9ec778b6,

+	0xce1a3883,

+	0x7c5e5eaf,

+	0xd16ec37a,

+	0xa69e45f4,

+	0xc36cd4aa,

+	0x045b391f,

+	0x5a2a08f1,

+	0x4dd8d53e,

+	0xd64796ec,

+	0x4476fc28,

+	0x18dbaa50,

+	0x00fb2407,

+	0x177db915,

+	0x5969758b,

+	0x3030964a,

+	0x81d6485b,

+	0x7d2e12b0,

+	0x624d6c5f,

+	0x0746bbc0,

+	0xe669d150,

+	0x0465eef7,

+	0x09764011,

+	0x551995e4,

+	0x8422dedf,

+	0x0ca56194,

+	0x293eab2e,

+	0xf20a137a,

+	0x55117fc2,

+	0xbc5431af,

+	0x064751fa,

+	0xc0dafdb2,

+	0x6c3b1d4f,

+	0xeac335b3,

+	0x71173afc,

+	0x31c84b7c,

+	0xfef2b4ab,

+	0x59ca5fa2,

+	0x664c8b4e,

+	0x7dfd560b,

+	0xdb0daff3,

+	0x51f87bfa,

+	0x58015d2e,

+	0x67a827b4,

+	0x62cebc1a,

+	0x24b37298,

+	0x75b589be,

+	0x874f1800,

+	0x277b795c,

+	0xf762489e,

+	0x87d00752,

+	0x9be45ed1,

+	0x296ec120,

+	0x61162480,

+	0x792e8a2c,

+	0x3b631590,

+	0xe33ba0cf,

+	0x542ac23c,

+	0xe1e8cffa,

+	0xfc084cd8,

+	0xc115ad31,

+	0x71559928,

+	0x791f1e33,

+	0x662ed92b,

+	0x7222c76d,

+	0x02dcd566,

+	0x8db9b4d4,

+	0xa5f344c8,

+	0x15806b12,

+	0x81e572f7,

+	0x3b3fbe25,

+	0x2133b413,

+	0x2d68a367,

+	0x356f6ce7,

+	0xcd6dfed1,

+	0xd8b3a26e,

+	0xe9d328da,

+	0x127425ab,

+	0x83a60aac,

+	0x8cc26190,

+	0x7f87ab26,

+	0x56faab5f,

+	0x76d0feaa,

+	0x4b25dd10,

+	0x4f6286ea,

+	0x79298d06,

+	0x8002bf83,

+	0x2977c85e,

+	0xd3b3d19a,

+	0xa92bf132,

+	0xa280efd8,

+	0x83f7ad6e,

+	0x748969c7,

+	0x25ff411d,

+	0x3854d3a8,

+	0x55746aa2,

+	0x00db5c54,

+	0x36949e0d,

+	0x40402ab6,

+	0x1a720211,

+	0xe02ce823,

+	0x4ac104a2,

+	0x214d2e4b,

+	0x267e5c83,

+	0x38a3a483,

+	0xd1da1f67,

+	0x0c68db2c,

+	0xd7035d63,

+	0xa29393bb,

+	0xa5743519,

+	0xcb97c84e,

+	0xa853974f,

+	0x147360a0,

+	0x2df9b3f4,

+	0x0aff129e,

+	0x177d687f,

+	0x87eff911,

+	0x6c60b354,

+	0x6c356c38,

+	0x7d480965,

+	0xbb06a193,

+	0x25b0568e,

+	0x6fd6da9a,

+	0x82b64f14,

+	0x3d267a78,

+	0xf100b6a7,

+	0x32c74539,

+	0x6042e152,

+	0x4548276e,

+	0xa3a32b70,

+	0xf029fe15,

+	0xa9b8bd2f,

+	0x5618eee4,

+	0x9815a5f0,

+	0x89fb2850,

+	0xa9261b26,

+	0xded9e505,

+	0x37e9d749,

+	0xdc4aeb78,

+	0x9e634f7a,

+	0xcf638d2d,

+	0x6b679f92,

+	0x2b64911d,

+	0xe6d1312f,

+	0x88b3e76a,

+	0x56311f62,

+	0x00916de7,

+	0x39d0bc61,

+	0x8ac09356,

+	0x47abcfce,

+	0x324cb73e,

+	0xfadcd0a8,

+	0x2f2fbca8,

+	0x945eda22,

+	0xba23cab1,

+	0xf9fb4212,

+	0x1fa71d45,

+	0x867a034e,

+	0x3bee5db1,

+	0xf54adced,

+	0x6633ba77,

+	0xe1eb4f1e,

+	0x97ef01f6,

+	0x57fd3b32,

+	0x5234d80d,

+	0xe8ee95f3,

+	0x5dc990bf,

+	0xaba833e1,

+/*  Dummy terminator  */

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+};

+                                                                                

+

diff --git a/src/mainboard/supermicro/x6dhe_g2/mptable.c b/src/mainboard/supermicro/x6dhe_g2/mptable.c
new file mode 100644
index 0000000..6a28498
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/mptable.c
@@ -0,0 +1,202 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "LNXI    ";
+	static const char productid[12] = "X6DHE       ";
+	struct mp_config_table *mc;
+	unsigned char bus_num;
+	unsigned char bus_isa;
+	unsigned char bus_pxhd_1;
+	unsigned char bus_pxhd_2;
+	unsigned char bus_esb6300_1;
+	unsigned char bus_esb6300_2;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* initially just the header */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* not yet computed */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet... */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+	
+	{
+		device_t dev;
+
+		/* esb6300_2 */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1c,0));
+		if (dev) {
+			bus_esb6300_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1c.0, using defaults\n");
+
+			bus_esb6300_2 = 6;
+		}
+		/* esb6300_1 */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
+		if (dev) {
+			bus_esb6300_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_isa++;
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n");
+
+			bus_esb6300_1 = 7;
+			bus_isa = 8;
+		}
+		/* pxhd-1 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x0,0));
+		if (dev) {
+			bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n");
+
+			bus_pxhd_1 = 2;
+		}
+		/* pxhd-2 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,2));
+		if (dev) {
+			bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
+
+			bus_pxhd_2 = 3;
+		}
+	}
+	
+	/* define bus and isa numbers */
+	for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+		smp_write_bus(mc, bus_num, "PCI	  ");
+	}
+	smp_write_bus(mc, bus_isa, "ISA	  ");
+
+	/* IOAPIC handling */
+
+	smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
+	smp_write_ioapic(mc, 3, 0x20, 0xfec10000);
+	{
+	    	struct resource *res;
+		device_t dev;
+		/* PXHd apic 4 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,1));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x04, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n");
+			printk_debug("DEBUG: Dev= %p\n", dev);
+		}
+		/* PXHd apic 5 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,3));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x05, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n");
+			printk_debug("DEBUG: Dev= %p\n", dev);
+		}
+	}
+
+	
+	/* ISA backward compatibility interrupts  */
+	smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x01, 0x02, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x02);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x03, 0x02, 0x03);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x04, 0x02, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x06, 0x02, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, // added
+		bus_isa, 0x07, 0x02, 0x07);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x08, 0x02, 0x08);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x09, 0x02, 0x09);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x77, 0x02, 0x17);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x75, 0x02, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0c, 0x02, 0x0c);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0d, 0x02, 0x0d);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0e, 0x02, 0x0e);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0f, 0x02, 0x0f);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7c, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7d, 0x02, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		0x03, 0x08, 0x05, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		0x03, 0x08, 0x05, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_1, 0x04, 0x03, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_1, 0x08, 0x03, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_2, 0x04, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added
+		bus_esb6300_2, 0x08, 0x02, 0x14);
+	
+	/* Standard local interrupt assignments */
+	smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x00);
+	smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x01);
+
+#warning "FIXME verify I have the irqs handled for all of the risers"
+
+	/* Compute the checksums */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+	printk_debug("Wrote the mp table end at: %p - %p\n",
+		mc, smp_next_mpe_entry(mc));
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/reset.c b/src/mainboard/supermicro/x6dhe_g2/reset.c
new file mode 100644
index 0000000..874bfc4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/reset.c
@@ -0,0 +1,40 @@
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#ifndef __ROMCC__
+#include <device/device.h>
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+#define PCI_DEV_INVALID 0
+
+static inline device_t pci_locate_device(unsigned pci_id, device_t from)
+{
+	return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
+}
+#endif
+
+void soft_reset(void)
+{
+        outb(0x04, 0xcf9);
+}
+void hard_reset(void)
+{
+        outb(0x02, 0xcf9);
+        outb(0x06, 0xcf9);
+}
+void full_reset(void)
+{
+	device_t dev;
+	/* Enable power on after power fail... */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0);
+	if (dev != PCI_DEV_INVALID) {
+		unsigned byte;
+		byte = pci_read_config8(dev, 0xa4);
+		byte &= 0xfe;
+		pci_write_config8(dev, 0xa4, byte);
+		
+	}
+        outb(0x0e, 0xcf9);
+}
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/watchdog.c b/src/mainboard/supermicro/x6dhe_g2/watchdog.c
new file mode 100644
index 0000000..3904a7d
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/watchdog.c
@@ -0,0 +1,99 @@
+#include <device/pnp_def.h>
+
+#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
+#define NSC_WDBASE 0x600
+#define ESB6300_WDBASE 0x400
+#define ESB6300_GPIOBASE 0x500
+
+static void disable_sio_watchdog(device_t dev)
+{
+#if 0
+	/* FIXME move me somewhere more appropriate */
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 1);
+	pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
+	/* disable the sio watchdog */
+	outb(0, NSC_WDBASE + 0);
+	pnp_set_enable(dev, 0);
+#endif
+}
+
+static void disable_esb6300_watchdog(void)
+{
+	/* FIXME move me somewhere more appropriate */
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing esb6300?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ESB6300_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ESB6300_WDBASE + 0x60;
+	
+	/* Set bit 11 in TCO1_CNT */
+	value = inw(base + 0x08);
+	value |= 1 << 11;
+	outw(value, base + 0x08);
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+}
+
+static void disable_jarell_frb3(void)
+{
+#if 0
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing esb6300?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 0);
+	pci_write_config16(dev, 0x04, value);
+
+	/* Set gpio base */
+	pci_write_config32(dev, 0x58, ESB6300_GPIOBASE | 1);
+	base = ESB6300_GPIOBASE;
+
+	/* Enable GPIO Bar */
+	value = pci_read_config32(dev, 0x5c);
+	value |= 0x10;
+	pci_write_config32(dev, 0x5c, value);
+
+	/* Configure GPIO 48 and 40 as GPIO */
+	value = inl(base + 0x30);
+	value |= (1 << 16) | ( 1 << 8);
+	outl(value, base + 0x30);
+
+	/* Configure GPIO 48 as Output */
+	value = inl(base + 0x34);
+	value &= ~(1 << 16);
+	outl(value, base + 0x34);
+
+	/* Toggle GPIO 48 high to low */
+	value = inl(base + 0x38);
+	value |= (1 << 16);
+	outl(value, base + 0x38);
+	value &= ~(1 << 16);
+	outl(value, base + 0x38);
+#endif				  
+}
+
+static void disable_watchdogs(void)
+{
+//	disable_sio_watchdog(NSC_WD_DEV);
+	disable_esb6300_watchdog();
+//	disable_jarell_frb3();
+	print_debug("Watchdogs disabled\r\n");
+}
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/x6dhe_g2_fixups.c b/src/mainboard/supermicro/x6dhe_g2/x6dhe_g2_fixups.c
new file mode 100644
index 0000000..82c070b
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhe_g2/x6dhe_g2_fixups.c
@@ -0,0 +1,23 @@
+#include <arch/romcc_io.h>
+
+static void mch_reset(void)
+{
+        return;
+}
+
+
+
+static void mainboard_set_e7520_pll(unsigned bits)
+{
+	return; 
+}
+
+
+static void mainboard_set_e7520_leds(void)
+{
+	return; 
+}
+
+
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/Config.lb b/src/mainboard/supermicro/x6dhr_ig/Config.lb
new file mode 100644
index 0000000..e6cdc0c
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/Config.lb
@@ -0,0 +1,218 @@
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=131072
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc" 
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc 
+	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc    -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc
+	ldscript /cpu/x86/16bit/reset16.lds
+else
+	mainboardinit cpu/x86/32bit/reset32.inc
+	ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/E7520 # mch
+	device pci_domain 0 on 
+		chip southbridge/intel/ich5r # ich5r
+			# USB ports
+			device pci 1d.0 on end
+			device pci 1d.1 on end
+			device pci 1d.2 on end 
+			device pci 1d.3 on end
+			device pci 1d.7 on end
+		
+			# -> VGA
+			device pci 1e.0 on end
+		
+			# -> IDE
+			device pci 1f.0 on 
+				chip superio/winbond/w83627hf
+					device pnp 2e.0 off end
+					device pnp 2e.2 on 
+						 io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.3 on
+						 io 0x60 = 0x2f8
+						irq 0x70 = 3
+					end
+					device pnp 2e.4 off end
+					device pnp 2e.5 off end
+					device pnp 2e.6 off end
+					device pnp 2e.7 off end
+					device pnp 2e.9 off end
+					device pnp 2e.a on  end
+					device pnp 2e.b off end
+				end
+			end
+			device pci 1f.1 on end
+			device pci 1f.2 on end
+			device pci 1f.3 on end
+
+			register "pirq_a_d" = "0x0b070a05"
+			register "pirq_e_h" = "0x0a808080"
+		end
+		device pci 00.0 on end 
+		device pci 00.1  on end
+		device pci 01.0 on end 
+		device pci 02.0 on end 
+		device pci 03.0 on 
+			chip southbridge/intel/pxhd # pxhd1
+				# Bus bridges and ioapics usually bus 2
+				device pci 0.0 on end
+				device pci 0.1 on end
+				device pci 0.2 on 
+				# On board gig e1000
+					chip drivers/generic/generic 
+        		        	        device pci 02.0 on end
+        		        	        device pci 02.1 on end
+        		        	end
+				end
+				device pci 0.3 on end
+			end
+		end
+		device pci 04.0 on 
+			chip southbridge/intel/pxhd # pxhd2
+				# Bus bridges and ioapics usually bus 5
+				device pci 0.0 on end
+				# Slot 6  is usually 6:2.0
+				device pci 0.1 on end
+				device pci 0.2 on end
+				# Slot 7 is usually 7:2.0
+				device pci 0.3 on end
+			end
+		end
+		device pci 06.0 on end
+	end
+	device apic_cluster 0 on
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu 0
+			device apic 0 on end
+		end
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu 1
+			device apic 6 on end
+		end
+	end
+	register "intrline" = "0x00070105"
+end
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/Options.lb b/src/mainboard/supermicro/x6dhr_ig/Options.lb
new file mode 100644
index 0000000..8461cdb
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/Options.lb
@@ -0,0 +1,228 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_BTEXT
+uses CC
+uses HOSTCC
+uses CROSS_COMPILE
+uses OBJCOPY
+
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=1048576
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Delay timer options
+## Use timer2
+## 
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=16
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=4
+default CONFIG_LOGICAL_CPUS=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="X6DHR"
+default MAINBOARD_VENDOR=     "Supermicro"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x5580
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+default FALLBACK_SIZE=131072
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM=1
+
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+##
+## Don't enable the btext console
+##
+default  CONFIG_CONSOLE_BTEXT=0
+
+
+### End Options.lb
+end
diff --git a/src/mainboard/supermicro/x6dhr_ig/auto.c b/src/mainboard/supermicro/x6dhr_ig/auto.c
new file mode 100644
index 0000000..ce72954
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/auto.c
@@ -0,0 +1,169 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/ich5r/ich5r_early_smbus.c"
+#include "northbridge/intel/E7520/raminit.h"
+#include "superio/winbond/w83627hf/w83627hf.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "debug.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "x6dhr_fixups.c"
+#include "superio/winbond/w83627hf/w83627hf_early_init.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, W83627HF_SP2)
+
+#define DEVPRES_CONFIG  ( \
+	DEVPRES_D0F0 | \
+	DEVPRES_D1F0 | \
+	DEVPRES_D2F0 | \
+	DEVPRES_D3F0 | \
+	DEVPRES_D4F0 | \
+	DEVPRES_D6F0 | \
+	0 )
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+#define RECVENA_CONFIG  0x0808090a
+#define RECVENB_CONFIG  0x0808090a
+
+//void udelay(int usecs)
+//{
+//        int i;
+//        for(i = 0; i < usecs; i++)
+//                outb(i&0xff, 0x80);
+//}
+
+#if 0
+static void hard_reset(void)
+{
+	/* enable cf9 */
+	pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+	/* reset */
+	outb(0x0e, 0x0cf9);
+}
+#endif
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7520/raminit.c"
+#include "sdram/generic_sdram.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+			.channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, },
+			.channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, },
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
+	w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+//	report_bist_failure(bist);
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing ich5?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	display_cpuid_update_microcode();
+#endif
+#if 0
+	print_pci_devices();
+#endif
+#if 1
+	enable_smbus();
+#endif
+#if 0
+//	dump_spd_registers(&cpu[0]);
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+//	dump_ipmi_registers();
+	mainboard_set_e7520_leds();	
+//	memreset_setup();
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+#if 1
+	dump_pci_devices();
+#endif
+#if 0
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+	dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+//	ram_check(0x00100000, 0x01000000);
+	ram_check(0x00100000, 0x00100100);
+	/* check the first 1M in the 3rd Gig */
+//	ram_check(0x30100000, 0x31000000);
+#endif
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/supermicro/x6dhr_ig/chip.h b/src/mainboard/supermicro/x6dhr_ig/chip.h
new file mode 100644
index 0000000..495788e
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/chip.h
@@ -0,0 +1,5 @@
+struct chip_operations mainboard_supermicro_x6dhr_ig_ops;
+
+struct mainboard_supermicro_x6dhr_ig_config {
+	int nothing;
+};
diff --git a/src/mainboard/supermicro/x6dhr_ig/cmos.layout b/src/mainboard/supermicro/x6dhr_ig/cmos.layout
new file mode 100644
index 0000000..6f3cd18
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/cmos.layout
@@ -0,0 +1,80 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       2        hyper_threading
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/debug.c b/src/mainboard/supermicro/x6dhr_ig/debug.c
new file mode 100644
index 0000000..5546421
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/debug.c
@@ -0,0 +1,330 @@
+#define SMBUS_MEM_DEVICE_START 0x50
+#define SMBUS_MEM_DEVICE_END 0x57
+#define SMBUS_MEM_DEVICE_INC 1
+
+static void print_reg(unsigned char index)
+{
+        unsigned char data;
+                                                                                
+        outb(index, 0x2e);
+        data = inb(0x2f);
+	print_debug("0x");
+	print_debug_hex8(index);
+	print_debug(": 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+        return;
+}
+        
+static void xbus_en(void)
+{
+        /* select the XBUS function in the SIO */
+        outb(0x07, 0x2e);
+        outb(0x0f, 0x2f);
+        outb(0x30, 0x2e);
+        outb(0x01, 0x2f);
+	return;
+}
+                                                                        
+static void setup_func(unsigned char func)
+{
+        /* select the function in the SIO */
+        outb(0x07, 0x2e);
+        outb(func, 0x2f);
+        /* print out the regs */
+        print_reg(0x30);
+        print_reg(0x60);
+        print_reg(0x61);
+        print_reg(0x62);
+        print_reg(0x63);
+        print_reg(0x70);
+        print_reg(0x71);
+        print_reg(0x74);
+        print_reg(0x75);
+        return;
+}
+                                                                                
+static void siodump(void)
+{
+        int i;
+        unsigned char data;
+       
+	 print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
+        for (i=0x10; i<=0x2d; i++) {
+                print_reg((unsigned char)i);
+        }
+#if 0                                                                         
+        print_debug("\r\n*** XBUS REGISTERS ***\r\n");
+        setup_func(0x0f);
+        for (i=0xf0; i<=0xff; i++) {
+                print_reg((unsigned char)i);
+        }
+                                                                                
+        print_debug("\r\n***  SERIAL 1 CONFIG REGISTERS ***\r\n");
+        setup_func(0x03);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  SERIAL 2 CONFIG REGISTERS ***\r\n");
+        setup_func(0x02);
+        print_reg(0xf0);
+
+#endif
+        print_debug("\r\n***  GPIO REGISTERS ***\r\n");
+        setup_func(0x07);
+        for (i=0xf0; i<=0xf8; i++) {
+                print_reg((unsigned char)i);
+        }
+        print_debug("\r\n***  GPIO VALUES ***\r\n");
+        data = inb(0x68a);
+	print_debug("\r\nGPDO 4: 0x");
+	print_debug_hex8(data);
+        data = inb(0x68b);
+	print_debug("\r\nGPDI 4: 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+	
+#if 0                                                                                
+                                                                                
+        print_debug("\r\n***  WATCHDOG TIMER REGISTERS ***\r\n");
+        setup_func(0x0a);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  FAN CONTROL REGISTERS ***\r\n");
+        setup_func(0x09);
+        print_reg(0xf0);
+        print_reg(0xf1);
+
+        print_debug("\r\n***  RTC REGISTERS ***\r\n");
+        setup_func(0x10);
+        print_reg(0xf0);
+        print_reg(0xf1);
+        print_reg(0xf3);
+        print_reg(0xf6);
+        print_reg(0xf7);
+        print_reg(0xfe);
+        print_reg(0xff);
+                                                                                
+        print_debug("\r\n***  HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
+        setup_func(0x14);
+        print_reg(0xf0);
+#endif                                                                           
+        return;
+}
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_bar14(unsigned dev)
+{
+	int i;
+	unsigned long bar;
+	
+	print_debug("BAR 14 Dump\r\n");
+	
+	bar = pci_read_config32(dev, 0x14);
+	for(i = 0; i <= 0x300; i+=4) {
+#if 0		
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+#endif		
+		if((i%4)==0) {
+		print_debug("\r\n");
+		print_debug_hex16(i);
+		print_debug_char(' ');
+		}
+		print_debug_hex32(read32(bar + i));
+		print_debug_char(' ');
+	}
+	print_debug("\r\n");
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+#if 0
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+	}
+}
+#endif
+
+void dump_spd_registers(void)
+{
+        unsigned device;
+        device = SMBUS_MEM_DEVICE_START;
+        while(device <= SMBUS_MEM_DEVICE_END) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("dimm ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 256) ; i++) {
+	                unsigned char byte;
+                        if ((i % 16) == 0) {
+				print_debug("\r\n");
+				print_debug_hex8(i);
+				print_debug(": ");
+                        }
+			status = smbus_read_byte(device, i);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}
+
+void dump_ipmi_registers(void)
+{
+        unsigned device;
+        device = 0x42;
+        while(device <= 0x42) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("ipmi ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 8) ; i++) {
+	                unsigned char byte;
+			status = smbus_read_byte(device, 2);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}	
diff --git a/src/mainboard/supermicro/x6dhr_ig/failover.c b/src/mainboard/supermicro/x6dhr_ig/failover.c
new file mode 100644
index 0000000..5029d98
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/failover.c
@@ -0,0 +1,46 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "pc80/mc146818rtc_early.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* Did just the cpu reset? */
+	if (memory_initialized()) {
+	 	if (last_boot_normal()) {
+			goto normal_image;
+		} else {
+			goto cpu_reset;
+		}
+	}
+
+	/* This is the primary cpu how should I boot? */
+	else if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
diff --git a/src/mainboard/supermicro/x6dhr_ig/irq_tables.c b/src/mainboard/supermicro/x6dhr_ig/irq_tables.c
new file mode 100644
index 0000000..5ed51fe
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/irq_tables.c
@@ -0,0 +1,34 @@
+/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */
+
+#include <arch/pirq_routing.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+	0x52495024, /* u32 signature */
+	0x0100,     /* u16 version   */
+	272,        /* u16 Table size 32+(15*devices)  */
+	0x00,       /* u8 Bus 0 */
+	0xf8,       /* u8 Device 1, Function 0 */
+	0x0000,     /* u16 reserve IRQ for PCI */
+	0x8086,     /* u16 Vendor */
+	0x24d0,     /* Device ID */
+	0x00000000, /* u32 miniport_data */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0xc4,   /*  u8 checksum - mod 256 checksum must give zero */
+	{  /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  */
+	    {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06,  0x00},
+	    {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07,  0x00}
+	}
+};
diff --git a/src/mainboard/supermicro/x6dhr_ig/mainboard.c b/src/mainboard/supermicro/x6dhr_ig/mainboard.c
new file mode 100644
index 0000000..cae000d
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include "chip.h"
+
+struct chip_operations mainboard_supermicro_x6dhr_ig_ops = {
+	CHIP_NAME("Supermicro x6dhr-ig")
+};
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/microcode_updates.c b/src/mainboard/supermicro/x6dhr_ig/microcode_updates.c
new file mode 100644
index 0000000..b2e72ab
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/microcode_updates.c
@@ -0,0 +1,1563 @@
+/* WARNING - Intel has a new data structure that has variable length

+ * microcode update lengths.  They are encoded in int 8 and 9.  A

+ * dummy header of nulls must terminate the list.

+ */

+                                                                                

+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {

+        /*

+           Copyright  Intel Corporation, 1995, 96, 97, 98, 99, 2000.

+           These microcode updates are distributed for the sole purpose of

+           installation in the BIOS or Operating System of computer systems

+           which include an Intel P6 family microprocessor sold or distributed

+           to or by you.  You are authorized to copy and install this material

+           on such systems.  You are not authorized to use this material for

+           any other purpose.

+        */

+                                                                                

+        /*  M1DF3413.TXT - Noconoa D-0  */

+                                                                                

+        0x00000001, /* Header Version   */

+        0x00000013, /* Patch ID         */

+        0x07302004, /* DATE             */

+        0x00000f34, /* CPUID            */

+        0x95f183f0, /* Checksum         */

+        0x00000001, /* Loader Version   */

+        0x0000001d, /* Platform ID      */

+        0x000017d0, /* Data size        */

+        0x00001800, /* Total size       */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+ 

+	0x9fbf327a,

+	0x2b41b451,

+	0xb2abaca8,

+	0x6b62b8e0,

+	0x0af32c41,

+	0x12ca6048,

+	0x5bd55ae6,

+	0xb90dfc1d,

+	0x565fe2b2,

+	0x326b1718,

+	0x61f3a40d,

+	0xceb53db3,

+	0x14fb5261,

+	0xbb23b6c3,

+	0x9d7c0466,

+	0xde90a25e,

+	0x9450e9bb,

+	0x497bd6e4,

+	0x97d1041a,

+	0x1831013f,

+	0x6e6fa37e,

+	0x0b5c1d03,

+	0x5eae4db2,

+	0xc029d9e3,

+	0x5373bca3,

+	0xe15fccca,

+	0x39043db0,

+	0xaeb0ea0c,

+	0x62b4e391,

+	0x0b280c6b,

+	0x279eb9d3,

+	0x98d95ada,

+	0xc1cb45a7,

+	0x06917bda,

+	0xdde8aafa,

+	0xdff9d15c,

+	0xd07f8f0a,

+	0x192bcf9d,

+	0xf77de31f,

+	0xadf8be55,

+	0x3f7a5d95,

+	0x0e2140b6,

+	0xf0c75eec,

+	0x3254876a,

+	0x684a1698,

+	0x4ad0cca7,

+	0x6d705304,

+	0xf957d91b,

+	0xe8bb864a,

+	0x440d636c,

+	0xaf4d7d06,

+	0x12680ecf,

+	0x5d0f9e53,

+	0x60148a5d,

+	0x81008364,

+	0x243a8aed,

+	0xd55976de,

+	0xd6a84520,

+	0x932d4b77,

+	0xe67e5f19,

+	0x7dba0e47,

+	0xfee3b153,

+	0x46b6a20c,

+	0x2594e6f6,

+	0x210cab0f,

+	0xf6e47d5d,

+	0xe38276e4,

+	0x90fc2728,

+	0x9faefa11,

+	0xc972217c,

+	0xc8d079dd,

+	0x5f7dc338,

+	0x106f7b7b,

+	0xd04c0a1c,

+	0x0eca300e,

+	0x1ddae8a6,

+	0x6e7fd42e,

+	0xa56c514d,

+	0x56a4e255,

+	0x975ea2bf,

+	0x0eaa78cc,

+	0x0c3e284f,

+	0xbacb6c71,

+	0x1645006f,

+	0xe9a2b955,

+	0x0677c019,

+	0x24b33da0,

+	0x62f200fa,

+	0x234238c4,

+	0x81d5ad79,

+	0x9f754bc9,

+	0xeffd5016,

+	0x041b2cc2,

+	0x2f020bc7,

+	0x4fcd68b8,

+	0x22c3579c,

+	0x4804a114,

+	0xc42db3ea,

+	0x7cde8141,

+	0x47e167c8,

+	0x01aa38cc,

+	0x74a5c25e,

+	0xe0c48d67,

+	0x562365ad,

+	0x38321e57,

+	0x0395885a,

+	0x6888323e,

+	0xd6fc518f,

+	0x1854b64c,

+	0x06a58476,

+	0x3662f898,

+	0xe2bcdaee,

+	0x84c40693,

+	0xef09d374,

+	0x353cc799,

+	0x742223d4,

+	0x05b3c99b,

+	0x0c51ee45,

+	0xd145824a,

+	0xac30806c,

+	0x2ed70c0d,

+	0x71ae10ff,

+	0xbf491854,

+	0x3e1f03b4,

+	0x76bfd6cd,

+	0x1449aa8a,

+	0xf954d3fb,

+	0xf8c7c940,

+	0x70233f85,

+	0x0729e257,

+	0x10bb8936,

+	0xc35bb5b5,

+	0x95d78b5c,

+	0xcc1ba443,

+	0x6f507126,

+	0xa607cfd0,

+	0xce22f2f3,

+	0x5134ed8c,

+	0xec8d2f06,

+	0xa92413d5,

+	0xb973f431,

+	0x16e136dd,

+	0xf7d41bed,

+	0x01b002fe,

+	0x646ed771,

+	0x76ea3d26,

+	0x5024af20,

+	0x84270f51,

+	0x9b3d7820,

+	0x2454a2c6,

+	0xc1f072ed,

+	0x155e864f,

+	0x4c39a6e5,

+	0x928206e5,

+	0x9d1685f5,

+	0x45542ee7,

+	0x1fd27d9e,

+	0x5f2dd9ff,

+	0x222005eb,

+	0x354e8a55,

+	0x1f0de29a,

+	0xb86dc696,

+	0x9eafafad,

+	0x191b197e,

+	0x0e0900e1,

+	0xe0ac42bb,

+	0x3143236f,

+	0x44177def,

+	0x05259274,

+	0xb21af44a,

+	0x6ddee4df,

+	0xc7b56255,

+	0xb6b1d39d,

+	0x218f9070,

+	0x96545a42,

+	0x98cc2d4a,

+	0xb21bac9e,

+	0x83e12d44,

+	0x2ef4fb39,

+	0xbc03528f,

+	0x9485af58,

+	0xd9f1e6ab,

+	0xde7607e6,

+	0x3b398733,

+	0x9cd9b1a9,

+	0xabd77984,

+	0xcce18826,

+	0x701c5c21,

+	0xe6591cbf,

+	0x07a9b9e1,

+	0x69459c90,

+	0xe0cdcad6,

+	0xc4c6c4b6,

+	0x12748024,

+	0x4a33c567,

+	0x7d26a37e,

+	0xcae163bf,

+	0xeb7547fa,

+	0xccc6a01c,

+	0x3cb8abb8,

+	0x64aa67b2,

+	0x51ddf6de,

+	0xbfe1b905,

+	0x50923949,

+	0xacfa43af,

+	0x1fdb5a44,

+	0x091533cb,

+	0x7c92e5dc,

+	0x1c5d0d3e,

+	0x195271f5,

+	0x96e73a4a,

+	0xe1b11968,

+	0xb42906f2,

+	0x5a2940b3,

+	0x611283e9,

+	0x65829161,

+	0x5d1357b7,

+	0x019428ad,

+	0x836c5c3c,

+	0xc0e5e169,

+	0xd360e424,

+	0x257a9d69,

+	0xdca09040,

+	0x85f1c060,

+	0xae7cae79,

+	0xa5ddcfd6,

+	0xdba8f68e,

+	0xd98df596,

+	0xe6e3cd51,

+	0xcfb2be8f,

+	0x368fe6cd,

+	0x58486b75,

+	0x791f1a48,

+	0xf81a61f2,

+	0x58a38155,

+	0x30a86547,

+	0xd7fb2db1,

+	0x300e0b1d,

+	0x3f838461,

+	0xf278805a,

+	0x49529931,

+	0x601d5649,

+	0xe500ba1a,

+	0xc4f78965,

+	0xe10ed02d,

+	0x1f777ebd,

+	0x2db1d17d,

+	0x48a22e6a,

+	0x5a14b738,

+	0xdcf899e0,

+	0xc845bd04,

+	0xd04a52b9,

+	0xf2f19b06,

+	0xdb5ba97a,

+	0xf05605ff,

+	0xc787b72c,

+	0x9f197770,

+	0x87b31150,

+	0x3ff00d57,

+	0x89d1dcb3,

+	0x07528ff4,

+	0x4105fcef,

+	0xb087de2e,

+	0x3bd333a5,

+	0x84a094f4,

+	0x9ab8fb97,

+	0xc9bba063,

+	0x664c52e5,

+	0x27fd05e4,

+	0x3f0e491d,

+	0xab8f4b9a,

+	0x344a0249,

+	0x727dd74f,

+	0x29587211,

+	0xbba262b9,

+	0x319ecbb3,

+	0xec54b023,

+	0xd0fa096d,

+	0x3d223f23,

+	0x0b6013e7,

+	0x513e045b,

+	0xcb1edf15,

+	0xfd44bb25,

+	0x023eb973,

+	0x3f55dac6,

+	0xc2df6514,

+	0x68589880,

+	0x4556878e,

+	0x86f6acfb,

+	0xbcd23f0b,

+	0x32c417c1,

+	0x45f3bb56,

+	0xbe60872b,

+	0x09457cc0,

+	0x2e18b62d,

+	0x065f54d1,

+	0xae3b4a20,

+	0x265b10ae,

+	0xb7547a1d,

+	0x5a9481a9,

+	0xd477ed02,

+	0x601ed0fc,

+	0x9a43257e,

+	0xc9922b72,

+	0xa2a696ae,

+	0xe9d6c37b,

+	0xfab8bdf9,

+	0x1deb34dc,

+	0xaa6bb090,

+	0xbdc3b72f,

+	0xecb3b010,

+	0xe64376e7,

+	0x40356095,

+	0x928b5047,

+	0xbd271c09,

+	0xfd806f61,

+	0x0821e090,

+	0x6afb3588,

+	0xd10e91ea,

+	0xbbc7fedd,

+	0xb1ac6d33,

+	0x07788e4b,

+	0xa10f8013,

+	0x4f8efd9d,

+	0xe5d8728d,

+	0x017f3e82,

+	0xf09ec7eb,

+	0x6bfd7906,

+	0xbcefcb44,

+	0x76699ad5,

+	0x1b976522,

+	0xa55b3dbd,

+	0x88bb33e2,

+	0x98ac5b7f,

+	0x61ac4c8b,

+	0xfd948f3d,

+	0xee610413,

+	0xc77c5035,

+	0x662825a9,

+	0x0009fcba,

+	0x3450fd88,

+	0xeb391fef,

+	0x6949960d,

+	0x1ccb13c3,

+	0x21dac5a6,

+	0x6bcc6b37,

+	0x37ad77a5,

+	0xf71d58b1,

+	0x84ed440d,

+	0xe606b699,

+	0xe43067a4,

+	0x21d5b8b3,

+	0xe11f83e2,

+	0xa0cc6585,

+	0x40eb6d16,

+	0xc5a6879f,

+	0xbd333fd5,

+	0xb44acab4,

+	0x68c016fc,

+	0xfbcd3cfc,

+	0xadf76e42,

+	0xc520e516,

+	0x7468cb61,

+	0x585c0d52,

+	0xea83cefe,

+	0x615d7760,

+	0x89c9b8fd,

+	0x367c355a,

+	0x409371a2,

+	0x7edb38a7,

+	0xca86d263,

+	0xda18250d,

+	0x26e1ed8b,

+	0x02fefede,

+	0x704cb5c8,

+	0x52cbe1eb,

+	0x9cdbc71a,

+	0xa0637560,

+	0xe31f03ca,

+	0x2b78969b,

+	0x803d5866,

+	0xec52d984,

+	0xd8df8bdb,

+	0x6cb1d5e8,

+	0x7b9aec01,

+	0xf7d39401,

+	0xdd04c6ae,

+	0x0e5ca4eb,

+	0x12b593c8,

+	0x38f6d4e5,

+	0x13a91268,

+	0x60c8251b,

+	0xa136cf9a,

+	0xda070cdd,

+	0x6142408c,

+	0xc28065dd,

+	0x50b73718,

+	0x36074eee,

+	0xc7b20fcb,

+	0x18d29f9b,

+	0xe97eb966,

+	0xe6936bcc,

+	0x1c9188ea,

+	0x7cff40e2,

+	0xee791ac8,

+	0xb099a323,

+	0x571d69b7,

+	0x22c1f7d0,

+	0x0b9662ee,

+	0x76e45cb9,

+	0xbd0d7020,

+	0x7794bd95,

+	0x1b0fe51a,

+	0xda2754ef,

+	0x7f3ad7a9,

+	0x58f627d3,

+	0x211670a3,

+	0xc7471b81,

+	0x495a93ac,

+	0xaad4f030,

+	0xa76614c8,

+	0xd63dba3c,

+	0x9c4f729c,

+	0x6e831cfb,

+	0xa6105c75,

+	0x95c62188,

+	0x723ef45d,

+	0xf59f2dd1,

+	0x5825283d,

+	0x768d8a86,

+	0x070d02ac,

+	0xfdbcbd73,

+	0x0d479795,

+	0x797aa7f7,

+	0x6c9e468b,

+	0xa961571d,

+	0xc7127ef0,

+	0x4b0442e7,

+	0xd99a9e87,

+	0x6c876cba,

+	0xe4f9f814,

+	0x120eeb8d,

+	0x4bbb9c8e,

+	0x22c0a29e,

+	0xff681fcc,

+	0x26777226,

+	0x6339e667,

+	0x2402333e,

+	0x2bf66a17,

+	0x63806e6c,

+	0x98416b75,

+	0x791b3e91,

+	0x79c09cd7,

+	0x0c157436,

+	0x6d99157c,

+	0xc8990984,

+	0xaf7d2ae4,

+	0xfe3ee7d9,

+	0xb7676de0,

+	0x9df8722e,

+	0x08462a7e,

+	0x99032839,

+	0xd726ff95,

+	0x5c1c78e8,

+	0x4ef1b747,

+	0x4e257ba7,

+	0xa83ad5f3,

+	0x523b3809,

+	0xc2ce4f19,

+	0xabfadaa5,

+	0x370b005c,

+	0x2d6a02e1,

+	0xbf6ee428,

+	0xfd84be50,

+	0xb79801b3,

+	0x488ad789,

+	0x65a87bda,

+	0x59f0fd6a,

+	0xa4106878,

+	0xdbadd916,

+	0x1f86f200,

+	0xefb7fc72,

+	0x26d4d47f,

+	0xf7892efc,

+	0x41f50167,

+	0xc6a28f9e,

+	0xffd4a8e0,

+	0xa00e4ea0,

+	0x8183f648,

+	0x030faa4c,

+	0x26c1715f,

+	0x322c9ea3,

+	0x5d60d054,

+	0x413470cb,

+	0x3d131892,

+	0x22f2ae86,

+	0x9f1c96b6,

+	0x015563f4,

+	0x3a5625ba,

+	0xcb95b598,

+	0xf0685fb9,

+	0x158af5ec,

+	0xfc01a406,

+	0x01841d19,

+	0x210b7e73,

+	0x19a416a1,

+	0xed254c44,

+	0x5bd51335,

+	0xb8905dc9,

+	0x9e52f38c,

+	0xef5d7dd0,

+	0x1516f6bb,

+	0xf13bb426,

+	0x9ee6d6cb,

+	0x28bde0a6,

+	0x766b655e,

+	0xaf2e0e52,

+	0xdec60f49,

+	0x254a0959,

+	0xb009d431,

+	0x2f6d3533,

+	0x0a074afc,

+	0xcd3d3a72,

+	0x52aa4fce,

+	0x16c4507d,

+	0x2f842898,

+	0xb087e98b,

+	0x68b41826,

+	0xd4adc5c9,

+	0x53b3e498,

+	0x2dff7b03,

+	0xda931e65,

+	0xf1d66edd,

+	0x2beb7555,

+	0x97b3f152,

+	0x035676f8,

+	0xca9c7cf6,

+	0x57992a53,

+	0x578a1004,

+	0x458e23c8,

+	0x2a2494bf,

+	0xa92c549b,

+	0x2ca46deb,

+	0xcd907478,

+	0x93baaeb5,

+	0xa70af4c6,

+	0x9767d5b8,

+	0x9874bcee,

+	0xb0413973,

+	0x9bfef4f7,

+	0x7fbed607,

+	0x2a255991,

+	0xa5e3109d,

+	0x90f09fef,

+	0xb7a3d468,

+	0x6db437aa,

+	0xe8dad585,

+	0xfbc19cbc,

+	0x34cacc6f,

+	0x6c5cc449,

+	0xcc6dc144,

+	0x70c6aaa0,

+	0x183bc459,

+	0x490ea5a8,

+	0xddf105bf,

+	0x3429facf,

+	0x79020f72,

+	0xd2de786d,

+	0xb776f3ed,

+	0x553e3da7,

+	0xaecff099,

+	0x2b471ce1,

+	0xe3a72af9,

+	0x04c9b2bf,

+	0xe84d9702,

+	0xec7cd831,

+	0xda66c6c1,

+	0x451b207c,

+	0x68243bc3,

+	0xb3012b1e,

+	0x1855c026,

+	0x1addac14,

+	0xc73834a2,

+	0xea91596d,

+	0x08f0d135,

+	0xc6021aa0,

+	0xc5d1726b,

+	0xc21d1f0b,

+	0x92b7c740,

+	0x9f024526,

+	0x6c91df6c,

+	0xfec85435,

+	0x3d5a9150,

+	0x93249836,

+	0x2ec5e71f,

+	0x23e96579,

+	0x81ce78d6,

+	0x49e45ccf,

+	0x4d5e9c78,

+	0x2a2cdfab,

+	0x148e1833,

+	0xa3fab11b,

+	0xd0ceb7e9,

+	0x4789b634,

+	0x147fc687,

+	0x48f4f59c,

+	0x21eea4e3,

+	0x411dfb7d,

+	0x033fe075,

+	0x57c9e07d,

+	0xb09edf4e,

+	0x9db83f5f,

+	0x6ef1343a,

+	0x64a68315,

+	0x300e34c3,

+	0x72ac2766,

+	0x640271a4,

+	0x0a282b82,

+	0xcaf1ec1b,

+	0x7d4849f9,

+	0x108c5eaa,

+	0xfaa96613,

+	0x0476639b,

+	0x70ee8371,

+	0x9db599ba,

+	0x85158d5f,

+	0x02912911,

+	0xe6fec86a,

+	0xcf3036f3,

+	0xccdd49a0,

+	0xe650b3cd,

+	0xf5429ef0,

+	0x411e4690,

+	0xa526e30b,

+	0x275822af,

+	0x91e12d05,

+	0x958881aa,

+	0xabf76cc4,

+	0x06e794a9,

+	0xa97d1577,

+	0x0188613c,

+	0x17c96558,

+	0x96c31832,

+	0x5696b201,

+	0x03e3dad2,

+	0xbe44d0ba,

+	0x4d552a6c,

+	0xe9fafb48,

+	0x4968ad28,

+	0xf109edce,

+	0xd1534f30,

+	0xc2d8b9e8,

+	0x66e911d7,

+	0xd67a594b,

+	0x4492b2b4,

+	0xeb86848d,

+	0x4106979b,

+	0x0f75039f,

+	0xf5f3ee2c,

+	0x04baf613,

+	0x00c6fd60,

+	0x32ebe198,

+	0xc7f129eb,

+	0x7cac0839,

+	0x57a1fde4,

+	0x2da04cfc,

+	0x93179aa5,

+	0xf3f4d2d9,

+	0xd8d2528a,

+	0x5fdd42af,

+	0xd08c7bdb,

+	0x53acd639,

+	0xe37aab85,

+	0x2d55b5a2,

+	0x7bc96248,

+	0x2fb42401,

+	0x2ff99915,

+	0x2be3b5ea,

+	0xf0ff9bdd,

+	0x1b6bbaa3,

+	0x83a13de0,

+	0x4503fc83,

+	0x08c24640,

+	0x2463a2b2,

+	0x2e264872,

+	0xc451a29d,

+	0xbfd2e09c,

+	0x15bcb009,

+	0x69102223,

+	0x4c8581e9,

+	0x4ec94cf0,

+	0x75017d7b,

+	0x0e5d8cf1,

+	0x50b9ca97,

+	0x55df1100,

+	0x245162e0,

+	0x0df18bca,

+	0x00776990,

+	0xf6790a03,

+	0x599ef43e,

+	0xe8bf7afb,

+	0xea141ddc,

+	0xad1a54b2,

+	0x55f767f8,

+	0xb661981c,

+	0xe1650342,

+	0x365adc95,

+	0xbb44e3a0,

+	0xa064fea1,

+	0x3516bf27,

+	0xfd40a414,

+	0x53f9a9e6,

+	0x2071a5ee,

+	0x56ca2713,

+	0x7afdd07a,

+	0xd62b7f6e,

+	0xe9dac904,

+	0xca212105,

+	0xb9d6e3de,

+	0x6af5033f,

+	0x34d9049b,

+	0xc51ec095,

+	0xe5eddb9d,

+	0x122b5c6a,

+	0x9f562e58,

+	0x20ec8986,

+	0x760857f2,

+	0x8d8aadb3,

+	0xbc8f0807,

+	0x0f79eae7,

+	0xbfa6bfa8,

+	0x28151aeb,

+	0xbe4b4d4b,

+	0xc65d58b0,

+	0xcf99ba1b,

+	0xc1049197,

+	0xe36d8c87,

+	0x548b7676,

+	0xbe7bb2c4,

+	0x77923781,

+	0x5fbd631e,

+	0x770e5a41,

+	0xd2f2948a,

+	0x074f5428,

+	0xc7a1562e,

+	0xf55618c6,

+	0x8bf8a3d1,

+	0x837ed4a8,

+	0xe42e0298,

+	0xd3754b0c,

+	0xbaa24c25,

+	0x793ac973,

+	0x814e66ec,

+	0xa4154fa9,

+	0x3e0e65ca,

+	0x5a783bd5,

+	0x2bb37f6c,

+	0xb3c2526e,

+	0x34c9a28a,

+	0x6c8b4795,

+	0x64605fa8,

+	0x2e6aae2e,

+	0xd9b28f27,

+	0x6a9a200b,

+	0x3acd1e3a,

+	0xce9a4a6c,

+	0xd2a0bd14,

+	0x700f2003,

+	0x501cbef7,

+	0x4068b05e,

+	0xa24c4580,

+	0x4da75506,

+	0x500b9b0f,

+	0x22e3a600,

+	0x7bec4e94,

+	0x8f0958e2,

+	0x42129a1e,

+	0xb46d8dc5,

+	0x29f8851c,

+	0x83fb38bd,

+	0x17b0de15,

+	0x15340d20,

+	0x74f00fde,

+	0x6c646b32,

+	0x905897c4,

+	0x4d8ed991,

+	0x3cf91fd5,

+	0x0ee02ddf,

+	0xec069ce6,

+	0x0b977683,

+	0xa0bf31f6,

+	0xa1d135a9,

+	0xa882d1db,

+	0xa731a63a,

+	0x48e211f1,

+	0xf3d89e99,

+	0xf982e6ea,

+	0x23dde303,

+	0x7f1ff8da,

+	0xdc8c6414,

+	0x806f432e,

+	0xd047bc02,

+	0x671bacff,

+	0xd40ba2a8,

+	0xe3666685,

+	0x31265f9f,

+	0x3931a952,

+	0x62f35606,

+	0xc48f0c5e,

+	0xfd107640,

+	0xf636da24,

+	0xb8f5c3b0,

+	0x1c91e88f,

+	0xed9dd432,

+	0x2b85fa5d,

+	0x8b15d2ac,

+	0x1e06cf24,

+	0x1def6e9c,

+	0xfae9175f,

+	0x03ac6f02,

+	0x37318c87,

+	0xbc0b1ce5,

+	0xa0640cab,

+	0x6cc20a3c,

+	0x1c7b2524,

+	0x4685dacc,

+	0xeab8bb31,

+	0x8063b5d0,

+	0x79817d52,

+	0x211b1972,

+	0xd7bfc987,

+	0xab9128dc,

+	0x150d9b36,

+	0x6a5838ab,

+	0x9a0a304d,

+	0x2e43c331,

+	0x84f2c4b8,

+	0x435146c1,

+	0xed64a280,

+	0x553ecb4c,

+	0x5c800db2,

+	0xeef4df95,

+	0x5dcf2c37,

+	0x70755ddf,

+	0x4274737b,

+	0xe610350e,

+	0xd97a5997,

+	0x7af5edce,

+	0xfd18ba0c,

+	0xb7587cd8,

+	0xfa5e42d6,

+	0x76bde9eb,

+	0xec41eead,

+	0x604d2423,

+	0xb4adbcf9,

+	0xce728fa3,

+	0x02361c31,

+	0x02fab64d,

+	0x00316b1c,

+	0x562f9aa4,

+	0x71f85790,

+	0x9cb6d464,

+	0x32949ebf,

+	0x434fc23d,

+	0xee7fac51,

+	0xda5cc63a,

+	0x17e616b4,

+	0xcd1bd1bc,

+	0x14638cae,

+	0xd31808fa,

+	0xb16e0727,

+	0xfdda2b0f,

+	0xbc11c678,

+	0xfe79dc6e,

+	0xe26eefb4,

+	0x9a78de16,

+	0xb68f2df2,

+	0xd47da234,

+	0xbdff28a4,

+	0x937bb1f4,

+	0x0786dd46,

+	0xbd1160f5,

+	0xf77b070c,

+	0x72b7c51e,

+	0xcbb3a371,

+	0x5e50e904,

+	0x00fbc379,

+	0x680757dd,

+	0xd38193f7,

+	0x93113e25,

+	0x7b258da7,

+	0x991aaa09,

+	0xab1415be,

+	0xa3740774,

+	0x370b72e5,

+	0x2fc643f4,

+	0x3916d70e,

+	0xea2838d3,

+	0xe4840c42,

+	0xd18e6959,

+	0x69a270ee,

+	0xee4a494e,

+	0x0329799b,

+	0x07480357,

+	0x0260c46f,

+	0x7b75346e,

+	0x787234f4,

+	0xe0adf25b,

+	0xba85cacf,

+	0xb5724eb1,

+	0xfde2c080,

+	0x2b6bb492,

+	0xd2f70545,

+	0x9ca97510,

+	0x4034c18f,

+	0x616bcb12,

+	0x5667f52a,

+	0xe2f6bfce,

+	0x1f25969e,

+	0x569eaab7,

+	0x27ad8196,

+	0x2d30a6d0,

+	0x96d6c10a,

+	0xcb9f024f,

+	0x3d7941ef,

+	0xf7a76bc5,

+	0xe9a701d4,

+	0xd53293a3,

+	0x252cf5df,

+	0xaf9172f6,

+	0xd090c809,

+	0xb1a17387,

+	0x045a0987,

+	0x92d9ffd9,

+	0xb30c449c,

+	0x2180ff58,

+	0x2929f7de,

+	0x3f91766e,

+	0x9f488e3d,

+	0x05dd6734,

+	0x82482f5b,

+	0x01da3ca2,

+	0x42f33408,

+	0xf8e3ba89,

+	0x750ac2ff,

+	0x39f11551,

+	0x71087971,

+	0x368fa634,

+	0xefda0572,

+	0x14b8f750,

+	0xe5768705,

+	0x71c168e2,

+	0x8c012c63,

+	0x12ad74ce,

+	0x841c17ea,

+	0xe6f44176,

+	0x36cf2557,

+	0x14760a6d,

+	0x4bb3b7c2,

+	0x14d1437d,

+	0xbe673210,

+	0x4d6ba9f5,

+	0xe68abbf9,

+	0xc311908d,

+	0x46b63956,

+	0xac2c9fb3,

+	0xab769ce8,

+	0xa29d7040,

+	0xec3d67e3,

+	0xdef311de,

+	0x52a53b14,

+	0xca924769,

+	0xf35d1514,

+	0x524b0471,

+	0xc0d08591,

+	0x454fc34c,

+	0xca719639,

+	0x9af2f230,

+	0xa023a821,

+	0x3d6539ba,

+	0x90d0d7a2,

+	0xc65fc56e,

+	0x4eb2aa19,

+	0xeba3b0e7,

+	0x1bb5b33e,

+	0xab8c68c2,

+	0x0f1793d3,

+	0xdcf176e9,

+	0x1b7bbba0,

+	0x96170a27,

+	0x1955452d,

+	0x42e88c71,

+	0x48cad4b3,

+	0xdcc36042,

+	0x90619951,

+	0x7566bc7c,

+	0xe14ba224,

+	0xc24ad73d,

+	0xdb04144d,

+	0xd9792727,

+	0x11150943,

+	0xe45f0c57,

+	0xb87d184e,

+	0x3cf13243,

+	0x2010d95c,

+	0x84c347c1,

+	0x6d0f2461,

+	0xb5c41194,

+	0xde7ccb2e,

+	0xb929ecb0,

+	0x51fbd8f7,

+	0x45dc65fb,

+	0x6902d2c0,

+	0xb940814f,

+	0xf339e083,

+	0x6f370d56,

+	0xcaf5638e,

+	0xe8a3cb83,

+	0xacf414b6,

+	0xe61095a1,

+	0x99b4cde4,

+	0x55112fed,

+	0x606b9d53,

+	0x5a05974a,

+	0xa4c7db34,

+	0xdc92469b,

+	0xf9280621,

+	0xe7b1ef95,

+	0xc0fc5be8,

+	0x74a1da09,

+	0xa92a4b7f,

+	0x3d65d75e,

+	0xe3804335,

+	0x1ff49e19,

+	0x71da8170,

+	0xac69069b,

+	0x04aae3d5,

+	0xc0ef4b46,

+	0x091a3482,

+	0x8356c7ae,

+	0x32ecb208,

+	0x900c89ed,

+	0x2a206ff5,

+	0x7eed5032,

+	0x5b55b25d,

+	0xf98d6df2,

+	0xf52bc8a9,

+	0x1aa2f5fe,

+	0x1d33c0bf,

+	0x3cd34e89,

+	0x9a0da4ae,

+	0x1c205917,

+	0x7ca784cd,

+	0xf7dda662,

+	0xad97f3ff,

+	0x525c53ec,

+	0x024f11ff,

+	0x32c3ae5b,

+	0xbf372800,

+	0x8ff15f4d,

+	0x7605d019,

+	0x0dae7740,

+	0x5f5dd0ef,

+	0x0f6c37d0,

+	0xee6fa91e,

+	0xb9f51051,

+	0x39a9f0d1,

+	0x22bf03fb,

+	0x485a0922,

+	0x7384b30e,

+	0x85ba7f16,

+	0xb1f0a524,

+	0x7e9c5113,

+	0x240d9306,

+	0x1ca7b0ea,

+	0x18a0d114,

+	0x76b64213,

+	0x31212cc0,

+	0xc9dca5c3,

+	0x69f2ae52,

+	0x545caa7c,

+	0xfb2ff045,

+	0x3f3a1af5,

+	0xe75b6913,

+	0x775a1c79,

+	0x4627e25f,

+	0x90a14b97,

+	0x06456383,

+	0x3d52cf69,

+	0xfb2492c3,

+	0x39f25a22,

+	0x81f68c55,

+	0x87b14e15,

+	0x0920af5d,

+	0xe2585678,

+	0x0671e46d,

+	0xb77ddb67,

+	0x3948c4b3,

+	0x122dddef,

+	0xd0726172,

+	0xd3302234,

+	0x58bab4e4,

+	0x195ac247,

+	0x082459f0,

+	0x18a2566d,

+	0xbf56078d,

+	0x116ed409,

+	0x5ccc0f80,

+	0xbae0b4ca,

+	0x21a6325d,

+	0x7e1f0c40,

+	0x595326d4,

+	0x518b2244,

+	0x8ab3cdb7,

+	0xbe6b4835,

+	0xfc39f8ac,

+	0x63b167aa,

+	0x194f070d,

+	0xed3d0416,

+	0xae16758a,

+	0xb9bb6bbf,

+	0x477d9c85,

+	0x9808c304,

+	0xe1d8cec4,

+	0x7ee22e17,

+	0x0a7a9d7f,

+	0xcc98173a,

+	0x5f78dc21,

+	0x364bc95e,

+	0xb54608d9,

+	0x5d4d70ea,

+	0x083a7f79,

+	0x59ffbd73,

+	0x4f3e9eaf,

+	0x68755ad4,

+	0xab254689,

+	0x11bf09a8,

+	0xbbc40098,

+	0x969ca3eb,

+	0x30eee9d2,

+	0xe35bc37e,

+	0xcb2d678f,

+	0x7846876b,

+	0xf0d28ae7,

+	0xc092fbb2,

+	0x321b344a,

+	0xcc5ee81b,

+	0xd2afa00f,

+	0xfeccd86a,

+	0x6e5e55c2,

+	0x2b5543ea,

+	0x810e4009,

+	0xea2d8e20,

+	0x6acae3b9,

+	0x3828e15e,

+	0xe1e4821c,

+	0xf429da70,

+	0x35f6565c,

+	0x64b1baa8,

+	0x350e9583,

+	0xd2522d4f,

+	0x5e28a3f1,

+	0x949ff0aa,

+	0x3c1b5694,

+	0x146dde1f,

+	0x6f3430e1,

+	0x71c077b7,

+	0x4d145924,

+	0xe431cd28,

+	0xb315cfde,

+	0xa0365a4a,

+	0x473de1aa,

+	0xcbe4e999,

+	0x319906e9,

+	0xad0fea9c,

+	0x89e4e72d,

+	0x9dbba94d,

+	0xd395c1c5,

+	0xa1fff11a,

+	0x8447e120,

+	0xe5c59100,

+	0xa07cb778,

+	0x8f30a039,

+	0xed78facb,

+	0x86de9373,

+	0x550c4889,

+	0xce71e3a8,

+	0x06167b3a,

+	0x5abdd9a3,

+	0xc8a9e48d,

+	0xe3312905,

+	0x7a63a146,

+	0xc0f19763,

+	0xda0cf9db,

+	0x1d708306,

+	0x0e41f0ba,

+	0x4c7939fe,

+	0x768e48c2,

+	0xe925fd31,

+	0x309e7870,

+	0xfc261b87,

+	0xc897b2de,

+	0x6c714792,

+	0x41c7fbac,

+	0x57d0b3c3,

+	0x4fa82a55,

+	0xd56b4a87,

+	0x81e5cabc,

+	0xb260cb7b,

+	0x520927ab,

+	0x20d0ab46,

+	0xc9f92ddf,

+	0x81f4a21d,

+	0xfc5a0ca2,

+	0x95d16aad,

+	0xe54d7847,

+	0x6080cc07,

+	0x0df73f7e,

+	0xaa8d5187,

+	0x97a0bc12,

+	0xb22c5e68,

+	0x0954d7dc,

+	0x3368ab5a,

+	0xd12541df,

+	0x58119260,

+	0xe5b0e1df,

+	0x25027fa4,

+	0x5780425d,

+	0x29bb8791,

+	0x4100b7a9,

+	0x076b3519,

+	0x15e0ebb4,

+	0xe5fb9273,

+	0x6dbf07e7,

+	0x1f82bddd,

+	0x03691b6b,

+	0xbacef28c,

+	0x9909ed5a,

+	0x98886793,

+	0x544f9a82,

+	0x9d9749d0,

+	0x38441606,

+	0xc4a9f4d2,

+	0x6ce2bcf1,

+	0x1c7c3abd,

+	0x62c621f1,

+	0x871ee1e4,

+	0xa83930ce,

+	0xbe1ee459,

+	0xd61f1ca4,

+	0x8c4450e5,

+	0x98031ca9,

+	0xe52f54e2,

+	0xd0c4c737,

+	0x76074160,

+	0xbf050c3b,

+	0x2603af14,

+	0x43cbb0bc,

+	0xc631b9e8,

+	0x26030719,

+	0x993f570c,

+	0xdda34038,

+	0xe34a9793,

+	0x337a124c,

+	0x2aa8af16,

+	0xf80d7473,

+	0xf01d9397,

+	0x68e1afb9,

+	0x0eb37ad2,

+	0xf71969f9,

+	0xdf020552,

+	0x75aa9b30,

+	0xffa210cf,

+	0x543c414f,

+	0xa1e3faec,

+	0x40891d7e,

+	0x6b48a6c5,

+	0xec09a1a0,

+	0x97a31f2a,

+	0x5a6be2d7,

+	0xd06e492b,

+	0xc54290af,

+	0xcb524021,

+	0x420e8c4d,

+	0xfb135c17,

+	0x2bfc8adb,

+	0x9f0cfb46,

+	0x564db712,

+	0x7a97a227,

+	0x8bb98daf,

+	0xdd0d6180,

+	0x3d28b9e3,

+	0xe505050f,

+	0x19a9868e,

+	0x7bf5685f,

+	0x35d698c4,

+	0xce7e1de3,

+	0x360a64af,

+	0x25a1f022,

+	0xe26c1d04,

+	0x5b3fb364,

+	0x932f25f7,

+	0x9a2aa00d,

+	0xc50fb773,

+	0xec45ea3a,

+	0x22ddf8e4,

+	0xafb6a6c8,

+	0x876d04f7,

+	0xd9c86c3c,

+	0xd54bee2d,

+	0xf4e28199,

+	0xc3456776,

+	0x04c3107b,

+	0xbf914e9d,

+	0x23fefaa5,

+	0x0931a133,

+	0x41467758,

+	0x8ec49707,

+	0x5ed48709,

+	0xd11c2de8,

+	0xb687a0b9,

+	0xdc908383,

+	0xd8037ff3,

+	0xd4311a9f,

+	0xd00aeb6a,

+	0xfe54df3b,

+	0x9c51ce4d,

+	0x36956408,

+	0xcd28ef09,

+	0xc68932b0,

+	0x7c31e782,

+	0x28b4723c,

+	0xededacc2,

+	0x6ddbac6b,

+	0x775a7fc1,

+	0x6909906f,

+	0xa774123c,

+	0xf63145ad,

+	0x287b191e,

+	0x59d79300,

+	0xbf76a2fc,

+	0xfbaf9207,

+	0x2fe5b7f6,

+	0xebe7c103,

+	0x71ac0a8d,

+	0x2028c3c7,

+	0xd2cb4917,

+	0xd74a4ee4,

+	0xfce405d8,

+	0xad83fd0f,

+	0x8f9ec3da,

+	0xaab2301c,

+	0xc6f1339f,

+	0xc652bced,

+	0xe378b272,

+	0x18e1ff34,

+	0x9ec778b6,

+	0xce1a3883,

+	0x7c5e5eaf,

+	0xd16ec37a,

+	0xa69e45f4,

+	0xc36cd4aa,

+	0x045b391f,

+	0x5a2a08f1,

+	0x4dd8d53e,

+	0xd64796ec,

+	0x4476fc28,

+	0x18dbaa50,

+	0x00fb2407,

+	0x177db915,

+	0x5969758b,

+	0x3030964a,

+	0x81d6485b,

+	0x7d2e12b0,

+	0x624d6c5f,

+	0x0746bbc0,

+	0xe669d150,

+	0x0465eef7,

+	0x09764011,

+	0x551995e4,

+	0x8422dedf,

+	0x0ca56194,

+	0x293eab2e,

+	0xf20a137a,

+	0x55117fc2,

+	0xbc5431af,

+	0x064751fa,

+	0xc0dafdb2,

+	0x6c3b1d4f,

+	0xeac335b3,

+	0x71173afc,

+	0x31c84b7c,

+	0xfef2b4ab,

+	0x59ca5fa2,

+	0x664c8b4e,

+	0x7dfd560b,

+	0xdb0daff3,

+	0x51f87bfa,

+	0x58015d2e,

+	0x67a827b4,

+	0x62cebc1a,

+	0x24b37298,

+	0x75b589be,

+	0x874f1800,

+	0x277b795c,

+	0xf762489e,

+	0x87d00752,

+	0x9be45ed1,

+	0x296ec120,

+	0x61162480,

+	0x792e8a2c,

+	0x3b631590,

+	0xe33ba0cf,

+	0x542ac23c,

+	0xe1e8cffa,

+	0xfc084cd8,

+	0xc115ad31,

+	0x71559928,

+	0x791f1e33,

+	0x662ed92b,

+	0x7222c76d,

+	0x02dcd566,

+	0x8db9b4d4,

+	0xa5f344c8,

+	0x15806b12,

+	0x81e572f7,

+	0x3b3fbe25,

+	0x2133b413,

+	0x2d68a367,

+	0x356f6ce7,

+	0xcd6dfed1,

+	0xd8b3a26e,

+	0xe9d328da,

+	0x127425ab,

+	0x83a60aac,

+	0x8cc26190,

+	0x7f87ab26,

+	0x56faab5f,

+	0x76d0feaa,

+	0x4b25dd10,

+	0x4f6286ea,

+	0x79298d06,

+	0x8002bf83,

+	0x2977c85e,

+	0xd3b3d19a,

+	0xa92bf132,

+	0xa280efd8,

+	0x83f7ad6e,

+	0x748969c7,

+	0x25ff411d,

+	0x3854d3a8,

+	0x55746aa2,

+	0x00db5c54,

+	0x36949e0d,

+	0x40402ab6,

+	0x1a720211,

+	0xe02ce823,

+	0x4ac104a2,

+	0x214d2e4b,

+	0x267e5c83,

+	0x38a3a483,

+	0xd1da1f67,

+	0x0c68db2c,

+	0xd7035d63,

+	0xa29393bb,

+	0xa5743519,

+	0xcb97c84e,

+	0xa853974f,

+	0x147360a0,

+	0x2df9b3f4,

+	0x0aff129e,

+	0x177d687f,

+	0x87eff911,

+	0x6c60b354,

+	0x6c356c38,

+	0x7d480965,

+	0xbb06a193,

+	0x25b0568e,

+	0x6fd6da9a,

+	0x82b64f14,

+	0x3d267a78,

+	0xf100b6a7,

+	0x32c74539,

+	0x6042e152,

+	0x4548276e,

+	0xa3a32b70,

+	0xf029fe15,

+	0xa9b8bd2f,

+	0x5618eee4,

+	0x9815a5f0,

+	0x89fb2850,

+	0xa9261b26,

+	0xded9e505,

+	0x37e9d749,

+	0xdc4aeb78,

+	0x9e634f7a,

+	0xcf638d2d,

+	0x6b679f92,

+	0x2b64911d,

+	0xe6d1312f,

+	0x88b3e76a,

+	0x56311f62,

+	0x00916de7,

+	0x39d0bc61,

+	0x8ac09356,

+	0x47abcfce,

+	0x324cb73e,

+	0xfadcd0a8,

+	0x2f2fbca8,

+	0x945eda22,

+	0xba23cab1,

+	0xf9fb4212,

+	0x1fa71d45,

+	0x867a034e,

+	0x3bee5db1,

+	0xf54adced,

+	0x6633ba77,

+	0xe1eb4f1e,

+	0x97ef01f6,

+	0x57fd3b32,

+	0x5234d80d,

+	0xe8ee95f3,

+	0x5dc990bf,

+	0xaba833e1,

+/*  Dummy terminator  */

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+};

+                                                                                

+

diff --git a/src/mainboard/supermicro/x6dhr_ig/mptable.c b/src/mainboard/supermicro/x6dhr_ig/mptable.c
new file mode 100644
index 0000000..7c13b8f
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/mptable.c
@@ -0,0 +1,236 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "LNXI    ";
+	static const char productid[12] = "X6DHR-iG    ";
+	struct mp_config_table *mc;
+	unsigned char bus_num;
+	unsigned char bus_isa;
+	unsigned char bus_pxhd_1;
+	unsigned char bus_pxhd_2;
+	unsigned char bus_pxhd_3;
+	unsigned char bus_pxhd_4;
+	unsigned char bus_ich5r_1;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* initially just the header */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* not yet computed */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet... */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+	
+	{
+		device_t dev;
+
+		/* ich5r */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
+		if (dev) {
+			bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_isa++;
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1f.0, using defaults\n");
+
+			bus_ich5r_1 = 9;
+			bus_isa = 10;
+		}
+		/* pxhd-1 */
+		dev = dev_find_slot(2, PCI_DEVFN(0x0,0));
+		if (dev) {
+			bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n");
+
+			bus_pxhd_1 = 3;
+		}
+		/* pxhd-2 */
+		dev = dev_find_slot(2, PCI_DEVFN(0x00,2));
+		if (dev) {
+			bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
+
+			bus_pxhd_2 = 4;
+		}
+
+		/* pxhd-3 */
+		dev = dev_find_slot(5, PCI_DEVFN(0x0,0));
+		if (dev) {
+			bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n");
+
+			bus_pxhd_3 = 6;
+		}
+		/* pxhd-4 */
+		dev = dev_find_slot(5, PCI_DEVFN(0x00,2));
+		if (dev) {
+			bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
+
+			bus_pxhd_4 = 7;
+		}
+	
+	}
+	
+	/* define bus and isa numbers */
+	for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+		smp_write_bus(mc, bus_num, "PCI	  ");
+	}
+	smp_write_bus(mc, bus_isa, "ISA	  ");
+
+	/* IOAPIC handling */
+
+	smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
+	{
+		struct resource *res;
+		device_t dev;
+		/* pxhd apic 3 */
+		dev = dev_find_slot(2, PCI_DEVFN(0x00,1));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x03, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 2:00.1\n");
+		}
+		/* pxhd apic 4 */
+		dev = dev_find_slot(2, PCI_DEVFN(0x00,3));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x04, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 2:00.3\n");
+		}
+		/* pxhd apic 5 */
+		dev = dev_find_slot(5, PCI_DEVFN(0x00,1));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x05, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 5:00.1\n");
+		}
+		/* pxhd apic 8 */
+		dev = dev_find_slot(5, PCI_DEVFN(0x00,3));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x08, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 5:00.3\n");
+		}
+	}
+
+	
+	/* ISA backward compatibility interrupts  */
+	smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x01, 0x02, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x02);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x03, 0x02, 0x03);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x04, 0x02, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x06, 0x02, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x76, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x08, 0x02, 0x08);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x09, 0x02, 0x09);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x77, 0x02, 0x17);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x75, 0x02, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0c, 0x02, 0x0c);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0d, 0x02, 0x0d);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0e, 0x02, 0x0e);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0f, 0x02, 0x0f);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7c, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7d, 0x02, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_2, 0x08, 0x04, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_2, 0x09, 0x04, 0x07);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_3, 0x08, 0x05, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_4, 0x08, 0x08, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		(bus_isa - 1), 0x04, 0x02, 0x10);
+
+	/* Standard local interrupt assignments */
+	smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x00);
+	smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x01);
+
+	/* There is no extension information... */
+
+	/* Compute the checksums */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+	printk_debug("Wrote the mp table end at: %p - %p\n",
+		mc, smp_next_mpe_entry(mc));
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/reset.c b/src/mainboard/supermicro/x6dhr_ig/reset.c
new file mode 100644
index 0000000..874bfc4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/reset.c
@@ -0,0 +1,40 @@
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#ifndef __ROMCC__
+#include <device/device.h>
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+#define PCI_DEV_INVALID 0
+
+static inline device_t pci_locate_device(unsigned pci_id, device_t from)
+{
+	return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
+}
+#endif
+
+void soft_reset(void)
+{
+        outb(0x04, 0xcf9);
+}
+void hard_reset(void)
+{
+        outb(0x02, 0xcf9);
+        outb(0x06, 0xcf9);
+}
+void full_reset(void)
+{
+	device_t dev;
+	/* Enable power on after power fail... */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0);
+	if (dev != PCI_DEV_INVALID) {
+		unsigned byte;
+		byte = pci_read_config8(dev, 0xa4);
+		byte &= 0xfe;
+		pci_write_config8(dev, 0xa4, byte);
+		
+	}
+        outb(0x0e, 0xcf9);
+}
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/watchdog.c b/src/mainboard/supermicro/x6dhr_ig/watchdog.c
new file mode 100644
index 0000000..e9012a4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/watchdog.c
@@ -0,0 +1,99 @@
+#include <device/pnp_def.h>
+
+#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
+#define NSC_WDBASE 0x600
+#define ICH5_WDBASE 0x400
+#define ICH5_GPIOBASE 0x500
+
+static void disable_sio_watchdog(device_t dev)
+{
+#if 0
+	/* FIXME move me somewhere more appropriate */
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 1);
+	pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
+	/* disable the sio watchdog */
+	outb(0, NSC_WDBASE + 0);
+	pnp_set_enable(dev, 0);
+#endif
+}
+
+static void disable_ich5_watchdog(void)
+{
+	/* FIXME move me somewhere more appropriate */
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ICH5_WDBASE + 0x60;
+	
+	/* Set bit 11 in TCO1_CNT */
+	value = inw(base + 0x08);
+	value |= 1 << 11;
+	outw(value, base + 0x08);
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+}
+
+static void disable_jarell_frb3(void)
+{
+#if 0
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 0);
+	pci_write_config16(dev, 0x04, value);
+
+	/* Set gpio base */
+	pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
+	base = ICH5_GPIOBASE;
+
+	/* Enable GPIO Bar */
+	value = pci_read_config32(dev, 0x5c);
+	value |= 0x10;
+	pci_write_config32(dev, 0x5c, value);
+
+	/* Configure GPIO 48 and 40 as GPIO */
+	value = inl(base + 0x30);
+	value |= (1 << 16) | ( 1 << 8);
+	outl(value, base + 0x30);
+
+	/* Configure GPIO 48 as Output */
+	value = inl(base + 0x34);
+	value &= ~(1 << 16);
+	outl(value, base + 0x34);
+
+	/* Toggle GPIO 48 high to low */
+	value = inl(base + 0x38);
+	value |= (1 << 16);
+	outl(value, base + 0x38);
+	value &= ~(1 << 16);
+	outl(value, base + 0x38);
+#endif				  
+}
+
+static void disable_watchdogs(void)
+{
+//	disable_sio_watchdog(NSC_WD_DEV);
+	disable_ich5_watchdog();
+//	disable_jarell_frb3();
+	print_debug("Watchdogs disabled\r\n");
+}
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/x6dhr_fixups.c b/src/mainboard/supermicro/x6dhr_ig/x6dhr_fixups.c
new file mode 100644
index 0000000..82c070b
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig/x6dhr_fixups.c
@@ -0,0 +1,23 @@
+#include <arch/romcc_io.h>
+
+static void mch_reset(void)
+{
+        return;
+}
+
+
+
+static void mainboard_set_e7520_pll(unsigned bits)
+{
+	return; 
+}
+
+
+static void mainboard_set_e7520_leds(void)
+{
+	return; 
+}
+
+
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/Config.lb b/src/mainboard/supermicro/x6dhr_ig2/Config.lb
new file mode 100644
index 0000000..dff583c
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/Config.lb
@@ -0,0 +1,209 @@
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
+
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size size of
+## The linuxBIOS bootloader.
+##
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=131072
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+if HAVE_MP_TABLE object mptable.o end
+if HAVE_PIRQ_TABLE object irq_tables.o end
+object reset.o
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc" 
+	action "./romcc -fno-simplify-phi -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc -fno-simplify-phi -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E 
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc" 
+	action	"./romcc -fno-simplify-phi -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc 
+	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc -fno-simplify-phi -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE 
+	mainboardinit cpu/x86/16bit/reset16.inc
+	ldscript /cpu/x86/16bit/reset16.lds
+else
+	mainboardinit cpu/x86/32bit/reset32.inc
+	ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup 
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds 
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/x86/mmx/enable_mmx.inc
+mainboardinit cpu/x86/sse/enable_sse.inc
+mainboardinit ./auto.inc
+mainboardinit cpu/x86/sse/disable_sse.inc
+mainboardinit cpu/x86/mmx/disable_mmx.inc
+
+##
+## Include the secondary Configuration files 
+##
+dir /pc80
+config chip.h
+
+chip northbridge/intel/E7520 # mch
+	device pci_domain 0 on 
+		chip southbridge/intel/ich5r # ich5r
+			# USB ports
+			device pci 1d.0 on end
+			device pci 1d.1 on end
+			device pci 1d.2 on end 
+			device pci 1d.3 on end
+			device pci 1d.7 on end
+		
+			# -> Bridge
+			device pci 1e.0 on end
+		
+			# -> ISA
+			device pci 1f.0 on 
+				chip superio/winbond/w83627hf
+					device pnp 2e.0 off end
+					device pnp 2e.2 on 
+						 io 0x60 = 0x3f8
+						irq 0x70 = 4
+					end
+					device pnp 2e.3 on
+						 io 0x60 = 0x2f8
+						irq 0x70 = 3
+					end
+					device pnp 2e.4 off end
+					device pnp 2e.5 off end
+					device pnp 2e.6 off end
+					device pnp 2e.7 off end
+					device pnp 2e.9 off end
+					device pnp 2e.a on  end
+					device pnp 2e.b off end
+				end
+			end
+			# -> IDE
+			device pci 1f.1 on end
+			# -> SATA 
+			device pci 1f.2 on end
+			device pci 1f.3 on end
+
+			register "pirq_a_d" = "0x0b070a05"
+			register "pirq_e_h" = "0x0a808080"
+		end
+		device pci 00.0 on end 
+		device pci 00.1 on end
+		device pci 01.0 on end 
+		device pci 02.0 on 
+			chip southbridge/intel/pxhd # pxhd1
+				# Bus bridges and ioapics usually bus 1
+				device pci 0.0 on 
+				# On board gig e1000
+					chip drivers/generic/generic 
+        		        	        device pci 03.0 on end
+        		        	        device pci 03.1 on end
+        		        	end
+				end
+				device pci 0.1 on end
+				device pci 0.2 on end
+				device pci 0.3 on end
+			end
+		end
+		device pci 04.0 on end
+		device pci 06.0 on end
+	end
+	device apic_cluster 0 on
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu 0
+			device apic 0 on end
+		end
+		chip cpu/intel/socket_mPGA604_800Mhz # cpu 1
+			device apic 6 on end
+		end
+	end
+	register "intrline" = "0x00070105"
+end
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/Options.lb b/src/mainboard/supermicro/x6dhr_ig2/Options.lb
new file mode 100644
index 0000000..8461cdb
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/Options.lb
@@ -0,0 +1,228 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses IRQ_SLOT_COUNT
+uses HAVE_OPTION_TABLE
+uses CONFIG_LOGICAL_CPUS
+uses CONFIG_MAX_CPUS
+uses CONFIG_IOAPIC
+uses CONFIG_SMP
+uses FALLBACK_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_STREAM
+uses CONFIG_ROM_STREAM_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses USE_OPTION_TABLE
+uses LB_CKS_RANGE_START
+uses LB_CKS_RANGE_END
+uses LB_CKS_LOC
+uses MAINBOARD
+uses MAINBOARD_PART_NUMBER
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
+uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
+uses LINUXBIOS_EXTRA_VERSION
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+uses _RAMBASE
+uses CONFIG_GDB_STUB
+uses CONFIG_CONSOLE_SERIAL8250
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+uses CONFIG_CONSOLE_BTEXT
+uses CC
+uses HOSTCC
+uses CROSS_COMPILE
+uses OBJCOPY
+
+
+###
+### Build options
+###
+
+##
+## ROM_SIZE is the size of boot ROM that this board will use.
+##
+default ROM_SIZE=1048576
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## Delay timer options
+## Use timer2
+## 
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=16
+
+##
+## Build code to export an x86 MP table
+## Useful for specifying IRQ routing values
+##
+default HAVE_MP_TABLE=1
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=1
+
+##
+## Move the default LinuxBIOS cmos range off of AMD RTC registers
+##
+default LB_CKS_RANGE_START=49
+default LB_CKS_RANGE_END=122
+default LB_CKS_LOC=123
+
+##
+## Build code for SMP support
+## Only worry about 2 micro processors
+##
+default CONFIG_SMP=1
+default CONFIG_MAX_CPUS=4
+default CONFIG_LOGICAL_CPUS=0
+
+##
+## Build code to setup a generic IOAPIC
+##
+default CONFIG_IOAPIC=1
+
+##
+## Clean up the motherboard id strings
+##
+default MAINBOARD_PART_NUMBER="X6DHR"
+default MAINBOARD_VENDOR=     "Supermicro"
+default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9
+default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x5580
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 32K heap
+##
+default HEAP_SIZE=0x8000
+
+
+###
+### Compute the location and size of where this firmware image
+### (linuxBIOS plus bootloader) will live in the boot rom chip.
+###
+default FALLBACK_SIZE=131072
+
+##
+## LinuxBIOS C code runs at this location in RAM
+##
+default _RAMBASE=0x00004000
+
+##
+## Load the payload from the ROM
+##
+default CONFIG_ROM_STREAM=1
+
+
+###
+### Defaults of options that you may want to override in the target config file
+### 
+
+##
+## The default compiler
+##
+default CC="$(CROSS_COMPILE)gcc -m32"
+default HOSTCC="gcc"
+
+##
+## Disable the gdb stub by default
+##
+default CONFIG_GDB_STUB=0
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable               
+## ALERT      2   action must be taken immediately 
+## CRIT       3   critical conditions              
+## ERR        4   error conditions                 
+## WARNING    5   warning conditions               
+## NOTICE     6   normal but significant condition 
+## INFO       7   informational                    
+## DEBUG      8   debug-level messages             
+## SPEW       9   Way too many details             
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+
+##
+## Select power on after power fail setting
+default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
+
+##
+## Don't enable the btext console
+##
+default  CONFIG_CONSOLE_BTEXT=0
+
+
+### End Options.lb
+end
diff --git a/src/mainboard/supermicro/x6dhr_ig2/auto.c b/src/mainboard/supermicro/x6dhr_ig2/auto.c
new file mode 100644
index 0000000..cd7c181
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/auto.c
@@ -0,0 +1,169 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "southbridge/intel/ich5r/ich5r_early_smbus.c"
+#include "northbridge/intel/E7520/raminit.h"
+#include "superio/winbond/w83627hf/w83627hf.h"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "debug.c"
+#include "watchdog.c"
+#include "reset.c"
+#include "x6dhr2_fixups.c"
+#include "superio/winbond/w83627hf/w83627hf_early_init.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+#include "cpu/x86/bist.h"
+
+
+#define SIO_GPIO_BASE 0x680
+#define SIO_XBUS_BASE 0x4880
+
+#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+#define HIDDEN_SERIAL_DEV  PNP_DEV(0x2e, W83627HF_SP2)
+
+#define DEVPRES_CONFIG  ( \
+	DEVPRES_D0F0 | \
+	DEVPRES_D1F0 | \
+	DEVPRES_D2F0 | \
+	DEVPRES_D3F0 | \
+	DEVPRES_D4F0 | \
+	DEVPRES_D6F0 | \
+	0 )
+#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
+
+#define RECVENA_CONFIG  0x0808090a
+#define RECVENB_CONFIG  0x0808090a
+
+//void udelay(int usecs)
+//{
+//        int i;
+//        for(i = 0; i < usecs; i++)
+//                outb(i&0xff, 0x80);
+//}
+
+#if 0
+static void hard_reset(void)
+{
+	/* enable cf9 */
+	pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+	/* reset */
+	outb(0x0e, 0x0cf9);
+}
+#endif
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+#include "northbridge/intel/E7520/raminit.c"
+#include "sdram/generic_sdram.c"
+
+
+static void main(unsigned long bist)
+{
+	/*
+	 * 
+	 * 
+	 */
+	static const struct mem_controller mch[] = {
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x00, 0),
+			.f1 = PCI_DEV(0, 0x00, 1),
+			.f2 = PCI_DEV(0, 0x00, 2),
+			.f3 = PCI_DEV(0, 0x00, 3),
+			.channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, },
+			.channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, },
+		}
+	};
+
+	if (bist == 0) {
+		/* Skip this if there was a built in self test failure */
+		early_mtrr_init();
+		if (memory_initialized()) {
+			asm volatile ("jmp __cpu_reset");
+		}
+	}
+	/* Setup the console */
+	outb(0x87,0x2e);
+	outb(0x87,0x2e);
+	pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
+	w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+//	report_bist_failure(bist);
+
+	/* MOVE ME TO A BETTER LOCATION !!! */
+	/* config LPC decode for flash memory access */
+        device_t dev;
+        dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+        if (dev == PCI_DEV_INVALID) {
+                die("Missing ich5?");
+        }
+        pci_write_config32(dev, 0xe8, 0x00000000);
+        pci_write_config8(dev, 0xf0, 0x00);
+
+#if 0
+	display_cpuid_update_microcode();
+#endif
+#if 0
+	print_pci_devices();
+#endif
+#if 1
+	enable_smbus();
+#endif
+#if 0
+//	dump_spd_registers(&cpu[0]);
+	int i;
+	for(i = 0; i < 1; i++) {
+		dump_spd_registers();
+	}
+#endif
+	disable_watchdogs();
+//	dump_ipmi_registers();
+	mainboard_set_e7520_leds();	
+//	memreset_setup();
+	sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
+#if 0
+	dump_pci_devices();
+#endif
+#if 0
+	dump_pci_device(PCI_DEV(0, 0x00, 0));
+	dump_bar14(PCI_DEV(0, 0x00, 0));
+#endif
+
+#if 0 // temporarily disabled 
+	/* Check the first 1M */
+//	ram_check(0x00000000, 0x000100000);
+//	ram_check(0x00000000, 0x000a0000);
+//	ram_check(0x00100000, 0x01000000);
+	ram_check(0x00100000, 0x00100100);
+	/* check the first 1M in the 3rd Gig */
+//	ram_check(0x30100000, 0x31000000);
+#endif
+#if 0
+	ram_check(0x00000000, 0x02000000);
+#endif
+	
+#if 0	
+	while(1) {
+		hlt();
+	}
+#endif
+}
diff --git a/src/mainboard/supermicro/x6dhr_ig2/chip.h b/src/mainboard/supermicro/x6dhr_ig2/chip.h
new file mode 100644
index 0000000..016f20a
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/chip.h
@@ -0,0 +1,5 @@
+struct chip_operations mainboard_supermicro_x6dhr_ig2_ops;
+
+struct mainboard_supermicro_x6dhr_ig2_config {
+	int nothing;
+};
diff --git a/src/mainboard/supermicro/x6dhr_ig2/cmos.layout b/src/mainboard/supermicro/x6dhr_ig2/cmos.layout
new file mode 100644
index 0000000..6f3cd18
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/cmos.layout
@@ -0,0 +1,80 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+395          1       e       2        hyper_threading
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+728        256       h       0        user_data
+984         16       h       0        check_sum
+# Reserve the extended AMD configuration registers
+1000        24       r       0        reserved_memory
+
+
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 983 984
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/debug.c b/src/mainboard/supermicro/x6dhr_ig2/debug.c
new file mode 100644
index 0000000..5546421
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/debug.c
@@ -0,0 +1,330 @@
+#define SMBUS_MEM_DEVICE_START 0x50
+#define SMBUS_MEM_DEVICE_END 0x57
+#define SMBUS_MEM_DEVICE_INC 1
+
+static void print_reg(unsigned char index)
+{
+        unsigned char data;
+                                                                                
+        outb(index, 0x2e);
+        data = inb(0x2f);
+	print_debug("0x");
+	print_debug_hex8(index);
+	print_debug(": 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+        return;
+}
+        
+static void xbus_en(void)
+{
+        /* select the XBUS function in the SIO */
+        outb(0x07, 0x2e);
+        outb(0x0f, 0x2f);
+        outb(0x30, 0x2e);
+        outb(0x01, 0x2f);
+	return;
+}
+                                                                        
+static void setup_func(unsigned char func)
+{
+        /* select the function in the SIO */
+        outb(0x07, 0x2e);
+        outb(func, 0x2f);
+        /* print out the regs */
+        print_reg(0x30);
+        print_reg(0x60);
+        print_reg(0x61);
+        print_reg(0x62);
+        print_reg(0x63);
+        print_reg(0x70);
+        print_reg(0x71);
+        print_reg(0x74);
+        print_reg(0x75);
+        return;
+}
+                                                                                
+static void siodump(void)
+{
+        int i;
+        unsigned char data;
+       
+	 print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
+        for (i=0x10; i<=0x2d; i++) {
+                print_reg((unsigned char)i);
+        }
+#if 0                                                                         
+        print_debug("\r\n*** XBUS REGISTERS ***\r\n");
+        setup_func(0x0f);
+        for (i=0xf0; i<=0xff; i++) {
+                print_reg((unsigned char)i);
+        }
+                                                                                
+        print_debug("\r\n***  SERIAL 1 CONFIG REGISTERS ***\r\n");
+        setup_func(0x03);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  SERIAL 2 CONFIG REGISTERS ***\r\n");
+        setup_func(0x02);
+        print_reg(0xf0);
+
+#endif
+        print_debug("\r\n***  GPIO REGISTERS ***\r\n");
+        setup_func(0x07);
+        for (i=0xf0; i<=0xf8; i++) {
+                print_reg((unsigned char)i);
+        }
+        print_debug("\r\n***  GPIO VALUES ***\r\n");
+        data = inb(0x68a);
+	print_debug("\r\nGPDO 4: 0x");
+	print_debug_hex8(data);
+        data = inb(0x68b);
+	print_debug("\r\nGPDI 4: 0x");
+	print_debug_hex8(data);
+	print_debug("\r\n");
+	
+#if 0                                                                                
+                                                                                
+        print_debug("\r\n***  WATCHDOG TIMER REGISTERS ***\r\n");
+        setup_func(0x0a);
+        print_reg(0xf0);
+                                                                                
+        print_debug("\r\n***  FAN CONTROL REGISTERS ***\r\n");
+        setup_func(0x09);
+        print_reg(0xf0);
+        print_reg(0xf1);
+
+        print_debug("\r\n***  RTC REGISTERS ***\r\n");
+        setup_func(0x10);
+        print_reg(0xf0);
+        print_reg(0xf1);
+        print_reg(0xf3);
+        print_reg(0xf6);
+        print_reg(0xf7);
+        print_reg(0xfe);
+        print_reg(0xff);
+                                                                                
+        print_debug("\r\n***  HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
+        setup_func(0x14);
+        print_reg(0xf0);
+#endif                                                                           
+        return;
+}
+
+static void print_debug_pci_dev(unsigned dev)
+{
+	print_debug("PCI: ");
+	print_debug_hex8((dev >> 16) & 0xff);
+	print_debug_char(':');
+	print_debug_hex8((dev >> 11) & 0x1f);
+	print_debug_char('.');
+	print_debug_hex8((dev >> 8) & 7);
+}
+
+static void print_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		print_debug_pci_dev(dev);
+		print_debug("\r\n");
+	}
+}
+
+static void dump_pci_device(unsigned dev)
+{
+	int i;
+	print_debug_pci_dev(dev);
+	print_debug("\r\n");
+	
+	for(i = 0; i <= 255; i++) {
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+		print_debug_char(' ');
+		print_debug_hex8(val);
+		if ((i & 0x0f) == 0x0f) {
+			print_debug("\r\n");
+		}
+	}
+}
+
+static void dump_bar14(unsigned dev)
+{
+	int i;
+	unsigned long bar;
+	
+	print_debug("BAR 14 Dump\r\n");
+	
+	bar = pci_read_config32(dev, 0x14);
+	for(i = 0; i <= 0x300; i+=4) {
+#if 0		
+		unsigned char val;
+		if ((i & 0x0f) == 0) {
+			print_debug_hex8(i);
+			print_debug_char(':');
+		}
+		val = pci_read_config8(dev, i);
+#endif		
+		if((i%4)==0) {
+		print_debug("\r\n");
+		print_debug_hex16(i);
+		print_debug_char(' ');
+		}
+		print_debug_hex32(read32(bar + i));
+		print_debug_char(' ');
+	}
+	print_debug("\r\n");
+}
+
+static void dump_pci_devices(void)
+{
+	device_t dev;
+	for(dev = PCI_DEV(0, 0, 0); 
+		dev <= PCI_DEV(0, 0x1f, 0x7); 
+		dev += PCI_DEV(0,0,1)) {
+		uint32_t id;
+		id = pci_read_config32(dev, PCI_VENDOR_ID);
+		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000)) {
+			continue;
+		}
+		dump_pci_device(dev);
+	}
+}
+
+#if 0
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+	int i;
+	print_debug("\r\n");
+	for(i = 0; i < 4; i++) {
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".0: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			int j;
+			print_debug("dimm: "); 
+			print_debug_hex8(i); 
+			print_debug(".1: ");
+			print_debug_hex8(device);
+			for(j = 0; j < 256; j++) {
+				int status;
+				unsigned char byte;
+				if ((j & 0xf) == 0) {
+					print_debug("\r\n");
+					print_debug_hex8(j);
+					print_debug(": ");
+				}
+				status = smbus_read_byte(device, j);
+				if (status < 0) {
+					print_debug("bad device\r\n");
+					break;
+				}
+				byte = status & 0xff;
+				print_debug_hex8(byte);
+				print_debug_char(' ');
+			}
+			print_debug("\r\n");
+		}
+	}
+}
+#endif
+
+void dump_spd_registers(void)
+{
+        unsigned device;
+        device = SMBUS_MEM_DEVICE_START;
+        while(device <= SMBUS_MEM_DEVICE_END) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("dimm ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 256) ; i++) {
+	                unsigned char byte;
+                        if ((i % 16) == 0) {
+				print_debug("\r\n");
+				print_debug_hex8(i);
+				print_debug(": ");
+                        }
+			status = smbus_read_byte(device, i);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}
+
+void dump_ipmi_registers(void)
+{
+        unsigned device;
+        device = 0x42;
+        while(device <= 0x42) {
+                int status = 0;
+                int i;
+        	print_debug("\r\n");
+                print_debug("ipmi ");
+		print_debug_hex8(device);
+		
+                for(i = 0; (i < 8) ; i++) {
+	                unsigned char byte;
+			status = smbus_read_byte(device, 2);
+                        if (status < 0) {
+			         print_debug("bad device: ");
+				 print_debug_hex8(-status);
+				 print_debug("\r\n");
+			         break; 
+			}
+			print_debug_hex8(status);
+			print_debug_char(' ');
+		}
+		device += SMBUS_MEM_DEVICE_INC;
+		print_debug("\n");
+	}
+}	
diff --git a/src/mainboard/supermicro/x6dhr_ig2/failover.c b/src/mainboard/supermicro/x6dhr_ig2/failover.c
new file mode 100644
index 0000000..5029d98
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/failover.c
@@ -0,0 +1,46 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "pc80/mc146818rtc_early.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+#include "northbridge/intel/E7520/memory_initialized.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* Did just the cpu reset? */
+	if (memory_initialized()) {
+	 	if (last_boot_normal()) {
+			goto normal_image;
+		} else {
+			goto cpu_reset;
+		}
+	}
+
+	/* This is the primary cpu how should I boot? */
+	else if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else {
+		goto fallback_image;
+	}
+ normal_image:
+	asm volatile ("jmp __normal_image" 
+		: /* outputs */ 
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+ cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */ 
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+ fallback_image:
+	return bist;
+}
diff --git a/src/mainboard/supermicro/x6dhr_ig2/irq_tables.c b/src/mainboard/supermicro/x6dhr_ig2/irq_tables.c
new file mode 100644
index 0000000..5ed51fe
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/irq_tables.c
@@ -0,0 +1,34 @@
+/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */
+
+#include <arch/pirq_routing.h>
+
+const struct irq_routing_table intel_irq_routing_table = {
+	0x52495024, /* u32 signature */
+	0x0100,     /* u16 version   */
+	272,        /* u16 Table size 32+(15*devices)  */
+	0x00,       /* u8 Bus 0 */
+	0xf8,       /* u8 Device 1, Function 0 */
+	0x0000,     /* u16 reserve IRQ for PCI */
+	0x8086,     /* u16 Vendor */
+	0x24d0,     /* Device ID */
+	0x00000000, /* u32 miniport_data */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0xc4,   /*  u8 checksum - mod 256 checksum must give zero */
+	{  /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  */
+	    {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00,  0x00},
+	    {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06,  0x00},
+	    {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07,  0x00}
+	}
+};
diff --git a/src/mainboard/supermicro/x6dhr_ig2/mainboard.c b/src/mainboard/supermicro/x6dhr_ig2/mainboard.c
new file mode 100644
index 0000000..c1891a2
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include "chip.h"
+
+struct chip_operations mainboard_supermicro_x6dhr_ig2_ops = {
+	CHIP_NAME("Supermicro x6dhr-ig2")
+};
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/microcode_updates.c b/src/mainboard/supermicro/x6dhr_ig2/microcode_updates.c
new file mode 100644
index 0000000..b2e72ab
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/microcode_updates.c
@@ -0,0 +1,1563 @@
+/* WARNING - Intel has a new data structure that has variable length

+ * microcode update lengths.  They are encoded in int 8 and 9.  A

+ * dummy header of nulls must terminate the list.

+ */

+                                                                                

+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {

+        /*

+           Copyright  Intel Corporation, 1995, 96, 97, 98, 99, 2000.

+           These microcode updates are distributed for the sole purpose of

+           installation in the BIOS or Operating System of computer systems

+           which include an Intel P6 family microprocessor sold or distributed

+           to or by you.  You are authorized to copy and install this material

+           on such systems.  You are not authorized to use this material for

+           any other purpose.

+        */

+                                                                                

+        /*  M1DF3413.TXT - Noconoa D-0  */

+                                                                                

+        0x00000001, /* Header Version   */

+        0x00000013, /* Patch ID         */

+        0x07302004, /* DATE             */

+        0x00000f34, /* CPUID            */

+        0x95f183f0, /* Checksum         */

+        0x00000001, /* Loader Version   */

+        0x0000001d, /* Platform ID      */

+        0x000017d0, /* Data size        */

+        0x00001800, /* Total size       */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+        0x00000000, /* reserved         */

+ 

+	0x9fbf327a,

+	0x2b41b451,

+	0xb2abaca8,

+	0x6b62b8e0,

+	0x0af32c41,

+	0x12ca6048,

+	0x5bd55ae6,

+	0xb90dfc1d,

+	0x565fe2b2,

+	0x326b1718,

+	0x61f3a40d,

+	0xceb53db3,

+	0x14fb5261,

+	0xbb23b6c3,

+	0x9d7c0466,

+	0xde90a25e,

+	0x9450e9bb,

+	0x497bd6e4,

+	0x97d1041a,

+	0x1831013f,

+	0x6e6fa37e,

+	0x0b5c1d03,

+	0x5eae4db2,

+	0xc029d9e3,

+	0x5373bca3,

+	0xe15fccca,

+	0x39043db0,

+	0xaeb0ea0c,

+	0x62b4e391,

+	0x0b280c6b,

+	0x279eb9d3,

+	0x98d95ada,

+	0xc1cb45a7,

+	0x06917bda,

+	0xdde8aafa,

+	0xdff9d15c,

+	0xd07f8f0a,

+	0x192bcf9d,

+	0xf77de31f,

+	0xadf8be55,

+	0x3f7a5d95,

+	0x0e2140b6,

+	0xf0c75eec,

+	0x3254876a,

+	0x684a1698,

+	0x4ad0cca7,

+	0x6d705304,

+	0xf957d91b,

+	0xe8bb864a,

+	0x440d636c,

+	0xaf4d7d06,

+	0x12680ecf,

+	0x5d0f9e53,

+	0x60148a5d,

+	0x81008364,

+	0x243a8aed,

+	0xd55976de,

+	0xd6a84520,

+	0x932d4b77,

+	0xe67e5f19,

+	0x7dba0e47,

+	0xfee3b153,

+	0x46b6a20c,

+	0x2594e6f6,

+	0x210cab0f,

+	0xf6e47d5d,

+	0xe38276e4,

+	0x90fc2728,

+	0x9faefa11,

+	0xc972217c,

+	0xc8d079dd,

+	0x5f7dc338,

+	0x106f7b7b,

+	0xd04c0a1c,

+	0x0eca300e,

+	0x1ddae8a6,

+	0x6e7fd42e,

+	0xa56c514d,

+	0x56a4e255,

+	0x975ea2bf,

+	0x0eaa78cc,

+	0x0c3e284f,

+	0xbacb6c71,

+	0x1645006f,

+	0xe9a2b955,

+	0x0677c019,

+	0x24b33da0,

+	0x62f200fa,

+	0x234238c4,

+	0x81d5ad79,

+	0x9f754bc9,

+	0xeffd5016,

+	0x041b2cc2,

+	0x2f020bc7,

+	0x4fcd68b8,

+	0x22c3579c,

+	0x4804a114,

+	0xc42db3ea,

+	0x7cde8141,

+	0x47e167c8,

+	0x01aa38cc,

+	0x74a5c25e,

+	0xe0c48d67,

+	0x562365ad,

+	0x38321e57,

+	0x0395885a,

+	0x6888323e,

+	0xd6fc518f,

+	0x1854b64c,

+	0x06a58476,

+	0x3662f898,

+	0xe2bcdaee,

+	0x84c40693,

+	0xef09d374,

+	0x353cc799,

+	0x742223d4,

+	0x05b3c99b,

+	0x0c51ee45,

+	0xd145824a,

+	0xac30806c,

+	0x2ed70c0d,

+	0x71ae10ff,

+	0xbf491854,

+	0x3e1f03b4,

+	0x76bfd6cd,

+	0x1449aa8a,

+	0xf954d3fb,

+	0xf8c7c940,

+	0x70233f85,

+	0x0729e257,

+	0x10bb8936,

+	0xc35bb5b5,

+	0x95d78b5c,

+	0xcc1ba443,

+	0x6f507126,

+	0xa607cfd0,

+	0xce22f2f3,

+	0x5134ed8c,

+	0xec8d2f06,

+	0xa92413d5,

+	0xb973f431,

+	0x16e136dd,

+	0xf7d41bed,

+	0x01b002fe,

+	0x646ed771,

+	0x76ea3d26,

+	0x5024af20,

+	0x84270f51,

+	0x9b3d7820,

+	0x2454a2c6,

+	0xc1f072ed,

+	0x155e864f,

+	0x4c39a6e5,

+	0x928206e5,

+	0x9d1685f5,

+	0x45542ee7,

+	0x1fd27d9e,

+	0x5f2dd9ff,

+	0x222005eb,

+	0x354e8a55,

+	0x1f0de29a,

+	0xb86dc696,

+	0x9eafafad,

+	0x191b197e,

+	0x0e0900e1,

+	0xe0ac42bb,

+	0x3143236f,

+	0x44177def,

+	0x05259274,

+	0xb21af44a,

+	0x6ddee4df,

+	0xc7b56255,

+	0xb6b1d39d,

+	0x218f9070,

+	0x96545a42,

+	0x98cc2d4a,

+	0xb21bac9e,

+	0x83e12d44,

+	0x2ef4fb39,

+	0xbc03528f,

+	0x9485af58,

+	0xd9f1e6ab,

+	0xde7607e6,

+	0x3b398733,

+	0x9cd9b1a9,

+	0xabd77984,

+	0xcce18826,

+	0x701c5c21,

+	0xe6591cbf,

+	0x07a9b9e1,

+	0x69459c90,

+	0xe0cdcad6,

+	0xc4c6c4b6,

+	0x12748024,

+	0x4a33c567,

+	0x7d26a37e,

+	0xcae163bf,

+	0xeb7547fa,

+	0xccc6a01c,

+	0x3cb8abb8,

+	0x64aa67b2,

+	0x51ddf6de,

+	0xbfe1b905,

+	0x50923949,

+	0xacfa43af,

+	0x1fdb5a44,

+	0x091533cb,

+	0x7c92e5dc,

+	0x1c5d0d3e,

+	0x195271f5,

+	0x96e73a4a,

+	0xe1b11968,

+	0xb42906f2,

+	0x5a2940b3,

+	0x611283e9,

+	0x65829161,

+	0x5d1357b7,

+	0x019428ad,

+	0x836c5c3c,

+	0xc0e5e169,

+	0xd360e424,

+	0x257a9d69,

+	0xdca09040,

+	0x85f1c060,

+	0xae7cae79,

+	0xa5ddcfd6,

+	0xdba8f68e,

+	0xd98df596,

+	0xe6e3cd51,

+	0xcfb2be8f,

+	0x368fe6cd,

+	0x58486b75,

+	0x791f1a48,

+	0xf81a61f2,

+	0x58a38155,

+	0x30a86547,

+	0xd7fb2db1,

+	0x300e0b1d,

+	0x3f838461,

+	0xf278805a,

+	0x49529931,

+	0x601d5649,

+	0xe500ba1a,

+	0xc4f78965,

+	0xe10ed02d,

+	0x1f777ebd,

+	0x2db1d17d,

+	0x48a22e6a,

+	0x5a14b738,

+	0xdcf899e0,

+	0xc845bd04,

+	0xd04a52b9,

+	0xf2f19b06,

+	0xdb5ba97a,

+	0xf05605ff,

+	0xc787b72c,

+	0x9f197770,

+	0x87b31150,

+	0x3ff00d57,

+	0x89d1dcb3,

+	0x07528ff4,

+	0x4105fcef,

+	0xb087de2e,

+	0x3bd333a5,

+	0x84a094f4,

+	0x9ab8fb97,

+	0xc9bba063,

+	0x664c52e5,

+	0x27fd05e4,

+	0x3f0e491d,

+	0xab8f4b9a,

+	0x344a0249,

+	0x727dd74f,

+	0x29587211,

+	0xbba262b9,

+	0x319ecbb3,

+	0xec54b023,

+	0xd0fa096d,

+	0x3d223f23,

+	0x0b6013e7,

+	0x513e045b,

+	0xcb1edf15,

+	0xfd44bb25,

+	0x023eb973,

+	0x3f55dac6,

+	0xc2df6514,

+	0x68589880,

+	0x4556878e,

+	0x86f6acfb,

+	0xbcd23f0b,

+	0x32c417c1,

+	0x45f3bb56,

+	0xbe60872b,

+	0x09457cc0,

+	0x2e18b62d,

+	0x065f54d1,

+	0xae3b4a20,

+	0x265b10ae,

+	0xb7547a1d,

+	0x5a9481a9,

+	0xd477ed02,

+	0x601ed0fc,

+	0x9a43257e,

+	0xc9922b72,

+	0xa2a696ae,

+	0xe9d6c37b,

+	0xfab8bdf9,

+	0x1deb34dc,

+	0xaa6bb090,

+	0xbdc3b72f,

+	0xecb3b010,

+	0xe64376e7,

+	0x40356095,

+	0x928b5047,

+	0xbd271c09,

+	0xfd806f61,

+	0x0821e090,

+	0x6afb3588,

+	0xd10e91ea,

+	0xbbc7fedd,

+	0xb1ac6d33,

+	0x07788e4b,

+	0xa10f8013,

+	0x4f8efd9d,

+	0xe5d8728d,

+	0x017f3e82,

+	0xf09ec7eb,

+	0x6bfd7906,

+	0xbcefcb44,

+	0x76699ad5,

+	0x1b976522,

+	0xa55b3dbd,

+	0x88bb33e2,

+	0x98ac5b7f,

+	0x61ac4c8b,

+	0xfd948f3d,

+	0xee610413,

+	0xc77c5035,

+	0x662825a9,

+	0x0009fcba,

+	0x3450fd88,

+	0xeb391fef,

+	0x6949960d,

+	0x1ccb13c3,

+	0x21dac5a6,

+	0x6bcc6b37,

+	0x37ad77a5,

+	0xf71d58b1,

+	0x84ed440d,

+	0xe606b699,

+	0xe43067a4,

+	0x21d5b8b3,

+	0xe11f83e2,

+	0xa0cc6585,

+	0x40eb6d16,

+	0xc5a6879f,

+	0xbd333fd5,

+	0xb44acab4,

+	0x68c016fc,

+	0xfbcd3cfc,

+	0xadf76e42,

+	0xc520e516,

+	0x7468cb61,

+	0x585c0d52,

+	0xea83cefe,

+	0x615d7760,

+	0x89c9b8fd,

+	0x367c355a,

+	0x409371a2,

+	0x7edb38a7,

+	0xca86d263,

+	0xda18250d,

+	0x26e1ed8b,

+	0x02fefede,

+	0x704cb5c8,

+	0x52cbe1eb,

+	0x9cdbc71a,

+	0xa0637560,

+	0xe31f03ca,

+	0x2b78969b,

+	0x803d5866,

+	0xec52d984,

+	0xd8df8bdb,

+	0x6cb1d5e8,

+	0x7b9aec01,

+	0xf7d39401,

+	0xdd04c6ae,

+	0x0e5ca4eb,

+	0x12b593c8,

+	0x38f6d4e5,

+	0x13a91268,

+	0x60c8251b,

+	0xa136cf9a,

+	0xda070cdd,

+	0x6142408c,

+	0xc28065dd,

+	0x50b73718,

+	0x36074eee,

+	0xc7b20fcb,

+	0x18d29f9b,

+	0xe97eb966,

+	0xe6936bcc,

+	0x1c9188ea,

+	0x7cff40e2,

+	0xee791ac8,

+	0xb099a323,

+	0x571d69b7,

+	0x22c1f7d0,

+	0x0b9662ee,

+	0x76e45cb9,

+	0xbd0d7020,

+	0x7794bd95,

+	0x1b0fe51a,

+	0xda2754ef,

+	0x7f3ad7a9,

+	0x58f627d3,

+	0x211670a3,

+	0xc7471b81,

+	0x495a93ac,

+	0xaad4f030,

+	0xa76614c8,

+	0xd63dba3c,

+	0x9c4f729c,

+	0x6e831cfb,

+	0xa6105c75,

+	0x95c62188,

+	0x723ef45d,

+	0xf59f2dd1,

+	0x5825283d,

+	0x768d8a86,

+	0x070d02ac,

+	0xfdbcbd73,

+	0x0d479795,

+	0x797aa7f7,

+	0x6c9e468b,

+	0xa961571d,

+	0xc7127ef0,

+	0x4b0442e7,

+	0xd99a9e87,

+	0x6c876cba,

+	0xe4f9f814,

+	0x120eeb8d,

+	0x4bbb9c8e,

+	0x22c0a29e,

+	0xff681fcc,

+	0x26777226,

+	0x6339e667,

+	0x2402333e,

+	0x2bf66a17,

+	0x63806e6c,

+	0x98416b75,

+	0x791b3e91,

+	0x79c09cd7,

+	0x0c157436,

+	0x6d99157c,

+	0xc8990984,

+	0xaf7d2ae4,

+	0xfe3ee7d9,

+	0xb7676de0,

+	0x9df8722e,

+	0x08462a7e,

+	0x99032839,

+	0xd726ff95,

+	0x5c1c78e8,

+	0x4ef1b747,

+	0x4e257ba7,

+	0xa83ad5f3,

+	0x523b3809,

+	0xc2ce4f19,

+	0xabfadaa5,

+	0x370b005c,

+	0x2d6a02e1,

+	0xbf6ee428,

+	0xfd84be50,

+	0xb79801b3,

+	0x488ad789,

+	0x65a87bda,

+	0x59f0fd6a,

+	0xa4106878,

+	0xdbadd916,

+	0x1f86f200,

+	0xefb7fc72,

+	0x26d4d47f,

+	0xf7892efc,

+	0x41f50167,

+	0xc6a28f9e,

+	0xffd4a8e0,

+	0xa00e4ea0,

+	0x8183f648,

+	0x030faa4c,

+	0x26c1715f,

+	0x322c9ea3,

+	0x5d60d054,

+	0x413470cb,

+	0x3d131892,

+	0x22f2ae86,

+	0x9f1c96b6,

+	0x015563f4,

+	0x3a5625ba,

+	0xcb95b598,

+	0xf0685fb9,

+	0x158af5ec,

+	0xfc01a406,

+	0x01841d19,

+	0x210b7e73,

+	0x19a416a1,

+	0xed254c44,

+	0x5bd51335,

+	0xb8905dc9,

+	0x9e52f38c,

+	0xef5d7dd0,

+	0x1516f6bb,

+	0xf13bb426,

+	0x9ee6d6cb,

+	0x28bde0a6,

+	0x766b655e,

+	0xaf2e0e52,

+	0xdec60f49,

+	0x254a0959,

+	0xb009d431,

+	0x2f6d3533,

+	0x0a074afc,

+	0xcd3d3a72,

+	0x52aa4fce,

+	0x16c4507d,

+	0x2f842898,

+	0xb087e98b,

+	0x68b41826,

+	0xd4adc5c9,

+	0x53b3e498,

+	0x2dff7b03,

+	0xda931e65,

+	0xf1d66edd,

+	0x2beb7555,

+	0x97b3f152,

+	0x035676f8,

+	0xca9c7cf6,

+	0x57992a53,

+	0x578a1004,

+	0x458e23c8,

+	0x2a2494bf,

+	0xa92c549b,

+	0x2ca46deb,

+	0xcd907478,

+	0x93baaeb5,

+	0xa70af4c6,

+	0x9767d5b8,

+	0x9874bcee,

+	0xb0413973,

+	0x9bfef4f7,

+	0x7fbed607,

+	0x2a255991,

+	0xa5e3109d,

+	0x90f09fef,

+	0xb7a3d468,

+	0x6db437aa,

+	0xe8dad585,

+	0xfbc19cbc,

+	0x34cacc6f,

+	0x6c5cc449,

+	0xcc6dc144,

+	0x70c6aaa0,

+	0x183bc459,

+	0x490ea5a8,

+	0xddf105bf,

+	0x3429facf,

+	0x79020f72,

+	0xd2de786d,

+	0xb776f3ed,

+	0x553e3da7,

+	0xaecff099,

+	0x2b471ce1,

+	0xe3a72af9,

+	0x04c9b2bf,

+	0xe84d9702,

+	0xec7cd831,

+	0xda66c6c1,

+	0x451b207c,

+	0x68243bc3,

+	0xb3012b1e,

+	0x1855c026,

+	0x1addac14,

+	0xc73834a2,

+	0xea91596d,

+	0x08f0d135,

+	0xc6021aa0,

+	0xc5d1726b,

+	0xc21d1f0b,

+	0x92b7c740,

+	0x9f024526,

+	0x6c91df6c,

+	0xfec85435,

+	0x3d5a9150,

+	0x93249836,

+	0x2ec5e71f,

+	0x23e96579,

+	0x81ce78d6,

+	0x49e45ccf,

+	0x4d5e9c78,

+	0x2a2cdfab,

+	0x148e1833,

+	0xa3fab11b,

+	0xd0ceb7e9,

+	0x4789b634,

+	0x147fc687,

+	0x48f4f59c,

+	0x21eea4e3,

+	0x411dfb7d,

+	0x033fe075,

+	0x57c9e07d,

+	0xb09edf4e,

+	0x9db83f5f,

+	0x6ef1343a,

+	0x64a68315,

+	0x300e34c3,

+	0x72ac2766,

+	0x640271a4,

+	0x0a282b82,

+	0xcaf1ec1b,

+	0x7d4849f9,

+	0x108c5eaa,

+	0xfaa96613,

+	0x0476639b,

+	0x70ee8371,

+	0x9db599ba,

+	0x85158d5f,

+	0x02912911,

+	0xe6fec86a,

+	0xcf3036f3,

+	0xccdd49a0,

+	0xe650b3cd,

+	0xf5429ef0,

+	0x411e4690,

+	0xa526e30b,

+	0x275822af,

+	0x91e12d05,

+	0x958881aa,

+	0xabf76cc4,

+	0x06e794a9,

+	0xa97d1577,

+	0x0188613c,

+	0x17c96558,

+	0x96c31832,

+	0x5696b201,

+	0x03e3dad2,

+	0xbe44d0ba,

+	0x4d552a6c,

+	0xe9fafb48,

+	0x4968ad28,

+	0xf109edce,

+	0xd1534f30,

+	0xc2d8b9e8,

+	0x66e911d7,

+	0xd67a594b,

+	0x4492b2b4,

+	0xeb86848d,

+	0x4106979b,

+	0x0f75039f,

+	0xf5f3ee2c,

+	0x04baf613,

+	0x00c6fd60,

+	0x32ebe198,

+	0xc7f129eb,

+	0x7cac0839,

+	0x57a1fde4,

+	0x2da04cfc,

+	0x93179aa5,

+	0xf3f4d2d9,

+	0xd8d2528a,

+	0x5fdd42af,

+	0xd08c7bdb,

+	0x53acd639,

+	0xe37aab85,

+	0x2d55b5a2,

+	0x7bc96248,

+	0x2fb42401,

+	0x2ff99915,

+	0x2be3b5ea,

+	0xf0ff9bdd,

+	0x1b6bbaa3,

+	0x83a13de0,

+	0x4503fc83,

+	0x08c24640,

+	0x2463a2b2,

+	0x2e264872,

+	0xc451a29d,

+	0xbfd2e09c,

+	0x15bcb009,

+	0x69102223,

+	0x4c8581e9,

+	0x4ec94cf0,

+	0x75017d7b,

+	0x0e5d8cf1,

+	0x50b9ca97,

+	0x55df1100,

+	0x245162e0,

+	0x0df18bca,

+	0x00776990,

+	0xf6790a03,

+	0x599ef43e,

+	0xe8bf7afb,

+	0xea141ddc,

+	0xad1a54b2,

+	0x55f767f8,

+	0xb661981c,

+	0xe1650342,

+	0x365adc95,

+	0xbb44e3a0,

+	0xa064fea1,

+	0x3516bf27,

+	0xfd40a414,

+	0x53f9a9e6,

+	0x2071a5ee,

+	0x56ca2713,

+	0x7afdd07a,

+	0xd62b7f6e,

+	0xe9dac904,

+	0xca212105,

+	0xb9d6e3de,

+	0x6af5033f,

+	0x34d9049b,

+	0xc51ec095,

+	0xe5eddb9d,

+	0x122b5c6a,

+	0x9f562e58,

+	0x20ec8986,

+	0x760857f2,

+	0x8d8aadb3,

+	0xbc8f0807,

+	0x0f79eae7,

+	0xbfa6bfa8,

+	0x28151aeb,

+	0xbe4b4d4b,

+	0xc65d58b0,

+	0xcf99ba1b,

+	0xc1049197,

+	0xe36d8c87,

+	0x548b7676,

+	0xbe7bb2c4,

+	0x77923781,

+	0x5fbd631e,

+	0x770e5a41,

+	0xd2f2948a,

+	0x074f5428,

+	0xc7a1562e,

+	0xf55618c6,

+	0x8bf8a3d1,

+	0x837ed4a8,

+	0xe42e0298,

+	0xd3754b0c,

+	0xbaa24c25,

+	0x793ac973,

+	0x814e66ec,

+	0xa4154fa9,

+	0x3e0e65ca,

+	0x5a783bd5,

+	0x2bb37f6c,

+	0xb3c2526e,

+	0x34c9a28a,

+	0x6c8b4795,

+	0x64605fa8,

+	0x2e6aae2e,

+	0xd9b28f27,

+	0x6a9a200b,

+	0x3acd1e3a,

+	0xce9a4a6c,

+	0xd2a0bd14,

+	0x700f2003,

+	0x501cbef7,

+	0x4068b05e,

+	0xa24c4580,

+	0x4da75506,

+	0x500b9b0f,

+	0x22e3a600,

+	0x7bec4e94,

+	0x8f0958e2,

+	0x42129a1e,

+	0xb46d8dc5,

+	0x29f8851c,

+	0x83fb38bd,

+	0x17b0de15,

+	0x15340d20,

+	0x74f00fde,

+	0x6c646b32,

+	0x905897c4,

+	0x4d8ed991,

+	0x3cf91fd5,

+	0x0ee02ddf,

+	0xec069ce6,

+	0x0b977683,

+	0xa0bf31f6,

+	0xa1d135a9,

+	0xa882d1db,

+	0xa731a63a,

+	0x48e211f1,

+	0xf3d89e99,

+	0xf982e6ea,

+	0x23dde303,

+	0x7f1ff8da,

+	0xdc8c6414,

+	0x806f432e,

+	0xd047bc02,

+	0x671bacff,

+	0xd40ba2a8,

+	0xe3666685,

+	0x31265f9f,

+	0x3931a952,

+	0x62f35606,

+	0xc48f0c5e,

+	0xfd107640,

+	0xf636da24,

+	0xb8f5c3b0,

+	0x1c91e88f,

+	0xed9dd432,

+	0x2b85fa5d,

+	0x8b15d2ac,

+	0x1e06cf24,

+	0x1def6e9c,

+	0xfae9175f,

+	0x03ac6f02,

+	0x37318c87,

+	0xbc0b1ce5,

+	0xa0640cab,

+	0x6cc20a3c,

+	0x1c7b2524,

+	0x4685dacc,

+	0xeab8bb31,

+	0x8063b5d0,

+	0x79817d52,

+	0x211b1972,

+	0xd7bfc987,

+	0xab9128dc,

+	0x150d9b36,

+	0x6a5838ab,

+	0x9a0a304d,

+	0x2e43c331,

+	0x84f2c4b8,

+	0x435146c1,

+	0xed64a280,

+	0x553ecb4c,

+	0x5c800db2,

+	0xeef4df95,

+	0x5dcf2c37,

+	0x70755ddf,

+	0x4274737b,

+	0xe610350e,

+	0xd97a5997,

+	0x7af5edce,

+	0xfd18ba0c,

+	0xb7587cd8,

+	0xfa5e42d6,

+	0x76bde9eb,

+	0xec41eead,

+	0x604d2423,

+	0xb4adbcf9,

+	0xce728fa3,

+	0x02361c31,

+	0x02fab64d,

+	0x00316b1c,

+	0x562f9aa4,

+	0x71f85790,

+	0x9cb6d464,

+	0x32949ebf,

+	0x434fc23d,

+	0xee7fac51,

+	0xda5cc63a,

+	0x17e616b4,

+	0xcd1bd1bc,

+	0x14638cae,

+	0xd31808fa,

+	0xb16e0727,

+	0xfdda2b0f,

+	0xbc11c678,

+	0xfe79dc6e,

+	0xe26eefb4,

+	0x9a78de16,

+	0xb68f2df2,

+	0xd47da234,

+	0xbdff28a4,

+	0x937bb1f4,

+	0x0786dd46,

+	0xbd1160f5,

+	0xf77b070c,

+	0x72b7c51e,

+	0xcbb3a371,

+	0x5e50e904,

+	0x00fbc379,

+	0x680757dd,

+	0xd38193f7,

+	0x93113e25,

+	0x7b258da7,

+	0x991aaa09,

+	0xab1415be,

+	0xa3740774,

+	0x370b72e5,

+	0x2fc643f4,

+	0x3916d70e,

+	0xea2838d3,

+	0xe4840c42,

+	0xd18e6959,

+	0x69a270ee,

+	0xee4a494e,

+	0x0329799b,

+	0x07480357,

+	0x0260c46f,

+	0x7b75346e,

+	0x787234f4,

+	0xe0adf25b,

+	0xba85cacf,

+	0xb5724eb1,

+	0xfde2c080,

+	0x2b6bb492,

+	0xd2f70545,

+	0x9ca97510,

+	0x4034c18f,

+	0x616bcb12,

+	0x5667f52a,

+	0xe2f6bfce,

+	0x1f25969e,

+	0x569eaab7,

+	0x27ad8196,

+	0x2d30a6d0,

+	0x96d6c10a,

+	0xcb9f024f,

+	0x3d7941ef,

+	0xf7a76bc5,

+	0xe9a701d4,

+	0xd53293a3,

+	0x252cf5df,

+	0xaf9172f6,

+	0xd090c809,

+	0xb1a17387,

+	0x045a0987,

+	0x92d9ffd9,

+	0xb30c449c,

+	0x2180ff58,

+	0x2929f7de,

+	0x3f91766e,

+	0x9f488e3d,

+	0x05dd6734,

+	0x82482f5b,

+	0x01da3ca2,

+	0x42f33408,

+	0xf8e3ba89,

+	0x750ac2ff,

+	0x39f11551,

+	0x71087971,

+	0x368fa634,

+	0xefda0572,

+	0x14b8f750,

+	0xe5768705,

+	0x71c168e2,

+	0x8c012c63,

+	0x12ad74ce,

+	0x841c17ea,

+	0xe6f44176,

+	0x36cf2557,

+	0x14760a6d,

+	0x4bb3b7c2,

+	0x14d1437d,

+	0xbe673210,

+	0x4d6ba9f5,

+	0xe68abbf9,

+	0xc311908d,

+	0x46b63956,

+	0xac2c9fb3,

+	0xab769ce8,

+	0xa29d7040,

+	0xec3d67e3,

+	0xdef311de,

+	0x52a53b14,

+	0xca924769,

+	0xf35d1514,

+	0x524b0471,

+	0xc0d08591,

+	0x454fc34c,

+	0xca719639,

+	0x9af2f230,

+	0xa023a821,

+	0x3d6539ba,

+	0x90d0d7a2,

+	0xc65fc56e,

+	0x4eb2aa19,

+	0xeba3b0e7,

+	0x1bb5b33e,

+	0xab8c68c2,

+	0x0f1793d3,

+	0xdcf176e9,

+	0x1b7bbba0,

+	0x96170a27,

+	0x1955452d,

+	0x42e88c71,

+	0x48cad4b3,

+	0xdcc36042,

+	0x90619951,

+	0x7566bc7c,

+	0xe14ba224,

+	0xc24ad73d,

+	0xdb04144d,

+	0xd9792727,

+	0x11150943,

+	0xe45f0c57,

+	0xb87d184e,

+	0x3cf13243,

+	0x2010d95c,

+	0x84c347c1,

+	0x6d0f2461,

+	0xb5c41194,

+	0xde7ccb2e,

+	0xb929ecb0,

+	0x51fbd8f7,

+	0x45dc65fb,

+	0x6902d2c0,

+	0xb940814f,

+	0xf339e083,

+	0x6f370d56,

+	0xcaf5638e,

+	0xe8a3cb83,

+	0xacf414b6,

+	0xe61095a1,

+	0x99b4cde4,

+	0x55112fed,

+	0x606b9d53,

+	0x5a05974a,

+	0xa4c7db34,

+	0xdc92469b,

+	0xf9280621,

+	0xe7b1ef95,

+	0xc0fc5be8,

+	0x74a1da09,

+	0xa92a4b7f,

+	0x3d65d75e,

+	0xe3804335,

+	0x1ff49e19,

+	0x71da8170,

+	0xac69069b,

+	0x04aae3d5,

+	0xc0ef4b46,

+	0x091a3482,

+	0x8356c7ae,

+	0x32ecb208,

+	0x900c89ed,

+	0x2a206ff5,

+	0x7eed5032,

+	0x5b55b25d,

+	0xf98d6df2,

+	0xf52bc8a9,

+	0x1aa2f5fe,

+	0x1d33c0bf,

+	0x3cd34e89,

+	0x9a0da4ae,

+	0x1c205917,

+	0x7ca784cd,

+	0xf7dda662,

+	0xad97f3ff,

+	0x525c53ec,

+	0x024f11ff,

+	0x32c3ae5b,

+	0xbf372800,

+	0x8ff15f4d,

+	0x7605d019,

+	0x0dae7740,

+	0x5f5dd0ef,

+	0x0f6c37d0,

+	0xee6fa91e,

+	0xb9f51051,

+	0x39a9f0d1,

+	0x22bf03fb,

+	0x485a0922,

+	0x7384b30e,

+	0x85ba7f16,

+	0xb1f0a524,

+	0x7e9c5113,

+	0x240d9306,

+	0x1ca7b0ea,

+	0x18a0d114,

+	0x76b64213,

+	0x31212cc0,

+	0xc9dca5c3,

+	0x69f2ae52,

+	0x545caa7c,

+	0xfb2ff045,

+	0x3f3a1af5,

+	0xe75b6913,

+	0x775a1c79,

+	0x4627e25f,

+	0x90a14b97,

+	0x06456383,

+	0x3d52cf69,

+	0xfb2492c3,

+	0x39f25a22,

+	0x81f68c55,

+	0x87b14e15,

+	0x0920af5d,

+	0xe2585678,

+	0x0671e46d,

+	0xb77ddb67,

+	0x3948c4b3,

+	0x122dddef,

+	0xd0726172,

+	0xd3302234,

+	0x58bab4e4,

+	0x195ac247,

+	0x082459f0,

+	0x18a2566d,

+	0xbf56078d,

+	0x116ed409,

+	0x5ccc0f80,

+	0xbae0b4ca,

+	0x21a6325d,

+	0x7e1f0c40,

+	0x595326d4,

+	0x518b2244,

+	0x8ab3cdb7,

+	0xbe6b4835,

+	0xfc39f8ac,

+	0x63b167aa,

+	0x194f070d,

+	0xed3d0416,

+	0xae16758a,

+	0xb9bb6bbf,

+	0x477d9c85,

+	0x9808c304,

+	0xe1d8cec4,

+	0x7ee22e17,

+	0x0a7a9d7f,

+	0xcc98173a,

+	0x5f78dc21,

+	0x364bc95e,

+	0xb54608d9,

+	0x5d4d70ea,

+	0x083a7f79,

+	0x59ffbd73,

+	0x4f3e9eaf,

+	0x68755ad4,

+	0xab254689,

+	0x11bf09a8,

+	0xbbc40098,

+	0x969ca3eb,

+	0x30eee9d2,

+	0xe35bc37e,

+	0xcb2d678f,

+	0x7846876b,

+	0xf0d28ae7,

+	0xc092fbb2,

+	0x321b344a,

+	0xcc5ee81b,

+	0xd2afa00f,

+	0xfeccd86a,

+	0x6e5e55c2,

+	0x2b5543ea,

+	0x810e4009,

+	0xea2d8e20,

+	0x6acae3b9,

+	0x3828e15e,

+	0xe1e4821c,

+	0xf429da70,

+	0x35f6565c,

+	0x64b1baa8,

+	0x350e9583,

+	0xd2522d4f,

+	0x5e28a3f1,

+	0x949ff0aa,

+	0x3c1b5694,

+	0x146dde1f,

+	0x6f3430e1,

+	0x71c077b7,

+	0x4d145924,

+	0xe431cd28,

+	0xb315cfde,

+	0xa0365a4a,

+	0x473de1aa,

+	0xcbe4e999,

+	0x319906e9,

+	0xad0fea9c,

+	0x89e4e72d,

+	0x9dbba94d,

+	0xd395c1c5,

+	0xa1fff11a,

+	0x8447e120,

+	0xe5c59100,

+	0xa07cb778,

+	0x8f30a039,

+	0xed78facb,

+	0x86de9373,

+	0x550c4889,

+	0xce71e3a8,

+	0x06167b3a,

+	0x5abdd9a3,

+	0xc8a9e48d,

+	0xe3312905,

+	0x7a63a146,

+	0xc0f19763,

+	0xda0cf9db,

+	0x1d708306,

+	0x0e41f0ba,

+	0x4c7939fe,

+	0x768e48c2,

+	0xe925fd31,

+	0x309e7870,

+	0xfc261b87,

+	0xc897b2de,

+	0x6c714792,

+	0x41c7fbac,

+	0x57d0b3c3,

+	0x4fa82a55,

+	0xd56b4a87,

+	0x81e5cabc,

+	0xb260cb7b,

+	0x520927ab,

+	0x20d0ab46,

+	0xc9f92ddf,

+	0x81f4a21d,

+	0xfc5a0ca2,

+	0x95d16aad,

+	0xe54d7847,

+	0x6080cc07,

+	0x0df73f7e,

+	0xaa8d5187,

+	0x97a0bc12,

+	0xb22c5e68,

+	0x0954d7dc,

+	0x3368ab5a,

+	0xd12541df,

+	0x58119260,

+	0xe5b0e1df,

+	0x25027fa4,

+	0x5780425d,

+	0x29bb8791,

+	0x4100b7a9,

+	0x076b3519,

+	0x15e0ebb4,

+	0xe5fb9273,

+	0x6dbf07e7,

+	0x1f82bddd,

+	0x03691b6b,

+	0xbacef28c,

+	0x9909ed5a,

+	0x98886793,

+	0x544f9a82,

+	0x9d9749d0,

+	0x38441606,

+	0xc4a9f4d2,

+	0x6ce2bcf1,

+	0x1c7c3abd,

+	0x62c621f1,

+	0x871ee1e4,

+	0xa83930ce,

+	0xbe1ee459,

+	0xd61f1ca4,

+	0x8c4450e5,

+	0x98031ca9,

+	0xe52f54e2,

+	0xd0c4c737,

+	0x76074160,

+	0xbf050c3b,

+	0x2603af14,

+	0x43cbb0bc,

+	0xc631b9e8,

+	0x26030719,

+	0x993f570c,

+	0xdda34038,

+	0xe34a9793,

+	0x337a124c,

+	0x2aa8af16,

+	0xf80d7473,

+	0xf01d9397,

+	0x68e1afb9,

+	0x0eb37ad2,

+	0xf71969f9,

+	0xdf020552,

+	0x75aa9b30,

+	0xffa210cf,

+	0x543c414f,

+	0xa1e3faec,

+	0x40891d7e,

+	0x6b48a6c5,

+	0xec09a1a0,

+	0x97a31f2a,

+	0x5a6be2d7,

+	0xd06e492b,

+	0xc54290af,

+	0xcb524021,

+	0x420e8c4d,

+	0xfb135c17,

+	0x2bfc8adb,

+	0x9f0cfb46,

+	0x564db712,

+	0x7a97a227,

+	0x8bb98daf,

+	0xdd0d6180,

+	0x3d28b9e3,

+	0xe505050f,

+	0x19a9868e,

+	0x7bf5685f,

+	0x35d698c4,

+	0xce7e1de3,

+	0x360a64af,

+	0x25a1f022,

+	0xe26c1d04,

+	0x5b3fb364,

+	0x932f25f7,

+	0x9a2aa00d,

+	0xc50fb773,

+	0xec45ea3a,

+	0x22ddf8e4,

+	0xafb6a6c8,

+	0x876d04f7,

+	0xd9c86c3c,

+	0xd54bee2d,

+	0xf4e28199,

+	0xc3456776,

+	0x04c3107b,

+	0xbf914e9d,

+	0x23fefaa5,

+	0x0931a133,

+	0x41467758,

+	0x8ec49707,

+	0x5ed48709,

+	0xd11c2de8,

+	0xb687a0b9,

+	0xdc908383,

+	0xd8037ff3,

+	0xd4311a9f,

+	0xd00aeb6a,

+	0xfe54df3b,

+	0x9c51ce4d,

+	0x36956408,

+	0xcd28ef09,

+	0xc68932b0,

+	0x7c31e782,

+	0x28b4723c,

+	0xededacc2,

+	0x6ddbac6b,

+	0x775a7fc1,

+	0x6909906f,

+	0xa774123c,

+	0xf63145ad,

+	0x287b191e,

+	0x59d79300,

+	0xbf76a2fc,

+	0xfbaf9207,

+	0x2fe5b7f6,

+	0xebe7c103,

+	0x71ac0a8d,

+	0x2028c3c7,

+	0xd2cb4917,

+	0xd74a4ee4,

+	0xfce405d8,

+	0xad83fd0f,

+	0x8f9ec3da,

+	0xaab2301c,

+	0xc6f1339f,

+	0xc652bced,

+	0xe378b272,

+	0x18e1ff34,

+	0x9ec778b6,

+	0xce1a3883,

+	0x7c5e5eaf,

+	0xd16ec37a,

+	0xa69e45f4,

+	0xc36cd4aa,

+	0x045b391f,

+	0x5a2a08f1,

+	0x4dd8d53e,

+	0xd64796ec,

+	0x4476fc28,

+	0x18dbaa50,

+	0x00fb2407,

+	0x177db915,

+	0x5969758b,

+	0x3030964a,

+	0x81d6485b,

+	0x7d2e12b0,

+	0x624d6c5f,

+	0x0746bbc0,

+	0xe669d150,

+	0x0465eef7,

+	0x09764011,

+	0x551995e4,

+	0x8422dedf,

+	0x0ca56194,

+	0x293eab2e,

+	0xf20a137a,

+	0x55117fc2,

+	0xbc5431af,

+	0x064751fa,

+	0xc0dafdb2,

+	0x6c3b1d4f,

+	0xeac335b3,

+	0x71173afc,

+	0x31c84b7c,

+	0xfef2b4ab,

+	0x59ca5fa2,

+	0x664c8b4e,

+	0x7dfd560b,

+	0xdb0daff3,

+	0x51f87bfa,

+	0x58015d2e,

+	0x67a827b4,

+	0x62cebc1a,

+	0x24b37298,

+	0x75b589be,

+	0x874f1800,

+	0x277b795c,

+	0xf762489e,

+	0x87d00752,

+	0x9be45ed1,

+	0x296ec120,

+	0x61162480,

+	0x792e8a2c,

+	0x3b631590,

+	0xe33ba0cf,

+	0x542ac23c,

+	0xe1e8cffa,

+	0xfc084cd8,

+	0xc115ad31,

+	0x71559928,

+	0x791f1e33,

+	0x662ed92b,

+	0x7222c76d,

+	0x02dcd566,

+	0x8db9b4d4,

+	0xa5f344c8,

+	0x15806b12,

+	0x81e572f7,

+	0x3b3fbe25,

+	0x2133b413,

+	0x2d68a367,

+	0x356f6ce7,

+	0xcd6dfed1,

+	0xd8b3a26e,

+	0xe9d328da,

+	0x127425ab,

+	0x83a60aac,

+	0x8cc26190,

+	0x7f87ab26,

+	0x56faab5f,

+	0x76d0feaa,

+	0x4b25dd10,

+	0x4f6286ea,

+	0x79298d06,

+	0x8002bf83,

+	0x2977c85e,

+	0xd3b3d19a,

+	0xa92bf132,

+	0xa280efd8,

+	0x83f7ad6e,

+	0x748969c7,

+	0x25ff411d,

+	0x3854d3a8,

+	0x55746aa2,

+	0x00db5c54,

+	0x36949e0d,

+	0x40402ab6,

+	0x1a720211,

+	0xe02ce823,

+	0x4ac104a2,

+	0x214d2e4b,

+	0x267e5c83,

+	0x38a3a483,

+	0xd1da1f67,

+	0x0c68db2c,

+	0xd7035d63,

+	0xa29393bb,

+	0xa5743519,

+	0xcb97c84e,

+	0xa853974f,

+	0x147360a0,

+	0x2df9b3f4,

+	0x0aff129e,

+	0x177d687f,

+	0x87eff911,

+	0x6c60b354,

+	0x6c356c38,

+	0x7d480965,

+	0xbb06a193,

+	0x25b0568e,

+	0x6fd6da9a,

+	0x82b64f14,

+	0x3d267a78,

+	0xf100b6a7,

+	0x32c74539,

+	0x6042e152,

+	0x4548276e,

+	0xa3a32b70,

+	0xf029fe15,

+	0xa9b8bd2f,

+	0x5618eee4,

+	0x9815a5f0,

+	0x89fb2850,

+	0xa9261b26,

+	0xded9e505,

+	0x37e9d749,

+	0xdc4aeb78,

+	0x9e634f7a,

+	0xcf638d2d,

+	0x6b679f92,

+	0x2b64911d,

+	0xe6d1312f,

+	0x88b3e76a,

+	0x56311f62,

+	0x00916de7,

+	0x39d0bc61,

+	0x8ac09356,

+	0x47abcfce,

+	0x324cb73e,

+	0xfadcd0a8,

+	0x2f2fbca8,

+	0x945eda22,

+	0xba23cab1,

+	0xf9fb4212,

+	0x1fa71d45,

+	0x867a034e,

+	0x3bee5db1,

+	0xf54adced,

+	0x6633ba77,

+	0xe1eb4f1e,

+	0x97ef01f6,

+	0x57fd3b32,

+	0x5234d80d,

+	0xe8ee95f3,

+	0x5dc990bf,

+	0xaba833e1,

+/*  Dummy terminator  */

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+        0x0, 0x0, 0x0, 0x0,

+};

+                                                                                

+

diff --git a/src/mainboard/supermicro/x6dhr_ig2/mptable.c b/src/mainboard/supermicro/x6dhr_ig2/mptable.c
new file mode 100644
index 0000000..61ece13
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/mptable.c
@@ -0,0 +1,219 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+	static const char sig[4] = "PCMP";
+	static const char oem[8] = "LNXI    ";
+	static const char productid[12] = "X6DHR-iG    ";
+	struct mp_config_table *mc;
+	unsigned char bus_num;
+	unsigned char bus_isa;
+	unsigned char bus_pxhd_1;
+	unsigned char bus_pxhd_2;
+	unsigned char bus_pxhd_3;
+	unsigned char bus_pxhd_4;
+	unsigned char bus_ich5r_1;
+
+	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+	memset(mc, 0, sizeof(*mc));
+
+	memcpy(mc->mpc_signature, sig, sizeof(sig));
+	mc->mpc_length = sizeof(*mc); /* initially just the header */
+	mc->mpc_spec = 0x04;
+	mc->mpc_checksum = 0; /* not yet computed */
+	memcpy(mc->mpc_oem, oem, sizeof(oem));
+	memcpy(mc->mpc_productid, productid, sizeof(productid));
+	mc->mpc_oemptr = 0;
+	mc->mpc_oemsize = 0;
+	mc->mpc_entry_count = 0; /* No entries yet... */
+	mc->mpc_lapic = LAPIC_ADDR;
+	mc->mpe_length = 0;
+	mc->mpe_checksum = 0;
+	mc->reserved = 0;
+
+	smp_write_processors(mc);
+	
+	{
+		device_t dev;
+
+		/* ich5r */
+		dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
+		if (dev) {
+			bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+			bus_isa	   = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_isa++;
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n");
+
+			bus_ich5r_1 = 7;
+			bus_isa = 8;
+		}
+		/* pxhd-1 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x0,0));
+		if (dev) {
+			bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.0, using defaults\n");
+
+			bus_pxhd_1 = 2;
+		}
+		/* pxhd-2 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,2));
+		if (dev) {
+			bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 1:00.2, using defaults\n");
+
+			bus_pxhd_2 = 3;
+		}
+
+		/* pxhd-3 */
+		dev = dev_find_slot(0, PCI_DEVFN(0x4,0));
+		if (dev) {
+			bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:04.0, using defaults\n");
+
+			bus_pxhd_3 = 5;
+		}
+		/* pxhd-4 */
+		dev = dev_find_slot(0, PCI_DEVFN(0x06,0));
+		if (dev) {
+			bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+
+		}
+		else {
+			printk_debug("ERROR - could not find PCI 0:06.0, using defaults\n");
+
+			bus_pxhd_4 = 6;
+		}
+	
+	}
+	
+	/* define bus and isa numbers */
+	for(bus_num = 0; bus_num < bus_isa; bus_num++) {
+		smp_write_bus(mc, bus_num, "PCI	  ");
+	}
+	smp_write_bus(mc, bus_isa, "ISA	  ");
+
+	/* IOAPIC handling */
+
+	smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
+	{
+		struct resource *res;
+		device_t dev;
+		/* pxhd apic 3 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,1));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x03, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n");
+		}
+		/* pxhd apic 4 */
+		dev = dev_find_slot(1, PCI_DEVFN(0x00,3));
+		if (dev) {
+			res = find_resource(dev, PCI_BASE_ADDRESS_0);
+			if (res) {
+				smp_write_ioapic(mc, 0x04, 0x20, res->base);
+			}
+		}
+		else {
+			printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n");
+		}
+	}	
+	/* ISA backward compatibility interrupts  */
+	smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x01, 0x02, 0x01);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, 0x02, 0x02);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x03, 0x02, 0x03);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x04, 0x02, 0x04);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x06, 0x02, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x76, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x08, 0x02, 0x08);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x09, 0x02, 0x09);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x77, 0x02, 0x17);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x75, 0x02, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0c, 0x02, 0x0c);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0d, 0x02, 0x0d);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0e, 0x02, 0x0e);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x0f, 0x02, 0x0f);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x74, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7c, 0x02, 0x12);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		0x00, 0x7d, 0x02, 0x11);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_1, 0x08, 0x03, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_1, 0x0c, 0x03, 0x06);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_1, 0x0d, 0x03, 0x07);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_2, 0x08, 0x04, 0x00);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_ich5r_1, 0x04, 0x02, 0x10);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		bus_pxhd_4, 0x00, 0x02, 0x10);
+#if 0
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
+		(bus_isa - 1), 0x04, 0x02, 0x10);
+#endif
+	/* Standard local interrupt assignments */
+#if 0
+	smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x00);
+#endif
+	smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
+		bus_isa, 0x00, MP_APIC_ALL, 0x01);
+
+	/* There is no extension information... */
+
+	/* Compute the checksums */
+	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+
+	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+	printk_debug("Wrote the mp table end at: %p - %p\n",
+		mc, smp_next_mpe_entry(mc));
+	return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+	void *v;
+	v = smp_write_floating_table(addr);
+	return (unsigned long)smp_write_config_table(v);
+}
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/reset.c b/src/mainboard/supermicro/x6dhr_ig2/reset.c
new file mode 100644
index 0000000..874bfc4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/reset.c
@@ -0,0 +1,40 @@
+#include <arch/io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#ifndef __ROMCC__
+#include <device/device.h>
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+#define PCI_DEV_INVALID 0
+
+static inline device_t pci_locate_device(unsigned pci_id, device_t from)
+{
+	return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
+}
+#endif
+
+void soft_reset(void)
+{
+        outb(0x04, 0xcf9);
+}
+void hard_reset(void)
+{
+        outb(0x02, 0xcf9);
+        outb(0x06, 0xcf9);
+}
+void full_reset(void)
+{
+	device_t dev;
+	/* Enable power on after power fail... */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0);
+	if (dev != PCI_DEV_INVALID) {
+		unsigned byte;
+		byte = pci_read_config8(dev, 0xa4);
+		byte &= 0xfe;
+		pci_write_config8(dev, 0xa4, byte);
+		
+	}
+        outb(0x0e, 0xcf9);
+}
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/watchdog.c b/src/mainboard/supermicro/x6dhr_ig2/watchdog.c
new file mode 100644
index 0000000..e9012a4
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/watchdog.c
@@ -0,0 +1,99 @@
+#include <device/pnp_def.h>
+
+#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
+#define NSC_WDBASE 0x600
+#define ICH5_WDBASE 0x400
+#define ICH5_GPIOBASE 0x500
+
+static void disable_sio_watchdog(device_t dev)
+{
+#if 0
+	/* FIXME move me somewhere more appropriate */
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 1);
+	pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
+	/* disable the sio watchdog */
+	outb(0, NSC_WDBASE + 0);
+	pnp_set_enable(dev, 0);
+#endif
+}
+
+static void disable_ich5_watchdog(void)
+{
+	/* FIXME move me somewhere more appropriate */
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 10);
+	pci_write_config16(dev, 0x04, value);
+	
+	/* Set and enable acpibase */
+	pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
+	pci_write_config8(dev, 0x44, 0x10);
+	base = ICH5_WDBASE + 0x60;
+	
+	/* Set bit 11 in TCO1_CNT */
+	value = inw(base + 0x08);
+	value |= 1 << 11;
+	outw(value, base + 0x08);
+	
+	/* Clear TCO timeout status */
+	outw(0x0008, base + 0x04);
+	outw(0x0002, base + 0x06);
+}
+
+static void disable_jarell_frb3(void)
+{
+#if 0
+	device_t dev;
+	unsigned long value, base;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("Missing ich5?");
+	}
+	/* Enable I/O space */
+	value = pci_read_config16(dev, 0x04);
+	value |= (1 << 0);
+	pci_write_config16(dev, 0x04, value);
+
+	/* Set gpio base */
+	pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
+	base = ICH5_GPIOBASE;
+
+	/* Enable GPIO Bar */
+	value = pci_read_config32(dev, 0x5c);
+	value |= 0x10;
+	pci_write_config32(dev, 0x5c, value);
+
+	/* Configure GPIO 48 and 40 as GPIO */
+	value = inl(base + 0x30);
+	value |= (1 << 16) | ( 1 << 8);
+	outl(value, base + 0x30);
+
+	/* Configure GPIO 48 as Output */
+	value = inl(base + 0x34);
+	value &= ~(1 << 16);
+	outl(value, base + 0x34);
+
+	/* Toggle GPIO 48 high to low */
+	value = inl(base + 0x38);
+	value |= (1 << 16);
+	outl(value, base + 0x38);
+	value &= ~(1 << 16);
+	outl(value, base + 0x38);
+#endif				  
+}
+
+static void disable_watchdogs(void)
+{
+//	disable_sio_watchdog(NSC_WD_DEV);
+	disable_ich5_watchdog();
+//	disable_jarell_frb3();
+	print_debug("Watchdogs disabled\r\n");
+}
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/x6dhr2_fixups.c b/src/mainboard/supermicro/x6dhr_ig2/x6dhr2_fixups.c
new file mode 100644
index 0000000..82c070b
--- /dev/null
+++ b/src/mainboard/supermicro/x6dhr_ig2/x6dhr2_fixups.c
@@ -0,0 +1,23 @@
+#include <arch/romcc_io.h>
+
+static void mch_reset(void)
+{
+        return;
+}
+
+
+
+static void mainboard_set_e7520_pll(unsigned bits)
+{
+	return; 
+}
+
+
+static void mainboard_set_e7520_leds(void)
+{
+	return; 
+}
+
+
+
+
diff --git a/src/mainboard/tyan/s2735/Config.lb b/src/mainboard/tyan/s2735/Config.lb
index 568bc9b..3977db1 100644
--- a/src/mainboard/tyan/s2735/Config.lb
+++ b/src/mainboard/tyan/s2735/Config.lb
@@ -43,7 +43,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 if USE_DCACHE_RAM
 
 if CONFIG_USE_INIT
diff --git a/src/mainboard/tyan/s2735/Options.lb b/src/mainboard/tyan/s2735/Options.lb
index 16b23a6..ada1beb 100644
--- a/src/mainboard/tyan/s2735/Options.lb
+++ b/src/mainboard/tyan/s2735/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -92,21 +89,16 @@
 ##
 default HAVE_HARD_RESET=1
 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
 ## Delay timer options
 ##
 default CONFIG_UDELAY_TSC=1
 default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
 
-
 ##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
-default IRQ_SLOT_COUNT=11
+default IRQ_SLOT_COUNT=15
 
 ##
 ## Build code to export an x86 MP table
@@ -148,8 +140,8 @@
 ## enable CACHE_AS_RAM specifics
 ##
 default USE_DCACHE_RAM=1
-default DCACHE_RAM_BASE=0xF2000000
-#default DCACHE_RAM_BASE=0xcf000
+#default DCACHE_RAM_BASE=0xF2000000
+default DCACHE_RAM_BASE=0xcf000
 default DCACHE_RAM_SIZE=0x1000
 #default CONFIG_USE_INIT=1
 
diff --git a/src/mainboard/tyan/s2735/reset.c b/src/mainboard/tyan/s2735/reset.c
new file mode 100644
index 0000000..3cc3d54
--- /dev/null
+++ b/src/mainboard/tyan/s2735/reset.c
@@ -0,0 +1,5 @@
+
+void hard_reset(void)
+{
+	i82801er_hard_reset();
+}
diff --git a/src/mainboard/tyan/s2850/Config.lb b/src/mainboard/tyan/s2850/Config.lb
index 89de7db..df87882 100644
--- a/src/mainboard/tyan/s2850/Config.lb
+++ b/src/mainboard/tyan/s2850/Config.lb
@@ -39,9 +39,33 @@
 ##
 
 driver mainboard.o
+
+#dir /drivers/si/3114
+
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
+
+if USE_DCACHE_RAM
+
+if CONFIG_USE_INIT
+
+makerule ./auto.o
+        depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+        action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o auto.o" 
+end
+
+else    
+                
+makerule ./auto.inc
+        depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+        action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@"         
+        action "perl -e 's/.rodata/.rom.data/g' -pi $@"
+        action "perl -e 's/.text/.section .rom.text/g' -pi $@"
+end
+
+end
+else
 
 ##
 ## Romcc output
@@ -65,13 +89,22 @@
         action  "./romcc    -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
 end
 
+end
 ##
 ## Build our 16 bit and 32 bit linuxBIOS entry code
 ##
 mainboardinit cpu/x86/16bit/entry16.inc
 mainboardinit cpu/x86/32bit/entry32.inc
 ldscript /cpu/x86/16bit/entry16.lds
-ldscript /cpu/x86/32bit/entry32.lds
+if USE_DCACHE_RAM
+        if CONFIG_USE_INIT
+                ldscript /cpu/x86/32bit/entry32.lds
+        end
+
+        if CONFIG_USE_INIT
+                ldscript      /cpu/amd/car/cache_as_ram.lds
+        end
+end
 
 ##
 ## Build our reset vector (This is where linuxBIOS is entered)
@@ -84,8 +117,11 @@
 	ldscript /cpu/x86/32bit/reset32.lds 
 end
 
+if USE_DCACHE_RAM
+else
 ### Should this be in the northbridge code?
 mainboardinit arch/i386/lib/cpu_reset.inc
+end
 
 ##
 ## Include an id string (For safe flashing)
@@ -93,14 +129,25 @@
 mainboardinit arch/i386/lib/id.inc
 ldscript /arch/i386/lib/id.lds
 
+if USE_DCACHE_RAM
+##
+## Setup Cache-As-Ram
+##
+mainboardinit cpu/amd/car/cache_as_ram.inc
+end
+
 ###
 ### This is the early phase of linuxBIOS startup 
 ### Things are delicate and we test to see if we should
 ### failover to another image.
 ###
 if USE_FALLBACK_IMAGE
-	ldscript /arch/i386/lib/failover.lds 
-	mainboardinit ./failover.inc
+if USE_DCACHE_RAM
+       ldscript /arch/i386/lib/failover.lds
+else
+       ldscript /arch/i386/lib/failover.lds
+        mainboardinit ./failover.inc
+end
 end
 
 ###
@@ -110,6 +157,19 @@
 ##
 ## Setup RAM
 ##
+if USE_DCACHE_RAM
+
+if CONFIG_USE_INIT
+initobject auto.o
+else
+mainboardinit ./auto.inc
+end
+
+else
+
+##
+## Setup RAM
+##
 mainboardinit cpu/x86/fpu/enable_fpu.inc
 mainboardinit cpu/x86/mmx/enable_mmx.inc
 mainboardinit cpu/x86/sse/enable_sse.inc
@@ -117,11 +177,13 @@
 mainboardinit cpu/x86/sse/disable_sse.inc
 mainboardinit cpu/x86/mmx/disable_mmx.inc
 
+end
+
 ##
 ## Include the secondary Configuration files 
 ##
 if CONFIG_CHIP_NAME
-        config chip.h
+	config chip.h
 end
 
 # sample config for tyan/s2850
diff --git a/src/mainboard/tyan/s2850/Options.lb b/src/mainboard/tyan/s2850/Options.lb
index c9b56b2..646293e 100644
--- a/src/mainboard/tyan/s2850/Options.lb
+++ b/src/mainboard/tyan/s2850/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -45,9 +42,9 @@
 uses MAXIMUM_CONSOLE_LOGLEVEL
 uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
 uses CONFIG_CONSOLE_SERIAL8250
-uses CONFIG_CONSOLE_BTEXT
 uses HAVE_INIT_TIMER
 uses CONFIG_GDB_STUB
+uses CONFIG_GDB_STUB
 uses CROSS_COMPILE
 uses CC
 uses HOSTCC
@@ -57,6 +54,9 @@
 uses CONFIG_PCI_ROM_RUN
 uses K8_E0_MEM_HOLE_SIZEK
 
+uses USE_DCACHE_RAM
+uses DCACHE_RAM_BASE
+uses DCACHE_RAM_SIZE
 uses CONFIG_USE_INIT
 
 ###
@@ -84,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=2
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
@@ -119,20 +112,29 @@
 ## Only worry about 2 micro processors
 ##
 default CONFIG_SMP=1
-default CONFIG_MAX_CPUS=1
+default CONFIG_MAX_CPUS=2
 default CONFIG_MAX_PHYSICAL_CPUS=1
-default CONFIG_LOGICAL_CPUS=0
+default CONFIG_LOGICAL_CPUS=1
+
+#CHIP_NAME ?
+default CONFIG_CHIP_NAME=1
 
 #1G memory hole
 default K8_E0_MEM_HOLE_SIZEK=0x100000
 
-#BTEXT CONSOLE
-#default CONFIG_CONSOLE_BTEXT=1
-
-#VGA
+#VGA Console
 default CONFIG_CONSOLE_VGA=1
 default CONFIG_PCI_ROM_RUN=1
 
+
+##
+## enable CACHE_AS_RAM specifics
+##
+default USE_DCACHE_RAM=1
+default DCACHE_RAM_BASE=0xcf000
+default DCACHE_RAM_SIZE=0x1000
+default CONFIG_USE_INIT=1
+
 ##
 ## Build code to setup a generic IOAPIC
 ##
@@ -141,7 +143,7 @@
 ##
 ## Clean up the motherboard id strings
 ##
-default MAINBOARD_PART_NUMBER="s2850"
+default MAINBOARD_PART_NUMBER="S2850"
 default MAINBOARD_VENDOR="Tyan"
 default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1
 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2850
@@ -231,9 +233,9 @@
 ## SPEW       9   Way too many details             
 
 ## Request this level of debugging output
-default  DEFAULT_CONSOLE_LOGLEVEL=7
+default  DEFAULT_CONSOLE_LOGLEVEL=8
 ## At a maximum only compile in this level of debugging
-default  MAXIMUM_CONSOLE_LOGLEVEL=7
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
 
 ##
 ## Select power on after power fail setting
diff --git a/src/mainboard/tyan/s2850/auto.c b/src/mainboard/tyan/s2850/auto.c
index 9220738..0b9012a 100644
--- a/src/mainboard/tyan/s2850/auto.c
+++ b/src/mainboard/tyan/s2850/auto.c
@@ -25,21 +25,52 @@
 #include "cpu/x86/bist.h"
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
 
 static void hard_reset(void)
 {
-	set_bios_reset();
+        device_t dev;
 
-	/* enable cf9 */
-	pci_write_config8(PCI_DEV(0, 0x02, 3), 0x41, 0xf1);
-	/* reset */
-	outb(0x0e, 0x0cf9);
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
+
+        set_bios_reset();
+
+        /* enable cf9 */
+        pci_write_config8(dev, 0x41, 0xf1);
+        /* reset */
+        outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
-	set_bios_reset();
-	pci_write_config8(PCI_DEV(0, 0x02, 0), 0x47, 1);
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
+
+        set_bios_reset();
+        pci_write_config8(dev, 0x47, 1);
 }
 
 #define REV_B_RESET 0
diff --git a/src/mainboard/tyan/s2850/mptable.c b/src/mainboard/tyan/s2850/mptable.c
index 6a28ecb..fe17579 100644
--- a/src/mainboard/tyan/s2850/mptable.c
+++ b/src/mainboard/tyan/s2850/mptable.c
@@ -7,6 +7,42 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -16,6 +52,7 @@
 
         unsigned char bus_num;
         unsigned char bus_isa;
+	unsigned char bus_chain_0;
         unsigned char bus_8111_1;
         unsigned apicid_base;
         unsigned apicid_8111;
@@ -41,8 +78,14 @@
         {
                 device_t dev;
 
+                /* HT chain 0 */
+                bus_chain_0 = node_link_to_bus(0, 0);
+                if (bus_chain_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_chain_0 = 1;
+                }
                 /* 8111 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
                 if (dev) {
                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
@@ -89,7 +132,7 @@
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf);
 
 
-	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (2<<2)|3, apicid_8111, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (2<<2)|3, apicid_8111, 0x13);
 	
 //On Board AMD USB
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13);
diff --git a/src/mainboard/tyan/s2850/reset.c b/src/mainboard/tyan/s2850/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/tyan/s2850/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/tyan/s2875/Config.lb b/src/mainboard/tyan/s2875/Config.lb
index f042467..bd61fcb 100644
--- a/src/mainboard/tyan/s2875/Config.lb
+++ b/src/mainboard/tyan/s2875/Config.lb
@@ -39,11 +39,34 @@
 ##
 
 driver mainboard.o
+
+#dir /drivers/si/3114
+
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 
+if USE_DCACHE_RAM
 
+if CONFIG_USE_INIT
+
+makerule ./auto.o
+        depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+        action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o auto.o" 
+end
+
+else    
+                
+makerule ./auto.inc
+        depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+        action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@"         
+        action "perl -e 's/.rodata/.rom.data/g' -pi $@"
+        action "perl -e 's/.text/.section .rom.text/g' -pi $@"
+end
+
+end
+else
+  
 ##
 ## Romcc output
 ##
@@ -66,13 +89,22 @@
         action  "./romcc    -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
 end
 
+end
 ##
 ## Build our 16 bit and 32 bit linuxBIOS entry code
 ##
 mainboardinit cpu/x86/16bit/entry16.inc
 mainboardinit cpu/x86/32bit/entry32.inc
 ldscript /cpu/x86/16bit/entry16.lds
-ldscript /cpu/x86/32bit/entry32.lds
+if USE_DCACHE_RAM
+        if CONFIG_USE_INIT
+                ldscript /cpu/x86/32bit/entry32.lds
+        end
+
+        if CONFIG_USE_INIT
+                ldscript      /cpu/amd/car/cache_as_ram.lds
+        end
+end
 
 ##
 ## Build our reset vector (This is where linuxBIOS is entered)
@@ -85,8 +117,11 @@
 	ldscript /cpu/x86/32bit/reset32.lds 
 end
 
+if USE_DCACHE_RAM
+else
 ### Should this be in the northbridge code?
 mainboardinit arch/i386/lib/cpu_reset.inc
+end
 
 ##
 ## Include an id string (For safe flashing)
@@ -94,14 +129,25 @@
 mainboardinit arch/i386/lib/id.inc
 ldscript /arch/i386/lib/id.lds
 
+if USE_DCACHE_RAM
+##
+## Setup Cache-As-Ram
+##
+mainboardinit cpu/amd/car/cache_as_ram.inc
+end
+
 ###
 ### This is the early phase of linuxBIOS startup 
 ### Things are delicate and we test to see if we should
 ### failover to another image.
 ###
 if USE_FALLBACK_IMAGE
-	ldscript /arch/i386/lib/failover.lds 
-	mainboardinit ./failover.inc
+if USE_DCACHE_RAM
+       ldscript /arch/i386/lib/failover.lds
+else
+       ldscript /arch/i386/lib/failover.lds
+        mainboardinit ./failover.inc
+end
 end
 
 ###
@@ -111,6 +157,19 @@
 ##
 ## Setup RAM
 ##
+if USE_DCACHE_RAM
+
+if CONFIG_USE_INIT
+initobject auto.o
+else
+mainboardinit ./auto.inc
+end
+
+else
+
+##
+## Setup RAM
+##
 mainboardinit cpu/x86/fpu/enable_fpu.inc
 mainboardinit cpu/x86/mmx/enable_mmx.inc
 mainboardinit cpu/x86/sse/enable_sse.inc
@@ -118,11 +177,13 @@
 mainboardinit cpu/x86/sse/disable_sse.inc
 mainboardinit cpu/x86/mmx/disable_mmx.inc
 
+end
+
 ##
 ## Include the secondary Configuration files 
 ##
 if CONFIG_CHIP_NAME
-        config chip.h
+	config chip.h
 end
 
 # sample config for tyan/s2875
diff --git a/src/mainboard/tyan/s2875/Options.lb b/src/mainboard/tyan/s2875/Options.lb
index 5851318..a584d1b 100644
--- a/src/mainboard/tyan/s2875/Options.lb
+++ b/src/mainboard/tyan/s2875/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -47,6 +44,7 @@
 uses CONFIG_CONSOLE_SERIAL8250
 uses HAVE_INIT_TIMER
 uses CONFIG_GDB_STUB
+uses CONFIG_GDB_STUB
 uses CROSS_COMPILE
 uses CC
 uses HOSTCC
@@ -56,6 +54,9 @@
 uses CONFIG_PCI_ROM_RUN
 uses K8_E0_MEM_HOLE_SIZEK
 
+uses USE_DCACHE_RAM
+uses DCACHE_RAM_BASE
+uses DCACHE_RAM_SIZE
 uses CONFIG_USE_INIT
 
 ###
@@ -83,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=5
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
@@ -118,16 +112,28 @@
 ## Only worry about 2 micro processors
 ##
 default CONFIG_SMP=1
-default CONFIG_MAX_CPUS=2
+default CONFIG_MAX_CPUS=4
 default CONFIG_MAX_PHYSICAL_CPUS=2
-default CONFIG_LOGICAL_CPUS=0
+default CONFIG_LOGICAL_CPUS=1
+
+#CHIP_NAME ?
+default CONFIG_CHIP_NAME=1
 
 #1G memory hole
 default K8_E0_MEM_HOLE_SIZEK=0x100000
 
 #VGA Console
-#default CONFIG_CONSOLE_VGA=1
-#default CONFIG_PCI_ROM_RUN=1
+default CONFIG_CONSOLE_VGA=1
+default CONFIG_PCI_ROM_RUN=1
+
+
+##
+## enable CACHE_AS_RAM specifics
+##
+default USE_DCACHE_RAM=1
+default DCACHE_RAM_BASE=0xcf000
+default DCACHE_RAM_SIZE=0x1000
+default CONFIG_USE_INIT=1
 
 ##
 ## Build code to setup a generic IOAPIC
diff --git a/src/mainboard/tyan/s2875/auto.c b/src/mainboard/tyan/s2875/auto.c
index 1b055bf..7b75db2 100644
--- a/src/mainboard/tyan/s2875/auto.c
+++ b/src/mainboard/tyan/s2875/auto.c
@@ -27,20 +27,52 @@
  
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x05, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x05, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -141,6 +173,7 @@
                                 asm volatile ("jmp __cpu_reset");
                         }
                         distinguish_cpu_resets(id.nodeid);
+//                        start_other_core(id.nodeid);
                 }
 #else
                 nodeid = lapicid();
@@ -155,7 +188,7 @@
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
 
diff --git a/src/mainboard/tyan/s2875/mptable.c b/src/mainboard/tyan/s2875/mptable.c
index 9b93dec..394410b 100644
--- a/src/mainboard/tyan/s2875/mptable.c
+++ b/src/mainboard/tyan/s2875/mptable.c
@@ -7,6 +7,40 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -16,6 +50,7 @@
 
         unsigned char bus_num;
         unsigned char bus_isa;
+	unsigned char bus_chain_0;
         unsigned char bus_8111_1;
 	unsigned char bus_8151_1;
         unsigned apicid_base;
@@ -43,8 +78,15 @@
         {
                 device_t dev;
 
+                /* HT chain 0 */
+                bus_chain_0 = node_link_to_bus(0, 0);
+                if (bus_chain_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_chain_0 = 1;
+                }
+
                 /* 8111 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x04,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x04,0));
                 if (dev) {
                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
@@ -58,7 +100,7 @@
                         bus_isa = 4;
                 }
 	               /* 8151 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
                 if (dev) {
                         bus_8151_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
                         printk_debug("bus_8151_1=%d\n",bus_8151_1);
@@ -105,9 +147,9 @@
 
 
 //??? What
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (5<<2)|3, apicid_8111, 0x13);
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (5<<2)|3, apicid_8111, 0x13);
 //Onboard AMD AC97 Audio ???
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (5<<2)|1, apicid_8111, 0x11);
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (5<<2)|1, apicid_8111, 0x11);
 // Onboard AMD USB
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13);
 
diff --git a/src/mainboard/tyan/s2875/reset.c b/src/mainboard/tyan/s2875/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/tyan/s2875/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/tyan/s2880/Config.lb b/src/mainboard/tyan/s2880/Config.lb
index 6c4ac7b..f7ad508 100644
--- a/src/mainboard/tyan/s2880/Config.lb
+++ b/src/mainboard/tyan/s2880/Config.lb
@@ -39,10 +39,33 @@
 ##
 
 driver mainboard.o
+
+#dir /drivers/si/3114
+
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 
+if USE_DCACHE_RAM
+
+if CONFIG_USE_INIT
+
+makerule ./auto.o
+        depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+        action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o auto.o" 
+end
+
+else    
+                
+makerule ./auto.inc
+        depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h"
+        action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@"         
+        action "perl -e 's/.rodata/.rom.data/g' -pi $@"
+        action "perl -e 's/.text/.section .rom.text/g' -pi $@"
+end
+
+end
+else
 
 ##
 ## Romcc output
@@ -66,13 +89,22 @@
         action  "./romcc    -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
 end
 
+end
 ##
 ## Build our 16 bit and 32 bit linuxBIOS entry code
 ##
 mainboardinit cpu/x86/16bit/entry16.inc
 mainboardinit cpu/x86/32bit/entry32.inc
 ldscript /cpu/x86/16bit/entry16.lds
-ldscript /cpu/x86/32bit/entry32.lds
+if USE_DCACHE_RAM
+        if CONFIG_USE_INIT
+                ldscript /cpu/x86/32bit/entry32.lds
+        end
+
+        if CONFIG_USE_INIT
+                ldscript      /cpu/amd/car/cache_as_ram.lds
+        end
+end
 
 ##
 ## Build our reset vector (This is where linuxBIOS is entered)
@@ -85,8 +117,11 @@
 	ldscript /cpu/x86/32bit/reset32.lds 
 end
 
+if USE_DCACHE_RAM
+else
 ### Should this be in the northbridge code?
 mainboardinit arch/i386/lib/cpu_reset.inc
+end
 
 ##
 ## Include an id string (For safe flashing)
@@ -94,14 +129,25 @@
 mainboardinit arch/i386/lib/id.inc
 ldscript /arch/i386/lib/id.lds
 
+if USE_DCACHE_RAM
+##
+## Setup Cache-As-Ram
+##
+mainboardinit cpu/amd/car/cache_as_ram.inc
+end
+
 ###
 ### This is the early phase of linuxBIOS startup 
 ### Things are delicate and we test to see if we should
 ### failover to another image.
 ###
 if USE_FALLBACK_IMAGE
-	ldscript /arch/i386/lib/failover.lds 
-	mainboardinit ./failover.inc
+if USE_DCACHE_RAM
+       ldscript /arch/i386/lib/failover.lds
+else
+       ldscript /arch/i386/lib/failover.lds
+        mainboardinit ./failover.inc
+end
 end
 
 ###
@@ -111,6 +157,19 @@
 ##
 ## Setup RAM
 ##
+if USE_DCACHE_RAM
+
+if CONFIG_USE_INIT
+initobject auto.o
+else
+mainboardinit ./auto.inc
+end
+
+else
+
+##
+## Setup RAM
+##
 mainboardinit cpu/x86/fpu/enable_fpu.inc
 mainboardinit cpu/x86/mmx/enable_mmx.inc
 mainboardinit cpu/x86/sse/enable_sse.inc
@@ -118,11 +177,13 @@
 mainboardinit cpu/x86/sse/disable_sse.inc
 mainboardinit cpu/x86/mmx/disable_mmx.inc
 
+end
+
 ##
 ## Include the secondary Configuration files 
 ##
 if CONFIG_CHIP_NAME
-        config chip.h
+	config chip.h
 end
 
 # sample config for tyan/s2880
diff --git a/src/mainboard/tyan/s2880/Options.lb b/src/mainboard/tyan/s2880/Options.lb
index a6b4e86..1f929b0 100644
--- a/src/mainboard/tyan/s2880/Options.lb
+++ b/src/mainboard/tyan/s2880/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -47,6 +44,7 @@
 uses CONFIG_CONSOLE_SERIAL8250
 uses HAVE_INIT_TIMER
 uses CONFIG_GDB_STUB
+uses CONFIG_GDB_STUB
 uses CROSS_COMPILE
 uses CC
 uses HOSTCC
@@ -56,6 +54,9 @@
 uses CONFIG_PCI_ROM_RUN
 uses K8_E0_MEM_HOLE_SIZEK
 
+uses USE_DCACHE_RAM
+uses DCACHE_RAM_BASE
+uses DCACHE_RAM_SIZE
 uses CONFIG_USE_INIT
 
 ###
@@ -83,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
@@ -122,6 +116,9 @@
 default CONFIG_MAX_PHYSICAL_CPUS=2
 default CONFIG_LOGICAL_CPUS=0
 
+#CHIP_NAME ?
+default CONFIG_CHIP_NAME=1
+
 #1G memory hole
 default K8_E0_MEM_HOLE_SIZEK=0x100000
 
@@ -129,6 +126,15 @@
 default CONFIG_CONSOLE_VGA=1
 default CONFIG_PCI_ROM_RUN=1
 
+
+##
+## enable CACHE_AS_RAM specifics
+##
+default USE_DCACHE_RAM=1
+default DCACHE_RAM_BASE=0xcf000
+default DCACHE_RAM_SIZE=0x1000
+default CONFIG_USE_INIT=1
+
 ##
 ## Build code to setup a generic IOAPIC
 ##
@@ -137,7 +143,7 @@
 ##
 ## Clean up the motherboard id strings
 ##
-default MAINBOARD_PART_NUMBER="s2880"
+default MAINBOARD_PART_NUMBER="S2880"
 default MAINBOARD_VENDOR="Tyan"
 default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1
 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2880
diff --git a/src/mainboard/tyan/s2880/auto.c b/src/mainboard/tyan/s2880/auto.c
index 1ed43bc..2532386 100644
--- a/src/mainboard/tyan/s2880/auto.c
+++ b/src/mainboard/tyan/s2880/auto.c
@@ -27,20 +27,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -155,7 +187,7 @@
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
                         
@@ -179,8 +211,4 @@
                 soft_reset();
         }
 	
-	enable_smbus();
-	memreset_setup();
-	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
-
 }
diff --git a/src/mainboard/tyan/s2880/irq_tables.c b/src/mainboard/tyan/s2880/irq_tables.c
index 4ffc5cf..08c5179 100644
--- a/src/mainboard/tyan/s2880/irq_tables.c
+++ b/src/mainboard/tyan/s2880/irq_tables.c
@@ -37,5 +37,5 @@
 };
 unsigned long write_pirq_routing_table(unsigned long addr)
 {
-        return copy_pirq_routing_table(addr);
+	return copy_pirq_routing_table(addr);   
 }
diff --git a/src/mainboard/tyan/s2880/mptable.c b/src/mainboard/tyan/s2880/mptable.c
index 9c4764a..d013a46 100644
--- a/src/mainboard/tyan/s2880/mptable.c
+++ b/src/mainboard/tyan/s2880/mptable.c
@@ -7,6 +7,42 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -16,6 +52,7 @@
 
         unsigned char bus_num;
         unsigned char bus_isa;
+	unsigned char bus_chain_0;
         unsigned char bus_8131_1;
         unsigned char bus_8131_2;
         unsigned char bus_8111_1;
@@ -45,9 +82,16 @@
 
         {
                 device_t dev;
+
+                /* HT chain 0 */
+                bus_chain_0 = node_link_to_bus(0, 0);
+                if (bus_chain_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_chain_0 = 1;
+                }
                 
                 /* 8111 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x03,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
                 if (dev) {
                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
@@ -60,7 +104,7 @@
                         bus_isa = 5;
                 }
                 /* 8131-1 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
                 if (dev) {
                         bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 
@@ -71,7 +115,7 @@
                         bus_8131_1 = 2;
                 }
                 /* 8131-2 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
                 if (dev) {
                         bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 
@@ -105,14 +149,14 @@
 
                 device_t dev;
                 struct resource *res;
-                dev = dev_find_slot(1, PCI_DEVFN(0x1,1));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x1,1));
                 if (dev) {
                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
                         if (res) {
                                 smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
                         }
                 }
-                dev = dev_find_slot(1, PCI_DEVFN(0x2,1));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x2,1));
                 if (dev) {
                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
                         if (res) {
@@ -137,7 +181,7 @@
 	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf);
 	
 
-	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (4<<2)|0, apicid_8111, 0x13);
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (4<<2)|0, apicid_8111, 0x13);
 
 
 //On Board AMD USB
diff --git a/src/mainboard/tyan/s2880/reset.c b/src/mainboard/tyan/s2880/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/tyan/s2880/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/tyan/s2881/Config.lb b/src/mainboard/tyan/s2881/Config.lb
index 2e564ce..02c6ec8 100644
--- a/src/mainboard/tyan/s2881/Config.lb
+++ b/src/mainboard/tyan/s2881/Config.lb
@@ -44,8 +44,7 @@
 
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
-
+object reset.o
 if USE_DCACHE_RAM
 
 if CONFIG_USE_INIT
@@ -67,6 +66,7 @@
 end
 else
 
+
 ##
 ## Romcc output
 ##
diff --git a/src/mainboard/tyan/s2881/Options.lb b/src/mainboard/tyan/s2881/Options.lb
index 84fa34e..38eb3be 100644
--- a/src/mainboard/tyan/s2881/Options.lb
+++ b/src/mainboard/tyan/s2881/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -87,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/tyan/s2881/auto.c b/src/mainboard/tyan/s2881/auto.c
index 391be78..fc62279 100644
--- a/src/mainboard/tyan/s2881/auto.c
+++ b/src/mainboard/tyan/s2881/auto.c
@@ -27,20 +27,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -155,7 +187,7 @@
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
 
diff --git a/src/mainboard/tyan/s2881/cache_as_ram_auto.c b/src/mainboard/tyan/s2881/cache_as_ram_auto.c
index 5ac861d..bb037a4 100644
--- a/src/mainboard/tyan/s2881/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s2881/cache_as_ram_auto.c
@@ -13,6 +13,7 @@
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
 
+
 #include "northbridge/amd/amdk8/cpu_rev.c"
 #define K8_HT_FREQ_1G_SUPPORT 0
 #include "northbridge/amd/amdk8/incoherent_ht.c"
@@ -37,20 +38,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -93,6 +126,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 
 #define FIRST_CPU  1
@@ -136,7 +171,6 @@
         }
 
         /* Is this a secondary cpu? */
-//        post_code(0x21);
         if (!boot_cpu()) {
                 if (last_boot_normal()) {
                         goto normal_image;
@@ -154,7 +188,6 @@
         amd8111_enable_rom();
 
         /* Is this a deliberate reset by the bios */
-//        post_code(0x22);
         if (bios_reset_detected() && last_boot_normal()) {
                 goto normal_image;
         }
@@ -166,13 +199,11 @@
                 goto fallback_image;
         }
  normal_image:
-//        post_code(0x23);
         __asm__ volatile ("jmp __normal_image"
                 : /* outputs */
                 : "a" (bist) /* inputs */
                 );
  cpu_reset:
-//        post_code(0x24);
 #if 0
         //CPU reset will reset memtroller ???
         asm volatile ("jmp __cpu_reset" 
@@ -182,7 +213,6 @@
 #endif
 
  fallback_image:
-//        post_code(0x25);
         real_main(bist);
 }
 void real_main(unsigned long bist)
@@ -275,17 +305,13 @@
 	report_bist_failure(bist);
 
         setup_s2881_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
 
 	needs_reset = setup_coherent_ht_domain();
 	
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
-
         needs_reset |= ht_setup_chains_x();
 
        	if (needs_reset) {
@@ -294,20 +320,10 @@
        	}
 
 	enable_smbus();
-#if 0
-	dump_spd_registers(&cpu[0]);
-#endif
-#if 0
-	dump_smbus_registers();
-#endif
 
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-#if 0
-	dump_pci_devices();
-#endif
-
 #if 1
         {
         /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
@@ -324,6 +340,8 @@
         }
 #endif
 
+#if 1
+
 
 cpu_reset_x:
 
@@ -386,6 +404,7 @@
 		copy_and_run(new_cpu_reset);
 		/* We will not return */
 	}
+#endif
 
 
 	print_debug("should not be here -\r\n");
diff --git a/src/mainboard/tyan/s2881/mptable.c b/src/mainboard/tyan/s2881/mptable.c
index 06f1301..ee92919 100644
--- a/src/mainboard/tyan/s2881/mptable.c
+++ b/src/mainboard/tyan/s2881/mptable.c
@@ -7,6 +7,41 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -16,6 +51,7 @@
 
         unsigned char bus_num;
         unsigned char bus_isa;
+	unsigned char bus_chain_0;
         unsigned char bus_8131_1;
         unsigned char bus_8131_2;
         unsigned char bus_8111_1;
@@ -46,9 +82,16 @@
        
         {
                 device_t dev;
+
+                /* HT chain 0 */
+                bus_chain_0 = node_link_to_bus(0, 2);
+                if (bus_chain_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_chain_0 = 1;
+                }
                 
                 /* 8111 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x03,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
                 if (dev) {
                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
@@ -61,7 +104,7 @@
                         bus_isa = 5;
                 }
                 /* 8131-1 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
                 if (dev) {
                         bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 
@@ -72,7 +115,7 @@
                         bus_8131_1 = 2;
                 }
                 /* 8131-2 */
-                dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
                 if (dev) {
                         bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 
@@ -106,14 +149,14 @@
         {
                 device_t dev;
                 struct resource *res;
-                dev = dev_find_slot(1, PCI_DEVFN(0x1,1));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x1,1));
                 if (dev) {
                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
                         if (res) {
                                 smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
                         }
                 }
-                dev = dev_find_slot(1, PCI_DEVFN(0x2,1));
+                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x2,1));
                 if (dev) {
                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
                         if (res) {
@@ -138,7 +181,7 @@
 	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf);
 	
 //8111 LPC ????
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (4<<2)|0, apicid_8111, 0x13);
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (4<<2)|0, apicid_8111, 0x13);
 
 //On Board AMD USB ???
 	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13);
diff --git a/src/mainboard/tyan/s2881/reset.c b/src/mainboard/tyan/s2881/reset.c
new file mode 100644
index 0000000..6395818
--- /dev/null
+++ b/src/mainboard/tyan/s2881/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 2);
+}
diff --git a/src/mainboard/tyan/s2882/Config.lb b/src/mainboard/tyan/s2882/Config.lb
index 7739a67..6f71a49 100644
--- a/src/mainboard/tyan/s2882/Config.lb
+++ b/src/mainboard/tyan/s2882/Config.lb
@@ -44,7 +44,7 @@
 
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 
 if USE_DCACHE_RAM
 
@@ -278,36 +278,37 @@
 					end
 					device pci 1.1 on end
 					device pci 1.2 on end
-                                        device pci 1.3 on 
-#                                                chip drivers/generic/generic #dimm 0-0-0
-#                                                        device i2c 50 on end
-#                                                end
-#                                                chip drivers/generic/generic #dimm 0-0-1
-#                                                        device i2c 51 on end
-#                                                end     
-#                                                chip drivers/generic/generic #dimm 0-1-0
-#                                                        device i2c 52 on end
-#                                                end
-#                                                chip drivers/generic/generic #dimm 0-1-1
-#                                                        device i2c 53 on end
-#                                                end
-#                                                chip drivers/generic/generic #dimm 1-0-0
-#                                                        device i2c 54 on end
-#                                                end
-#                                                chip drivers/generic/generic #dimm 1-0-1
-#                                                        device i2c 55 on end
-#                                                end
-#                                                chip drivers/generic/generic #dimm 1-1-0
-#                                                        device i2c 56 on end
-#                                                end
-#                                                chip drivers/generic/generic #dimm 1-1-1
-#                                                        device i2c 57 on end
-#                                                end
+					device pci 1.3 on end
+					device pci 1.3 on 
+#						 chip drivers/generic/generic #dimm 0-0-0
+#							 device i2c 50 on end
+#						 end
+#						 chip drivers/generic/generic #dimm 0-0-1
+#							 device i2c 51 on end
+#						 end	 
+#						 chip drivers/generic/generic #dimm 0-1-0
+#							 device i2c 52 on end
+#						 end
+#						 chip drivers/generic/generic #dimm 0-1-1
+#							 device i2c 53 on end
+#						 end
+#						 chip drivers/generic/generic #dimm 1-0-0
+#							 device i2c 54 on end
+#						 end
+#						 chip drivers/generic/generic #dimm 1-0-1
+#							 device i2c 55 on end
+#						 end
+#						 chip drivers/generic/generic #dimm 1-1-0
+#							 device i2c 56 on end
+#						 end
+#						 chip drivers/generic/generic #dimm 1-1-1
+#							 device i2c 57 on end
+#						 end
                                         end # acpi
 					device pci 1.5 off end
 					device pci 1.6 off end
-                                        register "ide0_enable" = "1"
-                                        register "ide1_enable" = "1"
+					register "ide0_enable" = "1"
+					register "ide1_enable" = "1"
 				end
 			end #  device pci 18.0 
 			
diff --git a/src/mainboard/tyan/s2882/Options.lb b/src/mainboard/tyan/s2882/Options.lb
index 1249719..ffa34c4 100644
--- a/src/mainboard/tyan/s2882/Options.lb
+++ b/src/mainboard/tyan/s2882/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -87,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=1
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
@@ -153,7 +143,7 @@
 ##
 ## Clean up the motherboard id strings
 ##
-default MAINBOARD_PART_NUMBER="s2882"
+default MAINBOARD_PART_NUMBER="S2882"
 default MAINBOARD_VENDOR="Tyan"
 default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1
 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2882
diff --git a/src/mainboard/tyan/s2882/auto.c b/src/mainboard/tyan/s2882/auto.c
index fb7a63a..910db9e 100644
--- a/src/mainboard/tyan/s2882/auto.c
+++ b/src/mainboard/tyan/s2882/auto.c
@@ -27,20 +27,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
+
         set_bios_reset();
-        
+
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 #define REV_B_RESET 0
@@ -64,7 +96,6 @@
    }
 }
 
-
 static inline void activate_spd_rom(const struct mem_controller *ctrl)
 {
         /* nothing to do */
@@ -160,7 +191,7 @@
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
 
@@ -176,7 +207,6 @@
 #if CONFIG_LOGICAL_CPUS==1
         start_other_cores();
 #endif
-        // automatically set that for you, but you might meet tight space
         needs_reset |= ht_setup_chains_x();
         if (needs_reset) {
                 print_info("ht reset -\r\n");
diff --git a/src/mainboard/tyan/s2882/cache_as_ram_auto.c b/src/mainboard/tyan/s2882/cache_as_ram_auto.c
index 1b3d77a..f0adb42 100644
--- a/src/mainboard/tyan/s2882/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s2882/cache_as_ram_auto.c
@@ -36,21 +36,52 @@
 #include "northbridge/amd/amdk8/setup_resource_map.c"
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
 
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -93,6 +124,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 
 #define FIRST_CPU  1
@@ -236,6 +269,7 @@
 #if CONFIG_LOGICAL_CPUS==1
                 if(id.coreid == 0) {
                         if (cpu_init_detected(id.nodeid)) {
+//                                __asm__ volatile ("jmp __cpu_reset");
 				cpu_reset = 1;
 				goto cpu_reset_x;
                         }
@@ -249,7 +283,6 @@
                 distinguish_cpu_resets(nodeid);
 #endif
 
-
                 if (!boot_cpu()
 #if CONFIG_LOGICAL_CPUS==1 
                         || (id.coreid != 0)
@@ -261,7 +294,6 @@
                 }
         }
 
-	
  	w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE);
         uart_init();
         console_init();
@@ -270,14 +302,11 @@
 	report_bist_failure(bist);
 
         setup_default_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
 
 	needs_reset = setup_coherent_ht_domain();
 	
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
         needs_reset |= ht_setup_chains_x();
@@ -288,21 +317,10 @@
        	}
 
 	enable_smbus();
-#if 0
-	dump_spd_registers(&cpu[0]);
-#endif
-#if 0
-	dump_smbus_registers();
-#endif
 
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-#if 0
-	dump_pci_devices();
-#endif
-
-
 #if 1
         {
         /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
@@ -319,6 +337,7 @@
         }
 #endif
 
+#if 1
 
 
 cpu_reset_x:
@@ -382,6 +401,7 @@
 		copy_and_run(new_cpu_reset);
 		/* We will not return */
 	}
+#endif
 
 
 	print_debug("should not be here -\r\n");
diff --git a/src/mainboard/tyan/s2882/irq_tables.c b/src/mainboard/tyan/s2882/irq_tables.c
index cdff230..add22b4 100644
--- a/src/mainboard/tyan/s2882/irq_tables.c
+++ b/src/mainboard/tyan/s2882/irq_tables.c
@@ -1,301 +1,48 @@
-/* This file was generated by getpir.c, do not modify! 
-   (but if you do, please run checkpir on it to verify)
-   Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
-
-   Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
-*/
-#include <console/console.h>
-#include <device/pci.h>
-#include <string.h>
-#include <stdint.h>
 #include <arch/pirq_routing.h>
+#include <device/pci.h>
+
+#define IRQ_ROUTER_BUS		1
+#define IRQ_ROUTER_DEVFN	PCI_DEVFN(4,3)
+#define IRQ_ROUTER_VENDOR	0x1022
+#define IRQ_ROUTER_DEVICE	0x746b
+
+#define AVAILABLE_IRQS 0xdef8
+#define IRQ_SLOT(slot, bus, dev, fn, linka, linkb, linkc, linkd) \
+	{ bus, (dev<<3)|fn, {{ linka, AVAILABLE_IRQS}, { linkb, AVAILABLE_IRQS}, \
+	{linkc, AVAILABLE_IRQS}, {linkd, AVAILABLE_IRQS}}, slot, 0}
+
+/*  Each IRQ_SLOT entry consists of:
+ *  bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu  
+ */
 
 const struct irq_routing_table intel_irq_routing_table = {
-        PIRQ_SIGNATURE, /* u32 signature */
-        PIRQ_VERSION,   /* u16 version   */
-        32+16*15,        /* there can be total 15 devices on the bus */
-        1,           /* Where the interrupt router lies (bus) */
-        (4<<3)|3,           /* Where the interrupt router lies (dev) */
-        0,         /* IRQs devoted exclusively to PCI usage */
-        0x1022,         /* Vendor */
-        0x746b,         /* Device */
-        0,         /* Crap (miniport) */
-        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-        0xff,         /*  u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structu
-re (including checksum) */
-        {
-                {1,(4<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
-                {0x4,0, {{0, 0}, {0, 0}, {0, 0}, {0x4, 0xdef8}}, 0, 0},
-                {0x4,(6<<3)|0, {{0x3, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
-                {0x3,(3<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x1, 0},
-                {0x3,(1<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x2, 0},
-                {0x2,(3<<3)|0, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x3, 0},
-                {0x2,(2<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0},
-                {0x4,(4<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x5, 0},
-                {0x4,(5<<3)|0, {{0x4, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
-                {0x4,(8<<3)|0, {{0x3, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0},
-                {0x2,(6<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0},
-                {0x2,(5<<3)|0, {{0x3, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0, 0}}, 0, 0},
-                {0x2,(9<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0},
-                {0x3,(4<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x6, 0},
-                {0x3,(5<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x7, 0},
-        }
+	PIRQ_SIGNATURE,		/* u32 signature */
+	PIRQ_VERSION,           /* u16 version   */
+	32+16*IRQ_SLOT_COUNT,	/* there can be total IRQ_SLOT_COUNT table entries */
+	IRQ_ROUTER_BUS,		/* Where the interrupt router lies (bus) */
+	IRQ_ROUTER_DEVFN,	/* Where the interrupt router lies (dev) */
+	0x00,			/* IRQs devoted exclusively to PCI usage */
+	IRQ_ROUTER_VENDOR,	/* Vendor */
+	IRQ_ROUTER_DEVICE,	/* Device */
+	0x00,			/* Crap (miniport) */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+	0xb0,           /*  u8 checksum , mod 256 checksum must give zero */
+	{	/* slot(0=onboard), devfn, irqlinks (line id, 0=not routed) */
+		/* PCI Slot 1-6 */
+		IRQ_SLOT(1, 3,1,0, 2,3,4,1 ),
+		IRQ_SLOT(2, 3,2,0, 3,4,1,2 ),
+		IRQ_SLOT(3, 2,1,0, 2,3,4,1 ),
+		IRQ_SLOT(4, 2,2,0, 3,4,1,2 ),
+		IRQ_SLOT(5, 4,5,0, 2,3,4,1 ),
+		IRQ_SLOT(6, 4,4,0, 1,2,3,4 ),
+		/* Onboard NICs */
+		IRQ_SLOT(0, 2,3,0, 4,0,0,0 ),
+		IRQ_SLOT(0, 2,4,0, 4,0,0,0 ),
+		/* Let Linux know about bus 1 */
+		IRQ_SLOT(0, 1,4,3, 0,0,0,0 ),
+	}
 };
-
-static unsigned node_link_to_bus(unsigned node, unsigned link)
-{
-        device_t dev;
-        unsigned reg;
-
-        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
-        if (!dev) {
-                return 0;
-        }
-        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
-                uint32_t config_map;
-                unsigned dst_node;
-                unsigned dst_link;
-                unsigned bus_base;
-                config_map = pci_read_config32(dev, reg);
-                if ((config_map & 3) != 3) {
-                        continue;
-                }
-                dst_node = (config_map >> 4) & 7;
-                dst_link = (config_map >> 8) & 3;
-                bus_base = (config_map >> 16) & 0xff;
-#if 0                           
-                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
-                        dst_node, dst_link, bus_base,
-                        reg, config_map);
-#endif
-                if ((dst_node == node) && (dst_link == link))
-                {
-                        return bus_base;
-                }
-        }
-        return 0;
-}
-
-static void write_pirq_info(struct irq_info *pirq_info, uint8_t bus, uint8_t devfn, uint8_t link0, uint16_t bitmap0, 
-		uint8_t link1, uint16_t bitmap1, uint8_t link2, uint16_t bitmap2,uint8_t link3, uint16_t bitmap3,
-		uint8_t slot, uint8_t rfu)
-{
-        pirq_info->bus = bus; 
-        pirq_info->devfn = devfn;
-                pirq_info->irq[0].link = link0;
-                pirq_info->irq[0].bitmap = bitmap0;
-                pirq_info->irq[1].link = link1;
-                pirq_info->irq[1].bitmap = bitmap1;
-                pirq_info->irq[2].link = link2;
-                pirq_info->irq[2].bitmap = bitmap2;
-                pirq_info->irq[3].link = link3;
-                pirq_info->irq[3].bitmap = bitmap3;
-        pirq_info->slot = slot;
-        pirq_info->rfu = rfu;
-}
-
 unsigned long write_pirq_routing_table(unsigned long addr)
 {
-
-	struct irq_routing_table *pirq;
-	struct irq_info *pirq_info;
-	unsigned slot_num;
-	uint8_t *v;
-
-        uint8_t sum=0;
-        int i;
-
-        unsigned char bus_chain_0;
-        unsigned char bus_8131_1;
-        unsigned char bus_8131_2;
-        unsigned char bus_8111_1;
-        {
-                device_t dev;
-
-                /* HT chain 0 */
-                bus_chain_0 = node_link_to_bus(0, 0);
-                if (bus_chain_0 == 0) {
-                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
-                        bus_chain_0 = 1;
-                }
-
-                /* 8111 */
-                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
-                if (dev) {
-                        bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
-                }
-                else {
-                        printk_debug("ERROR - could not find PCI 1:03.0, using defaults\n");
-
-                        bus_8111_1 = 4;
-                }
-                /* 8131-1 */
-                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
-                if (dev) {
-                        bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
-
-                }
-                else {
-                        printk_debug("ERROR - could not find PCI 1:01.0, using defaults\n");
-
-                        bus_8131_1 = 2;
-                }
-                /* 8131-2 */
-                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
-                if (dev) {
-                        bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
-
-                }
-                else {
-                        printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
-
-                        bus_8131_2 = 3;
-                }
-        }
-
-        /* Align the table to be 16 byte aligned. */
-        addr += 15;
-        addr &= ~15;
-
-        /* This table must be betweeen 0xf0000 & 0x100000 */
-        printk_info("Writing IRQ routing tables to 0x%x...", addr);
-
-	pirq = (void *)(addr);
-	v = (uint8_t *)(addr);
-	
-	pirq->signature = PIRQ_SIGNATURE;
-	pirq->version  = PIRQ_VERSION;
-	
-	pirq->rtr_bus = bus_chain_0;
-	pirq->rtr_devfn = (4<<3)|3;
-
-	pirq->exclusive_irqs = 0;
-	
-	pirq->rtr_vendor = 0x1022;
-	pirq->rtr_device = 0x746b;
-
-	pirq->miniport_data = 0;
-
-	memset(pirq->rfu, 0, sizeof(pirq->rfu));
-
-	pirq_info = (void *) ( &pirq->checksum + 1);
-	slot_num = 0;
-
-        {
-                device_t dev;
-                dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x04,3));
-                if (dev) {
-                        /* initialize PCI interupts - these assignments depend
-                        on the PCB routing of PINTA-D 
-
-                        PINTA = IRQ5
-                        PINTB = IRQ9
-                        PINTC = IRQ11
-                        PINTD = IRQ10
-                        */
-                        pci_write_config16(dev, 0x56, 0xab95);
-                }
-        }
-
-        printk_info("setting Onboard AMD Southbridge \n");
-        static const unsigned char slotIrqs_1_4[4] = { 5, 9, 11, 10 };
-        pci_assign_irqs(bus_chain_0, 4, slotIrqs_1_4);
-        write_pirq_info(pirq_info, bus_chain_0,(4<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0);
-	pirq_info++; slot_num++;
-	
-        printk_info("setting Onboard AMD USB \n");
-        static const unsigned char slotIrqs_8111_1_0[4] = { 0, 0, 0, 10 };
-        pci_assign_irqs(bus_8111_1, 0, slotIrqs_8111_1_0);
-        write_pirq_info(pirq_info, bus_8111_1,0, 0, 0, 0, 0, 0, 0, 0x4, 0xdef8, 0, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Onboard ATI Display Adapter\n");
-        static const unsigned char slotIrqs_8111_1_6[4] = { 11, 0, 0, 0 };
-        pci_assign_irqs(bus_8111_1, 6, slotIrqs_8111_1_6);
-        write_pirq_info(pirq_info, bus_8111_1,(6<<3)|0, 0x3, 0xdef8, 0, 0, 0, 0, 0, 0, 0, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Slot 1\n");
-        static const unsigned char slotIrqs_8131_2_3[4] = { 5, 9, 11, 10 };
-        pci_assign_irqs(bus_8131_2, 3, slotIrqs_8131_2_3);
-        write_pirq_info(pirq_info, bus_8131_2,(3<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Slot 2\n");
-        static const unsigned char slotIrqs_8131_2_1[4] = { 9, 11, 10, 5 };
-        pci_assign_irqs(bus_8131_2, 1, slotIrqs_8131_2_1);
-        write_pirq_info(pirq_info, bus_8131_2,(1<<3)|0, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Slot 3\n");
-        static const unsigned char slotIrqs_8131_1_3[4] = { 10, 5, 9, 11 };
-        pci_assign_irqs(bus_8131_1, 3, slotIrqs_8131_1_3);
-        write_pirq_info(pirq_info, bus_8131_1,(3<<3)|0, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x3, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Slot 4\n");
-        static const unsigned char slotIrqs_8131_1_2[4] = { 11, 10, 5, 9 };
-        pci_assign_irqs(bus_8131_1, 2, slotIrqs_8131_1_2);
-        write_pirq_info(pirq_info, bus_8131_1,(2<<3)|0, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0x4, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Slot 5 \n");
-        static const unsigned char slotIrqs_8111_1_4[4] = { 5, 9, 11, 10 };
-        pci_assign_irqs(bus_8111_1, 4, slotIrqs_8111_1_4);
-        write_pirq_info(pirq_info, bus_8111_1,(4<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x5, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Onboard SI Serail ATA\n");
-        static const unsigned char slotIrqs_8111_1_5[4] = { 10, 0, 0, 0 };
-        pci_assign_irqs(bus_8111_1, 5, slotIrqs_8111_1_5);
-        write_pirq_info(pirq_info, bus_8111_1,(5<<3)|0, 0x4, 0xdef8, 0, 0, 0, 0, 0, 0, 0, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Onboard Intel NIC\n");
-        static const unsigned char slotIrqs_8111_1_8[4] = { 11, 0, 0, 0 };
-        pci_assign_irqs(bus_8111_1, 8, slotIrqs_8111_1_8);
-        write_pirq_info(pirq_info, bus_8111_1,(8<<3)|0, 0x3, 0xdef8, 0, 0, 0, 0, 0, 0, 0, 0);
-	pirq_info++; slot_num++;
-
-        printk_info("setting Onboard Adaptec  SCSI\n");
-        static const unsigned char slotIrqs_8131_1_6[4] = { 5, 9, 0, 0 };
-        pci_assign_irqs(bus_8131_1, 6, slotIrqs_8131_1_6);
-        write_pirq_info(pirq_info, bus_8131_1,(6<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0, 0, 0, 0, 0, 0);
-	pirq_info++; slot_num++;
-#if 0
-	//??
-        write_pirq_info(pirq_info, bus_8131_1,(5<<3)|0, 0x3, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0, 0, 0, 0);
-	pirq_info++; slot_num++;
-#endif
-
-        printk_info("setting Onboard Broadcom NIC\n");
-        static const unsigned char slotIrqs_8131_1_9[4] = { 5, 9, 0, 0 };
-        pci_assign_irqs(bus_8131_1, 9, slotIrqs_8131_1_9);
-        write_pirq_info(pirq_info, bus_8131_1,(9<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0, 0, 0, 0, 0, 0);
-	pirq_info++; slot_num++;
-#if 0
-	//?? what's this?
-        write_pirq_info(pirq_info, bus_8131_2,(4<<3)|0, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x6, 0);
-	pirq_info++; slot_num++;
-#endif
-
-#if 0	
-	//?? what's this?
-        write_pirq_info(pirq_info, bus_8131_2,(5<<3)|0, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0x7, 0);
-	pirq_info++; slot_num++;
-#endif
-                
-	pirq->size = 32 + 16 * slot_num; 
-
-        for (i = 0; i < pirq->size; i++)
-                sum += v[i];	
-
-	sum = pirq->checksum - sum;
-
-        if (sum != pirq->checksum) {
-                pirq->checksum = sum;
-        }
-
-	return	(unsigned long) pirq_info;
-
+        return copy_pirq_routing_table(addr);
 }
diff --git a/src/mainboard/tyan/s2882/reset.c b/src/mainboard/tyan/s2882/reset.c
new file mode 100644
index 0000000..3db3956
--- /dev/null
+++ b/src/mainboard/tyan/s2882/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 0);
+}
diff --git a/src/mainboard/tyan/s2885/Config.lb b/src/mainboard/tyan/s2885/Config.lb
index a29c713..f6ea627 100644
--- a/src/mainboard/tyan/s2885/Config.lb
+++ b/src/mainboard/tyan/s2885/Config.lb
@@ -44,7 +44,7 @@
 
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 
 if USE_DCACHE_RAM
 
@@ -66,7 +66,7 @@
 
 end
 else
-
+  
 ##
 ## Romcc output
 ##
diff --git a/src/mainboard/tyan/s2885/Options.lb b/src/mainboard/tyan/s2885/Options.lb
index 7bc324e..79d60a3 100644
--- a/src/mainboard/tyan/s2885/Options.lb
+++ b/src/mainboard/tyan/s2885/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -87,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=3
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/tyan/s2885/auto.c b/src/mainboard/tyan/s2885/auto.c
index cff103b..8275f6d 100644
--- a/src/mainboard/tyan/s2885/auto.c
+++ b/src/mainboard/tyan/s2885/auto.c
@@ -26,20 +26,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {
+                        return (config_map >> 16) & 0xff;
+                }
+        }
+        return 0;
+}
+
 static void hard_reset(void)
 {
-        set_bios_reset();
+	device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3);
+
+	set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -192,7 +224,7 @@
 			|| (id.coreid != 0)
 #endif
 		) {
-                	stop_this_cpu(); 
+                	stop_this_cpu(); // it will stop all cores except core0 of cpu0
         	}
 	}
 	
@@ -223,4 +255,5 @@
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
 
+
 }
diff --git a/src/mainboard/tyan/s2885/cache_as_ram_auto.c b/src/mainboard/tyan/s2885/cache_as_ram_auto.c
index 3d27071..85d4da9 100644
--- a/src/mainboard/tyan/s2885/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s2885/cache_as_ram_auto.c
@@ -13,7 +13,6 @@
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
 
-
 #include "northbridge/amd/amdk8/cpu_rev.c"
 #define K8_HT_FREQ_1G_SUPPORT 0
 #include "northbridge/amd/amdk8/incoherent_ht.c"
@@ -38,20 +37,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -103,6 +134,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 
 #define FIRST_CPU  1
@@ -159,6 +192,7 @@
 
         enumerate_ht_chain();
 
+        /* Setup the ck804 */
         amd8111_enable_rom();
 
         /* Is this a deliberate reset by the bios */
@@ -296,15 +330,10 @@
         uart_init();
         console_init();
 
-	
 	/* Halt if there was a built in self test failure */
 	report_bist_failure(bist);
 
         setup_s2885_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
 
 	needs_reset = setup_coherent_ht_domain();
 	
@@ -319,17 +348,10 @@
        	}
 
 	enable_smbus();
-#if 0
-	dump_spd_registers(&cpu[0]);
-#endif
-#if 0
-	dump_smbus_registers();
-#endif
 
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-
 #if 1
         {
         /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
diff --git a/src/mainboard/tyan/s2885/mptable.c b/src/mainboard/tyan/s2885/mptable.c
index 2396ade..a9683d5 100644
--- a/src/mainboard/tyan/s2885/mptable.c
+++ b/src/mainboard/tyan/s2885/mptable.c
@@ -7,6 +7,42 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -51,9 +87,14 @@
        {
                 device_t dev;
 
+                /* HT chain 0 */
+                bus_8151_0 = node_link_to_bus(0, 0);
+                if (bus_8151_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_8151_0 = 1;
+                }
 		/* 8151 */
-		bus_8151_0 = 1;
-                dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
+                dev = dev_find_slot(bus_8151_0, PCI_DEVFN(0x02,0));
                 if (dev) {
                         bus_8151_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
 //                        printk_debug("bus_8151_1=%d\n",bus_8151_1);
diff --git a/src/mainboard/tyan/s2885/reset.c b/src/mainboard/tyan/s2885/reset.c
new file mode 100644
index 0000000..6395818
--- /dev/null
+++ b/src/mainboard/tyan/s2885/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 2);
+}
diff --git a/src/mainboard/tyan/s2891/Config.lb b/src/mainboard/tyan/s2891/Config.lb
index 53a7fee..6341926 100644
--- a/src/mainboard/tyan/s2891/Config.lb
+++ b/src/mainboard/tyan/s2891/Config.lb
@@ -346,12 +346,13 @@
 	end # pci_domain
 #       chip drivers/generic/debug                      
 #                device pnp 0.0 off end # chip name      
-#                device pnp 0.1 on end # pci_regs_all
+#                device pnp 0.1 off end # pci_regs_all
 #                device pnp 0.2 off end # mem
 #                device pnp 0.3 off end # cpuid
-#                device pnp 0.4 on end # smbus_regs_all
+#                device pnp 0.4 off end # smbus_regs_all
 #                device pnp 0.5 off end # dual core msr
 #                device pnp 0.6 off end # cache size
 #                device pnp 0.7 off end # tsc
+#		device pnp 0.8 on  end # hard_reset
 #       end 
 end # root_complex
diff --git a/src/mainboard/tyan/s2891/Options.lb b/src/mainboard/tyan/s2891/Options.lb
index 7147c69..58b052e 100644
--- a/src/mainboard/tyan/s2891/Options.lb
+++ b/src/mainboard/tyan/s2891/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -92,10 +89,6 @@
 ##
 default HAVE_HARD_RESET=1
 
-#default HARD_RESET_BUS=1
-#default HARD_RESET_DEVICE=4
-#default HARD_RESET_FUNCTION=0
-
 ##
 ## Build code to export a programmable irq routing table
 ##
@@ -134,7 +127,7 @@
 
 #CK804 setting
 
-default CK804_DEVN_BASE=0
+#default CK804_DEVN_BASE=0
 
 #BTEXT Console
 #default CONFIG_CONSOLE_BTEXT=1
diff --git a/src/mainboard/tyan/s2891/auto.c b/src/mainboard/tyan/s2891/auto.c
index 4a8ef3f..4637b4e 100644
--- a/src/mainboard/tyan/s2891/auto.c
+++ b/src/mainboard/tyan/s2891/auto.c
@@ -87,7 +87,6 @@
 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
 
 #define CK804_NUM 1
-#include "southbridge/nvidia/ck804/ck804_early_setup.h"
 #include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
 #include "southbridge/nvidia/ck804/ck804_early_setup.c"
 
@@ -136,6 +135,7 @@
                 enable_lapic();
                 init_timer();
 
+
 #if CONFIG_LOGICAL_CPUS==1
                 id = get_node_core_id_x();
                 if(id.coreid == 0) {
@@ -152,16 +152,19 @@
                 distinguish_cpu_resets(nodeid);
 #endif
 
+                post_code(0x31);
 
                 if (!boot_cpu()
 #if CONFIG_LOGICAL_CPUS==1 
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
 
+	post_code(0x32);
+	
  	w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE);
         uart_init();
         console_init();
@@ -174,6 +177,7 @@
 	needs_reset = setup_coherent_ht_domain();
 
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
         needs_reset |= ht_setup_chains_x();
@@ -190,5 +194,4 @@
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-
 }
diff --git a/src/mainboard/tyan/s2891/cache_as_ram_auto.c b/src/mainboard/tyan/s2891/cache_as_ram_auto.c
index ba2dfc1..b78a899 100644
--- a/src/mainboard/tyan/s2891/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s2891/cache_as_ram_auto.c
@@ -15,6 +15,7 @@
 
 #include "northbridge/amd/amdk8/cpu_rev.c"
 //#define K8_HT_FREQ_1G_SUPPORT 1
+//#define K8_SCAN_PCI_BUS 1
 #include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/nvidia/ck804/ck804_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
@@ -84,6 +85,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 
 #define FIRST_CPU  1
@@ -259,6 +262,7 @@
                                 goto cpu_reset_x;
                         }
                         distinguish_cpu_resets(id.nodeid);
+//                        start_other_core(id.nodeid);
                 }
 #else
                 if (cpu_init_detected(nodeid)) {
@@ -292,16 +296,14 @@
 	report_bist_failure(bist);
 
         setup_s2891_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
 
 	needs_reset = setup_coherent_ht_domain();
 	
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
+	// automatically set that for you, but you might meet tight space
         needs_reset |= ht_setup_chains_x();
 
         needs_reset |= ck804_early_setup_x();
@@ -312,20 +314,10 @@
        	}
 
 	enable_smbus();
-#if 0
-	dump_spd_registers(&cpu[0]);
-#endif
-#if 0
-	dump_smbus_registers();
-#endif
 
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-#if 0
-	dump_pci_devices();
-#endif
-
 #if 1
         {
         	/* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
@@ -342,6 +334,7 @@
         }
 
 #endif
+#if 1
 
 cpu_reset_x:
 
@@ -386,7 +379,7 @@
 			"movl %%ebx, %0\n\t"
 			:"=a" (new_cpu_reset)
 		);
-
+		
                 /* We can not go back any more, we lost old stack data in cache as ram*/
                 if(new_cpu_reset==0) {
                         print_debug("Use Ram as Stack now - done\r\n");
@@ -404,6 +397,7 @@
 		copy_and_run(new_cpu_reset);
 		/* We will not return */
 	}
+#endif
 
 
 	print_debug("should not be here -\r\n");
diff --git a/src/mainboard/tyan/s2891/irq_tables.c b/src/mainboard/tyan/s2891/irq_tables.c
index d6f75a0..0d880a2 100644
--- a/src/mainboard/tyan/s2891/irq_tables.c
+++ b/src/mainboard/tyan/s2891/irq_tables.c
@@ -18,7 +18,11 @@
 	0x005c,         /* Device */
 	0,         /* Crap (miniport) */
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
+#if CK804_DEVN_BASE==0
 	0x5a,         /*  u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
+#else
+	0x4a,
+#endif
 	{
 		{1,((CK804_DEVN_BASE+9)<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
 		{0x5,(1<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0},
diff --git a/src/mainboard/tyan/s2891/mptable.c b/src/mainboard/tyan/s2891/mptable.c
index e8d5f4c..e62ec6e 100644
--- a/src/mainboard/tyan/s2891/mptable.c
+++ b/src/mainboard/tyan/s2891/mptable.c
@@ -7,6 +7,41 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -52,22 +87,60 @@
        {
                 device_t dev;
 
+                bus_ck804_0 = node_link_to_bus(0, 0);
+                if (bus_ck804_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_ck804_0 = 1;
+                }
 
                 /* CK804 */
-		bus_ck804_0 = 1;
                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
                 if (dev) {
                         bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if 0
+                        bus_ck804_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_2++;
+#else 
                         bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
                         bus_ck804_4++;
+#endif
                 }
                 else {
                         printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09);
 
                         bus_ck804_1 = 2;
+#if 0
+                        bus_ck804_2 = 3;
+#else
                         bus_ck804_4 = 3;
+#endif
 
                 }
+#if 0
+                dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0));
+                if (dev) {
+                        bus_ck804_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_3++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0b);
+
+                        bus_ck804_3 = bus_ck804_2+1;
+                }
+
+                dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0));
+                if (dev) {
+                        bus_ck804_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_4++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0c);
+
+                        bus_ck804_4 = bus_ck804_3+1;
+                }
+#endif
                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0));
                 if (dev) {
                         bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
@@ -157,12 +230,9 @@
 	        	pci_write_config32(dev, 0x7c, dword);
 
 		        dword = 0x12008a00;
-
-
 		        pci_write_config32(dev, 0x80, dword);
 
 	        	dword = 0x0000007d;
-
 		        pci_write_config32(dev, 0x84, dword);
 
                 }
@@ -199,40 +269,51 @@
 	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xf, apicid_ck804, 0xf);
 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa);
+// 10
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); // 21
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); // 20
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); // 23
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); // 22
 
-#if 1
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 
+#if CK804_DEVN_BASE == 0 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 18
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // 
+#else
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x11); // 17
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x12); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x13); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x10); // 
 #endif
 
-#if 1
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // 
+#if CK804_DEVN_BASE == 0
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // 17
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x12); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x13); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x10); // 
+#else
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x10); // 16
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x11); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x12); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x13); // 
 #endif
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); // 19
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0); //
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0); //24+4+0 = 28
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x1);
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x0); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x0); // 24
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x1);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x2);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x3);//
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x2); //
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x2); // 26
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, apicid_8131_1, 0x3);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|2, apicid_8131_1, 0x0);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|3, apicid_8131_1, 0x1);//
diff --git a/src/mainboard/tyan/s2892/Options.lb b/src/mainboard/tyan/s2892/Options.lb
index 20b58bce..8a229a1 100644
--- a/src/mainboard/tyan/s2892/Options.lb
+++ b/src/mainboard/tyan/s2892/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -92,10 +89,6 @@
 ##
 default HAVE_HARD_RESET=1
 
-#default HARD_RESET_BUS=1
-#default HARD_RESET_DEVICE=4
-#default HARD_RESET_FUNCTION=0
-
 ##
 ## Build code to export a programmable irq routing table
 ##
diff --git a/src/mainboard/tyan/s2892/auto.c b/src/mainboard/tyan/s2892/auto.c
index d2512e9..2596705 100644
--- a/src/mainboard/tyan/s2892/auto.c
+++ b/src/mainboard/tyan/s2892/auto.c
@@ -142,7 +142,6 @@
                 enable_lapic();
                 init_timer();
 
-
 #if CONFIG_LOGICAL_CPUS==1
                 id = get_node_core_id_x();
                 if(id.coreid == 0) {
@@ -150,6 +149,7 @@
                                 asm volatile ("jmp __cpu_reset");
                         }
                         distinguish_cpu_resets(id.nodeid);
+//                        start_other_core(id.nodeid);
                 }
 #else
                 nodeid = lapicid();
@@ -164,7 +164,7 @@
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
 
@@ -174,13 +174,14 @@
         console_init();
 	
 	/* Halt if there was a built in self test failure */
-	report_bist_failure(bist);
+//	report_bist_failure(bist);
 
         setup_s2892_resource_map();
 
 	needs_reset = setup_coherent_ht_domain();
 
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
         needs_reset |= ht_setup_chains_x();
diff --git a/src/mainboard/tyan/s2892/cache_as_ram_auto.c b/src/mainboard/tyan/s2892/cache_as_ram_auto.c
index 30a78f5..5158bcc 100644
--- a/src/mainboard/tyan/s2892/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s2892/cache_as_ram_auto.c
@@ -86,6 +86,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 
 #define FIRST_CPU  1
@@ -295,15 +297,10 @@
 	report_bist_failure(bist);
 
         setup_s2892_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
 
 	needs_reset = setup_coherent_ht_domain();
 	
 #if CONFIG_LOGICAL_CPUS==1
-        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
         needs_reset |= ht_setup_chains_x();
@@ -316,19 +313,10 @@
        	}
 
 	enable_smbus();
-#if 0
-	dump_spd_registers(&cpu[0]);
-#endif
-#if 0
-	dump_smbus_registers();
-#endif
 
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-#if 0
-	dump_pci_devices();
-#endif
 
 #if 1
         {
@@ -346,6 +334,7 @@
         }
 
 #endif
+#if 1
 
 cpu_reset_x:
 
@@ -408,6 +397,7 @@
 		copy_and_run(new_cpu_reset);
 		/* We will not return */
 	}
+#endif
 
 
 	print_debug("should not be here -\r\n");
diff --git a/src/mainboard/tyan/s2892/mptable.c b/src/mainboard/tyan/s2892/mptable.c
index b4f26aa..02754a1 100644
--- a/src/mainboard/tyan/s2892/mptable.c
+++ b/src/mainboard/tyan/s2892/mptable.c
@@ -7,6 +7,41 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -52,22 +87,60 @@
        {
                 device_t dev;
 
+                bus_ck804_0 = node_link_to_bus(0, 0);
+                if (bus_ck804_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_ck804_0 = 1;
+                }
 
                 /* CK804 */
-		bus_ck804_0 = 1;
                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
                 if (dev) {
                         bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if 0
+                        bus_ck804_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_2++;
+#else 
                         bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
                         bus_ck804_4++;
+#endif
                 }
                 else {
                         printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09);
 
                         bus_ck804_1 = 2;
+#if 0
+                        bus_ck804_2 = 3;
+#else
                         bus_ck804_4 = 3;
+#endif
 
                 }
+#if 0
+                dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0));
+                if (dev) {
+                        bus_ck804_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_3++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0b);
+
+                        bus_ck804_3 = bus_ck804_2+1;
+                }
+
+                dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0));
+                if (dev) {
+                        bus_ck804_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_4++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0c);
+
+                        bus_ck804_4 = bus_ck804_3+1;
+                }
+#endif
                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0));
                 if (dev) {
                         bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
@@ -152,6 +225,8 @@
 				smp_write_ioapic(mc, apicid_ck804, 0x11, res->base);
 			}
         
+	/* Initialize interrupt mapping*/
+
 			dword = 0x0000d218;
 	        	pci_write_config32(dev, 0x7c, dword);
 
@@ -195,57 +270,77 @@
 	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xf, apicid_ck804, 0xf);
 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa);
+// 10
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); // 21
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); // 20
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); // 23
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); // 22
 
-#if 1
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 
+#if CK804_DEVN_BASE == 0
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 18
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // 
+#else
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x11); // 17
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x12); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x13); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x10); // 
 #endif
 
-#if 1
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // 
+#if CK804_DEVN_BASE == 0
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // 17
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x12); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x13); // 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x10); // 
+#else
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x10); // 16
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x11); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x12); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x13); // 
 #endif
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // 
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (6<<2)|0, apicid_ck804, 0x12); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (8<<2)|0, apicid_ck804, 0x12); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // 16
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // 17
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // 18
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // 19
+
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (6<<2)|0, apicid_ck804, 0x12); // 18
+
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (8<<2)|0, apicid_ck804, 0x12); // 18
+
+//Channel B of 8131
 
 
-
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0);//
+//Onboard Broadcom NIC
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0);//24+4= 28
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x1);
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (7<<2)|0, apicid_8131_2, 0x0);// 
+//SO DIMM PCI-X
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (7<<2)|0, apicid_8131_2, 0x0);//28 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (7<<2)|1, apicid_8131_2, 0x1); 
-
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x2); // 
+//Slot 4 PCIX 133/100/66
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x2); // 30
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, apicid_8131_2, 0x3);//
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, apicid_8131_2, 0x0);// 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, apicid_8131_2, 0x0);// 28
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x1);//
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, apicid_8131_1, 0x3); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, apicid_8131_1, 0x0);//
+//Channel A of 8131
+
+//Slot 5 PCIX 133/100/66        
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, apicid_8131_1, 0x3); //28 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, apicid_8131_1, 0x0);//24
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|2, apicid_8131_1, 0x1);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|3, apicid_8131_1, 0x2);//
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); // 
+//Slot 6 PCIX 133/100/66 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); // 27
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|1, apicid_8131_1, 0x3);//
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, apicid_8131_1, 0x0);// 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, apicid_8131_1, 0x0);// 24
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|3, apicid_8131_1, 0x1);//
 
 
diff --git a/src/mainboard/tyan/s2895/Options.lb b/src/mainboard/tyan/s2895/Options.lb
index e2d2202..fc63823 100644
--- a/src/mainboard/tyan/s2895/Options.lb
+++ b/src/mainboard/tyan/s2895/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -90,10 +87,6 @@
 ##
 default HAVE_HARD_RESET=1
 
-#default HARD_RESET_BUS=1
-#default HARD_RESET_DEVICE=4
-#default HARD_RESET_FUNCTION=0
-
 ##
 ## Build code to export a programmable irq routing table
 ##
@@ -134,7 +127,7 @@
 default K8_E0_MEM_HOLE_SIZEK=0x100000
 
 #CK804 setting
-default CK804_DEVN_BASE=0
+#default CK804_DEVN_BASE=0
 
 #VGA
 default CONFIG_CONSOLE_VGA=1
diff --git a/src/mainboard/tyan/s2895/auto.c b/src/mainboard/tyan/s2895/auto.c
index b6f121e..0a26f21 100644
--- a/src/mainboard/tyan/s2895/auto.c
+++ b/src/mainboard/tyan/s2895/auto.c
@@ -14,7 +14,7 @@
 #include "ram/ramtest.c"
 
 #include "northbridge/amd/amdk8/cpu_rev.c"
-#define K8_HT_FREQ_1G_SUPPORT 1
+//#define K8_HT_FREQ_1G_SUPPORT 1
 #include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/nvidia/ck804/ck804_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
@@ -70,8 +70,9 @@
 
 	unsigned value;
 
+//	lpc47b397_enable_serial(SUPERIO_GPIO_DEV, SUPERIO_GPIO_IO_BASE); // Already enable in failover.c
+
 #if 1
-	/*Enable onboard scsi*/
 	lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x2c, (1<<7)|(0<<2)|(0<<1)|(0<<0)); // GP21, offset 0x2c, DISABLE_SCSI_L 
 	value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x4c);
 	lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x4c, (value|(1<<1)));
@@ -117,10 +118,9 @@
 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
 
 #define CK804_NUM 2
-#define CK804B_BUSN 0xc
+#define CK804B_BUSN 0x80
 #define CK804_USE_NIC 1
 #define CK804_USE_ACI 1
-#include "southbridge/nvidia/ck804/ck804_early_setup.h"
 #include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
 
 //set GPIO to input mode
@@ -192,11 +192,12 @@
                 enable_lapic();
                 init_timer();
 
+                post_code(0x30);
 
 #if CONFIG_LOGICAL_CPUS==1
         #if ENABLE_APIC_EXT_ID == 1
             #if LIFT_BSP_APIC_ID == 0
-                if( id.nodeid != 0 ) 
+                if( id.nodeid != 0 ) //all except cores in node0
             #endif
                         lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) );
         #endif
@@ -213,7 +214,7 @@
             #if LIFT_BSP_APIC_ID == 0
                 if(nodeid != 0)
             #endif
-                        lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); 
+                        lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10
 
         #endif
 
@@ -223,16 +224,18 @@
                 distinguish_cpu_resets(nodeid);
 #endif
 
+                post_code(0x31);
 
                 if (!boot_cpu()
 #if CONFIG_LOGICAL_CPUS==1 
                         || (id.coreid != 0)
 #endif
                 ) {
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
 
+	post_code(0x32);
 
         lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE);
         uart_init();
@@ -247,6 +250,7 @@
 
 	needs_reset = setup_coherent_ht_domain();
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
 
diff --git a/src/mainboard/tyan/s2895/cache_as_ram_auto.c b/src/mainboard/tyan/s2895/cache_as_ram_auto.c
index fde94cc..2cf73c3 100644
--- a/src/mainboard/tyan/s2895/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s2895/cache_as_ram_auto.c
@@ -13,9 +13,10 @@
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
 
-
 #include "northbridge/amd/amdk8/cpu_rev.c"
-#define K8_HT_FREQ_1G_SUPPORT 0
+#define K8_HT_FREQ_1G_SUPPORT 1
+#define K8_ALLOCATE_IO_RANGE 1
+//#define K8_SCAN_PCI_BUS 1
 #include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/nvidia/ck804/ck804_early_smbus.c"
 #include "northbridge/amd/amdk8/raminit.h"
@@ -75,13 +76,11 @@
 
         unsigned value;
 
+//      lpc47b397_enable_serial(SUPERIO_GPIO_DEV, SUPERIO_GPIO_IO_BASE); // Already enable in failover.c
 
-#if 1
-        /*Enable onboard scsi*/
         lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x2c, (1<<7)|(0<<2)|(0<<1)|(0<<0)); // GP21, offset 0x2c, DISABLE_SCSI_L 
         value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x4c);
         lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x4c, (value|(1<<1)));
-#endif
 
 }
 
@@ -114,6 +113,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 
 #define FIRST_CPU  1
@@ -121,8 +122,7 @@
 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
 
 #define CK804_NUM 2
-//#define CK804B_BUSN 0x80
-#define CK804B_BUSN 0xc
+#define CK804B_BUSN 0x80
 #define CK804_USE_NIC 1
 #define CK804_USE_ACI 1
 
@@ -155,13 +155,18 @@
         uint8_t byte;
 
         
+        /* LPC Variable Range Decode 1 0x400-0x47f */
+        /* to make sure lpc47b397 gpio on device work */
         pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1, 0), 0xac, 0x047f0400);
         
+        /* subject decoding*/
         byte = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b);
         byte |= 0x20; 
         pci_write_config8(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b, byte);
         
+        /* LPC Positive Decode 0 */
         dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0);
+        /*decode VAR1, serial 0 */
         dword |= (1<<29)|(1<<0);
         pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0, dword);
         
@@ -311,7 +316,7 @@
 
 		enable_lapic();
 
-                init_timer();
+//                init_timer();
 
 
 #if CONFIG_LOGICAL_CPUS==1
@@ -323,10 +328,12 @@
         #endif
                 if(id.coreid == 0) {
                         if (cpu_init_detected(id.nodeid)) {
+//                                __asm__ volatile ("jmp __cpu_reset");
                                 cpu_reset = 1;
                                 goto cpu_reset_x;
                         }
                         distinguish_cpu_resets(id.nodeid);
+//                        start_other_core(id.nodeid);
                 }
 #else
         #if ENABLE_APIC_EXT_ID == 1
@@ -337,6 +344,7 @@
 
         #endif
                 if (cpu_init_detected(nodeid)) {
+//                                __asm__ volatile ("jmp __cpu_reset");
                                 cpu_reset = 1;
                                 goto cpu_reset_x;
                 }
@@ -355,6 +363,8 @@
                 }
         }
 
+	init_timer(); // only do it it first CPU
+
 
 	lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE);
         uart_init();
@@ -364,10 +374,6 @@
 	report_bist_failure(bist);
 
         setup_s2895_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
 
 	needs_reset = setup_coherent_ht_domain();
 
@@ -376,15 +382,7 @@
         start_other_cores();
 #endif
 
-#if CK804B_BUSN == 0x80 
-        // You need to preset bus num in PCI_DEV(0, 0x18,1) 0xe0, 0xe4, 0xe8, 0xec
-        needs_reset |= ht_setup_chains(3);
-#else
-        // automatically set that for you, but you might meet tight space
-        // Bcause it has two Ck804, we need to set CK804B_BUSN to 0xc (ht_setup_chains_x will let second CK804 use that bus num.    
-    // otherwise ck804_eary_setup can not work rightly.
         needs_reset |= ht_setup_chains_x();
-#endif
 
         needs_reset |= ck804_early_setup_x();
 
@@ -394,20 +392,10 @@
        	}
 
 	enable_smbus();
-#if 0
-	dump_spd_registers(&cpu[0]);
-#endif
-#if 0
-	dump_smbus_registers();
-#endif
 
 	memreset_setup();
 	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-#if 0
-	dump_pci_devices();
-#endif
-
 #if 1
 	{	
 	/* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
@@ -424,6 +412,7 @@
 	}
 
 #endif
+#if 1
 
 cpu_reset_x:    
 
@@ -486,6 +475,7 @@
                 copy_and_run(new_cpu_reset);
                 /* We will not return */
         }
+#endif
 
 
         print_err("should not be here -\r\n");
diff --git a/src/mainboard/tyan/s2895/irq_tables.c b/src/mainboard/tyan/s2895/irq_tables.c
index cf1a438..aa16866 100644
--- a/src/mainboard/tyan/s2895/irq_tables.c
+++ b/src/mainboard/tyan/s2895/irq_tables.c
@@ -403,6 +403,8 @@
                 pirq->checksum = sum;
         }
 
+	printk_info("done.\n");
+
 	return	(unsigned long) pirq_info;
 
 }
diff --git a/src/mainboard/tyan/s2895/mptable.c b/src/mainboard/tyan/s2895/mptable.c
index f6b534d..810e234 100644
--- a/src/mainboard/tyan/s2895/mptable.c
+++ b/src/mainboard/tyan/s2895/mptable.c
@@ -8,6 +8,41 @@
 #include <cpu/amd/dualcore.h>
 #endif
 
+
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        device_t dev;
+        unsigned reg;
+
+        dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+        if (!dev) {
+                return 0;
+        }
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                uint32_t config_map;
+                unsigned dst_node;
+                unsigned dst_link;
+                unsigned bus_base;
+                config_map = pci_read_config32(dev, reg);
+                if ((config_map & 3) != 3) {
+                        continue;
+                }
+                dst_node = (config_map >> 4) & 7;
+                dst_link = (config_map >> 8) & 3;
+                bus_base = (config_map >> 16) & 0xff;
+#if 0                           
+                printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
+                        dst_node, dst_link, bus_base,
+                        reg, config_map);
+#endif
+                if ((dst_node == node) && (dst_link == link))
+                {
+                        return bus_base;
+                }
+        }
+        return 0;
+}
+
 void *smp_write_config_table(void *v)
 {
         static const char sig[4] = "PCMP";
@@ -62,21 +97,71 @@
                 device_t dev;
 
 
+                bus_ck804_0 = node_link_to_bus(0, 0);
+                if (bus_ck804_0 == 0) {
+                        printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
+                        bus_ck804_0 = 1;
+                }
                 /* CK804 */
-		bus_ck804_0 = 1;
                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
                 if (dev) {
                         bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+#if 0
+			bus_ck804_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+			bus_ck804_2++;
+#else 
                         bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
                         bus_ck804_5++;
+#endif
                 }
                 else {
                         printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09);
 
                         bus_ck804_1 = 2;
+#if 0
+			bus_ck804_2 = 3;
+#else
 			bus_ck804_5 = 3;
+#endif
 
                 }
+#if 0                
+		dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0));
+                if (dev) {
+                        bus_ck804_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_3++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0b);
+
+                        bus_ck804_3 = bus_ck804_2+1;
+                }
+
+                dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0));
+                if (dev) {
+                        bus_ck804_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_4++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0c);
+
+                        bus_ck804_4 = bus_ck804_3+1;
+                }
+
+                dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0));
+                if (dev) {
+                        bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804_5++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0d);
+
+                        bus_ck804_5 = bus_ck804_4+1;
+                }
+#endif
 
                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0));
                 if (dev) {
@@ -119,6 +204,59 @@
 
                 /* CK804b */
 
+#if 0
+                dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
+                if (dev) {
+                        bus_ck804b_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804b_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804b_2++;
+                }       
+                else {  
+                        printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x09);
+                
+                        bus_ck804b_1 = bus_ck804b_0+1;
+                        bus_ck804b_2 = bus_ck804b_0+2;
+                }
+                        
+                dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0));
+                if (dev) {
+                        bus_ck804b_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804b_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804b_3++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0b);
+
+                        bus_ck804b_2 = bus_ck804b_0+1;
+                        bus_ck804b_3 = bus_ck804b_0+2;
+                }
+
+                dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0));
+                if (dev) {
+                        bus_ck804b_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804b_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804b_4++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0c);
+
+                        bus_ck804b_4 = bus_ck804b_3+1;
+                }
+
+                dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0));
+                if (dev) {
+                        bus_ck804b_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
+                        bus_ck804b_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
+                        bus_ck804b_5++;
+                }
+                else {
+                        printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0d);
+
+                     	bus_ck804b_5 = bus_ck804b_4+1;
+                }
+
+#endif
+
                 dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0));
                 if (dev) {
                         bus_ck804b_5 = pci_read_config8(dev, PCI_SECONDARY_BUS);
@@ -168,7 +306,7 @@
 				smp_write_ioapic(mc, apicid_ck804, 0x11, res->base);
 			}
 
-			dword = 0x0120d218;
+			dword = 0x0000d218;
 	        	pci_write_config32(dev, 0x7c, dword);
 
 		        dword = 0x12008a00;
@@ -229,58 +367,77 @@
 	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xf, apicid_ck804, 0xf);
 
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa);
+// 10
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); // 21
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); // 20
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+4)<<2)|0, apicid_ck804, 0x14); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+4)<<2)|0, apicid_ck804, 0x14); // 20
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); // 23
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); // 22
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +0x0a)<<2)|0, apicid_ck804, 0x15); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +0x0a)<<2)|0, apicid_ck804, 0x15); // 21
 
-#if 1
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // 
+#if CK804_DEVN_BASE == 0
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 18
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // 19
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // 16
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // 17
+#else
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x11); // 17
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x12); // 18
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x13); // 19
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x10); // 16
 #endif
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x05<<2)|0, apicid_ck804, 0x13); // 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x05<<2)|0, apicid_ck804, 0x13); // 19
 
-	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // 
+	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // 16
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // 17
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // 18
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // 19
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_0, ((CK804_DEVN_BASE+0x0a)<<2)|0, apicid_ck804b, 0x15);//
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_0, ((CK804_DEVN_BASE+0x0a)<<2)|0, apicid_ck804b, 0x15);//24+4+4+21=53
 
-#if 1
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x12);//
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x13); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x10); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x11); // 
+#if CK804_DEVN_BASE == 0
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x12);//18+24+4+4=50
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x13); // 19
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x10); // 16
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x11); // 17
+#else
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x11);
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x12); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x13); 
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x10); 
 #endif
 
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|0, apicid_8131_2, 0x0); //
+//Channel B of 8131
+
+//Slot 4 PCI-X 100/66
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|0, apicid_8131_2, 0x0); //24+4 = 28
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|1, apicid_8131_2, 0x1);
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|2, apicid_8131_2, 0x2); //
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|3, apicid_8131_2, 0x3); //
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x1); //
+//Slot 5 PCIX 100/66
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x1); //24+4+1 = 29
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x2);
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|2, apicid_8131_2, 0x3);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|3, apicid_8131_2, 0x0);//
 
+//OnBoard LSI SCSI
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x2); // 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x3);
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x2); // 24+4+2 = 30
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x3);	//	31
 
-        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); // 
+//Channel A of 8131
+
+//Slot 6 PCIX 133/100/66        
+        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); // 24
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|1, apicid_8131_1, 0x1);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|2, apicid_8131_1, 0x2);//
         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|3, apicid_8131_1, 0x3);//
diff --git a/src/mainboard/tyan/s4880/Config.lb b/src/mainboard/tyan/s4880/Config.lb
index 3b3806f..e3c5b03 100644
--- a/src/mainboard/tyan/s4880/Config.lb
+++ b/src/mainboard/tyan/s4880/Config.lb
@@ -43,7 +43,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-##object reset.o
+object reset.o
 if USE_DCACHE_RAM
 
 	if CONFIG_USE_INIT
diff --git a/src/mainboard/tyan/s4880/Options.lb b/src/mainboard/tyan/s4880/Options.lb
index f3d7351..fc98b83 100644
--- a/src/mainboard/tyan/s4880/Options.lb
+++ b/src/mainboard/tyan/s4880/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -87,14 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-##
-default HARD_RESET_BUS=3
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
diff --git a/src/mainboard/tyan/s4880/auto.c b/src/mainboard/tyan/s4880/auto.c
index fc1bf58..3e0d482 100644
--- a/src/mainboard/tyan/s4880/auto.c
+++ b/src/mainboard/tyan/s4880/auto.c
@@ -95,65 +95,6 @@
    }
 }
 
-#if 0
-static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes)
-{
-	/* Routing Table Node i 
-	 *
-	 * F0: 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c 
-	 *  i:    0,    1,    2,    3,    4,    5,    6,    7
-	 *
-	 * [ 0: 3] Request Route
-	 *     [0] Route to this node
-	 *     [1] Route to Link 0
-	 *     [2] Route to Link 1
-	 *     [3] Route to Link 2
-	 * [11: 8] Response Route
-	 *     [0] Route to this node
-	 *     [1] Route to Link 0
-	 *     [2] Route to Link 1
-	 *     [3] Route to Link 2
-	 * [19:16] Broadcast route
-	 *     [0] Route to this node
-	 *     [1] Route to Link 0
-	 *     [2] Route to Link 1
-	 *     [3] Route to Link 2
-	 */
-        uint32_t ret=0x00010101; /* default row entry */
-
-/*
-            (L1)       (L2)     
-        CPU3-------------CPU1
-     (L0)|                |(L0)
-         |                |
-         |                |
-         |                |
-         |                |
-     (L0)|                |(L0)
-        CPU2-------------CPU0---------8131----------8111
-            (L2)       (L1)  (L2)       
-*/
-
-        /* Link0 of CPU0 to Link0 of CPU1 */
-        /* Link1 of CPU0 to Link2 of CPU2 */
-        /* Link2 of CPU1 to Link1 of CPU3 */
-        /* Link0 of CPU2 to Link0 of CPU3 */
-
-        static const unsigned int rows_4p[4][4] = {
-                { 0x00070101, 0x00010202, 0x00030404, 0x00010204 },
-                { 0x00010202, 0x000b0101, 0x00010208, 0x00030808 },
-                { 0x00030808, 0x00010208, 0x000b0101, 0x00010202 },
-                { 0x00010204, 0x00030404, 0x00010202, 0x00070101 }
-        };
-        
-        if (!(node>=maxnodes || row>=maxnodes)) {
-		ret=rows_4p[node][row];
-        }
-
-        return ret;
-}
-#endif
-
 static inline void activate_spd_rom(const struct mem_controller *ctrl)
 {
 #define SMBUS_HUB 0x18
@@ -161,6 +102,14 @@
         smbus_write_byte(SMBUS_HUB , 0x01, device);
         smbus_write_byte(SMBUS_HUB , 0x03, 0);
 }
+#if 0
+static inline void change_i2c_mux(unsigned device)
+{
+#define SMBUS_HUB 0x18
+        smbus_write_byte(SMBUS_HUB , 0x01, device);
+        smbus_write_byte(SMBUS_HUB , 0x03, 0);
+}
+#endif
 
 static inline int spd_read_byte(unsigned device, unsigned address)
 {
@@ -308,22 +257,19 @@
         needs_reset = setup_coherent_ht_domain();
 
 #if CONFIG_LOGICAL_CPUS==1
-        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
 
-#if 0
-        needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0);
-#else
-        // automatically set that for you, but you might meet tight space
         needs_reset |= ht_setup_chains_x();
-#endif
 	
         if (needs_reset) {
                 print_info("ht reset -\r\n");
                 soft_reset();
         }
 	
+#if 0
+	dump_pci_devices();
+#endif
 	enable_smbus();
 
 	memreset_setup();
diff --git a/src/mainboard/tyan/s4880/cache_as_ram_auto.c b/src/mainboard/tyan/s4880/cache_as_ram_auto.c
index f39ff15..bddcd08 100644
--- a/src/mainboard/tyan/s4880/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s4880/cache_as_ram_auto.c
@@ -325,6 +325,7 @@
                 enable_lapic();
                 init_timer();
 
+//                post_code(0x30);
 
 #if CONFIG_LOGICAL_CPUS==1
         #if ENABLE_APIC_EXT_ID == 1
@@ -355,7 +356,6 @@
                 distinguish_cpu_resets(nodeid);
 #endif
 
-
                 if (!boot_cpu()
 #if CONFIG_LOGICAL_CPUS==1 
                         || (id.coreid != 0)
@@ -380,9 +380,9 @@
 	needs_reset = setup_coherent_ht_domain();
 	
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
-
         needs_reset |= ht_setup_chains_x();
 
        	if (needs_reset) {
diff --git a/src/mainboard/tyan/s4880/reset.c b/src/mainboard/tyan/s4880/reset.c
new file mode 100644
index 0000000..6395818
--- /dev/null
+++ b/src/mainboard/tyan/s4880/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 2);
+}
diff --git a/src/mainboard/tyan/s4882/Config.lb b/src/mainboard/tyan/s4882/Config.lb
index 95ef046..18fec09 100644
--- a/src/mainboard/tyan/s4882/Config.lb
+++ b/src/mainboard/tyan/s4882/Config.lb
@@ -43,7 +43,7 @@
 driver mainboard.o
 if HAVE_MP_TABLE object mptable.o end
 if HAVE_PIRQ_TABLE object irq_tables.o end
-#object reset.o
+object reset.o
 if USE_DCACHE_RAM
 
 	if CONFIG_USE_INIT
diff --git a/src/mainboard/tyan/s4882/Options.lb b/src/mainboard/tyan/s4882/Options.lb
index 56a2548..0c5571a 100644
--- a/src/mainboard/tyan/s4882/Options.lb
+++ b/src/mainboard/tyan/s4882/Options.lb
@@ -3,9 +3,6 @@
 uses USE_FALLBACK_IMAGE
 uses HAVE_FALLBACK_BOOT
 uses HAVE_HARD_RESET
-uses HARD_RESET_BUS
-uses HARD_RESET_DEVICE
-uses HARD_RESET_FUNCTION
 uses IRQ_SLOT_COUNT
 uses HAVE_OPTION_TABLE
 uses CONFIG_MAX_CPUS
@@ -31,9 +28,9 @@
 uses LB_CKS_RANGE_START
 uses LB_CKS_RANGE_END
 uses LB_CKS_LOC
+uses MAINBOARD
 uses MAINBOARD_PART_NUMBER
 uses MAINBOARD_VENDOR
-uses MAINBOARD
 uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
 uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
 uses LINUXBIOS_EXTRA_VERSION
@@ -87,13 +84,6 @@
 default HAVE_HARD_RESET=1
 
 ##
-## Funky hard reset implementation
-## 
-default HARD_RESET_BUS=3
-default HARD_RESET_DEVICE=4
-default HARD_RESET_FUNCTION=0
-
-##
 ## Build code to export a programmable irq routing table
 ##
 default HAVE_PIRQ_TABLE=1
@@ -153,8 +143,8 @@
 ##
 ## Clean up the motherboard id strings
 ##
-default MAINBOARD_PART_NUMBER="s4882"
 default MAINBOARD_VENDOR="Tyan"
+default MAINBOARD_PART_NUMBER="s4882"
 default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1
 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x4882
 
diff --git a/src/mainboard/tyan/s4882/auto.c b/src/mainboard/tyan/s4882/auto.c
index 21d459b..e8d46e7 100644
--- a/src/mainboard/tyan/s4882/auto.c
+++ b/src/mainboard/tyan/s4882/auto.c
@@ -26,26 +26,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
-        set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
-}
+        device_t dev;
 
-static void soft2_reset(void)
-{  
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(3, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -73,6 +99,7 @@
 #define SMBUS_HUB 0x18
 	int ret,i;
         unsigned device=(ctrl->channel0[0])>>8;
+	/* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
 	i=2;
 	do {
 	        ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
@@ -194,7 +221,7 @@
 #if CONFIG_LOGICAL_CPUS==1
                 set_apicid_cpuid_lo();
 
-                id = get_node_core_id_x(); 
+                id = get_node_core_id_x(); // that is initid
         #if ENABLE_APIC_EXT_ID == 1
                 if(id.coreid == 0) {
                         enable_apic_ext_id(id.nodeid);
@@ -213,7 +240,7 @@
 #if CONFIG_LOGICAL_CPUS==1
         #if ENABLE_APIC_EXT_ID == 1
             #if LIFT_BSP_APIC_ID == 0
-                if( id.nodeid != 0 ) 
+                if( id.nodeid != 0 ) //all except cores in node0
             #endif
                         lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) );
         #endif
@@ -241,7 +268,7 @@
                         || (id.coreid != 0)
 #endif          
                 ) {     
-                        stop_this_cpu(); 
+                        stop_this_cpu(); // it will stop all cores except core0 of cpu0
                 }
         }
                         
@@ -257,10 +284,10 @@
         needs_reset = setup_coherent_ht_domain();
 
 #if CONFIG_LOGICAL_CPUS==1
+        // It is said that we should start core1 after all core0 launched
         start_other_cores();
 #endif
 
-        // automatically set that for you, but you might meet tight space
         needs_reset |= ht_setup_chains_x();
         if (needs_reset) {
                 print_info("ht reset -\r\n");
diff --git a/src/mainboard/tyan/s4882/cache_as_ram_auto.c b/src/mainboard/tyan/s4882/cache_as_ram_auto.c
index bbcc49a..234e3a0 100644
--- a/src/mainboard/tyan/s4882/cache_as_ram_auto.c
+++ b/src/mainboard/tyan/s4882/cache_as_ram_auto.c
@@ -37,20 +37,52 @@
 
 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
 
+/* Look up a which bus a given node/link combination is on.
+ * return 0 when we can't find the answer.
+ */
+static unsigned node_link_to_bus(unsigned node, unsigned link)
+{
+        unsigned reg;
+        
+        for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+                unsigned config_map;
+                config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+                if ((config_map & 3) != 3) {
+                        continue; 
+                }       
+                if ((((config_map >> 4) & 7) == node) &&
+                        (((config_map >> 8) & 3) == link))
+                {       
+                        return (config_map >> 16) & 0xff;
+                }       
+        }       
+        return 0;
+}       
+
 static void hard_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 3);
+
         set_bios_reset();
 
         /* enable cf9 */
-        pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
+        pci_write_config8(dev, 0x41, 0xf1);
         /* reset */
         outb(0x0e, 0x0cf9);
 }
 
 static void soft_reset(void)
 {
+        device_t dev;
+
+        /* Find the device */
+        dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 0);
+
         set_bios_reset();
-        pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
+        pci_write_config8(dev, 0x47, 1);
 }
 
 static void memreset_setup(void)
@@ -77,6 +109,7 @@
 #define SMBUS_HUB 0x18
         int ret,i;
         unsigned device=(ctrl->channel0[0])>>8;
+        /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
         i=2;
         do {
                 ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
@@ -109,6 +142,8 @@
 #if CONFIG_LOGICAL_CPUS==1
 #define SET_NB_CFG_54 1
 #include "cpu/amd/dualcore/dualcore.c"
+#else
+#include "cpu/amd/model_fxx/node_id.c"
 #endif
 #define FIRST_CPU  1
 #define SECOND_CPU 1
@@ -325,7 +360,6 @@
                 distinguish_cpu_resets(nodeid);
 #endif
 
-
                 if (!boot_cpu()
 #if CONFIG_LOGICAL_CPUS==1 
                         || (id.coreid != 0)
@@ -337,22 +371,15 @@
                 }
         }
 
-	
  	w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE);
         uart_init();
         console_init();
 
-	dump_mem(DCACHE_RAM_BASE+DCACHE_RAM_SIZE-0x200, DCACHE_RAM_BASE+DCACHE_RAM_SIZE);
-	
 	/* Halt if there was a built in self test failure */
 	report_bist_failure(bist);
 
         setup_s4882_resource_map();
-#if 0
-        dump_pci_device(PCI_DEV(0, 0x18, 0));
-	dump_pci_device(PCI_DEV(0, 0x19, 0));
-#endif
-
+	
 	needs_reset = setup_coherent_ht_domain();
 	
 #if CONFIG_LOGICAL_CPUS==1
@@ -387,6 +414,7 @@
         }
 #endif
 
+#if 1
 
 
 cpu_reset_x:
@@ -450,6 +478,7 @@
 		copy_and_run(new_cpu_reset);
 		/* We will not return */
 	}
+#endif
 
 
 	print_debug("should not be here -\r\n");
diff --git a/src/mainboard/tyan/s4882/reset.c b/src/mainboard/tyan/s4882/reset.c
new file mode 100644
index 0000000..7f58d01
--- /dev/null
+++ b/src/mainboard/tyan/s4882/reset.c
@@ -0,0 +1,6 @@
+#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
+
+void hard_reset(void)
+{
+	amd8111_hard_reset(0, 1);
+}
diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c
index d7be557..c79a432 100644
--- a/src/northbridge/amd/amdk8/coherent_ht.c
+++ b/src/northbridge/amd/amdk8/coherent_ht.c
@@ -145,15 +145,16 @@
 
 	print_spew("Disabling read/write/fill probes for UP... ");
 
-	val=pci_read_config32(NODE_HT(0), 0x68);
-	val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
-	pci_write_config32(NODE_HT(0), 0x68, val);
+	val=pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL);
+	val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C |
+		HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P | 
+		HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P;
+	pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val);
 
 	print_spew("done.\r\n");
 
 }
 
-
 #ifndef ENABLE_APIC_EXT_ID
 #define ENABLE_APIC_EXT_ID 0 
 #endif
@@ -163,7 +164,7 @@
 #if ENABLE_APIC_EXT_ID==1
 #warning "FIXME Is the right place to enable apic ext id here?"
 
-	u32 val;
+      u32 val;
 
         val = pci_read_config32(NODE_HT(node), 0x68);
         val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
@@ -171,8 +172,6 @@
 #endif
 }
 
-
-
 static void enable_routing(u8 node)
 {
 	u32 val;
@@ -277,11 +276,11 @@
 }
 #endif
 
-static int check_connection(u8 dest)
+static int verify_connection(u8 dest)
 {
 	/* See if we have a valid connection to dest */
 	u32 val;
-
+	
 	/* Verify that the coherent hypertransport link is
 	 * established and actually working by reading the
 	 * remode node's vendor/device id
@@ -289,10 +288,6 @@
         val = pci_read_config32(NODE_HT(dest),0);
 	if(val != 0x11001022)
 		return 0;
-// needed?
-#if K8_HT_CHECK_PENDING_LINK == 1
-	wait_ht_stable(dest);
-#endif
 
 	return 1;
 }
@@ -306,11 +301,11 @@
 	freq_cap = pci_read_config16(dev, pos);
 	freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
 
-
-        #if K8_HT_FREQ_1G_SUPPORT == 1
-         if (!is_cpu_pre_e0()) 
+#if K8_HT_FREQ_1G_SUPPORT == 1
+	if (!is_cpu_pre_e0()) {
 		return freq_cap;
-        #endif
+	}
+#endif
 
 	id = pci_read_config32(dev, 0);
 
@@ -726,8 +721,8 @@
 	print_linkn("(0,1) link=", byte);
 	setup_row_direct(0,1, byte);
 	setup_temp_row(0, 1);
-
-	check_connection(7);
+	
+	verify_connection(7);
 
 	/* We found 2 nodes so far */
 	val = pci_read_config32(NODE_HT(7), 0x6c);
@@ -751,8 +746,8 @@
 		print_linkn("\t-->(0,1) link=", byte);
 		setup_row_direct(0,1, byte);
 		setup_temp_row(0, 1);
-
-		check_connection(7);
+	
+		verify_connection(7);
 			
 		/* We found 2 nodes so far */
 		val = pci_read_config32(NODE_HT(7), 0x6c);
@@ -832,7 +827,7 @@
 	setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
 
 	setup_temp_row(0,2);
-	check_connection(7);
+	verify_connection(7);
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
 	print_linkn("(2,0) link=", byte); 
@@ -846,7 +841,7 @@
 
 	setup_temp_row(0,1);
 	setup_temp_row(1,3);
-	check_connection(7);
+	verify_connection(7);
 
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
@@ -865,7 +860,7 @@
 	setup_row_direct(2,3, byte & 0x3);
 	setup_temp_row(0,2);
 	setup_temp_row(2,3);
-	check_connection(7); /* to 3*/
+	verify_connection(7); /* to 3*/
 
 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
 	/* We need to find out which link is to node3 */
@@ -878,7 +873,7 @@
 			print_linkn("\t-->(2,3) link=", byte); 
 			setup_row_direct(2,3,byte);
 			setup_temp_row(2,3);
-			check_connection(7); /* to 3*/
+			verify_connection(7); /* to 3*/
 		}
 	} 
 #endif
@@ -1016,7 +1011,7 @@
 	for(byte=0; byte<4; byte+=2) {
 		setup_temp_row(byte,byte+2);
 	}
-	check_connection(7);
+	verify_connection(7);
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
 	print_linkn("(4,2) link=", byte); 
@@ -1044,7 +1039,7 @@
 	for(byte=0; byte<4; byte+=2) {
 		setup_temp_row(byte+1,byte+3);
 	}
-	check_connection(7);
+	verify_connection(7);
 
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
@@ -1064,7 +1059,7 @@
 	setup_temp_row(0,2);
 	setup_temp_row(2,4);
 	setup_temp_row(4,5);
-	check_connection(7); /* to 5*/
+	verify_connection(7); /* to 5*/
 
 #if CONFIG_MAX_PHYSICAL_CPUS > 6
 	/* We need to find out which link is to node5 */
@@ -1078,7 +1073,7 @@
 			print_linkn("\t-->(4,5) link=", byte);
 			setup_row_direct(4,5,byte);
 			setup_temp_row(4,5);
-			check_connection(7); /* to 5*/
+			verify_connection(7); /* to 5*/
 		}
 	} 
 #endif
@@ -1254,7 +1249,7 @@
 	for(byte=0; byte<6; byte+=2) {
 		setup_temp_row(byte,byte+2);
 	}
-	check_connection(7);
+	verify_connection(7);
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
 	print_linkn("(6,4) link=", byte);
@@ -1294,7 +1289,7 @@
         }
 	setup_temp_row(5,6);
 
-        check_connection(7);
+        verify_connection(7);
 
 	val = get_row(7,6); // to chect it if it is node6 before renaming
 	if( (val>>16) == 1) { // it is real node 7 so swap it
@@ -1316,7 +1311,7 @@
 #endif
 		setup_temp_row(5,6);
 
-       	        check_connection(7);
+       	        verify_connection(7);
 	}
         val = pci_read_config32(NODE_HT(7), 0x6c);
         byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
@@ -1334,7 +1329,7 @@
 		setup_temp_row(byte+1,byte+3);
 	}
 
-	check_connection(7);
+	verify_connection(7);
 
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
@@ -1354,7 +1349,7 @@
 		setup_temp_row(byte,byte+2);
 	}
 
-        check_connection(7);
+        verify_connection(7);
 
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
@@ -1379,7 +1374,7 @@
 		setup_temp_row(byte+1,byte+3); 
 	}
 
-	check_connection(7);
+	verify_connection(7);
 
 	val = pci_read_config32(NODE_HT(7), 0x6c);
 	byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
@@ -1568,7 +1563,6 @@
 #endif
 	
 	return result;
-
 }
 
 static unsigned verify_mp_capabilities(unsigned nodes)
@@ -1663,10 +1657,10 @@
 #endif
 	
 	/* set up cpu count and node count and enable Limit
-	* Config Space Range for all available CPUs.
-	* Also clear non coherent hypertransport bus range
-	* registers on Hammer A0 revision.
-	*/
+	 * Config Space Range for all available CPUs.
+	 * Also clear non coherent hypertransport bus range
+	 * registers on Hammer A0 revision.
+	 */
 
 	print_spew("coherent_ht_finalize\r\n");
 	rev_a0 = is_cpu_rev_a0();
@@ -1686,21 +1680,19 @@
 		pci_write_config32(dev, 0x60, val);
 
 		/* Only respond to real cpu pci configuration cycles
-		* and optimize the HT settings 
-		*/
-		val=pci_read_config32(dev, 0x68);
+		 * and optimize the HT settings 
+		 */
+		val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
 		val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
 			(HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
 			(HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
 		val |= HTTC_LIMIT_CLDT_CFG | 
 			(HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
-			HTTC_RSP_PASS_PW |
 			(3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
 			(3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
-		pci_write_config32(dev, 0x68, val);
+		pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
 
 		if (rev_a0) {
-			print_spew("shit it is an old cup\n");
 			pci_write_config32(dev, 0x94, 0);
 			pci_write_config32(dev, 0xb4, 0);
 			pci_write_config32(dev, 0xd4, 0);
@@ -1720,8 +1712,8 @@
 		if (is_cpu_pre_c0()) {
 
 			/* Errata 66
-			* Limit the number of downstream posted requests to 1 
-			*/
+			 * Limit the number of downstream posted requests to 1 
+			 */
 			cmd = pci_read_config32(dev, 0x70);
 			if ((cmd & (3 << 0)) != 2) {
 				cmd &= ~(3<<0);
@@ -1745,12 +1737,12 @@
 			}
 
 		}
-		else if(is_cpu_pre_d0()) { // d0 later don't need it 
+		else if (is_cpu_pre_d0()) { // d0 later don't need it
 			uint32_t cmd_ref;
 			/* Errata 98 
-			* Set Clk Ramp Hystersis to 7
-			* Clock Power/Timing Low
-			*/
+			 * Set Clk Ramp Hystersis to 7
+			 * Clock Power/Timing Low
+			 */
 			cmd_ref = 0x04e20707; /* Registered */
 			cmd = pci_read_config32(dev, 0xd4);
 			if(cmd != cmd_ref) {
@@ -1778,7 +1770,10 @@
 			/* This works on an Athlon64 because unimplemented links return 0 */
 			reg = 0x98 + (link * 0x20);
 			link_type = pci_read_config32(f0_dev, reg);
-			if ((link_type & 7) == 3) { /* only handle coherent link here*/
+			/* Only handle coherent links */
+			if ((link_type & (LinkConnected | InitComplete|NonCoherent)) == 
+				(LinkConnected|InitComplete)) 
+			{
 				cmd &= ~(0xff << (link *8));
 				cmd |= 0x25 << (link *8);
 			}
@@ -1794,6 +1789,8 @@
 static int setup_coherent_ht_domain(void)
 {
 	struct setup_smp_result result;
+	result.nodes = 1;
+	result.needs_reset = 0;
 
 #if K8_HT_CHECK_PENDING_LINK == 1 
 	//needed?
@@ -1802,17 +1799,14 @@
 	enable_bsp_routing();
 
 #if CONFIG_MAX_PHYSICAL_CPUS > 1
-	result = setup_smp();
-	result.nodes = verify_mp_capabilities(result.nodes);
-	clear_dead_routes(result.nodes);
-#else
-	result.nodes = 1;
-	result.needs_reset = 0;
+        result = setup_smp();
+        result.nodes = verify_mp_capabilities(result.nodes);
+        clear_dead_routes(result.nodes);
 #endif
 
 	if (result.nodes == 1) {
 		setup_uniprocessor();
-	} 
+	}
 	coherent_ht_finalize(result.nodes);
 	result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
 	result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
diff --git a/src/northbridge/amd/amdk8/debug.c b/src/northbridge/amd/amdk8/debug.c
index 861ad8c..d0841e8 100644
--- a/src/northbridge/amd/amdk8/debug.c
+++ b/src/northbridge/amd/amdk8/debug.c
@@ -5,12 +5,16 @@
 #if 1
 static void print_debug_pci_dev(unsigned dev)
 {
+#if CONFIG_USE_INIT
+	printk_debug("PCI: %02x:%02x.%02x", (dev>>16) & 0xff, (dev>>11) & 0x1f, (dev>>8) & 0x7);
+#else
 	print_debug("PCI: ");
 	print_debug_hex8((dev >> 16) & 0xff);
 	print_debug_char(':');
 	print_debug_hex8((dev >> 11) & 0x1f);
 	print_debug_char('.');
 	print_debug_hex8((dev >> 8) & 7);
+#endif
 }
 
 static void print_pci_devices(void)
@@ -27,7 +31,19 @@
 			continue;
 		}
 		print_debug_pci_dev(dev);
+#if CONFIG_USE_INIT
+		printk_debug(" %04x:%04x\r\n", (id & 0xffff), (id>>16));
+#else
+		print_debug_hex32(id);
 		print_debug("\r\n");
+#endif
+		if(((dev>>8) & 0x07) == 0) {
+			uint8_t hdr_type;
+			hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
+			if((hdr_type & 0x80) != 0x80) {
+				dev += PCI_DEV(0,0,7);
+			}
+		}
 	}
 }
 
@@ -72,6 +88,14 @@
 			continue;
 		}
 		dump_pci_device(dev);
+
+                if(((dev>>8) & 0x07) == 0) {
+                        uint8_t hdr_type;
+                        hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
+                        if((hdr_type & 0x80) != 0x80) {
+                                dev += PCI_DEV(0,0,7);
+                        }
+                }
 	}
 }
 
@@ -89,6 +113,14 @@
                         continue;
                 }
                 dump_pci_device(dev);
+
+                if(((dev>>8) & 0x07) == 0) {
+                        uint8_t hdr_type;
+                        hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
+                        if((hdr_type & 0x80) != 0x80) {
+                                dev += PCI_DEV(0,0,7);
+                        }
+                }
         }
 }
 
diff --git a/src/northbridge/amd/amdk8/early_ht.c b/src/northbridge/amd/amdk8/early_ht.c
index ab9d459..2711657 100644
--- a/src/northbridge/amd/amdk8/early_ht.c
+++ b/src/northbridge/amd/amdk8/early_ht.c
@@ -17,8 +17,9 @@
 		id = pci_read_config32(PCI_DEV(0,0,0), PCI_VENDOR_ID);
 		/* If the chain is enumerated quit */
 		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
-		    (((id >> 16) & 0xffff) == 0xffff) ||
-		    (((id >> 16) & 0xffff) == 0x0000)) {
+			(((id >> 16) & 0xffff) == 0xffff) ||
+			(((id >> 16) & 0xffff) == 0x0000))
+		{
 			break;
 		}
 
@@ -35,7 +36,8 @@
 		hdr_type &= 0x7f;
 
 		if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
-		    (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
+			(hdr_type == PCI_HEADER_TYPE_BRIDGE)) 
+		{
 			pos = pci_read_config8(PCI_DEV(0,0,0), PCI_CAPABILITY_LIST);
 		}
 		while(pos != 0) {
@@ -43,24 +45,39 @@
 			cap = pci_read_config8(PCI_DEV(0,0,0), pos + PCI_CAP_LIST_ID);
 			if (cap == PCI_CAP_ID_HT) {
 				uint16_t flags;
+				/* Read and write and reread flags so the link
+				 * direction bit is valid.
+				 */
+				flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS);
+				pci_write_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS, flags);
 				flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS);
 				if ((flags >> 13) == 0) {
 					unsigned count;
+					unsigned ctrl, ctrl_off;
 
 					flags &= ~0x1f;
 					flags |= next_unitid & 0x1f;
 					count = (flags >> 5) & 0x1f;
+					next_unitid += count;
+
+					/* Test for end of chain */
+					ctrl_off = ((flags >> 10) & 1)?
+						PCI_HT_CAP_SLAVE_CTRL1 : PCI_HT_CAP_SLAVE_CTRL0;
+					ctrl = pci_read_config16(PCI_DEV(0,0,0), pos + ctrl_off);
+					/* Is this the end of the hypertransport chain.
+					 * or has the link failed?
+					 */
+					if (ctrl & ((1 << 6)|(1 << 4))) {
+						next_unitid = 0x20;
+					}
 					
 					pci_write_config16(PCI_DEV(0, 0, 0), pos + PCI_CAP_FLAGS, flags);
-
-					next_unitid += count;
 					break;
 				}
 			}
 			pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
 		}
-	} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));  
-	
+	} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
 
 	return reset_needed;
 }
diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c
index 7bb315d..d4271ef 100644
--- a/src/northbridge/amd/amdk8/incoherent_ht.c
+++ b/src/northbridge/amd/amdk8/incoherent_ht.c
@@ -10,6 +10,10 @@
         #define K8_HT_FREQ_1G_SUPPORT 0
 #endif
 
+#ifndef K8_SCAN_PCI_BUS
+	#define K8_SCAN_PCI_BUS 0
+#endif
+
 static inline void print_linkn_in (const char *strval, uint8_t byteval)
 {
 #if 1
@@ -21,7 +25,7 @@
 #endif
 }
 
-static uint8_t ht_lookup_slave_capability(device_t dev)
+static uint8_t ht_lookup_capability(device_t dev, uint16_t val)
 {
 	uint8_t pos;
 	uint8_t hdr_type;
@@ -44,8 +48,8 @@
 			uint16_t flags;
 
 			flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
-			if ((flags >> 13) == 0) {
-				/* Entry is a Slave secondary, success... */
+			if ((flags >> 13) == val) {
+				/* Entry is a slave or host , success... */
 				break;
 			}
 		}
@@ -54,6 +58,16 @@
 	return pos;
 }
 
+static uint8_t ht_lookup_slave_capability(device_t dev)
+{          
+	return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format
+}
+
+static uint8_t ht_lookup_host_capability(device_t dev)
+{
+        return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format
+}
+
 static void ht_collapse_previous_enumeration(uint8_t bus)
 {
 	device_t dev;
@@ -135,25 +149,28 @@
 
 	return freq_cap;
 }
+#define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
+      (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
 
-#define LINK_OFFS(WIDTH,FREQ,FREQ_CAP)					\
-	(((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
-
+#define LINK_CTRL(OFFS)     ((OFFS >> 24) & 0xFF)
 #define LINK_WIDTH(OFFS)    ((OFFS >> 16) & 0xFF)
 #define LINK_FREQ(OFFS)     ((OFFS >> 8) & 0xFF)
 #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
 
 #define PCI_HT_HOST_OFFS LINK_OFFS(		\
+		PCI_HT_CAP_HOST_CTRL,           \
 		PCI_HT_CAP_HOST_WIDTH,		\
 		PCI_HT_CAP_HOST_FREQ,		\
 		PCI_HT_CAP_HOST_FREQ_CAP)
 
 #define PCI_HT_SLAVE0_OFFS LINK_OFFS(		\
+		PCI_HT_CAP_SLAVE_CTRL0,         \
 		PCI_HT_CAP_SLAVE_WIDTH0,	\
 		PCI_HT_CAP_SLAVE_FREQ0,		\
 		PCI_HT_CAP_SLAVE_FREQ_CAP0)
 
 #define PCI_HT_SLAVE1_OFFS LINK_OFFS(		\
+		PCI_HT_CAP_SLAVE_CTRL1,         \
 		PCI_HT_CAP_SLAVE_WIDTH1,	\
 		PCI_HT_CAP_SLAVE_FREQ1,		\
 		PCI_HT_CAP_SLAVE_FREQ_CAP1)
@@ -164,8 +181,8 @@
 {
 	static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
 	static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
-	uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
-	uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
+	uint16_t freq_cap1, freq_cap2;
+	uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
 	uint8_t freq, old_freq;
 	int needs_reset;
 	/* Set link width and frequency */
@@ -228,94 +245,123 @@
 
 	return needs_reset;
 }
-static int ht_setup_chain(device_t udev, uint8_t upos)
+#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
+static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus);
+static int scan_pci_bus( unsigned bus) 
 {
-	/* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
-	 * On most boards this just happens.  If a cpu has multiple
-	 * non Coherent links the appropriate bus registers for the
-	 * links needs to be programed to point at bus 0.
-	 */
-	uint8_t next_unitid, last_unitid;
-	int reset_needed;
-	unsigned uoffs;
+        /*      
+                here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
+                So We can scan these devices to find out if they are bridge 
+                If it is pci bridge, We need to set busn in bridge, and go on
+                For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
+        */    
+	unsigned int devfn;
+	unsigned new_bus;
+	unsigned max_bus;
 
-	/* Make certain the HT bus is not enumerated */
-	ht_collapse_previous_enumeration(0);
+	new_bus = (bus & 0xff); // mask out the reset_needed
 
-	reset_needed = 0;
-	uoffs = PCI_HT_HOST_OFFS;
-	next_unitid = 1;
-	do {
-		uint32_t id;
-		uint8_t pos;
-		uint16_t flags;
-		uint8_t count;
-		unsigned offs;
+	if(new_bus<0x40) {
+		max_bus = 0x3f;
+	} else if (new_bus<0x80) {
+		max_bus = 0x7f;
+	} else if (new_bus<0xc0) {
+		max_bus = 0xbf;
+	} else {
+		max_bus = 0xff;
+	}
 
-		device_t dev = PCI_DEV(0, 0, 0);
-		last_unitid = next_unitid;
+	new_bus = bus;
 
-		id = pci_read_config32(dev, PCI_VENDOR_ID);
-		/* If the chain is enumerated quit */
-		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
-		    (((id >> 16) & 0xffff) == 0xffff) ||
-		    (((id >> 16) & 0xffff) == 0x0000)) {
-			break;
+#if 0
+#if CONFIG_USE_INIT == 1
+	printk_debug("bus_num=%02x\r\n", bus);
+#endif
+#endif
+
+	for (devfn = 0; devfn <= 0xff; devfn++) { 
+	        uint8_t hdr_type;
+	        uint16_t class;
+		uint32_t buses;
+		device_t dev;
+		uint16_t cr;
+		dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7));
+                hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
+                class = pci_read_config16(dev, PCI_CLASS_DEVICE);
+
+#if 0
+#if CONFIG_USE_INIT == 1
+		if(hdr_type !=0xff ) {
+			printk_debug("dev=%02x fn=%02x hdr_type=%02x class=%04x\r\n", 
+				(devfn>>3)& 0x1f, (devfn & 0x7), hdr_type, class);
 		}
-
-		pos = ht_lookup_slave_capability(dev);
-		if (!pos) {
-			print_err("HT link capability not found\r\n");
-			break;
-		}
-#if CK804_DEVN_BASE==0 
-                //CK804 workaround: 
-                // CK804 UnitID changes not use
-                id = pci_read_config32(dev, PCI_VENDOR_ID);
-                if(id != 0x005e10de) {
 #endif
-
-                /* Update the Unitid of the current device */
-                flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
-                flags &= ~0x1f; /* mask out the bse Unit ID */
-                flags |= next_unitid & 0x1f;
-                pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
-
-                dev = PCI_DEV(0, next_unitid, 0);
-#if CK804_DEVN_BASE==0  
-                }
-                else {
-                        dev = PCI_DEV(0, 0, 0);
-                }
 #endif
+		switch(hdr_type & 0x7f) {  /* header type */
+		        case PCI_HEADER_TYPE_BRIDGE:
+		                if (class  != PCI_CLASS_BRIDGE_PCI) goto bad;
+				/* set the bus range dev */
 
-                /* Compute the number of unitids consumed */
-                count = (flags >> 5) & 0x1f;
-                next_unitid += count;
+			        /* Clear all status bits and turn off memory, I/O and master enables. */
+			        cr = pci_read_config16(dev, PCI_COMMAND);
+			        pci_write_config16(dev, PCI_COMMAND, 0x0000);
+			        pci_write_config16(dev, PCI_STATUS, 0xffff);
 
-                /* get ht direction */
-                flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
+			        buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
 
-                offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
+			        buses &= 0xff000000;
+				new_bus++;
+			        buses |= (((unsigned int) (bus & 0xff) << 0) |
+			                ((unsigned int) (new_bus & 0xff) << 8) |
+			                ((unsigned int) max_bus << 16));
+			        pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
+				
+				{
+				/* here we need to figure out if dev is a ht bridge
+					if it is ht bridge, we need to call ht_setup_chainx at first
+				   Not verified --- yhlu
+				*/
+					uint8_t upos;
+			                upos = ht_lookup_host_capability(dev); // one func one ht sub
+			                if (upos) { // sub ht chain
+						uint8_t busn;
+						busn = (new_bus & 0xff);
+				                /* Make certain the HT bus is not enumerated */
+				                ht_collapse_previous_enumeration(busn);
+						/* scan the ht chain */
+				                new_bus |= (ht_setup_chainx(dev,upos,busn)<<16); // store reset_needed to upword
+			                }
+				}
+				
+				new_bus = scan_pci_bus(new_bus);
+				/* set real max bus num in that */
 
-                /* Setup the Hypertransport link */
-                reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
+			        buses = (buses & 0xff00ffff) |
+			                ((unsigned int) (new_bus & 0xff) << 16);
+				        pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
 
-#if CK804_DEVN_BASE==0
-                if(id == 0x005e10de) {
-                        break;
+				pci_write_config16(dev, PCI_COMMAND, cr);
+
+                		break;  
+        		default:
+		        bad:
+				;
+        	}
+
+                /* if this is not a multi function device, 
+                 * or the device is not present don't waste
+                 * time probing another function. 
+                 * Skip to next device. 
+                 */
+                if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
+                {
+                        devfn += 0x07;
                 }
-#endif
-
-		/* Remeber the location of the last device */
-		udev = dev;
-		upos = pos;
-		uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
-
-	} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
-	return reset_needed;
+        }
+	
+	return new_bus; 
 }
-
+#endif
 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
 {
 	uint8_t next_unitid, last_unitid;
@@ -328,25 +374,38 @@
 	do {
 		uint32_t id;
 		uint8_t pos;
-		uint16_t flags;
+		uint16_t flags, ctrl;
 		uint8_t count;
 		unsigned offs;
-		
+	
+		/* Wait until the link initialization is complete */
+		do {
+			ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
+			/* Is this the end of the hypertransport chain? */
+			if (ctrl & (1 << 6)) {
+				break;
+			}
+			/* Has the link failed */
+			if (ctrl & (1 << 4)) {
+				break;
+			}
+		} while((ctrl & (1 << 5)) == 0);
+	
 		device_t dev = PCI_DEV(bus, 0, 0);
 		last_unitid = next_unitid;
 
 		id = pci_read_config32(dev, PCI_VENDOR_ID);
 
 		/* If the chain is enumerated quit */
-		if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
-		    (((id >> 16) & 0xffff) == 0xffff) ||
-		    (((id >> 16) & 0xffff) == 0x0000)) {
+		if (    (id == 0xffffffff) || (id == 0x00000000) ||
+			(id == 0x0000ffff) || (id == 0xffff0000))
+		{
 			break;
 		}
 
 		pos = ht_lookup_slave_capability(dev);
 		if (!pos) {
-			print_err(" HT link capability not found\r\n");
+			print_err("HT link capability not found\r\n");
 			break;
 		}
 
@@ -363,6 +422,7 @@
 		flags |= next_unitid & 0x1f;
 		pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
 
+		/* Note the change in device number */
 		dev = PCI_DEV(bus, next_unitid, 0);
 #if CK804_DEVN_BASE==0	
 		} 
@@ -375,9 +435,11 @@
                 count = (flags >> 5) & 0x1f;
                 next_unitid += count;
 
-                /* get ht direction */
-		flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ??
-
+		/* Find which side of the ht link we are on,
+		 * by reading which direction our last write to PCI_CAP_FLAGS
+		 * came from.
+		 */
+		flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
                 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
                 
                 /* Setup the Hypertransport link */
@@ -395,9 +457,23 @@
 		uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
 
 	} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
+
 	return reset_needed;
 }
 
+static int ht_setup_chain(device_t udev, unsigned upos)
+{
+        /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
+         * On most boards this just happens.  If a cpu has multiple
+         * non Coherent links the appropriate bus registers for the
+         * links needs to be programed to point at bus 0.
+         */
+
+        /* Make certain the HT bus is not enumerated */
+        ht_collapse_previous_enumeration(0);
+
+        return ht_setup_chainx(udev, upos, 0);
+}
 static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
 {
 	uint32_t dword, dword_old;
@@ -444,7 +520,7 @@
 		reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID);
 		if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
 			val = 0x25;
-		} else if ( (reg & 0xffff) == 0x10de ) {
+		} else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
 			val = 0x25;//???
 		} else {
 			continue;
@@ -477,6 +553,9 @@
 		unsigned regpos;
 		uint32_t dword;
 		uint8_t busn;
+		#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
+		unsigned bus;
+		#endif
 		
 		reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
 
@@ -498,7 +577,11 @@
 		
 		reset_needed |= ht_setup_chainx(udev,upos,busn);
 
-
+		#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
+	        /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
+		bus = busn; // we need 32 bit 
+        	reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
+		#endif
 	}
 
 	reset_needed |= optimize_link_in_coherent(ht_c_num);		
@@ -506,6 +589,10 @@
 	return reset_needed;
 }
 
+#ifndef K8_ALLOCATE_IO_RANGE 
+	#define K8_ALLOCATE_IO_RANGE 0
+#endif
+
 static int ht_setup_chains_x(void)
 {               
         uint8_t nodeid;
@@ -514,18 +601,34 @@
         uint8_t next_busn;
         uint8_t ht_c_num;
 	uint8_t nodes;
+#if K8_ALLOCATE_IO_RANGE == 1	
+	unsigned next_io_base;
+#endif
       
         /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
         reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
-        /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=5+1 */
+        /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
 	print_linkn_in("SBLink=", ((reg>>8) & 3) );
-        tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (5<<24);
+        tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
 
-        next_busn=5+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
+	next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
+
+#if K8_ALLOCATE_IO_RANGE == 1
+	/* io range allocation */
+	tempreg = 0 | (((reg>>8) & 0x3) << 4 )|  (0x3<<12); //limit
+	pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
+	tempreg = 3 | ( 3<<4) | (0<<12);	//base
+	pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
+	next_io_base = 0x3+0x1;
+#endif
+
 	/* clean others */
         for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
+		/* io range allocation */
+		pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
+		pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
         }
  
 	nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
@@ -548,13 +651,23 @@
                                         break;
                                 }
                         }
-                        if(ht_c_num == 4) break; /*used up onle 4 non conherent allowed*/
+                        if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
                         /*update to 0xe0...*/
 			if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
 			print_linkn_in("\tbusn=", next_busn);
-                        tempreg |= (next_busn<<16)|((next_busn+5)<<24);
+                        tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
-                        next_busn+=5+1;
+			next_busn+=0x3f+1;
+
+#if K8_ALLOCATE_IO_RANGE == 1			
+			/* io range allocation */
+		        tempreg = nodeid | (linkn<<4) |  ((next_io_base+0x3)<<12); //limit
+		        pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
+		        tempreg = 3 | ( 3<<4) | (next_io_base<<12);        //base
+		        pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
+		        next_io_base += 0x3+0x1;
+#endif
+
                 }
         }
         /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
@@ -568,8 +681,23 @@
                         regpos = 0xe0 + i * 4;
                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
                         pci_write_config32(dev, regpos, reg);
-
                 }
+
+#if K8_ALLOCATE_IO_RANGE == 1
+		/* io range allocation */
+                for(i = 0; i< 4; i++) {
+                        unsigned regpos;
+                        regpos = 0xc4 + i * 8;
+                        reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
+                        pci_write_config32(dev, regpos, reg);
+                }
+                for(i = 0; i< 4; i++) {
+                        unsigned regpos;
+                        regpos = 0xc0 + i * 8;
+                        reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
+                        pci_write_config32(dev, regpos, reg);
+                }
+#endif
         }
 	
 	/* recount ht_c_num*/
diff --git a/src/northbridge/amd/amdk8/misc_control.c b/src/northbridge/amd/amdk8/misc_control.c
index 4ac6ef4..4cd3d0d 100644
--- a/src/northbridge/amd/amdk8/misc_control.c
+++ b/src/northbridge/amd/amdk8/misc_control.c
@@ -187,7 +187,10 @@
 			/* This works on an Athlon64 because unimplemented links return 0 */
 			reg = 0x98 + (link * 0x20);
 			link_type = pci_read_config32(f0_dev, reg);
-			if ((link_type & 7) == 3) { /* Only handle coherent link here */
+			/* Only handle coherent link here please */
+			if ((link_type & (LinkConnected|InitComplete|NonCoherent)) 
+				== (LinkConnected|InitComplete))
+			{
 				cmd &= ~(0xff << (link *8));
 				/* FIXME this assumes the device on the other side is an AMD device */
 				cmd |= 0x25 << (link *8);
diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c
index 89602f3..e45aff8 100644
--- a/src/northbridge/amd/amdk8/northbridge.c
+++ b/src/northbridge/amd/amdk8/northbridge.c
@@ -40,7 +40,7 @@
 static void debug_fx_devs(void)
 {
 	int i;
-	for (i = 0; i < FX_DEVS; i++) {
+	for(i = 0; i < FX_DEVS; i++) {
 		device_t dev;
 		dev = __f0_dev[i];
 		if (dev) {
@@ -62,7 +62,7 @@
 	if (__f1_dev[0]) {
 		return;
 	}
-	for (i = 0; i < FX_DEVS; i++) {
+	for(i = 0; i < FX_DEVS; i++) {
 		__f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
 		__f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
 	}
@@ -81,7 +81,7 @@
 {
 	int i;
 	get_fx_devs();
-	for (i = 0; i < FX_DEVS; i++) {
+	for(i = 0; i < FX_DEVS; i++) {
 		device_t dev;
 		dev = __f1_dev[i];
 		if (dev && dev->enabled) {
@@ -102,9 +102,9 @@
 	nodeid = amdk8_nodeid(dev);
 #if 0
 	printk_debug("%s amdk8_scan_chains max: %d starting...\n", 
-		     dev_path(dev), max);
+		dev_path(dev), max);
 #endif
-	for (link = 0; link < dev->links; link++) {
+	for(link = 0; link < dev->links; link++) {
 		uint32_t link_type;
 		uint32_t busses, config_busses;
 		unsigned free_reg, config_reg;
@@ -122,9 +122,10 @@
 			continue;
 		}
 		/* See if there is an available configuration space mapping
-		 * register in function 1. */
+		 * register in function 1. 
+		 */
 		free_reg = 0;
-		for (config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
+		for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
 			uint32_t config;
 			config = f1_read_config32(config_reg);
 			if (!free_reg && ((config & 3) == 0)) {
@@ -132,8 +133,8 @@
 				continue;
 			}
 			if (((config & 3) == 3) && 
-			    (((config >> 4) & 7) == nodeid) &&
-			    (((config >> 8) & 3) == link)) {
+				(((config >> 4) & 7) == nodeid) &&
+				(((config >> 8) & 3) == link)) {
 				break;
 			}
 		}
@@ -141,7 +142,8 @@
 			config_reg = free_reg;
 		}
 		/* If we can't find an available configuration space mapping
-		 * register skip this bus */
+		 * register skip this bus 
+		 */
 		if (config_reg > 0xec) {
 			continue;
 		}
@@ -158,15 +160,15 @@
 		 */
 		busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
 		config_busses = f1_read_config32(config_reg);
-
+		
 		/* Configure the bus numbers for this bridge: the configuration
 		 * transactions will not be propagates by the bridge if it is
 		 * not correctly configured
 		 */
 		busses &= 0xff000000;
 		busses |= (((unsigned int)(dev->bus->secondary) << 0) |
-			   ((unsigned int)(dev->link[link].secondary) << 8) |
-			   ((unsigned int)(dev->link[link].subordinate) << 16));
+			((unsigned int)(dev->link[link].secondary) << 8) |
+			((unsigned int)(dev->link[link].subordinate) << 16));
 		pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
 
 		config_busses &= 0x000fc88;
@@ -183,13 +185,14 @@
 			dev_path(dev), link, max);
 #endif
 		/* Now we can scan all of the subordinate busses i.e. the
-		 * chain on the hypertranport link */
-		max = hypertransport_scan_chain(&dev->link[link], max);
+		 * chain on the hypertranport link 
+		 */
+		max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max);
 
 #if 0
 		printk_debug("%s Hyper transport scan link: %d new max: %d\n",
 			dev_path(dev), link, max);
-#endif
+#endif		
 
 		/* We know the number of busses behind this bridge.  Set the
 		 * subordinate bus number to it's real value
@@ -202,6 +205,7 @@
 		config_busses = (config_busses & 0x00ffffff) |
 			(dev->link[link].subordinate << 24);
 		f1_write_config32(config_reg, config_busses);
+
 #if 0
 		printk_debug("%s Hypertransport scan link: %d done\n",
 			dev_path(dev), link);
@@ -214,32 +218,34 @@
 	return max;
 }
 
-static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid,
-		       unsigned goal_link)
+static int reg_useable(unsigned reg, 
+	device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
 {
 	struct resource *res;
 	unsigned nodeid, link;
 	int result;
 	res = 0;
-	for (nodeid = 0; !res && (nodeid < 8); nodeid++) {
+	for(nodeid = 0; !res && (nodeid < 8); nodeid++) {
 		device_t dev;
 		dev = __f0_dev[nodeid];
-		for (link = 0; !res && (link < 3); link++) {
+		for(link = 0; !res && (link < 3); link++) {
 			res = probe_resource(dev, 0x100 + (reg | link));
 		}
 	}
 	result = 2;
 	if (res) {
 		result = 0;
-		if ((goal_link == (link - 1)) && 
-		    (goal_nodeid == (nodeid - 1)) &&
-		    (res->flags <= 1)) {
+		if (	(goal_link == (link - 1)) && 
+			(goal_nodeid == (nodeid - 1)) &&
+			(res->flags <= 1)) {
 			result = 1;
 		}
 	}
 #if 0
 	printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n",
-		     reg, result, goal_nodeid, goal_link, nodeid, link);
+		reg, result, 
+		goal_nodeid, goal_link, 
+		nodeid, link);
 #endif
 	return result;
 }
@@ -250,7 +256,7 @@
 	unsigned free_reg, reg;
 	resource = 0;
 	free_reg = 0;
-	for (reg = 0xc0; reg <= 0xd8; reg += 0x8) {
+	for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
 		int result;
 		result = reg_useable(reg, dev, nodeid, link);
 		if (result == 1) {
@@ -277,7 +283,7 @@
 	unsigned free_reg, reg;
 	resource = 0;
 	free_reg = 0;
-	for (reg = 0x80; reg <= 0xb8; reg += 0x8) {
+	for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
 		int result;
 		result = reg_useable(reg, dev, nodeid, link);
 		if (result == 1) {
@@ -348,7 +354,7 @@
 {
 	unsigned nodeid, link;
 	nodeid = amdk8_nodeid(dev);
-	for (link = 0; link < dev->links; link++) {
+	for(link = 0; link < dev->links; link++) {
 		if (dev->link[link].children) {
 			amdk8_link_read_bases(dev, nodeid, link);
 		}
@@ -499,11 +505,11 @@
 	amdk8_create_vga_resource(dev, nodeid);
 	
 	/* Set each resource we have found */
-	for (i = 0; i < dev->resources; i++) {
+	for(i = 0; i < dev->resources; i++) {
 		amdk8_set_resource(dev, &dev->resource[i], nodeid);
 	}
 
-	for (link = 0; link < dev->links; link++) {
+	for(link = 0; link < dev->links; link++) {
 		struct bus *bus;
 		bus = &dev->link[link];
 		if (bus->children) {
@@ -520,26 +526,9 @@
 
 static void mcf0_control_init(struct device *dev)
 {
-	uint32_t cmd;
-
 #if 0	
 	printk_debug("NB: Function 0 Misc Control.. ");
 #endif
-#if 1
-	/* improve latency and bandwith on HT */
-	cmd = pci_read_config32(dev, 0x68);
-	cmd &= 0xffff80ff;
-	cmd |= 0x00004800;
-	pci_write_config32(dev, 0x68, cmd );
-#endif
-
-#if 0	
-	/* over drive the ht port to 1000 Mhz */
-	cmd = pci_read_config32(dev, 0xa8);
-	cmd &= 0xfffff0ff;
-	cmd |= 0x00000600;
-	pci_write_config32(dev, 0xdc, cmd );
-#endif	
 #if 0
 	printk_debug("done.\n");
 #endif
@@ -578,7 +567,7 @@
 
 	/* Find the already assigned resource pairs */
 	get_fx_devs();
-	for (reg = 0x80; reg <= 0xd8; reg+= 0x08) {
+	for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
 		uint32_t base, limit;
 		base  = f1_read_config32(reg);
 		limit = f1_read_config32(reg + 0x04);
@@ -612,8 +601,8 @@
 	resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
 }
 
-static void ram_resource(device_t dev, unsigned long index,
-			 unsigned long basek, unsigned long sizek)
+static void ram_resource(device_t dev, unsigned long index, 
+	unsigned long basek, unsigned long sizek)
 {
 	struct resource *resource;
 
@@ -691,7 +680,7 @@
 #endif
 
 	idx = 10;
-	for (i = 0; i < 8; i++) {
+	for(i = 0; i < 8; i++) {
 		uint32_t base, limit;
 		unsigned basek, limitk, sizek;
 		base  = f1_read_config32(0x40 + (i << 3));
@@ -737,11 +726,35 @@
 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
 {
 	unsigned reg;
+	int i;
 	/* Unmap all of the HT chains */
-	for (reg = 0xe0; reg <= 0xec; reg += 4) {
+	for(reg = 0xe0; reg <= 0xec; reg += 4) {
 		f1_write_config32(reg, 0);
 	}
 	max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
+	
+	/* Tune the hypertransport transaction for best performance.
+	 * Including enabling relaxed ordering if it is safe.
+	 */
+	get_fx_devs();
+	for(i = 0; i < FX_DEVS; i++) {
+		device_t f0_dev;
+		f0_dev = __f0_dev[i];
+		if (f0_dev && f0_dev->enabled) {
+			uint32_t httc;
+			int j;
+			httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
+			httc &= ~HTTC_RSP_PASS_PW;
+			if (!dev->link[0].disable_relaxed_ordering) {
+				httc |= HTTC_RSP_PASS_PW;
+			}
+			printk_spew("%s passpw: %s\n",
+				dev_path(dev),
+				(!dev->link[0].disable_relaxed_ordering)?
+				"enabled":"disabled");
+			pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
+		}
+	}
 	return max;
 }
 
@@ -755,20 +768,34 @@
 };
 
 #define APIC_ID_OFFSET 0x10
+
 static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
 {
 	struct bus *cpu_bus;
 	device_t dev_mc;
+	int bsp_apic_id;
+	int apic_id_offset;
 	int i,j;
-	unsigned nb_cfg_54 = 0;
-	unsigned siblings = 0;
-	int enable_apic_ext_id = 0;
-	int bsp_apic_id = lapicid(); // bsp apicid
-	int apic_id_offset = bsp_apic_id;
+	unsigned nb_cfg_54;
+	int enable_apic_ext_id;
+	unsigned siblings;
+#if CONFIG_LOGICAL_CPUS == 1
+	int e0_later_single_core; 
+	int disable_siblings;
+#endif
 
-#if CONFIG_LOGICAL_CPUS==1
-	int e0_later_single_core;
-	int disable_siblings = !CONFIG_LOGICAL_CPUS;
+	nb_cfg_54 = 0;
+	enable_apic_ext_id = 0;
+	siblings = 0;
+
+	/* Find the bootstrap processors apicid */
+	bsp_apic_id = lapicid();
+
+	/* See if I will enable extended ids' */
+	apic_id_offset = bsp_apic_id;
+
+#if CONFIG_LOGICAL_CPUS == 1
+	disable_siblings = !CONFIG_LOGICAL_CPUS;
 	get_option(&disable_siblings, "dual_core");
 
 	// for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it still be 0)
@@ -776,45 +803,42 @@
  
 	nb_cfg_54 = read_nb_cfg_54();
 #endif
-
 	dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
-	if(pci_read_config32(dev_mc, 0x68) & ( HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST)) {
+	if (!dev_mc) {
+		die("0:18.0 not found?");
+	}
+	if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
+	{
 		enable_apic_ext_id = 1;
-		if(apic_id_offset==0) { //bsp apic id is not changed
+		if (apic_id_offset == 0) {
+			/* bsp apic id is not changed */
 			apic_id_offset = APIC_ID_OFFSET;
 		}
 	}
 
-
 	/* Find which cpus are present */
 	cpu_bus = &dev->link[0];
-	for (i = 0; i < 8; i++) {
+	for(i = 0; i < 8; i++) {
 		device_t dev, cpu;
 		struct device_path cpu_path;
 
-		/* Find the cpu's memory controller */
+		/* Find the cpu's pci device */
 		dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
-		if(!dev) { // in case we move apic cluser before pci_domain and not set that for second CPU
-			for(j=0; j<4; j++) {
-	                        struct device dummy;
-				uint32_t id;
-	                        dummy.bus              = dev_mc->bus;
-	                        dummy.path.type        = DEVICE_PATH_PCI;
-	                        dummy.path.u.pci.devfn = PCI_DEVFN(0x18 + i, j);
-	                        id = pci_read_config32(&dummy, PCI_VENDOR_ID);
-	                        if (id != 0xffffffff && id != 0x00000000 &&
-        	                        id != 0x0000ffff && id != 0xffff0000) {
-                	        	//create that for it
-	                	        dev = alloc_dev(dev_mc->bus, &dummy.path);
-				}
+		if (!dev) {
+			/* If I am probing things in a weird order
+			 * ensure all of the cpu's pci devices are found.
+			 */
+			int j;
+			for(j = 0; j <= 3; j++) {
+				dev = pci_probe_dev(NULL, dev_mc->bus,
+					PCI_DEVFN(0x18 + i, j));
 			}
 		}
 
-#if CONFIG_LOGICAL_CPUS==1
+#if CONFIG_LOGICAL_CPUS == 1
 		e0_later_single_core = 0;
-		if((!disable_siblings) && dev && dev->enabled) {
-			j = (pci_read_config32(dev, 0xe8) >> 12) & 3;  //dev is func 3
-
+		if ((!disable_siblings) && dev && dev->enabled) {
+			j = (pci_read_config32(dev, 0xe8) >> 12) & 3; // dev is func 3
 			printk_debug("  %s siblings=%d\r\n", dev_path(dev), j);
 
 			if(nb_cfg_54) {
@@ -843,51 +867,49 @@
 				}
 			} else {
 				siblings = j;
-			}
+  			}
 		}
 #endif
-
 #if CONFIG_LOGICAL_CPUS==1
                 for (j = 0; j <= (e0_later_single_core?0:siblings); j++ ) {
 #else 
-		for (j = 0; j <= siblings; j++ ) {
+              	for (j = 0; j <= siblings; j++ ) {
 #endif
-                        /* Build the cpu device path */
-                        cpu_path.type = DEVICE_PATH_APIC;
-                        cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
-  
-                        /* See if I can find the cpu */
-                        cpu = find_dev_path(cpu_bus, &cpu_path);
-  
-                        /* Enable the cpu if I have the processor */
-                        if (dev && dev->enabled) {
-                                if (!cpu) {
-                                        cpu = alloc_dev(cpu_bus, &cpu_path);
-                                }
-                                if (cpu) {
-                                        cpu->enabled = 1; 
-                                }
-                        }
-
-                        /* Disable the cpu if I don't have the processor */
-                        if (cpu && (!dev || !dev->enabled)) {
-                                cpu->enabled = 0;
-                        }
-
-                        /* Report what I have done */
-                        if (cpu) {
-				if(enable_apic_ext_id) {
-			                if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0
-						if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) )
-	        		                        cpu->path.u.apic.apic_id += apic_id_offset;
-                			}
+			/* Build the cpu device path */
+			cpu_path.type = DEVICE_PATH_APIC;
+			cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
+			
+			/* See if I can find the cpu */
+			cpu = find_dev_path(cpu_bus, &cpu_path);
+			
+			/* Enable the cpu if I have the processor */
+			if (dev && dev->enabled) {
+				if (!cpu) {
+					cpu = alloc_dev(cpu_bus, &cpu_path);
 				}
-                                printk_debug("CPU: %s %s\n",
-                                        dev_path(cpu), cpu->enabled?"enabled":"disabled");
-                        }
-                } //j
+				if (cpu) {
+					cpu->enabled = 1;
+				}
+			}
+			
+			/* Disable the cpu if I don't have the processor */
+			if (cpu && (!dev || !dev->enabled)) {
+				cpu->enabled = 0;
+			}
+			
+			/* Report what I have done */
+			if (cpu) {
+                                if(enable_apic_ext_id) {
+                                       if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0
+                                               if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) )
+                                                       cpu->path.u.apic.apic_id += apic_id_offset;
+                                       }
+				}
+				printk_debug("CPU: %s %s\n",
+					dev_path(cpu), cpu->enabled?"enabled":"disabled");
+			}
+		} //j
 	}
-
 	return max;
 }
 
diff --git a/src/northbridge/amd/amdk8/setup_resource_map.c b/src/northbridge/amd/amdk8/setup_resource_map.c
index ebd1978..27da719 100644
--- a/src/northbridge/amd/amdk8/setup_resource_map.c
+++ b/src/northbridge/amd/amdk8/setup_resource_map.c
@@ -1,16 +1,53 @@
 #define RES_DEBUG 0
 
+static void setup_resource_map_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base)
+{       
+        int i;
+//      print_debug("setting up resource map offset....");
+#if 0
+        print_debug("\r\n");
+#endif
+        for(i = 0; i < max; i += 3) {
+                device_t dev;
+                unsigned where;
+                unsigned long reg;
+#if 0
+        #if CONFIG_USE_INIT
+                prink_debug("%08x <- %08x\r\n", register_values[i] +  offset_pci_dev, register_values[i+2]);
+        #else
+                print_debug_hex32(register_values[i] + offset_pci_dev);
+                print_debug(" <-");
+                print_debug_hex32(register_values[i+2]);
+                print_debug("\r\n");
+        #endif
+#endif
+                dev = (register_values[i] & ~0xff) + offset_pci_dev;
+                where = register_values[i] & 0xff;
+                reg = pci_read_config32(dev, where);
+                reg &= register_values[i+1];
+                reg |= register_values[i+2] + offset_io_base;
+                pci_write_config32(dev, where, reg);
+#if 0
+                reg = pci_read_config32(register_values[i]);
+                reg &= register_values[i+1];
+                reg |= register_values[i+2] & ~register_values[i+1];
+                pci_write_config32(register_values[i], reg);
+#endif
+        }
+//      print_debug("done.\r\n");
+}
+
 #define RES_PCI_IO 0x10
 #define RES_PORT_IO_8 0x22 
 #define RES_PORT_IO_32 0x20
-#define RES_MEM_IO 0x30
+#define RES_MEM_IO 0x40
 
-static void setup_resource_map_x(const unsigned int *register_values, int max)
+static void setup_resource_map_x_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base)
 {
 	int i;
 
 #if RES_DEBUG
-	print_debug("setting up resource map ex....");
+	print_debug("setting up resource map ex offset....");
 
 #endif
 
@@ -21,17 +58,23 @@
 #if RES_DEBUG
 	#if CONFIG_USE_INIT
                 printk_debug("%04x: %02x %08x <- & %08x | %08x\r\n", 
-			i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]);
+			i/4, register_values[i], 
+			register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0), 
+			register_values[i+2], 
+			register_values[i+3] + ( ( (register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
+			);
 	#else		
                 print_debug_hex16(i/4);
                 print_debug(": ");
                 print_debug_hex8(register_values[i]);
                 print_debug(" ");
-                print_debug_hex32(register_values[i+1]);
+                print_debug_hex32(register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0) );
                 print_debug(" <- & ");
                 print_debug_hex32(register_values[i+2]);
                 print_debug(" | ");
-                print_debug_hex32(register_values[i+3]);
+                print_debug_hex32(register_values[i+3] + 
+			(((register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
+			);
                 print_debug("\r\n");
 	#endif
 #endif
@@ -41,7 +84,7 @@
 			device_t dev;
 			unsigned where;
 			unsigned long reg;
-			dev = register_values[i+1] & ~0xff;
+			dev = (register_values[i+1] & ~0xff) + offset_pci_dev;
 			where = register_values[i+1] & 0xff;
 			reg = pci_read_config32(dev, where);
 			reg &= register_values[i+2];
@@ -53,7 +96,7 @@
 			{
 			unsigned where;
 			unsigned reg;
-			where = register_values[i+1];
+			where = register_values[i+1] + offset_io_base;
 			reg = inb(where);
 			reg &= register_values[i+2];
 			reg |= register_values[i+3];
@@ -64,7 +107,7 @@
 			{
 			unsigned where;
 			unsigned long reg;
-			where = register_values[i+1];
+			where = register_values[i+1] + offset_io_base;
 			reg = inl(where);
 			reg &= register_values[i+2];
 			reg |= register_values[i+3];
@@ -94,7 +137,95 @@
 	print_debug("done.\r\n");
 #endif
 }
+static void setup_resource_map_x(const unsigned int *register_values, int max)
+{                       
+        int i;
 
+#if RES_DEBUG
+        print_debug("setting up resource map ex offset....");
+
+#endif
+
+#if RES_DEBUG
+        print_debug("\r\n");
+#endif
+        for(i = 0; i < max; i += 4) {
+#if RES_DEBUG
+        #if CONFIG_USE_INIT
+                printk_debug("%04x: %02x %08x <- & %08x | %08x\r\n",
+                        i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]);
+        #else
+                print_debug_hex16(i/4);
+                print_debug(": ");
+                print_debug_hex8(register_values[i]);
+                print_debug(" ");
+                print_debug_hex32(register_values[i+1]);
+                print_debug(" <- & ");
+                print_debug_hex32(register_values[i+2]);
+                print_debug(" | ");
+                print_debug_hex32(register_values[i+3]);
+                print_debug("\r\n");
+        #endif
+#endif
+                switch (register_values[i]) {
+                case RES_PCI_IO: //PCI 
+                        {
+                        device_t dev;
+                        unsigned where;
+                        unsigned long reg;
+                        dev = register_values[i+1] & ~0xff;
+                        where = register_values[i+1] & 0xff;
+                        reg = pci_read_config32(dev, where);
+                        reg &= register_values[i+2];
+                        reg |= register_values[i+3];
+                        pci_write_config32(dev, where, reg);
+                        }
+                        break;
+                case RES_PORT_IO_8: // io 8
+                        {
+                        unsigned where;
+                        unsigned reg;
+                        where = register_values[i+1];
+                        reg = inb(where);
+                        reg &= register_values[i+2];
+                        reg |= register_values[i+3];
+                        outb(reg, where);
+                        }
+                        break;
+                case RES_PORT_IO_32:  //io32
+                        {
+                        unsigned where;
+                        unsigned long reg;
+                        where = register_values[i+1];
+                        reg = inl(where);
+                        reg &= register_values[i+2];
+                        reg |= register_values[i+3];
+                        outl(reg, where);
+                        }
+                        break;
+#if 0
+                case RES_MEM_IO: //mem 
+                        {
+                        unsigned where;
+                        unsigned long reg;
+                        where = register_values[i+1];
+                        reg = read32(where);
+                        reg &= register_values[i+2];
+                        reg |= register_values[i+3];
+                        write32( where, reg);
+                        }
+                        break;
+#endif
+
+                } // switch
+
+
+        }
+
+#if RES_DEBUG
+        print_debug("done.\r\n");
+#endif
+}
 
 static void setup_iob_resource_map(const unsigned int *register_values, int max)
 {
diff --git a/src/northbridge/intel/E7520/Config.lb b/src/northbridge/intel/E7520/Config.lb
new file mode 100644
index 0000000..064c867
--- /dev/null
+++ b/src/northbridge/intel/E7520/Config.lb
@@ -0,0 +1,12 @@
+config chip.h
+driver northbridge.o
+driver pciexp_porta.o
+driver pciexp_porta1.o
+driver pciexp_portb.o
+driver pciexp_portc.o
+
+makerule raminit_test
+	depends "$(TOP)/src/northbridge/intel/e7520/raminit_test.c"
+	depends "$(TOP)/src/northbridge/intel/e7520/raminit.c"
+	action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g  $< -o $@"
+end
diff --git a/src/northbridge/intel/E7520/chip.h b/src/northbridge/intel/E7520/chip.h
new file mode 100644
index 0000000..e9ee0a2
--- /dev/null
+++ b/src/northbridge/intel/E7520/chip.h
@@ -0,0 +1,7 @@
+struct northbridge_intel_E7520_config
+{
+        /* Interrupt line connect */
+        unsigned int intrline;
+};
+
+extern struct chip_operations northbridge_intel_E7520_ops;
diff --git a/src/northbridge/intel/E7520/e7520.h b/src/northbridge/intel/E7520/e7520.h
new file mode 100644
index 0000000..be76303
--- /dev/null
+++ b/src/northbridge/intel/E7520/e7520.h
@@ -0,0 +1,44 @@
+#define VID     0X00
+#define DID     0X02
+#define PCICMD  0X04
+#define PCISTS  0X06
+#define RID	0X08
+#define IURBASE	0X14
+#define MCHCFG0	0X50
+#define MCHSCRB	0X52
+#define FDHC	0X58
+#define PAM	0X59
+#define DRB	0X60
+#define DRA	0X70
+#define DRT	0X78
+#define DRC	0X7C
+#define DRM	0X80
+#define DRORC	0X82
+#define ECCDIAG	0X84
+#define SDRC	0X88
+#define CKDIS	0X8C
+#define CKEDIS	0X8D
+#define DDRCSR	0X9A
+#define DEVPRES	0X9C
+#define  DEVPRES_D0F0 (1 << 0)
+#define  DEVPRES_D1F0 (1 << 1)
+#define  DEVPRES_D2F0 (1 << 2)
+#define  DEVPRES_D3F0 (1 << 3)
+#define  DEVPRES_D4F0 (1 << 4)
+#define  DEVPRES_D5F0 (1 << 5)
+#define  DEVPRES_D6F0 (1 << 6)
+#define  DEVPRES_D7F0 (1 << 7)
+#define ESMRC	0X9D
+#define SMRC	0X9E
+#define EXSMRC	0X9F
+#define DDR2ODTC 0XB0
+#define TOLM	0XC4
+#define REMAPBASE 0XC6
+#define REMAPLIMIT 0XC8
+#define REMAPOFFSET 0XCA
+#define TOM	0XCC
+#define EXPECBASE 0XCE
+#define DEVPRES1 0XF4
+#define  DEVPRES1_D0F1 (1 << 5)
+#define  DEVPRES1_D8F0 (1 << 1)
+#define MSCFG	0XF6
diff --git a/src/northbridge/intel/E7520/memory_initialized.c b/src/northbridge/intel/E7520/memory_initialized.c
new file mode 100644
index 0000000..3b9b696
--- /dev/null
+++ b/src/northbridge/intel/E7520/memory_initialized.c
@@ -0,0 +1,13 @@
+#include "e7520.h"
+#define NB_DEV PCI_DEV(0, 0, 0)
+
+static inline int memory_initialized(void)
+{
+	uint32_t drc;
+        drc = pci_read_config32(NB_DEV, DRC);
+        //print_debug("memory_initialized: DRC: ");
+        //print_debug_hex32(drc);
+        //print_debug("\r\n");
+
+    	return (drc & (1<<29));
+}	
diff --git a/src/northbridge/intel/E7520/northbridge.c b/src/northbridge/intel/E7520/northbridge.c
new file mode 100644
index 0000000..4449086
--- /dev/null
+++ b/src/northbridge/intel/E7520/northbridge.c
@@ -0,0 +1,270 @@
+#include <console/console.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/hypertransport.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bitops.h>
+#include <cpu/cpu.h>
+#include "chip.h"
+#include "northbridge.h"
+#include "e7520.h"
+
+
+static unsigned int max_bus;
+
+static void ram_resource(device_t dev, unsigned long index, 
+	unsigned long basek, unsigned long sizek)
+{
+	struct resource *resource;
+
+	resource = new_resource(dev, index);
+	resource->base  = ((resource_t)basek) << 10;
+	resource->size  = ((resource_t)sizek) << 10;
+	resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+		IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+
+static void pci_domain_read_resources(device_t dev)
+{
+	struct resource *resource;
+
+	/* Initialize the system wide io space constraints */
+	resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0,0));
+	resource->base  = 0;
+	resource->size  = 0;
+	resource->align = 0;
+	resource->gran  = 0;
+	resource->limit = 0xffffUL;
+	resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+	/* Initialize the system wide memory resources constraints */
+	resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1,0));
+	resource->base  = 0;
+	resource->size  = 0;
+	resource->align = 0;
+	resource->gran  = 0;
+	resource->limit = 0xffffffffUL;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void tolm_test(void *gp, struct device *dev, struct resource *new)
+{
+	struct resource **best_p = gp;
+	struct resource *best;
+	best = *best_p;
+	if (!best || (best->base > new->base)) {
+		best = new;
+	}
+	*best_p = best;
+}
+
+static uint32_t find_pci_tolm(struct bus *bus)
+{
+	struct resource *min;
+	uint32_t tolm;
+	min = 0;
+	search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
+	tolm = 0xffffffffUL;
+	if (min && tolm > min->base) {
+		tolm = min->base;
+	}
+	return tolm;
+}
+
+
+static void pci_domain_set_resources(device_t dev)
+{
+	device_t mc_dev;
+	uint32_t pci_tolm;
+
+        pci_tolm = find_pci_tolm(&dev->link[0]);
+
+#if 1
+	printk_debug("PCI mem marker = %x\n", pci_tolm);
+#endif	
+	/* FIXME Me temporary hack */
+	if(pci_tolm > 0xe0000000)
+		pci_tolm = 0xe0000000;
+	/* Ensure pci_tolm is 128M aligned */
+	pci_tolm &= 0xf8000000;
+	mc_dev = dev->link[0].children;
+	if (mc_dev) {
+		/* Figure out which areas are/should be occupied by RAM.
+		 * This is all computed in kilobytes and converted to/from
+		 * the memory controller right at the edges.
+		 * Having different variables in different units is
+		 * too confusing to get right.  Kilobytes are good up to
+		 * 4 Terabytes of RAM...
+		 */
+		uint16_t tolm_r, remapbase_r, remaplimit_r, remapoffset_r;
+		unsigned long tomk, tolmk;
+		unsigned long remapbasek, remaplimitk, remapoffsetk;
+
+		/* Get the Top of Memory address, units are 128M */
+		tomk = ((unsigned long)pci_read_config16(mc_dev, TOM)) << 17;
+		/* Compute the Top of Low Memory */
+		tolmk = (pci_tolm  & 0xf8000000) >> 10;
+
+		if (tolmk >= tomk) {
+			/* The PCI hole does not overlap memory
+			 * we won't use the remap window.
+			 */
+			tolmk = tomk;
+			remapbasek   = 0x3ff << 16;
+			remaplimitk  = 0 << 16;
+			remapoffsetk = 0 << 16;
+		} 
+		else {
+			/* The PCI memory hole overlaps memory
+			 * setup the remap window.
+			 */
+			/* Find the bottom of the remap window
+			 * is it above 4G?
+			 */
+			remapbasek = 4*1024*1024;
+			if (tomk > remapbasek) {
+				remapbasek = tomk;
+			}
+			/* Find the limit of the remap window */
+			remaplimitk  = (remapbasek + (4*1024*1024 - tolmk) - (1 << 16));
+			/* Find the offset of the remap window from tolm */
+			remapoffsetk = remapbasek - tolmk;
+		}
+		/* Write the ram configruation registers,
+		 * preserving the reserved bits.
+		 */
+		tolm_r = pci_read_config16(mc_dev, 0xc4);
+		tolm_r = ((tolmk >> 17) << 11) | (tolm_r & 0x7ff);
+		pci_write_config16(mc_dev, 0xc4, tolm_r);
+
+		remapbase_r = pci_read_config16(mc_dev, 0xc6);
+		remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00);
+		pci_write_config16(mc_dev, 0xc6, remapbase_r);
+
+		remaplimit_r = pci_read_config16(mc_dev, 0xc8);
+		remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00);
+		pci_write_config16(mc_dev, 0xc8, remaplimit_r);
+
+		remapoffset_r = pci_read_config16(mc_dev, 0xca);
+		remapoffset_r = (remapoffsetk >> 16) | (remapoffset_r & 0xfc00);
+		pci_write_config16(mc_dev, 0xca, remapoffset_r);
+
+		/* Report the memory regions */
+    		ram_resource(dev, 3,   0, 640);
+		ram_resource(dev, 4, 768, (tolmk - 768));
+		if (tomk > 4*1024*1024) {
+			ram_resource(dev, 5, 4096*1024, tomk - 4*1024*1024);
+		}
+		if (remaplimitk >= remapbasek) {
+			ram_resource(dev, 6, remapbasek, 
+				(remaplimitk + 64*1024) - remapbasek);
+		}
+	}
+	assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+	max = pci_scan_bus(&dev->link[0], 0, 0xff, max);
+	if (max > max_bus) {
+		max_bus = max;
+	}
+	return max;
+}
+
+static struct device_operations pci_domain_ops = {
+	.read_resources   = pci_domain_read_resources,
+	.set_resources    = pci_domain_set_resources,
+	.enable_resources = enable_childrens_resources,
+	.init             = 0,
+	.scan_bus         = pci_domain_scan_bus,
+	.ops_pci_bus      = &pci_cf8_conf1, /* Do we want to use the memory mapped space here? */
+};
+
+static void mc_read_resources(device_t dev)
+{
+	struct resource *resource;
+
+	pci_dev_read_resources(dev);
+
+	resource = new_resource(dev, 0xcf);
+	resource->base = 0xe0000000;
+	resource->size = max_bus * 4096*256;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |  IORESOURCE_ASSIGNED;
+}
+
+static void mc_set_resources(device_t dev)
+{
+	struct resource *resource, *last;
+
+	last = &dev->resource[dev->resources];
+	resource = find_resource(dev, 0xcf);
+	if (resource) {
+		report_resource_stored(dev, resource, "<mmconfig>");
+	}
+	pci_dev_set_resources(dev);
+}
+
+static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations intel_pci_ops = {
+	.set_subsystem = intel_set_subsystem,
+};
+
+static struct device_operations mc_ops = {
+	.read_resources   = mc_read_resources,
+	.set_resources    = mc_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = 0,
+	.ops_pci          = &intel_pci_ops,
+};
+
+static struct pci_driver mc_driver __pci_driver = {
+	.ops = &mc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x3590,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+        initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+        .read_resources   = cpu_bus_noop,
+        .set_resources    = cpu_bus_noop,
+        .enable_resources = cpu_bus_noop,
+        .init             = cpu_bus_init,
+        .scan_bus         = 0,
+};
+
+
+static void enable_dev(device_t dev)
+{
+	/* Set the operations if it is a special bus type */
+	if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+		dev->ops = &pci_domain_ops;
+	}
+	else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+		dev->ops = &cpu_bus_ops;
+	}
+}
+
+struct chip_operations northbridge_intel_E7520_ops = {
+	CHIP_NAME("Intel E7520 Northbridge")
+	.enable_dev = enable_dev,
+};
diff --git a/src/northbridge/intel/E7520/northbridge.h b/src/northbridge/intel/E7520/northbridge.h
new file mode 100644
index 0000000..516834f
--- /dev/null
+++ b/src/northbridge/intel/E7520/northbridge.h
@@ -0,0 +1,8 @@
+#ifndef NORTHBRIDGE_INTEL_E7520_H
+#define NORTHBRIDGE_INTEL_E7520_H
+
+extern unsigned int e7520_scan_root_bus(device_t root, unsigned int max);
+
+
+#endif /* NORTHBRIDGE_INTEL_E7520_H */
+
diff --git a/src/northbridge/intel/E7520/pciexp_porta.c b/src/northbridge/intel/E7520/pciexp_porta.c
new file mode 100644
index 0000000..5443d66
--- /dev/null
+++ b/src/northbridge/intel/E7520/pciexp_porta.c
@@ -0,0 +1,62 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+#include <part/hard_reset.h>
+                                                           
+typedef struct northbridge_intel_E7520_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static unsigned int pcie_scan_bridge(struct device *dev, unsigned int max)
+{
+	uint16_t val;
+	uint16_t ctl;
+	int flag = 0;
+	do {
+		val = pci_read_config16(dev, 0x76);
+		printk_debug("pcie porta 0x76: %02x\n", val);
+		if((val & (1<<10) )&&(!flag)) { /* training error */
+			ctl = pci_read_config16(dev, 0x74);
+			pci_write_config16(dev, 0x74, (ctl | (1<<5)));
+			val = pci_read_config16(dev, 0x76);
+			printk_debug("pcie porta reset 0x76: %02x\n", val);
+			flag=1;
+			hard_reset();
+		}
+	} while	( val & (3<<10) );
+	return pciexp_scan_bridge(dev, max);
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pcie_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PA,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7520/pciexp_porta1.c b/src/northbridge/intel/E7520/pciexp_porta1.c
new file mode 100644
index 0000000..b4dcb2f
--- /dev/null
+++ b/src/northbridge/intel/E7520/pciexp_porta1.c
@@ -0,0 +1,41 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7520_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PA1,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7520/pciexp_portb.c b/src/northbridge/intel/E7520/pciexp_portb.c
new file mode 100644
index 0000000..7f17925
--- /dev/null
+++ b/src/northbridge/intel/E7520/pciexp_portb.c
@@ -0,0 +1,42 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7520_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PB,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7520/pciexp_portc.c b/src/northbridge/intel/E7520/pciexp_portc.c
new file mode 100644
index 0000000..c46610b
--- /dev/null
+++ b/src/northbridge/intel/E7520/pciexp_portc.c
@@ -0,0 +1,41 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7520_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PC,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7520/raminit.c b/src/northbridge/intel/E7520/raminit.c
new file mode 100644
index 0000000..22ac115
--- /dev/null
+++ b/src/northbridge/intel/E7520/raminit.c
@@ -0,0 +1,1333 @@
+#include <cpu/x86/mem.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include "raminit.h"
+#include "e7520.h"
+
+#define BAR 0x40000000
+
+static void sdram_set_registers(const struct mem_controller *ctrl)
+{
+	static const unsigned int register_values[] = {
+
+		/* CKDIS 0x8c disable clocks */
+	PCI_ADDR(0, 0x00, 0, CKDIS), 0xffff0000, 0x0000ffff,
+
+		/* 0x9c Device present and extended RAM control 
+		 * DEVPRES is very touchy, hard code the initialization
+		 * of PCI-E ports here.
+		 */
+	PCI_ADDR(0, 0x00, 0, DEVPRES), 0x00000000, 0x07020801 | DEVPRES_CONFIG,
+
+		/* 0xc8 Remap RAM base and limit off */	
+	PCI_ADDR(0, 0x00, 0, REMAPLIMIT), 0x00000000, 0x03df0000,
+
+		/* ??? */
+	PCI_ADDR(0, 0x00, 0, 0xd8), 0x00000000, 0xb5930000,
+	PCI_ADDR(0, 0x00, 0, 0xe8), 0x00000000, 0x00004a2a,
+
+		/* 0x50 scrub */
+	PCI_ADDR(0, 0x00, 0, MCHCFG0), 0xfce0ffff, 0x00006000, /* 6000 */
+
+		/* 0x58 0x5c PAM */
+	PCI_ADDR(0, 0x00, 0, PAM-1), 0xcccccc7f, 0x33333000,
+	PCI_ADDR(0, 0x00, 0, PAM+3), 0xcccccccc, 0x33333333,
+
+		/* 0xf4 */
+	PCI_ADDR(0, 0x00, 0, DEVPRES1), 0xffbffff, (1<<22)|(6<<2) | DEVPRES1_CONFIG,
+
+		/* 0x14 */
+	PCI_ADDR(0, 0x00, 0, IURBASE), 0x00000fff, BAR |0,  
+	};
+	int i;
+	int max;
+
+	max = sizeof(register_values)/sizeof(register_values[0]);
+	for(i = 0; i < max; i += 3) {
+		device_t dev;
+		unsigned where;
+		unsigned long reg;
+		dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x00, 0) + ctrl->f0;
+		where = register_values[i] & 0xff;
+		reg = pci_read_config32(dev, where);
+		reg &= register_values[i+1];
+		reg |= register_values[i+2];
+		pci_write_config32(dev, where, reg);
+	}
+	print_spew("done.\r\n");
+}
+
+
+
+struct dimm_size {
+	unsigned long side1;
+	unsigned long side2;
+};
+
+static struct dimm_size spd_get_dimm_size(unsigned device)
+{
+	/* Calculate the log base 2 size of a DIMM in bits */
+	struct dimm_size sz;
+	int value, low, ddr2;
+	sz.side1 = 0;
+	sz.side2 = 0;
+
+	/* test for ddr2 */
+	ddr2=0;
+	value = spd_read_byte(device, 2);       /* type */
+        if (value < 0) goto hw_err;
+	if (value == 8) ddr2 = 1;
+
+	/* Note it might be easier to use byte 31 here, it has the DIMM size as
+	 * a multiple of 4MB.  The way we do it now we can size both
+	 * sides of an assymetric dimm.
+	 */
+	value = spd_read_byte(device, 3);	/* rows */
+	if (value < 0) goto hw_err;
+	if ((value & 0xf) == 0) goto val_err;
+	sz.side1 += value & 0xf;
+
+	value = spd_read_byte(device, 4);	/* columns */
+	if (value < 0) goto hw_err;
+	if ((value & 0xf) == 0) goto val_err;
+	sz.side1 += value & 0xf;
+
+	value = spd_read_byte(device, 17);	/* banks */
+	if (value < 0) goto hw_err;
+	if ((value & 0xff) == 0) goto val_err;
+	sz.side1 += log2(value & 0xff);
+
+	/* Get the module data width and convert it to a power of two */
+	value = spd_read_byte(device, 7);	/* (high byte) */
+	if (value < 0) goto hw_err;
+	value &= 0xff;
+	value <<= 8;
+	
+	low = spd_read_byte(device, 6);	/* (low byte) */
+	if (low < 0) goto hw_err;
+	value = value | (low & 0xff);
+	if ((value != 72) && (value != 64)) goto val_err;
+	sz.side1 += log2(value);
+
+	/* side 2 */
+	value = spd_read_byte(device, 5);	/* number of physical banks */
+
+	if (value < 0) goto hw_err;
+	value &= 7;
+	if(ddr2) value++;
+	if (value == 1) goto out;
+	if (value != 2) goto val_err;
+
+	/* Start with the symmetrical case */
+	sz.side2 = sz.side1;
+
+	value = spd_read_byte(device, 3);	/* rows */
+	if (value < 0) goto hw_err;
+	if ((value & 0xf0) == 0) goto out;	/* If symmetrical we are done */
+	sz.side2 -= (value & 0x0f);		/* Subtract out rows on side 1 */
+	sz.side2 += ((value >> 4) & 0x0f);	/* Add in rows on side 2 */
+
+	value = spd_read_byte(device, 4);	/* columns */
+	if (value < 0) goto hw_err;
+	if ((value & 0xff) == 0) goto val_err;
+	sz.side2 -= (value & 0x0f);		/* Subtract out columns on side 1 */
+	sz.side2 += ((value >> 4) & 0x0f);	/* Add in columsn on side 2 */
+	goto out;
+
+ val_err:
+	die("Bad SPD value\r\n");
+	/* If an hw_error occurs report that I have no memory */
+hw_err:
+	sz.side1 = 0;
+	sz.side2 = 0;
+ out:
+	return sz;
+
+}
+
+static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
+{
+	int i;
+	int cum;
+	
+	for(i = cum = 0; i < DIMM_SOCKETS; i++) {
+		struct dimm_size sz;
+		if (dimm_mask & (1 << i)) {
+			sz = spd_get_dimm_size(ctrl->channel0[i]);
+			if (sz.side1 < 29) {
+				return -1; /* Report SPD error */
+			}
+			/* convert bits to multiples of 64MB */
+			sz.side1 -= 29;
+			cum += (1 << sz.side1);
+			/* DRB = 0x60 */
+			pci_write_config8(ctrl->f0, DRB + (i*2), cum);
+			if( sz.side2 > 28) {
+				sz.side2 -= 29;
+				cum += (1 << sz.side2);
+			}
+			pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
+		}
+		else {
+			pci_write_config8(ctrl->f0, DRB + (i*2), cum);
+			pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
+		}
+	}
+	/* set TOM top of memory 0xcc */
+	pci_write_config16(ctrl->f0, TOM, cum);
+	/* set TOLM top of low memory */
+	if(cum > 0x18) {
+		cum = 0x18;
+	}
+	cum <<= 11;
+	/* 0xc4 TOLM */
+	pci_write_config16(ctrl->f0, TOLM, cum);
+	return 0;
+}
+
+
+static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
+{
+	unsigned dimm_mask;
+	int i;
+	dimm_mask = 0;
+	for(i = 0; i < DIMM_SOCKETS; i++) {
+		int byte;
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			byte = spd_read_byte(device, 2);  /* Type */
+			if ((byte == 7) || (byte == 8)) {
+				dimm_mask |= (1 << i);
+			}
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			byte = spd_read_byte(device, 2);
+			if ((byte == 7) || (byte == 8)) {
+				dimm_mask |= (1 << (i + DIMM_SOCKETS));
+			}
+		}
+	}
+	return dimm_mask;
+}
+
+
+static int spd_set_row_attributes(const struct mem_controller *ctrl, 
+		long dimm_mask)
+{
+
+	int value;
+	int reg;
+	int dra;
+	int cnt;
+
+	dra = 0;
+	for(cnt=0; cnt < 4; cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+			continue;
+		}
+		reg =0;
+		value = spd_read_byte(ctrl->channel0[cnt], 3);	/* rows */
+		if (value < 0) goto hw_err;
+		if ((value & 0xf) == 0) goto val_err;
+		reg += value & 0xf;
+
+		value = spd_read_byte(ctrl->channel0[cnt], 4);	/* columns */
+		if (value < 0) goto hw_err;
+		if ((value & 0xf) == 0) goto val_err;
+		reg += value & 0xf;
+
+		value = spd_read_byte(ctrl->channel0[cnt], 17);	/* banks */
+		if (value < 0) goto hw_err;
+		if ((value & 0xff) == 0) goto val_err;
+		reg += log2(value & 0xff);
+
+		/* Get the device width and convert it to a power of two */
+		value = spd_read_byte(ctrl->channel0[cnt], 13);	
+		if (value < 0) goto hw_err;
+		value = log2(value & 0xff);
+		reg += value;
+		if(reg < 27) goto hw_err;
+		reg -= 27;
+		reg += (value << 2);
+	
+		dra += reg << (cnt*8);
+		value = spd_read_byte(ctrl->channel0[cnt], 5);
+		if (value & 2)
+			dra += reg << ((cnt*8)+4);	
+	}
+
+	/* 0x70 DRA */
+	pci_write_config32(ctrl->f0, DRA, dra);	
+	goto out;
+
+ val_err:
+	die("Bad SPD value\r\n");
+	/* If an hw_error occurs report that I have no memory */
+hw_err:
+	dra = 0;
+ out:
+	return dra;
+
+}
+
+
+static int spd_set_drt_attributes(const struct mem_controller *ctrl, 
+		long dimm_mask, uint32_t drc)
+{
+	int value;
+	int reg;
+	uint32_t drt;
+	int cnt;
+	int first_dimm;
+	int cas_latency=0;
+	int latency;
+	uint32_t index = 0;
+	uint32_t index2 = 0;
+	static const unsigned char cycle_time[3] = {0x75,0x60,0x50}; 
+	static const int latency_indicies[] = { 26, 23, 9 };
+
+	/* 0x78 DRT */
+	drt = pci_read_config32(ctrl->f0, DRT);
+	drt &= 3;  /* save bits 1:0 */
+	
+	for(first_dimm = 0; first_dimm < 4; first_dimm++) {
+		if (dimm_mask & (1 << first_dimm)) 
+			break;
+	}
+	
+	/* get dimm type */
+	value = spd_read_byte(ctrl->channel0[first_dimm], 2);
+	if(value == 8) {
+		drt |= (3<<5); /* back to bark write turn around & cycle add */
+	}	
+
+	drt |= (3<<18);  /* Trasmax */
+
+	for(cnt=0; cnt < 4; cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+			continue;
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 18); /* CAS Latency */
+		/* Compute the lowest cas latency supported */
+		latency = log2(reg) -2;
+	
+		/* Loop through and find a fast clock with a low latency */
+		for(index = 0; index < 3; index++, latency++) {
+			if ((latency < 2) || (latency > 4) ||
+				(!(reg & (1 << latency)))) {
+				continue;
+			}
+			value = spd_read_byte(ctrl->channel0[cnt], 
+				        latency_indicies[index]);
+	  
+			if(value <= cycle_time[drc&3]) {
+				if( latency > cas_latency) {
+					cas_latency = latency;
+				}
+				break;
+			}	
+		}
+	}
+	index = (cas_latency-2);
+	if((index)==0) cas_latency = 20;
+	else if((index)==1) cas_latency = 25;
+	else cas_latency = 30;
+
+	for(cnt=0;cnt<4;cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+                        continue;
+                }
+		reg = spd_read_byte(ctrl->channel0[cnt], 27)&0x0ff;
+		if(((index>>8)&0x0ff)<reg) {
+			index &= ~(0x0ff << 8);
+			index |= (reg << 8);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 28)&0x0ff;
+		if(((index>>16)&0x0ff)<reg) {
+			index &= ~(0x0ff << 16);
+			index |= (reg<<16);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 29)&0x0ff;
+		if(((index2>>0)&0x0ff)<reg) {
+			index2 &= ~(0x0ff << 0);
+			index2 |= (reg<<0);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 41)&0x0ff;
+		if(((index2>>8)&0x0ff)<reg) {
+			index2 &= ~(0x0ff << 8);
+			index2 |= (reg<<8);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 42)&0x0ff;
+		if(((index2>>16)&0x0ff)<reg) {
+			index2 &= ~(0x0ff << 16);
+			index2 |= (reg<<16);
+		}
+	}
+
+	/* get dimm speed */
+	value = cycle_time[drc&3];
+	if(value <= 0x50) {  /* 200 MHz */
+		if((index&7) > 2) {
+			drt |= (2<<2);  /* CAS latency 4 */
+			cas_latency = 40;
+		} else {
+			drt |= (1<<2);  /* CAS latency 3 */
+			cas_latency = 30;
+		}
+		if((index&0x0ff00)<=0x03c00) {
+			drt |= (1<<8);  /* Trp RAS Precharg */
+		} else {
+			drt |= (2<<8);  /* Trp RAS Precharg */
+		}
+		
+		/* Trcd RAS to CAS delay */
+		if((index2&0x0ff)<=0x03c) {
+			drt |= (0<<10);
+		} else {
+			drt |= (1<<10);
+		}
+
+		/* Tdal Write auto precharge recovery delay */
+		drt |= (1<<12);
+	
+		/* Trc TRS min */
+		if((index2&0x0ff00)<=0x03700)
+			drt |= (0<<14);
+		else if((index2&0xff00)<=0x03c00)
+			drt |= (1<<14);
+		else
+			drt |= (2<<14); /* spd 41 */
+		
+		drt |= (2<<16);  /* Twr not defined for DDR docs say use 2 */
+		
+		/* Trrd Row Delay */
+		if((index&0x0ff0000)<=0x0140000) {
+			drt |= (0<<20);
+		} else if((index&0x0ff0000)<=0x0280000) {
+			drt |= (1<<20);
+		} else if((index&0x0ff0000)<=0x03c0000) {
+			drt |= (2<<20);
+		} else {
+			drt |= (3<<20);
+		}
+		
+		/* Trfc Auto refresh cycle time */
+		if((index2&0x0ff0000)<=0x04b0000) {
+			drt |= (0<<22);
+		} else if((index2&0x0ff0000)<=0x0690000) {
+			drt |= (1<<22);
+		} else {
+			drt |= (2<<22);
+		}
+		/* Docs say use 55 for all 200Mhz */
+		drt |= (0x055<<24);
+	}
+	else if(value <= 0x60) { /* 167 Mhz */
+		/* according to new documentation CAS latency is 00
+		 * for bits 3:2 for all 167 Mhz 
+		drt |= ((index&3)<<2); */  /* set CAS latency */
+		if((index&0x0ff00)<=0x03000) {
+			drt |= (1<<8);  /* Trp RAS Precharg */
+		} else {
+			drt |= (2<<8);  /* Trp RAS Precharg */
+		}
+		
+		/* Trcd RAS to CAS delay */
+		if((index2&0x0ff)<=0x030) {
+			drt |= (0<<10);
+		} else {
+			drt |= (1<<10);
+		}
+
+		/* Tdal Write auto precharge recovery delay */
+		drt |= (2<<12); 
+		
+		/* Trc TRS min */
+		drt |= (2<<14); /* spd 41, but only one choice */
+		
+		drt |= (2<<16);  /* Twr not defined for DDR docs say 2 */
+		
+		/* Trrd Row Delay */
+		if((index&0x0ff0000)<=0x0180000) {
+			drt |= (0<<20);
+		} else if((index&0x0ff0000)<=0x0300000) {
+			drt |= (1<<20);
+		} else {
+			drt |= (2<<20);
+		}
+		
+		/* Trfc Auto refresh cycle time */
+		if((index2&0x0ff0000)<=0x0480000) {
+			drt |= (0<<22);
+		} else if((index2&0x0ff0000)<=0x0780000) {
+			drt |= (2<<22);
+		} else {
+			drt |= (2<<22);
+		}
+		/* Docs state to use 99 for all 167 Mhz */
+		drt |= (0x099<<24);
+	}
+	else if(value <= 0x75) { /* 133 Mhz */
+		drt |= ((index&3)<<2);  /* set CAS latency */
+		if((index&0x0ff00)<=0x03c00) {
+			drt |= (1<<8);  /* Trp RAS Precharg */
+		} else {
+			drt |= (2<<8);  /* Trp RAS Precharg */
+		}
+
+		/* Trcd RAS to CAS delay */
+		if((index2&0x0ff)<=0x03c) {
+			drt |= (0<<10);
+		} else {
+			drt |= (1<<10);
+		}
+
+		/* Tdal Write auto precharge recovery delay */
+		drt |= (1<<12); 
+		
+		/* Trc TRS min */
+		drt |= (2<<14); /* spd 41, but only one choice */
+		
+		drt |= (1<<16);  /* Twr not defined for DDR docs say 1 */
+		
+		/* Trrd Row Delay */
+		if((index&0x0ff0000)<=0x01e0000) {
+			drt |= (0<<20);
+		} else if((index&0x0ff0000)<=0x03c0000) {
+			drt |= (1<<20);
+		} else {
+			drt |= (2<<20);
+		}
+		
+		/* Trfc Auto refresh cycle time */
+		if((index2&0x0ff0000)<=0x04b0000) {
+			drt |= (0<<22);
+		} else if((index2&0x0ff0000)<=0x0780000) {
+			drt |= (2<<22);
+		} else {
+			drt |= (2<<22);
+		}
+		
+		/* Based on CAS latency */
+		if(index&7)
+			drt |= (0x099<<24);
+		else
+			drt |= (0x055<<24);
+		
+	}
+	else {
+		die("Invalid SPD 9 bus speed.\r\n");
+	}
+
+	/* 0x78 DRT */
+	pci_write_config32(ctrl->f0, DRT, drt);
+
+	return(cas_latency);
+}
+
+static int spd_set_dram_controller_mode(const struct mem_controller *ctrl, 
+		long dimm_mask)
+{
+	int value;
+	int reg;
+	int drc;
+	int cnt;
+	msr_t msr;
+	unsigned char dram_type = 0xff;
+	unsigned char ecc = 0xff;
+	unsigned char rate = 62;
+	static const unsigned char spd_rates[6] = {15,3,7,7,62,62}; 
+	static const unsigned char drc_rates[5] = {0,15,7,62,3};
+	static const unsigned char fsb_conversion[4] = {3,1,3,2};
+
+	/* 0x7c DRC */
+	drc = pci_read_config32(ctrl->f0, DRC);	
+	for(cnt=0; cnt < 4; cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+			continue;
+		}
+		value = spd_read_byte(ctrl->channel0[cnt], 11);	/* ECC */
+		reg = spd_read_byte(ctrl->channel0[cnt], 2); /* Type */
+		if (value == 2) {    /* RAM is ECC capable */
+			if (reg == 8) {
+				if ( ecc == 0xff ) {
+					ecc = 2;
+				}
+				else if (ecc == 1) {
+					die("ERROR - Mixed DDR & DDR2 RAM\r\n");
+				}
+			} 
+			else if ( reg == 7 ) {
+				if ( ecc == 0xff) {
+					ecc = 1;
+				}
+				else if ( ecc > 1 ) {
+					die("ERROR - Mixed DDR & DDR2 RAM\r\n");
+				}
+			}	
+			else {
+				die("ERROR - RAM not DDR\r\n");
+			}
+		}
+		else {
+			die("ERROR - Non ECC memory dimm\r\n");
+		}
+
+		value = spd_read_byte(ctrl->channel0[cnt], 12);	/*refresh rate*/
+		value &= 0x0f;    /* clip self refresh bit */
+		if (value > 5) goto hw_err;
+		if (rate > spd_rates[value])
+			rate = spd_rates[value];
+
+		value = spd_read_byte(ctrl->channel0[cnt], 9);	/* cycle time */
+		if (value > 0x75) goto hw_err;
+		if (value <= 0x50) {
+			if (dram_type >= 2) {
+				if (reg == 8) { /*speed is good, is this ddr2?*/
+					dram_type = 2;
+				} else { /* not ddr2 so use ddr333 */
+					dram_type = 1;
+				}
+			}
+		}
+		else if (value <= 0x60) {
+			if (dram_type >= 1)  dram_type = 1;
+		}
+		else dram_type = 0; /* ddr266 */
+
+	}
+	ecc = 2;
+	if (read_option(CMOS_VSTART_ECC_memory,CMOS_VLEN_ECC_memory,1) == 0) {
+		ecc = 0;  /* ECC off in CMOS so disable it */
+		print_debug("ECC off\r\n");
+	}
+	else {
+		print_debug("ECC on\r\n");
+	}
+	drc &= ~(3 << 20); /* clear the ecc bits */
+	drc |= (ecc << 20);  /* or in the calculated ecc bits */
+	for ( cnt = 1; cnt < 5; cnt++)
+		if (drc_rates[cnt] == rate)
+			break;
+	if (cnt < 5) {
+		drc &= ~(7 << 8);  /* clear the rate bits */
+		drc |= (cnt << 8);
+	}
+
+	if (reg == 8) { /* independant clocks */
+		drc |= (1 << 4);
+	}
+
+	drc |= (1 << 26); /* set the overlap bit - the factory BIOS does */
+	drc |= (1 << 27); /* set DED retry enable - the factory BIOS does */
+	/* front side bus */
+	msr = rdmsr(0x2c);
+	value = msr.lo >> 16;
+	value &= 0x03;
+	drc &= ~(3 << 2); /* set the front side bus */
+	drc |= (fsb_conversion[value] << 2);
+	drc &= ~(3 << 0); /* set the dram type */
+	drc |= (dram_type << 0);
+		
+	goto out;
+
+ val_err:
+	die("Bad SPD value\r\n");
+	/* If an hw_error occurs report that I have no memory */
+hw_err:
+	drc = 0;
+ out:
+	return drc;
+}
+
+static void sdram_set_spd_registers(const struct mem_controller *ctrl) 
+{
+	long dimm_mask;
+
+	/* Test if we can read the spd and if ram is ddr or ddr2 */
+	dimm_mask = spd_detect_dimms(ctrl);
+	if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
+		print_err("No memory for this cpu\r\n");
+		return;
+	}
+	return;
+}
+
+static void do_delay(void)
+{
+	int i;
+	unsigned char b;
+	for(i=0;i<16;i++)
+		b=inb(0x80);
+}	
+
+static void pll_setup(uint32_t drc)
+{
+	unsigned pins;
+	if(drc&3) { /* DDR 333 or DDR 400 */
+		if((drc&0x0c) == 0x0c) { /* FSB 200 */
+			pins = 2 | 1;
+		}
+		else if((drc&0x0c) == 0x08) {   /* FSB 167 */
+			pins = 0 | 1;
+		}
+		else if(drc&1){  /* FSB 133 DDR 333 */
+			pins = 2 | 1;
+		}
+		else { /* FSB 133 DDR 400 */
+			pins = 0 | 1;
+		}
+	}
+	else { /* DDR 266 */
+		if((drc&0x08) == 0x08) { /* FSB 200 or 167 */
+			pins = 0 | 0;
+		}
+		else { /* FSB 133 */
+			pins = 0 | 1;
+		}
+	}
+	mainboard_set_e7520_pll(pins);
+	return;
+}	
+
+#define TIMEOUT_LOOPS 300000
+
+#define DCALCSR  0x100
+#define DCALADDR 0x104
+#define DCALDATA 0x108
+
+static void set_on_dimm_termination_enable(const struct mem_controller *ctrl)
+{
+	unsigned char c1,c2;
+        unsigned int dimm,i;
+        unsigned int data32;
+	unsigned int t4;
+ 
+	/* Set up northbridge values */
+	/* ODT enable */
+  	pci_write_config32(ctrl->f0, 0x88, 0xf0000180);
+	/* Figure out which slots are Empty, Single, or Double sided */
+	for(i=0,t4=0,c2=0;i<8;i+=2) {
+		c1 = pci_read_config8(ctrl->f0, DRB+i);
+		if(c1 == c2) continue;
+		c2 = pci_read_config8(ctrl->f0, DRB+1+i);
+		if(c1 == c2)
+			t4 |= (1 << (i*4));
+		else
+			t4 |= (2 << (i*4));
+	}
+	for(i=0;i<1;i++) {
+	    if((t4&0x0f) == 1) {
+		if( ((t4>>8)&0x0f) == 0 ) {
+			data32 = 0x00000010; /* EEES */ 
+			break;
+		}
+		if ( ((t4>>16)&0x0f) == 0 ) { 
+			data32 = 0x00003132; /* EESS */
+			break;
+		}
+		if ( ((t4>>24)&0x0f)  == 0 ) {
+			data32 = 0x00335566; /* ESSS */
+			break;
+		}
+		data32 = 0x77bbddee; /* SSSS */
+		break;
+	    }
+	    if((t4&0x0f) == 2) {
+		if( ((t4>>8)&0x0f) == 0 ) {
+			data32 = 0x00003132; /* EEED */ 
+			break;
+		}
+		if ( ((t4>>8)&0x0f) == 2 ) {
+			data32 = 0xb373ecdc; /* EEDD */
+			break;
+		}
+		if ( ((t4>>16)&0x0f) == 0 ) {
+			data32 = 0x00b3a898; /* EESD */
+			break;
+		}
+		data32 = 0x777becdc; /* ESSD */
+		break;
+	    }
+	    die("Error - First dimm slot empty\r\n");
+	}
+
+	print_debug("ODT Value = ");
+	print_debug_hex32(data32);
+	print_debug("\r\n");
+
+  	pci_write_config32(ctrl->f0, 0xb0, data32);
+
+	for(dimm=0;dimm<8;dimm+=1) {
+
+		write32(BAR+DCALADDR, 0x0b840001);
+		write32(BAR+DCALCSR, 0x83000003 | (dimm << 20));
+		
+		for(i=0;i<1001;i++) {
+			data32 = read32(BAR+DCALCSR);
+			if(!(data32 & (1<<31)))
+				break;
+		}
+	}
+}	
+static void set_receive_enable(const struct mem_controller *ctrl)
+{
+	unsigned int i;
+	unsigned int cnt;
+	uint32_t recena=0;
+	uint32_t recenb=0;
+
+	{	
+	unsigned int dimm;
+	unsigned int edge;
+	int32_t data32;
+	uint32_t data32_dram;
+	uint32_t dcal_data32_0;
+	uint32_t dcal_data32_1;
+	uint32_t dcal_data32_2;
+	uint32_t dcal_data32_3;
+	uint32_t work32l;
+	uint32_t work32h;
+	uint32_t data32r;
+	int32_t recen;
+	for(dimm=0;dimm<8;dimm+=1) {
+
+		if(!(dimm&1)) {
+			write32(BAR+DCALDATA+(17*4), 0x04020000);
+			write32(BAR+DCALCSR, 0x83800004 | (dimm << 20));
+		
+			for(i=0;i<1001;i++) {
+				data32 = read32(BAR+DCALCSR);
+				if(!(data32 & (1<<31)))
+					break;
+			}
+			if(i>=1000)
+				continue;
+		
+			dcal_data32_0 = read32(BAR+DCALDATA + 0);
+			dcal_data32_1 = read32(BAR+DCALDATA + 4);
+			dcal_data32_2 = read32(BAR+DCALDATA + 8);
+			dcal_data32_3 = read32(BAR+DCALDATA + 12);
+		}
+		else {
+			dcal_data32_0 = read32(BAR+DCALDATA + 16);
+			dcal_data32_1 = read32(BAR+DCALDATA + 20);
+			dcal_data32_2 = read32(BAR+DCALDATA + 24);
+			dcal_data32_3 = read32(BAR+DCALDATA + 28);
+		}
+
+		/* check if bank is installed */
+		if((dcal_data32_0 == 0) && (dcal_data32_2 == 0))
+			continue;
+		/* Calculate the timing value */
+		{
+		unsigned int bit;
+		for(i=0,edge=0,bit=63,cnt=31,data32r=0,
+			work32l=dcal_data32_1,work32h=dcal_data32_3;
+				(i<4) && bit; i++) {
+			for(;;bit--,cnt--) {
+				if(work32l & (1<<cnt))
+					break;
+				if(!cnt) {
+					work32l = dcal_data32_0;
+					work32h = dcal_data32_2;
+					cnt = 32;
+				}
+				if(!bit) break;
+			}
+			for(;;bit--,cnt--) {
+				if(!(work32l & (1<<cnt)))
+					break;
+				if(!cnt) {
+					work32l = dcal_data32_0;
+					work32h = dcal_data32_2;
+					cnt = 32;
+				}
+				if(!bit) break;
+			}
+			if(!bit) {
+				break;
+			}
+			data32 = ((bit%8) << 1);
+			if(work32h & (1<<cnt))
+				data32 += 1;
+			if(data32 < 4) {
+				if(!edge) {
+					edge = 1;
+				}
+				else {
+					if(edge != 1) {
+						data32 = 0x0f;
+					}
+				}
+			}
+			if(data32 > 12) {
+				if(!edge) {
+					edge = 2;
+				}
+				else {
+					if(edge != 2) {
+						data32 = 0x00;
+					}
+				}
+			}
+			data32r += data32;
+		}
+		}
+		work32l = dcal_data32_0;
+		work32h = dcal_data32_2;
+		recen = data32r;
+		recen += 3;
+		recen = recen>>2;
+		for(cnt=5;cnt<24;) {
+			for(;;cnt++)
+				if(!(work32l & (1<<cnt)))
+					break;
+			for(;;cnt++) {
+				if(work32l & (1<<cnt))
+					break;
+			}
+			data32 = (((cnt-1)%8)<<1);
+			if(work32h & (1<<(cnt-1))) {
+				data32++;
+			}
+			/* test for frame edge cross overs */
+			if((edge == 1) && (data32 > 12) && 
+			    (((recen+16)-data32) < 3)) {
+				data32 = 0;
+				cnt += 2;
+			}
+			if((edge == 2) && (data32 < 4) &&
+			    ((recen - data32) > 12))  {
+				data32 = 0x0f;
+				cnt -= 2;
+			}
+			if(((recen+3) >= data32) && ((recen-3) <= data32))
+				break;
+		}
+		cnt--;
+		cnt /= 8;
+		cnt--;
+		if(recen&1)
+			recen+=2;
+		recen >>= 1;
+		recen += (cnt*8);
+		recen+=2;      /* this is not in the spec, but matches
+				 the factory output, and has less failure */
+		recen <<= (dimm/2) * 8;
+		if(!(dimm&1)) {
+			recena |= recen;
+		}
+		else {
+			recenb |= recen;
+		}
+	}
+	}
+	/* Check for Eratta problem */
+	for(i=cnt=0;i<32;i+=8) {
+		if (((recena>>i)&0x0f)>7) {
+			cnt+= 0x101;
+		}
+		else {
+			if((recena>>i)&0x0f) {
+				cnt++;
+			}
+		}
+	}
+	if(cnt&0x0f00) {
+		cnt = (cnt&0x0f) - (cnt>>16);
+		if(cnt>1) {
+			for(i=0;i<32;i+=8) {
+				if(((recena>>i)&0x0f)>7) {
+					recena &= ~(0x0f<<i);
+					recena |= (7<<i);
+				}
+			}
+		}
+		else {
+			for(i=0;i<32;i+=8) {
+				if(((recena>>i)&0x0f)<8) {
+					recena &= ~(0x0f<<i);
+					recena |= (8<<i);
+				}
+			}
+		}
+	}
+	for(i=cnt=0;i<32;i+=8) {
+		if (((recenb>>i)&0x0f)>7) {
+			cnt+= 0x101;
+		}
+		else {
+			if((recenb>>i)&0x0f) {
+				cnt++;
+			}
+		}
+	}
+	if(cnt & 0x0f00) {
+		cnt = (cnt&0x0f) - (cnt>>16);
+		if(cnt>1) {
+			for(i=0;i<32;i+=8) {
+				if(((recenb>>i)&0x0f)>7) {
+					recenb &= ~(0x0f<<i);
+					recenb |= (7<<i);
+				}
+			}
+		}
+		else {
+			for(i=0;i<32;i+=8) {
+				if(((recenb>>8)&0x0f)<8) {
+					recenb &= ~(0x0f<<i);
+					recenb |= (8<<i);
+				}
+			}
+		}
+	}
+
+	print_debug("Receive enable A = ");
+	print_debug_hex32(recena);
+	print_debug(",  Receive enable B = ");
+	print_debug_hex32(recenb);
+	print_debug("\r\n");
+
+	/* clear out the calibration area */
+	write32(BAR+DCALDATA+(16*4), 0x00000000);
+	write32(BAR+DCALDATA+(17*4), 0x00000000);
+	write32(BAR+DCALDATA+(18*4), 0x00000000);
+	write32(BAR+DCALDATA+(19*4), 0x00000000);
+
+	/* No command */
+	write32(BAR+DCALCSR, 0x0000000f);
+
+	write32(BAR+0x150, recena);
+	write32(BAR+0x154, recenb);
+}
+
+
+static void sdram_enable(int controllers, const struct mem_controller *ctrl)
+{
+	int i;
+	int cs;
+	int cnt;
+	int cas_latency;
+	long mask;
+	uint32_t drc;
+	uint32_t data32;
+	uint32_t mode_reg;
+	uint32_t *iptr;
+	volatile unsigned long *iptrv;
+	msr_t msr;
+	uint32_t scratch;
+	uint8_t byte;
+	uint16_t data16;
+	static const struct {
+		uint32_t clkgr[4];
+	} gearing [] = {
+		/* FSB 133 DIMM 266 */
+	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+		/* FSB 133 DIMM 333 */
+	{{ 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+		/* FSB 133 DIMM 400 */
+	{{ 0x00000120, 0x00000000, 0x00000032, 0x00000010}},
+		/* FSB 167 DIMM 266 */
+	{{ 0x00005432, 0x00001000, 0x00004325, 0x00000000}},
+		/* FSB 167 DIMM 333 */
+	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+		/* FSB 167 DIMM 400 */
+	{{ 0x00154320, 0x00000000, 0x00065432, 0x00010000}},
+		/* FSB 200 DIMM 266 */
+	{{ 0x00000032, 0x00000010, 0x00000120, 0x00000000}},
+		/* FSB 200 DIMM 333 */
+	{{ 0x00065432, 0x00010000, 0x00154320, 0x00000000}},
+		/* FSB 200 DIMM 400 */
+	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+	};
+	
+	static const uint32_t dqs_data[] = {
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff,	0x000000ff,
+		0xffffffff, 0xffffffff, 0x000000ff,
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff};
+
+	mask = spd_detect_dimms(ctrl);
+	print_debug("Starting SDRAM Enable\r\n");
+
+	/* 0x80 */
+#ifdef DIMM_MAP_LOGICAL
+	pci_write_config32(ctrl->f0, DRM,
+		0x00210000 | DIMM_MAP_LOGICAL);
+#else
+	pci_write_config32(ctrl->f0, DRM, 0x00211248);
+#endif
+	/* set dram type and Front Side Bus freq. */
+	drc = spd_set_dram_controller_mode(ctrl, mask);
+	if( drc == 0) {
+		die("Error calculating DRC\r\n");
+	}
+	pll_setup(drc);
+	data32 = drc & ~(3 << 20);  /* clear ECC mode */
+	data32 = data32 & ~(7 << 8);  /* clear refresh rates */
+	data32 = data32 | (1 << 5);  /* temp turn off of ODT */
+  	/* Set gearing, then dram controller mode */
+  	/* drc bits 1:0 = DIMM speed, bits 3:2 = FSB speed */
+  	for(iptr = gearing[(drc&3)+((((drc>>2)&3)-1)*3)].clkgr,cnt=0;
+			cnt<4;cnt++) {
+  		pci_write_config32(ctrl->f0, 0xa0+(cnt*4), iptr[cnt]);
+	}
+	/* 0x7c DRC */
+  	pci_write_config32(ctrl->f0, DRC, data32);
+	
+		/* turn the clocks on */
+	/* 0x8c CKDIS */
+  	pci_write_config16(ctrl->f0, CKDIS, 0x0000);
+	
+		/* 0x9a DDRCSR Take subsystem out of idle */
+  	data16 = pci_read_config16(ctrl->f0, DDRCSR);
+	data16 &= ~(7 << 12);
+	data16 |= (3 << 12);   /* use dual channel lock step */
+  	pci_write_config16(ctrl->f0, DDRCSR, data16);
+	
+		/* program row size DRB */
+	spd_set_ram_size(ctrl, mask);
+
+		/* program page size DRA */
+	spd_set_row_attributes(ctrl, mask);
+
+		/* program DRT timing values */	
+	cas_latency = spd_set_drt_attributes(ctrl, mask, drc);
+
+	for(i=0;i<8;i++) { /* loop throught each dimm to test for row */
+		print_debug("DIMM ");
+		print_debug_hex8(i);
+		print_debug("\r\n");
+		/* Apply NOP */
+		do_delay();
+		
+		write32(BAR + 0x100, (0x03000000 | (i<<20)));
+
+		write32(BAR+0x100, (0x83000000 | (i<<20)));
+
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+
+	}
+	
+	/* Apply NOP */
+	do_delay();
+
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR + DCALCSR, (0x83000000 | (cs<<20))); 
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Precharg all banks */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		if ((drc & 3) == 2) /* DDR2  */
+                        write32(BAR+DCALADDR, 0x04000000);
+                else   /* DDR1  */
+                        write32(BAR+DCALADDR, 0x00000000);
+		write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+		
+	/* EMRS dll's enabled */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		if ((drc & 3) == 2) /* DDR2  */
+			/* fixme hard code AL additive latency */
+                        write32(BAR+DCALADDR, 0x0b940001);
+                else   /* DDR1  */
+                        write32(BAR+DCALADDR, 0x00000001);
+		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	/* MRS reset dll's */
+	do_delay();
+	if ((drc & 3) == 2) {  /* DDR2  */
+                if(cas_latency == 30)
+                        mode_reg = 0x053a0000;
+                else
+                        mode_reg = 0x054a0000;
+        }
+        else {  /* DDR1  */
+                if(cas_latency == 20)
+                        mode_reg = 0x012a0000;
+                else  /*  CAS Latency 2.5 */
+                        mode_reg = 0x016a0000;
+        }
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALADDR, mode_reg);
+		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Precharg all banks */
+	do_delay();
+	do_delay();
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		if ((drc & 3) == 2) /* DDR2  */
+                        write32(BAR+DCALADDR, 0x04000000);
+                else   /* DDR1  */
+                        write32(BAR+DCALADDR, 0x00000000);
+		write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	
+	/* Do 2 refreshes */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	do_delay();
+	/* for good luck do 6 more */
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	/* MRS reset dll's normal */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALADDR, (mode_reg & ~(1<<24)));
+		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Do only if DDR2  EMRS dll's enabled */
+        if ((drc & 3) == 2) { /* DDR2  */
+                do_delay();
+                for(cs=0;cs<8;cs++) {
+                        write32(BAR+DCALADDR, (0x0b940001));
+                        write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+			data32 = read32(BAR+DCALCSR);
+			while(data32 & 0x80000000)
+				data32 = read32(BAR+DCALCSR);
+                }
+        }
+
+	do_delay();
+	/* No command */
+	write32(BAR+DCALCSR, 0x0000000f);
+
+	/* DDR1 This is test code to copy some codes in the factory setup */
+	
+	write32(BAR, 0x00100000);
+
+        if ((drc & 3) == 2) { /* DDR2  */
+	/* enable on dimm termination */
+		set_on_dimm_termination_enable(ctrl);
+	}
+	else { /* ddr */
+                pci_write_config32(ctrl->f0, 0x88, 0xa0000000 );
+        }
+
+	/* receive enable calibration */
+	set_receive_enable(ctrl);
+	
+	/* DQS */
+	pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); 
+	for(i = 0, cnt = (BAR+0x200); i < 24; i++, cnt+=4) {
+		write32(cnt, dqs_data[i]);
+	}
+	pci_write_config32(ctrl->f0, 0x94, 0x3904a100 );
+
+	/* Enable refresh */
+	/* 0x7c DRC */
+	data32 = drc & ~(3 << 20);  /* clear ECC mode */
+	pci_write_config32(ctrl->f0, DRC, data32);	
+	write32(BAR+DCALCSR, 0x0008000f);
+
+	/* clear memory and init ECC */
+	print_debug("Clearing memory\r\n");
+	for(i=0;i<64;i+=4) {
+		write32(BAR+DCALDATA+i, 0x00000000);
+	}
+	
+	for(cs=0;cs<8;cs++) {
+		write32(BAR+DCALCSR, (0x830831d8 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Bring memory subsystem on line */
+	data32 = pci_read_config32(ctrl->f0, 0x98);
+	data32 |= (1 << 31);
+	pci_write_config32(ctrl->f0, 0x98, data32);
+	/* wait for completion */
+	print_debug("Waiting for mem complete\r\n");
+	while(1) {
+		data32 = pci_read_config32(ctrl->f0, 0x98);
+		if( (data32 & (1<<31)) == 0)
+			break;
+	}
+	print_debug("Done\r\n");
+	
+	/* Set initialization complete */
+	/* 0x7c DRC */
+	drc |= (1 << 29);
+	data32 = drc & ~(3 << 20);  /* clear ECC mode */
+	pci_write_config32(ctrl->f0, DRC, data32);	
+
+	/* Set the ecc mode */
+	pci_write_config32(ctrl->f0, DRC, drc);	
+
+	/* Enable memory scrubbing */
+	/* 0x52 MCHSCRB */	
+	data16 = pci_read_config16(ctrl->f0, MCHSCRB);
+	data16 &= ~0x0f;
+	data16 |= ((2 << 2) | (2 << 0));
+	pci_write_config16(ctrl->f0, MCHSCRB, data16);	
+
+	/* The memory is now setup, use it */
+	cache_lbmem(MTRR_TYPE_WRBACK);
+}
diff --git a/src/northbridge/intel/E7520/raminit.h b/src/northbridge/intel/E7520/raminit.h
new file mode 100644
index 0000000..183ace8
--- /dev/null
+++ b/src/northbridge/intel/E7520/raminit.h
@@ -0,0 +1,12 @@
+#ifndef RAMINIT_H
+#define RAMINIT_H
+
+#define DIMM_SOCKETS 4
+struct mem_controller {
+	unsigned node_id;
+	device_t f0, f1, f2, f3;
+	uint16_t channel0[DIMM_SOCKETS];
+	uint16_t channel1[DIMM_SOCKETS];
+};
+
+#endif /* RAMINIT_H */
diff --git a/src/northbridge/intel/E7520/raminit_test.c b/src/northbridge/intel/E7520/raminit_test.c
new file mode 100644
index 0000000..a69bafd
--- /dev/null
+++ b/src/northbridge/intel/E7520/raminit_test.c
@@ -0,0 +1,442 @@
+#include <unistd.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <setjmp.h>
+#include <device/pci_def.h>
+#include "e7520.h"
+
+jmp_buf end_buf;
+
+static int is_cpu_pre_c0(void)
+{
+	return 0;
+}
+
+#define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
+	(((BUS) & 0xFF) << 16) | \
+	(((DEV) & 0x1f) << 11) | \
+	(((FN) & 0x07) << 8) | \
+	((WHERE) & 0xFF))
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+	(((BUS) & 0xFF) << 16) | \
+	(((DEV) & 0x1f) << 11) | \
+	(((FN)  & 0x7) << 8))
+
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+
+typedef unsigned device_t;
+
+unsigned char pci_register[256*5*3*256];
+
+static uint8_t pci_read_config8(device_t dev, unsigned where)
+{
+	unsigned addr;
+	addr = dev | where;
+	return pci_register[addr];
+}
+
+static uint16_t pci_read_config16(device_t dev, unsigned where)
+{
+	unsigned addr;
+	addr = dev | where;
+	return pci_register[addr] | (pci_register[addr + 1]  << 8);
+}
+
+static uint32_t pci_read_config32(device_t dev, unsigned where)
+{
+	unsigned addr;
+	uint32_t value;
+	addr = dev | where;
+	value =  pci_register[addr] | 
+		(pci_register[addr + 1]  << 8) |
+		(pci_register[addr + 2]  << 16) |
+		(pci_register[addr + 3]  << 24);
+
+#if 0
+	print_debug("pcir32(");
+	print_debug_hex32(addr);
+	print_debug("):");
+	print_debug_hex32(value);
+	print_debug("\n");
+#endif
+	return value;
+
+}
+
+static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
+{
+	unsigned addr;
+	addr = dev | where;
+	pci_register[addr] = value;
+}
+
+static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
+{
+	unsigned addr;
+	addr = dev | where;
+	pci_register[addr] = value & 0xff;
+	pci_register[addr + 1] = (value >> 8) & 0xff;
+}
+
+static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
+{
+	unsigned addr;
+	addr = dev | where;
+	pci_register[addr] = value & 0xff;
+	pci_register[addr + 1] = (value >> 8) & 0xff;
+	pci_register[addr + 2] = (value >> 16) & 0xff;
+	pci_register[addr + 3] = (value >> 24) & 0xff;
+
+#if 0
+	print_debug("pciw32(");
+	print_debug_hex32(addr);
+	print_debug(", ");
+	print_debug_hex32(value);
+	print_debug(")\n");
+#endif
+}
+
+#define PCI_DEV_INVALID (0xffffffffU)
+static device_t pci_locate_device(unsigned pci_id, device_t dev)
+{
+	for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
+		unsigned int id;
+		id = pci_read_config32(dev, 0);
+		if (id == pci_id) {
+			return dev;
+		}
+	}
+	return PCI_DEV_INVALID;
+}
+
+
+
+
+static void uart_tx_byte(unsigned char data)
+{
+	write(STDOUT_FILENO, &data, 1);
+}
+static void hlt(void)
+{
+	longjmp(end_buf, 2);
+}
+#include "../../../arch/i386/lib/console.c"
+
+unsigned long log2(unsigned long x)
+{
+        // assume 8 bits per byte.
+        unsigned long i = 1 << (sizeof(x)*8 - 1);
+        unsigned long pow = sizeof(x) * 8 - 1;
+
+        if (! x) {
+		static const char errmsg[] = " called with invalid parameter of 0\n";
+		write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
+		write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+                hlt();
+        }
+        for(; i > x; i >>= 1, pow--)
+                ;
+
+        return pow;
+}
+
+typedef struct msr_struct 
+{
+	unsigned lo;
+	unsigned hi;
+} msr_t;
+
+static inline msr_t rdmsr(unsigned index)
+{
+	msr_t result;
+	result.lo = 0;
+	result.hi = 0;
+	return result;
+}
+
+static inline void wrmsr(unsigned index, msr_t msr)
+{
+}
+
+#include "raminit.h"
+
+#define SIO_BASE 0x2e
+
+static void hard_reset(void)
+{
+	/* FIXME implement the hard reset case... */
+	longjmp(end_buf, 3);
+}
+
+static void memreset_setup(void)
+{
+	/* Nothing to do */
+}
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+	/* Nothing to do */
+}
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+
+
+static uint8_t spd_mt4lsdt464a[256] = 
+{
+	0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70, 
+	0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01, 
+	0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
+
+	0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
+	0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
+	0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
+	0x06, 0x07, 0x08, 0x09, 0x00,
+};
+
+static uint8_t spd_micron_512MB_DDR333[256] = 
+{
+	0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60, 
+	0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01, 
+	0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48, 
+	0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31, 
+	0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 
+	0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff 
+};
+
+static uint8_t spd_micron_256MB_DDR333[256] = 
+{
+	0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60, 
+	0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01, 
+	0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48, 
+	0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36, 
+	0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
+	0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+};
+
+#define MAX_DIMMS 16
+static uint8_t spd_data[MAX_DIMMS*256];
+
+static unsigned spd_count, spd_fail_count;
+static int spd_read_byte(unsigned device, unsigned address)
+{
+	int result;
+	spd_count++;
+	if ((device < 0x50) || (device >= (0x50 +MAX_DIMMS))) {
+		result = -1;
+	}
+	else {
+		device -= 0x50;
+		
+		if (address > 256) {
+			result = -1;
+		}
+		else if (spd_data[(device << 8) | 2] != 7) {
+			result = -1;
+		}
+		else {
+			result = spd_data[(device << 8) | address];
+		}
+	}
+#if 0
+	print_debug("spd_read_byte(");
+	print_debug_hex32(device);
+	print_debug(", ");
+	print_debug_hex32(address);
+	print_debug(") -> ");
+	print_debug_hex32(result);
+	print_debug("\n");
+#endif
+	if (spd_count >= spd_fail_count) {
+		result = -1;
+	}
+	return result;
+}
+
+/* no specific code here. this should go away completely */
+static void coherent_ht_mainboard(unsigned cpus)
+{
+}
+
+#include "raminit.c"
+#include "../../../sdram/generic_sdram.c"
+
+#define FIRST_CPU  1
+#define SECOND_CPU 1
+#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
+static void raminit_main(void)
+{
+	/*
+	 * GPIO28 of 8111 will control H0_MEMRESET_L
+	 * GPIO29 of 8111 will control H1_MEMRESET_L
+	 */
+	static const struct mem_controller cpu[] = {
+#if FIRST_CPU
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x18, 0),
+			.f1 = PCI_DEV(0, 0x18, 1),
+			.f2 = PCI_DEV(0, 0x18, 2),
+			.f3 = PCI_DEV(0, 0x18, 3),
+			.channel0 = { 0x50+0, 0x50+2, 0x50+4, 0x50+6 },
+			.channel1 = { 0x50+1, 0x50+3, 0x50+5, 0x50+7 },
+		},
+#endif
+#if SECOND_CPU
+		{
+			.node_id = 1,
+			.f0 = PCI_DEV(0, 0x19, 0),
+			.f1 = PCI_DEV(0, 0x19, 1),
+			.f2 = PCI_DEV(0, 0x19, 2),
+			.f3 = PCI_DEV(0, 0x19, 3),
+			.channel0 = { 0x50+8, 0x50+10, 0x50+12, 0x50+14 },
+			.channel1 = { 0x50+9, 0x50+11, 0x50+13, 0x50+15 },
+		},
+#endif
+	};
+	console_init();
+	memreset_setup();
+	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
+
+}
+
+static void reset_tests(void)
+{
+	/* Clear the results of any previous tests */
+	memset(pci_register, 0, sizeof(pci_register));
+	memset(spd_data, 0, sizeof(spd_data));
+	spd_count = 0;
+	spd_fail_count = UINT_MAX;
+
+	pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
+		NBCAP_128Bit |
+		NBCAP_MP|  NBCAP_BIG_MP |
+		/* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
+		(NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
+		NBCAP_MEMCTRL);
+
+	pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
+		NBCAP_128Bit |
+		NBCAP_MP|  NBCAP_BIG_MP |
+		/* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
+		(NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
+		NBCAP_MEMCTRL);
+
+#if 0
+	pci_read_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP);
+#endif
+}
+
+static void test1(void)
+{
+	reset_tests();
+
+	memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
+#if 0
+	memcpy(&spd_data[2*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[3*256], spd_micron_512MB_DDR333, 256);
+
+	memcpy(&spd_data[8*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[9*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[10*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[11*256], spd_micron_512MB_DDR333, 256);
+#endif
+
+	raminit_main();
+	
+#if 0
+	print_debug("spd_count: ");
+	print_debug_hex32(spd_count);
+	print_debug("\r\n");
+#endif
+	
+}
+
+
+static void do_test2(int i)
+{
+	jmp_buf tmp_buf;
+	memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
+	if (setjmp(end_buf) != 0) {
+		goto done;
+	}
+	reset_tests();
+	spd_fail_count = i;
+
+	print_debug("\r\nSPD will fail after: ");
+	print_debug_hex32(spd_fail_count);
+	print_debug(" accesses.\r\n");
+	
+	memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
+	
+	raminit_main();
+
+ done:
+	memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
+}
+
+static void test2(void)
+{
+	int i;
+	for(i = 0; i < 0x48; i++) {
+		do_test2(i);
+	}
+	
+}
+
+int main(int argc, char **argv)
+{
+	if (setjmp(end_buf) != 0) {
+		return -1;
+	}
+	test1();
+	test2();
+	return 0;
+}
diff --git a/src/northbridge/intel/E7525/Config.lb b/src/northbridge/intel/E7525/Config.lb
new file mode 100644
index 0000000..919e0f8
--- /dev/null
+++ b/src/northbridge/intel/E7525/Config.lb
@@ -0,0 +1,12 @@
+config chip.h
+driver northbridge.o
+driver pciexp_porta.o
+driver pciexp_porta1.o
+driver pciexp_portb.o
+driver pciexp_portc.o
+
+makerule raminit_test
+	depends "$(TOP)/src/northbridge/intel/e7525/raminit_test.c"
+	depends "$(TOP)/src/northbridge/intel/e7525/raminit.c"
+	action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g  $< -o $@"
+end
diff --git a/src/northbridge/intel/E7525/chip.h b/src/northbridge/intel/E7525/chip.h
new file mode 100644
index 0000000..19d8c4e
--- /dev/null
+++ b/src/northbridge/intel/E7525/chip.h
@@ -0,0 +1,7 @@
+struct northbridge_intel_E7525_config
+{
+        /* Interrupt line connect */
+        unsigned int intrline;
+};
+
+extern struct chip_operations northbridge_intel_E7525_ops;
diff --git a/src/northbridge/intel/E7525/e7525.h b/src/northbridge/intel/E7525/e7525.h
new file mode 100644
index 0000000..be76303
--- /dev/null
+++ b/src/northbridge/intel/E7525/e7525.h
@@ -0,0 +1,44 @@
+#define VID     0X00
+#define DID     0X02
+#define PCICMD  0X04
+#define PCISTS  0X06
+#define RID	0X08
+#define IURBASE	0X14
+#define MCHCFG0	0X50
+#define MCHSCRB	0X52
+#define FDHC	0X58
+#define PAM	0X59
+#define DRB	0X60
+#define DRA	0X70
+#define DRT	0X78
+#define DRC	0X7C
+#define DRM	0X80
+#define DRORC	0X82
+#define ECCDIAG	0X84
+#define SDRC	0X88
+#define CKDIS	0X8C
+#define CKEDIS	0X8D
+#define DDRCSR	0X9A
+#define DEVPRES	0X9C
+#define  DEVPRES_D0F0 (1 << 0)
+#define  DEVPRES_D1F0 (1 << 1)
+#define  DEVPRES_D2F0 (1 << 2)
+#define  DEVPRES_D3F0 (1 << 3)
+#define  DEVPRES_D4F0 (1 << 4)
+#define  DEVPRES_D5F0 (1 << 5)
+#define  DEVPRES_D6F0 (1 << 6)
+#define  DEVPRES_D7F0 (1 << 7)
+#define ESMRC	0X9D
+#define SMRC	0X9E
+#define EXSMRC	0X9F
+#define DDR2ODTC 0XB0
+#define TOLM	0XC4
+#define REMAPBASE 0XC6
+#define REMAPLIMIT 0XC8
+#define REMAPOFFSET 0XCA
+#define TOM	0XCC
+#define EXPECBASE 0XCE
+#define DEVPRES1 0XF4
+#define  DEVPRES1_D0F1 (1 << 5)
+#define  DEVPRES1_D8F0 (1 << 1)
+#define MSCFG	0XF6
diff --git a/src/northbridge/intel/E7525/memory_initialized.c b/src/northbridge/intel/E7525/memory_initialized.c
new file mode 100644
index 0000000..6eb31a8
--- /dev/null
+++ b/src/northbridge/intel/E7525/memory_initialized.c
@@ -0,0 +1,9 @@
+#include "e7525.h"
+#define NB_DEV PCI_DEV(0, 0, 0)
+
+static inline int memory_initialized(void)
+{
+	uint32_t drc;
+        drc = pci_read_config32(NB_DEV, DRC);
+    	return (drc & (1<<29));
+}	
diff --git a/src/northbridge/intel/E7525/northbridge.c b/src/northbridge/intel/E7525/northbridge.c
new file mode 100644
index 0000000..71f1722
--- /dev/null
+++ b/src/northbridge/intel/E7525/northbridge.c
@@ -0,0 +1,270 @@
+#include <console/console.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/hypertransport.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bitops.h>
+#include <cpu/cpu.h>
+#include "chip.h"
+#include "northbridge.h"
+#include "e7525.h"
+
+
+static unsigned int max_bus;
+
+static void ram_resource(device_t dev, unsigned long index, 
+	unsigned long basek, unsigned long sizek)
+{
+	struct resource *resource;
+
+	resource = new_resource(dev, index);
+	resource->base  = ((resource_t)basek) << 10;
+	resource->size  = ((resource_t)sizek) << 10;
+	resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+		IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+
+static void pci_domain_read_resources(device_t dev)
+{
+	struct resource *resource;
+
+	/* Initialize the system wide io space constraints */
+	resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0,0));
+	resource->base  = 0;
+	resource->size  = 0;
+	resource->align = 0;
+	resource->gran  = 0;
+	resource->limit = 0xffffUL;
+	resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+	/* Initialize the system wide memory resources constraints */
+	resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1,0));
+	resource->base  = 0;
+	resource->size  = 0;
+	resource->align = 0;
+	resource->gran  = 0;
+	resource->limit = 0xffffffffUL;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void tolm_test(void *gp, struct device *dev, struct resource *new)
+{
+	struct resource **best_p = gp;
+	struct resource *best;
+	best = *best_p;
+	if (!best || (best->base > new->base)) {
+		best = new;
+	}
+	*best_p = best;
+}
+
+static uint32_t find_pci_tolm(struct bus *bus)
+{
+	struct resource *min;
+	uint32_t tolm;
+	min = 0;
+	search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
+	tolm = 0xffffffffUL;
+	if (min && tolm > min->base) {
+		tolm = min->base;
+	}
+	return tolm;
+}
+
+
+static void pci_domain_set_resources(device_t dev)
+{
+	device_t mc_dev;
+	uint32_t pci_tolm;
+
+        pci_tolm = find_pci_tolm(&dev->link[0]);
+
+#if 1
+	printk_debug("PCI mem marker = %x\n", pci_tolm);
+#endif	
+	/* FIXME Me temporary hack */
+	if(pci_tolm > 0xe0000000)
+		pci_tolm = 0xe0000000;
+	/* Ensure pci_tolm is 128M aligned */
+	pci_tolm &= 0xf8000000;
+	mc_dev = dev->link[0].children;
+	if (mc_dev) {
+		/* Figure out which areas are/should be occupied by RAM.
+		 * This is all computed in kilobytes and converted to/from
+		 * the memory controller right at the edges.
+		 * Having different variables in different units is
+		 * too confusing to get right.  Kilobytes are good up to
+		 * 4 Terabytes of RAM...
+		 */
+		uint16_t tolm_r, remapbase_r, remaplimit_r, remapoffset_r;
+		unsigned long tomk, tolmk;
+		unsigned long remapbasek, remaplimitk, remapoffsetk;
+
+		/* Get the Top of Memory address, units are 128M */
+		tomk = ((unsigned long)pci_read_config16(mc_dev, TOM)) << 17;
+		/* Compute the Top of Low Memory */
+		tolmk = (pci_tolm  & 0xf8000000) >> 10;
+
+		if (tolmk >= tomk) {
+			/* The PCI hole does not overlap memory
+			 * we won't use the remap window.
+			 */
+			tolmk = tomk;
+			remapbasek   = 0x3ff << 16;
+			remaplimitk  = 0 << 16;
+			remapoffsetk = 0 << 16;
+		} 
+		else {
+			/* The PCI memory hole overlaps memory
+			 * setup the remap window.
+			 */
+			/* Find the bottom of the remap window
+			 * is it above 4G?
+			 */
+			remapbasek = 4*1024*1024;
+			if (tomk > remapbasek) {
+				remapbasek = tomk;
+			}
+			/* Find the limit of the remap window */
+			remaplimitk  = (remapbasek + (4*1024*1024 - tolmk) - (1 << 16));
+			/* Find the offset of the remap window from tolm */
+			remapoffsetk = remapbasek - tolmk;
+		}
+		/* Write the ram configruation registers,
+		 * preserving the reserved bits.
+		 */
+		tolm_r = pci_read_config16(mc_dev, 0xc4);
+		tolm_r = ((tolmk >> 17) << 11) | (tolm_r & 0x7ff);
+		pci_write_config16(mc_dev, 0xc4, tolm_r);
+
+		remapbase_r = pci_read_config16(mc_dev, 0xc6);
+		remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00);
+		pci_write_config16(mc_dev, 0xc6, remapbase_r);
+
+		remaplimit_r = pci_read_config16(mc_dev, 0xc8);
+		remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00);
+		pci_write_config16(mc_dev, 0xc8, remaplimit_r);
+
+		remapoffset_r = pci_read_config16(mc_dev, 0xca);
+		remapoffset_r = (remapoffsetk >> 16) | (remapoffset_r & 0xfc00);
+		pci_write_config16(mc_dev, 0xca, remapoffset_r);
+
+		/* Report the memory regions */
+    		ram_resource(dev, 3,   0, 640);
+		ram_resource(dev, 4, 768, tolmk - 768);
+		if (tomk > 4*1024*1024) {
+			ram_resource(dev, 5, 4096*1024, tomk - 4*1024*1024);
+		}
+		if (remaplimitk >= remapbasek) {
+			ram_resource(dev, 6, remapbasek, 
+				(remaplimitk + 64*1024) - remapbasek);
+		}
+	}
+	assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+	max = pci_scan_bus(&dev->link[0], 0, 0xff, max);
+	if (max > max_bus) {
+		max_bus = max;
+	}
+	return max;
+}
+
+static struct device_operations pci_domain_ops = {
+	.read_resources   = pci_domain_read_resources,
+	.set_resources    = pci_domain_set_resources,
+	.enable_resources = enable_childrens_resources,
+	.init             = 0,
+	.scan_bus         = pci_domain_scan_bus,
+	.ops_pci_bus      = &pci_cf8_conf1, /* Do we want to use the memory mapped space here? */
+};
+
+static void mc_read_resources(device_t dev)
+{
+	struct resource *resource;
+
+	pci_dev_read_resources(dev);
+
+	resource = new_resource(dev, 0xcf);
+	resource->base = 0xe0000000;
+	resource->size = max_bus * 4096*256;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |  IORESOURCE_ASSIGNED;
+}
+
+static void mc_set_resources(device_t dev)
+{
+	struct resource *resource, *last;
+
+	last = &dev->resource[dev->resources];
+	resource = find_resource(dev, 0xcf);
+	if (resource) {
+		report_resource_stored(dev, resource, "<mmconfig>");
+	}
+	pci_dev_set_resources(dev);
+}
+
+static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations intel_pci_ops = {
+	.set_subsystem = intel_set_subsystem,
+};
+
+static struct device_operations mc_ops = {
+	.read_resources   = mc_read_resources,
+	.set_resources    = mc_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = 0,
+	.ops_pci          = &intel_pci_ops,
+};
+
+static struct pci_driver mc_driver __pci_driver = {
+	.ops = &mc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x359e,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+        initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+        .read_resources   = cpu_bus_noop,
+        .set_resources    = cpu_bus_noop,
+        .enable_resources = cpu_bus_noop,
+        .init             = cpu_bus_init,
+        .scan_bus         = 0,
+};
+
+
+static void enable_dev(device_t dev)
+{
+	/* Set the operations if it is a special bus type */
+	if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+		dev->ops = &pci_domain_ops;
+	}
+	else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+		dev->ops = &cpu_bus_ops;
+	}
+}
+
+struct chip_operations northbridge_intel_E7525_ops = {
+	CHIP_NAME("Intel E7525 Northbridge")
+	.enable_dev = enable_dev,
+};
diff --git a/src/northbridge/intel/E7525/northbridge.h b/src/northbridge/intel/E7525/northbridge.h
new file mode 100644
index 0000000..0ee533f
--- /dev/null
+++ b/src/northbridge/intel/E7525/northbridge.h
@@ -0,0 +1,8 @@
+#ifndef NORTHBRIDGE_INTEL_E7525_H
+#define NORTHBRIDGE_INTEL_E7525_H
+
+extern unsigned int e7525_scan_root_bus(device_t root, unsigned int max);
+
+
+#endif /* NORTHBRIDGE_INTEL_E7525_H */
+
diff --git a/src/northbridge/intel/E7525/pciexp_porta.c b/src/northbridge/intel/E7525/pciexp_porta.c
new file mode 100644
index 0000000..093edec
--- /dev/null
+++ b/src/northbridge/intel/E7525/pciexp_porta.c
@@ -0,0 +1,41 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7525_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PA,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7525/pciexp_porta1.c b/src/northbridge/intel/E7525/pciexp_porta1.c
new file mode 100644
index 0000000..7118caa
--- /dev/null
+++ b/src/northbridge/intel/E7525/pciexp_porta1.c
@@ -0,0 +1,41 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7525_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PA1,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7525/pciexp_portb.c b/src/northbridge/intel/E7525/pciexp_portb.c
new file mode 100644
index 0000000..f623a54
--- /dev/null
+++ b/src/northbridge/intel/E7525/pciexp_portb.c
@@ -0,0 +1,41 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7525_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PB,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7525/pciexp_portc.c b/src/northbridge/intel/E7525/pciexp_portc.c
new file mode 100644
index 0000000..05e0b68
--- /dev/null
+++ b/src/northbridge/intel/E7525/pciexp_portc.c
@@ -0,0 +1,41 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+                                                           
+typedef struct northbridge_intel_E7525_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+        config_t *config;
+                                                                                
+        /* Get the chip configuration */
+        config = dev->chip_info;
+                                                                                
+        if(config->intrline) {
+                pci_write_config32(dev, 0x3c, config->intrline);
+        }
+
+}
+
+static struct device_operations pcie_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+        .enable_resources = pci_bus_enable_resources,
+        .init             = pcie_init,
+        .scan_bus         = pciexp_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+        .ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+        .ops    = &pcie_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_PCIE_PC,
+};
+                                                                                
+
diff --git a/src/northbridge/intel/E7525/raminit.c b/src/northbridge/intel/E7525/raminit.c
new file mode 100644
index 0000000..c0e6b42
--- /dev/null
+++ b/src/northbridge/intel/E7525/raminit.c
@@ -0,0 +1,1300 @@
+#include <cpu/x86/mem.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include "raminit.h"
+#include "e7525.h"
+
+#define BAR 0x40000000
+
+static void sdram_set_registers(const struct mem_controller *ctrl)
+{
+	static const unsigned int register_values[] = {
+
+		/* CKDIS 0x8c disable clocks */
+	PCI_ADDR(0, 0x00, 0, CKDIS), 0xffff0000, 0x0000ffff,
+
+		/* 0x9c Device present and extended RAM control 
+		 * DEVPRES is very touchy, hard code the initialization
+		 * of PCI-E ports here.
+		 */
+	PCI_ADDR(0, 0x00, 0, DEVPRES), 0x00000000, 0x07020801 | DEVPRES_CONFIG,
+
+		/* 0xc8 Remap RAM base and limit off */	
+	PCI_ADDR(0, 0x00, 0, REMAPLIMIT), 0x00000000, 0x03df0000,
+
+		/* ??? */
+	PCI_ADDR(0, 0x00, 0, 0xd8), 0x00000000, 0xb5930000,
+	PCI_ADDR(0, 0x00, 0, 0xe8), 0x00000000, 0x00004a2a,
+
+		/* 0x50 scrub */
+	PCI_ADDR(0, 0x00, 0, MCHCFG0), 0xfce0ffff, 0x00006000, /* 6000 */
+
+		/* 0x58 0x5c PAM */
+	PCI_ADDR(0, 0x00, 0, PAM-1), 0xcccccc7f, 0x33333000,
+	PCI_ADDR(0, 0x00, 0, PAM+3), 0xcccccccc, 0x33333333,
+
+		/* 0xf4 */
+	PCI_ADDR(0, 0x00, 0, DEVPRES1), 0xffbffff, (1<<22)|(6<<2) | DEVPRES1_CONFIG,
+
+		/* 0x14 */
+	PCI_ADDR(0, 0x00, 0, IURBASE), 0x00000fff, BAR |0,  
+	};
+	int i;
+	int max;
+
+	max = sizeof(register_values)/sizeof(register_values[0]);
+	for(i = 0; i < max; i += 3) {
+		device_t dev;
+		unsigned where;
+		unsigned long reg;
+		dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x00, 0) + ctrl->f0;
+		where = register_values[i] & 0xff;
+		reg = pci_read_config32(dev, where);
+		reg &= register_values[i+1];
+		reg |= register_values[i+2];
+		pci_write_config32(dev, where, reg);
+	}
+	print_spew("done.\r\n");
+}
+
+
+
+struct dimm_size {
+	unsigned long side1;
+	unsigned long side2;
+};
+
+static struct dimm_size spd_get_dimm_size(unsigned device)
+{
+	/* Calculate the log base 2 size of a DIMM in bits */
+	struct dimm_size sz;
+	int value, low, ddr2;
+	sz.side1 = 0;
+	sz.side2 = 0;
+
+	/* test for ddr2 */
+	ddr2=0;
+	value = spd_read_byte(device, 2);       /* type */
+        if (value < 0) goto hw_err;
+	if (value == 8) ddr2 = 1;
+
+	/* Note it might be easier to use byte 31 here, it has the DIMM size as
+	 * a multiple of 4MB.  The way we do it now we can size both
+	 * sides of an assymetric dimm.
+	 */
+	value = spd_read_byte(device, 3);	/* rows */
+	if (value < 0) goto hw_err;
+	if ((value & 0xf) == 0) goto val_err;
+	sz.side1 += value & 0xf;
+
+	value = spd_read_byte(device, 4);	/* columns */
+	if (value < 0) goto hw_err;
+	if ((value & 0xf) == 0) goto val_err;
+	sz.side1 += value & 0xf;
+
+	value = spd_read_byte(device, 17);	/* banks */
+	if (value < 0) goto hw_err;
+	if ((value & 0xff) == 0) goto val_err;
+	sz.side1 += log2(value & 0xff);
+
+	/* Get the module data width and convert it to a power of two */
+	value = spd_read_byte(device, 7);	/* (high byte) */
+	if (value < 0) goto hw_err;
+	value &= 0xff;
+	value <<= 8;
+	
+	low = spd_read_byte(device, 6);	/* (low byte) */
+	if (low < 0) goto hw_err;
+	value = value | (low & 0xff);
+	if ((value != 72) && (value != 64)) goto val_err;
+	sz.side1 += log2(value);
+
+	/* side 2 */
+	value = spd_read_byte(device, 5);	/* number of physical banks */
+
+	if (value < 0) goto hw_err;
+	value &= 7;
+	if(ddr2) value++;
+	if (value == 1) goto out;
+	if (value != 2) goto val_err;
+
+	/* Start with the symmetrical case */
+	sz.side2 = sz.side1;
+
+	value = spd_read_byte(device, 3);	/* rows */
+	if (value < 0) goto hw_err;
+	if ((value & 0xf0) == 0) goto out;	/* If symmetrical we are done */
+	sz.side2 -= (value & 0x0f);		/* Subtract out rows on side 1 */
+	sz.side2 += ((value >> 4) & 0x0f);	/* Add in rows on side 2 */
+
+	value = spd_read_byte(device, 4);	/* columns */
+	if (value < 0) goto hw_err;
+	if ((value & 0xff) == 0) goto val_err;
+	sz.side2 -= (value & 0x0f);		/* Subtract out columns on side 1 */
+	sz.side2 += ((value >> 4) & 0x0f);	/* Add in columsn on side 2 */
+	goto out;
+
+ val_err:
+	die("Bad SPD value\r\n");
+	/* If an hw_error occurs report that I have no memory */
+hw_err:
+	sz.side1 = 0;
+	sz.side2 = 0;
+ out:
+	return sz;
+
+}
+
+static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
+{
+	int i;
+	int cum;
+	
+	for(i = cum = 0; i < DIMM_SOCKETS; i++) {
+		struct dimm_size sz;
+		if (dimm_mask & (1 << i)) {
+			sz = spd_get_dimm_size(ctrl->channel0[i]);
+			if (sz.side1 < 29) {
+				return -1; /* Report SPD error */
+			}
+			/* convert bits to multiples of 64MB */
+			sz.side1 -= 29;
+			cum += (1 << sz.side1);
+			/* DRB = 0x60 */
+			pci_write_config8(ctrl->f0, DRB + (i*2), cum);
+			if( sz.side2 > 28) {
+				sz.side2 -= 29;
+				cum += (1 << sz.side2);
+			}
+			pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
+		}
+		else {
+			pci_write_config8(ctrl->f0, DRB + (i*2), cum);
+			pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
+		}
+	}
+	/* set TOM top of memory 0xcc */
+	pci_write_config16(ctrl->f0, TOM, cum);
+	/* set TOLM top of low memory */
+	if(cum > 0x18) {
+		cum = 0x18;
+	}
+	cum <<= 11;
+	/* 0xc4 TOLM */
+	pci_write_config16(ctrl->f0, TOLM, cum);
+	return 0;
+}
+
+
+static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
+{
+	unsigned dimm_mask;
+	int i;
+	dimm_mask = 0;
+	for(i = 0; i < DIMM_SOCKETS; i++) {
+		int byte;
+		unsigned device;
+		device = ctrl->channel0[i];
+		if (device) {
+			byte = spd_read_byte(device, 2);  /* Type */
+			if ((byte == 7) || (byte == 8)) {
+				dimm_mask |= (1 << i);
+			}
+		}
+		device = ctrl->channel1[i];
+		if (device) {
+			byte = spd_read_byte(device, 2);
+			if ((byte == 7) || (byte == 8)) {
+				dimm_mask |= (1 << (i + DIMM_SOCKETS));
+			}
+		}
+	}
+	return dimm_mask;
+}
+
+
+static int spd_set_row_attributes(const struct mem_controller *ctrl, 
+		long dimm_mask)
+{
+
+	int value;
+	int reg;
+	int dra;
+	int cnt;
+
+	dra = 0;
+	for(cnt=0; cnt < 4; cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+			continue;
+		}
+		reg =0;
+		value = spd_read_byte(ctrl->channel0[cnt], 3);	/* rows */
+		if (value < 0) goto hw_err;
+		if ((value & 0xf) == 0) goto val_err;
+		reg += value & 0xf;
+
+		value = spd_read_byte(ctrl->channel0[cnt], 4);	/* columns */
+		if (value < 0) goto hw_err;
+		if ((value & 0xf) == 0) goto val_err;
+		reg += value & 0xf;
+
+		value = spd_read_byte(ctrl->channel0[cnt], 17);	/* banks */
+		if (value < 0) goto hw_err;
+		if ((value & 0xff) == 0) goto val_err;
+		reg += log2(value & 0xff);
+
+		/* Get the device width and convert it to a power of two */
+		value = spd_read_byte(ctrl->channel0[cnt], 13);	
+		if (value < 0) goto hw_err;
+		value = log2(value & 0xff);
+		reg += value;
+		if(reg < 27) goto hw_err;
+		reg -= 27;
+		reg += (value << 2);
+	
+		dra += reg << (cnt*8);
+		value = spd_read_byte(ctrl->channel0[cnt], 5);
+		if (value & 2)
+			dra += reg << ((cnt*8)+4);	
+	}
+
+	/* 0x70 DRA */
+	pci_write_config32(ctrl->f0, DRA, dra);	
+	goto out;
+
+ val_err:
+	die("Bad SPD value\r\n");
+	/* If an hw_error occurs report that I have no memory */
+hw_err:
+	dra = 0;
+ out:
+	return dra;
+
+}
+
+
+static int spd_set_drt_attributes(const struct mem_controller *ctrl, 
+		long dimm_mask, uint32_t drc)
+{
+	int value;
+	int reg;
+	uint32_t drt;
+	int cnt;
+	int first_dimm;
+	int cas_latency=0;
+	int latency;
+	uint32_t index = 0;
+	uint32_t index2 = 0;
+	static const unsigned char cycle_time[3] = {0x75,0x60,0x50}; 
+	static const int latency_indicies[] = { 26, 23, 9 };
+
+	/* 0x78 DRT */
+	drt = pci_read_config32(ctrl->f0, DRT);
+	drt &= 3;  /* save bits 1:0 */
+	
+	for(first_dimm = 0; first_dimm < 4; first_dimm++) {
+		if (dimm_mask & (1 << first_dimm)) 
+			break;
+	}
+	
+	/* get dimm type */
+	value = spd_read_byte(ctrl->channel0[first_dimm], 2);
+	if(value == 8) {
+		drt |= (3<<5); /* back to bark write turn around & cycle add */
+	}	
+
+	drt |= (3<<18);  /* Trasmax */
+
+	for(cnt=0; cnt < 4; cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+			continue;
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 18); /* CAS Latency */
+		/* Compute the lowest cas latency supported */
+		latency = log2(reg) -2;
+	
+		/* Loop through and find a fast clock with a low latency */
+		for(index = 0; index < 3; index++, latency++) {
+			if ((latency < 2) || (latency > 4) ||
+				(!(reg & (1 << latency)))) {
+				continue;
+			}
+			value = spd_read_byte(ctrl->channel0[cnt], 
+				        latency_indicies[index]);
+	  
+			if(value <= cycle_time[drc&3]) {
+				if( latency > cas_latency) {
+					cas_latency = latency;
+				}
+				break;
+			}	
+		}
+	}
+	index = (cas_latency-2);
+	if((index)==0) cas_latency = 20;
+	else if((index)==1) cas_latency = 25;
+	else cas_latency = 30;
+
+	for(cnt=0;cnt<4;cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+                        continue;
+                }
+		reg = spd_read_byte(ctrl->channel0[cnt], 27)&0x0ff;
+		if(((index>>8)&0x0ff)<reg) {
+			index &= ~(0x0ff << 8);
+			index |= (reg << 8);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 28)&0x0ff;
+		if(((index>>16)&0x0ff)<reg) {
+			index &= ~(0x0ff << 16);
+			index |= (reg<<16);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 29)&0x0ff;
+		if(((index2>>0)&0x0ff)<reg) {
+			index2 &= ~(0x0ff << 0);
+			index2 |= (reg<<0);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 41)&0x0ff;
+		if(((index2>>8)&0x0ff)<reg) {
+			index2 &= ~(0x0ff << 8);
+			index2 |= (reg<<8);
+		}
+		reg = spd_read_byte(ctrl->channel0[cnt], 42)&0x0ff;
+		if(((index2>>16)&0x0ff)<reg) {
+			index2 &= ~(0x0ff << 16);
+			index2 |= (reg<<16);
+		}
+	}
+
+	/* get dimm speed */
+	value = cycle_time[drc&3];
+	if(value <= 0x50) {  /* 200 MHz */
+		if((index&7) > 2) {
+			drt |= (2<<2);  /* CAS latency 4 */
+			cas_latency = 40;
+		} else {
+			drt |= (1<<2);  /* CAS latency 3 */
+			cas_latency = 30;
+		}
+		if((index&0x0ff00)<=0x03c00) {
+			drt |= (1<<8);  /* Trp RAS Precharg */
+		} else {
+			drt |= (2<<8);  /* Trp RAS Precharg */
+		}
+		
+		/* Trcd RAS to CAS delay */
+		if((index2&0x0ff)<=0x03c) {
+			drt |= (0<<10);
+		} else {
+			drt |= (1<<10);
+		}
+
+		/* Tdal Write auto precharge recovery delay */
+		drt |= (1<<12);
+	
+		/* Trc TRS min */
+		if((index2&0x0ff00)<=0x03700)
+			drt |= (0<<14);
+		else if((index2&0xff00)<=0x03c00)
+			drt |= (1<<14);
+		else
+			drt |= (2<<14); /* spd 41 */
+		
+		drt |= (2<<16);  /* Twr not defined for DDR docs say use 2 */
+		
+		/* Trrd Row Delay */
+		if((index&0x0ff0000)<=0x0140000) {
+			drt |= (0<<20);
+		} else if((index&0x0ff0000)<=0x0280000) {
+			drt |= (1<<20);
+		} else if((index&0x0ff0000)<=0x03c0000) {
+			drt |= (2<<20);
+		} else {
+			drt |= (3<<20);
+		}
+		
+		/* Trfc Auto refresh cycle time */
+		if((index2&0x0ff0000)<=0x04b0000) {
+			drt |= (0<<22);
+		} else if((index2&0x0ff0000)<=0x0690000) {
+			drt |= (1<<22);
+		} else {
+			drt |= (2<<22);
+		}
+		/* Docs say use 55 for all 200Mhz */
+		drt |= (0x055<<24);
+	}
+	else if(value <= 0x60) { /* 167 Mhz */
+		/* according to new documentation CAS latency is 00
+		 * for bits 3:2 for all 167 Mhz 
+		drt |= ((index&3)<<2); */  /* set CAS latency */
+		if((index&0x0ff00)<=0x03000) {
+			drt |= (1<<8);  /* Trp RAS Precharg */
+		} else {
+			drt |= (2<<8);  /* Trp RAS Precharg */
+		}
+		
+		/* Trcd RAS to CAS delay */
+		if((index2&0x0ff)<=0x030) {
+			drt |= (0<<10);
+		} else {
+			drt |= (1<<10);
+		}
+
+		/* Tdal Write auto precharge recovery delay */
+		drt |= (2<<12); 
+		
+		/* Trc TRS min */
+		drt |= (2<<14); /* spd 41, but only one choice */
+		
+		drt |= (2<<16);  /* Twr not defined for DDR docs say 2 */
+		
+		/* Trrd Row Delay */
+		if((index&0x0ff0000)<=0x0180000) {
+			drt |= (0<<20);
+		} else if((index&0x0ff0000)<=0x0300000) {
+			drt |= (1<<20);
+		} else {
+			drt |= (2<<20);
+		}
+		
+		/* Trfc Auto refresh cycle time */
+		if((index2&0x0ff0000)<=0x0480000) {
+			drt |= (0<<22);
+		} else if((index2&0x0ff0000)<=0x0780000) {
+			drt |= (2<<22);
+		} else {
+			drt |= (2<<22);
+		}
+		/* Docs state to use 99 for all 167 Mhz */
+		drt |= (0x099<<24);
+	}
+	else if(value <= 0x75) { /* 133 Mhz */
+		drt |= ((index&3)<<2);  /* set CAS latency */
+		if((index&0x0ff00)<=0x03c00) {
+			drt |= (1<<8);  /* Trp RAS Precharg */
+		} else {
+			drt |= (2<<8);  /* Trp RAS Precharg */
+		}
+
+		/* Trcd RAS to CAS delay */
+		if((index2&0x0ff)<=0x03c) {
+			drt |= (0<<10);
+		} else {
+			drt |= (1<<10);
+		}
+
+		/* Tdal Write auto precharge recovery delay */
+		drt |= (1<<12); 
+		
+		/* Trc TRS min */
+		drt |= (2<<14); /* spd 41, but only one choice */
+		
+		drt |= (1<<16);  /* Twr not defined for DDR docs say 1 */
+		
+		/* Trrd Row Delay */
+		if((index&0x0ff0000)<=0x01e0000) {
+			drt |= (0<<20);
+		} else if((index&0x0ff0000)<=0x03c0000) {
+			drt |= (1<<20);
+		} else {
+			drt |= (2<<20);
+		}
+		
+		/* Trfc Auto refresh cycle time */
+		if((index2&0x0ff0000)<=0x04b0000) {
+			drt |= (0<<22);
+		} else if((index2&0x0ff0000)<=0x0780000) {
+			drt |= (2<<22);
+		} else {
+			drt |= (2<<22);
+		}
+		
+		/* Based on CAS latency */
+		if(index&7)
+			drt |= (0x099<<24);
+		else
+			drt |= (0x055<<24);
+		
+	}
+	else {
+		die("Invalid SPD 9 bus speed.\r\n");
+	}
+
+	/* 0x78 DRT */
+	pci_write_config32(ctrl->f0, DRT, drt);
+
+	return(cas_latency);
+}
+
+static int spd_set_dram_controller_mode(const struct mem_controller *ctrl, 
+		long dimm_mask)
+{
+	int value;
+	int reg;
+	int drc;
+	int cnt;
+	msr_t msr;
+	unsigned char dram_type = 0xff;
+	unsigned char ecc = 0xff;
+	unsigned char rate = 62;
+	static const unsigned char spd_rates[6] = {15,3,7,7,62,62}; 
+	static const unsigned char drc_rates[5] = {0,15,7,62,3};
+	static const unsigned char fsb_conversion[4] = {3,1,3,2};
+
+	/* 0x7c DRC */
+	drc = pci_read_config32(ctrl->f0, DRC);	
+	for(cnt=0; cnt < 4; cnt++) {
+		if (!(dimm_mask & (1 << cnt))) {
+			continue;
+		}
+		value = spd_read_byte(ctrl->channel0[cnt], 11);	/* ECC */
+		reg = spd_read_byte(ctrl->channel0[cnt], 2); /* Type */
+		if (value == 2) {    /* RAM is ECC capable */
+			if (reg == 8) {
+				if ( ecc == 0xff ) {
+					ecc = 2;
+				}
+				else if (ecc == 1) {
+					die("ERROR - Mixed DDR & DDR2 RAM\r\n");
+				}
+			} 
+			else if ( reg == 7 ) {
+				if ( ecc == 0xff) {
+					ecc = 1;
+				}
+				else if ( ecc > 1 ) {
+					die("ERROR - Mixed DDR & DDR2 RAM\r\n");
+				}
+			}	
+			else {
+				die("ERROR - RAM not DDR\r\n");
+			}
+		}
+		else {
+			die("ERROR - Non ECC memory dimm\r\n");
+		}
+
+		value = spd_read_byte(ctrl->channel0[cnt], 12);	/*refresh rate*/
+		value &= 0x0f;    /* clip self refresh bit */
+		if (value > 5) goto hw_err;
+		if (rate > spd_rates[value])
+			rate = spd_rates[value];
+
+		value = spd_read_byte(ctrl->channel0[cnt], 9);	/* cycle time */
+		if (value > 0x75) goto hw_err;
+		if (value <= 0x50) {
+			if (dram_type >= 2) {
+				if (reg == 8) { /*speed is good, is this ddr2?*/
+					dram_type = 2;
+				} else { /* not ddr2 so use ddr333 */
+					dram_type = 1;
+				}
+			}
+		}
+		else if (value <= 0x60) {
+			if (dram_type >= 1)  dram_type = 1;
+		}
+		else dram_type = 0; /* ddr266 */
+
+	}
+	ecc = 2;
+	if (read_option(CMOS_VSTART_ECC_memory,CMOS_VLEN_ECC_memory,1) == 0) {
+		ecc = 0;  /* ECC off in CMOS so disable it */
+		print_debug("ECC off\r\n");
+	}
+	else {
+		print_debug("ECC on\r\n");
+	}
+	drc &= ~(3 << 20); /* clear the ecc bits */
+	drc |= (ecc << 20);  /* or in the calculated ecc bits */
+	for ( cnt = 1; cnt < 5; cnt++)
+		if (drc_rates[cnt] == rate)
+			break;
+	if (cnt < 5) {
+		drc &= ~(7 << 8);  /* clear the rate bits */
+		drc |= (cnt << 8);
+	}
+
+	if (reg == 8) { /* independant clocks */
+		drc |= (1 << 4);
+	}
+
+	drc |= (1 << 26); /* set the overlap bit - the factory BIOS does */
+	drc |= (1 << 27); /* set DED retry enable - the factory BIOS does */
+	/* front side bus */
+	msr = rdmsr(0x2c);
+	value = msr.lo >> 16;
+	value &= 0x03;
+	drc &= ~(3 << 2); /* set the front side bus */
+	drc |= (fsb_conversion[value] << 2);
+	drc &= ~(3 << 0); /* set the dram type */
+	drc |= (dram_type << 0);
+		
+	goto out;
+
+ val_err:
+	die("Bad SPD value\r\n");
+	/* If an hw_error occurs report that I have no memory */
+hw_err:
+	drc = 0;
+ out:
+	return drc;
+}
+
+static void sdram_set_spd_registers(const struct mem_controller *ctrl) 
+{
+	long dimm_mask;
+
+	/* Test if we can read the spd and if ram is ddr or ddr2 */
+	dimm_mask = spd_detect_dimms(ctrl);
+	if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
+		print_err("No memory for this cpu\r\n");
+		return;
+	}
+	return;
+}
+
+static void do_delay(void)
+{
+	int i;
+	unsigned char b;
+	for(i=0;i<16;i++)
+		b=inb(0x80);
+}	
+
+#define TIMEOUT_LOOPS 300000
+
+#define DCALCSR  0x100
+#define DCALADDR 0x104
+#define DCALDATA 0x108
+
+static void set_on_dimm_termination_enable(const struct mem_controller *ctrl)
+{
+	unsigned char c1,c2;
+        unsigned int dimm,i;
+        unsigned int data32;
+	unsigned int t4;
+ 
+	/* Set up northbridge values */
+	/* ODT enable */
+  	pci_write_config32(ctrl->f0, 0x88, 0xf0000180);
+	/* Figure out which slots are Empty, Single, or Double sided */
+	for(i=0,t4=0,c2=0;i<8;i+=2) {
+		c1 = pci_read_config8(ctrl->f0, DRB+i);
+		if(c1 == c2) continue;
+		c2 = pci_read_config8(ctrl->f0, DRB+1+i);
+		if(c1 == c2)
+			t4 |= (1 << (i*4));
+		else
+			t4 |= (2 << (i*4));
+	}
+	for(i=0;i<1;i++) {
+	    if((t4&0x0f) == 1) {
+		if( ((t4>>8)&0x0f) == 0 ) {
+			data32 = 0x00000010; /* EEES */ 
+			break;
+		}
+		if ( ((t4>>16)&0x0f) == 0 ) { 
+			data32 = 0x00003132; /* EESS */
+			break;
+		}
+		if ( ((t4>>24)&0x0f)  == 0 ) {
+			data32 = 0x00335566; /* ESSS */
+			break;
+		}
+		data32 = 0x77bbddee; /* SSSS */
+		break;
+	    }
+	    if((t4&0x0f) == 2) {
+		if( ((t4>>8)&0x0f) == 0 ) {
+			data32 = 0x00003132; /* EEED */ 
+			break;
+		}
+		if ( ((t4>>8)&0x0f) == 2 ) {
+			data32 = 0xb373ecdc; /* EEDD */
+			break;
+		}
+		if ( ((t4>>16)&0x0f) == 0 ) {
+			data32 = 0x00b3a898; /* EESD */
+			break;
+		}
+		data32 = 0x777becdc; /* ESSD */
+		break;
+	    }
+	    die("Error - First dimm slot empty\r\n");
+	}
+
+	print_debug("ODT Value = ");
+	print_debug_hex32(data32);
+	print_debug("\r\n");
+
+  	pci_write_config32(ctrl->f0, 0xb0, data32);
+
+	for(dimm=0;dimm<8;dimm+=1) {
+
+		write32(BAR+DCALADDR, 0x0b840001);
+		write32(BAR+DCALCSR, 0x83000003 | (dimm << 20));
+		
+		for(i=0;i<1001;i++) {
+			data32 = read32(BAR+DCALCSR);
+			if(!(data32 & (1<<31)))
+				break;
+		}
+	}
+}	
+static void set_receive_enable(const struct mem_controller *ctrl)
+{
+	unsigned int i;
+	unsigned int cnt,bit;
+	uint32_t recena=0;
+	uint32_t recenb=0;
+
+	{	
+	unsigned int dimm;
+	unsigned int edge;
+	int32_t data32;
+	uint32_t data32_dram;
+	uint32_t dcal_data32_0;
+	uint32_t dcal_data32_1;
+	uint32_t dcal_data32_2;
+	uint32_t dcal_data32_3;
+	uint32_t work32l;
+	uint32_t work32h;
+	uint32_t data32r;
+	int32_t recen;
+	for(dimm=0;dimm<8;dimm+=1) {
+
+		if(!(dimm&1)) {
+			write32(BAR+DCALDATA+(17*4), 0x04020000);
+			write32(BAR+DCALCSR, 0x83800004 | (dimm << 20));
+		
+			for(i=0;i<1001;i++) {
+				data32 = read32(BAR+DCALCSR);
+				if(!(data32 & (1<<31)))
+					break;
+			}
+			if(i>=1000)
+				continue;
+		
+			dcal_data32_0 = read32(BAR+DCALDATA + 0);
+			dcal_data32_1 = read32(BAR+DCALDATA + 4);
+			dcal_data32_2 = read32(BAR+DCALDATA + 8);
+			dcal_data32_3 = read32(BAR+DCALDATA + 12);
+		}
+		else {
+			dcal_data32_0 = read32(BAR+DCALDATA + 16);
+			dcal_data32_1 = read32(BAR+DCALDATA + 20);
+			dcal_data32_2 = read32(BAR+DCALDATA + 24);
+			dcal_data32_3 = read32(BAR+DCALDATA + 28);
+		}
+
+		/* check if bank is installed */
+		if((dcal_data32_0 == 0) && (dcal_data32_2 == 0))
+			continue;
+		/* Calculate the timing value */
+		for(i=0,edge=0,bit=63,cnt=31,data32r=0,
+			work32l=dcal_data32_1,work32h=dcal_data32_3;
+				(i<4) && bit; i++) {
+			for(;;bit--,cnt--) {
+				if(work32l & (1<<cnt))
+					break;
+				if(!cnt) {
+					work32l = dcal_data32_0;
+					work32h = dcal_data32_2;
+					cnt = 32;
+				}
+				if(!bit) break;
+			}
+			for(;;bit--,cnt--) {
+				if(!(work32l & (1<<cnt)))
+					break;
+				if(!cnt) {
+					work32l = dcal_data32_0;
+					work32h = dcal_data32_2;
+					cnt = 32;
+				}
+				if(!bit) break;
+			}
+			if(!bit) {
+				break;
+			}
+			data32 = ((bit%8) << 1);
+			if(work32h & (1<<cnt))
+				data32 += 1;
+			if(data32 < 4) {
+				if(!edge) {
+					edge = 1;
+				}
+				else {
+					if(edge != 1) {
+						data32 = 0x0f;
+					}
+				}
+			}
+			if(data32 > 12) {
+				if(!edge) {
+					edge = 2;
+				}
+				else {
+					if(edge != 2) {
+						data32 = 0x00;
+					}
+				}
+			}
+			data32r += data32;
+		}
+
+		work32l = dcal_data32_0;
+		work32h = dcal_data32_2;
+		recen = data32r;
+		recen += 3;
+		recen = recen>>2;
+		for(cnt=5;cnt<24;) {
+			for(;;cnt++)
+				if(!(work32l & (1<<cnt)))
+					break;
+			for(;;cnt++) {
+				if(work32l & (1<<cnt))
+					break;
+			}
+			data32 = (((cnt-1)%8)<<1);
+			if(work32h & (1<<(cnt-1))) {
+				data32++;
+			}
+			/* test for frame edge cross overs */
+			if((edge == 1) && (data32 > 12) && 
+			    (((recen+16)-data32) < 3)) {
+				data32 = 0;
+				cnt += 2;
+			}
+			if((edge == 2) && (data32 < 4) &&
+			    ((recen - data32) > 12))  {
+				data32 = 0x0f;
+				cnt -= 2;
+			}
+			if(((recen+3) >= data32) && ((recen-3) <= data32))
+				break;
+		}
+		cnt--;
+		cnt /= 8;
+		cnt--;
+		if(recen&1)
+			recen+=2;
+		recen >>= 1;
+		recen += (cnt*8);
+	recen+=2;
+		recen <<= (dimm/2) * 8;
+		if(!(dimm&1)) {
+			recena |= recen;
+		}
+		else {
+			recenb |= recen;
+		}
+	}
+	}
+	/* Check for Eratta problem */
+	for(i=cnt=bit=0;i<4;i++) {
+		if (((recena>>(i*8))&0x0f)>7) {
+			cnt++; bit++;
+		}
+		else {
+			if((recena>>(i*8))&0x0f) {
+				cnt++;
+			}
+		}
+	}
+	if(bit) {
+		cnt-=bit;
+		if(cnt>1) {
+			for(i=0;i<4;i++) {
+				if(((recena>>(i*8))&0x0f)>7) {
+					recena &= ~(0x0f<<(i*8));
+					recena |= (7<<(i*8));
+				}
+			}
+		}
+		else {
+			for(i=0;i<4;i++) {
+				if(((recena>>(i*8))&0x0f)<8) {
+					recena &= ~(0x0f<<(i*8));
+					recena |= (8<<(i*8));
+				}
+			}
+		}
+	}
+	for(i=cnt=bit=0;i<4;i++) {
+		if (((recenb>>(i*8))&0x0f)>7) {
+			cnt++; bit++;
+		}
+		else {
+			if((recenb>>(i*8))&0x0f) {
+				cnt++;
+			}
+		}
+	}
+	if(bit) {
+		cnt-=bit;
+		if(cnt>1) {
+			for(i=0;i<4;i++) {
+				if(((recenb>>(i*8))&0x0f)>7) {
+					recenb &= ~(0x0f<<(i*8));
+					recenb |= (7<<(i*8));
+				}
+			}
+		}
+		else {
+			for(i=0;i<4;i++) {
+				if(((recenb>>(i*8))&0x0f)<8) {
+					recenb &= ~(0x0f<<(i*8));
+					recenb |= (8<<(i*8));
+				}
+			}
+		}
+	}
+
+//  recena = 0x0000090a;
+//  recenb = 0x0000090a;
+
+	print_debug("Receive enable A = ");
+	print_debug_hex32(recena);
+	print_debug(",  Receive enable B = ");
+	print_debug_hex32(recenb);
+	print_debug("\r\n");
+
+	/* clear out the calibration area */
+	write32(BAR+DCALDATA+(16*4), 0x00000000);
+	write32(BAR+DCALDATA+(17*4), 0x00000000);
+	write32(BAR+DCALDATA+(18*4), 0x00000000);
+	write32(BAR+DCALDATA+(19*4), 0x00000000);
+
+	/* No command */
+	write32(BAR+DCALCSR, 0x0000000f);
+
+	write32(BAR+0x150, recena);
+	write32(BAR+0x154, recenb);
+}
+
+
+static void sdram_enable(int controllers, const struct mem_controller *ctrl)
+{
+	int i;
+	int cs;
+	int cnt;
+	int cas_latency;
+	long mask;
+	uint32_t drc;
+	uint32_t data32;
+	uint32_t mode_reg;
+	uint32_t *iptr;
+	volatile unsigned long *iptrv;
+	msr_t msr;
+	uint32_t scratch;
+	uint8_t byte;
+	uint16_t data16;
+	static const struct {
+		uint32_t clkgr[4];
+	} gearing [] = {
+		/* FSB 133 DIMM 266 */
+	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+		/* FSB 133 DIMM 333 */
+	{{ 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+		/* FSB 133 DIMM 400 */
+	{{ 0x00000120, 0x00000000, 0x00000032, 0x00000010}},
+		/* FSB 167 DIMM 266 */
+	{{ 0x00005432, 0x00001000, 0x00004325, 0x00000000}},
+		/* FSB 167 DIMM 333 */
+	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+		/* FSB 167 DIMM 400 */
+	{{ 0x00154320, 0x00000000, 0x00065432, 0x00010000}},
+		/* FSB 200 DIMM 266 */
+	{{ 0x00000032, 0x00000010, 0x00000120, 0x00000000}},
+		/* FSB 200 DIMM 333 */
+	{{ 0x00065432, 0x00010000, 0x00054326, 0x00000000}},
+		/* FSB 200 DIMM 400 */
+	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+	};
+	
+	static const uint32_t dqs_data[] = {
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff,	0x000000ff,
+		0xffffffff, 0xffffffff, 0x000000ff,
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff, 
+		0xffffffff, 0xffffffff, 0x000000ff};
+
+	mask = spd_detect_dimms(ctrl);
+	print_debug("Starting SDRAM Enable\r\n");
+
+	/* 0x80 */
+#ifdef DIMM_MAP_LOGICAL
+	pci_write_config32(ctrl->f0, DRM,
+		0x00210000 | DIMM_MAP_LOGICAL);
+#else
+	pci_write_config32(ctrl->f0, DRM, 0x00211248);
+#endif
+	/* set dram type and Front Side Bus freq. */
+	drc = spd_set_dram_controller_mode(ctrl, mask);
+	if( drc == 0) {
+		die("Error calculating DRC\r\n");
+	}
+	data32 = drc & ~(3 << 20);  /* clear ECC mode */
+	data32 = data32 & ~(7 << 8);  /* clear refresh rates */
+	data32 = data32 | (1 << 5);  /* temp turn off of ODT */
+  	/* Set gearing, then dram controller mode */
+  	/* drc bits 1:0 = DIMM speed, bits 3:2 = FSB speed */
+  	for(iptr = gearing[(drc&3)+((((drc>>2)&3)-1)*3)].clkgr,cnt=0;
+			cnt<4;cnt++) {
+  		pci_write_config32(ctrl->f0, 0xa0+(cnt*4), iptr[cnt]);
+	}
+	/* 0x7c DRC */
+  	pci_write_config32(ctrl->f0, DRC, data32);
+	
+		/* turn the clocks on */
+	/* 0x8c CKDIS */
+  	pci_write_config16(ctrl->f0, CKDIS, 0x0000);
+	
+		/* 0x9a DDRCSR Take subsystem out of idle */
+  	data16 = pci_read_config16(ctrl->f0, DDRCSR);
+	data16 &= ~(7 << 12);
+	data16 |= (3 << 12);   /* use dual channel lock step */
+  	pci_write_config16(ctrl->f0, DDRCSR, data16);
+	
+		/* program row size DRB */
+	spd_set_ram_size(ctrl, mask);
+
+		/* program page size DRA */
+	spd_set_row_attributes(ctrl, mask);
+
+		/* program DRT timing values */	
+	cas_latency = spd_set_drt_attributes(ctrl, mask, drc);
+
+	for(i=0;i<8;i++) { /* loop throught each dimm to test for row */
+		print_debug("DIMM ");
+		print_debug_hex8(i);
+		print_debug("\r\n");
+		/* Apply NOP */
+		do_delay();
+		
+		write32(BAR + 0x100, (0x03000000 | (i<<20)));
+
+		write32(BAR+0x100, (0x83000000 | (i<<20)));
+
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+
+	}
+	
+	/* Apply NOP */
+	do_delay();
+
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR + DCALCSR, (0x83000000 | (cs<<20))); 
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Precharg all banks */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		if ((drc & 3) == 2) /* DDR2  */
+                        write32(BAR+DCALADDR, 0x04000000);
+                else   /* DDR1  */
+                        write32(BAR+DCALADDR, 0x00000000);
+		write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+		
+	/* EMRS dll's enabled */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		if ((drc & 3) == 2) /* DDR2  */
+			/* fixme hard code AL additive latency */
+                        write32(BAR+DCALADDR, 0x0b940001);
+                else   /* DDR1  */
+                        write32(BAR+DCALADDR, 0x00000001);
+		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	/* MRS reset dll's */
+	do_delay();
+	if ((drc & 3) == 2) {  /* DDR2  */
+                if(cas_latency == 30)
+                        mode_reg = 0x053a0000;
+                else
+                        mode_reg = 0x054a0000;
+        }
+        else {  /* DDR1  */
+                if(cas_latency == 20)
+                        mode_reg = 0x012a0000;
+                else  /*  CAS Latency 2.5 */
+                        mode_reg = 0x016a0000;
+        }
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALADDR, mode_reg);
+		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Precharg all banks */
+	do_delay();
+	do_delay();
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		if ((drc & 3) == 2) /* DDR2  */
+                        write32(BAR+DCALADDR, 0x04000000);
+                else   /* DDR1  */
+                        write32(BAR+DCALADDR, 0x00000000);
+		write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	
+	/* Do 2 refreshes */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+	do_delay();
+	/* for good luck do 6 more */
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
+	}
+	do_delay();
+	/* MRS reset dll's normal */
+	do_delay();
+	for(cs=0;cs<8;cs++) {	
+		write32(BAR+DCALADDR, (mode_reg & ~(1<<24)));
+		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Do only if DDR2  EMRS dll's enabled */
+        if ((drc & 3) == 2) { /* DDR2  */
+                do_delay();
+                for(cs=0;cs<8;cs++) {
+                        write32(BAR+DCALADDR, (0x0b940001));
+                        write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
+			data32 = read32(BAR+DCALCSR);
+			while(data32 & 0x80000000)
+				data32 = read32(BAR+DCALCSR);
+                }
+        }
+
+	do_delay();
+	/* No command */
+	write32(BAR+DCALCSR, 0x0000000f);
+
+	/* DDR1 This is test code to copy some codes in the factory setup */
+	
+	write32(BAR, 0x00100000);
+
+        if ((drc & 3) == 2) { /* DDR2  */
+	/* enable on dimm termination */
+		set_on_dimm_termination_enable(ctrl);
+	}
+
+	/* receive enable calibration */
+	set_receive_enable(ctrl);
+	
+	/* DQS */
+	pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); 
+	for(i = 0, cnt = (BAR+0x200); i < 24; i++, cnt+=4) {
+		write32(cnt, dqs_data[i]);
+	}
+	pci_write_config32(ctrl->f0, 0x94, 0x3904a100 );
+
+	/* Enable refresh */
+	/* 0x7c DRC */
+	data32 = drc & ~(3 << 20);  /* clear ECC mode */
+	pci_write_config32(ctrl->f0, DRC, data32);	
+	write32(BAR+DCALCSR, 0x0008000f);
+
+	/* clear memory and init ECC */
+	print_debug("Clearing memory\r\n");
+	for(i=0;i<64;i+=4) {
+		write32(BAR+DCALDATA+i, 0x00000000);
+	}
+	
+	for(cs=0;cs<8;cs++) {
+		write32(BAR+DCALCSR, (0x830831d8 | (cs<<20)));
+		data32 = read32(BAR+DCALCSR);
+		while(data32 & 0x80000000)
+			data32 = read32(BAR+DCALCSR);
+	}
+
+	/* Bring memory subsystem on line */
+	data32 = pci_read_config32(ctrl->f0, 0x98);
+	data32 |= (1 << 31);
+	pci_write_config32(ctrl->f0, 0x98, data32);
+	/* wait for completion */
+	print_debug("Waiting for mem complete\r\n");
+	while(1) {
+		data32 = pci_read_config32(ctrl->f0, 0x98);
+		if( (data32 & (1<<31)) == 0)
+			break;
+	}
+	print_debug("Done\r\n");
+	
+	/* Set initialization complete */
+	/* 0x7c DRC */
+	drc |= (1 << 29);
+	data32 = drc & ~(3 << 20);  /* clear ECC mode */
+	pci_write_config32(ctrl->f0, DRC, data32);	
+
+	/* Set the ecc mode */
+	pci_write_config32(ctrl->f0, DRC, drc);	
+
+	/* Enable memory scrubbing */
+	/* 0x52 MCHSCRB */	
+	data16 = pci_read_config16(ctrl->f0, MCHSCRB);
+	data16 &= ~0x0f;
+	data16 |= ((2 << 2) | (2 << 0));
+	pci_write_config16(ctrl->f0, MCHSCRB, data16);	
+
+	/* The memory is now setup, use it */
+	cache_lbmem(MTRR_TYPE_WRBACK);
+}
diff --git a/src/northbridge/intel/E7525/raminit.h b/src/northbridge/intel/E7525/raminit.h
new file mode 100644
index 0000000..183ace8
--- /dev/null
+++ b/src/northbridge/intel/E7525/raminit.h
@@ -0,0 +1,12 @@
+#ifndef RAMINIT_H
+#define RAMINIT_H
+
+#define DIMM_SOCKETS 4
+struct mem_controller {
+	unsigned node_id;
+	device_t f0, f1, f2, f3;
+	uint16_t channel0[DIMM_SOCKETS];
+	uint16_t channel1[DIMM_SOCKETS];
+};
+
+#endif /* RAMINIT_H */
diff --git a/src/northbridge/intel/E7525/raminit_test.c b/src/northbridge/intel/E7525/raminit_test.c
new file mode 100644
index 0000000..2d44d25
--- /dev/null
+++ b/src/northbridge/intel/E7525/raminit_test.c
@@ -0,0 +1,393 @@
+#include <unistd.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <setjmp.h>
+#include <device/pci_def.h>
+#include "e7525.h"
+
+jmp_buf end_buf;
+
+static int is_cpu_pre_c0(void)
+{
+	return 0;
+}
+
+#define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
+	(((BUS) & 0xFF) << 16) | \
+	(((DEV) & 0x1f) << 11) | \
+	(((FN) & 0x07) << 8) | \
+	((WHERE) & 0xFF))
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+	(((BUS) & 0xFF) << 16) | \
+	(((DEV) & 0x1f) << 11) | \
+	(((FN)  & 0x7) << 8))
+
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+
+typedef unsigned device_t;
+
+unsigned char pci_register[256*5*3*256];
+
+static uint8_t pci_read_config8(device_t dev, unsigned where)
+{
+	unsigned addr;
+	addr = dev | where;
+	return pci_register[addr];
+}
+
+static uint16_t pci_read_config16(device_t dev, unsigned where)
+{
+	unsigned addr;
+	addr = dev | where;
+	return pci_register[addr] | (pci_register[addr + 1]  << 8);
+}
+
+static uint32_t pci_read_config32(device_t dev, unsigned where)
+{
+	unsigned addr;
+	uint32_t value;
+	addr = dev | where;
+	value =  pci_register[addr] | 
+		(pci_register[addr + 1]  << 8) |
+		(pci_register[addr + 2]  << 16) |
+		(pci_register[addr + 3]  << 24);
+
+	return value;
+
+}
+
+static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
+{
+	unsigned addr;
+	addr = dev | where;
+	pci_register[addr] = value;
+}
+
+static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
+{
+	unsigned addr;
+	addr = dev | where;
+	pci_register[addr] = value & 0xff;
+	pci_register[addr + 1] = (value >> 8) & 0xff;
+}
+
+static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
+{
+	unsigned addr;
+	addr = dev | where;
+	pci_register[addr] = value & 0xff;
+	pci_register[addr + 1] = (value >> 8) & 0xff;
+	pci_register[addr + 2] = (value >> 16) & 0xff;
+	pci_register[addr + 3] = (value >> 24) & 0xff;
+}
+
+#define PCI_DEV_INVALID (0xffffffffU)
+static device_t pci_locate_device(unsigned pci_id, device_t dev)
+{
+	for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
+		unsigned int id;
+		id = pci_read_config32(dev, 0);
+		if (id == pci_id) {
+			return dev;
+		}
+	}
+	return PCI_DEV_INVALID;
+}
+
+
+
+
+static void uart_tx_byte(unsigned char data)
+{
+	write(STDOUT_FILENO, &data, 1);
+}
+static void hlt(void)
+{
+	longjmp(end_buf, 2);
+}
+#include "../../../arch/i386/lib/console.c"
+
+unsigned long log2(unsigned long x)
+{
+        // assume 8 bits per byte.
+        unsigned long i = 1 << (sizeof(x)*8 - 1);
+        unsigned long pow = sizeof(x) * 8 - 1;
+
+        if (! x) {
+		static const char errmsg[] = " called with invalid parameter of 0\n";
+		write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
+		write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+                hlt();
+        }
+        for(; i > x; i >>= 1, pow--)
+                ;
+
+        return pow;
+}
+
+typedef struct msr_struct 
+{
+	unsigned lo;
+	unsigned hi;
+} msr_t;
+
+static inline msr_t rdmsr(unsigned index)
+{
+	msr_t result;
+	result.lo = 0;
+	result.hi = 0;
+	return result;
+}
+
+static inline void wrmsr(unsigned index, msr_t msr)
+{
+}
+
+#include "raminit.h"
+
+#define SIO_BASE 0x2e
+
+static void hard_reset(void)
+{
+	/* FIXME implement the hard reset case... */
+	longjmp(end_buf, 3);
+}
+
+static void memreset_setup(void)
+{
+	/* Nothing to do */
+}
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+	/* Nothing to do */
+}
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+	/* nothing to do */
+}
+
+
+static uint8_t spd_mt4lsdt464a[256] = 
+{
+	0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70, 
+	0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01, 
+	0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
+
+	0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
+	0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
+	0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
+	0x06, 0x07, 0x08, 0x09, 0x00,
+};
+
+static uint8_t spd_micron_512MB_DDR333[256] = 
+{
+	0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60, 
+	0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01, 
+	0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48, 
+	0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31, 
+	0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 
+	0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff 
+};
+
+static uint8_t spd_micron_256MB_DDR333[256] = 
+{
+	0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60, 
+	0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01, 
+	0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48, 
+	0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36, 
+	0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
+	0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+};
+
+#define MAX_DIMMS 16
+static uint8_t spd_data[MAX_DIMMS*256];
+
+static unsigned spd_count, spd_fail_count;
+static int spd_read_byte(unsigned device, unsigned address)
+{
+	int result;
+	spd_count++;
+	if ((device < 0x50) || (device >= (0x50 +MAX_DIMMS))) {
+		result = -1;
+	}
+	else {
+		device -= 0x50;
+		
+		if (address > 256) {
+			result = -1;
+		}
+		else if (spd_data[(device << 8) | 2] != 7) {
+			result = -1;
+		}
+		else {
+			result = spd_data[(device << 8) | address];
+		}
+	}
+	if (spd_count >= spd_fail_count) {
+		result = -1;
+	}
+	return result;
+}
+
+#include "raminit.c"
+#include "../../../sdram/generic_sdram.c"
+
+#define FIRST_CPU  1
+#define SECOND_CPU 1
+#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
+#if 0
+static void raminit_main(void)
+{
+	/*
+	 * GPIO28 of 8111 will control H0_MEMRESET_L
+	 * GPIO29 of 8111 will control H1_MEMRESET_L
+	 */
+	static const struct mem_controller cpu[] = {
+#if FIRST_CPU
+		{
+			.node_id = 0,
+			.f0 = PCI_DEV(0, 0x18, 0),
+			.f1 = PCI_DEV(0, 0x18, 1),
+			.f2 = PCI_DEV(0, 0x18, 2),
+			.f3 = PCI_DEV(0, 0x18, 3),
+			.channel0 = { 0x50+0, 0x50+2, 0x50+4, 0x50+6 },
+			.channel1 = { 0x50+1, 0x50+3, 0x50+5, 0x50+7 },
+		},
+#endif
+#if SECOND_CPU
+		{
+			.node_id = 1,
+			.f0 = PCI_DEV(0, 0x19, 0),
+			.f1 = PCI_DEV(0, 0x19, 1),
+			.f2 = PCI_DEV(0, 0x19, 2),
+			.f3 = PCI_DEV(0, 0x19, 3),
+			.channel0 = { 0x50+8, 0x50+10, 0x50+12, 0x50+14 },
+			.channel1 = { 0x50+9, 0x50+11, 0x50+13, 0x50+15 },
+		},
+#endif
+	};
+	console_init();
+	memreset_setup();
+	sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
+
+}
+#endif
+static void reset_tests(void)
+{
+	/* Clear the results of any previous tests */
+	memset(pci_register, 0, sizeof(pci_register));
+	memset(spd_data, 0, sizeof(spd_data));
+	spd_count = 0;
+	spd_fail_count = UINT_MAX;
+
+	pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
+		NBCAP_128Bit |
+		NBCAP_MP|  NBCAP_BIG_MP |
+		/* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
+		(NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
+		NBCAP_MEMCTRL);
+
+	pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
+		NBCAP_128Bit |
+		NBCAP_MP|  NBCAP_BIG_MP |
+		/* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
+		(NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
+		NBCAP_MEMCTRL);
+}
+
+static void test1(void)
+{
+	reset_tests();
+
+	memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
+//	raminit_main();
+}
+
+
+static void do_test2(int i)
+{
+	jmp_buf tmp_buf;
+	memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
+	if (setjmp(end_buf) != 0) {
+		goto done;
+	}
+	reset_tests();
+	spd_fail_count = i;
+
+	print_debug("\r\nSPD will fail after: ");
+	print_debug_hex32(spd_fail_count);
+	print_debug(" accesses.\r\n");
+	
+	memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
+	memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
+	
+//	raminit_main();
+
+ done:
+	memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
+}
+
+static void test2(void)
+{
+	int i;
+	for(i = 0; i < 0x48; i++) {
+		do_test2(i);
+	}
+	
+}
+
+int main(int argc, char **argv)
+{
+	if (setjmp(end_buf) != 0) {
+		return -1;
+	}
+	test1();
+	test2();
+	return 0;
+}
diff --git a/src/southbridge/amd/amd8111/amd8111_reset.c b/src/southbridge/amd/amd8111/amd8111_reset.c
index 822a1e3..435904a 100644
--- a/src/southbridge/amd/amd8111/amd8111_reset.c
+++ b/src/southbridge/amd/amd8111/amd8111_reset.c
@@ -1,14 +1,15 @@
+/* Include this file in the mainboards reset.c
+ */
 #include <arch/io.h>
+#include <device/pci_ids.h>
 
 #define PCI_DEV(BUS, DEV, FN) ( \
 	(((BUS) & 0xFF) << 16) | \
 	(((DEV) & 0x1f) << 11) | \
 	(((FN)  & 0x7) << 8))
 
-#define AMD8111_RESET PCI_DEV(     \
-		HARD_RESET_BUS,    \
-		HARD_RESET_DEVICE, \
-		HARD_RESET_FUNCTION)
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
 
 typedef unsigned device_t;
 
@@ -36,10 +37,57 @@
         return inl(0xCFC);
 }
 
+#define PCI_DEV_INVALID (0xffffffffU)
+static device_t pci_locate_device(unsigned pci_id, unsigned bus)
+{
+	device_t dev, last;
+	dev = PCI_DEV(bus, 0, 0);
+	last = PCI_DEV(bus, 31, 7);
+	for(; dev <= last; dev += PCI_DEV(0,0,1)) {
+		unsigned int id;
+		id = pci_read_config32(dev, 0);
+		if (id == pci_id) {
+			return dev;
+		}
+	}
+	return PCI_DEV_INVALID;
+}
+
 #include "../../../northbridge/amd/amdk8/reset_test.c"
 
-void hard_reset(void)
+static unsigned node_link_to_bus(unsigned node, unsigned link)
 {
+	unsigned reg;
+
+	for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
+		unsigned config_map;
+		config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
+		if ((config_map & 3) != 3) {
+			continue;
+		}
+		if ((((config_map >> 4) & 7) == node) &&
+			(((config_map >> 8) & 3) == link)) 
+		{
+			return (config_map >> 16) & 0xff;
+		}
+	}
+	return 0;
+}
+
+static void amd8111_hard_reset(unsigned node, unsigned link)
+{
+	device_t dev;
+	unsigned bus;
+
+	/* Find the device.
+	 * There can only be one 8111 on a hypertransport chain/bus.
+	 */
+	bus = node_link_to_bus(node, link);
+	dev = pci_locate_device(
+		PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_ISA), 
+		bus);
+
+	/* Reset */
 	set_bios_reset();
-	pci_write_config8(AMD8111_RESET, 0x47, 1);
+	pci_write_config8(dev, 0x47, 1);
 }
diff --git a/src/southbridge/amd/amd8131-disable/Config.lb b/src/southbridge/amd/amd8131-disable/Config.lb
new file mode 100644
index 0000000..9968e9a
--- /dev/null
+++ b/src/southbridge/amd/amd8131-disable/Config.lb
@@ -0,0 +1 @@
+driver amd8131_bridge.o
diff --git a/src/southbridge/amd/amd8131-disable/amd8131_bridge.c b/src/southbridge/amd/amd8131-disable/amd8131_bridge.c
new file mode 100644
index 0000000..648dbba
--- /dev/null
+++ b/src/southbridge/amd/amd8131-disable/amd8131_bridge.c
@@ -0,0 +1,116 @@
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+
+static void amd8131_bus_read_resources(device_t dev)
+{
+	return;
+}
+
+static void amd8131_bus_set_resources(device_t dev)
+{
+#if 0
+	pci_bus_read_resources(dev);
+#endif
+	return;
+}
+
+static void amd8131_bus_enable_resources(device_t dev)
+{
+#if 0
+	pci_dev_set_resources(dev);
+#endif
+	return;
+}
+
+static void amd8131_bus_init(device_t dev)
+{
+#if 0
+	pcix_init(dev);
+#endif
+	return;
+}
+
+static unsigned int amd8131_scan_bus(device_t bus, unsigned int max)
+{
+#if 0
+	max = pcix_scan_bridge(bus, max);
+#endif
+	return max;
+}
+
+static void amd8131_enable(device_t dev)
+{
+	uint32_t buses;
+	uint16_t cr;
+
+	/* Clear all status bits and turn off memory, I/O and master enables. */
+	pci_write_config16(dev, PCI_COMMAND, 0x0000);
+	pci_write_config16(dev, PCI_STATUS, 0xffff);
+
+	/*
+	 * Read the existing primary/secondary/subordinate bus
+	 * number configuration.
+	 */
+	buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
+
+	/* Configure the bus numbers for this bridge: the configuration
+	 * transactions will not be propagated by the bridge if it is not
+	 * correctly configured.
+	 */
+	buses &= 0xff000000;
+	buses |= (((unsigned int) (dev->bus->secondary) << 0) |
+		((unsigned int) (dev->bus->secondary) << 8) |
+		((unsigned int) (dev->bus->secondary) << 16));
+	pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
+}
+
+static struct device_operations pcix_ops  = {
+        .read_resources   = amd8131_bus_read_resources,
+        .set_resources    = amd8131_bus_set_resources,
+	.enable_resources = amd8131_bus_enable_resources,
+        .init             = amd8131_bus_init,
+	.scan_bus         = 0,
+	.enable           = amd8131_enable,
+};
+
+static struct pci_driver pcix_driver __pci_driver = {
+        .ops    = &pcix_ops,
+        .vendor = PCI_VENDOR_ID_AMD,
+        .device = 0x7450,
+};
+
+
+static void ioapic_enable(device_t dev)
+{
+	uint32_t value;
+	value = pci_read_config32(dev, 0x44);
+	if (dev->enabled) {
+		value |= ((1 << 1) | (1 << 0));
+	} else {
+		value &= ~((1 << 1) | (1 << 0));
+	}
+	pci_write_config32(dev, 0x44, value);
+}
+
+static struct device_operations ioapic_ops = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init     = 0,
+	.scan_bus = 0,
+	.enable   = ioapic_enable,
+};
+
+static struct pci_driver ioapic_driver __pci_driver = {
+	.ops    = &ioapic_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = 0x7451,
+	
+};
diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c
index 357059d..828b083 100644
--- a/src/southbridge/amd/amd8131/amd8131_bridge.c
+++ b/src/southbridge/amd/amd8131/amd8131_bridge.c
@@ -7,10 +7,273 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <pc80/mc146818rtc.h>
+#include <device/pci_def.h>
+#include <device/pcix.h>
 
 #define NMI_OFF 0
 
-static void pcix_init(device_t dev)
+#define NPUML 0xD9	/* Non prefetchable upper memory limit */
+#define NPUMB 0xD8	/* Non prefetchable upper memory base */
+
+static void amd8131_walk_children(struct bus *bus,
+	void (*visit)(device_t dev, void *ptr), void *ptr)
+{
+	device_t child;
+	for(child = bus->children; child; child = child->sibling)
+	{
+		if (child->path.type != DEVICE_PATH_PCI) {
+			continue;
+		}
+		if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+			amd8131_walk_children(&child->link[0], visit, ptr);
+		}
+		visit(child, ptr);
+	}
+}
+
+struct amd8131_bus_info {
+	unsigned sstatus;
+	unsigned rev;
+	int errata_56;
+	int master_devices;
+	int max_func;
+};
+
+static void amd8131_count_dev(device_t dev, void *ptr)
+{
+	struct amd8131_bus_info *info = ptr;
+	/* Don't count pci bridges */
+	if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+		info->master_devices++;
+	}
+	if (PCI_FUNC(dev->path.u.pci.devfn) > info->max_func) {
+		info->max_func = PCI_FUNC(dev->path.u.pci.devfn);
+	}
+}
+
+
+static void amd8131_pcix_tune_dev(device_t dev, void *ptr)
+{
+	struct amd8131_bus_info *info = ptr;
+	unsigned cap;
+	unsigned status, cmd, orig_cmd;
+	unsigned max_read, max_tran;
+	int sib_funcs, sibs;
+	device_t sib;
+
+	if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
+		return;
+	}
+	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	if (!cap) {
+		return;
+	}
+	/* How many siblings does this device have? */
+	sibs = info->master_devices - 1;
+	/* Count how many sibling functions this device has */
+	sib_funcs = 0;
+	for(sib = dev->bus->children; sib; sib = sib->sibling) {
+		if (sib == dev) {
+			continue;
+		}
+		if (PCI_SLOT(sib->path.u.pci.devfn) != PCI_SLOT(dev->path.u.pci.devfn)) {
+			continue;
+		}
+		sib_funcs++;
+	}
+
+
+	printk_debug("%s AMD8131 PCI-X tuning\n", dev_path(dev));
+	status = pci_read_config32(dev, cap + PCI_X_STATUS);
+	orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
+
+	max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
+	max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
+
+	/* Errata #49 don't allow 4K transactions */
+	if (max_read >= 2) {
+		max_read = 2;
+	}
+
+	/* Errata #37 Limit the number of split transactions to avoid starvation */
+	if (sibs >= 2) {
+		/* At most 2 outstanding split transactions when we have
+		 * 3 or more bus master devices on the bus.
+		 */
+		if (max_tran > 1) {
+			max_tran = 1;
+		}
+	}
+	else if (sibs == 1) {
+		/* At most 4 outstanding split transactions when we have
+		 * 2 bus master devices on the bus.
+		 */
+		if (max_tran > 3) {
+			max_tran = 3;
+		}
+	}
+	else {
+		/* At most 8 outstanding split transactions when we have
+		 * only one bus master device on the bus.
+		 */
+		if (max_tran > 4) {
+			max_tran = 4;
+		}
+	}
+	/* Errata #56 additional limits when the bus runs at 133Mhz */
+	if (info->errata_56 && 
+		(PCI_X_SSTATUS_MFREQ(info->sstatus) == PCI_X_SSTATUS_MODE1_133MHZ))
+	{
+		unsigned limit_read;
+		/* Look at the number of siblings and compute the
+		 * largest legal read size.
+		 */
+		if (sib_funcs == 0) {
+			/* 2k reads */
+			limit_read = 2;
+		} 
+		else if (sib_funcs <= 1) {
+			/* 1k reads */
+			limit_read = 1;
+		}
+		else {
+			/* 512 byte reads */
+			limit_read = 0;
+		}
+		if (max_read > limit_read) {
+			max_read = limit_read;
+		}
+		/* Look at the read size and the nubmer of siblings
+		 * and compute how many outstanding transactions I can have.
+		 */
+		if (max_read == 2) {
+			/* 2K reads */
+			if (max_tran > 0) {
+				/* Only 1 outstanding transaction allowed */
+				max_tran = 0;
+			}
+		}
+		else if (max_read == 1) {
+			/* 1K reads */
+			if (max_tran > (1 - sib_funcs)) {
+				/* At most 2 outstanding transactions */
+				max_tran = 1 - sib_funcs;
+			}
+		}
+		else {
+			/* 512 byte reads */
+			max_read = 0;
+			if (max_tran > (2 - sib_funcs)) {
+				/* At most 3 outstanding transactions */
+				max_tran = 2 - sib_funcs;
+			}
+		}
+	}
+#if 0
+	printk_debug("%s max_read: %d max_tran: %d sibs: %d sib_funcs: %d\n",
+		dev_path(dev), max_read, max_tran, sibs, sib_funcs, sib_funcs);
+#endif
+	if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
+		cmd &= ~PCI_X_CMD_MAX_READ;
+		cmd |= max_read << 2;
+		}
+	if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
+		cmd &= ~PCI_X_CMD_MAX_SPLIT;
+		cmd |= max_tran << 4;
+	}
+
+	/* Don't attempt to handle PCI-X errors */
+	cmd &= ~PCI_X_CMD_DPERR_E;
+	/* The 8131 does not work properly with relax ordering enabled.
+	 * Errata #58
+	 */
+	cmd &= ~PCI_X_CMD_ERO;
+	if (orig_cmd != cmd) {
+		pci_write_config16(dev, cap + PCI_X_CMD, cmd);
+	}
+}
+static unsigned int amd8131_scan_bus(struct bus *bus,
+	unsigned min_devfn, unsigned max_devfn, unsigned int max)
+{
+	struct amd8131_bus_info info;
+	struct bus *pbus;
+	unsigned pos;
+
+
+	/* Find the children on the bus */
+	max = pci_scan_bus(bus, min_devfn, max_devfn, max);
+
+	/* Find the revision of the 8131 */
+	info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION);
+
+	/* See which errata apply */
+	info.errata_56 = info.rev <= 0x12;
+
+	/* Find the pcix capability and get the secondary bus status */
+	pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX);
+	info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS);
+
+	/* Print the PCI-X bus speed */
+	printk_debug("PCI: %02x: %s\n", bus->secondary, pcix_speed(info.sstatus));
+
+
+	/* Examine the bus and find out how loaded it is */
+	info.max_func = 0;
+	info.master_devices  = 0;
+	amd8131_walk_children(bus, amd8131_count_dev, &info);
+
+	/* Disable the bus if there are no devices on it or
+	 * we are running at 133Mhz and have a 4 function device.
+	 * see errata #56
+	 */
+	if (!bus->children || 
+		(info.errata_56 && 
+			(info.max_func >= 3) &&
+			(PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_MODE1_133MHZ)))
+	{
+		unsigned pcix_misc;
+		/* Disable all of my children */
+		disable_children(bus);
+
+		/* Remember the device is disabled */
+		bus->dev->enabled = 0;
+
+		/* Disable the PCI-X clocks */
+		pcix_misc = pci_read_config32(bus->dev, 0x40);
+		pcix_misc &= ~(0x1f << 16);
+		pci_write_config32(bus->dev, 0x40, pcix_misc);
+		
+		return max;
+	}
+
+	/* If we are in conventional PCI mode nothing more is necessary.
+	 */
+	if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
+		return max;
+	}
+
+
+	/* Tune the devices on the bus */
+	amd8131_walk_children(bus, amd8131_pcix_tune_dev, &info);
+
+	/* Don't allow the 8131 or any of it's parent busses to
+	 * implement relaxed ordering.  Errata #58
+	 */
+	for(pbus = bus; !pbus->disable_relaxed_ordering; pbus = pbus->dev->bus) {
+		printk_spew("%s disabling relaxed ordering\n",
+			bus_path(pbus));
+		pbus->disable_relaxed_ordering = 1;
+	}
+	return max;
+}
+
+static unsigned int amd8131_scan_bridge(device_t dev, unsigned int max)
+{
+	return do_pci_scan_bridge(dev, max, amd8131_scan_bus);
+}
+
+
+static void amd8131_pcix_init(device_t dev)
 {
 	uint32_t dword;
 	uint16_t word;
@@ -24,18 +287,19 @@
  	
 	/* Set drive strength */
 	word = pci_read_config16(dev, 0xe0);
-        word = 0x0808;
+        word = 0x0404;
         pci_write_config16(dev, 0xe0, word);
 	word = pci_read_config16(dev, 0xe4);
-        word = 0x0808;
+        word = 0x0404;
         pci_write_config16(dev, 0xe4, word);
 	
 	/* Set impedance */
 	word = pci_read_config16(dev, 0xe8);
-        word = 0x0f0f;
+        word = 0x0404;
         pci_write_config16(dev, 0xe8, word);
 
 	/* Set discard unrequested prefetch data */
+	/* Errata #51 */
 	word = pci_read_config16(dev, 0x4c);
         word |= 1;
         pci_write_config16(dev, 0x4c, word);
@@ -76,16 +340,58 @@
 		dword |= (1<<1);
 		pci_write_config32(dev, 0xc8, dword);
 	}
-	
 	return;
 }
 
+#define BRIDGE_40_BIT_SUPPORT 0
+#if BRIDGE_40_BIT_SUPPORT
+static void bridge_read_resources(struct device *dev)
+{
+	struct resource *res;
+	pci_bus_read_resources(dev);
+	res = find_resource(dev, PCI_MEMORY_BASE);	
+	if (res) {
+		res->limit = 0xffffffffffULL;
+	}
+}
+
+static void bridge_set_resources(struct device *dev)
+{
+	struct resource *res;
+	res = find_resource(dev, PCI_MEMORY_BASE);
+	if (res) {
+		resource_t base, end;
+		/* set the memory range */
+		dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+		res->flags |= IORESOURCE_STORED;
+		compute_allocate_resource(&dev->link[0], res,
+			IORESOURCE_MEM | IORESOURCE_PREFETCH,
+			IORESOURCE_MEM);
+		base = res->base;
+		end  = resource_end(res);
+		pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
+		pci_write_config8(dev, NPUML, (base >> 32) & 0xff);
+		pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
+		pci_write_config8(dev, NPUMB, (end >> 32) & 0xff);
+
+		report_resource_stored(dev, res, "");
+	}
+	pci_dev_set_resources(dev);
+}
+#endif /* BRIDGE_40_BIT_SUPPORT */
+
 static struct device_operations pcix_ops  = {
+#if BRIDGE_40_BIT_SUPPORT
+        .read_resources   = bridge_read_resources,
+        .set_resources    = bridge_set_resources,
+#else
         .read_resources   = pci_bus_read_resources,
         .set_resources    = pci_dev_set_resources,
+#endif
 	.enable_resources = pci_bus_enable_resources,
-        .init             = pcix_init,
-        .scan_bus         = pci_scan_bridge,
+        .init             = amd8131_pcix_init,
+        .scan_bus         = amd8131_scan_bridge,
+	.reset_bus        = pci_bus_reset,
 };
 
 static struct pci_driver pcix_driver __pci_driver = {
diff --git a/src/southbridge/intel/esb6300/Config.lb b/src/southbridge/intel/esb6300/Config.lb
new file mode 100644
index 0000000..9674c1f
--- /dev/null
+++ b/src/southbridge/intel/esb6300/Config.lb
@@ -0,0 +1,12 @@
+config chip.h
+driver esb6300.o
+driver esb6300_uhci.o
+driver esb6300_lpc.o
+driver esb6300_ide.o
+driver esb6300_sata.o
+driver esb6300_ehci.o
+driver esb6300_smbus.o
+driver esb6300_pci.o
+driver esb6300_pic.o
+driver esb6300_bridge1c.o
+driver esb6300_ac97.o
diff --git a/src/southbridge/intel/esb6300/chip.h b/src/southbridge/intel/esb6300/chip.h
new file mode 100644
index 0000000..ff74e61
--- /dev/null
+++ b/src/southbridge/intel/esb6300/chip.h
@@ -0,0 +1,30 @@
+struct southbridge_intel_esb6300_config 
+{
+#define ESB6300_GPIO_USE_MASK      0x03
+#define ESB6300_GPIO_USE_DEFAULT   0x00
+#define ESB6300_GPIO_USE_AS_NATIVE 0x01
+#define ESB6300_GPIO_USE_AS_GPIO   0x02
+
+#define ESB6300_GPIO_SEL_MASK      0x0c
+#define ESB6300_GPIO_SEL_DEFAULT   0x00
+#define ESB6300_GPIO_SEL_OUTPUT    0x04
+#define ESB6300_GPIO_SEL_INPUT     0x08
+
+#define ESB6300_GPIO_LVL_MASK      0x30
+#define ESB6300_GPIO_LVL_DEFAULT   0x00
+#define ESB6300_GPIO_LVL_LOW       0x10
+#define ESB6300_GPIO_LVL_HIGH      0x20
+#define ESB6300_GPIO_LVL_BLINK     0x30
+
+#define ESB6300_GPIO_INV_MASK      0xc0
+#define ESB6300_GPIO_INV_DEFAULT   0x00
+#define ESB6300_GPIO_INV_OFF       0x40
+#define ESB6300_GPIO_INV_ON        0x80
+
+	/* GPIO use select */
+	unsigned char gpio[64];
+	unsigned int  pirq_a_d;
+	unsigned int  pirq_e_h;
+};
+extern struct chip_operations southbridge_intel_esb6300_ops;
+
diff --git a/src/southbridge/intel/esb6300/esb6300.c b/src/southbridge/intel/esb6300/esb6300.c
new file mode 100644
index 0000000..3551a59
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300.c
@@ -0,0 +1,48 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "esb6300.h"
+
+void esb6300_enable(device_t dev)
+{
+	device_t lpc_dev;
+	unsigned index = 0;
+	uint16_t reg_old, reg;
+
+	/* See if we are on the behind the 6300 pci bridge */
+	lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0));
+	if((dev->path.u.pci.devfn &0xf8)== 0xf8) {
+		index = dev->path.u.pci.devfn & 7;
+	}
+	else if((dev->path.u.pci.devfn &0xf8)== 0xe8) {
+		index = (dev->path.u.pci.devfn & 7) +8;
+	}
+	if ((!lpc_dev) || (index >= 16) || ((1<<index)&0x3091)) {
+		return;
+	}
+	if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) ||
+		(lpc_dev->device != PCI_DEVICE_ID_INTEL_6300ESB_ISA)) {
+		uint32_t id;
+		id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
+		if (id != (PCI_VENDOR_ID_INTEL | 
+				(PCI_DEVICE_ID_INTEL_6300ESB_ISA << 16))) {
+			return;
+		}
+	}
+
+	reg = reg_old = pci_read_config16(lpc_dev, 0xf2);
+	reg &= ~(1 << index);
+	if (!dev->enabled) {
+		reg |= (1 << index);
+	}
+	if (reg != reg_old) {
+		pci_write_config16(lpc_dev, 0xf2, reg);
+	}
+	
+}
+
+struct chip_operations southbridge_intel_esb6300_ops = {
+	CHIP_NAME("INTEL 6300ESB")
+	.enable_dev = esb6300_enable,
+};
diff --git a/src/southbridge/intel/esb6300/esb6300.h b/src/southbridge/intel/esb6300/esb6300.h
new file mode 100644
index 0000000..2c91fcb
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300.h
@@ -0,0 +1,7 @@
+#ifndef ESB6300_H
+#define ESB6300_H
+#include "chip.h"
+
+void esb6300_enable(device_t dev);
+
+#endif /* ESB6300 */
diff --git a/src/southbridge/intel/esb6300/esb6300_ac97.c b/src/southbridge/intel/esb6300/esb6300_ac97.c
new file mode 100644
index 0000000..cc221f6
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_ac97.c
@@ -0,0 +1,37 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	/* Write the subsystem vendor and device id */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = ac97_set_subsystem,
+};
+static struct device_operations ac97_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = 0,
+	.enable           = esb6300_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ac97_audio_driver __pci_driver = {
+	.ops    = &ac97_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_AUDIO,
+};
+static struct pci_driver ac97_modem_driver __pci_driver = {
+	.ops    = &ac97_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_MODEM,
+};
diff --git a/src/southbridge/intel/esb6300/esb6300_bridge1c.c b/src/southbridge/intel/esb6300/esb6300_bridge1c.c
new file mode 100644
index 0000000..49e3b05
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_bridge1c.c
@@ -0,0 +1,51 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void bridge1c_init(struct device *dev)
+{
+
+	uint16_t word;
+
+	/* configuration */
+	pci_write_config8(dev, 0x1b, 0x30);
+//	pci_write_config8(dev, 0x3e, 0x07);
+	pci_write_config8(dev, 0x3e, 0x04);  /* parity ignore */
+	pci_write_config8(dev, 0x6c, 0x0c);  /* undocumented  */
+	pci_write_config8(dev, 0xe0, 0x20);
+
+	/* SRB enable */
+	pci_write_config16(dev, 0xe4, 0x0232);
+
+	/* Burst size */
+	pci_write_config8(dev, 0xf0, 0x02);
+
+	/* prefetch threshold size */
+	pci_write_config16(dev, 0xf8, 0x2121);
+
+	/* primary latency */
+	pci_write_config8(dev, 0x0d, 0x28);
+
+	/* multi transaction timer */
+	pci_write_config8(dev, 0x42, 0x08);
+
+}
+
+static struct device_operations pci_ops  = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init             = bridge1c_init,
+	.scan_bus         = pci_scan_bridge,
+	.ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_BRIDGE1C,
+};
+
diff --git a/src/southbridge/intel/esb6300/esb6300_early_smbus.c b/src/southbridge/intel/esb6300/esb6300_early_smbus.c
new file mode 100644
index 0000000..e115e3a
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_early_smbus.c
@@ -0,0 +1,107 @@
+#include "esb6300_smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+	device_t dev;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a4), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("SMBUS controller not found\r\n");
+	}
+	uint8_t enable;
+	print_spew("SMBus controller enabled\r\n");
+	pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+	pci_write_config8(dev, 0x40, 1);
+	pci_write_config8(dev, 0x4, 1);
+	/* SMBALERT_DIS */
+	pci_write_config8(dev, 0x11, 4);
+	
+	/* Disable interrupt generation */
+	outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+	dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("ISA bridge not found\r\n");
+	}
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+	return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+	if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+		return;
+	}
+	return;
+}
+
+static int smbus_write_block(unsigned device, unsigned length, unsigned cmd, 
+		 unsigned data1, unsigned data2)
+{
+	unsigned char global_control_register;
+	unsigned char global_status_register;
+	unsigned char byte;
+	unsigned char stat;
+	int i;
+
+	/* chear the PM timeout flags, SECOND_TO_STS */
+	outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
+	
+	if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+		return -2;
+	}
+	
+	/* setup transaction */
+	/* Obtain ownership */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+	for(stat=0;(stat&0x40)==0;) {
+	stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+	/* clear the done bit */
+	outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
+	/* disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+	
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
+	
+	/* set the command address */
+	outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	
+	/* set the block length */
+	outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
+	
+	/* try sending out the first byte of data here */
+	byte=(data1>>(0))&0x0ff;
+	outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+	/* issue a block write command */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40, 
+			SMBUS_IO_BASE + SMBHSTCTL);
+
+	for(i=0;i<length;i++) {
+		
+		/* poll for transaction completion */
+		if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
+			return -3;
+		}
+		
+		/* load the next byte */
+		if(i>3)
+			byte=(data2>>(i%4))&0x0ff;
+		else
+			byte=(data1>>(i))&0x0ff;
+		outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+		
+		/* clear the done bit */
+		outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), 
+				SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+
+	print_debug("SMBUS Block complete\r\n");
+	return 0;
+}
+
diff --git a/src/southbridge/intel/esb6300/esb6300_ehci.c b/src/southbridge/intel/esb6300/esb6300_ehci.c
new file mode 100644
index 0000000..58dcd95
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_ehci.c
@@ -0,0 +1,50 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void ehci_init(struct device *dev)
+{
+	uint32_t cmd;
+
+	printk_debug("EHCI: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_MASTER);
+
+	printk_debug("done.\n");
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	uint8_t access_cntl;
+	access_cntl = pci_read_config8(dev, 0x80);
+	/* Enable writes to protected registers */
+	pci_write_config8(dev, 0x80, access_cntl | 1);
+	/* Write the subsystem vendor and device id */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+	/* Restore protection */
+	pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = &ehci_set_subsystem,
+};
+static struct device_operations ehci_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = ehci_init,
+	.scan_bus         = 0,
+	.enable           = esb6300_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ehci_driver __pci_driver = {
+	.ops    = &ehci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_EHCI,
+};
diff --git a/src/southbridge/intel/esb6300/esb6300_ide.c b/src/southbridge/intel/esb6300/esb6300_ide.c
new file mode 100644
index 0000000..bb77ad7
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_ide.c
@@ -0,0 +1,56 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void ide_init(struct device *dev)
+{
+
+	/* Enable ide devices so the linux ide driver will work */
+	uint16_t word;
+
+	/* Enable IDE devices */
+        pci_write_config16(dev, 0x40, 0x0a307);
+        pci_write_config16(dev, 0x42, 0x0a307);
+        pci_write_config8(dev, 0x48, 0x05);
+        pci_write_config16(dev, 0x4a, 0x0101);
+        pci_write_config16(dev, 0x54, 0x5055);
+ 
+#if 0
+	word = pci_read_config16(dev, 0x40);
+	word |= (1 << 15);
+	pci_write_config16(dev, 0x40, word);
+	word = pci_read_config16(dev, 0x42);
+	word |= (1 << 15);
+	pci_write_config16(dev, 0x42, word);
+#endif
+	printk_debug("IDE Enabled\n");
+}
+
+static void esb6300_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	/* This value is also visible in uchi[0-2] and smbus functions */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = esb6300_ide_set_subsystem,
+};
+static struct device_operations ide_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = ide_init,
+	.scan_bus         = 0,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+	.ops    = &ide_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_IDE,
+};
+
diff --git a/src/southbridge/intel/esb6300/esb6300_lpc.c b/src/southbridge/intel/esb6300/esb6300_lpc.c
new file mode 100644
index 0000000..caef888
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_lpc.c
@@ -0,0 +1,410 @@
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include "esb6300.h"
+
+#define ACPI_BAR 0x40
+#define GPIO_BAR 0x58
+
+#define NMI_OFF 0
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON  1
+
+#ifndef MAINBOARD_POWER_ON_AFTER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#define ALL		(0xff << 24)
+#define NONE		(0)
+#define DISABLED	(1 << 16)
+#define ENABLED		(0 << 16)
+#define TRIGGER_EDGE	(0 << 15)
+#define TRIGGER_LEVEL	(1 << 15)
+#define POLARITY_HIGH	(0 << 13)
+#define POLARITY_LOW	(1 << 13)
+#define PHYSICAL_DEST	(0 << 11)
+#define LOGICAL_DEST	(1 << 11)
+#define ExtINT		(7 << 8)
+#define NMI		(4 << 8)
+#define SMI		(2 << 8)
+#define INT		(1 << 8)
+
+static void setup_ioapic(device_t dev)
+{
+	int i;
+	unsigned long value_low, value_high;
+	unsigned long ioapic_base = 0xfec00000;
+	volatile unsigned long *l;
+	unsigned interrupts;
+
+	l = (unsigned long *) ioapic_base;
+
+	l[0] = 0x01;
+	interrupts = (l[04] >> 16) & 0xff;
+	for (i = 0; i < interrupts; i++) {
+		l[0] = (i * 2) + 0x10;
+		l[4] = DISABLED;
+		value_low = l[4];
+		l[0] = (i * 2) + 0x11;
+		l[4] = NONE; /* Should this be an address? */
+		value_high = l[4];
+		if (value_low == 0xffffffff) {
+			printk_warning("%d IO APIC not responding.\n",
+				dev_path(dev));
+			return;
+		}
+	}
+
+	/* Put the ioapic in virtual wire mode */
+	l[0] = 0 + 0x10;
+	l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT;
+}
+
+#define SERIRQ_CNTL 0x64
+static void esb6300_enable_serial_irqs(device_t dev)
+{
+	/* set packet length and toggle silent mode bit */
+	pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+	pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+}
+
+#define PCI_DMA_CFG 0x90
+static void esb6300_pci_dma_cfg(device_t dev)
+{
+	/* Set PCI DMA CFG to lpc I/F DMA */
+	pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
+}
+
+#define LPC_EN 0xe6
+static void esb6300_enable_lpc(device_t dev)
+{
+        /* lpc i/f enable */
+        pci_write_config8(dev, LPC_EN, 0x0d);
+}
+
+typedef struct southbridge_intel_esb6300_config config_t;
+
+static void set_esb6300_gpio_use_sel(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_use_sel, gpio_use_sel2;
+	int i;
+
+//	gpio_use_sel  = 0x1B003100;
+//	gpio_use_sel2 = 0x03000000;
+	gpio_use_sel  = 0x1BBC31C0;
+	gpio_use_sel2 = 0x03000FE1;
+#if 0
+	for(i = 0; i < 64; i++) {
+		int val;
+		switch(config->gpio[i] & ESB6300_GPIO_USE_MASK) {
+		case ESB6300_GPIO_USE_AS_NATIVE: val = 0; break;
+		case ESB6300_GPIO_USE_AS_GPIO:   val = 1; break;
+		default:
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_use_sel  &= ~( 1 << i);
+			gpio_use_sel  |= (val << i);
+		} else {
+			gpio_use_sel2 &= ~( 1 << (i - 32));
+			gpio_use_sel2 |= (val << (i - 32));
+		}
+	}
+#endif
+	outl(gpio_use_sel,  res->base + 0x00);
+	outl(gpio_use_sel2, res->base + 0x30);
+}
+
+static void set_esb6300_gpio_direction(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_io_sel, gpio_io_sel2;
+	int i;
+
+//	gpio_io_sel  = 0x0000ffff;
+//	gpio_io_sel2 = 0x00000000;
+	gpio_io_sel  = 0x1900ffff;
+	gpio_io_sel2 = 0x00000fe1;
+#if 0
+	for(i = 0; i < 64; i++) {
+		int val;
+		switch(config->gpio[i] & ESB6300_GPIO_SEL_MASK) {
+		case ESB6300_GPIO_SEL_OUTPUT: val = 0; break;
+		case ESB6300_GPIO_SEL_INPUT:  val = 1; break;
+		default: 
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_io_sel  &= ~( 1 << i);
+			gpio_io_sel  |= (val << i);
+		} else {
+			gpio_io_sel2 &= ~( 1 << (i - 32));
+			gpio_io_sel2 |= (val << (i - 32));
+		}
+	}
+#endif
+	outl(gpio_io_sel,  res->base + 0x04);
+	outl(gpio_io_sel2, res->base + 0x34);
+}
+
+static void set_esb6300_gpio_level(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_lvl, gpio_lvl2;
+	uint32_t gpio_blink;
+	int i;
+
+//	gpio_lvl   = 0x1b3f0000;
+//	gpio_blink = 0x00040000;
+//	gpio_lvl2  = 0x00000fff;
+	gpio_lvl   = 0x19370000;
+	gpio_blink = 0x00000000;
+	gpio_lvl2  = 0x00000fff;
+#if 0
+	for(i = 0; i < 64; i++) {
+		int val, blink;
+		switch(config->gpio[i] & ESB6300_GPIO_LVL_MASK) {
+		case ESB6300_GPIO_LVL_LOW:   val = 0; blink = 0; break;
+		case ESB6300_GPIO_LVL_HIGH:  val = 1; blink = 0; break;
+		case ESB6300_GPIO_LVL_BLINK: val = 1; blink = 1; break;
+		default: 
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_lvl   &= ~(   1 << i);
+			gpio_blink &= ~(   1 << i);
+			gpio_lvl   |= (  val << i);
+			gpio_blink |= (blink << i);
+		} else {
+			gpio_lvl2  &= ~( 1 << (i - 32));
+			gpio_lvl2  |= (val << (i - 32));
+		}
+	}
+#endif
+	outl(gpio_lvl,   res->base + 0x0c);
+	outl(gpio_blink, res->base + 0x18);
+	outl(gpio_lvl2,  res->base + 0x38);
+}
+
+static void set_esb6300_gpio_inv(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_inv;
+	int i;
+
+	gpio_inv   = 0x00003100;
+#if 0
+	for(i = 0; i < 32; i++) {
+		int val;
+		switch(config->gpio[i] & ESB6300_GPIO_INV_MASK) {
+		case ESB6300_GPIO_INV_OFF: val = 0; break;
+		case ESB6300_GPIO_INV_ON:  val = 1; break;
+		default: 
+			continue;
+		}
+		gpio_inv &= ~( 1 << i);
+		gpio_inv |= (val << i);
+	}
+#endif
+	outl(gpio_inv,   res->base + 0x2c);
+}
+
+static void esb6300_pirq_init(device_t dev)
+{
+	config_t *config;
+
+	/* Get the chip configuration */
+	config = dev->chip_info;
+
+	if(config->pirq_a_d) {
+		pci_write_config32(dev, 0x60, config->pirq_a_d);
+	}
+	if(config->pirq_e_h) {
+		pci_write_config32(dev, 0x68, config->pirq_e_h);
+	}
+}
+
+
+static void esb6300_gpio_init(device_t dev)
+{
+	struct resource *res;
+	config_t *config;
+
+	/* Skip if I don't have any configuration */
+	if (!dev->chip_info) {
+		return;
+	}
+	/* The programmer is responsible for ensuring
+	 * a valid gpio configuration.
+	 */
+
+	/* Get the chip configuration */
+	config = dev->chip_info;
+	/* Find the GPIO bar */
+	res = find_resource(dev, GPIO_BAR);
+	if (!res) {
+		return; 
+	}
+
+	/* Set the use selects */
+	set_esb6300_gpio_use_sel(dev, res, config);
+
+	/* Set the IO direction */
+	set_esb6300_gpio_direction(dev, res, config);
+
+	/* Setup the input inverters */
+	set_esb6300_gpio_inv(dev, res, config);
+
+	/* Set the value on the GPIO output pins */
+	set_esb6300_gpio_level(dev, res, config);
+
+}
+
+
+static void lpc_init(struct device *dev)
+{
+	uint8_t byte;
+	uint32_t value;
+	int pwr_on=MAINBOARD_POWER_ON_AFTER_FAIL;
+
+	/* sata settings */
+	pci_write_config32(dev, 0x58, 0x00001181);
+
+	/* IO APIC initialization */
+	value = pci_read_config32(dev, 0xd0);
+	value |= (1 << 8)|(1<<7);
+	value |= (6 << 0)|(1<<13)|(1<<11);
+	pci_write_config32(dev, 0xd0, value);
+	setup_ioapic(dev);
+
+	/* disable reset timer */
+	pci_write_config8(dev, 0xd4, 0x02);
+
+	/* cmos ram 2nd 128 */
+	pci_write_config8(dev, 0xd8, 0x04);
+
+	/* comm 2 */
+	pci_write_config8(dev, 0xe0, 0x10);
+
+	/* fwh sellect */
+	pci_write_config32(dev, 0xe8, 0x00112233);
+
+	/* fwh decode */
+	pci_write_config8(dev, 0xf0, 0x0f);
+
+	/* av disable, sata controller */
+	pci_write_config8(dev, 0xf2, 0xc0);
+
+	/* undocumented */
+	pci_write_config8(dev, 0xa0, 0x20);
+	pci_write_config8(dev, 0xad, 0x03);
+	pci_write_config8(dev, 0xbb, 0x09);
+
+	/* apic1 rout */
+	pci_write_config8(dev, 0xf4, 0x40);
+
+	/* undocumented */
+	pci_write_config8(dev, 0xa0, 0x20);
+	pci_write_config8(dev, 0xad, 0x03);
+	pci_write_config8(dev, 0xbb, 0x09);
+	
+	esb6300_enable_serial_irqs(dev);
+
+	esb6300_pci_dma_cfg(dev);
+
+	esb6300_enable_lpc(dev);
+
+        get_option(&pwr_on, "power_on_after_fail");
+	byte = pci_read_config8(dev, 0xa4);
+	byte &= 0xfe;
+	if (!pwr_on) {
+		byte |= 1;
+	}
+	pci_write_config8(dev, 0xa4, byte);
+	printk_info("set power %s after power fail\n", pwr_on?"on":"off");
+
+	/* Set up the PIRQ */
+	esb6300_pirq_init(dev);
+	
+	/* Set the state of the gpio lines */
+	esb6300_gpio_init(dev);
+
+	/* Initialize the real time clock */
+	rtc_init(0);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+}
+
+static void esb6300_lpc_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Get the normal pci resources of this device */
+	pci_dev_read_resources(dev);
+
+	/* Add the ACPI BAR */
+	res = pci_get_resource(dev, ACPI_BAR);
+
+	/* Add the GPIO BAR */
+	res = pci_get_resource(dev, GPIO_BAR);
+
+	/* Add an extra subtractive resource for both memory and I/O */
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void esb6300_lpc_enable_resources(device_t dev)
+{
+	uint8_t acpi_cntl, gpio_cntl;
+
+	/* Enable the normal pci resources */
+	pci_dev_enable_resources(dev);
+
+	/* Enable the ACPI bar */
+	acpi_cntl = pci_read_config8(dev, 0x44);
+	acpi_cntl |= (1 << 4);
+	pci_write_config8(dev, 0x44, acpi_cntl);
+	
+	/* Enable the GPIO bar */
+	gpio_cntl = pci_read_config8(dev, 0x5c);
+	gpio_cntl |= (1 << 4);
+	pci_write_config8(dev, 0x5c, gpio_cntl);
+
+	enable_childrens_resources(dev);
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = 0,
+};
+
+static struct device_operations lpc_ops  = {
+	.read_resources   = esb6300_lpc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = esb6300_lpc_enable_resources,
+	.init             = lpc_init,
+	.scan_bus         = scan_static_bus,
+	.enable           = esb6300_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_ISA,
+};
diff --git a/src/southbridge/intel/esb6300/esb6300_pci.c b/src/southbridge/intel/esb6300/esb6300_pci.c
new file mode 100644
index 0000000..1131941
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_pci.c
@@ -0,0 +1,37 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void pci_init(struct device *dev)
+{
+
+	uint16_t word;
+
+	/* Clear system errors */
+	word = pci_read_config16(dev, 0x06);
+	word |= 0xf900; /* Clear possible errors */
+	pci_write_config16(dev, 0x06, word);
+
+	word = pci_read_config16(dev, 0x1e);
+	word |= 0xf800; /* Clear possible errors */
+	pci_write_config16(dev, 0x1e, word);
+}
+
+static struct device_operations pci_ops  = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init             = pci_init,
+	.scan_bus         = pci_scan_bridge,
+	.ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_PCI,
+};
+
diff --git a/src/southbridge/intel/esb6300/esb6300_pic.c b/src/southbridge/intel/esb6300/esb6300_pic.c
new file mode 100644
index 0000000..024c7e2
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_pic.c
@@ -0,0 +1,109 @@
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+#define ALL		(0xff << 24)
+#define NONE		(0)
+#define DISABLED	(1 << 16)
+#define ENABLED		(0 << 16)
+#define TRIGGER_EDGE	(0 << 15)
+#define TRIGGER_LEVEL	(1 << 15)
+#define POLARITY_HIGH	(0 << 13)
+#define POLARITY_LOW	(1 << 13)
+#define PHYSICAL_DEST	(0 << 11)
+#define LOGICAL_DEST	(1 << 11)
+#define ExtINT		(7 << 8)
+#define NMI		(4 << 8)
+#define SMI		(2 << 8)
+#define INT		(1 << 8)
+
+static void setup_ioapic(device_t dev)
+{
+	int i;
+	unsigned long value_low, value_high;
+	unsigned long ioapic_base = 0xfec10000;
+	volatile unsigned long *l;
+	unsigned interrupts;
+
+	l = (unsigned long *) ioapic_base;
+
+	l[0] = 0x01;
+	interrupts = (l[04] >> 16) & 0xff;
+	for (i = 0; i < interrupts; i++) {
+		l[0] = (i * 2) + 0x10;
+		l[4] = DISABLED;
+		value_low = l[4];
+		l[0] = (i * 2) + 0x11;
+		l[4] = NONE; /* Should this be an address? */
+		value_high = l[4];
+		if (value_low == 0xffffffff) {
+			printk_warning("%s IO APIC not responding.\n", 
+				dev_path(dev));
+			return;
+		}
+	}
+}
+
+static void pic_init(struct device *dev)
+{
+
+	uint16_t word;
+
+	/* Clear system errors */
+	word = pci_read_config16(dev, 0x06);
+	word |= 0xf900; /* Clear possible errors */
+	pci_write_config16(dev, 0x06, word);
+
+	/* enable interrupt lines */
+	pci_write_config8(dev, 0x3c, 0xff);
+
+	/* Setup the ioapic */
+	setup_ioapic(dev);
+}
+
+static void pic_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Get the normal pci resources of this device */
+	pci_dev_read_resources(dev);
+
+	/* Report the pic1 mbar resource */
+	res = new_resource(dev, 0x44);
+	res->base  = 0xfec10000;
+	res->size  = 256;
+	res->limit = res->base + res->size -1;
+	res->align = 8;
+	res->gran  = 8;
+	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | 
+		IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+	dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+}
+
+static struct pci_operations lops_pci = {
+	/* Can we set the pci subsystem and device id? */
+	.set_subsystem = 0,
+};
+
+static struct device_operations pci_ops  = {
+	.read_resources   = pic_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = pic_init,
+	.scan_bus         = 0,
+	.enable           = esb6300_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_PIC1,
+};
+
diff --git a/src/southbridge/intel/esb6300/esb6300_sata.c b/src/southbridge/intel/esb6300/esb6300_sata.c
new file mode 100644
index 0000000..9d8fb75
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_sata.c
@@ -0,0 +1,77 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void sata_init(struct device *dev)
+{
+
+	/* Enable sata devices so the linux sata driver will work */
+	uint16_t word;
+
+	/* Enable SATA devices */
+
+	printk_debug("SATA init\n");
+        /* SATA configuration */
+        pci_write_config8(dev, 0x04, 0x07);
+        pci_write_config8(dev, 0x09, 0x8f);
+                                                                                
+        /* Set timmings */
+        pci_write_config16(dev, 0x40, 0x0a307);
+        pci_write_config16(dev, 0x42, 0x0a307);
+                                                                                
+        /* Sync DMA */
+        pci_write_config16(dev, 0x48, 0x000f);
+        pci_write_config16(dev, 0x4a, 0x1111);
+                                                                                
+        /* 66 mhz */
+        pci_write_config16(dev, 0x54, 0xf00f);
+                                                                                
+        /* Combine ide - sata configuration */
+        pci_write_config8(dev, 0x90, 0x0);
+                                                                                
+        /* port 0 & 1 enable */
+        pci_write_config8(dev, 0x92, 0x33);
+                                                                                
+        /* initialize SATA  */
+        pci_write_config16(dev, 0xa0, 0x0018);
+        pci_write_config32(dev, 0xa4, 0x00000264);
+        pci_write_config16(dev, 0xa0, 0x0040);
+        pci_write_config32(dev, 0xa4, 0x00220043);
+                                                                                
+	printk_debug("SATA Enabled\n");
+}
+
+static void esb6300_sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	/* This value is also visible in usb1, usb2 and smbus functions */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = esb6300_sata_set_subsystem,
+};
+static struct device_operations sata_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = sata_init,
+	.scan_bus         = 0,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver sata_driver __pci_driver = {
+        .ops    = &sata_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA,
+};
+                                                                                
+static struct pci_driver sata_driver_nr __pci_driver = {
+        .ops    = &sata_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA_R,
+};
+
diff --git a/src/southbridge/intel/esb6300/esb6300_smbus.c b/src/southbridge/intel/esb6300/esb6300_smbus.c
new file mode 100644
index 0000000..6cb6f2d
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_smbus.c
@@ -0,0 +1,45 @@
+#include <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "esb6300.h"
+#include "esb6300_smbus.h"
+
+static int lsmbus_read_byte(struct bus *bus, device_t dev, uint8_t address)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(bus->dev, 0x20);
+	
+	return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+	.read_byte  = lsmbus_read_byte,
+};
+static struct pci_operations lops_pci = {
+	/* The subsystem id follows the ide controller */
+	.set_subsystem = 0,
+};
+static struct device_operations smbus_ops = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = scan_static_bus,
+	.enable           = esb6300_enable,
+	.ops_pci          = &lops_pci,
+	.ops_smbus_bus    = &lops_smbus_bus,
+};
+
+static struct pci_driver smbus_driver __pci_driver = {
+	.ops    = &smbus_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_SMB,
+};
+
diff --git a/src/southbridge/intel/esb6300/esb6300_smbus.h b/src/southbridge/intel/esb6300/esb6300_smbus.h
new file mode 100644
index 0000000..861230e
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_smbus.h
@@ -0,0 +1,105 @@
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL  0x2
+#define SMBHSTCMD  0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT  0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL  0xf 
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+
+static void smbus_delay(void)
+{
+	outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+		smbus_delay();
+		if (--loops == 0)
+			break;
+		byte = inb(smbus_io_base + SMBHSTSTAT);
+	} while(byte & 1);
+	return loops?0:-1;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+	        smbus_delay();
+	        if (--loops == 0)
+	               break;
+	        byte = inb(smbus_io_base + SMBHSTSTAT);
+	} while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
+	return loops?0:-1;
+}
+
+static int smbus_wait_until_blk_done(unsigned smbus_io_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+	        smbus_delay();
+	        if (--loops == 0)
+	               break;
+	        byte = inb(smbus_io_base + SMBHSTSTAT);
+	} while((byte&(1<<7)) == 0);
+	return loops?0:-1;
+}
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+	unsigned char global_status_register;
+	unsigned char byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+	/* setup transaction */
+	/* disable interrupts */
+	outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+	/* set the command/address... */
+	outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+	/* set up for a byte data read */
+	outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+	/* clear the data byte...*/
+	outb(0, smbus_io_base + SMBHSTDAT0);
+
+	/* start the command */
+	outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+
+	global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+	/* Ignore the In Use Status... */
+	global_status_register &= ~(3 << 5);
+
+	/* read results of transaction */
+	byte = inb(smbus_io_base + SMBHSTDAT0);
+	if (global_status_register != (1 << 1)) {
+		return SMBUS_ERROR;
+	}
+	return byte;
+}
+
diff --git a/src/southbridge/intel/esb6300/esb6300_uhci.c b/src/southbridge/intel/esb6300/esb6300_uhci.c
new file mode 100644
index 0000000..835a39c
--- /dev/null
+++ b/src/southbridge/intel/esb6300/esb6300_uhci.c
@@ -0,0 +1,56 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void uhci_init(struct device *dev)
+{
+	uint32_t cmd;
+
+#if 1
+	printk_debug("UHCI: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_MASTER);
+
+
+	printk_debug("done.\n");
+#endif
+
+}
+
+static struct pci_operations lops_pci = {
+	/* The subsystem id follows the ide controller */
+	.set_subsystem = 0,
+};
+
+static struct device_operations uhci_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = uhci_init,
+	.scan_bus         = 0,
+	.enable           = esb6300_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver uhci_driver __pci_driver = {
+	.ops    = &uhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_USB,
+};
+
+static struct pci_driver usb2_driver __pci_driver = {
+	.ops    = &uhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_USB2,
+};
+
+static struct pci_driver usb3_driver __pci_driver = {
+	.ops    = &uhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_6300ESB_USB3,
+};
+
diff --git a/src/southbridge/intel/i82801er/i82801er_reset.c b/src/southbridge/intel/i82801er/i82801er_reset.c
index 3d7a4b7..fa41756 100644
--- a/src/southbridge/intel/i82801er/i82801er_reset.c
+++ b/src/southbridge/intel/i82801er/i82801er_reset.c
@@ -1,6 +1,6 @@
 #include <arch/io.h>
 
-void hard_reset(void)
+void i82801er_hard_reset(void)
 {
         /* Try rebooting through port 0xcf9 */
         outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
diff --git a/src/southbridge/intel/i82870/p64h2_pcibridge.c b/src/southbridge/intel/i82870/p64h2_pcibridge.c
index 6f161e9..01f8717 100644
--- a/src/southbridge/intel/i82870/p64h2_pcibridge.c
+++ b/src/southbridge/intel/i82870/p64h2_pcibridge.c
@@ -29,6 +29,7 @@
         .enable_resources = pci_bus_enable_resources,
         .init             = p64h2_pcix_init,
         .scan_bus         = pci_scan_bridge,
+	.reset_bus        = pci_bus_reset,
 };
 
 static struct pci_driver pcix_driver __pci_driver = {
diff --git a/src/southbridge/intel/ich5r/Config.lb b/src/southbridge/intel/ich5r/Config.lb
new file mode 100644
index 0000000..0bad3f0
--- /dev/null
+++ b/src/southbridge/intel/ich5r/Config.lb
@@ -0,0 +1,11 @@
+config chip.h
+driver ich5r.o
+driver ich5r_uhci.o
+driver ich5r_lpc.o
+driver ich5r_ide.o
+driver ich5r_sata.o
+driver ich5r_ehci.o
+driver ich5r_smbus.o
+driver ich5r_pci.o
+driver ich5r_ac97.o
+object ich5r_watchdog.o
diff --git a/src/southbridge/intel/ich5r/chip.h b/src/southbridge/intel/ich5r/chip.h
new file mode 100644
index 0000000..b3abeab
--- /dev/null
+++ b/src/southbridge/intel/ich5r/chip.h
@@ -0,0 +1,30 @@
+struct southbridge_intel_ich5r_config 
+{
+
+#define ICH5R_GPIO_USE_MASK      0x03
+#define ICH5R_GPIO_USE_DEFAULT   0x00
+#define ICH5R_GPIO_USE_AS_NATIVE 0x01
+#define ICH5R_GPIO_USE_AS_GPIO   0x02
+
+#define ICH5R_GPIO_SEL_MASK      0x0c
+#define ICH5R_GPIO_SEL_DEFAULT   0x00
+#define ICH5R_GPIO_SEL_OUTPUT    0x04
+#define ICH5R_GPIO_SEL_INPUT     0x08
+
+#define ICH5R_GPIO_LVL_MASK      0x30
+#define ICH5R_GPIO_LVL_DEFAULT   0x00
+#define ICH5R_GPIO_LVL_LOW       0x10
+#define ICH5R_GPIO_LVL_HIGH      0x20
+#define ICH5R_GPIO_LVL_BLINK     0x30
+
+#define ICH5R_GPIO_INV_MASK      0xc0
+#define ICH5R_GPIO_INV_DEFAULT   0x00
+#define ICH5R_GPIO_INV_OFF       0x40
+#define ICH5R_GPIO_INV_ON        0x80
+
+	/* GPIO use select */
+	unsigned char gpio[64];
+	unsigned int  pirq_a_d;
+	unsigned int  pirq_e_h;
+};
+extern struct chip_operations southbridge_intel_ich5r_ops;
diff --git a/src/southbridge/intel/ich5r/ich5r.c b/src/southbridge/intel/ich5r/ich5r.c
new file mode 100644
index 0000000..1b65465
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r.c
@@ -0,0 +1,48 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "ich5r.h"
+
+void ich5r_enable(device_t dev)
+{
+	device_t lpc_dev;
+	unsigned index = 0;
+	uint16_t reg_old, reg;
+
+	/* See if we are on the behind the ich5r pci bridge */
+	lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0));
+	if((dev->path.u.pci.devfn &0xf8)== 0xf8) {
+		index = dev->path.u.pci.devfn & 7;
+	}
+	else if((dev->path.u.pci.devfn &0xf8)== 0xe8) {
+		index = (dev->path.u.pci.devfn & 7) +8;
+	}
+	if ((!lpc_dev) || (index >= 16) || ((1<<index)&0x3091)) {
+		return;
+	}
+	if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) ||
+		(lpc_dev->device != PCI_DEVICE_ID_INTEL_82801ER_ISA)) {
+		uint32_t id;
+		id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
+		if (id != (PCI_VENDOR_ID_INTEL | 
+				(PCI_DEVICE_ID_INTEL_82801ER_ISA << 16))) {
+			return;
+		}
+	}
+
+	reg = reg_old = pci_read_config16(lpc_dev, 0xf2);
+	reg &= ~(1 << index);
+	if (!dev->enabled) {
+		reg |= (1 << index);
+	}
+	if (reg != reg_old) {
+		pci_write_config16(lpc_dev, 0xf2, reg);
+	}
+	
+}
+
+struct chip_operations southbridge_intel_ich5r_ops = {
+	CHIP_NAME("INTEL 82801ER")
+	.enable_dev = ich5r_enable,
+};
diff --git a/src/southbridge/intel/ich5r/ich5r.h b/src/southbridge/intel/ich5r/ich5r.h
new file mode 100644
index 0000000..28572c9
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r.h
@@ -0,0 +1,7 @@
+#ifndef ICH5R_H
+#define ICH5R_H
+
+#include "chip.h"
+void ich5r_enable(device_t dev);
+
+#endif /* ICH5R_H */
diff --git a/src/southbridge/intel/ich5r/ich5r_ac97.c b/src/southbridge/intel/ich5r/ich5r_ac97.c
new file mode 100644
index 0000000..17d924b
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_ac97.c
@@ -0,0 +1,37 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ich5r.h"
+
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	/* Write the subsystem vendor and device id */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = ac97_set_subsystem,
+};
+static struct device_operations ac97_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = 0,
+	.enable           = ich5r_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ac97_audio_driver __pci_driver = {
+	.ops    = &ac97_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_AC97_AUDIO,
+};
+static struct pci_driver ac97_modem_driver __pci_driver = {
+	.ops    = &ac97_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_AC97_MODEM,
+};
diff --git a/src/southbridge/intel/ich5r/ich5r_early_smbus.c b/src/southbridge/intel/ich5r/ich5r_early_smbus.c
new file mode 100644
index 0000000..6880fde
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_early_smbus.c
@@ -0,0 +1,130 @@
+#include "ich5r_smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+	device_t dev;
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d3), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("SMBUS controller not found\r\n");
+	}
+	uint8_t enable;
+	print_spew("SMBus controller enabled\r\n");
+	pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+	pci_write_config8(dev, 0x40, 1);
+	pci_write_config8(dev, 0x4, 1);
+	/* SMBALERT_DIS */
+	pci_write_config8(dev, 0x11, 4);
+	
+	/* Disable interrupt generation */
+	outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+	dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
+	if (dev == PCI_DEV_INVALID) {
+		die("ISA bridge not found\r\n");
+	}
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+	return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+	if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+		return;
+	}
+#if 0
+	/* setup transaction */
+	/* disable interrupts */
+	outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)),
+			SMBUS_IO_BASE + SMBGCTL);
+	/* set the device I'm talking too */
+	outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR);
+	outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	/* set up for a byte data write */ /* FIXME */
+	outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x1), SMBUS_IO_BASE + SMBGCTL);
+	/* clear any lingering errors, so the transaction will run */
+	/* Do I need to write the bits to a 1 to clear an error? */
+	outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
+
+	/* clear the data word...*/
+	outw(val, SMBUS_IO_BASE + SMBHSTDAT);
+
+	/* start the command */
+	outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL);
+
+	/* poll for transaction completion */
+	smbus_wait_until_done(SMBUS_IO_BASE);
+#endif	
+	return;
+}
+
+static int smbus_write_block(unsigned device, unsigned length, unsigned cmd, 
+		 unsigned data1, unsigned data2)
+{
+	unsigned char global_control_register;
+	unsigned char global_status_register;
+	unsigned char byte;
+	unsigned char stat;
+	int i;
+
+	/* chear the PM timeout flags, SECOND_TO_STS */
+	outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
+	
+	if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+		return -2;
+	}
+	
+	/* setup transaction */
+	/* Obtain ownership */
+	outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+	for(stat=0;(stat&0x40)==0;) {
+	stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+	/* clear the done bit */
+	outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
+	/* disable interrupts */
+	outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+	
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
+	
+	/* set the command address */
+	outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+	
+	/* set the block length */
+	outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
+	
+	/* try sending out the first byte of data here */
+	byte=(data1>>(0))&0x0ff;
+	outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+	/* issue a block write command */
+	outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40, 
+			SMBUS_IO_BASE + SMBHSTCTL);
+
+	for(i=0;i<length;i++) {
+		
+		/* poll for transaction completion */
+		if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
+			return -3;
+		}
+		
+		/* load the next byte */
+		if(i>3)
+			byte=(data2>>(i%4))&0x0ff;
+		else
+			byte=(data1>>(i))&0x0ff;
+		outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+		
+		/* clear the done bit */
+		outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), 
+				SMBUS_IO_BASE + SMBHSTSTAT);
+	}
+
+	print_debug("SMBUS Block complete\r\n");
+	return 0;
+}
+
diff --git a/src/southbridge/intel/ich5r/ich5r_ehci.c b/src/southbridge/intel/ich5r/ich5r_ehci.c
new file mode 100644
index 0000000..d1650c1
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_ehci.c
@@ -0,0 +1,50 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ich5r.h"
+
+static void ehci_init(struct device *dev)
+{
+	uint32_t cmd;
+
+	printk_debug("EHCI: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_MASTER);
+
+	printk_debug("done.\n");
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	uint8_t access_cntl;
+	access_cntl = pci_read_config8(dev, 0x80);
+	/* Enable writes to protected registers */
+	pci_write_config8(dev, 0x80, access_cntl | 1);
+	/* Write the subsystem vendor and device id */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+	/* Restore protection */
+	pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = &ehci_set_subsystem,
+};
+static struct device_operations ehci_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = ehci_init,
+	.scan_bus         = 0,
+	.enable           = ich5r_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ehci_driver __pci_driver = {
+	.ops    = &ehci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_EHCI,
+};
diff --git a/src/southbridge/intel/ich5r/ich5r_ide.c b/src/southbridge/intel/ich5r/ich5r_ide.c
new file mode 100644
index 0000000..7bfd925
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_ide.c
@@ -0,0 +1,44 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ich5r.h"
+
+static void ide_init(struct device *dev)
+{
+
+	/* Enable IDE devices and timmings */
+	pci_write_config16(dev, 0x40, 0x0a307);
+	pci_write_config16(dev, 0x42, 0x0a307);
+	pci_write_config8(dev, 0x48, 0x05);
+	pci_write_config16(dev, 0x4a, 0x0101);
+	pci_write_config16(dev, 0x54, 0x5055);
+	printk_debug("IDE Enabled\n");
+}
+
+static void ich5r_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	/* This value is also visible in uchi[0-2] and smbus functions */
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = ich5r_ide_set_subsystem,
+};
+static struct device_operations ide_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = ide_init,
+	.scan_bus         = 0,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver ide_driver __pci_driver = {
+	.ops    = &ide_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_IDE,
+};
+
diff --git a/src/southbridge/intel/ich5r/ich5r_lpc.c b/src/southbridge/intel/ich5r/ich5r_lpc.c
new file mode 100644
index 0000000..d9d9889
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_lpc.c
@@ -0,0 +1,369 @@
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include "ich5r.h"
+
+#define ACPI_BAR 0x40
+#define GPIO_BAR 0x58
+
+#define NMI_OFF 0
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON  1
+
+#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#define ALL		(0xff << 24)
+#define NONE		(0)
+#define DISABLED	(1 << 16)
+#define ENABLED		(0 << 16)
+#define TRIGGER_EDGE	(0 << 15)
+#define TRIGGER_LEVEL	(1 << 15)
+#define POLARITY_HIGH	(0 << 13)
+#define POLARITY_LOW	(1 << 13)
+#define PHYSICAL_DEST	(0 << 11)
+#define LOGICAL_DEST	(1 << 11)
+#define ExtINT		(7 << 8)
+#define NMI		(4 << 8)
+#define SMI		(2 << 8)
+#define INT		(1 << 8)
+
+static void setup_ioapic(void)
+{
+	int i;
+	unsigned long value_low, value_high;
+	unsigned long ioapic_base = 0xfec00000;
+	volatile unsigned long *l;
+	unsigned interrupts;
+
+	l = (unsigned long *) ioapic_base;
+
+	l[0] = 0x01;
+	interrupts = (l[04] >> 16) & 0xff;
+	for (i = 0; i < interrupts; i++) {
+		l[0] = (i * 2) + 0x10;
+		l[4] = DISABLED;
+		value_low = l[4];
+		l[0] = (i * 2) + 0x11;
+		l[4] = NONE; /* Should this be an address? */
+		value_high = l[4];
+		if (value_low == 0xffffffff) {
+			printk_warning("IO APIC not responding.\n");
+			return;
+		}
+	}
+
+	/* Put the ioapic in virtual wire mode */
+	l[0] = 0 + 0x10;
+	l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT;
+}
+
+#define SERIRQ_CNTL 0x64
+static void ich5r_enable_serial_irqs(device_t dev)
+{
+	/* set packet length and toggle silent mode bit */
+	pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+	pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+}
+
+#define PCI_DMA_CFG 0x90
+static void ich5r_pci_dma_cfg(device_t dev)
+{
+	/* Set PCI DMA CFG to lpc I/F DMA */
+	pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
+}
+
+#define LPC_EN 0xe6
+static void ich5r_enable_lpc(device_t dev)
+{
+        /* lpc i/f enable */
+        pci_write_config8(dev, LPC_EN, 0x0d);
+}
+
+typedef struct southbridge_intel_ich5r_config config_t;
+
+static void set_ich5r_gpio_use_sel(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_use_sel, gpio_use_sel2;
+	int i;
+
+	gpio_use_sel  = 0x1A003180;
+	gpio_use_sel2 = 0x00000007;
+	for(i = 0; i < 64; i++) {
+		int val;
+		switch(config->gpio[i] & ICH5R_GPIO_USE_MASK) {
+		case ICH5R_GPIO_USE_AS_NATIVE: val = 0; break;
+		case ICH5R_GPIO_USE_AS_GPIO:   val = 1; break;
+		default:
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_use_sel  &= ~( 1 << i);
+			gpio_use_sel  |= (val << i);
+		} else {
+			gpio_use_sel2 &= ~( 1 << (i - 32));
+			gpio_use_sel2 |= (val << (i - 32));
+		}
+	}
+	outl(gpio_use_sel,  res->base + 0x00);
+	outl(gpio_use_sel2, res->base + 0x30);
+}
+
+static void set_ich5r_gpio_direction(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_io_sel, gpio_io_sel2;
+	int i;
+
+	gpio_io_sel  = 0x0000ffff;
+	gpio_io_sel2 = 0x00000300;
+	for(i = 0; i < 64; i++) {
+		int val;
+		switch(config->gpio[i] & ICH5R_GPIO_SEL_MASK) {
+		case ICH5R_GPIO_SEL_OUTPUT: val = 0; break;
+		case ICH5R_GPIO_SEL_INPUT:  val = 1; break;
+		default: 
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_io_sel  &= ~( 1 << i);
+			gpio_io_sel  |= (val << i);
+		} else {
+			gpio_io_sel2 &= ~( 1 << (i - 32));
+			gpio_io_sel2 |= (val << (i - 32));
+		}
+	}
+	outl(gpio_io_sel,  res->base + 0x04);
+	outl(gpio_io_sel2, res->base + 0x34);
+}
+
+static void set_ich5r_gpio_level(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_lvl, gpio_lvl2;
+	uint32_t gpio_blink;
+	int i;
+
+	gpio_lvl   = 0x1b3f0000;
+	gpio_blink = 0x00040000;
+	gpio_lvl2  = 0x00030207;
+	for(i = 0; i < 64; i++) {
+		int val, blink;
+		switch(config->gpio[i] & ICH5R_GPIO_LVL_MASK) {
+		case ICH5R_GPIO_LVL_LOW:   val = 0; blink = 0; break;
+		case ICH5R_GPIO_LVL_HIGH:  val = 1; blink = 0; break;
+		case ICH5R_GPIO_LVL_BLINK: val = 1; blink = 1; break;
+		default: 
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_lvl   &= ~(   1 << i);
+			gpio_blink &= ~(   1 << i);
+			gpio_lvl   |= (  val << i);
+			gpio_blink |= (blink << i);
+		} else {
+			gpio_lvl2  &= ~( 1 << (i - 32));
+			gpio_lvl2  |= (val << (i - 32));
+		}
+	}
+	outl(gpio_lvl,   res->base + 0x0c);
+	outl(gpio_blink, res->base + 0x18);
+	outl(gpio_lvl2,  res->base + 0x38);
+}
+
+static void set_ich5r_gpio_inv(
+	device_t dev, struct resource *res, config_t *config)
+{
+	uint32_t gpio_inv;
+	int i;
+
+	gpio_inv   = 0x00000000;
+	for(i = 0; i < 32; i++) {
+		int val;
+		switch(config->gpio[i] & ICH5R_GPIO_INV_MASK) {
+		case ICH5R_GPIO_INV_OFF: val = 0; break;
+		case ICH5R_GPIO_INV_ON:  val = 1; break;
+		default: 
+			continue;
+		}
+		gpio_inv &= ~( 1 << i);
+		gpio_inv |= (val << i);
+	}
+	outl(gpio_inv,   res->base + 0x2c);
+}
+
+static void ich5r_pirq_init(device_t dev)
+{
+	config_t *config;
+
+	/* Get the chip configuration */
+	config = dev->chip_info;
+
+	if(config->pirq_a_d) {
+		pci_write_config32(dev, 0x60, config->pirq_a_d);
+	}
+	if(config->pirq_e_h) {
+		pci_write_config32(dev, 0x68, config->pirq_e_h);
+	}
+}
+
+
+static void ich5r_gpio_init(device_t dev)
+{
+	struct resource *res;
+	config_t *config;
+
+	/* Skip if I don't have any configuration */
+	if (!dev->chip_info) {
+		return;
+	}
+	/* The programmer is responsible for ensuring
+	 * a valid gpio configuration.
+	 */
+
+	/* Get the chip configuration */
+	config = dev->chip_info;
+	/* Find the GPIO bar */
+	res = find_resource(dev, GPIO_BAR);
+	if (!res) {
+		return; 
+	}
+
+	/* Set the use selects */
+	set_ich5r_gpio_use_sel(dev, res, config);
+
+	/* Set the IO direction */
+	set_ich5r_gpio_direction(dev, res, config);
+
+	/* Setup the input inverters */
+	set_ich5r_gpio_inv(dev, res, config);
+
+	/* Set the value on the GPIO output pins */
+	set_ich5r_gpio_level(dev, res, config);
+
+}
+
+
+static void lpc_init(struct device *dev)
+{
+	uint8_t byte;
+	uint32_t value;
+	int pwr_on=MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+	/* IO APIC initialization */
+	value = pci_read_config32(dev, 0xd0);
+	value |= (1 << 8)|(1<<7)|(1<<1);
+	pci_write_config32(dev, 0xd0, value);
+	value = pci_read_config32(dev, 0xd4);
+	value |= (1<<1);
+	pci_write_config32(dev, 0xd4, value);
+	setup_ioapic();
+
+	ich5r_enable_serial_irqs(dev);
+
+	ich5r_pci_dma_cfg(dev);
+
+	ich5r_enable_lpc(dev);
+
+	/* Clear SATA to non raid */
+	pci_write_config8(dev, 0xae, 0x00);
+
+        get_option(&pwr_on, "power_on_after_fail");
+	byte = pci_read_config8(dev, 0xa4);
+	byte &= 0xfe;
+	if (!pwr_on) {
+		byte |= 1;
+	}
+	pci_write_config8(dev, 0xa4, byte);
+	printk_info("set power %s after power fail\n", pwr_on?"on":"off");
+
+	/* Set up the PIRQ */
+	ich5r_pirq_init(dev);
+	
+	/* Set the state of the gpio lines */
+	ich5r_gpio_init(dev);
+
+	/* Initialize the real time clock */
+	rtc_init(0);
+
+	/* Initialize isa dma */
+	isa_dma_init();
+
+	/* Disable IDE (needed when sata is enabled) */
+	pci_write_config8(dev, 0xf2, 0x60);
+	
+}
+
+static void ich5r_lpc_read_resources(device_t dev)
+{
+	struct resource *res;
+
+	/* Get the normal pci resources of this device */
+	pci_dev_read_resources(dev);
+
+	/* Add the ACPI BAR */
+	res = pci_get_resource(dev, ACPI_BAR);
+
+	/* Add the GPIO BAR */
+	res = pci_get_resource(dev, GPIO_BAR);
+
+	/* Add an extra subtractive resource for both memory and I/O */
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+	res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void ich5r_lpc_enable_resources(device_t dev)
+{
+	uint8_t acpi_cntl, gpio_cntl;
+
+	/* Enable the normal pci resources */
+	pci_dev_enable_resources(dev);
+
+	/* Enable the ACPI bar */
+	acpi_cntl = pci_read_config8(dev, 0x44);
+	acpi_cntl |= (1 << 4);
+	pci_write_config8(dev, 0x44, acpi_cntl);
+	
+	/* Enable the GPIO bar */
+	gpio_cntl = pci_read_config8(dev, 0x5c);
+	gpio_cntl |= (1 << 4);
+	pci_write_config8(dev, 0x5c, gpio_cntl);
+
+	enable_childrens_resources(dev);
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = 0,
+};
+
+static struct device_operations lpc_ops  = {
+	.read_resources   = ich5r_lpc_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = ich5r_lpc_enable_resources,
+	.init             = lpc_init,
+	.scan_bus         = scan_static_bus,
+	.enable           = ich5r_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &lpc_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_ISA,
+};
diff --git a/src/southbridge/intel/ich5r/ich5r_pci.c b/src/southbridge/intel/ich5r/ich5r_pci.c
new file mode 100644
index 0000000..d2c94c7
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_pci.c
@@ -0,0 +1,37 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ich5r.h"
+
+static void pci_init(struct device *dev)
+{
+
+	uint16_t word;
+
+	/* Clear system errors */
+	word = pci_read_config16(dev, 0x06);
+	word |= 0xf900; /* Clear possible errors */
+	pci_write_config16(dev, 0x06, word);
+
+	word = pci_read_config16(dev, 0x1e);
+	word |= 0xf800; /* Clear possible errors */
+	pci_write_config16(dev, 0x1e, word);
+}
+
+static struct device_operations pci_ops  = {
+	.read_resources   = pci_bus_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+	.init             = pci_init,
+	.scan_bus         = pci_scan_bridge,
+	.ops_pci          = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+	.ops    = &pci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_PCI,
+};
+
diff --git a/src/southbridge/intel/ich5r/ich5r_sata.c b/src/southbridge/intel/ich5r/ich5r_sata.c
new file mode 100644
index 0000000..803d878
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_sata.c
@@ -0,0 +1,63 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ich5r.h"
+
+static void sata_init(struct device *dev)
+{
+
+	uint16_t word;
+
+  printk_debug("SATA init\n");
+	/* SATA configuration */
+	pci_write_config8(dev, 0x04, 0x07);
+	pci_write_config8(dev, 0x09, 0x8f);
+	
+	/* Set timmings */
+	pci_write_config16(dev, 0x40, 0x0a307);
+	pci_write_config16(dev, 0x42, 0x0a307);
+
+	/* Sync DMA */
+	pci_write_config16(dev, 0x48, 0x000f);
+	pci_write_config16(dev, 0x4a, 0x1111);
+
+	/* 66 mhz */
+	pci_write_config16(dev, 0x54, 0xf00f);
+
+	/* Combine ide - sata configuration */
+	pci_write_config8(dev, 0x90, 0x0);
+	
+	/* port 0 & 1 enable */
+	pci_write_config8(dev, 0x92, 0x33);
+	
+	/* initialize SATA  */
+	pci_write_config16(dev, 0xa0, 0x0018);
+	pci_write_config32(dev, 0xa4, 0x00000264);
+	pci_write_config16(dev, 0xa0, 0x0040);
+	pci_write_config32(dev, 0xa4, 0x00220043);
+
+}
+
+static struct device_operations sata_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = sata_init,
+	.scan_bus         = 0,
+	.ops_pci          = 0,
+};
+
+static struct pci_driver sata_driver __pci_driver = {
+	.ops    = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F2_R,
+};
+
+static struct pci_driver sata_driver_nr __pci_driver = {
+	.ops    = &sata_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_1F2,
+};
+
diff --git a/src/southbridge/intel/ich5r/ich5r_smbus.c b/src/southbridge/intel/ich5r/ich5r_smbus.c
new file mode 100644
index 0000000..3337a65
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_smbus.c
@@ -0,0 +1,45 @@
+#include <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "ich5r.h"
+#include "ich5r_smbus.h"
+
+static int lsmbus_read_byte(struct bus *bus, device_t dev, uint8_t address)
+{
+	unsigned device;
+	struct resource *res;
+
+	device = dev->path.u.i2c.device;
+	res = find_resource(bus->dev, 0x20);
+	
+	return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+	.read_byte  = lsmbus_read_byte,
+};
+static struct pci_operations lops_pci = {
+	/* The subsystem id follows the ide controller */
+	.set_subsystem = 0,
+};
+static struct device_operations smbus_ops = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = 0,
+	.scan_bus         = scan_static_bus,
+	.enable           = ich5r_enable,
+	.ops_pci          = &lops_pci,
+	.ops_smbus_bus    = &lops_smbus_bus,
+};
+
+static struct pci_driver smbus_driver __pci_driver = {
+	.ops    = &smbus_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_SMB,
+};
+
diff --git a/src/southbridge/intel/ich5r/ich5r_smbus.h b/src/southbridge/intel/ich5r/ich5r_smbus.h
new file mode 100644
index 0000000..861230e
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_smbus.h
@@ -0,0 +1,105 @@
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL  0x2
+#define SMBHSTCMD  0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT  0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL  0xf 
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+
+static void smbus_delay(void)
+{
+	outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+		smbus_delay();
+		if (--loops == 0)
+			break;
+		byte = inb(smbus_io_base + SMBHSTSTAT);
+	} while(byte & 1);
+	return loops?0:-1;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+	        smbus_delay();
+	        if (--loops == 0)
+	               break;
+	        byte = inb(smbus_io_base + SMBHSTSTAT);
+	} while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
+	return loops?0:-1;
+}
+
+static int smbus_wait_until_blk_done(unsigned smbus_io_base)
+{
+	unsigned loops = SMBUS_TIMEOUT;
+	unsigned char byte;
+	do {
+	        smbus_delay();
+	        if (--loops == 0)
+	               break;
+	        byte = inb(smbus_io_base + SMBHSTSTAT);
+	} while((byte&(1<<7)) == 0);
+	return loops?0:-1;
+}
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+	unsigned char global_status_register;
+	unsigned char byte;
+
+	if (smbus_wait_until_ready(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+	}
+	/* setup transaction */
+	/* disable interrupts */
+	outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+	/* set the device I'm talking too */
+	outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+	/* set the command/address... */
+	outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+	/* set up for a byte data read */
+	outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
+	/* clear any lingering errors, so the transaction will run */
+	outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+	/* clear the data byte...*/
+	outb(0, smbus_io_base + SMBHSTDAT0);
+
+	/* start the command */
+	outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(smbus_io_base) < 0) {
+		return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+	}
+
+	global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+	/* Ignore the In Use Status... */
+	global_status_register &= ~(3 << 5);
+
+	/* read results of transaction */
+	byte = inb(smbus_io_base + SMBHSTDAT0);
+	if (global_status_register != (1 << 1)) {
+		return SMBUS_ERROR;
+	}
+	return byte;
+}
+
diff --git a/src/southbridge/intel/ich5r/ich5r_uhci.c b/src/southbridge/intel/ich5r/ich5r_uhci.c
new file mode 100644
index 0000000..ad4ae97
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_uhci.c
@@ -0,0 +1,56 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ich5r.h"
+
+static void uhci_init(struct device *dev)
+{
+	uint32_t cmd;
+
+#if 1
+	printk_debug("UHCI: Setting up controller.. ");
+	cmd = pci_read_config32(dev, PCI_COMMAND);
+	pci_write_config32(dev, PCI_COMMAND, 
+		cmd | PCI_COMMAND_MASTER);
+
+
+	printk_debug("done.\n");
+#endif
+
+}
+
+static struct pci_operations lops_pci = {
+	/* The subsystem id follows the ide controller */
+	.set_subsystem = 0,
+};
+
+static struct device_operations uhci_ops  = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = uhci_init,
+	.scan_bus         = 0,
+	.enable           = ich5r_enable,
+	.ops_pci          = &lops_pci,
+};
+
+static struct pci_driver uhci_driver __pci_driver = {
+	.ops    = &uhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_USB,
+};
+
+static struct pci_driver usb2_driver __pci_driver = {
+	.ops    = &uhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_USB2,
+};
+
+static struct pci_driver usb3_driver __pci_driver = {
+	.ops    = &uhci_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = PCI_DEVICE_ID_INTEL_82801ER_USB3,
+};
+
diff --git a/src/southbridge/intel/ich5r/ich5r_watchdog.c b/src/southbridge/intel/ich5r/ich5r_watchdog.c
new file mode 100644
index 0000000..c9c09f5
--- /dev/null
+++ b/src/southbridge/intel/ich5r/ich5r_watchdog.c
@@ -0,0 +1,28 @@
+#include <console/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+
+void watchdog_off(void)
+{
+        device_t dev;
+        unsigned long value,base;
+
+	/* turn off the ICH5 watchdog */
+        dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
+        /* Enable I/O space */
+        value = pci_read_config16(dev, 0x04);
+        value |= (1 << 10);
+        pci_write_config16(dev, 0x04, value);
+        /* Get TCO base */
+        base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
+        /* Disable the watchdog timer */
+        value = inw(base + 0x08);
+        value |= 1 << 11;
+        outw(value, base + 0x08);
+        /* Clear TCO timeout status */
+        outw(0x0008, base + 0x04);
+        outw(0x0002, base + 0x06);
+        printk_debug("Watchdog ICH5 disabled\r\n");
+}
+
diff --git a/src/southbridge/intel/pxhd/Config.lb b/src/southbridge/intel/pxhd/Config.lb
new file mode 100644
index 0000000..349b8dd
--- /dev/null
+++ b/src/southbridge/intel/pxhd/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+driver pxhd_bridge.o
diff --git a/src/southbridge/intel/pxhd/chip.h b/src/southbridge/intel/pxhd/chip.h
new file mode 100644
index 0000000..516f1df
--- /dev/null
+++ b/src/southbridge/intel/pxhd/chip.h
@@ -0,0 +1,5 @@
+struct southbridge_intel_pxhd_config
+{
+	/* nothing */
+};
+struct chip_operations southbridge_intel_pxhd_ops;
diff --git a/src/southbridge/intel/pxhd/pxhd.h b/src/southbridge/intel/pxhd/pxhd.h
new file mode 100644
index 0000000..c3e6ce5
--- /dev/null
+++ b/src/southbridge/intel/pxhd/pxhd.h
@@ -0,0 +1,6 @@
+#ifndef PXHD_H
+#define PXHD_H
+
+#include "chip.h"
+
+#endif /* PXHD_H */
diff --git a/src/southbridge/intel/pxhd/pxhd_bridge.c b/src/southbridge/intel/pxhd/pxhd_bridge.c
new file mode 100644
index 0000000..bceca29
--- /dev/null
+++ b/src/southbridge/intel/pxhd/pxhd_bridge.c
@@ -0,0 +1,258 @@
+/*
+ * (C) 2003-2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pcix.h>
+#include <pc80/mc146818rtc.h>
+#include <delay.h>
+#include "pxhd.h"
+
+static void pxhd_enable(device_t dev)
+{
+	device_t bridge;
+	uint16_t value;
+	if ((dev->path.u.pci.devfn & 1) == 0) {
+		/* Can we enable/disable the bridges? */
+	  	return;
+	}
+	bridge = dev_find_slot(dev->bus->secondary, dev->path.u.pci.devfn & ~1);
+	if (!bridge) {
+		printk_err("Cannot find bridge for ioapic: %s\n",
+			   dev_path(dev));
+		return;
+	}
+	value = pci_read_config16(bridge, 0x40);
+	value &= ~(1 << 13);
+	if (!dev->enabled) {
+		value |= (1 << 13);
+	}
+	pci_write_config16(bridge, 0x40, value);
+}
+
+
+#define NMI_OFF 0
+
+static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max)
+{
+	int bus_100Mhz = 0;
+
+	dev->link[0].dev = dev;
+	dev->links = 1;
+
+	get_option(&bus_100Mhz, "pxhd_bus_speed_100");
+	if(bus_100Mhz) {
+		uint16_t word;
+
+		printk_debug("setting pxhd bus to 100 Mhz\n");
+		/* set to pcix 100 mhz */
+		word = pci_read_config16(dev, 0x40);
+		word &= ~(3 << 14);
+		word |= (1 << 14);
+		word &= ~(3 << 9);
+		word |= (2 << 9);
+		pci_write_config16(dev, 0x40, word);
+		
+		/* reset the bus to make the new frequencies effective */
+		pci_bus_reset(&dev->link[0]);
+	}	
+	return pcix_scan_bridge(dev, max);
+}
+static void pcix_init(device_t dev)
+{
+	uint32_t dword;
+	uint16_t word;
+	uint8_t byte;
+	int nmi_option;
+
+	/* Bridge control ISA enable */
+	pci_write_config8(dev, 0x3e, 0x07);
+
+#if 0
+
+	/* Enable memory write and invalidate ??? */
+	byte = pci_read_config8(dev, 0x04);
+        byte |= 0x10;
+        pci_write_config8(dev, 0x04, byte);
+ 	
+	/* Set drive strength */
+	word = pci_read_config16(dev, 0xe0);
+        word = 0x0404;
+        pci_write_config16(dev, 0xe0, word);
+	word = pci_read_config16(dev, 0xe4);
+        word = 0x0404;
+        pci_write_config16(dev, 0xe4, word);
+	
+	/* Set impedance */
+	word = pci_read_config16(dev, 0xe8);
+        word = 0x0404;
+        pci_write_config16(dev, 0xe8, word);
+
+	/* Set discard unrequested prefetch data */
+	word = pci_read_config16(dev, 0x4c);
+        word |= 1;
+        pci_write_config16(dev, 0x4c, word);
+	
+	/* Set split transaction limits */
+	word = pci_read_config16(dev, 0xa8);
+        pci_write_config16(dev, 0xaa, word);
+	word = pci_read_config16(dev, 0xac);
+        pci_write_config16(dev, 0xae, word);
+
+	/* Set up error reporting, enable all */
+	/* system error enable */
+	dword = pci_read_config32(dev, 0x04);
+        dword |= (1<<8);
+        pci_write_config32(dev, 0x04, dword);
+ 	
+	/* system and error parity enable */
+	dword = pci_read_config32(dev, 0x3c);
+        dword |= (3<<16);
+        pci_write_config32(dev, 0x3c, dword);
+ 	
+	/* NMI enable */
+	nmi_option = NMI_OFF;
+	get_option(&nmi_option, "nmi");
+	if(nmi_option) {
+		dword = pci_read_config32(dev, 0x44);
+        	dword |= (1<<0);
+        	pci_write_config32(dev, 0x44, dword);
+	}
+ 	
+	/* Set up CRC flood enable */
+	dword = pci_read_config32(dev, 0xc0);
+	if(dword) {  /* do device A only */
+		dword = pci_read_config32(dev, 0xc4);
+		dword |= (1<<1);
+		pci_write_config32(dev, 0xc4, dword);
+		dword = pci_read_config32(dev, 0xc8);
+		dword |= (1<<1);
+		pci_write_config32(dev, 0xc8, dword);
+	}
+	
+	return;
+#endif
+}
+
+static struct device_operations pcix_ops  = {
+        .read_resources   = pci_bus_read_resources,
+        .set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_bus_enable_resources,
+        .init             = pcix_init,
+        .scan_bus         = pxhd_scan_bridge,
+	.reset_bus        = pci_bus_reset,
+	.ops_pci          = 0,
+};
+
+static struct pci_driver pcix_driver __pci_driver = {
+        .ops    = &pcix_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = 0x0329,
+};
+
+static struct pci_driver pcix_driver2 __pci_driver = {
+        .ops    = &pcix_ops,
+        .vendor = PCI_VENDOR_ID_INTEL,
+        .device = 0x032a,
+};
+
+#define ALL		(0xff << 24)
+#define NONE		(0)
+#define DISABLED	(1 << 16)
+#define ENABLED		(0 << 16)
+#define TRIGGER_EDGE	(0 << 15)
+#define TRIGGER_LEVEL	(1 << 15)
+#define POLARITY_HIGH	(0 << 13)
+#define POLARITY_LOW	(1 << 13)
+#define PHYSICAL_DEST	(0 << 11)
+#define LOGICAL_DEST	(1 << 11)
+#define ExtINT		(7 << 8)
+#define NMI		(4 << 8)
+#define SMI		(2 << 8)
+#define INT		(1 << 8)
+	/* IO-APIC virtual wire mode configuration */
+	/* mask, trigger, polarity, destination, delivery, vector */
+
+static void setup_ioapic(device_t dev)
+{
+	int i;
+	unsigned long value_low, value_high;
+	unsigned long ioapic_base;
+	volatile unsigned long *l;
+	unsigned interrupts;
+
+	ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+	l = (unsigned long *) ioapic_base;
+
+	/* Enable front side bus delivery */
+	l[0] = 0x03;
+	l[4] = 1;
+
+	l[0] = 0x01;
+	interrupts = (l[04] >> 16) & 0xff;
+	for (i = 0; i < interrupts; i++) {
+		l[0] = (i * 2) + 0x10;
+		l[4] = DISABLED;
+		value_low = l[4];
+		l[0] = (i * 2) + 0x11;
+		l[4] = NONE; /* Should this be an address? */
+		value_high = l[4];
+		if (value_low == 0xffffffff) {
+			printk_warning("IO APIC not responding.\n");
+			return;
+		}
+	}
+}
+
+static void ioapic_init(device_t dev)
+{
+	uint32_t value;
+	/* Enable bus mastering so IOAPICs work */
+	value = pci_read_config16(dev, PCI_COMMAND);
+	value |= PCI_COMMAND_MASTER;
+	pci_write_config16(dev, PCI_COMMAND, value);
+
+	setup_ioapic(dev);
+}
+
+static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
+		((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations intel_ops_pci = {
+	.set_subsystem = intel_set_subsystem,
+};
+
+static struct device_operations ioapic_ops = {
+	.read_resources   = pci_dev_read_resources,
+	.set_resources    = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init             = ioapic_init,
+	.scan_bus         = 0,
+	.enable           = pxhd_enable,
+	.ops_pci          = &intel_ops_pci,
+};
+
+static struct pci_driver ioapic_driver __pci_driver = {
+	.ops    = &ioapic_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x0326,
+	
+};
+
+static struct pci_driver ioapic2_driver __pci_driver = {
+	.ops    = &ioapic_ops,
+	.vendor = PCI_VENDOR_ID_INTEL,
+	.device = 0x0327,
+	
+};
+
+struct chip_operations southbridge_intel_pxhd_ops = {
+	CHIP_NAME("PXHD")
+	.enable_dev = pxhd_enable,
+};
diff --git a/src/superio/NSC/pc87427/Config.lb b/src/superio/NSC/pc87427/Config.lb
new file mode 100644
index 0000000..f62a567
--- /dev/null
+++ b/src/superio/NSC/pc87427/Config.lb
@@ -0,0 +1,2 @@
+config chip.h
+object superio.o
diff --git a/src/superio/NSC/pc87427/chip.h b/src/superio/NSC/pc87427/chip.h
new file mode 100644
index 0000000..ae46971
--- /dev/null
+++ b/src/superio/NSC/pc87427/chip.h
@@ -0,0 +1,16 @@
+#ifndef SIO_COM1
+#define SIO_COM1_BASE   0x3F8
+#endif
+#ifndef SIO_COM2
+#define SIO_COM2_BASE   0x2F8
+#endif
+
+extern struct chip_operations superio_NSC_pc87427_ops;
+
+#include <pc80/keyboard.h>
+#include <uart8250.h>
+
+struct superio_NSC_pc87427_config {
+	struct uart8250 com1, com2;
+	struct pc_keyboard keyboard;
+};
diff --git a/src/superio/NSC/pc87427/pc87427.h b/src/superio/NSC/pc87427/pc87427.h
new file mode 100644
index 0000000..d998bd6
--- /dev/null
+++ b/src/superio/NSC/pc87427/pc87427.h
@@ -0,0 +1,94 @@
+#define PC87427_FDC  0x00 /* Floppy */
+#define PC87427_SP2  0x02 /* Com2 */
+#define PC87427_SP1  0x03 /* Com1 */
+#define PC87427_SWC  0x04
+#define PC87427_KBCM 0x05 /* Mouse */
+#define PC87427_KBCK 0x06 /* Keyboard */
+#define PC87427_GPIO 0x07
+#define PC87427_FMC  0x09
+#define PC87427_WDT  0x0A
+#define PC87427_XBUS 0x0F
+#define PC87427_RTC  0x10
+#define PC87427_MHC  0x14
+
+#define PC87427_GPIO_DEV PNP_DEV(0x2e, PC87427_GPIO)
+/* This is to get around a romcc bug */
+//#define PC87427_XBUS_DEV PNP_DEV(0x2e, PC87427_XBUS)
+#define PC87427_XBUS_DEV PNP_DEV(0x2e, 0x0f)
+
+#define PC87427_GPSEL		0xf0
+#define PC87427_GPCFG1		0xf1
+#define PC87427_GPEVR		0xf2
+#define PC87427_GPCFG2		0xf3
+#define PC87427_EXTCFG		0xf4
+#define PC87427_IOEXT1A		0xf5
+#define PC87427_IOEXT1B		0xf6
+#define PC87427_IOEXT2A		0xf7
+#define PC87427_IOEXT2B		0xf8
+
+#define PC87427_GPDO_0		0x00
+#define PC87427_GPDI_0		0x01
+#define PC87427_GPDO_1		0x02
+#define PC87427_GPDI_1		0x03
+#define PC87427_GPEVEN_1	0x04
+#define PC87427_GPEVST_1	0x05
+#define PC87427_GPDO_2		0x06
+#define PC87427_GPDI_2		0x07
+#define PC87427_GPDO_3		0x08
+#define PC87427_GPDI_3		0x09
+#define PC87427_GPDO_4		0x0a
+#define PC87427_GPDI_4		0x0b
+#define PC87427_GPEVEN_4	0x0c
+#define PC87427_GPEVST_4	0x0d
+#define PC87427_GPDO_5		0x0e
+#define PC87427_GPDI_5		0x0f
+#define PC87427_GPDO_6		0x10
+#define PC87427_GPDO_7A		0x11
+#define PC87427_GPDO_7B		0x12
+#define PC87427_GPDO_7C		0x13
+#define PC87427_GPDO_7D		0x14
+#define PC87427_GPDI_7A		0x15
+#define PC87427_GPDI_7B		0x16
+#define PC87427_GPDI_7C		0x17
+#define PC87427_GPDI_7D		0x18
+
+#define PC87427_XIOCNF		0xf0
+#define PC87427_XIOBA1H		0xf1
+#define PC87427_XIOBA1L		0xf2
+#define PC87427_XIOSIZE1	0xf3
+#define PC87427_XIOBA2H		0xf4
+#define PC87427_XIOBA2L		0xf5
+#define PC87427_XIOSIZE2	0xf6
+#define PC87427_XMEMCNF1	0xf7
+#define PC87427_XMEMCNF2	0xf8
+#define PC87427_XMEMBAH		0xf9
+#define PC87427_XMEMBAL		0xfa
+#define PC87427_XMEMSIZE	0xfb
+#define PC87427_XIRQMAP1	0xfc
+#define PC87427_XIRQMAP2	0xfd
+#define PC87427_XBIMM		0xfe
+#define PC87427_XBBSL		0xff
+
+#define PC87427_XBCNF		0x00
+#define PC87427_XZCNF0		0x01
+#define PC87427_XZCNF1		0x02
+#define PC87427_XIRQC0		0x04
+#define PC87427_XIRQC1		0x05
+#define PC87427_XIRQC2		0x06
+#define PC87427_XIMA0		0x08
+#define PC87427_XIMA1		0x09
+#define PC87427_XIMA2		0x0a
+#define PC87427_XIMA3		0x0b
+#define PC87427_XIMD		0x0c
+#define PC87427_XZCNF2		0x0d
+#define PC87427_XZCNF3		0x0e
+#define PC87427_XZM0		0x0f
+#define PC87427_XZM1		0x10
+#define PC87427_XZM2		0x11
+#define PC87427_XZM3		0x12
+#define PC87427_HAP0		0x13
+#define PC87427_HAP1		0x14
+#define PC87427_XSCNF		0x15
+#define PC87427_XWBCNF		0x16
+
+
diff --git a/src/superio/NSC/pc87427/pc87427_early_init.c b/src/superio/NSC/pc87427/pc87427_early_init.c
new file mode 100644
index 0000000..71f702f
--- /dev/null
+++ b/src/superio/NSC/pc87427/pc87427_early_init.c
@@ -0,0 +1,31 @@
+#include <arch/romcc_io.h>
+#include "pc87427.h"
+
+static void pc87427_disable_dev(device_t dev)
+{
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 0);
+}
+static void pc87427_enable_dev(device_t dev, unsigned iobase)
+{
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 0);
+	pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+	pnp_set_enable(dev, 1);
+}
+static void xbus_cfg(device_t dev)
+{
+	uint8_t i, data;
+	uint16_t xbus_index;
+
+	pnp_set_logical_device(dev);
+	/* select proper BIOS size (4MB) */
+	pnp_write_config(dev, PC87427_XMEMCNF2, (pnp_read_config(dev, PC87427_XMEMCNF2)) | 0x04);
+	xbus_index = pnp_read_iobase(dev, 0x60);
+
+	/* enable writes to devices attached to XCS0 (XBUS Chip Select 0) */
+	for (i=0; i<= 0xf; i++) {
+		outb((i<<4), xbus_index + PC87427_HAP0);
+	}
+	return; 
+}	
diff --git a/src/superio/NSC/pc87427/superio.c b/src/superio/NSC/pc87427/superio.c
new file mode 100644
index 0000000..84c6ecb
--- /dev/null
+++ b/src/superio/NSC/pc87427/superio.c
@@ -0,0 +1,77 @@
+/* Copyright 2000  AG Electronics Ltd. */
+/* Copyright 2003-2004 Linux Networx */
+/* This code is distributed without warranty under the GPL v2 (see COPYING) */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#include <console/console.h>
+#include <string.h>
+#include <bitops.h>
+#include "chip.h"
+#include "pc87427.h"
+
+
+static void init(device_t dev)
+{
+	struct superio_NSC_pc87427_config *conf;
+	struct resource *res0, *res1;
+	/* Wishlist handle well known programming interfaces more
+	 * generically.
+	 */
+	if (!dev->enabled) {
+		return;
+	}
+	conf = dev->chip_info;
+	switch(dev->path.u.pnp.device) {
+	case PC87427_SP1: 
+		res0 = find_resource(dev, PNP_IDX_IO0);
+		init_uart8250(res0->base, &conf->com1);
+		break;
+	case PC87427_SP2:
+		res0 = find_resource(dev, PNP_IDX_IO0);
+		init_uart8250(res0->base, &conf->com2);
+		break;
+	case PC87427_KBCK:
+		res0 = find_resource(dev, PNP_IDX_IO0);
+		res1 = find_resource(dev, PNP_IDX_IO1);
+		init_pc_keyboard(res0->base, res1->base, &conf->keyboard);
+		break;
+	}
+}
+
+static struct device_operations ops = {
+	.read_resources   = pnp_read_resources,
+	.set_resources    = pnp_set_resources,
+	.enable_resources = pnp_enable_resources,
+	.enable           = pnp_enable,
+	.init             = init,
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { &ops,  PC87427_FDC,  PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, },
+ { &ops,  PC87427_SP2,  PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops,  PC87427_SP1,  PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops,  PC87427_SWC,  PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0, 
+   { 0xfff0, 0 }, { 0xfffc, 0 }, { 0xfffc, 0 }, { 0xfff8, 0 } },
+ { &ops,  PC87427_KBCM, PNP_IRQ0 },
+ { &ops,  PC87427_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, },
+ { &ops,  PC87427_GPIO, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
+ { &ops,  PC87427_WDT,  PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 } },
+ { &ops,  PC87427_FMC,  PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
+ { &ops,  PC87427_XBUS, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } },
+ { &ops,  PC87427_RTC,  PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0xfffe, 0 }, { 0xfffe, 0 } },
+ { &ops,  PC87427_MHC,  PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0xffe0, 0 }, { 0xffe0, 0 } },
+};
+
+
+static void enable_dev(struct device *dev)
+{
+	pnp_enable_devices(dev, &ops,
+		sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info); 
+}
+
+struct chip_operations superio_NSC_pc87427_ops = {
+	CHIP_NAME("NSC 87427")
+	.enable_dev = enable_dev,
+};
diff --git a/src/superio/smsc/lpc47b397/superio.c b/src/superio/smsc/lpc47b397/superio.c
index 5a45609..ab9da13 100644
--- a/src/superio/smsc/lpc47b397/superio.c
+++ b/src/superio/smsc/lpc47b397/superio.c
@@ -45,33 +45,6 @@
         value |= 0x01;
         pnp_write_config(dev, reg, value);
 } 
-#if 0
-static void dump_pnp_device(device_t dev)
-{
-        int i;
-        print_debug("\r\n");
-
-        for(i = 0; i <= 255; i++) {
-                uint8_t reg, val;
-                if ((i & 0x0f) == 0) {
-                        print_debug_hex8(i);
-                        print_debug_char(':');
-                }
-		reg = i;
-		if(i!=0xaa) {
-                	val = pnp_read_config(dev, reg);
-		}
-		else {
-			val = 0xaa;
-		}
-                print_debug_char(' ');
-                print_debug_hex8(val);
-                if ((i & 0x0f) == 0x0f) {
-                        print_debug("\r\n");
-                }
-        }
-}
-#endif
 
 
 static void lpc47b397_init(device_t dev)
diff --git a/src/superio/winbond/w83627hf/superio.c b/src/superio/winbond/w83627hf/superio.c
index 57d475b..559bdf1 100644
--- a/src/superio/winbond/w83627hf/superio.c
+++ b/src/superio/winbond/w83627hf/superio.c
@@ -12,6 +12,7 @@
 #include <bitops.h>
 #include <uart8250.h>
 #include <pc80/keyboard.h>
+#include <pc80/mc146818rtc.h>
 #include "chip.h"
 #include "w83627hf.h"
 
@@ -47,33 +48,22 @@
 	pnp_write_config(dev, reg, value);
 }
 
-#if 0
-static void dump_pnp_device(device_t dev)
+static void init_acpi(device_t dev)
 {
-        int i;
-        print_debug("\r\n");
+	uint8_t  value = 0x20;
+	int power_on = 1;
 
-        for(i = 0; i <= 255; i++) {
-                uint8_t reg, val;
-                if ((i & 0x0f) == 0) {
-                        print_debug_hex8(i);
-                        print_debug_char(':');
-                }
-		reg = i;
-		if(i!=0xaa) {
-                	val = pnp_read_config(dev, reg);
-		}
-		else {
-			val = 0xaa;
-		}
-                print_debug_char(' ');
-                print_debug_hex8(val);
-                if ((i & 0x0f) == 0x0f) {
-                        print_debug("\r\n");
-                }
-        }
+	get_option(&power_on, "power_on_after_fail");
+	pnp_enter_ext_func_mode(dev);
+	pnp_write_index(dev->path.u.pnp.port,7,0x0a); 
+	value = pnp_read_config(dev, 0xE4);
+	value &= ~(3<<5);
+	if(power_on) {
+		value |= (1<<5);
+	}
+	pnp_write_config(dev, 0xE4, value);
+        pnp_exit_ext_func_mode(dev);  
 }
-#endif
 
 static void init_hwm(unsigned long base)
 {
@@ -105,7 +95,6 @@
 	}
 }
 
-
 static void w83627hf_init(device_t dev)
 {
 	struct superio_winbond_w83627hf_config *conf;
@@ -133,21 +122,16 @@
 #define HWM_INDEX_PORT 5
                 init_hwm(res0->base + HWM_INDEX_PORT);
                 break;
+        case W83627HF_ACPI:
+                init_acpi(dev);
+                break;
 	}
-	
 }
 
 void w83627hf_pnp_set_resources(device_t dev)
 {
-
 	pnp_enter_ext_func_mode(dev);  
-
 	pnp_set_resources(dev);
-
-#if 0
-        dump_pnp_device(dev);
-#endif
-                
         pnp_exit_ext_func_mode(dev);  
         
 }       
@@ -155,20 +139,13 @@
 void w83627hf_pnp_enable_resources(device_t dev)
 {       
         pnp_enter_ext_func_mode(dev);  
-	
 	pnp_enable_resources(dev);               
-
         switch(dev->path.u.pnp.device) {
 	case W83627HF_HWM:
 		printk_debug("w83627hf hwm smbus enabled\n");
 		enable_hwm_smbus(dev);
 		break;
 	}
-
-#if 0  
-        dump_pnp_device(dev);
-#endif
-
         pnp_exit_ext_func_mode(dev);  
 
 }
@@ -219,4 +196,3 @@
 	CHIP_NAME("Winbond w83627hf")
 	.enable_dev = enable_dev,
 };
-
diff --git a/src/superio/winbond/w83627hf/w83627hf.h b/src/superio/winbond/w83627hf/w83627hf.h
index 0cf1631..7cd664c 100644
--- a/src/superio/winbond/w83627hf/w83627hf.h
+++ b/src/superio/winbond/w83627hf/w83627hf.h
@@ -9,3 +9,83 @@
 #define W83627HF_GPIO3            9
 #define W83627HF_ACPI            10
 #define W83627HF_HWM             11   /* Hardware Monitor */
+
+//#define W83627HF_GPIO_DEV PNP_DEV(0x2e, W83627HF_GPIO)
+//#define W83627HF_XBUS_DEV PNP_DEV(0x2e, W83627HF_XBUS)
+
+#define W83627HF_GPSEL		0xf0
+#define W83627HF_GPCFG1		0xf1
+#define W83627HF_GPEVR		0xf2
+#define W83627HF_GPCFG2		0xf3
+#define W83627HF_EXTCFG		0xf4
+#define W83627HF_IOEXT1A		0xf5
+#define W83627HF_IOEXT1B		0xf6
+#define W83627HF_IOEXT2A		0xf7
+#define W83627HF_IOEXT2B		0xf8
+
+#define W83627HF_GPDO_0		0x00
+#define W83627HF_GPDI_0		0x01
+#define W83627HF_GPDO_1		0x02
+#define W83627HF_GPDI_1		0x03
+#define W83627HF_GPEVEN_1	0x04
+#define W83627HF_GPEVST_1	0x05
+#define W83627HF_GPDO_2		0x06
+#define W83627HF_GPDI_2		0x07
+#define W83627HF_GPDO_3		0x08
+#define W83627HF_GPDI_3		0x09
+#define W83627HF_GPDO_4		0x0a
+#define W83627HF_GPDI_4		0x0b
+#define W83627HF_GPEVEN_4	0x0c
+#define W83627HF_GPEVST_4	0x0d
+#define W83627HF_GPDO_5		0x0e
+#define W83627HF_GPDI_5		0x0f
+#define W83627HF_GPDO_6		0x10
+#define W83627HF_GPDO_7A		0x11
+#define W83627HF_GPDO_7B		0x12
+#define W83627HF_GPDO_7C		0x13
+#define W83627HF_GPDO_7D		0x14
+#define W83627HF_GPDI_7A		0x15
+#define W83627HF_GPDI_7B		0x16
+#define W83627HF_GPDI_7C		0x17
+#define W83627HF_GPDI_7D		0x18
+
+#define W83627HF_XIOCNF		0xf0
+#define W83627HF_XIOBA1H		0xf1
+#define W83627HF_XIOBA1L		0xf2
+#define W83627HF_XIOSIZE1	0xf3
+#define W83627HF_XIOBA2H		0xf4
+#define W83627HF_XIOBA2L		0xf5
+#define W83627HF_XIOSIZE2	0xf6
+#define W83627HF_XMEMCNF1	0xf7
+#define W83627HF_XMEMCNF2	0xf8
+#define W83627HF_XMEMBAH		0xf9
+#define W83627HF_XMEMBAL		0xfa
+#define W83627HF_XMEMSIZE	0xfb
+#define W83627HF_XIRQMAP1	0xfc
+#define W83627HF_XIRQMAP2	0xfd
+#define W83627HF_XBIMM		0xfe
+#define W83627HF_XBBSL		0xff
+
+#define W83627HF_XBCNF		0x00
+#define W83627HF_XZCNF0		0x01
+#define W83627HF_XZCNF1		0x02
+#define W83627HF_XIRQC0		0x04
+#define W83627HF_XIRQC1		0x05
+#define W83627HF_XIRQC2		0x06
+#define W83627HF_XIMA0		0x08
+#define W83627HF_XIMA1		0x09
+#define W83627HF_XIMA2		0x0a
+#define W83627HF_XIMA3		0x0b
+#define W83627HF_XIMD		0x0c
+#define W83627HF_XZCNF2		0x0d
+#define W83627HF_XZCNF3		0x0e
+#define W83627HF_XZM0		0x0f
+#define W83627HF_XZM1		0x10
+#define W83627HF_XZM2		0x11
+#define W83627HF_XZM3		0x12
+#define W83627HF_HAP0		0x13
+#define W83627HF_HAP1		0x14
+#define W83627HF_XSCNF		0x15
+#define W83627HF_XWBCNF		0x16
+
+
diff --git a/src/superio/winbond/w83627hf/w83627hf_early_init.c b/src/superio/winbond/w83627hf/w83627hf_early_init.c
new file mode 100644
index 0000000..e449c4a
--- /dev/null
+++ b/src/superio/winbond/w83627hf/w83627hf_early_init.c
@@ -0,0 +1,15 @@
+#include <arch/romcc_io.h>
+#include "w83627hf.h"
+
+static void w83627hf_disable_dev(device_t dev)
+{
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 0);
+}
+static void w83627hf_enable_dev(device_t dev, unsigned iobase)
+{
+	pnp_set_logical_device(dev);
+	pnp_set_enable(dev, 0);
+	pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+	pnp_set_enable(dev, 1);
+}
diff --git a/targets/tyan/s2850/Config.lb b/targets/tyan/s2850/Config.lb
index 3b52fcc..a2258c8 100644
--- a/targets/tyan/s2850/Config.lb
+++ b/targets/tyan/s2850/Config.lb
@@ -15,9 +15,9 @@
 #        option ROM_SIZE = 458752 
 	option USE_FALLBACK_IMAGE=0
 #	option ROM_IMAGE_SIZE=0x11800
-#	option ROM_IMAGE_SIZE=0x16000
+	option ROM_IMAGE_SIZE=0x16000
 #	option ROM_IMAGE_SIZE=0x17800
-	option ROM_IMAGE_SIZE=0x13c00
+#	option ROM_IMAGE_SIZE=0x13c00
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -26,8 +26,8 @@
 #       payload ../../../payloads/filo.zelf
 #	payload ../../../payloads/tg3.zelf
 #	payload ../../../payloads/tg3_vga.zelf
-#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
-	payload ../../../payloads/tg3--filo_u_hda2_vga.zelf
+	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3--filo_u_hda2_vga.zelf
 #        payload ../../../payloads/tg3--filo_hda2_com2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
@@ -37,9 +37,9 @@
 romimage "fallback" 
 	option USE_FALLBACK_IMAGE=1
 #	option ROM_IMAGE_SIZE=0x11800
-#	option ROM_IMAGE_SIZE=0x16000
+	option ROM_IMAGE_SIZE=0x16000
 #	option ROM_IMAGE_SIZE=0x17800
-	option ROM_IMAGE_SIZE=0x13c00
+#	option ROM_IMAGE_SIZE=0x13c00
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -48,8 +48,8 @@
 #       payload ../../../payloads/filo.zelf
 #	payload ../../../payloads/tg3.zelf
 #	payload ../../../payloads/tg3_vga.zelf
-#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
-	payload ../../../payloads/tg3--filo_u_hda2_vga.zelf
+	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3--filo_u_hda2_vga.zelf
 #        payload ../../../payloads/tg3--filo_hda2_com2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
diff --git a/targets/tyan/s2880/Config.lb b/targets/tyan/s2880/Config.lb
index 6dbde57..72b7152 100644
--- a/targets/tyan/s2880/Config.lb
+++ b/targets/tyan/s2880/Config.lb
@@ -8,9 +8,9 @@
 # Tyan s2880
 romimage "normal"
 #       48K for SCSI FW or ATI ROM
-        option ROM_SIZE = 475136
+#        option ROM_SIZE = 475136
 #       48K for SCSI FW and 48K for ATI ROM
-#       option ROM_SIZE = 425984 
+       option ROM_SIZE = 425984 
 #       64K for Etherboot
 #        option ROM_SIZE = 458752 
 	option USE_FALLBACK_IMAGE=0
diff --git a/targets/tyan/s2881/Config.lb b/targets/tyan/s2881/Config.lb
index 1caa8e5..332fc24 100644
--- a/targets/tyan/s2881/Config.lb
+++ b/targets/tyan/s2881/Config.lb
@@ -16,7 +16,7 @@
 	option USE_FALLBACK_IMAGE=0
 #        option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13000
-	option ROM_IMAGE_SIZE=0x16200
+	option ROM_IMAGE_SIZE=0x16000
         option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -24,7 +24,8 @@
 #        payload ../../../payloads/filo_mem.elf
 #       payload ../../../payloads/filo.zelf
 #        payload ../../../payloads/tg3--filo.zelf
-	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+	 payload ../../../payloads/tg3--filo_hda1_vga_md1.zelf
 #	payload ../../../payloads/tg3--filo_btext_hda2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
@@ -35,7 +36,7 @@
 	option USE_FALLBACK_IMAGE=1
 #        option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13000
-	option ROM_IMAGE_SIZE=0x16200
+	option ROM_IMAGE_SIZE=0x16000
         option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -43,7 +44,8 @@
 #        payload ../../../payloads/filo_mem.elf
 #       payload ../../../payloads/filo.zelf
 #        payload ../../../payloads/tg3--filo.zelf
-	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+	payload ../../../payloads/tg3--filo_hda1_vga_md1.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #	payload ../../../payloads/tg3--filo_btext_hda2.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
diff --git a/targets/tyan/s2882/Config.lb b/targets/tyan/s2882/Config.lb
index 7118d47..2913109 100644
--- a/targets/tyan/s2882/Config.lb
+++ b/targets/tyan/s2882/Config.lb
@@ -15,7 +15,7 @@
 #        option ROM_SIZE = 458752 
 	option USE_FALLBACK_IMAGE=0
 #        option ROM_IMAGE_SIZE=0x11800
-	option ROM_IMAGE_SIZE=0x16300
+	option ROM_IMAGE_SIZE=0x16000
         option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -32,7 +32,7 @@
 romimage "fallback" 
 	option USE_FALLBACK_IMAGE=1
 #        option ROM_IMAGE_SIZE=0x11800
-	option ROM_IMAGE_SIZE=0x16300
+	option ROM_IMAGE_SIZE=0x16000
         option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
 #       payload ../../../payloads/tg3--ide_disk.zelf
diff --git a/targets/tyan/s2885/Config.lb b/targets/tyan/s2885/Config.lb
index 98e0082..1ec013b 100644
--- a/targets/tyan/s2885/Config.lb
+++ b/targets/tyan/s2885/Config.lb
@@ -15,8 +15,8 @@
 #        option ROM_SIZE = 458752 
 	option USE_FALLBACK_IMAGE=0
 #	option ROM_IMAGE_SIZE=0x13800
-	option ROM_IMAGE_SIZE=0x17800
-#	option ROM_IMAGE_SIZE=0x16000
+#	option ROM_IMAGE_SIZE=0x17800
+	option ROM_IMAGE_SIZE=0x16200
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -25,8 +25,8 @@
 #        payload ../../../payloads/filo.zelf
 #        payload ../../../payloads/tg3--filo_hda2.zelf
 #	payload ../../../payloads/tg3.zelf
-	payload ../../../payloads/tg3_vga.zelf
-#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3_vga.zelf
+	payload ../../../payloads/tg3--filo_hda2_vga.zelf
 #	payload ../../../payloads/tg3_com2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
@@ -38,8 +38,8 @@
 romimage "fallback" 
 	option USE_FALLBACK_IMAGE=1
 #	option ROM_IMAGE_SIZE=0x13800
-	option ROM_IMAGE_SIZE=0x17800
-#	option ROM_IMAGE_SIZE=0x16000
+#	option ROM_IMAGE_SIZE=0x17800
+	option ROM_IMAGE_SIZE=0x16200
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -48,8 +48,8 @@
 #        payload ../../../payloads/filo.zelf
 #        payload ../../../payloads/tg3--filo_hda2.zelf
 #	payload ../../../payloads/tg3.zelf
-	payload ../../../payloads/tg3_vga.zelf
-#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3_vga.zelf
+	payload ../../../payloads/tg3--filo_hda2_vga.zelf
 #	payload ../../../payloads/tg3_com2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
diff --git a/targets/tyan/s2891/Config.lb b/targets/tyan/s2891/Config.lb
index 24f9046..2b80499 100644
--- a/targets/tyan/s2891/Config.lb
+++ b/targets/tyan/s2891/Config.lb
@@ -7,6 +7,8 @@
 
 # Tyan s2891
 romimage "normal"
+#       48K for ATI ROM in 1M
+#	option ROM_SIZE = 999424
 #       48K for SCSI FW or ATI ROM
         option ROM_SIZE = 475136
 #       48K for SCSI FW and 48K for ATI ROM
@@ -16,7 +18,7 @@
 	option USE_FALLBACK_IMAGE=0
 #        option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13000
-	option ROM_IMAGE_SIZE=0x15800
+	option ROM_IMAGE_SIZE=0x16000
         option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -37,7 +39,7 @@
 	option USE_FALLBACK_IMAGE=1
 #        option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13000
-	option ROM_IMAGE_SIZE=0x15800
+	option ROM_IMAGE_SIZE=0x16000
         option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
 #       payload ../../../payloads/tg3--ide_disk.zelf
diff --git a/targets/tyan/s2892/Config.lb b/targets/tyan/s2892/Config.lb
index dd5a70b..20d6c87 100644
--- a/targets/tyan/s2892/Config.lb
+++ b/targets/tyan/s2892/Config.lb
@@ -16,7 +16,7 @@
 	option USE_FALLBACK_IMAGE=0
 #	option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13800
-	option ROM_IMAGE_SIZE=0x16000
+	option ROM_IMAGE_SIZE=0x16380
 #	option ROM_IMAGE_SIZE=0x17800
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
@@ -37,7 +37,7 @@
 	option USE_FALLBACK_IMAGE=1
 #	option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13800
-	option ROM_IMAGE_SIZE=0x16000
+	option ROM_IMAGE_SIZE=0x16380
 #	option ROM_IMAGE_SIZE=0x17800
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
diff --git a/targets/tyan/s2895/Config.lb b/targets/tyan/s2895/Config.lb
index 58a0d150..53b17f3 100644
--- a/targets/tyan/s2895/Config.lb
+++ b/targets/tyan/s2895/Config.lb
@@ -18,7 +18,7 @@
 	option USE_FALLBACK_IMAGE=0
 #	option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13800
-	option ROM_IMAGE_SIZE=0x16000
+	option ROM_IMAGE_SIZE=0x15000
 #	option ROM_IMAGE_SIZE=0x17800
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
@@ -27,7 +27,13 @@
 #        payload ../../../payloads/filo_mem.elf
 #       payload ../../../payloads/filo.zelf
 #	payload ../../../payloads/tg3.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
 	payload ../../../payloads/forcedeth--filo_hda2_vga.zelf
+#	payload ../../../payloads/forcedeth_vga.zelf
+#	payload ../../../payloads/forcedeth--filo_hda2_vga_5_4.zelf
+#	payload ../../../../../../elf/ram0_2.5_2.6.11.tiny.elf
+#	payload ../../../../../../elf/ram0_2.5_2.6.12.tiny.elf
+#	payload ../../../payloads/tg3--filo_hda2_vga_5_4.zelf
 #	 payload ../../../payloads/tg3_vga.zelf
 #	payload ../../../payloads/tg3--filo_hda2_vgax.zelf
 #        payload ../../../payloads/tg3--filo_hda2_com2.zelf
@@ -40,7 +46,7 @@
 	option USE_FALLBACK_IMAGE=1
 #	option ROM_IMAGE_SIZE=0x11800
 #	option ROM_IMAGE_SIZE=0x13800
-	option ROM_IMAGE_SIZE=0x16000
+	option ROM_IMAGE_SIZE=0x15000
 #	option ROM_IMAGE_SIZE=0x17800
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
@@ -49,7 +55,10 @@
 #        payload ../../../payloads/filo_mem.elf
 #       payload ../../../payloads/filo.zelf
 #	payload ../../../payloads/tg3.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
 	payload ../../../payloads/forcedeth--filo_hda2_vga.zelf
+#	payload ../../../payloads/forcedeth_vga.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga_5_4.zelf
 #	payload ../../../payloads/tg3_vga.zelf
 #	payload ../../../payloads/tg3--filo_hda2_vgax.zelf
 #        payload ../../../payloads/tg3--filo_hda2_com2.zelf
diff --git a/targets/tyan/s4880/Config.lb b/targets/tyan/s4880/Config.lb
index 84a7f21..c61bb9f 100644
--- a/targets/tyan/s4880/Config.lb
+++ b/targets/tyan/s4880/Config.lb
@@ -8,9 +8,9 @@
 # Tyan s4880
 romimage "normal"
 #       48K for SCSI FW or ATI ROM
-        option ROM_SIZE = 475136
+#        option ROM_SIZE = 475136
 #       48K for SCSI FW and 48K for ATI ROM
-#       option ROM_SIZE = 425984 
+       option ROM_SIZE = 425984 
 #       64K for Etherboot
 #        option ROM_SIZE = 458752 
 	option USE_FALLBACK_IMAGE=0
diff --git a/targets/tyan/s4882/Config.lb b/targets/tyan/s4882/Config.lb
index 0e4f336..e8a1553 100644
--- a/targets/tyan/s4882/Config.lb
+++ b/targets/tyan/s4882/Config.lb
@@ -15,9 +15,9 @@
 #        option ROM_SIZE = 458752 
 	option USE_FALLBACK_IMAGE=0
 #	option ROM_IMAGE_SIZE=0x19000
-#	option ROM_IMAGE_SIZE=0x19c00
+	option ROM_IMAGE_SIZE=0x19c00
 #	option ROM_IMAGE_SIZE=0x18800
-	option ROM_IMAGE_SIZE=0x16200
+#	option ROM_IMAGE_SIZE=0x16200
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -25,9 +25,9 @@
 #        payload ../../../payloads/filo_mem.elf
 #       payload ../../../payloads/filo.zelf
 #	payload ../../../payloads/tg3.zelf
-#	payload ../../../payloads/tg3_vga.zelf
+	payload ../../../payloads/tg3_vga.zelf
 #	payload ../../../payloads/filo_vga_memtest.zelf
-	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
 #        payload ../../../payloads/tg3--filo_hda2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
@@ -37,9 +37,9 @@
 romimage "fallback" 
 	option USE_FALLBACK_IMAGE=1
 #	option ROM_IMAGE_SIZE=0x19000
-#	option ROM_IMAGE_SIZE=0x19c00
+	option ROM_IMAGE_SIZE=0x19c00
 #	option ROM_IMAGE_SIZE=0x18800
-	option ROM_IMAGE_SIZE=0x16200
+#	option ROM_IMAGE_SIZE=0x16200
 	option XIP_ROM_SIZE=0x20000
 	option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback"
 #       payload ../../../payloads/tg3--ide_disk.zelf
@@ -47,9 +47,9 @@
 #        payload ../../../payloads/filo_mem.elf
 #       payload ../../../payloads/filo.zelf
 #	payload ../../../payloads/tg3.zelf
-#	payload ../../../payloads/tg3_vga.zelf
+	payload ../../../payloads/tg3_vga.zelf
 #	payload ../../../payloads/filo_vga_kernel.zelf
-	payload ../../../payloads/tg3--filo_hda2_vga.zelf
+#	payload ../../../payloads/tg3--filo_hda2_vga.zelf
 #        payload ../../../payloads/tg3--filo_hda2.zelf
 #       payload ../../../payloads/e1000--filo.zelf
 #        payload ../../../payloads/tg3--e1000--filo.zelf
diff --git a/util/romcc/Makefile b/util/romcc/Makefile
index c06777d..1734fe5 100644
--- a/util/romcc/Makefile
+++ b/util/romcc/Makefile
@@ -1,5 +1,3 @@
-
-
 # Move the configuration defines to makefile.conf
 CC=gcc
 CPPFLAGS=
@@ -110,6 +108,10 @@
 	simple_test84.c \
 	simple_test85.c \
 	simple_test86.c \
+	simple_test87.c \
+	simple_test88.c \
+	simple_test89.c \
+	simple_test90.c \
 	raminit_test1.c \
 	raminit_test2.c \
 	raminit_test3.c \
diff --git a/util/romcc/tests.sh b/util/romcc/tests.sh
index 0dba165..4dddbb1 100644
--- a/util/romcc/tests.sh
+++ b/util/romcc/tests.sh
@@ -21,13 +21,15 @@
 base=tests/$stem
 op="-Itests/include"
 op="$op -feliminate-inefectual-code -fsimplify -fscc-transform "
-#op="$op -O2"
+#op="$op -O2 " 
+#op="$op -mmmx -msse"
 op="$op -finline-policy=defaulton"
 #op="$op -finline-policy=nopenalty"
 #op="$op -finline-policy=never"
 op="$op -fdebug -fdebug-triples -fdebug-interference  -fdebug-verification"
-#op="$op -fdebug-inline"
-#op="$op -fdebug-calls"
+op="$op -fdebug-fdominators"
+op="$op -fdebug-inline"
+op="$op -fdebug-calls"
 #op="$op -mnoop-copy"
 #op="$op -fsimplify -fno-simplify-op -fno-simplify-phi -fno-simplify-label -fno-simplify-branch -fno-simplify-copy -fno-simplify-arith -fno-simplify-shift -fno-simplify-bitwise -fno-simplify-logical"
 #op="$op -fdebug-rebuild-ssa-form"