Unified setup...

Stefan Reinauer stepan at suse.de
Thu Aug 28 09:09:00 CEST 2003


Hi LYH, Ron and others,

I've been looking at the recent changes that went into the tree, and I
don't like the fact that a lot of code is duplicated. Is there some way
to unify this?

--- raminit.c   2003-08-28 14:43:39.000000000 +0200
+++ raminit.1.c 2003-08-28 06:42:50.000000000 +0200
[..]
-       PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00,
+       PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff20,

This changes the link id where the southbridge is connected.
We can get this information out of the configuration file since we
are able to describe a map of all CHT components.
On most machines the southbridge is probably connected to LDT0, but
having two files for this one setting seems inappropriate.
Ron, what is the easiest way of getting this information from the
config file?

LYH: To get this unified again, I added a resourcemap.c file to the
s2885 directory that contains the resource map of the 2885. In auto.c
this is used instead of the default.

-       PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff000,
+       PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff020,

same as above.

-       PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000003,
-       PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000,
+       PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x03000203,
+       PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x05040003,

These change the bus numbers and read/write enables. How can we write
these more general?

+/*
 //BY LYH  add IOMMU 64M APERTURE
        PCI_ADDR(0, 0x18, 3, 0x94), 0xffff8000, 0x00000f70,
        PCI_ADDR(0, 0x18, 3, 0x90), 0xffffff80, 0x00000002,
        PCI_ADDR(0, 0x18, 3, 0x98), 0x0000000f, 0x00068300,
 
 //BY LYH END
+*/

I added a configuration variable ENABLE_IOMMU and set it to 1 for all
existing boards except the s2885. It would be nice to have the size of
the aperture also selectable via the configuration file, or even better 
during firmware run time. 

I am scared that changes for special motherboards will contaminate the
source tree and make it hard for anyone to see what is actually going
on. If this happens in a source tree for a special motherboard, it does
not really matter, but I think it is a good goal to keep the generic
code clean and generic and make it even more generic in the places where
it's not sufficient.

I'll look into coherent_ht.1.c and see if this can be done more general
as well.

I commited the attached patch. Please comment.

Stefan

-- 
Architecture Team
    SuSE Linux AG
-------------- next part --------------
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/config/Options.lb freebios2/src/config/Options.lb
--- mylinuxbios/LinuxBIOS/freebios2/src/config/Options.lb	2003-08-14 11:09:07.000000000 +0200
+++ freebios2/src/config/Options.lb	2003-08-28 15:14:23.000000000 +0200
@@ -590,6 +590,11 @@
 	export used
 	comment "Disable watchdog if we're doing lots of output"
 end
+define ENABLE_IOMMU
+	default 1
+	export used
+	comment "Enable IOMMU aperture"
+end
 
 ###############################################
 # Misc device options
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/amd/quartet/Config.lb freebios2/src/mainboard/amd/quartet/Config.lb
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/amd/quartet/Config.lb	2003-08-14 11:09:11.000000000 +0200
+++ freebios2/src/mainboard/amd/quartet/Config.lb	2003-08-28 15:19:27.000000000 +0200
@@ -2,7 +2,7 @@
 uses HAVE_PIRQ_TABLE
 uses USE_FALLBACK_IMAGE
 uses USE_NORMAL_IMAGE
-uses AMD8111_DEV
+uses ENABLE_IOMMU
 #
 #
 ###
@@ -141,3 +141,5 @@
 cpu p6 end
 cpu k7 end
 cpu k8 end
+
+option ENABLE_IOMMU=1
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/arima/hdama/Config.lb freebios2/src/mainboard/arima/hdama/Config.lb
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/arima/hdama/Config.lb	2003-08-14 11:09:12.000000000 +0200
+++ freebios2/src/mainboard/arima/hdama/Config.lb	2003-08-28 15:19:55.000000000 +0200
@@ -5,6 +5,7 @@
 uses AMD8111_DEV
 uses MAINBOARD
 uses ARCH
+uses ENABLE_IOMMU
 #
 #
 ###
@@ -163,3 +164,5 @@
 
 cpu k8 "cpu1" 
 end
+
+option ENABLE_IOMMU=1
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2880/Config.lb freebios2/src/mainboard/tyan/s2880/Config.lb
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2880/Config.lb	2003-08-28 15:25:23.000000000 +0200
+++ freebios2/src/mainboard/tyan/s2880/Config.lb	2003-08-28 15:18:28.000000000 +0200
@@ -5,6 +5,7 @@
 uses AMD8111_DEV
 uses MAINBOARD
 uses ARCH
+uses ENABLE_IOMMU
 #
 #
 ###
@@ -174,3 +175,5 @@
 
 cpu k8 "cpu1"
 end
+
+option ENABLE_IOMMU=1
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2882/Config.lb freebios2/src/mainboard/tyan/s2882/Config.lb
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2882/Config.lb	2003-08-27 16:33:13.000000000 +0200
+++ freebios2/src/mainboard/tyan/s2882/Config.lb	2003-08-28 15:18:00.000000000 +0200
@@ -5,6 +5,7 @@
 uses AMD8111_DEV
 uses MAINBOARD
 uses ARCH
+uses ENABLE_IOMMU
 #
 #
 ###
@@ -173,3 +174,5 @@
 
 cpu k8 "cpu1"
 end
+
+option ENABLE_IOMMU=1
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2885/auto.c freebios2/src/mainboard/tyan/s2885/auto.c
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2885/auto.c	2003-08-27 16:33:13.000000000 +0200
+++ freebios2/src/mainboard/tyan/s2885/auto.c	2003-08-28 15:21:38.000000000 +0200
@@ -84,10 +84,12 @@
 #include "northbridge/amd/amdk8/cpu_ldtstop.c"
 #include "southbridge/amd/amd8111/amd8111_ldtstop.c"
 
-#include "northbridge/amd/amdk8/raminit.1.c"
+#include "northbridge/amd/amdk8/raminit.c"
 #include "northbridge/amd/amdk8/coherent_ht.1.c"
 #include "sdram/generic_sdram.c"
 
+#include "resourcemap.c" /* tyan does not want the default */
+
 static void enable_lapic(void)
 {
 	msr_t msr;
@@ -164,7 +166,7 @@
 	}
 	uart_init();
 	console_init();
-	setup_default_resource_map();
+	setup_s2885_resource_map();
 	setup_coherent_ht_domain();
         enumerate_ht_chain(0);
 	//setup_resource_map_x();
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2885/Config.lb freebios2/src/mainboard/tyan/s2885/Config.lb
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2885/Config.lb	2003-08-27 16:33:13.000000000 +0200
+++ freebios2/src/mainboard/tyan/s2885/Config.lb	2003-08-28 15:15:35.000000000 +0200
@@ -5,6 +5,7 @@
 uses AMD8111_DEV
 uses MAINBOARD
 uses ARCH
+uses ENABLE_IOMMU
 #
 #
 ###
@@ -176,3 +177,6 @@
 
 cpu k8 "cpu1"
 end
