aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2016-11-29 15:52:08 -0600
committerAaron Durbin <adurbin@chromium.org>2016-12-01 08:17:19 +0100
commitd008413a3c46d4346f3cc398bbfd60b875ff3084 (patch)
tree64efd8619f78e914cdbe6ed4c4d6f8f44d5dd803
parentafe8aeed81003e941d91e8733ea7459a58d1a4d7 (diff)
arch/x86: cache postcar in stage cache
Stash and reload postcar stage in the stage cache for increased S3 resume speed. It's impact is small (2 ms or so), but there's no need to go to the boot media on resume to reload something that was already loaded. This aligns with the same paths we take on ramstage as well. Change-Id: I4313794826120853163c7366e81346858747ed0a Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/17649 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh <furquan@google.com>
-rw-r--r--src/arch/x86/postcar_loader.c28
-rw-r--r--src/include/stage_cache.h1
2 files changed, 22 insertions, 7 deletions
diff --git a/src/arch/x86/postcar_loader.c b/src/arch/x86/postcar_loader.c
index d9719ff729..948e4459fa 100644
--- a/src/arch/x86/postcar_loader.c
+++ b/src/arch/x86/postcar_loader.c
@@ -20,6 +20,8 @@
#include <cpu/x86/mtrr.h>
#include <program_loading.h>
#include <rmodule.h>
+#include <romstage_handoff.h>
+#include <stage_cache.h>
static inline void stack_push(struct postcar_frame *pcf, uint32_t val)
{
@@ -110,18 +112,14 @@ void *postcar_commit_mtrrs(struct postcar_frame *pcf)
return (void *) pcf->stack;
}
-void run_postcar_phase(struct postcar_frame *pcf)
+static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
{
- struct prog prog =
- PROG_INIT(PROG_UNKNOWN, CONFIG_CBFS_PREFIX "/postcar");
struct rmod_stage_load rsl = {
.cbmem_id = CBMEM_ID_AFTER_CAR,
- .prog = &prog,
+ .prog = prog,
};
- postcar_commit_mtrrs(pcf);
-
- if (prog_locate(&prog))
+ if (prog_locate(prog))
die("Failed to locate after CAR program.\n");
if (rmodule_stage_load(&rsl))
die("Failed to load after CAR program.\n");
@@ -139,5 +137,21 @@ void run_postcar_phase(struct postcar_frame *pcf)
prog_segment_loaded((uintptr_t)rsl.params, sizeof(uintptr_t),
SEG_FINAL);
+ if (!IS_ENABLED(CONFIG_NO_STAGE_CACHE))
+ stage_cache_add(STAGE_POSTCAR, prog);
+}
+
+void run_postcar_phase(struct postcar_frame *pcf)
+{
+ struct prog prog =
+ PROG_INIT(PROG_UNKNOWN, CONFIG_CBFS_PREFIX "/postcar");
+
+ postcar_commit_mtrrs(pcf);
+
+ if (!IS_ENABLED(CONFIG_NO_STAGE_CACHE) && romstage_handoff_is_resume())
+ stage_cache_load_stage(STAGE_POSTCAR, &prog);
+ else
+ load_postcar_cbfs(&prog, pcf);
+
prog_run(&prog);
}
diff --git a/src/include/stage_cache.h b/src/include/stage_cache.h
index a24ea71f96..fbf9c46578 100644
--- a/src/include/stage_cache.h
+++ b/src/include/stage_cache.h
@@ -23,6 +23,7 @@
enum {
STAGE_RAMSTAGE,
STAGE_REFCODE,
+ STAGE_POSTCAR,
};
/* Cache the loaded stage provided according to the parameters. */