aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/amd/agesa/cache_as_ram.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/amd/agesa/cache_as_ram.S')
-rw-r--r--src/cpu/amd/agesa/cache_as_ram.S46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/cpu/amd/agesa/cache_as_ram.S b/src/cpu/amd/agesa/cache_as_ram.S
index b96a5e70e4..50242f7a54 100644
--- a/src/cpu/amd/agesa/cache_as_ram.S
+++ b/src/cpu/amd/agesa/cache_as_ram.S
@@ -29,6 +29,7 @@
.code32
.globl _cache_as_ram_setup, _cache_as_ram_setup_end
+.globl chipset_teardown_car
_cache_as_ram_setup:
@@ -105,20 +106,44 @@ _cache_as_ram_setup:
movd %mm0, %eax /* bist */
pushl %eax
call romstage_main
- movl %eax, %esp
-/* Register %esp is new stacktop for remaining of romstage.
- * It is the only register preserved in AMD_DISABLE_STACK.
+#if IS_ENABLED(CONFIG_POSTCAR_STAGE)
+
+/* We do not return. Execution continues with run_postcar_phase()
+ * calling to chipset_teardown_car below.
+ */
+ jmp postcar_entry_failure
+
+chipset_teardown_car:
+
+/*
+ * Retrieve return address from stack as it will get trashed below if
+ * execution is utilizing the cache-as-ram stack.
*/
+ pop %esp
+
+#else
+
+ movl %eax, %esp
+
+/* Register %esp is new stacktop for remaining of romstage. */
+
+#endif
-disable_cache_as_ram:
/* Disable cache */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
+/* Register %esp is preserved in AMD_DISABLE_STACK. */
AMD_DISABLE_STACK
+#if IS_ENABLED(CONFIG_POSTCAR_STAGE)
+
+ jmp *%esp
+
+#else
+
/* enable cache */
movl %cr0, %eax
andl $0x9fffffff, %eax
@@ -126,9 +151,22 @@ disable_cache_as_ram:
call romstage_after_car
+#endif
+
/* Should never see this postcode */
post_code(0xaf)
+
stop:
+ hlt
+ jmp stop
+
+/* These are here for linking purposes. */
+.weak early_all_cores, romstage_main
+early_all_cores:
+romstage_main:
+postcar_entry_failure:
+ /* Should never see this postcode */
+ post_code(0xae)
jmp stop
_cache_as_ram_setup_end: