Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8849
-gerrit
commit aa26ee71eec7d7e8759abbb558f3dc335c091e98 Author: Aaron Durbin adurbin@chromium.org Date: Fri Mar 20 16:37:12 2015 -0500
program loading: unify on struct prog
Instead of having different structures for loading ramstage and payload align to using struct prog. This also removes arch_payload_run() in favor of the prog_run() interface.
Change-Id: I31483096094eacc713a7433811cd69cc5621c43e Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/arch/arm/boot.c | 5 ---- src/arch/arm64/boot.c | 5 ---- src/arch/mips/boot.c | 5 ---- src/arch/riscv/boot.c | 5 ---- src/arch/x86/boot/boot.c | 21 +++++++++----- src/include/program_loading.h | 49 ++++++++++++--------------------- src/lib/loaders/cbfs_payload_loader.c | 10 +++---- src/lib/loaders/cbfs_ramstage_loader.c | 4 +-- src/lib/loaders/load_and_run_payload.c | 35 +++++++++++------------ src/lib/loaders/load_and_run_ramstage.c | 12 ++++---- src/lib/selfboot.c | 8 +++--- 11 files changed, 65 insertions(+), 94 deletions(-)
diff --git a/src/arch/arm/boot.c b/src/arch/arm/boot.c index 6a2934b..806e0d1 100644 --- a/src/arch/arm/boot.c +++ b/src/arch/arm/boot.c @@ -29,8 +29,3 @@ void arch_prog_run(struct prog *prog) doit = prog_entry(prog); doit(prog_entry_arg(prog)); } - -void arch_payload_run(struct payload *payload) -{ - arch_prog_run(&payload->prog); -} diff --git a/src/arch/arm64/boot.c b/src/arch/arm64/boot.c index f3632b5..bb771b2 100644 --- a/src/arch/arm64/boot.c +++ b/src/arch/arm64/boot.c @@ -82,8 +82,3 @@ void arch_prog_run(struct prog *prog) doit = prog_entry(prog); doit(prog_entry_arg(prog)); } - -void arch_payload_run(struct payload *payload) -{ - arch_prog_run(&payload->prog); -} diff --git a/src/arch/mips/boot.c b/src/arch/mips/boot.c index ebc45bb..549d483 100644 --- a/src/arch/mips/boot.c +++ b/src/arch/mips/boot.c @@ -24,8 +24,3 @@ void arch_prog_run(struct prog *prog) { stage_exit(prog_entry(prog)); } - -void arch_payload_run(struct payload *payload) -{ - arch_prog_run(&payload->prog); -} diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c index f66c02f..d273430 100644 --- a/src/arch/riscv/boot.c +++ b/src/arch/riscv/boot.c @@ -26,8 +26,3 @@ void arch_prog_run(struct prog *prog) doit = prog_entry(prog); doit(prog_entry_arg(prog)); } - -void arch_payload_run(struct payload *payload) -{ - arch_prog_run(&payload->prog); -} diff --git a/src/arch/x86/boot/boot.c b/src/arch/x86/boot/boot.c index d536584..1b61bcb 100644 --- a/src/arch/x86/boot/boot.c +++ b/src/arch/x86/boot/boot.c @@ -4,6 +4,7 @@ #include <ip_checksum.h> #include <string.h>
+#if ENV_RAMSTAGE /* When the ramstage is relocatable the elf loading ensures an elf image cannot * be loaded over the ramstage code. */ static void jmp_payload_no_bounce_buffer(void *entry) @@ -123,18 +124,24 @@ static void jmp_payload(void *entry, unsigned long buffer, unsigned long size) ); }
-void arch_payload_run(struct payload *payload) +static void try_payload(struct prog *prog) { - if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) - jmp_payload_no_bounce_buffer(prog_entry(&payload->prog)); - else - jmp_payload(prog_entry(&payload->prog), - (uintptr_t)payload->bounce.data, - payload->bounce.size); + if (prog->type == PROG_PAYLOAD) { + if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) + jmp_payload_no_bounce_buffer(prog_entry(prog)); + else + jmp_payload(prog_entry(prog), + (uintptr_t)prog->bounce.data, + prog->bounce.size); + } } +#else +static inline void try_payload(struct prog *prog) {} +#endif
void arch_prog_run(struct prog *prog) { + try_payload(prog); __asm__ volatile ( "jmp *%%edi\n" :: "D"(prog_entry(prog)) diff --git a/src/include/program_loading.h b/src/include/program_loading.h index 1df1825..0261b59 100644 --- a/src/include/program_loading.h +++ b/src/include/program_loading.h @@ -22,6 +22,7 @@
#include <stdint.h> #include <stddef.h> +#include <rules.h>
enum { /* Last segment of program. Can be used to take different actions for @@ -52,6 +53,10 @@ struct prog { * program is. e.g. a payload prog uses this field for the backing * store of the payload_segments and data. */ struct buffer_area area; +#if ENV_RAMSTAGE + /* Only payloads use the bounce buffer so conditionally include it. */ + struct buffer_area bounce; +#endif /* Entry to program with optional argument. It's up to the architecture * to decide if argument is passed. */ void (*entry)(void *); @@ -100,6 +105,14 @@ void arch_prog_run(struct prog *prog); * code it needs to that as well. */ void platform_prog_run(struct prog *prog);
+struct prog_loader_ops { + const char *name; + /* Returns < 0 on error or 0 on success. This function needs to do + * different things depending on the prog type. See definition + * of struct prog above. */ + int (*prepare)(struct prog *prog); +}; + /************************ * ROMSTAGE LOADING * ************************/ @@ -111,6 +124,9 @@ void run_romstage(void); * RAMSTAGE LOADING * ************************/
+/* Run ramstage from romstage. */ +void run_ramstage(void); + struct romstage_handoff; #if IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE) /* Cache the loaded ramstage described by prog. */ @@ -124,25 +140,10 @@ static inline void load_cached_ramstage(struct romstage_handoff *h, struct prog *p) {} #endif
-/* Run ramstage from romstage. */ -void run_ramstage(void); - -struct ramstage_loader_ops { - const char *name; - /* Returns 0 on succes. < 0 on error. */ - int (*load)(struct prog *ramstage); -}; - /*********************** * PAYLOAD LOADING * ***********************/
-struct payload { - struct prog prog; - /* Used when payload wants memory coreboot ramstage is running at. */ - struct buffer_area bounce; -}; - /* Load payload into memory in preparation to run. */ void payload_load(void);
@@ -150,23 +151,9 @@ void payload_load(void); void payload_run(void);
/* Mirror the payload to be loaded. */ -void mirror_payload(struct payload *payload); - -/* architecture specific function to run payload. */ -void arch_payload_run(struct payload *payload); - -/* Payload loading operations. */ -struct payload_loader_ops { - const char *name; - /* - * Fill in payload_backing_store structure. Return 0 on success, < 0 - * on failure. - */ - int (*locate)(struct payload *payload); -}; +void mirror_payload(struct prog *payload);
/* Defined in src/lib/selfboot.c */ -void *selfload(struct payload *payload); - +void *selfload(struct prog *payload);
#endif /* PROGRAM_LOADING_H */ diff --git a/src/lib/loaders/cbfs_payload_loader.c b/src/lib/loaders/cbfs_payload_loader.c index 609d123..3928613 100644 --- a/src/lib/loaders/cbfs_payload_loader.c +++ b/src/lib/loaders/cbfs_payload_loader.c @@ -20,24 +20,24 @@ #include <cbfs.h> #include <program_loading.h>
-static int cbfs_locate_payload(struct payload *payload) +static int cbfs_locate_payload(struct prog *payload) { void *buffer; size_t size; const int type = CBFS_TYPE_PAYLOAD;
- buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->prog.name, + buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->name, type, &size);
if (buffer == NULL) return -1;
- prog_set_area(&payload->prog, buffer, size); + prog_set_area(payload, buffer, size);
return 0; }
-const struct payload_loader_ops cbfs_payload_loader = { +const struct prog_loader_ops cbfs_payload_loader = { .name = "CBFS", - .locate = cbfs_locate_payload, + .prepare = cbfs_locate_payload, }; diff --git a/src/lib/loaders/cbfs_ramstage_loader.c b/src/lib/loaders/cbfs_ramstage_loader.c index 27be88e..e565329 100644 --- a/src/lib/loaders/cbfs_ramstage_loader.c +++ b/src/lib/loaders/cbfs_ramstage_loader.c @@ -54,7 +54,7 @@ static int cbfs_load_ramstage(struct prog *ramstage)
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
-const struct ramstage_loader_ops cbfs_ramstage_loader = { +const struct prog_loader_ops cbfs_ramstage_loader = { .name = "CBFS", - .load = cbfs_load_ramstage, + .prepare = cbfs_load_ramstage, }; diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c index e3208a9..6c42a58 100644 --- a/src/lib/loaders/load_and_run_payload.c +++ b/src/lib/loaders/load_and_run_payload.c @@ -26,24 +26,22 @@ #include <program_loading.h> #include <timestamp.h>
-extern const struct payload_loader_ops vboot_payload_loader; -extern const struct payload_loader_ops cbfs_payload_loader; +extern const struct prog_loader_ops vboot_payload_loader; +extern const struct prog_loader_ops cbfs_payload_loader;
-static const struct payload_loader_ops *payload_ops[] = { +static const struct prog_loader_ops *payload_ops[] = { #if CONFIG_VBOOT_VERIFY_FIRMWARE &vboot_payload_loader, #endif &cbfs_payload_loader, };
-static struct payload global_payload = { - .prog = { - .name = CONFIG_CBFS_PREFIX "/payload", - .type = PROG_PAYLOAD, - }, +static struct prog global_payload = { + .name = CONFIG_CBFS_PREFIX "/payload", + .type = PROG_PAYLOAD, };
-void __attribute__((weak)) mirror_payload(struct payload *payload) +void __attribute__((weak)) mirror_payload(struct prog *payload) { return; } @@ -51,19 +49,18 @@ void __attribute__((weak)) mirror_payload(struct payload *payload) void payload_load(void) { int i; - const struct payload_loader_ops *ops; - struct payload *payload = &global_payload; - struct prog * prog = &payload->prog; + const struct prog_loader_ops *ops; + struct prog *payload = &global_payload;
for (i = 0; i < ARRAY_SIZE(payload_ops); i++) { ops = payload_ops[i]; - if (ops->locate(payload) < 0) { + if (ops->prepare(payload) < 0) { printk(BIOS_DEBUG, "%s: could not locate payload.\n", ops->name); continue; } printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n", - ops->name, prog_start(prog), prog_size(prog)); + ops->name, prog_start(payload), prog_size(payload)); break; }
@@ -73,23 +70,23 @@ void payload_load(void) mirror_payload(payload);
/* Pass cbtables to payload if architecture desires it. */ - prog_set_entry(&payload->prog, selfload(payload), + prog_set_entry(payload, selfload(payload), cbmem_find(CBMEM_ID_CBTABLE));
out: - if (prog_entry(&payload->prog) == NULL) + if (prog_entry(payload) == NULL) die("Payload not loaded.\n"); }
void payload_run(void) { - struct payload *payload = &global_payload; + struct prog *payload = &global_payload;
/* Reset to booting from this image as late as possible */ boot_successful();
printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n", - prog_entry(&payload->prog), prog_entry_arg(&payload->prog)); + prog_entry(payload), prog_entry_arg(payload)); post_code(POST_ENTER_ELF_BOOT);
timestamp_add_now(TS_SELFBOOT_JUMP); @@ -99,5 +96,5 @@ void payload_run(void) */ checkstack(_estack, 0);
- arch_payload_run(payload); + prog_run(payload); } diff --git a/src/lib/loaders/load_and_run_ramstage.c b/src/lib/loaders/load_and_run_ramstage.c index 9067a28..b3728a1 100644 --- a/src/lib/loaders/load_and_run_ramstage.c +++ b/src/lib/loaders/load_and_run_ramstage.c @@ -25,10 +25,10 @@ #include <romstage_handoff.h> #include <timestamp.h>
-extern const struct ramstage_loader_ops cbfs_ramstage_loader; -extern const struct ramstage_loader_ops vboot_ramstage_loader; +extern const struct prog_loader_ops cbfs_ramstage_loader; +extern const struct prog_loader_ops vboot_ramstage_loader;
-static const struct ramstage_loader_ops *loaders[] = { +static const struct prog_loader_ops *loaders[] = { #if CONFIG_VBOOT_VERIFY_FIRMWARE &vboot_ramstage_loader, #endif @@ -36,12 +36,12 @@ static const struct ramstage_loader_ops *loaders[] = { };
static void -load_ramstage(const struct ramstage_loader_ops *ops, +load_ramstage(const struct prog_loader_ops *ops, struct romstage_handoff *handoff, struct prog *ramstage) { timestamp_add_now(TS_START_COPYRAM);
- if (ops->load(ramstage)) + if (ops->prepare(ramstage)) return;
cache_loaded_ramstage(handoff, ramstage); @@ -68,7 +68,7 @@ static void run_ramstage_from_resume(struct romstage_handoff *handoff, void run_ramstage(void) { struct romstage_handoff *handoff; - const struct ramstage_loader_ops *ops; + const struct prog_loader_ops *ops; int i; struct prog ramstage = { .name = CONFIG_CBFS_PREFIX "/ramstage", diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index 164dce9..ac9c647 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -214,13 +214,13 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
static int build_self_segment_list( struct segment *head, - struct payload *payload, uintptr_t *entry) + struct prog *payload, uintptr_t *entry) { struct segment *new; struct segment *ptr; struct cbfs_payload_segment *segment, *first_segment; struct cbfs_payload *cbfs_payload; - cbfs_payload = prog_start(&payload->prog); + cbfs_payload = prog_start(payload); memset(head, 0, sizeof(*head)); head->next = head->prev = head; first_segment = segment = &cbfs_payload->segments; @@ -311,7 +311,7 @@ static int build_self_segment_list(
static int load_self_segments( struct segment *head, - struct payload *payload) + struct prog *payload) { struct segment *ptr; struct segment *last_non_empty; @@ -457,7 +457,7 @@ static int load_self_segments( return 1; }
-void *selfload(struct payload *payload) +void *selfload(struct prog *payload) { uintptr_t entry = 0; struct segment head;