summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/fit_payload.c16
-rw-r--r--src/lib/prog_loaders.c15
-rw-r--r--src/lib/selfboot.c50
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);
}