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

Signed-off-by: Marc Jones <marc.jones@amd.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com> 



git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@459 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Marc Jones 2007-07-19 15:15:57 +00:00
parent b48030fa84
commit 064cd70619
6 changed files with 49 additions and 143 deletions

View file

@ -205,7 +205,7 @@ DCacheSetup:
/* 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 @@ DCacheSetupBad:
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 @@ lout:
/* 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. */
/*

View file

@ -27,29 +27,39 @@ static struct msrinit {
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");
}

View file

@ -280,7 +280,7 @@ int last_boot_normal(void)
* 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 @@ int do_normal_boot(void)
/* Save the boot byte */
CMOS_WRITE(byte, RTC_BOOT_BYTE);
return (byte & RTC_LAST_BOOT_FLAG_SET);
return (byte & RTC_NORMAL_BOOT_FLAG_SET);
}

View file

@ -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 uart_init(void);
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 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
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 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
// We have cache as ram running and can start executing code in C.
//
hardware_stage1();
//
@ -101,29 +99,37 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
// 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 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
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)

View file

@ -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 */

View file

@ -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)
{
}