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.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
index 1129cd13c3..226578bc8c 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
@@ -25,6 +25,7 @@
#include <rules.h>
#include <string.h>
#include "misc.h"
+#include "../vboot_handoff.h"
#include "../symbols.h"
/* The stage loading code is compiled and entered from multiple stages. The
@@ -121,10 +122,11 @@ static int vboot_loader_active(struct prog *prog)
if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES) &&
run_verification) {
/* RW A or B */
- struct region fw_main;
+ struct region_device fw_main;
- vb2_get_selected_region(wd, &fw_main);
- cbfs_set_header_offset(region_offset(&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));
}
return 1;
}
@@ -132,25 +134,35 @@ static int vboot_loader_active(struct prog *prog)
return 0;
}
-static int vboot_fw_region(int fw_index, struct region *fw_main,
- struct vboot_components *fw_info,
- struct region *fc)
+static int vboot_fw_region(int fw_index, const struct region_device *fw_main,
+ struct region_device *fw)
{
- size_t fw_main_end;
- size_t fc_end;
+ struct vboot_components *fw_info;
+ size_t metadata_sz;
+ size_t offset;
+ size_t size;
+
+ metadata_sz = sizeof(*fw_info);
+ metadata_sz += MAX_PARSED_FW_COMPONENTS * sizeof(fw_info->entries[0]);
+
+ fw_info = rdev_mmap(fw_main, 0, metadata_sz);
+
+ if (fw_info == NULL) {
+ printk(BIOS_INFO, "No component metadata.\n");
+ return -1;
+ }
if (fw_index >= fw_info->num_components) {
printk(BIOS_INFO, "invalid stage index: %d\n", fw_index);
+ rdev_munmap(fw_main, fw_info);
return -1;
}
- fc->offset = region_offset(fw_main) + fw_info->entries[fw_index].offset;
- fc->size = fw_info->entries[fw_index].size;
+ offset = fw_info->entries[fw_index].offset;
+ size = fw_info->entries[fw_index].size;
+ rdev_munmap(fw_main, fw_info);
- fw_main_end = region_offset(fw_main) + region_sz(fw_main);
- fc_end = region_offset(fc) + region_sz(fc);
-
- if (region_sz(fc) == 0 || fc_end > fw_main_end) {
+ if (rdev_chain(fw, fw_main, offset, size)) {
printk(BIOS_INFO, "invalid stage address or size\n");
return -1;
}
@@ -163,8 +175,7 @@ static int vboot_fw_region(int fw_index, struct region *fw_main,
static int vboot_prepare(struct prog *prog)
{
struct vb2_working_data *wd;
- struct region fw_main;
- struct vboot_components *fw_info;
+ struct region_device fw_main;
/* Code size optimization. We'd never actually get called under the
* followin cirumstances because verstage was loaded and ran -- never
@@ -198,29 +209,26 @@ static int vboot_prepare(struct prog *prog)
}
wd = vboot_get_working_data();
- vb2_get_selected_region(wd, &fw_main);
- fw_info = vboot_locate_components(&fw_main);
- if (fw_info == NULL)
- die("failed to locate firmware components\n");
+ if (vb2_get_selected_region(wd, &fw_main))
+ die("failed to reference selected region\n");
/* Load payload in ramstage. */
if (ENV_RAMSTAGE) {
- struct region payload;
+ struct region_device payload;
void *payload_ptr;
if (vboot_fw_region(CONFIG_VBOOT_BOOT_LOADER_INDEX,
- &fw_main, fw_info, &payload))
+ &fw_main, &payload))
die("Couldn't load payload.");
- payload_ptr = vboot_get_region(region_offset(&payload),
- region_sz(&payload), NULL);
+ payload_ptr = rdev_mmap_full(&payload);
if (payload_ptr == NULL)
die("Couldn't load payload.");
- prog_set_area(prog, payload_ptr, region_sz(&payload));
+ prog_set_area(prog, payload_ptr, region_device_sz(&payload));
} else {
- struct region stage;
+ struct region_device stage;
int stage_index = 0;
if (prog->type == PROG_ROMSTAGE)
@@ -230,7 +238,7 @@ static int vboot_prepare(struct prog *prog)
else
die("Invalid program type for vboot.");
- if (vboot_fw_region(stage_index, &fw_main, fw_info, &stage))
+ if (vboot_fw_region(stage_index, &fw_main, &stage))
die("Vboot stage load failed.");
if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) {
@@ -240,8 +248,7 @@ static int vboot_prepare(struct prog *prog)
.prog = prog,
};
- stage_ptr = vboot_get_region(region_offset(&stage),
- region_sz(&stage), NULL);
+ stage_ptr = rdev_mmap_full(&stage);
if (stage_ptr == NULL)
die("Vboot couldn't load stage.");
@@ -249,7 +256,7 @@ static int vboot_prepare(struct prog *prog)
if (rmodule_stage_load(&rmod_ram, stage_ptr))
die("Vboot couldn't load stage");
} else {
- size_t offset = region_offset(&stage);
+ size_t offset = region_device_offset(&stage);
if (cbfs_load_prog_stage_by_offset(CBFS_DEFAULT_MEDIA,
prog, offset))