[coreboot] [v2] r4313 - in trunk/coreboot-v2/src/northbridge/via: . vx800 vx800/ddr2init vx800/ddr2init/vx800 vx800/examples

svn at coreboot.org svn at coreboot.org
Wed May 27 15:12:42 CEST 2009


Author: uwe
Date: 2009-05-27 15:12:42 +0200 (Wed, 27 May 2009)
New Revision: 4313

Added:
   trunk/coreboot-v2/src/northbridge/via/vx800/
   trunk/coreboot-v2/src/northbridge/via/vx800/Config.lb
   trunk/coreboot-v2/src/northbridge/via/vx800/DrivingClkPhaseData.h
   trunk/coreboot-v2/src/northbridge/via/vx800/chip.h
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.h
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.h
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/Translatorddr2init.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/ClkCtrl.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DQSSearch.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DRDY_BL.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/Detection.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DevInit.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DrivingSetting.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FinalSetting.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FreqSetting.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/RankMap.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/TimingSetting.c
   trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/UMARamSetting.c
   trunk/coreboot-v2/src/northbridge/via/vx800/examples/
   trunk/coreboot-v2/src/northbridge/via/vx800/examples/DrivingClkPhaseData.c
   trunk/coreboot-v2/src/northbridge/via/vx800/examples/cache_as_ram_auto.c
   trunk/coreboot-v2/src/northbridge/via/vx800/examples/chipset_init.c
   trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.c
   trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.h
   trunk/coreboot-v2/src/northbridge/via/vx800/raminit.c
   trunk/coreboot-v2/src/northbridge/via/vx800/raminit.h
   trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.inc
   trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.lds
   trunk/coreboot-v2/src/northbridge/via/vx800/vga.c
   trunk/coreboot-v2/src/northbridge/via/vx800/vgabios.c
   trunk/coreboot-v2/src/northbridge/via/vx800/vgachip.h
   trunk/coreboot-v2/src/northbridge/via/vx800/vx800.h
   trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_serial.c
   trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_smbus.c
   trunk/coreboot-v2/src/northbridge/via/vx800/vx800_ide.c
   trunk/coreboot-v2/src/northbridge/via/vx800/vx800_lpc.c
Log:
Here's the VIA vx800 patch from OLPC.

It's untested, but a good starting point for everyone.

Signed-off-by: Bari Ari <bari at onelabs.com>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>
Acked-by: Uwe Hermann <uwe at hermann-uwe.de>



Added: trunk/coreboot-v2/src/northbridge/via/vx800/Config.lb
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/Config.lb	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/Config.lb	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,25 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2009 One Laptop per Child, Association, Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+##
+
+config chip.h
+object vgabios.o
+driver northbridge.o
+driver vga.o
+driver vx800_lpc.o
+driver vx800_ide.o

Added: trunk/coreboot-v2/src/northbridge/via/vx800/DrivingClkPhaseData.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/DrivingClkPhaseData.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/DrivingClkPhaseData.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef DRIVINGCLKPHASEDATA_H
+#define DRIVINGCLKPHASEDATA_H
+
+//extern u8 DDR2_DQSA_Driving_Table[4] ;
+//extern u8 DDR2_DQSB_Driving_Table[2] ;
+
+//extern u8 DDR2_DQA_Driving_Table[4] ;
+//extern u8 DDR2_DQB_Driving_Table[2] ;
+
+//extern u8 DDR2_CSA_Driving_Table_x8[4] ;
+//extern u8 DDR2_CSB_Driving_Table_x8[2] ;
+//extern u8 DDR2_CSA_Driving_Table_x16[4];
+//extern u8 DDR2_CSB_Driving_Table_x16[2];
+
+#define  MA_Table   3
+//extern u8 DDR2_MAA_Driving_Table[MA_Table][4];
+//extern u8 DDR2_MAB_Driving_Table[MA_Table][2];
+
+//extern u8 DDR2_DCLKA_Driving_Table[4] ;
+//extern u8 DDR2_DCLKB_Driving_Table[4];
+
+#define DUTY_CYCLE_FREQ_NUM   6
+#define DUTY_CYCLE_REG_NUM     3
+//extern u8 ChA_Duty_Control_DDR2[DUTY_CYCLE_REG_NUM][DUTY_CYCLE_FREQ_NUM];
+//extern u8 ChB_Duty_Control_DDR2[DUTY_CYCLE_REG_NUM][DUTY_CYCLE_FREQ_NUM];
+
+#define Clk_Phase_Table_DDR2_Width	  6
+//extern u8 DDR2_ChA_Clk_Phase_Table_1R[3][Clk_Phase_Table_DDR2_Width];
+//extern u8 DDR2_ChB_Clk_Phase_Table_1R[3][Clk_Phase_Table_DDR2_Width];
+//extern u8 DDR2_ChA_Clk_Phase_Table_2R[3][Clk_Phase_Table_DDR2_Width];
+
+#define WrtData_REG_NUM        4
+#define WrtData_FREQ_NUM      6
+//extern u8 DDR2_ChA_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM];
+//extern u8 DDR2_ChB_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM];
+
+#define DQ_DQS_Delay_Table_Width  4
+//extern u8 DDR2_CHA_DQ_DQS_Delay_Table[4][DQ_DQS_Delay_Table_Width];
+//extern u8 DDR2_CHB_DQ_DQS_Delay_Table[4][DQ_DQS_Delay_Table_Width];
+
+#define DQS_INPUT_CAPTURE_REG_NUM            3
+#define DQS_INPUT_CAPTURE_FREQ_NUM             6
+//extern u8 DDR2_ChA_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM];
+//extern u8 DDR2_ChB_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM];
+
+//extern u8 Fixed_DQSA_1_2_Rank_Table[4][2];
+//extern u8 Fixed_DQSA_3_4_Rank_Table[4][2];
+
+//extern u8 Fixed_DQSB_1_2_Rank_Table[4][2];
+//extern u8 Fixed_DQSB_3_4_Rank_Table[4][2];
+#endif /* DRIVINGCLKPHASEDATA_H */

Added: trunk/coreboot-v2/src/northbridge/via/vx800/chip.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/chip.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/chip.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+struct northbridge_via_vx800_config
+{
+};
+
+extern struct chip_operations northbridge_via_vx800_ops;

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "lib/memset.c"
+CB_STATUS DDR2_DRAM_INIT()
+{
+	CB_STATUS Status;
+	u8 i;
+	u32 RamSize;
+	BOOLEAN bTest;
+	DRAM_SYS_ATTR DramAttr;
+
+	PRINT_DEBUG_MEM("DRAM_INIT \r");
+
+	memset(&DramAttr, 0, sizeof(DRAM_SYS_ATTR));
+	/*Step1 DRAM Detection; DDR1 or DDR2; Get SPD Data; Rank Presence;64 or 128bit; Unbuffered or registered; 1T or 2T */
+	DRAMDetect(&DramAttr);
+
+	//Step2 set Frequency; calculate CL and Frequncy from SPD data; set the Frequency
+	DRAMFreqSetting(&DramAttr);
+	//Step3 Set DRAM Timing; CL, tRP, tRCD, tRAS, tRFC, tRRD, tWR, tWTR, tRTP
+	DRAMTimingSetting(&DramAttr);
+	//Step4 DRDY
+	DRAMDRDYSetting(&DramAttr);
+	//Step5 Burst length
+	DRAMBurstLength(&DramAttr);
+	//Step6 DRAM Driving Adjustment
+	DRAMDriving(&DramAttr);
+	//Step7 duty cycle control
+	DutyCycleCtrl(&DramAttr);
+	//Step8 DRAM clock phase and delay control
+	DRAMClkCtrl(&DramAttr);
+	//Step9 set register before init DRAM device
+	DRAMRegInitValue(&DramAttr);
+	//Step10 DDR and DDR2 initialize process
+	DRAMInitializeProc(&DramAttr);
+
+	//Step13 Interleave function in rankmap.c
+	DRAMBankInterleave(&DramAttr);
+	//Step14 Sizing
+	DRAMSizingMATypeM(&DramAttr);
+
+	//Step11 Search DQS and DQ output delay
+	DRAMDQSOutputSearch(&DramAttr);
+	//Step12 Search DQS  input delay
+	DRAMDQSInputSearch(&DramAttr);
+
+	//Step15 DDR fresh counter setting
+	DRAMRefreshCounter(&DramAttr);
+	//Step16 Final register setting for improve performance
+	DRAMRegFinalValue(&DramAttr);
+
+	RamSize = 0;
+	for (i = 0; i < MAX_RANKS; i++) {
+		if (DramAttr.RankSize[i] == 0) {
+			continue;
+		}
+		RamSize += DramAttr.RankSize[i];
+	}
+	PRINT_DEBUG_MEM("RamSize=");
+	PRINT_DEBUG_MEM_HEX32(RamSize);
+	PRINT_DEBUG_MEM("\r");
+	DumpRegisters(0, 3);
+	//bTest = DramBaseTest( M1, RamSize - M1 * 2,SPARE, FALSE);
+	/* the memory can not correct work, this is because the user set the incorrect memory
+	   parameter from setup interface.so we must set the boot mode to recovery mode, let
+	   the system to reset and use the spd value to initialize the memory */
+	SetUMARam();
+	return CB_SUCCESS;
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramInit.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,263 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __DRAMINIT_H_
+#define __DRAMINIT_H_
+
+//Dram Size
+#define M   (1024*1024)
+#define M1  (1*M)
+#define M64  (64*M)
+#define M128  (128*M)
+#define M256  (256*M)
+#define M384  (384*M)
+#define M512  (512*M)
+
+// UMA size
+#define 	UMASIZE  M64
+
+#define  ENABLE_CHC   0		//CHC enable, how ever, this CHC,used some reg define in CHB
+#define  ENABLE_CHB   0		//CHB enable , CHB is VX800's, VX855 no this CHB.
+//Dram Freq
+#define DIMMFREQ_800	400
+#define DIMMFREQ_667	333
+//#define DIMMFREQ_600  300
+#define DIMMFREQ_533	266
+#define DIMMFREQ_400	200
+#define DIMMFREQ_333	166
+#define DIMMFREQ_266	133
+#define DIMMFREQ_200	100
+
+//Dram Type
+#define  RAMTYPE_FPMDRAM   1
+#define  RAMTYPE_EDO       2
+#define  RAMTYPE_PipelinedNibble 3
+#define  RAMTYPE_SDRAM     4
+#define  RAMTYPE_ROM       5
+#define  RAMTYPE_SGRAMDDR  6
+#define  RAMTYPE_SDRAMDDR  7
+#define  RAMTYPE_SDRAMDDR2 8
+
+/* CAS latency constant */
+#define CASLAN_15         15
+#define CASLAN_2           20
+#define CASLAN_25         25
+#define CASLAN_3           30
+#define CASLAN_35         35
+#define CASLAN_4           40
+#define CASLAN_45         45
+#define CASLAN_5           50
+#define CASLAN_NULL     00
+
+//Burst length
+#define  BURSTLENGTH8    8
+#define  BURSTLENGTH4    4
+
+//Data Width
+//#define  DATAWIDTHX16    16
+//#define  DATAWIDTHX8       8
+//#define  DATAWIDTHX4       4
+
+
+#define SPD_MEMORY_TYPE              2	/*Memory type FPM,EDO,SDRAM,DDR,DDR2 */
+#define SPD_SDRAM_ROW_ADDR           3	/*Number of row addresses on this assembly */
+#define SPD_SDRAM_COL_ADDR           4	/*Number of column addresses on this assembly */
+#define SPD_SDRAM_DIMM_RANKS         5	/*Number of RANKS on this assembly */
+#define SPD_SDRAM_MOD_DATA_WIDTH     6	/*Data width of this assembly */
+#define SPD_SDRAM_TCLK_X             9	/*Cycle time at Maximum supported CAS latency (CL=X) */
+#define SPD_SDRAM_TAC_X              10	/*Access time for highest CL */
+#define SPD_SDRAM_CONFIG_TYPE        11	/*Non-parity , Parity or ECC */
+#define SPD_SDRAM_REFRESH            12	/*Refresh rate/type */
+#define SPD_SDRAM_WIDTH              13	/*Primary sdram width */
+#define SPD_SDRAM_MIN_CLK_DLY        15	/*Minimum clock delay */
+#define SPD_SDRAM_BURSTLENGTH        16	/*Burst Lengths supported */
+#define SPD_SDRAM_NO_OF_BANKS        17	/*Number of banks on this assembly */
+#define SPD_SDRAM_CAS_LATENCY        18	/*CAS latency */
+#define SPD_SDRAM_DIMM_TYPE_DDR2     20	/*DIMM type information; identifies the DDR2 memory module type */
+#define SPD_SDRAM_DEV_ATTR_DDR1      20	/*WE latency */
+#define SPD_SDRAM_MODULES_ATTR       21	/*This byte depicts various aspects of the modules; DDR DDR2 have different aspects */
+#define SPD_SDRAM_DEV_ATTR_GEN       22	/*General device attributes */
+#define SPD_SDRAM_TCLK_X_1           23	/*Minimum clock cycle time at Reduced CL, DDR: X-0.5 DDR2: X-1 */
+#define SPD_SDRAM_TAC_X_1            24	/*Maximum Data Access time from Clock at reduced CL,DDR: X-0.5 DDR2: X-1 */
+#define SPD_SDRAM_TCLK_X_2           25	/*Minimum clock cycle time at reduced CL, DDR: X-1 DDR2: X-2 */
+#define SPD_SDRAM_TAC_X_2            26	/*Maximum Data Access time from Clock at reduced CL, DDR: X-1 DDR2: X-2 */
+#define SPD_SDRAM_TRP                27	/*minimum row precharge time */
+#define SPD_SDRAM_TRRD               28	/*minimum row active to row active delay */
+#define SPD_SDRAM_TRCD               29	/*minimum RAS to CAS delay */
+#define SPD_SDRAM_TRAS               30	/*minimum active to precharge time */
+#define SPD_SDRAM_TWR                36	/*write recovery time, only DDR2 use it */
+#define SPD_SDRAM_TWTR               37	/*internal write to read command delay, only DDR2 use it */
+#define SPD_SDRAM_TRTP               38	/*internal read to prechange command delay, only DDR2 use it */
+#define SPD_SDRAM_TRFC2              40	/*extension of byte 41 tRC and byte 42 tRFC, only DDR2 use it */
+#define SPC_SDRAM_TRC				 41	/*minimum active to active/refresh time */
+#define SPD_SDRAM_TRFC               42	/*minimum refresh to active / refresh command period */
+
+#define  SPD_DATA_SIZE 44
+//Dram cofig are
+/*the most number of socket*/
+//#define  MAX_RAM_SLOTS  2
+#define MAX_SOCKETS MAX_RAM_SLOTS
+#define  MAX_DIMMS     MAX_SOCKETS	/*every sockets can plug one DIMM */
+/*the most number of RANKs on a DIMM*/
+#define  MAX_RANKS  MAX_SOCKETS*2
+
+struct mem_controller {
+	u8 channel0[MAX_DIMMS];
+};
+
+static const struct mem_controller ctrl = {
+	.channel0 = {0x50, 0x51},
+};
+
+typedef struct _DRAM_CONFIG_DATA {
+	u8 DramClk;
+	u8 DramTiming;
+	u8 CasLatency;
+	u8 BankIntlv;
+	u8 Trp;
+	u8 Tras;
+	u8 Trcd;
+	u8 Trfc;
+	u8 Trrd;
+	u8 Trtp;
+	u8 Twtr;
+	u8 Twr;
+
+	u8 CmdRate;
+	u8 DualEn;
+	//u8    IntLv0;
+	//u8    IntLv1;
+	//u8    Ba0Sel;
+	//u8    Ba1Sel;
+	//u8    Ba2Sel;
+	u8 BaScmb;
+	u8 DrdyTiming;
+	//u8    Above4G;
+	//u8    RdsaitMode;
+	//u8    Rdsait;
+	//u8    TopPerf;
+
+	u16 UMASize;
+} DRAM_CONFIG_DATA;
+
+/*DIMM(assembly) information*/
+typedef struct _DIMM_INFO_tag {
+	u8 bPresence;
+	u8 SPDDataBuf[SPD_DATA_SIZE];	/*get all information from spd data */
+} DIMM_INFO;
+
+typedef struct _DRAM_SYS_ATTR_tag {
+	DIMM_INFO DimmInfo[MAX_DIMMS];
+
+	u8 RankPresentMap;	/*bit0,1 Rank0,1 on DIMM0, bit2,3 Rank2,3 on DIMM1,
+				   bit4,5 Rank4,5 on DIMM2, bit6,7 Rank6,7 on DIMM3 */
+	u8 DimmNumChA;		/*Dimm number */
+	u8 DimmNumChB;
+	u8 RankNumChA;		/*the number of Ranks on the mortherbaord */
+	u8 RankNumChB;
+	u8 LoadNumChA;		/*the number of chips on all DIMM */
+	u8 LoadNumChB;
+
+	u8 DramType;		/*DDR1 or DDR2 */
+	u16 DramFreq;
+	u16 DramCyc;		/*10ns, 7.5ns, 6ns, 5ns, 3.75ns, 3ns, 2.5ns   =1/SysFreq, unit: 100*ns. */
+
+	//u16    HFreq; /*100, 133, 166, 200, 266, 333, 400*/
+
+	u8 CL;			/* CAS lantency */
+	u8 CmdRate;		/*1T or 2T */
+
+	u32 RankSize[MAX_RANKS];
+	u8 Dual_Channel;
+	DRAM_CONFIG_DATA ConfigData;
+	u8 reserved[4];
+
+} DRAM_SYS_ATTR;
+
+typedef struct _DRAM_SIZE_INFO {
+	u32 RankLength[MAX_RANKS];
+} DRAM_SIZE_INFO;
+
+//detection.c
+/*Step1 detect DRAM type, Read SPD data,command rate*/
+CB_STATUS DRAMDetect(DRAM_SYS_ATTR * DramAttr);
+//FreqSetting.c
+/*Step2 set Frequency, calculate CAL*/
+void DRAMFreqSetting(DRAM_SYS_ATTR * DramAttr);
+//TimingSetting.c
+/*Step3 Set DRAM	Timing*/
+void DRAMTimingSetting(DRAM_SYS_ATTR * DramAttr);
+//DRDY_BL.c
+/*Step4 DRDY*/
+void DRAMDRDYSetting(DRAM_SYS_ATTR * DramAttr);
+//DRDY_BL.c
+/*Step5 Burst Length*/
+void DRAMBurstLength(DRAM_SYS_ATTR * DramAttr);
+//DrivingSetting.c
+/*Step6 DRAM Driving Adjustment*/
+void DRAMDriving(DRAM_SYS_ATTR * DramAttr);
+
+//ClkCtrl.c
+/*Step7 duty cycle control*/
+void DutyCycleCtrl(DRAM_SYS_ATTR * DramAttr);
+//ClkCtrl.c
+/*Step8 DRAM clock phase and delay control*/
+void DRAMClkCtrl(DRAM_SYS_ATTR * DramAttr);
+
+//DevInit.c
+/*Step9 set register before init DRAM device*/
+void DRAMRegInitValue(DRAM_SYS_ATTR * DramAttr);
+
+//DevInit.c
+/*Step10 DDR and DDR2 initialize process*/
+void DRAMInitializeProc(DRAM_SYS_ATTR * DramAttr);
+
+//DQSSearch.c
+/*Step11 Search DQS and DQ output delay*/
+void DRAMDQSOutputSearch(DRAM_SYS_ATTR * DramAttr);
+
+//DQSSearch.c
+/*Step12 Search DQS  input delay*/
+void DRAMDQSInputSearch(DRAM_SYS_ATTR * DramAttr);
+
+//RankMap.c
+/*Step13 Interleav function in rankmap.c*/
+void DRAMBankInterleave(DRAM_SYS_ATTR * DramAttr);
+
+//RankMap.c
+/*Step14 Sizing*/
+void DRAMSizingMATypeM(DRAM_SYS_ATTR * DramAttr);
+
+
+//FinalSetting.c
+/*Step15 DDR fresh counter setting*/
+void DRAMRefreshCounter(DRAM_SYS_ATTR * DramAttr);
+
+//FinnalSetting.c
+/*Step16 Final register setting for improve performance*/
+void DRAMRegFinalValue(DRAM_SYS_ATTR * DramAttr);
+
+
+/*set UMA*/
+void SetUMARam();
+
+CB_STATUS InstallMemory(DRAM_SYS_ATTR * DramAttr, u32 RamSize);
+CB_STATUS DDR2_DRAM_INIT();
+
+#endif

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,249 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+void WaitMicroSec(UINTN MicroSeconds)
+{
+	u32 i;
+
+	for (i = 0; i < 1024 * MicroSeconds; i++) {
+		__asm__ volatile ("nop\n\t");
+	}
+
+	return;
+}
+
+/*===================================================================
+Function   : via_write_phys()
+Precondition : 
+Input      :  addr
+                  value
+Output     : void
+Purpose    : 
+Reference  : None
+===================================================================*/
+
+void via_write_phys(volatile u32 addr, volatile u32 value)
+{
+	volatile u32 *ptr;
+	ptr = (volatile u32 *) addr;
+	*ptr = (volatile u32) value;
+}
+
+/*===================================================================
+Function   : via_read_phys()
+Precondition : 
+Input      :  addr
+Output     : u32 
+Purpose    : 
+Reference  : None
+===================================================================*/
+
+u32 via_read_phys(volatile u32 addr)
+{
+	volatile u32 *ptr;
+	volatile u32 y;
+//    ptr = (volatile u32 *)addr;
+	y = *(volatile u32 *) addr;
+//    return *ptr;
+	return y;
+}
+
+
+/*===================================================================
+Function   : DimmRead()
+Precondition : 
+Input      :  x
+Output     : u32 
+Purpose    : 
+Reference  : None
+===================================================================*/
+
+u32 DimmRead(volatile u32 x)
+{				//  volatile u32 z;
+	volatile u32 y;
+	y = *(volatile u32 *) x;
+
+	return y;
+}
+
+
+/*===================================================================
+Function   : DramBaseTest()
+Precondition : this function used to verify memory  
+Input      :  
+                 BaseAdd,
+                 length,
+                 mode
+Output     : u32
+Purpose    :write into and read out to verify if dram is correct 
+Reference  : None
+===================================================================*/
+BOOLEAN DramBaseTest(u32 BaseAdd, u32 Length,
+		     DRAM_TEST_MODE Mode, BOOLEAN PrintFlag)
+{
+	u32 TestSpan;
+	u32 Data, Address, Address2;
+	u8 i, TestCount;
+
+	//decide the test mode is continous or step
+	if (Mode == EXTENSIVE) {
+		//the test mode is continuos and must test each unit
+		TestSpan = 4;
+		TestCount = 1;
+	} else if (Mode == SPARE) {
+		// the test mode is step and test some unit
+		TestSpan = STEPSPAN;
+		TestCount = TESTCOUNT;
+	} else {
+		PRINT_DEBUG_MEM("the test mode is error\r");
+		return FALSE;
+	}
+
+	//write each test unit the value with TEST_PATTERN
+	for (Address = BaseAdd; Address < BaseAdd + Length;
+	     Address += TestSpan) {
+		for (i = 0; i < TestCount; i++)
+			via_write_phys(Address + i * 4, TEST_PATTERN);
+		if (PrintFlag) {
+			if ((u32) Address % 0x10000000 == 0) {
+				PRINT_DEBUG_MEM("Write in Addr =");
+				PRINT_DEBUG_MEM_HEX32(Address);
+				PRINT_DEBUG_MEM("\r");
+			}
+		}
+	}
+
+	//compare each test unit with the value of TEST_PATTERN
+	//and write it with compliment of TEST_PATTERN
+	for (Address = BaseAdd; Address < BaseAdd + Length;
+	     Address += TestSpan) {
+		for (i = 0; i < TestCount; i++) {
+			Data = via_read_phys(Address + i * 4);
+			via_write_phys(Address + i * 4,
+				       (u32) (~TEST_PATTERN));
+			if (Data != TEST_PATTERN) {
+				PRINT_DEBUG_MEM
+				    ("TEST_PATTERN ERROR !!!!! ");
+				Address2 = Address + i * 4;
+				PRINT_DEBUG_MEM_HEX32(Address2);
+				PRINT_DEBUG_MEM(" : ");
+				PRINT_DEBUG_MEM_HEX32(Data);
+				PRINT_DEBUG_MEM(" \r");
+				return FALSE;
+			}
+		}
+		if (PrintFlag) {
+			if ((u32) Address % 0x10000000 == 0) {
+				PRINT_DEBUG_MEM("Write in Addr =");
+				PRINT_DEBUG_MEM_HEX32(Address);
+				PRINT_DEBUG_MEM("\r");
+			}
+		}
+	}
+
+
+	//compare each test unit with the value of ~TEST_PATTERN
+	for (Address = BaseAdd; Address < BaseAdd + Length;
+	     Address += TestSpan) {
+		for (i = (u8) (TestCount); i > 0; i--) {
+			Data = via_read_phys(Address + (i - 1) * 4);
+			if (Data != ~TEST_PATTERN) {
+
+				PRINT_DEBUG_MEM
+				    ("~TEST_PATTERN ERROR !!!!! ");
+				Address2 = Address + (i - 1) * 4;
+				PRINT_DEBUG_MEM_HEX32(Address2);
+				PRINT_DEBUG_MEM(" : ");
+				PRINT_DEBUG_MEM_HEX32(Data);
+				PRINT_DEBUG_MEM(" \r");
+				return FALSE;
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+/*===================================================================
+Function   : DumpRegisters()
+Precondition : 
+Input      :  
+                pPCIPPI,
+                DevNum,
+                FuncNum
+Output     : Void
+Purpose    :
+Reference  : None
+===================================================================*/
+
+void DumpRegisters(INTN DevNum, INTN FuncNum)
+{
+	INTN i, j;
+	u8 ByteVal;
+
+	ByteVal = 0;
+	//pci_write_config8(PCI_DEV(0, DevNum, FuncNum), 0xA1, ByteVal);
+	PRINT_DEBUG_MEM("\rDev %02x Fun %02x\r");
+	PRINT_DEBUG_MEM
+	    ("\r    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\r");
+	PRINT_DEBUG_MEM
+	    ("---------------------------------------------------\r");
+	for (i = 0; i < 0x10; i++) {
+		PRINT_DEBUG_MEM_HEX32(i);
+		for (j = 0; j < 0x10; j++) {
+			ByteVal =
+			    pci_read_config8(PCI_DEV(0, DevNum, FuncNum),
+					     i * 0x10 + j);
+			PRINT_DEBUG_MEM_HEX8(ByteVal);
+			PRINT_DEBUG_MEM(" ");
+
+		}
+		PRINT_DEBUG_MEM("\r");
+	}
+	return;
+}
+
+
+/*===================================================================
+Function   : dumpnorth()
+Precondition : 
+Input      :  
+                pPCIPPI,
+                Func
+Output     : Void
+Purpose    :
+Reference  : None
+===================================================================*/
+
+void dumpnorth(u8 Func)
+{
+	u16 r, c;
+	u8 ByteVal;
+	PRINT_DEBUG_MEM("Dump North!!!\r");
+	for (r = 0; r < 32; r++) {
+		for (c = (u16) (r << 3); c < (r << 3) + 8; c++) {
+			ByteVal = 0;
+			ByteVal = pci_read_config8(PCI_DEV(0, 0, Func), c);
+			PRINT_DEBUG_MEM_HEX16(c);
+			PRINT_DEBUG_MEM("= ");
+			PRINT_DEBUG_MEM_HEX8(ByteVal);
+		}
+		PRINT_DEBUG_MEM("\r");
+	}
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/DramUtil.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef __DRAM_UTIL_H__
+#define __DRAM_UTIL_H__
+
+#define STEPSPAN	0x1000	//the span when test memory in spare mode
+#define TESTCOUNT	0x4	// the test count in each range when test memory in spare mode
+#define TEST_PATTERN	0x5A5A5A5A	//the test pattern
+
+typedef enum __DRAM_TEST_MODE {
+	EXTENSIVE,
+	SPARE,
+	MAXMODE
+} DRAM_TEST_MODE;
+
+void WaitMicroSec(UINTN MicroSeconds);
+
+void via_write_phys(u32 addr, u32 value);
+
+u32 via_read_phys(u32 addr);
+
+u32 DimmRead(u32 x);
+
+BOOLEAN DramBaseTest(u32 BaseAdd, u32 Length,
+		     DRAM_TEST_MODE mode, BOOLEAN PrintFlag);
+
+void DumpRegisters(INTN DevNum, INTN FuncNum);
+
+void dumpnorth(u8 Func);
+#endif

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/Translatorddr2init.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/Translatorddr2init.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/Translatorddr2init.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define CB_SUCCESS		0x0
+#define CB_INVALID_PARAMETER	0x2
+#define CB_NOT_READY		0x6
+#define CB_DEVICE_ERROR		0x7
+#define TRUE  1
+#define FALSE 0
+
+
+typedef int8_t INT8;
+typedef unsigned long uintn_t;
+typedef uintn_t UINTN;
+typedef long intn_t;
+typedef intn_t INTN;
+typedef UINTN CB_STATUS;
+typedef uint8_t BOOLEAN;

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/ClkCtrl.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/ClkCtrl.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/ClkCtrl.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,312 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+void DutyCycleCtrl(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 FreqId;
+	u8 i;
+
+	if (DIMMFREQ_800 == DramAttr->DramFreq)
+		FreqId = 2;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		FreqId = 3;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		FreqId = 4;
+	else if (DIMMFREQ_400 == DramAttr->DramFreq)
+		FreqId = 5;
+	else
+		FreqId = 5;
+
+	if (DramAttr->RankNumChA > 0) {	// 1 rank
+		for (i = 0; i < DUTY_CYCLE_REG_NUM; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     ChA_Duty_Control_DDR2[i][0]);
+			Data &= ChA_Duty_Control_DDR2[i][1];	/*Mask */
+			Data |= ChA_Duty_Control_DDR2[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  ChA_Duty_Control_DDR2[i][0],
+					  Data);
+		}
+	}
+	if (1 == ENABLE_CHC) {	// 1 rank
+		for (i = 0; i < DUTY_CYCLE_REG_NUM; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     ChB_Duty_Control_DDR2[i][0]);
+			Data &= ChB_Duty_Control_DDR2[i][1];	/*Mask */
+			Data |= ChB_Duty_Control_DDR2[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  ChB_Duty_Control_DDR2[i][0],
+					  Data);
+		}
+	}
+
+}
+
+/*
+DRAM clock phase and delay control
+*/
+//sub routine list
+void ClkPhsCtrlFBMDDR2(DRAM_SYS_ATTR * DramAttr);
+
+void WrtDataPhsCtrl(DRAM_SYS_ATTR * DramAttr);
+
+void DQDQSOutputDlyCtrl(DRAM_SYS_ATTR * DramAttr);
+
+void DQSInputCaptureCtrl(DRAM_SYS_ATTR * DramAttr);
+
+void DCLKPhsCtrl(DRAM_SYS_ATTR * DramAttr);
+
+
+void DRAMClkCtrl(DRAM_SYS_ATTR * DramAttr)
+{
+	/*write data clock phase control */
+	WrtDataPhsCtrl(DramAttr);
+	/*clock phase control */
+	ClkPhsCtrlFBMDDR2(DramAttr);
+	 /**/ DQDQSOutputDlyCtrl(DramAttr);
+	 /**/ DQSInputCaptureCtrl(DramAttr);
+	DCLKPhsCtrl(DramAttr);
+}
+
+void ClkPhsCtrlFBMDDR2(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+
+	u8 FreqId, i;
+
+	if (DramAttr->DramFreq == DIMMFREQ_800)
+		FreqId = 2;
+	else if (DramAttr->DramFreq == DIMMFREQ_667)
+		FreqId = 3;
+	else if (DramAttr->DramFreq == DIMMFREQ_533)
+		FreqId = 4;
+	else if (DramAttr->DramFreq == DIMMFREQ_400)
+		FreqId = 5;
+	else
+		FreqId = 5;
+	/*channel A */// 2~4 Rank
+	if (DramAttr->RankNumChA == 1) {	// 1 rank
+		for (i = 0; i < 3; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChA_Clk_Phase_Table_1R[i]
+					     [0]);
+			Data &= DDR2_ChA_Clk_Phase_Table_1R[i][1];	/*Mask */
+			Data |= DDR2_ChA_Clk_Phase_Table_1R[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChA_Clk_Phase_Table_1R[i]
+					  [0], Data);
+		}
+	} else if (DramAttr->RankNumChA > 1) {	// 2~4 Rank
+		for (i = 0; i < 3; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChA_Clk_Phase_Table_2R[i]
+					     [0]);
+			Data &= DDR2_ChA_Clk_Phase_Table_2R[i][1];	/*Mask */
+			Data |= DDR2_ChA_Clk_Phase_Table_2R[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChA_Clk_Phase_Table_2R[i]
+					  [0], Data);
+		}
+	}
+#if ENABLE_CHB
+	if (DramAttr->RankNumChB > 0) {	// 1 rank
+		for (i = 0; i < 3; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChB_Clk_Phase_Table_1R[i]
+					     [0]);
+			Data &= DDR2_ChB_Clk_Phase_Table_1R[i][1];	/*Mask */
+			Data |= DDR2_ChB_Clk_Phase_Table_1R[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChB_Clk_Phase_Table_1R[i]
+					  [0], Data);
+		}
+	}
+#endif
+}
+
+void WrtDataPhsCtrl(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 FreqId, i;
+
+
+	if (DIMMFREQ_800 == DramAttr->DramFreq)
+		FreqId = 2;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		FreqId = 3;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		FreqId = 4;
+	else if (DIMMFREQ_400 == DramAttr->DramFreq)
+		FreqId = 5;
+	else
+		FreqId = 5;
+
+	if (DramAttr->RankNumChA > 0) {	// 1 rank
+		for (i = 0; i < WrtData_REG_NUM; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChA_WrtData_Phase_Table
+					     [i][0]);
+			Data &= DDR2_ChA_WrtData_Phase_Table[i][1];	/*Mask */
+			Data |= DDR2_ChA_WrtData_Phase_Table[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChA_WrtData_Phase_Table[i]
+					  [0], Data);
+		}
+	}
+#if ENABLE_CHB
+	if (DramAttr->RankNumChB > 0) {	// 1 rank
+		for (i = 0; i < WrtData_REG_NUM; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChB_WrtData_Phase_Table
+					     [i][0]);
+			Data &= DDR2_ChB_WrtData_Phase_Table[i][1];	/*Mask */
+			Data |= DDR2_ChB_WrtData_Phase_Table[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChB_WrtData_Phase_Table[i]
+					  [0], Data);
+		}
+	}
+#endif
+	Data = pci_read_config8(MEMCTRL, 0x8C);
+	Data &= 0xFC;
+	Data |= 0x03;
+	pci_write_config8(MEMCTRL, 0x8C, Data);
+}
+
+void DQDQSOutputDlyCtrl(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 FreqId;
+
+	if (DIMMFREQ_400 == DramAttr->DramFreq)
+		FreqId = 0;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		FreqId = 1;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		FreqId = 2;
+	else if (DIMMFREQ_800 == DramAttr->DramFreq)
+		FreqId = 2;
+	else
+		FreqId = 0;
+	if (DramAttr->RankNumChA > 0) {
+		Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][0];
+		pci_write_config8(MEMCTRL, 0xf0, Data);
+
+		Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][1];
+		pci_write_config8(MEMCTRL, 0xf1, Data);
+
+		Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][2];
+		pci_write_config8(MEMCTRL, 0xf2, Data);
+
+		Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][3];
+		pci_write_config8(MEMCTRL, 0xf3, Data);
+	}
+#if ENABLE_CHB
+	if (DramAttr->RankNumChB > 0) {
+		Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][0];
+		pci_write_config8(MEMCTRL, 0xf4, Data);
+
+		Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][1];
+		pci_write_config8(MEMCTRL, 0xf5, Data);
+
+		Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][2];
+		pci_write_config8(MEMCTRL, 0xf6, Data);
+
+		Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][3];
+		pci_write_config8(MEMCTRL, 0xf7, Data);
+	}
+#endif
+}
+
+void DQSInputCaptureCtrl(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 FreqId, i;
+
+	if (DIMMFREQ_800 == DramAttr->DramFreq)
+		FreqId = 2;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		FreqId = 3;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		FreqId = 4;
+	else if (DIMMFREQ_400 == DramAttr->DramFreq)
+		FreqId = 5;
+	else
+		FreqId = 2;
+
+	Data = 0x8A;
+	pci_write_config8(MEMCTRL, 0x77, Data);
+
+	if (DramAttr->RankNumChA > 0) {	// 1 rank
+		for (i = 0; i < DQS_INPUT_CAPTURE_REG_NUM; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChA_DQS_Input_Capture_Tbl
+					     [i][0]);
+			Data &= DDR2_ChA_DQS_Input_Capture_Tbl[i][1];	/*Mask */
+			Data |= DDR2_ChA_DQS_Input_Capture_Tbl[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChA_DQS_Input_Capture_Tbl[i]
+					  [0], Data);
+		}
+	}
+#if ENABLE_CHB
+	if (DramAttr->RankNumChB > 0) {	// 1 rank
+		for (i = 0; i < DQS_INPUT_CAPTURE_REG_NUM; i++) {
+			Data =
+			    pci_read_config8(MEMCTRL,
+					     DDR2_ChB_DQS_Input_Capture_Tbl
+					     [i][0]);
+			Data &= DDR2_ChB_DQS_Input_Capture_Tbl[i][1];	/*Mask */
+			Data |= DDR2_ChB_DQS_Input_Capture_Tbl[i][FreqId];	/*set Value */
+			pci_write_config8(MEMCTRL,
+					  DDR2_ChB_DQS_Input_Capture_Tbl[i]
+					  [0], Data);
+		}
+	}
+#endif
+}
+
+//This is very important, if you don't set it correctly, dram will be unreliable
+//set  DCLK Phase control(Reg99H[6:1]) according the DDRII  in the dimm
+void DCLKPhsCtrl(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+
+	Data = 0;
+	Data = pci_read_config8(MEMCTRL, 0x99);
+	Data &= 0xE1;
+	//DDR in Dimm1, MCLKOA[4,3,0] will output MCLK
+	if (DramAttr->RankPresentMap & 0x03)
+		Data |= 0x09 << 1;
+	//DDR in Dimm2, MCLKOA[5,2,1] will output MCLK
+	if (DramAttr->RankPresentMap & 0x0C)
+		Data |= 0x06 << 1;
+
+	pci_write_config8(MEMCTRL, 0x99, Data);
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DQSSearch.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DQSSearch.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DQSSearch.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,98 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+void SetDQSOutputCHA(DRAM_SYS_ATTR * DramAttr);
+void SetDQSOutputCHB(DRAM_SYS_ATTR * DramAttr);
+
+/*===================================================================
+Function   : DRAMDQSOutputSearchCHA()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : set DQS output delay register reg70  and DQ output delay register reg71
+===================================================================*/
+
+#define CH_A      0
+#define CH_B      1
+void DRAMDQSOutputSearch(DRAM_SYS_ATTR * DramAttr)
+{
+	if (DramAttr->RankNumChA > 0)
+		SetDQSOutputCHA(DramAttr);
+}
+
+/*===================================================================
+Function   : SetDQSOutputCHA()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   :  according the frequence set CHA DQS output 
+===================================================================*/
+void SetDQSOutputCHA(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Reg70, Reg71;
+	u8 Index;
+
+	if (DramAttr->DramFreq == DIMMFREQ_400)
+		Index = 3;
+	else if (DramAttr->DramFreq == DIMMFREQ_533)
+		Index = 2;
+	else if (DramAttr->DramFreq == DIMMFREQ_667)
+		Index = 1;
+	else if (DramAttr->DramFreq == DIMMFREQ_800)
+		Index = 0;
+	else
+		Index = 3;
+
+	if (DramAttr->RankNumChA > 2) {
+		Reg70 = Fixed_DQSA_3_4_Rank_Table[Index][0];
+		Reg71 = Fixed_DQSA_3_4_Rank_Table[Index][1];
+	} else {
+		Reg70 = Fixed_DQSA_1_2_Rank_Table[Index][0];
+		Reg71 = Fixed_DQSA_1_2_Rank_Table[Index][1];
+	}
+	pci_write_config8(MEMCTRL, 0x70, Reg70);
+	pci_write_config8(MEMCTRL, 0x71, Reg71);
+}
+
+
+//################
+//     STEP 12   #
+//################
+
+/*===================================================================
+Function   : DRAMDQSInputSearch()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : search DQS input delay for CHA/CHB
+===================================================================*/
+
+void DRAMDQSInputSearch(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	//auto mode
+	Data = 0x0;
+	pci_write_config8(MEMCTRL, 0x77, Data);
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DRDY_BL.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DRDY_BL.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DRDY_BL.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,600 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+// Set P6IF DRDY Timing
+// Because there are 1.5T & 2.5T CAS latency in DDR1 mode, we need to use RDELAYMD-0
+//
+//      Entry:
+//        EBP[29:25] = DRAM Speed, Dual_Channel
+//        VIA_NB2HOST_REG54[7:5]        Host Frequency
+//        VIA_NB3DRAM_REG62[2:0]        CAS Latency
+//
+//      Modify NB_Reg:
+//        VIA_NB2HOST_REG54[3,1]
+//        VIA_NB2HOST_REG55[1]
+//        VIA_NB2HOST_REG60
+//        VIA_NB2HOST_REG61
+//        VIA_NB2HOST_REG62[3:0]
+//        VIA_NB2HOST_REG63
+//        VIA_NB2HOST_REG64
+//        VIA_NB2HOST_REG65[3:0]
+//        VIA_NB2HOST_REG66
+//        VIA_NB2HOST_REG67[5:4]
+//
+// Processing:
+//--------------------------------------------------------------------------
+// P6IF DRDY Timing Control:
+// *Following algorithm to set DRDY timing
+// Set P6IF DRDY Timing by the following 3      conditions:
+// 1. RDELAYMD
+//    a.RDRPH(MD        input internal timing control)
+//    b.CAS Latency
+//    RDELAYMD(1bit) = bit0 of (CL + RDRPH)
+//    for example: RDRPH=10b, CL3 -> F3_Rx56[5:4]=11b, 10b + 11b        = 101b, RDELAYMD=1 (bit0)
+//                RDRPH=00b, CL2.5 -> F3_Rx56[5:4]=10b, 00b + 10b = 010b, RDELAYMD=0 (bit0)
+// 2. CPU Frequency
+// 3. DRAM Frequency
+//
+// According to above conditions, we create different tables:
+// 1. RDELAYMD=0        : for integer CAS latency(ex. CL=3)
+// 2. RDELAYMD=1        : for non-integer CAS latency(ex. CL=2.5)
+// 3. Normal performance
+// 4. Top performance :
+//                     Using phase0 to a case has better performance.
+//
+// Note: The setting are        related to performance and maybe affect DRAM initialize.
+//      Turn OFF(F2_Rx51[7]=0) this feature at csDRAMRegInitValueJ procedure.
+//      Turn ON(F2_Rx51[7]=1) this feature at csDRAMRegFinalValueJ procedure.
+//
+// If F2_Rx51[7]=0, then        CPU always wait 8QW, a slower but most stable way
+// If F2_Rx51[7]=1, then        the timing will refer to F2_Rx60 ~ F2_Rx67,
+// a fast way but may cause the system to be unstable.
+//
+// Coding:
+// 1. RDELAYMD and user's option        for performance can determine which table
+// 2. CPU Frequency can get block offset        of table
+// 3. DRAM Frequency can        get row offset of block
+// 4. Set value
+//
+// PS: Fun2 Rx62, Rx65, Rx67 are        don't care bits in 3296, CPU 266MHz doesn't be supported by 3296,
+//     but I still keep these bits in table to avoid the        usage in future
+//     and do the fewest        modification for code.
+//
+
+// Early 3T
+// Early 3T
+#define P6IF_Misc_RFASTH		0x08
+#define P6IF_Misc2_RRRDYH3E		0x10
+#define P6IF_Misc2_RHTSEL		0x02
+
+#define Rx54E3T			P6IF_Misc_RFASTH
+#define Rx55E3T			P6IF_Misc2_RRRDYH3E
+
+// Early 2T
+#define Rx54E2T			0x00
+#define Rx55E2T			P6IF_Misc2_RRRDYH3E
+
+// Early 1T
+#define Rx54E1T			0x00
+#define Rx55E1T			0x00
+
+// Early 0T
+#define Rx54E0T			P6IF_Misc_RFASTH
+#define Rx55E0T			P6IF_Misc2_RRRDYH3E + P6IF_Misc2_RHTSEL
+
+// Latter       1T
+#define Rx54L1T			P6IF_Misc_RFASTH
+#define Rx55L1T			P6IF_Misc2_RHTSEL
+
+
+#define PH0_0_0_0	0x00
+#define PH0_0_0_1	0x01
+#define PH0_0_0_2	0x02
+#define PH0_0_0_3	0x03
+#define PH0_0_1_0	0x04
+#define PH0_0_1_1	0x05
+#define PH0_0_1_2	0x06
+#define PH0_0_2_1	0x09
+#define PH0_0_2_2	0x0a
+#define PH0_0_2_3	0x0b
+#define PH0_0_3_2	0x0e
+#define PH0_0_3_3	0x0f
+#define PH0_1_1_0	0x14
+#define PH0_1_1_1	0x15
+#define PH0_2_1_2	0x26
+#define PH0_2_2_1	0x29
+#define PH0_2_2_2	0x2a
+#define PH0_2_2_3	0x2b
+#define PH0_2_3_2	0x2e
+#define PH0_2_3_3	0x2f
+#define PH0_3_2_2	0x3a
+#define PH0_3_3_3	0x3f
+#define PH1_0_0_0	0x40
+#define PH1_0_0_1	0x41
+#define PH1_0_1_1	0x45
+#define PH1_1_1_1	0x55
+#define PH1_2_1_1	0x65
+#define PH1_2_2_1	0x69
+#define PH2_1_1_1	0x95
+#define PH2_1_2_1	0x99
+#define PH2_1_2_2	0x9a
+#define PH2_2_1_2	0xa6
+#define PH2_2_2_1	0xa9
+#define PH2_2_2_2	0xaa
+#define PH2_2_3_2	0xae
+#define PH2_2_3_3	0xaf
+#define PH2_3_2_2	0xba
+#define PH2_3_2_3	0xbb
+#define PH2_3_3_2	0xbe
+#define PH3_2_2_3	0xeb
+#define PH3_2_3_2	0xee
+#define PH3_2_3_3	0xef
+#define PH3_3_3_3	0xff
+
+#define PT894_RDRDY_TBL_Width		10
+#define PT894_RDRDY_TBL_Block		60
+
+static const u8 PT894_128bit_DELAYMD0_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
+//    -----------------------------------------------------------------------------------------------------------------
+//    RX60           RX61           RX62            RX63           RX64       RX65           RX66  RX67   RX54[3,1]  RX55[3,1]    CPU/DRAM
+//    LN4:1          LN8:5          LN10:9          QW4:1          QW8:5      QW10:9     WS8:1 WS10:9 RFASTH     RRRDYH3E
+//                                                                                                                            RCONV          RHTSEL
+//    -----------------------------------------------------------------------------------------------------------------
+{
+// cpu100
+	{
+	 {PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/100
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/133
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 100/333
+	 },
+// cpu133
+	{
+	 {PH0_2_2_1, PH0_0_0_0, PH0_0_0_0, PH0_2_2_1, PH0_0_0_0, PH0_0_0_0, 0x01, 0x00, Rx54E3T, Rx55E3T},	// 133/100
+	 {PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/133
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 133/333
+	 },
+// cpu200
+	{
+	 {PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E2T, Rx55E2T},	// 200/100
+	 {PH2_3_2_3, PH0_0_0_0, PH0_0_0_0, PH2_3_2_3, PH0_0_0_0, PH0_0_0_0, 0x0a, 0x00, Rx54E3T, Rx55E3T},	// 200/133
+	 {PH1_2_2_1, PH0_0_0_1, PH0_0_0_0, PH1_2_2_1, PH0_0_0_1, PH0_0_0_0, 0x01, 0x00, Rx54E3T, Rx55E3T},	// 200/166
+	 {PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 200/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 200/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 200/333
+	 },
+// cpu166
+	{
+	 {PH0_2_3_3, PH0_0_0_0, PH0_0_0_0, PH0_2_2_3, PH0_0_0_0, PH0_0_0_0, 0x05, 0x00, Rx54E3T, Rx55E3T},	// 166/100
+	 {PH1_2_2_1, PH0_0_0_0, PH0_0_0_0, PH1_2_2_1, PH0_0_0_0, PH0_0_0_0, 0x01, 0x00, Rx54E3T, Rx55E3T},	// 166/133
+	 {PH1_1_1_1, PH0_0_0_1, PH0_0_0_0, PH1_1_1_1, PH0_0_0_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 166/333
+	 },
+// cpu266
+	{
+	 {PH0_2_2_3, PH0_0_0_0, PH0_0_0_0, PH0_0_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T},	// 266/100
+	 {PH3_3_3_3, PH0_0_0_0, PH0_0_0_0, PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E2T, Rx55E2T},	// 266/133
+	 {PH3_2_3_3, PH0_0_0_3, PH0_0_0_0, PH3_2_3_3, PH0_0_0_2, PH0_0_0_0, 0x0d, 0x00, Rx54E3T, Rx55E3T},	// 266/166
+	 {PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH2_1_2_2, PH0_0_1_2, PH0_0_0_0, 0x12, 0x00, Rx54E3T, Rx55E3T},	// 266/200
+	 {PH1_1_1_1, PH1_1_1_1, PH0_0_0_0, PH1_1_1_1, PH1_1_1_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 266/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 266/333
+	 },
+// cpu333
+	{
+	 {PH0_1_1_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T},	// 333/100
+	 {PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T},	// 333/133
+	 {PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, 0x1f, 0x00, Rx54E2T, Rx55E2T},	// 333/166
+	 {PH2_2_1_2, PH0_0_2_1, PH0_0_0_0, PH1_2_1_1, PH0_0_2_1, PH0_0_0_0, 0x36, 0x00, Rx54E2T, Rx55E2T},	// 333/200
+	 {PH2_1_1_1, PH2_1_1_1, PH0_0_0_0, PH2_1_1_1, PH2_1_1_1, PH0_0_0_0, 0x44, 0x00, Rx54E3T, Rx55E3T},	// 333/266
+	 {PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 333/333
+	 }
+};
+
+static const u8 PT894_128bit_DELAYMD1_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
+//    -----------------------------------------------------------------------------------------------------------------
+//    RX60           RX61           RX62            RX63           RX64       RX65           RX66  RX67   RX54[3,1]  RX55[3,1]    CPU/DRAM
+//    LN4:1          LN8:5          LN10:9          QW4:1          QW8:5      QW10:9     WS8:1 WS10:9 RFASTH     RRRDYH3E
+//                                                                                                                            RCONV          RHTSEL
+//    -----------------------------------------------------------------------------------------------------------------
+{
+// cpu100
+	{
+	 {PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/100
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/133
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 100/333
+	 },
+// cpu133
+	{
+	 {PH0_3_2_2, PH0_0_0_0, PH0_0_0_0, PH0_3_2_2, PH0_0_0_0, PH0_0_0_0, 0x02, 0x00, Rx54E3T, Rx55E3T},	// 133/100
+	 {PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/133
+	 {PH1_0_0_0, PH0_0_0_0, PH0_0_0_0, PH1_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 133/333
+	 },
+// cpu200
+	{
+	 {PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T},	// 200/100
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH2_1_2_1, PH0_0_0_0, PH0_0_0_0, 0x0a, 0x00, Rx54E2T, Rx55E2T},	// 200/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x04, 0x00, Rx54E3T, Rx55E3T},	// 200/166
+	 {PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 200/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 200/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 200/333
+	 },
+// cpu166
+	{
+	 {PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_2_1_2, PH0_0_0_0, PH0_0_0_0, 0x05, 0x00, Rx54E2T, Rx55E2T},	// 166/100
+	 {PH2_3_2_2, PH0_0_0_0, PH0_0_0_0, PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, 0x02, 0x00, Rx54E3T, Rx55E3T},	// 166/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/166
+	 {PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 166/333
+	 },
+// cpu266
+	{
+	 {PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T},	// 266/100
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T},	// 266/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_1_2, PH0_0_0_2, PH0_0_0_0, 0x15, 0x00, Rx54E2T, Rx55E2T},	// 266/166
+	 {PH3_2_3_3, PH0_0_2_3, PH0_0_0_0, PH2_2_3_2, PH0_0_2_3, PH0_0_0_0, 0x24, 0x00, Rx54E3T, Rx55E3T},	// 266/200
+	 {PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 266/266
+	 {PH0_0_0_1, PH0_0_1_1, PH0_0_1_0, PH0_0_0_1, PH0_0_1_1, PH0_0_1_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 266/333
+	 },
+// cpu333
+	{
+	 {PH0_3_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T},	// 333/100
+	 {PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E0T, Rx55E0T},	// 333/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x1f, 0x00, Rx54E1T, Rx55E1T},	// 333/166
+	 {PH2_3_2_2, PH0_0_3_2, PH0_0_0_0, PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, 0x1b, 0x00, Rx54E2T, Rx55E2T},	// 333/200
+	 {PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, PH2_2_2_1, PH2_2_2_1, PH0_0_0_0, 0x88, 0x00, Rx54E3T, Rx55E3T},	// 333/266
+	 {PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 333/333
+	 }
+};
+
+
+static const u8 PT894_64bit_DELAYMD0_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
+//    -----------------------------------------------------------------------------------------------------------------
+//    RX60           RX61           RX62            RX63           RX64       RX65           RX66  RX67   RX54[3,1]  RX55[3,1]    CPU/DRAM
+//    LN4:1          LN8:5          LN10:9          QW4:1          QW8:5      QW10:9     WS8:1 WS10:9 RFASTH     RRRDYH3E
+//                                                                                                                            RCONV          RHTSEL
+//    -----------------------------------------------------------------------------------------------------------------
+{
+// cpu100
+	{
+	 {PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E3T, Rx55E3T},	// 100/100
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x09, 0x00, Rx54E3T, Rx55E3T},	// 100/133
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 100/333
+	 },
+// cpu133
+	{
+	 {PH0_2_3_2, PH0_0_0_0, PH0_0_0_0, PH0_0_1_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E2T, Rx55E2T},	// 133/100
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E3T, Rx55E3T},	// 133/133
+	 {PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E3T, Rx55E3T},	// 133/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 133/333
+	 },
+// cpu200
+	{
+	 {PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T},	// 200/100
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T},	// 200/133
+	 {PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, PH1_2_2_1, PH0_0_0_1, PH0_0_0_0, 0x1f, 0x00, Rx54E3T, Rx55E3T},	// 200/166
+	 {PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, 0x3f, 0x00, Rx54E3T, Rx55E3T},	// 200/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E1T, Rx55E1T},	// 200/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 200/333
+// DDR2 Both E3T and E2T Fail, need set to E1T,  db     PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0,       00110011b, 00000000b, Rx54E3T,  Rx55E3T  ;200/266
+	 },
+// cpu166
+	{
+	 {PH0_2_3_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T},	// 166/100
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_1_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E2T, Rx55E2T},	// 166/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH1_1_1_1, PH0_0_0_1, PH0_0_0_0, 0x1f, 0x00, Rx54E3T, Rx55E3T},	// 166/166
+	 {PH1_0_0_1, PH0_0_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1e, 0x00, Rx54E3T, Rx55E3T},	// 166/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 166/333
+	 },
+// cpu266
+	{
+	 {PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54L1T, Rx55L1T},	// 266/100
+	 {PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T},	// 266/133
+	 {PH3_2_3_2, PH0_0_0_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54E1T, Rx55E1T},	// 266/166
+	 {PH3_2_2_3, PH0_0_2_2, PH0_0_0_0, PH1_0_0_1, PH0_0_0_0, PH0_0_0_0, 0x3f, 0x00, Rx54E2T, Rx55E2T},	// 266/200
+	 {PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, PH1_1_1_1, PH1_1_1_1, PH0_0_0_0, 0xff, 0x00, Rx54E3T, Rx55E3T},	// 266/266
+	 {PH0_0_1_1, PH0_1_1_1, PH0_0_1_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x9c, 0x03, Rx54E3T, Rx55E3T}	// 266/333
+	 },
+// cpu333
+	{
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54L1T, Rx55L1T},	// 333/100  ;DO NOT Support
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T},	// 333/133
+	 {PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54E0T, Rx55E0T},	// 333/166
+	 {PH2_3_3_2, PH0_0_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x3f, 0x00, Rx54E1T, Rx55E1T},	// 333/200
+	 {PH3_3_3_3, PH3_3_3_3, PH0_0_0_0, PH2_1_1_1, PH2_1_1_1, PH0_0_0_0, 0xff, 0x00, Rx54E3T, Rx55E3T},	// 333/266
+	 {PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0xff, 0x03, Rx54E3T, Rx55E3T}	// 333/333
+	 }
+};
+
+
+static const u8 PT894_64bit_DELAYMD1_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
+//    -----------------------------------------------------------------------------------------------------------------
+//    RX60           RX61           RX62            RX63           RX64       RX65           RX66  RX67   RX54[3,1]  RX55[3,1]    CPU/DRAM
+//    LN4:1          LN8:5          LN10:9          QW4:1          QW8:5      QW10:9     WS8:1 WS10:9 RFASTH     RRRDYH3E
+//                                                                                                                            RCONV          RHTSEL
+//    -----------------------------------------------------------------------------------------------------------------
+{
+// cpu100
+	{
+	 {PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E3T, Rx55E3T},	// 100/100
+	 {PH1_0_0_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x06, 0x00, Rx54E3T, Rx55E3T},	// 100/133
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 100/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// ;100/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 100/333
+	 },
+// cpu133
+	{
+	 {PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E2T, Rx55E2T},	// 133/100
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E3T, Rx55E3T},	// 133/133
+	 {PH1_0_1_1, PH0_0_0_1, PH0_0_0_0, PH1_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1c, 0x00, Rx54E3T, Rx55E3T},	// 133/166
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x09, 0x00, Rx54E3T, Rx55E3T},	// 133/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 133/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 133/333
+	 },
+// cpu200
+	{
+	 {PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54L1T, Rx55L1T},	// 200/100
+	 {PH3_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T},	// 200/133
+	 {PH2_2_3_3, PH0_0_0_2, PH0_0_0_0, PH1_0_1_1, PH0_0_0_1, PH0_0_0_0, 0x1f, 0x00, Rx54E2T, Rx55E2T},	// 200/166
+	 {PH3_3_3_3, PH0_0_3_3, PH0_0_0_0, PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, 0x3f, 0x00, Rx54E3T, Rx55E3T},	// 200/200
+	 {PH0_0_1_1, PH0_0_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0xcc, 0x00, Rx54E3T, Rx55E3T},	// 200/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 200/333
+	 },
+// cpu166
+	{
+	 {PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T},	// 166/100
+	 {PH2_2_3_3, PH0_0_0_0, PH0_0_0_0, PH1_0_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E2T, Rx55E2T},	// 166/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x1f, 0x00, Rx54E3T, Rx55E3T},	// 166/166
+	 {PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, 0x39, 0x00, Rx54E3T, Rx55E3T},	// 166/200
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T},	// 166/266
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}	// 166/333
+	 },
+// cpu266
+	{
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54L1T, Rx55L1T},	// 266/100  ;DO NOT Support
+	 {PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T},	// 266/133
+	 {PH2_2_1_2, PH0_0_0_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54E0T, Rx55E0T},	// 266/166
+	 {PH3_3_3_3, PH0_0_3_3, PH0_0_0_0, PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, 0x3f, 0x00, Rx54E2T, Rx55E2T},	// 266/200
+	 {PH3_3_3_3, PH3_3_3_3, PH0_0_0_0, PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, 0xff, 0x00, Rx54E3T, Rx55E3T},	// 266/266
+	 {PH1_1_1_1, PH1_1_1_1, PH0_0_1_1, PH0_0_0_1, PH0_0_1_1, PH0_0_1_0, 0x73, 0x02, Rx54E3T, Rx55E3T}	// 266/333
+	 },
+// cpu333
+	{
+	 {PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54L1T, Rx55L1T},	// 333/100  ;DO NOT Support
+	 {PH3_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T},	// 333/133
+	 {PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54L1T, Rx55L1T},	// 333/166
+	 {PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x3f, 0x00, Rx54E1T, Rx55E1T},	// 333/200
+	 {PH2_3_2_2, PH2_3_2_2, PH0_0_0_0, PH0_1_1_0, PH0_1_1_0, PH0_0_0_0, 0xff, 0x00, Rx54E2T, Rx55E2T},	// 333/266
+	 {PH3_3_3_3, PH3_3_3_3, PH0_0_3_3, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0xff, 0x03, Rx54E3T, Rx55E3T}	// 333/333
+	 }
+};
+
+void DRAMDRDYSetting(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data, CL, RDRPH;
+	u8 CpuFreq, DramFreq;
+	u8 ProgData[PT894_RDRDY_TBL_Width];
+	u8 DelayMode;
+	u8 DrdyMode;
+	u8 Index;
+
+	/*
+	   this function has 3 switchs, correspond to 3 level of Drdy setting.
+	   0:Slowest, 1:Default, 2:Optimize
+	   you can only open one switch
+	    */
+#if 1				//this is slowest
+	//  0 -> Slowest
+	//Write slowest value to register
+
+	Data = 0xAA;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x60, Data);
+
+	Data = 0x0A;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x61, Data);
+
+	Data = 0x00;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x62, Data);
+
+	Data = 0xAA;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x63, Data);
+
+	Data = 0x0A;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x64, Data);
+
+	Data = 0x00;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x65, Data);
+
+	Data = 0x00;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x66, Data);
+
+	Data = 0x00;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x67, Data);
+
+	Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x54);
+	Data = Data & 0xF5;
+	Data |= 0x08;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x54, Data);
+
+	//Data=pci_read_config8(PCI_DEV(0,0,2), 0x55);
+	//Data = Data & (~0x20);
+	//pci_write_config8(PCI_DEV(0,0,2), 0x55, Data);
+
+	//enable drdy timing
+	Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x51);
+	Data = Data | 0x80;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x51, Data);
+#endif
+#if 0				//default
+	{
+		//disable drdy timing
+		Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x51);
+		Data = Data & 0x7F;
+		pci_write_config8(PCI_DEV(0, 0, 2), 0x51, Data);
+	}
+#endif
+#if 0				//  2:Optimize
+	//CL :reg6x[2:0]
+	Data = pci_read_config8(MEMCTRL, 0x62);
+	CL = Data & 0x07;
+
+	//RDRPH: reg7B[6:4]
+	Data = pci_read_config8(MEMCTRL, 0x7B);
+	RDRPH = (Data & 0x70) >> 4;
+
+	//CpuFreq: F2Reg54[7:5]
+	Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x54);
+	CpuFreq = (Data & 0xE0) >> 5;
+
+	//DramFreq:F3Reg90[2:0]
+	Data = pci_read_config8(MEMCTRL, 0x90);
+	DramFreq = Data & 0x07;
+
+	DelayMode = CL + RDRPH;	// RDELAYMD = bit0 of (CAS Latency + RDRPH)
+	DelayMode &= 0x01;
+
+	//In 364, there is no 128 bit
+	if (DelayMode == 1) {	// DelayMode 1
+		for (Index = 0; Index < PT894_RDRDY_TBL_Width; Index++)
+			ProgData[Index] =
+			    PT894_64bit_DELAYMD1_RCONV0[CpuFreq][DramFreq]
+			    [Index];
+	} else {		// DelayMode 0
+		for (Index = 0; Index < PT894_RDRDY_TBL_Width; Index++)
+			ProgData[Index] =
+			    PT894_64bit_DELAYMD0_RCONV0[CpuFreq][DramFreq]
+			    [Index];
+	}
+
+	Data = ProgData[0];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x60, Data);
+
+	Data = ProgData[1];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x61, Data);
+
+	Data = ProgData[2];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x62, Data);
+
+	Data = ProgData[3];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x63, Data);
+
+	Data = ProgData[4];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x64, Data);
+
+	Data = ProgData[5];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x65, Data);
+
+	Data = ProgData[6];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x66, Data);
+
+	Data = ProgData[7];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x67, Data);
+
+	Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x54);
+	Data = (Data & 0xF5) | ProgData[8];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x54, Data);
+
+	Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x55);
+	Data = Data & (~0x22) | ProgData[9];
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x62, Data);
+
+	//enable drdy timing
+	Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x51);
+	Data = Data | 0x80;
+	pci_write_config8(PCI_DEV(0, 0, 2), 0x51, Data);
+#endif
+}
+
+
+/*This routine process the ability for North Bridge side burst functionality
+There are 3 variances that are valid:
+	1. DIMM	BL=8, chipset BL=8
+	2. DIMM	BL=4, chipset BL=4
+	3. DIMM	BL=4, chipset BL=8 (only happened on Dual channel)
+     Device 0 function 2 HOST:REG54[4] must be 1 when 128-bit mode.
+Since DIMM will be initialized	in each	rank individually,
+	1.If all DIMM BL=4, DIMM will initialize BL=4 first,
+	  then check dual_channel flag to enable VIA_NB2HOST_REG54[4].
+	2.If all DIMM BL=8, DIMM will initialize BL=8 first,
+	  then check dual_channel flag for re-initialize DIMM BL=4.
+	  also VIA_NB2HOST_REG54[4] need	to be enabled.
+Chipset_BL8==>chipset side can	set burst length=8
+two register need to set
+ 1. Device 0 function 2 HOST:REG54[4]
+ 2. Device 0 function 3 DRAM:REG6C[3]
+*/
+void DRAMBurstLength(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data, BL;
+	u8 Sockets;
+	/*SPD byte16 bit3,2 describes the burst length supported. bit3=1 support BL=8 bit2=1 support BL=4 */
+	BL = 0x0c;
+	for (Sockets = 0; Sockets < 2; Sockets++) {
+		if (DramAttr->DimmInfo[Sockets].bPresence) {
+			BL &=
+			    (DramAttr->DimmInfo[Sockets].
+			     SPDDataBuf[SPD_SDRAM_BURSTLENGTH]);
+		}
+	}
+
+	/*D0F3Rx6c bit3 CHA SDRAM effective burst length, for 64bit mode ranks =0 BL=4 ; =1 BL=8 */
+
+	if (BL & 0x08)		/*All Assembly support BL=8 */
+		BL = 0x8;	/*set bit3 */
+	else
+		BL = 0x00;	/*clear bit3 */
+
+	Data = pci_read_config8(MEMCTRL, 0x6c);
+	Data = (u8) ((Data & 0xf7) | BL);
+
+#if ENABLE_CHB
+	if (DramAttr->RankNumChB > 0) {
+		BL = DramAttr->DimmInfo[2].
+		    SPDDataBuf[SPD_SDRAM_BURSTLENGTH];
+		//Rx6c[1], CHB burst length
+		if (BL & 0x08)	/*CHB support BL=8 */
+			BL = 0x2;	/*set bit1 */
+		else
+			BL = 0x00;	/*clear bit1 */
+
+		Data = (Data & 0xFD) | BL;
+	}
+#endif
+	pci_write_config8(MEMCTRL, 0x6c, Data);
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/Detection.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/Detection.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/Detection.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,192 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define SMBUS_ADDR_CH_A_1         0xA0	// Dimmx
+#define SMBUS_ADDR_CH_A_2         0xA2	// Dimmx
+#define SMBUS_ADDR_CH_B_1         0xA4	// Dimmx
+#define SMBUS_ADDR_CH_B_2         0xA6	// Dimmx
+
+/*read data*/
+CB_STATUS GetSPDData(u8 Slot, u8 Length, u8 * Buf);
+
+void DRAMCmdRate(DRAM_SYS_ATTR * DramAttr);
+
+
+
+CB_STATUS GetInfoFromSPD(DRAM_SYS_ATTR * DramAttr);
+
+CB_STATUS GetSPDData(u8 Slot, u8 Length, u8 * Buf)
+{
+	// CB_STATUS Status = CB_NOT_READY;
+	u8 Val;
+	u8 i;
+
+	if (1 > Length || NULL == Buf)
+		return CB_INVALID_PARAMETER;
+
+	for (i = 0; i < Length; i++) {
+		Val = get_spd_data(ctrl.channel0[Slot], i);
+		*(Buf + i) = Val;
+	}
+	return CB_SUCCESS;
+}
+
+CB_STATUS DRAMDetect(DRAM_SYS_ATTR * DramAttr)
+{
+	CB_STATUS Status = CB_SUCCESS;
+
+	PRINT_DEBUG_MEM("Dram Detection \r");
+
+	/*Read D0F3Rx6C , detect memory type DDR1 or DDR2 */
+	// 353 supports DDR2 only
+	DramAttr->DramType = RAMTYPE_SDRAMDDR2;
+	/*get information for SPD */
+	Status = GetInfoFromSPD(DramAttr);
+	if (CB_SUCCESS == Status) {
+		/*64bit or 128Bit */
+		//
+		//  if (RAMTYPE_SDRAMDDR == DramAttr->DramType)
+
+		/*select command rate */
+		DRAMCmdRate(DramAttr);
+	}
+	return Status;
+}
+
+
+// Determine 1T or 2T Command Rate:
+// To enable 1T command Rate, the       system will satisfy the following 3 conditions:
+// 1. Each DRAM channel may have 1 or 2 ranks of DIMM. 3/4 ranks can not support 1T command rate
+//    It's for loading issue. 1T can supports (a). only one socket with two ranks OR
+//    (b). two sockets each with 1 rank.
+// 2. User wishes       to enable 1T command rate mode and turn on by Setup menu
+// 3. If 1T command rate can    be enabled, just set EBP bit here.
+void DRAMCmdRate(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+
+	// 5.1t/2t command rate, use the stable set
+	//offset50
+	DramAttr->CmdRate = 2;
+	Data = pci_read_config8(MEMCTRL, 0x50);
+	Data = (u8) (Data & 0xEE);
+	pci_write_config8(MEMCTRL, 0x50, Data);
+}
+
+/*get SPD data and set RANK presence map*/
+/*
+Sockets0,1 is Channel A / Sockets2,3 is Channel B
+socket0 SPD device address 0x50 / socket1 SPD device address 0x51
+socket2 SPD device address 0x52 / socket3 SPD device address 0x53
+*/
+CB_STATUS GetInfoFromSPD(DRAM_SYS_ATTR * DramAttr)
+{
+	CB_STATUS Status;
+	u8 *pSPDDataBuf;
+	u8 ModuleDataWidth;
+	u8 ChipWidth;
+	u8 RankNum;
+	u8 LoadNum;
+	u8 Sockets, i;
+	BOOLEAN bFind;
+	bFind = FALSE;
+	Status = CB_DEVICE_ERROR;
+
+	for (Sockets = 0; Sockets < MAX_SOCKETS; Sockets++) {
+		pSPDDataBuf = DramAttr->DimmInfo[Sockets].SPDDataBuf;
+		pSPDDataBuf[SPD_MEMORY_TYPE] =
+		    get_spd_data(ctrl.channel0[Sockets], SPD_MEMORY_TYPE);
+		if (pSPDDataBuf[SPD_MEMORY_TYPE] == 0) {
+			Status = CB_NOT_READY;
+		} else {
+			Status =
+			    GetSPDData(Sockets, SPD_DATA_SIZE,
+				       pSPDDataBuf);
+			PRINT_DEBUG_MEM("SPD : \r");
+			for (i = 0; i < SPD_DATA_SIZE; i++) {
+				PRINT_DEBUG_MEM(" ");
+				PRINT_DEBUG_MEM_HEX8(pSPDDataBuf[i]);
+			}
+		}
+		if (CB_SUCCESS == Status) {
+			/*if Dram Controller detected type not same as the type got from SPD, There are ERROR */
+			if (pSPDDataBuf[SPD_MEMORY_TYPE] !=
+			    DramAttr->DramType) {
+				Status = CB_DEVICE_ERROR;	/*Memory int error */
+				PRINT_DEBUG_MEM
+				    ("Memory Device ERROR: Dram Controller detected type != type got from SPD \r");
+				break;
+			}
+			DramAttr->DimmInfo[Sockets].bPresence = TRUE;
+			/*calculate load number (chips number) */
+			ModuleDataWidth =
+			    (u8) (DramAttr->DimmInfo[Sockets].
+				  SPDDataBuf[SPD_SDRAM_MOD_DATA_WIDTH +
+					     1]);
+			ModuleDataWidth = (u8) (ModuleDataWidth << 8);
+			ModuleDataWidth |=
+			    (u8) (DramAttr->DimmInfo[Sockets].
+				  SPDDataBuf[SPD_SDRAM_MOD_DATA_WIDTH]);
+			ChipWidth =
+			    (u8) ((DramAttr->DimmInfo[Sockets].
+				   SPDDataBuf[SPD_SDRAM_WIDTH]) & 0x7F);
+			LoadNum = (u8) (ModuleDataWidth / ChipWidth);
+
+			/*set the RANK map */
+			RankNum = (u8) (pSPDDataBuf[SPD_SDRAM_DIMM_RANKS] & 0x3);	/*get bit0,1, the Most number of supported RANK is 2 */
+			if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
+				RankNum++;	/*for DDR bit[0,1] 01->1 RANK  10->2 RANK; for DDR2 bit[0,1] = 00 -> 1 RANK  01 -> 2 RANK */
+			if (RankNum != 2 && RankNum != 1) {	/*every DIMM have 1 or 2 ranks */
+				Status = CB_DEVICE_ERROR;
+				PRINT_DEBUG_MEM
+				    ("Memory Device ERROR: the number of RANK not support!\r");
+				break;
+			}
+
+			if (Sockets < 2) {	/*sockets0,1 is channel A */
+				DramAttr->RankNumChA =
+				    (u8) (DramAttr->RankNumChA + RankNum);
+				DramAttr->DimmNumChA++;
+				DramAttr->LoadNumChA =
+				    (u8) (DramAttr->LoadNumChA * LoadNum *
+					  RankNum);
+			} else {	/*sockets2,3 is channel B */
+
+				DramAttr->RankNumChB =
+				    (u8) (DramAttr->RankNumChB + RankNum);
+				DramAttr->DimmNumChB++;
+				DramAttr->LoadNumChB =
+				    (u8) (DramAttr->LoadNumChB * LoadNum *
+					  RankNum);;
+			}
+			RankNum |= 1;	/*set rank map */
+			DramAttr->RankPresentMap |=
+			    (RankNum << (Sockets * 2));
+			bFind = TRUE;
+		}
+	}
+	PRINT_DEBUG_MEM("Rank Present Map:");
+	PRINT_DEBUG_MEM_HEX8(DramAttr->RankPresentMap);
+	PRINT_DEBUG_MEM("\r");
+
+	if (bFind)
+		Status = CB_SUCCESS;
+
+	return Status;
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DevInit.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DevInit.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DevInit.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,1318 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+void DRAMSetVRNum(DRAM_SYS_ATTR * DramAttr, u8 PhyRank,	// Physical Rank
+		  u8 VirRank,	// Virtual Rank
+		  BOOLEAN Enable);
+
+void SetEndingAddr(DRAM_SYS_ATTR * DramAttr, u8 VirRank,	// Ending address register      number indicator (INDEX
+		   INT8 Value	// (value) add or subtract value to this and after banks
+    );
+
+void InitDDR2CHA(DRAM_SYS_ATTR * DramAttr);
+
+void InitDDR2CHB(DRAM_SYS_ATTR * DramAttr);
+
+void InitDDR2CHC(DRAM_SYS_ATTR * DramAttr);
+
+CB_STATUS VerifyChc();
+/*===================================================================
+Function   : DRAMRegInitValue()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : Set necessary register before DRAM initialize
+===================================================================*/
+
+static const u8 DramRegTbl[][3] = {
+	//Register     AND             OR
+	{0x50, 0x11, 0xEE},	// DDR default MA7 for DRAM init
+	{0x51, 0x11, 0x60},	// DDR default MA3 for CHB init
+	{0x52, 0x00, 0x33},	// DDR use BA0=M17, BA1=M18,
+	{0x53, 0x00, 0x3F},	// DDR    BA2=M19
+
+	{0x54, 0x00, 0x00},	// default PR0=VR0; PR1=VR1
+	{0x55, 0x00, 0x00},	// default PR2=VR2; PR3=VR3
+	{0x56, 0x00, 0x00},	// default PR4=VR4; PR5=VR5
+	{0x57, 0x00, 0x00},	// default PR4=VR4; PR5=VR5
+
+	{0x60, 0x00, 0x00},	// disable fast turn-around
+	{0x65, 0x00, 0xD9},	// AGP timer = 0XD; Host timer = 8;
+	{0x66, 0x00, 0x88},	//DRAMC Queue Size = 4; park at the last bus owner,Priority promotion timer = 8
+	{0x68, 0x00, 0x0C},
+	{0x69, 0xF0, 0x04},	// set RX69[3:0]=0000b
+	{0x6A, 0x00, 0x00},	// refresh counter
+	{0x6E, 0xF8, 0x80},	//must set 6E[7],or else DDR2  probe test will fail
+	// In here, we not set RX70~RX74,       because we just init DRAM but no need R/W DRAM,
+	// when we check DQS input/output       delay, then we need R/W DRAM.
+
+	//{0x79,         0x00,         0x8F },
+	{0x85, 0x00, 0x00},
+	// {0x90,         0x87,        0x78 },
+	// {0x91,         0x00,        0x46 }, 
+	{0x40, 0x00, 0x00},
+	{0, 0, 0}
+};
+
+void DRAMRegInitValue(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Idx, CL;
+	u8 Data;
+
+	for (Idx = 0; DramRegTbl[Idx][0] != 0; Idx++) {
+		Data = pci_read_config8(MEMCTRL, DramRegTbl[Idx][0]);
+		Data &= DramRegTbl[Idx][1];
+		Data |= DramRegTbl[Idx][2];
+		pci_write_config8(MEMCTRL, DramRegTbl[Idx][0], Data);
+	}
+
+	Data = 0x80;
+	pci_write_config8(PCI_DEV(0, 0, 4), 0xa3, Data);
+
+	//set Dram Controllor mode 
+	Data = pci_read_config8(MEMCTRL, 0x6c);
+	Data &= 0xFB;
+	if (ENABLE_CHC == 0) {
+		Data |= 0x4;	//only CHA 64 bit mode
+		pci_write_config8(MEMCTRL, 0x6c, Data);
+	} else {
+		Data |= 0x0;	//CHA + CHC 
+		pci_write_config8(MEMCTRL, 0x6c, Data);
+
+		//Data = 0xAA;
+		//pci_write_config8(MEMCTRL, 0xb1, Data);
+
+		//set CHB DQSB input delay, or else will meet error which is some byte is right
+		//but another bit is error
+		Data = pci_read_config8(MEMCTRL, 0xff);
+		Data = (Data & 0x03) | 0x3D;
+		pci_write_config8(MEMCTRL, 0xff, Data);
+
+		//enable CHC  RXDB[7]
+		//Data=pci_read_config8(MEMCTRL, 0xdb);
+		//  Data = (Data & 0x7F) | 0x80;
+		//pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		//rx62[2:0],CHA and CHB CL
+		Data = pci_read_config8(MEMCTRL, 0x62);
+		CL = Data & 0x07;
+
+		//if CL = 6 , so I set CHB CL = 5 default
+		if (CL >= 4)
+			CL = 3;
+
+		// set CHC  Read CL rxDC[6:7]
+		Data = pci_read_config8(MEMCTRL, 0xdc);
+		Data = (Data & 0x3F) | (CL << 6);
+		pci_write_config8(MEMCTRL, 0xdc, Data);
+		// set CHC  write CL rxDF[6:7]
+		Data = pci_read_config8(MEMCTRL, 0xdf);
+		Data = (Data & 0x3F) | (CL << 6);
+		pci_write_config8(MEMCTRL, 0xdf, Data);
+		// set CHC ODT  RxDC[5:0]
+		Data = pci_read_config8(MEMCTRL, 0xdc);
+		Data = (Data & 0xC0) | 0x03;
+		pci_write_config8(MEMCTRL, 0xdc, Data);
+
+		//set column type RXDD[6] and enable ODT PAD  RXDD[7]
+		Data = pci_read_config8(MEMCTRL, 0xdd);
+		Data |= 0x80;
+		Idx = DramAttr->DimmInfo[2].SPDDataBuf[SPD_SDRAM_COL_ADDR];
+		if ((Idx & 0x0F) == 10)
+			Data |= 0x40;	//MA9~MA0
+		else
+			Data &= 0xBF;	//MA8~MA0
+		pci_write_config8(MEMCTRL, 0xdd, Data);
+	}
+
+	// Disable read DRAM fast   ready   ;Rx51[7]
+	// Disable Read Around Write                ;Rx51[6]
+
+	// Disable Consecutive Read                 ;RX52[1:0]
+	// disable speculative read
+
+}
+
+/*===================================================================
+Function   : DRAMInitializeProc()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : DRAM initialize according to the bios porting guid
+===================================================================*/
+
+#define EXIST_TEST_PATTERN		0x55555555
+#define NOT_EXIST_TEST_PATTERN		0xAAAAAAAA
+BOOLEAN ChkForExistLowBank()
+{
+	u32 *Address, data32;
+
+	// Check Pattern
+
+	Address = (u32 *) 8;
+	*Address = EXIST_TEST_PATTERN;
+	Address = (u32 *) 4;
+	*Address = EXIST_TEST_PATTERN;
+
+//      _asm {WBINVD}   
+	WaitMicroSec(100);
+	Address = (u32 *) 8;
+	data32 = *Address;
+	if (data32 != EXIST_TEST_PATTERN)
+		return FALSE;
+	Address = (u32 *) 4;
+	data32 = *Address;
+	if (data32 != EXIST_TEST_PATTERN)
+		return FALSE;
+
+	// Check not Pattern
+	Address = (u32 *) 8;
+	*Address = NOT_EXIST_TEST_PATTERN;
+	Address = (u32 *) 4;
+	*Address = NOT_EXIST_TEST_PATTERN;
+	//_asm {WBINVD}
+	WaitMicroSec(100);
+
+
+	Address = (u32 *) 8;
+	data32 = *Address;
+	if (data32 != (u32) (NOT_EXIST_TEST_PATTERN))
+		return FALSE;
+	Address = (u32 *) 4;
+	data32 = *Address;
+	if (data32 != (u32) (NOT_EXIST_TEST_PATTERN))
+		return FALSE;
+
+	return TRUE;
+}
+
+void InitDDR2CHC(DRAM_SYS_ATTR * DramAttr);
+void InitDDR2CHB(DRAM_SYS_ATTR * DramAttr);
+void DRAMInitializeProc(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 shift, idx;
+	BOOLEAN Status;
+
+	shift = 1;
+	for (idx = 0; idx < MAX_RANKS; idx++) {
+		if ((DramAttr->RankPresentMap & shift) != 0) {
+			// Set VR# to physical rank indicated = PR + physical rank enable bit
+			DRAMSetVRNum(DramAttr, idx, idx, TRUE);
+			SetEndingAddr(DramAttr, idx, 0x10);	// assume 1G size
+			if (idx < 4)	//CHA init
+				InitDDR2CHA(DramAttr);	//temp wjb 2007/1 only for compiling
+			// in the function InitDDR2,the parameter is no need   
+			Status = ChkForExistLowBank();
+			if (Status == TRUE) {
+				PRINT_DEBUG_MEM(" S\r");
+			} else {
+				PRINT_DEBUG_MEM(" F\r");
+			}
+			// Set VR# to physical rank indicated = 00h + physical rank enable bit
+			DRAMSetVRNum(DramAttr, idx, 0, FALSE);
+			SetEndingAddr(DramAttr, idx, -16);
+		}
+		shift <<= 1;
+	}
+	if (ENABLE_CHC)
+		InitDDR2CHC(DramAttr);
+
+}
+
+
+/*===================================================================
+Function   : DRAMSetVRNUM()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+		  PhyRank:   Physical Rank number
+		  VirRank:    Virtual Rank number
+		  Enable:      Enable/Disable Physical Rank
+Output     : Void
+Purpose   : Set virtual rank number for physical rank
+                 Program the specific physical rank with specific virtual rank number
+                 Program when necessary, otherwise don't touch the pr-vr-mapping registers
+===================================================================*/
+
+void DRAMSetVRNum(DRAM_SYS_ATTR * DramAttr, u8 PhyRank,	// Physical Rank
+		  u8 VirRank,	// Virtual Rank
+		  BOOLEAN Enable)
+{
+	u8 Data;
+	u8 AndData, OrData;
+	Data = pci_read_config8(MEMCTRL, (0x54 + (PhyRank >> 1)));
+
+	OrData = 0;
+	if (Enable)
+		OrData |= 0x08;
+	OrData |= VirRank;
+	if ((PhyRank & 0x01) == 0x00) {
+		AndData = 0x0F;	//  keep the value of odd rank on PR # is even(keep 1,3,5,7)
+		OrData <<= 4;	// VR #, value to be set
+	} else {
+		AndData = 0xF0;	// keep the value of even rank on PR # is odd(keep 0,2,4,6)
+	}
+	Data &= AndData;
+	Data |= OrData;
+	pci_write_config8(MEMCTRL, (0x54 + (PhyRank >> 1)), Data);
+}
+
+
+/*===================================================================
+Function   : SetEndingAddr()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+		  VirRank:    Virtual Rank number
+		  Value:       (value) add or subtract value to this and after banks 
+Output     : Void
+Purpose   : Set ending address of virtual rank specified by VirRank 
+===================================================================*/
+
+void SetEndingAddr(DRAM_SYS_ATTR * DramAttr, u8 VirRank,	// Ending address register      number indicator (INDEX
+		   INT8 Value	// (value) add or subtract value to this and after banks
+    ) {
+	u8 Data;
+
+	// Read register,Rx40-Rx47(0,1,2,3,4,5,6,7) and set the ending address
+	Data = pci_read_config8(MEMCTRL, 0x40 + VirRank);
+	Data = (u8) (Data + Value);
+	pci_write_config8(MEMCTRL, 0x40 + VirRank, Data);
+
+	//program the virank's begining address to zero
+	Data = 0x00;
+	pci_write_config8(MEMCTRL, 0x48 + VirRank, Data);
+}
+
+/*===================================================================
+Function   : InitDDR2()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : Initialize DDR2 by standard sequence
+===================================================================*/
+
+//                               DLL:         Enable                              Reset
+static const u32 CHA_MRS_DLL_150[2] = { 0x00020200, 0x00000800 };	// with 150 ohm (A17=1, A9=1), (A11=1)(cpu address)
+static const u32 CHA_MRS_DLL_75[2] = { 0x00020020, 0x00000800 };	// with 75 ohm  (A17=1, A5=1), (A11=1)(cpu address)
+
+//               CPU(DRAM)
+// { DLL: Enable. A17(BA0)=1 and A3(MA0)=0 }
+// { DLL: reset.  A11(MA8)=1 }
+//
+//                      DDR2                    CL=2    CL=3    CL=4    CL=5     CL=6(Burst type=interleave)(WR fine tune in code)
+static const u16 CHA_DDR2_MRS_table[5] = { 0x0150, 0x01D0, 0x0250, 0x02D0, 0x350 };	// BL=4 ;Use 1X-bandwidth MA table to init DRAM
+
+//                                                       MA11        MA10(AP)      MA9
+#define CHA_MRS_DDR2_TWR2		(0 << 13) + (0 << 20) + (1 << 12)	// Value = 001000h
+#define CHA_MRS_DDR2_TWR3		(0 << 13) + (1 << 20) + (0 << 12)	// Value = 100000h
+#define CHA_MRS_DDR2_TWR4		(0 << 13) + (1 << 20) + (1 << 12)	// Value = 101000h
+#define CHA_MRS_DDR2_TWR5		(1 << 13) + (0 << 20) + (0 << 12)	// Value = 002000h
+#define CHA_MRS_DDR2_TWR6		(1 << 13) + (0 << 20) + (1 << 12)	// Value = 003000h
+
+//                              DDR2             Twr=2                  Twr=3              Twr=4                  Twr=5
+static const u32 CHA_DDR2_Twr_table[5] =
+    { CHA_MRS_DDR2_TWR2, CHA_MRS_DDR2_TWR3, CHA_MRS_DDR2_TWR4,
+CHA_MRS_DDR2_TWR5, CHA_MRS_DDR2_TWR6 };
+
+#define CHA_OCD_Exit_150ohm		0x20200	// EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=1,MA2=0 (DRAM bus address)
+//                A17=1, A12=A11=A10=0,A9=1 ,A5=0  (CPU address)
+#define CHA_OCD_Default_150ohm	      0x21E00	// EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=1,MA2=0 (DRAM bus address)
+//               A17=1, A12=A11=A10=1,A9=1 ,A5=0  (CPU address)
+#define CHA_OCD_Exit_75ohm		0x20020	// EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=0,MA2=1 (DRAM bus address)
+//              A17=1, A12=A11=A10=0,A9=0 ,A5=1  (CPU address)
+#define CHA_OCD_Default_75ohm	0x21C20	// EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=0,MA2=1 (DRAM bus address)
+//              A17=1, A12=A11=A10=1,A9=0 ,A5=1  (CPU address)
+
+void InitDDR2CHA(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 Reg6BVal;
+	u8 Idx, CL, BL, Twr;
+	u32 AccessAddr;
+	u8 DimmNum;
+
+	// step2.
+	//disable bank paging and multi page
+	Data = pci_read_config8(MEMCTRL, 0x69);
+	Data &= ~0x03;
+	pci_write_config8(MEMCTRL, 0x69, Data);
+
+	Reg6BVal = pci_read_config8(MEMCTRL, 0x6b);
+	Reg6BVal &= ~0x07;
+	// Step 3.
+	// At least one NOP cycle   will be issued after the 1m sec device deselect.
+	Data = Reg6BVal | 0x01;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	// step4.
+	//Read a double word from any address of the DIMM
+	DimmRead(0x0);
+
+	// Step 5.
+	// A minimum pause of 200u sec will be provided after the NOP.
+	// - <<<    reduce BOOT UP time >>> -
+	// Loop 200us
+	for (Idx = 0; Idx < 0x10; Idx++)
+		WaitMicroSec(100);
+
+	// Step 6.
+	// Precharge all (PALL) will be issued to the DDR.
+	Data = Reg6BVal | 0x02;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	// Step7.
+	//Read a double word from any address of the DIMM
+	DimmRead(0x0);
+
+	// Step 8.
+	// MSR Eable will be issued to the DDR
+	Data = Reg6BVal | 0x03;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+
+	// Step 9,10. check ODT value for EMRS(1) command
+	// according to  ODTLookUp_TBL in DrivingSetting.c if there is one dimm in MB's one channel , the DDR2's ODT is 150ohm
+	// if there is two dimm in MB's one channel, the DDR2's ODT is 75 ohm
+	DimmNum = DramAttr->DimmNumChA;
+
+	if (DimmNum == 1)	//DDR's ODT is 150ohm
+	{
+		AccessAddr = (u32) CHA_MRS_DLL_150[0];
+		DimmRead(AccessAddr);	//issue EMRS  DLL  Enable
+		PRINT_DEBUG_MEM("Step 9 Address ");
+		PRINT_DEBUG_MEM_HEX32(AccessAddr);
+		PRINT_DEBUG_MEM("\r");
+
+		AccessAddr = (u32) CHA_MRS_DLL_150[1];
+		DimmRead(AccessAddr);	//issue MRS    DLL   Reset
+		PRINT_DEBUG_MEM("Step 10 Address ");
+		PRINT_DEBUG_MEM_HEX32(AccessAddr);
+		PRINT_DEBUG_MEM("\r");
+	} else if (DimmNum == 2)	//DDR's ODT is 75ohm
+	{
+		AccessAddr = (u32) CHA_MRS_DLL_75[0];
+		DimmRead(AccessAddr);	//issue EMRS  DLL  Enable
+		AccessAddr = (u32) CHA_MRS_DLL_75[1];
+		DimmRead(AccessAddr);	//issue MRS    DLL   Reset
+	} else {
+		PRINT_DEBUG_MEM("Dimm NUM ERROR:");
+		PRINT_DEBUG_MEM_HEX8(DimmNum);
+		PRINT_DEBUG_MEM("\r");
+	}
+
+	// Step 11.
+	// Precharge all (PALL) will be issued to the DDR.
+	Data = Reg6BVal | 0x02;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	// Step12.
+	//Read a double word from any address of the DIMM
+	DimmRead(0x0);
+
+	// Step 13.
+	// Execute 8 CBR refresh
+	Data = Reg6BVal | 0x04;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	// issue 14,15 , 16
+	//reads and wait 100us between each read
+	for (Idx = 0; Idx < 8; Idx++) {
+		DimmRead(0x0);
+		WaitMicroSec(100);
+	}
+
+	// Step 17.
+	//  enable  MRS for MAA
+	Data = Reg6BVal | 0x03;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	//Step 18
+	//the SDRAM parameters.(Burst Length, CAS# Latency , Write recovery etc.)
+	//-------------------------------------------------------------
+	//Burst Length : really offset Rx6c[3]
+	Data = pci_read_config8(MEMCTRL, 0x6c);
+	BL = (Data & 0x08) >> 3;
+
+	// CL = really offset RX62[2:0]
+	Data = pci_read_config8(MEMCTRL, 0x62);
+	CL = Data & 0x03;
+
+	AccessAddr = (u32) (CHA_DDR2_MRS_table[CL]);
+	if (BL) {
+		AccessAddr += 8;
+	}
+	//Write recovery  : really offset Rx63[7-5]
+	Data = pci_read_config8(MEMCTRL, 0x63);
+	Twr = (Data & 0xE0) >> 5;
+
+	AccessAddr += CHA_DDR2_Twr_table[Twr];
+	// AccessAddr = 0x1012D8;
+	DimmRead(AccessAddr);	// Set MRS command
+	PRINT_DEBUG_MEM("Step 18 Address");
+	PRINT_DEBUG_MEM_HEX32(AccessAddr);
+	PRINT_DEBUG_MEM("\r");
+
+	//Step 19,20
+	if (DimmNum == 1)	//DDR's ODT is 150ohm
+	{
+		AccessAddr = (u32) CHA_OCD_Default_150ohm;
+		DimmRead(AccessAddr);	//issue EMRS OCD Default
+		PRINT_DEBUG_MEM("Step 19 Address ");
+		PRINT_DEBUG_MEM_HEX32(AccessAddr);
+		PRINT_DEBUG_MEM("\r");
+
+		AccessAddr = (u32) CHA_OCD_Exit_150ohm;
+		DimmRead(AccessAddr);	//issue EMRS OCD Calibration Mode Exit
+		PRINT_DEBUG_MEM("Step 20 Address ");
+		PRINT_DEBUG_MEM_HEX32(AccessAddr);
+		PRINT_DEBUG_MEM("\r");
+	} else if (DimmNum == 2)	//DDR's ODT is 75ohm
+	{
+		AccessAddr = (u32) CHA_OCD_Default_75ohm;
+		DimmRead(AccessAddr);	//issue EMRS OCD Default
+		AccessAddr = (u32) CHA_OCD_Exit_75ohm;
+		DimmRead(AccessAddr);	//issue EMRS OCD Calibration Mode Exit
+	} else {
+		PRINT_DEBUG_MEM("Dimm NUM ERROR: ");
+		PRINT_DEBUG_MEM_HEX8(DimmNum);
+		PRINT_DEBUG_MEM("\r");
+	}
+
+	//Step 21
+	//After MRS the device should be    ready for full functionality within 3 clocks
+	// after Tmrd is met.
+	Data = Reg6BVal;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	// Enable bank paging and multi page
+	Data = pci_read_config8(MEMCTRL, 0x69);
+	Data |= 0x03;
+	pci_write_config8(MEMCTRL, 0x69, Data);
+}
+
+/*===================================================================
+Function   : InitDDR2_CHB()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : Initialize DDR2 of CHB by standard sequence
+Reference  : 
+===================================================================*/
+/*//		                 DLL:	      Enable				  Reset
+static const  u32 CHB_MRS_DLL_150[2] =	{ 0x00020200 | (1 << 20), 0x00000800 };	// with 150 ohm (A17=1, A9=1), (A11=1)(cpu address)
+//u32 CHB_MRS_DLL_75[2]  =	{ 0x00020020 | (1 << 20), 0x00000800 };	// with 75 ohm  (A17=1, A5=1), (A11=1)(cpu address)
+//		 CPU(DRAM)
+// { DLL: Enable. A17(BA0)=1 and A3(MA0)=0 }
+// { DLL: reset.  A11(MA8)=1 }
+//
+//                      DDR2 			CL=2	CL=3	CL=4	CL=5 	(Burst type=interleave)(WR fine tune in code)
+static const  u16 CHB_DDR2_MRS_table[4] ={ 0x0150, 0x01D0, 0x0250, 0x02D0 };	// BL=4 ;Use 1X-bandwidth MA table to init DRAM
+
+//			 				 MA11	     MA10(AP)      MA9
+#define CHB_MRS_DDR2_TWR2		(0 << 13) + (0 << 20) + (1 << 12)	// Value = 001000h
+#define CHB_MRS_DDR2_TWR3		(0 << 13) + (1 << 20) + (0 << 12)	// Value = 100000h
+#define CHB_MRS_DDR2_TWR4		(0 << 13) + (1 << 20) + (1 << 12)	// Value = 101000h
+#define CHB_MRS_DDR2_TWR5		(1 << 13) + (0 << 20) + (0 << 12)	// Value = 002000h
+#define CHB_MRS_DDR2_TWR6		(1 << 13) + (0 << 20) + (1 << 12)	// Value = 003000h
+
+//				DDR2 		 Twr=2			Twr=3		   Twr=4		  Twr=5
+static const u32 CHB_DDR2_Twr_table[5] = { CHB_MRS_DDR2_TWR2,	CHB_MRS_DDR2_TWR3, CHB_MRS_DDR2_TWR4, CHB_MRS_DDR2_TWR5, CHB_MRS_DDR2_TWR6 };
+
+#define CHB_OCD_Exit_150ohm		0x20200 | (1 << 20) 		 // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=1,MA2=0 (DRAM bus address)
+//	          A17=1, A12=A11=A10=0,A9=1 ,A5=0  (CPU address)
+#define CHB_OCD_Default_150ohm	0x21E00 | (1 << 20)     	// EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=1,MA2=0 (DRAM bus address)
+//	         A17=1, A12=A11=A10=1,A9=1 ,A5=0  (CPU address)
+//#define CHB_OCD_Exit_75ohm		0x20020 | (1 << 20) 	      // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=0,MA2=1 (DRAM bus address)
+//	        A17=1, A12=A11=A10=0,A9=0 ,A5=1  (CPU address)
+//#define CHB_OCD_Default_75ohm	0x21C20 | (1 << 20)      // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=0,MA2=1 (DRAM bus address)
+//	        A17=1, A12=A11=A10=1,A9=0 ,A5=1  (CPU address)
+void InitDDR2CHB(
+               DRAM_SYS_ATTR          *DramAttr
+             )
+
+{
+    u8     Data;
+    u8	    Idx, CL, BL, Twr;
+    u32   AccessAddr;
+
+    Data = 0x80;
+    pci_write_config8(MEMCTRL, 0x54, Data);
+	
+    // step3.
+    //disable bank paging and multi page
+    Data=pci_read_config8(MEMCTRL, 0x69);
+    Data &= ~0x03;
+    pci_write_config8(MEMCTRL, 0x69, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data |= 0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+	
+    //step 4. Initialize CHB begin
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data |= 0x40;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+	
+    //Step 5. NOP command enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data  |= 0x08;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+   
+    //Step 6.  issue a nop cycle,RegD3[7]  0 -> 1
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+    // Step 7.
+    // A minimum pause of 200u sec will be provided after the NOP.
+    // - <<<	reduce BOOT UP time >>>	-
+    // Loop 200us
+    for (Idx = 0; Idx < 0x10; Idx++)
+        WaitMicroSec(10);
+	
+    // Step 8.
+    // all banks precharge command enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x10;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+   //step 9. issue a precharge all cycle,RegD3[7]  0 -> 1
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+	
+   //step10. EMRS enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x18;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xC7;
+    Data |= 0x08;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //step11. EMRS DLL Enable and Disable DQS
+    AccessAddr = CHB_MRS_DLL_150[0] >> 3;
+    Data =(u8) (AccessAddr & 0xff);
+    pci_write_config8(MEMCTRL, 0xd9, Data);
+
+    Data = (u8)((AccessAddr & 0xff00) >> 8);
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xF9;
+    Data |= (u8)((AccessAddr & 0x30000) >> 15);
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    //step12.  issue EMRS cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //step13. MSR enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x18;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xC7;
+    Data |= 0x00;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+    //step 14. MSR DLL Reset 
+    AccessAddr = CHB_MRS_DLL_150[1] >> 3;
+    Data =(u8) (AccessAddr & 0xff);
+    pci_write_config8(MEMCTRL, 0xd9, Data);
+
+    Data = (u8)((AccessAddr & 0xff00) >> 8);
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xF9;
+    Data |= (u8)((AccessAddr & 0x30000) >> 15);
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    //step15.  issue MRS cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //clear the address
+    Data = 0x00;
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+     //step16.  all banks precharge command enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x10;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+   
+   // step17. issue precharge all cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //step18.  CBR cycle enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x20;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    //step 19.20.21
+    //repeat issue 8 CBR cycle, between each cycle stop 100us
+    for (Idx = 0; Idx < 8; Idx++)
+    {
+         // issue CBR cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    WaitMicroSec(200);
+    }
+	
+    //step22. MSR enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x18;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xC7;
+    Data |= 0x00;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+  
+    //the SDRAM parameters.(Burst Length, CAS# Latency , Write recovery etc.)
+    //-------------------------------------------------------------
+    //Burst Length : really offset Rx6c[1]
+    Data=pci_read_config8(MEMCTRL, 0x6C);
+    BL = (Data & 0x02) >> 1;
+
+    // CL = really offset RX62[2:0]
+    Data=pci_read_config8(MEMCTRL, 0x62);
+    CL = Data & 0x03;
+
+
+    AccessAddr  = (u32)(CHB_DDR2_MRS_table[CL]);
+    if (BL)
+    {
+        AccessAddr += 8;
+    }
+
+    //Write recovery  : really offset Rx63[7:5]
+    Data=pci_read_config8(MEMCTRL, 0x63);
+    Twr = (Data & 0xE0) >> 5;
+
+    AccessAddr += CHB_DDR2_Twr_table[Twr];
+    //MSR Address use addr[20:3]
+    AccessAddr >>= 3;
+
+   //step 23. MSR command
+    Data = (u8)(AccessAddr & 0xFF);
+    pci_write_config8(MEMCTRL, 0xD9, Data);
+
+    Data = (u8)((AccessAddr & 0xFF00) >> 8);
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xF9;
+    Data |= (u8)(((AccessAddr & 0x30000)>>16) << 1);
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+     //step 24.  issue MRS cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+	
+    //step 25. EMRS enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x18;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xC7;
+    Data |= 0x08;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+	
+
+    //step 26. OCD default
+     AccessAddr = (CHB_OCD_Default_150ohm) >> 3;
+    Data =(u8) (AccessAddr & 0xff);
+    pci_write_config8(MEMCTRL, 0xd9, Data);
+
+    Data = (u8)((AccessAddr & 0xff00) >> 8);
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xF9;
+    Data |= (u8)((AccessAddr & 0x30000) >> 15);
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+    //step 27.  issue EMRS cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+	
+     //step 25. EMRS enable
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x18;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xC7;
+    Data |= 0x08;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //step 28. OCD Exit
+     AccessAddr = (CHB_OCD_Exit_150ohm) >> 3;
+     Data =(u8) (AccessAddr & 0xff);
+    pci_write_config8(MEMCTRL, 0xd9, Data);
+
+    Data = (u8)((AccessAddr & 0xff00) >> 8);
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xF9;
+    Data |= (u8)((AccessAddr & 0x30000) >> 15);
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+     //step 29. issue EMRS cycle
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0x7F;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+    Data |=  0x80;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //clear  all the address
+    Data = 0x00;
+    pci_write_config8(MEMCTRL, 0xd9, Data);
+
+    Data = 0x00;
+    pci_write_config8(MEMCTRL, 0xda, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xF9;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+    //step 30. normal SDRAM Mode
+    Data=pci_read_config8(MEMCTRL, 0xd7);
+    Data &= 0xC7;
+    Data |= 0x00;
+    pci_write_config8(MEMCTRL, 0xd7, Data);
+
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xC7;
+    Data |= 0x00;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+    //step 31.  exit the initialization mode 
+    Data=pci_read_config8(MEMCTRL, 0xd3);
+    Data &= 0xBF;
+    pci_write_config8(MEMCTRL, 0xd3, Data);
+
+	
+    //step 32. Enable bank paging and multi page
+    Data=pci_read_config8(MEMCTRL, 0x69);
+    Data |= 0x03;
+    pci_write_config8(MEMCTRL, 0x69, Data);
+}
+*/
+/*===================================================================
+Function   : InitDDR2CHC()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : Initialize DDR2 of CHC by standard sequence
+Reference  : 
+===================================================================*/
+//                      DDR2                 CL=2          CL=3 CL=4   CL=5     (Burst type=interleave)(WR fine tune in code)
+static const u16 CHC_MRS_table[4] = { 0x22B, 0x23B, 0x24B, 0x25B };	// Use 1X-bandwidth MA table to init DRAM
+
+void InitDDR2CHC(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 Idx, CL, Twr;
+	u32 AccessAddr;
+	CB_STATUS Status;
+
+	// step3.
+	//clear RxDF[2] to disable Tri-state output 
+	Data = pci_read_config8(MEMCTRL, 0xdf);
+	Data &= 0xFB;
+	pci_write_config8(MEMCTRL, 0xdf, Data);
+
+
+
+	//step 4. Enable the initialization mode of DRAM Controller C with NB's PLL clock
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x60;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//Step 5. NOP command enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x00;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+	//Step 6.  issue a nop cycle,RegDB[1]  0 -> 1
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+	// Step 7.
+	// A minimum pause of 200u sec will be provided after the NOP.
+	// - <<<    reduce BOOT UP time >>> -
+	// Loop 200us
+	for (Idx = 0; Idx < 0x10; Idx++)
+		WaitMicroSec(100);
+
+	// Step 8.
+	// signal bank  precharge command enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x14;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//set  MA10 =1, precharge all bank
+	Data = 0x00;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+
+	Data = 0x04;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	//step 9. issue a precharge all cycle,RegD3[7]  0 -> 1
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step10. MRS enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x1C;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+	//step11. EMRS DLL enable and Disable DQS
+	Data = 0x40;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = 0x24;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	//step12.  issue EMRS cycle
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step13. MSR enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x1C;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step 14. MSR DLL Reset 
+	Data = 0x00;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = 0x01;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	//step15.  issue MRS cycle
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step16.  signal banks precharge command enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x14;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//set  MA10 =1, precharge all bank
+	Data = 0x00;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = 0x04;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	// step17. issue precharge all cycle
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step18.  CBR cycle enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x18;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	Data = 0x00;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = 0x00;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	//step 19.20.21
+	//repeat issue 8 CBR cycle, between each cycle stop 100us
+	for (Idx = 0; Idx < 8; Idx++) {
+		// issue CBR cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		WaitMicroSec(100);
+	}
+
+	//the SDRAM parameters.(, CAS# Latency , Write recovery etc.)
+	//------------------------------------------------------------
+
+	// CL = really offset RXDC[7:6]
+	Data = pci_read_config8(MEMCTRL, 0xdc);
+	CL = (Data & 0xC0) >> 6;
+
+	AccessAddr = (u32) (CHC_MRS_table[CL]);
+
+	//Write recovery  : really offset Rx63[7:5]
+	Data = pci_read_config8(MEMCTRL, 0x63);
+	Twr = (Data & 0xE0) >> 5;
+
+	AccessAddr += Twr * 0x200;
+
+	//step22. MSR enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x1C;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step 23. MSR command
+	Data = (u8) (AccessAddr & 0xFF);
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = (u8) ((AccessAddr & 0xFF00) >> 8);
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	//step 24.  issue MRS cycle
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step 25. EMRS enable
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0xE3;
+	Data |= 0x1C;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+	//step 26. OCD default
+	Data = 0xC0;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = 0x27;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+	//step 27.  issue EMRS cycle
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	//step 28. OCD Exit
+	Data = 0x40;
+	pci_write_config8(MEMCTRL, 0xf8, Data);
+
+	Data = 0x24;
+	pci_write_config8(MEMCTRL, 0xf9, Data);
+
+
+	//step 29. issue EMRS cycle
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data |= 0x2;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+	Data &= 0xFD;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+
+	Status = VerifyChc();
+	if (Status != CB_SUCCESS)
+		PRINT_DEBUG_MEM("Error!!!!CHC init error!\r");
+	//step 31.  exit the initialization mode 
+	Data = pci_read_config8(MEMCTRL, 0xdb);
+	Data &= 0x9F;
+	pci_write_config8(MEMCTRL, 0xdb, Data);
+}
+
+CB_STATUS VerifyChc()
+{
+	u8 Data, ByteVal, Index, pad;
+	u16 row;
+
+	//first write the pad to all the address
+
+	//the  row bits is 13 and  rank bit is 2, so the  address bits is 15 and the value is 0x7fff
+	//verify each MA[0:12],BA[0:1]
+	pad = 1;
+	for (row = 0; row < 0x8000; row++) {
+		//set the write value;
+		//verify each MD[15:0]
+		for (Data = pad, Index = 0; Index < 16; Index++) {
+			Data <<= 1;
+			if (Data == 0)
+				Data = 1;
+			pci_write_config8(PCI_DEV(0, 0, 7), 0xC0 + Index,
+					  Data);
+
+		}
+
+		//issue the bank active command
+		// bank active command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x10;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = (u8) (row && 0xFF);
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = (u8) ((row && 0xFF) >> 8);
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue active cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		//issue ready/completion for read/write
+		// read/completion command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x04;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue read/completion cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		//issue write command
+		// write command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x0C;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = (u8) ((row & 0x60) << 5);
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue write cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		////issue ready/completion for read/write
+		// read/completion command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x04;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue read/completion cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		//issue the bank active command
+		// bank active command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x10;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = (u8) (row && 0xFF);
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = (u8) ((row && 0xFF) >> 8);
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue active cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		////issue ready/completion for read/write
+		// read/completion command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x04;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue read/completion cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		////issue read command
+		// read/completion command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x08;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = (u8) ((row & 0x60) << 5);
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue read cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		////issue ready/completion for read/write
+		// read/completion command enable
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data &= 0xE3;
+		Data |= 0x04;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf8, Data);
+
+		Data = 0x00;
+		pci_write_config8(MEMCTRL, 0xf9, Data);
+
+		//  issue read/completion cycle
+		Data = pci_read_config8(MEMCTRL, 0xdb);
+		Data |= 0x2;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+		Data &= 0xFD;
+		pci_write_config8(MEMCTRL, 0xdb, Data);
+
+		//verify the  value;
+		for (ByteVal = pad, Index = 0; Index < 16; Index++) {
+			Data =
+			    pci_read_config8(PCI_DEV(0, 0, 7),
+					     0xD0 + Index);
+			if (ByteVal != Data) {
+				PRINT_DEBUG_MEM
+				    ("error!!!! row = %x,Index =%x,Data = %x,ByteVal=%x\r");
+			}
+			ByteVal <<= 1;
+			if (ByteVal == 0)
+				ByteVal = 1;
+		}
+		pad <<= 1;
+		if (pad == 0)
+			pad = 1;
+	}
+
+	return CB_SUCCESS;
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DrivingSetting.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DrivingSetting.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/DrivingSetting.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,396 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+      Driving setting:  ODT/DQS/DQ/CS/MAA/MAB/DCLK
+    */
+
+void DrivingODT(DRAM_SYS_ATTR * DramAttr);
+
+void DrivingDQS(DRAM_SYS_ATTR * DramAttr);
+
+void DrivingDQ(DRAM_SYS_ATTR * DramAttr);
+
+void DrivingCS(DRAM_SYS_ATTR * DramAttr);
+
+void DrivingMA(DRAM_SYS_ATTR * DramAttr);
+
+void DrivingDCLK(DRAM_SYS_ATTR * DramAttr);
+
+/* DRAM Driving Adjustment*/
+void DRAMDriving(DRAM_SYS_ATTR * DramAttr)
+{
+	PRINT_DEBUG_MEM("set ODT!\r");
+	DrivingODT(DramAttr);
+
+	PRINT_DEBUG_MEM("set DQS!\r");
+	DrivingDQS(DramAttr);
+
+	PRINT_DEBUG_MEM(("set DQ!\r"));
+	DrivingDQ(DramAttr);
+
+	PRINT_DEBUG_MEM("set CS!\r");
+	DrivingCS(DramAttr);
+
+	PRINT_DEBUG_MEM("set MAA!\r");
+	DrivingMA(DramAttr);
+
+	PRINT_DEBUG_MEM("set DCLK!\r");
+	DrivingDCLK(DramAttr);
+}
+
+
+/*
+ODT	Control	for DQ/DQS/CKE/SCMD/DCLKO in ChA & ChB
+which include driving enable/range and strong/weak selection
+ 
+Processing: According to DRAM frequency to ODT control bits.
+      		Because function enable bit must be the last one to be set.
+      		So the register VIA_NB3DRAM_REGD4 and VIA_NB3DRAM_REGD3 should be
+      		the last register	to be programmed.
+*/
+//-------------------------------------------------------------------------------
+//                      ODT Lookup Table
+//-------------------------------------------------------------------------------
+#define Rank0_ODT				0
+#define Rank1_ODT				1
+#define Rank2_ODT				2
+#define Rank3_ODT				3
+#define NA_ODT					0
+#define NB_ODT_75ohm			0
+#define NB_ODT_150ohm			1
+
+#define DDR2_ODT_75ohm			0x20
+#define DDR2_ODT_150ohm			0x40
+
+// Setting of ODT Lookup TBL
+//                      RankMAP , Rank 3               Rank 2              Rank 1              Rank 0           , DRAM & NB ODT setting
+//                  db  0000b   , Reserved
+#define ODTLookup_Tbl_count 8
+static const u8 ODTLookup_TBL[ODTLookup_Tbl_count][3] = {
+	// 0001b
+	{0x01,
+	 (Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank1_ODT << 2) +
+	 Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
+	// 0010b        , Reserved
+	// 0011b
+	{0x03,
+	 (Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank0_ODT << 2) +
+	 Rank1_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
+	// 0100b
+	{0x04,
+	 (Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank1_ODT << 2) +
+	 Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
+	// 0101b
+	{0x05,
+	 (Rank3_ODT << 6) + (Rank0_ODT << 4) + (Rank1_ODT << 2) +
+	 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
+	// 0110b        , Reserved
+	// 0111b
+	{0x07,
+	 (Rank3_ODT << 6) + (Rank0_ODT << 4) + (Rank2_ODT << 2) +
+	 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
+	// 1000b        , Reserved
+	// 1001b        , Reserved
+	// 1010b        , Reserved
+	// 1011b        , Reserved
+	// 1100b
+	{0x0c,
+	 (Rank2_ODT << 6) + (Rank3_ODT << 4) + (Rank1_ODT << 2) +
+	 Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
+	// 1101b
+	{0x0d,
+	 (Rank0_ODT << 6) + (Rank0_ODT << 4) + (Rank1_ODT << 2) +
+	 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
+	// 1110b        , Reserved
+	// 1111b
+	{0x0f,
+	 (Rank0_ODT << 6) + (Rank0_ODT << 4) + (Rank2_ODT << 2) +
+	 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm}
+};
+
+#define ODT_Table_Width_DDR2		4
+//                                                                                               RxD6   RxD3 
+static const u8 ODT_Control_DDR2[ODT_Table_Width_DDR2] = { 0xFC, 0x01 };
+
+void DrivingODT(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 i;
+	BOOLEAN bFound;
+
+	pci_write_config8(MEMCTRL, 0xD0, 0x88);
+
+	Data = ODT_Control_DDR2[0];
+	pci_write_config8(MEMCTRL, 0xd6, Data);
+
+	Data = ODT_Control_DDR2[1];
+	pci_write_config8(MEMCTRL, 0xd3, Data);
+
+	Data = pci_read_config8(MEMCTRL, 0x9e);
+	//set MD turn_around wait state
+	Data &= 0xCF;		/*clear bit4,5 */
+	if (DIMMFREQ_400 == DramAttr->DramFreq)
+		Data |= 0x0;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		Data |= 0x10;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		Data |= 0x20;
+	else if (DIMMFREQ_800 == DramAttr->DramFreq)
+		Data |= 0x20;
+	else
+		Data |= 0;
+	pci_write_config8(MEMCTRL, 0x9e, Data);
+
+
+	if (DIMMFREQ_400 == DramAttr->DramFreq)
+		Data = 0x0;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		Data = 0x11;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		Data = 0x11;
+	else if (DIMMFREQ_800 == DramAttr->DramFreq)
+		Data = 0x11;
+	else
+		Data = 0;
+	pci_write_config8(MEMCTRL, 0x9f, Data);
+
+
+	/*channel A ODT select */
+	if (DramAttr->DimmNumChA > 0) {
+		Data = pci_read_config8(MEMCTRL, 0xd5);
+		Data &= 0x5F;	/*clear bit7,5 */
+		if (DramAttr->RankNumChA > 2)
+			Data |= 0xA0;	/*if rank number > 2 (3or4), set bit7,5 */
+		else
+			Data |= 0x00;	/*if rank number is 1or2, clear bit5 */
+		pci_write_config8(MEMCTRL, 0xd5, Data);
+
+		Data = pci_read_config8(MEMCTRL, 0xd7);
+		Data &= 0xEF;	/*clear bit7 */
+		if (DramAttr->RankNumChA > 2)
+			Data |= 0x80;	/*if rank number > 2 (3or4), set bit7 */
+		else
+			Data |= 0x00;	/*if rank number is 1or2,  clear bit7 */
+		pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+		/*channel A */
+		Data = pci_read_config8(MEMCTRL, 0xd5);
+		Data &= 0xF3;	//bit2,3
+		if (DramAttr->DimmNumChA == 2)	/*2 Dimm, 3or4 Ranks */
+			Data |= 0x00;
+		else if (DramAttr->DimmNumChA == 1)
+			Data |= 0x04;
+		pci_write_config8(MEMCTRL, 0xd5, Data);
+
+		if ((DramAttr->RankPresentMap & 0x0F) != 0) {	/*channel A */
+			// MAA ODT Lookup Table
+			bFound = FALSE;
+			for (i = 0; i < ODTLookup_Tbl_count; i++) {
+				if ((DramAttr->RankPresentMap & 0x0F) ==
+				    ODTLookup_TBL[i][0]) {
+					Data = ODTLookup_TBL[i][1];
+					bFound = TRUE;
+				}
+			}
+			if (!bFound) {	/*set default value */
+				Data =
+				    ODTLookup_TBL[ODTLookup_Tbl_count -
+						  1][1];
+			}
+			pci_write_config8(MEMCTRL, 0x9c, Data);
+
+
+			//set CHA MD ODT control State Dynamic-on
+			Data = pci_read_config8(MEMCTRL, 0xD4);
+			Data &= 0xC9;
+			Data |= 0x30;
+			pci_write_config8(MEMCTRL, 0xD4, Data);
+
+			Data = pci_read_config8(MEMCTRL, 0x9e);
+			Data |= 0x01;
+			pci_write_config8(MEMCTRL, 0x9e, Data);
+		}
+
+	}
+	/*channel B */
+	if (1 == ENABLE_CHC) {
+		//CHB has not auto compensation mode ,so must set it manual,or else CHB initialization will not successful
+		//   Data =0x88;
+		//pci_write_config8(MEMCTRL, 0xd0, Data);
+
+		Data = pci_read_config8(MEMCTRL, 0xd5);
+		Data &= 0xAF;
+		if (DramAttr->RankNumChB > 2)	/*rank number 3 or 4 */
+			Data |= 0x50;
+		else
+			Data |= 0x00;
+		pci_write_config8(MEMCTRL, 0xd5, Data);
+
+		Data = pci_read_config8(MEMCTRL, 0xd7);
+		Data &= 0xBF;	/*clear bit6 */
+		if (DramAttr->RankNumChB > 2)
+			Data |= 0x40;	/*if rank number > 2 (3or4), set bit7 */
+		else
+			Data |= 0x00;	/*if rank number is 1or2,  clear bit7 */
+		pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+		Data = pci_read_config8(MEMCTRL, 0xd5);
+		Data &= 0xFC;
+		if (DramAttr->DimmNumChB == 2)	/*2 Dimm, 3or4 Ranks */
+			Data |= 0x00;	// 2 dimm RxD5[2,0]=0,0b
+		else if (DramAttr->DimmNumChB == 1)
+			Data |= 0x01;	// 1 dimm RxD5[2,0]=1,1b
+		pci_write_config8(MEMCTRL, 0xd5, Data);
+
+		//set CHB MD ODT control State Dynamic-on
+		Data = pci_read_config8(MEMCTRL, 0xD4);
+		Data &= 0xF6;
+		Data |= 0x08;
+		pci_write_config8(MEMCTRL, 0xD4, Data);
+
+
+		//enable CHB differential DQS input
+		Data = pci_read_config8(MEMCTRL, 0x9E);
+		Data |= 0x02;
+		pci_write_config8(MEMCTRL, 0x9E, Data);
+	}
+	//enable ODT Control
+	Data = pci_read_config8(MEMCTRL, 0x9e);
+	Data |= 0x80;
+	pci_write_config8(MEMCTRL, 0x9e, Data);
+}
+
+void DrivingDQS(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+
+	/*channel A */
+	if (DramAttr->RankNumChA > 0) {
+		Data = DDR2_DQSA_Driving_Table[DramAttr->RankNumChA - 1];
+		pci_write_config8(MEMCTRL, 0xe0, Data);
+	}
+
+	/*channel B */
+	if (1 == ENABLE_CHC) {
+		Data = DDR2_DQSB_Driving_Table[DramAttr->RankNumChB - 1];
+		pci_write_config8(MEMCTRL, 0xe1, Data);
+	}
+
+}
+
+void DrivingDQ(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+
+	/*channel A */
+	if (DramAttr->RankNumChA > 0) {
+		Data = DDR2_DQA_Driving_Table[DramAttr->RankNumChA - 1];
+		pci_write_config8(MEMCTRL, 0xe2, Data);
+
+	}
+	/*channel B */
+	if (1 == ENABLE_CHC) {
+		Data = DDR2_DQB_Driving_Table[DramAttr->RankNumChB - 1];
+		pci_write_config8(MEMCTRL, 0xe3, Data);
+	}
+}
+
+void DrivingCS(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	/*Channel A */
+	if (DramAttr->RankNumChA > 0) {
+		Data = DDR2_CSA_Driving_Table_x8[DramAttr->RankNumChA - 1];
+		pci_write_config8(MEMCTRL, 0xe4, Data);
+	}
+	/*channel B */
+	if (1 == ENABLE_CHC) {
+		Data = DDR2_CSB_Driving_Table_x8[DramAttr->RankNumChB - 1];
+		pci_write_config8(MEMCTRL, 0xe5, Data);
+	}
+}
+
+void DrivingMA(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 i, FreqId;
+
+	if (DramAttr->RankNumChA > 0) {
+		if (DIMMFREQ_400 == DramAttr->DramFreq)
+			FreqId = 1;
+		else if (DIMMFREQ_533 == DramAttr->DramFreq)
+			FreqId = 2;
+		else if (DIMMFREQ_667 == DramAttr->DramFreq)
+			FreqId = 3;
+		else if (DIMMFREQ_800 == DramAttr->DramFreq)
+			FreqId = 4;
+		else
+			FreqId = 1;
+		for (i = 0; i < MA_Table; i++) {
+			if (DramAttr->LoadNumChA <=
+			    DDR2_MAA_Driving_Table[i][0]) {
+				Data = DDR2_MAA_Driving_Table[i][FreqId];
+				break;
+			}
+		}
+		pci_write_config8(MEMCTRL, 0xe8, Data);
+	}
+	if (1 == ENABLE_CHC) {
+		for (i = 0; i < MA_Table; i++) {
+			if (DramAttr->LoadNumChA <=
+			    DDR2_MAB_Driving_Table[i][0]) {
+				Data = DDR2_MAB_Driving_Table[i][1];
+				break;
+			}
+		}
+		pci_write_config8(MEMCTRL, 0xe9, Data);
+	}
+}
+
+void DrivingDCLK(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 FreqId;
+
+	if (DIMMFREQ_400 == DramAttr->DramFreq)
+		FreqId = 0;
+	else if (DIMMFREQ_533 == DramAttr->DramFreq)
+		FreqId = 1;
+	else if (DIMMFREQ_667 == DramAttr->DramFreq)
+		FreqId = 2;
+	else if (DIMMFREQ_800 == DramAttr->DramFreq)
+		FreqId = 4;
+	else
+		FreqId = 0;
+
+	/*channel A */
+	if (DramAttr->RankNumChA > 0) {
+		Data = DDR2_DCLKA_Driving_Table[FreqId];
+		pci_write_config8(MEMCTRL, 0xe6, Data);
+	}
+	/*channel B */
+	if (1 == ENABLE_CHC) {
+		Data = DDR2_DCLKB_Driving_Table[FreqId];
+		pci_write_config8(MEMCTRL, 0xe7, Data);
+	}
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FinalSetting.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FinalSetting.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FinalSetting.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,129 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+static const u8 RefreshCounter[7][2] = {
+	//Non_256Mbit, 256Mbit
+	{0xCA, 0xA8},		// DRAM400
+	{0xCA, 0xA8},		// DRAM333
+	{0xCA, 0x86},		// DRAM266
+	{0xCA, 0x65},		// DRAM200
+	{0xA8, 0x54},		// DRAM166
+	{0x86, 0x43},		// DRAM133
+	{0x65, 0x32}		// DRAM100
+};
+
+void DRAMRefreshCounter(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 Freq = 5, i, Dram_256_Mb;
+	if (DramAttr->DramFreq == DIMMFREQ_800)
+		Freq = 0;
+	else if (DramAttr->DramFreq == DIMMFREQ_667)
+		Freq = 1;
+	else if (DramAttr->DramFreq == DIMMFREQ_533)
+		Freq = 2;
+	else if (DramAttr->DramFreq == DIMMFREQ_400)
+		Freq = 3;
+	else if (DramAttr->DramFreq == DIMMFREQ_333)
+		Freq = 4;
+	else if (DramAttr->DramFreq == DIMMFREQ_266)
+		Freq = 5;
+	else if (DramAttr->DramFreq == DIMMFREQ_200)
+		Freq = 6;
+	else
+		Freq = 6;
+
+	Dram_256_Mb = 0;
+	for (i = 0; i < MAX_SOCKETS; i++) {
+		if (DramAttr->DimmInfo[i].SPDDataBuf[SPD_SDRAM_ROW_ADDR] ==
+		    13) {
+			Dram_256_Mb = 1;
+			break;
+		}
+	}
+
+	Data = RefreshCounter[Freq][Dram_256_Mb];
+
+	pci_write_config8(MEMCTRL, 0x6a, Data);
+}
+
+
+/*===================================================================
+Function   : DRAMRegFinalValue()
+Precondition : 
+Input      :  
+		   DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
+		                    in MotherBoard
+Output     : Void
+Purpose   : Chipset Performance UP and other setting after DRAM Sizing
+                 Turn on register directly to promote performance
+===================================================================*/
+
+//--------------------------------------------------------------------------
+//        register       AND   OR
+//--------------------------------------------------------------------------
+#define DRAM_table_item		9
+static const u8 DRAM_table[DRAM_table_item][3] = {
+	{0x60, 0xff, 0xD0},
+	{0x66, 0xcf, 0x80},	// DRAMC queue > 2
+	{0x69, 0xff, 0x07},	// Enable multiple page
+	{0x95, 0x00, 0x0D},
+	{0x96, 0x0F, 0xA0},
+	{0xFB, 0x00, 0x3E},
+	{0xFD, 0x00, 0xA9},
+	{0xFE, 0x00, 0x0f},
+	{0xFF, 0x00, 0x3D}
+};
+
+#define PM_table_item		5
+static const u8 PM_table[PM_table_item][3] = {
+	{0xA0, 0x0F, 0xF0},
+	{0xA1, 0x1F, 0xE0},
+	{0xA2, 0x00, 0xFE},
+	{0xA3, 0x7F, 0x80},
+	{0xA5, 0x7E, 0x81},
+};
+
+void DRAMRegFinalValue(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 i;
+
+	for (i = 0; i < DRAM_table_item; i++) {
+		Data = pci_read_config8(MEMCTRL, DRAM_table[i][0]);
+		Data = (u8) ((Data & DRAM_table[i][1]) | DRAM_table[i][2]);
+		pci_write_config8(MEMCTRL, DRAM_table[i][0], Data);
+	}
+
+	//enable dram By-Rank self refresh
+	Data = pci_read_config8(MEMCTRL, 0x96);
+	Data &= 0xF0;
+	for (i = 0x01; i < 0x10; i = i << 1) {
+		if ((DramAttr->RankPresentMap & i) != 0x00)
+			Data |= i;
+	}
+	pci_write_config8(MEMCTRL, 0x96, Data);
+
+	for (i = 0; i < PM_table_item; i++) {
+		Data = pci_read_config8(PCI_DEV(0, 0, 4), PM_table[i][0]);
+		Data = (u8) ((Data & PM_table[i][1]) | PM_table[i][2]);
+		pci_write_config8(PCI_DEV(0, 0, 4), PM_table[i][0], Data);
+	}
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FreqSetting.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FreqSetting.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/FreqSetting.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,235 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+void CalcCLAndFreq(DRAM_SYS_ATTR * DramAttr);
+
+/*
+ Set DRAM Frequency
+*/
+void DRAMFreqSetting(DRAM_SYS_ATTR * DramAttr)
+{
+
+	u8 Data = 0;
+
+	PRINT_DEBUG_MEM("Dram Frequency setting \r");
+
+	//calculate dram frequency using SPD data
+	CalcCLAndFreq(DramAttr);
+
+	//init some Dramc control by Simon Chu slide
+	//Must use "CPU delay" to make sure VLINK is dis-connect
+	Data = pci_read_config8(PCI_DEV(0, 0, 7), 0x47);
+	Data = (u8) (Data | 0x04);
+	pci_write_config8(PCI_DEV(0, 0, 7), 0x47, Data);
+
+	//in order to make sure NB command buffer don`t have pending request(C2P cycle)
+	//CPU DELAY
+	WaitMicroSec(20);
+
+	//Before Set Dram Frequency, we must set 111 by Simon Chu slide.
+	Data = pci_read_config8(MEMCTRL, 0x90);
+	Data = (u8) ((Data & 0xf8) | 7);
+	pci_write_config8(MEMCTRL, 0x90, Data);
+
+	WaitMicroSec(20);
+
+	//Set Dram Frequency.
+	Data = pci_read_config8(MEMCTRL, 0x90);
+	switch (DramAttr->DramFreq) {
+	case DIMMFREQ_400:
+		Data = (u8) ((Data & 0xf8) | 3);
+		break;
+	case DIMMFREQ_533:
+		Data = (u8) ((Data & 0xf8) | 4);
+		break;
+	case DIMMFREQ_667:
+		Data = (u8) ((Data & 0xf8) | 5);
+		break;
+	case DIMMFREQ_800:
+		Data = (u8) ((Data & 0xf8) | 6);
+		break;
+	default:
+		Data = (u8) ((Data & 0xf8) | 1);;
+	}
+	pci_write_config8(MEMCTRL, 0x90, Data);
+
+	//CPU Delay
+	WaitMicroSec(20);
+
+	// Manual       reset and adjust DLL when DRAM change frequency
+	Data = pci_read_config8(MEMCTRL, 0x6B);
+	Data = (u8) ((Data & 0x2f) | 0xC0);
+	pci_write_config8(MEMCTRL, 0x6B, Data);
+
+	//CPU Delay
+	WaitMicroSec(20);
+
+	Data = pci_read_config8(MEMCTRL, 0x6B);
+	Data = (u8) (Data | 0x10);
+	pci_write_config8(MEMCTRL, 0x6B, Data);
+
+	//CPU Delay
+	WaitMicroSec(20);
+
+	Data = pci_read_config8(MEMCTRL, 0x6B);
+	Data = (u8) (Data & 0x3f);
+	pci_write_config8(MEMCTRL, 0x6B, Data);
+
+	//disable V_LINK Auto-Disconnect, or else program may stopped at some place and
+	//we cannot find the reason
+	Data = pci_read_config8(PCI_DEV(0, 0, 7), 0x47);
+	Data = (u8) (Data & 0xFB);
+	pci_write_config8(PCI_DEV(0, 0, 7), 0x47, Data);
+
+}
+
+
+/*
+ calculate CL and dram freq
+ DDR1
+ +---+---+---+---+---+---+---+---+
+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+ +---+---+---+---+---+---+---+---+
+ |TBD| 4 |3.5| 3 |2.5| 2 |1.5| 1 |
+ +---+---+---+---+---+---+---+---+
+ DDR2
+ +---+---+---+---+---+---+---+---+
+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+ +---+---+---+---+---+---+---+---+
+ |TBD| 6 | 5 | 4 | 3 | 2 |TBD|TBD|
+ +---+---+---+---+---+---+---+---+
+*/
+static const u8 CL_DDR1[7] = { 10, 15, 20, 25, 30, 35, 40 };
+static const u8 CL_DDR2[7] = { 0, 0, 20, 30, 40, 50, 60 };
+
+void CalcCLAndFreq(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 AllDimmSupportedCL, Tmp;
+	u8 CLMask, tmpMask, IndexDelta;
+	u8 SckId, BitId, TmpId;
+	u16 CycTime, TmpCycTime;
+
+	/*1.list the CL value that all DIMM supported */
+	AllDimmSupportedCL = 0xFF;
+	if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
+		AllDimmSupportedCL &= 0x7C;	/*bit2,3,4,5,6 */
+	else			/*DDR1 */
+		AllDimmSupportedCL &= 0x7F;	/*bit0,1,2,3,4,5,6 */
+	for (SckId = 0; SckId < MAX_SOCKETS; SckId++) {
+		if (DramAttr->DimmInfo[SckId].bPresence) {	/*all DIMM supported CL */
+			AllDimmSupportedCL &=
+			    (DramAttr->DimmInfo[SckId].
+			     SPDDataBuf[SPD_SDRAM_CAS_LATENCY]);
+		}
+	}
+	if (!AllDimmSupportedCL) {	/*if equal 0, no supported CL */
+		PRINT_DEBUG_MEM("SPD Data Error, Can not get CL !!!! \r");
+		for (;;);
+	}
+
+	/*Get CL Value */
+	CLMask = 0x40;		/*from Bit6 */
+
+	for (BitId = 7; BitId > 0; BitId--) {
+		if ((AllDimmSupportedCL & CLMask) == CLMask) {	/*find the first bit */
+			if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
+				DramAttr->CL = CL_DDR2[BitId - 1];
+			else	/*DDR1 */
+				DramAttr->CL = CL_DDR1[BitId - 1];
+			break;
+		}
+		CLMask >>= 1;
+	}
+
+	/*according the CL value calculate the cycle time, for X or X-1 or X-2 */
+	CycTime = 0;
+	TmpCycTime = 0;
+
+	for (SckId = 0; SckId < MAX_SOCKETS; SckId++) {
+		if (DramAttr->DimmInfo[SckId].bPresence) {
+			Tmp =
+			    (DramAttr->DimmInfo[SckId].
+			     SPDDataBuf[SPD_SDRAM_CAS_LATENCY]);
+			tmpMask = 0x40;
+			for (TmpId = 7; TmpId > 0; TmpId--) {
+				if ((Tmp & tmpMask) == tmpMask)
+					break;
+				tmpMask >>= 1;
+			}
+			if (TmpId - BitId == 0) {	/*get Cycle time for X, SPD BYTE9 */
+				TmpCycTime =
+				    DramAttr->DimmInfo[SckId].
+				    SPDDataBuf[SPD_SDRAM_TCLK_X];
+			} else if (TmpId - BitId == 1) {	/*get Cycle time for X-1, SPD BYTE23 */
+				TmpCycTime =
+				    DramAttr->DimmInfo[SckId].
+				    SPDDataBuf[SPD_SDRAM_TCLK_X_1];
+			} else if (TmpId - BitId == 2) {	/*get cycle time for X-2, SPD BYTE25 */
+				TmpCycTime =
+				    DramAttr->DimmInfo[SckId].
+				    SPDDataBuf[SPD_SDRAM_TCLK_X_2];
+			} else {
+				//error!!!
+			}
+			if (TmpCycTime > CycTime)	/*get the most cycle time,there is some problem! */
+				CycTime = TmpCycTime;
+		}
+	}
+
+	if (CycTime <= 0) {
+		//error!
+		for (;;);
+	}
+
+	/* cycle time value
+	   0x25-->2.5ns Freq=400  DDR800
+	   0x30-->3.0ns Freq=333  DDR667
+	   0x3D-->3.75ns Freq=266 DDR533
+	   0x50-->5.0ns Freq=200  DDR400
+	   0x60-->6.0ns Freq=166  DDR333
+	   0x75-->7.5ns Freq=133  DDR266
+	   0xA0-->10.0ns Freq=100 DDR200
+	 */
+	if (CycTime <= 0x25) {
+		DramAttr->DramFreq = DIMMFREQ_800;
+		DramAttr->DramCyc = 250;
+	} else if (CycTime <= 0x30) {
+		DramAttr->DramFreq = DIMMFREQ_667;
+		DramAttr->DramCyc = 300;
+	} else if (CycTime <= 0x3d) {
+		DramAttr->DramFreq = DIMMFREQ_533;
+		DramAttr->DramCyc = 375;
+	} else if (CycTime <= 0x50) {
+		DramAttr->DramFreq = DIMMFREQ_400;
+		DramAttr->DramCyc = 500;
+	} else if (CycTime <= 0x60) {
+		DramAttr->DramFreq = DIMMFREQ_333;
+		DramAttr->DramCyc = 600;
+	} else if (CycTime <= 0x75) {
+		DramAttr->DramFreq = DIMMFREQ_266;
+		DramAttr->DramCyc = 750;
+	} else if (CycTime <= 0xA0) {
+		DramAttr->DramFreq = DIMMFREQ_200;
+		DramAttr->DramCyc = 1000;
+	}
+	//if set the frequence mannul                
+	PRINT_DEBUG_MEM("Dram Frequency:");
+	PRINT_DEBUG_MEM_HEX16(DramAttr->DramFreq);
+	PRINT_DEBUG_MEM(" \r");
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/RankMap.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/RankMap.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/RankMap.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,363 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+extern void DRAMSetVRNum(DRAM_SYS_ATTR * DramAttr,
+			 u8 PhyRank, u8 VirRank, BOOLEAN Enable);
+
+extern void SetEndingAddr(DRAM_SYS_ATTR * DramAttr, u8 VirRank,	// Ending address register      number indicator (INDEX
+			  INT8 Value);	// (value) add or subtract value to this and after banks
+
+
+void DRAMClearEndingAddress(DRAM_SYS_ATTR * DramAttr);
+
+void DRAMSizingEachRank(DRAM_SYS_ATTR * DramAttr);
+
+BOOLEAN DoDynamicSizing1XM(DRAM_SYS_ATTR * DramAttr,
+			   u8 * nRA, u8 * nCA, u8 * nBS, u8 PhyRank);
+
+void DRAMSetRankMAType(DRAM_SYS_ATTR * DramAttr);
+
+void DRAMSetEndingAddress(DRAM_SYS_ATTR * DramAttr);
+
+void DRAMPRToVRMapping(DRAM_SYS_ATTR * DramAttr);
+
+/*===================================================================
+Function   : DRAMBankInterleave()
+Precondition : 
+Input        : 
+		   DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     :  Void
+Purpose   :  STEP 13 Set Bank Interleave  VIANB3DRAMREG69[7:6] 00:No Interleave 01:2 Bank 10:4 Bank	11:8 Bank
+                   Scan all DIMMs on board to find out the lowest Bank Interleave among these DIMMs and set register.
+===================================================================*/
+void DRAMBankInterleave(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data, SpdBAData;
+	DIMM_INFO *CurrentDimminfo;
+	u8 Bank = 3, Shift, RankNO, Count;
+	Shift = 1;
+	for (RankNO = 0; RankNO < 4; RankNO += 2)	//all_even  0 RankNO 4 6
+	{
+		if ((DramAttr->RankPresentMap & Shift) != 0) {
+			CurrentDimminfo = &(DramAttr->DimmInfo[RankNO >> 1]);	//this Rank in a dimm
+			SpdBAData =
+			    (u8) (CurrentDimminfo->
+				  SPDDataBuf[SPD_SDRAM_NO_OF_BANKS]);
+			if (SpdBAData == 4)
+				Count = 2;
+			else if (SpdBAData == 8)
+				Count = 3;
+			else
+				Count = 0;
+			if (Count < Bank)
+				Bank = Count;
+		}
+		Shift <<= 2;
+	}
+
+	Data = pci_read_config8(MEMCTRL, 0x69);
+	Data &= ~0xc0;
+	Data |= (Bank << 6);
+	pci_write_config8(MEMCTRL, 0x69, Data);
+
+
+	if (DramAttr->DimmNumChB > 0) {
+		CurrentDimminfo = &(DramAttr->DimmInfo[3]);	//this Rank in a dimm
+		SpdBAData =
+		    (u8) (CurrentDimminfo->
+			  SPDDataBuf[SPD_SDRAM_NO_OF_BANKS]);
+		if (SpdBAData == 4)
+			Bank = 2;
+		else if (SpdBAData == 2)
+			Bank = 1;
+		else
+			Bank = 0;
+		pci_write_config8(MEMCTRL, 0x87, Bank);
+	}
+}
+
+/*===================================================================
+Function   : DRAMSizingMATypeM()
+Precondition : 
+Input        :
+		   DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     :  Void
+ Purpose  : STEP 14  1 DRAM Sizing 2  Fill MA type 3 Prank to vrankMapping 
+===================================================================*/
+void DRAMSizingMATypeM(DRAM_SYS_ATTR * DramAttr)
+{
+	DRAMClearEndingAddress(DramAttr);
+	DRAMSizingEachRank(DramAttr);
+	//DRAMReInitDIMMBL           (DramAttr);
+	DRAMSetRankMAType(DramAttr);
+	DRAMSetEndingAddress(DramAttr);
+	DRAMPRToVRMapping(DramAttr);
+}
+
+/*===================================================================
+Function   : DRAMClearEndingAddress()
+Precondition : 
+Input        : 
+		   DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     : Void
+Purpose   : clear Ending and Start adress from 0x40-4f to zero
+===================================================================*/
+void DRAMClearEndingAddress(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data, Reg;
+	Data = 0;
+	for (Reg = 0x40; Reg <= 0x4f; Reg++) {
+		pci_write_config8(MEMCTRL, Reg, Data);
+	}
+}
+
+/*===================================================================
+Function   : DRAMSizingEachRank()
+Precondition : 
+Input        : 
+		   DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     : Void
+Purpose   : Sizing each Rank invidually, by number of rows column banks pins, be care about 128bit
+===================================================================*/
+void DRAMSizingEachRank(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Slot, RankIndex, Rows, Columns, Banks;
+	u32 Size;
+	BOOLEAN HasThreeBitBA;
+	u8 Data;
+	u32 Address;
+
+	HasThreeBitBA = FALSE;
+	for (Slot = 0; Slot < 2; Slot++) {
+		if (!DramAttr->DimmInfo[Slot].bPresence)
+			continue;
+		Rows =
+		    DramAttr->DimmInfo[Slot].
+		    SPDDataBuf[SPD_SDRAM_ROW_ADDR];
+		Columns =
+		    DramAttr->DimmInfo[Slot].
+		    SPDDataBuf[SPD_SDRAM_COL_ADDR];
+		Banks = DramAttr->DimmInfo[Slot].SPDDataBuf[SPD_SDRAM_NO_OF_BANKS];	//this is Bank number not Bank address bit
+		if (Banks == 4)
+			Banks = 2;
+		else if (Banks == 8)
+			Banks = 3;
+		else
+			Banks = 0;
+		Size = (u32) (1 << (Rows + Columns + Banks + 3));
+		RankIndex = 2 * Slot;
+		DramAttr->RankSize[RankIndex] = Size;
+		//if this module have two ranks
+		if ((DramAttr->DimmInfo[Slot].
+		     SPDDataBuf[SPD_SDRAM_DIMM_RANKS] & 0x07) == 0x01) {
+			RankIndex++;
+			DramAttr->RankSize[RankIndex] = Size;
+		}
+
+		PRINT_DEBUG_MEM("rows: ");
+		PRINT_DEBUG_MEM_HEX8(Rows);
+		PRINT_DEBUG_MEM(", columns:");
+		PRINT_DEBUG_MEM_HEX8(Columns);
+		PRINT_DEBUG_MEM(", banks:");
+		PRINT_DEBUG_MEM_HEX8(Banks);
+		PRINT_DEBUG_MEM("\r");
+
+		if (Banks == 3)
+			HasThreeBitBA = TRUE;
+	}
+
+	//must set BA2 enable if any 8-bank device exists
+	if (HasThreeBitBA) {
+		Data = pci_read_config8(MEMCTRL, 0x53);
+		Data |= 0x80;
+		pci_write_config8(MEMCTRL, 0x53, Data);
+	}
+#if 1
+	for (RankIndex = 0; DramAttr->RankSize[RankIndex] != 0;
+	     RankIndex++) {
+		PRINT_DEBUG_MEM("Rank:");
+		PRINT_DEBUG_MEM_HEX8(RankIndex);
+		PRINT_DEBUG_MEM(", Size:");
+		PRINT_DEBUG_MEM_HEX32(DramAttr->RankSize[RankIndex] >> 20);
+		PRINT_DEBUG_MEM("\r");
+	}
+#endif
+}
+
+/*===================================================================
+Function   : DRAMSetRankMAType()
+Precondition : 
+Input       : 
+		  DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     : Void
+Purpose   : set the matype Reg by MAMapTypeTbl, which the rule can be found in memoryinit
+===================================================================*/
+void DRAMSetRankMAType(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 SlotNum, Data, j, Reg, or, and;
+	u8 ShiftBits[] = { 5, 1, 5, 1 };	/* Rank 0/1 MA Map Type is 7:5, Rank 2/3 MA Map Type is 3:1. See  Fun3Rx50. */
+	u8 MAMapTypeTbl[] = {	/* Table 12 of P4M800 Pro DataSheet. */
+		2, 9, 0,	/* Bank Address Bits, Column Address Bits, Rank MA Map Type */
+		2, 10, 1,
+		2, 11, 2,
+		2, 12, 3,
+		3, 10, 5,
+		3, 11, 6,
+		3, 12, 7,
+		0, 0, 0
+	};
+	Data = pci_read_config8(MEMCTRL, 0x50);
+	Data &= 0x1;
+	pci_write_config8(MEMCTRL, 0x50, Data);
+	// disable MA32/16 MA33/17 swap   in memory init it has this Reg fill
+	Data = pci_read_config8(MEMCTRL, 0x6b);
+	Data &= ~0x08;
+	pci_write_config8(MEMCTRL, 0x6b, Data);
+
+	Data = 0x00;
+	for (SlotNum = 0; SlotNum < MAX_DIMMS; SlotNum++) {
+		if (DramAttr->DimmInfo[SlotNum].bPresence) {
+			for (j = 0; MAMapTypeTbl[j] != 0; j += 3) {
+				if ((1 << MAMapTypeTbl[j]) ==
+				    DramAttr->DimmInfo[SlotNum].
+				    SPDDataBuf[SPD_SDRAM_NO_OF_BANKS]
+				    && MAMapTypeTbl[j + 1] ==
+				    DramAttr->DimmInfo[SlotNum].
+				    SPDDataBuf[SPD_SDRAM_COL_ADDR]) {
+					break;
+				}
+			}
+			if (0 == MAMapTypeTbl[j]) {
+				PRINT_DEBUG_MEM
+				    ("UNSUPPORTED Bank, Row and Column Addr Bits!\r");
+				return;
+			}
+			or = MAMapTypeTbl[j + 2] << ShiftBits[SlotNum];
+			if (DramAttr->CmdRate == 1)
+				or |= 0x01 << (ShiftBits[SlotNum] - 1);
+
+			Reg = SlotNum / 2;
+			if ((SlotNum & 0x01) == 0x01) {
+				and = 0xf1;	// BUGBUG: it should be 0xf0
+			} else {
+				and = 0x1f;	// BUGBUG: it should be 0x0f
+			}
+			Data = pci_read_config8(MEMCTRL, 0x50 + Reg);
+			Data &= and;
+			Data |= or;
+			pci_write_config8(MEMCTRL, 0x50 + Reg, Data);
+		}
+	}
+	//may have some Reg filling at add 3-52 11 and 3-53   in his function
+}
+
+/*===================================================================
+Function   : DRAMSetEndingAddress()
+Precondition : 
+Input      :  
+		  DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     : Void
+Purpose   : realize the Vrank 40...Reg (Start and Ending Regs). Vrank have  same order with phy Rank, Size is actual Size  
+===================================================================*/
+void DRAMSetEndingAddress(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Shift = 1, Data, RankNO, Size, Start = 0, End = 0, Vrank;
+	for (RankNO = 0; RankNO < 4; RankNO++) {
+		if ((DramAttr->RankPresentMap & Shift) != 0) {
+			Size = (u8) (DramAttr->RankSize[RankNO] >> 26);	// current Size in the unit of 64M
+			if (Size != 0) {
+
+				End = End + Size;	// calculate current ending address,   add the current Size to ending
+				Vrank = RankNO;	// get virtual Rank
+				Data = End;	// set begin/End address register to correspondig virtual       Rank #
+				pci_write_config8(MEMCTRL, 0x40 + Vrank,
+						  Data);
+				Data = Start;
+				pci_write_config8(MEMCTRL, 0x48 + Vrank,
+						  Data);
+				PRINT_DEBUG_MEM("Rank: ");
+				PRINT_DEBUG_MEM_HEX8(Vrank);
+				PRINT_DEBUG_MEM(", Start:");
+				PRINT_DEBUG_MEM_HEX8(Start);
+				PRINT_DEBUG_MEM(", End:");
+				PRINT_DEBUG_MEM_HEX8(End);
+				PRINT_DEBUG_MEM("\r");
+
+				Start = End;
+			}
+		}
+		Shift <<= 1;
+	}
+
+	if (DramAttr->RankNumChB > 0) {
+		//this is a bug,fixed is to 2,so the max LL size is 128M
+		Data = 0x02;
+		pci_write_config8(MEMCTRL, 0x44, Data);
+	}
+	Data = End * 4;
+	pci_write_config8(PCI_DEV(0, 17, 7), 0x60, Data);
+	// We should directly write to south Bridge, not in north bridge
+	// program LOW TOP Address
+	Data = pci_read_config8(MEMCTRL, 0x88);
+	pci_write_config8(MEMCTRL, 0x85, Data);
+
+	// also program vlink mirror
+	// We should directly write to south Bridge, not in north bridge
+	pci_write_config8(PCI_DEV(0, 17, 7), 0xe5, Data);
+}
+
+/*===================================================================
+Function   : DRAMPRToVRMapping()
+Precondition : 
+Input       : 
+		  DramAttr: pointer point to  DRAMSYSATTR  which consist the DDR and Dimm information in MotherBoard
+Output     : Void
+Purpose   : set the Vrank-prank map with the same order
+===================================================================*/
+void DRAMPRToVRMapping(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Shift, Data, and, or, DimmNO = 0, PhyRankNO, Reg;
+
+	for (Reg = 0x54; Reg <= 0x57; Reg++)	//clear the map-reg
+	{
+		Data = 0;
+		pci_write_config8(MEMCTRL, Reg, Data);
+	}
+
+	Shift = 1;
+	for (PhyRankNO = 0; PhyRankNO < MAX_RANKS; PhyRankNO++) {
+		if ((DramAttr->RankPresentMap & Shift) != 0) {
+			or = PhyRankNO;	// get virtual Rank   ,same with PhyRank
+			or |= 0x08;
+
+			if ((PhyRankNO & 0x01) == 0x01)	// get mask for register
+				and = 0xf0;
+			else {
+				and = 0x0f;
+				or <<= 4;
+			}
+			DimmNO = (PhyRankNO >> 1);
+			Data = pci_read_config8(MEMCTRL, 0x54 + DimmNO);
+			Data &= and;
+			Data |= or;
+			pci_write_config8(MEMCTRL, 0x54 + DimmNO, Data);
+		}
+		Shift <<= 1;
+	}
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/TimingSetting.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/TimingSetting.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/TimingSetting.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,492 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+ /*
+    Set Dram Timing functions
+  */
+
+void SetCL(DRAM_SYS_ATTR * DramAttr);
+
+void SetTrp(DRAM_SYS_ATTR * DramAttr);
+
+void SetTrcd(DRAM_SYS_ATTR * DramAttr);
+
+void SetTras(DRAM_SYS_ATTR * DramAttr);
+
+void SetTrfc(DRAM_SYS_ATTR * DramAttr);
+
+void SetTrrd(DRAM_SYS_ATTR * DramAttr);
+
+void SetTwr(DRAM_SYS_ATTR * DramAttr);
+
+void SetTwtr(DRAM_SYS_ATTR * DramAttr);
+
+void SetTrtp(DRAM_SYS_ATTR * DramAttr);
+
+/* Set DRAM	Timing*/
+void DRAMTimingSetting(DRAM_SYS_ATTR * DramAttr)
+{
+	PRINT_DEBUG_MEM("Set CAS latency value!");
+	SetCL(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tRP value!");
+	SetTrp(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tRCD value!");
+	SetTrcd(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tRAS value!");
+	SetTras(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tRFC value!");
+	SetTrfc(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tRRD value!");
+	SetTrrd(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tWR value!");
+	SetTwr(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tWTR value!");
+	SetTwtr(DramAttr);
+
+	PRINT_DEBUG_MEM("Set tRTP value!");
+	SetTrtp(DramAttr);
+}
+
+
+/*
+Set DRAM Timing: CAS Latency for DDR1
+D0F3RX62 bit[0:2] for CAS Latency; 
+*/
+void SetCL(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u8 CL;
+
+	/*DDR2 CL Value: 20, 30, 40, 50 -> 2, 3, 4, 5 */
+	CL = (u8) ((DramAttr->CL - 20) / 10);	//000,001,010,011
+
+	PRINT_DEBUG_MEM("CAS = ");
+	PRINT_DEBUG_MEM_HEX8(CL);
+	PRINT_DEBUG_MEM("\n");
+	Data = pci_read_config8(MEMCTRL, 0x62);
+	Data = (u8) ((Data & 0xf8) | CL);
+	pci_write_config8(MEMCTRL, 0x62, Data);
+}
+
+
+/*
+ Minimum row precharge time, Trp for DDR1/DDR2
+ D0F3Rx64[3:2] for Trp 2T~5T
+*/
+#define MAX_TRP 6
+#define MIN_TRP 2
+
+void SetTrp(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+
+	/*get the max Trp value from SPD data
+	   SPD Byte27, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TRP]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+		/*Calculate clock,this value should be 2T,3T,4T,5T */
+	}
+	Tmp =
+	    (u16) ((Max * 100 + ((DramAttr->DramCyc) << 2) -
+		    1) / ((DramAttr->DramCyc) << 2));
+	PRINT_DEBUG_MEM("Trp = ");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	if (Tmp > MAX_TRP)
+		Tmp = MAX_TRP;
+	else if (Tmp < MIN_TRP)
+		Tmp = MIN_TRP;
+
+	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
+	Tmp <<= 1;		//bit1,2,3
+
+	Data = pci_read_config8(MEMCTRL, 0x64);
+	Data = (u8) ((Data & 0xf1) | (u8) Tmp);
+	pci_write_config8(MEMCTRL, 0x64, Data);
+
+	//enable DDR2 8-Bank Device Timing Constraint
+	Data = pci_read_config8(MEMCTRL, 0x62);
+	Data = (u8) ((Data & 0xf7) | 0x08);
+	pci_write_config8(MEMCTRL, 0x62, Data);
+}
+
+
+/*
+Minimum RAS to CAS dely,Trcd for DDR1/DDR2
+D0F3Rx64[7:6] for Trcd
+*/
+#define MAX_TRCD 6
+#define MIN_TRCD 2
+
+void SetTrcd(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+
+	/*get the max Trcd value from SPD data
+	   SPD Byte29, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TRCD]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+	/*Calculate clock,this value should be 2T,3T,4T,5T */
+	Tmp =
+	    (u16) ((Max * 100 + ((DramAttr->DramCyc) << 2) -
+		    1) / ((DramAttr->DramCyc) << 2));
+	PRINT_DEBUG_MEM("Trcd =");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	if (Tmp > MAX_TRCD)
+		Tmp = MAX_TRCD;
+	else if (Tmp < MIN_TRCD)
+		Tmp = MIN_TRCD;
+	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
+	Tmp <<= 5;		//bit5,6,7
+
+	Data = pci_read_config8(MEMCTRL, 0x64);
+	Data = (u8) ((Data & 0x1f) | (u8) Tmp);
+	pci_write_config8(MEMCTRL, 0x64, Data);
+
+}
+
+/*
+ minimum active to precharge time,Tras for DDR1/DDR2
+ D0F3Rx62[7:4] Tras
+*/
+#define MAX_TRAS 20		//20T
+#define MIN_TRAS 5		//5T
+void SetTras(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+
+	/*get the max Tras value from SPD data
+	   SPD byte30: bit0:7 1ns~255ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TRAS]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+
+	/*Calculate clock,value range 5T-20T */
+	Tmp =
+	    (u16) ((Max * 100 + DramAttr->DramCyc -
+		    1) / (DramAttr->DramCyc));
+	PRINT_DEBUG_MEM("Tras =");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	if (Tmp > MAX_TRAS)
+		Tmp = MAX_TRAS;
+	else if (Tmp < MIN_TRAS)
+		Tmp = MIN_TRAS;
+	Tmp -= 5;		//0->5T  ... 1111->20T
+	Tmp <<= 4;		//bit4:7
+
+	Data = pci_read_config8(MEMCTRL, 0x62);
+	Data = (u8) ((Data & 0x0f) | (u8) Tmp);
+	pci_write_config8(MEMCTRL, 0x62, Data);
+}
+
+/*
+Minimum refresh to activate/refresh command period Trfc for DDR1/DDR2
+D0F3Rx61[5:0] for Trfc
+*/
+
+#define MAX_TRFC 71		// Max supported,71T
+#define MIN_TRFC 8		// Min supported,8T
+
+void SetTrfc(DRAM_SYS_ATTR * DramAttr)
+{
+
+	u8 Data;
+	u32 Max, Tmp;
+	u8 Byte40;
+	u8 Socket;
+
+	/*get the max Trfc value from SPD data */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u32) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TRFC]) * 100;
+			/*only DDR2 need to add byte 40 bit[7:4] */
+			Byte40 =
+			    (DramAttr->DimmInfo[Socket].
+			     SPDDataBuf[SPD_SDRAM_TRFC2]);
+			/*if bit0 = 1, byte42(RFC)+256ns, SPD spec JEDEC standard No.21.c */
+			if (Byte40 & 0x01)
+				Tmp += (256 * 100);
+			/*bit1,2,3 000->0ns+byte42; 001->0.25ns+byte42; 010->0.33ns+byte42; 011->0.5ns+byte42;100-> 0.75ns+byte42 */
+			switch ((Byte40 >> 1) & 0x07) {	/*bit1,2,3 */
+			case 1:
+				Tmp += 25;
+				break;
+			case 2:
+				Tmp += 33;
+				break;
+			case 3:
+				Tmp += 50;
+				break;
+			case 4:
+				Tmp += 66;
+				break;
+			case 5:
+				Tmp += 75;
+				break;
+			case 6:	//what is FRU???
+			default:
+				break;
+			}
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+
+	/*Calculate clock,value range 8T-71T */
+	Tmp = (u16) ((Max + DramAttr->DramCyc - 1) / (DramAttr->DramCyc));
+	PRINT_DEBUG_MEM("Trfc = ");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+	if (Tmp > MAX_TRFC)
+		Tmp = MAX_TRFC;
+	else if (Tmp < MIN_TRFC) {
+		// return;
+		Tmp = 0x40;
+	}
+	/*D0F3Rx61 bit[0:5] 0->8T ... 63->71T */
+	Tmp -= 8;
+
+	Data = pci_read_config8(MEMCTRL, 0x61);
+	Data = (u8) ((Data & 0xc0) | ((u8) Tmp & 0x3f));
+	pci_write_config8(MEMCTRL, 0x61, Data);
+}
+
+
+/*
+Minimum row active to row active delay: Trrd for DDR1/DDR2
+D0F3Rx61[7:6]:Trrd  00->2T, 01->3T, 10->4T, 11->5T
+*/
+#define MAX_TRRD 5
+#define MIN_TRRD 2
+
+void SetTrrd(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+
+	/*get the max Trrd value from SPD data
+	   SPD Byte28, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TRRD]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+
+	/*Calculate clock,this value should be 2T,3T,4T,5T */
+	Tmp =
+	    (u16) ((Max * 100 + ((DramAttr->DramCyc) << 2) -
+		    1) / ((DramAttr->DramCyc) << 2));
+	PRINT_DEBUG_MEM("Trrd =");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	if (Tmp > MAX_TRRD)
+		Tmp = MAX_TRRD;
+	else if (Tmp < MIN_TRRD)
+		Tmp = MIN_TRRD;
+	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
+	Tmp <<= 6;
+
+	Data = pci_read_config8(MEMCTRL, 0x61);
+	Data = (u8) ((Data & 0x3f) | (u8) Tmp);
+	pci_write_config8(MEMCTRL, 0x61, Data);
+}
+
+
+/*
+Write recovery time: Twr for DDR1/DDR2
+Device 0 Function 3:REG63[7:5]:Twr 00->2T 01->3T 10->4T 11->5T
+*/
+#define MAX_TWR 6
+#define MIN_TWR 2
+
+void SetTwr(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+	/*get the max Trtp value from SPD data
+	   SPD Byte36, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TWR]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+	/*Calculate clock */
+	Tmp = (u16) ((Max * 100 + ((DramAttr->DramCyc) << 2) - 1) / ((DramAttr->DramCyc) << 2));	//this value should be 2T,3T,4T,5T
+	PRINT_DEBUG_MEM("Twr = ");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	if (Tmp > MAX_TWR)
+		Tmp = MAX_TWR;
+	else if (Tmp < MIN_TWR)
+		Tmp = MIN_TWR;
+	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
+	Tmp <<= 5;
+
+	Data = pci_read_config8(MEMCTRL, 0x63);
+	Data = (u8) ((Data & 0x1f) | (u8) Tmp);
+	pci_write_config8(MEMCTRL, 0x63, Data);
+}
+
+
+/*
+Internal write to read command delay: Twtr for DDR1/DDR2
+Device 0 Function 3:REG63[1,0]:Twtr   DDR: 1T or 2T; DDR2 2T or 3T
+*/
+#define MAX_TWTR 5		//5T
+#define MIN_TWTR 2		//2T
+
+void SetTwtr(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+	/*get the max Trtp value from SPD data
+	   SPD Byte37, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TWTR]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+	/*Calculate clock */
+	Tmp = (u16) ((Max * 100 + ((DramAttr->DramCyc) << 2) - 1) / ((DramAttr->DramCyc) << 2));	//this value should be 2T or 3T
+
+	PRINT_DEBUG_MEM("Twtr =");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	if (Tmp > MAX_TWR)
+		Tmp = MAX_TWTR;
+	else if (Tmp < MIN_TWR)
+		Tmp = MIN_TWTR;
+	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
+	Data = pci_read_config8(MEMCTRL, 0x63);
+	Data = (u8) ((Data & 0xFC) | Tmp);
+	pci_write_config8(MEMCTRL, 0x63, Data);
+}
+
+
+/*
+Internal read to precharge command delay, Trtp for DDR1/DDR2
+Device 0 Function 3:REG63[3]:Trtp  2T or 3T
+*/
+#define MAX_TRTP 3		//3T
+#define MIN_TRTP 2		//2T
+
+void SetTrtp(DRAM_SYS_ATTR * DramAttr)
+{
+	u8 Data;
+	u16 Max, Tmp;
+	u8 Socket;
+
+
+	/*get the max Trtp value from SPD data
+	   SPD Byte38, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
+	Max = 0;
+	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
+		if (DramAttr->DimmInfo[Socket].bPresence) {
+			Tmp =
+			    (u16) (DramAttr->DimmInfo[Socket].
+				   SPDDataBuf[SPD_SDRAM_TRTP]);
+			if (Tmp > Max)
+				Max = Tmp;
+		}
+	}
+	/*Calculate clock */
+	Tmp = (u16) ((Max * 100 + ((DramAttr->DramCyc) << 2) - 1) / ((DramAttr->DramCyc) << 2));	//this value should be 2T or 3T
+
+	PRINT_DEBUG_MEM("Trtp =");
+	PRINT_DEBUG_MEM_HEX16(Tmp);
+	PRINT_DEBUG_MEM("\r");
+
+	Data = pci_read_config8(MEMCTRL, 0x63);
+	if (Tmp > MIN_TRTP)
+		Data = (u8) (Data | 0x08);	/*set bit3, set 3T */
+	else
+		Data = (u8) (Data & 0xf7);	/*clear bit3, set 2T */
+
+	pci_write_config8(MEMCTRL, 0x63, Data);
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/UMARamSetting.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/UMARamSetting.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/ddr2init/vx800/UMARamSetting.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,445 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+typedef struct __UMA_RAM_tag {
+	u16 DramSize;
+	u8 D0F3Val;
+	u8 D1F0Val;
+	u8 VgaPortVal;
+} UMARAM;
+#define UMARAM_512M	7
+#define UMARAM_256M	6
+#define UMARAM_128M	5
+#define UMARAM_64M 	4
+#define UMARAM_32M	3
+#define UMARAM_16M	2
+#define UMARAM_8M	1
+#define UMARAM_0M	0
+
+
+#define FB_512M		0
+#define FB_256M		0x40
+#define FB_128M		0x60
+#define FB_64M		0x70
+#define FB_32M		0x78
+#define FB_16M		0x7c
+#define FB_8M		0x7E
+#define FB_4M		0x7F
+
+#define VGA_PORT_512M	0x00
+#define VGA_PORT_256M	0x80
+#define VGA_PORT_128M	0xC0
+#define VGA_PORT_64M	0xE0
+#define VGA_PORT_32M	0xF0
+#define VGA_PORT_16M	0xF8
+
+static const UMARAM UMARamArr[] = {
+	{0, UMARAM_0M, FB_4M, 0xFE},
+	{8, UMARAM_8M, FB_8M, 0xFC},
+	{16, UMARAM_16M, FB_16M, VGA_PORT_16M},
+	{32, UMARAM_32M, FB_32M, VGA_PORT_32M},
+	{64, UMARAM_64M, FB_64M, VGA_PORT_64M},
+	{128, UMARAM_128M, FB_128M, VGA_PORT_128M},
+	{256, UMARAM_256M, FB_256M, VGA_PORT_256M},
+	{512, UMARAM_512M, FB_512M, VGA_PORT_512M},
+	{0xffff, 0xff, 0xff, 0xFF}
+};
+
+void SetUMARam(void)
+{
+#if 1
+	u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
+	device_t vga_dev = PCI_DEV(0, 1, 0), d0f0_dev = PCI_DEV(0, 0, 0);
+	u8 ByteVal, temp;
+	UMARAM *pUMARamTable;
+	u16 UmaSize;
+	u8 SLD0F3Val, SLD1F0Val, VgaPortVal;
+	u32 RamSize, SLBase, Tmp;
+	u8 i;
+	PRINT_DEBUG_MEM("Entering vx800 SetUMARam.\n");
+	SLD0F3Val = 0;
+	SLD1F0Val = 0;
+	VgaPortVal = 0;
+
+
+	ByteVal = pci_read_config8(MEMCTRL, 0xa1);
+	ByteVal |= 0x80;
+	pci_write_config8(MEMCTRL, 0xa1, ByteVal);
+
+	//set VGA Timer
+	pci_write_config8(MEMCTRL, 0xa2, 0xee);
+
+	//set agp misc
+	//GFX Data Delay to Sync with Clock
+	pci_write_config8(MEMCTRL, 0xa4, 0x01);
+
+	//page register life timer
+	pci_write_config8(MEMCTRL, 0xa6, 0x76);
+
+	//GMINT and GFX relatate
+	//note Bit 3 VGA Enable
+	pci_write_config8(MEMCTRL, 0xa7, 0x8c);
+	// ByteVal = 0x4c;
+
+	//GMINT Misc.1
+	//pci_write_config8(MEMCTRL, 0xb0, 0x80);
+
+	//pci_write_config8(MEMCTRL, 0xb1, 0xaa);
+
+	//AGPCINT MISC
+	//pci_write_config8(MEMCTRL, 0xb2, 0x82);
+	//ByteVal = 0x8A;
+
+	//GMINT MISC.2
+	//disable read pass write
+	pci_write_config8(MEMCTRL, 0xb3, 0x9A);
+
+	//EPLL Register
+	//pci_write_config8(MEMCTRL, 0xb4, 0x04);
+
+	//enable CHA and CHB merge mode
+	pci_write_config8(MEMCTRL, 0xde, 0x06);
+
+	//if can get the value from setup interface, so get the value
+	//else use the default value
+	UmaSize = CONFIG_VIDEO_MB;
+
+	for (pUMARamTable = UMARamArr; pUMARamTable->DramSize != 0xffff;
+	     pUMARamTable++) {
+		if (UmaSize == pUMARamTable->DramSize) {
+			SLD0F3Val = pUMARamTable->D0F3Val;
+			SLD1F0Val = pUMARamTable->D1F0Val;
+			VgaPortVal = pUMARamTable->VgaPortVal;
+		}
+	}
+	//set SL size
+	//Fill in Fun3_RXA1[6:4] with the Frame Buffer size for the Integrated Graphic Device.
+	ByteVal = pci_read_config8(MEMCTRL, 0xa1);
+	ByteVal = (ByteVal & 0x8f) | (SLD0F3Val << 4);
+	pci_write_config8(MEMCTRL, 0xa1, ByteVal);
+
+
+//      vga_dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_VGA, 0);
+
+	//RxB2 may be for S.L. and RxB1 may be for L. L. 
+	// It is different from Spec.
+	ByteVal = SLD1F0Val;
+	pci_write_config8(vga_dev, 0xb2, ByteVal);
+
+
+	//set M1 size
+	//ByteVal=pci_read_config8(MEMCTRL, 0xa3);
+	//ByteVal = 0x02;
+	//pci_write_config8(MEMCTRL, 0xa3, ByteVal);
+
+	PRINT_DEBUG_MEM("UMA setting - 3\n");
+
+
+
+
+	//Enable p2p  IO/mem
+	ByteVal = 0x07;
+	pci_write_config8(vga_dev, 0x04, ByteVal);
+
+
+
+
+	//must set SL and MMIO base, or else when enable GFX memory space, system will hang
+	//set S.L base
+	Tmp = pci_read_config32(vga_dev, 0x10);
+	Tmp = 0xfffffff8;
+	pci_write_config32(vga_dev, 0x10, Tmp);
+	Tmp = pci_read_config32(vga_dev, 0x10);
+	Tmp = VIACONFIG_VGA_PCI_10;
+	pci_write_config32(vga_dev, 0x10, Tmp);
+
+	//set MMIO base
+	Tmp = pci_read_config32(vga_dev, 0x14);
+	Tmp = 0xfffffffC;
+	pci_write_config32(vga_dev, 0x14, Tmp);
+	Tmp = pci_read_config32(vga_dev, 0x14);
+	Tmp = VIACONFIG_VGA_PCI_14;
+	pci_write_config32(vga_dev, 0x14, Tmp);
+
+
+//enable direct cpu frame buffer access
+	i = pci_rawread_config8(PCI_RAWDEV(0, 0, 3), 0xa1);
+	i = (i & 0xf0) | (VIACONFIG_VGA_PCI_10 >> 28);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa1, i);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xa0, 0x01);
+
+
+	//enable GFx memory space access control for S.L and mmio
+	ByteVal = pci_read_config8(d0f0_dev, 0xD4);
+	ByteVal |= 0x03;
+	//ByteVal |= 0x01;
+	pci_write_config8(d0f0_dev, 0xD4, ByteVal);
+
+
+	//enable Base VGA 16 Bits Decode
+	ByteVal = pci_read_config8(d0f0_dev, 0xfe);
+	ByteVal |= 0x10;
+	pci_write_config8(d0f0_dev, 0xfe, ByteVal);
+
+
+	//disable CHB L.L
+	//set VGA memory selection
+	ByteVal = pci_read_config8(vga_dev, 0xb0);
+	ByteVal &= 0xF8;
+	//ByteVal |= 0x01;
+	ByteVal |= 0x03;
+	pci_write_config8(vga_dev, 0xb0, ByteVal);
+
+	//set LL size
+
+	//enable memory access to SL,MMIO,LL and IO to 3B0~3BB,3C0 ~3DF
+	//ByteVal = 0x03;
+	//pci_write_config8(d0f0_dev, 0xc0, ByteVal);
+
+	//Turn on Graphic chip IO port port access
+	ByteVal = inb(0x03C3);
+	ByteVal |= 0x01;
+	outb(ByteVal, 0x03C3);
+
+	//Turn off Graphic chip Register protection
+	outb(0x10, 0x03C4);
+
+	ByteVal = inb(0x03C5);
+	ByteVal |= 0x01;
+	outb(ByteVal, 0x03C5);
+
+	//set VGA memory Frequence
+	//direct IO port 0x3DX to vga io space 0x3C2[0]
+	ByteVal = inb(0x03CC);
+	ByteVal |= 0x03;
+	outb(ByteVal, 0x03C2);
+	//  ByteVal=inb(0x03C2);
+	//   ByteVal |= 0x01;
+	//   outb(ByteVal,0x03C2);
+
+
+#if 1				//bios porting guide has no this two defination:  3d  on 3d4/3d5 and  39 on 3c4/3c5
+	//set frequence 0x3D5.3d[7:4]
+	outb(0x3d, 0x03d4);
+
+	temp = pci_read_config8(MEMCTRL, 0x90);
+	temp = (u8) (temp & 0x07);
+	ByteVal = inb(0x03d5);
+	switch (temp) {
+	case 0:		//DIMMFREQ_200:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x30);
+		break;
+	case 1:		//DIMMFREQ_266:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x40);
+		break;
+	case 3:		//DIMMFREQ_400:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x60);
+		break;
+	case 4:		//DIMMFREQ_533:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
+		break;
+	case 5:		//DIMMFREQ_667:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x80);
+		break;
+	case 6:		//DIMMFREQ_800:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x90);
+		break;
+	default:
+		ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
+		break;
+	}
+	outb(ByteVal, 0x03d5);
+
+	// Set frame buffer size 
+	outb(0x39, 0x03c4);
+	outb(1 << SLD0F3Val, 0x03c5);
+
+#endif
+	// Set S.L. size in GFX's register
+	outb(0x68, 0x03c4);
+	outb(VgaPortVal, 0x03c5);
+
+	//  ECLK Selection (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
+	// set 3C5.5A[0]=1, address maps to secondary resgiters
+	outb(0x5a, 0x03c4);
+	ByteVal = inb(0x03c5);
+	ByteVal |= 0x01;
+	outb(ByteVal, 0x03c5);
+
+	// Set 3D5.4C[7:6] (00:166Mhz, 01:185Mhz, 10:250Mhz, 11:275Mhz)
+	outb(0x4c, 0x03d4);
+	ByteVal = inb(0x03d5);
+	ByteVal = (ByteVal & 0x3F) | 0x80;
+	outb(ByteVal, 0x03d5);
+
+	// set 3C5.5A[0]=0, address maps to first resgiters
+	outb(0x5a, 0x03c4);
+	ByteVal = inb(0x03c5);
+	ByteVal &= 0xFE;
+	outb(ByteVal, 0x03c5);
+
+	// Set S.L. Address in System Memory
+	//calculate dram size
+	for (RamSize = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
+		RamSize = pci_read_config8(MEMCTRL, ramregs[i]);
+		if (RamSize != 0)
+			break;
+	}
+	//calculate SL Base Address
+	SLBase = (RamSize << 26) - (UmaSize << 20);
+
+
+	outb(0x6D, 0x03c4);
+	//SL Base[28:21] 
+	outb((u8) ((SLBase >> 21) & 0xFF), 0x03c5);
+
+	outb(0x6e, 0x03c4);
+	//SL Base[36:29]
+	outb((u8) ((SLBase >> 29) & 0xFF), 0x03c5);
+
+	outb(0x6f, 0x03c4);
+	outb(0x00, 0x03c5);
+
+	// Set SVID high byte
+	outb(0x36, 0x03c4);
+	outb(0x11, 0x03c5);
+
+	// Set SVID Low byte
+	outb(0x35, 0x03c4);
+	outb(0x06, 0x03c5);
+
+	// Set SID high byte
+	outb(0x38, 0x03c4);
+	outb(0x51, 0x03c5);
+
+	// Set SID Low byte
+	outb(0x37, 0x03c4);
+	outb(0x22, 0x03c5);
+
+	//start : For enable snapshot mode control
+	// program 3C5 for SNAPSHOT Mode control, set RxF3h=1Ah
+	outb(0xf3, 0x03c4);
+	ByteVal = inb(0x03c5);
+	ByteVal = (ByteVal & 0xE5) | 0x1A;
+	outb(ByteVal, 0x03c5);
+
+
+	outb(0xf3, 0x03d4);
+	ByteVal = inb(0x03d5);
+	ByteVal = (ByteVal & 0xE5) | 0x1A;
+	outb(ByteVal, 0x03d5);
+
+	u8 table3c43c5[0x70] = {
+		0x03, 0x01, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x78, 0x00, 0x00, 0x00, 0xBE, 0x20, 0x7F,
+		0x60, 0x7F, 0x08, 0x31, 0xCC, 0x00, 0x01, 0x00,
+		0x00, 0x18, 0x10, 0x00, 0x00, 0x00, 0x3D, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x04, 0xF3, 0xFF, 0xFC,
+		0xF8, 0x0C, 0x00, 0x00, 0x40, 0x06, 0x11, 0x22,
+		0x51, 0x10, 0x00, 0x01, 0x19, 0x0C, 0x00, 0xFF,
+		0x38, 0x40, 0x30, 0xFF, 0x70, 0x8C, 0x85, 0x9D,
+		0x80, 0x05, 0x54, 0x90, 0x03, 0x30, 0x00, 0x5F,
+		0x1F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
+		0x06, 0xDF, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x20, 0x20,
+		0xE0, 0x20, 0xD0, 0x3F, 0x00, 0xE0, 0x00, 0x00
+	};
+	u8 table3d43d5[0x88] = {
+		0x7F, 0x63, 0x63, 0x83, 0x69, 0x19, 0x72, 0xE0,
+		0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x58, 0x9C, 0x57, 0x90, 0x00, 0x57, 0x73, 0xE3,
+		0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x0C, 0x00, 0x11, 0x06, 0x00, 0x20, 0x01, 0x34,
+		0xEE, 0x74, 0x01, 0x01, 0x08, 0x84, 0x00, 0x00,
+		0x00, 0xF3, 0x40, 0x90, 0x00, 0x00, 0x00, 0x01,
+		0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00,
+		0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
+		0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x10,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x9D, 0x9D,
+		0x9D, 0x9D, 0x9D, 0x9D, 0x00, 0x9D, 0x1D, 0x00,
+		0x00, 0x00, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
+		0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
+	};
+
+
+	u8 table3c0space[0xc0] = {
+		0x11, 0x00, 0x10, 0x01, 0x26, 0x3D, 0xFF, 0x00,
+		0x10, 0x3F, 0x00, 0x00, 0x2F, 0x00, 0x22, 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, 0x50, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 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,
+	};
+#if 0
+//for(i=0;i<0xc0;i++)
+	for (i = 0; i < 0x40; i++)	//
+	{
+		outb(table3c0space[i], 0x03c0 + i);
+	}
+
+
+	for (i = 0; i < 0x70; i++) {
+		outb(i, 0x03c4);
+		outb(table3c43c5[i], 0x03c5);
+	}
+	for (i = 0; i < 0x88; i++) {
+		outb(i, 0x03d4);
+		outb(table3d43d5[i], 0x03d5);
+	}
+	outb(0x92, 0x03d4);
+	outb(0x80, 0x03d5);
+
+	outb(0xa3, 0x03d4);
+	outb(0x00, 0x03d5);
+
+	outb(0xe8, 0x03d4);
+	outb(0x40, 0x03d5);
+#endif
+//3d4 3d freq
+//IO Port / Index: 3X5.3D
+//Scratch Pad Register 4
+
+//    outb(0x39,0x03c4);//
+	//outb(1 << SLD0F3Val ,0x03c5);
+//
+#endif
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/examples/DrivingClkPhaseData.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/examples/DrivingClkPhaseData.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/examples/DrivingClkPhaseData.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,242 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+ #include "northbridge/via/vx800/DrivingClkPhaseData.h"
+
+// DQS	Driving  
+//Reg0xE0, 0xE1
+// According to #Bank to set DRAM DQS Driving
+//	                          #Bank	   1	 2     3     4	   5	 6     7     8
+static const u8 DDR2_DQSA_Driving_Table[4] = { 0xEE, 0xEE, 0xEE, 0xEE};
+static const u8 DDR2_DQSB_Driving_Table[2] = { 0xEE, 0xEE};
+
+// DQ Driving
+//Reg0xE2, 0xE3
+// For DDR2: According to bank  to set DRAM DQ Driving
+static const  u8 DDR2_DQA_Driving_Table[4] = {	0xAC, 0xAC, 0xAC, 0xAC };
+static const  u8 DDR2_DQB_Driving_Table[2] = { 0xCA, 0xCA };
+
+
+// CS	Driving
+//Reg0xE4, 0xE5
+// According to #Bank to set DRAM CS Driving
+// DDR1                       #Bank	     1	   2     3     4	 5	   6     7     8
+static const  u8 DDR2_CSA_Driving_Table_x8[4] = { 0x44, 0x44, 0x44, 0x44 };
+static const  u8 DDR2_CSB_Driving_Table_x8[2] = { 0x44, 0x44};
+static const  u8 DDR2_CSA_Driving_Table_x16[4]= { 0x44, 0x44, 0x44, 0x44};
+static const  u8 DDR2_CSB_Driving_Table_x16[2]= { 0x44, 0x44};
+// MAA	Driving
+//Reg0xE8, Reg0xE9
+static const  u8 DDR2_MAA_Driving_Table[MA_Table][5] =
+    {
+        //Chip number,	   400,   533,   667	  800   ;(SRAS,	SCAS, SWE)RxE8
+        {  6,	                0x86, 0x86, 0x86, 0x86},		// total MAA chips = 00 ~	06
+        { 18,	                0x86, 0x86, 0x86, 0x86},		// total MAA chips = 06 ~	18
+        {255,	                0xDB, 0xDB, 0xDB, 0xDB}		// total MAA chips = 18 ~
+    };
+
+static const  u8 DDR2_MAB_Driving_Table[MA_Table][2] =
+    {
+        //	Chip number,	Value	;(SRAS,	SCAS, SWE)RxE9
+        {  6,	0x86 },		// total MAB chips = 00 ~	06
+        { 18,	0x86 },		// total MAB chips = 06 ~	18
+        {255,	0xDB }		// total MAB chips = 18 ~
+    };
+
+// DCLK Driving
+//Reg0xE6, 0xE7
+// For DDR2: According to #Freq to set DRAM DCLK Driving
+//                        freq		  400M, 533M, 667M, 800M
+
+static const  u8 DDR2_DCLKA_Driving_Table[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
+static const  u8 DDR2_DCLKB_Driving_Table[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
+
+/*
+Duty cycle
+Duty cycle Control for DQ/DQS/DDRCKG in ChA & ChB
+D0F3RxEC/D0F3RxED/D0F3RxEE/D0F3RxEF
+According to DRAM frequency to control Duty Cycle
+*/
+static const  u8 ChA_Duty_Control_DDR2[DUTY_CYCLE_REG_NUM][DUTY_CYCLE_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0xEC,  0x00,  0x30,  0x30,  0x30,  0x30 },	// 1Rank
+        {0xEE,  0x0F,  0x40,  0x40,  0x00,  0x00 },
+        {0xEF,  0xCF,  0x00,  0x30,  0x30,  0x30}
+    };
+
+static const  u8 ChB_Duty_Control_DDR2[DUTY_CYCLE_REG_NUM][DUTY_CYCLE_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0xED,  0x00,  0x88,  0x88,  0x84,  0x88 },	// 1Rank
+        {0xEE,  0xF0,  0x00,  0x00,  0x00,  0x00 },
+        {0xEF,  0xFC,  0x00,  0x00,  0x00,  0x00 }
+    };
+
+
+/*
+DRAM Clock Phase Control for FeedBack Mode
+Modify NB Reg: Rx90[7]/Rx91/Rx92/Rx93/Rx94
+Processing:
+		1.Program VIA_NB3DRAM_REG90[7]=0b for FeedBack mode
+		2.Program clock	phase value with ChA/B DCLK enable, VIA_NB3DRAM_REG91[7:3]=00b
+		3.Check	ChB rank #, if 0, VIA_NB3DRAM_REG91[7]=1b, to disable ChB DCLKO
+		  ChA DCLKO can	not be disable,	so always program VIA_NB3DRAM_REG91[3]=0b
+ */
+static const  u8 DDR2_ChA_Clk_Phase_Table_1R[3][Clk_Phase_Table_DDR2_Width] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0x91,  0xF8,  0x02,  0x01,  0x00,  0x07 },	// 1Rank
+        {0x92,  0xF8,  0x04,  0x03,  0x03,  0x02 },
+        {0x93,  0xF8,  0x06,  0x05,  0x04,  0x03 }
+    };
+
+static const  u8 DDR2_ChB_Clk_Phase_Table_1R[3][Clk_Phase_Table_DDR2_Width] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value Value Value Value
+        {0x91, 0x0F, 0x20, 0x10, 0x00, 0x70 },	// 1Rank
+        {0x92, 0x0F, 0x40, 0x30, 0x30, 0x20 },
+        {0x93, 0x0F, 0x60, 0x50, 0x40, 0x30 }
+    };
+
+/*static const  u8 DDR2_ChA_Clk_Phase_Table_2R[3][Clk_Phase_Table_DDR2_Width] =
+    {
+        //     (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+       {0x91,  0xF8,  0x04,  0x03,  0x04,  0x01 },	// 1Rank
+        {0x92,  0xF8,  0x03,  0x06,  0x05,  0x04 },
+        {0x93,  0xF8,  0x03,  0x07,  0x06,  0x05 }
+    };*/
+
+static const  u8 DDR2_ChA_Clk_Phase_Table_2R[3][Clk_Phase_Table_DDR2_Width] =
+    {
+        //     (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0x91,  0xF8,  0x02,  0x01,  0x00,  0x07},	// 1Rank
+        {0x92,  0xF8,  0x04,  0x03,  0x03,  0x02 },
+        {0x93,  0xF8,  0x06,  0x05,  0x04,  0x03 }
+    };
+
+/*
+DRAM Write Data phase control
+Modify NB Reg: Rx74/Rx75/Rx76
+*/
+/*static const  u8 DDR2_ChA_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0x74,  0xF8,  0x03,  0x04,  0x05,  0x02 },	// 1Rank
+        {0x75,  0xF8,  0x03,  0x04,  0x05,  0x02 },
+        {0x76,  0x00,  0x10,  0x80,  0x00,  0x07 }
+    };*/
+
+static const  u8 DDR2_ChA_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0x74,  0xF8,  0x01,  0x00,  0x00,  0x07 },	// 1Rank
+        {0x75,  0xF8,  0x01,  0x00,  0x00,  0x07 },
+        {0x76,  0x10,  0x80,  0x87,  0x07,  0x06 },
+        {0x8C,  0xFC,  0x03,  0x03,  0x03,  0x03 }
+    };
+
+/*static const  u8 DDR2_ChB_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM] = 
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value Value Value Value
+        {0x74, 0x8F, 0x30, 0x40, 0x30, 0x20 },	// 1Rank
+        {0x75, 0x8F, 0x30, 0x40, 0x30, 0x20 },
+        {0x8A, 0x00, 0x10, 0x80, 0x07, 0x07 }
+    };
+*/
+/*
+DQ/DQS Output Delay Control
+Modify NB D0F3: RxF0/RxF1/RxF2/RxF3
+*/
+static const  u8 DDR2_CHA_DQ_DQS_Delay_Table[4][DQ_DQS_Delay_Table_Width] =
+    {
+        // RxF0	RxF1  RxF2	RxF3
+        { 0x00,	0x00, 0x00,	0x00 },// DDR400
+        { 0x00,	0x00, 0x00,	0x00 },// DDR533
+        { 0x00,	0x00, 0x00,	0x00 },// DDR667
+        { 0x00,	0x00, 0x00,	0x00 }// DDR800
+    };
+static const  u8 DDR2_CHB_DQ_DQS_Delay_Table[4][DQ_DQS_Delay_Table_Width] =
+    {
+        // RxF4	RxF5  RxF6	RxF7
+        { 0x00,	0x00, 0x00,	0x00 },// DDR400
+        { 0x00,	0x00, 0x00,	0x00 },// DDR533
+        { 0x00,	0x00, 0x00,	0x00 },// DDR667
+        { 0x00,	0x00, 0x00,	0x00 }// DDR800
+    };
+
+/*
+DQ/DQS input Capture Control
+modify NB D0F3_Reg:Rx78/Rx79/Rx7A/Rx7B
+*/
+
+/*static const  u8 DDR2_ChA_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0x78,  0x00,  0x83,  0x8D,  0x87,  0x83 },	// 1Rank
+        {0x7A,  0xF0,  0x00,  0x00,  0x00,  0x00 },
+        {0x7B,  0x00,  0x10,  0x30,  0x20,  0x10 }
+    };*/
+
+
+static const  u8 DDR2_ChA_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value  Value  Value  Value
+        {0x78,  0xC0,  0x0D,  0x07,  0x03,  0x01 },	// 1Rank
+        {0x7A,  0xF0,  0x00,  0x00,  0x00,  0x00 },
+        {0x7B,  0x00,  0x34,  0x34,  0x20,  0x10 }
+    };
+
+static const  u8 DDR2_ChB_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM] =
+    {
+        //    (And NOT) DDR800 DDR667 DDR533 DDR400
+        //Reg  Mask  Value Value Value Value
+        {0x79, 0x00, 0x89, 0x89, 0x87, 0x83 },	// 1Rank
+        {0x7A, 0x0F, 0x00, 0x00, 0x00, 0x00 },
+        {0x8B, 0x00, 0x34, 0x34, 0x20, 0x10 }
+    };
+
+static const  u8 Fixed_DQSA_1_2_Rank_Table[4][2] =
+{
+// 	  Rx70	Rx71
+	{ 0x00,	0x05 },		// DDR800
+	{ 0x00,	0x06 },		// DDR667
+	{ 0x00,	0x04 },		// DDR533
+	{ 0x00,	0x05 }		// DDR400
+};
+static const  u8 Fixed_DQSA_3_4_Rank_Table[4][2] =
+{
+// 	  Rx70	Rx71
+	{0x00 ,	0x04},		// DDR800
+	{0x00 ,	0x04},		// DDR667
+	{0x00 ,	0x03},		// DDR533
+	{0x00 ,	0x04}		// DDR400
+};

Added: trunk/coreboot-v2/src/northbridge/via/vx800/examples/cache_as_ram_auto.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/examples/cache_as_ram_auto.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/examples/cache_as_ram_auto.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,660 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define ASSEMBLY 1
+#define __ROMCC__
+#define RAMINIT_SYSINFO 1
+#define CACHE_AS_RAM_ADDRESS_DEBUG 0
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <arch/hlt.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+#include "northbridge/via/vx800/vx800.h"
+#include "cpu/x86/mtrr/earlymtrr.c"
+#include "cpu/x86/bist.h"
+#include "pc80/udelay_io.c"
+#include "lib/delay.c"
+#if CONFIG_USE_INIT == 0
+#include "lib/memcpy.c"
+#endif
+#include "cpu/x86/lapic/boot_cpu.c"
+
+#include "DrivingClkPhaseData.c"
+
+#include "northbridge/via/vx800/raminit.h"
+#include "northbridge/via/vx800/raminit.c"
+#include "cpu/x86/car/copy_and_run.c"
+
+int acpi_is_wakeup_early_via_vx800(void)
+{
+	device_t dev;
+	u16 tmp, result;
+
+	print_debug("In acpi_is_wakeup_early_via_vx800\r\n");
+	/* Power management controller */
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+				       PCI_DEVICE_ID_VIA_VX855_LPC), 0);
+
+	if (dev == PCI_DEV_INVALID)
+		die("Power management controller not found\r\n");
+
+	/* Set ACPI base address to I/O VX800_ACPI_IO_BASE. */
+	pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 0x1);
+
+	/* Enable ACPI accessm RTC signal gated with PSON. */
+	pci_write_config8(dev, 0x81, 0x84);
+
+	tmp = inw(VX800_ACPI_IO_BASE + 0x04);
+	result = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0;
+	print_debug("         boot_mode=");
+	print_debug_hex16(result);
+	print_debug("\r\n");
+	return result;
+}
+
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+	return smbus_read_byte(device, address);
+}
+
+
+static void enable_mainboard_devices(void)
+{
+	device_t dev;
+	uint16_t values;
+
+	print_debug("In enable_mainboard_devices \r\n");
+
+	/*
+	   Enable P2P Bridge Header for External PCI BUS.
+	 */
+	dev = pci_locate_device(PCI_ID(0x1106, 0xa353), 0);
+	pci_write_config8(dev, 0x4f, 0x41);
+}
+
+static void enable_shadow_ram(void)
+{
+	uint8_t shadowreg;
+	pci_write_config8(PCI_DEV(0, 0, 3), 0x80, 0xff);
+	/* 0xf0000-0xfffff - ACPI tables */
+	shadowreg = pci_read_config8(PCI_DEV(0, 0, 3), 0x83);
+	shadowreg |= 0x30;
+	pci_write_config8(PCI_DEV(0, 0, 3), 0x83, shadowreg);
+	/* 0xe0000-0xeffff - elfload? */
+
+	pci_write_config8(PCI_DEV(0, 0, 3), 0x82, 0xff);
+
+}
+
+
+/*
+this table contains the value needed to be set before begin to init dram.
+Note: REV_Bx should be cared when porting a new board!!!!! */
+static const struct VIA_PCI_REG_INIT_TABLE mNbStage1InitTbl[] = {
+	//VT3409 no pcie
+	0x00, 0xFF, NB_APIC_REG(0x61), 0xFF, 0x0E,	// Set Exxxxxxx as pcie mmio config range
+	0x00, 0xFF, NB_APIC_REG(0x60), 0xF4, 0x0B,	// Support extended cfg address of pcie
+	//0x00, 0xFF, NB_APIC_REG(0x42), 0xF9, 0x02, // APIC Interrupt((BT_INTR)) Control
+	// Set ROMSIP value by software
+
+	/*0x00, 0xFF, NB_HOST_REG(0x70), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pullup Driving = 3
+	   0x00, 0xFF, NB_HOST_REG(0x71), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pulldown Driving = 3
+	   0x00, 0xFF, NB_HOST_REG(0x72), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pullup Driving = 3
+	   0x00, 0xFF, NB_HOST_REG(0x73), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pulldown Driving = 3
+	   0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0x21, // Memory I/F timing ctrl
+	   0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0xE1, // Memory I/F timing ctrl
+	   0x00, 0xFF, NB_HOST_REG(0x75), 0xFF, 0x18, // AGTL+ I/O Circuit
+	   0x00, 0xFF, NB_HOST_REG(0x76), 0xFB, 0x0C, // AGTL+ Compensation Status
+	   0x00, 0xFF, NB_HOST_REG(0x78), 0xFF, 0x33, // 2X AGTL+ Auto Compensation Offset
+	   0x00, 0xFF, NB_HOST_REG(0x79), 0xFF, 0x33, // 4X AGTL+ Auto Compensation Offset
+	   0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x72, // AGTL Compensation Status
+	   0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x77, // AGTL Compensation Status
+	   0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x44, // Input Host Address / Host Strobe Delay Control for HA Group
+	   0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x22, // Input Host Address / Host Strobe Delay Control for HA Group
+	   0x00, 0xFF, NB_HOST_REG(0x7C), 0xFF, 0x00, // Output Delay Control of PAD for HA Group
+	   0x00, 0xFF, NB_HOST_REG(0x7D), 0xFF, 0xAA, // Host Address / Address Clock Output Delay Control (Only for P4 Bus)
+	   0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
+	   0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
+	   0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
+	   0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus)
+	   0x00, 0xFF, NB_HOST_REG(0x80), 0x3F, 0x44, // Host Data Receiving Strobe Delay Ctrl 1
+	   0x00, 0xFF, NB_HOST_REG(0x81), 0xFF, 0x44, // Host Data Receiving Strobe Delay Ctrl 2
+	   0x00, 0xFF, NB_HOST_REG(0x82), 0xFF, 0x00, // Output Delay of PAD for HDSTB
+	   0x00, 0xFF, NB_HOST_REG(0x83), 0xFF, 0x00, // Output Delay of PAD for HD
+	   0x00, 0xFF, NB_HOST_REG(0x84), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 0)
+	   0x00, 0xFF, NB_HOST_REG(0x85), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 1)
+	   0x00, 0xFF, NB_HOST_REG(0x86), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 2)
+	   0x00, 0xFF, NB_HOST_REG(0x87), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 3) */
+
+
+	// CPU Host Bus Control
+	0x00, 0xFF, NB_HOST_REG(0x50), 0x1F, 0x08,	// Request phase ctrl: Dynamic Defer Snoop Stall Count = 8
+	//0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7F, // CPU I/F Ctrl-1: Disable Fast DRDY and RAW
+	0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7C,	// CPU I/F Ctrl-1: Disable Fast DRDY and RAW
+	0x00, 0xFF, NB_HOST_REG(0x52), 0xCB, 0xCB,	// CPU I/F Ctrl-2: Enable all for performance
+	//0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x88, // Arbitration: Host/Master Occupancy timer = 8*4 HCLK
+	0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x44,	// Arbitration: Host/Master Occupancy timer = 4*4 HCLK
+	0x00, 0xFF, NB_HOST_REG(0x54), 0x1E, 0x1C,	// Misc Ctrl: Enable 8QW burst Mem Access
+	//0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x06, // Miscellaneous Control 2
+	0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x04,	// Miscellaneous Control 2
+	0x00, 0xFF, NB_HOST_REG(0x56), 0xF7, 0x63,	// Write Policy 1
+	//0x00, 0xFF, NB_HOST_REG(0x59), 0x3D, 0x01, // CPU Miscellaneous Control 1, enable Lowest-Priority IPL
+	//0x00, 0xFF, NB_HOST_REG(0x5c), 0xFF, 0x00, // CPU Miscellaneous Control 2
+	0x00, 0xFF, NB_HOST_REG(0x5D), 0xFF, 0xA2,	// Write Policy
+	0x00, 0xFF, NB_HOST_REG(0x5E), 0xFF, 0x88,	// Bandwidth Timer
+	0x00, 0xFF, NB_HOST_REG(0x5F), 0x46, 0x46,	// CPU Misc Ctrl
+	// 0x00, 0xFF, NB_HOST_REG(0x90), 0xFF, 0x0B, // CPU Miscellaneous Control 3
+	//0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0B, // CPU Miscellaneous Control 2
+	0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0A,	// CPU Miscellaneous Control 2
+	0x00, 0xFF, NB_HOST_REG(0x98), 0xC1, 0x41,	// CPU Miscellaneous Control 3
+	0x00, 0xFF, NB_HOST_REG(0x99), 0x0E, 0x06,	// CPU Miscellaneous Control 4
+
+
+	// Set APIC and SMRAM
+	0x00, 0xFF, NB_HOST_REG(0x97), 0xFF, 0x00,	// APIC Related Control
+	0x00, 0xFF, NB_DRAMC_REG(0x86), 0xD6, 0x29,	// SMM and APIC Decoding: enable APIC, MSI and SMRAM A-Seg
+	0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	// End of the table
+};
+
+#define USE_VCP     1		//0 means use DVP
+#define USE_COM1    1
+#define USE_COM2    0
+
+#define gCom1Base   0x3f8
+#define gCom2Base   0x2f8
+void EmbedComInit()
+{
+	u8 ByteVal;
+	u16 ComBase;
+
+	//enable NB multiple function control
+	ByteVal = pci_read_config8(PCI_DEV(0, 0, 0), 0x4f);
+	ByteVal = ByteVal | 0x01;
+	pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, ByteVal);
+
+	//VGA Enable
+	ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA1);
+	ByteVal = ByteVal | 0x80;
+	pci_write_config8(PCI_DEV(0, 0, 3), 0xA1, ByteVal);
+
+	ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA7);
+	ByteVal = ByteVal | 0x08;
+	pci_write_config8(PCI_DEV(0, 0, 3), 0xA7, ByteVal);
+
+	//Enable p2p  IO/mem
+	ByteVal = pci_read_config8(PCI_DEV(0, 1, 0), 0x4);
+	ByteVal = ByteVal | 0x07;
+	pci_write_config8(PCI_DEV(0, 1, 0), 0x4, ByteVal);
+
+	//Turn on Graphic chip IO port port access
+	ByteVal = inb(0x3C3);
+	ByteVal = ByteVal | 0x01;
+	outb(ByteVal, 0x3C3);
+
+	//Turn off Graphic chip Register protection
+	outb(0x10, 0x3C4);
+	ByteVal = inb(0x3C5);
+	ByteVal = ByteVal | 0x01;
+	outb(ByteVal, 0x3C5);
+
+	//south module pad share enable 0x3C5.78[7]
+	outb(0x78, 0x3C4);
+	ByteVal = inb(0x3C5);
+	ByteVal = ByteVal | 0x80;
+	outb(ByteVal, 0x3C5);
+
+	//enable  UART Function multiplex with DVP or VCP pad D17F0Rx46[7,6]
+	ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0x46);
+	//multiplex with VCP
+	if (USE_VCP == 1)
+		ByteVal = (ByteVal & 0x3F) | 0x40;
+	//multiplex with DVP
+	else
+		ByteVal = (ByteVal & 0x3F) | 0xC0;
+	pci_write_config8(PCI_DEV(0, 17, 0), 0x46, ByteVal);
+
+
+
+	//enable embeded com1 and com2 D17F0RxB0[5,4]
+	ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xB0);
+	ByteVal = ByteVal & 0xcf;
+	//multiplex with VCP
+	if (USE_COM1 == 1)
+		ByteVal = ByteVal | 0x10;
+	if (USE_COM2 == 1)
+		ByteVal = ByteVal | 0x20;
+	pci_write_config8(PCI_DEV(0, 17, 0), 0xB0, ByteVal);
+
+	if (USE_COM1 == 1)
+		ComBase = gCom1Base;
+	else
+		ComBase = gCom2Base;
+
+//noharddrive
+
+	//set embeded com1 IO base = 0x3E8
+	//D17F0RB4
+	//ByteVal = 0xFD;
+	if (USE_COM1 == 1) {
+		ByteVal = (u8) ((gCom1Base >> 3) | 0x80);
+		pci_write_config8(PCI_DEV(0, 17, 0), 0xB4, ByteVal);
+		ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2);
+		ByteVal = (ByteVal & 0xf0) | 0x04;
+		pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal);
+	}
+	//set embeded com2 IO base = 0x2E8
+	//D17F0RB5
+	//ByteVal = 0xDD;
+	if (USE_COM2 == 1) {
+		ByteVal = (u8) ((gCom2Base >> 3) | 0x80);
+		pci_write_config8(PCI_DEV(0, 17, 0), 0xB5, ByteVal);
+		ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2);
+		ByteVal = (ByteVal & 0x0f) | 0x30;
+		pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal);
+	}
+	//no port 80 biger then 0x10
+
+	//disable interrupt
+	ByteVal = inb(ComBase + 3);
+	outb(ByteVal & 0x7F, ComBase + 3);
+	outb(0x00, ComBase + 1);
+
+	//set baudrate
+	ByteVal = inb(ComBase + 3);
+	outb(ByteVal | 0x80, ComBase + 3);
+	outb(0x01, ComBase);
+	outb(0x00, ComBase + 1);
+
+	//set  frame  fromat
+	ByteVal = inb(ComBase + 3);
+	outb(ByteVal & 0x3F, ComBase + 3);
+	outb(0x03, ComBase + 3);
+	outb(0x00, ComBase + 2);
+	outb(0x00, ComBase + 4);
+
+	//SOutput("Embeded com output\n");
+	//while(1);
+}
+
+/* cache_as_ram.inc jump to here
+*/
+void amd64_main(unsigned long bist)
+{
+	unsigned cpu_reset = 0;
+	u16 boot_mode;
+	u8 rambits;
+
+	//device_t dev;
+	/* Enable multifunction for northbridge. */
+	pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, 0x01);
+	EmbedComInit();
+	//enable_vx800_serial();
+	//uart_init();
+
+
+/*	1.    D15F0
+
+a)      RxBAh = 71h
+
+b)      RxBBh = 05h
+
+c)      RxBEh = 71h
+
+d)      RxBFh = 05h
+
+2.    D17F0
+
+a)      RxA0h = 06h
+
+b)      RxA1h = 11h
+
+c)      RxA2h = 27h
+
+d)      RxA3h = 32h
+
+e)      Rx79h = 40h
+
+f)      Rx72h = 27h
+
+g)      Rx73h = 32h
+*/
+
+	u8 Data8;
+
+	pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBA,
+			   PCI_DEVICE_ID_VIA_VX855_IDE);
+	pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBE,
+			   PCI_DEVICE_ID_VIA_VX855_IDE);
+	pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA0, PCI_VENDOR_ID_VIA);
+	pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA2,
+			   PCI_DEVICE_ID_VIA_VX855_LPC);
+	Data8 = pci_read_config8(PCI_DEV(0, 0x11, 0), 0x79);
+	Data8 &= ~0x40;
+	Data8 |= 0x40;
+	pci_write_config8(PCI_DEV(0, 0x11, 0), 0x79, Data8);
+	pci_write_config16(PCI_DEV(0, 0x11, 0), 0x72,
+			   PCI_DEVICE_ID_VIA_VX855_LPC);
+
+	console_init();		//there are to function defination of console_init(), while the src/archi386/lib is the right one
+
+	/* decide if this is a s3 wakeup or a normal boot */
+	boot_mode = acpi_is_wakeup_early_via_vx800();
+	/*add this, to transfer "cpu restart" to "cold boot"
+	   When this boot is not a S3 resume, and PCI registers had been written, 
+	   then this must be a cpu restart(result of os reboot cmd). so we need a real "cold boot". */
+	if ((boot_mode != 3)
+	    && (pci_read_config8(PCI_DEV(0, 0, 3), 0x80) != 0)) {
+		outb(6, 0xcf9);
+	}
+
+	/*x86 cold boot I/O cmd */
+	enable_smbus();
+	//smbus_fixup(&ctrl);// this fix does help vx800!, but vx855 no need this 
+
+	if (bist == 0) {
+		// CAR need mtrr untill mem is ok, so i disable this early_mtrr_init();
+		//print_debug("doing early_mtrr\r\n");
+		//early_mtrr_init();
+	}
+
+	/* Halt if there was a built-in self test failure. */
+	report_bist_failure(bist);
+
+	print_debug("Enabling mainboard devices\r\n");
+	enable_mainboard_devices();
+
+	u8 Data;
+	device_t device;
+	/* Get NB Chip revision from D0F4RxF6, revision will be used in via_pci_inittable */
+	device = PCI_DEV(0, 0, 4);
+	Data = pci_read_config8(device, 0xf6);
+	print_debug("NB chip revision =");
+	print_debug_hex8(Data);
+	print_debug("\r\n");
+	/* make NB ready before draminit */
+	via_pci_inittable(Data, mNbStage1InitTbl);
+
+	/*add this.
+	   When resume from s3, draminit is skiped, so need to recovery any PCI register related to draminit.
+	   and d0f3 didnt lost its Power during whole s3 time, so any register not belongs to d0f3 need to be recoveried . */
+#if 1
+	if (boot_mode == 3) {
+		u8 i;
+		u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
+		DRAM_SYS_ATTR DramAttr;
+
+		print_debug("This is a S3 wakeup\r\n");
+
+		memset(&DramAttr, 0, sizeof(DRAM_SYS_ATTR));
+		/*Step1 DRAM Detection; DDR1 or DDR2; Get SPD Data; Rank Presence;64 or 128bit; Unbuffered or registered; 1T or 2T */
+		DRAMDetect(&DramAttr);
+
+		/*begin to get ram size, 43,42 41 40 contains the end address of last rank in ddr2-slot */
+		device = PCI_DEV(0, 0, 3);
+		for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
+			rambits = pci_read_config8(device, ramregs[i]);
+			if (rambits != 0)
+				break;
+		}
+
+		DRAMDRDYSetting(&DramAttr);
+
+		Data = 0x80;	// this value is same with DevInit.c
+		pci_write_config8(PCI_DEV(0, 0, 4), 0xa3, Data);
+		pci_write_config8(PCI_DEV(0, 17, 7), 0x60, rambits << 2);
+		Data = pci_read_config8(MEMCTRL, 0x88);
+		pci_write_config8(PCI_DEV(0, 17, 7), 0xE5, Data);
+
+		DRAMRegFinalValue(&DramAttr);	// I just copy this function from draminit to here!
+		SetUMARam();	// I just copy this function from draminit to here!
+		print_debug("Resume from S3, RAM init was ignored\r\n");
+	} else {
+		ddr2_ram_setup();
+		ram_check(0, 640 * 1024);
+	}
+#endif
+	//ddr2_ram_setup();
+	/*this line is the same with cx700 port . */
+	enable_shadow_ram();
+
+	/*
+	   For coreboot most time of S3 resume is the same as normal boot, so some memory area under 1M become dirty,
+	   so before this happen, I need to backup the content of mem to top-mem. 
+	   I will reserve the 1M top-men in LBIO table in coreboot_table.c and recovery the content of 1M-mem in wakeup.c
+	 */
+#if PAYLOAD_IS_SEABIOS==1	//
+	if (boot_mode == 3) {
+		/*   some idea of Libo.Feng at amd.com in  http://www.coreboot.org/pipermail/coreboot/2008-December/043111.html
+		   I want move the 1M data, I have to set some MTRRs myself. */
+		/* seting mtrr before back memoy save s3 resume time about 0.14 seconds */
+		/*because CAR stack use cache, and here to use cache , must be careful, 
+		   1 during these mtrr code, must no function call, (after this mtrr, I think it should be ok to use function)
+		   2 before stack switch, no use variable that have value set before this
+		   3 due to 2, take care of "cpu_reset", I directlly set it to ZERO.
+		 */
+		u32 memtop = *(u32 *) WAKE_MEM_INFO;
+		u32 memtop1 = *(u32 *) WAKE_MEM_INFO - 0x100000;
+		u32 memtop2 = *(u32 *) WAKE_MEM_INFO - 0x200000;
+		u32 memtop3 =
+		    *(u32 *) WAKE_MEM_INFO - 64 * 1024 - 0x100000;
+		u32 memtop4 =
+		    *(u32 *) WAKE_MEM_INFO - 64 * 1024 - 0x100000 +
+		    0xe0000;
+		/*      __asm__ volatile (              
+		   "movl    $0x204, %%ecx\n\t"
+		   "xorl    %%edx, %%edx\n\t"
+		   "movl     %0,%%eax\n\t"
+		   "orl     $(0 | 6), %%eax\n\t"
+		   "wrmsr\n\t"
+
+		   "movl    $0x205, %%ecx\n\t"
+		   "xorl    %%edx, %%edx\n\t"
+		   "movl   $0x100000,%%eax\n\t"
+		   "decl                %%eax\n\t"
+		   "notl                %%eax\n\t"
+		   "orl    $(0 | 0x800), %%eax\n\t"
+		   "wrmsr\n\t"
+		   ::"g"(memtop2)
+		   );
+		   __asm__ volatile (           
+		   "movl    $0x206, %%ecx\n\t"
+		   "xorl    %%edx, %%edx\n\t"
+		   "movl     %0,%%eax\n\t"
+		   "orl     $(0 | 6), %%eax\n\t"
+		   "wrmsr\n\t"
+
+		   "movl    $0x207, %%ecx\n\t"
+		   "xorl    %%edx, %%edx\n\t"
+		   "movl   $0x100000,%%eax\n\t"
+		   "decl                %%eax\n\t"
+		   "notl                %%eax\n\t"
+		   "orl    $(0 | 0x800), %%eax\n\t"
+		   "wrmsr\n\t"
+		   ::"g"(memtop1)
+		   );
+		   __asm__ volatile (       
+		   "movl    $0x208, %ecx\n\t"
+		   "xorl    %edx, %edx\n\t"
+		   "movl    $0,%eax\n\t"
+		   "orl     $(0 | 6), %eax\n\t"
+		   "wrmsr\n\t"
+
+		   "movl    $0x209, %ecx\n\t"
+		   "xorl    %edx, %edx\n\t"
+		   "movl     $0x100000,%eax\n\t"
+		   "decl                %eax\n\t"
+		   "notl                %eax\n\t"
+		   "orl     $(0 | 0x800), %eax\n\t"
+		   "wrmsr\n\t"
+		   );
+		 */
+		// WAKE_MEM_INFO is  inited in get_set_top_available_mem in tables.c
+		// these two memcpy not not be enabled if set the MTRR around this two lines.
+		/*__asm__ volatile (		
+	 			"movl    $0, %%esi\n\t"
+        "movl    %0, %%edi\n\t"
+       	"movl    $0xa0000, %%ecx\n\t"
+       	"shrl    $2, %%ecx\n\t"
+        "rep movsd\n\t"    
+        ::"g"(memtop3)        
+   	);
+	__asm__ volatile (		
+	 			"movl    $0xe0000, %%esi\n\t"
+        "movl    %0, %%edi\n\t"
+       	"movl    $0x20000, %%ecx\n\t"
+       	"shrl    $2, %%ecx\n\t"
+        "rep movsd\n\t"    
+        ::"g"(memtop4)        
+   	);*/
+		print_debug("copy memory to high memory to protect s3 wakeup vector code \r\n");	//this can have function call, because no variable used before this
+		memcpy((unsigned char *) ((*(u32 *) WAKE_MEM_INFO) -
+					  64 * 1024 - 0x100000),
+		       (unsigned char *) 0, 0xa0000);
+		memcpy((unsigned char *) ((*(u32 *) WAKE_MEM_INFO) -
+					  64 * 1024 - 0x100000 + 0xe0000),
+		       (unsigned char *) 0xe0000, 0x20000);
+
+		/* restore the MTRR previously modified. */
+/*		__asm__ volatile (	
+        "wbinvd\n\t"     			
+        "xorl    %edx, %edx\n\t"
+       	"xorl    %eax, %eax\n\t"
+       	"movl    $0x204, %ecx\n\t"
+        "wrmsr\n\t"
+	 			"movl    $0x205, %ecx\n\t"                                      
+        "wrmsr\n\t"        
+	 			"movl    $0x206, %ecx\n\t"
+        "wrmsr\n\t"
+	 			"movl    $0x207, %ecx\n\t"                     
+        "wrmsr\n\t"        
+	 			"movl    $0x208, %ecx\n\t"                     
+        "wrmsr\n\t"        
+	 			"movl    $0x209, %ecx\n\t"                     
+        "wrmsr\n\t"        
+		);*/
+	}
+#endif
+/*
+the following code is  copied from src\mainboard\tyan\s2735\cache_as_ram_auto.c
+Only the code around CLEAR_FIRST_1M_RAM is changed.
+I remove all the code around CLEAR_FIRST_1M_RAM and #include "cpu/x86/car/cache_as_ram_post.c"
+the CLEAR_FIRST_1M_RAM seems to make cpu/x86/car/cache_as_ram_post.c stop at somewhere, 
+and cpu/x86/car/cache_as_ram_post.c  do not cache my $XIP_ROM_BASE+SIZE area.
+
+So,I use: #include "cpu/via/car/cache_as_ram_post.c". my via-version post.c have some diff withx86-version
+*/
+#if 1
+	{
+		/* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
+		unsigned v_esp;
+		__asm__ volatile ("movl   %%esp, %0\n\t":"=a" (v_esp)
+		    );
+#if CONFIG_USE_INIT
+		printk_debug("v_esp=%08x\r\n", v_esp);
+#else
+		print_debug("v_esp=");
+		print_debug_hex32(v_esp);
+		print_debug("\r\n");
+#endif
+	}
+
+#endif
+#if 1
+
+      cpu_reset_x:
+// it seems that cpu_reset is not used before this, so I just reset it, (this is because the s3 resume, setting in mtrr and copy data may destroy 
+//stack
+	cpu_reset = 0;
+#if CONFIG_USE_INIT
+	printk_debug("cpu_reset = %08x\r\n", cpu_reset);
+#else
+	print_debug("cpu_reset = ");
+	print_debug_hex32(cpu_reset);
+	print_debug("\r\n");
+#endif
+
+	if (cpu_reset == 0) {
+		print_debug("Clearing initial memory region: ");
+	}
+	print_debug("No cache as ram now - ");
+
+	/* store cpu_reset to ebx */
+	__asm__ volatile ("movl %0, %%ebx\n\t"::"a" (cpu_reset)
+	    );
+
+
+/* cancel these lines, CLEAR_FIRST_1M_RAM cause the cpu/x86/car/cache_as_ram_post.c stop at somewhere
+
+	if(cpu_reset==0) {
+#define CLEAR_FIRST_1M_RAM 1
+#include "cpu/via/car/cache_as_ram_post.c"	
+	}
+	else {
+#undef CLEAR_FIRST_1M_RAM 
+#include "cpu/via/car/cache_as_ram_post.c"
+	}
+*/
+#include "cpu/via/car/cache_as_ram_post.c"
+//#include "cpu/x86/car/cache_as_ram_post.c"    
+	__asm__ volatile (
+				 /* set new esp *//* before _RAMBASE */
+				 "subl   %0, %%ebp\n\t"
+				 "subl   %0, %%esp\n\t"::
+				 "a" ((DCACHE_RAM_BASE + DCACHE_RAM_SIZE) -
+				      _RAMBASE)
+	    );
+
+	{
+		unsigned new_cpu_reset;
+
+		/* get back cpu_reset from ebx */
+		__asm__ volatile ("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");
+		} else {
+			print_debug("Use Ram as Stack now - \r\n");
+		}
+#if CONFIG_USE_INIT
+		printk_debug("new_cpu_reset = %08x\r\n", new_cpu_reset);
+#else
+		print_debug("new_cpu_reset = ");
+		print_debug_hex32(new_cpu_reset);
+		print_debug("\r\n");
+#endif
+		/*copy and execute coreboot_ram */
+		copy_and_run(new_cpu_reset);
+		/* We will not return */
+	}
+#endif
+
+
+	print_debug("should not be here -\r\n");
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/examples/chipset_init.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/examples/chipset_init.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/examples/chipset_init.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,1298 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#if HAVE_ACPI_RESUME == 1
+#include <arch/acpi.h>
+#endif
+#include <../northbridge/via/vx800/vx800.h>
+
+#include <arch/io.h>
+#include <arch/pci_rawops.h>
+
+static const struct VIA_PCI_REG_INIT_TABLE mSbStage1InitTbl[] = {
+	// Combine Stage1 registers
+	{0x00, 0xFF, SB_LPC_REG(0x41), 0x40, 0x40},
+
+	// Acpi init registers in sb stage1
+	{0x00, 0xFF, SB_LPC_REG(0x40), 0x04, 0x04},	// Enable 4D0/4D1 support
+	{0x00, 0xFF, SB_LPC_REG(0x4E), 0x00, 0x08},	// Enable RTC port 74/75
+	{0x00, 0xFF, SB_LPC_REG(0x51), 0x0D, 0x0D},	// and KBC
+	{0x00, 0xFF, SB_LPC_REG(0x52), 0x0F, 0x09},	// Enable Serial IRQ
+	{0x00, 0xFF, SB_LPC_REG(0x67), 0x00, 0x04},	// Set FERR voltage to 1.5v
+	{0x00, 0xFF, SB_LPC_REG(0x98), 0xFF, 0x00},	// Disable GP3 Timer
+
+	{0x00, 0xFF, SB_IDEC_REG(0xb9), 0x01, 0x01},
+
+	{0x00, 0xFF, SB_VLINK_REG(0xE6), 0xFF, 0x39},	// Enable SMM A-Seg, MSI and Io APIC
+	///// SPI-BAR.
+	//// SPI_BASE_ADDRESS = 0xFED1 0000
+	0x00, 0xFF, SB_LPC_REG(0xBC), 0xFF, 0x00,
+	0x00, 0xFF, SB_LPC_REG(0xBD), 0xFF, 0xD1,
+	0x00, 0xFF, SB_LPC_REG(0xBE), 0xFF, 0xFE,
+//      0x00, 0xFF, ((0x11<<16)|(0x00<<8)|0xBC), 0xFF, 0x00,//this , for the different macro
+//      0x00, 0xFF, ((0x11<<16)|(0x00<<8)|0xBD), 0xFF, 0xD1,
+//      0x00, 0xFF, ((0x11<<16)|(0x00<<8)|0xBE), 0xFF, 0xFE,
+	///// End of 2008-04-17
+
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+};
+
+static const struct VIA_PCI_REG_INIT_TABLE mNbStage2InitTable[] = {
+	// D0F0: AGP Feature. For 3353, No AGP Feature
+
+	// D0F2~D0F3 is configured by MemoryInit Peim
+
+	// D0F4: NB PMU
+	0x00, 0xFF, NB_PMU_REG(0x84), 0x00, 0xDB,
+	0x00, 0xFF, NB_PMU_REG(0x85), 0x00, 0x05,
+	0x00, 0xFF, NB_PMU_REG(0x89), 0x00, 0xF8,
+	0x00, 0xFF, NB_PMU_REG(0x8B), 0x00, 0xBF,
+	0x00, 0xFF, NB_PMU_REG(0x8D), 0x00, 0xFC,
+	0x00, 0xFF, NB_PMU_REG(0x8E), 0x00, 0x19,
+	0x00, 0xFF, NB_PMU_REG(0x8F), 0x03, 0x00,
+	0x00, 0xFF, NB_PMU_REG(0x90), 0x00, 0xFF,
+	0x00, 0xFF, NB_PMU_REG(0x91), 0x00, 0xFF,
+	0x00, 0xFF, NB_PMU_REG(0x92), 0x00, 0xCC,
+	0x00, 0xFF, NB_PMU_REG(0xA0), 0x00, 0x80,
+	0x00, 0xFF, NB_PMU_REG(0xA1), 0x00, 0xE0,
+	0x00, 0xFF, NB_PMU_REG(0xA2), 0x00, 0xD6,
+	0x00, 0xFF, NB_PMU_REG(0xA3), 0x00, 0x80,
+	0x00, 0xFF, NB_PMU_REG(0xA8), 0x00, 0x20,
+
+	// D0F5: NB APIC, PXPTRF and MSGC
+	//Note: the Rx6A, RCRBH Base Address, is not set, which is related to PCIE Root Complex.
+	//Note: the Rx60, Extended CFG Address. Support and Rx61, Extended CFG Address, are set by NB Peim that is in the PEI Phase.
+	//Note: the Rx42, APIC Interrupt((BT_INTR)) Control, is set by NB Peim that is in PEI phase.
+	0x00, 0xFF, NB_PXPTRF_REG(0x50), 0x00, 0x00,
+	0x00, 0xFF, NB_PXPTRF_REG(0x54), 0x00, 0x80,
+	0x00, 0xFF, NB_PXPTRF_REG(0x55), 0x00, 0x04,
+	0x00, 0xFF, NB_PXPTRF_REG(0x58), 0x00, 0x00,
+	0x00, 0xFF, NB_PXPTRF_REG(0x59), 0x00, 0x02,
+	0x00, 0xFF, NB_PXPTRF_REG(0x5E), 0x00, 0x00,
+	0x00, 0xFF, NB_PXPTRF_REG(0x5F), 0x00, 0x06,
+	0x00, 0xFF, NB_PXPTRF_REG(0x80), 0x00, 0x18,	//Set RVC1DM, RTHBHIT, RUWRDYD, RUPRRDY1, RUWPOPHD to 1.
+	0x00, 0xFF, NB_PXPTRF_REG(0x82), 0x00, 0x00,	//Set RVC1RPSW, RVC1RQ1T to 1.
+	0x00, 0xFF, NB_PXPTRF_REG(0x83), 0x00, 0x81,
+	0x00, 0xFF, NB_PXPTRF_REG(0x84), 0x00, 0x28,
+	0x00, 0xFF, NB_PXPTRF_REG(0x85), 0x00, 0xC0,
+	0x00, 0xFF, NB_MSGC_REG(0xA3), 0x00, 0x01,	// RWAKEEN
+//  0x00, 0xFF, NB_PXPTRF_REG(0x64), 0x40, 0x00, //RTDNP2B32EN 
+	0x00, 0xFF, NB_PXPTRF_REG(0xF3), 0xFC, 0x20,
+	0x00, 0xFF, NB_PXPTRF_REG(0x85), 0x00, 0x00,	//RP2P1ABORT
+
+
+// fine-tune 
+// If no settings, C7 will hang or reboot in XP, but CN will not.
+	0x00, 0xFF, NB_HOST_REG(0x51), 0x84, 0x00,
+	0x00, 0xFF, NB_HOST_REG(0x52), 0x0F, 0x03,
+	0x00, 0xFF, NB_HOST_REG(0x54), 0x04, 0x00,
+	0x00, 0xFF, NB_HOST_REG(0x55), 0x04, 0x00,
+	0x00, 0xFF, NB_HOST_REG(0x59), 0x09, 0x01,
+	0x00, 0xFF, NB_HOST_REG(0x5C), 0x10, 0x10,
+	0x00, 0xFF, NB_HOST_REG(0x5F), 0x0E, 0x08,
+	0x00, 0xFF, NB_HOST_REG(0x92), 0xFF, 0x04,	// ACPI Base addr
+	0x00, 0xFF, NB_HOST_REG(0x97), 0x01, 0x01,	// APIC MSI  
+	0x00, 0xFF, NB_HOST_REG(0x99), 0x02, 0x00,	// APIC MSI  
+	//GTL
+	0x00, 0xFF, NB_HOST_REG(0x73), 0xFF, 0x66,
+	0x00, 0xFF, NB_HOST_REG(0xB2), 0xFF, 0x33,
+	0x00, 0xFF, NB_HOST_REG(0xB3), 0xFF, 0x33,
+	0x00, 0xFF, NB_HOST_REG(0xBC), 0xFF, 0x33,
+	0x00, 0xFF, NB_HOST_REG(0xBD), 0xFF, 0x33,
+	0x00, 0xFF, NB_HOST_REG(0xC5), 0x30, 0x20,
+	0x00, 0xFF, NB_HOST_REG(0xC8), 0x10, 0x00,
+
+
+	// End of Table
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+
+};
+
+static const struct VIA_PCI_REG_INIT_TABLE mBusControllerInitTable[] = {
+	// D17F0: LPC
+	0x00, 0xFF, SB_LPC_REG(0x40), 0x44, 0x44,	//  Enable I/O Recovery Time,  4D0/4D1 Support
+	0x00, 0xFF, SB_LPC_REG(0x42), 0xF8, 0xF0,	//  ENLBUF, GINTREN, FLUSHEN, RBRSTRD
+	0x00, 0xFF, SB_LPC_REG(0x43), 0x0F, 0x0B,	//  RENDTX, ENWBTO, ENRBTO
+	//  0x00, 0xFF, SB_LPC_REG(0x46), 0x00, 0x10,     // It is related to INTH#
+	//0x00, 0xFF, SB_LPC_REG(0x48), 0x00, 0x0C,      //RMRPW, RIRPW  // Reserved in 409 by Eric
+
+	// Internal RTC, Mouse, Keyboard // set in PEI by Eric
+	//0x00, 0xFF, SB_LPC_REG(0x51), 0x10, 0x0D,      // Enable Internal RTC, Internal PS2 Mouse/Keyboard
+
+	// RTC
+	0x00, 0xFF, SB_LPC_REG(0x58), 0x00, 0x01,	//RTC Rx32 Map to Centrury Byte
+
+	// 0x00, 0xFF, SB_LPC_REG(0x40), 0x00, 0x02,    // RDMEGAS
+	//0x00, 0xFF, SB_LPC_REG(0x4E), 0x00, 0x08,  // Enable RTC port 74/75, ENEXRTC // set in PEI by Eric
+
+	// Serial IRQ  // set in PEI by Eric
+	//0x00, 0xFF, SB_LPC_REG(0x52), 0x0F, 0x09,    // Enable Serial IRQ, Start Frame Width is 6 PCI Clock.
+
+	// Enable 4D0h/4D1h Port
+	//0x00, 0xFF, SB_LPC_REG(0x40), 0x00, 0x04,    // EISAXT // set in PEI by Eric
+
+	// Config ROM Interface
+	// Enable SPI/Set SPI Memory Base Address
+	// It is initialized in PEI Phase
+
+	// Subsystem ID/Vendor ID Back Door
+	0x00, 0xFF, SB_LPC_REG(0x70), 0xFF, 0x06,
+	0x00, 0xFF, SB_LPC_REG(0x71), 0xFF, 0x11,
+	0x00, 0xFF, SB_LPC_REG(0x72), 0xFF, 0x09,
+	0x00, 0xFF, SB_LPC_REG(0x73), 0xFF, 0x34,
+
+	0x00, 0xFF, SB_LPC_REG(0x4C), 0xC0, 0x40,
+	0x00, 0xFF, SB_LPC_REG(0x5B), 0x00, 0x51,	// Orgin value 0x53, modify for 409 by Eric
+	0x00, 0xFF, SB_LPC_REG(0x67), 0x03, 0x01,
+
+
+	0x00, 0xFF, SB_LPC_REG(0x50), 0x7E, 0x00,	// Setting PCI device enable       
+	0x00, 0xFF, SB_LPC_REG(0x51), 0xD0, 0x00,	// Setting PCI device enable       
+	0x00, 0xFF, SB_VLINK_REG(0xD1), 0x04, 0x00,	// Setting HDAC enable      
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+};
+
+static const struct VIA_PCI_REG_INIT_TABLE mPCI1InitTable[] = {
+	//PCI1 Programming Sequence
+	//(1)Configure D17F7
+	0x00, 0xFF, SB_VLINK_REG(0x04), 0x00, 0x03,
+	0x00, 0xFF, SB_VLINK_REG(0x0C), 0x00, 0x08,	// Reserved in 409 by Eric
+	0x00, 0xFF, SB_VLINK_REG(0x4F), 0x40, 0x41,	//RENPPB, RP2CFLSH
+	0x00, 0xFF, SB_VLINK_REG(0x77), 0x00, 0x48,	//ROP2CFLSH, RFFTMR[1:0]. ROP2CFLSH work with Rx4F[0](RP2CFLSH) assertion
+	// 0x00, 0xFF, SB_VLINK_REG(0x51), 0x00, 0x80,      //RSUB_DEC_P2P, RSUBDECOD(Window xp). If Bit7 is set, PCI lock will occured.
+	//0x00, 0xFF, SB_VLINK_REG(0x51), 0x00, 0x81,      //RSUB_DEC_P2P, RSUBDECOD(Window Vista)
+	//(2)Configure D19F0
+	0x00, 0xFF, SB_P2PB_REG(0x04), 0x00, 0x07,
+
+	//(3)Performance Recommended Setting
+
+	//Save Power
+	0x00, 0xFF, SB_VLINK_REG(0xE2), 0x1F, 0x01,
+	0x00, 0xFF, SB_VLINK_REG(0xE3), 0xF1, 0x5E,
+	0x00, 0xFF, SB_VLINK_REG(0x74), 0x40, 0x00,
+	//Enhence Host To PCI cycle performance and PCI-To-Host Cycle performance
+	0x00, 0xFF, SB_VLINK_REG(0x70), 0x00, 0x82,
+	0x00, 0xFF, SB_VLINK_REG(0x71), 0x30, 0xC0,
+	0x00, 0xFF, SB_VLINK_REG(0x72), 0x00, 0xEE,
+
+	//Cycle Control
+	0x00, 0xFF, SB_VLINK_REG(0x73), 0x00, 0x01,
+	0x00, 0xFF, SB_VLINK_REG(0x74), 0x00, 0x0C,
+	//Arbitration control
+	0x00, 0xFF, SB_VLINK_REG(0x75), 0x00, 0x0F,
+	0x00, 0xFF, SB_VLINK_REG(0x76), 0x00, 0xD0,
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+};
+
+static const struct VIA_PCI_REG_INIT_TABLE mCCAInitTable[] = {
+
+	0x00, 0xFF, SB_VLINK_REG(0xFC), 0x02, 0x08,	//RVWREQ, ROABKDOOR
+
+	//CCA's Register Programming sequence
+	0x00, 0xFF, SB_VLINK_REG(0x50), 0x00, 0x08,	//Config Azalia's upstream cycle high priority and other low priority
+	0x00, 0xFF, SB_VLINK_REG(0x51), 0x40, 0x80,	//Disable bypass asynchronous circuit
+	0x00, 0xFF, SB_VLINK_REG(0x52), 0x00, 0x11,	// Set SM Internal Device and HDAC Occupy Timer
+	0x00, 0xFF, SB_VLINK_REG(0x53), 0x00, 0x11,	// Set SM Internal Device and HDAC Promote Timer
+	0x00, 0xFF, SB_VLINK_REG(0x54), 0xFF, 0x02,	//Use SB internal devices's original REQ
+	0x00, 0xFF, SB_VLINK_REG(0x73), 0x10, 0x00,	//RPINOWSC. Enable APIC Cycle Block P2C Write Cycle
+	0x00, 0xFF, SB_VLINK_REG(0x74), 0x00, 0x3C,	//RLCKXP2C, RFSBVK.
+	0x00, 0xFF, SB_VLINK_REG(0xE1), 0x07, 0x00,	//RBLKAPIC, RAZC3
+	0x00, 0xFF, SB_VLINK_REG(0x7C), 0x04, 0x02,	//RNMIFSB, RFSBVK
+	0x00, 0xFF, SB_VLINK_REG(0xE0), 0xF0, 0x90,	//RCCA_NEWCLK, RCCA_CLKON. Use New dynamic clock scheme
+	0x00, 0xFF, SB_VLINK_REG(0xE7), 0xFF, 0x00,	//Let CCA use dynamic clock.
+	//The CCA is also relate to D17F0
+	//    0x00, 0xFF, SB_LPC_REG(0x49), 0x1F, 0x00,       //Disable CCA Test Mode
+	0x00, 0xFF, SB_LPC_REG(0x74), 0xFF, 0x00,	// Let DMA cycles from internal devices directly go to NB // Reserved in 409 by Eric
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+};
+
+static const struct VIA_PCI_REG_INIT_TABLE IDEC_INIT[] = {
+
+	// 0x00, 0xFF, SB_IDEC_REG(0x09), 0x00, 0x05, //set to native mode
+	0x00, 0xFF, SB_IDEC_REG(0x04), 0x00, 0x07,
+	//0x00, 0xFF, SB_VLINK_REG(0x7C), 0x00, 0x7F,
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+
+};
+
+static const struct VIA_PCI_REG_INIT_TABLE mSbApicInitTable[] = {
+	0x00, 0xFF, SB_LPC_REG(0x4D), 0x04, 0x00,
+	0x00, 0xFF, SB_LPC_REG(0x5B), 0x0E, 0x00,
+	0x00, 0xFF, SB_LPC_REG(0x6C), 0x08, 0x00,
+	0x00, 0xFF, SB_LPC_REG(0x58), 0x00, 0x40,
+	0x00, 0xFF, SB_VLINK_REG(0x74), 0x00, 0x04,
+	//0x00, 0xFF, SB_VLINK_REG(0x7C), 0x00, 0x7F,
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+
+};
+
+
+
+void AcpiInit(void)
+{
+	device_t_raw rawdevice = 0;
+	u8 sbchiprev;
+	rawdevice = PCI_RAWDEV(0, 0x11, 0);
+	// Set the PMIO base io address 
+	pci_rawmodify_config16(rawdevice, 0x88, VX800_ACPI_IO_BASE,
+			       0xff80);
+	// Enable PMIO
+	pci_rawmodify_config16(rawdevice, 0x80, 0x8000, 0x8000);
+	// Enable Soft Resume
+	outw(inw(VX800_ACPI_IO_BASE + 0x04) | 0x8000,
+	     VX800_ACPI_IO_BASE + 0x04);
+
+	// Get SB Revision
+	sbchiprev = pci_rawread_config8(rawdevice, 0xf6);
+	printk_debug("SB chip revision =%x\n", sbchiprev);
+
+	// Fill Register Table
+	via_pci_inittable(sbchiprev, mSbStage1InitTbl);
+
+	// Close all SMI/Io Traps
+	outb(0x00, VX800_ACPI_IO_BASE + 0x42);
+
+}
+
+
+void Stage2NbInit(void)
+{
+	device_t_raw rawdevice = 0;
+	u8 nbchiprev;
+	u32 subid = 0;
+	rawdevice = PCI_RAWDEV(0, 0, 4);
+	nbchiprev = pci_rawread_config8(rawdevice, 0xf6);
+	printk_debug("NB chip revision =%x\n", nbchiprev);
+
+	via_pci_inittable(nbchiprev, mNbStage2InitTable);
+
+	rawdevice = PCI_RAWDEV(0, 0, 0);
+
+	subid = PCI_DEVICE_ID_VIA_VX855_D0F0 << 16 + PCI_VENDOR_ID_VIA;
+	pci_rawwrite_config32(rawdevice, 0x2C, subid);
+
+	//vx855 NB no pcie bus
+	//vx855 NB no apic
+
+}
+
+void IDECSupportOption(u8 sbchiprev)
+{
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0, 0x08);
+
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0xf, 0), 0x45, 0x00, 0x80);
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0xf, 0), 0x0A, 0x01, 0xFF);
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0xf, 0), 0x45, 0x80, 0x00);
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0xf, 0), 0x40, 0x02, 0x00);
+
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0xf, 0), 0x09, 0x00, 0x05);	//COMPATIBLE MODE 
+//      pci_rawmodify_config8(PCI_RAWDEV(0, 0xf, 0), 0x09, 0x05, 0x05);//native MODE 
+
+	via_pci_inittable(sbchiprev, IDEC_INIT);
+}
+
+void InitIDEC(u8 sbchiprev)
+{
+	IDECSupportOption(sbchiprev);
+}
+
+
+void InitUHCI(u8 Number, u8 bEnable)
+{
+	u8 Mask, Value;
+	u16 D16;
+	u8 BaseAddress;
+	u8 BitShift;
+	// USB Device 16
+	// Function : Number
+	//         0      :      0
+	//         1      :      1
+	//         2      :      2
+	// The BitShift is got from Datasheet.
+
+	switch (Number) {
+	case 0:
+		BaseAddress = 0;
+		BitShift = 4;
+		break;
+	case 1:
+		BaseAddress = 1;
+		BitShift = 5;
+		break;
+	case 2:
+	default:
+		BaseAddress = 2;
+		BitShift = 2;
+		break;
+	}
+
+	if (bEnable) {
+		Mask = 0x1 << BitShift;
+		Value = 0x0;
+	} else {
+		Mask = 0x0;
+		Value = 0x1 << BitShift;
+	}
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, Value, Mask);
+
+
+	if (bEnable) {
+		D16 = 0;
+		pci_rawwrite_config16(PCI_RAWDEV(0, 0x10, BaseAddress),
+				      0x20, D16);
+
+		// Config some Control Register
+		Mask = 0x00;
+		Value = 0x12;
+
+		pci_rawmodify_config8(PCI_RAWDEV(0, 0x10, BaseAddress),
+				      0x41, Value, Mask);
+		Mask = 0x00;
+		Value = 0xEB;
+		pci_rawmodify_config8(PCI_RAWDEV(0, 0x10, BaseAddress),
+				      0x4B, Value, Mask);
+	}
+	return;
+}
+
+static const struct VIA_PCI_REG_INIT_TABLE mEHCIInitTable[] = {
+	//EHCI
+	0x00, 0xFF, SB_EHCI_REG(0x43), 0x00, 0xC0,
+	0x00, 0xFF, SB_EHCI_REG(0x50), 0x00, 0x80,
+	0x00, 0xFF, SB_EHCI_REG(0x48), 0x20, 0x9E,
+	0x00, 0xFF, SB_EHCI_REG(0x49), 0x10, 0x68,
+	0x00, 0xFF, SB_EHCI_REG(0x4B), 0x00, 0x69,
+	0x00, 0xFF, SB_EHCI_REG(0x4D), 0x00, 0x94,
+	0x00, 0xFF, SB_EHCI_REG(0x52), 0x08, 0x00,
+	0x00, 0xFF, SB_EHCI_REG(0x5A), 0x00, 0x8A,
+	0x00, 0xFF, SB_EHCI_REG(0x5B), 0x00, 0x89,
+	0x00, 0xFF, SB_EHCI_REG(0x5C), 0x00, 0x03,
+	0x00, 0xFF, SB_EHCI_REG(0x5D), 0x00, 0x9A,
+	0x00, 0xFF, SB_EHCI_REG(0x5E), 0x00, 0x00,
+	0x00, 0xFF, SB_EHCI_REG(0x6B), 0x00, 0x00,
+	0x00, 0xFF, SB_EHCI_REG(0x6D), 0x00, 0x00,
+	0x00, 0xFF, SB_EHCI_REG(0x6F), 0xF0, 0x00,
+	0x00, 0xFF, SB_EHCI_REG(0x4E), 0x01, 0x01,
+	0x00, 0xFF, SB_EHCI_REG(0x4F), 0x00, 0x11,
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table
+
+};
+
+void InitEHCI(u8 Number, u8 bEnable)
+{
+	u8 Mask, Value;
+	u8 EHCIRevision;
+
+	if (bEnable) {
+		Mask = 0x1 << 1;
+		Value = 0x0;
+	} else {
+		Mask = 0x0;
+		Value = 0x1 << 1;
+	}
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, Value, Mask);
+
+
+	if (bEnable) {
+		// Get Chipset Revision
+		EHCIRevision =
+		    pci_rawread_config8(PCI_RAWDEV(0, 0x10, 4), 0xF6);
+		printk_debug("EHCI Revision =%x\n", EHCIRevision);
+		via_pci_inittable(EHCIRevision, mEHCIInitTable);
+	}
+}
+
+#define TRUE  1
+void InitUSBC(u8 sbchiprev)
+{
+	InitUHCI(0, TRUE);
+	InitUHCI(1, TRUE);
+	InitUHCI(2, TRUE);
+	InitEHCI(0, TRUE);
+}
+
+void WriteSbApicIndexedReg(u8 Idx, u32 Data)
+{
+	u32 Data32;
+	u32 ApicIdxAdr = VX800SB_APIC_BASE;
+	u32 ApicDataAdr = VX800SB_APIC_BASE + VX800SB_APIC_DATA_OFFSET;
+	*((u8 *) ApicIdxAdr) = Idx;
+	Data32 = (*((u32 *) ApicDataAdr));	//this read is needed when write APIC ID ,dont know why.
+	Data32 = Data;
+	*((u32 *) ApicDataAdr) = Data32;
+}
+
+void SbApicMmioRegInit(void)
+{
+	u32 Offset;
+	WriteSbApicIndexedReg(3, 1);
+	WriteSbApicIndexedReg(0, 4);
+	for (Offset = 0x10; Offset < VX800SB_APIC_ENTRY_NUMBER;
+	     Offset += 2) {
+		WriteSbApicIndexedReg(Offset + 1, 0);
+		WriteSbApicIndexedReg(Offset, 0x10000);
+	}
+}
+
+void SbApicInit(u8 sbchiprev)
+{
+	via_pci_inittable(sbchiprev, mSbApicInitTable);
+	SbApicMmioRegInit();
+}
+
+void SbAcpiInit(void)
+{
+	u8 Mask, Value;
+	// Enable ACPI
+	Mask = 0x01;
+	Value = 0x01;
+	io_rawmodify_config8(VX800_ACPI_IO_BASE + 0x04, Value, Mask);
+}
+
+#define HPET_ENABLE_BIT			0x80
+#define R_SB_HPET_CONTROL		0x68
+#define HPET_BASE_ADDRESS		0xFED0	// 0xFED00000
+#define R_SB_HPET_ADDRESS		0x69
+
+void HpetInit(void)
+{
+	u8 HpetEnable = HPET_ENABLE_BIT;
+	u16 HpetBase = HPET_BASE_ADDRESS;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), R_SB_HPET_CONTROL,
+			     HpetEnable);
+	pci_rawwrite_config16(PCI_RAWDEV(0, 0x11, 0),
+			      R_SB_HPET_ADDRESS + 1, HpetBase);
+}
+
+static const struct VIA_PCI_REG_INIT_TABLE mPMUInitTable[] = {
+	// Power Management
+	0x00, 0xFF, SB_LPC_REG(0x80), 0x00, 0x20,
+	0x00, 0xFF, SB_LPC_REG(0x8C), 0x02, 0x00,
+	0x00, 0xFF, SB_LPC_REG(0x8D), 0x00, 0x18,
+
+	//Miscellaneous Configuration 1
+	0x00, 0xFF, SB_LPC_REG(0x94), 0xF0, 0x28,
+	0x00, 0xFF, SB_LPC_REG(0x95), 0x00, 0xC1,
+	0x00, 0xFF, SB_LPC_REG(0x96), 0xFF, 0x10,
+	0x00, 0xFF, SB_LPC_REG(0x97), 0x00, 0xB2,
+
+	//Voltage Change Function Enable
+	0x00, 0xFF, SB_LPC_REG(0x9F), 0x00, 0x21,
+	//Internal PCIe and NM PLL Control
+	0x00, 0xFF, SB_LPC_REG(0xE2), 0x00, 0xEA,
+
+	0x00, 0xFF, SB_LPC_REG(0xE7), 0x00, 0x80,
+	{0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},	// End of Table   
+};
+
+void InitPMU(u8 sbchiprev)
+{
+	u8 Mask, Value;
+	// Set PMU Registers
+	via_pci_inittable(sbchiprev, mPMUInitTable);
+
+
+	// Set SCI IRQ and its level trigger
+	Mask = 0x0F;
+	Value = 0x09;
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x82, Value, Mask);
+
+	Mask = 0x02;
+	Value = 0x02;
+	io_rawmodify_config8(0x4d1, Value, Mask);
+}
+
+#define R_SB_MULTI_FUNCTION_SELECT_1  0xE4
+#define R_SB_CX_STATE_BREAK_EVENT_ENABLE_1  0xE6
+#define PMIO_PROCESSOR_CONTROL  0x26
+#define R_SB_PCI_ARBITRATION_2      0x76
+#define R_SB_AUTO_SWITCH_P_STATE        0x8A
+
+void InitCPUCStatueSupport()
+{
+	u8 Mask, Value;
+
+	// Config Cx State
+	// Now it is C2 & C4 Up Down Mode
+	Mask = 0xFF;
+	Value = 0x30;
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), R_SB_CX_STATE_BREAK_EVENT_ENABLE_1, Value, Mask);	//SB_LPC_REG
+
+	Mask = 0xFF;
+	Value = 0x1F;
+	io_rawmodify_config8(VX800_ACPI_IO_BASE + PMIO_PROCESSOR_CONTROL,
+			     Value, Mask);
+
+	Mask = 0x00;
+	Value = 0x80;
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 7), R_SB_PCI_ARBITRATION_2, Value, Mask);	//SB_VLINK_REG
+
+	Mask = 0xFF;
+	Value = 0x00;
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), R_SB_MULTI_FUNCTION_SELECT_1, Value, Mask);	//SB_VLINK_REG
+
+	Mask = 0xFF;
+	Value = 0x1F;
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), R_SB_AUTO_SWITCH_P_STATE, Value, Mask);	//SB_VLINK_REG
+}
+
+void InitSBPM(u8 sbchiprev)
+{
+	InitPMU(sbchiprev);
+	SbAcpiInit();
+	InitCPUCStatueSupport();
+}
+
+void Stage2SbInit(void)
+{
+	device_t_raw rawdevice = 0;
+	u8 sbchiprev;
+
+	rawdevice = PCI_RAWDEV(0, 11, 0);
+	sbchiprev = pci_rawread_config8(rawdevice, 0xf6);
+	printk_debug("SB chip revision =%x\n", sbchiprev);
+
+	//SBBasicInit
+	via_pci_inittable(sbchiprev, mBusControllerInitTable);
+	via_pci_inittable(sbchiprev, mPCI1InitTable);
+	via_pci_inittable(sbchiprev, mCCAInitTable);
+
+
+	InitIDEC(sbchiprev);
+
+	InitUSBC(sbchiprev);
+
+	InitSBPM(sbchiprev);
+
+	SbApicInit(sbchiprev);
+
+	HpetInit();
+
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x76, 0);//SB_VLINK_REG
+
+}
+
+
+void init_VIA_chipset(void)
+{
+	printk_debug("In: init_VIA_chipset\n");
+	//1.nbstage1 is done in raminit. 
+	//2.sbstage1 
+	AcpiInit();
+	//3.nbstage2
+	Stage2NbInit();
+
+	//4.sbstage2
+	Stage2SbInit();
+
+	//5.open hdac
+	pci_rawmodify_config32(PCI_RAWDEV(0, 0x11, 7), 0xd1, 0, 0x04);
+	printk_debug("End: init_VIA_chipset\n");
+}
+
+/**
+ * @brief Main function of the DRAM part of coreboot.
+ *
+ * Coreboot is divided into Pre-DRAM part and DRAM part. 
+ *
+ * 
+ * Device Enumeration:
+ *	In the dev_enumerate() phase, 
+ */
+
+void hardwaremain(int boot_complete)
+{
+	struct lb_memory *lb_mem;
+#if HAVE_ACPI_RESUME == 1
+	void *wake_vec;
+#endif
+
+	u16 tmp;
+	tmp = inw(VX800_ACPI_IO_BASE + 0x04);
+	acpi_sleep_type = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0;
+
+	u8 y, x;
+	init_VIA_chipset();
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+#if 0
+
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 4), 0xa3, 0x80);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 17, 7), 0x60, 0x20);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 17, 7), 0xE5,
+			     pci_rawread_config8(PCI_RAWDEV(0, 3, 0),
+						 0x88));
+#endif
+
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x51, 0x40, 0x40);	//close CE-ATA (Consumer Electronics-ATA) and NFC
+
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x0, 0x40);//open USB Device Mode Enable 
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x40, 0x40);	//close USB Device Mode
+
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x04, 0x04);//close USB 1.1 UHCI Port 4-5
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x02, 0x02);//close USB 2.0 ehci
+
+
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x00, 0x76);//open all usb and usb mode
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x50, 0x76, 0x76);//close all usb
+
+	printk_info("=================SB 50h=%02x \n",
+		    pci_rawread_config8(PCI_RAWDEV(0, 0x11, 0), 0x50));
+
+
+	/* FIXME: Is there a better way to handle this? */
+	init_timer();
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+	/* Find the devices we don't have hard coded knowledge about. */
+	dev_enumerate();
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+#if 0
+	x = y = 0;
+	printk_info("dump ehci3 \n");
+	for (; x < 16; x++) {
+		y = 0;
+		for (; y < 16; y++) {
+			printk_info("%02x ",
+				    pci_rawread_config8(PCI_RAWDEV
+							(0, 0x10, 4),
+							x * 16 + y));
+		}
+		printk_info("\n");
+	}
+#endif
+
+	post_code(0x66);
+	/* Now compute and assign the bus resources. */
+	dev_configure();
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+#if 0
+	x = y = 0;
+	printk_info("dump ehci3 \n");
+	for (; x < 16; x++) {
+		y = 0;
+		for (; y < 16; y++) {
+			printk_info("%02x ",
+				    pci_rawread_config8(PCI_RAWDEV
+							(0, 0x10, 4),
+							x * 16 + y));
+		}
+		printk_info("\n");
+	}
+#endif
+
+	post_code(0x88);
+	/* Now actually enable devices on the bus */
+	dev_enable();
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+	/* And of course initialize devices on the bus */
+#if 0
+	x = y = 0;
+	printk_info("dump ehci3 \n");
+	for (; x < 16; x++) {
+		y = 0;
+		for (; y < 16; y++) {
+			printk_info("%02x ",
+				    pci_rawread_config8(PCI_RAWDEV
+							(0, 0x10, 4),
+							x * 16 + y));
+		}
+		printk_info("\n");
+	}
+#endif
+
+	dev_initialize();
+	post_code(0x89);
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+
+//          pci_rawwrite_config16(PCI_RAWDEV(0, 0xf, 0), 0xBA, 0x0571);
+
+#if 0
+	x = y = 0;
+	printk_info("dump ehci3 \n");
+	for (; x < 16; x++) {
+		y = 0;
+		for (; y < 16; y++) {
+			printk_info("%02x ",
+				    pci_rawread_config8(PCI_RAWDEV
+							(0, 0x10, 4),
+							x * 16 + y));
+		}
+		printk_info("\n");
+	}
+#endif
+
+
+#if 0
+
+	y = pci_rawread_config8(PCI_RAWDEV(0, 0xf, 0), 0x0d);
+	y &= 0x0f;
+	y |= 0x40;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0xf, 0), 0x0d, y);
+#endif
+
+#if 0
+
+
+	static const d0f0pcitable[5] = { 0xD0, 0, 0, 0, 0xFD };
+	static const d0f2pcitable[16 * 7 + 1] = {
+		0x88, 0xF8, 0xEF, 0x44, 0x7C, 0x24, 0x63, 0x01, 0x00, 0x09,
+		    0x00, 0x00, 0x10, 0xA2, 0x88, 0xCE,
+		0xFF, 0x0F, 0x00, 0xAA, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xCC, 0x66, 0xAA, 0x55, 0x30, 0x38, 0x0C, 0x00, 0x00, 0x00,
+		    0x00, 0x22, 0x00, 0xAA, 0x00, 0x00,
+		0x44, 0x44, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x0B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x41, 0x06,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x88, 0x56, 0x70, 0x77, 0x77, 0x07, 0x77, 0x77, 0x04,
+		    0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+		0x77, 0x77, 0x33, 0x33, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+		    0x77, 0x77, 0x44, 0x44, 0x14, 0x00,
+		0x75
+	};
+
+	static const d0f4pcitable[16 * 6 + 3] = {
+		0x30, 0x00, 0x00,
+		0xFF, 0xFF, 0xCC, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x80, 0xE0, 0xD6, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 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, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x00, 0x00, 0x04, 0x04,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x08, 0xF4,
+		    0x01, 0x01, 0x79, 0x79, 0x0A, 0x00,
+	};
+	static const d0f5pcitable[16 * 10] = {
+		0x13, 0x0E, 0x00, 0x00, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x18, 0x9A, 0x00, 0x81, 0x28, 0xC0, 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, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x26, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	};
+
+	static const d0f7pcitable[16 * 9] = {
+		0x00, 0x2A, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 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, 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, 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, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x29, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	};
+	static const d1f0pcitable[3] = {
+		0x01, 0x80, 0x40
+	};
+
+	static const dcf0pcitable[96] = {
+		0x10, 0x00, 0x00, 0x00, 0x01, 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, 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, 0x00,
+		0x01, 0x00, 0xC2, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+		    0x40, 0x01, 0x03, 0x01, 0x7E, 0x01,
+		0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9,
+		    0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+	};
+
+	static const d10f4pcitable[48] = {
+		0x00, 0x20, 0x43, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x68,
+		    0x00, 0x09, 0x13, 0x94, 0x03, 0x10,
+		0x80, 0x60, 0x11, 0xBF, 0x00, 0xFF, 0x0F, 0x00, 0x04, 0x0B,
+		    0xCC, 0xCC, 0x00, 0xCC, 0x00, 0x00,
+		0x20, 0x20, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00,
+		    0x00, 0x00, 0x00, 0x20, 0x00, 0xC0,
+	};
+
+	static const d11f0pcitable[16 * 12] = {
+		0x44, 0x40, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20,
+		    0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
+		0xC1, 0x4D, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+		    0x00, 0x51, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00,
+		    0xD0, 0xFE, 0x00, 0x00, 0x00, 0x00,
+		0x06, 0x11, 0x09, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+		0x20, 0x84, 0x49, 0x00, 0x88, 0x00, 0x00, 0x00, 0x01, 0x08,
+		    0x1F, 0x00, 0x07, 0x1A, 0x00, 0x00,
+		0x00, 0x6E, 0xBC, 0x88, 0x28, 0xC1, 0x10, 0x80, 0x00, 0x80,
+		    0x20, 0x88, 0x00, 0x00, 0x00, 0xAD,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+		    0x00, 0x00, 0x10, 0xD0, 0xFE, 0x90,
+		0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0xE7, 0x03, 0xA0, 0x60, 0x20, 0xC0, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	};
+
+	static const d11f7pcitable[192] = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
+		0x08, 0x80, 0x11, 0x11, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x80, 0x00, 0x00, 0x20, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x82, 0xC8, 0xEE, 0x01, 0x0C, 0x0F, 0xD0, 0x48, 0x00, 0x00,
+		    0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+		0x07, 0x00, 0x21, 0x00, 0x0C, 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, 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, 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, 0x00, 0x00, 0x00, 0x00,
+		0x93, 0x08, 0x00, 0x5E, 0x00, 0x80, 0x29, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
+	};
+
+
+#define OPTION_1 1
+#define NOOPTION_1 1
+#ifdef OPTION_1
+	static const OPTION_1_d11f0pcitable[16 * 12] = {
+		0x44, 0x80, 0xf0, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20,
+		    0x00, 0x00, 0x04, 0x01, 0x08, 0x00,
+		0xc0, 0x4d, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+		    0x00, 0x53, 0x00, 0xfe, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x80, 0x00,
+		    0xd0, 0xfe, 0x00, 0x00, 0xdf, 0x00,
+		0x06, 0x11, 0x53, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x20, 0x84, 0x4a, 0x00, 0xda, 0x40, 0x00, 0x00, 0x01, 0x40,
+		    0x1f, 0x00, 0x07, 0x18, 0x00, 0x00,
+		0x00, 0x2e, 0xbc, 0x00, 0x28, 0xc1, 0x10, 0x80, 0x00, 0x80,
+		    0x08, 0x88, 0x00, 0x00, 0x00, 0xad,
+		0x06, 0x11, 0x53, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x40,
+		    0x00, 0x00, 0x00, 0xd3, 0xfe, 0x53,
+		0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0xeb, 0x03, 0xa0, 0x60, 0x20, 0x80, 0x00, 0x00,
+		    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		    0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	};
+#endif
+
+
+
+	u8 i;
+/* error form ---- but add the chance to resume
+for(i=0;i<5;i++){
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 0), i, d0f0pcitable[i+0xcb]);
+	}
+
+	
+*/
+
+/* RO reg
+for(i=0;i<5;i++){
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 0), i+0xcb, d0f0pcitable[i]);
+	}
+*/
+
+
+//boot ok, resume still err in linux    
+#if 1
+	for (i = 0; i < 9; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), i + 0x50,
+				     d0f2pcitable[i]);
+	}
+	//9 is warm reset reg,   // boot err in coreboot
+	for (i = 10; i < 64; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), i + 0x50,
+				     d0f2pcitable[i]);
+	}
+	//0x90 look d0f2 appendixA1 ,   if set this to 09 or 0b, then some ddr2 will crash.
+	for (i = 65; i < 113; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), i + 0x50,
+				     d0f2pcitable[i]);
+	}
+#endif
+#ifdef OPTION_1
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), 0x66, 0x09);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), 0x70, 0xdd);
+	//  pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), 0x90, 0x09);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 2), 0x92, 0x40);
+
+#endif
+
+
+
+#if 1
+
+
+//d0f3 
+/*		*/
+	//      pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0x86, 0x3b);  setting, my lspci is 0x29
+	//set bit4 cause the ide not be found
+//              pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0x86, 0x2b);
+	//set bit1 cause the ide not be found
+
+//              pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0x86, 0x29);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0x95, 0x05);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0x99, 0x12);
+
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 3), 0xde, 0x00);
+#endif
+
+//boot ok,  resume err in coreboot 
+#if 1
+	for (i = 0; i < 99; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 4), i + 0x8d,
+				     d0f4pcitable[i]);
+	}
+#endif
+
+#ifdef OPTION_1
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 4), 0xe9, 0x90);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 4), 0xec, 0x0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 4), 0xed, 0x0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 4), 0xee, 0x0);
+#endif
+
+
+#if 1
+//boot ok, resume still err in linux    
+	for (i = 0; i < 160; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 5), i + 0x60,
+				     d0f5pcitable[i]);
+	}
+	for (i = 0; i < 144; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0, 7), i + 0x60,
+				     d0f7pcitable[i]);
+	}
+	for (i = 0; i < 3; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 1, 0), i + 0xb0,
+				     d1f0pcitable[i]);
+	}
+	for (i = 0; i < 96; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0xc, 0), i + 0x40,
+				     dcf0pcitable[i]);
+	}
+#endif
+
+#ifdef OPTION_1
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 7), 0x61, 0x0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 7), 0x63, 0x0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0, 7), 0x76, 0xd0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0xc, 0), 0x88, 0x81);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0xc, 0), 0x89, 0x01);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0xc, 0), 0x8A, 0x60);
+#endif
+
+//d15f0
+
+
+
+
+#if 1
+
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 0), 0x4a, 0xa2);	// no affect.
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 1), 0x4a, 0xa2);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 2), 0x4a, 0xa2);
+
+//boot ok, resume still err in linux,  and if disable USB, then all ok
+//      for(i=0;i<48;i++){
+	for (i = 0; i < 44; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 4), i + 0x40,
+				     d10f4pcitable[i]);
+	}
+#endif
+
+//#ifdef NOOPTION_1
+#if 0
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 4), 0x6b, 0x01);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 4), 0x6d, 0x00);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 4), 0x6e, 0x08);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x10, 4), 0x6f, 0x80);
+#endif
+
+
+
+#if 1
+//before (11.0)is add, s3 resume has already always dead in first resume(more frequenly), and sleep ok
+//      for(i=0;i<192;i++){
+	for (i = 0; i < 6; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+	//6 is uart and dvp vcp,   will have // HAVE no com1 ,and no gui show,textmode ok ,s3 sleep ok, resume fail
+
+	//7-18 is my familar part
+	for (i = 7; i < 18; i++) {	//sleep ok ,resume sleep err 2 
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+
+
+	for (i = 18; i < 21; i++) {	//sleep ok ,   sleep err 1, resume 
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+	//0x55 56 57 irq intA#B#C# linkA#linkB#linkC#
+	for (i = 24; i < 27; i++) {	//sleep ok , resume sleep err 1  resume  1
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+	//5b port 80h
+	pci_rawmodify_config8(PCI_RAWDEV(0, 0x11, 0), 0x5b, 0x0, 0x08);
+	//          i++;
+	//      pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i+0x40, d11f0pcitable[i]);
+
+	for (i = 28; i < 72; i++) {	//sleep ok , resume  sleep err 1 , resume 1ci
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+	//7273ACPI BASE
+
+	for (i = 74; i < 112; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+
+	//B0B4B5 dvp vcp,  if copy this ,then no uart, no gui(of unbuntu)
+	// pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), 0xb0, d11f0pcitable[112]);
+	i = pci_rawread_config8(PCI_RAWDEV(0, 17, 0), 0xB0);
+	//multiplex with VCP
+	//    i = i | 0x30;
+	i = i & 0xf7;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 17, 0), 0xB0, i);
+
+
+
+	for (i = 113; i < 114; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+
+	for (i = 115; i < 116; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+
+
+	for (i = 118; i < 192; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+#endif
+#ifdef NOOPTION_1
+//      for(i=0;i<192;i++){
+	for (i = 0; i < 6; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+	//6 is uart and dvp vcp,   will have // HAVE no com1 ,and no gui show,textmode ok ,s3 sleep ok, resume fail
+
+	//7-18 is my familar part
+	for (i = 7; i < 18; i++) {	//   sleep err 2
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+
+	for (i = 18; i < 21; i++) {	//sleep ok , resume ???
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+	//0x55 56 57 irq intA#B#C# linkA#linkB#linkC#
+	for (i = 24; i < 27; i++) {	//sleep ok , resume ???
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     d11f0pcitable[i]);
+	}
+	//5b port 80h
+	i++;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+			     OPTION_1_d11f0pcitable[i]);
+
+	for (i = 28; i < 72; i++) {	//sleep ok , resume???
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+	//7273ACPI BASE
+
+	for (i = 74; i < 112; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+
+	//B0B4B5 dvp vcp,  if copy this ,then no uart, no gui(of unbuntu)
+	// pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), 0xb0, OPTION_1_d11f0pcitable[112]);
+	i = pci_rawread_config8(PCI_RAWDEV(0, 17, 0), 0xB0);
+	//multiplex with VCP
+	//    i = i | 0x30;
+	i = i & 0xf7;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 17, 0), 0xB0, i);
+
+
+
+	for (i = 113; i < 114; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+
+	for (i = 115; i < 116; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+
+	for (i = 118; i < 192; i++) {	//boot ok, resume still err in linux
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), i + 0x40,
+				     OPTION_1_d11f0pcitable[i]);
+	}
+#endif
+
+#if 1
+	pci_rawwrite_config16(PCI_RAWDEV(0, 0xf, 0), 0xBA, PCI_DEVICE_ID_VIA_VX855_IDE);	//5324
+	pci_rawwrite_config16(PCI_RAWDEV(0, 0xf, 0), 0xBE,
+			      PCI_DEVICE_ID_VIA_VX855_IDE);
+	pci_rawwrite_config16(PCI_RAWDEV(0, 0x11, 0), 0xA0,
+			      PCI_VENDOR_ID_VIA);
+	pci_rawwrite_config16(PCI_RAWDEV(0, 0x11, 0), 0xA2, PCI_DEVICE_ID_VIA_VX855_LPC);	//8353
+	i = pci_rawread_config8(PCI_RAWDEV(0, 0x11, 0), 0x79);
+	i &= ~0x40;
+	i |= 0x40;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 0), 0x79, i);
+	pci_rawwrite_config16(PCI_RAWDEV(0, 0x11, 0), 0x72,
+			      PCI_DEVICE_ID_VIA_VX855_LPC);
+
+
+//boot ok, resume still err in linux
+	for (i = 0; i < 192; i++) {
+		pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), i + 0x40,
+				     d11f7pcitable[i]);
+	}
+#endif
+#ifdef OPTION_1
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), 0x61, 0x2a);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), 0x63, 0xa0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), 0x64, 0xaa);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), 0x84, 0x0);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), 0x88, 0x02);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x11, 7), 0xe6, 0x3f);
+#endif
+
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x14, 0), 0x40, 0x20);
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x14, 0), 0x41, 0x31);
+
+
+
+#ifdef OPTION_1
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x14, 0), 0x40, 0x00);
+#endif
+
+
+#endif
+
+	u8 i911;
+	//disable CHB L.L
+	//set VGA memory selection
+	i911 = pci_rawread_config8(PCI_RAWDEV(0, 0x1, 0), 0xb0);
+	i911 &= 0xF8;
+	//ByteVal |= 0x03;
+	i911 |= 0x01;
+	pci_rawwrite_config8(PCI_RAWDEV(0, 0x1, 0), 0xb0, i911);
+
+
+#if 1
+	struct device *dev;
+	printk_info("=========zjldump all  devices...\n");
+	for (dev = all_devices; dev; dev = dev->next) {
+		if (dev->path.type == DEVICE_PATH_PCI) {
+			printk_debug("%s dump\n", dev_path(dev));
+			x = y = 0;
+			for (; x < 16; x++) {
+				y = 0;
+				for (; y < 16; y++) {
+					printk_info("%02x ",
+						    pci_read_config8(dev,
+								     x *
+								     16 +
+								     y));
+				}
+				printk_info("\n");
+			}
+
+		}
+		printk_info("\n");
+	}
+#endif
+
+
+
+
+	//pci_rawmodify_config8(PCI_RAWDEV(0, 0x10, 4), 0x04, 0x17, 0x17);//
+//      pci_rawmodify_config8(PCI_RAWDEV(0, 0x10, 4), 0x0c, 0x08, 0xff);///
+
+
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,247 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+    part of this file is from cx700 port, part of is from cn700 port,
+   */
+
+#include <console/console.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bitops.h>
+#include <cpu/cpu.h>
+#include "chip.h"
+#include "northbridge.h"
+#include "vx800.h"
+
+static void memctrl_init(device_t dev)
+{
+/*
+  set VGA in UMARamSetting.c, not in this function.
+*/
+#if 0
+	pci_write_config8(dev, 0x85, 0x20);
+	pci_write_config8(dev, 0x86, 0x2d);
+
+	/* Set up VGA timers */
+	pci_write_config8(dev, 0xa2, 0x44);
+
+	/* Enable VGA with a 32mb framebuffer */
+	pci_write_config16(dev, 0xa0, 0xd000);
+
+	pci_write_config16(dev, 0xa4, 0x0010);
+
+	//b0: 60 aa aa 5a 0f 00 00 00 08
+	pci_write_config16(dev, 0xb0, 0xaa00);
+	pci_write_config8(dev, 0xb8, 0x08);
+#endif
+}
+
+static const struct device_operations memctrl_operations = {
+	.read_resources = vx800_noop,
+	.init = memctrl_init,
+};
+
+static const struct pci_driver memctrl_driver __pci_driver = {
+	.ops = &memctrl_operations,
+	.vendor = PCI_VENDOR_ID_VIA,
+	.device = PCI_DEVICE_ID_VIA_VX855_MEMCTRL,
+};
+
+static void pci_domain_read_resources(device_t dev)
+{
+	struct resource *resource;
+
+	printk_spew("Entering vx800 pci_domain_read_resources.\n");
+
+	/* Initialize the system wide io space constraints */
+	resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+	resource->limit = 0xffffUL;
+	resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+	    IORESOURCE_ASSIGNED;
+
+	/* Initialize the system wide memory resources constraints */
+	resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+	resource->limit = 0xffffffffULL;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+	    IORESOURCE_ASSIGNED;
+
+	printk_spew("Leaving vx800 pci_domain_read_resources.\n");
+}
+
+static void ram_resource(device_t dev, unsigned long index,
+			 unsigned long basek, unsigned long sizek)
+{
+	struct resource *resource;
+
+	if (!sizek) {
+		return;
+	}
+	resource = new_resource(dev, index);
+	resource->base = ((resource_t) basek) << 10;
+	resource->size = ((resource_t) sizek) << 10;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE |
+	    IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+static void tolm_test(void *gp, struct device *dev, struct resource *new)
+{
+	struct resource **best_p = gp;
+	struct resource *best;
+	best = *best_p;
+	if (!best || (best->base > new->base)) {
+		best = new;
+	}
+	*best_p = best;
+}
+
+static u32 find_pci_tolm(struct bus *bus)
+{
+	print_debug("Entering find_pci_tolm\n");
+	struct resource *min;
+	u32 tolm;
+	min = 0;
+	search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM,
+			     tolm_test, &min);
+	tolm = 0xffffffffUL;
+	if (min && tolm > min->base) {
+		tolm = min->base;
+	}
+	print_debug("Leaving find_pci_tolm\n");
+	return tolm;
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+	/* 
+	 * the order is important to find the correct ram size.
+	 */
+	u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
+	device_t mc_dev;
+	u32 pci_tolm;
+	u8 reg;
+
+	printk_spew("Entering vx800 pci_domain_set_resources.\n");
+
+	pci_tolm = find_pci_tolm(&dev->link[0]);
+	mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
+				 PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
+
+	if (mc_dev) {
+		unsigned long tomk, tolmk;
+		unsigned char rambits;
+		u8 i, idx;
+
+		/*
+		 * once the register value is not zero, the ramsize is
+		 * this register's value multiply 64 * 1024 * 1024
+		 */
+		for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
+			unsigned char reg;
+			rambits = pci_read_config8(mc_dev, ramregs[i]);
+			if (rambits != 0)
+				break;
+		}
+/*
+Get memory size and frame buffer from northbridge's registers.
+if register with invalid value we set frame buffer size to 32M for default, but it won't happen.
+*/
+		reg = pci_read_config8(mc_dev, 0xa1);
+		reg &= 0x70;
+		reg = reg >> 4;
+		/* TOP 1M SM Memory */
+		if (reg == 0x0)
+			tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024);	// Set frame buffer 32M for default
+		else
+			tomk =
+			    (((rambits << 6) - (4 << reg) -
+			      VIACONFIG_TOP_SM_SIZE_MB) * 1024);
+
+		printk_spew("tomk is 0x%x\n", tomk);
+		/* Compute the Top Of Low Memory, in Kb */
+		tolmk = pci_tolm >> 10;
+		if (tolmk >= tomk) {
+			/* The PCI hole does does not overlap the memory. */
+			tolmk = tomk;
+		}
+		/* Report the memory regions */
+		idx = 10;
+		/* TODO: Hole needed? */
+		ram_resource(dev, idx++, 0, 640);	/* first 640k */
+		/* Leave a hole for vga, 0xa0000 - 0xc0000 */
+		ram_resource(dev, idx++, 768, (tolmk - 768));
+	}
+	assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+	printk_debug("Entering vx800 pci_domain_scan_bus.\n");
+
+	max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+	return max;
+}
+
+static const struct device_operations pci_domain_ops = {
+	.read_resources = pci_domain_read_resources,
+	.set_resources = pci_domain_set_resources,
+	.enable_resources = enable_childrens_resources,
+	.init = 0,
+	.scan_bus = pci_domain_scan_bus,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+	initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static const struct device_operations cpu_bus_ops = {
+	.read_resources = cpu_bus_noop,
+	.set_resources = cpu_bus_noop,
+	.enable_resources = cpu_bus_noop,
+	.init = cpu_bus_init,
+	.scan_bus = 0,
+};
+
+static void enable_dev(struct device *dev)
+{
+	printk_spew("In VX800 enable_dev for device %s.\n", dev_path(dev));
+
+	/* Set the operations if it is a special bus type */
+	if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+		dev->ops = &pci_domain_ops;
+		pci_set_method(dev);
+	} else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+		dev->ops = &cpu_bus_ops;
+	}
+}
+
+struct chip_operations northbridge_via_vx800_ops = {
+	CHIP_NAME("VIA VX800 Chipset")
+	    .enable_dev = enable_dev,
+};

Added: trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/northbridge.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef NORTHBRIDGE_VIA_VX800_H
+#define NORTHBRIDGE_VIA_VX800_H
+
+extern unsigned int vx800_scan_root_bus(device_t root, unsigned int max);
+
+#endif /* NORTHBRIDGE_VIA_VX800_H */

Added: trunk/coreboot-v2/src/northbridge/via/vx800/raminit.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/raminit.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/raminit.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <spd.h>
+#include <sdram_mode.h>
+#include <delay.h>
+#include <arch/pci_rawops.h>
+
+#define DEBUG_RAM_SETUP 1
+
+
+#ifdef DEBUG_RAM_SETUP
+#define PRINT_DEBUG_MEM(x)		print_debug(x)
+#define PRINT_DEBUG_MEM_HEX8(x)		print_debug_hex8(x)
+#define PRINT_DEBUG_MEM_HEX16(x)	print_debug_hex16(x)
+#define PRINT_DEBUG_MEM_HEX32(x)	print_debug_hex32(x)
+#define DUMPNORTH()			dump_pci_device(PCI_DEV(0, 0, 0))
+#else
+#define PRINT_DEBUG_MEM(x)
+#define PRINT_DEBUG_MEM_HEX8(x)
+#define PRINT_DEBUG_MEM_HEX16(x)
+#define PRINT_DEBUG_MEM_HEX32(x)
+#define DUMPNORTH()
+#endif
+#include "northbridge/via/vx800/ddr2init/Translatorddr2init.c"
+#include "northbridge/via/vx800/ddr2init/DramInit.h"
+#include "northbridge/via/vx800/vx800_early_smbus.c"
+#include "northbridge/via/vx800/vx800_early_serial.c"
+#include "northbridge/via/vx800/ddr2init/DramUtil.h"
+#include "northbridge/via/vx800/ddr2init/DramUtil.c"
+#include "northbridge/via/vx800/ddr2init/vx800/Detection.c"
+#include "northbridge/via/vx800/ddr2init/vx800/FreqSetting.c"
+#include "northbridge/via/vx800/ddr2init/vx800/TimingSetting.c"
+#include "northbridge/via/vx800/ddr2init/vx800/DRDY_BL.c"
+#include "northbridge/via/vx800/ddr2init/vx800/DrivingSetting.c"
+#include "northbridge/via/vx800/ddr2init/vx800/ClkCtrl.c"
+#include "northbridge/via/vx800/ddr2init/vx800/DevInit.c"
+#include "northbridge/via/vx800/ddr2init/vx800/RankMap.c"
+#include "northbridge/via/vx800/ddr2init/vx800/DQSSearch.c"
+#include "northbridge/via/vx800/ddr2init/vx800/FinalSetting.c"
+#include "northbridge/via/vx800/ddr2init/vx800/UMARamSetting.c"
+#include "northbridge/via/vx800/ddr2init/DramInit.c"
+/*
+ * Support one dimm with up to 2 ranks
+ */
+
+static void ddr2_ram_setup()
+{
+	u8 Data;
+	CB_STATUS Status;
+	PRINT_DEBUG_MEM("In ddr2_ram_setup\r");
+
+	Status = DDR2_DRAM_INIT();
+	if (CB_SUCCESS != Status) {
+		PRINT_DEBUG_MEM("Dram init error. Status = %x\r");
+	}
+
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/raminit.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/raminit.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/raminit.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef RAMINIT_H
+#define RAMINIT_H
+
+#define MEMCTRL	PCI_DEV(0,0,3)
+#endif /* RAMINIT_H */

Added: trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.inc
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.inc	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.inc	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * (Written by Yinghai Lu <yhlu at tyan.com> for Tyan Computer)
+ * Copyright (C) 2007 Rudolf Marek <r.marek at assembler.cz>
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* This file constructs the ROM strap table for K8T890 and K8M890 */
+
+	.section ".romstrap", "a", @progbits
+
+	.globl __romstrap_start
+__romstrap_start:
+tblpointer:
+	.long 0x55aa66cc
+	.long 0x88012554
+	.long 0x77107777
+	.long 0x00770814
+
+
+	.long 0x00000000
+	.long 0x00000000
+	.long 0x00000000
+	.long 0x00000000
+
+/*
+ * The pointer to above table should be at 0xffffffd0,
+ * the table itself MUST be aligned to 128B it seems!
+ */
+rspointers:
+	.long tblpointer				// It will be 0xffffffd0
+
+	.globl __romstrap_end
+
+__romstrap_end:
+.previous

Added: trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.lds
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.lds	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/romstrap.lds	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 AMD
+ * (Written by Yinghai Lu <yinghai.lu at amd.com> for AMD)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+SECTIONS {
+	. = (_ROMBASE + ROM_IMAGE_SIZE - 0x2c) - (__romstrap_end - __romstrap_start);
+	.romstrap (.): {
+		*(.romstrap)
+	}
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vga.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vga.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vga.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,148 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* Note: Some of the VGA control registers are located on the memory controller.
+   Registers are set both in raminit.c and northbridge.c */
+
+#include <console/console.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bitops.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include "chip.h"
+#include "northbridge.h"
+#include "vgachip.h"
+
+/* PCI Domain 1 Device 0 Function 0 */
+
+#define SR_INDEX	0x3c4
+#define SR_DATA		0x3c5
+#define CRTM_INDEX	0x3b4
+#define CRTM_DATA	0x3b5
+#define CRTC_INDEX	0x3d4
+#define CRTC_DATA	0x3d5
+
+void write_protect_vgabios(void)
+{
+	device_t dev;
+
+	printk_info("write_protect_vgabios\n");
+	/* there are two possible devices. Just do both. */
+	dev =
+	    dev_find_device(PCI_VENDOR_ID_VIA,
+			    PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
+	if (dev)
+		pci_write_config8(dev, 0x80, 0xff);
+	/*vx855 no th 0x61 reg */
+	/*dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_NB_VLINK, 0);
+	   //if(dev)
+	   //   pci_write_config8(dev, 0x61, 0xff); */
+}
+
+extern u8 acpi_sleep_type;
+static void vga_init(device_t dev)
+{
+	uint8_t reg8;
+
+	print_debug("Initiailizing VGA...\n");
+	u8 tmp8;
+//A20 OPEN
+	tmp8 = inb(0x92);
+	tmp8 = tmp8 | 2;
+	outb(tmp8, 0x92);
+
+	//*
+	//pci_write_config8(dev, 0x04, 0x07);
+	//pci_write_config32(dev,0x10, 0xa0000008);
+	//pci_write_config32(dev,0x14, 0xdd000000);
+	pci_write_config32(dev, 0x10, VIACONFIG_VGA_PCI_10);
+	pci_write_config32(dev, 0x14, VIACONFIG_VGA_PCI_14);
+	pci_write_config8(dev, 0x3c, 0x0a);	//same with vx855_lpc.c
+	//*/
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+
+#if 1
+	printk_debug("INSTALL REAL-MODE IDT\n");
+	setup_realmode_idt();
+	printk_debug("DO THE VGA BIOS\n");
+
+	do_vgabios();
+	if ((acpi_sleep_type == 3) || (PAYLOAD_IS_SEABIOS == 0)) {
+		printk_debug("Enable VGA console\n");
+		// remove this function since in cn700 it is said "VGA seems to work without this, but crash & burn with it"
+		//but the existense of  vga_enable_console()  seems do not hurt my coreboot. XP+ubuntu s3 can resume with and without this function.
+		//and remove it also do not help my s3 problem: desktop screen have some thin black line, after resuming back to win.
+		vga_enable_console();
+	}
+#else
+/* Attempt to manually force the rom to load */
+	printk_debug("Forcing rom load\r\n");
+	pci_rom_load(dev, 0xfff80000);
+	run_bios(dev, 0xc0000);
+#endif
+	if ((acpi_sleep_type == 3) || (PAYLOAD_IS_SEABIOS == 0)) {
+		/* It's not clear if these need to be programmed before or after
+		 * the VGA bios runs. Try both, clean up later */
+		/* Set memory rate to 200MHz */
+		outb(0x3d, CRTM_INDEX);
+		reg8 = inb(CRTM_DATA);
+		reg8 &= 0x0f;
+		reg8 |= (0x3 << 4);
+		outb(0x3d, CRTM_INDEX);
+		outb(reg8, CRTM_DATA);
+
+		/* Set framebuffer size to CONFIG_VIDEO_MB mb */
+		/*reg8 = (CONFIG_VIDEO_MB/4);
+		   outb(0x39, SR_INDEX);
+		   outb(reg8, SR_DATA); */
+	}
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+}
+
+static void vga_read_resources(device_t dev)
+{
+	dev->rom_address = (void *) (0xffffffff - FULL_ROM_SIZE + 1);
+	dev->on_mainboard = 1;
+	pci_dev_read_resources(dev);
+}
+
+
+static struct device_operations vga_operations = {
+	.read_resources = vga_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = vga_init,
+	.ops_pci = 0,
+};
+
+
+static const struct pci_driver vga_driver __pci_driver = {
+	.ops = &vga_operations,
+	.vendor = PCI_VENDOR_ID_VIA,
+	.device = PCI_DEVICE_ID_VIA_VX855_VGA,
+};

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vgabios.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vgabios.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vgabios.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,862 @@
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#undef __KERNEL__
+#include <arch/io.h>
+#include <string.h>
+#include "vgachip.h"
+
+
+/* vgabios.c. Derived from: */
+
+/*------------------------------------------------------------ -*- C -*-
+ *  2 Kernel Monte a.k.a. Linux loading Linux on x86
+ *
+ *  Erik Arjan Hendriks <hendriks at lanl.gov>
+ *
+ *  This version is a derivative of the original two kernel monte
+ *  which is (C) 2000 Scyld.
+ *
+ *  Copyright (C) 2000 Scyld Computing Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Portions related to the alpha architecture are:
+ *
+ *  Copyright(C) 2001 University of California.  LA-CC Number 01-67.
+ *  This software has been authored by an employee or employees of the
+ *  University of California, operator of the Los Alamos National
+ *  Laboratory under Contract No.  W-7405-ENG-36 with the U.S.
+ *  Department of Energy.  The U.S. Government has rights to use,
+ *  reproduce, and distribute this software. If the software is
+ *  modified to produce derivative works, such modified software should
+ *  be clearly marked, so as not to confuse it with the version
+ *  available from LANL.
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by
+ *  reference to http://www.gnu.org/licenses/gpl.html.
+ *
+ *  This software is provided by the author(s) "as is" and any express
+ *  or implied warranties, including, but not limited to, the implied
+ *  warranties of merchantability and fitness for a particular purpose
+ *  are disclaimed.  In no event shall the author(s) be liable for any
+ *  direct, indirect, incidental, special, exemplary, or consequential
+ *  damages (including, but not limited to, procurement of substitute
+ *  goods or services; loss of use, data, or profits; or business
+ *  interruption) however caused and on any theory of liability,
+ *  whether in contract, strict liability, or tort (including
+ *  negligence or otherwise) arising in any way out of the use of this
+ *  software, even if advised of the possibility of such damage.
+ *
+ *  $Id: vgabios.c,v 1.5 2004/10/06 17:33:52 rminnich Exp $
+ *--------------------------------------------------------------------*/
+
+/* Modified to be a self sufficient plug in so that it can be used 
+   without reliance on other parts of coreboot's core
+   (C) 2005 Nick.Barker9 at btinternet.com
+
+  Used initially for epia-m where there are problems getting the bios
+  emulator to successfully run this bios.
+*/
+/* Declare a temporary global descriptor table - necessary because the
+   Core part of the bios no longer sets up any 16 bit segments */
+__asm__(
+	       /* pointer to original gdt */
+	       "gdtarg:			\n"
+	       "	.word	gdt_limit	\n"
+	       "	.long	gdt	       	\n"
+	       /* compute the table limit */
+	       "__mygdt_limit = __mygdt_end - __mygdt - 1	\n"
+	       "__mygdtaddr:			\n"
+	       "	.word	__mygdt_limit  	\n"
+	       "	.long	__mygdt	       	\n"
+	       "__mygdt: 		       	\n"
+	       /* selgdt 0, unused */
+	       "	.word	0x0000, 0x0000	\n"
+	       "	.byte	0x00, 0x00, 0x00, 0x00	\n"
+	       /* selgdt 8, unused */
+	       "	.word	0x0000, 0x0000	       	\n"
+	       "	.byte	0x00, 0x00, 0x00, 0x00	\n"
+	       /* selgdt 0x10, flat code segment */
+	       "	.word	0xffff, 0x0000	       	\n"
+	       "	.byte	0x00, 0x9b, 0xcf, 0x00	\n"
+	       /* selgdt 0x18, flat data segment */
+	       "	.word	0xffff, 0x0000	       	\n"
+	       "	.byte	0x00, 0x93, 0xcf, 0x00	\n"
+	       /* selgdt 0x20, unused */
+	       "	.word	0x0000, 0x0000	       	\n"
+	       "	.byte	0x00, 0x00, 0x00, 0x00	\n"
+	       /* selgdt 0x28 16-bit 64k code at 0x00000000 */
+	       "	.word	0xffff, 0x0000	       	\n"
+	       "	.byte	0, 0x9a, 0, 0	       	\n"
+	       /* selgdt 0x30 16-bit 64k data at 0x00000000 */
+	       "	.word	0xffff, 0x0000	       	\n"
+	       "	.byte	0, 0x92, 0, 0	       	\n"
+	       "__mygdt_end:				\n");
+
+/* Declare a pointer to where our idt is going to be i.e. at mem zero */
+__asm__("__myidt:		\n"
+	/* 16-bit limit */
+	"	.word 1023	\n"
+	/* 24-bit base */
+	"	.long 0		\n" "	.word 0		\n");
+
+/* The address arguments to this function are PHYSICAL ADDRESSES */
+extern u8 acpi_sleep_type;
+
+static void real_mode_switch_call_vga(unsigned long devfn)
+{
+	if ((acpi_sleep_type == 0) && (PAYLOAD_IS_SEABIOS == 1))
+		return;
+	__asm__ __volatile__(
+				    // paranoia -- does ecx get saved? not sure. This is 
+				    // the easiest safe thing to do.
+				    "	pushal			\n"
+				    /* save the stack */
+				    "	mov 	%esp, __stack	\n"
+				    "	jmp 	1f		\n"
+				    "__stack: .long 0		\n" "1:\n"
+				    /* get devfn into %ecx */
+				    "	movl    %esp, %ebp	\n"
+				    "	movl    8(%ebp), %ecx	\n"
+				    /* load 'our' gdt */
+				    "	lgdt	%cs:__mygdtaddr	\n"
+				    /*  This configures CS properly for real mode. */
+				    "	ljmp	$0x28, $__rms_16bit\n"
+				    "__rms_16bit:		  	\n"
+				    "	.code16			\n"
+				    /* 16 bit code from here on... */
+				    /* Load the segment registers w/ properly configured segment
+				     * descriptors.  They will retain these configurations (limits,
+				     * writability, etc.) once protected mode is turned off. */
+				    "	mov	$0x30, %ax	\n"
+				    "	mov	%ax, %ds       	\n"
+				    "	mov	%ax, %es       	\n"
+				    "	mov	%ax, %fs       	\n"
+				    "	mov	%ax, %gs       	\n"
+				    "	mov	%ax, %ss       	\n"
+				    /* Turn off protection (bit 0 in CR0) */
+				    "	movl	%cr0, %eax	\n"
+				    "	andl	$0xFFFFFFFE, %eax \n"
+				    "	movl	%eax, %cr0	\n"
+				    /* Now really going into real mode */
+				    "	ljmp	$0,  $__rms_real\n"
+				    "__rms_real:			\n"
+				    /* put the stack at the end of page zero. 
+				     * that way we can easily share it between real and protected, 
+				     * since the 16-bit ESP at segment 0 will work for any case. 
+				     /* Setup a stack */
+				    "	mov	$0x0, %ax	\n"
+				    "	mov	%ax, %ss	\n"
+				    "	movl	$0x1000, %eax	\n"
+				    "	movl	%eax, %esp	\n"
+				    /* Load our 16 it idt */
+				    "	xor	%ax, %ax	\n"
+				    "	mov	%ax, %ds	\n"
+				    "	lidt	__myidt		\n"
+				    /* Dump zeros in the other segregs */
+				    "	mov	%ax, %es       	\n"
+				    "	mov	%ax, %fs       	\n"
+				    "	mov	%ax, %gs       	\n"
+				    "	mov	$0x40, %ax	\n"
+				    "	mov	%ax, %ds	\n"
+				    "	mov	%cx, %ax	\n"
+				    /* run VGA BIOS at 0xc000:0003 */
+				    "	lcall	$0xc000, $0x0003\n"
+				    /* if we got here, just about done. 
+				     * Need to get back to protected mode */
+				    "	movl	%cr0, %eax	\n" "	orl	$0x0000001, %eax\n"	/* PE = 1 */
+				    "	movl	%eax, %cr0	\n"
+				    /* Now that we are in protected mode jump to a 32 bit code segment. */
+				    "	data32	ljmp	$0x10, $vgarestart\n"
+				    "vgarestart:\n"
+				    "	.code32\n"
+				    "	movw	$0x18, %ax     	\n"
+				    "	mov	%ax, %ds       	\n"
+				    "	mov	%ax, %es	\n"
+				    "	mov	%ax, %fs	\n"
+				    "	mov	%ax, %gs	\n"
+				    "	mov	%ax, %ss	\n"
+				    /* restore proper gdt and idt */
+				    "	lgdt	%cs:gdtarg	\n"
+				    "	lidt	idtarg		\n"
+				    ".globl vga_exit		\n"
+				    "vga_exit:			\n"
+				    "	mov	__stack, %esp	\n"
+				    "	popal			\n");
+}
+
+__asm__(".text\n" "real_mode_switch_end:\n");
+extern char real_mode_switch_end[];
+
+/* call vga bios int 10 function 0x4f14 to enable main console 
+   epia-m does not always autosence the main console so forcing it on is good !! */
+void vga_enable_console()
+{
+	if ((acpi_sleep_type == 0) && (PAYLOAD_IS_SEABIOS == 1))
+		return;
+	__asm__ __volatile__(
+				    /* paranoia -- does ecx get saved? not sure. This is 
+				     * the easiest safe thing to do. */
+				    "	pushal			\n"
+				    /* save the stack */
+				    "	mov	%esp, __stack	\n"
+				    /* load 'our' gdt */
+				    "	lgdt 	%cs:__mygdtaddr	\n"
+				    /*  This configures CS properly for real mode. */
+				    "	ljmp 	$0x28, $__vga_ec_16bit\n"
+				    "__vga_ec_16bit:		\n"
+				    "	.code16			\n"
+				    /* 16 bit code from here on... */
+				    /* Load the segment registers w/ properly configured segment
+				     * descriptors.  They will retain these configurations (limits,
+				     * writability, etc.) once protected mode is turned off. */
+				    "	mov	$0x30, %ax     	\n"
+				    "	mov	%ax, %ds       	\n"
+				    "	mov	%ax, %es       	\n"
+				    "	mov	%ax, %fs       	\n"
+				    "	mov	%ax, %gs       	\n"
+				    "	mov	%ax, %ss       	\n"
+				    /* Turn off protection (bit 0 in CR0) */
+				    "	movl	%cr0, %eax     	\n"
+				    "	andl	$0xFFFFFFFE, %eax\n"
+				    "	movl	%eax, %cr0     	\n"
+				    /* Now really going into real mode */
+				    "	ljmp	$0, $__vga_ec_real \n"
+				    "__vga_ec_real:                  \n"
+				    /* put the stack at the end of page zero. 
+				     * that way we can easily share it between real and protected, 
+				     * since the 16-bit ESP at segment 0 will work for any case. 
+				     /* Setup a stack */
+				    "	mov	$0x0, %ax	\n"
+				    "	mov	%ax, %ss	\n"
+				    "	movl	$0x1000, %eax	\n"
+				    "	movl	%eax, %esp	\n"
+				    /* debugging for RGM */
+				    "	mov	$0x11, %al	\n"
+				    "	outb	%al, $0x80	\n"
+				    /* Load our 16 it idt */
+				    "	xor	%ax, %ax       	\n"
+				    "	mov	%ax, %ds	\n"
+				    "	lidt	__myidt		\n"
+				    /* Dump zeros in the other segregs */
+				    "	mov	%ax, %ds	\n"
+				    "	mov	%ax, %es	\n"
+				    "	mov	%ax, %fs	\n"
+				    "	mov	%ax, %gs	\n"
+				    /* ask bios to enable main console */
+				    /* set up for int 10 call - values found from X server
+				     * bios call routines */
+				    "	movw	$0x4f14,%ax	\n"
+				    "	movw	$0x8003,%bx	\n"
+				    "	movw	$1, %cx		\n"
+				    "	movw	$0, %dx		\n"
+				    "	movw	$0, %di		\n"
+				    "	int	$0x10		\n"
+				    "	movb	$0x55, %al	\n"
+				    "	outb	%al, $0x80	\n"
+				    /* if we got here, just about done. 
+				     * Need to get back to protected mode */
+				    "	movl	%cr0, %eax	\n" "	orl	$0x0000001, %eax\n"	/* PE = 1 */
+				    "	movl	%eax, %cr0	\n"
+				    /* Now that we are in protected mode jump to a 32 bit code segment. */
+				    "	data32	ljmp	$0x10, $vga_ec_restart\n"
+				    "vga_ec_restart:\n"
+				    "	.code32\n"
+				    "	movw	$0x18, %ax	\n"
+				    "	mov	%ax, %ds	\n"
+				    "	mov	%ax, %es	\n"
+				    "	mov	%ax, %fs	\n"
+				    "	mov	%ax, %gs	\n"
+				    "	mov	%ax, %ss	\n"
+				    /* restore proper gdt and idt */
+				    "	lgdt	%cs:gdtarg 	\n"
+				    "	lidt	idtarg		\n"
+				    "	.globl	vga__ec_exit	\n"
+				    "vga_ec_exit:\n"
+				    "	mov	__stack, %esp	\n"
+				    "	popal\n");
+}
+
+void do_vgabios(void)
+{
+	device_t dev;
+	unsigned long busdevfn;
+	unsigned int rom = 0;
+	unsigned char *buf;
+	unsigned int size = 64 * 1024;
+	int i;
+	u16 tmp;
+	u8 tmp8;
+
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+	/* clear vga bios data area */
+	for (i = 0x400; i < 0x500; i++) {
+		*(unsigned char *) i = 0;
+	}
+
+	dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
+
+	if (!dev) {
+		printk_debug("NO VGA FOUND\n");
+		return;
+	}
+	printk_debug("found VGA: vid=%x, did=%x\n", dev->vendor,
+		     dev->device);
+
+	/* declare rom address here - keep any config data out of the way
+	 * of core LXB stuff */
+
+	rom = 0xffffffff - FULL_ROM_SIZE + 1;
+	pci_write_config32(dev, PCI_ROM_ADDRESS, rom | 1);
+	printk_debug("rom base: %x\n", rom);
+	buf = (unsigned char *) rom;
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+	if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
+		memcpy((void *) 0xc0000, buf, size);
+
+
+		printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+		write_protect_vgabios();	// in northbridge
+
+		// check signature again
+		buf = (unsigned char *) 0xc0000;
+		if (buf[0] == 0x55 && buf[1] == 0xAA) {
+			busdevfn =
+			    (dev->bus->secondary << 8) | dev->path.pci.
+			    devfn;
+			printk_debug("bus/devfn = %#x\n", busdevfn);
+			real_mode_switch_call_vga(busdevfn);
+		} else
+			printk_debug
+			    ("Failed to copy VGA BIOS to 0xc0000\n");
+	} else
+		printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
+
+	printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__);
+
+	pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
+}
+
+
+// we had hoped to avoid this. 
+// this is a stub IDT only. It's main purpose is to ignore calls 
+// to the BIOS. 
+// no longer. Dammit. We have to respond to these.
+struct realidt {
+	unsigned short offset, cs;
+};
+
+// from a handy writeup that andrey found.
+
+// handler. 
+// There are some assumptions we can make here. 
+// First, the Top Of Stack (TOS) is located on the top of page zero. 
+// we can share this stack between real and protected mode. 
+// that simplifies a lot of things ...
+// we'll just push all the registers on the stack as longwords, 
+// and pop to protected mode. 
+// second, since this only ever runs as part of coreboot, 
+// we know all the segment register values -- so we don't save any.
+// keep the handler that calls things small. It can do a call to 
+// more complex code in coreboot itself. This helps a lot as we don't
+// have to do address fixup in this little stub, and calls are absolute
+// so the handler is relocatable.
+void handler(void)
+{
+	__asm__ __volatile__("	.code16		\n"
+			     "idthandle:		\n"
+			     "	pushal		\n"
+			     "	movb 	$0, %al	\n"
+			     "	ljmp 	$0, $callbiosint16\n"
+			     "end_idthandle:		\n"
+			     "	.code32		\n");
+}
+
+void debughandler(void)
+{
+	__asm__ __volatile__("	.code16		\n"
+			     "debughandle:		\n"
+			     "	pushw	%cx	\n"
+			     "	movw	$250, %cx \n"
+			     "dbh1:			\n"
+			     "	loop	dbh1	\n"
+			     "	popw	%cx	\n"
+			     "	iret		\n"
+			     "end_debughandle:	\n"
+			     ".code32		\n");
+}
+
+// Calling conventions. The first C function is called with this stuff
+// on the stack. They look like value parameters, but note that if you
+// modify them they will go back to the INTx function modified. 
+// the C function will call the biosint function with these as
+// REFERENCE parameters. In this way, we can easily get 
+// returns back to the INTx caller (i.e. vgabios)
+void callbiosint(void)
+{
+	__asm__ __volatile__("	.code16		\n"
+			     "callbiosint16:		\n"
+			     "	push	%ds	\n"
+			     "	push	%es	\n"
+			     "	push	%fs	\n" "	push	%gs	\n"
+			     // clean up the int #. To save space we put it in the lower
+			     // byte. But the top 24 bits are junk. 
+			     "	andl	$0xff, %eax\n"
+			     // this push does two things:
+			     // - put the INT # on the stack as a parameter
+			     // - provides us with a temp for the %cr0 mods.
+			     "	pushl	%eax	\n" "	movl    %cr0, %eax\n" "	orl	$0x00000001, %eax\n"	/* PE = 1 */
+			     "	movl	%eax, %cr0\n"
+			     /* Now that we are in protected mode jump to a 32 bit code segment. */
+			     "	data32  ljmp    $0x10, $biosprotect\n"
+			     "biosprotect:		\n"
+			     "	.code32		\n"
+			     "	movw	$0x18, %ax          \n"
+			     "	mov	%ax, %ds          \n"
+			     "	mov	%ax, %es          \n"
+			     "	mov	%ax, %fs          \n"
+			     "	mov	%ax, %gs          \n"
+			     "	mov	%ax, %ss          \n"
+			     "	lidt	idtarg         \n"
+			     "	call	biosint	\n"
+			     // back to real mode ...
+			     "	ljmp	$0x28, $__rms_16bit2\n"
+			     "__rms_16bit2:			\n"
+			     "	.code16			\n"
+			     /* 16 bit code from here on... */
+			     /* Load the segment registers w/ properly configured segment
+			      * descriptors.  They will retain these configurations (limits,
+			      * writability, etc.) once protected mode is turned off. */
+			     "	mov	$0x30, %ax	\n"
+			     "	mov	%ax, %ds	\n"
+			     "	mov	%ax, %es	\n"
+			     "	mov	%ax, %fs	\n"
+			     "	mov	%ax, %gs	\n"
+			     "	mov	%ax, %ss	\n"
+			     /* Turn off protection (bit 0 in CR0) */
+			     "	movl	%cr0, %eax		\n"
+			     "	andl	$0xFFFFFFFE, %eax	\n"
+			     "	movl	%eax, %cr0		\n"
+			     /* Now really going into real mode */
+			     "	ljmp $0,  $__rms_real2	\n"
+			     "__rms_real2:			\n"
+			     /* Setup a stack
+			      * FixME: where is esp? */
+			     "	mov	$0x0, %ax       \n"
+			     "	mov	%ax, %ss	\n"
+			     /* ebugging for RGM */
+			     "	mov	$0x11, %al	\n"
+			     "	outb	%al, $0x80	\n"
+			     /* Load our 16 it idt */
+			     "	xor	%ax, %ax	\n"
+			     "	mov	%ax, %ds	\n"
+			     "	lidt	__myidt		\n"
+			     /* Dump zeros in the other segregs */
+			     "	mov	%ax, %es	\n"
+			     "	mov	%ax, %fs	\n"
+			     "	mov	%ax, %gs	\n"
+			     "	mov	$0x40, %ax	\n"
+			     "	mov	%ax, %ds	\n"
+			     /* pop the INT # that you pushed earlier */
+			     "	popl	%eax		\n"
+			     "	pop	%gs		\n"
+			     "	pop	%fs		\n"
+			     "	pop	%es		\n"
+			     "	pop	%ds		\n"
+			     "	popal			\n"
+			     "	iret			\n"
+			     "	.code32			\n");
+}
+
+enum {
+	PCIBIOS = 0x1a,
+	MEMSIZE = 0x12
+};
+
+int pcibios(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
+	    unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
+	    unsigned long *pecx, unsigned long *peax,
+	    unsigned long *pflags);
+
+int handleint21(unsigned long *pedi, unsigned long *pesi,
+		unsigned long *pebp, unsigned long *pesp,
+		unsigned long *pebx, unsigned long *pedx,
+		unsigned long *pecx, unsigned long *peax,
+		unsigned long *pflags);
+
+extern void vga_exit(void);
+
+int biosint(unsigned long intnumber,
+	    unsigned long gsfs, unsigned long dses,
+	    unsigned long edi, unsigned long esi,
+	    unsigned long ebp, unsigned long esp,
+	    unsigned long ebx, unsigned long edx,
+	    unsigned long ecx, unsigned long eax,
+	    unsigned long cs_ip, unsigned short stackflags)
+{
+	unsigned long ip;
+	unsigned long cs;
+	unsigned long flags;
+	int ret = -1;
+
+	ip = cs_ip & 0xffff;
+	cs = cs_ip >> 16;
+	flags = stackflags;
+
+	printk_debug("biosint: INT# 0x%lx\n", intnumber);
+	printk_debug("biosint: eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n",
+		     eax, ebx, ecx, edx);
+	printk_debug("biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n",
+		     ebp, esp, edi, esi);
+	printk_debug("biosint:  ip 0x%x   cs 0x%x  flags 0x%x\n",
+		     ip, cs, flags);
+
+	// cases in a good compiler are just as good as your own tables. 
+	switch (intnumber) {
+	case 0...15:
+		// These are not BIOS service, but the CPU-generated exceptions
+		printk_info("biosint: Oops, exception %u\n", intnumber);
+		if (esp < 0x1000) {
+			printk_debug("Stack contents: ");
+			while (esp < 0x1000) {
+				printk_debug("0x%04x ",
+					     *(unsigned short *) esp);
+				esp += 2;
+			}
+			printk_debug("\n");
+		}
+		printk_debug("biosint: Bailing out\n");
+		// "longjmp"
+		if ((acpi_sleep_type == 3) || (PAYLOAD_IS_SEABIOS == 0))	// add this to keep same with kevin's seabios patch in 2008-9-8
+			vga_exit();
+		break;
+
+	case PCIBIOS:
+		ret = pcibios(&edi, &esi, &ebp, &esp,
+			      &ebx, &edx, &ecx, &eax, &flags);
+		break;
+	case MEMSIZE:
+		// who cares. 
+		eax = 64 * 1024;
+		ret = 0;
+		break;
+	case 0x15:
+		ret = handleint21(&edi, &esi, &ebp, &esp,
+				  &ebx, &edx, &ecx, &eax, &flags);
+		break;
+	default:
+		printk_info("BIOSINT: Unsupport int #0x%x\n", intnumber);
+		break;
+	}
+	if (ret)
+		flags |= 1;	// carry flags
+	else
+		flags &= ~1;
+	stackflags = flags;
+	return ret;
+}
+
+
+void setup_realmode_idt(void)
+{
+	extern unsigned char idthandle, end_idthandle;
+	extern unsigned char debughandle, end_debughandle;
+
+	int i;
+	struct realidt *idts = (struct realidt *) 0;
+	int codesize = &end_idthandle - &idthandle;
+	unsigned char *intbyte, *codeptr;
+
+	// for each int, we create a customized little handler
+	// that just pushes %ax, puts the int # in %al, 
+	// then calls the common interrupt handler. 
+	// this necessitated because intel didn't know much about 
+	// architecture when they did the 8086 (it shows)
+	// (hmm do they know anymore even now :-)
+	// obviously you can see I don't really care about memory 
+	// efficiency. If I did I would probe back through the stack
+	// and get it that way. But that's really disgusting.
+	for (i = 0; i < 256; i++) {
+		idts[i].cs = 0;
+		codeptr = (char *) 4096 + i * codesize;
+		idts[i].offset = (unsigned) codeptr;
+		memcpy(codeptr, &idthandle, codesize);
+		intbyte = codeptr + 3;
+		*intbyte = i;
+	}
+
+	// fixed entry points
+
+	// VGA BIOSes tend to hardcode f000:f065 as the previous handler of
+	// int10. 
+	// calling convention here is the same as INTs, we can reuse
+	// the int entry code.
+	codeptr = (char *) 0xff065;
+	memcpy(codeptr, &idthandle, codesize);
+	intbyte = codeptr + 3;
+	*intbyte = 0x42;	/* int42 is the relocated int10 */
+/*
+ Fixed entry points
+  VBIOS will call f000:f859 instead of sending int15.
+ calling convertion here is the same as INTs, we can reuse the int entry code.
+*/
+	codeptr = (char *) 0xff859;
+	memcpy(codeptr, &idthandle, codesize);
+	intbyte = codeptr + 3;
+	*intbyte = 0x15;
+
+	/* debug handler - useful to set a programmable delay between instructions if the
+	   TF bit is set upon call to real mode */
+	idts[1].cs = 0;
+	idts[1].offset = 16384;
+	memcpy(16384, &debughandle, &end_debughandle - &debughandle);
+
+
+}
+
+
+
+enum {
+	CHECK = 0xb001,
+	FINDDEV = 0xb102,
+	READCONFBYTE = 0xb108,
+	READCONFWORD = 0xb109,
+	READCONFDWORD = 0xb10a,
+	WRITECONFBYTE = 0xb10b,
+	WRITECONFWORD = 0xb10c,
+	WRITECONFDWORD = 0xb10d
+};
+
+// errors go in AH. Just set these up so that word assigns
+// will work. KISS. 
+enum {
+	PCIBIOS_NODEV = 0x8600,
+	PCIBIOS_BADREG = 0x8700
+};
+
+int
+pcibios(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
+	unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
+	unsigned long *pecx, unsigned long *peax, unsigned long *pflags)
+{
+	unsigned long edi = *pedi;
+	unsigned long esi = *pesi;
+	unsigned long ebp = *pebp;
+	unsigned long esp = *pesp;
+	unsigned long ebx = *pebx;
+	unsigned long edx = *pedx;
+	unsigned long ecx = *pecx;
+	unsigned long eax = *peax;
+	unsigned long flags = *pflags;
+	unsigned short func = (unsigned short) eax;
+	int retval = 0;
+	unsigned short devid, vendorid, devfn;
+	short devindex;		/* Use short to get rid of garbage in upper half of 32-bit register */
+	unsigned char bus;
+	device_t dev;
+
+	switch (func) {
+	case CHECK:
+		*pedx = 0x4350;
+		*pecx = 0x2049;
+		retval = 0;
+		break;
+	case FINDDEV:
+		{
+			devid = *pecx;
+			vendorid = *pedx;
+			devindex = *pesi;
+			dev = 0;
+			while ((dev =
+				dev_find_device(vendorid, devid, dev))) {
+				if (devindex <= 0)
+					break;
+				devindex--;
+			}
+			if (dev) {
+				unsigned short busdevfn;
+				*peax = 0;
+				// busnum is an unsigned char;
+				// devfn is an int, so we mask it off. 
+				busdevfn = (dev->bus->secondary << 8)
+				    | (dev->path.pci.devfn & 0xff);
+				printk_debug("0x%x: return 0x%x\n", func,
+					     busdevfn);
+				*pebx = busdevfn;
+				retval = 0;
+			} else {
+				*peax = PCIBIOS_NODEV;
+				retval = -1;
+			}
+		}
+		break;
+	case READCONFDWORD:
+	case READCONFWORD:
+	case READCONFBYTE:
+	case WRITECONFDWORD:
+	case WRITECONFWORD:
+	case WRITECONFBYTE:
+		{
+			unsigned long dword;
+			unsigned short word;
+			unsigned char byte;
+			unsigned char reg;
+
+			devfn = *pebx & 0xff;
+			bus = *pebx >> 8;
+			reg = *pedi;
+			dev = dev_find_slot(bus, devfn);
+			if (!dev) {
+				printk_debug
+				    ("0x%x: BAD DEVICE bus %d devfn 0x%x\n",
+				     func, bus, devfn);
+				// idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
+				*peax = PCIBIOS_BADREG;
+				retval = -1;
+			}
+			switch (func) {
+			case READCONFBYTE:
+				byte = pci_read_config8(dev, reg);
+				*pecx = byte;
+				break;
+			case READCONFWORD:
+				word = pci_read_config16(dev, reg);
+				*pecx = word;
+				break;
+			case READCONFDWORD:
+				dword = pci_read_config32(dev, reg);
+				*pecx = dword;
+				break;
+			case WRITECONFBYTE:
+				byte = *pecx;
+				pci_write_config8(dev, reg, byte);
+				break;
+			case WRITECONFWORD:
+				word = *pecx;
+				pci_write_config16(dev, reg, word);
+				break;
+			case WRITECONFDWORD:
+				dword = *pecx;
+				pci_write_config32(dev, reg, dword);
+				break;
+			}
+
+			if (retval)
+				retval = PCIBIOS_BADREG;
+			printk_debug
+			    ("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n",
+			     func, bus, devfn, reg, *pecx);
+			*peax = 0;
+			retval = 0;
+		}
+		break;
+	default:
+		printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
+		break;
+	}
+
+	return retval;
+}
+
+
+/* return value of int0x15(int21)
+AH  AL  		Completion status 
+??  5Fh  		Function call supported 
+??  !=5Fh  	Function not supported 
+00  5Fh  		Function call successful 
+01  5Fh  		Function call failed 
+*/
+int handleint21(unsigned long *edi, unsigned long *esi, unsigned long *ebp,
+		unsigned long *esp, unsigned long *ebx, unsigned long *edx,
+		unsigned long *ecx, unsigned long *eax,
+		unsigned long *flags)
+{
+	int res = -1;
+	switch (*eax & 0xffff) {
+	case 0x5f19:
+		*eax = 0x5f;
+		*ecx = 0x3;
+		res = 0;
+		break;
+	case 0x5f18:
+		{
+			/*
+			   BL  
+			   Bit[7:4] 
+			   Memory Data Rate 
+			   0000: 66MHz 
+			   0001: 100MHz 
+			   0010: 133MHz 
+			   0011: 200MHz ( DDR200 ) 
+			   0100: 266MHz ( DDR266 ) 
+			   0101: 333MHz ( DDR333 ) 
+			   0110: 400MHz ( DDR400 ) 
+			   0111: 533MHz ( DDR I/II 533 
+			   1000: 667MHz ( DDR I/II 667)
+			   Bit[3:0]  
+			   N:  Frame Buffer Size 2^N  MB 
+			 */
+			u8 i;
+			device_t dev;
+			dev = dev_find_slot(0, PCI_DEVFN(0, 3));
+			i = pci_read_config8(dev, 0xa1);
+			i = (i & 0x70);
+			i = i >> 4;
+			if (i == 0) {
+				*eax = 0x00;	//not support 5f18
+				break;
+			}
+			i = i + 2;
+			*ebx = (u32) i;
+			i = pci_read_config8(dev, 0x90);
+			i = (i & 0x07);
+			i = i + 3;
+			i = i << 4;
+			*ebx = (*ebx) + ((u32) i);
+			*eax = 0x5f;
+			res = 0;
+			break;
+		}
+	case 0x5f00:
+		*eax = 0x005f;
+		res = 0;
+		break;
+	case 0x5f01:
+		*eax = 0x5f;
+		*ecx = (*ecx & 0xffffff00) | 2;	// panel type =  2 = 1024 * 768
+		res = 0;
+		break;
+	case 0x5f02:
+		*eax = 0x5f;
+		*ebx = (*ebx & 0xffff0000) | 2;
+		*ecx = (*ecx & 0xffff0000) | 0x401;	// PAL + crt only 
+		*edx = (*edx & 0xffff0000) | 0;	// TV Layout - default
+		res = 0;
+		break;
+	case 0x5f0f:
+		*eax = 0x005f;
+		res = 0;
+		break;
+	default:
+		*eax = 0;
+		break;
+	}
+	return res;
+}

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vgachip.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vgachip.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vgachip.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey.osgood at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef _PC80_VGABIOS
+#define _PC80_VGABIOS
+
+extern struct chip_control pc80_vgabios_control;
+
+struct pc80_vgabios_config {
+	int nothing;
+};
+
+void vga_enable_console(void);
+void do_vgabios(void);
+void setup_realmode_idt(void);
+void write_protect_vgabios(void);
+
+#endif /* _PC80_VGABIOS */

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vx800.h
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vx800.h	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vx800.h	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef VX800_H
+#define  VX800_H 1
+
+
+#ifndef __ROMCC__
+static void vx800_noop(){}
+#endif
+#define REV_B0  0x10
+#define REV_B1 0x11
+#define REV_B2 0x12 
+#define REV_B3 0x13
+#define REV_B4 0x14
+#define REV_B2 0xB4
+#define REV_B0 0x00
+#define REV_B2 0x01
+
+/* VGA stuff */
+#define SR_INDEX	0x3c4
+#define SR_DATA		0x3c5
+#define CRTM_INDEX	0x3b4
+#define CRTM_DATA	0x3b5
+#define CRTC_INDEX	0x3d4
+#define CRTC_DATA	0x3d5
+
+/* Memory Controller Registers */
+#define RANK0_END		0x40
+#define RANK1_END		0x41
+#define RANK2_END		0x42
+#define RANK3_END		0x43
+#define RANK0_START		0x48
+#define RANK1_START		0x49
+#define RANK2_START		0x4a
+#define RANK3_START		0x4b
+#define DDR_PAGE_CTL		0x69
+#define DRAM_REFRESH_COUNTER	0x6a
+#define DRAM_MISC_CTL		0x6b
+#define CH_A_DQS_OUTPUT_DELAY	0x70
+#define CH_A_MD_OUTPUT_DELAY	0x71
+
+/* RAM Init Commands */
+#define RAM_COMMAND_NORMAL	0x0
+#define RAM_COMMAND_NOP		0x1
+#define RAM_COMMAND_PRECHARGE	0x2
+#define RAM_COMMAND_MRS		0x3
+#define RAM_COMMAND_CBR		0x4
+
+
+
+
+/* IDE specific bits */
+#define IDE_MODE_REG		0x09
+#define IDE0_NATIVE_MODE	(1 << 0)
+#define IDE1_NATIVE_MODE	(1 << 2)
+
+/* These are default addresses according to Via */
+#define IDE0_DATA_ADDR		0x1f0
+#define IDE0_CONTROL_ADDR	0x3f4
+#define IDE1_DATA_ADDR		0x170
+#define IDE1_CONTROL_ADDR	0x370
+
+
+/* By Award default, Via default is 0xCC0 */
+#define BUS_MASTER_ADDR		0xfe00
+
+#define CHANNEL_ENABLE_REG	0x40
+#define ENABLE_IDE0		(1 << 0)
+#define ENABLE_IDE1		(1 << 1)
+
+
+
+#define VX800_ACPI_IO_BASE	0x0400
+
+
+#define NB_APIC_REG 0,0,5,
+#define NB_PXPTRF_REG  NB_APIC_REG 
+#define NB_MSGC_REG NB_APIC_REG 
+#define NB_HOST_REG 0,0,2,
+#define NB_P6IF_REG NB_HOST_REG
+
+#define NB_DRAMC_REG 0,0,3,
+#define NB_PMU_REG 0,0,4,
+#define NB_VLINK_REG 0,0,7,
+#define NB_PEG_BRIDGE_REG 0,2, 0,
+#define NB_D3F0_REG 0,3, 0,
+#define NB_D3F1_REG 0,3, 1,
+
+
+#define SB_LPC_REG 0,0x11,0,
+#define SB_VLINK_REG 0,0x11,7,
+#define SB_SATA_REG 0,0xf, 0,
+#define SB_IDEC_REG 0,0xf, 0,
+#define SB_P2PB_REG 0,0x13, 0,
+#define SB_USB0_REG 0,0x10, 0,
+#define SB_USB1_REG 0,0x10, 1,
+#define SB_USB2_REG 0,0x10, 2,
+#define SB_EHCI_REG 0,0x10, 4,
+
+
+#define VX800SB_APIC_ID			0x4
+#define VX800SB_APIC_BASE		0xfec00000ULL
+#define VX800SB_APIC_DATA_OFFSET             0x10
+#define VX800SB_APIC_ENTRY_NUMBER 0x40
+
+#define VX800_D0F5_MMCONFIG_MBAR	0x61
+
+#endif

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_serial.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_serial.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_serial.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+*/
+
+/*
+ * Enable the serial devices on the VIA
+ */
+#include <arch/romcc_io.h>
+
+/* The base address is 0x15c, 0x2e, depending on config bytes */
+
+#define SIO_BASE 0x3f0
+#define SIO_DATA  SIO_BASE+1
+
+static void vx800_writesuper(uint8_t reg, uint8_t val) 
+{
+	outb(reg, SIO_BASE);
+	outb(val, SIO_DATA);
+}
+
+static void vx800_writepnpaddr(uint8_t val) 
+{
+	outb(val, 0x2e);
+	outb(val, 0xeb);
+}
+
+static void vx800_writepnpdata(uint8_t val) 
+{
+	outb(val, 0x2f);
+	outb(val, 0xeb);
+}
+
+static void vx800_writesiobyte(uint16_t reg, uint8_t val) 
+{
+	outb(val, reg);
+}
+
+static void vx800_writesioword(uint16_t reg, uint16_t val) 
+{
+	outw(val, reg);
+}
+
+
+/* regs we use: 85, and the southbridge devfn is defined by the
+   mainboard
+ */
+
+static void enable_vx800_serial(void) 
+{
+	outb(6, 0x80);
+	outb(0x03, 0x22);
+
+
+	//pci_write_config8(PCI_DEV(0,17,0),0xb4,0x7e);
+	//pci_write_config8(PCI_DEV(0,17,0),0xb0,0x10);
+	
+	// turn on pnp
+	vx800_writepnpaddr(0x87);
+	vx800_writepnpaddr(0x87);
+	// now go ahead and set up com1. 
+	// set address
+	vx800_writepnpaddr(0x7);
+	vx800_writepnpdata(0x2);
+	// enable serial out
+	vx800_writepnpaddr(0x30);
+	vx800_writepnpdata(0x1);
+	// serial port 1 base address (FEh)
+	vx800_writepnpaddr(0x60);
+	vx800_writepnpdata(0xfe);
+	// serial port 1 IRQ (04h)
+	vx800_writepnpaddr(0x70);
+	vx800_writepnpdata(0x4);
+	// serial port 1 control
+	vx800_writepnpaddr(0xf0);
+	vx800_writepnpdata(0x2);
+	// turn of pnp
+	vx800_writepnpaddr(0xaa);
+
+	// set up reg to set baud rate.
+	vx800_writesiobyte(0x3fb, 0x80);
+	// Set 115 kb
+	vx800_writesioword(0x3f8, 1);
+	// Set 9.6 kb
+	//	WRITESIOWORD(0x3f8, 12)
+	// now set no parity, one stop, 8 bits
+	vx800_writesiobyte(0x3fb, 3);
+	// now turn on RTS, DRT
+	vx800_writesiobyte(0x3fc, 3);
+	// Enable interrupts
+	vx800_writesiobyte(0x3f9, 0xf);
+	// should be done. Dump a char for fun.
+	vx800_writesiobyte(0x3f8, 48);
+	outb(7, 0x80);
+}
+

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_smbus.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_smbus.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vx800_early_smbus.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,321 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+ #include <device/pci_ids.h>
+ #include "vx800.h"
+#define SMBUS_IO_BASE		0x0500 //from award bios
+#define PMIO_BASE		VX800_ACPI_IO_BASE //might as well set this while we're here
+
+#define SMBHSTSTAT		SMBUS_IO_BASE + 0x0
+#define SMBSLVSTAT		SMBUS_IO_BASE + 0x1
+#define SMBHSTCTL		SMBUS_IO_BASE + 0x2
+#define SMBHSTCMD		SMBUS_IO_BASE + 0x3
+#define SMBXMITADD		SMBUS_IO_BASE + 0x4
+#define SMBHSTDAT0		SMBUS_IO_BASE + 0x5
+#define SMBHSTDAT1		SMBUS_IO_BASE + 0x6
+/* Rest of these aren't currently used... */
+#define SMBBLKDAT		SMBUS_IO_BASE + 0x7
+#define SMBSLVCTL		SMBUS_IO_BASE + 0x8
+#define SMBTRNSADD		SMBUS_IO_BASE + 0x9
+#define SMBSLVDATA 		SMBUS_IO_BASE + 0xa
+#define SMLINK_PIN_CTL		SMBUS_IO_BASE + 0xe
+#define SMBUS_PIN_CTL		SMBUS_IO_BASE + 0xf
+
+/* Define register settings */
+#define HOST_RESET	0xff
+#define DIMM_BASE		0xa0	// 1010000 is base for DIMM in SMBus
+#define READ_CMD		0x01	// 1 in the 0 bit of SMBHSTADD states to READ
+
+#define SMBUS_TIMEOUT		(100*1000*10)
+
+#define I2C_TRANS_CMD		0x40
+#define CLOCK_SLAVE_ADDRESS	0x69
+
+#define SMBUS_DELAY()		outb(0x80, 0x80)
+
+/* Debugging macros. Only necessary if something isn't working right */
+
+#define DEBUG_SMBUS 1
+
+#ifdef DEBUG_SMBUS
+#define PRINT_DEBUG(x)		print_debug(x)
+#define PRINT_DEBUG_HEX16(x)	print_debug_hex16(x)
+#else
+#define PRINT_DEBUG(x)
+#define PRINT_DEBUG_HEX16(x)
+#endif
+
+/* Internal functions */
+static void smbus_print_error(unsigned char host_status_register, int loops)
+{
+//		print_err("some i2c error\r\n");
+	/* Check if there actually was an error */
+	if ( host_status_register == 0x00 || host_status_register == 0x40 ||
+					host_status_register == 0x42) return;
+	print_err("smbus_error: ");
+	print_err_hex8(host_status_register);
+	print_err("\r\n");
+	if (loops >= SMBUS_TIMEOUT) {
+		print_err("SMBus Timout\r\n");
+	}
+	if (host_status_register & (1 << 4)) {
+		print_err("Interrup/SMI# was Failed Bus Transaction\r\n");
+	}
+	if (host_status_register & (1 << 3)) {
+		print_err("Bus Error\r\n");
+	}
+	if (host_status_register & (1 << 2)) {
+		print_err("Device Error\r\n");
+	}
+	if (host_status_register & (1 << 1)) {
+		/* This isn't a real error... */
+		print_debug("Interrupt/SMI# was Successful Completion\r\n");
+	}
+	if (host_status_register & (1 << 0)) {
+		print_err("Host Busy\r\n");
+	}
+}
+
+static void smbus_wait_until_ready(void)
+{
+	int loops;
+
+	loops = 0;
+	/* Yes, this is a mess, but it's the easiest way to do it */
+	while(((inb(SMBHSTSTAT) & 1) == 1) && (loops <= SMBUS_TIMEOUT)) {
+		SMBUS_DELAY();
+		++loops;
+	}
+	smbus_print_error(inb(SMBHSTSTAT), loops);
+}
+
+static void smbus_reset(void)
+{
+	outb(HOST_RESET, SMBHSTSTAT);
+}
+
+/* Public functions */
+static unsigned int set_ics_data(unsigned char dev, int data, char len)
+{
+	int i;
+	smbus_reset();
+	/* clear host data port */
+	outb(0x00, SMBHSTDAT0);
+	SMBUS_DELAY();
+	smbus_wait_until_ready();
+
+	/* read to reset block transfer counter */
+	inb(SMBHSTCTL);
+
+	/* fill blocktransfer array */
+	if (dev=0xd2) {
+		//char d2_data[] = {0x0d,0x00,0x3f,0xcd,0x7f,0xbf,0x1a,0x2a,0x01,0x0f,0x0b,0x00,0x8d,0x9b};
+		outb(0x0d,SMBBLKDAT);
+		outb(0x00,SMBBLKDAT);
+		outb(0x3f,SMBBLKDAT);
+		outb(0xcd,SMBBLKDAT);
+		outb(0x7f,SMBBLKDAT);
+		outb(0xbf,SMBBLKDAT);
+		outb(0x1a,SMBBLKDAT);
+		outb(0x2a,SMBBLKDAT);
+		outb(0x01,SMBBLKDAT);
+		outb(0x0f,SMBBLKDAT);
+		outb(0x0b,SMBBLKDAT);
+		outb(0x80,SMBBLKDAT);
+		outb(0x8d,SMBBLKDAT);
+		outb(0x9b,SMBBLKDAT);
+	} else {
+		//char d4_data[] = {0x08,0xff,0x3f,0x00,0x00,0xff,0xff,0xff,0xff};
+		outb(0x08,SMBBLKDAT);
+		outb(0xff,SMBBLKDAT);
+		outb(0x3f,SMBBLKDAT);
+		outb(0x00,SMBBLKDAT);
+		outb(0x00,SMBBLKDAT);
+		outb(0xff,SMBBLKDAT);
+		outb(0xff,SMBBLKDAT);
+		outb(0xff,SMBBLKDAT);
+		outb(0xff,SMBBLKDAT);
+	}
+
+	//for (i=0; i < len; i++)
+	//	outb(data[i],SMBBLKDAT);
+
+	outb(dev, SMBXMITADD);
+	outb(0, SMBHSTCMD);
+	outb(len, SMBHSTDAT0);
+	outb(0x74, SMBHSTCTL);
+
+	SMBUS_DELAY();
+
+	smbus_wait_until_ready();
+
+	smbus_reset();
+	return 0;
+}
+
+static unsigned int get_spd_data(unsigned int dimm, unsigned int offset)
+{
+	unsigned int val;
+
+	smbus_reset();
+	/* clear host data port */
+	outb(0x00, SMBHSTDAT0);
+	SMBUS_DELAY();
+	smbus_wait_until_ready();
+
+	/* Do some mathmatic magic */
+	dimm = (dimm << 1);
+	dimm &= 0x0E;
+	dimm |= 0xA0;
+
+	outb(dimm|0x1, SMBXMITADD);
+	outb(offset, SMBHSTCMD);
+	outb(0x48, SMBHSTCTL);
+
+	SMBUS_DELAY();
+
+	smbus_wait_until_ready();
+
+	val = inb(SMBHSTDAT0);
+	smbus_reset();
+	return val;
+}
+
+static void enable_smbus(void)
+{
+	device_t dev;
+
+	dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_LPC), 0);
+
+	if (dev == PCI_DEV_INVALID)	{
+		/* This won't display text if enable_smbus() is before serial init */
+		die("Power Managment Controller not found\r\n");
+	}
+
+	/* Set clock source */
+	pci_write_config8(dev, 0x94, 0x20);
+
+	/* Write SMBus IO base to 0xd0, and enable SMBus */
+	pci_write_config16(dev, 0xd0, SMBUS_IO_BASE | 1);
+
+	/* Set to Award value */
+	pci_write_config8(dev, 0xd2, 0x05);
+
+	/* Make it work for I/O ...*/
+	pci_write_config16(dev, 0x04, 0x0003);
+
+        /*
+            coreboot hangs at this two lines after os reboot(this even happen after I change os 
+            reboot to cold reboot, this also interfere S3 wakeup)*/
+	/* Setup clock chips */
+	//set_ics_data(0xd2, 0, 14);
+	//set_ics_data(0xd4, 0, 9);
+	
+	smbus_reset();
+	/* clear host data port */
+	outb(0x00, SMBHSTDAT0);
+	SMBUS_DELAY();
+ 	smbus_wait_until_ready();
+}
+
+/**
+ * A fixup for some systems that need time for the SMBus to "warm up". This is 
+ * needed on some VT823x based systems, where the SMBus spurts out bad data for 
+ * a short time after power on. This has been seen on the VIA Epia series and 
+ * Jetway J7F2-series. It reads the ID byte from SMBus, looking for 
+ * known-good data from a slot/address. Exits on either good data or a timeout.
+ *
+ * TODO: This should probably go into some global file, but one would need to
+ *       be created just for it. If some other chip needs/wants it, we can
+ *       worry about it then.
+ *
+ * @param ctrl The memory controller and SMBus addresses.
+ */
+void smbus_fixup(const struct mem_controller *ctrl)
+{
+	int i, ram_slots, current_slot = 0;
+	u8 result = 0;
+
+	ram_slots = ARRAY_SIZE(ctrl->channel0);
+	if (!ram_slots) {
+		print_err("smbus_fixup() thinks there are no RAM slots!\r\n");
+		return;
+	}
+
+	PRINT_DEBUG("Waiting for SMBus to warm up");
+
+	/*
+	 * Bad SPD data should be either 0 or 0xff, but YMMV. So we look for
+	 * the ID bytes of SDRAM, DDR, DDR2, and DDR3 (and anything in between).
+	 * VT8237R has only been seen on DDR and DDR2 based systems, so far.
+	 */
+	for (i = 0; (i < SMBUS_TIMEOUT && ((result < SPD_MEMORY_TYPE_SDRAM) ||
+				(result > SPD_MEMORY_TYPE_SDRAM_DDR3))); i++) {
+
+		if (current_slot > ram_slots)
+			current_slot = 0;
+
+		result = get_spd_data(ctrl->channel0[current_slot],
+					 SPD_MEMORY_TYPE);
+		current_slot++;
+		PRINT_DEBUG(".");
+	}
+
+	if (i >= SMBUS_TIMEOUT)
+		print_err("SMBus timed out while warming up\r\n");
+	else
+		PRINT_DEBUG("Done\r\n");
+}
+
+/* Debugging Function */
+#ifdef DEBUG_SMBUS
+static void dump_spd_data(void)
+{
+	int dimm, offset, regs;
+	unsigned int val;
+
+	for(dimm = 0; dimm < 8; dimm++)
+	{
+		print_debug("SPD Data for DIMM ");
+		print_debug_hex8(dimm);
+		print_debug("\r\n");
+
+		val = get_spd_data(dimm, 0);
+		if(val == 0xff)
+		{
+			regs = 256;
+		} else if(val == 0x80) {
+			regs = 128;
+		} else {
+			print_debug("No DIMM present\r\n");
+			regs = 0;
+		}
+		for(offset = 0; offset < regs; offset++)
+		{
+			print_debug("  Offset ");
+			print_debug_hex8(offset);
+			print_debug(" = 0x");
+			print_debug_hex8(get_spd_data(dimm, offset));
+			print_debug("\r\n");
+		}
+	}
+}
+#else
+#define dump_spd_data()
+#endif

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vx800_ide.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vx800_ide.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vx800_ide.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,204 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "chip.h"
+#include <arch/io.h>
+#include "vx800.h"
+
+static const idedevicepcitable[16 * 12] = {
+//
+/*0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0xF0, 0x00, 0x00, 0xB6,
+0x00, 0x00, 0x01, 0x21, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
+0x00, 0xC2, 0xF9, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+*/
+//
+	0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x99, 0x20, 0xf0, 0x00, 0x00, 0x20,
+	0x00, 0x00, 0x17, 0xF1, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
+	0x00, 0xc2, 0x09, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+//legacybios xp pci value
+/*0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x20, 0x00, 0x00, 0x00, 0xb6, 
+0x00, 0x00, 0x16, 0xF1, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4, 
+0x00, 0x02, 0x09, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+*/
+//rom  legacybios on cn_8562b
+/*
+0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x99, 0x20, 0x60, 0x00, 0x00, 0x20, 
+0x00, 0x00, 0x1E, 0xF1, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4, 
+0x00, 0x02, 0x09, 0x01, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+*/
+//from egacybios on c7_8562b
+/*0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x20, 0x60, 0x00, 0x00, 0xB6, 
+0x00, 0x00, 0x1E, 0xF1, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4, 
+0x00, 0x02, 0x09, 0x01, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, */
+};
+
+static void ide_init(struct device *dev)
+{
+	uint8_t enables, Rx89, RxC0;
+	u8 i, data;
+	struct ATA_REG_INIT_TABLE *pEntry;
+	printk_info("ide_init\n");
+
+#if 1
+	/*these 3 lines help to keep interl back door for DID VID SUBID untouched */
+	u16 data16_1, data16_2;
+	data16_1 = pci_read_config16(dev, 0xba);
+	data16_2 = pci_read_config16(dev, 0xbe);
+
+	for (i = 0; i < (16 * 12); i++) {
+		pci_write_config8(dev, 0x40 + i, idedevicepcitable[i]);
+	}
+	//pci_write_config8(dev, 0x0d, 0x20);
+	data = pci_read_config8(dev, 0x0d);
+	data &= 0x0f;
+	data |= 0x40;
+	pci_write_config8(dev, 0x0d, data);
+
+	//these 2 lines help to keep interl back door for DID VID SUBID untouched
+	pci_write_config16(dev, 0xba, data16_1);
+	pci_write_config16(dev, 0xbe, data16_2);
+#endif
+	/* Force interrupts to use compat mode. */
+	pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
+	pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
+#if 0
+
+
+
+	struct southbridge_via_vt8237r_config *sb =
+	    (struct southbridge_via_vt8237r_config *) dev->chip_info;
+
+	u8 enables;
+	u32 cablesel;
+
+	pci_write_config16(dev, 0x04, 0x0007);
+
+	enables = pci_read_config8(dev, IDE_CS) & ~0x3;
+	enables |= 0x02;
+	pci_write_config8(dev, IDE_CS, enables);
+	enables = pci_read_config8(dev, IDE_CS);
+	printk_debug("Enables in reg 0x40 read back as 0x%x\n", enables);
+
+	/* Enable only compatibility mode. */
+	enables = pci_read_config8(dev, IDE_CONF_II);
+	enables &= ~0xc0;
+	pci_write_config8(dev, IDE_CONF_II, enables);
+	enables = pci_read_config8(dev, IDE_CONF_II);
+	printk_debug("Enables in reg 0x42 read back as 0x%x\n", enables);
+
+	/* Enable prefetch buffers. */
+	enables = pci_read_config8(dev, IDE_CONF_I);
+	enables |= 0xf0;
+	pci_write_config8(dev, IDE_CONF_I, enables);
+
+	/* Flush FIFOs at half. */
+	enables = pci_read_config8(dev, IDE_CONF_FIFO);
+	enables &= 0xf0;
+	enables |= (1 << 2) | (1 << 0);
+	pci_write_config8(dev, IDE_CONF_FIFO, enables);
+
+	/* PIO read prefetch counter, Bus Master IDE Status Reg. Read Retry. */
+	enables = pci_read_config8(dev, IDE_MISC_I);
+	enables &= 0xe2;
+	enables |= (1 << 4) | (1 << 3);
+	pci_write_config8(dev, IDE_MISC_I, enables);
+
+	/* Use memory read multiple, Memory-Write-and-Invalidate. */
+	enables = pci_read_config8(dev, IDE_MISC_II);
+	enables |= (1 << 2) | (1 << 3);
+	pci_write_config8(dev, IDE_MISC_II, enables);
+
+	/* Force interrupts to use compat mode. */
+	pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
+	pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
+
+	/* Cable guy... */
+	cablesel = pci_read_config32(dev, IDE_UDMA);
+	cablesel &= ~((1 << 28) | (1 << 20) | (1 << 12) | (1 << 4));
+	cablesel |= (sb->ide0_80pin_cable << 28) |
+	    (sb->ide0_80pin_cable << 20) |
+	    (sb->ide1_80pin_cable << 12) | (sb->ide1_80pin_cable << 4);
+	pci_write_config32(dev, IDE_UDMA, cablesel);
+#endif
+}
+
+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,
+	.enable = 0,
+	.ops_pci = 0,
+};
+
+static struct pci_driver via_ide_driver __pci_driver = {
+	.ops = &ide_ops,
+	.vendor = PCI_VENDOR_ID_VIA,
+	.device = PCI_DEVICE_ID_VIA_VX855_IDE,
+};

Added: trunk/coreboot-v2/src/northbridge/via/vx800/vx800_lpc.c
===================================================================
--- trunk/coreboot-v2/src/northbridge/via/vx800/vx800_lpc.c	                        (rev 0)
+++ trunk/coreboot-v2/src/northbridge/via/vx800/vx800_lpc.c	2009-05-27 13:12:42 UTC (rev 4313)
@@ -0,0 +1,384 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+
+#include <pc80/mc146818rtc.h>
+#include <pc80/keyboard.h>
+#include <pc80/i8259.h>
+#include "vx800.h"
+#include "chip.h"
+
+static const unsigned char pciIrqs[4] = {0xa, 0x9, 0xb, 0xa};
+
+static const unsigned char vgaPins[4] = { 'A', 'B', 'C', 'D' };//only INTA
+
+static const unsigned char slotPins[4] = { 'A', 'A', 'A', 'A'};//all 4
+
+static const unsigned char usbdevicePins[4] = { 'A', 'B', 'C', 'D' };//only INTA
+static const unsigned char sdioPins[4] = { 'A', 'B', 'C', 'D' };//only INTA
+static const unsigned char sd_ms_ctrl_Pins[4] = { 'B', 'C', 'D', 'A' };//only INTA
+static const unsigned char ce_ata_nf_ctrl_Pins[4] = { 'C', 'C', 'D', 'A' };//only INTA
+static const unsigned char idePins[4] = { 'B', 'C', 'D', 'A' };//only INTA
+
+static const unsigned char usbPins[4] = { 'A', 'B', 'C', 'D' };//all 4 
+
+static const unsigned char hdacaudioPins[4] = { 'B', 'C', 'D', 'A' };//only INTA 
+
+static unsigned char *pin_to_irq(const unsigned char *pin)
+{
+	static unsigned char Irqs[4];
+	int i;
+	for (i = 0 ; i < 4 ; i++)
+		Irqs[i] = pciIrqs[ pin[i] - 'A' ];
+
+	return Irqs;
+}
+
+static void pci_routing_fixup(struct device *dev)
+{
+	printk_info("%s: dev is %p\n", __FUNCTION__, dev);
+
+	/* set up PCI IRQ routing */
+	pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
+	pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
+	pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
+
+	/* VGA */
+	printk_info("setting vga\n");
+	pci_assign_irqs(0, 0x1, pin_to_irq(vgaPins));
+
+	/* PCI slot */
+	printk_info("setting pci slot\n");
+	pci_assign_irqs(0, 0x08, pin_to_irq(slotPins));
+
+	/* PCI slot */
+	printk_info("setting USB Device Controller\n");
+	pci_assign_irqs(0, 0x0b, pin_to_irq(usbdevicePins));
+
+	/* PCI slot */
+	printk_info("setting SDIO Controller\n");
+	pci_assign_irqs(0, 0x0c, pin_to_irq(sdioPins));
+
+	/* PCI slot */
+	printk_info("setting SD $ MS Controller\n");
+	pci_assign_irqs(0, 0x0d, pin_to_irq(sd_ms_ctrl_Pins));
+
+	/* PCI slot */
+	printk_info("setting CE-ATA NF Controller(Card Boot)\n");
+	pci_assign_irqs(0, 0x0e, pin_to_irq(ce_ata_nf_ctrl_Pins));
+
+	/* PCI slot */
+	printk_info("setting ide\n");
+	//pci_assign_irqs(0, 0x0f, pin_to_irq(idePins));
+
+	/* Standard usb components */
+	printk_info("setting usb1-2\n");
+//	pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
+
+	/* sound hardware */
+	printk_info("setting hdac audio\n");
+	pci_assign_irqs(0, 0x14, pin_to_irq(hdacaudioPins));
+
+	printk_spew("%s: DONE\n", __FUNCTION__);
+}
+
+void setup_pm(device_t dev)
+{
+	u16 tmp;
+	/* Debounce LID and PWRBTN# Inputs for 16ms. */
+	pci_write_config8(dev, 0x80, 0x20);
+
+	/* Set ACPI base address to IO VX800_ACPI_IO_BASE */
+	pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE|1);
+
+	/* set ACPI irq to 9 */
+	pci_write_config8(dev, 0x82, 0x49);
+
+	/* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
+//	pci_write_config16(dev, 0x84, 0x30f2);
+	pci_write_config16(dev, 0x84, 0x609a); // 0x609a??
+
+	/* SMI output level to low, 7.5us throttle clock */
+	pci_write_config8(dev, 0x8d, 0x18);
+
+	/* GP Timer Control 1s */
+	pci_write_config8(dev, 0x93, 0x88);
+	
+	/* Power Well */
+	pci_write_config8(dev, 0x94, 0x20);	// 0x20??
+
+	/* 7 = stp to sust delay 1msec
+         * 6 = SUSST# Deasserted Before PWRGD for STD
+         */
+	pci_write_config8(dev, 0x95, 0xc0);	// 0xc1??
+
+	/* Disable GP2 & GP3 Timer */
+	pci_write_config8(dev, 0x98, 0);
+
+	/* GP2 Timer Counter */
+	pci_write_config8(dev, 0x99, 0xfb);
+	/* GP3 Timer Counter */
+	//pci_write_config8(dev, 0x9a, 0x20);
+
+	/* Multi Function Select 1 */
+	pci_write_config8(dev, 0xe4, 0x00);
+	/* Multi Function Select 2 */
+	pci_write_config8(dev, 0xe5, 0x41);	//??
+
+
+	/* Enable ACPI access (and setup like award) */
+	pci_write_config8(dev, 0x81, 0x84);
+
+	/* Clear status events. */
+	outw(0xffff, VX800_ACPI_IO_BASE + 0x00);
+	outw(0xffff, VX800_ACPI_IO_BASE + 0x20);
+	outw(0xffff, VX800_ACPI_IO_BASE + 0x28);
+	outl(0xffffffff, VX800_ACPI_IO_BASE + 0x30);
+
+	/* Disable SCI on GPIO. */
+	outw(0x0, VX800_ACPI_IO_BASE + 0x22);
+
+	/* Disable SMI on GPIO. */
+	outw(0x0, VX800_ACPI_IO_BASE + 0x24);
+
+	/* Disable all global enable SMIs. */
+	outw(0x0, VX800_ACPI_IO_BASE + 0x2a);
+
+	/* All SMI off, both IDE buses ON, PSON rising edge. */
+	outw(0x0, VX800_ACPI_IO_BASE + 0x2c);
+
+	/* Primary activity SMI disable. */
+	outl(0x0, VX800_ACPI_IO_BASE + 0x34);
+
+	/* GP timer reload on none. */
+	outl(0x0, VX800_ACPI_IO_BASE + 0x38);
+
+	/* Disable extended IO traps. */
+	outb(0x0, VX800_ACPI_IO_BASE + 0x42);
+
+	tmp = inw(VX800_ACPI_IO_BASE + 0x04);
+	/* SCI is generated for RTC/pwrBtn/slpBtn. */
+	tmp |= 1;
+	outw(tmp, VX800_ACPI_IO_BASE + 0x04);
+
+	/* Allow SLP# signal to assert LDTSTOP_L.
+	 * Will work for C3 and for FID/VID change.
+	 */
+	outb(0x1, VX800_ACPI_IO_BASE + 0x11);
+/*
+	outw(0x0, 0x424);
+	outw(0x0, 0x42a);
+	outw(0x1, 0x42c);
+	outl(0x0, 0x434);
+	outl(0x01, 0x438);
+	outb(0x0, 0x442);
+	outl(0xffff7fff, 0x448);
+	outw(0x001, 0x404);
+*/
+}
+void S3_ps2_kb_ms_wakeup(struct device *dev)
+{	u8 enables;
+	enables = pci_read_config8(dev, 0x51);
+	enables |= 2;
+	pci_write_config8(dev, 0x51, enables);
+	
+	outb(0xe0, 0x2e);
+	outb(0x0b, 0x2f);//if 09,then only support kb wakeup
+
+	outb(0xe1, 0x2e);//set any key scan code can wakeup
+	outb(0x00, 0x2f);
+	
+	outb(0xe9, 0x2e);//set any mouse scan code can wakeup
+	outb(0x00, 0x2f);
+
+	enables &= 0xd;
+	pci_write_config8(dev, 0x51, enables);
+
+	outb(inb(VX800_ACPI_IO_BASE+0x02)|0x20, VX800_ACPI_IO_BASE+0x02);//ACPI golabe enable for sci smi trigger
+	outw(inw(VX800_ACPI_IO_BASE+0x22)|0x204, VX800_ACPI_IO_BASE+0x22);//ACPI SCI on Internal KBC PME and mouse PME	
+		
+}
+void S3_usb_wakeup(struct device *dev)
+{
+	outw(inw(VX800_ACPI_IO_BASE+0x22)|0x4000, VX800_ACPI_IO_BASE+0x22);//SCI on USB PME
+}
+
+void S3_lid_wakeup(struct device *dev)
+{
+	outw(inw(VX800_ACPI_IO_BASE+0x22)|0x800, VX800_ACPI_IO_BASE+0x22);//SCI on LID PME
+}
+
+
+/* This looks good enough to work, maybe */
+static void vx800_sb_init(struct device *dev)
+{
+	unsigned char enables;
+
+	// enable the internal I/O decode
+	enables = pci_read_config8(dev, 0x6C);
+	enables |= 0x80;
+	pci_write_config8(dev, 0x6C, enables);
+
+	// Map 4MB of FLASH into the address space
+//	pci_write_config8(dev, 0x41, 0x7f);
+
+	// Set bit 6 of 0x40, because Award does it (IO recovery time)
+	// IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
+	// interrupts can be properly marked as level triggered.
+	enables = pci_read_config8(dev, 0x40);
+	enables |= 0x44;
+	pci_write_config8(dev, 0x40, enables);
+
+	/* DMA Line buffer control */
+	enables = pci_read_config8(dev, 0x42);
+	enables |= 0xf0;
+	pci_write_config8(dev, 0x42, enables);
+
+	/* I/O recovery time */
+	pci_write_config8(dev, 0x4c, 0x44);
+
+	/* ROM memory cycles go to LPC. */
+        pci_write_config8(dev, 0x59, 0x80);
+
+	/* Set 0x5b to 0x01 to match Award */
+	//pci_write_config8(dev, 0x5b, 0x01);
+	enables = pci_read_config8(dev, 0x5b);
+	enables |= 0x01;
+	pci_write_config8(dev, 0x5b, enables);
+
+
+	/* Set Read Pass Write Control Enable */
+	pci_write_config8(dev, 0x48, 0x0c);
+
+	/* Set 0x58 to 0x42 APIC and RTC. */
+	//pci_write_config8(dev, 0x58, 0x42); this cmd cause the irq0 can not be triggerd,since bit 5 was set to 0.
+	enables=pci_read_config8(dev, 0x58); 
+	enables|=0x41;//
+	pci_write_config8(dev, 0x58,enables); 
+
+
+	/* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
+	enables = pci_read_config8(dev, 0x4f);
+	enables |= 0x08;
+	pci_write_config8(dev, 0x4f, enables);
+
+	/* enable serial irq */
+	pci_write_config8(dev, 0x52, 0x9);
+
+	/* dma */
+	pci_write_config8(dev, 0x53, 0x00);
+
+	// Power management setup
+	setup_pm(dev);
+
+	/* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
+	pci_write_config8(dev, 0x40, 0x54);
+
+	// Start the rtc
+	rtc_init(0);
+}
+
+/* total kludge to get lxb to call our childrens set/enable functions - these are
+   not called unless this device has a resource to set - so set a dummy one */
+void vx800_read_resources(device_t dev)
+{
+
+	struct resource *resource;
+	pci_dev_read_resources(dev);
+	resource = new_resource(dev, 1);
+	resource->flags |= IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO | IORESOURCE_STORED;
+	resource->size = 2;
+	resource->base = 0x2e;
+
+}
+void vx800_set_resources(device_t dev)
+{
+	struct resource *resource;
+	resource = find_resource(dev,1);
+	resource->flags |= IORESOURCE_STORED;
+	pci_dev_set_resources(dev);
+}
+
+void vx800_enable_resources(device_t dev)
+ {
+	/* vx800 is not a pci bridge and has no resources of its own (other than
+	   standard PC i/o addresses). however it does control the isa bus and so
+	   we need to manually call enable childrens resources on that bus */
+	/* TODO: do we even care about ISA? If so, for what? SuperIO on LPC bus */
+	pci_dev_enable_resources(dev);
+	enable_childrens_resources(dev);
+}
+
+static void southbridge_init(struct device *dev)
+{ 
+	printk_debug("vx800 sb init\n");
+	vx800_sb_init(dev);
+	pci_routing_fixup(dev);
+
+	setup_i8259();   // make sure interupt controller is configured before keyboard init
+
+  /* turn on keyboard and RTC, no need to visit this reg twice */
+	init_pc_keyboard(0x60, 0x64, 0);
+	printk_debug("ps2 usb lid, you  set who can wakeup system from s3 sleep\n");		
+	S3_ps2_kb_ms_wakeup(dev);
+	S3_usb_wakeup(dev); 
+
+/*	enable acpi cpu c3 state. (c2 state need not do anything.)
+	#1
+		fadt->pm2_cnt_blk = 0x22;//to support cpu-c3
+		fadt->p_lvl2_lat = 0x50; //this is the coreboot source
+		fadt->p_lvl3_lat = 0x320;//
+		fadt->pm2_cnt_len = 1;//to support cpu-c3
+	#2
+		ssdt? ->every cpu has a P_BLK address. set it to 0x10 (so that "Read Processor Level3 register(PMIORx15<7:0>) to enter C3 state"---VIA vx800 P SPEC )
+       #3    write 0x17 in to PMIO=VX800_ACPI_IO_BASE + 0x26, following the describtion in the P-spec. 
+	       1  enable SLP# asserts in C3 state  PMIORx26<1> =1
+		2    enable CPUSTP# asserts in C3 state;  PMIORx26<2> =1
+		3  CLKRUN# is always asserted  PMIORx26<3> =0
+		4    Disable PCISTP# When CLKRUN# is asserted 
+		1: PCISTP# will not assert When CLKRUN# is asserted 
+		PMIORx26<4> =1
+		5  This bit controls whether the CPU voltage is lowered when in C3/S1 state.     
+		VRDSLP will be active in either this bit set in C3 or LVL4 register read 
+		PMIORx26<0> =0
+		6  Read Processor Level3 register(PMIORx15<7:0>) to enter C3 state  PMIORx15 
+	*/
+	outb(0x17, VX800_ACPI_IO_BASE + 0x26);
+
+}
+
+static struct device_operations vx800_lpc_ops = {
+	.read_resources   = vx800_read_resources,
+	.set_resources    = vx800_set_resources,
+	.enable_resources = vx800_enable_resources,
+	.init             = &southbridge_init,
+	.scan_bus         = scan_static_bus,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+	.ops    = &vx800_lpc_ops,
+	.vendor = PCI_VENDOR_ID_VIA,
+	.device = PCI_DEVICE_ID_VIA_VX855_LPC,
+};





More information about the coreboot mailing list