diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/fit_payload.c | 16 | ||||
-rw-r--r-- | src/lib/prog_loaders.c | 15 | ||||
-rw-r--r-- | src/lib/selfboot.c | 50 |
3 files changed, 35 insertions, 46 deletions
diff --git a/src/lib/fit_payload.c b/src/lib/fit_payload.c index b3a03a1942..9613418b95 100644 --- a/src/lib/fit_payload.c +++ b/src/lib/fit_payload.c @@ -13,7 +13,6 @@ #include <timestamp.h> #include <string.h> #include <lib.h> -#include <fit_payload.h> #include <boardid.h> /* Pack the device_tree and place it at given position. */ @@ -168,16 +167,10 @@ static void add_cb_fdt_data(struct device_tree *tree) /* * Parse the uImage FIT, choose a configuration and extract images. */ -void fit_payload(struct prog *payload) +void fit_payload(struct prog *payload, void *data) { struct device_tree *dt = NULL; struct region kernel = {0}, fdt = {0}, initrd = {0}; - void *data; - - data = rdev_mmap_full(prog_rdev(payload)); - - if (data == NULL) - return; printk(BIOS_INFO, "FIT: Examine payload %s\n", payload->name); @@ -185,14 +178,12 @@ void fit_payload(struct prog *payload) if (!config) { printk(BIOS_ERR, "ERROR: Could not load FIT\n"); - rdev_munmap(prog_rdev(payload), data); return; } dt = unpack_fdt(config->fdt); if (!dt) { printk(BIOS_ERR, "ERROR: Failed to unflatten the FDT.\n"); - rdev_munmap(prog_rdev(payload), data); return; } @@ -225,7 +216,6 @@ void fit_payload(struct prog *payload) if (!fit_payload_arch(payload, config, &kernel, &fdt, &initrd)) { printk(BIOS_ERR, "ERROR: Failed to find free memory region\n"); bootmem_dump_ranges(); - rdev_munmap(prog_rdev(payload), data); return; } @@ -240,7 +230,6 @@ void fit_payload(struct prog *payload) extract(&initrd, config->ramdisk)) { printk(BIOS_ERR, "ERROR: Failed to extract initrd\n"); prog_set_entry(payload, NULL, NULL); - rdev_munmap(prog_rdev(payload), data); return; } @@ -249,11 +238,8 @@ void fit_payload(struct prog *payload) if (extract(&kernel, config->kernel)) { printk(BIOS_ERR, "ERROR: Failed to extract kernel\n"); prog_set_entry(payload, NULL, NULL); - rdev_munmap(prog_rdev(payload), data); return; } timestamp_add_now(TS_START_KERNEL); - - rdev_munmap(prog_rdev(payload), data); } diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c index b31d79341f..22abeb5dfd 100644 --- a/src/lib/prog_loaders.c +++ b/src/lib/prog_loaders.c @@ -14,7 +14,6 @@ #include <stage_cache.h> #include <symbols.h> #include <timestamp.h> -#include <fit_payload.h> #include <security/vboot/vboot_common.h> /* Only can represent up to 1 byte less than size_t. */ @@ -154,24 +153,30 @@ void payload_load(void) timestamp_add_now(TS_LOAD_PAYLOAD); - if (prog_locate(payload)) + 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); + if (!mapping) goto out; switch (prog_cbfs_type(payload)) { case CBFS_TYPE_SELF: /* Simple ELF */ - selfload_check(payload, BM_MEM_RAM); + selfload_mapped(payload, mapping, BM_MEM_RAM); break; case CBFS_TYPE_FIT: /* Flattened image tree */ if (CONFIG(PAYLOAD_FIT_SUPPORT)) { - fit_payload(payload); + fit_payload(payload, mapping); break; } /* else fall-through */ default: die_with_post_code(POST_INVALID_ROM, - "Unsupported payload type.\n"); + "Unsupported payload type %d.\n", payload->cbfs_type); break; } + cbfs_unmap(mapping); out: if (prog_entry(payload) == NULL) die_with_post_code(POST_INVALID_ROM, "Payload not loaded.\n"); diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index a08dcaba8e..641631a03e 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -126,12 +126,15 @@ static int last_loadable_segment(struct cbfs_payload_segment *seg) } static int check_payload_segments(struct cbfs_payload_segment *cbfssegs, - void *args) + enum bootmem_type dest_type) { uint8_t *dest; size_t memsz; struct cbfs_payload_segment *seg, segment; - enum bootmem_type dest_type = *(enum bootmem_type *)args; + + /* dest_type == INVALID means we're not supposed to check anything. */ + if (dest_type == BM_MEM_INVALID) + return 0; for (seg = cbfssegs;; ++seg) { printk(BIOS_DEBUG, "Checking segment from ROM address %p\n", seg); @@ -224,50 +227,45 @@ __weak int payload_arch_usable_ram_quirk(uint64_t start, uint64_t size) return 0; } -static void *selfprepare(struct prog *payload) -{ - void *data; - data = rdev_mmap_full(prog_rdev(payload)); - return data; -} - -static bool _selfload(struct prog *payload, checker_t f, void *args) +bool selfload_mapped(struct prog *payload, void *mapping, + enum bootmem_type dest_type) { uintptr_t entry = 0; struct cbfs_payload_segment *cbfssegs; - void *data; - - data = selfprepare(payload); - if (data == NULL) - return false; - cbfssegs = &((struct cbfs_payload *)data)->segments; + cbfssegs = &((struct cbfs_payload *)mapping)->segments; - if (f && f(cbfssegs, args)) - goto out; + if (check_payload_segments(cbfssegs, dest_type)) + return false; if (load_payload_segments(cbfssegs, &entry)) - goto out; + return false; printk(BIOS_SPEW, "Loaded segments\n"); - rdev_munmap(prog_rdev(payload), data); - /* Pass cbtables to payload if architecture desires it. */ prog_set_entry(payload, (void *)entry, cbmem_find(CBMEM_ID_CBTABLE)); return true; -out: - rdev_munmap(prog_rdev(payload), data); - return false; } bool selfload_check(struct prog *payload, enum bootmem_type dest_type) { - return _selfload(payload, check_payload_segments, &dest_type); + if (prog_locate_hook(payload)) + return false; + + payload->cbfs_type = CBFS_TYPE_SELF; + void *mapping = cbfs_type_map(prog_name(payload), NULL, &payload->cbfs_type); + if (!mapping) + return false; + + bool ret = selfload_mapped(payload, mapping, dest_type); + + cbfs_unmap(mapping); + return ret; } bool selfload(struct prog *payload) { - return _selfload(payload, NULL, 0); + return selfload_check(payload, BM_MEM_INVALID); } |