aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/google/chromeos/vboot2/vboot_loader.c')
-rw-r--r--src/vendorcode/google/chromeos/vboot2/vboot_loader.c149
1 files changed, 53 insertions, 96 deletions
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
index 226578bc8c..5248305a04 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
@@ -98,7 +98,8 @@ static int vboot_loader_active(struct prog *prog)
printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
/* load verstage from RO */
- if (cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, &verstage))
+ if (cbfs_boot_locate(&verstage.rdev, verstage.name, NULL) ||
+ cbfs_prog_stage_load(&verstage))
die("failed to load verstage");
/* verify and select a slot */
@@ -118,29 +119,34 @@ static int vboot_loader_active(struct prog *prog)
wd = vboot_get_working_data();
- if (vboot_is_slot_selected(wd)) {
- if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES) &&
- run_verification) {
- /* RW A or B */
- struct region_device fw_main;
-
- if (vb2_get_selected_region(wd, &fw_main))
- die("failed to reference selected region\n");
- cbfs_set_header_offset(region_device_offset(&fw_main));
- }
+ if (vboot_is_slot_selected(wd))
return 1;
- }
return 0;
}
-static int vboot_fw_region(int fw_index, const struct region_device *fw_main,
- struct region_device *fw)
+static int vboot_locate_by_components(const struct region_device *fw_main,
+ struct prog *prog)
{
struct vboot_components *fw_info;
size_t metadata_sz;
size_t offset;
size_t size;
+ struct region_device *fw = &prog->rdev;
+ int fw_index = 0;
+
+ if (prog->type == PROG_ROMSTAGE)
+ fw_index = CONFIG_VBOOT_ROMSTAGE_INDEX;
+ else if (prog->type == PROG_RAMSTAGE)
+ fw_index = CONFIG_VBOOT_RAMSTAGE_INDEX;
+ else if (prog->type == PROG_PAYLOAD)
+ fw_index = CONFIG_VBOOT_BOOT_LOADER_INDEX;
+ else if (prog->type == PROG_REFCODE)
+ fw_index = CONFIG_VBOOT_REFCODE_INDEX;
+ else if (prog->type == PROG_BL31)
+ fw_index = CONFIG_VBOOT_BL31_INDEX;
+ else
+ die("Invalid program type for vboot.");
metadata_sz = sizeof(*fw_info);
metadata_sz += MAX_PARSED_FW_COMPONENTS * sizeof(fw_info->entries[0]);
@@ -153,7 +159,7 @@ static int vboot_fw_region(int fw_index, const struct region_device *fw_main,
}
if (fw_index >= fw_info->num_components) {
- printk(BIOS_INFO, "invalid stage index: %d\n", fw_index);
+ printk(BIOS_INFO, "invalid index: %d\n", fw_index);
rdev_munmap(fw_main, fw_info);
return -1;
}
@@ -163,16 +169,44 @@ static int vboot_fw_region(int fw_index, const struct region_device *fw_main,
rdev_munmap(fw_main, fw_info);
if (rdev_chain(fw, fw_main, offset, size)) {
- printk(BIOS_INFO, "invalid stage address or size\n");
+ printk(BIOS_INFO, "invalid offset or size\n");
return -1;
}
return 0;
}
+static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main,
+ struct prog *prog)
+{
+ struct cbfsd cbfs;
+ struct region_device rdev;
+ struct cbfs_props props;
+
+ if (cbfs_boot_region_properties(&props))
+ return -1;
+
+ if (rdev_chain(&rdev, fw_main, props.offset, props.size))
+ return -1;
+
+ cbfs.rdev = &rdev;
+ cbfs.align = props.align;
+
+ return cbfs_locate(&prog->rdev, &cbfs, prog->name, NULL);
+}
+
+static int vboot_prog_locate(const struct region_device *fw_main,
+ struct prog *prog)
+{
+ if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES))
+ return vboot_locate_by_multi_cbfs(fw_main, prog);
+ else
+ return vboot_locate_by_components(fw_main, prog);
+}
+
/* This function is only called when vboot_loader_active() returns 1. That
* means we are taking vboot paths. */
-static int vboot_prepare(struct prog *prog)
+static int vboot_locate(struct prog *prog)
{
struct vb2_working_data *wd;
struct region_device fw_main;
@@ -183,92 +217,15 @@ static int vboot_prepare(struct prog *prog)
if (verstage_should_load() && !IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
return 0;
- /* In the multi cbfs case the cbfs offset pointer has already been
- * updated after firmware verification. */
- if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)) {
- if (!ENV_RAMSTAGE &&
- cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, prog) != 0)
- return -1;
-
- /* Need to load payload. */
- if (ENV_RAMSTAGE) {
- void *payload;
- size_t size;
-
- payload = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
- prog->name,
- CBFS_TYPE_PAYLOAD,
- &size);
-
- if (payload == NULL)
- die("Couldn't load payload\n");
-
- prog_set_area(prog, payload, size);
- }
- return 0;
- }
-
wd = vboot_get_working_data();
if (vb2_get_selected_region(wd, &fw_main))
die("failed to reference selected region\n");
- /* Load payload in ramstage. */
- if (ENV_RAMSTAGE) {
- struct region_device payload;
- void *payload_ptr;
-
- if (vboot_fw_region(CONFIG_VBOOT_BOOT_LOADER_INDEX,
- &fw_main, &payload))
- die("Couldn't load payload.");
-
- payload_ptr = rdev_mmap_full(&payload);
-
- if (payload_ptr == NULL)
- die("Couldn't load payload.");
-
- prog_set_area(prog, payload_ptr, region_device_sz(&payload));
- } else {
- struct region_device stage;
- int stage_index = 0;
-
- if (prog->type == PROG_ROMSTAGE)
- stage_index = CONFIG_VBOOT_ROMSTAGE_INDEX;
- else if (prog->type == PROG_RAMSTAGE)
- stage_index = CONFIG_VBOOT_RAMSTAGE_INDEX;
- else
- die("Invalid program type for vboot.");
-
- if (vboot_fw_region(stage_index, &fw_main, &stage))
- die("Vboot stage load failed.");
-
- if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) {
- void *stage_ptr;
- struct rmod_stage_load rmod_ram = {
- .cbmem_id = CBMEM_ID_RAMSTAGE,
- .prog = prog,
- };
-
- stage_ptr = rdev_mmap_full(&stage);
-
- if (stage_ptr == NULL)
- die("Vboot couldn't load stage.");
-
- if (rmodule_stage_load(&rmod_ram, stage_ptr))
- die("Vboot couldn't load stage");
- } else {
- size_t offset = region_device_offset(&stage);
-
- if (cbfs_load_prog_stage_by_offset(CBFS_DEFAULT_MEDIA,
- prog, offset))
- die("Vboot couldn't load stage");
- }
- }
-
- return 0;
+ return vboot_prog_locate(&fw_main, prog);
}
const struct prog_loader_ops vboot_loader = {
.name = "VBOOT",
.is_loader_active = vboot_loader_active,
- .prepare = vboot_prepare,
+ .locate = vboot_locate,
};