AGESA,binaryPI: Fix stack location on entry to romstage
For BSP CPU, set up stack location to match the symbol from car.ld.
For AP CPUs the stack is located outside _car_region and is currently
not accounted for in the linker scripts.
Change-Id: I0ec84ae4e73ecca5034f799cdc2a5c1056ad8b74
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37351
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
diff --git a/src/drivers/amd/agesa/cache_as_ram.S b/src/drivers/amd/agesa/cache_as_ram.S
index 4f1cbea..e86830f 100644
--- a/src/drivers/amd/agesa/cache_as_ram.S
+++ b/src/drivers/amd/agesa/cache_as_ram.S
@@ -22,6 +22,7 @@
*/
#include "gcccar.inc"
+#include <cpu/x86/lapic_def.h>
#include <cpu/x86/post_code.h>
.code32
@@ -36,6 +37,19 @@
AMD_ENABLE_STACK
+ /*
+ * Set up bootblock stack on BSP.
+ * AMD_ENABLE_STACK macro sets up a stack for BSP at BSP_STACK_BASE_ADDR
+ * which is 0x30000 (_car_region_end), but for C bootblock the stack
+ * begins at _ecar_stack (see arch/x86/car.ld)
+ */
+ mov $LAPIC_BASE_MSR, %ecx
+ rdmsr
+ test $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
+ jz ap_entry
+
+ mov $_ecar_stack, %esp
+
/* Align the stack. */
and $0xFFFFFFF0, %esp
@@ -47,11 +61,19 @@
pushl %eax
call romstage_main
- /* Should never see this postcode */
- post_code(0xae)
+ /* Never reached. */
stop:
+ post_code(POST_DEAD_CODE)
hlt
jmp stop
+ap_entry:
+ /* Align the stack for call to ap_romstage_main() */
+ and $0xfffffff0, %esp
+ call ap_romstage_main
+
+ /* Never reached. */
+ jmp stop
+
_cache_as_ram_setup_end:
diff --git a/src/drivers/amd/agesa/romstage.c b/src/drivers/amd/agesa/romstage.c
index 8460035..571397f 100644
--- a/src/drivers/amd/agesa/romstage.c
+++ b/src/drivers/amd/agesa/romstage.c
@@ -39,7 +39,7 @@
agesa_set_interface(cb);
}
-static void bsp_romstage_main(void)
+asmlinkage void romstage_main(unsigned long bist)
{
struct postcar_frame pcf;
struct sysinfo romstage_state;
@@ -99,7 +99,7 @@
/* We do not return. */
}
-static void __noreturn ap_romstage_main(void)
+asmlinkage void ap_romstage_main(void)
{
struct sysinfo romstage_state;
struct sysinfo *cb = &romstage_state;
@@ -116,11 +116,3 @@
/* Not reached. */
halt();
}
-
-asmlinkage void romstage_main(unsigned long bist)
-{
- if (boot_cpu())
- bsp_romstage_main();
- else
- ap_romstage_main();
-}