[coreboot-gerrit] Patch set updated for coreboot: 9644c74 vboot: move vboot files to designated directory
Aaron Durbin (adurbin@chromium.org)
gerrit at coreboot.org
Thu Apr 9 19:52:45 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/9433
-gerrit
commit 9644c74ecb6039737778fb43dfd19cc05f1da241
Author: Daisuke Nojiri <dnojiri at chromium.org>
Date: Fri Oct 10 10:51:06 2014 -0700
vboot: move vboot files to designated directory
This moves vboot1 and vboot2 files to their designated directory. Common
code stays in vendorcode/google/chromeos.
BUG=none
BRANCH=none
TEST=built cosmos, veyron_pinky, rush_ryu, nyan_blaze, samus, parrot,
lumpy, daisy_spring, and storm.
Signed-off-by: Daisuke Nojiri <dnojiri at chromium.org>
Original-Change-Id: Ia9fb41ba30930b79b222269acfade7ef44b23626
Original-Reviewed-on: https://chromium-review.googlesource.com/222874
Original-Reviewed-by: Daisuke Nojiri <dnojiri at chromium.org>
Original-Commit-Queue: Daisuke Nojiri <dnojiri at chromium.org>
Original-Tested-by: Daisuke Nojiri <dnojiri at chromium.org>
(cherry picked from commit cbfef9ad40776d890e2149b9db788fe0b387d210)
Signed-off-by: Aaron Durbin <adurbin at chromium.org>
Change-Id: Ia73696accfd93cc14ca83516fa77f87331faef51
---
src/mainboard/google/nyan_blaze/romstage.c | 2 +-
src/mainboard/google/veyron_pinky/romstage.c | 2 +-
src/soc/nvidia/tegra124/include/soc/memlayout.ld | 2 +-
.../tegra132/include/soc/memlayout_vboot2.ld | 2 +-
src/soc/rockchip/rk3288/include/soc/memlayout.ld | 2 +-
src/vendorcode/google/chromeos/Kconfig | 47 +--
src/vendorcode/google/chromeos/Makefile.inc | 97 +----
src/vendorcode/google/chromeos/antirollback.c | 329 ----------------
src/vendorcode/google/chromeos/chromeos.c | 183 +--------
src/vendorcode/google/chromeos/chromeos.h | 99 +----
src/vendorcode/google/chromeos/memlayout.h | 47 ---
src/vendorcode/google/chromeos/symbols.h | 32 --
src/vendorcode/google/chromeos/vboot1/Kconfig | 34 ++
src/vendorcode/google/chromeos/vboot1/Makefile.inc | 74 ++++
.../google/chromeos/vboot1/vboot_loader.c | 416 +++++++++++++++++++++
.../google/chromeos/vboot1/vboot_wrapper.c | 266 +++++++++++++
src/vendorcode/google/chromeos/vboot2/Kconfig | 43 +++
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 60 +++
.../google/chromeos/vboot2/antirollback.c | 329 ++++++++++++++++
src/vendorcode/google/chromeos/vboot2/common.c | 70 ++++
src/vendorcode/google/chromeos/vboot2/memlayout.h | 47 +++
src/vendorcode/google/chromeos/vboot2/misc.h | 72 ++++
src/vendorcode/google/chromeos/vboot2/symbols.h | 32 ++
.../google/chromeos/vboot2/vboot_handoff.c | 175 +++++++++
src/vendorcode/google/chromeos/vboot2/verstage.c | 252 +++++++++++++
src/vendorcode/google/chromeos/vboot2/verstage.ld | 58 +++
src/vendorcode/google/chromeos/vboot2/verstub.c | 97 +++++
src/vendorcode/google/chromeos/vboot_common.c | 122 ++++++
src/vendorcode/google/chromeos/vboot_common.h | 55 +++
src/vendorcode/google/chromeos/vboot_handoff.c | 174 ---------
src/vendorcode/google/chromeos/vboot_handoff.h | 11 +
src/vendorcode/google/chromeos/vboot_loader.c | 416 ---------------------
src/vendorcode/google/chromeos/vboot_wrapper.c | 266 -------------
src/vendorcode/google/chromeos/verstage.c | 251 -------------
src/vendorcode/google/chromeos/verstage.ld | 58 ---
src/vendorcode/google/chromeos/verstub.c | 96 -----
36 files changed, 2241 insertions(+), 2077 deletions(-)
diff --git a/src/mainboard/google/nyan_blaze/romstage.c b/src/mainboard/google/nyan_blaze/romstage.c
index 034a929..c9510d6 100644
--- a/src/mainboard/google/nyan_blaze/romstage.c
+++ b/src/mainboard/google/nyan_blaze/romstage.c
@@ -96,7 +96,7 @@ static void __attribute__((noinline)) romstage(void)
early_mainboard_init();
#if CONFIG_VBOOT2_VERIFY_FIRMWARE
- entry = vboot_load_ramstage();
+ entry = vboot2_load_ramstage();
#else
early_mainboard_init();
vboot_verify_firmware(romstage_handoff_find_or_add());
diff --git a/src/mainboard/google/veyron_pinky/romstage.c b/src/mainboard/google/veyron_pinky/romstage.c
index 38166ed..b050228 100644
--- a/src/mainboard/google/veyron_pinky/romstage.c
+++ b/src/mainboard/google/veyron_pinky/romstage.c
@@ -117,7 +117,7 @@ void main(void)
#endif
#if IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)
- void *entry = vboot_load_ramstage();
+ void *entry = vboot2_load_ramstage();
if (entry != NULL)
stage_exit(entry);
#endif
diff --git a/src/soc/nvidia/tegra124/include/soc/memlayout.ld b/src/soc/nvidia/tegra124/include/soc/memlayout.ld
index 0d9e772..c8db5c5 100644
--- a/src/soc/nvidia/tegra124/include/soc/memlayout.ld
+++ b/src/soc/nvidia/tegra124/include/soc/memlayout.ld
@@ -18,7 +18,7 @@
*/
#include <memlayout.h>
-#include <vendorcode/google/chromeos/memlayout.h>
+#include <vendorcode/google/chromeos/vboot2/memlayout.h>
#include <arch/header.ld>
diff --git a/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld b/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld
index 8743268..1709392 100644
--- a/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld
+++ b/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld
@@ -18,7 +18,7 @@
*/
#include <memlayout.h>
-#include <vendorcode/google/chromeos/memlayout.h>
+#include <vendorcode/google/chromeos/vboot2/memlayout.h>
#include <arch/header.ld>
diff --git a/src/soc/rockchip/rk3288/include/soc/memlayout.ld b/src/soc/rockchip/rk3288/include/soc/memlayout.ld
index 2ddb6a6..922e2f8 100644
--- a/src/soc/rockchip/rk3288/include/soc/memlayout.ld
+++ b/src/soc/rockchip/rk3288/include/soc/memlayout.ld
@@ -18,7 +18,7 @@
*/
#include <memlayout.h>
-#include <vendorcode/google/chromeos/memlayout.h>
+#include <vendorcode/google/chromeos/vboot2/memlayout.h>
#include <arch/header.ld>
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 8826a14..62a415b 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -94,22 +94,6 @@ config FLASHMAP_OFFSET
help
Offset of flash map in firmware image
-config VBOOT_VERIFY_FIRMWARE
- bool "Verify firmware with vboot."
- default n
- select RELOCATABLE_MODULES
- help
- Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
- and boot loader.
-
-config VBOOT2_VERIFY_FIRMWARE
- bool "Firmware Verification with vboot2"
- default n
- depends on CHROMEOS && HAVE_HARD_RESET
- help
- Enabling VBOOT2_VERIFY_FIRMWARE will use vboot2 to verify the romstage
- and boot loader.
-
config EC_SOFTWARE_SYNC
bool "Enable EC software sync"
default n
@@ -141,16 +125,6 @@ config VIRTUAL_DEV_SWITCH
help
Whether this platform has a virtual developer switch.
-config RETURN_FROM_VERSTAGE
- bool "return from verstage"
- default n
- depends on VBOOT2_VERIFY_FIRMWARE
- help
- If this is set, the verstage returns back to the bootblock instead of
- exits to the romstage so that the verstage space can be reused by the
- romstage. Useful if a ram space is too small to fit both the verstage
- and the romstage.
-
# These VBOOT_X_INDEX are the position of X in FW_MAIN_A/B region. The index
# table is created by cros_bundle_firmware at build time based on the positions
# of the blobs listed in fmap.dts and stored at the top of FW_MAIN_A/B region.
@@ -164,14 +138,6 @@ config VBOOT_BOOT_LOADER_INDEX
This is the index of the bootloader component in the verified
firmware block.
-config VBOOT_ROMSTAGE_INDEX
- hex
- default 2
- depends on VBOOT2_VERIFY_FIRMWARE
- help
- This is the index of the romstage component in the verified
- firmware block.
-
config VBOOT_RAMSTAGE_INDEX
hex "Ramstage component index"
default 1
@@ -180,14 +146,6 @@ config VBOOT_RAMSTAGE_INDEX
This is the index of the ramstage component in the verified
firmware block.
-config VBOOT_REFCODE_INDEX
- hex "Reference code firmware index"
- default 1
- depends on VBOOT_VERIFY_FIRMWARE
- help
- This is the index of the reference code component in the verified
- firmware block.
-
config NO_TPM_RESUME
bool
default n
@@ -196,5 +154,8 @@ config NO_TPM_RESUME
boards, booting Windows will break if the TPM resume command
is sent during an S3 resume.
-endif
+source src/vendorcode/google/chromeos/vboot1/Kconfig
+source src/vendorcode/google/chromeos/vboot2/Kconfig
+
+endif # CHROMEOS
endmenu
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index f43a87e..cc50d2f 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -37,101 +37,8 @@ else
CFLAGS_common += -DMOCK_TPM=0
endif
-ifeq ($(CONFIG_VBOOT_VERIFY_FIRMWARE),y)
-romstage-y += vboot_helper.c
-ramstage-y += vboot_helper.c
-romstage-y += vboot_loader.c
-rmodules_$(ARCH-romstage-y)-y += vboot_wrapper.c
-
-ifneq ($(CONFIG_SPI_FLASH_MEMORY_MAPPED),y)
-VBOOT_MAKEFLAGS = REGION_READ=1
-endif
-
-VB_LIB = $(obj)/external/vboot_reference/vboot_fw.a
-# Currently, vboot comes into picture only during the romstage, thus
-# is compiled for being used in romstage only. Since, we are splitting
-# up all components in one of the three stages of coreboot, vboot seems
-# most logical to fall under the romstage. Thus, all references to arch
-# and other compiler stuff for vboot is using the romstage arch.
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y))
-VB_SOURCE := vboot_reference
-
-# Add the vboot include paths.
-CPPFLAGS_common += -I$(VB_SOURCE)/firmware/include
-
-VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vbootstub.elf
-VBOOT_STUB = $(VBOOT_STUB_ELF).rmod
-
-# Dependency for the vboot rmodules. Ordering matters.
-VBOOT_STUB_DEPS += $(obj)/vendorcode/google/chromeos/vboot_wrapper.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(VB_LIB)
-# Remove the '-include' option since that will break vboot's build and ensure
-# vboot_reference can get to coreboot's include files.
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_romstage) $(CPPFLAGS_romstage)))
-VBOOT_CFLAGS += -DVBOOT_DEBUG
-VBOOT_CFLAGS += $(rmodules_$(ARCH-ROMSTAGE-y)-c-ccopts)
-
-# Link the vbootstub module with a 64KiB-byte heap.
-$(eval $(call rmodule_link,$(VBOOT_STUB_ELF), $(VBOOT_STUB_DEPS), 0x10000,$(ARCH-romstage-y)))
-
-# Build vboot library without the default includes from coreboot proper.
-$(VB_LIB):
- @printf " MAKE $(subst $(obj)/,,$(@))\n"
- $(Q)$(MAKE) -C $(VB_SOURCE) \
- CC="$(CC_romstage)" \
- CFLAGS="$(VBOOT_CFLAGS)" \
- $(VBOOT_MAKEFLAGS) \
- FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
- BUILD=$(top)/$(dir $(VB_LIB)) \
- V=$(V) \
- fwlib
-
-endif
-
-ifeq ($(CONFIG_VBOOT2_VERIFY_FIRMWARE),y)
VB_SOURCE := vboot_reference
+subdirs-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot1
+subdirs-$(CONFIG_VBOOT2_VERIFY_FIRMWARE) += vboot2
CPPFLAGS_common += -I$(VB_SOURCE)/firmware/2lib/include
CPPFLAGS_common += -I$(VB_SOURCE)/firmware/include
-
-verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
-
-ifeq ($(CONFIG_RETURN_FROM_VERSTAGE),y)
-bootblock-y += verstub.c chromeos.c
-else
-verstage-y += verstub.c
-endif
-verstage-y += verstage.c fmap.c chromeos.c
-verstage-y += antirollback.c
-verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c
-verstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c
-verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c
-romstage-y += vboot_handoff.c
-
-verstage-y += verstage.ld
-
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
-VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage) $(CPPFLAGS_verstage)))
-VBOOT_CFLAGS += $(verstage-c-ccopts)
-VBOOT_CFLAGS += -include $(top)/src/include/kconfig.h -Wno-missing-prototypes
-VBOOT_CFLAGS += -DVBOOT_DEBUG
-
-$(VB2_LIB): $(obj)/config.h
- @printf " MAKE $(subst $(obj)/,,$(@))\n"
- $(Q)$(MAKE) -C $(VB_SOURCE) \
- CC="$(CC_verstage)" \
- CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \
- FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
- BUILD=$(top)/$(dir $(VB2_LIB)) \
- V=$(V) \
- fwlib2
-
-VERSTAGE_ELF = $(objcbfs)/verstage.elf
-cbfs-files-y += $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage
-fallback/verstage-file = $(VERSTAGE_ELF)
-fallback/verstage-type = stage
-fallback/verstage-compression = none
-endif # CONFIG_VBOOT2_VERIFY_FIRMWARE
diff --git a/src/vendorcode/google/chromeos/antirollback.c b/src/vendorcode/google/chromeos/antirollback.c
deleted file mode 100644
index bb547b5..0000000
--- a/src/vendorcode/google/chromeos/antirollback.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Functions for querying, manipulating and locking rollback indices
- * stored in the TPM NVRAM.
- */
-
-#include <2api.h>
-#include <2sysincludes.h>
-#include <antirollback.h>
-#include <tpm_lite/tlcl.h>
-#include <tpm_lite/tss_constants.h>
-
-#ifndef offsetof
-#define offsetof(A,B) __builtin_offsetof(A,B)
-#endif
-
-#ifdef FOR_TEST
-#include <stdio.h>
-#define VBDEBUG(format, args...) printf(format, ## args)
-#else
-#include <console/console.h>
-#define VBDEBUG(format, args...) \
- printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
-#endif
-
-#define RETURN_ON_FAILURE(tpm_cmd) do { \
- uint32_t result_; \
- if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
- VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
- "\n", (int)result_); \
- return result_; \
- } \
- } while (0)
-
-uint32_t tpm_clear_and_reenable(void)
-{
- VBDEBUG("TPM: Clear and re-enable\n");
- RETURN_ON_FAILURE(tlcl_force_clear());
- RETURN_ON_FAILURE(tlcl_set_enable());
- RETURN_ON_FAILURE(tlcl_set_deactivated(0));
-
- return TPM_SUCCESS;
-}
-
-uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
- uint32_t result = tlcl_write(index, data, length);
- if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
- return tlcl_write(index, data, length);
- } else {
- return result;
- }
-}
-
-uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
- uint32_t result = tlcl_define_space(index, perm, size);
- if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
- return tlcl_define_space(index, perm, size);
- } else {
- return result;
- }
-}
-
-static uint32_t read_space_firmware(struct vb2_context *ctx)
-{
- int attempts = 3;
-
- while (attempts--) {
- RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
- VB2_SECDATA_SIZE));
-
- if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
- return TPM_SUCCESS;
-
- VBDEBUG("TPM: %s() - bad CRC\n", __func__);
- }
-
- VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
- return TPM_E_CORRUPTED_STATE;
-}
-
-static uint32_t write_secdata(uint32_t index,
- const uint8_t *secdata,
- uint32_t len)
-{
- uint8_t sd[32];
- uint32_t rv;
- int attempts = 3;
-
- if (len > sizeof(sd)) {
- VBDEBUG("TPM: %s() - data is too large\n", __func__);
- return TPM_E_WRITE_FAILURE;
- }
-
- while (attempts--) {
- rv = safe_write(index, secdata, len);
- /* Can't write, not gonna try again */
- if (rv != TPM_SUCCESS)
- return rv;
-
- /* Read it back to be sure it got the right values. */
- rv = tlcl_read(index, sd, len);
- if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
- return rv;
-
- VBDEBUG("TPM: %s() failed. trying again\n", __func__);
- /* Try writing it again. Maybe it was garbled on the way out. */
- }
-
- VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
-
- return TPM_E_CORRUPTED_STATE;
-}
-
-uint32_t factory_initialize_tpm(struct vb2_context *ctx)
-{
- TPM_PERMANENT_FLAGS pflags;
- uint32_t result;
- /* this is derived from rollback_index.h of vboot_reference. see struct
- * RollbackSpaceKernel for details. */
- static const uint8_t secdata_kernel[] = {
- 0x02,
- 0x4C, 0x57, 0x52, 0x47,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0xE8,
- };
-
- VBDEBUG("TPM: factory initialization\n");
-
- /*
- * Do a full test. This only happens the first time the device is
- * turned on in the factory, so performance is not an issue. This is
- * almost certainly not necessary, but it gives us more confidence
- * about some code paths below that are difficult to
- * test---specifically the ones that set lifetime flags, and are only
- * executed once per physical TPM.
- */
- result = tlcl_self_test_full();
- if (result != TPM_SUCCESS)
- return result;
-
- result = tlcl_get_permanent_flags(&pflags);
- if (result != TPM_SUCCESS)
- return result;
-
- /*
- * TPM may come from the factory without physical presence finalized.
- * Fix if necessary.
- */
- VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
- pflags.physicalPresenceLifetimeLock);
- if (!pflags.physicalPresenceLifetimeLock) {
- VBDEBUG("TPM: Finalizing physical presence\n");
- RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
- }
-
- /*
- * The TPM will not enforce the NV authorization restrictions until the
- * execution of a TPM_NV_DefineSpace with the handle of
- * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
- * exist. */
- VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
- if (!pflags.nvLocked) {
- VBDEBUG("TPM: Enabling NV locking\n");
- RETURN_ON_FAILURE(tlcl_set_nv_locked());
- }
-
- /* Clear TPM owner, in case the TPM is already owned for some reason. */
- VBDEBUG("TPM: Clearing owner\n");
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
-
- /* Define the backup space. No need to initialize it, though. */
- RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX,
- TPM_NV_PER_PPWRITE,
- VB2_NVDATA_SIZE));
-
- /* Define and initialize the kernel space */
- RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
- TPM_NV_PER_PPWRITE,
- sizeof(secdata_kernel)));
- RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
- secdata_kernel,
- sizeof(secdata_kernel)));
-
- /* Defines and sets vb2 secdata space */
- vb2api_secdata_create(ctx);
- RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
- TPM_NV_PER_GLOBALLOCK |
- TPM_NV_PER_PPWRITE,
- VB2_SECDATA_SIZE));
- RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
- ctx->secdata,
- VB2_SECDATA_SIZE));
-
- VBDEBUG("TPM: factory initialization successful\n");
-
- return TPM_SUCCESS;
-}
-
-/*
- * SetupTPM starts the TPM and establishes the root of trust for the
- * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
- * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
- * general we cannot easily distinguish the kind of failure, so our strategy is
- * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
- * again, which executes (almost) the same sequence of operations. There is a
- * good chance that, if recovery mode was entered because of a TPM failure, the
- * failure will repeat itself. (In general this is impossible to guarantee
- * because we have no way of creating the exact TPM initial state at the
- * previous boot.) In recovery mode, we ignore the failure and continue, thus
- * giving the recovery kernel a chance to fix things (that's why we don't set
- * bGlobalLock). The choice is between a knowingly insecure device and a
- * bricked device.
- *
- * As a side note, observe that we go through considerable hoops to avoid using
- * the STCLEAR permissions for the index spaces. We do this to avoid writing
- * to the TPM flashram at every reboot or wake-up, because of concerns about
- * the durability of the NVRAM.
- */
-uint32_t setup_tpm(struct vb2_context *ctx)
-{
- uint8_t disable;
- uint8_t deactivated;
- uint32_t result;
-
- RETURN_ON_FAILURE(tlcl_lib_init());
-
-#ifdef TEGRA_SOFT_REBOOT_WORKAROUND
- result = tlcl_startup();
- if (result == TPM_E_INVALID_POSTINIT) {
- /*
- * Some prototype hardware doesn't reset the TPM on a CPU
- * reset. We do a hard reset to get around this.
- */
- VBDEBUG("TPM: soft reset detected\n", result);
- return TPM_E_MUST_REBOOT;
- } else if (result != TPM_SUCCESS) {
- VBDEBUG("TPM: tlcl_startup returned %08x\n", result);
- return result;
- }
-#else
- RETURN_ON_FAILURE(tlcl_startup());
-#endif
-
- /*
- * Some TPMs start the self test automatically at power on. In that case
- * we don't need to call ContinueSelfTest. On some (other) TPMs,
- * continue_self_test may block. In that case, we definitely don't want
- * to call it here. For TPMs in the intersection of these two sets, we
- * are screwed. (In other words: TPMs that require manually starting the
- * self-test AND block will have poor performance until we split
- * tlcl_send_receive() into send() and receive(), and have a state
- * machine to control setup.)
- *
- * This comment is likely to become obsolete in the near future, so
- * don't trust it. It may have not been updated.
- */
-#ifdef TPM_MANUAL_SELFTEST
-#ifdef TPM_BLOCKING_CONTINUESELFTEST
-#warning "lousy TPM!"
-#endif
- RETURN_ON_FAILURE(tlcl_continue_self_test());
-#endif
- result = tlcl_assert_physical_presence();
- if (result != TPM_SUCCESS) {
- /*
- * It is possible that the TPM was delivered with the physical
- * presence command disabled. This tries enabling it, then
- * tries asserting PP again.
- */
- RETURN_ON_FAILURE(tlcl_physical_presence_cmd_enable());
- RETURN_ON_FAILURE(tlcl_assert_physical_presence());
- }
-
- /* Check that the TPM is enabled and activated. */
- RETURN_ON_FAILURE(tlcl_get_flags(&disable, &deactivated, NULL));
- if (disable || deactivated) {
- VBDEBUG("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
- disable, deactivated);
- RETURN_ON_FAILURE(tlcl_set_enable());
- RETURN_ON_FAILURE(tlcl_set_deactivated(0));
- VBDEBUG("TPM: Must reboot to re-enable\n");
- return TPM_E_MUST_REBOOT;
- }
-
- VBDEBUG("TPM: SetupTPM() succeeded\n");
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
-{
- uint32_t rv;
-
- rv = setup_tpm(ctx);
- if (rv)
- return rv;
-
- /* Read the firmware space. */
- rv = read_space_firmware(ctx);
- if (rv == TPM_E_BADINDEX) {
- /*
- * This seems the first time we've run. Initialize the TPM.
- */
- VBDEBUG("TPM: Not initialized yet.\n");
- RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
- } else if (rv != TPM_SUCCESS) {
- VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
- //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
- return TPM_E_CORRUPTED_STATE;
- }
-
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
-{
- return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
-}
-
-uint32_t antirollback_lock_space_firmware()
-{
- return tlcl_set_global_lock();
-}
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index c4d651a..437e128 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -20,18 +20,11 @@
#include <stddef.h>
#include <string.h>
#include "chromeos.h"
-#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-#include "fmap.h"
-#include "symbols.h"
-#include "vboot_handoff.h"
-#include <reset.h>
-#endif
#include <boot/coreboot_tables.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
static int vboot_enable_developer(void)
{
struct vboot_handoff *vbho;
@@ -58,10 +51,18 @@ static int vboot_enable_recovery(void)
return !!(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_RECOVERY);
}
-#else
-static inline int vboot_enable_developer(void) { return 0; }
-static inline int vboot_enable_recovery(void) { return 0; }
-#endif
+
+int vboot_skip_display_init(void)
+{
+ struct vboot_handoff *vbho;
+
+ vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vbho == NULL)
+ return 0;
+
+ return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
+}
int developer_mode_enabled(void)
{
@@ -92,22 +93,6 @@ int __attribute__((weak)) clear_recovery_mode_switch(void)
return 0;
}
-int vboot_skip_display_init(void)
-{
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
- struct vboot_handoff *vbho;
-
- vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vbho == NULL)
- return 0;
-
- return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
-#else
- return 0;
-#endif
-}
-
#ifdef __ROMSTAGE__
void __attribute__((weak)) save_chromeos_gpios(void)
{
@@ -120,147 +105,3 @@ int __attribute((weak)) vboot_get_sw_write_protect(void)
return 0;
}
#endif
-
-#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-void vboot_locate_region(const char *name, struct vboot_region *region)
-{
- region->size = find_fmap_entry(name, (void **)®ion->offset_addr);
-}
-
-void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest)
-{
- if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- if (dest != NULL)
- return memcpy(dest, (void *)offset_addr, size);
- else
- return (void *)offset_addr;
- } else {
- struct cbfs_media default_media, *media = &default_media;
- void *cache;
-
- init_default_cbfs_media(media);
- media->open(media);
- if (dest != NULL) {
- cache = dest;
- if (media->read(media, dest, offset_addr, size) != size)
- cache = NULL;
- } else {
- cache = media->map(media, offset_addr, size);
- if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS)
- cache = NULL;
- }
- media->close(media);
- return cache;
- }
-}
-
-int vboot_get_handoff_info(void **addr, uint32_t *size)
-{
- struct vboot_handoff *vboot_handoff;
-
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return -1;
-
- *addr = vboot_handoff;
- *size = sizeof(*vboot_handoff);
- return 0;
-}
-
-/* This will leak a mapping of a fw region */
-struct vboot_components *vboot_locate_components(struct vboot_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_addr, req_size, NULL);
- if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
- vbc = NULL;
-
- return vbc;
-}
-
-void *vboot_get_payload(int *len)
-{
- struct vboot_handoff *vboot_handoff;
- struct firmware_component *fwc;
-
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return NULL;
-
- if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid boot loader index: %d\n",
- CONFIG_VBOOT_BOOT_LOADER_INDEX);
- return NULL;
- }
-
- fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX];
-
- /* If payload size is zero fall back to cbfs path. */
- if (fwc->size == 0)
- return NULL;
-
- if (len != NULL)
- *len = fwc->size;
-
- printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n",
- fwc->size, fwc->address);
-
- /* This will leak a mapping. */
- return vboot_get_region(fwc->address, fwc->size, NULL);
-}
-#endif
-
-#if CONFIG_VBOOT2_VERIFY_FIRMWARE
-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;
-}
-
-void vboot_reboot(void)
-{
- hard_reset();
- die("failed to reboot");
-}
-
-#endif
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index ed6c75b..5ba5457 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -23,6 +23,8 @@
#include <stddef.h>
#include <stdint.h>
#include <bootmode.h>
+#include "vboot_common.h"
+#include "vboot2/misc.h"
/*for mainboard use only*/
void setup_chromeos_gpios(void);
@@ -47,54 +49,14 @@ static inline void elog_add_boot_reason(void) { return; }
struct romstage_handoff;
-/* TODO(shawnn): Remove these CONFIGs and define default weak functions
- * that can be overridden in the platform / MB code. */
#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-struct vboot_region {
- uintptr_t offset_addr;
- int32_t size;
-};
-
-/*
- * The vboot handoff structure keeps track of a maximum number of firmware
- * components in the verfieid RW area of flash. This is not a restriction on
- * the number of components packed in a firmware block. It's only the maximum
- * number of parsed firmware components (address and size) included in the
- * handoff structure.
- */
-#define MAX_PARSED_FW_COMPONENTS 5
-
-/* The FW areas consist of multiple components. At the beginning of
- * each area is the number of total compoments as well as the size and
- * offset for each component. One needs to caculate the total size of the
- * signed firmware region based off of the embedded metadata. */
-struct vboot_component_entry {
- uint32_t offset;
- uint32_t size;
-} __attribute__((packed));
-
-struct vboot_components {
- uint32_t num_components;
- struct vboot_component_entry entries[0];
-} __attribute__((packed));
-
-void vboot_locate_region(const char *name, struct vboot_region *region);
-
-struct vboot_components *vboot_locate_components(struct vboot_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(uintptr_t offset_addr, size_t size, void *dest);
/* Returns 0 on success < 0 on error. */
int vboot_get_handoff_info(void **addr, uint32_t *size);
int vboot_enable_developer(void);
int vboot_enable_recovery(void);
int vboot_skip_display_init(void);
-#else
+void *vboot_get_payload(int *len);
+#else /* CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE */
static inline void vboot_verify_firmware(struct romstage_handoff *h) {}
static inline void *vboot_get_payload(int *len) { return NULL; }
static inline int vboot_get_handoff_info(void **addr, uint32_t *size)
@@ -121,55 +83,4 @@ static inline void chromeos_ram_oops_init(chromeos_acpi_t *chromeos) {}
static inline void chromeos_reserve_ram_oops(struct device *dev, int idx) {}
#endif /* CONFIG_CHROMEOS_RAMOOPS */
-void vboot2_verify_firmware(void);
-
-#if CONFIG_VBOOT2_VERIFY_FIRMWARE
-void *vboot_load_ramstage(void);
-void verstage_main(void);
-void *vboot_load_stage(int stage_index,
- struct vboot_region *fw_main,
- struct vboot_components *fw_info);
-void vboot_reboot(void);
-
-/*
- * 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
- * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
- * stage boundaries.
- */
-struct vb2_working_data {
- uint32_t selected_region_offset;
- uint32_t selected_region_size;
- uint64_t buffer_size;
- uint64_t buffer;
-};
-
-struct vb2_working_data * const vboot_get_working_data(void);
-
-static inline void vb2_get_selected_region(struct vb2_working_data *wd,
- struct vboot_region *region)
-{
- region->offset_addr = wd->selected_region_offset;
- region->size = wd->selected_region_size;
-}
-
-static inline void vb2_set_selected_region(struct vb2_working_data *wd,
- struct vboot_region *region)
-{
- wd->selected_region_offset = region->offset_addr;
- wd->selected_region_size = region->size;
-}
-
-static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
-{
- return wd->selected_region_size > 0;
-}
-
-static inline int vboot_is_readonly_path(struct vb2_working_data *wd)
-{
- return wd->selected_region_size == 0;
-}
-
-#endif /* CONFIG_VBOOT2_VERIFY_FIRMWARE */
-
-#endif
+#endif /* __CHROMEOS_H__ */
diff --git a/src/vendorcode/google/chromeos/memlayout.h b/src/vendorcode/google/chromeos/memlayout.h
deleted file mode 100644
index 468f746..0000000
--- a/src/vendorcode/google/chromeos/memlayout.h
+++ /dev/null
@@ -1,47 +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
- */
-
-/* This file contains macro definitions for memlayout.ld linker scripts. */
-
-#ifndef __CHROMEOS_MEMLAYOUT_H
-#define __CHROMEOS_MEMLAYOUT_H
-
-#define VBOOT2_WORK(addr, size) \
- REGION(vboot2_work, addr, size, 4) \
- _ = ASSERT(size >= 16K, "vboot2 work buffer must be at least 16K!");
-
-#ifdef __VERSTAGE__
- #define VERSTAGE(addr, sz) \
- SET_COUNTER(VERSTAGE, addr) \
- _ = ASSERT(_everstage - _verstage <= sz, \
- STR(Verstage exceeded its allotted size! (sz))); \
- INCLUDE "vendorcode/google/chromeos/verstage.verstage.ld"
-#else
- #define VERSTAGE(addr, sz) \
- SET_COUNTER(VERSTAGE, addr) \
- . += sz;
-#endif
-
-#ifdef __VERSTAGE__
- #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) VERSTAGE(addr, size)
-#else
- #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) ROMSTAGE(addr, size)
-#endif
-
-#endif /* __CHROMEOS_MEMLAYOUT_H */
diff --git a/src/vendorcode/google/chromeos/symbols.h b/src/vendorcode/google/chromeos/symbols.h
deleted file mode 100644
index 21169f0..0000000
--- a/src/vendorcode/google/chromeos/symbols.h
+++ /dev/null
@@ -1,32 +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
- */
-
-#ifndef __CHROMEOS_SYMBOLS_H
-#define __CHROMEOS_SYMBOLS_H
-
-extern u8 _vboot2_work[];
-extern u8 _evboot2_work[];
-#define _vboot2_work_size (_evboot2_work - _vboot2_work)
-
-/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */
-extern u8 _verstage[];
-extern u8 _everstage[];
-#define _verstage_size (_everstage - _verstage)
-
-#endif /* __CHROMEOS_SYMBOLS_H */
diff --git a/src/vendorcode/google/chromeos/vboot1/Kconfig b/src/vendorcode/google/chromeos/vboot1/Kconfig
new file mode 100644
index 0000000..0102869
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/Kconfig
@@ -0,0 +1,34 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## 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
+##
+
+config VBOOT_VERIFY_FIRMWARE
+ bool "Verify firmware with vboot."
+ default n
+ depends on CHROMEOS
+ select RELOCATABLE_MODULES
+ help
+ Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
+ and boot loader.
+
+config VBOOT_REFCODE_INDEX
+ hex "Reference code firmware index"
+ default 1
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ This is the index of the reference code component in the verified
+ firmware block.
diff --git a/src/vendorcode/google/chromeos/vboot1/Makefile.inc b/src/vendorcode/google/chromeos/vboot1/Makefile.inc
new file mode 100644
index 0000000..a2d42b4
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/Makefile.inc
@@ -0,0 +1,74 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## 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
+##
+
+ramstage-y += ../vboot_common.c
+romstage-y += vboot_loader.c ../vboot_common.c
+rmodules_$(ARCH-ROMSTAGE-y)-y += vboot_wrapper.c ../vboot_common.c
+
+ifneq ($(CONFIG_SPI_FLASH_MEMORY_MAPPED),y)
+VBOOT_MAKEFLAGS = REGION_READ=1
+endif
+
+VB_LIB = $(obj)/external/vboot_reference/vboot_fw.a
+# Currently, vboot comes into picture only during the romstage, thus
+# is compiled for being used in romstage only. Since, we are splitting
+# up all components in one of the three stages of coreboot, vboot seems
+# most logical to fall under the romstage. Thus, all references to arch
+# and other compiler stuff for vboot is using the romstage arch.
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-ROMSTAGE-y))
+
+VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vboot1/vbootstub.elf
+VBOOT_STUB = $(VBOOT_STUB_ELF).rmod
+
+# Dependency for the vboot rmodules. Ordering matters.
+VBOOT_STUB_DEPS += $(obj)/vendorcode/google/chromeos/vboot1/vboot_wrapper.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules_$(ARCH-ROMSTAGE-y).o
+ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32),y)
+VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules_$(ARCH-ROMSTAGE-y).o
+endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM),y)
+VBOOT_STUB_DEPS += $(obj)/arch/arm/memset.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/arch/arm/memcpy.rmodules_$(ARCH-ROMSTAGE-y).o
+endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM64),y)
+VBOOT_STUB_DEPS += $(obj)/lib/memset.rmodules.o
+VBOOT_STUB_DEPS += $(obj)/lib/memcpy.rmodules.o
+endif
+VBOOT_STUB_DEPS += $(VB_LIB)
+# Remove the '-include' option since that will break vboot's build and ensure
+# vboot_reference can get to coreboot's include files.
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_romstage)))
+VBOOT_CFLAGS += -DVBOOT_DEBUG
+VBOOT_CFLAGS += $(rmodules_$(ARCH-ROMSTAGE-y)-c-ccopts)
+
+# Link the vbootstub module with a 64KiB-byte heap.
+$(eval $(call rmodule_link,$(VBOOT_STUB_ELF), $(VBOOT_STUB_DEPS), 0x10000,$(ARCH-ROMSTAGE-y)))
+
+# Build vboot library without the default includes from coreboot proper.
+$(VB_LIB):
+ @printf " MAKE $(subst $(obj)/,,$(@))\n"
+ $(Q)FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
+ CC="$(CC_romstage)" \
+ CFLAGS="$(VBOOT_CFLAGS)" \
+ $(MAKE) -C $(VB_SOURCE) \
+ $(VBOOT_MAKEFLAGS) \
+ BUILD=$(top)/$(dir $(VB_LIB)) \
+ V=$(V) \
+ fwlib
diff --git a/src/vendorcode/google/chromeos/vboot1/vboot_loader.c b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
new file mode 100644
index 0000000..0353a3a
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
@@ -0,0 +1,416 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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 <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <program_loading.h>
+#include <tpm.h>
+#include <reset.h>
+#include <romstage_handoff.h>
+#include <rmodule.h>
+#include <string.h>
+#include <stdlib.h>
+#include <timestamp.h>
+#include "../chromeos.h"
+#include "../vboot_context.h"
+#include "../vboot_handoff.h"
+
+#define TEMP_CBMEM_ID_VBOOT 0xffffffff
+#define TEMP_CBMEM_ID_VBLOCKS 0xfffffffe
+
+static void vboot_run_stub(struct vboot_context *context)
+{
+ struct rmod_stage_load rmod_stage = {
+ .cbmem_id = TEMP_CBMEM_ID_VBOOT,
+ .name = CONFIG_CBFS_PREFIX "/vboot",
+ };
+ void (*entry)(struct vboot_context *context);
+
+ if (rmodule_stage_load_from_cbfs(&rmod_stage)) {
+ printk(BIOS_DEBUG, "Could not load vboot stub.\n");
+ goto out;
+ }
+
+ entry = rmod_stage.entry;
+
+ /* Call stub. */
+ entry(context);
+
+out:
+ /* Tear down the region no longer needed. */
+ if (rmod_stage.cbmem_entry != NULL)
+ cbmem_entry_remove(rmod_stage.cbmem_entry);
+}
+
+/* Helper routines for the vboot stub. */
+static void log_msg(const char *fmt, va_list args)
+{
+ do_vtxprintf(fmt, args);
+}
+
+static void fatal_error(void)
+{
+ printk(BIOS_ERR, "vboot encountered fatal error. Resetting.\n");
+ hard_reset();
+}
+
+static int fw_region_size(struct vboot_region *r)
+{
+ struct vboot_components *fw_info;
+ int32_t size;
+ int i;
+
+ fw_info = vboot_locate_components(r);
+ if (fw_info == NULL)
+ return -1;
+
+ if (fw_info->num_components > MAX_PARSED_FW_COMPONENTS)
+ return -1;
+
+ size = sizeof(*fw_info);
+ size += sizeof(struct vboot_component_entry) * fw_info->num_components;
+
+ for (i = 0; i < fw_info->num_components; i++)
+ size += ALIGN(fw_info->entries[i].size, sizeof(uint32_t));
+
+ /* Check that size of comopnents does not exceed the region's size. */
+ if (size > r->size)
+ return -1;
+
+ /* Update region with the correct size. */
+ r->size = size;
+
+ return 0;
+}
+
+static int vboot_fill_params(struct vboot_context *ctx)
+{
+ VbCommonParams *cparams;
+ VbSelectFirmwareParams *fparams;
+
+ if (fw_region_size(&ctx->fw_a))
+ return -1;
+
+ if (fw_region_size(&ctx->fw_b))
+ return -1;
+
+ cparams = ctx->cparams;
+ fparams = ctx->fparams;
+
+ cparams->gbb_size = ctx->gbb.size;
+ fparams->verification_size_A = ctx->vblock_a.size;
+ fparams->verification_size_B = ctx->vblock_b.size;
+
+ if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ /* Get memory-mapped pointers to the regions. */
+ cparams->gbb_data = vboot_get_region(ctx->gbb.offset_addr,
+ ctx->gbb.size, NULL);
+ fparams->verification_block_A =
+ vboot_get_region(ctx->vblock_a.offset_addr,
+ ctx->vblock_a.size, NULL);
+ fparams->verification_block_B =
+ vboot_get_region(ctx->vblock_b.offset_addr,
+ ctx->vblock_b.size, NULL);
+ } else {
+ /*
+ * Copy the vblock info into a buffer in cbmem. The gbb will
+ * be read using VbExRegionRead().
+ */
+ char *dest;
+ size_t vblck_sz;
+
+ vblck_sz = ctx->vblock_a.size + ctx->vblock_b.size;
+ ctx->vblocks = cbmem_entry_add(TEMP_CBMEM_ID_VBLOCKS, vblck_sz);
+ if (ctx->vblocks == NULL)
+ return -1;
+ dest = cbmem_entry_start(ctx->vblocks);
+ if (vboot_get_region(ctx->vblock_a.offset_addr,
+ ctx->vblock_a.size, dest) == NULL)
+ return -1;
+ fparams->verification_block_A = (void *)dest;
+ dest += ctx->vblock_a.size;
+ if (vboot_get_region(ctx->vblock_b.offset_addr,
+ ctx->vblock_b.size, dest) == NULL)
+ return -1;
+ fparams->verification_block_B = (void *)dest;
+ }
+
+ return 0;
+}
+
+static void fill_handoff(struct vboot_context *context)
+{
+ struct vboot_components *fw_info;
+ struct vboot_region *region;
+ int i;
+
+ /* Fix up the handoff structure. */
+ context->handoff->selected_firmware =
+ context->fparams->selected_firmware;
+
+ /* Parse out the components for downstream consumption. */
+ if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_A)
+ region = &context->fw_a;
+ else if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_B)
+ region = &context->fw_b;
+ else
+ return;
+
+ fw_info = vboot_locate_components(region);
+ if (fw_info == NULL)
+ return;
+
+ for (i = 0; i < fw_info->num_components; i++) {
+ context->handoff->components[i].address =
+ region->offset_addr + fw_info->entries[i].offset;
+ context->handoff->components[i].size = fw_info->entries[i].size;
+ }
+}
+
+static void vboot_clean_up(struct vboot_context *context)
+{
+ if (context->vblocks != NULL)
+ cbmem_entry_remove(context->vblocks);
+}
+
+static void reset(void)
+{
+ hard_reset();
+}
+
+static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
+{
+ VbCommonParams cparams;
+ VbSelectFirmwareParams fparams;
+ struct vboot_context context;
+ uint32_t *iflags;
+
+ vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
+
+ memset(&cparams, 0, sizeof(cparams));
+ memset(&fparams, 0, sizeof(fparams));
+ memset(&context, 0, sizeof(context));
+
+ iflags = &vboot_handoff->init_params.flags;
+ if (get_developer_mode_switch())
+ *iflags |= VB_INIT_FLAG_DEV_SWITCH_ON;
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ *iflags |= VB_INIT_FLAG_REC_BUTTON_PRESSED;
+ }
+ if (get_write_protect_state())
+ *iflags |= VB_INIT_FLAG_WP_ENABLED;
+ if (vboot_get_sw_write_protect())
+ *iflags |= VB_INIT_FLAG_SW_WP_ENABLED;
+ if (CONFIG_VIRTUAL_DEV_SWITCH)
+ *iflags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
+ if (CONFIG_EC_SOFTWARE_SYNC) {
+ *iflags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC;
+ *iflags |= VB_INIT_FLAG_VIRTUAL_REC_SWITCH;
+ }
+ if (CONFIG_VBOOT_EC_SLOW_UPDATE)
+ *iflags |= VB_INIT_FLAG_EC_SLOW_UPDATE;
+ if (CONFIG_VBOOT_OPROM_MATTERS) {
+ *iflags |= VB_INIT_FLAG_OPROM_MATTERS;
+ /* Will load VGA option rom during this boot */
+ if (developer_mode_enabled() || recovery_mode_enabled() ||
+ vboot_wants_oprom()) {
+ *iflags |= VB_INIT_FLAG_OPROM_LOADED;
+ }
+ }
+
+ context.handoff = vboot_handoff;
+ context.cparams = &cparams;
+ context.fparams = &fparams;
+
+ cparams.shared_data_blob = &vboot_handoff->shared_data[0];
+ cparams.shared_data_size = VB_SHARED_DATA_MIN_SIZE;
+ cparams.caller_context = &context;
+
+ vboot_locate_region("GBB", &context.gbb);
+ vboot_locate_region("VBLOCK_A", &context.vblock_a);
+ vboot_locate_region("VBLOCK_B", &context.vblock_b);
+ vboot_locate_region("FW_MAIN_A", &context.fw_a);
+ vboot_locate_region("FW_MAIN_B", &context.fw_b);
+
+ /* Check all fmap entries. */
+ if (context.fw_a.size < 0 || context.fw_b.size < 0 ||
+ context.vblock_a.size < 0 || context.vblock_b.size < 0 ||
+ context.gbb.size < 0) {
+ printk(BIOS_DEBUG, "Not all fmap entries found for vboot.\n");
+ return;
+ }
+
+ /* Fill in vboot parameters. */
+ if (vboot_fill_params(&context)) {
+ vboot_clean_up(&context);
+ return;
+ }
+
+ /* Initialize callbacks. */
+ context.read_vbnv = &read_vbnv;
+ context.save_vbnv = &save_vbnv;
+ context.tis_init = &tis_init;
+ context.tis_open = &tis_open;
+ context.tis_close = &tis_close;
+ context.tis_sendrecv = &tis_sendrecv;
+ context.log_msg = &log_msg;
+ context.fatal_error = &fatal_error;
+ context.get_region = &vboot_get_region;
+ context.reset = &reset;
+
+ vboot_run_stub(&context);
+
+ fill_handoff(&context);
+
+ vboot_clean_up(&context);
+}
+
+#if CONFIG_RELOCATABLE_RAMSTAGE
+static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
+ const struct cbmem_entry **cbmem_entry)
+{
+ struct vboot_handoff *vboot_handoff;
+ struct cbfs_stage *stage;
+ const struct firmware_component *fwc;
+ struct rmod_stage_load rmod_load = {
+ .cbmem_id = cbmem_id,
+ .name = name,
+ };
+
+ timestamp_add_now(TS_START_VBOOT);
+
+ vboot_handoff = cbmem_add(CBMEM_ID_VBOOT_HANDOFF,
+ sizeof(*vboot_handoff));
+
+ if (vboot_handoff == NULL) {
+ printk(BIOS_DEBUG, "Could not add vboot_handoff structure.\n");
+ return NULL;
+ }
+
+ memset(vboot_handoff, 0, sizeof(*vboot_handoff));
+
+ vboot_invoke_wrapper(vboot_handoff);
+
+ timestamp_add_now(TS_END_VBOOT);
+
+ /* Take RO firmware path since no RW area was selected. */
+ if (vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_A &&
+ vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_B) {
+ printk(BIOS_DEBUG, "No RW firmware selected: 0x%08x\n",
+ vboot_handoff->selected_firmware);
+ return NULL;
+ }
+
+ if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid ramstage index: %d\n",
+ CONFIG_VBOOT_RAMSTAGE_INDEX);
+ return NULL;
+ }
+
+ /* Check for invalid address. */
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
+ if (fwc->address == 0) {
+ printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
+ return NULL;
+ }
+
+ printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
+ fwc->address, fwc->size);
+
+ stage = (void *)fwc->address;
+
+ if (rmodule_stage_load(&rmod_load, stage)) {
+ vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
+ printk(BIOS_DEBUG, "Could not load ramstage region.\n");
+ return NULL;
+ }
+
+ *cbmem_entry = rmod_load.cbmem_entry;
+
+ return rmod_load.entry;
+}
+#else /* CONFIG_RELOCATABLE_RAMSTAGE */
+static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
+ struct romstage_handoff *handoff)
+{
+ struct cbfs_stage *stage;
+ const struct firmware_component *fwc;
+
+ if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid ramstage index: %d\n",
+ CONFIG_VBOOT_RAMSTAGE_INDEX);
+ return;
+ }
+
+ /* Check for invalid address. */
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
+ if (fwc->address == 0) {
+ printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
+ fwc->address, fwc->size);
+
+ /* This will leak a mapping. */
+ stage = vboot_get_region(fwc->address, fwc->size, NULL);
+
+ if (stage == NULL) {
+ printk(BIOS_DEBUG, "Unable to get RW ramstage region.\n");
+ return;
+ }
+
+ timestamp_add_now(TS_START_COPYRAM);
+
+ /* Stages rely the below clearing so that the bss is initialized. */
+ memset((void *) (uintptr_t) stage->load, 0, stage->memlen);
+
+ if (cbfs_decompress(stage->compression,
+ ((unsigned char *) stage) +
+ sizeof(struct cbfs_stage),
+ (void *) (uintptr_t) stage->load,
+ stage->len))
+ return;
+
+ timestamp_add_now(TS_END_COPYRAM);
+
+#if CONFIG_ARCH_X86
+ __asm__ volatile (
+ "movl $0, %%ebp\n"
+ "jmp *%%edi\n"
+ :: "D"(stage->entry)
+ );
+#elif CONFIG_ARCH_ARM
+ stage_exit((void *)(uintptr_t)stage->entry);
+#endif
+}
+#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
+
+
+const struct ramstage_loader_ops vboot_ramstage_loader = {
+ .name = "VBOOT",
+ .load = vboot_load_ramstage,
+};
diff --git a/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c b/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c
new file mode 100644
index 0000000..5b9dbbb
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c
@@ -0,0 +1,266 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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 <console/vtxprintf.h>
+#if CONFIG_ARCH_X86
+#include <cpu/x86/tsc.h>
+#else
+#include <timer.h>
+#endif
+#include <rmodule.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../vboot_context.h"
+#include "../vboot_handoff.h"
+
+/* Keep a global context pointer around for the callbacks to use. */
+static struct vboot_context *gcontext;
+
+static void vboot_wrapper(void *arg)
+{
+ VbError_t res;
+ struct vboot_context *context;
+
+ context = arg;
+ gcontext = context;
+
+ VbExDebug("Calling VbInit()\n");
+ res = VbInit(context->cparams, &context->handoff->init_params);
+ VbExDebug("VbInit() returned 0x%08x\n", res);
+
+ if (res != VBERROR_SUCCESS) {
+ if(res == VBERROR_TPM_REBOOT_REQUIRED) {
+ VbExDebug("TPM Reboot Required. Proceeding reboot.\n");
+ gcontext->reset();
+ }
+ return;
+ }
+
+ VbExDebug("Calling VbSelectFirmware()\n");
+ res = VbSelectFirmware(context->cparams, context->fparams);
+ VbExDebug("VbSelectFirmware() returned 0x%08x\n", res);
+
+ if (res != VBERROR_SUCCESS)
+ return;
+}
+
+void VbExError(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ gcontext->log_msg(format, args);
+ va_end(args);
+
+ gcontext->fatal_error();
+}
+
+void VbExDebug(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ gcontext->log_msg(format, args);
+ va_end(args);
+}
+
+uint64_t VbExGetTimer(void)
+{
+#if CONFIG_ARCH_X86
+ return rdtscll();
+#else
+ struct mono_time mt;
+ timer_monotonic_get(&mt);
+ return mt.microseconds;
+#endif
+}
+
+VbError_t VbExNvStorageRead(uint8_t *buf)
+{
+ gcontext->read_vbnv(buf);
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExNvStorageWrite(const uint8_t *buf)
+{
+ gcontext->save_vbnv(buf);
+ return VBERROR_SUCCESS;
+}
+
+extern char _heap[];
+extern char _eheap[];
+static char *heap_current;
+static int heap_size;
+
+void *VbExMalloc(size_t size)
+{
+ void *ptr;
+
+ if (heap_current == NULL) {
+ heap_current = &_heap[0];
+ heap_size = &_eheap[0] - &_heap[0];
+ VbExDebug("vboot heap: %p 0x%08x bytes\n",
+ heap_current, heap_size);
+ }
+
+ if (heap_size < size) {
+ VbExError("vboot heap request cannot be fulfilled. "
+ "0x%08x available, 0x%08x requested\n",
+ heap_size, size);
+ }
+
+ ptr = heap_current;
+ heap_size -= size;
+ heap_current += size;
+
+ return ptr;
+}
+
+void VbExFree(void *ptr)
+{
+ /* Leak all memory. */
+}
+
+/* vboot doesn't expose these through the vboot_api.h, but they are needed.
+ * coreboot requires declarations so provide them to avoid compiler errors. */
+int Memcmp(const void *src1, const void *src2, size_t n);
+void *Memcpy(void *dest, const void *src, uint64_t n);
+void *Memset(void *dest, const uint8_t c, uint64_t n);
+
+int Memcmp(const void *src1, const void *src2, size_t n)
+{
+ return memcmp(src1, src2, n);
+}
+
+void *Memcpy(void *dest, const void *src, uint64_t n)
+{
+ return memcpy(dest, src, n);
+}
+
+void *Memset(void *dest, const uint8_t c, uint64_t n)
+{
+ return memset(dest, c, n);
+}
+
+static inline size_t get_hash_block_size(size_t requested_size)
+{
+ if (!IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ const size_t block_size = 64 * 1024;
+ if (requested_size > block_size)
+ return block_size;
+ }
+ return requested_size;
+}
+
+VbError_t VbExHashFirmwareBody(VbCommonParams *cparams, uint32_t firmware_index)
+{
+ uint8_t *data;
+ struct vboot_region *region;
+ struct vboot_context *ctx;
+ size_t data_size;
+ uintptr_t offset_addr;
+
+ ctx = cparams->caller_context;
+
+ switch (firmware_index) {
+ case VB_SELECT_FIRMWARE_A:
+ region = &ctx->fw_a;
+ break;
+ case VB_SELECT_FIRMWARE_B:
+ region = &ctx->fw_b;
+ break;
+ default:
+ return VBERROR_UNKNOWN;
+ }
+
+ data_size = region->size;
+ offset_addr = region->offset_addr;
+ while (data_size) {
+ size_t block_size;
+
+ block_size = get_hash_block_size(data_size);
+ data = ctx->get_region(offset_addr, block_size, NULL);
+ if (data == NULL)
+ return VBERROR_UNKNOWN;
+ VbUpdateFirmwareBodyHash(cparams, data, block_size);
+
+ data_size -= block_size;
+ offset_addr += block_size;
+ }
+
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExTpmInit(void)
+{
+ if (gcontext->tis_init())
+ return VBERROR_UNKNOWN;
+ return VbExTpmOpen();
+}
+
+VbError_t VbExTpmClose(void)
+{
+ if (gcontext->tis_close())
+ return VBERROR_UNKNOWN;
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExTpmOpen(void)
+{
+ if (gcontext->tis_open())
+ return VBERROR_UNKNOWN;
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length,
+ uint8_t *response, uint32_t *response_length)
+{
+ size_t len = *response_length;
+ if (gcontext->tis_sendrecv(request, request_length, response, &len))
+ return VBERROR_UNKNOWN;
+ /* check 64->32bit overflow and (re)check response buffer overflow */
+ if (len > *response_length)
+ return VBERROR_UNKNOWN;
+ *response_length = len;
+ return VBERROR_SUCCESS;
+}
+
+#if !CONFIG_SPI_FLASH_MEMORY_MAPPED
+VbError_t VbExRegionRead(VbCommonParams *cparams,
+ enum vb_firmware_region region, uint32_t offset,
+ uint32_t size, void *buf)
+{
+ struct vboot_context *ctx;
+ VbExDebug("VbExRegionRead: offset=%x size=%x, buf=%p\n",
+ offset, size, buf);
+ ctx = cparams->caller_context;
+
+ if (region == VB_REGION_GBB) {
+ if (offset + size > cparams->gbb_size)
+ return VBERROR_REGION_READ_INVALID;
+ offset += ctx->gbb.offset_addr;
+ if (ctx->get_region(offset, size, buf) == NULL)
+ return VBERROR_REGION_READ_INVALID;
+ return VBERROR_SUCCESS;
+ }
+
+ return VBERROR_UNSUPPORTED_REGION;
+}
+#endif /* CONFIG_SPI_FLASH_MEMORY_MAPPED */
+
+RMODULE_ENTRY(vboot_wrapper);
diff --git a/src/vendorcode/google/chromeos/vboot2/Kconfig b/src/vendorcode/google/chromeos/vboot2/Kconfig
new file mode 100644
index 0000000..20d2f1f
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/Kconfig
@@ -0,0 +1,43 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## 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
+##
+
+config VBOOT2_VERIFY_FIRMWARE
+ bool "Firmware Verification with vboot2"
+ default n
+ depends on CHROMEOS && HAVE_HARD_RESET
+ help
+ Enabling VBOOT2_VERIFY_FIRMWARE will use vboot2 to verify the romstage
+ and boot loader.
+
+config RETURN_FROM_VERSTAGE
+ bool "return from verstage"
+ default n
+ depends on VBOOT2_VERIFY_FIRMWARE
+ help
+ If this is set, the verstage returns back to the bootblock instead of
+ exits to the romstage so that the verstage space can be reused by the
+ romstage. Useful if a ram space is too small to fit both the verstage
+ and the romstage.
+
+config VBOOT_ROMSTAGE_INDEX
+ hex
+ default 2
+ depends on VBOOT2_VERIFY_FIRMWARE
+ help
+ This is the index of the romstage component in the verified
+ firmware block.
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
new file mode 100644
index 0000000..3c07a51
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -0,0 +1,60 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## 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
+##
+
+verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
+
+ramstage-y += ../vboot_common.c
+romstage-y += ../vboot_common.c
+
+ifeq ($(CONFIG_RETURN_FROM_VERSTAGE),y)
+bootblock-y += common.c verstub.c ../chromeos.c ../vboot_common.c
+else
+verstage-y += verstub.c
+endif
+verstage-y += verstage.c ../fmap.c ../chromeos.c ../vboot_common.c
+verstage-y += antirollback.c common.c
+verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += ../vbnv_cmos.c
+verstage-$(CONFIG_CHROMEOS_VBNV_EC) += ../vbnv_ec.c
+verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += ../vbnv_flash.c
+romstage-y += vboot_handoff.c common.c
+
+verstage-y += verstage.ld
+
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
+VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage)))
+VBOOT_CFLAGS += $(verstage-c-ccopts)
+VBOOT_CFLAGS += -include $(top)/src/include/kconfig.h -Wno-missing-prototypes
+VBOOT_CFLAGS += -DVBOOT_DEBUG
+
+$(VB2_LIB): $(obj)/config.h
+ @printf " MAKE $(subst $(obj)/,,$(@))\n"
+ $(Q)FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
+ CC="$(CC_verstage)" \
+ CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \
+ $(MAKE) -C $(VB_SOURCE) \
+ BUILD=$(top)/$(dir $(VB2_LIB)) \
+ V=$(V) \
+ fwlib2
+
+VERSTAGE_ELF = $(objcbfs)/verstage.elf
+cbfs-files-y += $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage
+fallback/verstage-file = $(VERSTAGE_ELF)
+fallback/verstage-type = stage
+fallback/verstage-compression = none
diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
new file mode 100644
index 0000000..bb547b5
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/antirollback.c
@@ -0,0 +1,329 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Functions for querying, manipulating and locking rollback indices
+ * stored in the TPM NVRAM.
+ */
+
+#include <2api.h>
+#include <2sysincludes.h>
+#include <antirollback.h>
+#include <tpm_lite/tlcl.h>
+#include <tpm_lite/tss_constants.h>
+
+#ifndef offsetof
+#define offsetof(A,B) __builtin_offsetof(A,B)
+#endif
+
+#ifdef FOR_TEST
+#include <stdio.h>
+#define VBDEBUG(format, args...) printf(format, ## args)
+#else
+#include <console/console.h>
+#define VBDEBUG(format, args...) \
+ printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
+#endif
+
+#define RETURN_ON_FAILURE(tpm_cmd) do { \
+ uint32_t result_; \
+ if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
+ VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
+ "\n", (int)result_); \
+ return result_; \
+ } \
+ } while (0)
+
+uint32_t tpm_clear_and_reenable(void)
+{
+ VBDEBUG("TPM: Clear and re-enable\n");
+ RETURN_ON_FAILURE(tlcl_force_clear());
+ RETURN_ON_FAILURE(tlcl_set_enable());
+ RETURN_ON_FAILURE(tlcl_set_deactivated(0));
+
+ return TPM_SUCCESS;
+}
+
+uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
+{
+ uint32_t result = tlcl_write(index, data, length);
+ if (result == TPM_E_MAXNVWRITES) {
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl_write(index, data, length);
+ } else {
+ return result;
+ }
+}
+
+uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ uint32_t result = tlcl_define_space(index, perm, size);
+ if (result == TPM_E_MAXNVWRITES) {
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl_define_space(index, perm, size);
+ } else {
+ return result;
+ }
+}
+
+static uint32_t read_space_firmware(struct vb2_context *ctx)
+{
+ int attempts = 3;
+
+ while (attempts--) {
+ RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
+ VB2_SECDATA_SIZE));
+
+ if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
+ return TPM_SUCCESS;
+
+ VBDEBUG("TPM: %s() - bad CRC\n", __func__);
+ }
+
+ VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
+ return TPM_E_CORRUPTED_STATE;
+}
+
+static uint32_t write_secdata(uint32_t index,
+ const uint8_t *secdata,
+ uint32_t len)
+{
+ uint8_t sd[32];
+ uint32_t rv;
+ int attempts = 3;
+
+ if (len > sizeof(sd)) {
+ VBDEBUG("TPM: %s() - data is too large\n", __func__);
+ return TPM_E_WRITE_FAILURE;
+ }
+
+ while (attempts--) {
+ rv = safe_write(index, secdata, len);
+ /* Can't write, not gonna try again */
+ if (rv != TPM_SUCCESS)
+ return rv;
+
+ /* Read it back to be sure it got the right values. */
+ rv = tlcl_read(index, sd, len);
+ if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
+ return rv;
+
+ VBDEBUG("TPM: %s() failed. trying again\n", __func__);
+ /* Try writing it again. Maybe it was garbled on the way out. */
+ }
+
+ VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
+
+ return TPM_E_CORRUPTED_STATE;
+}
+
+uint32_t factory_initialize_tpm(struct vb2_context *ctx)
+{
+ TPM_PERMANENT_FLAGS pflags;
+ uint32_t result;
+ /* this is derived from rollback_index.h of vboot_reference. see struct
+ * RollbackSpaceKernel for details. */
+ static const uint8_t secdata_kernel[] = {
+ 0x02,
+ 0x4C, 0x57, 0x52, 0x47,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xE8,
+ };
+
+ VBDEBUG("TPM: factory initialization\n");
+
+ /*
+ * Do a full test. This only happens the first time the device is
+ * turned on in the factory, so performance is not an issue. This is
+ * almost certainly not necessary, but it gives us more confidence
+ * about some code paths below that are difficult to
+ * test---specifically the ones that set lifetime flags, and are only
+ * executed once per physical TPM.
+ */
+ result = tlcl_self_test_full();
+ if (result != TPM_SUCCESS)
+ return result;
+
+ result = tlcl_get_permanent_flags(&pflags);
+ if (result != TPM_SUCCESS)
+ return result;
+
+ /*
+ * TPM may come from the factory without physical presence finalized.
+ * Fix if necessary.
+ */
+ VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
+ pflags.physicalPresenceLifetimeLock);
+ if (!pflags.physicalPresenceLifetimeLock) {
+ VBDEBUG("TPM: Finalizing physical presence\n");
+ RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
+ }
+
+ /*
+ * The TPM will not enforce the NV authorization restrictions until the
+ * execution of a TPM_NV_DefineSpace with the handle of
+ * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
+ * exist. */
+ VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
+ if (!pflags.nvLocked) {
+ VBDEBUG("TPM: Enabling NV locking\n");
+ RETURN_ON_FAILURE(tlcl_set_nv_locked());
+ }
+
+ /* Clear TPM owner, in case the TPM is already owned for some reason. */
+ VBDEBUG("TPM: Clearing owner\n");
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+
+ /* Define the backup space. No need to initialize it, though. */
+ RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX,
+ TPM_NV_PER_PPWRITE,
+ VB2_NVDATA_SIZE));
+
+ /* Define and initialize the kernel space */
+ RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
+ TPM_NV_PER_PPWRITE,
+ sizeof(secdata_kernel)));
+ RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
+ secdata_kernel,
+ sizeof(secdata_kernel)));
+
+ /* Defines and sets vb2 secdata space */
+ vb2api_secdata_create(ctx);
+ RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
+ TPM_NV_PER_GLOBALLOCK |
+ TPM_NV_PER_PPWRITE,
+ VB2_SECDATA_SIZE));
+ RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
+ ctx->secdata,
+ VB2_SECDATA_SIZE));
+
+ VBDEBUG("TPM: factory initialization successful\n");
+
+ return TPM_SUCCESS;
+}
+
+/*
+ * SetupTPM starts the TPM and establishes the root of trust for the
+ * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
+ * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
+ * general we cannot easily distinguish the kind of failure, so our strategy is
+ * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
+ * again, which executes (almost) the same sequence of operations. There is a
+ * good chance that, if recovery mode was entered because of a TPM failure, the
+ * failure will repeat itself. (In general this is impossible to guarantee
+ * because we have no way of creating the exact TPM initial state at the
+ * previous boot.) In recovery mode, we ignore the failure and continue, thus
+ * giving the recovery kernel a chance to fix things (that's why we don't set
+ * bGlobalLock). The choice is between a knowingly insecure device and a
+ * bricked device.
+ *
+ * As a side note, observe that we go through considerable hoops to avoid using
+ * the STCLEAR permissions for the index spaces. We do this to avoid writing
+ * to the TPM flashram at every reboot or wake-up, because of concerns about
+ * the durability of the NVRAM.
+ */
+uint32_t setup_tpm(struct vb2_context *ctx)
+{
+ uint8_t disable;
+ uint8_t deactivated;
+ uint32_t result;
+
+ RETURN_ON_FAILURE(tlcl_lib_init());
+
+#ifdef TEGRA_SOFT_REBOOT_WORKAROUND
+ result = tlcl_startup();
+ if (result == TPM_E_INVALID_POSTINIT) {
+ /*
+ * Some prototype hardware doesn't reset the TPM on a CPU
+ * reset. We do a hard reset to get around this.
+ */
+ VBDEBUG("TPM: soft reset detected\n", result);
+ return TPM_E_MUST_REBOOT;
+ } else if (result != TPM_SUCCESS) {
+ VBDEBUG("TPM: tlcl_startup returned %08x\n", result);
+ return result;
+ }
+#else
+ RETURN_ON_FAILURE(tlcl_startup());
+#endif
+
+ /*
+ * Some TPMs start the self test automatically at power on. In that case
+ * we don't need to call ContinueSelfTest. On some (other) TPMs,
+ * continue_self_test may block. In that case, we definitely don't want
+ * to call it here. For TPMs in the intersection of these two sets, we
+ * are screwed. (In other words: TPMs that require manually starting the
+ * self-test AND block will have poor performance until we split
+ * tlcl_send_receive() into send() and receive(), and have a state
+ * machine to control setup.)
+ *
+ * This comment is likely to become obsolete in the near future, so
+ * don't trust it. It may have not been updated.
+ */
+#ifdef TPM_MANUAL_SELFTEST
+#ifdef TPM_BLOCKING_CONTINUESELFTEST
+#warning "lousy TPM!"
+#endif
+ RETURN_ON_FAILURE(tlcl_continue_self_test());
+#endif
+ result = tlcl_assert_physical_presence();
+ if (result != TPM_SUCCESS) {
+ /*
+ * It is possible that the TPM was delivered with the physical
+ * presence command disabled. This tries enabling it, then
+ * tries asserting PP again.
+ */
+ RETURN_ON_FAILURE(tlcl_physical_presence_cmd_enable());
+ RETURN_ON_FAILURE(tlcl_assert_physical_presence());
+ }
+
+ /* Check that the TPM is enabled and activated. */
+ RETURN_ON_FAILURE(tlcl_get_flags(&disable, &deactivated, NULL));
+ if (disable || deactivated) {
+ VBDEBUG("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
+ disable, deactivated);
+ RETURN_ON_FAILURE(tlcl_set_enable());
+ RETURN_ON_FAILURE(tlcl_set_deactivated(0));
+ VBDEBUG("TPM: Must reboot to re-enable\n");
+ return TPM_E_MUST_REBOOT;
+ }
+
+ VBDEBUG("TPM: SetupTPM() succeeded\n");
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
+{
+ uint32_t rv;
+
+ rv = setup_tpm(ctx);
+ if (rv)
+ return rv;
+
+ /* Read the firmware space. */
+ rv = read_space_firmware(ctx);
+ if (rv == TPM_E_BADINDEX) {
+ /*
+ * This seems the first time we've run. Initialize the TPM.
+ */
+ VBDEBUG("TPM: Not initialized yet.\n");
+ RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
+ } else if (rv != TPM_SUCCESS) {
+ VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
+ //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
+ return TPM_E_CORRUPTED_STATE;
+ }
+
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
+{
+ return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
+}
+
+uint32_t antirollback_lock_space_firmware()
+{
+ return tlcl_set_global_lock();
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c
new file mode 100644
index 0000000..178e8b5
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/common.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * 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 <cbfs.h>
+#include <console/console.h>
+#include <reset.h>
+#include "../chromeos.h"
+#include "../vboot_handoff.h"
+#include "misc.h"
+#include "symbols.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;
+}
+
+void vboot_reboot(void)
+{
+ hard_reset();
+ die("failed to reboot");
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/memlayout.h b/src/vendorcode/google/chromeos/vboot2/memlayout.h
new file mode 100644
index 0000000..9e19200
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/memlayout.h
@@ -0,0 +1,47 @@
+/*
+ * 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
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __CHROMEOS_VBOOT2_MEMLAYOUT_H
+#define __CHROMEOS_VBOOT2_MEMLAYOUT_H
+
+#define VBOOT2_WORK(addr, size) \
+ REGION(vboot2_work, addr, size, 4) \
+ _ = ASSERT(size >= 16K, "vboot2 work buffer must be at least 16K!");
+
+#ifdef __VERSTAGE__
+ #define VERSTAGE(addr, sz) \
+ SET_COUNTER(VERSTAGE, addr) \
+ _ = ASSERT(_everstage - _verstage <= sz, \
+ STR(Verstage exceeded its allotted size! (sz))); \
+ INCLUDE "vendorcode/google/chromeos/vboot2/verstage.verstage.ld"
+#else
+ #define VERSTAGE(addr, sz) \
+ SET_COUNTER(VERSTAGE, addr) \
+ . += sz;
+#endif
+
+#ifdef __VERSTAGE__
+ #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) VERSTAGE(addr, size)
+#else
+ #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) ROMSTAGE(addr, size)
+#endif
+
+#endif /* __CHROMEOS_VBOOT2_MEMLAYOUT_H */
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
new file mode 100644
index 0000000..cae302b
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * 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
+ */
+
+#ifndef __CHROMEOS_VBOOT2_MISC_H__
+#define __CHROMEOS_VBOOT2_MISC_H__
+
+#include "../vboot_common.h"
+
+void vboot2_verify_firmware(void);
+void *vboot2_load_ramstage(void);
+void verstage_main(void);
+void *vboot_load_stage(int stage_index,
+ struct vboot_region *fw_main,
+ struct vboot_components *fw_info);
+void vboot_reboot(void);
+
+/*
+ * 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
+ * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
+ * stage boundaries.
+ */
+struct vb2_working_data {
+ uint32_t selected_region_offset;
+ uint32_t selected_region_size;
+ uint64_t buffer_size;
+ uint64_t buffer;
+};
+
+struct vb2_working_data * const vboot_get_working_data(void);
+
+static inline void vb2_get_selected_region(struct vb2_working_data *wd,
+ struct vboot_region *region)
+{
+ region->offset_addr = wd->selected_region_offset;
+ region->size = wd->selected_region_size;
+}
+
+static inline void vb2_set_selected_region(struct vb2_working_data *wd,
+ struct vboot_region *region)
+{
+ wd->selected_region_offset = region->offset_addr;
+ wd->selected_region_size = region->size;
+}
+
+static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
+{
+ return wd->selected_region_size > 0;
+}
+
+static inline int vboot_is_readonly_path(struct vb2_working_data *wd)
+{
+ return wd->selected_region_size == 0;
+}
+
+#endif /* __CHROMEOS_VBOOT2_MISC_H__ */
diff --git a/src/vendorcode/google/chromeos/vboot2/symbols.h b/src/vendorcode/google/chromeos/vboot2/symbols.h
new file mode 100644
index 0000000..fda7114
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/symbols.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+#ifndef __CHROMEOS_VBOOT2_SYMBOLS_H
+#define __CHROMEOS_VBOOT2_SYMBOLS_H
+
+extern u8 _vboot2_work[];
+extern u8 _evboot2_work[];
+#define _vboot2_work_size (_evboot2_work - _vboot2_work)
+
+/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */
+extern u8 _verstage[];
+extern u8 _everstage[];
+#define _verstage_size (_everstage - _verstage)
+
+#endif /* __CHROMEOS_VBOOT2_SYMBOLS_H */
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
new file mode 100644
index 0000000..a8573d0
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -0,0 +1,175 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 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 <2recovery_reasons.h>
+#include <2struct.h>
+#include <arch/stages.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <stdlib.h>
+#include <timestamp.h>
+#include <vboot_struct.h>
+#include "../chromeos.h"
+#include "../fmap.h"
+#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;
+ 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;
+ }
+
+ return vboot_load_stage(CONFIG_VBOOT_RAMSTAGE_INDEX, fw_main, fw_info);
+}
+
+/**
+ * Sets vboot_handoff based on the information in vb2_shared_data
+ *
+ * TODO: Read wp switch to set VBSD_BOOT_FIRMWARE_WP_ENABLED
+ */
+static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
+ struct vb2_shared_data *vb2_sd)
+{
+ VbSharedDataHeader *vb_sd =
+ (VbSharedDataHeader *)vboot_handoff->shared_data;
+ uint32_t *oflags = &vboot_handoff->init_params.out_flags;
+
+ vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
+
+ vboot_handoff->selected_firmware = vb2_sd->fw_slot;
+
+ vb_sd->firmware_index = vb2_sd->fw_slot;
+
+ vb_sd->magic = VB_SHARED_DATA_MAGIC;
+ vb_sd->struct_version = VB_SHARED_DATA_VERSION;
+ vb_sd->struct_size = sizeof(VbSharedDataHeader);
+ vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE;
+ vb_sd->data_used = sizeof(VbSharedDataHeader);
+
+ if (vb2_sd->recovery_reason) {
+ vb_sd->firmware_index = 0xFF;
+ if (vb2_sd->recovery_reason == VB2_RECOVERY_RO_MANUAL)
+ vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
+ *oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
+ *oflags |= VB_INIT_OUT_CLEAR_RAM;
+ *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
+ *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
+ }
+ if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) {
+ *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER;
+ *oflags |= VB_INIT_OUT_CLEAR_RAM;
+ *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
+ *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
+ vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
+ vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
+ }
+ /* TODO: Set these in depthcharge */
+ if (CONFIG_VIRTUAL_DEV_SWITCH)
+ vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
+ if (CONFIG_EC_SOFTWARE_SYNC) {
+ vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
+ vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
+ }
+ /* In vboot1, VBSD_FWB_TRIED is
+ * set only if B is booted as explicitly requested. Therefore, if B is
+ * booted because A was found bad, the flag should not be set. It's
+ * better not to touch it if we can only ambiguously control it. */
+ /* if (vb2_sd->fw_slot)
+ vb_sd->flags |= VBSD_FWB_TRIED; */
+
+ /* copy kernel subkey if it's found */
+ if (vb2_sd->workbuf_preamble_size) {
+ struct vb2_fw_preamble *fp;
+ uintptr_t dst, src;
+ printk(BIOS_INFO, "Copying FW preamble\n");
+ fp = (struct vb2_fw_preamble *)((uintptr_t)vb2_sd +
+ vb2_sd->workbuf_preamble_offset);
+ src = (uintptr_t)&fp->kernel_subkey +
+ fp->kernel_subkey.key_offset;
+ dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
+ assert(dst + fp->kernel_subkey.key_size <=
+ (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
+ memcpy((void *)dst, (void *)src,
+ fp->kernel_subkey.key_size);
+ vb_sd->data_used += fp->kernel_subkey.key_size;
+ vb_sd->kernel_subkey.key_offset =
+ dst - (uintptr_t)&vb_sd->kernel_subkey;
+ vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
+ vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
+ vb_sd->kernel_subkey.key_version =
+ fp->kernel_subkey.key_version;
+ }
+
+ vb_sd->recovery_reason = vb2_sd->recovery_reason;
+}
+
+/**
+ * Load ramstage and return the entry point
+ */
+void *vboot2_load_ramstage(void)
+{
+ struct vboot_handoff *vh;
+ struct vb2_shared_data *sd;
+ struct vboot_region fw_main;
+ struct vb2_working_data *wd = vboot_get_working_data();
+
+ sd = (struct vb2_shared_data *)(uintptr_t)wd->buffer;
+ sd->workbuf_hash_offset = 0;
+ sd->workbuf_hash_size = 0;
+
+ printk(BIOS_INFO, "creating vboot_handoff structure\n");
+ vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
+ if (vh == NULL)
+ /* we don't need to failover gracefully here because this
+ * shouldn't happen with the image that has passed QA. */
+ die("failed to allocate vboot_handoff structure\n");
+
+ memset(vh, 0, sizeof(*vh));
+
+ /* 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;
+
+ 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);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
new file mode 100644
index 0000000..572e161
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -0,0 +1,252 @@
+/*
+ * 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 <2api.h>
+#include <2struct.h>
+#include <antirollback.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <string.h>
+
+#include "../chromeos.h"
+#include "misc.h"
+
+#define TODO_BLOCK_SIZE 1024
+
+static int is_slot_a(struct vb2_context *ctx)
+{
+ return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
+}
+
+/* exports */
+
+void vb2ex_printf(const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ printk(BIOS_INFO, "VB2:%s() ", func);
+ va_start(args, fmt);
+ vprintk(BIOS_INFO, fmt, args);
+ va_end(args);
+
+ return;
+}
+
+int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
+{
+ uint32_t rv;
+ printk(BIOS_INFO, "Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
+}
+
+int vb2ex_read_resource(struct vb2_context *ctx,
+ enum vb2_resource_index index,
+ uint32_t offset,
+ void *buf,
+ uint32_t size)
+{
+ struct vboot_region region;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ vboot_locate_region("GBB", ®ion);
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ vboot_locate_region("VBLOCK_A", ®ion);
+ else
+ vboot_locate_region("VBLOCK_B", ®ion);
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (offset + size > region.size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (vboot_get_region(region.offset_addr + offset, size, buf) == NULL)
+ return VB2_ERROR_UNKNOWN;
+
+ return VB2_SUCCESS;
+}
+
+static int hash_body(struct vb2_context *ctx, struct vboot_region *fw_main)
+{
+ uint32_t expected_size;
+ MAYBE_STATIC uint8_t block[TODO_BLOCK_SIZE];
+ size_t block_size = sizeof(block);
+ uintptr_t offset;
+ int rv;
+
+ expected_size = fw_main->size;
+ offset = fw_main->offset_addr;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /* Extend over the body */
+ while (expected_size) {
+ void *b;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ b = vboot_get_region(offset, block_size, block);
+ if (b == NULL)
+ return VB2_ERROR_UNKNOWN;
+ rv = vb2api_extend_hash(ctx, b, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ /* Check the result */
+ rv = vb2api_check_hash(ctx);
+ if (rv)
+ return rv;
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct vboot_region *fw_main)
+{
+ if (is_slot_a(ctx))
+ vboot_locate_region("FW_MAIN_A", fw_main);
+ else
+ vboot_locate_region("FW_MAIN_B", fw_main);
+
+ if (fw_main->size < 0)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * Save non-volatile and/or secure data if needed.
+ */
+static void save_if_needed(struct vb2_context *ctx)
+{
+ if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving nvdata\n");
+ save_vbnv(ctx->nvdata);
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+ if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving secdata\n");
+ antirollback_write_space_firmware(ctx);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
+ }
+}
+
+/**
+ * Verify and select the firmware in the RW image
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
+#if CONFIG_RETURN_FROM_VERSTAGE
+void main(void)
+#else
+void verstage_main(void)
+#endif /* CONFIG_RETURN_FROM_VERSTAGE */
+{
+ struct vb2_context ctx;
+ struct vboot_region fw_main;
+ struct vb2_working_data *wd = vboot_get_working_data();
+ int rv;
+
+ /* Set up context and work buffer */
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = (uint8_t *)(uintptr_t)wd->buffer;
+ ctx.workbuf_size = wd->buffer_size;
+
+ /* Read nvdata from a non-volatile storage */
+ read_vbnv(ctx.nvdata);
+
+ /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
+ * check the return value here because vb2api_fw_phase1 will catch
+ * invalid secdata and tell us what to do (=reboot). */
+ antirollback_read_space_firmware(&ctx);
+
+ if (get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ }
+
+ /* Do early init */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ /* If we need recovery mode, leave firmware selection now */
+ save_if_needed(&ctx);
+ return;
+ }
+
+ /* Determine which firmware slot to boot */
+ printk(BIOS_INFO, "Phase 2\n");
+ rv = vb2api_fw_phase2(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Try that slot */
+ printk(BIOS_INFO, "Phase 3\n");
+ rv = vb2api_fw_phase3(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Phase 4\n");
+ rv = locate_firmware(&ctx, &fw_main);
+ if (rv)
+ die("Failed to read FMAP to locate firmware");
+
+ rv = hash_body(&ctx, &fw_main);
+ save_if_needed(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ vboot_reboot();
+ }
+
+ /* Lock TPM */
+ rv = antirollback_lock_space_firmware();
+ if (rv) {
+ printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
+ vb2_set_selected_region(wd, &fw_main);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.ld b/src/vendorcode/google/chromeos/vboot2/verstage.ld
new file mode 100644
index 0000000..c7fd646
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.ld
@@ -0,0 +1,58 @@
+/*
+ * 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
+ */
+
+/* This file is included inside a SECTIONS block */
+
+.text . : {
+ _program = .;
+ _verstage = .;
+ *(.text._start);
+ *(.text.stage_entry);
+ *(.text);
+ *(.text.*);
+} : to_load
+
+.data . : {
+ *(.rodata);
+ *(.rodata.*);
+ *(.data);
+ *(.data.*);
+ . = ALIGN(8);
+}
+
+.bss . : {
+ . = ALIGN(8);
+ _bss = .;
+ *(.bss)
+ *(.bss.*)
+ *(.sbss)
+ *(.sbss.*)
+ _ebss = .;
+ _everstage = .;
+ _eprogram = .;
+}
+
+/* Discard the sections we don't need/want */
+/DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.eh_frame);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstub.c b/src/vendorcode/google/chromeos/vboot2/verstub.c
new file mode 100644
index 0000000..e8faa07
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/verstub.c
@@ -0,0 +1,97 @@
+/*
+ * 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 "../chromeos.h"
+#include "misc.h"
+#include "symbols.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);
+ /* 8-byte alignment for ARMv7 */
+ wd->buffer = ALIGN_UP((uintptr_t)&wd[1], 8);
+ wd->buffer_size = _vboot2_work_size + (uintptr_t)wd
+ - (uintptr_t)wd->buffer;
+
+ 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 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();
+#endif /* CONFIG_RETURN_FROM_VERSTAGE */
+
+ /* jump to the selected slot */
+ entry = NULL;
+ if (vboot_is_slot_selected(wd)) {
+ /* RW A or B */
+ struct vboot_region fw_main;
+ struct vboot_components *fw_info;
+ 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");
+ 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");
+ }
+
+ if (entry != NULL && entry != (void *)-1)
+ stage_exit(entry);
+
+ die("failed to exit from stage\n");
+}
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
new file mode 100644
index 0000000..b2893d9
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot_common.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * 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 <stddef.h>
+#include <string.h>
+#include <boot/coreboot_tables.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include "chromeos.h"
+#include "vboot_common.h"
+
+void vboot_locate_region(const char *name, struct vboot_region *region)
+{
+ region->size = find_fmap_entry(name, (void **)®ion->offset_addr);
+}
+
+void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest)
+{
+ if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ if (dest != NULL)
+ return memcpy(dest, (void *)offset_addr, size);
+ else
+ return (void *)offset_addr;
+ } else {
+ struct cbfs_media default_media, *media = &default_media;
+ void *cache;
+
+ init_default_cbfs_media(media);
+ media->open(media);
+ if (dest != NULL) {
+ cache = dest;
+ if (media->read(media, dest, offset_addr, size) != size)
+ cache = NULL;
+ } else {
+ cache = media->map(media, offset_addr, size);
+ if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS)
+ cache = NULL;
+ }
+ media->close(media);
+ return cache;
+ }
+}
+
+int vboot_get_handoff_info(void **addr, uint32_t *size)
+{
+ struct vboot_handoff *vboot_handoff;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return -1;
+
+ *addr = vboot_handoff;
+ *size = sizeof(*vboot_handoff);
+ return 0;
+}
+
+/* This will leak a mapping of a fw region */
+struct vboot_components *vboot_locate_components(struct vboot_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_addr, req_size, NULL);
+ if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
+ vbc = NULL;
+
+ return vbc;
+}
+
+void *vboot_get_payload(int *len)
+{
+ struct vboot_handoff *vboot_handoff;
+ struct firmware_component *fwc;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return NULL;
+
+ if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid boot loader index: %d\n",
+ CONFIG_VBOOT_BOOT_LOADER_INDEX);
+ return NULL;
+ }
+
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX];
+
+ /* If payload size is zero fall back to cbfs path. */
+ if (fwc->size == 0)
+ return NULL;
+
+ if (len != NULL)
+ *len = fwc->size;
+
+ printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n",
+ fwc->size, fwc->address);
+
+ /* This will leak a mapping. */
+ return vboot_get_region(fwc->address, fwc->size, NULL);
+}
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
new file mode 100644
index 0000000..c6c9b50
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 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
+ */
+#ifndef VBOOT_COMMON_H
+#define VBOOT_COMMON_H
+
+#include <stdint.h>
+
+struct vboot_region {
+ uintptr_t offset_addr;
+ int32_t size;
+};
+
+/* The FW areas consist of multiple components. At the beginning of
+ * each area is the number of total compoments as well as the size and
+ * offset for each component. One needs to caculate the total size of the
+ * signed firmware region based off of the embedded metadata. */
+struct vboot_component_entry {
+ uint32_t offset;
+ uint32_t size;
+} __attribute__((packed));
+
+struct vboot_components {
+ uint32_t num_components;
+ struct vboot_component_entry entries[0];
+} __attribute__((packed));
+
+void vboot_locate_region(const char *name, struct vboot_region *region);
+
+struct vboot_components *vboot_locate_components(struct vboot_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(uintptr_t offset_addr, size_t size, void *dest);
+
+#endif /* VBOOT_COMMON_H */
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot_handoff.c
deleted file mode 100644
index f929a59..0000000
--- a/src/vendorcode/google/chromeos/vboot_handoff.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 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 <2recovery_reasons.h>
-#include <2struct.h>
-#include <arch/stages.h>
-#include <assert.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <stdlib.h>
-#include <timestamp.h>
-#include "chromeos.h"
-#include "fmap.h"
-#include "vboot_handoff.h"
-#include <vboot_struct.h>
-
-static void *load_ramstage(struct vboot_handoff *vboot_handoff,
- struct vboot_region *fw_main)
-{
- struct vboot_components *fw_info;
- 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;
- }
-
- return vboot_load_stage(CONFIG_VBOOT_RAMSTAGE_INDEX, fw_main, fw_info);
-}
-
-/**
- * Sets vboot_handoff based on the information in vb2_shared_data
- *
- * TODO: Read wp switch to set VBSD_BOOT_FIRMWARE_WP_ENABLED
- */
-static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
- struct vb2_shared_data *vb2_sd)
-{
- VbSharedDataHeader *vb_sd =
- (VbSharedDataHeader *)vboot_handoff->shared_data;
- uint32_t *oflags = &vboot_handoff->init_params.out_flags;
-
- vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
-
- vboot_handoff->selected_firmware = vb2_sd->fw_slot;
-
- vb_sd->firmware_index = vb2_sd->fw_slot;
-
- vb_sd->magic = VB_SHARED_DATA_MAGIC;
- vb_sd->struct_version = VB_SHARED_DATA_VERSION;
- vb_sd->struct_size = sizeof(VbSharedDataHeader);
- vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE;
- vb_sd->data_used = sizeof(VbSharedDataHeader);
-
- if (vb2_sd->recovery_reason) {
- vb_sd->firmware_index = 0xFF;
- if (vb2_sd->recovery_reason == VB2_RECOVERY_RO_MANUAL)
- vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
- *oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
- *oflags |= VB_INIT_OUT_CLEAR_RAM;
- *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
- *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
- }
- if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) {
- *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER;
- *oflags |= VB_INIT_OUT_CLEAR_RAM;
- *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
- *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
- vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
- vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
- }
- /* TODO: Set these in depthcharge */
- if (CONFIG_VIRTUAL_DEV_SWITCH)
- vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
- if (CONFIG_EC_SOFTWARE_SYNC) {
- vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
- vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
- }
- /* In vboot1, VBSD_FWB_TRIED is
- * set only if B is booted as explicitly requested. Therefore, if B is
- * booted because A was found bad, the flag should not be set. It's
- * better not to touch it if we can only ambiguously control it. */
- /* if (vb2_sd->fw_slot)
- vb_sd->flags |= VBSD_FWB_TRIED; */
-
- /* copy kernel subkey if it's found */
- if (vb2_sd->workbuf_preamble_size) {
- struct vb2_fw_preamble *fp;
- uintptr_t dst, src;
- printk(BIOS_INFO, "Copying FW preamble\n");
- fp = (struct vb2_fw_preamble *)( (uintptr_t)vb2_sd +
- vb2_sd->workbuf_preamble_offset);
- src = (uintptr_t)&fp->kernel_subkey +
- fp->kernel_subkey.key_offset;
- dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
- assert(dst + fp->kernel_subkey.key_size <=
- (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
- memcpy((void *)dst, (void *)src,
- fp->kernel_subkey.key_size);
- vb_sd->data_used += fp->kernel_subkey.key_size;
- vb_sd->kernel_subkey.key_offset =
- dst - (uintptr_t)&vb_sd->kernel_subkey;
- vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
- vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
- vb_sd->kernel_subkey.key_version =
- fp->kernel_subkey.key_version;
- }
-
- vb_sd->recovery_reason = vb2_sd->recovery_reason;
-}
-
-/**
- * Load ramstage and return the entry point
- */
-void *vboot_load_ramstage(void)
-{
- struct vboot_handoff *vh;
- struct vb2_shared_data *sd;
- struct vboot_region fw_main;
- struct vb2_working_data *wd = vboot_get_working_data();
-
- sd = (struct vb2_shared_data *)(uintptr_t)wd->buffer;
- sd->workbuf_hash_offset = 0;
- sd->workbuf_hash_size = 0;
-
- printk(BIOS_INFO, "creating vboot_handoff structure\n");
- vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
- if (vh == NULL)
- /* we don't need to failover gracefully here because this
- * shouldn't happen with the image that has passed QA. */
- die("failed to allocate vboot_handoff structure\n");
-
- memset(vh, 0, sizeof(*vh));
-
- /* 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;
-
- 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);
-}
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.h b/src/vendorcode/google/chromeos/vboot_handoff.h
index b001743..e6b2d69 100644
--- a/src/vendorcode/google/chromeos/vboot_handoff.h
+++ b/src/vendorcode/google/chromeos/vboot_handoff.h
@@ -19,9 +19,20 @@
#ifndef VBOOT_HANDOFF_H
#define VBOOT_HANDOFF_H
+
#include <vboot_api.h>
#include <vboot_struct.h>
#include "chromeos.h"
+#include "vboot_common.h"
+
+/*
+ * The vboot handoff structure keeps track of a maximum number of firmware
+ * components in the verfieid RW area of flash. This is not a restriction on
+ * the number of components packed in a firmware block. It's only the maximum
+ * number of parsed firmware components (address and size) included in the
+ * handoff structure.
+ */
+#define MAX_PARSED_FW_COMPONENTS 5
struct firmware_component {
uint32_t address;
diff --git a/src/vendorcode/google/chromeos/vboot_loader.c b/src/vendorcode/google/chromeos/vboot_loader.c
deleted file mode 100644
index d13608c..0000000
--- a/src/vendorcode/google/chromeos/vboot_loader.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 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 <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <program_loading.h>
-#include <tpm.h>
-#include <reset.h>
-#include <romstage_handoff.h>
-#include <rmodule.h>
-#include <string.h>
-#include <stdlib.h>
-#include <timestamp.h>
-#include "chromeos.h"
-#include "vboot_context.h"
-#include "vboot_handoff.h"
-
-#define TEMP_CBMEM_ID_VBOOT 0xffffffff
-#define TEMP_CBMEM_ID_VBLOCKS 0xfffffffe
-
-static void vboot_run_stub(struct vboot_context *context)
-{
- struct rmod_stage_load rmod_stage = {
- .cbmem_id = TEMP_CBMEM_ID_VBOOT,
- .name = CONFIG_CBFS_PREFIX "/vboot",
- };
- void (*entry)(struct vboot_context *context);
-
- if (rmodule_stage_load_from_cbfs(&rmod_stage)) {
- printk(BIOS_DEBUG, "Could not load vboot stub.\n");
- goto out;
- }
-
- entry = rmod_stage.entry;
-
- /* Call stub. */
- entry(context);
-
-out:
- /* Tear down the region no longer needed. */
- if (rmod_stage.cbmem_entry != NULL)
- cbmem_entry_remove(rmod_stage.cbmem_entry);
-}
-
-/* Helper routines for the vboot stub. */
-static void log_msg(const char *fmt, va_list args)
-{
- do_vtxprintf(fmt, args);
-}
-
-static void fatal_error(void)
-{
- printk(BIOS_ERR, "vboot encountered fatal error. Resetting.\n");
- hard_reset();
-}
-
-static int fw_region_size(struct vboot_region *r)
-{
- struct vboot_components *fw_info;
- int32_t size;
- int i;
-
- fw_info = vboot_locate_components(r);
- if (fw_info == NULL)
- return -1;
-
- if (fw_info->num_components > MAX_PARSED_FW_COMPONENTS)
- return -1;
-
- size = sizeof(*fw_info);
- size += sizeof(struct vboot_component_entry) * fw_info->num_components;
-
- for (i = 0; i < fw_info->num_components; i++)
- size += ALIGN(fw_info->entries[i].size, sizeof(uint32_t));
-
- /* Check that size of comopnents does not exceed the region's size. */
- if (size > r->size)
- return -1;
-
- /* Update region with the correct size. */
- r->size = size;
-
- return 0;
-}
-
-static int vboot_fill_params(struct vboot_context *ctx)
-{
- VbCommonParams *cparams;
- VbSelectFirmwareParams *fparams;
-
- if (fw_region_size(&ctx->fw_a))
- return -1;
-
- if (fw_region_size(&ctx->fw_b))
- return -1;
-
- cparams = ctx->cparams;
- fparams = ctx->fparams;
-
- cparams->gbb_size = ctx->gbb.size;
- fparams->verification_size_A = ctx->vblock_a.size;
- fparams->verification_size_B = ctx->vblock_b.size;
-
- if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- /* Get memory-mapped pointers to the regions. */
- cparams->gbb_data = vboot_get_region(ctx->gbb.offset_addr,
- ctx->gbb.size, NULL);
- fparams->verification_block_A =
- vboot_get_region(ctx->vblock_a.offset_addr,
- ctx->vblock_a.size, NULL);
- fparams->verification_block_B =
- vboot_get_region(ctx->vblock_b.offset_addr,
- ctx->vblock_b.size, NULL);
- } else {
- /*
- * Copy the vblock info into a buffer in cbmem. The gbb will
- * be read using VbExRegionRead().
- */
- char *dest;
- size_t vblck_sz;
-
- vblck_sz = ctx->vblock_a.size + ctx->vblock_b.size;
- ctx->vblocks = cbmem_entry_add(TEMP_CBMEM_ID_VBLOCKS, vblck_sz);
- if (ctx->vblocks == NULL)
- return -1;
- dest = cbmem_entry_start(ctx->vblocks);
- if (vboot_get_region(ctx->vblock_a.offset_addr,
- ctx->vblock_a.size, dest) == NULL)
- return -1;
- fparams->verification_block_A = (void *)dest;
- dest += ctx->vblock_a.size;
- if (vboot_get_region(ctx->vblock_b.offset_addr,
- ctx->vblock_b.size, dest) == NULL)
- return -1;
- fparams->verification_block_B = (void *)dest;
- }
-
- return 0;
-}
-
-static void fill_handoff(struct vboot_context *context)
-{
- struct vboot_components *fw_info;
- struct vboot_region *region;
- int i;
-
- /* Fix up the handoff structure. */
- context->handoff->selected_firmware =
- context->fparams->selected_firmware;
-
- /* Parse out the components for downstream consumption. */
- if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_A)
- region = &context->fw_a;
- else if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_B)
- region = &context->fw_b;
- else
- return;
-
- fw_info = vboot_locate_components(region);
- if (fw_info == NULL)
- return;
-
- for (i = 0; i < fw_info->num_components; i++) {
- context->handoff->components[i].address =
- region->offset_addr + fw_info->entries[i].offset;
- context->handoff->components[i].size = fw_info->entries[i].size;
- }
-}
-
-static void vboot_clean_up(struct vboot_context *context)
-{
- if (context->vblocks != NULL)
- cbmem_entry_remove(context->vblocks);
-}
-
-static void reset(void)
-{
- hard_reset();
-}
-
-static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
-{
- VbCommonParams cparams;
- VbSelectFirmwareParams fparams;
- struct vboot_context context;
- uint32_t *iflags;
-
- vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
-
- memset(&cparams, 0, sizeof(cparams));
- memset(&fparams, 0, sizeof(fparams));
- memset(&context, 0, sizeof(context));
-
- iflags = &vboot_handoff->init_params.flags;
- if (get_developer_mode_switch())
- *iflags |= VB_INIT_FLAG_DEV_SWITCH_ON;
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- *iflags |= VB_INIT_FLAG_REC_BUTTON_PRESSED;
- }
- if (get_write_protect_state())
- *iflags |= VB_INIT_FLAG_WP_ENABLED;
- if (vboot_get_sw_write_protect())
- *iflags |= VB_INIT_FLAG_SW_WP_ENABLED;
- if (CONFIG_VIRTUAL_DEV_SWITCH)
- *iflags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
- if (CONFIG_EC_SOFTWARE_SYNC) {
- *iflags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC;
- *iflags |= VB_INIT_FLAG_VIRTUAL_REC_SWITCH;
- }
- if (CONFIG_VBOOT_EC_SLOW_UPDATE)
- *iflags |= VB_INIT_FLAG_EC_SLOW_UPDATE;
- if (CONFIG_VBOOT_OPROM_MATTERS) {
- *iflags |= VB_INIT_FLAG_OPROM_MATTERS;
- /* Will load VGA option rom during this boot */
- if (developer_mode_enabled() || recovery_mode_enabled() ||
- vboot_wants_oprom()) {
- *iflags |= VB_INIT_FLAG_OPROM_LOADED;
- }
- }
-
- context.handoff = vboot_handoff;
- context.cparams = &cparams;
- context.fparams = &fparams;
-
- cparams.shared_data_blob = &vboot_handoff->shared_data[0];
- cparams.shared_data_size = VB_SHARED_DATA_MIN_SIZE;
- cparams.caller_context = &context;
-
- vboot_locate_region("GBB", &context.gbb);
- vboot_locate_region("VBLOCK_A", &context.vblock_a);
- vboot_locate_region("VBLOCK_B", &context.vblock_b);
- vboot_locate_region("FW_MAIN_A", &context.fw_a);
- vboot_locate_region("FW_MAIN_B", &context.fw_b);
-
- /* Check all fmap entries. */
- if (context.fw_a.size < 0 || context.fw_b.size < 0 ||
- context.vblock_a.size < 0 || context.vblock_b.size < 0 ||
- context.gbb.size < 0) {
- printk(BIOS_DEBUG, "Not all fmap entries found for vboot.\n");
- return;
- }
-
- /* Fill in vboot parameters. */
- if (vboot_fill_params(&context)) {
- vboot_clean_up(&context);
- return;
- }
-
- /* Initialize callbacks. */
- context.read_vbnv = &read_vbnv;
- context.save_vbnv = &save_vbnv;
- context.tis_init = &tis_init;
- context.tis_open = &tis_open;
- context.tis_close = &tis_close;
- context.tis_sendrecv = &tis_sendrecv;
- context.log_msg = &log_msg;
- context.fatal_error = &fatal_error;
- context.get_region = &vboot_get_region;
- context.reset = &reset;
-
- vboot_run_stub(&context);
-
- fill_handoff(&context);
-
- vboot_clean_up(&context);
-}
-
-#if CONFIG_RELOCATABLE_RAMSTAGE
-static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
- const struct cbmem_entry **cbmem_entry)
-{
- struct vboot_handoff *vboot_handoff;
- struct cbfs_stage *stage;
- const struct firmware_component *fwc;
- struct rmod_stage_load rmod_load = {
- .cbmem_id = cbmem_id,
- .name = name,
- };
-
- timestamp_add_now(TS_START_VBOOT);
-
- vboot_handoff = cbmem_add(CBMEM_ID_VBOOT_HANDOFF,
- sizeof(*vboot_handoff));
-
- if (vboot_handoff == NULL) {
- printk(BIOS_DEBUG, "Could not add vboot_handoff structure.\n");
- return NULL;
- }
-
- memset(vboot_handoff, 0, sizeof(*vboot_handoff));
-
- vboot_invoke_wrapper(vboot_handoff);
-
- timestamp_add_now(TS_END_VBOOT);
-
- /* Take RO firmware path since no RW area was selected. */
- if (vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_A &&
- vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_B) {
- printk(BIOS_DEBUG, "No RW firmware selected: 0x%08x\n",
- vboot_handoff->selected_firmware);
- return NULL;
- }
-
- if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid ramstage index: %d\n",
- CONFIG_VBOOT_RAMSTAGE_INDEX);
- return NULL;
- }
-
- /* Check for invalid address. */
- fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
- if (fwc->address == 0) {
- printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
- return NULL;
- }
-
- printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
- fwc->address, fwc->size);
-
- stage = (void *)fwc->address;
-
- if (rmodule_stage_load(&rmod_load, stage)) {
- vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
- printk(BIOS_DEBUG, "Could not load ramstage region.\n");
- return NULL;
- }
-
- *cbmem_entry = rmod_load.cbmem_entry;
-
- return rmod_load.entry;
-}
-#else /* CONFIG_RELOCATABLE_RAMSTAGE */
-static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
- struct romstage_handoff *handoff)
-{
- struct cbfs_stage *stage;
- const struct firmware_component *fwc;
-
- if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid ramstage index: %d\n",
- CONFIG_VBOOT_RAMSTAGE_INDEX);
- return;
- }
-
- /* Check for invalid address. */
- fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
- if (fwc->address == 0) {
- printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
- return;
- }
-
- printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
- fwc->address, fwc->size);
-
- /* This will leak a mapping. */
- stage = vboot_get_region(fwc->address, fwc->size, NULL);
-
- if (stage == NULL) {
- printk(BIOS_DEBUG, "Unable to get RW ramstage region.\n");
- return;
- }
-
- timestamp_add_now(TS_START_COPYRAM);
-
- /* Stages rely the below clearing so that the bss is initialized. */
- memset((void *) (uintptr_t) stage->load, 0, stage->memlen);
-
- if (cbfs_decompress(stage->compression,
- ((unsigned char *) stage) +
- sizeof(struct cbfs_stage),
- (void *) (uintptr_t) stage->load,
- stage->len))
- return;
-
- timestamp_add_now(TS_END_COPYRAM);
-
-#if CONFIG_ARCH_X86
- __asm__ volatile (
- "movl $0, %%ebp\n"
- "jmp *%%edi\n"
- :: "D"(stage->entry)
- );
-#elif CONFIG_ARCH_ARM
- stage_exit((void *)(uintptr_t)stage->entry);
-#endif
-}
-#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
-
-
-const struct ramstage_loader_ops vboot_ramstage_loader = {
- .name = "VBOOT",
- .load = vboot_load_ramstage,
-};
diff --git a/src/vendorcode/google/chromeos/vboot_wrapper.c b/src/vendorcode/google/chromeos/vboot_wrapper.c
deleted file mode 100644
index dd6065c..0000000
--- a/src/vendorcode/google/chromeos/vboot_wrapper.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 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 <console/vtxprintf.h>
-#if CONFIG_ARCH_X86
-#include <cpu/x86/tsc.h>
-#else
-#include <timer.h>
-#endif
-#include <rmodule.h>
-#include <stdlib.h>
-#include <string.h>
-#include "vboot_context.h"
-#include "vboot_handoff.h"
-
-/* Keep a global context pointer around for the callbacks to use. */
-static struct vboot_context *gcontext;
-
-static void vboot_wrapper(void *arg)
-{
- VbError_t res;
- struct vboot_context *context;
-
- context = arg;
- gcontext = context;
-
- VbExDebug("Calling VbInit()\n");
- res = VbInit(context->cparams, &context->handoff->init_params);
- VbExDebug("VbInit() returned 0x%08x\n", res);
-
- if (res != VBERROR_SUCCESS) {
- if(res == VBERROR_TPM_REBOOT_REQUIRED) {
- VbExDebug("TPM Reboot Required. Proceeding reboot.\n");
- gcontext->reset();
- }
- return;
- }
-
- VbExDebug("Calling VbSelectFirmware()\n");
- res = VbSelectFirmware(context->cparams, context->fparams);
- VbExDebug("VbSelectFirmware() returned 0x%08x\n", res);
-
- if (res != VBERROR_SUCCESS)
- return;
-}
-
-void VbExError(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- gcontext->log_msg(format, args);
- va_end(args);
-
- gcontext->fatal_error();
-}
-
-void VbExDebug(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- gcontext->log_msg(format, args);
- va_end(args);
-}
-
-uint64_t VbExGetTimer(void)
-{
-#if CONFIG_ARCH_X86
- return rdtscll();
-#else
- struct mono_time mt;
- timer_monotonic_get(&mt);
- return mt.microseconds;
-#endif
-}
-
-VbError_t VbExNvStorageRead(uint8_t *buf)
-{
- gcontext->read_vbnv(buf);
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExNvStorageWrite(const uint8_t *buf)
-{
- gcontext->save_vbnv(buf);
- return VBERROR_SUCCESS;
-}
-
-extern char _heap[];
-extern char _eheap[];
-static char *heap_current;
-static int heap_size;
-
-void *VbExMalloc(size_t size)
-{
- void *ptr;
-
- if (heap_current == NULL) {
- heap_current = &_heap[0];
- heap_size = &_eheap[0] - &_heap[0];
- VbExDebug("vboot heap: %p 0x%08x bytes\n",
- heap_current, heap_size);
- }
-
- if (heap_size < size) {
- VbExError("vboot heap request cannot be fulfilled. "
- "0x%08x available, 0x%08x requested\n",
- heap_size, size);
- }
-
- ptr = heap_current;
- heap_size -= size;
- heap_current += size;
-
- return ptr;
-}
-
-void VbExFree(void *ptr)
-{
- /* Leak all memory. */
-}
-
-/* vboot doesn't expose these through the vboot_api.h, but they are needed.
- * coreboot requires declarations so provide them to avoid compiler errors. */
-int Memcmp(const void *src1, const void *src2, size_t n);
-void *Memcpy(void *dest, const void *src, uint64_t n);
-void *Memset(void *dest, const uint8_t c, uint64_t n);
-
-int Memcmp(const void *src1, const void *src2, size_t n)
-{
- return memcmp(src1, src2, n);
-}
-
-void *Memcpy(void *dest, const void *src, uint64_t n)
-{
- return memcpy(dest, src, n);
-}
-
-void *Memset(void *dest, const uint8_t c, uint64_t n)
-{
- return memset(dest, c, n);
-}
-
-static inline size_t get_hash_block_size(size_t requested_size)
-{
- if (!IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- const size_t block_size = 64 * 1024;
- if (requested_size > block_size)
- return block_size;
- }
- return requested_size;
-}
-
-VbError_t VbExHashFirmwareBody(VbCommonParams *cparams, uint32_t firmware_index)
-{
- uint8_t *data;
- struct vboot_region *region;
- struct vboot_context *ctx;
- size_t data_size;
- uintptr_t offset_addr;
-
- ctx = cparams->caller_context;
-
- switch (firmware_index) {
- case VB_SELECT_FIRMWARE_A:
- region = &ctx->fw_a;
- break;
- case VB_SELECT_FIRMWARE_B:
- region = &ctx->fw_b;
- break;
- default:
- return VBERROR_UNKNOWN;
- }
-
- data_size = region->size;
- offset_addr = region->offset_addr;
- while (data_size) {
- size_t block_size;
-
- block_size = get_hash_block_size(data_size);
- data = ctx->get_region(offset_addr, block_size, NULL);
- if (data == NULL)
- return VBERROR_UNKNOWN;
- VbUpdateFirmwareBodyHash(cparams, data, block_size);
-
- data_size -= block_size;
- offset_addr += block_size;
- }
-
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExTpmInit(void)
-{
- if (gcontext->tis_init())
- return VBERROR_UNKNOWN;
- return VbExTpmOpen();
-}
-
-VbError_t VbExTpmClose(void)
-{
- if (gcontext->tis_close())
- return VBERROR_UNKNOWN;
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExTpmOpen(void)
-{
- if (gcontext->tis_open())
- return VBERROR_UNKNOWN;
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length,
- uint8_t *response, uint32_t *response_length)
-{
- size_t len = *response_length;
- if (gcontext->tis_sendrecv(request, request_length, response, &len))
- return VBERROR_UNKNOWN;
- /* check 64->32bit overflow and (re)check response buffer overflow */
- if (len > *response_length)
- return VBERROR_UNKNOWN;
- *response_length = len;
- return VBERROR_SUCCESS;
-}
-
-#if !CONFIG_SPI_FLASH_MEMORY_MAPPED
-VbError_t VbExRegionRead(VbCommonParams *cparams,
- enum vb_firmware_region region, uint32_t offset,
- uint32_t size, void *buf)
-{
- struct vboot_context *ctx;
- VbExDebug("VbExRegionRead: offset=%x size=%x, buf=%p\n",
- offset, size, buf);
- ctx = cparams->caller_context;
-
- if (region == VB_REGION_GBB) {
- if (offset + size > cparams->gbb_size)
- return VBERROR_REGION_READ_INVALID;
- offset += ctx->gbb.offset_addr;
- if (ctx->get_region(offset, size, buf) == NULL)
- return VBERROR_REGION_READ_INVALID;
- return VBERROR_SUCCESS;
- }
-
- return VBERROR_UNSUPPORTED_REGION;
-}
-#endif /* CONFIG_SPI_FLASH_MEMORY_MAPPED */
-
-RMODULE_ENTRY(vboot_wrapper);
diff --git a/src/vendorcode/google/chromeos/verstage.c b/src/vendorcode/google/chromeos/verstage.c
deleted file mode 100644
index 1b42bb6..0000000
--- a/src/vendorcode/google/chromeos/verstage.c
+++ /dev/null
@@ -1,251 +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 <2api.h>
-#include <2struct.h>
-#include <antirollback.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <string.h>
-
-#include "chromeos.h"
-
-#define TODO_BLOCK_SIZE 1024
-
-static int is_slot_a(struct vb2_context *ctx)
-{
- return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
-}
-
-/* exports */
-
-void vb2ex_printf(const char *func, const char *fmt, ...)
-{
- va_list args;
-
- printk(BIOS_INFO, "VB2:%s() ", func);
- va_start(args, fmt);
- vprintk(BIOS_INFO, fmt, args);
- va_end(args);
-
- return;
-}
-
-int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
-{
- uint32_t rv;
- printk(BIOS_INFO, "Clearing TPM owner\n");
- rv = tpm_clear_and_reenable();
- if (rv)
- return VB2_ERROR_EX_TPM_CLEAR_OWNER;
- return VB2_SUCCESS;
-}
-
-int vb2ex_read_resource(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- void *buf,
- uint32_t size)
-{
- struct vboot_region region;
-
- switch (index) {
- case VB2_RES_GBB:
- vboot_locate_region("GBB", ®ion);
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- vboot_locate_region("VBLOCK_A", ®ion);
- else
- vboot_locate_region("VBLOCK_B", ®ion);
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (offset + size > region.size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (vboot_get_region(region.offset_addr + offset, size, buf) == NULL)
- return VB2_ERROR_UNKNOWN;
-
- return VB2_SUCCESS;
-}
-
-static int hash_body(struct vb2_context *ctx, struct vboot_region *fw_main)
-{
- uint32_t expected_size;
- MAYBE_STATIC uint8_t block[TODO_BLOCK_SIZE];
- size_t block_size = sizeof(block);
- uintptr_t offset;
- int rv;
-
- expected_size = fw_main->size;
- offset = fw_main->offset_addr;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /* Extend over the body */
- while (expected_size) {
- void *b;
- if (block_size > expected_size)
- block_size = expected_size;
-
- b = vboot_get_region(offset, block_size, block);
- if (b == NULL)
- return VB2_ERROR_UNKNOWN;
- rv = vb2api_extend_hash(ctx, b, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- /* Check the result */
- rv = vb2api_check_hash(ctx);
- if (rv)
- return rv;
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct vboot_region *fw_main)
-{
- if (is_slot_a(ctx))
- vboot_locate_region("FW_MAIN_A", fw_main);
- else
- vboot_locate_region("FW_MAIN_B", fw_main);
-
- if (fw_main->size < 0)
- return 1;
-
- return 0;
-}
-
-/**
- * Save non-volatile and/or secure data if needed.
- */
-static void save_if_needed(struct vb2_context *ctx)
-{
- if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
- printk(BIOS_INFO, "Saving nvdata\n");
- save_vbnv(ctx->nvdata);
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- }
- if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
- printk(BIOS_INFO, "Saving secdata\n");
- antirollback_write_space_firmware(ctx);
- ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
- }
-}
-
-/**
- * Verify and select the firmware in the RW image
- *
- * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
- * when per-stage verification is ready.
- */
-#if CONFIG_RETURN_FROM_VERSTAGE
-void main(void)
-#else
-void verstage_main(void)
-#endif /* CONFIG_RETURN_FROM_VERSTAGE */
-{
- struct vb2_context ctx;
- struct vboot_region fw_main;
- struct vb2_working_data *wd = vboot_get_working_data();
- int rv;
-
- /* Set up context and work buffer */
- memset(&ctx, 0, sizeof(ctx));
- ctx.workbuf = (uint8_t *)(uintptr_t)wd->buffer;
- ctx.workbuf_size = wd->buffer_size;
-
- /* Read nvdata from a non-volatile storage */
- read_vbnv(ctx.nvdata);
-
- /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
- * check the return value here because vb2api_fw_phase1 will catch
- * invalid secdata and tell us what to do (=reboot). */
- antirollback_read_space_firmware(&ctx);
-
- if (get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- }
-
- /* Do early init */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- /* If we need recovery mode, leave firmware selection now */
- save_if_needed(&ctx);
- return;
- }
-
- /* Determine which firmware slot to boot */
- printk(BIOS_INFO, "Phase 2\n");
- rv = vb2api_fw_phase2(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Try that slot */
- printk(BIOS_INFO, "Phase 3\n");
- rv = vb2api_fw_phase3(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Phase 4\n");
- rv = locate_firmware(&ctx, &fw_main);
- if (rv)
- die("Failed to read FMAP to locate firmware");
-
- rv = hash_body(&ctx, &fw_main);
- save_if_needed(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- vboot_reboot();
- }
-
- /* Lock TPM */
- rv = antirollback_lock_space_firmware();
- if (rv) {
- printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
- vb2_set_selected_region(wd, &fw_main);
-}
diff --git a/src/vendorcode/google/chromeos/verstage.ld b/src/vendorcode/google/chromeos/verstage.ld
deleted file mode 100644
index c7fd646..0000000
--- a/src/vendorcode/google/chromeos/verstage.ld
+++ /dev/null
@@ -1,58 +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
- */
-
-/* This file is included inside a SECTIONS block */
-
-.text . : {
- _program = .;
- _verstage = .;
- *(.text._start);
- *(.text.stage_entry);
- *(.text);
- *(.text.*);
-} : to_load
-
-.data . : {
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- . = ALIGN(8);
-}
-
-.bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- _everstage = .;
- _eprogram = .;
-}
-
-/* Discard the sections we don't need/want */
-/DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
-}
diff --git a/src/vendorcode/google/chromeos/verstub.c b/src/vendorcode/google/chromeos/verstub.c
deleted file mode 100644
index eb91c22..0000000
--- a/src/vendorcode/google/chromeos/verstub.c
+++ /dev/null
@@ -1,96 +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 "chromeos.h"
-#include "symbols.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);
- /* 8-byte alignment for ARMv7 */
- wd->buffer = ALIGN_UP((uintptr_t)&wd[1], 8);
- wd->buffer_size = _vboot2_work_size + (uintptr_t)wd
- - (uintptr_t)wd->buffer;
-
- 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 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();
-#endif /* CONFIG_RETURN_FROM_VERSTAGE */
-
- /* jump to the selected slot */
- entry = NULL;
- if (vboot_is_slot_selected(wd)) {
- /* RW A or B */
- struct vboot_region fw_main;
- struct vboot_components *fw_info;
- 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");
- 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");
- }
-
- if (entry != NULL && entry != (void *)-1)
- stage_exit(entry);
-
- die("failed to exit from stage\n");
-}
More information about the coreboot-gerrit
mailing list