[coreboot-gerrit] New patch to review for coreboot: vboot: prepare for x86 verstage

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Thu Oct 8 17:12:46 CET 2015


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

-gerrit

commit 35cbed3726c45935f2d9753b3f96870613d351c9
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Oct 7 16:03:41 2015 -0500

    vboot: prepare for x86 verstage
    
    In order to support x86 verstage proper the work buffer
    needs to live in cache-as-ram. However, after cache-as-ram
    is torn down one still needs the verification results to
    know which slot was selected. Though the platforms with
    a dedicated SRAM can just use the work buffer in SRAM, the
    x86 cache-as-ram platforms need a place to stash the
    results. For that situation cbmem is employed. This works
    because when cbmem is initialized cache-as-ram is still
    enabled. The VBOOT_DYNAMIC_WORK_BUFFER case assumes
    verified boot doesn't start until after cbmem is up. That
    doesn't change, but it's a goal to get rid of that option
    entirely once all other x86 platforms are moved over to
    pre-romstage vboot.
    
    BUG=chrome-os-partner:44827
    BRANCH=None
    TEST=Built and booted glados with pre-romstage verification
         as well as VBOOT_DYNAMIC_WORK_BUFFER case.
    
    Change-Id: I7eacd0edb2b6ca52b59b74075d17c00b50676d4c
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/commonlib/include/commonlib/cbmem_id.h         |  2 +
 src/vendorcode/google/chromeos/vboot2/common.c     | 81 ++++++++++++++++++----
 src/vendorcode/google/chromeos/vboot2/misc.h       |  3 +
 .../google/chromeos/vboot2/vboot_handoff.c         | 14 ++++
 .../google/chromeos/vboot2/vboot_loader.c          | 14 +++-
 5 files changed, 99 insertions(+), 15 deletions(-)

diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h
index 6812c41..4a5b660 100644
--- a/src/commonlib/include/commonlib/cbmem_id.h
+++ b/src/commonlib/include/commonlib/cbmem_id.h
@@ -65,6 +65,7 @@
 #define CBMEM_ID_TCPA_LOG	0x54435041
 #define CBMEM_ID_TIMESTAMP	0x54494d45
 #define CBMEM_ID_VBOOT_HANDOFF	0x780074f0
+#define CBMEM_ID_VBOOT_SEL_REG	0x780074f1
 #define CBMEM_ID_VBOOT_WORKBUF	0x78007343
 #define CBMEM_ID_WIFI_CALIBRATION 0x57494649
 
@@ -108,6 +109,7 @@
 	{ CBMEM_ID_TCPA_LOG,		"TCPA LOG   " }, \
 	{ CBMEM_ID_TIMESTAMP,		"TIME STAMP " }, \
 	{ CBMEM_ID_VBOOT_HANDOFF,	"VBOOT      " }, \
+	{ CBMEM_ID_VBOOT_SEL_REG,	"VBOOT SEL  " }, \
 	{ CBMEM_ID_VBOOT_WORKBUF,	"VBOOT WORK " }, \
 	{ CBMEM_ID_WIFI_CALIBRATION,	"WIFI CLBR  " },
 #endif /* _CBMEM_ID_H_ */
diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c
index a33fb8e..663ffd8 100644
--- a/src/vendorcode/google/chromeos/vboot2/common.c
+++ b/src/vendorcode/google/chromeos/vboot2/common.c
@@ -28,6 +28,11 @@
 #include "../vboot_handoff.h"
 #include "misc.h"
 
+struct selected_region {
+	uint32_t offset;
+	uint32_t size;
+};
+
 /*
  * this is placed at the start of the vboot work buffer. selected_region is used
  * for the verstage to return the location of the selected slot. buffer is used
@@ -35,8 +40,7 @@
  * stage boundaries.
  */
 struct vb2_working_data {
-	uint32_t selected_region_offset;
-	uint32_t selected_region_size;
+	struct selected_region selected_region;
 	/* offset of the buffer from the start of this struct */
 	uint32_t buffer_offset;
 	uint32_t buffer_size;
@@ -61,6 +65,30 @@ static size_t vb2_working_data_size(void)
 		return _vboot2_work_size;
 }
 
