summaryrefslogtreecommitdiff
path: root/src/vendorcode/google/chromeos/vboot2
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2015-05-15 23:25:46 -0500
committerAaron Durbin <adurbin@chromium.org>2015-05-26 22:34:23 +0200
commit4e50cdd979c03a0d64cc1b4c9ada45822aa6d346 (patch)
treeea3dd5b45f7bb56d68a07ad94421e6cd7bd0b99c /src/vendorcode/google/chromeos/vboot2
parent0424c95a6dafdb65070538d6c5aa394b75eb9850 (diff)
vboot: move to region_devices
Now that vboot is using offsets for everything remove the pass through vboot_get_region() and use region_devices as first class citizens. Change-Id: I1a86f3725e5bce38e6ca31e9641b1a8f4ac50e96 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/10225 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/vendorcode/google/chromeos/vboot2')
-rw-r--r--src/vendorcode/google/chromeos/vboot2/misc.h18
-rw-r--r--src/vendorcode/google/chromeos/vboot2/vboot_handoff.c19
-rw-r--r--src/vendorcode/google/chromeos/vboot2/vboot_loader.c67
-rw-r--r--src/vendorcode/google/chromeos/vboot2/verstage.c43
4 files changed, 83 insertions, 64 deletions
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index 1b3f41eb6f..d4f9f48cf0 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -46,18 +46,22 @@ struct vb2_working_data * const vboot_get_working_data(void);
size_t vb2_working_data_size(void);
void *vboot_get_work_buffer(struct vb2_working_data *wd);
-static inline void vb2_get_selected_region(struct vb2_working_data *wd,
- struct region *region)
+/* Returns 0 on success. < 0 on failure. */
+static inline int vb2_get_selected_region(struct vb2_working_data *wd,
+ struct region_device *rdev)
{
- region->offset = wd->selected_region_offset;
- region->size = wd->selected_region_size;
+ struct region reg = {
+ .offset = wd->selected_region_offset,
+ .size = wd->selected_region_size,
+ };
+ return vboot_region_device(&reg, rdev);
}
static inline void vb2_set_selected_region(struct vb2_working_data *wd,
- struct region *region)
+ struct region_device *rdev)
{
- wd->selected_region_offset = region_offset(region);
- wd->selected_region_size = region_sz(region);
+ wd->selected_region_offset = region_device_offset(rdev);
+ wd->selected_region_size = region_device_sz(rdev);
}
static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
index e7e0d99632..955d72fa43 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -127,8 +127,9 @@ void vboot_fill_handoff(void)
int i;
struct vboot_handoff *vh;
struct vb2_shared_data *sd;
- struct region fw_main;
+ struct region_device fw_main;
struct vboot_components *fw_info;
+ size_t metadata_sz;
struct vb2_working_data *wd = vboot_get_working_data();
sd = vboot_get_work_buffer(wd);
@@ -151,15 +152,23 @@ void vboot_fill_handoff(void)
if (vboot_is_readonly_path(wd))
return;
- vb2_get_selected_region(wd, &fw_main);
- fw_info = vboot_locate_components(&fw_main);
+ if (vb2_get_selected_region(wd, &fw_main))
+ die("No component metadata.\n");
+
+ 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)
die("failed to locate firmware components\n");
/* these offset & size are used to load a rw boot loader */
for (i = 0; i < fw_info->num_components; i++) {
- vh->components[i].address =
- region_offset(&fw_main) + fw_info->entries[i].offset;
+ vh->components[i].address = region_device_offset(&fw_main);
+ vh->components[i].address += fw_info->entries[i].offset;
vh->components[i].size = fw_info->entries[i].size;
}
+
+ rdev_munmap(&fw_main, fw_info);
}
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))
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
index 249053cffe..bc7846a37d 100644
--- a/src/vendorcode/google/chromeos/vboot2/verstage.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -67,27 +67,28 @@ int vb2ex_read_resource(struct vb2_context *ctx,
void *buf,
uint32_t size)
{
- struct region region;
+ struct region_device rdev;
+ const char *name;
switch (index) {
case VB2_RES_GBB:
- vboot_locate_region("GBB", &region);
+ name = "GBB";
break;
case VB2_RES_FW_VBLOCK:
if (is_slot_a(ctx))
- vboot_locate_region("VBLOCK_A", &region);
+ name = "VBLOCK_A";
else
- vboot_locate_region("VBLOCK_B", &region);
+ name = "VBLOCK_B";
break;
default:
return VB2_ERROR_EX_READ_RESOURCE_INDEX;
}
- if (offset + size > region_sz(&region))
+ if (vboot_named_region_device(name, &rdev))
return VB2_ERROR_EX_READ_RESOURCE_SIZE;
- if (vboot_get_region(region_offset(&region) + offset, size, buf) == NULL)
- return VB2_ERROR_UNKNOWN;
+ if (rdev_readat(&rdev, buf, offset, size) != size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
return VB2_SUCCESS;
}
@@ -114,7 +115,7 @@ int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
return VB2_ERROR_UNKNOWN;
}
-static int hash_body(struct vb2_context *ctx, struct region *fw_main)
+static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
{
uint64_t load_ts;
uint32_t expected_size;
@@ -132,8 +133,8 @@ static int hash_body(struct vb2_context *ctx, struct region *fw_main)
load_ts = timestamp_get();
timestamp_add(TS_START_HASH_BODY, load_ts);
- expected_size = region_sz(fw_main);
- offset = region_offset(fw_main);
+ expected_size = region_device_sz(fw_main);
+ offset = 0;
/* Start the body hash */
rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
@@ -143,17 +144,15 @@ static int hash_body(struct vb2_context *ctx, struct region *fw_main)
/* Extend over the body */
while (expected_size) {
uint64_t temp_ts;
- void *b;
if (block_size > expected_size)
block_size = expected_size;
temp_ts = timestamp_get();
- b = vboot_get_region(offset, block_size, block);
- if (b == NULL)
+ if (rdev_readat(fw_main, block, offset, block_size) < 0)
return VB2_ERROR_UNKNOWN;
load_ts += timestamp_get() - temp_ts;
- rv = vb2api_extend_hash(ctx, b, block_size);
+ rv = vb2api_extend_hash(ctx, block, block_size);
if (rv)
return rv;
@@ -174,17 +173,17 @@ static int hash_body(struct vb2_context *ctx, struct region *fw_main)
return VB2_SUCCESS;
}
-static int locate_firmware(struct vb2_context *ctx, struct region *fw_main)
+static int locate_firmware(struct vb2_context *ctx,
+ struct region_device *fw_main)
{
+ const char *name;
+
if (is_slot_a(ctx))
- vboot_locate_region("FW_MAIN_A", fw_main);
+ name = "FW_MAIN_A";
else
- vboot_locate_region("FW_MAIN_B", fw_main);
-
- if (region_sz(fw_main) == 0)
- return 1;
+ name = "FW_MAIN_B";
- return 0;
+ return vboot_named_region_device(name, fw_main);
}
/**
@@ -219,7 +218,7 @@ static uint32_t extend_pcrs(struct vb2_context *ctx)
void verstage_main(void)
{
struct vb2_context ctx;
- struct region fw_main;
+ struct region_device fw_main;
struct vb2_working_data *wd = vboot_get_working_data();
int rv;
timestamp_add_now(TS_START_VBOOT);