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:
Kyösti Mälkki 2016-11-23 06:47:15 +02:00
parent 1779d534e5
commit ba22e159bb
12 changed files with 137 additions and 113 deletions

View File

@ -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:

View File

@ -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();
}

View File

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

View File

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

View File

@ -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();
}
}

View File

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

View File

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

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

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

View File

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