Stage0 and Stage1 improvements. Gets Geode LX into initram. Use LAR XIP. Add disable_CAR().

Signed-off-by: Marc Jones <marc.jones@amd.com>


Index: LinuxBIOSv3/arch/x86/geodelx/stage0.S
===================================================================
--- LinuxBIOSv3.orig/arch/x86/geodelx/stage0.S	2007-07-18 13:13:59.000000000 -0600
+++ LinuxBIOSv3/arch/x86/geodelx/stage0.S	2007-07-18 13:27:39.000000000 -0600
@@ -205,7 +205,7 @@
 	/* In LX DCDIS is set after POR which disables the cache..., clear
 	 * this bit.
 	 */
-	movl	CPU_DM_CONFIG0,%ecx
+	movl	$CPU_DM_CONFIG0,%ecx
 	rdmsr
 
 	/* TODO: Make consistent with i$ init, either whole reg = 0, or just
@@ -368,16 +368,6 @@
 	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.
-	 * TODO: There is no crt0.S.lb (anymore?).
-	 */
-	wbinvd
-
 	/* At this point, CAR should be working. */
 	movl	$(LX_STACK_END), %eax
 	movl	%eax, %esp
@@ -395,21 +385,9 @@
 	/* We need to set ebp? No need. */
 	movl	%esp, %ebp
 	pushl	%eax		/* BIST */
-	call	stage1_main
+	jmp	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. */
 
 /*
Index: LinuxBIOSv3/arch/x86/geodelx/stage1.c
===================================================================
--- LinuxBIOSv3.orig/arch/x86/geodelx/stage1.c	2007-07-18 13:13:59.000000000 -0600
+++ LinuxBIOSv3/arch/x86/geodelx/stage1.c	2007-07-18 13:27:39.000000000 -0600
@@ -27,29 +27,39 @@
 	u32 msrnum;
 	struct msr msr;
 } msr_table[] = {
-  /* Setup access to the cache for under 1MB. */
+  /* Setup access to cache under 1MB. */
   {CPU_RCONF_DEFAULT, {.hi = 0x24fffc02,.lo = 0x1000A000}}, // 0x00000-0xA0000
   {CPU_RCONF_A0_BF,   {.hi = 0x00000000,.lo = 0x00000000}}, // 0xA0000-0xBFFFF
   {CPU_RCONF_C0_DF,   {.hi = 0x00000000,.lo = 0x00000000}}, // 0xC0000-0xDFFFF
   {CPU_RCONF_E0_FF,   {.hi = 0x00000000,.lo = 0x00000000}}, // 0xE0000-0xFFFFF
 
-  /* Setup access to the cache for under 640KB. */
+  /* Setup access to memory under 1MB. Note: VGA hole at 0xA0000-0xBFFFF */
   {MSR_GLIU0_BASE1,   {.hi = 0x20000000,.lo = 0x000fff80}}, // 0x00000-0x7FFFF
   {MSR_GLIU0_BASE2,   {.hi = 0x20000000,.lo = 0x080fffe0}}, // 0x80000-0x9FFFF
+  {MSR_GLIU0_SHADOW,  {.hi = 0x2000FFFF,.lo = 0xFFFF0003}}, // 0xC0000-0xFFFFF
   {MSR_GLIU1_BASE1,   {.hi = 0x20000000,.lo = 0x000fff80}}, // 0x00000-0x7FFFF
   {MSR_GLIU1_BASE2,   {.hi = 0x20000000,.lo = 0x080fffe0}}, // 0x80000-0x9FFFF
+  {MSR_GLIU1_SHADOW,  {.hi = 0x2000FFFF,.lo = 0xFFFF0003}}, // 0xC0000-0xFFFFF
 };
 
 /**
- * Set up Geode LX registers for sane behaviour.
- *
- * Set all low memory (under 1MB) to write-back cacheable. Do some setup for
- * Cache-as-RAM (CAR) as well. Note: The memory controller is not set up, yet.
- */
+  * Set up Geode LX registers for sane behaviour.
+  */
 void geodelx_msr_init(void)
 {
+}
+
+/**
+  * Disable Cache As RAM(CAR) after memory is setup.
+  *  Geode can write back the cache contents to RAM and continue on.
+  *  Assumes that anything in the cache was under 1MB.
+  */
+void disable_car(void)
+{
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(msr_table); i++)
 		wrmsr(msr_table[i].msrnum, msr_table[i].msr);
+
+	__asm__("wbinvd\n");
 }
Index: LinuxBIOSv3/arch/x86/mc146818rtc.c
===================================================================
--- LinuxBIOSv3.orig/arch/x86/mc146818rtc.c	2007-07-18 13:26:38.000000000 -0600
+++ LinuxBIOSv3/arch/x86/mc146818rtc.c	2007-07-18 13:27:39.000000000 -0600
@@ -280,7 +280,7 @@
   * Check CMOS for normal or fallback boot mode.
   * Use lxbios to set normal mode once the system is operational.
   */
-int do_normal_boot(void)
+int check_normal_boot_flag(void)
 {
 	u8 byte;
 
@@ -321,7 +321,7 @@
 	/* Save the boot byte */
 	CMOS_WRITE(byte, RTC_BOOT_BYTE);
 
-	return (byte & RTC_LAST_BOOT_FLAG_SET);
+	return (byte & RTC_NORMAL_BOOT_FLAG_SET);
 }
 
 
Index: LinuxBIOSv3/arch/x86/stage1.c
===================================================================
--- LinuxBIOSv3.orig/arch/x86/stage1.c	2007-07-18 13:13:59.000000000 -0600
+++ LinuxBIOSv3/arch/x86/stage1.c	2007-07-18 12:34:15.000000000 -0600
@@ -2,6 +2,7 @@
  * This file is part of the LinuxBIOS project.
  *
  * Copyright (C) 2007 Stefan Reinauer <stepan@coresystems.de>
+ * 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 version 2 as
@@ -32,10 +33,7 @@
 void die(const char *msg);
 int find_file(struct mem_file *archive, char *filename, struct mem_file *result);
 void hardware_stage1(void);
