[coreboot-gerrit] Patch set updated for coreboot: ba7d0c3 vboot checkopoint

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu May 7 12:31:34 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10059

-gerrit

commit ba7d0c38b62f263a0783bdf40ae57f56b8c84e48
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Fri May 1 16:48:54 2015 -0500

    vboot checkopoint
    
    Change-Id: I2a43c8a2f8f0626a7635150aa3efc44329a477d9
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/arch/arm/Makefile.inc                          |   9 +-
 src/arch/arm64/Makefile.inc                        |   5 +-
 src/include/program_loading.h                      |   1 +
 src/lib/Makefile.inc                               |   1 +
 src/lib/loaders/Makefile.inc                       |   1 +
 src/lib/loaders/load_and_run_payload.c             |   4 +-
 src/lib/loaders/load_and_run_ramstage.c            |   7 +-
 src/lib/loaders/load_and_run_romstage.c            |   7 +
 src/vendorcode/google/chromeos/chromeos.c          |  19 +-
 src/vendorcode/google/chromeos/vboot2/Kconfig      |   8 +-
 src/vendorcode/google/chromeos/vboot2/Makefile.inc |  22 +-
 src/vendorcode/google/chromeos/vboot2/common.c     |  33 ---
 src/vendorcode/google/chromeos/vboot2/misc.h       |   3 +-
 .../google/chromeos/vboot2/vboot_handoff.c         |  53 ++---
 .../google/chromeos/vboot2/vboot_loader.c          | 243 +++++++++++++++++++++
 src/vendorcode/google/chromeos/vboot2/verstub.c    | 107 ---------
 16 files changed, 321 insertions(+), 202 deletions(-)

diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
index c05b33e..6e52def 100644
--- a/src/arch/arm/Makefile.inc
+++ b/src/arch/arm/Makefile.inc
@@ -61,9 +61,9 @@ bootblock-y += memmove.S
 bootblock-y += div0.c
 bootblock-y += clock.c
 
-$(objcbfs)/bootblock.debug: $$(bootblock-objs) $$(VERSTAGE_LIB)
+$(objcbfs)/bootblock.debug: $$(bootblock-objs) $(objgenerated)/libverstage.a
 	@printf "    LINK       $(subst $(obj)/,,$(@))\n"
-	$(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group
+	$(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld --start-group $(filter-out %.ld,$(bootblock-objs)) $(objgenerated)/libverstage.a --end-group
 
 endif # CONFIG_ARCH_BOOTBLOCK_ARM
 
@@ -73,10 +73,11 @@ endif # CONFIG_ARCH_BOOTBLOCK_ARM
 
 ifeq ($(CONFIG_ARCH_VERSTAGE_ARM),y)
 
-$(objcbfs)/verstage.debug: $(objgenerated)/libverstage.a $$(verstage-objs) $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld
+$(objcbfs)/verstage.debug: $(objgenerated)/libverstage.a $$(verstage-objs)
 	@printf "    LINK       $(subst $(obj)/,,$(@))\n"
-	$(LD_verstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld --start-group $(objgenerated)/libverstage.a $$(verstage-objs) --end-group
+	$(LD_verstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld --start-group $(filter-out %.ld,$(verstage-objs)) $(objgenerated)/libverstage.a --end-group
 
+verstage-y += boot.c
 verstage-y += div0.c
 verstage-y += eabi_compat.c
 verstage-y += memset.S
diff --git a/src/arch/arm64/Makefile.inc b/src/arch/arm64/Makefile.inc
index 3791ae7..095457e 100644
--- a/src/arch/arm64/Makefile.inc
+++ b/src/arch/arm64/Makefile.inc
@@ -84,11 +84,12 @@ endif # CONFIG_ARCH_BOOTBLOCK_ARM64
 
 ifeq ($(CONFIG_ARCH_VERSTAGE_ARM64),y)
 
-$(objcbfs)/verstage.debug: $(objgenerated)/libverstage.a $$(verstage-objs) $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld $(obj)/config.h
+$(objcbfs)/verstage.debug: $(objgenerated)/libverstage.a $$(libverstage-objs) $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld $(obj)/config.h
 	@printf "    LINK       $(subst $(obj)/,,$(@))\n"
-	$(LD_verstage) --gc-sections -static -o $@ -L$(obj) --start-group $(objgenerated)/libverstage.a $$(verstage-objs)--end-group -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld
+	$(LD_verstage) --gc-sections -static -o $@ -L$(obj) --start-group $(objgenerated)/libverstage.a $$(libverstage-objs)--end-group -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld
 
 verstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
+verstage-y += boot.c
 verstage-y += div0.c
 verstage-y += eabi_compat.c
 verstage-y += ../../lib/memset.c
diff --git a/src/include/program_loading.h b/src/include/program_loading.h
index ca80b0e..5fc0fd6 100644
--- a/src/include/program_loading.h
+++ b/src/include/program_loading.h
@@ -39,6 +39,7 @@ struct buffer_area {
 };
 
 enum prog_type {
+	PROG_VERSTAGE,
 	PROG_ROMSTAGE,
 	PROG_RAMSTAGE,
 	PROG_PAYLOAD,
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 1d0851f..db83698 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -34,6 +34,7 @@ verstage-y += prog_ops.c
 verstage-y += delay.c
 verstage-y += cbfs.c
 verstage-y += cbfs_core.c
+verstage-y += halt.c
 verstage-y += memcmp.c
 verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
 verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
diff --git a/src/lib/loaders/Makefile.inc b/src/lib/loaders/Makefile.inc
index fbc7f87..6b22801 100644
--- a/src/lib/loaders/Makefile.inc
+++ b/src/lib/loaders/Makefile.inc
@@ -23,3 +23,4 @@ romstage-y += cbfs_ramstage_loader.c
 romstage-y += load_and_run_ramstage.c
 ramstage-y += cbfs_payload_loader.c
 ramstage-y += load_and_run_payload.c
+verstage-y += load_and_run_romstage.c
diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c
index 7a08097..4928e0c 100644
--- a/src/lib/loaders/load_and_run_payload.c
+++ b/src/lib/loaders/load_and_run_payload.c
@@ -27,12 +27,12 @@
 #include <symbols.h>
 #include <timestamp.h>
 
-extern const struct prog_loader_ops vboot_payload_loader;
+extern const struct prog_loader_ops vboot_loader;
 extern const struct prog_loader_ops cbfs_payload_loader;
 
 static const struct prog_loader_ops *payload_ops[] = {
 #if CONFIG_VBOOT_VERIFY_FIRMWARE
-	&vboot_payload_loader,
+	&vboot_loader,
 #endif
 	&cbfs_payload_loader,
 };
diff --git a/src/lib/loaders/load_and_run_ramstage.c b/src/lib/loaders/load_and_run_ramstage.c
index fddea4d..af8667a 100644
--- a/src/lib/loaders/load_and_run_ramstage.c
+++ b/src/lib/loaders/load_and_run_ramstage.c
@@ -23,17 +23,20 @@
 #include <cbfs.h>
 #include <program_loading.h>
 #include <romstage_handoff.h>
+#include <rules.h>
 #include <stage_cache.h>
 #include <timestamp.h>
 
 extern const struct prog_loader_ops cbfs_ramstage_loader;
-extern const struct prog_loader_ops vboot_ramstage_loader;
+extern const struct prog_loader_ops vboot_loader;
 
 static const struct prog_loader_ops *loaders[] = {
 #if CONFIG_VBOOT_VERIFY_FIRMWARE
-	&vboot_ramstage_loader,
+	&vboot_loader,
 #endif
+#if !ENV_VERSTAGE
 	&cbfs_ramstage_loader,
+#endif
 };
 
 void __attribute__((weak)) stage_cache_add(int stage_id, struct prog *stage) {}
diff --git a/src/lib/loaders/load_and_run_romstage.c b/src/lib/loaders/load_and_run_romstage.c
index b54bfc7..25a75bd 100644
--- a/src/lib/loaders/load_and_run_romstage.c
+++ b/src/lib/loaders/load_and_run_romstage.c
@@ -24,12 +24,19 @@
 #include <cbfs.h>
 #include <halt.h>
 #include <program_loading.h>
+#include <rules.h>
 #include <timestamp.h>
 
 extern const struct prog_loader_ops cbfs_romstage_loader;
+extern const struct prog_loader_ops vboot_loader;
 
 static const struct prog_loader_ops *loaders[] = {
+#if CONFIG_VBOOT_VERIFY_FIRMWARE
+	&vboot_loader,
+#endif
+#if !ENV_VERSTAGE
 	&cbfs_romstage_loader,
+#endif
 };
 
 void run_romstage(void)
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index fb72673..1e49bd1 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -26,7 +26,7 @@
 #include <console/console.h>
 #include "vboot_handoff.h"
 
-int vboot_skip_display_init(void)
+static int vboot_handoff_flag(uint32_t flag)
 {
 	struct vboot_handoff *vbho;
 
@@ -35,7 +35,22 @@ int vboot_skip_display_init(void)
 	if (vbho == NULL)
 		return 0;
 
-	return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
+	return !!(vbho->init_params.out_flags & flag);
+}
+
+int vboot_skip_display_init(void)
+{
+	return !vboot_handoff_flag(VB_INIT_OUT_ENABLE_DISPLAY);
+}
+
+int vboot_enable_developer(void)
+{
+	return vboot_handoff_flag(VB_INIT_OUT_ENABLE_DEVELOPER);
+}
+
+int vboot_enable_recovery(void)
+{
+	return vboot_handoff_flag(VB_INIT_OUT_ENABLE_RECOVERY);
 }
 
 int __attribute__((weak)) clear_recovery_mode_switch(void)
diff --git a/src/vendorcode/google/chromeos/vboot2/Kconfig b/src/vendorcode/google/chromeos/vboot2/Kconfig
index 8396113..bb6c1ad 100644
--- a/src/vendorcode/google/chromeos/vboot2/Kconfig
+++ b/src/vendorcode/google/chromeos/vboot2/Kconfig
@@ -17,14 +17,14 @@
 ##
 
 config VBOOT_STARTS_IN_BOOTBLOCK
-	bool
+	bool "Vboot starts verifying in bootblock"
 	default n
 	depends on VBOOT_VERIFY_FIRMWARE
 	help
 	  Firmware verification happens during or at the end of bootblock.
 
 config VBOOT_STARTS_IN_ROMSTAGE
-	bool
+	bool "Vboot starts verifying in romstage"
 	default n
 	depends on VBOOT_VERIFY_FIRMWARE && !VBOOT_STARTS_IN_BOOTBLOCK
 	help
@@ -51,12 +51,12 @@ config VBOOT_DISABLE_DEV_ON_RECOVERY
 	  handy on embedded devices with limited input capabilities.
 
 config SEPARATE_VERSTAGE
-	bool
+	bool "Vboot verification is built into a separate stage"
 	default n
 	depends on VBOOT_VERIFY_FIRMWARE
 
 config RETURN_FROM_VERSTAGE
-	bool
+	bool "The separate verification stage returns to its caller"
 	default n
 	depends on SEPARATE_VERSTAGE
 	help
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
index a27e2fc..6ec352f 100644
--- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -20,13 +20,16 @@
 libverstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
 verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
 
+bootblock-y += vboot_loader.c
+romstage-y += vboot_loader.c
+ramstage-y += vboot_loader.c
+verstage-y += vboot_loader.c
+
 bootblock-y += ../vboot_common.c
 verstage-y += ../vboot_common.c
 romstage-y += ../vboot_common.c
 ramstage-y += ../vboot_common.c
 
-bootblock-y += verstub.c
-libverstage-y += verstub.c
 bootblock-y += common.c
 libverstage-y += verstage.c
 verstage-y += common.c
@@ -37,9 +40,20 @@ libverstage-y += antirollback.c
 endif
 romstage-y += vboot_handoff.c common.c
 
+ramstage-y += common.c
+
 verstage-y += verstage.ld
 
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
+ifeq ($(CONFIG_SEPARATE_VERSTAGE),y)
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-verstage-y))
+else
+ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y)
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-bootblock-y))
+else
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y))
+endif
+endif # CONFIG_SEPARATE_VERSTAGE
+
 VB2_LIB = $(obj)/external/vboot_reference/vboot_fw20.a
 VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CPPFLAGS_verstage)))
 VBOOT_CFLAGS += $(libverstage-c-ccopts)
