From 621ee8080af5a13999d6cbda9d471a0a71fca930 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Wed, 24 Apr 2013 22:59:45 -0500 Subject: [PATCH] BACKPORT: boot state: rebalance payload load vs actual boot The notion of loading a payload in the current boot state machine isn't actually loading the payload. The reason is that cbfs is just walked to find the payload. The actual loading and booting were occuring in selfboot(). Change this balance so that loading occurs in one function and actual booting happens in another. This allows for ample opportunity to delay work until just before booting. Change-Id: I8c2af24a12a77d22e61c0bd8c392714bd1dfdedd Signed-off-by: Aaron Durbin Reviewed-on: https://gerrit.chromium.org/gerrit/49747 Reviewed-by: Duncan Laurie --- src/include/cbfs.h | 3 ++- src/lib/hardwaremain.c | 12 +++++++++--- src/lib/selfboot.c | 18 +++++++++++------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/include/cbfs.h b/src/include/cbfs.h index ac249aabf5..c0098eacdb 100644 --- a/src/include/cbfs.h +++ b/src/include/cbfs.h @@ -78,7 +78,8 @@ int run_address(void *f); /* Defined in src/lib/selfboot.c */ struct lb_memory; -int selfboot(struct lb_memory *mem, struct cbfs_payload *payload); +void *selfload(struct lb_memory *mem, struct cbfs_payload *payload); +void selfboot(void *entry); /* Defined in individual arch / board implementation. */ int init_default_cbfs_media(struct cbfs_media *media); diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c index adee3ca709..ed2a516372 100644 --- a/src/lib/hardwaremain.c +++ b/src/lib/hardwaremain.c @@ -198,6 +198,7 @@ static boot_state_t bs_write_tables(void *arg) static boot_state_t bs_payload_load(void *arg) { void *payload; + void *entry; timestamp_add_now(TS_LOAD_PAYLOAD); @@ -206,15 +207,20 @@ static boot_state_t bs_payload_load(void *arg) if (! payload) die("Could not find a payload\n"); + entry = selfload(get_lb_mem(), payload); + + if (! entry) + die("Could not load payload\n"); + /* Pass the payload to the next state. */ - boot_states[BS_PAYLOAD_BOOT].arg = payload; + boot_states[BS_PAYLOAD_BOOT].arg = entry; return BS_PAYLOAD_BOOT; } -static boot_state_t bs_payload_boot(void *payload) +static boot_state_t bs_payload_boot(void *entry) { - selfboot(get_lb_mem(), payload); + selfboot(entry); printk(BIOS_EMERG, "Boot failed"); /* Returning from this state will fail because the following signals diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index 324d43e838..4ebe10935d 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -512,7 +512,7 @@ static int load_self_segments( return 1; } -int selfboot(struct lb_memory *mem, struct cbfs_payload *payload) +void *selfload(struct lb_memory *mem, struct cbfs_payload *payload) { u32 entry=0; struct segment head; @@ -527,10 +527,18 @@ int selfboot(struct lb_memory *mem, struct cbfs_payload *payload) printk(BIOS_SPEW, "Loaded segments\n"); + return (void *)entry; + +out: + return NULL; +} + +void selfboot(void *entry) +{ /* Reset to booting from this image as late as possible */ boot_successful(); - printk(BIOS_DEBUG, "Jumping to boot code at %x\n", entry); + printk(BIOS_DEBUG, "Jumping to boot code at %p\n", entry); post_code(POST_ENTER_ELF_BOOT); #if CONFIG_COLLECT_TIMESTAMPS @@ -543,9 +551,5 @@ int selfboot(struct lb_memory *mem, struct cbfs_payload *payload) checkstack(_estack, 0); /* Jump to kernel */ - jmp_to_elf_entry((void*)entry, bounce_buffer, bounce_size); - return 1; - -out: - return 0; + jmp_to_elf_entry(entry, bounce_buffer, bounce_size); }