summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2019-11-25 12:20:01 +0100
committerLean Sheng Tan <sheng.tan@9elements.com>2023-03-13 13:42:32 +0000
commit3134a8152590f6d93232f6e56ab08fd87ebe1a0d (patch)
tree8a7569aa1f9f204e36cc7571bd2ed71eca714b24 /src/arch
parent4bad919ce47fae7187dfc8ed0c0186a78fd10597 (diff)
cpu/x86/cache: CLFLUSH programs to memory before running
When cbmem is initialized in romstage and postcar placed in the stage cache + cbmem where it is run, the assumption is made that these are all in UC memory such that calling INVD in postcar is OK. For performance reasons (e.g. postcar decompression) it is desirable to cache cbmem and the stage cache during romstage. Another reason is that AGESA sets up MTRR during romstage to cache all dram, which is currently worked around by using additional MTRR's to make that UC. TESTED on asus/p5ql-em, up/squared on both regular and S3 resume bootpath. Sometimes there are minimal performance improvements when cbmem is cached (few ms). Change-Id: I7ff2a57aee620908b71829457ea0f5a0c410ec5b Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37196 Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com> Reviewed-by: Kapil Porwal <kapilporwal@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/postcar_loader.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/arch/x86/postcar_loader.c b/src/arch/x86/postcar_loader.c
index a8a77e0227..17286805ef 100644
--- a/src/arch/x86/postcar_loader.c
+++ b/src/arch/x86/postcar_loader.c
@@ -9,6 +9,7 @@
#include <program_loading.h>
#include <reset.h>
#include <rmodule.h>
+#include <romstage_handoff.h>
#include <security/vboot/vboot_common.h>
#include <stage_cache.h>
#include <timestamp.h>
@@ -137,6 +138,25 @@ static void postcar_cache_invalid(void)
board_reset();
}
+/*
+ * POSTCAR will call invd so don't make assumptions on cbmem
+ * and external stage cache being UC.
+ */
+static void postcar_flush_cache(void)
+{
+ uintptr_t cbmem_base;
+ size_t cbmem_size;
+ uintptr_t stage_cache_base;
+ size_t stage_cache_size;
+
+ cbmem_get_region((void **)&cbmem_base, &cbmem_size);
+ prog_segment_loaded(cbmem_base, cbmem_size, SEG_FINAL);
+ if (CONFIG(TSEG_STAGE_CACHE) && !romstage_handoff_is_resume()) {
+ stage_cache_external_region((void **)&stage_cache_base, &stage_cache_size);
+ prog_segment_loaded(stage_cache_base, stage_cache_size, SEG_FINAL);
+ }
+}
+
static void run_postcar_phase(struct postcar_frame *pcf)
{
struct prog prog =
@@ -159,6 +179,8 @@ static void run_postcar_phase(struct postcar_frame *pcf)
console_time_report();
+ postcar_flush_cache();
+
prog_set_arg(&prog, cbmem_top());
prog_run(&prog);