@@ -64,7 +78,7 @@ $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage-file = $(objcbfs)/verstage.e
 $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage-type = stage
 $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage-compression = none
 else
-ifeq ($(VBOOT_STARTS_IN_BOOTBLOCK),y)
+ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y)
 bootblock-srcs += $(objgenerated)/libverstage.a
 else
 romstage-srcs += $(objgenerated)/libverstage.a
diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c
index d70a108..beffebe 100644
--- a/src/vendorcode/google/chromeos/vboot2/common.c
+++ b/src/vendorcode/google/chromeos/vboot2/common.c
@@ -25,39 +25,6 @@
 #include "../vboot_handoff.h"
 #include "misc.h"
 
-void *vboot_load_stage(int stage_index,
-		       struct vboot_region *fw_main,
-		       struct vboot_components *fw_info)
-{
-	struct cbfs_media default_media, *media = &default_media;
-	uintptr_t fc_addr;
-	uint32_t fc_size;
-	void *entry;
-
-	if (stage_index >= fw_info->num_components) {
-		printk(BIOS_INFO, "invalid stage index\n");
-		return NULL;
-	}
-
-	fc_addr = fw_main->offset_addr + fw_info->entries[stage_index].offset;
-	fc_size = fw_info->entries[stage_index].size;
-	if (fc_size == 0 ||
-	    fc_addr + fc_size > fw_main->offset_addr + fw_main->size) {
-		printk(BIOS_INFO, "invalid stage address or size\n");
-		return NULL;
-	}
-
-	init_default_cbfs_media(media);
-
-	/* we're making cbfs access offset outside of the region managed by
-	 * cbfs. this works because cbfs_load_stage_by_offset does not check
-	 * the offset. */
-	entry = cbfs_load_stage_by_offset(media, fc_addr);
-	if (entry == (void *)-1)
-		entry = NULL;
-	return entry;
-}
-
 struct vb2_working_data * const vboot_get_working_data(void)
 {
 	return (struct vb2_working_data *)_vboot2_work;
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index 7425082..d942d56 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -22,8 +22,7 @@
 
 #include "../vboot_common.h"
 
-void *vboot2_verify_firmware(void);
-void *vboot2_load_ramstage(void);
+void vboot_fill_handoff(void);
 void verstage_main(void);
 void *vboot_load_stage(int stage_index,
 		       struct vboot_region *fw_main,
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
index b84e47e..16261b4 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -36,30 +36,6 @@
 #include "../vboot_handoff.h"
 #include "misc.h"
 
-static void *load_ramstage(struct vboot_handoff *vboot_handoff,
-			   struct vboot_region *fw_main)
-{
-	struct vboot_components *fw_info;
-	void *ret;
-	int i;
-
-	fw_info = vboot_locate_components(fw_main);
-	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++) {
-		vboot_handoff->components[i].address =
-			fw_main->offset_addr + fw_info->entries[i].offset;
-		vboot_handoff->components[i].size = fw_info->entries[i].size;
-	}
-
-	timestamp_add_now(TS_START_COPYRAM);
-	ret = vboot_load_stage(CONFIG_VBOOT_RAMSTAGE_INDEX, fw_main, fw_info);
-	timestamp_add_now(TS_END_COPYRAM);
-	return ret;
-}
-
 /**
  * Sets vboot_handoff based on the information in vb2_shared_data
  *
@@ -146,14 +122,13 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
 	vb_sd->recovery_reason = vb2_sd->recovery_reason;
 }
 
-/**
- * Load ramstage and return the entry point
- */
-void *vboot2_load_ramstage(void)
+void vboot_fill_handoff(void)
 {
+	int i;
 	struct vboot_handoff *vh;
 	struct vb2_shared_data *sd;
 	struct vboot_region fw_main;
+	struct vboot_components *fw_info;
 	struct vb2_working_data *wd = vboot_get_working_data();
 
 	sd = vboot_get_work_buffer(wd);
@@ -172,17 +147,15 @@ void *vboot2_load_ramstage(void)
 	/* needed until we finish transtion to vboot2 for kernel verification */
 	fill_vboot_handoff(vh, sd);
 
-	if (vboot_is_readonly_path(wd))
-		/* we're on recovery path. continue to ro-ramstage. */
-		return NULL;
-
-	if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)) {
-		return cbfs_load_stage(CBFS_DEFAULT_MEDIA,
-				       CONFIG_CBFS_PREFIX "/ramstage");
-	} else {
-		printk(BIOS_INFO, "loading ramstage from Slot %c\n",
-		       sd->fw_slot ? 'B' : 'A');
-		vb2_get_selected_region(wd, &fw_main);
-		return load_ramstage(vh, &fw_main);
+	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");
+
+	/* these offset & size are used to load a rw boot loader */
+	for (i = 0; i < fw_info->num_components; i++) {
+		vh->components[i].address =
+			fw_main.offset_addr + fw_info->entries[i].offset;
+		vh->components[i].size = fw_info->entries[i].size;
 	}
 }
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
new file mode 100644
index 0000000..c731abb
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
@@ -0,0 +1,243 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <cbfs.h>
+#include <console/console.h>
+#include <program_loading.h>
+#include <rules.h>
+#include <string.h>
+#include "misc.h"
+#include "../symbols.h"
+
+/* The stage loading code is compiled and entered from mutilple stages. The
+ * helper functions below attempt to provde more clarity on when certain
+ * code should be called. */
+
+static int verification_should_run(void)
+{
+	if (ENV_VERSTAGE && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
+		return 1;
+
+	if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) {
+		if (ENV_ROMSTAGE &&
+		    IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
+			return 1;
+		if (ENV_BOOTBLOCK &&
+		    IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+			return 1;
+	}
+
+	return 0;
+}
+
+static int verstage_should_load(void)
+{
+	if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
+		return 0;
+
+	if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
+		return 1;
+
+	if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+		return 1;
+
+	return 0;
+}
+
+static void init_vb2_working_data(void)
+{
+	struct vb2_working_data *wd;
+
+	wd = vboot_get_working_data();
+	memset(wd, 0, _vboot2_work_size);
+	/*
+	 * vboot prefers 16-byte alignment. This takes away 16 bytes
+	 * from the VBOOT2_WORK region, but the vboot devs said that's okay.
+	 */
+	wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
+	wd->buffer_size = _vboot2_work_size - wd->buffer_offset;
+}
+
+static int vboot_loader_active(struct prog *prog)
+{
+	struct vb2_working_data *wd;
+	int run_verification;
+
+	run_verification = verification_should_run();
+
+	if (run_verification) {
+		init_vb2_working_data();
+		verstage_main();
+	} else if (verstage_should_load()) {
+		struct prog verstage = {
+			.type = PROG_VERSTAGE,
+			.name = CONFIG_CBFS_PREFIX "/verstage",
+		};
+
+		/* load verstage from RO */
+		if (cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, &verstage))
+			die("failed to load verstage");
+
+		/* verify and select a slot */
+		prog_run(&verstage);
+
+		/* This is not actually possible to hit this condition at
+		 * runtime, but this provides a hint to the compiler for dead
+		 * code elimination below. */
+		if (!IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
+			return 0;
+	}
+
+	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 vboot_region fw_main;
+
+			vb2_get_selected_region(wd, &fw_main);
+			cbfs_set_header_offset(fw_main.offset_addr);
+		}
+		return 1;
+	}
+
+	return 0;
+}
+
+static uintptr_t vboot_fw_region(int fw_index, struct vboot_region *fw_main,
+				struct vboot_components *fw_info, size_t *size)
+{
+	uintptr_t fc_addr;
+	uint32_t fc_size;
+
+	if (fw_index >= fw_info->num_components) {
+		printk(BIOS_INFO, "invalid stage index: %d\n", fw_index);
+		return 0;
+	}
+
+	fc_addr = fw_main->offset_addr + fw_info->entries[fw_index].offset;
+	fc_size = fw_info->entries[fw_index].size;
+	if (fc_size == 0 ||
+	    fc_addr + fc_size > fw_main->offset_addr + fw_main->size) {
+		printk(BIOS_INFO, "invalid stage address or size\n");
+		return 0;
+	}
+
+	*size = fc_addr;
+	return fc_addr;
+}
+
+/* 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)
+{
+	struct vb2_working_data *wd;
+	struct vboot_region fw_main;
+	struct vboot_components *fw_info;
+
+	/* Code size optimization. We'd never actually get called under the
+	 * followin cirumstances because verstage was loaded and ran -- never
+	 * returning. */
+	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();
+	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");
+
+	/* Load payload in ramstage. */
+	if (ENV_RAMSTAGE) {
+		uintptr_t payload;
+		void *payload_ptr;
+		size_t size;
+
+		payload = vboot_fw_region(CONFIG_VBOOT_BOOT_LOADER_INDEX,
+						&fw_main, fw_info, &size);
+
+		if (payload == 0)
+			die("Couldn't load payload.");
+
+		payload_ptr = vboot_get_region(payload, size, NULL);
+
+		if (payload_ptr == NULL)
+			die("Couldn't load payload.");
+
+		prog_set_area(prog, payload_ptr, size);
+	} else {
+		uintptr_t stage;
+		size_t size;
+		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.");
+
+		stage = vboot_fw_region(stage_index, &fw_main, fw_info, &size);
+
+		if (stage == 0)
+			die("Vboot stage load failed.");
+
+		if (cbfs_load_prog_stage_by_offset(CBFS_DEFAULT_MEDIA,
+							prog, stage) < 0)
+			die("Vboot couldn't load stage");
+	}
+
+	/* Fill in vboot handoff structure before moving to ramstage. */
+	if (ENV_ROMSTAGE)
+		vboot_fill_handoff();
+
+	return 0;
+}
+
+const struct prog_loader_ops vboot_loader = {
+	.name = "VBOOT",
+	.is_loader_active = vboot_loader_active,
+	.prepare = vboot_prepare,
+};
diff --git a/src/vendorcode/google/chromeos/vboot2/verstub.c b/src/vendorcode/google/chromeos/vboot2/verstub.c
deleted file mode 100644
index c4319ba..0000000
--- a/src/vendorcode/google/chromeos/vboot2/verstub.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/stages.h>
-#include <cbfs.h>
-#include <console/console.h>
-#include <string.h>
-#include <timestamp.h>
-#include "../chromeos.h"
-#include "../symbols.h"
-#include "misc.h"
-
-static struct vb2_working_data *init_vb2_working_data(void)
-{
-	struct vb2_working_data *wd;
-
-	wd = vboot_get_working_data();
-	memset(wd, 0, _vboot2_work_size);
-	/*
-	 * vboot prefers 16-byte alignment. This takes away 16 bytes
-	 * from the VBOOT2_WORK region, but the vboot devs said that's okay.
-	 */
-	wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
-	wd->buffer_size = _vboot2_work_size - wd->buffer_offset;
-
-	return wd;
-}
-
-/**
- * Verify a slot and jump to the next stage
- *
- * This could be either part of the (1) bootblock or the (2) verstage, depending
- * on CONFIG_RETURN_FROM_VERSTAGE.
- *
- * 1) It jumps to the verstage and comes back, then, loads the romstage over the
- * verstage space and exits to it. (note the cbfs cache is trashed on return
- * from the verstage.)
- *
- * 2) We're already in the verstage. Verify firmware, then load the romstage and
- * exits to it.
- */
-void *vboot2_verify_firmware(void)
-{
-	void *entry;
-	struct vb2_working_data *wd;
-
-	wd = init_vb2_working_data();
-
-	if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
-		/* load verstage from RO */
-		entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
-					CONFIG_CBFS_PREFIX "/verstage");
-		if (entry == (void *)-1)
-			die("failed to load verstage");
-
-		/* verify and select a slot */
-		stage_exit(entry);
-	} else {
-		verstage_main();
-	}
-
-	/* jump to the selected slot */
-	timestamp_add_now(TS_START_COPYROM);
-	entry = (void *)-1;
-	if (vboot_is_slot_selected(wd)) {
-		/* RW A or B */
-		struct vboot_region fw_main;
-
-		vb2_get_selected_region(wd, &fw_main);
-
-		if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)) {
-			cbfs_set_header_offset(fw_main.offset_addr);
-			entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
-						CONFIG_CBFS_PREFIX "/romstage");
-		} else {
-			struct vboot_components *fw_info;
-			fw_info = vboot_locate_components(&fw_main);
-			if (fw_info == NULL)
-				die("failed to locate firmware components\n");
-			entry = vboot_load_stage(CONFIG_VBOOT_ROMSTAGE_INDEX,
-						 &fw_main, fw_info);
-		}
-	} else if (vboot_is_readonly_path(wd)) {
-		/* RO */
-		entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
-					CONFIG_CBFS_PREFIX "/romstage");
-	}
-	timestamp_add_now(TS_END_COPYROM);
-
-	return entry;
-}



More information about the coreboot-gerrit mailing list