[LinuxBIOS] r387 - in LinuxBIOSv3/arch/x86: . geodelx

svn at openbios.org svn at openbios.org
Wed Jun 27 23:07:10 CEST 2007


Author: stepan
Date: 2007-06-27 23:07:10 +0200 (Wed, 27 Jun 2007)
New Revision: 387

Added:
   LinuxBIOSv3/arch/x86/geodelx/geodelx.c
   LinuxBIOSv3/arch/x86/geodelx/stage0.S
Removed:
   LinuxBIOSv3/arch/x86/geodelx.c
   LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S
Modified:
   LinuxBIOSv3/arch/x86/Makefile
Log:
make cpu code future proof

Signed-off-by: Stefan Reinauer <stepan at coresystems.de>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>



Modified: LinuxBIOSv3/arch/x86/Makefile
===================================================================
--- LinuxBIOSv3/arch/x86/Makefile	2007-06-27 21:01:01 UTC (rev 386)
+++ LinuxBIOSv3/arch/x86/Makefile	2007-06-27 21:07:10 UTC (rev 387)
@@ -83,7 +83,7 @@
 	STAGE0_CAR_OBJ = stage0_i586.o
 else
 ifeq ($(CONFIG_CPU_AMD_GEODELX),y)
-	STAGE0_CAR_OBJ = stage0_amd_geodelx.o
+	STAGE0_CAR_OBJ = geodelx/stage0.o
 else
 	STAGE0_CAR_OBJ = stage0_i586.o
 endif
@@ -181,4 +181,13 @@
 	$(Q)printf "  AS      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(AS) $(obj)/arch/x86/stage0_asm.s -o $@
 
+$(obj)/arch/x86/geodelx/stage0.o: $(src)/arch/x86/geodelx/stage0.S
+	$(Q)mkdir -p $(obj)/arch/x86/geodelx
+	$(Q)printf "  CC      $(subst $(shell pwd)/,,$(@))\n"
+	$(Q)$(CC) -E $(LINUXBIOSINCLUDE) $< \
+		-o $(obj)/arch/x86/stage0_asm.s -DBOOTBLK=0x1f00 \
+		-DRESRVED=0xf0 -DDATE=\"`date +%Y/%m/%d`\"
+	$(Q)printf "  AS      $(subst $(shell pwd)/,,$(@))\n"
+	$(Q)$(AS) $(obj)/arch/x86/stage0_asm.s -o $@
+
 endif

