AGESA: Disable CAR with empty stack
Calling disable_cache_as_ram() with valuables in stack is not a stable solution, as per documentation AMD_DISABLE_STACK should destroy stack in cache. Change-Id: I986bb7a88f53f7f7a0b05d4edcd5020f5dbeb4b7 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/18626 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
1779d534e5
commit
ba22e159bb
|
@ -26,12 +26,8 @@
|
|||
#include "gcccar.inc"
|
||||
#include <cpu/x86/cache.h>
|
||||
|
||||
/*
|
||||
* XMM map:
|
||||
*/
|
||||
|
||||
.code32
|
||||
.globl cache_as_ram_setup, disable_cache_as_ram, cache_as_ram_setup_out
|
||||
.globl cache_as_ram_setup, cache_as_ram_setup_out
|
||||
|
||||
cache_as_ram_setup:
|
||||
|
||||
|
@ -110,17 +106,13 @@ cache_as_ram_setup:
|
|||
pushl $0x0
|
||||
pushl %ebp
|
||||
call romstage_main
|
||||
movl %eax, %ebx
|
||||
|
||||
/* Should never see this postcode */
|
||||
post_code(0xaf)
|
||||
stop:
|
||||
jmp stop
|
||||
/* Register %ebx is new stacktop for remaining of romstage.
|
||||
* It is the only register preserved in AMD_DISABLE_STACK.
|
||||
*/
|
||||
|
||||
disable_cache_as_ram:
|
||||
/* Save return stack */
|
||||
movd 0(%esp), %xmm1
|
||||
movd %esp, %xmm0
|
||||
|
||||
/* Disable cache */
|
||||
movl %cr0, %eax
|
||||
orl $CR0_CacheDisable, %eax
|
||||
|
@ -132,12 +124,13 @@ disable_cache_as_ram:
|
|||
movl %cr0, %eax
|
||||
andl $0x9fffffff, %eax
|
||||
movl %eax, %cr0
|
||||
xorl %eax, %eax
|
||||
|
||||
/* Restore the return stack */
|
||||
wbinvd
|
||||
movd %xmm0, %esp
|
||||
movd %xmm1, (%esp)
|
||||
ret
|
||||
movl %ebx, %esp
|
||||
call romstage_after_car
|
||||
|
||||
/* Should never see this postcode */
|
||||
post_code(0xaf)
|
||||
stop:
|
||||
jmp stop
|
||||
|
||||
cache_as_ram_setup_out:
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <arch/stages.h>
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/car.h>
|
||||
|
||||
|
@ -49,8 +47,15 @@ void agesa_main(struct sysinfo *cb)
|
|||
post_code(0x37);
|
||||
agesawrapper_amdinitearly();
|
||||
|
||||
printk(BIOS_INFO, "Normal boot\n");
|
||||
|
||||
post_code(0x38);
|
||||
agesawrapper_amdinitpost();
|
||||
}
|
||||
|
||||
void agesa_postcar(struct sysinfo *cb)
|
||||
{
|
||||
printk(BIOS_INFO, "Normal boot postcar\n");
|
||||
|
||||
post_code(0x39);
|
||||
printk(BIOS_DEBUG, "sb_before_pci_init ");
|
||||
|
@ -59,7 +64,4 @@ void agesa_main(struct sysinfo *cb)
|
|||
|
||||
post_code(0x40);
|
||||
agesawrapper_amdinitenv();
|
||||
|
||||
post_code(0x43);
|
||||
copy_and_run();
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <arch/stages.h>
|
||||
#include <cpu/amd/agesa/s3_resume.h>
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/car.h>
|
||||
|
||||
|
@ -51,32 +48,31 @@ void agesa_main(struct sysinfo *cb)
|
|||
|
||||
post_code(0x40);
|
||||
agesawrapper_amdinitpost();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 detected\n");
|
||||
|
||||
post_code(0x60);
|
||||
agesawrapper_amdinitresume();
|
||||
}
|
||||
}
|
||||
|
||||
void agesa_postcar(struct sysinfo *cb)
|
||||
{
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot postcar\n");
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
|
||||
post_code(0x42);
|
||||
amd_initenv();
|
||||
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 detected\n");
|
||||
|
||||
post_code(0x60);
|
||||
|
||||
agesawrapper_amdinitresume();
|
||||
printk(BIOS_INFO, "S3 resume postcar\n");
|
||||
|
||||
post_code(0x61);
|
||||
|
||||
agesawrapper_amds3laterestore();
|
||||
|
||||
post_code(0x62);
|
||||
|
||||
prepare_for_resume();
|
||||
}
|
||||
|
||||
post_code(0x50);
|
||||
copy_and_run();
|
||||
|
||||
/* Not reached */
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#include <lib.h>
|
||||
#include <reset.h>
|
||||
#include <arch/stages.h>
|
||||
#include <cpu/amd/agesa/s3_resume.h>
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/car.h>
|
||||
|
@ -73,17 +71,13 @@ void agesa_main(struct sysinfo *cb)
|
|||
post_code(0x40);
|
||||
agesawrapper_amdinitpost();
|
||||
|
||||
printk(BIOS_INFO, "Normal boot\n");
|
||||
}
|
||||
|
||||
void agesa_postcar(struct sysinfo *cb)
|
||||
{
|
||||
printk(BIOS_INFO, "Normal boot postcar\n");
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
post_code(0x42);
|
||||
|
||||
post_code(0x50);
|
||||
print_debug("Disabling cache as ram ");
|
||||
disable_cache_as_ram();
|
||||
print_debug("done\n");
|
||||
|
||||
post_code(0x51);
|
||||
copy_and_run();
|
||||
|
||||
/* Not reached */
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <arch/stages.h>
|
||||
#include <cpu/amd/agesa/s3_resume.h>
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/car.h>
|
||||
|
||||
|
@ -43,29 +40,32 @@ void agesa_main(struct sysinfo *cb)
|
|||
agesawrapper_amdinitearly();
|
||||
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot\n");
|
||||
|
||||
post_code(0x40);
|
||||
agesawrapper_amdinitpost();
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
|
||||
disable_cache_as_ram();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 detected\n");
|
||||
|
||||
post_code(0x60);
|
||||
agesawrapper_amdinitresume();
|
||||
|
||||
amd_initcpuio();
|
||||
agesawrapper_amds3laterestore();
|
||||
|
||||
post_code(0x61);
|
||||
prepare_for_resume();
|
||||
}
|
||||
|
||||
post_code(0x50);
|
||||
copy_and_run();
|
||||
|
||||
/* Not reached */
|
||||
}
|
||||
void agesa_postcar(struct sysinfo *cb)
|
||||
{
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot postcar\n");
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 resume postcar\n");
|
||||
|
||||
post_code(0x61);
|
||||
amd_initcpuio();
|
||||
|
||||
post_code(0x62);
|
||||
agesawrapper_amds3laterestore();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <arch/stages.h>
|
||||
#include <cpu/amd/agesa/s3_resume.h>
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/car.h>
|
||||
|
||||
|
@ -45,28 +42,32 @@ void agesa_main(struct sysinfo *cb)
|
|||
agesawrapper_amdinitearly();
|
||||
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot\n");
|
||||
|
||||
post_code(0x40);
|
||||
agesawrapper_amdinitpost();
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
|
||||
disable_cache_as_ram();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 detected\n");
|
||||
|
||||
post_code(0x60);
|
||||
agesawrapper_amdinitresume();
|
||||
}
|
||||
}
|
||||
|
||||
amd_initcpuio();
|
||||
agesawrapper_amds3laterestore();
|
||||
void agesa_postcar(struct sysinfo *cb)
|
||||
{
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot postcar\n");
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 resume postcar\n");
|
||||
|
||||
post_code(0x61);
|
||||
prepare_for_resume();
|
||||
amd_initcpuio();
|
||||
|
||||
post_code(0x62);
|
||||
agesawrapper_amds3laterestore();
|
||||
}
|
||||
|
||||
post_code(0x50);
|
||||
copy_and_run();
|
||||
|
||||
/* Not reached */
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <arch/stages.h>
|
||||
#include <cpu/amd/agesa/s3_resume.h>
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/amd/car.h>
|
||||
|
||||
|
@ -43,30 +40,35 @@ void agesa_main(struct sysinfo *cb)
|
|||
agesawrapper_amdinitearly();
|
||||
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot\n");
|
||||
|
||||
post_code(0x40);
|
||||
agesawrapper_amdinitpost();
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
|
||||
/* TODO: Disable cache is not ok. */
|
||||
disable_cache_as_ram();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 detected\n");
|
||||
|
||||
post_code(0x60);
|
||||
agesawrapper_amdinitresume();
|
||||
|
||||
amd_initcpuio();
|
||||
agesawrapper_amds3laterestore();
|
||||
|
||||
post_code(0x61);
|
||||
prepare_for_resume();
|
||||
}
|
||||
|
||||
post_code(0x50);
|
||||
copy_and_run();
|
||||
|
||||
/* Not reached */
|
||||
}
|
||||
|
||||
void agesa_postcar(struct sysinfo *cb)
|
||||
{
|
||||
if (!cb->s3resume) {
|
||||
printk(BIOS_INFO, "Normal boot postcar\n");
|
||||
|
||||
post_code(0x41);
|
||||
agesawrapper_amdinitenv();
|
||||
} else {
|
||||
printk(BIOS_INFO, "S3 resume postcar\n");
|
||||
|
||||
post_code(0x61);
|
||||
amd_initcpuio();
|
||||
|
||||
post_code(0x62);
|
||||
agesawrapper_amds3laterestore();
|
||||
|
||||
post_code(0x63);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,17 @@
|
|||
|
||||
#include <arch/acpi.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <cbmem.h>
|
||||
#include <cpu/amd/car.h>
|
||||
#include <cpu/amd/agesa/s3_resume.h>
|
||||
#include <cpu/x86/bist.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <console/console.h>
|
||||
#include <halt.h>
|
||||
#include <program_loading.h>
|
||||
#include <smp/node.h>
|
||||
#include <string.h>
|
||||
#include <northbridge/amd/agesa/agesa_helper.h>
|
||||
#include <northbridge/amd/agesa/state_machine.h>
|
||||
|
||||
static void fill_sysinfo(struct sysinfo *cb)
|
||||
|
@ -51,6 +57,33 @@ void * asmlinkage romstage_main(unsigned long bist)
|
|||
|
||||
agesa_main(cb);
|
||||
|
||||
/* Not reached */
|
||||
return NULL;
|
||||
uintptr_t stack_top = CACHE_TMP_RAMTOP;
|
||||
if (cb->s3resume) {
|
||||
if (cbmem_recovery(1)) {
|
||||
printk(BIOS_EMERG, "Unable to recover CBMEM\n");
|
||||
halt();
|
||||
}
|
||||
stack_top = romstage_ram_stack_base(HIGH_ROMSTAGE_STACK_SIZE,
|
||||
ROMSTAGE_STACK_CBMEM);
|
||||
stack_top += HIGH_ROMSTAGE_STACK_SIZE;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "Move CAR stack.\n");
|
||||
return (void*)stack_top;
|
||||
}
|
||||
|
||||
void asmlinkage romstage_after_car(void)
|
||||
{
|
||||
struct sysinfo romstage_state;
|
||||
struct sysinfo *cb = &romstage_state;
|
||||
|
||||
printk(BIOS_DEBUG, "CAR disabled.\n");
|
||||
|
||||
fill_sysinfo(cb);
|
||||
agesa_postcar(cb);
|
||||
|
||||
if (cb->s3resume)
|
||||
set_resume_cache();
|
||||
|
||||
run_ramstage();
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ static void move_stack_high_mem(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void set_resume_cache(void)
|
||||
void set_resume_cache(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
void restore_mtrr(void);
|
||||
void prepare_for_resume(void);
|
||||
void set_resume_cache(void);
|
||||
|
||||
void backup_mtrr(void *mtrr_store, u32 *mtrr_store_size);
|
||||
const void *OemS3Saved_MTRR_Storage(void);
|
||||
|
|
|
@ -19,5 +19,6 @@ void disable_cache_as_ram(void);
|
|||
void asmlinkage early_all_cores(void);
|
||||
|
||||
void * asmlinkage romstage_main(unsigned long bist);
|
||||
void asmlinkage romstage_after_car(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,9 +23,10 @@ struct sysinfo
|
|||
int s3resume;
|
||||
};
|
||||
|
||||
void board_BeforeAgesa(struct sysinfo *cb);
|
||||
|
||||
void platform_once(struct sysinfo *cb);
|
||||
void agesa_main(struct sysinfo *cb);
|
||||
void agesa_postcar(struct sysinfo *cb);
|
||||
|
||||
void board_BeforeAgesa(struct sysinfo *cb);
|
||||
void platform_once(struct sysinfo *cb);
|
||||
|
||||
#endif /* _STATE_MACHINE_H_ */
|
||||
|
|
Loading…
Reference in New Issue