-
-// Is this value correct?
-#define DCACHE_RAM_SIZE 0x8000
-
+void disable_car(void);
 
 void post_code(u8 value)
 {
@@ -78,7 +76,7 @@
 
 	post_code(0x02);
 
-	// before we do anything, we want to stop if we dont run 
+	// before we do anything, we want to stop if we dont run
 	// on the bootstrap processor.
 	if (bist==0) {
 		// stop secondaries
@@ -87,7 +85,7 @@
 
 	// We have cache as ram running and can start executing code in C.
 	//
-	
+
 	hardware_stage1();
 
 	//
@@ -101,29 +99,37 @@
 
 	// enable rom
 	enable_rom();
-	
+
 	// location and size of image.
-	
+
 	// FIXME this should be defined in the VPD area
 	// but NOT IN THE CODE.
-	
+
 	/* The len field starts behind the reset vector on x86.
 	 * The start is not correct for all platforms. sc520 will
-	 * need some hands on here. 
+	 * need some hands on here.
 	 */
 	archive.len = *(u32 *)0xfffffff4;
-	archive.start =(void *)(0UL-archive.len); 
+	archive.start =(void *)(0UL-archive.len);
 
 	// FIXME check integrity
 
 
 	// find first initram
-	if (last_boot_normal()) {
+	if (check_normal_boot_flag()) {
 		printk(BIOS_DEBUG, "Choosing normal boot.\n");
-		ret = run_file(&archive, "normal/initram", (void *)(512*1024)); //CONFIG_CARBASE;
+		ret = execute_in_place(&archive, "normal/initram");
 	} else {
 		printk(BIOS_DEBUG, "Choosing fallback boot.\n");
-		ret = run_file(&archive, "fallback/initram", (void *)(512*1024)); //CONFIG_CARBASE;
+		ret = execute_in_place(&archive, "fallback/initram");
+		/* Try a normal boot if fallback doesn't exists in the lar.
+		 * TODO: There are other ways to do this.
+		 * It could be ifdef or the boot flag could be forced.
+		 */
+		if (ret) {
+			printk(BIOS_DEBUG, "Fallback failed. Try normal boot\n");
+			ret = execute_in_place(&archive, "normal/initram");
+		}
 	}
 
 	if (ret)
@@ -132,97 +138,8 @@
 	printk(BIOS_DEBUG, "Done RAM init code\n");
 
 
-	/* Turn off Cache-As-Ram, and do some other things.
-	 *
-	 * This has to be done inline -- You can't call a function because the
-	 * return stack does not survive.
- 	 */
- 
-        __asm__ volatile (
-	/* 
-	FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
-		It is only needed if we want to go back
-	*/
-	
-        /* We don't need cache as ram for now on */
-        /* disable cache */
-        "movl    %cr0, %eax\n\t"
-        "orl    $(0x1<<30),%eax\n\t"
-        "movl    %eax, %cr0\n\t"
-
-        /* clear sth */
-        "movl    $0x269, %ecx\n\t"  /* fix4k_c8000*/
-        "xorl    %edx, %edx\n\t"
-        "xorl    %eax, %eax\n\t"
-	"wrmsr\n\t"
-#if DCACHE_RAM_SIZE > 0x8000
-	"movl    $0x268, %ecx\n\t"  /* fix4k_c0000*/
-        "wrmsr\n\t"
-#endif
-
-        /* Set the default memory type and disable fixed and enable variable MTRRs */
-        "movl    $0x2ff, %ecx\n\t"
-//        "movl    $MTRRdefType_MSR, %ecx\n\t"
-        "xorl    %edx, %edx\n\t"
-        /* Enable Variable and Disable Fixed MTRRs */
-        "movl    $0x00000800, %eax\n\t"
-        "wrmsr\n\t"
-
-#if defined(CLEAR_FIRST_1M_RAM)
-        /* enable caching for first 1M using variable mtrr */
-        "movl    $0x200, %ecx\n\t"
-        "xorl    %edx, %edx\n\t"
-        "movl     $(0 | 1), %eax\n\t"
-//	"movl     $(0 | MTRR_TYPE_WRCOMB), %eax\n\t"
-        "wrmsr\n\t"
-
-        "movl    $0x201, %ecx\n\t"
-        "movl    $0x0000000f, %edx\n\t" /* AMD 40 bit 0xff*/
-        "movl    $((~(( 0 + 0x100000) - 1)) | 0x800), %eax\n\t"
-        "wrmsr\n\t"
-#endif
-
-        /* enable cache */
-        "movl    %cr0, %eax\n\t"
-        "andl    $0x9fffffff,%eax\n\t"
-        "movl    %eax, %cr0\n\t"
-#if defined(CLEAR_FIRST_1M_RAM)
-        /* clear the first 1M */
-        "movl    $0x0, %edi\n\t"
-        "cld\n\t"
-        "movl    $(0x100000>>2), %ecx\n\t"
-        "xorl    %eax, %eax\n\t"
-        "rep     stosl\n\t"
-
-        /* disable cache */
-        "movl    %cr0, %eax\n\t"
-        "orl    $(0x1<<30),%eax\n\t"
-        "movl    %eax, %cr0\n\t"
-
-        /* enable caching for first 1M using variable mtrr */
-        "movl    $0x200, %ecx\n\t"
-        "xorl    %edx, %edx\n\t"
-        "movl     $(0 | 6), %eax\n\t"
-//	"movl     $(0 | MTRR_TYPE_WRBACK), %eax\n\t"
-        "wrmsr\n\t"
-
-        "movl    $0x201, %ecx\n\t"
-        "movl    $0x0000000f, %edx\n\t" /* AMD 40 bit 0xff*/
-        "movl    $((~(( 0 + 0x100000) - 1)) | 0x800), %eax\n\t"
-        "wrmsr\n\t"
-
-        /* enable cache */
-        "movl    %cr0, %eax\n\t"
-        "andl    $0x9fffffff,%eax\n\t"
-        "movl    %eax, %cr0\n\t"
-	"invd\n\t"
-
-	/* 
-	FIXME: I hope we don't need to change esp and ebp value here, so we can restore value from mmx sse back
-		But the problem is the range is some io related, So don't go back
-	*/
-#endif
-        );
+	/* Turn off Cache-As-Ram */
+	disable_car();
 
 	ret = run_file(&archive, "normal/stage2", (void *)0x1000);
 	if (ret)
Index: LinuxBIOSv3/include/mc146818rtc.h
===================================================================
--- LinuxBIOSv3.orig/include/mc146818rtc.h	2007-07-18 13:26:23.000000000 -0600
+++ LinuxBIOSv3/include/mc146818rtc.h	2007-07-18 13:27:39.000000000 -0600
@@ -120,6 +120,6 @@
 void rtc_init(int invalid);
 int get_option(void *dest, char *name);
 int last_boot_normal(void);
-int do_normal_boot(void);
+int check_normal_boot_flag(void);
 
 #endif /* MC146818RTC_H */
Index: LinuxBIOSv3/mainboard/emulation/qemu-x86/stage1.c
===================================================================
--- LinuxBIOSv3.orig/mainboard/emulation/qemu-x86/stage1.c	2007-07-18 13:13:59.000000000 -0600
+++ LinuxBIOSv3/mainboard/emulation/qemu-x86/stage1.c	2007-07-18 13:27:39.000000000 -0600
@@ -17,12 +17,13 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+/* no printk allowed until hardware is ready; hardware is ready */
 /** 
- * Start up hardware needed for stage1.
- *
- * No printk() allowed until hardware is ready; hardware is ready.
- * TODO: Fix above comment? It's unclear.
+ * start up hardware needed for stage1
  */
 void hardware_stage1(void)
 {
 }
+void disable_car(void)
+{
+}
