This patch gets Geode LX into initram. It also cleans up some of the
generic stage0 and stage1 code for getting through CAR and initram.
At this point I need some help. We get into initram but I think that
there is a link problem where the first function call to post_code() is
past the beginning of the ROM.
I see the following:
lar finds normal/initram at 0xFFFC4B20
The call to 0xFFFC4B20 works and we are executing initram.
The call to post_code() is to 0xFFF427d4 <--- BAD!
Also, There aren't any map files being generated. I think that they
would be helpful in debugging stuff like this. Any volunteers better at
makefiles than I am?
--
Marc Jones
Senior Software Engineer
(970) 226-9684 Office
mailto:Marc.Jones@amd.com
http://www.amd.com/embeddedprocessors
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)
+{
+}