Copied: LinuxBIOSv3/arch/x86/geodelx/geodelx.c (from rev 386, LinuxBIOSv3/arch/x86/geodelx.c)
===================================================================
--- LinuxBIOSv3/arch/x86/geodelx/geodelx.c	                        (rev 0)
+++ LinuxBIOSv3/arch/x86/geodelx/geodelx.c	2007-06-27 21:07:10 UTC (rev 387)
@@ -0,0 +1,580 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2006 Indrek Kruusa <indrek.kruusa at artecdesign.ee>
+ * Copyright (C) 2006 Ronald G. Minnich <rminnich at gmail.com>
+ * Copyright (C) 2007 Advanced Micro Devices, 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 <types.h>
+#include <lib.h>
+#include <console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <msr.h>
+#include <io.h>
+#include <amd_geodelx.h>
+#include <spd.h>
+
+/* all these functions used to be in a lot of fiddly little files.  To
+  * make it easier to find functions, we are merging them here. This
+  * file is our first real cpu-specific support file and should serve
+  * as a model for v3 cpu-specific support. So, warning, you might
+  * think it makes sense to split this file up, but we've tried that,
+  * and it sucks.
+  */
+
+/**
+  * geodelx_msr_init Set up Geode LX registers for sane behaviour. Set
+  * all low memory (under 1MB) to write back.  Do some setup for cache
+  * as ram as well.
+  */
+void geodelx_msr_init(void)
+{
+	msr_t msr;
+	/* Setup access to the cache for under 1MB. */
+	msr.hi = 0x24fffc02;
+	msr.lo = 0x1000A000;	/* 0-A0000 write back */
+	wrmsr(CPU_RCONF_DEFAULT, msr);
+
+	msr.hi = 0x0;		/* write back */
+	msr.lo = 0x0;
+	wrmsr(CPU_RCONF_A0_BF, msr);
+	wrmsr(CPU_RCONF_C0_DF, msr);
+	wrmsr(CPU_RCONF_E0_FF, msr);
+
+	/* Setup access to the cache for under 640K. Note MC not setup yet. */
+	msr.hi = 0x20000000;
+	msr.lo = 0xfff80;
+	wrmsr(MSR_GLIU0 + 0x20, msr);
+
+	msr.hi = 0x20000000;
+	msr.lo = 0x80fffe0;
+	wrmsr(MSR_GLIU0 + 0x21, msr);
+
+	msr.hi = 0x20000000;
+	msr.lo = 0xfff80;
+	wrmsr(MSR_GLIU1 + 0x20, msr);
+
+	msr.hi = 0x20000000;
+	msr.lo = 0x80fffe0;
+	wrmsr(MSR_GLIU1 + 0x21, msr);
+
+}
+
+
+/** 
+  * start_time1 Starts Timer 1 for port 61 use. FIXME try to figure
+  * out what these values mean.
+  */
+void start_timer1(void)
+{
+	outb(0x56, 0x43);
+	outb(0x12, 0x41);
+}
+
+/** 
+  * system_preinit Very early initialization needed for almost
+  * everything else.  Currently, all we do is start timer1.
+  */
+void system_preinit(void)
+{
+	start_timer1();
+}
+
+/* cpu bug management */
+/**
+ *
+ *	pci_deadlock Bugtool #465 and #609 PCI cache deadlock There is
+ *	also fix code in cache and PCI functions. This bug is very is
+ *	pervasive.
+ *
+ */
+static void pci_deadlock(void)
+{
+	msr_t msr;
+
+	/*
+	 * forces serialization of all load misses. Setting this bit prevents the 
+	 * DM pipe from backing up if a read request has to be held up waiting 
+	 * for PCI writes to complete.
+	 */
+	msr = rdmsr(CPU_DM_CONFIG0);
+	msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
+	wrmsr(CPU_DM_CONFIG0, msr);
+
+	/* write serialize memory hole to PCI. Need to unWS when something is 
+	 * shadowed regardless of cachablility.
+	 */
+	msr.lo = 0x021212121;
+	msr.hi = 0x021212121;
+	wrmsr(CPU_RCONF_A0_BF, msr);
+	wrmsr(CPU_RCONF_C0_DF, msr);
+	wrmsr(CPU_RCONF_E0_FF, msr);
+}
+
+/**	disable_memory_reorder PBZ 3659: The MC reordered transactions
+  *	incorrectly and breaks coherency.  Disable reording and take a
+  *	potential performance hit.  This is safe to do here and not in
+  *	MC init since there is nothing to maintain coherency with and
+  *	the cache is not enabled yet.
+  */
+/****************************************************************************/
+static void disable_memory_reorder(void)
+{
+	msr_t msr;
+
+	msr = rdmsr(MC_CF8F_DATA);
+	msr.hi |= CF8F_UPPER_REORDER_DIS_SET;
+	wrmsr(MC_CF8F_DATA, msr);
+}
+
+/**
+  * Fix up register settings to manage known CPU bugs.  For cpu
+  * version C3. Should be the only released version
+  */
+void cpu_bug(void)
+{
+	pci_deadlock();
+	disable_memory_reorder();
+	printk(BIOS_DEBUG, "Done cpubug fixes \n");
+}
+
+/**
+ * Reset the phase locked loop hardware. After power on as part of
+ * this operation, we have to set the clock hardware and reboot. Thus,
+ * we have to know if we have been here before. To do this, we use the
+ * RSTPLL_LOWER_SWFLAGS_SHIFT flag in the msrGlcpSysRstpll. Also, the
+ * clocks can either be configured via passed-in parameters or
+ * hardware straps. Once set, we yank the hardware reset line and
+ * hlt. We should never reach the hlt, but one never knows.
+ *
+ * @param manualconf If non-zero, use passed-in parameters to
+ * determine how to configure pll -- manual or automagic. 
+ * If manual, use passed-in parameters pll_hi and pll_lo
+ * @param pll_hi value to use for the high 32 bits of the pll msr
+ * @param pll_lo value to use for the low 32 bits of the pll msr
+ */
+void pll_reset(int manualconf, u32 pll_hi, u32 pll_lo)
+{
+	msr_t msrGlcpSysRstpll;
+
+	msrGlcpSysRstpll = rdmsr(GLCP_SYS_RSTPLL);
+
+	printk(BIOS_DEBUG, 
+		"_MSR GLCP_SYS_RSTPLL (%08x) value is: %08x:%08x\n", msrGlcpSysRstpll.hi, msrGlcpSysRstpll.lo);
+	post_code(POST_PLL_INIT);
+
+	if (!(msrGlcpSysRstpll.lo & (1 << RSTPLL_LOWER_SWFLAGS_SHIFT))) {
+		printk(BIOS_DEBUG,"Configuring PLL\n");
+		if (manualconf) {
+			post_code(POST_PLL_MANUAL);
+			/* CPU and GLIU mult/div (GLMC_CLK = GLIU_CLK / 2)  */
+			msrGlcpSysRstpll.hi = pll_hi;
+
+			/* Hold Count - how long we will sit in reset */
+			msrGlcpSysRstpll.lo = pll_lo;
+		} else {
+			/*automatic configuration (straps) */
+			post_code(POST_PLL_STRAP);
+			msrGlcpSysRstpll.lo &=
+			    ~(0xFF << RSTPPL_LOWER_HOLD_COUNT_SHIFT);
+			msrGlcpSysRstpll.lo |=
+			    (0xDE << RSTPPL_LOWER_HOLD_COUNT_SHIFT);
+			msrGlcpSysRstpll.lo &=
+			    ~(RSTPPL_LOWER_COREBYPASS_SET |
+			      RSTPPL_LOWER_MBBYPASS_SET);
+			msrGlcpSysRstpll.lo |=
+			    RSTPPL_LOWER_COREPD_SET | RSTPPL_LOWER_CLPD_SET;
+		}
+		/* Use SWFLAGS to remember: "we've already been here"  */
+		msrGlcpSysRstpll.lo |= (1 << RSTPLL_LOWER_SWFLAGS_SHIFT);
+
+		/* "reset the chip" value */
+		msrGlcpSysRstpll.lo |= RSTPPL_LOWER_CHIP_RESET_SET;
+		wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll);
+
+		/*      You should never get here..... The chip has reset. */
+		printk(BIOS_EMERG,"CONFIGURING PLL FAILURE -- HALT\n");
+		post_code(POST_PLL_RESET_FAIL);
+		__asm__ __volatile__("hlt\n");
+
+	}
+	printk(BIOS_DEBUG, "Done pll_reset\n");
+	return;
+}
+
+
+/**
+ * Return the CPU clock rate. Rates in this system are always returned
+ * as multkiples of 33 Mhz.
+ *
+ */
+u32 cpu_speed(void)
+{
+	u32 speed;
+	msr_t msr;
+
+	msr = rdmsr(GLCP_SYS_RSTPLL);
+	speed = ((((msr.hi >> RSTPLL_UPPER_CPUMULT_SHIFT) & 0x1F) + 1) * 333) / 10;
+	if ((((((msr.hi >> RSTPLL_UPPER_CPUMULT_SHIFT) & 0x1F) + 1) * 333) % 10) > 5) {
+		++speed;
+	}
+	return (speed);
+}
+
+/**
+ * Return the Geode Link clock rate.  Rates in this system are always
+ * returned as multkiples of 33 Mhz.
+ *
+ */
+u32 geode_link_speed(void)
+{
+	unsigned int speed;
+	msr_t msr;
+
+	msr = rdmsr(GLCP_SYS_RSTPLL);
+	speed = ((((msr.hi >> RSTPLL_UPPER_GLMULT_SHIFT) & 0x1F) + 1) * 333) / 10;
+	if ((((((msr.hi >> RSTPLL_UPPER_GLMULT_SHIFT) & 0x1F) + 1) * 333) % 10) > 5) {
+		++speed;
+	}
+	return (speed);
+}
+
+
+/**
+ * Return the PCI bus clock rate.  Rates in this system are always
+ * returned as multkiples of 33 Mhz.
+ *
+ */
+u32 pci_speed(void)
+{
+	msr_t msr;
+
+	msr = rdmsr(GLCP_SYS_RSTPLL);
+	if (msr.hi & (1 << RSTPPL_LOWER_PCISPEED_SHIFT)) {
+		return (66);
+	} else {
+		return (33);
+	}
+}
+
+/**
+ * set_delay_control. This is Black Magic DRAM timing
+ * juju(http://www.thefreedictionary.com/juju) Dram delay depends on
+ * cpu clock, memory bus clock, memory bus loading, memory bus
+ * termination, your middle initial (ha! caught you!), Geode Link
+ * clock rate, and dram timing specifications. From this the code
+ * computes a number which is "known to work". No, hardware is not an
+ * exact science. And, finally, if an FS2 (jtag debugger) is hooked
+ * up, then just don't to anything. This code was written by a master
+ * of the Dark Arts at AMD and should not be modified in any way.
+ * 
+ * @param num_banks How many banks of DRAM there are
+ * @param dimm0 DIMM 0 SMBus address
+ * @param dimm1 DIMM 1 SMBus address
+ * @param sram_width Data width of the SDRAM
+ */
+
+void set_delay_control(u8 dimm0, u8 dimm1)
+{
+	u32 msrnum, glspeed;
+	u8 spdbyte0, spdbyte1;
+	int numdimms = 0;
+	msr_t msr;
+
+	glspeed = geode_link_speed();
+
+	/* fix delay controls for DM and IM arrays */
+	msrnum = CPU_BC_MSS_ARRAY_CTL0;
+	msr.hi = 0;
+	msr.lo = 0x2814D352;
+	wrmsr(msrnum, msr);
+
+	msrnum = CPU_BC_MSS_ARRAY_CTL1;
+	msr.hi = 0;
+	msr.lo = 0x1068334D;
+	wrmsr(msrnum, msr);
+
+	msrnum = CPU_BC_MSS_ARRAY_CTL2;
+	msr.hi = 0x00000106;
+	msr.lo = 0x83104104;
+	wrmsr(msrnum, msr);
+
+	msrnum = GLCP_FIFOCTL;
+	msr = rdmsr(msrnum);
+	msr.hi = 0x00000005;
+	wrmsr(msrnum, msr);
+
+	/* Enable setting */
+	msrnum = CPU_BC_MSS_ARRAY_CTL_ENA;
+	msr.hi = 0;
+	msr.lo = 0x00000001;
+	wrmsr(msrnum, msr);
+
+	/* Debug Delay Control Setup Check
+	  * 
+	  *  Leave it alone if it has been setup. FS2 or something is here. 
+	  */
+	msrnum = GLCP_DELAY_CONTROLS;
+	msr = rdmsr(msrnum);
+	if (msr.lo & ~(0x7C0)) {
+		return;
+	}
+
+	/*
+	 * Delay Controls based on DIMM loading. UGH!
+	 * # of Devices = Module Width (SPD6) / Device Width(SPD13) * Physical Banks(SPD5)
+	 * Note - We only support module width of 64.
+	 */
+	spdbyte0 = smbus_read_byte(dimm0, SPD_PRIMARY_SDRAM_WIDTH);
+	if (spdbyte0 != 0xFF) {
+		numdimms++;
+		spdbyte0 = (unsigned char)64 / spdbyte0 *
+		    (unsigned char)(smbus_read_byte(dimm0, SPD_NUM_DIMM_BANKS));
+	} else {
+		spdbyte0 = 0;
+	}
+
+	spdbyte1 = smbus_read_byte(dimm1, SPD_PRIMARY_SDRAM_WIDTH);
+	if (spdbyte1 != 0xFF) {
+		numdimms++;
+		spdbyte1 = (unsigned char)64 / spdbyte1 *
+		    (unsigned char)(smbus_read_byte(dimm1, SPD_NUM_DIMM_BANKS));
+	} else {
+		spdbyte1 = 0;
+	}
+
+/* The current thinking. Subject to change...
+
+;								   "FUTURE ROBUSTNESS" PROPOSAL
+;								   ----------------------------
+;		DIMM	 Max MBUS					   MC 0x2000001A bits 26:24
+;DIMMs	devices	 Frequency	 MCP 0x4C00000F Setting		 vvv
+;-----	-------	 ---------	 ----------------------	 ----------
+;1		 4		 400MHz		 0x82*100FF 0x56960004		  4
+;1		 8		 400MHz		 0x82*100AA 0x56960004		  4
+;1		 16		 400MHz		 0x82*10055 0x56960004		  4
+;
+;2		 4,4	 400MHz		 0x82710000 0x56960004		  4
+;2		 8,8	 400MHz		 0xC27100A5 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
+;
+;2		16,4	 >333		 0xB27100A5 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
+;2		16,8	 >333		 0xB27100A5 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
+;2		16,16	 >333		 0xB2710000 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
+;
+;1		 4		 <=333MHz	 0x83*100FF 0x56960004		  3
+;1		 8		 <=333MHz	 0x83*100AA 0x56960004		  3
+;1		 16		 <=333MHz	 0x83*100AA 0x56960004		  3
+;
+;2		 4,4	 <=333MHz	 0x837100A5 0x56960004		  3
+;2		 8,8	 <=333MHz	 0x937100A5 0x56960004		  3
+;
+;2		16,4	 <=333MHz	 0xB37100A5 0x56960004		  3	*** OUT OF PUBLISHED ENVELOPE ***
+;2		16,8	 <=333MHz	 0xB37100A5 0x56960004		  3	*** OUT OF PUBLISHED ENVELOPE ***
+;2		16,16	 <=333MHz	 0xB37100A5 0x56960004		  3	*** OUT OF PUBLISHED ENVELOPE ***
+;=========================================================================
+;* - Bit 55 (disable SDCLK 1,3,5) should be set if there is a single DIMM in slot 0,
+;	 but it should be clear for all 2 DIMM settings and if a single DIMM is in slot 1.
+;	 Bits 54:52 should always be set to '111'.
+
+;No VTT termination
+;-------------------------------------
+;ADDR/CTL have 22 ohm series R
+;DQ/DQM/DQS have 33 ohm series R
+;
+;		DIMM	 Max MBUS
+;DIMMs	devices	 Frequency	 MCP 0x4C00000F Setting
+;-----	-------	 ---------	 ----------------------
+;1		 4		 400MHz		 0xF2F100FF 0x56960004		  4			The MC changes improve Salsa.
+;1		 8		 400MHz		 0xF2F100FF 0x56960004		  4			Delay controls no real change,
+;1		 4		 <=333MHz	 0xF2F100FF 0x56960004		  3			just fixing typo in left side.
+;1		 8		 <=333MHz	 0xF2F100FF 0x56960004		  3
+;1		 16		 <=333MHz	 0xF2F100FF 0x56960004		  3
+*/
+	msr.hi = msr.lo = 0;
+
+	if (spdbyte0 == 0 || spdbyte1 == 0) {
+		/* one dimm solution */
+		if (spdbyte1 == 0) {
+			msr.hi |= 0x000800000;
+		}
+		spdbyte0 += spdbyte1;
+		if (spdbyte0 > 8) {
+			/* large dimm */
+			if (glspeed < 334) {
+				msr.hi |= 0x0837100AA;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x082710055;
+				msr.lo |= 0x056960004;
+			}
+		} else if (spdbyte0 > 4) {
+			/* medium dimm */
+			if (glspeed < 334) {
+				msr.hi |= 0x0837100AA;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x0827100AA;
+				msr.lo |= 0x056960004;
+			}
+		} else {
+			/* small dimm */
+			if (glspeed < 334) {
+				msr.hi |= 0x0837100FF;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x0827100FF;
+				msr.lo |= 0x056960004;
+			}
+		}
+	} else {
+		/* two dimm solution */
+		spdbyte0 += spdbyte1;
+		if (spdbyte0 > 24) {
+			/* huge dimms */
+			if (glspeed < 334) {
+				msr.hi |= 0x0B37100A5;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x0B2710000;
+				msr.lo |= 0x056960004;
+			}
+		} else if (spdbyte0 > 16) {
+			/* large dimms */
+			if (glspeed < 334) {
+				msr.hi |= 0x0B37100A5;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x0B27100A5;
+				msr.lo |= 0x056960004;
+			}
+		} else if (spdbyte0 >= 8) {
+			/* medium dimms */
+			if (glspeed < 334) {
+				msr.hi |= 0x0937100A5;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x0C27100A5;
+				msr.lo |= 0x056960004;
+			}
+		} else {
+			/* small dimms */
+			if (glspeed < 334) {
+				msr.hi |= 0x0837100A5;
+				msr.lo |= 0x056960004;
+			} else {
+				msr.hi |= 0x082710000;
+				msr.lo |= 0x056960004;
+			}
+		}
+	}
+	wrmsr(GLCP_DELAY_CONTROLS, msr);
+	return;
+}
+
+/**
+ * cpu_reg_init. All cpu register settings, here in one place, and
+ * done in the proper order.
+ *
+ * @param debug_clock_disable Disable the debug clock to save power. Currently ignored, but we need to 
+ * pick this up from a CMOS setting in future. 
+ * @param dimm0 SMBus address of dimm0 (mainboard dependent)
+ * @param dimm1 SMBus address of dimm1 (mainboard dependent)
+ */
+void cpu_reg_init(int debug_clock_disable, u8 dimm0, u8 dimm1)
+{
+	int msrnum;
+	msr_t msr;
+
+	/* Castle 2.0 BTM periodic sync period. */
+	/*      [40:37] 1 sync record per 256 bytes */
+	msrnum = CPU_PF_CONF;
+	msr = rdmsr(msrnum);
+	msr.hi |= (0x8 << 5);
+	wrmsr(msrnum, msr);
+
+	/*
+	   ; Castle performance setting.
+	   ; Enable Quack for fewer re-RAS on the MC
+	 */
+	msrnum = GLIU0_ARB;
+	msr = rdmsr(msrnum);
+	msr.hi &= ~ARB_UPPER_DACK_EN_SET;
+	msr.hi |= ARB_UPPER_QUACK_EN_SET;
+	wrmsr(msrnum, msr);
+
+	msrnum = GLIU1_ARB;
+	msr = rdmsr(msrnum);
+	msr.hi &= ~ARB_UPPER_DACK_EN_SET;
+	msr.hi |= ARB_UPPER_QUACK_EN_SET;
+	wrmsr(msrnum, msr);
+
+	/*      GLIU port active enable, limit south pole masters (AES and PCI) to one outstanding transaction. */
+	msrnum = GLIU1_PORT_ACTIVE;
+	msr = rdmsr(msrnum);
+	msr.lo &= ~0x880;
+	wrmsr(msrnum, msr);
+
+	/* Set the Delay Control in GLCP */
+	set_delay_control(dimm0, dimm1);
+
+	/*  Enable RSDC */
+	msrnum = CPU_AC_SMM_CTL;
+	msr = rdmsr(msrnum);
+	msr.lo |= SMM_INST_EN_SET;
+	wrmsr(msrnum, msr);
+
+	/* FPU imprecise exceptions bit */
+	msrnum = CPU_FPU_MSR_MODE;
+	msr = rdmsr(msrnum);
+	msr.lo |= FPU_IE_SET;
+	wrmsr(msrnum, msr);
+
+	/* Power Savers (Do after BIST) */
+	/* Enable Suspend on HLT & PAUSE instructions */
+	msrnum = CPU_XC_CONFIG;
+	msr = rdmsr(msrnum);
+	msr.lo |= XC_CONFIG_SUSP_ON_HLT | XC_CONFIG_SUSP_ON_PAUSE;
+	wrmsr(msrnum, msr);
+
+	/* Enable SUSP and allow TSC to run in Suspend (keep speed detection happy) */
+	msrnum = CPU_BC_CONF_0;
+	msr = rdmsr(msrnum);
+	msr.lo |= TSC_SUSP_SET | SUSP_EN_SET;
+	msr.lo &= 0x0F0FFFFFF;
+	msr.lo |= 0x002000000;	/* PBZ213: Set PAUSEDLY = 2 */
+	wrmsr(msrnum, msr);
+
+	/* Disable the debug clock to save power. */
+	/* NOTE: leave it enabled for fs2 debug */
+	if (debug_clock_disable && 0){
+		msrnum = GLCP_DBGCLKCTL;
+		msr.hi = 0;
+		msr.lo = 0;
+		wrmsr(msrnum, msr);
+	}
+
+	/* Setup throttling delays to proper mode if it is ever enabled. */
+	msrnum = GLCP_TH_OD;
+	msr.hi = 0;
+	msr.lo = 0x00000603C;
+	wrmsr(msrnum, msr);
+	/* fix cpu bugs */
+#warning testing fixing bugs in initram
+	cpu_bug();
+}

Copied: LinuxBIOSv3/arch/x86/geodelx/stage0.S (from rev 385, LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S)
===================================================================
--- LinuxBIOSv3/arch/x86/geodelx/stage0.S	                        (rev 0)
+++ LinuxBIOSv3/arch/x86/geodelx/stage0.S	2007-06-27 21:07:10 UTC (rev 387)
@@ -0,0 +1,443 @@
+##
+## This file is part of the LinuxBIOS project.
+##
+## Copyright (C) 2000,2007 Ronald G. Minnich <rminnich at gmail.com>
+## Copyright (C) 2005 Eswar Nallusamy, LANL
+## Copyright (C) 2005 Tyan
+## (Written by Yinghai Lu <yhlu at tyan.com> for Tyan)
+## Copyright (C) 2007 coresystems GmbH
+## (Written by Stefan Reinauer <stepan at coresystems.de> for coresystems GmbH)
+## Copyright (C) 2007 Advanced Micro Devices, 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
+##
+
+/* Init code - Switch CPU to protected mode and enable Cache-as-Ram. */
+
+#include "../macros.h"
+#include <amd_geodelx.h>
+
+/* This is where the DCache will be mapped and be used as stack. It would be
+ * cool if it was the same base as LinuxBIOS normal stack.
+ */
+#define	LX_STACK_BASE		DCACHE_RAM_BASE
+#define	LX_STACK_END		LX_STACK_BASE+(DCACHE_RAM_SIZE-4)
+
+#define	LX_NUM_CACHELINES	0x080	/* There are 128 lines per way. */
+#define	LX_CACHELINE_SIZE	0x020	/* There are 32 bytes per line. */
+#define	LX_CACHEWAY_SIZE	(LX_NUM_CACHELINES * LX_CACHELINE_SIZE)
+#define	CR0_CD			0x40000000 /* Bit 30 = Cache Disable */
+#define	CR0_NW			0x20000000 /* Bit 29 = Not Write Through */
+
+#define ROM_CODE_SEG 0x08
+#define ROM_DATA_SEG 0x10
+
+#define CACHE_RAM_CODE_SEG 0x18
+#define CACHE_RAM_DATA_SEG 0x20
+
+	.code16
+	.globl _stage0
+_stage0:
+	cli
+
+	/* Save the BIST result. */
+	movl	%eax, %ebp;
+
+	/* Thanks to kmliu at sis.com.tw for this TLB fix. */
+	/* IMMEDIATELY invalidate the translation lookaside buffer before
+	 * executing any further code. Even though paging is disabled we
+	 * could still get false address translations due to the TLB if we
+	 * didn't invalidate it.
+	 */
+
+	xorl	%eax, %eax
+	movl	%eax, %cr3	/* Invalidate TLB */
+
+	/* Switch to protected mode. */
+
+	/* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux)
+	 * using BFD version 2.15.94.0.2.2 20041220 this works fine without
+	 * all the ld hackery and so on. So leave it as is with this comment. 
+	 */
+
+	data32	lgdt %cs:gdtptr
+
+	movl	%cr0, %eax
+	andl	$0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */
+	orl	$0x60000001, %eax /* CD, NW, PE = 1 */
+	movl	%eax, %cr0
+
+	/* Restore BIST result. */
+	movl	%ebp, %eax
+
+	// port80_post(0x23)
+
+	/* Now we are in protected mode. Jump to a 32 bit code segment. */
+	data32 ljmp    $ROM_CODE_SEG, $protected_stage0
+	/* I am leaving this weird jump in here in the event that future gas
+	 * bugs force it to be used.
+	 */
+	#.byte 0x66
+	.code32
+	#ljmp    $ROM_CODE_SEG, $protected_stage0
+
+	#.code16
+	.align  4
+	.globl gdt16
+gdt16 = . - _stage0 
+gdt16x:
+	.word	gdt16xend - gdt16x -1	/* Compute the table limit. */
+	.long	gdt16x
+	.word	0
+
+	/* selgdt 0x08, flat code segment */
+	.word	0xffff, 0x0000
+	.byte	0x00, 0x9b, 0xcf, 0x00
+
+	/* selgdt 0x10, flat data segment */
+	.word	0xffff, 0x0000
+	.byte	0x00, 0x93, 0xcf, 0x00
+gdt16xend:
+
+	/* From now on we are 32bit. */
+	.code32
+
+	/* We have two gdts where we could have one. That is ok.
+	 *
+	 * Let's not worry about this -- optimizing gdt is pointless since
+	 * we're only in it for a little bit.
+	 *
+	 * BTW note the trick below: The GDT points to ITSELF, and the first
+	 * good descriptor is at offset 8. So you word-align the table, and
+	 * then because you chose 8, you get a nice 64-bit aligned GDT entry,
+	 * which is good as this is the size of the entry.
+	 *
+	 * Just in case you ever wonder why people do this. 
+	 */
+	.align  4
+	.globl gdtptr
+	.globl gdt_limit
+gdt_limit = gdt_end - gdt - 1   /* Compute the table limit. */
+
+gdt:
+gdtptr:
+	.word	gdt_end - gdt -1 /* Compute the table limit. */
+	.long	gdt              /* We know the offset. */
+	.word	0
+
+	/* selgdt 0x08, flat code segment */
+	.word	0xffff, 0x0000
+	.byte	0x00, 0x9b, 0xcf, 0x00
+
+	/* selgdt 0x10, flat data segment */
+	.word	0xffff, 0x0000
+	.byte	0x00, 0x93, 0xcf, 0x00
+
+	/* selgdt 0x18, flat code segment for CAR */
+	.word	0xffff, 0x0000
+	.byte	0x00, 0x9b, 0xcf, 0x00
+
+	/* selgdt 0x20, flat data segment for CAR */
+	.word	0xffff, 0x0000
+	.byte	0x00, 0x93, 0xcf, 0x00
+gdt_end:
+
+	/*
+	 * When we come here we are in protected mode. We expand the stack
+	 * and copy the data segment from ROM to the memory.
+	 *
+	 * After that, we call the chipset bootstrap routine that
+	 * does what is left of the chipset initialization.
+	 *
+	 * NOTE: Aligned to 4 so that we are sure that the prefetch
+	 * cache will be reloaded.
+	 */
+
+	.align  4
+	.globl protected_stage0
+protected_stage0:
+	// This code was used by v2. TODO
+	lgdt	%cs:gdtptr
+	ljmp	$ROM_CODE_SEG, $__protected_stage0
+
+.globl __protected_stage0
+__protected_stage0:
+	/* Save the BIST value. */
+	movl	%eax, %ebp
+
+	port80_post(0x01)
+
+	movw	$ROM_DATA_SEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %ss
+	movw	%ax, %fs
+	movw	%ax, %gs
+
+	/* Restore the BIST value to %eax. */
+	movl	%ebp, %eax
+
+.align 4
+	/* Here begins CAR support. */
+	/* This particular code is straight from LinuxBIOS V2. */
+
+	/* DCacheSetup: Setup data cache for use as RAM for a stack. */
+DCacheSetup:
+
+	invd
+	/* Set cache properties. */
+	movl	$CPU_RCONF_DEFAULT, %ecx
+	rdmsr
+	/* 1MB system memory in write back 1|00100|00. */
+	movl	$0x010010000, %eax
+	wrmsr
+
+	/* In LX DCDIS is set after POR which disables the cache..., clear
+	 * this bit.
+	 */
+	movl	CPU_DM_CONFIG0,%ecx
+	rdmsr
+	/* TODO: Make consistent with i$ init, either whole reg = 0, or just
+	 * this bit...
+	 */
+	andl	$(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax
+	wrmsr
+
+	/* Get cache timing params from BIOS config data locations and apply. */
+	/* Fix delay controls for DM and IM arrays. */
+	movl	$CPU_BC_MSS_ARRAY_CTL0, %ecx
+	xorl	%edx, %edx
+	movl	$0x2814D352, %eax
+	wrmsr
+
+	movl	$CPU_BC_MSS_ARRAY_CTL1, %ecx
+	xorl	%edx, %edx
+	movl	$0x1068334D, %eax
+	wrmsr
+
+	movl	$CPU_BC_MSS_ARRAY_CTL2, %ecx
+	movl	$0x00000106, %edx
+	movl	$0x83104104, %eax
+	wrmsr
+
+	movl	$GLCP_FIFOCTL, %ecx
+	rdmsr
+	movl	$0x00000005, %edx
+	wrmsr
+
+	/* Enable setting. */
+	movl	$CPU_BC_MSS_ARRAY_CTL_ENA, %ecx
+	xorl	%edx, %edx
+	movl	$0x01, %eax
+	wrmsr
+
+	/* Get cleaned up. */
+	xorl	%edi, %edi
+	xorl	%esi, %esi
+	xorl	%ebp, %ebp
+
+	/* DCache Ways0 through Ways7 will be tagged for
+	 * LX_STACK_BASE + DCACHE_RAM_SIZE for holding stack.
+	 */
+	/* Remember, there is NO stack yet... */
+
+	/* Tell cache we want to fill Way 0 starting at the top. */
+	xorl	%edx, %edx
+	xorl	%eax, %eax
+	movl	$CPU_DC_INDEX, %ecx
+	wrmsr
+
+	/* Startaddress for tag of Way0: ebp will hold the incrementing
+	 * address. dont destroy!
+	 */
+	movl	$LX_STACK_BASE, %ebp	/* Init to start address. */
+	/* Set valid bit and tag for this Way (B[31:12] : Cache tag value for
+	 * line/way curr. selected by CPU_DC_INDEX.
+	 */
+	orl	$1, %ebp
+
+	/* Start tag Ways 0 with 128 lines with 32 bytes each: edi will hold
+	 * the line counter. dont destroy!
+	 */
+	movl	$LX_NUM_CACHELINES, %edi
+
+DCacheSetupFillWay:
+	/* Fill with dummy data: zero it so we can tell it from PCI memory
+	 * space (returns FFs).
+	 */
+	/* We will now store a line (32 bytes = 4 x 8 bytes = 4 quad-words). */
+	movw	$0x04, %si
+	xorl	%edx, %edx
+	xorl	%eax, %eax
+	movl	$CPU_DC_DATA, %ecx
+
+DCacheSetup_quadWordLoop:
+	wrmsr
+	decw	%si
+	jnz	DCacheSetup_quadWordLoop
+
+	/* Set the tag for this line, need to do this for every new cache
+	 * line to validate it!
+	 */
+	/* Accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX
+	 * increment and thus continue in the next cache line...
+	 */
+	xorl	%edx, %edx
+	movl	%ebp, %eax
+	movl	$CPU_DC_TAG, %ecx
+	wrmsr
+
+	/* Switch to next line. Lines are in Bits10:4. */
+	/* When index is crossing 0x7F -> 0x80 writing a RSVD bit as 0x80 is
+	 * not a valid CL anymore!
+	 */
+	movl	$CPU_DC_INDEX, %ecx
+	rdmsr
+	/* TODO: Probably would be more elegant to calculate this from
+	 * counter var edi...
+	 */
+	addl	$0x010, %eax
+	wrmsr
+
+	decl	%edi
+	jnz	DCacheSetupFillWay
+
+	/* 1 Way has been filled, forward start address for next Way,
+	 * terminate if we have reached end of desired address range.
+	 */
+	addl	$LX_CACHEWAY_SIZE, %ebp
+	cmpl	$LX_STACK_END, %ebp
+	jge	leave_DCacheSetup
+	movl	$LX_NUM_CACHELINES, %edi
+
+	/* Switch to next way. */
+	movl	$CPU_DC_INDEX, %ecx
+	rdmsr
+	addl	$0x01, %eax
+	/* Let's be sure: reset line index Bits10:4. */
+	andl	$0xFFFFF80F, %eax
+	wrmsr
+
+	jmp	DCacheSetupFillWay
+
+leave_DCacheSetup:
+	xorl	%edi, %edi
+	xorl	%esi, %esi
+	xorl	%ebp, %ebp
+
+	/* Disable the cache, but... DO NOT INVALIDATE the tags. */
+	/* Memory reads and writes will all hit in the cache. */
+	/* Cache updates and memory write-backs will not occur! */
+	movl	%cr0, %eax
+	orl	$(CR0_CD + CR0_NW), %eax	/* Set the CD and NW bits. */
+	movl	%eax, %cr0
+
+	/* Now point sp to the cached stack. */
+	/* The stack will be fully functional at this location. No system
+	 * memory is required at all!
+	 */
+	/* Set up the stack pointer. */
+	movl	$LX_STACK_END, %eax
+	movl	%eax, %esp
+
+	/* Test the stack. */
+	movl	$0x0F0F05A5A, %edx
+	pushl	%edx
+	popl	%ecx
+	cmpl	%ecx, %edx
+	je	DCacheSetupGood
+	movb	$0xC5, %al
+	outb	%al, $0x80
+
+DCacheSetupBad:
+	hlt		/* Issues */
+	jmp DCacheSetupBad
+
+DCacheSetupGood:
+	/* If you wanted to maintain the stack in memory you would need to
+	 * set the tags as dirty so the wbinvd would push out the old stack
+	 * contents to memory.
+	 */
+	/* Clear the cache, the following code from crt0.S.lb will setup
+	 * a new stack.
+	 */
+	wbinvd
+
+	/* At this point, CAR should be working. */
+	movl	$(LX_STACK_END), %eax
+	movl	%eax, %esp
+
+	/* Load a different set of data segments. */
+	movw	$CACHE_RAM_DATA_SEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %ss
+
+lout:
+	/* Restore the BIST result. */
+	movl	%ebp, %eax
+	/* We need to set ebp? No need. */
+	movl	%esp, %ebp
+	pushl	%eax		/* BIST */
+	call	stage1_main
+	/* We will not go back. */
+
+fixed_mtrr_msr:
+	.long   0x250, 0x258, 0x259
+	.long   0x268, 0x269, 0x26A
+	.long   0x26B, 0x26C, 0x26D
+	.long   0x26E, 0x26F
+var_mtrr_msr:
+	.long   0x200, 0x201, 0x202, 0x203
+	.long   0x204, 0x205, 0x206, 0x207
+	.long   0x208, 0x209, 0x20A, 0x20B
+	.long   0x20C, 0x20D, 0x20E, 0x20F
+	.long   0x000 /* NULL, end of table */
+
+# Reset vector.
+
+/*
+ * RVECTOR: size of reset vector, default is 0x10
+ * RESRVED: size of vpd code, default is 0xf0
+ * BOOTBLK: size of bootblock code, default is 0x1f00 (8k-256b)
+ */
+
+SEGMENT_SIZE = 0x10000
+RVECTOR      = 0x00010
+
+# Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here.
+# I think we should leave it this way forever, as the bugs come and
+# go -- and come again.
+#	.code16
+#	.section ".rom.text"
+.section ".reset", "ax"
+	.globl _resetjump
+_resetjump:
+	/* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */
+#	jmp _stage0
+	.byte  0xe9
+	.int   _stage0 - ( . + 2 )
+	/* Note: The above jump is hand coded to work around bugs in binutils.
+	 * 5 bytes are used for a 3 byte instruction. This works because x86
+	 * is little endian and allows us to use supported 32 bit relocations
+	 * instead of the weird 16 bit relocations that binutils does not
+	 * handle consistenly between versions because they are used so rarely.
+	 */
+.byte	0
+
+# Date? ID string? We might want to put something else in here.
+.ascii DATE
+
+# Checksum.
+#.word	0

Deleted: LinuxBIOSv3/arch/x86/geodelx.c
===================================================================
--- LinuxBIOSv3/arch/x86/geodelx.c	2007-06-27 21:01:01 UTC (rev 386)
+++ LinuxBIOSv3/arch/x86/geodelx.c	2007-06-27 21:07:10 UTC (rev 387)
@@ -1,580 +0,0 @@
-/*
- * This file is part of the LinuxBIOS project.
- *
- * Copyright (C) 2006 Indrek Kruusa <indrek.kruusa at artecdesign.ee>
- * Copyright (C) 2006 Ronald G. Minnich <rminnich at gmail.com>
- * Copyright (C) 2007 Advanced Micro Devices, 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 <types.h>
-#include <lib.h>
-#include <console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <string.h>
-#include <msr.h>
-#include <io.h>
-#include <amd_geodelx.h>
-#include <spd.h>
-
-/* all these functions used to be in a lot of fiddly little files.  To
-  * make it easier to find functions, we are merging them here. This
-  * file is our first real cpu-specific support file and should serve
-  * as a model for v3 cpu-specific support. So, warning, you might
-  * think it makes sense to split this file up, but we've tried that,
-  * and it sucks.
-  */
-
-/**
-  * geodelx_msr_init Set up Geode LX registers for sane behaviour. Set
-  * all low memory (under 1MB) to write back.  Do some setup for cache
-  * as ram as well.
-  */
-void geodelx_msr_init(void)
-{
-	msr_t msr;
-	/* Setup access to the cache for under 1MB. */
-	msr.hi = 0x24fffc02;
-	msr.lo = 0x1000A000;	/* 0-A0000 write back */
-	wrmsr(CPU_RCONF_DEFAULT, msr);
-
-	msr.hi = 0x0;		/* write back */
-	msr.lo = 0x0;
-	wrmsr(CPU_RCONF_A0_BF, msr);
-	wrmsr(CPU_RCONF_C0_DF, msr);
-	wrmsr(CPU_RCONF_E0_FF, msr);
-
-	/* Setup access to the cache for under 640K. Note MC not setup yet. */
-	msr.hi = 0x20000000;
-	msr.lo = 0xfff80;
-	wrmsr(MSR_GLIU0 + 0x20, msr);
-
-	msr.hi = 0x20000000;
-	msr.lo = 0x80fffe0;
-	wrmsr(MSR_GLIU0 + 0x21, msr);
-
-	msr.hi = 0x20000000;
-	msr.lo = 0xfff80;
-	wrmsr(MSR_GLIU1 + 0x20, msr);
-
-	msr.hi = 0x20000000;
-	msr.lo = 0x80fffe0;
-	wrmsr(MSR_GLIU1 + 0x21, msr);
-
-}
-
-
-/** 
-  * start_time1 Starts Timer 1 for port 61 use. FIXME try to figure
-  * out what these values mean.
-  */
-void start_timer1(void)
-{
-	outb(0x56, 0x43);
-	outb(0x12, 0x41);
-}
-
-/** 
-  * system_preinit Very early initialization needed for almost
-  * everything else.  Currently, all we do is start timer1.
-  */
-void system_preinit(void)
-{
-	start_timer1();
-}
-
-/* cpu bug management */
-/**
- *
- *	pci_deadlock Bugtool #465 and #609 PCI cache deadlock There is
- *	also fix code in cache and PCI functions. This bug is very is
- *	pervasive.
- *
- */
-static void pci_deadlock(void)
-{
-	msr_t msr;
-
-	/*
-	 * forces serialization of all load misses. Setting this bit prevents the 
-	 * DM pipe from backing up if a read request has to be held up waiting 
-	 * for PCI writes to complete.
-	 */
-	msr = rdmsr(CPU_DM_CONFIG0);
-	msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
-	wrmsr(CPU_DM_CONFIG0, msr);
-
-	/* write serialize memory hole to PCI. Need to unWS when something is 
-	 * shadowed regardless of cachablility.
-	 */
-	msr.lo = 0x021212121;
-	msr.hi = 0x021212121;
-	wrmsr(CPU_RCONF_A0_BF, msr);
-	wrmsr(CPU_RCONF_C0_DF, msr);
-	wrmsr(CPU_RCONF_E0_FF, msr);
-}
-
-/**	disable_memory_reorder PBZ 3659: The MC reordered transactions
-  *	incorrectly and breaks coherency.  Disable reording and take a
-  *	potential performance hit.  This is safe to do here and not in
-  *	MC init since there is nothing to maintain coherency with and
-  *	the cache is not enabled yet.
-  */
-/****************************************************************************/
-static void disable_memory_reorder(void)
-{
-	msr_t msr;
-
-	msr = rdmsr(MC_CF8F_DATA);
-	msr.hi |= CF8F_UPPER_REORDER_DIS_SET;
-	wrmsr(MC_CF8F_DATA, msr);
-}
-
-/**
-  * Fix up register settings to manage known CPU bugs.  For cpu
-  * version C3. Should be the only released version
-  */
-void cpu_bug(void)
-{
-	pci_deadlock();
-	disable_memory_reorder();
-	printk(BIOS_DEBUG, "Done cpubug fixes \n");
-}
-
-/**
- * Reset the phase locked loop hardware. After power on as part of
- * this operation, we have to set the clock hardware and reboot. Thus,
- * we have to know if we have been here before. To do this, we use the
- * RSTPLL_LOWER_SWFLAGS_SHIFT flag in the msrGlcpSysRstpll. Also, the
- * clocks can either be configured via passed-in parameters or
- * hardware straps. Once set, we yank the hardware reset line and
- * hlt. We should never reach the hlt, but one never knows.
- *
- * @param manualconf If non-zero, use passed-in parameters to
- * determine how to configure pll -- manual or automagic. 
- * If manual, use passed-in parameters pll_hi and pll_lo
- * @param pll_hi value to use for the high 32 bits of the pll msr
- * @param pll_lo value to use for the low 32 bits of the pll msr
- */
-void pll_reset(int manualconf, u32 pll_hi, u32 pll_lo)
-{
-	msr_t msrGlcpSysRstpll;
-
-	msrGlcpSysRstpll = rdmsr(GLCP_SYS_RSTPLL);
-
-	printk(BIOS_DEBUG, 
-		"_MSR GLCP_SYS_RSTPLL (%08x) value is: %08x:%08x\n", msrGlcpSysRstpll.hi, msrGlcpSysRstpll.lo);
-	post_code(POST_PLL_INIT);
-
-	if (!(msrGlcpSysRstpll.lo & (1 << RSTPLL_LOWER_SWFLAGS_SHIFT))) {
-		printk(BIOS_DEBUG,"Configuring PLL\n");
-		if (manualconf) {
-			post_code(POST_PLL_MANUAL);
-			/* CPU and GLIU mult/div (GLMC_CLK = GLIU_CLK / 2)  */
-			msrGlcpSysRstpll.hi = pll_hi;
-
-			/* Hold Count - how long we will sit in reset */
-			msrGlcpSysRstpll.lo = pll_lo;
-		} else {
-			/*automatic configuration (straps) */
-			post_code(POST_PLL_STRAP);
-			msrGlcpSysRstpll.lo &=
-			    ~(0xFF << RSTPPL_LOWER_HOLD_COUNT_SHIFT);
-			msrGlcpSysRstpll.lo |=
-			    (0xDE << RSTPPL_LOWER_HOLD_COUNT_SHIFT);
-			msrGlcpSysRstpll.lo &=
-			    ~(RSTPPL_LOWER_COREBYPASS_SET |
-			      RSTPPL_LOWER_MBBYPASS_SET);
-			msrGlcpSysRstpll.lo |=
-			    RSTPPL_LOWER_COREPD_SET | RSTPPL_LOWER_CLPD_SET;
-		}
-		/* Use SWFLAGS to remember: "we've already been here"  */
-		msrGlcpSysRstpll.lo |= (1 << RSTPLL_LOWER_SWFLAGS_SHIFT);
-
-		/* "reset the chip" value */
-		msrGlcpSysRstpll.lo |= RSTPPL_LOWER_CHIP_RESET_SET;
-		wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll);
-
-		/*      You should never get here..... The chip has reset. */
-		printk(BIOS_EMERG,"CONFIGURING PLL FAILURE -- HALT\n");
-		post_code(POST_PLL_RESET_FAIL);
-		__asm__ __volatile__("hlt\n");
-
-	}
-	printk(BIOS_DEBUG, "Done pll_reset\n");
-	return;
-}
-
-
-/**
- * Return the CPU clock rate. Rates in this system are always returned
- * as multkiples of 33 Mhz.
- *
- */
-u32 cpu_speed(void)
-{
-	u32 speed;
-	msr_t msr;
-
-	msr = rdmsr(GLCP_SYS_RSTPLL);
-	speed = ((((msr.hi >> RSTPLL_UPPER_CPUMULT_SHIFT) & 0x1F) + 1) * 333) / 10;
-	if ((((((msr.hi >> RSTPLL_UPPER_CPUMULT_SHIFT) & 0x1F) + 1) * 333) % 10) > 5) {
-		++speed;
-	}
-	return (speed);
-}
-
-/**
- * Return the Geode Link clock rate.  Rates in this system are always
- * returned as multkiples of 33 Mhz.
- *
- */
-u32 geode_link_speed(void)
-{
-	unsigned int speed;
-	msr_t msr;
-
-	msr = rdmsr(GLCP_SYS_RSTPLL);
-	speed = ((((msr.hi >> RSTPLL_UPPER_GLMULT_SHIFT) & 0x1F) + 1) * 333) / 10;
-	if ((((((msr.hi >> RSTPLL_UPPER_GLMULT_SHIFT) & 0x1F) + 1) * 333) % 10) > 5) {
-		++speed;
-	}
-	return (speed);
-}
-
-
-/**
- * Return the PCI bus clock rate.  Rates in this system are always
- * returned as multkiples of 33 Mhz.
- *
- */
-u32 pci_speed(void)
-{
-	msr_t msr;
-
-	msr = rdmsr(GLCP_SYS_RSTPLL);
-	if (msr.hi & (1 << RSTPPL_LOWER_PCISPEED_SHIFT)) {
-		return (66);
-	} else {
-		return (33);
-	}
-}
-
-/**
- * set_delay_control. This is Black Magic DRAM timing
- * juju(http://www.thefreedictionary.com/juju) Dram delay depends on
- * cpu clock, memory bus clock, memory bus loading, memory bus
- * termination, your middle initial (ha! caught you!), Geode Link
- * clock rate, and dram timing specifications. From this the code
- * computes a number which is "known to work". No, hardware is not an
- * exact science. And, finally, if an FS2 (jtag debugger) is hooked
- * up, then just don't to anything. This code was written by a master
- * of the Dark Arts at AMD and should not be modified in any way.
- * 
- * @param num_banks How many banks of DRAM there are
- * @param dimm0 DIMM 0 SMBus address
- * @param dimm1 DIMM 1 SMBus address
- * @param sram_width Data width of the SDRAM
- */
-
-void set_delay_control(u8 dimm0, u8 dimm1)
-{
-	u32 msrnum, glspeed;
-	u8 spdbyte0, spdbyte1;
-	int numdimms = 0;
-	msr_t msr;
-
-	glspeed = geode_link_speed();
-
-	/* fix delay controls for DM and IM arrays */
-	msrnum = CPU_BC_MSS_ARRAY_CTL0;
-	msr.hi = 0;
-	msr.lo = 0x2814D352;
-	wrmsr(msrnum, msr);
-
-	msrnum = CPU_BC_MSS_ARRAY_CTL1;
-	msr.hi = 0;
-	msr.lo = 0x1068334D;
-	wrmsr(msrnum, msr);
-
-	msrnum = CPU_BC_MSS_ARRAY_CTL2;
-	msr.hi = 0x00000106;
-	msr.lo = 0x83104104;
-	wrmsr(msrnum, msr);
-
-	msrnum = GLCP_FIFOCTL;
-	msr = rdmsr(msrnum);
-	msr.hi = 0x00000005;
-	wrmsr(msrnum, msr);
-
-	/* Enable setting */
-	msrnum = CPU_BC_MSS_ARRAY_CTL_ENA;
-	msr.hi = 0;
-	msr.lo = 0x00000001;
-	wrmsr(msrnum, msr);
-
-	/* Debug Delay Control Setup Check
-	  * 
-	  *  Leave it alone if it has been setup. FS2 or something is here. 
-	  */
-	msrnum = GLCP_DELAY_CONTROLS;
-	msr = rdmsr(msrnum);
-	if (msr.lo & ~(0x7C0)) {
-		return;
-	}
-
-	/*
-	 * Delay Controls based on DIMM loading. UGH!
-	 * # of Devices = Module Width (SPD6) / Device Width(SPD13) * Physical Banks(SPD5)
-	 * Note - We only support module width of 64.
-	 */
-	spdbyte0 = smbus_read_byte(dimm0, SPD_PRIMARY_SDRAM_WIDTH);
-	if (spdbyte0 != 0xFF) {
-		numdimms++;
-		spdbyte0 = (unsigned char)64 / spdbyte0 *
-		    (unsigned char)(smbus_read_byte(dimm0, SPD_NUM_DIMM_BANKS));
-	} else {
-		spdbyte0 = 0;
-	}
-
-	spdbyte1 = smbus_read_byte(dimm1, SPD_PRIMARY_SDRAM_WIDTH);
-	if (spdbyte1 != 0xFF) {
-		numdimms++;
-		spdbyte1 = (unsigned char)64 / spdbyte1 *
-		    (unsigned char)(smbus_read_byte(dimm1, SPD_NUM_DIMM_BANKS));
-	} else {
-		spdbyte1 = 0;
-	}
-
-/* The current thinking. Subject to change...
-
-;								   "FUTURE ROBUSTNESS" PROPOSAL
-;								   ----------------------------
-;		DIMM	 Max MBUS					   MC 0x2000001A bits 26:24
-;DIMMs	devices	 Frequency	 MCP 0x4C00000F Setting		 vvv
-;-----	-------	 ---------	 ----------------------	 ----------
-;1		 4		 400MHz		 0x82*100FF 0x56960004		  4
-;1		 8		 400MHz		 0x82*100AA 0x56960004		  4
-;1		 16		 400MHz		 0x82*10055 0x56960004		  4
-;
-;2		 4,4	 400MHz		 0x82710000 0x56960004		  4
-;2		 8,8	 400MHz		 0xC27100A5 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
-;
-;2		16,4	 >333		 0xB27100A5 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
-;2		16,8	 >333		 0xB27100A5 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
-;2		16,16	 >333		 0xB2710000 0x56960004		  4	*** OUT OF PUBLISHED ENVELOPE ***
-;
-;1		 4		 <=333MHz	 0x83*100FF 0x56960004		  3
-;1		 8		 <=333MHz	 0x83*100AA 0x56960004		  3
-;1		 16		 <=333MHz	 0x83*100AA 0x56960004		  3
-;
-;2		 4,4	 <=333MHz	 0x837100A5 0x56960004		  3
-;2		 8,8	 <=333MHz	 0x937100A5 0x56960004		  3
-;
-;2		16,4	 <=333MHz	 0xB37100A5 0x56960004		  3	*** OUT OF PUBLISHED ENVELOPE ***
-;2		16,8	 <=333MHz	 0xB37100A5 0x56960004		  3	*** OUT OF PUBLISHED ENVELOPE ***
-;2		16,16	 <=333MHz	 0xB37100A5 0x56960004		  3	*** OUT OF PUBLISHED ENVELOPE ***
-;=========================================================================
-;* - Bit 55 (disable SDCLK 1,3,5) should be set if there is a single DIMM in slot 0,
-;	 but it should be clear for all 2 DIMM settings and if a single DIMM is in slot 1.
-;	 Bits 54:52 should always be set to '111'.
-
-;No VTT termination
-;-------------------------------------
-;ADDR/CTL have 22 ohm series R
-;DQ/DQM/DQS have 33 ohm series R
-;
-;		DIMM	 Max MBUS
-;DIMMs	devices	 Frequency	 MCP 0x4C00000F Setting
-;-----	-------	 ---------	 ----------------------
-;1		 4		 400MHz		 0xF2F100FF 0x56960004		  4			The MC changes improve Salsa.
-;1		 8		 400MHz		 0xF2F100FF 0x56960004		  4			Delay controls no real change,
-;1		 4		 <=333MHz	 0xF2F100FF 0x56960004		  3			just fixing typo in left side.
-;1		 8		 <=333MHz	 0xF2F100FF 0x56960004		  3
-;1		 16		 <=333MHz	 0xF2F100FF 0x56960004		  3
-*/
-	msr.hi = msr.lo = 0;
-
-	if (spdbyte0 == 0 || spdbyte1 == 0) {
-		/* one dimm solution */
-		if (spdbyte1 == 0) {
-			msr.hi |= 0x000800000;
-		}
-		spdbyte0 += spdbyte1;
-		if (spdbyte0 > 8) {
-			/* large dimm */
-			if (glspeed < 334) {
-				msr.hi |= 0x0837100AA;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x082710055;
-				msr.lo |= 0x056960004;
-			}
-		} else if (spdbyte0 > 4) {
-			/* medium dimm */
-			if (glspeed < 334) {
-				msr.hi |= 0x0837100AA;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x0827100AA;
-				msr.lo |= 0x056960004;
-			}
-		} else {
-			/* small dimm */
-			if (glspeed < 334) {
-				msr.hi |= 0x0837100FF;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x0827100FF;
-				msr.lo |= 0x056960004;
-			}
-		}
-	} else {
-		/* two dimm solution */
-		spdbyte0 += spdbyte1;
-		if (spdbyte0 > 24) {
-			/* huge dimms */
-			if (glspeed < 334) {
-				msr.hi |= 0x0B37100A5;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x0B2710000;
-				msr.lo |= 0x056960004;
-			}
-		} else if (spdbyte0 > 16) {
-			/* large dimms */
-			if (glspeed < 334) {
-				msr.hi |= 0x0B37100A5;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x0B27100A5;
-				msr.lo |= 0x056960004;
-			}
-		} else if (spdbyte0 >= 8) {
-			/* medium dimms */
-			if (glspeed < 334) {
-				msr.hi |= 0x0937100A5;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x0C27100A5;
-				msr.lo |= 0x056960004;
-			}
-		} else {
-			/* small dimms */
-			if (glspeed < 334) {
-				msr.hi |= 0x0837100A5;
-				msr.lo |= 0x056960004;
-			} else {
-				msr.hi |= 0x082710000;
-				msr.lo |= 0x056960004;
-			}
-		}
-	}
-	wrmsr(GLCP_DELAY_CONTROLS, msr);
-	return;
-}
-
-/**
- * cpu_reg_init. All cpu register settings, here in one place, and
- * done in the proper order.
- *
- * @param debug_clock_disable Disable the debug clock to save power. Currently ignored, but we need to 
- * pick this up from a CMOS setting in future. 
- * @param dimm0 SMBus address of dimm0 (mainboard dependent)
- * @param dimm1 SMBus address of dimm1 (mainboard dependent)
- */
-void cpu_reg_init(int debug_clock_disable, u8 dimm0, u8 dimm1)
-{
-	int msrnum;
-	msr_t msr;
-
-	/* Castle 2.0 BTM periodic sync period. */
-	/*      [40:37] 1 sync record per 256 bytes */
-	msrnum = CPU_PF_CONF;
-	msr = rdmsr(msrnum);
-	msr.hi |= (0x8 << 5);
-	wrmsr(msrnum, msr);
-
-	/*
-	   ; Castle performance setting.
-	   ; Enable Quack for fewer re-RAS on the MC
-	 */
-	msrnum = GLIU0_ARB;
-	msr = rdmsr(msrnum);
-	msr.hi &= ~ARB_UPPER_DACK_EN_SET;
-	msr.hi |= ARB_UPPER_QUACK_EN_SET;
-	wrmsr(msrnum, msr);
-
-	msrnum = GLIU1_ARB;
-	msr = rdmsr(msrnum);
-	msr.hi &= ~ARB_UPPER_DACK_EN_SET;
-	msr.hi |= ARB_UPPER_QUACK_EN_SET;
-	wrmsr(msrnum, msr);
-
-	/*      GLIU port active enable, limit south pole masters (AES and PCI) to one outstanding transaction. */
-	msrnum = GLIU1_PORT_ACTIVE;
-	msr = rdmsr(msrnum);
-	msr.lo &= ~0x880;
-	wrmsr(msrnum, msr);
-
-	/* Set the Delay Control in GLCP */
-	set_delay_control(dimm0, dimm1);
-
-	/*  Enable RSDC */
-	msrnum = CPU_AC_SMM_CTL;
-	msr = rdmsr(msrnum);
-	msr.lo |= SMM_INST_EN_SET;
-	wrmsr(msrnum, msr);
-
-	/* FPU imprecise exceptions bit */
-	msrnum = CPU_FPU_MSR_MODE;
-	msr = rdmsr(msrnum);
-	msr.lo |= FPU_IE_SET;
-	wrmsr(msrnum, msr);
-
-	/* Power Savers (Do after BIST) */
-	/* Enable Suspend on HLT & PAUSE instructions */
-	msrnum = CPU_XC_CONFIG;
-	msr = rdmsr(msrnum);
-	msr.lo |= XC_CONFIG_SUSP_ON_HLT | XC_CONFIG_SUSP_ON_PAUSE;
-	wrmsr(msrnum, msr);
-
-	/* Enable SUSP and allow TSC to run in Suspend (keep speed detection happy) */
-	msrnum = CPU_BC_CONF_0;
-	msr = rdmsr(msrnum);
-	msr.lo |= TSC_SUSP_SET | SUSP_EN_SET;
-	msr.lo &= 0x0F0FFFFFF;
-	msr.lo |= 0x002000000;	/* PBZ213: Set PAUSEDLY = 2 */
-	wrmsr(msrnum, msr);
-
-	/* Disable the debug clock to save power. */
-	/* NOTE: leave it enabled for fs2 debug */
-	if (debug_clock_disable && 0){
-		msrnum = GLCP_DBGCLKCTL;
-		msr.hi = 0;
-		msr.lo = 0;
-		wrmsr(msrnum, msr);
-	}
-
-	/* Setup throttling delays to proper mode if it is ever enabled. */
-	msrnum = GLCP_TH_OD;
-	msr.hi = 0;
-	msr.lo = 0x00000603C;
-	wrmsr(msrnum, msr);
-	/* fix cpu bugs */
-#warning testing fixing bugs in initram
-	cpu_bug();
-}

