mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
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:
parent
b48030fa84
commit
064cd70619
6 changed files with 49 additions and 143 deletions
|
@ -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. */
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -118,12 +116,20 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
|
|||
|
||||
|
||||
// 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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue