Raul Rangel has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/56051 )
Change subject: lib/prog_loaders: Add payload_preload ......................................................................
lib/prog_loaders: Add payload_preload
This method will allow the SoC code to start loading the payload before it is required.
BUG=b:177909625 TEST=Boot guybrush and see read/decompress drop by 23 ms.
Signed-off-by: Raul E Rangel rrangel@chromium.org Change-Id: Ifa8f30a0f4f931ece803c2e8e022e4d33d3fe581 --- M src/include/program_loading.h M src/include/symbols.h M src/lib/Kconfig M src/lib/prog_loaders.c 4 files changed, 62 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/51/56051/1
diff --git a/src/include/program_loading.h b/src/include/program_loading.h index 65a36b9..dbb0ffd 100644 --- a/src/include/program_loading.h +++ b/src/include/program_loading.h @@ -154,6 +154,8 @@
int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size);
+/* Tries to asynchronously load the payload before it is required */ +void payload_preload(void); /* Load payload into memory in preparation to run. */ void payload_load(void);
diff --git a/src/include/symbols.h b/src/include/symbols.h index 3e4694b..52624d4 100644 --- a/src/include/symbols.h +++ b/src/include/symbols.h @@ -52,6 +52,7 @@
/* Regions for execution units. */
+DECLARE_REGION(payload_preload_cache) DECLARE_REGION(payload) /* "program" always refers to the current execution unit. */ DECLARE_REGION(program) diff --git a/src/lib/Kconfig b/src/lib/Kconfig index b556f7d..3dfadaa 100644 --- a/src/lib/Kconfig +++ b/src/lib/Kconfig @@ -106,3 +106,19 @@ futures and poll them until completion. If this is disabled and futures are in use, they must be polled manually.
+config HAVE_PAYLOAD_PRELOAD_CACHE + bool + select FUTURES_EXECUTOR + help + Selected by the SoC to indicate it provides the payload_preload_cache + region. + +config PAYLOAD_PRELOAD_CACHE_SIZE + hex + default 0x30000 + depends on HAVE_PAYLOAD_PRELOAD_CACHE + help + On some systems with SPI DMA controllers, it is possible to preload + the payload while FSP-S is executing. This config sets the size of the + space in RAM allocated for the raw payload. This space is only + populated during non-S3, so it doesn't need to be reserved. diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c index 40f51eb..04faf8b 100644 --- a/src/lib/prog_loaders.c +++ b/src/lib/prog_loaders.c @@ -126,17 +126,56 @@ static struct prog global_payload = PROG_INIT(PROG_PAYLOAD, CONFIG_CBFS_PREFIX "/payload");
+static struct cbfs_load_async_context payload_preload_context; + +void payload_preload(void) +{ + cb_err_t err; + struct prog *payload = &global_payload; + struct cbfs_load_async_context *context = &payload_preload_context; + + if (!CONFIG(HAVE_PAYLOAD_PRELOAD_CACHE)) + return; + + if (prog_locate_hook(payload)) + return; + + printk(BIOS_INFO, "Preloading payload\n"); + + err = cbfs_load_async(prog_name(payload), context, _payload_preload_cache, + REGION_SIZE(payload_preload_cache)); + + if (err) + printk(BIOS_ERR, "Preloading payload failed: %d\n", err); + else + register_future(&context->future); +} + void payload_load(void) { struct prog *payload = &global_payload; + struct cbfs_load_async_context *context = &payload_preload_context; + void *mapping = NULL;
timestamp_add_now(TS_LOAD_PAYLOAD);
- if (prog_locate_hook(payload)) - goto out; + if (future_is_valid(&context->future)) { + wait_for_future(&context->future); + if (context->future.error == CB_SUCCESS) { + mapping = context->buffer; + payload->cbfs_type = context->type; + } else { + printk(BIOS_ERR, "%s: Failed to preload payload\n", __func__); + /* Fall through and try the synchronous route */ + } + } else { + if (prog_locate_hook(payload)) + goto out;
- payload->cbfs_type = CBFS_TYPE_QUERY; - void *mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type); + payload->cbfs_type = CBFS_TYPE_QUERY; + mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type); + } + if (!mapping) goto out;