Deleted: LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S
===================================================================
--- LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S	2007-06-27 21:01:01 UTC (rev 386)
+++ LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S	2007-06-27 21:07:10 UTC (rev 387)
@@ -1,443 +0,0 @@
-##
-## This file is part of the LinuxBIOS project.
-##
-## Copyright (C) 2000,2007 Ronald G. Minnich <rminnich at gmail.com>
-## Copyright (C) 2005 Eswar Nallusamy, LANL
-## Copyright (C) 2005 Tyan
-## (Written by Yinghai Lu <yhlu at tyan.com> for Tyan)
-## Copyright (C) 2007 coresystems GmbH
-## (Written by Stefan Reinauer <stepan at coresystems.de> for coresystems GmbH)
-## Copyright (C) 2007 Advanced Micro Devices, 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
-##
-
-/* Init code - Switch CPU to protected mode and enable Cache-as-Ram. */
-
-#include "macros.h"
-#include <amd_geodelx.h>
-
-/* This is where the DCache will be mapped and be used as stack. It would be
- * cool if it was the same base as LinuxBIOS normal stack.
- */
-#define	LX_STACK_BASE		DCACHE_RAM_BASE
-#define	LX_STACK_END		LX_STACK_BASE+(DCACHE_RAM_SIZE-4)
-
-#define	LX_NUM_CACHELINES	0x080	/* There are 128 lines per way. */
-#define	LX_CACHELINE_SIZE	0x020	/* There are 32 bytes per line. */
-#define	LX_CACHEWAY_SIZE	(LX_NUM_CACHELINES * LX_CACHELINE_SIZE)
-#define	CR0_CD			0x40000000 /* Bit 30 = Cache Disable */
-#define	CR0_NW			0x20000000 /* Bit 29 = Not Write Through */
-
-#define ROM_CODE_SEG 0x08
-#define ROM_DATA_SEG 0x10
-
-#define CACHE_RAM_CODE_SEG 0x18
-#define CACHE_RAM_DATA_SEG 0x20
-
-	.code16
-	.globl _stage0
-_stage0:
-	cli
-
-	/* Save the BIST result. */
-	movl	%eax, %ebp;
-
-	/* Thanks to kmliu at sis.com.tw for this TLB fix. */
-	/* IMMEDIATELY invalidate the translation lookaside buffer before
-	 * executing any further code. Even though paging is disabled we
-	 * could still get false address translations due to the TLB if we
-	 * didn't invalidate it.
-	 */
-
-	xorl	%eax, %eax
-	movl	%eax, %cr3	/* Invalidate TLB */
-
-	/* Switch to protected mode. */
-
-	/* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux)
-	 * using BFD version 2.15.94.0.2.2 20041220 this works fine without
-	 * all the ld hackery and so on. So leave it as is with this comment. 
-	 */
-
-	data32	lgdt %cs:gdtptr
-
-	movl	%cr0, %eax
-	andl	$0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */
-	orl	$0x60000001, %eax /* CD, NW, PE = 1 */
-	movl	%eax, %cr0
-
-	/* Restore BIST result. */
-	movl	%ebp, %eax
-
-	// port80_post(0x23)
-
-	/* Now we are in protected mode. Jump to a 32 bit code segment. */
-	data32 ljmp    $ROM_CODE_SEG, $protected_stage0
-	/* I am leaving this weird jump in here in the event that future gas
-	 * bugs force it to be used.
-	 */
-	#.byte 0x66
-	.code32
-	#ljmp    $ROM_CODE_SEG, $protected_stage0
-
-	#.code16
-	.align  4
-	.globl gdt16
-gdt16 = . - _stage0 
-gdt16x:
-	.word	gdt16xend - gdt16x -1	/* Compute the table limit. */
-	.long	gdt16x
-	.word	0
-
-	/* selgdt 0x08, flat code segment */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x9b, 0xcf, 0x00
-
-	/* selgdt 0x10, flat data segment */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x93, 0xcf, 0x00
-gdt16xend:
-
-	/* From now on we are 32bit. */
-	.code32
-
-	/* We have two gdts where we could have one. That is ok.
-	 *
-	 * Let's not worry about this -- optimizing gdt is pointless since
-	 * we're only in it for a little bit.
-	 *
-	 * BTW note the trick below: The GDT points to ITSELF, and the first
-	 * good descriptor is at offset 8. So you word-align the table, and
-	 * then because you chose 8, you get a nice 64-bit aligned GDT entry,
-	 * which is good as this is the size of the entry.
-	 *
-	 * Just in case you ever wonder why people do this. 
-	 */
-	.align  4
-	.globl gdtptr
-	.globl gdt_limit
-gdt_limit = gdt_end - gdt - 1   /* Compute the table limit. */
-
-gdt:
-gdtptr:
-	.word	gdt_end - gdt -1 /* Compute the table limit. */
-	.long	gdt              /* We know the offset. */
-	.word	0
-
-	/* selgdt 0x08, flat code segment */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x9b, 0xcf, 0x00
-
-	/* selgdt 0x10, flat data segment */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x93, 0xcf, 0x00
-
-	/* selgdt 0x18, flat code segment for CAR */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x9b, 0xcf, 0x00
-
-	/* selgdt 0x20, flat data segment for CAR */
-	.word	0xffff, 0x0000
-	.byte	0x00, 0x93, 0xcf, 0x00
-gdt_end:
-
-	/*
-	 * When we come here we are in protected mode. We expand the stack
-	 * and copy the data segment from ROM to the memory.
-	 *
-	 * After that, we call the chipset bootstrap routine that
-	 * does what is left of the chipset initialization.
-	 *
-	 * NOTE: Aligned to 4 so that we are sure that the prefetch
-	 * cache will be reloaded.
-	 */
-
-	.align  4
-	.globl protected_stage0
-protected_stage0:
-	// This code was used by v2. TODO
-	lgdt	%cs:gdtptr
-	ljmp	$ROM_CODE_SEG, $__protected_stage0
-
-.globl __protected_stage0
-__protected_stage0:
-	/* Save the BIST value. */
-	movl	%eax, %ebp
-
-	port80_post(0x01)
-
-	movw	$ROM_DATA_SEG, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	%ax, %fs
-	movw	%ax, %gs
-
-	/* Restore the BIST value to %eax. */
-	movl	%ebp, %eax
-
-.align 4
-	/* Here begins CAR support. */
-	/* This particular code is straight from LinuxBIOS V2. */
-
-	/* DCacheSetup: Setup data cache for use as RAM for a stack. */
-DCacheSetup:
-
-	invd
-	/* Set cache properties. */
-	movl	$CPU_RCONF_DEFAULT, %ecx
-	rdmsr
-	/* 1MB system memory in write back 1|00100|00. */
-	movl	$0x010010000, %eax
-	wrmsr
-
-	/* In LX DCDIS is set after POR which disables the cache..., clear
-	 * this bit.
-	 */
-	movl	CPU_DM_CONFIG0,%ecx
-	rdmsr
-	/* TODO: Make consistent with i$ init, either whole reg = 0, or just
-	 * this bit...
-	 */
-	andl	$(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax
-	wrmsr
-
-	/* Get cache timing params from BIOS config data locations and apply. */
-	/* Fix delay controls for DM and IM arrays. */
-	movl	$CPU_BC_MSS_ARRAY_CTL0, %ecx
-	xorl	%edx, %edx
-	movl	$0x2814D352, %eax
-	wrmsr
-
-	movl	$CPU_BC_MSS_ARRAY_CTL1, %ecx
-	xorl	%edx, %edx
-	movl	$0x1068334D, %eax
-	wrmsr
-
-	movl	$CPU_BC_MSS_ARRAY_CTL2, %ecx
-	movl	$0x00000106, %edx
-	movl	$0x83104104, %eax
-	wrmsr
-
-	movl	$GLCP_FIFOCTL, %ecx
-	rdmsr
-	movl	$0x00000005, %edx
-	wrmsr
-
-	/* Enable setting. */
-	movl	$CPU_BC_MSS_ARRAY_CTL_ENA, %ecx
-	xorl	%edx, %edx
-	movl	$0x01, %eax
-	wrmsr
-
-	/* Get cleaned up. */
-	xorl	%edi, %edi
-	xorl	%esi, %esi
-	xorl	%ebp, %ebp
-
-	/* DCache Ways0 through Ways7 will be tagged for
-	 * LX_STACK_BASE + DCACHE_RAM_SIZE for holding stack.
-	 */
-	/* Remember, there is NO stack yet... */
-
-	/* Tell cache we want to fill Way 0 starting at the top. */
-	xorl	%edx, %edx
-	xorl	%eax, %eax
-	movl	$CPU_DC_INDEX, %ecx
-	wrmsr
-
-	/* Startaddress for tag of Way0: ebp will hold the incrementing
-	 * address. dont destroy!
-	 */
-	movl	$LX_STACK_BASE, %ebp	/* Init to start address. */
-	/* Set valid bit and tag for this Way (B[31:12] : Cache tag value for
-	 * line/way curr. selected by CPU_DC_INDEX.
-	 */
-	orl	$1, %ebp
-
-	/* Start tag Ways 0 with 128 lines with 32 bytes each: edi will hold
-	 * the line counter. dont destroy!
-	 */
-	movl	$LX_NUM_CACHELINES, %edi
-
-DCacheSetupFillWay:
-	/* Fill with dummy data: zero it so we can tell it from PCI memory
-	 * space (returns FFs).
-	 */
-	/* We will now store a line (32 bytes = 4 x 8 bytes = 4 quad-words). */
-	movw	$0x04, %si
-	xorl	%edx, %edx
-	xorl	%eax, %eax
-	movl	$CPU_DC_DATA, %ecx
-
-DCacheSetup_quadWordLoop:
-	wrmsr
-	decw	%si
-	jnz	DCacheSetup_quadWordLoop
-
-	/* Set the tag for this line, need to do this for every new cache
-	 * line to validate it!
-	 */
-	/* Accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX
-	 * increment and thus continue in the next cache line...
-	 */
-	xorl	%edx, %edx
-	movl	%ebp, %eax
-	movl	$CPU_DC_TAG, %ecx
-	wrmsr
-
-	/* Switch to next line. Lines are in Bits10:4. */
-	/* When index is crossing 0x7F -> 0x80 writing a RSVD bit as 0x80 is
-	 * not a valid CL anymore!
-	 */
-	movl	$CPU_DC_INDEX, %ecx
-	rdmsr
-	/* TODO: Probably would be more elegant to calculate this from
-	 * counter var edi...
-	 */
-	addl	$0x010, %eax
-	wrmsr
-
-	decl	%edi
-	jnz	DCacheSetupFillWay
-
-	/* 1 Way has been filled, forward start address for next Way,
-	 * terminate if we have reached end of desired address range.
-	 */
-	addl	$LX_CACHEWAY_SIZE, %ebp
-	cmpl	$LX_STACK_END, %ebp
-	jge	leave_DCacheSetup
-	movl	$LX_NUM_CACHELINES, %edi
-
-	/* Switch to next way. */
-	movl	$CPU_DC_INDEX, %ecx
-	rdmsr
-	addl	$0x01, %eax
-	/* Let's be sure: reset line index Bits10:4. */
-	andl	$0xFFFFF80F, %eax
-	wrmsr
-
-	jmp	DCacheSetupFillWay
-
-leave_DCacheSetup:
-	xorl	%edi, %edi
-	xorl	%esi, %esi
-	xorl	%ebp, %ebp
-
-	/* Disable the cache, but... DO NOT INVALIDATE the tags. */
-	/* Memory reads and writes will all hit in the cache. */
-	/* Cache updates and memory write-backs will not occur! */
-	movl	%cr0, %eax
-	orl	$(CR0_CD + CR0_NW), %eax	/* Set the CD and NW bits. */
-	movl	%eax, %cr0
-
-	/* Now point sp to the cached stack. */
-	/* The stack will be fully functional at this location. No system
-	 * memory is required at all!
-	 */
-	/* Set up the stack pointer. */
-	movl	$LX_STACK_END, %eax
-	movl	%eax, %esp
-
-	/* Test the stack. */
-	movl	$0x0F0F05A5A, %edx
-	pushl	%edx
-	popl	%ecx
-	cmpl	%ecx, %edx
-	je	DCacheSetupGood
-	movb	$0xC5, %al
-	outb	%al, $0x80
-
-DCacheSetupBad:
-	hlt		/* Issues */
-	jmp DCacheSetupBad
-
-DCacheSetupGood:
-	/* If you wanted to maintain the stack in memory you would need to
-	 * set the tags as dirty so the wbinvd would push out the old stack
-	 * contents to memory.
-	 */
-	/* Clear the cache, the following code from crt0.S.lb will setup
-	 * a new stack.
-	 */
-	wbinvd
-
-	/* At this point, CAR should be working. */
-	movl	$(LX_STACK_END), %eax
-	movl	%eax, %esp
-
-	/* Load a different set of data segments. */
-	movw	$CACHE_RAM_DATA_SEG, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-
-lout:
-	/* Restore the BIST result. */
-	movl	%ebp, %eax
-	/* We need to set ebp? No need. */
-	movl	%esp, %ebp
-	pushl	%eax		/* BIST */
-	call	stage1_main
-	/* We will not go back. */
-
-fixed_mtrr_msr:
-	.long   0x250, 0x258, 0x259
-	.long   0x268, 0x269, 0x26A
-	.long   0x26B, 0x26C, 0x26D
-	.long   0x26E, 0x26F
-var_mtrr_msr:
-	.long   0x200, 0x201, 0x202, 0x203
-	.long   0x204, 0x205, 0x206, 0x207
-	.long   0x208, 0x209, 0x20A, 0x20B
-	.long   0x20C, 0x20D, 0x20E, 0x20F
-	.long   0x000 /* NULL, end of table */
-
-# Reset vector.
-
-/*
- * RVECTOR: size of reset vector, default is 0x10
- * RESRVED: size of vpd code, default is 0xf0
- * BOOTBLK: size of bootblock code, default is 0x1f00 (8k-256b)
- */
-
-SEGMENT_SIZE = 0x10000
-RVECTOR      = 0x00010
-
-# Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here.
-# I think we should leave it this way forever, as the bugs come and
-# go -- and come again.
-#	.code16
-#	.section ".rom.text"
-.section ".reset", "ax"
-	.globl _resetjump
-_resetjump:
-	/* GNU bintools bugs again. This jumps to stage0 - 2. Sigh. */
-#	jmp _stage0
-	.byte  0xe9
-	.int   _stage0 - ( . + 2 )
-	/* Note: The above jump is hand coded to work around bugs in binutils.
-	 * 5 bytes are used for a 3 byte instruction. This works because x86
-	 * is little endian and allows us to use supported 32 bit relocations
-	 * instead of the weird 16 bit relocations that binutils does not
-	 * handle consistenly between versions because they are used so rarely.
-	 */
-.byte	0
-
-# Date? ID string? We might want to put something else in here.
-.ascii DATE
-
-# Checksum.
-#.word	0





More information about the coreboot mailing list