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>
diff --git a/src/cpu/amd/agesa/romstage.c b/src/cpu/amd/agesa/romstage.c
index f77bab9..11a62ad 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 @@
 
 	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();
 }