[coreboot-gerrit] Patch set updated for coreboot: c11bc90 vboot: move to region_devices

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Mon May 18 20:40:16 CEST 2015


Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10225

-gerrit

commit c11bc90f3eab128585b2e16782df839e91c5b22e
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Fri May 15 23:25:46 2015 -0500

    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 at chromium.org>
---
 src/vendorcode/google/chromeos/vbnv_flash.c        | 26 +++++----
 src/vendorcode/google/chromeos/vboot2/misc.h       | 18 +++---
 .../google/chromeos/vboot2/vboot_handoff.c         | 19 ++++--
 .../google/chromeos/vboot2/vboot_loader.c          | 67 ++++++++++++----------
 src/vendorcode/google/chromeos/vboot2/verstage.c   | 43 +++++++-------
 src/vendorcode/google/chromeos/vboot_common.c      | 45 ++-------------
 src/vendorcode/google/chromeos/vboot_common.h      | 14 +----
 7 files changed, 104 insertions(+), 128 deletions(-)

diff --git a/src/vendorcode/google/chromeos/vbnv_flash.c b/src/vendorcode/google/chromeos/vbnv_flash.c
index c0d0fe2..ffd6d34 100644
--- a/src/vendorcode/google/chromeos/vbnv_flash.c
+++ b/src/vendorcode/google/chromeos/vbnv_flash.c
@@ -32,7 +32,7 @@
 #define BLOB_SIZE VB2_NVDATA_SIZE
 
 /* FMAP descriptor of the NVRAM area */
-static struct region nvram_region;
+static struct region_device nvram_region;
 
 /* offset of the current nvdata in SPI flash */
 static int blob_offset = -1;
@@ -73,8 +73,8 @@ static int init_vbnv(void)
 	int offset;
 	int i;
 
-	vboot_locate_region("RW_NVRAM", &nvram_region);
-	if (region_sz(&nvram_region) < BLOB_SIZE) {
+	if (vboot_named_region_device("RW_NVRAM", &nvram_region) ||
+	    region_device_sz(&nvram_region) < BLOB_SIZE) {
 		printk(BIOS_ERR, "%s: failed to locate NVRAM\n", __func__);
 		return 1;
 	}
@@ -83,8 +83,8 @@ static int init_vbnv(void)
 	for (i = 0; i < BLOB_SIZE; i++)
 		empty_blob[i] = erase_value();
 
-	offset = region_offset(&nvram_region);
-	top_offset = offset + region_sz(&nvram_region) - BLOB_SIZE;
+	offset = 0;
+	top_offset = region_device_sz(&nvram_region) - BLOB_SIZE;
 
 	/*
 	 * after the loop, offset is supposed to point the blob right before
@@ -92,8 +92,8 @@ static int init_vbnv(void)
 	 * empty blob, or the base of the region if the nvram has never been
 	 * used.
 	 */
-	for (i = offset; i <= top_offset; i += BLOB_SIZE) {
-		if (vboot_get_region(i, BLOB_SIZE, buf) == NULL) {
+	for (i = 0; i <= top_offset; i += BLOB_SIZE) {
+		if (rdev_readat(&nvram_region, buf, i, BLOB_SIZE) < 0) {
 			printk(BIOS_ERR, "failed to read nvdata\n");
 			return 1;
 		}
@@ -103,7 +103,7 @@ static int init_vbnv(void)
 	}
 
 	/* reread the nvdata and write it to the cache */
-	if (vboot_get_region(offset, BLOB_SIZE, cache) == NULL) {
+	if (rdev_readat(&nvram_region, cache, offset, BLOB_SIZE) < 0) {
 		printk(BIOS_ERR, "failed to read nvdata\n");
 		return 1;
 	}
@@ -130,8 +130,8 @@ static int erase_nvram(void)
 	if (vbnv_flash_probe())
 		return 1;
 
-	if (spi_flash->erase(spi_flash, region_offset(&nvram_region),
-			     region_sz(&nvram_region))) {
+	if (spi_flash->erase(spi_flash, region_device_offset(&nvram_region),
+			     region_device_sz(&nvram_region))) {
 		printk(BIOS_ERR, "failed to erase nvram\n");
 		return 1;
 	}
@@ -171,14 +171,16 @@ void save_vbnv(const uint8_t *vbnv_copy)
 			if (new_offset > top_offset) {
 				if (erase_nvram())
 					return;  /* error */
-				new_offset = region_offset(&nvram_region);
+				new_offset = 0;
 			}
 			break;
 		}
 	}
 
 	if (!vbnv_flash_probe() &&
-	    !spi_flash->write(spi_flash, new_offset, BLOB_SIZE, vbnv_copy)) {
+	    !spi_flash->write(spi_flash,
+			      region_device_offset(&nvram_region) + new_offset,
+			      BLOB_SIZE, vbnv_copy)) {
 		/* write was successful. safely move pointer forward */
 		blob_offset = new_offset;
 		memcpy(cache, vbnv_copy, BLOB_SIZE);
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index edeaf19..264e191 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 a20f85e..f35ef61 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 1129cd1..226578b 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 59ead4d..443b7ca 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);
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
index 7fa328e..b761ea1 100644
--- a/src/vendorcode/google/chromeos/vboot_common.c
+++ b/src/vendorcode/google/chromeos/vboot_common.c
@@ -31,34 +31,14 @@
 #include "vboot_common.h"
 #include "vboot_handoff.h"
 
-void vboot_locate_region(const char *name, struct region *region)
+int vboot_named_region_device(const char *name, struct region_device *rdev)
 {
-	if (fmap_locate_area(name, region))
-		region->size = 0;
+	return fmap_locate_area_as_rdev(name, rdev);
 }
 
-void *vboot_get_region(size_t offset, size_t size, void *dest)
+int vboot_region_device(const struct region *reg, struct region_device *rdev)
 {
-	const struct region_device *boot_dev;
-	struct region_device rdev;
-
-	boot_device_init();
-	boot_dev = boot_device_ro();
-
-	if (boot_dev == NULL)
-		return NULL;
-
-	if (rdev_chain(&rdev, boot_dev, offset, size))
-		return NULL;
-
-	/* Each call will leak a mapping. */
-	if (dest == NULL)
-		return rdev_mmap_full(&rdev);
-
-	if (rdev_readat(&rdev, dest, 0, size) != size)
-		return NULL;
-
-	return dest;
+	return boot_device_ro_subregion(reg, rdev);
 }
 
 int vboot_get_handoff_info(void **addr, uint32_t *size)
@@ -75,23 +55,6 @@ int vboot_get_handoff_info(void **addr, uint32_t *size)
 	return 0;
 }
 
-/* This will leak a mapping of a fw region */
-struct vboot_components *vboot_locate_components(struct region *region)
-{
-	size_t req_size;
-	struct vboot_components *vbc;
-
-	req_size = sizeof(*vbc);
-	req_size += sizeof(struct vboot_component_entry) *
-			MAX_PARSED_FW_COMPONENTS;
-
-	vbc = vboot_get_region(region_offset(region), req_size, NULL);
-	if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
-		vbc = NULL;
-
-	return vbc;
-}
-
 void vboot_reboot(void)
 {
 	if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index 3430fbe..268f0d2 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -36,16 +36,8 @@ struct vboot_components {
 	struct vboot_component_entry entries[0];
 } __attribute__((packed));
 
-void vboot_locate_region(const char *name, struct region *region);
-
-struct vboot_components *vboot_locate_components(struct region *region);
-
-/*
- * This is a dual purpose routine. If dest is non-NULL the region at
- * offset_addr will be read into the area pointed to by dest.  If dest
- * is NULL,the region will be mapped to a memory location. NULL is
- * returned on error else the location of the requested region.
- */
-void *vboot_get_region(size_t offset, size_t size, void *dest);
+/* The following functions return 0 on success, < 0 on error. */
+int vboot_named_region_device(const char *name, struct region_device *rdev);
+int vboot_region_device(const struct region *reg, struct region_device *rdev);
 
 #endif /* VBOOT_COMMON_H */



More information about the coreboot-gerrit mailing list