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
|
/* In LX DCDIS is set after POR which disables the cache..., clear
|
||||||
* this bit.
|
* this bit.
|
||||||
*/
|
*/
|
||||||
movl CPU_DM_CONFIG0,%ecx
|
movl $CPU_DM_CONFIG0,%ecx
|
||||||
rdmsr
|
rdmsr
|
||||||
|
|
||||||
/* TODO: Make consistent with i$ init, either whole reg = 0, or just
|
/* TODO: Make consistent with i$ init, either whole reg = 0, or just
|
||||||
|
@ -368,16 +368,6 @@ DCacheSetupBad:
|
||||||
jmp DCacheSetupBad
|
jmp DCacheSetupBad
|
||||||
|
|
||||||
DCacheSetupGood:
|
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. */
|
/* At this point, CAR should be working. */
|
||||||
movl $(LX_STACK_END), %eax
|
movl $(LX_STACK_END), %eax
|
||||||
movl %eax, %esp
|
movl %eax, %esp
|
||||||
|
@ -395,21 +385,9 @@ lout:
|
||||||
/* We need to set ebp? No need. */
|
/* We need to set ebp? No need. */
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
pushl %eax /* BIST */
|
pushl %eax /* BIST */
|
||||||
call stage1_main
|
jmp stage1_main
|
||||||
/* We will not go back. */
|
/* 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. */
|
/* Reset vector. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -27,29 +27,39 @@ static struct msrinit {
|
||||||
u32 msrnum;
|
u32 msrnum;
|
||||||
struct msr msr;
|
struct msr msr;
|
||||||
} msr_table[] = {
|
} 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_DEFAULT, {.hi = 0x24fffc02,.lo = 0x1000A000}}, // 0x00000-0xA0000
|
||||||
{CPU_RCONF_A0_BF, {.hi = 0x00000000,.lo = 0x00000000}}, // 0xA0000-0xBFFFF
|
{CPU_RCONF_A0_BF, {.hi = 0x00000000,.lo = 0x00000000}}, // 0xA0000-0xBFFFF
|
||||||
{CPU_RCONF_C0_DF, {.hi = 0x00000000,.lo = 0x00000000}}, // 0xC0000-0xDFFFF
|
{CPU_RCONF_C0_DF, {.hi = 0x00000000,.lo = 0x00000000}}, // 0xC0000-0xDFFFF
|
||||||
{CPU_RCONF_E0_FF, {.hi = 0x00000000,.lo = 0x00000000}}, // 0xE0000-0xFFFFF
|
{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_BASE1, {.hi = 0x20000000,.lo = 0x000fff80}}, // 0x00000-0x7FFFF
|
||||||
{MSR_GLIU0_BASE2, {.hi = 0x20000000,.lo = 0x080fffe0}}, // 0x80000-0x9FFFF
|
{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_BASE1, {.hi = 0x20000000,.lo = 0x000fff80}}, // 0x00000-0x7FFFF
|
||||||
{MSR_GLIU1_BASE2, {.hi = 0x20000000,.lo = 0x080fffe0}}, // 0x80000-0x9FFFF
|
{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 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)
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(msr_table); i++)
|
for (i = 0; i < ARRAY_SIZE(msr_table); i++)
|
||||||
wrmsr(msr_table[i].msrnum, msr_table[i].msr);
|
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.
|
* Check CMOS for normal or fallback boot mode.
|
||||||
* Use lxbios to set normal mode once the system is operational.
|
* Use lxbios to set normal mode once the system is operational.
|
||||||
*/
|
*/
|
||||||
int do_normal_boot(void)
|
int check_normal_boot_flag(void)
|
||||||
{
|
{
|
||||||
u8 byte;
|
u8 byte;
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ int do_normal_boot(void)
|
||||||
/* Save the boot byte */
|
/* Save the boot byte */
|
||||||
CMOS_WRITE(byte, RTC_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.
|
* This file is part of the LinuxBIOS project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Stefan Reinauer <stepan@coresystems.de>
|
* 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
|
* 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
|
* 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);
|
void die(const char *msg);
|
||||||
int find_file(struct mem_file *archive, char *filename, struct mem_file *result);
|
int find_file(struct mem_file *archive, char *filename, struct mem_file *result);
|
||||||
void hardware_stage1(void);
|
void hardware_stage1(void);
|
||||||
|
void disable_car(void);
|
||||||
// Is this value correct?
|
|
||||||
#define DCACHE_RAM_SIZE 0x8000
|
|
||||||
|
|
||||||
|
|
||||||
void post_code(u8 value)
|
void post_code(u8 value)
|
||||||
{
|
{
|
||||||
|
@ -118,12 +116,20 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
|
||||||
|
|
||||||
|
|
||||||
// find first initram
|
// find first initram
|
||||||
if (last_boot_normal()) {
|
if (check_normal_boot_flag()) {
|
||||||
printk(BIOS_DEBUG, "Choosing normal boot.\n");
|
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 {
|
} else {
|
||||||
printk(BIOS_DEBUG, "Choosing fallback boot.\n");
|
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)
|
if (ret)
|
||||||
|
@ -132,97 +138,8 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
|
||||||
printk(BIOS_DEBUG, "Done RAM init code\n");
|
printk(BIOS_DEBUG, "Done RAM init code\n");
|
||||||
|
|
||||||
|
|
||||||
/* Turn off Cache-As-Ram, and do some other things.
|
/* Turn off Cache-As-Ram */
|
||||||
*
|
disable_car();
|
||||||
* 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
|
|
||||||
);
|
|
||||||
|
|
||||||
ret = run_file(&archive, "normal/stage2", (void *)0x1000);
|
ret = run_file(&archive, "normal/stage2", (void *)0x1000);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -120,6 +120,6 @@
|
||||||
void rtc_init(int invalid);
|
void rtc_init(int invalid);
|
||||||
int get_option(void *dest, char *name);
|
int get_option(void *dest, char *name);
|
||||||
int last_boot_normal(void);
|
int last_boot_normal(void);
|
||||||
int do_normal_boot(void);
|
int check_normal_boot_flag(void);
|
||||||
|
|
||||||
#endif /* MC146818RTC_H */
|
#endif /* MC146818RTC_H */
|
||||||
|
|
|
@ -17,12 +17,13 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* 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.
|
* start up hardware needed for stage1
|
||||||
*
|
|
||||||
* No printk() allowed until hardware is ready; hardware is ready.
|
|
||||||
* TODO: Fix above comment? It's unclear.
|
|
||||||
*/
|
*/
|
||||||
void hardware_stage1(void)
|
void hardware_stage1(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
void disable_car(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue