summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2016-11-23 06:47:15 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2017-04-05 15:02:43 +0200
commitba22e159bb21549ba92eb6e9d91eaa097a54985b (patch)
treeb9195d45d7e01b7f4dbe4a646ff5c274d6e1d53c /src
parent1779d534e5b6e01e2aabfb30aa369e0aebe28488 (diff)
downloadcoreboot-ba22e159bb21549ba92eb6e9d91eaa097a54985b.tar.xz
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>
Diffstat (limited to 'src')
-rw-r--r--src/cpu/amd/agesa/cache_as_ram.inc31
-rw-r--r--src/cpu/amd/agesa/family12/romstage.c12
-rw-r--r--src/cpu/amd/agesa/family14/romstage.c30
-rw-r--r--src/cpu/amd/agesa/family15/romstage.c20
-rw-r--r--src/cpu/amd/agesa/family15rl/romstage.c34
-rw-r--r--src/cpu/amd/agesa/family15tn/romstage.c33
-rw-r--r--src/cpu/amd/agesa/family16kb/romstage.c34
-rw-r--r--src/cpu/amd/agesa/romstage.c37
-rw-r--r--src/cpu/amd/agesa/s3_resume.c2
-rw-r--r--src/cpu/amd/agesa/s3_resume.h1
-rw-r--r--src/include/cpu/amd/car.h1
-rw-r--r--src/northbridge/amd/agesa/state_machine.h5
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_ */