+static struct selected_region *vb2_selected_region(void)
+{
+	struct selected_region *sel_reg = NULL;
+
+	/* Ramstage always uses cbmem as a source of truth. */
+	if (ENV_RAMSTAGE)
+		sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
+	else if (ENV_ROMSTAGE) {
+		/* Try cbmem first. Fall back on working data if not found. */
+		sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
+
+		if (sel_reg == NULL) {
+			struct vb2_working_data *wd = vboot_get_working_data();
+			sel_reg = &wd->selected_region;
+		}
+	} else {
+		/* Stages such as bootblock and verstage use working data. */
+		struct vb2_working_data *wd = vboot_get_working_data();
+		sel_reg = &wd->selected_region;
+	}
+
+	return sel_reg;
+}
+
 void vb2_init_work_context(struct vb2_context *ctx)
 {
 	struct vb2_working_data *wd;
@@ -93,28 +121,57 @@ struct vb2_shared_data *vb2_get_shared_data(void)
 
 int vb2_get_selected_region(struct region_device *rdev)
 {
-	const struct vb2_working_data *wd = vboot_get_working_data();
-	struct region reg = {
-		.offset = wd->selected_region_offset,
-		.size = wd->selected_region_size,
+	const struct selected_region *reg = vb2_selected_region();
+	struct region region = {
+		.offset = reg->offset,
+		.size = reg->size,
 	};
-	return vboot_region_device(&reg, rdev);
+	return vboot_region_device(&region, rdev);
 }
 
 void vb2_set_selected_region(struct region_device *rdev)
 {
-	struct vb2_working_data *wd = vboot_get_working_data();
-	wd->selected_region_offset = region_device_offset(rdev);
-	wd->selected_region_size = region_device_sz(rdev);
+	struct selected_region *reg = vb2_selected_region();
+	reg->offset = region_device_offset(rdev);
+	reg->size = region_device_sz(rdev);
 }
 
 int vboot_is_slot_selected(void)
 {
-	const struct vb2_working_data *wd = vboot_get_working_data();
-	return wd->selected_region_size > 0;
+	const struct selected_region *reg = vb2_selected_region();
+	return reg->size > 0;
 }
 
 int vboot_is_readonly_path(void)
 {
 	return !vboot_is_slot_selected();
 }
+
+void vb2_store_selected_region(void)
+{
+	const struct vb2_working_data *wd;
+	struct selected_region *sel_reg;
+
+	/* Always use the working data in this path since it's the object
+	 * which has the result.. */
+	wd = vboot_get_working_data();
+
+	sel_reg = cbmem_add(CBMEM_ID_VBOOT_SEL_REG, sizeof(*sel_reg));
+
+	sel_reg->offset = wd->selected_region.offset;
+	sel_reg->size = wd->selected_region.size;
+}
+
+/*
+ * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
+ * verification doesn't happen until after cbmem is brought online.
+ * Therefore, the selected region contents would not be initialized
+ * so don't automatically add results when cbmem comes online.
+ */
+#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
+static void vb2_store_selected_region_cbmem(int unused)
+{
+	vb2_store_selected_region();
+}
+ROMSTAGE_CBMEM_INIT_HOOK(vb2_store_selected_region_cbmem)
+#endif
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index fbbc46e..2c26461 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -39,4 +39,7 @@ void vb2_set_selected_region(struct region_device *rdev);
 int vboot_is_slot_selected(void);
 int vboot_is_readonly_path(void);
 
+/* Store the selected region in cbmem for later use. */
+void vb2_store_selected_region(void);
+
 #endif /* __CHROMEOS_VBOOT2_MISC_H__ */
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
index bf7d654..769e267 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -171,3 +171,17 @@ void vboot_fill_handoff(void)
 
 	rdev_munmap(&fw_main, fw_info);
 }
+
+/*
+ * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
+ * verification doesn't happen until after cbmem is brought online.
+ * Therefore, the vboot results would not be initialized so don't
+ * automatically add results when cbmem comes online.
+ */
+#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
+static void vb2_fill_handoff_cbmem(int unused)
+{
+	vboot_fill_handoff();
+}
+ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem)
+#endif
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
index bb7bc4c..d2e7758 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
@@ -98,10 +98,18 @@ static int vboot_active(struct asset *asset)
 			return 0;
 	}
 
-	/* Fill in vboot handoff structure before moving to ramstage so all
-	 * downstream users have access to vboot results. */
-	if (ENV_ROMSTAGE)
+	/*
+	 * Fill in vboot cbmem objects before moving to ramstage so all
+	 * downstream users have access to vboot results. This path only
+	 * applies to platforms employing VBOOT_DYNAMIC_WORK_BUFFER because
+	 * cbmem comes online prior to vboot verification taking place. For
+	 * other platforms the vboot cbmem objects are initialized when
+	 * cbmem comes online.
+	 */
+	if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)) {
+		vb2_store_selected_region();
 		vboot_fill_handoff();
+	}
 
 	return vboot_is_slot_selected();
 }



More information about the coreboot-gerrit mailing list