diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2016-11-23 06:47:15 +0200 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2017-04-05 15:02:43 +0200 |
commit | ba22e159bb21549ba92eb6e9d91eaa097a54985b (patch) | |
tree | b9195d45d7e01b7f4dbe4a646ff5c274d6e1d53c | |
parent | 1779d534e5b6e01e2aabfb30aa369e0aebe28488 (diff) |
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>
-rw-r--r-- | src/cpu/amd/agesa/cache_as_ram.inc | 31 | ||||
-rw-r--r-- | src/cpu/amd/agesa/family12/romstage.c | 12 | ||||
-rw-r--r-- | src/cpu/amd/agesa/family14/romstage.c | 30 | ||||
-rw-r--r-- | src/cpu/amd/agesa/family15/romstage.c | 20 | ||||
-rw-r--r-- | src/cpu/amd/agesa/family15rl/romstage.c | 34 | ||||
-rw-r--r-- | src/cpu/amd/agesa/family15tn/romstage.c | 33 | ||||
-rw-r--r-- | src/cpu/amd/agesa/family16kb/romstage.c | 34 | ||||
-rw-r--r-- | src/cpu/amd/agesa/romstage.c | 37 | ||||
-rw-r--r-- | src/cpu/amd/agesa/s3_resume.c | 2 | ||||
-rw-r--r-- | src/cpu/amd/agesa/s3_resume.h | 1 | ||||
-rw-r--r-- | src/include/cpu/amd/car.h | 1 | ||||
-rw-r--r-- | src/northbridge/amd/agesa/state_machine.h | 5 |
12 files changed, 132 insertions, 108 deletions
diff --git a/src/cpu/amd/agesa/cache_as_ram.inc b/src/cpu/amd/agesa/cache_as_ram.inc index 1258d154c3..857873a682 100644 --- a/src/cpu/amd/agesa/cache_as_ram.inc +++ b/src/cpu/amd/agesa/cache_as_ram.inc @@ -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: diff --git a/src/cpu/amd/agesa/family12/romstage.c b/src/cpu/amd/agesa/family12/romstage.c index 13b9f06359..8f4e81a9d9 100644 --- a/src/cpu/amd/agesa/family12/romstage.c +++ b/src/cpu/amd/agesa/family12/romstage.c @@ -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(); } diff --git a/src/cpu/amd/agesa/family14/romstage.c b/src/cpu/amd/agesa/family14/romstage.c index b8c9bd345c..e89b2fc84c 100644 --- a/src/cpu/amd/agesa/family14/romstage.c +++ b/src/cpu/amd/agesa/family14/romstage.c @@ -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 */ } diff --git a/src/cpu/amd/agesa/family15/romstage.c b/src/cpu/amd/agesa/family15/romstage.c index 1c2330839f..7b5c0bcfc6 100644 --- a/src/cpu/amd/agesa/family15/romstage.c +++ b/src/cpu/amd/agesa/family15/romstage.c @@ -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(); - 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"); + printk(BIOS_INFO, "Normal boot\n"); +} - post_code(0x51); - copy_and_run(); +void agesa_postcar(struct sysinfo *cb) +{ + printk(BIOS_INFO, "Normal boot postcar\n"); - /* Not reached */ + post_code(0x41); + agesawrapper_amdinitenv(); } diff --git a/src/cpu/amd/agesa/family15rl/romstage.c b/src/cpu/amd/agesa/family15rl/romstage.c index 25cd987252..369ae33c02 100644 --- a/src/cpu/amd/agesa/family15rl/romstage.c +++ b/src/cpu/amd/agesa/family15rl/romstage.c @@ -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(); +} +void agesa_postcar(struct sysinfo *cb) +{ + if (!cb->s3resume) { + printk(BIOS_INFO, "Normal boot postcar\n"); - post_code(0x61); - prepare_for_resume(); - } + post_code(0x41); + agesawrapper_amdinitenv(); + } else { + printk(BIOS_INFO, "S3 resume postcar\n"); - post_code(0x50); - copy_and_run(); + post_code(0x61); + amd_initcpuio(); - /* Not reached */ + post_code(0x62); + agesawrapper_amds3laterestore(); + } } - diff --git a/src/cpu/amd/agesa/family15tn/romstage.c b/src/cpu/amd/agesa/family15tn/romstage.c index 55bb4b1f23..fc1aeee576 100644 --- a/src/cpu/amd/agesa/family15tn/romstage.c +++ b/src/cpu/amd/agesa/family15tn/romstage.c @@ -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(0x61); - prepare_for_resume(); - } + post_code(0x41); + agesawrapper_amdinitenv(); + } else { + printk(BIOS_INFO, "S3 resume postcar\n"); - post_code(0x50); - copy_and_run(); + post_code(0x61); + amd_initcpuio(); - /* Not reached */ + post_code(0x62); + agesawrapper_amds3laterestore(); + } } diff --git a/src/cpu/amd/agesa/family16kb/romstage.c b/src/cpu/amd/agesa/family16kb/romstage.c index 175ea54637..e0fff35ee3 100644 --- a/src/cpu/amd/agesa/family16kb/romstage.c +++ b/src/cpu/amd/agesa/family16kb/romstage.c @@ -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(); +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(0x50); - copy_and_run(); + post_code(0x62); + agesawrapper_amds3laterestore(); - /* Not reached */ + post_code(0x63); + } } - diff --git a/src/cpu/amd/agesa/romstage.c b/src/cpu/amd/agesa/romstage.c index f77bab9c38..11a62ad302 100644 --- a/src/cpu/amd/agesa/romstage.c +++ b/src/cpu/amd/agesa/romstage.c @@ -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(); } diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c index f45ff3c3e1..8aaa25b7fd 100644 --- a/src/cpu/amd/agesa/s3_resume.c +++ b/src/cpu/amd/agesa/s3_resume.c @@ -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; diff --git a/src/cpu/amd/agesa/s3_resume.h b/src/cpu/amd/agesa/s3_resume.h index b10489eeef..bb65af3f05 100644 --- a/src/cpu/amd/agesa/s3_resume.h +++ b/src/cpu/amd/agesa/s3_resume.h @@ -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); diff --git a/src/include/cpu/amd/car.h b/src/include/cpu/amd/car.h index 11fb8ae07b..df035137dc 100644 --- a/src/include/cpu/amd/car.h +++ b/src/include/cpu/amd/car.h @@ -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 diff --git a/src/northbridge/amd/agesa/state_machine.h b/src/northbridge/amd/agesa/state_machine.h index 3c78edb013..e55c152b20 100644 --- a/src/northbridge/amd/agesa/state_machine.h +++ b/src/northbridge/amd/agesa/state_machine.h @@ -23,9 +23,10 @@ struct sysinfo int s3resume; }; -void board_BeforeAgesa(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); -void agesa_main(struct sysinfo *cb); #endif /* _STATE_MACHINE_H_ */ |