diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/arch_ops.c | 1 | ||||
-rw-r--r-- | src/lib/cbfs.c | 53 | ||||
-rw-r--r-- | src/lib/loaders/cbfs_payload_loader.c | 5 | ||||
-rw-r--r-- | src/lib/loaders/cbfs_ramstage_loader.c | 29 | ||||
-rw-r--r-- | src/lib/loaders/load_and_run_payload.c | 22 | ||||
-rw-r--r-- | src/lib/loaders/load_and_run_ramstage.c | 43 | ||||
-rw-r--r-- | src/lib/loaders/load_and_run_romstage.c | 12 | ||||
-rw-r--r-- | src/lib/ramstage_cache.c | 55 | ||||
-rw-r--r-- | src/lib/selfboot.c | 2 |
9 files changed, 122 insertions, 100 deletions
diff --git a/src/lib/arch_ops.c b/src/lib/arch_ops.c index b9f57194d7..ac1be77c9e 100644 --- a/src/lib/arch_ops.c +++ b/src/lib/arch_ops.c @@ -26,4 +26,3 @@ void __attribute__ ((weak)) arch_segment_loaded(uintptr_t start, size_t size, { /* do nothing */ } - diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index ebcc134044..fc6e88721e 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -74,17 +74,18 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor, return dest; } -void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset) +static int cbfs_load_prog_stage_by_offset(struct cbfs_media *media, + struct prog *prog, ssize_t offset) { struct cbfs_stage stage; struct cbfs_media backing_store; if (init_backing_media(&media, &backing_store)) - return (void *)-1; + return -1; if (cbfs_read(media, &stage, offset, sizeof(stage)) != sizeof(stage)) { ERROR("ERROR: failed to read stage header\n"); - return (void *)-1; + return -1; } LOG("loading stage @ 0x%llx (%d bytes), entry @ 0x%llx\n", @@ -97,41 +98,71 @@ void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset) if (cbfs_read(media, (void *)(uintptr_t)stage.load, offset + sizeof(stage), stage.len) != stage.len) { ERROR("ERROR: Reading stage failed.\n"); - return (void *)-1; + return -1; } } else { void *data = media->map(media, offset + sizeof(stage), stage.len); if (data == CBFS_MEDIA_INVALID_MAP_ADDRESS) { ERROR("ERROR: Mapping stage failed.\n"); - return (void *)-1; + return -1; } if (!cbfs_decompress(stage.compression, data, (void *)(uintptr_t)stage.load, stage.len)) - return (void *)-1; + return -1; media->unmap(media, data); } arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL); DEBUG("stage loaded\n"); - return (void *)(uintptr_t)stage.entry; + prog_set_area(prog, (void *)(uintptr_t)stage.load, stage.memlen); + prog_set_entry(prog, (void *)(uintptr_t)stage.entry, NULL); + + return 0; } -void *cbfs_load_stage(struct cbfs_media *media, const char *name) +int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog) { struct cbfs_file file; ssize_t offset; struct cbfs_media backing_store; if (init_backing_media(&media, &backing_store)) - return (void *)-1; + return -1; - offset = cbfs_locate_file(media, &file, name); + offset = cbfs_locate_file(media, &file, prog->name); if (offset < 0 || file.type != CBFS_TYPE_STAGE) + return -1; + + if (cbfs_load_prog_stage_by_offset(media, prog, offset) < 0) + return -1; + + return 0; +} + +void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset) +{ + struct prog prog = { + .name = NULL, + }; + + if (cbfs_load_prog_stage_by_offset(media, &prog, offset) < 0) + return (void *)-1; + + return prog_entry(&prog); +} + +void *cbfs_load_stage(struct cbfs_media *media, const char *name) +{ + struct prog prog = { + .name = name, + }; + + if (cbfs_load_prog_stage(media, &prog) < 0) return (void *)-1; - return cbfs_load_stage_by_offset(media, offset); + return prog_entry(&prog); } /* Simple buffer */ diff --git a/src/lib/loaders/cbfs_payload_loader.c b/src/lib/loaders/cbfs_payload_loader.c index 22f4c2fcd6..609d1232e1 100644 --- a/src/lib/loaders/cbfs_payload_loader.c +++ b/src/lib/loaders/cbfs_payload_loader.c @@ -26,14 +26,13 @@ static int cbfs_locate_payload(struct payload *payload) size_t size; const int type = CBFS_TYPE_PAYLOAD; - buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->name, + buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->prog.name, type, &size); if (buffer == NULL) return -1; - payload->backing_store.data = buffer; - payload->backing_store.size = size; + prog_set_area(&payload->prog, buffer, size); return 0; } diff --git a/src/lib/loaders/cbfs_ramstage_loader.c b/src/lib/loaders/cbfs_ramstage_loader.c index 5155aea511..27be88ef7a 100644 --- a/src/lib/loaders/cbfs_ramstage_loader.c +++ b/src/lib/loaders/cbfs_ramstage_loader.c @@ -19,44 +19,37 @@ */ #include <console/console.h> #include <cbfs.h> -#include <arch/stages.h> #include <program_loading.h> -#include <timestamp.h> #if CONFIG_RELOCATABLE_RAMSTAGE #include <rmodule.h> +#include <cbmem.h> -static void *cbfs_load_ramstage(uint32_t cbmem_id, const char *name, - const struct cbmem_entry **cbmem_entry) +static int cbfs_load_ramstage(struct prog *ramstage) { struct rmod_stage_load rmod_ram = { - .cbmem_id = cbmem_id, - .name = name, + .cbmem_id = CBMEM_ID_RAMSTAGE, + .name = ramstage->name, }; if (rmodule_stage_load_from_cbfs(&rmod_ram)) { printk(BIOS_DEBUG, "Could not load ramstage.\n"); - return NULL; + return -1; } - *cbmem_entry = rmod_ram.cbmem_entry; + prog_set_area(ramstage, cbmem_entry_start(rmod_ram.cbmem_entry), + cbmem_entry_size(rmod_ram.cbmem_entry)); + prog_set_entry(ramstage, rmod_ram.entry, NULL); - return rmod_ram.entry; + return 0; } #else /* CONFIG_RELOCATABLE_RAMSTAGE */ -static void *cbfs_load_ramstage(uint32_t cbmem_id, const char *name, - const struct cbmem_entry **cbmem_entry) +static int cbfs_load_ramstage(struct prog *ramstage) { - void *entry; + return cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, ramstage); - entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, name); - - if ((void *)entry == (void *) -1) - entry = NULL; - - return entry; } #endif /* CONFIG_RELOCATABLE_RAMSTAGE */ diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c index 89b6da61f3..8e745c9b3b 100644 --- a/src/lib/loaders/load_and_run_payload.c +++ b/src/lib/loaders/load_and_run_payload.c @@ -19,6 +19,7 @@ #include <stdint.h> #include <stdlib.h> +#include <cbmem.h> #include <console/console.h> #include <fallback.h> #include <lib.h> @@ -36,7 +37,10 @@ static const struct payload_loader_ops *payload_ops[] = { }; static struct payload global_payload = { - .name = CONFIG_CBFS_PREFIX "/payload", + .prog = { + .name = CONFIG_CBFS_PREFIX "/payload", + .type = PROG_PAYLOAD, + }, }; void __attribute__((weak)) mirror_payload(struct payload *payload) @@ -47,9 +51,9 @@ void __attribute__((weak)) mirror_payload(struct payload *payload) void payload_load(void) { int i; - void *entry; const struct payload_loader_ops *ops; struct payload *payload = &global_payload; + struct prog * prog = &payload->prog; for (i = 0; i < ARRAY_SIZE(payload_ops); i++) { ops = payload_ops[i]; @@ -59,8 +63,7 @@ void payload_load(void) continue; } printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n", - ops->name, payload->backing_store.data, - payload->backing_store.size); + ops->name, prog_start(prog), prog_size(prog)); break; } @@ -69,12 +72,12 @@ void payload_load(void) mirror_payload(payload); - entry = selfload(payload); - - payload->entry = entry; + /* Pass cbtables to payload if architecture desires it. */ + prog_set_entry(&payload->prog, selfload(payload), + cbmem_find(CBMEM_ID_CBTABLE)); out: - if (payload->entry == NULL) + if (prog_entry(&payload->prog) == NULL) die("Payload not loaded.\n"); } @@ -85,7 +88,8 @@ void payload_run(void) /* Reset to booting from this image as late as possible */ boot_successful(); - printk(BIOS_DEBUG, "Jumping to boot code at %p\n", payload->entry); + printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n", + prog_entry(&payload->prog), prog_entry_arg(&payload->prog)); post_code(POST_ENTER_ELF_BOOT); timestamp_add_now(TS_SELFBOOT_JUMP); diff --git a/src/lib/loaders/load_and_run_ramstage.c b/src/lib/loaders/load_and_run_ramstage.c index b24e29fc2d..82bc1e08fd 100644 --- a/src/lib/loaders/load_and_run_ramstage.c +++ b/src/lib/loaders/load_and_run_ramstage.c @@ -21,7 +21,6 @@ #include <console/console.h> #include <arch/stages.h> #include <cbfs.h> -#include <cbmem.h> #include <program_loading.h> #include <romstage_handoff.h> #include <timestamp.h> @@ -36,46 +35,32 @@ static const struct ramstage_loader_ops *loaders[] = { &cbfs_ramstage_loader, }; -static const char *ramstage_name = CONFIG_CBFS_PREFIX "/ramstage"; -static const uint32_t ramstage_id = CBMEM_ID_RAMSTAGE; - static void -load_ramstage(const struct ramstage_loader_ops *ops, struct romstage_handoff *handoff) +load_ramstage(const struct ramstage_loader_ops *ops, + struct romstage_handoff *handoff, struct prog *ramstage) { - const struct cbmem_entry *cbmem_entry; - void *entry_point; - timestamp_add_now(TS_START_COPYRAM); - entry_point = ops->load(ramstage_id, ramstage_name, &cbmem_entry); - if (entry_point == NULL) + if (ops->load(ramstage)) return; - cache_loaded_ramstage(handoff, cbmem_entry, entry_point); + cache_loaded_ramstage(handoff, ramstage); timestamp_add_now(TS_END_COPYRAM); - stage_exit(entry_point); + stage_exit(prog_entry(ramstage)); } -static void run_ramstage_from_resume(struct romstage_handoff *handoff) +static void run_ramstage_from_resume(struct romstage_handoff *handoff, + struct prog *ramstage) { - void *entry; - const struct cbmem_entry *cbmem_entry; - if (handoff != NULL && handoff->s3_resume) { - cbmem_entry = cbmem_entry_find(ramstage_id); - - /* No place to load ramstage. */ - if (cbmem_entry == NULL) - return; - /* Load the cached ramstage to runtime location. */ - entry = load_cached_ramstage(handoff, cbmem_entry); + load_cached_ramstage(handoff, ramstage); - if (entry != NULL) { + if (prog_entry(ramstage) != NULL) { printk(BIOS_DEBUG, "Jumping to image.\n"); - stage_exit(entry); + stage_exit(prog_entry(ramstage)); } } } @@ -85,15 +70,19 @@ void run_ramstage(void) struct romstage_handoff *handoff; const struct ramstage_loader_ops *ops; int i; + struct prog ramstage = { + .name = CONFIG_CBFS_PREFIX "/ramstage", + .type = PROG_RAMSTAGE, + }; handoff = romstage_handoff_find_or_add(); - run_ramstage_from_resume(handoff); + run_ramstage_from_resume(handoff, &ramstage); for (i = 0; i < ARRAY_SIZE(loaders); i++) { ops = loaders[i]; printk(BIOS_DEBUG, "Trying %s ramstage loader.\n", ops->name); - load_ramstage(ops, handoff); + load_ramstage(ops, handoff, &ramstage); } die("Ramstage was not loaded!\n"); diff --git a/src/lib/loaders/load_and_run_romstage.c b/src/lib/loaders/load_and_run_romstage.c index ebc1243594..3ad9176877 100644 --- a/src/lib/loaders/load_and_run_romstage.c +++ b/src/lib/loaders/load_and_run_romstage.c @@ -27,16 +27,16 @@ void run_romstage(void) { - void *entry; + struct prog romstage = { + .name = CONFIG_CBFS_PREFIX "/romstage", + .type = PROG_ROMSTAGE, + }; - entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, - CONFIG_CBFS_PREFIX "/romstage"); - - if (entry == (void *)-1) { + if (cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, &romstage) < 0) { if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) die("Couldn't load romstage.\n"); halt(); } - stage_exit(entry); + stage_exit(prog_entry(&romstage)); } diff --git a/src/lib/ramstage_cache.c b/src/lib/ramstage_cache.c index d61f1c16e6..1dd40c7d5e 100644 --- a/src/lib/ramstage_cache.c +++ b/src/lib/ramstage_cache.c @@ -27,8 +27,7 @@ #if CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM void cache_loaded_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage, - void *entry_point) + struct prog *ramstage) { struct ramstage_cache *cache; uint32_t total_size; @@ -36,8 +35,8 @@ void cache_loaded_ramstage(struct romstage_handoff *handoff, void *ramstage_base; long cache_size = 0; - ramstage_size = cbmem_entry_size(ramstage); - ramstage_base = cbmem_entry_start(ramstage); + ramstage_size = prog_size(ramstage); + ramstage_base = prog_start(ramstage); cache = ramstage_cache_location(&cache_size); @@ -56,7 +55,7 @@ void cache_loaded_ramstage(struct romstage_handoff *handoff, } cache->magic = RAMSTAGE_CACHE_MAGIC; - cache->entry_point = (uint32_t)entry_point; + cache->entry_point = (uint32_t)prog_entry(ramstage); cache->load_address = (uint32_t)ramstage_base; cache->size = ramstage_size; @@ -68,11 +67,11 @@ void cache_loaded_ramstage(struct romstage_handoff *handoff, if (handoff == NULL) return; - handoff->ramstage_entry_point = (uint32_t)entry_point; + handoff->ramstage_entry_point = cache->entry_point; } -void *load_cached_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage) +void load_cached_ramstage(struct romstage_handoff *handoff, + struct prog *ramstage) { struct ramstage_cache *cache; long size = 0; @@ -82,14 +81,15 @@ void *load_cached_ramstage(struct romstage_handoff *handoff, if (!ramstage_cache_is_valid(cache)) { printk(BIOS_DEBUG, "Invalid ramstage cache found.\n"); ramstage_cache_invalid(cache); - return NULL; + return; } printk(BIOS_DEBUG, "Loading ramstage from %p.\n", cache); - memcpy((void *)cache->load_address, &cache->program[0], cache->size); + prog_set_area(ramstage, (void *)cache->load_address, cache->size); + prog_set_entry(ramstage, (void *)cache->entry_point, NULL); - return (void *)cache->entry_point; + memcpy((void *)cache->load_address, &cache->program[0], cache->size); } #else @@ -97,7 +97,7 @@ void *load_cached_ramstage(struct romstage_handoff *handoff, /* Cache relocated ramstage in CBMEM. */ void cache_loaded_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage, void *entry_point) + struct prog *ramstage) { uint32_t ramstage_size; const struct cbmem_entry *entry; @@ -105,7 +105,7 @@ void cache_loaded_ramstage(struct romstage_handoff *handoff, if (handoff == NULL) return; - ramstage_size = cbmem_entry_size(ramstage); + ramstage_size = prog_size(ramstage); /* cbmem_entry_add() does a find() before add(). */ entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE_CACHE, ramstage_size); @@ -113,30 +113,37 @@ void cache_loaded_ramstage(struct romstage_handoff *handoff, return; /* Keep track of the entry point in the handoff structure. */ - handoff->ramstage_entry_point = (uint32_t)entry_point; + handoff->ramstage_entry_point = (uint32_t)prog_entry(ramstage); - memcpy(cbmem_entry_start(entry), cbmem_entry_start(ramstage), - ramstage_size); + memcpy(cbmem_entry_start(entry), prog_start(ramstage), ramstage_size); } -void *load_cached_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage) +void load_cached_ramstage(struct romstage_handoff *handoff, + struct prog *ramstage) { const struct cbmem_entry *entry_cache; + const struct cbmem_entry *entry_dest; if (handoff == NULL) - return NULL; + return; entry_cache = cbmem_entry_find(CBMEM_ID_RAMSTAGE_CACHE); if (entry_cache == NULL) - return NULL; + return; - /* Load the cached ramstage copy into the to-be-run region. */ - memcpy(cbmem_entry_start(ramstage), cbmem_entry_start(entry_cache), - cbmem_entry_size(ramstage)); + entry_dest = cbmem_entry_find(CBMEM_ID_RAMSTAGE); + + if (entry_dest == NULL) + return; - return (void *)handoff->ramstage_entry_point; + prog_set_area(ramstage, cbmem_entry_start(entry_dest), + cbmem_entry_size(entry_dest)); + prog_set_entry(ramstage, (void *)handoff->ramstage_entry_point, NULL); + + /* Load the cached ramstage copy into the to-be-run region. */ + memcpy(prog_start(ramstage), cbmem_entry_start(entry_cache), + prog_size(ramstage)); } #endif diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index b29a34eb36..164dce90de 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -220,7 +220,7 @@ static int build_self_segment_list( struct segment *ptr; struct cbfs_payload_segment *segment, *first_segment; struct cbfs_payload *cbfs_payload; - cbfs_payload = payload->backing_store.data; + cbfs_payload = prog_start(&payload->prog); memset(head, 0, sizeof(*head)); head->next = head->prev = head; first_segment = segment = &cbfs_payload->segments; |