+
+option ENABLE_IOMMU=0
+
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2885/resourcemap.c freebios2/src/mainboard/tyan/s2885/resourcemap.c
--- mylinuxbios/LinuxBIOS/freebios2/src/mainboard/tyan/s2885/resourcemap.c	1970-01-01 01:00:00.000000000 +0100
+++ freebios2/src/mainboard/tyan/s2885/resourcemap.c	2003-08-28 15:11:53.000000000 +0200
@@ -0,0 +1,264 @@
+/*
+ * Tyan S2885 needs a different resource map
+ *
+ */
+
+static void setup_s2885_resource_map(void)
+{
+	static const unsigned int register_values[] = {
+	/* Careful set limit registers before base registers which contain the enables */
+	/* DRAM Limit i Registers
+	 * F1:0x44 i = 0
+	 * F1:0x4C i = 1
+	 * F1:0x54 i = 2
+	 * F1:0x5C i = 3
+	 * F1:0x64 i = 4
+	 * F1:0x6C i = 5
+	 * F1:0x74 i = 6
+	 * F1:0x7C i = 7
+	 * [ 2: 0] Destination Node ID
+	 *	   000 = Node 0
+	 *	   001 = Node 1
+	 *	   010 = Node 2
+	 *	   011 = Node 3
+	 *	   100 = Node 4
+	 *	   101 = Node 5
+	 *	   110 = Node 6
+	 *	   111 = Node 7
+	 * [ 7: 3] Reserved
+	 * [10: 8] Interleave select
+	 *	   specifies the values of A[14:12] to use with interleave enable.
+	 * [15:11] Reserved
+	 * [31:16] DRAM Limit Address i Bits 39-24
+	 *	   This field defines the upper address bits of a 40 bit  address
+	 *	   that define the end of the DRAM region.
+	 */
+	PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
+	PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
+	PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
+	PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
+	PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
+	PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
+	PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
+	/* DRAM Base i Registers
+	 * F1:0x40 i = 0
+	 * F1:0x48 i = 1
+	 * F1:0x50 i = 2
+	 * F1:0x58 i = 3
+	 * F1:0x60 i = 4
+	 * F1:0x68 i = 5
+	 * F1:0x70 i = 6
+	 * F1:0x78 i = 7
+	 * [ 0: 0] Read Enable
+	 *	   0 = Reads Disabled
+	 *	   1 = Reads Enabled
+	 * [ 1: 1] Write Enable
+	 *	   0 = Writes Disabled
+	 *	   1 = Writes Enabled
+	 * [ 7: 2] Reserved
+	 * [10: 8] Interleave Enable
+	 *	   000 = No interleave
+	 *	   001 = Interleave on A[12] (2 nodes)
+	 *	   010 = reserved
+	 *	   011 = Interleave on A[12] and A[14] (4 nodes)
+	 *	   100 = reserved
+	 *	   101 = reserved
+	 *	   110 = reserved
+	 *	   111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
+	 * [15:11] Reserved
+	 * [13:16] DRAM Base Address i Bits 39-24
+	 *	   This field defines the upper address bits of a 40-bit address
+	 *	   that define the start of the DRAM region.
+	 */
+	PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
+
+	/* Memory-Mapped I/O Limit i Registers
+	 * F1:0x84 i = 0
+	 * F1:0x8C i = 1
+	 * F1:0x94 i = 2
+	 * F1:0x9C i = 3
+	 * F1:0xA4 i = 4
+	 * F1:0xAC i = 5
+	 * F1:0xB4 i = 6
+	 * F1:0xBC i = 7
+	 * [ 2: 0] Destination Node ID
+	 *	   000 = Node 0
+	 *	   001 = Node 1
+	 *	   010 = Node 2
+	 *	   011 = Node 3
+	 *	   100 = Node 4
+	 *	   101 = Node 5
+	 *	   110 = Node 6
+	 *	   111 = Node 7
+	 * [ 3: 3] Reserved
+	 * [ 5: 4] Destination Link ID
+	 *	   00 = Link 0
+	 *	   01 = Link 1
+	 *	   10 = Link 2
+	 *	   11 = Reserved
+	 * [ 6: 6] Reserved
+	 * [ 7: 7] Non-Posted
+	 *	   0 = CPU writes may be posted
+	 *	   1 = CPU writes must be non-posted
+	 * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
+	 *	   This field defines the upp adddress bits of a 40-bit address that
+	 *	   defines the end of a memory-mapped I/O region n
+	 */
+	PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff20,
+
+	/* Memory-Mapped I/O Base i Registers
+	 * F1:0x80 i = 0
+	 * F1:0x88 i = 1
+	 * F1:0x90 i = 2
+	 * F1:0x98 i = 3
+	 * F1:0xA0 i = 4
+	 * F1:0xA8 i = 5
+	 * F1:0xB0 i = 6
+	 * F1:0xB8 i = 7
+	 * [ 0: 0] Read Enable
+	 *	   0 = Reads disabled
+	 *	   1 = Reads Enabled
+	 * [ 1: 1] Write Enable
+	 *	   0 = Writes disabled
+	 *	   1 = Writes Enabled
+	 * [ 2: 2] Cpu Disable
+	 *	   0 = Cpu can use this I/O range
+	 *	   1 = Cpu requests do not use this I/O range
+	 * [ 3: 3] Lock
+	 *	   0 = base/limit registers i are read/write
+	 *	   1 = base/limit registers i are read-only
+	 * [ 7: 4] Reserved
+	 * [31: 8] Memory-Mapped I/O Base Address i (39-16)
+	 *	   This field defines the upper address bits of a 40bit address 
+	 *	   that defines the start of memory-mapped I/O region i
+	 */
+	PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003,
+
+	/* PCI I/O Limit i Registers
+	 * F1:0xC4 i = 0
+	 * F1:0xCC i = 1
+	 * F1:0xD4 i = 2
+	 * F1:0xDC i = 3
+	 * [ 2: 0] Destination Node ID
+	 *	   000 = Node 0
+	 *	   001 = Node 1
+	 *	   010 = Node 2
+	 *	   011 = Node 3
+	 *	   100 = Node 4
+	 *	   101 = Node 5
+	 *	   110 = Node 6
+	 *	   111 = Node 7
+	 * [ 3: 3] Reserved
+	 * [ 5: 4] Destination Link ID
+	 *	   00 = Link 0
+	 *	   01 = Link 1
+	 *	   10 = Link 2
+	 *	   11 = reserved
+	 * [11: 6] Reserved
+	 * [24:12] PCI I/O Limit Address i
+	 *	   This field defines the end of PCI I/O region n
+	 * [31:25] Reserved
+	 */
+	PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff020,
+	PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
+
+	/* PCI I/O Base i Registers
+	 * F1:0xC0 i = 0
+	 * F1:0xC8 i = 1
+	 * F1:0xD0 i = 2
+	 * F1:0xD8 i = 3
+	 * [ 0: 0] Read Enable
+	 *	   0 = Reads Disabled
+	 *	   1 = Reads Enabled
+	 * [ 1: 1] Write Enable
+	 *	   0 = Writes Disabled
+	 *	   1 = Writes Enabled
+	 * [ 3: 2] Reserved
+	 * [ 4: 4] VGA Enable
+	 *	   0 = VGA matches Disabled
+	 *	   1 = matches all address < 64K and where A[9:0] is in the 
+	 *	       range 3B0-3BB or 3C0-3DF independen of the base & limit registers
+	 * [ 5: 5] ISA Enable
+	 *	   0 = ISA matches Disabled
+	 *	   1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
+	 *	       from matching agains this base/limit pair
+	 * [11: 6] Reserved
+	 * [24:12] PCI I/O Base i
+	 *	   This field defines the start of PCI I/O region n 
+	 * [31:25] Reserved
+	 */
+	PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000003,
+	PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
+
+	/* Config Base and Limit i Registers
+	 * F1:0xE0 i = 0
+	 * F1:0xE4 i = 1
+	 * F1:0xE8 i = 2
+	 * F1:0xEC i = 3
+	 * [ 0: 0] Read Enable
+	 *	   0 = Reads Disabled
+	 *	   1 = Reads Enabled
+	 * [ 1: 1] Write Enable
+	 *	   0 = Writes Disabled
+	 *	   1 = Writes Enabled
+	 * [ 2: 2] Device Number Compare Enable
+	 *	   0 = The ranges are based on bus number
+	 *	   1 = The ranges are ranges of devices on bus 0
+	 * [ 3: 3] Reserved
+	 * [ 6: 4] Destination Node
+	 *	   000 = Node 0
+	 *	   001 = Node 1
+	 *	   010 = Node 2
+	 *	   011 = Node 3
+	 *	   100 = Node 4
+	 *	   101 = Node 5
+	 *	   110 = Node 6
+	 *	   111 = Node 7
+	 * [ 7: 7] Reserved
+	 * [ 9: 8] Destination Link
+	 *	   00 = Link 0
+	 *	   01 = Link 1
+	 *	   10 = Link 2
+	 *	   11 - Reserved
+	 * [15:10] Reserved
+	 * [23:16] Bus Number Base i
+	 *	   This field defines the lowest bus number in configuration region i
+	 * [31:24] Bus Number Limit i
+	 *	   This field defines the highest bus number in configuration regin i
+	 */
+	PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x03000203,
+	PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x05040003,
+	PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
+	PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
+	};
+	int max;
+	max = sizeof(register_values)/sizeof(register_values[0]);
+	setup_resource_map(register_values, max);
+}
+
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/northbridge/amd/amdk8/raminit.1.c freebios2/src/northbridge/amd/amdk8/raminit.1.c
--- mylinuxbios/LinuxBIOS/freebios2/src/northbridge/amd/amdk8/raminit.1.c	2003-08-28 06:42:50.000000000 +0200
+++ freebios2/src/northbridge/amd/amdk8/raminit.1.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,2308 +0,0 @@
-//Changed by LYH to be used with Tyan s2885
-#include <cpu/k8/mtrr.h>
-#include "raminit.h"
-
-/* Function 2 */
-#define DRAM_CSBASE	   0x40
-#define DRAM_CSMASK	   0x60
-#define DRAM_BANK_ADDR_MAP 0x80
-#define DRAM_TIMING_LOW	   0x88
-#define	 DTL_TCL_SHIFT	   0
-#define	 DTL_TCL_MASK	   0x7
-#define	  DTL_CL_2	   1
-#define	  DTL_CL_3	   2
-#define	  DTL_CL_2_5	   5
-#define	 DTL_TRC_SHIFT	   4
-#define	 DTL_TRC_MASK	   0xf
-#define	  DTL_TRC_BASE	   7
-#define	  DTL_TRC_MIN	   7
-#define	  DTL_TRC_MAX	   22
-#define	 DTL_TRFC_SHIFT	   8
-#define	 DTL_TRFC_MASK	   0xf
-#define	  DTL_TRFC_BASE	   9
-#define	  DTL_TRFC_MIN	   9
-#define	  DTL_TRFC_MAX	   24
-#define	 DTL_TRCD_SHIFT	   12
-#define	 DTL_TRCD_MASK	   0x7
-#define	  DTL_TRCD_BASE	   0
-#define	  DTL_TRCD_MIN	   2
-#define	  DTL_TRCD_MAX	   6
-#define	 DTL_TRRD_SHIFT	   16
-#define	 DTL_TRRD_MASK	   0x7
-#define	  DTL_TRRD_BASE	   0
-#define	  DTL_TRRD_MIN	   2
-#define	  DTL_TRRD_MAX	   4
-#define	 DTL_TRAS_SHIFT	   20
-#define	 DTL_TRAS_MASK	   0xf
-#define	  DTL_TRAS_BASE	   0
-#define	  DTL_TRAS_MIN	   5
-#define	  DTL_TRAS_MAX	   15
-#define	 DTL_TRP_SHIFT	   24
-#define	 DTL_TRP_MASK	   0x7
-#define	  DTL_TRP_BASE	   0
-#define	  DTL_TRP_MIN	   2
-#define	  DTL_TRP_MAX	   6
-#define	 DTL_TWR_SHIFT	   28
-#define	 DTL_TWR_MASK	   0x1
-#define	  DTL_TWR_BASE	   2
-#define	  DTL_TWR_MIN	   2
-#define	  DTL_TWR_MAX	   3
-#define DRAM_TIMING_HIGH   0x8c
-#define	 DTH_TWTR_SHIFT	   0
-#define	 DTH_TWTR_MASK	   0x1
-#define	  DTH_TWTR_BASE	   1
-#define	  DTH_TWTR_MIN	   1
-#define	  DTH_TWTR_MAX	   2
-#define	 DTH_TRWT_SHIFT	   4
-#define	 DTH_TRWT_MASK	   0x7
-#define	  DTH_TRWT_BASE	   1
-#define	  DTH_TRWT_MIN	   1
-#define	  DTH_TRWT_MAX	   6
-#define	 DTH_TREF_SHIFT	   8
-#define	 DTH_TREF_MASK	   0x1f
-#define	  DTH_TREF_100MHZ_4K 0x00
-#define	  DTH_TREF_133MHZ_4K 0x01
-#define	  DTH_TREF_166MHZ_4K 0x02
-#define	  DTH_TREF_200MHZ_4K 0x03
-#define	  DTH_TREF_100MHZ_8K 0x08
-#define	  DTH_TREF_133MHZ_8K 0x09
-#define	  DTH_TREF_166MHZ_8K 0x0A
-#define	  DTH_TREF_200MHZ_8K 0x0B
-#define	 DTH_TWCL_SHIFT	    20
-#define	 DTH_TWCL_MASK	    0x7
-#define	  DTH_TWCL_BASE	    1
-#define	  DTH_TWCL_MIN	    1
-#define	  DTH_TWCL_MAX	    2
-#define DRAM_CONFIG_LOW	   0x90
-#define	 DCL_DLL_Disable   (1<<0)
-#define	 DCL_D_DRV	   (1<<1)
-#define	 DCL_QFC_EN	   (1<<2)
-#define	 DCL_DisDqsHys	   (1<<3)
-#define	 DCL_DramInit	   (1<<8)
-#define	 DCL_DramEnable	   (1<<10)
-#define	 DCL_MemClrStatus  (1<<11)
-#define	 DCL_ESR	   (1<<12)
-#define	 DCL_SRS	   (1<<13)
-#define	 DCL_128BitEn	   (1<<16)
-#define	 DCL_DimmEccEn	   (1<<17)
-#define	 DCL_UnBufDimm	   (1<<18)
-#define	 DCL_32ByteEn	   (1<<19)
-#define	 DCL_x4DIMM_SHIFT  20
-#define DRAM_CONFIG_HIGH   0x94
-#define	 DCH_ASYNC_LAT_SHIFT  0
-#define	 DCH_ASYNC_LAT_MASK   0xf
-#define	  DCH_ASYNC_LAT_BASE  0
-#define	  DCH_ASYNC_LAT_MIN   0
-#define	  DCH_ASYNC_LAT_MAX   15
-#define	 DCH_RDPREAMBLE_SHIFT 8
-#define	 DCH_RDPREAMBLE_MASK  0xf
-#define	  DCH_RDPREAMBLE_BASE ((2<<1)+0) /* 2.0 ns */
-#define	  DCH_RDPREAMBLE_MIN  ((2<<1)+0) /* 2.0 ns */
-#define	  DCH_RDPREAMBLE_MAX  ((9<<1)+1) /* 9.5 ns */
-#define	 DCH_IDLE_LIMIT_SHIFT 16
-#define	 DCH_IDLE_LIMIT_MASK  0x7
-#define	  DCH_IDLE_LIMIT_0    0
-#define	  DCH_IDLE_LIMIT_4    1
-#define	  DCH_IDLE_LIMIT_8    2
-#define	  DCH_IDLE_LIMIT_16   3
-#define	  DCH_IDLE_LIMIT_32   4
-#define	  DCH_IDLE_LIMIT_64   5
-#define	  DCH_IDLE_LIMIT_128  6
-#define	  DCH_IDLE_LIMIT_256  7
-#define	 DCH_DYN_IDLE_CTR_EN (1 << 19)
-#define	 DCH_MEMCLK_SHIFT     20
-#define	 DCH_MEMCLK_MASK      0x7
-#define	  DCH_MEMCLK_100MHZ   0
-#define	  DCH_MEMCLK_133MHZ   2
-#define	  DCH_MEMCLK_166MHZ   5
-#define	  DCH_MEMCLK_200MHZ   7
-#define	 DCH_MEMCLK_VALID     (1 << 25)
-#define	 DCH_MEMCLK_EN0	      (1 << 26) 
-#define	 DCH_MEMCLK_EN1	      (1 << 27) 
-#define	 DCH_MEMCLK_EN2	      (1 << 28) 
-#define	 DCH_MEMCLK_EN3	      (1 << 29) 
-
-/* Function 3 */
-#define SCRUB_CONTROL	   0x58
-#define	  SCRUB_NONE	    0
-#define	  SCRUB_40ns	    1
-#define	  SCRUB_80ns	    2
-#define	  SCRUB_160ns	    3
-#define	  SCRUB_320ns	    4
-#define	  SCRUB_640ns	    5
-#define	  SCRUB_1_28us	    6
-#define	  SCRUB_2_56us	    7
-#define	  SCRUB_5_12us	    8
-#define	  SCRUB_10_2us	    9
-#define	  SCRUB_20_5us	   10
-#define	  SCRUB_41_0us	   11
-#define	  SCRUB_81_9us	   12
-#define	  SCRUB_163_8us	   13
-#define	  SCRUB_327_7us	   14
-#define	  SCRUB_655_4us	   15
-#define	  SCRUB_1_31ms	   16
-#define	  SCRUB_2_62ms	   17
-#define	  SCRUB_5_24ms	   18 
-#define	  SCRUB_10_49ms	   19
-#define	  SCRUB_20_97ms	   20
-#define	  SCRUB_42ms	   21
-#define	  SCRUB_84ms	   22
-#define	 SC_DRAM_SCRUB_RATE_SHFIT  0
-#define	 SC_DRAM_SCRUB_RATE_MASK   0x1f
-#define	 SC_L2_SCRUB_RATE_SHIFT	   8
-#define	 SC_L2_SCRUB_RATE_MASK	   0x1f
-#define	 SC_L1D_SCRUB_RATE_SHIFT   16
-#define	 SC_L1D_SCRUB_RATE_MASK	   0x1f
-#define SCRUB_ADDR_LOW	   0x5C
-#define SCRUB_ADDR_HIGH	   0x60
-#define NORTHBRIDGE_CAP	   0xE8
-#define	 NBCAP_128Bit	      0x0001
-#define	 NBCAP_MP	      0x0002
-#define	 NBCAP_BIG_MP	      0x0004
-#define	 NBCAP_ECC	      0x0004
-#define	 NBCAP_CHIPKILL_ECC   0x0010
-#define	 NBCAP_MEMCLK_SHIFT   5
-#define	 NBCAP_MEMCLK_MASK    3
-#define	 NBCAP_MEMCLK_100MHZ  3
-#define	 NBCAP_MEMCLK_133MHZ  2
-#define	 NBCAP_MEMCLK_166MHZ  1
-#define	 NBCAP_MEMCLK_200MHZ  0
-#define	 NBCAP_MEMCTRL	      0x0100
-
-
-static void setup_resource_map(const unsigned int *register_values, int max)
-{
-	int i;
-	print_debug("setting up resource map....\r\n");
-	for(i = 0; i < max; i += 3) {
-		device_t dev;
-		unsigned where;
-		unsigned long reg;
-#if 0
-		print_debug_hex32(register_values[i]);
-		print_debug(" <-");
-		print_debug_hex32(register_values[i+2]);
-		print_debug("\r\n");
-#endif
-		dev = register_values[i] & ~0xff;
-		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);
-#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");
-}
-
-static void setup_default_resource_map(void)
-{
-	static const unsigned int register_values[] = {
-	/* Careful set limit registers before base registers which contain the enables */
-	/* DRAM Limit i Registers
-	 * F1:0x44 i = 0
-	 * F1:0x4C i = 1
-	 * F1:0x54 i = 2
-	 * F1:0x5C i = 3
-	 * F1:0x64 i = 4
-	 * F1:0x6C i = 5
-	 * F1:0x74 i = 6
-	 * F1:0x7C i = 7
-	 * [ 2: 0] Destination Node ID
-	 *	   000 = Node 0
-	 *	   001 = Node 1
-	 *	   010 = Node 2
-	 *	   011 = Node 3
-	 *	   100 = Node 4
-	 *	   101 = Node 5
-	 *	   110 = Node 6
-	 *	   111 = Node 7
-	 * [ 7: 3] Reserved
-	 * [10: 8] Interleave select
-	 *	   specifies the values of A[14:12] to use with interleave enable.
-	 * [15:11] Reserved
-	 * [31:16] DRAM Limit Address i Bits 39-24
-	 *	   This field defines the upper address bits of a 40 bit  address
-	 *	   that define the end of the DRAM region.
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
-	PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
-	PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
-	PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
-	PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
-	PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
-	PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
-	/* DRAM Base i Registers
-	 * F1:0x40 i = 0
-	 * F1:0x48 i = 1
-	 * F1:0x50 i = 2
-	 * F1:0x58 i = 3
-	 * F1:0x60 i = 4
-	 * F1:0x68 i = 5
-	 * F1:0x70 i = 6
-	 * F1:0x78 i = 7
-	 * [ 0: 0] Read Enable
-	 *	   0 = Reads Disabled
-	 *	   1 = Reads Enabled
-	 * [ 1: 1] Write Enable
-	 *	   0 = Writes Disabled
-	 *	   1 = Writes Enabled
-	 * [ 7: 2] Reserved
-	 * [10: 8] Interleave Enable
-	 *	   000 = No interleave
-	 *	   001 = Interleave on A[12] (2 nodes)
-	 *	   010 = reserved
-	 *	   011 = Interleave on A[12] and A[14] (4 nodes)
-	 *	   100 = reserved
-	 *	   101 = reserved
-	 *	   110 = reserved
-	 *	   111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
-	 * [15:11] Reserved
-	 * [13:16] DRAM Base Address i Bits 39-24
-	 *	   This field defines the upper address bits of a 40-bit address
-	 *	   that define the start of the DRAM region.
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
-
-	/* Memory-Mapped I/O Limit i Registers
-	 * F1:0x84 i = 0
-	 * F1:0x8C i = 1
-	 * F1:0x94 i = 2
-	 * F1:0x9C i = 3
-	 * F1:0xA4 i = 4
-	 * F1:0xAC i = 5
-	 * F1:0xB4 i = 6
-	 * F1:0xBC i = 7
-	 * [ 2: 0] Destination Node ID
-	 *	   000 = Node 0
-	 *	   001 = Node 1
-	 *	   010 = Node 2
-	 *	   011 = Node 3
-	 *	   100 = Node 4
-	 *	   101 = Node 5
-	 *	   110 = Node 6
-	 *	   111 = Node 7
-	 * [ 3: 3] Reserved
-	 * [ 5: 4] Destination Link ID
-	 *	   00 = Link 0
-	 *	   01 = Link 1
-	 *	   10 = Link 2
-	 *	   11 = Reserved
-	 * [ 6: 6] Reserved
-	 * [ 7: 7] Non-Posted
-	 *	   0 = CPU writes may be posted
-	 *	   1 = CPU writes must be non-posted
-	 * [31: 8] Memory-Mapped I/O Limit Address i (39-16)
-	 *	   This field defines the upp adddress bits of a 40-bit address that
-	 *	   defines the end of a memory-mapped I/O region n
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff20,
-
-	/* Memory-Mapped I/O Base i Registers
-	 * F1:0x80 i = 0
-	 * F1:0x88 i = 1
-	 * F1:0x90 i = 2
-	 * F1:0x98 i = 3
-	 * F1:0xA0 i = 4
-	 * F1:0xA8 i = 5
-	 * F1:0xB0 i = 6
-	 * F1:0xB8 i = 7
-	 * [ 0: 0] Read Enable
-	 *	   0 = Reads disabled
-	 *	   1 = Reads Enabled
-	 * [ 1: 1] Write Enable
-	 *	   0 = Writes disabled
-	 *	   1 = Writes Enabled
-	 * [ 2: 2] Cpu Disable
-	 *	   0 = Cpu can use this I/O range
-	 *	   1 = Cpu requests do not use this I/O range
-	 * [ 3: 3] Lock
-	 *	   0 = base/limit registers i are read/write
-	 *	   1 = base/limit registers i are read-only
-	 * [ 7: 4] Reserved
-	 * [31: 8] Memory-Mapped I/O Base Address i (39-16)
-	 *	   This field defines the upper address bits of a 40bit address 
-	 *	   that defines the start of memory-mapped I/O region i
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003,
-
-	/* PCI I/O Limit i Registers
-	 * F1:0xC4 i = 0
-	 * F1:0xCC i = 1
-	 * F1:0xD4 i = 2
-	 * F1:0xDC i = 3
-	 * [ 2: 0] Destination Node ID
-	 *	   000 = Node 0
-	 *	   001 = Node 1
-	 *	   010 = Node 2
-	 *	   011 = Node 3
-	 *	   100 = Node 4
-	 *	   101 = Node 5
-	 *	   110 = Node 6
-	 *	   111 = Node 7
-	 * [ 3: 3] Reserved
-	 * [ 5: 4] Destination Link ID
-	 *	   00 = Link 0
-	 *	   01 = Link 1
-	 *	   10 = Link 2
-	 *	   11 = reserved
-	 * [11: 6] Reserved
-	 * [24:12] PCI I/O Limit Address i
-	 *	   This field defines the end of PCI I/O region n
-	 * [31:25] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff020,
-	PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000,
-
-	/* PCI I/O Base i Registers
-	 * F1:0xC0 i = 0
-	 * F1:0xC8 i = 1
-	 * F1:0xD0 i = 2
-	 * F1:0xD8 i = 3
-	 * [ 0: 0] Read Enable
-	 *	   0 = Reads Disabled
-	 *	   1 = Reads Enabled
-	 * [ 1: 1] Write Enable
-	 *	   0 = Writes Disabled
-	 *	   1 = Writes Enabled
-	 * [ 3: 2] Reserved
-	 * [ 4: 4] VGA Enable
-	 *	   0 = VGA matches Disabled
-	 *	   1 = matches all address < 64K and where A[9:0] is in the 
-	 *	       range 3B0-3BB or 3C0-3DF independen of the base & limit registers
-	 * [ 5: 5] ISA Enable
-	 *	   0 = ISA matches Disabled
-	 *	   1 = Blocks address < 64K and in the last 768 bytes of eack 1K block
-	 *	       from matching agains this base/limit pair
-	 * [11: 6] Reserved
-	 * [24:12] PCI I/O Base i
-	 *	   This field defines the start of PCI I/O region n 
-	 * [31:25] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000003,
-	PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000,
-
-	/* Config Base and Limit i Registers
-	 * F1:0xE0 i = 0
-	 * F1:0xE4 i = 1
-	 * F1:0xE8 i = 2
-	 * F1:0xEC i = 3
-	 * [ 0: 0] Read Enable
-	 *	   0 = Reads Disabled
-	 *	   1 = Reads Enabled
-	 * [ 1: 1] Write Enable
-	 *	   0 = Writes Disabled
-	 *	   1 = Writes Enabled
-	 * [ 2: 2] Device Number Compare Enable
-	 *	   0 = The ranges are based on bus number
-	 *	   1 = The ranges are ranges of devices on bus 0
-	 * [ 3: 3] Reserved
-	 * [ 6: 4] Destination Node
-	 *	   000 = Node 0
-	 *	   001 = Node 1
-	 *	   010 = Node 2
-	 *	   011 = Node 3
-	 *	   100 = Node 4
-	 *	   101 = Node 5
-	 *	   110 = Node 6
-	 *	   111 = Node 7
-	 * [ 7: 7] Reserved
-	 * [ 9: 8] Destination Link
-	 *	   00 = Link 0
-	 *	   01 = Link 1
-	 *	   10 = Link 2
-	 *	   11 - Reserved
-	 * [15:10] Reserved
-	 * [23:16] Bus Number Base i
-	 *	   This field defines the lowest bus number in configuration region i
-	 * [31:24] Bus Number Limit i
-	 *	   This field defines the highest bus number in configuration regin i
-	 */
-	PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x03000203,
-	PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x05040003,
-	PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
-	};
-	int max;
-	max = sizeof(register_values)/sizeof(register_values[0]);
-	setup_resource_map(register_values, max);
-}
-
-static void sdram_set_registers(const struct mem_controller *ctrl)
-{
-	static const unsigned int register_values[] = {
-
-	/* Careful set limit registers before base registers which contain the enables */
-	/* DRAM Limit i Registers
-	 * F1:0x44 i = 0
-	 * F1:0x4C i = 1
-	 * F1:0x54 i = 2
-	 * F1:0x5C i = 3
-	 * F1:0x64 i = 4
-	 * F1:0x6C i = 5
-	 * F1:0x74 i = 6
-	 * F1:0x7C i = 7
-	 * [ 2: 0] Destination Node ID
-	 *	   000 = Node 0
-	 *	   001 = Node 1
-	 *	   010 = Node 2
-	 *	   011 = Node 3
-	 *	   100 = Node 4
-	 *	   101 = Node 5
-	 *	   110 = Node 6
-	 *	   111 = Node 7
-	 * [ 7: 3] Reserved
-	 * [10: 8] Interleave select
-	 *	   specifies the values of A[14:12] to use with interleave enable.
-	 * [15:11] Reserved
-	 * [31:16] DRAM Limit Address i Bits 39-24
-	 *	   This field defines the upper address bits of a 40 bit  address
-	 *	   that define the end of the DRAM region.
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
-	PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
-	PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
-	PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
-	PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
-	PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
-	PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
-	/* DRAM Base i Registers
-	 * F1:0x40 i = 0
-	 * F1:0x48 i = 1
-	 * F1:0x50 i = 2
-	 * F1:0x58 i = 3
-	 * F1:0x60 i = 4
-	 * F1:0x68 i = 5
-	 * F1:0x70 i = 6
-	 * F1:0x78 i = 7
-	 * [ 0: 0] Read Enable
-	 *	   0 = Reads Disabled
-	 *	   1 = Reads Enabled
-	 * [ 1: 1] Write Enable
-	 *	   0 = Writes Disabled
-	 *	   1 = Writes Enabled
-	 * [ 7: 2] Reserved
-	 * [10: 8] Interleave Enable
-	 *	   000 = No interleave
-	 *	   001 = Interleave on A[12] (2 nodes)
-	 *	   010 = reserved
-	 *	   011 = Interleave on A[12] and A[14] (4 nodes)
-	 *	   100 = reserved
-	 *	   101 = reserved
-	 *	   110 = reserved
-	 *	   111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
-	 * [15:11] Reserved
-	 * [13:16] DRAM Base Address i Bits 39-24
-	 *	   This field defines the upper address bits of a 40-bit address
-	 *	   that define the start of the DRAM region.
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
-
-	/* DRAM CS Base Address i Registers
-	 * F2:0x40 i = 0
-	 * F2:0x44 i = 1
-	 * F2:0x48 i = 2
-	 * F2:0x4C i = 3
-	 * F2:0x50 i = 4
-	 * F2:0x54 i = 5
-	 * F2:0x58 i = 6
-	 * F2:0x5C i = 7
-	 * [ 0: 0] Chip-Select Bank Enable
-	 *	   0 = Bank Disabled
-	 *	   1 = Bank Enabled
-	 * [ 8: 1] Reserved
-	 * [15: 9] Base Address (19-13)
-	 *	   An optimization used when all DIMM are the same size...
-	 * [20:16] Reserved
-	 * [31:21] Base Address (35-25)
-	 *	   This field defines the top 11 addresses bit of a 40-bit
-	 *	   address that define the memory address space.  These
-	 *	   bits decode 32-MByte blocks of memory.
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x50), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x54), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x58), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x5C), 0x001f01fe, 0x00000000,
-	/* DRAM CS Mask Address i Registers
-	 * F2:0x60 i = 0
-	 * F2:0x64 i = 1
-	 * F2:0x68 i = 2
-	 * F2:0x6C i = 3
-	 * F2:0x70 i = 4
-	 * F2:0x74 i = 5
-	 * F2:0x78 i = 6
-	 * F2:0x7C i = 7
-	 * Select bits to exclude from comparison with the DRAM Base address register.
-	 * [ 8: 0] Reserved
-	 * [15: 9] Address Mask (19-13)
-	 *	   Address to be excluded from the optimized case
-	 * [20:16] Reserved
-	 * [29:21] Address Mask (33-25)
-	 *	   The bits with an address mask of 1 are excluded from address comparison
-	 * [31:30] Reserved
-	 * 
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x70), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x74), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x78), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x7C), 0xC01f01ff, 0x00000000,
-	/* DRAM Bank Address Mapping Register
-	 * F2:0x80
-	 * Specify the memory module size
-	 * [ 2: 0] CS1/0 
-	 * [ 6: 4] CS3/2
-	 * [10: 8] CS5/4
-	 * [14:12] CS7/6
-	 *	   000 = 32Mbyte  (Rows = 12 & Col =  8)
-	 *	   001 = 64Mbyte  (Rows = 12 & Col =  9)
-	 *	   010 = 128Mbyte (Rows = 13 & Col =  9)|(Rows = 12 & Col = 10)
-	 *	   011 = 256Mbyte (Rows = 13 & Col = 10)|(Rows = 12 & Col = 11)
-	 *	   100 = 512Mbyte (Rows = 13 & Col = 11)|(Rows = 14 & Col = 10)
-	 *	   101 = 1Gbyte	  (Rows = 14 & Col = 11)|(Rows = 13 & Col = 12)
-	 *	   110 = 2Gbyte	  (Rows = 14 & Col = 12)
-	 *	   111 = reserved 
-	 * [ 3: 3] Reserved
-	 * [ 7: 7] Reserved
-	 * [11:11] Reserved
-	 * [31:15]
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000000,
-	/* DRAM Timing Low Register
-	 * F2:0x88
-	 * [ 2: 0] Tcl (Cas# Latency, Cas# to read-data-valid)
-	 *	   000 = reserved
-	 *	   001 = CL 2
-	 *	   010 = CL 3
-	 *	   011 = reserved
-	 *	   100 = reserved
-	 *	   101 = CL 2.5
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [ 3: 3] Reserved
-	 * [ 7: 4] Trc (Row Cycle Time, Ras#-active to Ras#-active/bank auto refresh)
-	 *	   0000 =  7 bus clocks
-	 *	   0001 =  8 bus clocks
-	 *	   ...
-	 *	   1110 = 21 bus clocks
-	 *	   1111 = 22 bus clocks
-	 * [11: 8] Trfc (Row refresh Cycle time, Auto-refresh-active to RAS#-active or RAS#auto-refresh)
-	 *	   0000 = 9 bus clocks
-	 *	   0010 = 10 bus clocks
-	 *	   ....
-	 *	   1110 = 23 bus clocks
-	 *	   1111 = 24 bus clocks
-	 * [14:12] Trcd (Ras#-active to Case#-read/write Delay)
-	 *	   000 = reserved
-	 *	   001 = reserved
-	 *	   010 = 2 bus clocks
-	 *	   011 = 3 bus clocks
-	 *	   100 = 4 bus clocks
-	 *	   101 = 5 bus clocks
-	 *	   110 = 6 bus clocks
-	 *	   111 = reserved
-	 * [15:15] Reserved
-	 * [18:16] Trrd (Ras# to Ras# Delay)
-	 *	   000 = reserved
-	 *	   001 = reserved
-	 *	   010 = 2 bus clocks
-	 *	   011 = 3 bus clocks
-	 *	   100 = 4 bus clocks
-	 *	   101 = reserved
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [19:19] Reserved
-	 * [23:20] Tras (Minmum Ras# Active Time)
-	 *	   0000 to 0100 = reserved
-	 *	   0101 = 5 bus clocks
-	 *	   ...
-	 *	   1111 = 15 bus clocks
-	 * [26:24] Trp (Row Precharge Time)
-	 *	   000 = reserved
-	 *	   001 = reserved
-	 *	   010 = 2 bus clocks
-	 *	   011 = 3 bus clocks
-	 *	   100 = 4 bus clocks
-	 *	   101 = 5 bus clocks
-	 *	   110 = 6 bus clocks
-	 *	   111 = reserved
-	 * [27:27] Reserved
-	 * [28:28] Twr (Write Recovery Time)
-	 *	   0 = 2 bus clocks
-	 *	   1 = 3 bus clocks
-	 * [31:29] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x88), 0xe8088008, 0x02522001 /* 0x03623125 */ ,
-	/* DRAM Timing High Register
-	 * F2:0x8C
-	 * [ 0: 0] Twtr (Write to Read Delay)
-	 *	   0 = 1 bus Clocks
-	 *	   1 = 2 bus Clocks
-	 * [ 3: 1] Reserved
-	 * [ 6: 4] Trwt (Read to Write Delay)
-	 *	   000 = 1 bus clocks
-	 *	   001 = 2 bus clocks
-	 *	   010 = 3 bus clocks
-	 *	   011 = 4 bus clocks
-	 *	   100 = 5 bus clocks
-	 *	   101 = 6 bus clocks
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [ 7: 7] Reserved
-	 * [12: 8] Tref (Refresh Rate)
-	 *	   00000 = 100Mhz 4K rows
-	 *	   00001 = 133Mhz 4K rows
-	 *	   00010 = 166Mhz 4K rows
-	 *	   00011 = 200Mhz 4K rows
-	 *	   01000 = 100Mhz 8K/16K rows
-	 *	   01001 = 133Mhz 8K/16K rows
-	 *	   01010 = 166Mhz 8K/16K rows
-	 *	   01011 = 200Mhz 8K/16K rows
-	 * [19:13] Reserved
-	 * [22:20] Twcl (Write CAS Latency)
-	 *	   000 = 1 Mem clock after CAS# (Unbuffered Dimms)
-	 *	   001 = 2 Mem clocks after CAS# (Registered Dimms)
-	 * [31:23] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x8c), 0xff8fe08e, (0 << 20)|(0 << 8)|(0 << 4)|(0 << 0),
-	/* DRAM Config Low Register
-	 * F2:0x90
-	 * [ 0: 0] DLL Disable
-	 *	   0 = Enabled
-	 *	   1 = Disabled
-	 * [ 1: 1] D_DRV
-	 *	   0 = Normal Drive
-	 *	   1 = Weak Drive
-	 * [ 2: 2] QFC_EN
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [ 3: 3] Disable DQS Hystersis  (FIXME handle this one carefully)
-	 *	   0 = Enable DQS input filter 
-	 *	   1 = Disable DQS input filtering 
-	 * [ 7: 4] Reserved
-	 * [ 8: 8] DRAM_Init
-	 *	   0 = Initialization done or not yet started.
-	 *	   1 = Initiate DRAM intialization sequence
-	 * [ 9: 9] SO-Dimm Enable
-	 *	   0 = Do nothing
-	 *	   1 = SO-Dimms present
-	 * [10:10] DramEnable
-	 *	   0 = DRAM not enabled
-	 *	   1 = DRAM initialized and enabled
-	 * [11:11] Memory Clear Status
-	 *	   0 = Memory Clear function has not completed
-	 *	   1 = Memory Clear function has completed
-	 * [12:12] Exit Self-Refresh
-	 *	   0 = Exit from self-refresh done or not yet started
-	 *	   1 = DRAM exiting from self refresh
-	 * [13:13] Self-Refresh Status
-	 *	   0 = Normal Operation
-	 *	   1 = Self-refresh mode active
-	 * [15:14] Read/Write Queue Bypass Count
-	 *	   00 = 2
-	 *	   01 = 4
-	 *	   10 = 8
-	 *	   11 = 16
-	 * [16:16] 128-bit/64-Bit
-	 *	   0 = 64bit Interface to DRAM
-	 *	   1 = 128bit Interface to DRAM
-	 * [17:17] DIMM ECC Enable
-	 *	   0 = Some DIMMs do not have ECC
-	 *	   1 = ALL DIMMS have ECC bits
-	 * [18:18] UnBuffered DIMMs
-	 *	   0 = Buffered DIMMS
-	 *	   1 = Unbuffered DIMMS
-	 * [19:19] Enable 32-Byte Granularity
-	 *	   0 = Optimize for 64byte bursts
-	 *	   1 = Optimize for 32byte bursts
-	 * [20:20] DIMM 0 is x4
-	 * [21:21] DIMM 1 is x4
-	 * [22:22] DIMM 2 is x4
-	 * [23:23] DIMM 3 is x4
-	 *	   0 = DIMM is not x4
-	 *	   1 = x4 DIMM present
-	 * [24:24] Disable DRAM Receivers
-	 *	   0 = Receivers enabled
-	 *	   1 = Receivers disabled
-	 * [27:25] Bypass Max
-	 *	   000 = Arbiters chois is always respected
-	 *	   001 = Oldest entry in DCQ can be bypassed 1 time
-	 *	   010 = Oldest entry in DCQ can be bypassed 2 times
-	 *	   011 = Oldest entry in DCQ can be bypassed 3 times
-	 *	   100 = Oldest entry in DCQ can be bypassed 4 times
-	 *	   101 = Oldest entry in DCQ can be bypassed 5 times
-	 *	   110 = Oldest entry in DCQ can be bypassed 6 times
-	 *	   111 = Oldest entry in DCQ can be bypassed 7 times
-	 * [31:28] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x90), 0xf0000000, 
-	(4 << 25)|(0 << 24)| 
-	(0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)| 
-	(1 << 19)|(0 << 18)|(1 << 17)|(0 << 16)| 
-	(2 << 14)|(0 << 13)|(0 << 12)| 
-	(0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)| 
-	(0 << 3) |(0 << 1) |(0 << 0),
-	/* DRAM Config High Register
-	 * F2:0x94
-	 * [ 0: 3] Maximum Asynchronous Latency
-	 *	   0000 = 0 ns
-	 *	   ...
-	 *	   1111 = 15 ns
-	 * [ 7: 4] Reserved
-	 * [11: 8] Read Preamble
-	 *	   0000 = 2.0 ns
-	 *	   0001 = 2.5 ns
-	 *	   0010 = 3.0 ns
-	 *	   0011 = 3.5 ns
-	 *	   0100 = 4.0 ns
-	 *	   0101 = 4.5 ns
-	 *	   0110 = 5.0 ns
-	 *	   0111 = 5.5 ns
-	 *	   1000 = 6.0 ns
-	 *	   1001 = 6.5 ns
-	 *	   1010 = 7.0 ns
-	 *	   1011 = 7.5 ns
-	 *	   1100 = 8.0 ns
-	 *	   1101 = 8.5 ns
-	 *	   1110 = 9.0 ns
-	 *	   1111 = 9.5 ns
-	 * [15:12] Reserved
-	 * [18:16] Idle Cycle Limit
-	 *	   000 = 0 cycles
-	 *	   001 = 4 cycles
-	 *	   010 = 8 cycles
-	 *	   011 = 16 cycles
-	 *	   100 = 32 cycles
-	 *	   101 = 64 cycles
-	 *	   110 = 128 cycles
-	 *	   111 = 256 cycles
-	 * [19:19] Dynamic Idle Cycle Center Enable
-	 *	   0 = Use Idle Cycle Limit
-	 *	   1 = Generate a dynamic Idle cycle limit
-	 * [22:20] DRAM MEMCLK Frequency
-	 *	   000 = 100Mhz
-	 *	   001 = reserved
-	 *	   010 = 133Mhz
-	 *	   011 = reserved
-	 *	   100 = reserved
-	 *	   101 = 166Mhz
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [24:23] Reserved
-	 * [25:25] Memory Clock Ratio Valid (FIXME carefully enable memclk)
-	 *	   0 = Disable MemClks
-	 *	   1 = Enable MemClks
-	 * [26:26] Memory Clock 0 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [27:27] Memory Clock 1 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [28:28] Memory Clock 2 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [29:29] Memory Clock 3 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [31:30] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x94), 0xc180f0f0,
-	(0 << 29)|(0 << 28)|(0 << 27)|(0 << 26)|(0 << 25)|
-	(0 << 20)|(0 << 19)|(DCH_IDLE_LIMIT_16 << 16)|(0 << 8)|(0 << 0),
-	/* DRAM Delay Line Register
-	 * F2:0x98
-	 * Adjust the skew of the input DQS strobe relative to DATA
-	 * [15: 0] Reserved
-	 * [23:16] Delay Line Adjust
-	 *	   Adjusts the DLL derived PDL delay by one or more delay stages
-	 *	   in either the faster or slower direction.
-	 * [24:24} Adjust Slower
-	 *	   0 = Do Nothing
-	 *	   1 = Adj is used to increase the PDL delay
-	 * [25:25] Adjust Faster
-	 *	   0 = Do Nothing
-	 *	   1 = Adj is used to decrease the PDL delay
-	 * [31:26] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x98), 0xfc00ffff, 0x00000000,
-	/* DRAM Scrub Control Register
-	 * F3:0x58
-	 * [ 4: 0] DRAM Scrube Rate
-	 * [ 7: 5] reserved
-	 * [12: 8] L2 Scrub Rate
-	 * [15:13] reserved
-	 * [20:16] Dcache Scrub
-	 * [31:21] reserved
-	 *	   Scrub Rates
-	 *	   00000 = Do not scrub
-	 *	   00001 =  40.00 ns
-	 *	   00010 =  80.00 ns
-	 *	   00011 = 160.00 ns
-	 *	   00100 = 320.00 ns
-	 *	   00101 = 640.00 ns
-	 *	   00110 =   1.28 us
-	 *	   00111 =   2.56 us
-	 *	   01000 =   5.12 us
-	 *	   01001 =  10.20 us
-	 *	   01011 =  41.00 us
-	 *	   01100 =  81.90 us
-	 *	   01101 = 163.80 us
-	 *	   01110 = 327.70 us
-	 *	   01111 = 655.40 us
-	 *	   10000 =   1.31 ms
-	 *	   10001 =   2.62 ms
-	 *	   10010 =   5.24 ms
-	 *	   10011 =  10.49 ms
-	 *	   10100 =  20.97 ms
-	 *	   10101 =  42.00 ms
-	 *	   10110 =  84.00 ms
-	 *	   All Others = Reserved
-	 */
-	PCI_ADDR(0, 0x18, 3, 0x58), 0xffe0e0e0, 0x00000000,
-	/* DRAM Scrub Address Low Register
-	 * F3:0x5C
-	 * [ 0: 0] DRAM Scrubber Redirect Enable
-	 *	   0 = Do nothing
-	 *	   1 = Scrubber Corrects errors found in normal operation
-	 * [ 5: 1] Reserved
-	 * [31: 6] DRAM Scrub Address 31-6
-	 */
-	PCI_ADDR(0, 0x18, 3, 0x5C), 0x0000003e, 0x00000000,
-	/* DRAM Scrub Address High Register
-	 * F3:0x60
-	 * [ 7: 0] DRAM Scrubb Address 39-32
-	 * [31: 8] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 3, 0x60), 0xffffff00, 0x00000000,
-/*
-//BY LYH  add IOMMU 64M APERTURE
-	PCI_ADDR(0, 0x18, 3, 0x94), 0xffff8000, 0x00000f70,
-	PCI_ADDR(0, 0x18, 3, 0x90), 0xffffff80, 0x00000002,
-	PCI_ADDR(0, 0x18, 3, 0x98), 0x0000000f, 0x00068300,
-
-//BY LYH END
-*/
-	};
-	int i;
-	int max;
-	print_debug("setting up CPU");
-	print_debug_hex8(ctrl->node_id);
-	print_debug(" northbridge registers\r\n");
-	max = sizeof(register_values)/sizeof(register_values[0]);
-	for(i = 0; i < max; i += 3) {
-		device_t dev;
-		unsigned where;
-		unsigned long reg;
-#if 0
-		print_debug_hex32(register_values[i]);
-		print_debug(" <-");
-		print_debug_hex32(register_values[i+2]);
-		print_debug("\r\n");
-#endif
-		dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x18, 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);
-#if 0
-
-		reg = pci_read_config32(register_values[i]);
-		reg &= register_values[i+1];
-		reg |= register_values[i+2];
-		pci_write_config32(register_values[i], reg);
-#endif
-	}
-	print_debug("done.\r\n");
-}
-
-
-static int is_dual_channel(const struct mem_controller *ctrl)
-{
-	uint32_t dcl;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	return dcl & DCL_128BitEn;
-}
-
-static int is_opteron(const struct mem_controller *ctrl)
-{
-	/* Test to see if I am an Opteron.  
-	 * FIXME Testing dual channel capability is correct for now
-	 * but a beter test is probably required.
-	 */
-#warning "FIXME implement a better test for opterons"
-	uint32_t nbcap;
-	nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-	return !!(nbcap & NBCAP_128Bit);
-}
-
-static int is_registered(const struct mem_controller *ctrl)
-{
-	/* Test to see if we are dealing with registered SDRAM.
-	 * If we are not registered we are unbuffered.
-	 * This function must be called after spd_handle_unbuffered_dimms.
-	 */
-	uint32_t dcl;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	return !(dcl & DCL_UnBufDimm);
-}
-
-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;
-	sz.side1 = 0;
-	sz.side2 = 0;
-
-	/* 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 out;
-	sz.side1 += value & 0xf;
-
-	value = spd_read_byte(device, 4);	/* columns */
-	if (value < 0) goto out;
-	sz.side1 += value & 0xf;
-
-	value = spd_read_byte(device, 17);	/* banks */
-	if (value < 0) goto out;
-	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 out;
-	value &= 0xff;
-	value <<= 8;
-	
-	low = spd_read_byte(device, 6);	/* (low byte) */
-	if (low < 0) goto out;
-	value = value | (low & 0xff);
-	sz.side1 += log2(value);
-
-	/* side 2 */
-	value = spd_read_byte(device, 5);	/* number of physical banks */
-	if (value <= 1) goto out;
-
-	/* Start with the symmetrical case */
-	sz.side2 = sz.side1;
-
-	value = spd_read_byte(device, 3);	/* rows */
-	if (value < 0) goto out;
-	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 out;
-	sz.side2 -= (value & 0x0f);		/* Subtract out columns on side 1 */
-	sz.side2 += ((value >> 4) & 0x0f);	/* Add in columsn on side 2 */
-
- out:
-	return sz;
-}
-
-static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index)
-{
-	uint32_t base0, base1, map;
-	uint32_t dch;
-
-#if 0
-	print_debug("set_dimm_size: (");
-	print_debug_hex32(sz.side1);
-	print_debug_char(',');
-	print_debug_hex32(sz.side2);
-	print_debug_char(',');
-	print_debug_hex32(index);
-	print_debug(")\r\n");
-#endif
-	if (sz.side1 != sz.side2) {
-		sz.side2 = 0;
-	}
-	map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
-	map &= ~(0xf << (index + 4));
-
-	/* For each base register.
-	 * Place the dimm size in 32 MB quantities in the bits 31 - 21.
-	 * The initialize dimm size is in bits.
-	 * Set the base enable bit0.
-	 */
-	
-	base0 = base1 = 0;
-
-	/* Make certain side1 of the dimm is at least 32MB */
-	if (sz.side1 >= (25 +3)) {
-		map |= (sz.side1 - (25 + 3)) << (index *4);
-		base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
-	}
-	/* Make certain side2 of the dimm is at least 32MB */
-	if (sz.side2 >= (25 + 3)) {
-		base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
-	}
-
-	/* Double the size if we are using dual channel memory */
-	if (is_dual_channel(ctrl)) {
-		base0 = (base0 << 1) | (base0 & 1);
-		base1 = (base1 << 1) | (base1 & 1);
-	}
-
-	/* Clear the reserved bits */
-	base0 &= ~0x001ffffe;
-	base1 &= ~0x001ffffe;
-
-	/* Set the appropriate DIMM base address register */
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), base0);
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), base1);
-	pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);
-	
-	/* Enable the memory clocks for this DIMM */
-	if (base0) {
-		dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-		dch |= DCH_MEMCLK_EN0 << index;
-		pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-	}
-}
-
-static void spd_set_ram_size(const struct mem_controller *ctrl)
-{
-	int i;
-	
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		struct dimm_size sz;
-		sz = spd_get_dimm_size(ctrl->channel0[i]);
-		set_dimm_size(ctrl, sz, i);
-	}
-}
-
-//BY LYH //Fill next base reg with right value
-static void fill_last(unsigned long node_id,unsigned long base)
-{
-        unsigned i;
-        unsigned base_reg;
-        base &=0xffff0000;
-        device_t device;
-        for(device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device
-+= PCI_DEV(0, 1, 0)) {
-                for(i=node_id+1;i<=7;i++) {
-                        base_reg=0x40+(i<<3);
-                        pci_write_config32(device,base_reg,base);
-                }
-        }
-}
-//BY LYH END
- 
-static void route_dram_accesses(const struct mem_controller *ctrl,
-	unsigned long base_k, unsigned long limit_k)
-{
-	/* Route the addresses to the controller node */
-	unsigned node_id;
-	unsigned limit;
-	unsigned base;
-	unsigned index;
-	unsigned limit_reg, base_reg;
-	device_t device;
-
-	node_id = ctrl->node_id;
-	index = (node_id << 3);
-	limit = (limit_k << 2);
-	limit &= 0xffff0000;
-	limit -= 0x00010000;
-	limit |= ( 0 << 8) | (node_id << 0);
-	base = (base_k << 2);
-	base &= 0xffff0000;
-	base |= (0 << 8) | (1<<1) | (1<<0);
-
-	limit_reg = 0x44 + index;
-	base_reg = 0x40 + index;
-	for(device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device += PCI_DEV(0, 1, 0)) {
-		pci_write_config32(device, limit_reg, limit);
-		pci_write_config32(device, base_reg, base);
-	}
-}
-
-static void set_top_mem(unsigned tom_k)
-{
-	/* Error if I don't have memory */
-	if (!tom_k) {
-		die("No memory");
-	}
-
-#if 1
-	/* Report the amount of memory. */
-	print_debug("RAM: 0x");
-	print_debug_hex32(tom_k);
-	print_debug(" KB\r\n");
-#endif
-
-	/* Now set top of memory */
-	msr_t msr;
-	msr.lo = (tom_k & 0x003fffff) << 10;
-	msr.hi = (tom_k & 0xffc00000) >> 22;
-	wrmsr(TOP_MEM2, msr);
-
-	/* Leave a 64M hole between TOP_MEM and TOP_MEM2
-	 * so I can see my rom chip and other I/O devices.
-	 */
-	if (tom_k >= 0x003f0000) {
-		tom_k = 0x3f0000;
-	}
-	msr.lo = (tom_k & 0x003fffff) << 10;
-	msr.hi = (tom_k & 0xffc00000) >> 22;
-	wrmsr(TOP_MEM, msr);
-}
-
-static void order_dimms(const struct mem_controller *ctrl)
-{
-	unsigned long tom, tom_k, base_k;
-	unsigned node_id;
-
-	/* Compute the memory base address address */
-	base_k = 0;
-	/* Remember which registers we have used in the high 8 bits of tom */
-	tom = base_k >> 15;
-	for(;;) {
-		/* Find the largest remaining canidate */
-		unsigned index, canidate;
-		uint32_t csbase, csmask;
-		unsigned size;
-		csbase = 0;
-		canidate = 0;
-		for(index = 0; index < 8; index++) {
-			uint32_t value;
-			value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-
-			/* Is it enabled? */
-			if (!(value & 1)) {
-				continue;
-			}
-			
-			/* Is it greater? */
-			if (value <= csbase) {
-				continue;
-			}
-			
-			/* Has it already been selected */
-			if (tom & (1 << (index + 24))) {
-				continue;
-			}
-			/* I have a new canidate */
-			csbase = value;
-			canidate = index;
-		}
-		/* See if I have found a new canidate */
-		if (csbase == 0) {
-			break;
-		}
-
-		/* Remember the dimm size */
-		size = csbase >> 21;
-
-		/* Remember I have used this register */
-		tom |= (1 << (canidate + 24));
-
-		/* Recompute the cs base register value */
-		csbase = (tom << 21) | 1;
-
-		/* Increment the top of memory */
-		tom += size;
-
-		/* Compute the memory mask */
-		csmask = ((size -1) << 21);
-		csmask |= 0xfe00;		/* For now don't optimize */
-#warning "Don't forget to optimize the DIMM size"
-
-		/* Write the new base register */
-		pci_write_config32(ctrl->f2, DRAM_CSBASE + (canidate << 2), csbase);
-		/* Write the new mask register */
-		pci_write_config32(ctrl->f2, DRAM_CSMASK + (canidate << 2), csmask);
-		
-	}
-	tom_k = (tom & ~0xff000000) << 15;
-
-	/* Compute the memory base address */
-	base_k = 0;
-	for(node_id = 0; node_id < ctrl->node_id; node_id++) {
-		uint32_t limit, base;
-		unsigned index;
-		index = node_id << 3;
-		base = pci_read_config32(ctrl->f1, 0x40 + index);
-		/* Only look at the limit if the base is enabled */
-		if ((base & 3) == 3) {
-			limit = pci_read_config32(ctrl->f1, 0x44 + index);
-			base_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
-		}
-	}
-	tom_k += base_k;
-#if 0
-	print_debug("tom: ");
-	print_debug_hex32(tom);
-	print_debug(" base_k: ");
-	print_debug_hex32(base_k);
-	print_debug(" tom_k: ");
-	print_debug_hex32(tom_k);
-	print_debug("\r\n");
-#endif
-	route_dram_accesses(ctrl, base_k, tom_k);
-//BY LYH
-        fill_last(ctrl->node_id, tom_k<<2);
-//BY LYH END
-	set_top_mem(tom_k);
-}
-
-static void disable_dimm(const struct mem_controller *ctrl, unsigned index)
-{
-	print_debug("disabling dimm"); 
-	print_debug_hex8(index); 
-	print_debug("\r\n");
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), 0);
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), 0);
-}
-
-
-static void spd_handle_unbuffered_dimms(const struct mem_controller *ctrl)
-{
-	int i;
-	int registered;
-	int unbuffered;
-	uint32_t dcl;
-	unbuffered = 0;
-	registered = 0;
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		int value;
-		value = spd_read_byte(ctrl->channel0[i], 21);
-		if (value < 0) {
-			disable_dimm(ctrl, i);
-			continue;
-		}
-		/* Registered dimm ? */
-		if (value & (1 << 1)) {
-			registered = 1;
-		} 
-		/* Otherwise it must be an unbuffered dimm */
-		else {
-			unbuffered = 1;
-		}
-	}
-	if (unbuffered && registered) {
-		die("Mixed buffered and registered dimms not supported");
-	}
-	if (unbuffered && is_opteron(ctrl)) {
-		die("Unbuffered Dimms not supported on Opteron");
-	}
-
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~DCL_UnBufDimm;
-	if (unbuffered) {
-		dcl |= DCL_UnBufDimm;
-	}
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-#if 0
-	if (is_registered(ctrl)) {
-		print_debug("Registered\r\n");
-	} else {
-		print_debug("Unbuffered\r\n");
-	}
-#endif
-}
-
-static void spd_enable_2channels(const struct mem_controller *ctrl)
-{
-	int i;
-	uint32_t nbcap;
-	/* SPD addresses to verify are identical */
-#warning "FINISHME review and see if these are the bytes I need"
-	/* FINISHME review and see if these are the bytes I need */
-	static const unsigned addresses[] = {
-		2,	/* Type should be DDR SDRAM */
-		3,	/* *Row addresses */
-		4,	/* *Column addresses */
-		5,	/* *Physical Banks */
-		6,	/* *Module Data Width low */
-		7,	/* *Module Data Width high */
-		9,	/* *Cycle time at highest CAS Latency CL=X */
-		11,	/* *SDRAM Type */
-		13,	/* *SDRAM Width */
-		17,	/* *Logical Banks */
-		18,	/* *Supported CAS Latencies */
-		21,	/* *SDRAM Module Attributes */
-		23,	/* *Cycle time at CAS Latnecy (CLX - 0.5) */
-		26,	/* *Cycle time at CAS Latnecy (CLX - 1.0) */
-		27,	/* *tRP Row precharge time */
-		28,	/* *Minimum Row Active to Row Active Delay (tRRD) */
-		29,	/* *tRCD RAS to CAS */
-		30,	/* *tRAS Activate to Precharge */
-		41,	/* *Minimum Active to Active/Auto Refresh Time(Trc) */
-		42,	/* *Minimum Auto Refresh Command Time(Trfc) */
-	};
-	nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-	if (!(nbcap & NBCAP_128Bit)) {
-		return;
-	}
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		unsigned device0, device1;
-		int value0, value1;
-		int j;
-		device0 = ctrl->channel0[i];
-		device1 = ctrl->channel1[i];
-		if (!device1)
-			return;
-		for(j = 0; j < sizeof(addresses)/sizeof(addresses[0]); j++) {
-			unsigned addr;
-			addr = addresses[j];
-			value0 = spd_read_byte(device0, addr);
-			if (value0 < 0) {
-				break;
-			}
-			value1 = spd_read_byte(device1, addr);
-			if (value1 < 0) {
-				return;
-			}
-			if (value0 != value1) {
-				return;
-			}
-		}
-	}
-	print_debug("Enabling dual channel memory\r\n");
-	uint32_t dcl;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~DCL_32ByteEn;
-	dcl |= DCL_128BitEn;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-}
-
-struct mem_param {
-	uint8_t cycle_time;
-	uint8_t divisor; /* In 1/2 ns increments */
-	uint8_t tRC;
-	uint8_t tRFC;
-	uint32_t dch_memclk;
-	uint16_t dch_tref4k, dch_tref8k;
-	uint8_t	 dtl_twr;
-	char name[9];
-};
-
-static const struct mem_param *get_mem_param(unsigned min_cycle_time)
-{
-	static const struct mem_param speed[] = {
-		{
-			.name	    = "100Mhz\r\n",
-			.cycle_time = 0xa0,
-			.divisor    = (10 <<1),
-			.tRC	    = 0x46,
-			.tRFC	    = 0x50,
-			.dch_memclk = DCH_MEMCLK_100MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_100MHZ_4K,
-			.dch_tref8k = DTH_TREF_100MHZ_8K,
-			.dtl_twr    = 2,
-		},
-		{
-			.name	    = "133Mhz\r\n",
-			.cycle_time = 0x75,
-			.divisor    = (7<<1)+1,
-			.tRC	    = 0x41,
-			.tRFC	    = 0x4B,
-			.dch_memclk = DCH_MEMCLK_133MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_133MHZ_4K,
-			.dch_tref8k = DTH_TREF_133MHZ_8K,
-			.dtl_twr    = 2,
-		},
-		{
-			.name	    = "166Mhz\r\n",
-			.cycle_time = 0x60,
-			.divisor    = (6<<1),
-			.tRC	    = 0x3C,
-			.tRFC	    = 0x48,
-			.dch_memclk = DCH_MEMCLK_166MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_166MHZ_4K,
-			.dch_tref8k = DTH_TREF_166MHZ_8K,
-			.dtl_twr    = 3,
-		},
-		{
-			.name	    = "200Mhz\r\n",
-			.cycle_time = 0x50,
-			.divisor    = (5<<1),
-			.tRC	    = 0x37,
-			.tRFC	    = 0x46,
-			.dch_memclk = DCH_MEMCLK_200MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_200MHZ_4K,
-			.dch_tref8k = DTH_TREF_200MHZ_8K,
-			.dtl_twr    = 3,
-		},
-		{
-			.cycle_time = 0x00,
-		},
-	};
-	const struct mem_param *param;
-	for(param = &speed[0]; param->cycle_time ; param++) {
-		if (min_cycle_time > (param+1)->cycle_time) {
-			break;
-		}
-	}
-	if (!param->cycle_time) {
-		die("min_cycle_time to low");
-	}
-#if 1
-	print_debug(param->name);
-#endif
-	return param;
-}
-
-static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl)
-{
-	/* Compute the minimum cycle time for these dimms */
-	const struct mem_param *param;
-	unsigned min_cycle_time, min_latency;
-	int i;
-	uint32_t value;
-
-	static const int latency_indicies[] = { 26, 23, 9 };
-	static const unsigned char min_cycle_times[] = {
-		[NBCAP_MEMCLK_200MHZ] = 0x50, /* 5ns */
-		[NBCAP_MEMCLK_166MHZ] = 0x60, /* 6ns */
-		[NBCAP_MEMCLK_133MHZ] = 0x75, /* 7.5ns */
-		[NBCAP_MEMCLK_100MHZ] = 0xa0, /* 10ns */
-	};
-
-
-	value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-	min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
-	min_latency = 2;
-
-#if 0
-	print_debug("min_cycle_time: "); 
-	print_debug_hex8(min_cycle_time); 
-	print_debug(" min_latency: ");
-	print_debug_hex8(min_latency);
-	print_debug("\r\n");
-#endif
-
-	/* Compute the least latency with the fastest clock supported
-	 * by both the memory controller and the dimms.
-	 */
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		int new_cycle_time, new_latency;
-		int index;
-		int latencies;
-		int latency;
-
-		/* First find the supported CAS latencies
-		 * Byte 18 for DDR SDRAM is interpreted:
-		 * bit 0 == CAS Latency = 1.0
-		 * bit 1 == CAS Latency = 1.5
-		 * bit 2 == CAS Latency = 2.0
-		 * bit 3 == CAS Latency = 2.5
-		 * bit 4 == CAS Latency = 3.0
-		 * bit 5 == CAS Latency = 3.5
-		 * bit 6 == TBD
-		 * bit 7 == TBD
-		 */
-		new_cycle_time = 0xa0;
-		new_latency = 5;
-
-		latencies = spd_read_byte(ctrl->channel0[i], 18);
-		if (latencies <= 0) continue;
-
-		/* Compute the lowest cas latency supported */
-		latency = log2(latencies) -2;
-
-		/* Loop through and find a fast clock with a low latency */
-		for(index = 0; index < 3; index++, latency++) {
-			int value;
-			if ((latency < 2) || (latency > 4) ||
-				(!(latencies & (1 << latency)))) {
-				continue;
-			}
-			value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
-			if (value < 0) {
-				continue;
-			}
-
-			/* Only increase the latency if we decreas the clock */
-			if ((value >= min_cycle_time) && (value < new_cycle_time)) {
-				new_cycle_time = value;
-				new_latency = latency;
-			}
-		}
-		if (new_latency > 4){
-			continue;
-		}
-		/* Does min_latency need to be increased? */
-		if (new_cycle_time > min_cycle_time) {
-			min_cycle_time = new_cycle_time;
-		}
-		/* Does min_cycle_time need to be increased? */
-		if (new_latency > min_latency) {
-			min_latency = new_latency;
-		}
-#if 0
-		print_debug("i: ");
-		print_debug_hex8(i);
-		print_debug(" min_cycle_time: "); 
-		print_debug_hex8(min_cycle_time); 
-		print_debug(" min_latency: ");
-		print_debug_hex8(min_latency);
-		print_debug("\r\n");
-#endif
-	}
-	/* Make a second pass through the dimms and disable
-	 * any that cannot support the selected memclk and cas latency.
-	 */
-	
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		int latencies;
-		int latency;
-		int index;
-		int value;
-		int dimm;
-		latencies = spd_read_byte(ctrl->channel0[i], 18);
-		if (latencies <= 0) {
-			goto dimm_err;
-		}
-
-		/* Compute the lowest cas latency supported */
-		latency = log2(latencies) -2;
-
-		/* Walk through searching for the selected latency */
-		for(index = 0; index < 3; index++, latency++) {
-			if (!(latencies & (1 << latency))) {
-				continue;
-			}
-			if (latency == min_latency)
-				break;
-		}
-		/* If I can't find the latency or my index is bad error */
-		if ((latency != min_latency) || (index >= 3)) {
-			goto dimm_err;
-		}
-		
-		/* Read the min_cycle_time for this latency */
-		value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
-		
-		/* All is good if the selected clock speed 
-		 * is what I need or slower.
-		 */
-		if (value <= min_cycle_time) {
-			continue;
-		}
-		/* Otherwise I have an error, disable the dimm */
-	dimm_err:
-		disable_dimm(ctrl, i);
-	}
-#if 0
-	print_debug("min_cycle_time: "); 
-	print_debug_hex8(min_cycle_time); 
-	print_debug(" min_latency: ");
-	print_debug_hex8(min_latency);
-	print_debug("\r\n");
-#endif
-	/* Now that I know the minimum cycle time lookup the memory parameters */
-	param = get_mem_param(min_cycle_time);
-
-	/* Update DRAM Config High with our selected memory speed */
-	value = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	value &= ~(DCH_MEMCLK_MASK << DCH_MEMCLK_SHIFT);
-	value |= param->dch_memclk;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
-
-	static const unsigned latencies[] = { DTL_CL_2, DTL_CL_2_5, DTL_CL_3 };
-	/* Update DRAM Timing Low with our selected cas latency */
-	value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	value &= ~(DTL_TCL_MASK << DTL_TCL_SHIFT);
-	value |= latencies[min_latency - 2] << DTL_TCL_SHIFT;
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, value);
-	
-	return param;
-}
-
-
-static int update_dimm_Trc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	uint32_t dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 41);
-	if (value < 0) return -1;
-	if ((value == 0) || (value == 0xff)) {
-		value = param->tRC;
-	}
-	clocks = ((value << 1) + param->divisor - 1)/param->divisor;
-	if (clocks < DTL_TRC_MIN) {
-		clocks = DTL_TRC_MIN;
-	}
-	if (clocks > DTL_TRC_MAX) {
-		return -1;
-	}
-
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRC_SHIFT) & DTL_TRC_MASK) + DTL_TRC_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRC_MASK << DTL_TRC_SHIFT);
-	dtl |=	((clocks - DTL_TRC_BASE) << DTL_TRC_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 0;
-}
-
-static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	uint32_t dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 42);
-	if (value < 0) return -1;
-	if ((value == 0) || (value == 0xff)) {
-		value = param->tRFC;
-	}
-	clocks = ((value << 1) + param->divisor - 1)/param->divisor;
-	if (clocks < DTL_TRFC_MIN) {
-		clocks = DTL_TRFC_MIN;
-	}
-	if (clocks > DTL_TRFC_MAX) {
-		return -1;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRFC_SHIFT) & DTL_TRFC_MASK) + DTL_TRFC_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRFC_MASK << DTL_TRFC_SHIFT);
-	dtl |= ((clocks - DTL_TRFC_BASE) << DTL_TRFC_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 0;
-}
-
-
-static int update_dimm_Trcd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	uint32_t dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 29);
-	if (value < 0) return -1;
-#if 0
-	clocks = (value + (param->divisor << 1) -1)/(param->divisor << 1);
-#else
-	clocks = (value + ((param->divisor & 0xff) << 1) -1)/((param->divisor & 0xff) << 1);
-#endif
-	if (clocks < DTL_TRCD_MIN) {
-		clocks = DTL_TRCD_MIN;
-	}
-	if (clocks > DTL_TRCD_MAX) {
-		return -1;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRCD_SHIFT) & DTL_TRCD_MASK) + DTL_TRCD_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRCD_MASK << DTL_TRCD_SHIFT);
-	dtl |= ((clocks - DTL_TRCD_BASE) << DTL_TRCD_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 0;
-}
-
-static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	uint32_t dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 28);
-	if (value < 0) return -1;
-	clocks = (value + ((param->divisor & 0xff) << 1) -1)/((param->divisor & 0xff) << 1);
-	if (clocks < DTL_TRRD_MIN) {
-		clocks = DTL_TRRD_MIN;
-	}
-	if (clocks > DTL_TRRD_MAX) {
-		return -1;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRRD_SHIFT) & DTL_TRRD_MASK) + DTL_TRRD_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRRD_MASK << DTL_TRRD_SHIFT);
-	dtl |= ((clocks - DTL_TRRD_BASE) << DTL_TRRD_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 0;
-}
-
-static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	uint32_t dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 30);
-	if (value < 0) return -1;
-	clocks = ((value << 1) + param->divisor - 1)/param->divisor;
-	if (clocks < DTL_TRAS_MIN) {
-		clocks = DTL_TRAS_MIN;
-	}
-	if (clocks > DTL_TRAS_MAX) {
-		return -1;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRAS_SHIFT) & DTL_TRAS_MASK) + DTL_TRAS_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRAS_MASK << DTL_TRAS_SHIFT);
-	dtl |= ((clocks - DTL_TRAS_BASE) << DTL_TRAS_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 0;
-}
-
-static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	uint32_t dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 27);
-	if (value < 0) return -1;
-#if 0
-	clocks = (value + (param->divisor << 1) - 1)/(param->divisor << 1);
-#else
-	clocks = (value + ((param->divisor & 0xff) << 1) - 1)/((param->divisor & 0xff) << 1);
-#endif
-#if 0
-	print_debug("Trp: ");
-	print_debug_hex8(clocks);
-	print_debug(" spd value: ");
-	print_debug_hex8(value);
-	print_debug(" divisor: ");
-	print_debug_hex8(param->divisor);
-	print_debug("\r\n");
-#endif
-	if (clocks < DTL_TRP_MIN) {
-		clocks = DTL_TRP_MIN;
-	}
-	if (clocks > DTL_TRP_MAX) {
-		return -1;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRP_SHIFT) & DTL_TRP_MASK) + DTL_TRP_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRP_MASK << DTL_TRP_SHIFT);
-	dtl |= ((clocks - DTL_TRP_BASE) << DTL_TRP_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 0;
-}
-
-static void set_Twr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dtl;
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	dtl &= ~(DTL_TWR_MASK << DTL_TWR_SHIFT);
-	dtl |= (param->dtl_twr - DTL_TWR_BASE) << DTL_TWR_SHIFT;
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-}
-
-
-static void init_Tref(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dth;
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
-	dth |= (param->dch_tref4k << DTH_TREF_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-static int update_dimm_Tref(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	uint32_t dth;
-	int value;
-	unsigned tref, old_tref;
-	value = spd_read_byte(ctrl->channel0[i], 3);
-	if (value < 0) return -1;
-	value &= 0xf;
-
-	tref = param->dch_tref8k;
-	if (value == 12) {
-		tref = param->dch_tref4k;
-	}
-
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	old_tref = (dth >> DTH_TREF_SHIFT) & DTH_TREF_MASK;
-	if ((value == 12) && (old_tref == param->dch_tref4k)) {
-		tref = param->dch_tref4k;
-	} else {
-		tref = param->dch_tref8k;
-	}
-	dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
-	dth |= (tref << DTH_TREF_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-	return 0;
-}
-
-
-static int update_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	uint32_t dcl;
-	int value;
-	int dimm;
-	value = spd_read_byte(ctrl->channel0[i], 13);
-	if (value < 0) {
-		return -1;
-	}
-	dimm = i;
-	dimm += DCL_x4DIMM_SHIFT;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~(1 << dimm);
-	if (value == 4) {
-		dcl |= (1 << dimm);
-	}
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	return 0;
-}
-
-static int update_dimm_ecc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	uint32_t dcl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 11);
-	if (value < 0) {
-		return -1;
-	}
-	if (value != 2) {
-		dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-		dcl &= ~DCL_DimmEccEn;
-		pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	}
-	return 0;
-}
-
-static int count_dimms(const struct mem_controller *ctrl)
-{
-	int dimms;
-	unsigned index;
-	dimms = 0;
-	for(index = 0; index < 8; index += 2) {
-		uint32_t csbase;
-		csbase = pci_read_config32(ctrl->f2, (DRAM_CSBASE + index << 2));
-		if (csbase & 1) {
-			dimms += 1;
-		}
-	}
-	return dimms;
-}
-
-static void set_Twtr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dth;
-	unsigned clocks;
-	clocks = 1; /* AMD says hard code this */
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TWTR_MASK << DTH_TWTR_SHIFT);
-	dth |= ((clocks - DTH_TWTR_BASE) << DTH_TWTR_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-static void set_Trwt(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dth, dtl;
-	unsigned divisor;
-	unsigned latency;
-	unsigned clocks;
-
-	clocks = 0;
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	latency = (dtl >> DTL_TCL_SHIFT) & DTL_TCL_MASK;
-	divisor = param->divisor;
-
-	if (is_opteron(ctrl)) {
-		if (latency == DTL_CL_2) {
-			if (divisor == ((6 << 0) + 0)) {
-				/* 166Mhz */
-				clocks = 3;
-			}
-			else if (divisor > ((6 << 0)+0)) {
-				/* 100Mhz && 133Mhz */
-				clocks = 2;
-			}
-		}
-		else if (latency == DTL_CL_2_5) {
-			clocks = 3;
-		}
-		else if (latency == DTL_CL_3) {
-			if (divisor == ((6 << 0)+0)) {
-				/* 166Mhz */
-				clocks = 4;
-			}
-			else if (divisor > ((6 << 0)+0)) {
-				/* 100Mhz && 133Mhz */
-				clocks = 3;
-			}
-		}
-	}
-	else /* Athlon64 */ {
-		if (is_registered(ctrl)) {
-			if (latency == DTL_CL_2) {
-				clocks = 2;
-			}
-			else if (latency == DTL_CL_2_5) {
-				clocks = 3;
-			}
-			else if (latency == DTL_CL_3) {
-				clocks = 3;
-			}
-		}
-		else /* Unbuffered */{
-			if (latency == DTL_CL_2) {
-				clocks = 3;
-			}
-			else if (latency == DTL_CL_2_5) {
-				clocks = 4;
-			}
-			else if (latency == DTL_CL_3) {
-				clocks = 4;
-			}
-		}
-	}
-	if ((clocks < DTH_TRWT_MIN) || (clocks > DTH_TRWT_MAX)) {
-		die("Unknown Trwt");
-	}
-	
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TRWT_MASK << DTH_TRWT_SHIFT);
-	dth |= ((clocks - DTH_TRWT_BASE) << DTH_TRWT_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-	return;
-}
-
-static void set_Twcl(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	/* Memory Clocks after CAS# */
-	uint32_t dth;
-	unsigned clocks;
-	if (is_registered(ctrl)) {
-		clocks = 2;
-	} else {
-		clocks = 1;
-	}
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TWCL_MASK << DTH_TWCL_SHIFT);
-	dth |= ((clocks - DTH_TWCL_BASE) << DTH_TWCL_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-
-static void set_read_preamble(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dch;
-	unsigned divisor;
-	unsigned rdpreamble;
-	divisor = param->divisor;
-	dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	dch &= ~(DCH_RDPREAMBLE_MASK << DCH_RDPREAMBLE_SHIFT);
-	rdpreamble = 0;
-	if (is_registered(ctrl)) {
-		if (divisor == ((10 << 1)+0)) {
-			/* 100Mhz, 9ns */
-			rdpreamble = ((9 << 1)+ 0);
-		}
-		else if (divisor == ((7 << 1)+1)) {
-			/* 133Mhz, 8ns */
-			rdpreamble = ((8 << 1)+0);
-		}
-		else if (divisor == ((6 << 1)+0)) {
-			/* 166Mhz, 7.5ns */
-			rdpreamble = ((7 << 1)+1);
-		}
-	}
-	else {
-		int slots;
-		int i;
-		slots = 0;
-		for(i = 0; i < 4; i++) {
-			if (ctrl->channel0[i]) {
-				slots += 1;
-			}
-		}
-		if (divisor == ((10 << 1)+0)) {
-			/* 100Mhz */
-			if (slots <= 2) {
-				/* 9ns */
-				rdpreamble = ((9 << 1)+0);
-			} else {
-				/* 14ns */
-				rdpreamble = ((14 << 1)+0);
-			}
-		}
-		else if (divisor == ((7 << 1)+1)) {
-			/* 133Mhz */
-			if (slots <= 2) {
-				/* 7ns */
-				rdpreamble = ((7 << 1)+0);
-			} else {
-				/* 11 ns */
-				rdpreamble = ((11 << 1)+0);
-			}
-		}
-		else if (divisor == ((6 << 1)+0)) {
-			/* 166Mhz */
-			if (slots <= 2) {
-				/* 6ns */
-				rdpreamble = ((7 << 1)+0);
-			} else {
-				/* 9ns */
-				rdpreamble = ((9 << 1)+0);
-			}
-		}
-		else if (divisor == ((5 << 1)+0)) {
-			/* 200Mhz */
-			if (slots <= 2) {
-				/* 5ns */
-				rdpreamble = ((5 << 1)+0);
-			} else {
-				/* 7ns */
-				rdpreamble = ((7 << 1)+0);
-			}
-		}
-	}
-	if ((rdpreamble < DCH_RDPREAMBLE_MIN) || (rdpreamble > DCH_RDPREAMBLE_MAX)) {
-		die("Unknown rdpreamble");
-	}
-	dch |= (rdpreamble - DCH_RDPREAMBLE_BASE) << DCH_RDPREAMBLE_SHIFT;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void set_max_async_latency(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dch;
-	int i;
-	unsigned async_lat;
-	int dimms;
-
-	dimms = count_dimms(ctrl);
-
-	dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	dch &= ~(DCH_ASYNC_LAT_MASK << DCH_ASYNC_LAT_SHIFT);
-	async_lat = 0;
-	if (is_registered(ctrl)) {
-		if (dimms == 4) {
-			/* 9ns */
-			async_lat = 9;
-		} 
-		else {
-			/* 8ns */
-			async_lat = 8;
-		}
-	}
-	else {
-		if (dimms > 3) {
-			die("Too many unbuffered dimms");
-		}
-		else if (dimms == 3) {
-			/* 7ns */
-			async_lat = 7;
-		}
-		else {
-			/* 6ns */
-			async_lat = 6;
-		}
-	}
-	dch |= ((async_lat - DCH_ASYNC_LAT_BASE) << DCH_ASYNC_LAT_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void set_idle_cycle_limit(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	uint32_t dch;
-	/* AMD says to Hardcode this */
-	dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	dch &= ~(DCH_IDLE_LIMIT_MASK << DCH_IDLE_LIMIT_SHIFT);
-	dch |= DCH_IDLE_LIMIT_16 << DCH_IDLE_LIMIT_SHIFT;
-	dch |= DCH_DYN_IDLE_CTR_EN;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void spd_set_dram_timing(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	int dimms;
-	int i;
-	init_Tref(ctrl, param);
-	for(i = 0; (i < 4) && ctrl->channel0[i]; i++) {
-		int rc;
-		/* DRAM Timing Low Register */
-		if (update_dimm_Trc (ctrl, param, i) < 0) goto dimm_err;
-		if (update_dimm_Trfc(ctrl, param, i) < 0) goto dimm_err;
-		if (update_dimm_Trcd(ctrl, param, i) < 0) goto dimm_err;
-		if (update_dimm_Trrd(ctrl, param, i) < 0) goto dimm_err;
-		if (update_dimm_Tras(ctrl, param, i) < 0) goto dimm_err;
-		if (update_dimm_Trp (ctrl, param, i) < 0) goto dimm_err;
-
-		/* DRAM Timing High Register */
-		if (update_dimm_Tref(ctrl, param, i) < 0) goto dimm_err;
-
-		/* DRAM Config Low */
-		if (update_dimm_x4 (ctrl, param, i) < 0) goto dimm_err;
-		if (update_dimm_ecc(ctrl, param, i) < 0) goto dimm_err;
-		continue;
-	dimm_err:
-		disable_dimm(ctrl, i);
-		
-	}
-	/* DRAM Timing Low Register */
-	set_Twr(ctrl, param);
-
-	/* DRAM Timing High Register */
-	set_Twtr(ctrl, param);
-	set_Trwt(ctrl, param);
-	set_Twcl(ctrl, param);
-
-	/* DRAM Config High */
-	set_read_preamble(ctrl, param);
-	set_max_async_latency(ctrl, param);
-	set_idle_cycle_limit(ctrl, param);
-}
-
-static void sdram_set_spd_registers(const struct mem_controller *ctrl) 
-{
-	const struct mem_param *param;
-	spd_enable_2channels(ctrl);
-	spd_set_ram_size(ctrl);
-	spd_handle_unbuffered_dimms(ctrl);
-	param = spd_set_memclk(ctrl);
-	spd_set_dram_timing(ctrl, param);
-	order_dimms(ctrl);
-}
-
-#define TIMEOUT_LOOPS 300000
-static void sdram_enable(int controllers, const struct mem_controller *ctrl)
-{
-	int i;
-
-	/* Before enabling memory start the memory clocks */
-	for(i = 0; i < controllers; i++) {
-		uint32_t dch;
-		dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
-		dch |= DCH_MEMCLK_VALID;
-		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
-	}
-
-	/* And if necessary toggle the the reset on the dimms by hand */
-	memreset(controllers, ctrl);
-
-	for(i = 0; i < controllers; i++) {
-		uint32_t dcl;
-		/* Toggle DisDqsHys to get it working */
-		dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-#if 0
-		print_debug("dcl: ");
-		print_debug_hex32(dcl);
-		print_debug("\r\n");
-#endif
-#warning "FIXME set the ECC type to perform"
-#warning "FIXME initialize the scrub registers"
-#if 1
-		if (dcl & DCL_DimmEccEn) {
-			print_debug("ECC enabled\r\n");
-		}
-#endif
-		dcl |= DCL_DisDqsHys;
-		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-		dcl &= ~DCL_DisDqsHys;
-		dcl &= ~DCL_DLL_Disable;
-		dcl &= ~DCL_D_DRV;
-		dcl &= ~DCL_QFC_EN;
-		dcl |= DCL_DramInit;
-		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-
-	}
-	for(i = 0; i < controllers; i++) {
-		uint32_t dcl;
-		print_debug("Initializing memory: ");
-		int loops = 0;
-		do {
-			dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-			loops += 1;
-			if ((loops & 1023) == 0) {
-				print_debug(".");
-			}
-		} while(((dcl & DCL_DramInit) != 0) && (loops < TIMEOUT_LOOPS));
-		if (loops >= TIMEOUT_LOOPS) {
-			print_debug(" failed\r\n");
-		} else {
-			print_debug(" done\r\n");
-		}
-#if 0
-		if (dcl & DCL_DimmEccEn) {
-			print_debug("Clearing memory: ");
-			loops = 0;
-			dcl &= ~DCL_MemClrStatus;
-			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-			
-			do {
-				dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-				loops += 1;
-				if ((loops & 1023) == 0) {
-					print_debug(" ");
-					print_debug_hex32(loops);
-				}
-			} while(((dcl & DCL_MemClrStatus) == 0) && (loops < TIMEOUT_LOOPS));
-			if (loops >= TIMEOUT_LOOPS) {
-				print_debug("failed\r\n");
-			} else {
-				print_debug("done\r\n");
-			}
-			pci_write_config32(ctrl[i].f3, SCRUB_ADDR_LOW, 0);
-			pci_write_config32(ctrl[i].f3, SCRUB_ADDR_HIGH, 0);
-		}
-#endif
-	}
-}
diff --exclude='*CVS*' -urN mylinuxbios/LinuxBIOS/freebios2/src/northbridge/amd/amdk8/raminit.c freebios2/src/northbridge/amd/amdk8/raminit.c
--- mylinuxbios/LinuxBIOS/freebios2/src/northbridge/amd/amdk8/raminit.c	2003-08-14 11:09:06.000000000 +0200
+++ freebios2/src/northbridge/amd/amdk8/raminit.c	2003-08-28 15:24:37.000000000 +0200
@@ -919,12 +919,13 @@
 	 * [31: 8] Reserved
 	 */
 	PCI_ADDR(0, 0x18, 3, 0x60), 0xffffff00, 0x00000000,
-//BY LYH  add IOMMU 64M APERTURE
+
+#if ENABLE_IOMMU != 0
+	/* BY LYH  add IOMMU 64M APERTURE */
 	PCI_ADDR(0, 0x18, 3, 0x94), 0xffff8000, 0x00000f70,
 	PCI_ADDR(0, 0x18, 3, 0x90), 0xffffff80, 0x00000002,
 	PCI_ADDR(0, 0x18, 3, 0x98), 0x0000000f, 0x00068300,
-
-//BY LYH END
+#endif
 	};
 	int i;
 	int max;


More information about the coreboot mailing list