Aaron Durbin (adurbin@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10059
-gerrit
commit 43473240e935f974daf6bca20f1cadf8f5c0e961 Author: Aaron Durbin adurbin@chromium.org Date: Fri May 1 16:48:54 2015 -0500
vboot checkopoint
Change-Id: I2a43c8a2f8f0626a7635150aa3efc44329a477d9 Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/arch/arm/Makefile.inc | 7 +- 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, 320 insertions(+), 201 deletions(-)
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc index c05b33e..0fd4fed 100644 --- a/src/arch/arm/Makefile.inc +++ b/src/arch/arm/Makefile.inc @@ -61,7 +61,7 @@ bootblock-y += memmove.S bootblock-y += div0.c bootblock-y += clock.c
-$(objcbfs)/bootblock.debug: $$(bootblock-objs) $$(VERSTAGE_LIB) +$(objcbfs)/bootblock.debug: $$(bootblock-objs) @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
@@ -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 ef4e2aa..b50e3aa 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; -}