[coreboot-gerrit] Patch set updated for coreboot: vboot: Separate vboot from chromeos
Furquan Shaikh (furquan@google.com)
gerrit at coreboot.org
Tue Jul 26 02:32:28 CEST 2016
Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15867
-gerrit
commit 985d684ce743d48bb2aebf13db163586b4bf2b7d
Author: Furquan Shaikh <furquan at google.com>
Date: Mon Jul 25 11:48:03 2016 -0700
vboot: Separate vboot from chromeos
VBOOT_VERIFY_FIRMWARE should be independent of CHROMEOS. This allows use
of verified boot library without having to stick to CHROMEOS.
BUG=chrome-os-partner:44531
Change-Id: Ia2c328712caedd230ab295b8a613e3c1ed1532d9
Signed-off-by: Furquan Shaikh <furquan at google.com>
---
src/mainboard/google/rush_ryu/mainboard.c | 4 +-
src/soc/intel/apollolake/pmutil.c | 2 +-
src/soc/intel/skylake/romstage/power_state.c | 2 +-
src/vendorcode/google/Kconfig | 2 +-
src/vendorcode/google/Makefile.inc | 1 +
src/vendorcode/google/chromeos/Kconfig | 22 --
src/vendorcode/google/chromeos/Makefile.inc | 2 -
src/vendorcode/google/chromeos/chromeos.h | 5 +-
src/vendorcode/google/chromeos/elog.c | 2 +-
src/vendorcode/google/chromeos/gnvs.c | 2 +-
src/vendorcode/google/chromeos/symbols.h | 9 -
src/vendorcode/google/chromeos/vboot2/Kconfig | 89 -----
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 118 ------
.../google/chromeos/vboot2/antirollback.c | 436 ---------------------
src/vendorcode/google/chromeos/vboot2/common.c | 183 ---------
src/vendorcode/google/chromeos/vboot2/misc.h | 40 --
src/vendorcode/google/chromeos/vboot2/recovery.c | 154 --------
.../google/chromeos/vboot2/secdata_mock.c | 38 --
.../google/chromeos/vboot2/vboot_handoff.c | 179 ---------
.../google/chromeos/vboot2/vboot_loader.c | 159 --------
.../google/chromeos/vboot2/vboot_logic.c | 415 --------------------
src/vendorcode/google/chromeos/vboot2/verstage.c | 44 ---
src/vendorcode/google/chromeos/vboot_common.c | 112 ------
src/vendorcode/google/chromeos/vboot_common.h | 106 -----
src/vendorcode/google/vboot2/Kconfig | 110 ++++++
src/vendorcode/google/vboot2/Makefile.inc | 118 ++++++
src/vendorcode/google/vboot2/antirollback.c | 436 +++++++++++++++++++++
src/vendorcode/google/vboot2/common.c | 182 +++++++++
src/vendorcode/google/vboot2/misc.h | 40 ++
src/vendorcode/google/vboot2/recovery.c | 157 ++++++++
src/vendorcode/google/vboot2/secdata_mock.c | 38 ++
src/vendorcode/google/vboot2/symbols.h | 28 ++
src/vendorcode/google/vboot2/vboot_common.c | 111 ++++++
src/vendorcode/google/vboot2/vboot_common.h | 104 +++++
src/vendorcode/google/vboot2/vboot_handoff.c | 184 +++++++++
src/vendorcode/google/vboot2/vboot_loader.c | 160 ++++++++
src/vendorcode/google/vboot2/vboot_logic.c | 418 ++++++++++++++++++++
src/vendorcode/google/vboot2/verstage.c | 44 +++
38 files changed, 2141 insertions(+), 2115 deletions(-)
diff --git a/src/mainboard/google/rush_ryu/mainboard.c b/src/mainboard/google/rush_ryu/mainboard.c
index 85034b3..28e2d99 100644
--- a/src/mainboard/google/rush_ryu/mainboard.c
+++ b/src/mainboard/google/rush_ryu/mainboard.c
@@ -35,8 +35,8 @@
#include <vendorcode/google/chromeos/cros_vpd.h>
#if IS_ENABLED(CONFIG_CHROMEOS)
#include <vboot_struct.h>
-#include <vendorcode/google/chromeos/vboot2/misc.h>
-#include <vendorcode/google/chromeos/vboot_common.h>
+#include <vendorcode/google/vboot2/misc.h>
+#include <vendorcode/google/vboot2/vboot_common.h>
#endif
#include "gpio.h"
diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c
index e23feb2..daf53c5 100644
--- a/src/soc/intel/apollolake/pmutil.c
+++ b/src/soc/intel/apollolake/pmutil.c
@@ -27,7 +27,7 @@
#include <soc/pm.h>
#include <device/device.h>
#include <device/pci.h>
-#include <vendorcode/google/chromeos/vboot_common.h>
+#include <vendorcode/google/vboot2/vboot_common.h>
static uintptr_t read_pmc_mmio_bar(void)
{
diff --git a/src/soc/intel/skylake/romstage/power_state.c b/src/soc/intel/skylake/romstage/power_state.c
index 209beeb..d8f8f93 100644
--- a/src/soc/intel/skylake/romstage/power_state.c
+++ b/src/soc/intel/skylake/romstage/power_state.c
@@ -30,7 +30,7 @@
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/romstage.h>
-#include <vendorcode/google/chromeos/vboot_common.h>
+#include <vendorcode/google/vboot2/vboot_common.h>
static struct chipset_power_state power_state CAR_GLOBAL;
diff --git a/src/vendorcode/google/Kconfig b/src/vendorcode/google/Kconfig
index 74c573a..1adbaab 100644
--- a/src/vendorcode/google/Kconfig
+++ b/src/vendorcode/google/Kconfig
@@ -13,4 +13,4 @@
##
source src/vendorcode/google/chromeos/Kconfig
-
+source src/vendorcode/google/vboot2/Kconfig
diff --git a/src/vendorcode/google/Makefile.inc b/src/vendorcode/google/Makefile.inc
index 6e950a1..99948e0 100644
--- a/src/vendorcode/google/Makefile.inc
+++ b/src/vendorcode/google/Makefile.inc
@@ -14,3 +14,4 @@
##
subdirs-$(CONFIG_CHROMEOS) += chromeos
+subdirs-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot2
\ No newline at end of file
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index f97a4e1..3809bb8 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -111,18 +111,6 @@ config VBOOT_EC_SLOW_UPDATE
Whether the EC (or PD) is slow to update and needs to display a
screen that informs the user the update is happening.
-config VBOOT_OPROM_MATTERS
- bool "Video option ROM matters (= can skip display init)"
- default n
- depends on VBOOT_VERIFY_FIRMWARE
- help
- Set this option to indicate to vboot that this platform will skip its
- display initialization on a normal (non-recovery, non-developer) boot.
- Vboot calls this "oprom matters" because on x86 devices this
- traditionally meant that the video option ROM will not be loaded, but
- it works functionally the same for other platforms that can skip their
- native display initialization code instead.
-
config VIRTUAL_DEV_SWITCH
bool "Virtual developer switch support"
default n
@@ -130,14 +118,6 @@ config VIRTUAL_DEV_SWITCH
help
Whether this platform has a virtual developer switch.
-config VBOOT_VERIFY_FIRMWARE
- bool "Verify firmware with vboot."
- default n
- depends on HAVE_HARD_RESET
- help
- Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the components
- of the firmware (stages, payload, etc).
-
config NO_TPM_RESUME
bool
default n
@@ -172,8 +152,6 @@ config HAVE_REGULATORY_DOMAIN
help
This option is needed to add ACPI regulatory domain methods
-source src/vendorcode/google/chromeos/vboot2/Kconfig
-
menu "GBB configuration"
config GBB_HWID
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index 18ce13e..590818f 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -60,8 +60,6 @@ else
CFLAGS_common += -DMOCK_TPM=0
endif
-subdirs-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot2
-
CONFIG_GBB_HWID := $(call strip_quotes,$(CONFIG_GBB_HWID))
CONFIG_GBB_BMPFV_FILE := $(call strip_quotes,$(CONFIG_GBB_BMPFV_FILE))
CONFIG_VBOOT_KEYBLOCK := $(call strip_quotes,$(CONFIG_VBOOT_KEYBLOCK))
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index ad9ef2f..04929d2 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -20,9 +20,10 @@
#include <stdint.h>
#include <bootmode.h>
#include <rules.h>
+#include <vendorcode/google/vboot2/misc.h>
+#include <vendorcode/google/vboot2/vboot_common.h>
+
#include "vbnv.h"
-#include "vboot_common.h"
-#include "vboot2/misc.h"
void save_chromeos_gpios(void);
diff --git a/src/vendorcode/google/chromeos/elog.c b/src/vendorcode/google/chromeos/elog.c
index 710d6f6..bd207dc 100644
--- a/src/vendorcode/google/chromeos/elog.c
+++ b/src/vendorcode/google/chromeos/elog.c
@@ -18,7 +18,7 @@
#include <elog.h>
#include <vendorcode/google/chromeos/chromeos.h>
#if CONFIG_VBOOT_VERIFY_FIRMWARE
-#include "vboot_common.h"
+#include <vendorcode/google/vboot2/vboot_common.h>
#include <vboot_struct.h>
#endif
diff --git a/src/vendorcode/google/chromeos/gnvs.c b/src/vendorcode/google/chromeos/gnvs.c
index 48668e8..c7dfecc 100644
--- a/src/vendorcode/google/chromeos/gnvs.c
+++ b/src/vendorcode/google/chromeos/gnvs.c
@@ -24,7 +24,7 @@
#include "chromeos.h"
#include "gnvs.h"
#if CONFIG_VBOOT_VERIFY_FIRMWARE
-#include "vboot_common.h"
+#include <vendorcode/google/vboot2/vboot_common.h>
#include <vboot_struct.h>
#endif
diff --git a/src/vendorcode/google/chromeos/symbols.h b/src/vendorcode/google/chromeos/symbols.h
index 78b28e2..d8e1ead 100644
--- a/src/vendorcode/google/chromeos/symbols.h
+++ b/src/vendorcode/google/chromeos/symbols.h
@@ -16,15 +16,6 @@
#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)
-
extern u8 _watchdog_tombstone[];
extern u8 _ewatchdog_tombstone[];
#define _watchdog_tombstone_size (_ewatchdog_tombstone - _watchdog_tombstone)
diff --git a/src/vendorcode/google/chromeos/vboot2/Kconfig b/src/vendorcode/google/chromeos/vboot2/Kconfig
deleted file mode 100644
index 5aaf932..0000000
--- a/src/vendorcode/google/chromeos/vboot2/Kconfig
+++ /dev/null
@@ -1,89 +0,0 @@
-## 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.
-##
-
-config VBOOT_STARTS_IN_BOOTBLOCK
- bool "Vboot starts verifying in bootblock"
- default n
- depends on VBOOT_VERIFY_FIRMWARE
- help
- Firmware verification happens during or at the end of bootblock.
-
-config VBOOT_STARTS_IN_ROMSTAGE
- bool "Vboot starts verifying in romstage"
- default n
- depends on VBOOT_VERIFY_FIRMWARE && !VBOOT_STARTS_IN_BOOTBLOCK
- help
- Firmware verification happens during or at the end of romstage.
-
-config VBOOT2_MOCK_SECDATA
- bool "Mock secdata for firmware verification"
- default n
- depends on VBOOT_VERIFY_FIRMWARE
- help
- Enabling VBOOT2_MOCK_SECDATA will mock secdata for the firmware
- verification to avoid access to a secdata storage (typically TPM).
- All operations for a secdata storage will be successful. This option
- can be used during development when a TPM is not present or broken.
- THIS SHOULD NOT BE LEFT ON FOR PRODUCTION DEVICES.
-
-config VBOOT_DISABLE_DEV_ON_RECOVERY
- bool "Disable dev mode on recovery requests"
- default n
- depends on VBOOT_VERIFY_FIRMWARE
- help
- When this option is enabled, the Chrome OS device leaves the
- developer mode as soon as recovery request is detected. This is
- handy on embedded devices with limited input capabilities.
-
-config SEPARATE_VERSTAGE
- bool "Vboot verification is built into a separate stage"
- default n
- depends on VBOOT_VERIFY_FIRMWARE
-
-config RETURN_FROM_VERSTAGE
- bool "The separate verification stage returns to its caller"
- default n
- depends on SEPARATE_VERSTAGE
- help
- If this is set, the verstage returns back to the calling stage instead
- of exiting to the succeeding stage so that the verstage space can be
- reused by the succeeding stage. This is useful if a ram space is too
- small to fit both the verstage and the succeeding stage.
-
-config CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL
- bool "The chipset provides the main() entry point for verstage"
- default n
- depends on SEPARATE_VERSTAGE
- help
- The chipset code provides their own main() entry point.
-
-config VBOOT_DYNAMIC_WORK_BUFFER
- bool "Vboot's work buffer is dynamically allocated."
- default y if ARCH_ROMSTAGE_X86_32 && !SEPARATE_VERSTAGE
- default n
- depends on VBOOT_VERIFY_FIRMWARE
- help
- This option is used when there isn't enough pre-main memory
- ram to allocate the vboot work buffer. That means vboot verification
- is after memory init and requires main memory to back the work
- buffer.
-
-config VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT
- bool
- default n
- depends on VBOOT_VERIFY_FIRMWARE
- help
- This option ensures that the recovery request is not lost because of
- reboots caused after vboot verification is run. e.g. reboots caused by
- FSP components on Intel platforms.
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
deleted file mode 100644
index 31889e2..0000000
--- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc
+++ /dev/null
@@ -1,118 +0,0 @@
-##
-## 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.
-##
-
-libverstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
-verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
-
-bootblock-y += vboot_loader.c
-romstage-y += vboot_loader.c
-ramstage-y += vboot_loader.c
-verstage-y += vboot_loader.c
-postcar-y += vboot_loader.c
-
-bootblock-y += ../vboot_common.c
-verstage-y += ../vboot_common.c
-romstage-y += ../vboot_common.c
-ramstage-y += ../vboot_common.c
-postcar-y += ../vboot_common.c
-
-bootblock-y += recovery.c
-romstage-y += recovery.c
-ramstage-y += recovery.c
-verstage-y += recovery.c
-postcar-y += recovery.c
-
-bootblock-y += common.c
-libverstage-y += vboot_logic.c
-verstage-y += common.c
-verstage-y += verstage.c
-ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y)
-libverstage-y += secdata_mock.c
-else
-libverstage-y += antirollback.c
-endif
-romstage-y += vboot_handoff.c common.c
-
-ramstage-y += common.c
-postcar-y += common.c
-
-ifeq ($(CONFIG_SEPARATE_VERSTAGE),y)
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-verstage-y))
-else
-ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y)
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-bootblock-y))
-else
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y))
-endif
-endif # CONFIG_SEPARATE_VERSTAGE
-
-VB2_LIB = $(obj)/external/vboot_reference/vboot_fw20.a
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%, $(filter-out -I$(obj), $(filter-out -include $(src)/include/kconfig.h, $(CPPFLAGS_libverstage))))
-VBOOT_CFLAGS += $(CFLAGS_libverstage)
-VBOOT_CFLAGS += $(libverstage-c-ccopts)
-VBOOT_CFLAGS += -I$(abspath $(obj)) -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=$(abspath $(dir $(VB2_LIB))) \
- V=$(V) \
- fwlib20
-
-libverstage-srcs += $(VB2_LIB)
-
-ifeq ($(CONFIG_SEPARATE_VERSTAGE),y)
-cbfs-files-$(CONFIG_SEPARATE_VERSTAGE) += $(CONFIG_CBFS_PREFIX)/verstage
-$(CONFIG_CBFS_PREFIX)/verstage-file := $(objcbfs)/verstage.elf
-$(CONFIG_CBFS_PREFIX)/verstage-type := stage
-$(CONFIG_CBFS_PREFIX)/verstage-compression := $(CBFS_PRERAM_COMPRESS_FLAG)
-
-ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)
-$(CONFIG_CBFS_PREFIX)/verstage-options := -a 64 -S ".car.data"
-
-# If CAR does not support execution of code, verstage on x86 is expected to be
-# xip.
-ifneq ($(CONFIG_NO_XIP_EARLY_STAGES),y)
-$(CONFIG_CBFS_PREFIX)/verstage-options += --xip
-endif
-
-endif
-
-else
-ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y)
-bootblock-srcs += $(objgenerated)/libverstage.a
-else
-romstage-srcs += $(objgenerated)/libverstage.a
-endif
-endif # CONFIG_SEPARATE_VERSTAGE
-
-# Define a list of files that need to be in RO only.
-# All other files will be installed into RO and RW regions
-# Use $(sort) to cut down on extra spaces that would be translated to commas
-regions-for-file = $(subst $(spc),$(comma),$(sort \
- $(if $(filter \
- $(if $(filter y,$(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)),, \
- %/romstage) \
- mts \
- %/verstage \
- locales \
- locale_%.bin \
- font.bin \
- vbgfx.bin \
- ,$(1)),COREBOOT,COREBOOT FW_MAIN_A FW_MAIN_B)))
diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
deleted file mode 100644
index a51e5d6..0000000
--- a/src/vendorcode/google/chromeos/vboot2/antirollback.c
+++ /dev/null
@@ -1,436 +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 <antirollback.h>
-#include <stdlib.h>
-#include <string.h>
-#include <tpm_lite/tlcl.h>
-#include <vb2_api.h>
-#include <console/console.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)
-
-
-static uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
-
-uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
- enum vb2_pcr_digest which_digest)
-{
- uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
- uint32_t size = sizeof(buffer);
- int rv;
-
- rv = vb2api_get_pcr_digest(ctx, which_digest, buffer, &size);
- if (rv != VB2_SUCCESS)
- return rv;
- if (size < TPM_PCR_DIGEST)
- return VB2_ERROR_UNKNOWN;
-
- return tlcl_extend(pcr, buffer, NULL);
-}
-
-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;
-}
-
-/*
- * 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,
-};
-
-#if IS_ENABLED(CONFIG_TPM2)
-
-/* Nothing special in the TPM2 path yet. */
-static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
- return tlcl_write(index, data, length);
-}
-
-static uint32_t set_firmware_space(const void *firmware_blob)
-{
- RETURN_ON_FAILURE(tlcl_define_space(FIRMWARE_NV_INDEX,
- VB2_SECDATA_SIZE));
- RETURN_ON_FAILURE(safe_write(FIRMWARE_NV_INDEX, firmware_blob,
- VB2_SECDATA_SIZE));
- return TPM_SUCCESS;
-}
-
-static uint32_t set_kernel_space(const void *kernel_blob)
-{
- RETURN_ON_FAILURE(tlcl_define_space(KERNEL_NV_INDEX,
- sizeof(secdata_kernel)));
- RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX, kernel_blob,
- sizeof(secdata_kernel)));
- return TPM_SUCCESS;
-}
-
-static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
-{
- RETURN_ON_FAILURE(tlcl_force_clear());
- RETURN_ON_FAILURE(set_firmware_space(ctx->secdata));
- RETURN_ON_FAILURE(set_kernel_space(secdata_kernel));
- return TPM_SUCCESS;
-}
-
-uint32_t tpm_clear_and_reenable(void)
-{
- VBDEBUG("TPM: Clear and re-enable\n");
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_lock_space_firmware(void)
-{
- return tlcl_lock_nv_write(FIRMWARE_NV_INDEX);
-}
-
-#else
-
-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;
-}
-
-/**
- * Like tlcl_write(), but checks for write errors due to hitting the 64-write
- * limit and clears the TPM when that happens. This can only happen when the
- * TPM is unowned, so it is OK to clear it (and we really have no choice).
- * This is not expected to happen frequently, but it could happen.
- */
-
-static 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;
- }
-}
-
-/**
- * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
- * we hit the TPM write limit. This is even less likely to happen than with
- * writes because we only define spaces once at initialization, but we'd
- * rather be paranoid about this.
- */
-static 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 _factory_initialize_tpm(struct vb2_context *ctx)
-{
- TPM_PERMANENT_FLAGS pflags;
- uint32_t 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));
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_lock_space_firmware(void)
-{
- return tlcl_set_global_lock();
-}
-#endif
-
-uint32_t factory_initialize_tpm(struct vb2_context *ctx)
-{
- uint32_t result;
-
- /* Defines and sets vb2 secdata space */
- vb2api_secdata_create(ctx);
-
- 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 = _factory_initialize_tpm(ctx);
- if (result != TPM_SUCCESS)
- return result;
-
- 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());
-
- /* Handle special init for S3 resume path */
- if (ctx->flags & VB2_CONTEXT_S3_RESUME) {
- result = tlcl_resume();
- if (result == TPM_E_INVALID_POSTINIT)
- printk(BIOS_DEBUG, "TPM: Already initialized.\n");
- return TPM_SUCCESS;
- }
-
-#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);
- ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
- 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");
- ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
- 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);
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c
deleted file mode 100644
index 58ea95d..0000000
--- a/src/vendorcode/google/chromeos/vboot2/common.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.
- */
-
-#include <assert.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <reset.h>
-#include <string.h>
-#include <vb2_api.h>
-#include "../chromeos.h"
-#include "../symbols.h"
-#include "../vboot_common.h"
-#include "misc.h"
-
-struct selected_region {
- uint32_t offset;
- uint32_t size;
-};
-
-/*
- * this is placed at the start of the vboot work buffer. selected_region is used
- * for the verstage to return the location of the selected slot. buffer is used
- * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
- * stage boundaries.
- */
-struct vb2_working_data {
- struct selected_region selected_region;
- /* offset of the buffer from the start of this struct */
- uint32_t buffer_offset;
- uint32_t buffer_size;
-};
-
-static const size_t vb_work_buf_size = 16 * KiB;
-
-static struct vb2_working_data * const vboot_get_working_data(void)
-{
- if (IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER))
- /* cbmem_add() does a cbmem_find() first. */
- return cbmem_add(CBMEM_ID_VBOOT_WORKBUF, vb_work_buf_size);
- else
- return (struct vb2_working_data *)_vboot2_work;
-}
-
-static size_t vb2_working_data_size(void)
-{
- if (IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER))
- return vb_work_buf_size;
- else
- return _vboot2_work_size;
-}
-
-static struct selected_region *vb2_selected_region(void)
-{
- struct selected_region *sel_reg = NULL;
-
- /* Ramstage and postcar always uses cbmem as a source of truth. */
- if (ENV_RAMSTAGE || ENV_POSTCAR)
- sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
- else if (ENV_ROMSTAGE) {
- /* Try cbmem first. Fall back on working data if not found. */
- sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
-
- if (sel_reg == NULL) {
- struct vb2_working_data *wd = vboot_get_working_data();
- sel_reg = &wd->selected_region;
- }
- } else {
- /* Stages such as bootblock and verstage use working data. */
- struct vb2_working_data *wd = vboot_get_working_data();
- sel_reg = &wd->selected_region;
- }
-
- return sel_reg;
-}
-
-void vb2_init_work_context(struct vb2_context *ctx)
-{
- struct vb2_working_data *wd;
- size_t work_size;
-
- /* First initialize the working data region. */
- work_size = vb2_working_data_size();
- wd = vboot_get_working_data();
- memset(wd, 0, work_size);
-
- /*
- * vboot prefers 16-byte alignment. This takes away 16 bytes
- * from the VBOOT2_WORK region, but the vboot devs said that's okay.
- */
- wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
- wd->buffer_size = work_size - wd->buffer_offset;
-
- /* Initialize the vb2_context. */
- memset(ctx, 0, sizeof(*ctx));
- ctx->workbuf = (void *)vb2_get_shared_data();
- ctx->workbuf_size = wd->buffer_size;
-
-}
-
-struct vb2_shared_data *vb2_get_shared_data(void)
-{
- struct vb2_working_data *wd = vboot_get_working_data();
- return (void *)((uintptr_t)wd + wd->buffer_offset);
-}
-
-int vb2_get_selected_region(struct region *region)
-{
- const struct selected_region *reg = vb2_selected_region();
-
- if (reg == NULL)
- return -1;
-
- if (reg->offset == 0 && reg->size == 0)
- return -1;
-
- region->offset = reg->offset;
- region->size = reg->size;
-
- return 0;
-}
-
-void vb2_set_selected_region(const struct region *region)
-{
- struct selected_region *reg = vb2_selected_region();
-
- assert(reg != NULL);
-
- reg->offset = region_offset(region);
- reg->size = region_sz(region);
-}
-
-int vb2_is_slot_selected(void)
-{
- const struct selected_region *reg = vb2_selected_region();
-
- assert(reg != NULL);
-
- return reg->size > 0;
-}
-
-void vb2_store_selected_region(void)
-{
- const struct vb2_working_data *wd;
- struct selected_region *sel_reg;
-
- /* Always use the working data in this path since it's the object
- * which has the result.. */
- wd = vboot_get_working_data();
-
- sel_reg = cbmem_add(CBMEM_ID_VBOOT_SEL_REG, sizeof(*sel_reg));
-
- assert(sel_reg != NULL);
-
- sel_reg->offset = wd->selected_region.offset;
- sel_reg->size = wd->selected_region.size;
-}
-
-/*
- * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
- * verification doesn't happen until after cbmem is brought online.
- * Therefore, the selected region contents would not be initialized
- * so don't automatically add results when cbmem comes online.
- */
-#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
-static void vb2_store_selected_region_cbmem(int unused)
-{
- vb2_store_selected_region();
-}
-ROMSTAGE_CBMEM_INIT_HOOK(vb2_store_selected_region_cbmem)
-#endif
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
deleted file mode 100644
index 9b771a2..0000000
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __CHROMEOS_VBOOT2_MISC_H__
-#define __CHROMEOS_VBOOT2_MISC_H__
-
-#include "../vboot_common.h"
-
-struct vb2_context;
-struct vb2_shared_data;
-
-void vboot_fill_handoff(void);
-
-void vb2_init_work_context(struct vb2_context *ctx);
-struct vb2_shared_data *vb2_get_shared_data(void);
-
-/* Returns 0 on success. < 0 on failure. */
-int vb2_get_selected_region(struct region *region);
-void vb2_set_selected_region(const struct region *region);
-int vb2_is_slot_selected(void);
-int vb2_logic_executed(void);
-
-/* Store the selected region in cbmem for later use. */
-void vb2_store_selected_region(void);
-
-void vb2_save_recovery_reason_vbnv(void);
-
-#endif /* __CHROMEOS_VBOOT2_MISC_H__ */
diff --git a/src/vendorcode/google/chromeos/vboot2/recovery.c b/src/vendorcode/google/chromeos/vboot2/recovery.c
deleted file mode 100644
index 94a8cc3..0000000
--- a/src/vendorcode/google/chromeos/vboot2/recovery.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2016 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.
- */
-
-#include <assert.h>
-#include <bootstate.h>
-#include <rules.h>
-#include <string.h>
-#include <vb2_api.h>
-
-#include "misc.h"
-#include "../vboot_common.h"
-
-static int vb2_get_recovery_reason_shared_data(void)
-{
- /* Shared data does not exist for Ramstage and Post-CAR stage. */
- if (ENV_RAMSTAGE || ENV_POSTCAR)
- return 0;
-
- struct vb2_shared_data *sd = vb2_get_shared_data();
- assert(sd);
- return sd->recovery_reason;
-}
-
-void vb2_save_recovery_reason_vbnv(void)
-{
- if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT))
- return;
-
- int reason = vb2_get_recovery_reason_shared_data();
- if (!reason)
- return;
-
- set_recovery_mode_into_vbnv(reason);
-}
-
-static void vb2_clear_recovery_reason_vbnv(void *unused)
-{
- if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT))
- return;
-
- set_recovery_mode_into_vbnv(0);
-}
-
-/*
- * Recovery reason stored in VBNV needs to be cleared before the state of VBNV
- * is backed-up anywhere or jumping to the payload (whichever occurs
- * first). Currently, vbnv_cmos.c backs up VBNV on POST_DEVICE. Thus, we need to
- * make sure that the stored recovery reason is cleared off before that
- * happens.
- * IMPORTANT: Any reboot occurring after BS_DEV_INIT state will cause loss of
- * recovery reason on reboot. Until now, we have seen reboots occuring on x86
- * only in FSP stages which run before BS_DEV_INIT.
- */
-BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT,
- vb2_clear_recovery_reason_vbnv, NULL);
-
-/*
- * Returns 0 for the stages where we know that cbmem does not come online.
- * Even if this function returns 1 for romstage, depending upon the point in
- * bootup, cbmem might not actually be online.
- */
-static int cbmem_possibly_online(void)
-{
- if (ENV_BOOTBLOCK)
- return 0;
-
- if (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
- return 0;
-
- return 1;
-}
-
-/*
- * Returns 1 if vboot is being used and currently in a stage which might have
- * already executed vboot verification.
- */
-static int vboot_possibly_executed(void)
-{
- if (!IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE))
- return 0;
-
- if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) {
- if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
- return 0;
- return 1;
- }
-
- if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) {
- if (ENV_BOOTBLOCK)
- return 0;
- return 1;
- }
-
- return 0;
-}
-
-/*
- * vb2_check_recovery_request looks up different components to identify if there
- * is a recovery request and returns appropriate reason code:
- * 1. Checks if recovery mode is initiated by EC. If yes, returns
- * VB2_RECOVERY_RO_MANUAL.
- * 2. Checks if recovery request is present in VBNV and returns the code read
- * from it.
- * 3. Checks recovery request in handoff for stages post-cbmem.
- * 4. For non-CBMEM stages, check if vboot verification is done and look-up
- * selected region to identify if vboot_refence library has requested recovery
- * path. If yes, return the reason code from shared data.
- * 5. If nothing applies, return 0 indicating no recovery request.
- */
-int vboot_check_recovery_request(void)
-{
- int reason = 0;
-
- /* EC-initiated recovery. */
- if (get_recovery_mode_switch())
- return VB2_RECOVERY_RO_MANUAL;
-
- /* Recovery request in VBNV. */
- if ((reason = get_recovery_mode_from_vbnv()) != 0)
- return reason;
-
- /*
- * Check recovery flag in vboot_handoff for stages post CBMEM coming
- * online. Since for some stages there is no way to know if cbmem has
- * already come online, try looking up handoff anyways. If it fails,
- * flow will fallback to looking up shared data.
- */
- if (cbmem_possibly_online() &&
- ((reason = vboot_handoff_get_recovery_reason()) != 0))
- return reason;
-
- /*
- * For stages where CBMEM might not be online, identify if vboot
- * verification is already complete and no slot was selected
- * i.e. recovery path was requested.
- */
- if (vboot_possibly_executed() && vb2_logic_executed() &&
- !vb2_is_slot_selected())
- return vb2_get_recovery_reason_shared_data();
-
- return 0;
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/secdata_mock.c b/src/vendorcode/google/chromeos/vboot2/secdata_mock.c
deleted file mode 100644
index 03616c1..0000000
--- a/src/vendorcode/google/chromeos/vboot2/secdata_mock.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2015 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 <antirollback.h>
-#include <stdlib.h>
-#include <vb2_api.h>
-
-uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
- enum vb2_pcr_digest which_digest)
-{
- return TPM_SUCCESS;
-}
-
-uint32_t tpm_clear_and_reenable(void)
-{
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
-{
- vb2api_secdata_create(ctx);
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
-{
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_lock_space_firmware()
-{
- return TPM_SUCCESS;
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
deleted file mode 100644
index 0e2cb84..0000000
--- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
+++ /dev/null
@@ -1,179 +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.
- */
-
-#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 <fmap.h>
-#include <stdlib.h>
-#include <timestamp.h>
-#define NEED_VB20_INTERNALS /* TODO: remove me! */
-#include <vb2_api.h>
-#include <vboot_struct.h>
-#include "../chromeos.h"
-#include "misc.h"
-
-/**
- * Sets vboot_handoff based on the information in vb2_shared_data
- */
-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);
- vb_sd->fw_version_tpm = vb2_sd->fw_version_secdata;
-
- if (get_write_protect_state())
- vb_sd->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED;
- if (get_sw_write_protect_state())
- vb_sd->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED;
-
- if (vb2_sd->recovery_reason) {
- vb_sd->firmware_index = 0xFF;
- if (vb2_sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY)
- 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 (IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH))
- vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
- if (IS_ENABLED(CONFIG_EC_SOFTWARE_SYNC))
- vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
- if (!IS_ENABLED(CONFIG_PHYSICAL_REC_SWITCH))
- vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
- if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE))
- vb_sd->flags |= VBSD_EC_SLOW_UPDATE;
- if (IS_ENABLED(CONFIG_VBOOT_OPROM_MATTERS)) {
- vb_sd->flags |= VBSD_OPROM_MATTERS;
- /*
- * Inform vboot if the display was enabled by dev/rec
- * mode or was requested by vboot kernel phase.
- */
- if (*oflags & VB_INIT_OUT_ENABLE_DISPLAY ||
- vboot_wants_oprom()) {
- vb_sd->flags |= VBSD_OPROM_LOADED;
- *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
- }
- }
-
- /* 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;
-}
-
-void vboot_fill_handoff(void)
-{
- struct vboot_handoff *vh;
- struct vb2_shared_data *sd;
-
- sd = vb2_get_shared_data();
- 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);
-
- /*
- * The recovery mode switch is cleared (typically backed by EC) here
- * to allow multiple queries to get_recovery_mode_switch() and have
- * them return consistent results during the verified boot path as well
- * as dram initialization. x86 systems ignore the saved dram settings
- * in the recovery path in order to start from a clean slate. Therefore
- * clear the state here since this function is called when memory
- * is known to be up.
- */
- clear_recovery_mode_switch();
-}
-
-/*
- * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
- * verification doesn't happen until after cbmem is brought online.
- * Therefore, the vboot results would not be initialized so don't
- * automatically add results when cbmem comes online.
- */
-#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
-static void vb2_fill_handoff_cbmem(int unused)
-{
- vboot_fill_handoff();
-}
-ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem)
-#endif
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
deleted file mode 100644
index b76d20b..0000000
--- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2015 Google, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <arch/early_variables.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <rmodule.h>
-#include <rules.h>
-#include <string.h>
-#include "misc.h"
-#include "../vboot_common.h"
-#include "../symbols.h"
-
-/* The stage loading code is compiled and entered from multiple stages. The
- * helper functions below attempt to provide more clarity on when certain
- * code should be called. */
-
-static int verification_should_run(void)
-{
- if (ENV_VERSTAGE && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
- return 1;
-
- if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) {
- if (ENV_ROMSTAGE &&
- IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
- return 1;
- if (ENV_BOOTBLOCK &&
- IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
- return 1;
- }
-
- return 0;
-}
-
-static int verstage_should_load(void)
-{
- if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
- return 0;
-
- if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
- return 1;
-
- if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
- return 1;
-
- return 0;
-}
-
-static int vboot_executed CAR_GLOBAL;
-
-int vb2_logic_executed(void)
-{
- /* If this stage is supposed to run the vboot logic ensure it has been
- * executed. */
- if (verification_should_run() && car_get_var(vboot_executed))
- return 1;
-
- /* If this stage is supposed to load verstage and verstage is returning
- * back to the calling stage check that it has been executed. */
- if (verstage_should_load() && IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
- if (car_get_var(vboot_executed))
- return 1;
-
- /* Handle all other stages post vboot execution. */
- if (!ENV_BOOTBLOCK) {
- if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
- return 1;
- if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) &&
- !ENV_ROMSTAGE)
- return 1;
- }
-
- return 0;
-}
-
-static void vboot_prepare(void)
-{
- if (verification_should_run()) {
- verstage_main();
- car_set_var(vboot_executed, 1);
- vb2_save_recovery_reason_vbnv();
- } else if (verstage_should_load()) {
- struct cbfsf file;
- struct prog verstage =
- PROG_INIT(PROG_VERSTAGE,
- CONFIG_CBFS_PREFIX "/verstage");
-
- printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
-
- /* load verstage from RO */
- if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
- die("failed to load verstage");
-
- cbfs_file_data(prog_rdev(&verstage), &file);
-
- if (cbfs_prog_stage_load(&verstage))
- die("failed to load verstage");
-
- /* verify and select a slot */
- prog_run(&verstage);
-
- /* This is not actually possible to hit this condition at
- * runtime, but this provides a hint to the compiler for dead
- * code elimination below. */
- if (!IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
- return;
-
- car_set_var(vboot_executed, 1);
- }
-
- /*
- * Fill in vboot cbmem objects before moving to ramstage so all
- * downstream users have access to vboot results. This path only
- * applies to platforms employing VBOOT_DYNAMIC_WORK_BUFFER because
- * cbmem comes online prior to vboot verification taking place. For
- * other platforms the vboot cbmem objects are initialized when
- * cbmem comes online.
- */
- if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)) {
- vb2_store_selected_region();
- vboot_fill_handoff();
- }
-}
-
-static int vboot_locate(struct cbfs_props *props)
-{
- struct region selected_region;
-
- /* Don't honor vboot results until the vboot logic has run. */
- if (!vb2_logic_executed())
- return -1;
-
- if (vb2_get_selected_region(&selected_region))
- return -1;
-
- props->offset = region_offset(&selected_region);
- props->size = region_sz(&selected_region);
-
- return 0;
-}
-
-const struct cbfs_locator vboot_locator = {
- .name = "VBOOT",
- .prepare = vboot_prepare,
- .locate = vboot_locate,
-};
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
deleted file mode 100644
index 4c799c9..0000000
--- a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
+++ /dev/null
@@ -1,415 +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.
- */
-
-#include <antirollback.h>
-#include <arch/exception.h>
-#include <assert.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <delay.h>
-#include <string.h>
-#include <timestamp.h>
-#include <vb2_api.h>
-
-#include "../chromeos.h"
-#include "misc.h"
-
-/* The max hash size to expect is for SHA512. */
-#define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
-
-#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);
- do_printk_va_list(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 region_device rdev;
- const char *name;
-
- switch (index) {
- case VB2_RES_GBB:
- name = "GBB";
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- name = "VBLOCK_A";
- else
- name = "VBLOCK_B";
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (vboot_named_region_device(name, &rdev))
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (rdev_readat(&rdev, buf, offset, size) != size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- return VB2_SUCCESS;
-}
-
-/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
- uint32_t data_size)
-{
- return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-static int handle_digest_result(void *slot_hash, size_t slot_hash_sz)
-{
- int is_resume;
-
- /*
- * Nothing to do since resuming on the platform doesn't require
- * vboot verification again.
- */
- if (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT))
- return 0;
-
- /*
- * Assume that if vboot doesn't start in bootblock verified
- * RW memory init code is not employed. i.e. memory init code
- * lives in RO CBFS.
- */
- if (!IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
- return 0;
-
- is_resume = vboot_platform_is_resuming();
-
- if (is_resume > 0) {
- uint8_t saved_hash[VBOOT_MAX_HASH_SIZE];
- const size_t saved_hash_sz = sizeof(saved_hash);
-
- assert(slot_hash_sz == saved_hash_sz);
-
- printk(BIOS_DEBUG, "Platform is resuming.\n");
-
- if (vboot_retrieve_hash(saved_hash, saved_hash_sz)) {
- printk(BIOS_ERR, "Couldn't retrieve saved hash.\n");
- return -1;
- }
-
- if (memcmp(saved_hash, slot_hash, slot_hash_sz)) {
- printk(BIOS_ERR, "Hash mismatch on resume.\n");
- return -1;
- }
- } else if (is_resume < 0)
- printk(BIOS_ERR, "Unable to determine if platform resuming.\n");
-
- printk(BIOS_DEBUG, "Saving vboot hash.\n");
-
- /* Always save the hash for the current boot. */
- if (vboot_save_hash(slot_hash, slot_hash_sz)) {
- printk(BIOS_ERR, "Error saving vboot hash.\n");
- /* Though this is an error don't report it up since it could
- * lead to a reboot loop. The consequence of this is that
- * we will most likely fail resuming because of EC issues or
- * the hash digest not matching. */
- return 0;
- }
-
- return 0;
-}
-
-static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
-{
- uint64_t load_ts;
- uint32_t expected_size;
- uint8_t block[TODO_BLOCK_SIZE];
- uint8_t hash_digest[VBOOT_MAX_HASH_SIZE];
- const size_t hash_digest_sz = sizeof(hash_digest);
- size_t block_size = sizeof(block);
- size_t offset;
- int rv;
-
- /* Clear the full digest so that any hash digests less than the
- * max have trailing zeros. */
- memset(hash_digest, 0, hash_digest_sz);
-
- /*
- * Since loading the firmware and calculating its hash is intertwined,
- * we use this little trick to measure them separately and pretend it
- * was first loaded and then hashed in one piece with the timestamps.
- * (This split won't make sense with memory-mapped media like on x86.)
- */
- load_ts = timestamp_get();
- timestamp_add(TS_START_HASH_BODY, load_ts);
-
- expected_size = region_device_sz(fw_main);
- offset = 0;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /*
- * Honor vboot's RW slot size. The expected size is pulled out of
- * the preamble and obtained through vb2api_init_hash() above. By
- * creating sub region the RW slot portion of the boot media is
- * limited.
- */
- if (rdev_chain(fw_main, fw_main, 0, expected_size)) {
- printk(BIOS_ERR, "Unable to restrict CBFS size.\n");
- return VB2_ERROR_UNKNOWN;
- }
-
- /* Extend over the body */
- while (expected_size) {
- uint64_t temp_ts;
- if (block_size > expected_size)
- block_size = expected_size;
-
- temp_ts = timestamp_get();
- if (rdev_readat(fw_main, block, offset, block_size) < 0)
- return VB2_ERROR_UNKNOWN;
- load_ts += timestamp_get() - temp_ts;
-
- rv = vb2api_extend_hash(ctx, block, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- timestamp_add(TS_DONE_LOADING, load_ts);
- timestamp_add_now(TS_DONE_HASHING);
-
- /* Check the result (with RSA signature verification) */
- rv = vb2api_check_hash_get_digest(ctx, hash_digest, hash_digest_sz);
- if (rv)
- return rv;
-
- timestamp_add_now(TS_END_HASH_BODY);
-
- if (handle_digest_result(hash_digest, hash_digest_sz))
- return VB2_ERROR_UNKNOWN;
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct region_device *fw_main)
-{
- const char *name;
-
- if (is_slot_a(ctx))
- name = "FW_MAIN_A";
- else
- name = "FW_MAIN_B";
-
- return vboot_named_region_device(name, fw_main);
-}
-
-/**
- * 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;
- }
-}
-
-static uint32_t extend_pcrs(struct vb2_context *ctx)
-{
- return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
- tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
-}
-
-/**
- * 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.
- */
-void verstage_main(void)
-{
- struct vb2_context ctx;
- struct region_device fw_main;
- int rv;
-
- timestamp_add_now(TS_START_VBOOT);
-
- /* Set up context and work buffer */
- vb2_init_work_context(&ctx);
-
- /* Read nvdata from a non-volatile storage. */
- read_vbnv(ctx.nvdata);
-
- /* Set S3 resume flag if vboot should behave differently when selecting
- * which slot to boot. This is only relevant to vboot if the platform
- * does verification of memory init and thus must ensure it resumes with
- * the same slot that it booted from. */
- if (IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) &&
- IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) &&
- vboot_platform_is_resuming())
- ctx.flags |= VB2_CONTEXT_S3_RESUME;
-
- /* 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). */
- timestamp_add_now(TS_START_TPMINIT);
- antirollback_read_space_firmware(&ctx);
- timestamp_add_now(TS_END_TPMINIT);
-
- if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
- get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
-
- if (get_recovery_mode_switch()) {
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
- ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
- }
-
- if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
-
- if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
- ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
-
- /* Do early init (set up secdata and NVRAM, load GBB) */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
-
- if (rv) {
- /*
- * If vb2api_fw_phase1 fails, check for return value.
- * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
- * into recovery mode.
- * For any other error code, save context if needed and reboot.
- */
- if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- save_if_needed(&ctx);
- extend_pcrs(&ctx); /* ignore failures */
- timestamp_add_now(TS_END_VBOOT);
- return;
- }
-
- printk(BIOS_INFO, "Reboot reqested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Determine which firmware slot to boot (based on NVRAM) */
- 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 (verify its keyblock and preamble) */
- printk(BIOS_INFO, "Phase 3\n");
- timestamp_add_now(TS_START_VERIFY_SLOT);
- rv = vb2api_fw_phase3(&ctx);
- timestamp_add_now(TS_END_VERIFY_SLOT);
- 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();
- }
-
- rv = extend_pcrs(&ctx);
- if (rv) {
- printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
- save_if_needed(&ctx);
- 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(region_device_region(&fw_main));
- timestamp_add_now(TS_END_VBOOT);
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
deleted file mode 100644
index 99bc28d..0000000
--- a/src/vendorcode/google/chromeos/vboot2/verstage.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2015 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <console/console.h>
-#include <program_loading.h>
-#include "../vboot_common.h"
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-void verstage(void)
-{
- console_init();
- exception_init();
- verstage_mainboard_init();
-
- if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
- verstage_main();
- } else {
- run_romstage();
- hlt();
- }
-}
-
-#if !IS_ENABLED(CONFIG_CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL)
-/* This is for boards that rely on main() for an entry point of a stage. */
-void main(void) __attribute__((alias ("verstage")));
-#endif
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
deleted file mode 100644
index 66800ed..0000000
--- a/src/vendorcode/google/chromeos/vboot_common.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.
- */
-
-#include <boot/coreboot_tables.h>
-#include <boot_device.h>
-#include <cbmem.h>
-#include <console/cbmem_console.h>
-#include <console/console.h>
-#include <fmap.h>
-#include <reset.h>
-#include <rules.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "chromeos.h"
-#include "vboot_common.h"
-
-int vboot_named_region_device(const char *name, struct region_device *rdev)
-{
- return fmap_locate_area_as_rdev(name, rdev);
-}
-
-/* ========================== VBOOT HANDOFF APIs =========================== */
-int vboot_get_handoff_info(void **addr, uint32_t *size)
-{
- /*
- * vboot_handoff is present only after cbmem comes online. If we are in
- * pre-ram stage, then bail out early.
- */
- if (ENV_BOOTBLOCK ||
- (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)))
- return -1;
-
- struct vboot_handoff *vboot_handoff;
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return -1;
-
- *addr = vboot_handoff;
-
- if (size)
- *size = sizeof(*vboot_handoff);
- return 0;
-}
-
-static int vboot_get_handoff_flag(uint32_t flag)
-{
- struct vboot_handoff *vbho;
-
- /*
- * If vboot_handoff cannot be found, return default value of flag as 0.
- */
- if (vboot_get_handoff_info((void **)&vbho, NULL))
- return 0;
-
- return !!(vbho->init_params.out_flags & flag);
-}
-
-int vboot_handoff_skip_display_init(void)
-{
- return !vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DISPLAY);
-}
-
-int vboot_handoff_check_developer_flag(void)
-{
- return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DEVELOPER);
-}
-
-int vboot_handoff_check_recovery_flag(void)
-{
- return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_RECOVERY);
-}
-
-int vboot_handoff_get_recovery_reason(void)
-{
- struct vboot_handoff *vbho;
- VbSharedDataHeader *sd;
-
- if (vboot_get_handoff_info((void **)&vbho, NULL))
- return 0;
-
- sd = (VbSharedDataHeader *)vbho->shared_data;
-
- return sd->recovery_reason;
-}
-
-/* ============================ VBOOT REBOOT ============================== */
-void __attribute__((weak)) vboot_platform_prepare_reboot(void)
-{
-}
-
-void vboot_reboot(void)
-{
- if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
- cbmem_dump_console();
- vboot_platform_prepare_reboot();
- hard_reset();
- die("failed to reboot");
-}
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
deleted file mode 100644
index 266ce4f..0000000
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.
- */
-#ifndef VBOOT_COMMON_H
-#define VBOOT_COMMON_H
-
-#include <commonlib/region.h>
-#include <stdint.h>
-#include <vboot_api.h>
-#include <vboot_struct.h>
-
-#include "chromeos.h"
-
-/* Locate vboot area by name. Returns 0 on success and -1 on error. */
-int vboot_named_region_device(const char *name, struct region_device *rdev);
-
-/*
- * Function to check if there is a request to enter recovery mode. Returns
- * reason code if request to enter recovery mode is present, otherwise 0.
- */
-int vboot_check_recovery_request(void);
-
-/* ========================== VBOOT HANDOFF APIs =========================== */
-/*
- * The vboot_handoff structure contains the data to be consumed by downstream
- * firmware after firmware selection has been completed. Namely it provides
- * vboot shared data as well as the flags from VbInit.
- */
-struct vboot_handoff {
- VbInitParams init_params;
- uint32_t selected_firmware;
- char shared_data[VB_SHARED_DATA_MIN_SIZE];
-} __attribute__((packed));
-
-/*
- * vboot_get_handoff_info returns pointer to the vboot_handoff structure if
- * available. vboot_handoff is available only after CBMEM comes online. If size
- * is not NULL, size of the vboot_handoff structure is returned in it.
- * Returns 0 on success and -1 on error.
- */
-int vboot_get_handoff_info(void **addr, uint32_t *size);
-
-/*
- * The following functions read vboot_handoff structure to obtain requested
- * information. If vboot handoff is not available, 0 is returned by default.
- * If vboot handoff is available:
- * Returns 1 for flag if true
- * Returns 0 for flag if false
- * Returns value read for other fields
- */
-int vboot_handoff_skip_display_init(void);
-int vboot_handoff_check_recovery_flag(void);
-int vboot_handoff_check_developer_flag(void);
-int vboot_handoff_get_recovery_reason(void);
-
-/* ============================ VBOOT REBOOT ============================== */
-/*
- * vboot_reboot handles the reboot requests made by vboot_reference library. It
- * allows the platform to run any preparation steps before the reboot and then
- * does a hard reset.
- */
-void vboot_reboot(void);
-
-/* Allow the platform to do any clean up work when vboot requests a reboot. */
-void vboot_platform_prepare_reboot(void);
-
-/* ============================ VBOOT RESUME ============================== */
-/*
- * Save the provided hash digest to a secure location to check against in
- * the resume path. Returns 0 on success, < 0 on error.
- */
-int vboot_save_hash(void *digest, size_t digest_size);
-
-/*
- * Retrieve the previously saved hash digest. Returns 0 on success,
- * < 0 on error.
- */
-int vboot_retrieve_hash(void *digest, size_t digest_size);
-
-/*
- * Determine if the platform is resuming from suspend. Returns 0 when
- * not resuming, > 0 if resuming, and < 0 on error.
- */
-int vboot_platform_is_resuming(void);
-
-/* ============================= VERSTAGE ================================== */
-/*
- * Main logic for verified boot. verstage() is the stage entry point
- * while the verstage_main() is just the core logic.
- */
-void verstage_main(void);
-void verstage(void);
-void verstage_mainboard_init(void);
-
-#endif /* VBOOT_COMMON_H */
diff --git a/src/vendorcode/google/vboot2/Kconfig b/src/vendorcode/google/vboot2/Kconfig
new file mode 100644
index 0000000..edeec52
--- /dev/null
+++ b/src/vendorcode/google/vboot2/Kconfig
@@ -0,0 +1,110 @@
+## 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.
+##
+
+config VBOOT_STARTS_IN_BOOTBLOCK
+ bool "Vboot starts verifying in bootblock"
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ Firmware verification happens during or at the end of bootblock.
+
+config VBOOT_STARTS_IN_ROMSTAGE
+ bool "Vboot starts verifying in romstage"
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE && !VBOOT_STARTS_IN_BOOTBLOCK
+ help
+ Firmware verification happens during or at the end of romstage.
+
+config VBOOT2_MOCK_SECDATA
+ bool "Mock secdata for firmware verification"
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ Enabling VBOOT2_MOCK_SECDATA will mock secdata for the firmware
+ verification to avoid access to a secdata storage (typically TPM).
+ All operations for a secdata storage will be successful. This option
+ can be used during development when a TPM is not present or broken.
+ THIS SHOULD NOT BE LEFT ON FOR PRODUCTION DEVICES.
+
+config VBOOT_DISABLE_DEV_ON_RECOVERY
+ bool "Disable dev mode on recovery requests"
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ When this option is enabled, the Chrome OS device leaves the
+ developer mode as soon as recovery request is detected. This is
+ handy on embedded devices with limited input capabilities.
+
+config SEPARATE_VERSTAGE
+ bool "Vboot verification is built into a separate stage"
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+
+config RETURN_FROM_VERSTAGE
+ bool "The separate verification stage returns to its caller"
+ default n
+ depends on SEPARATE_VERSTAGE
+ help
+ If this is set, the verstage returns back to the calling stage instead
+ of exiting to the succeeding stage so that the verstage space can be
+ reused by the succeeding stage. This is useful if a ram space is too
+ small to fit both the verstage and the succeeding stage.
+
+config CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL
+ bool "The chipset provides the main() entry point for verstage"
+ default n
+ depends on SEPARATE_VERSTAGE
+ help
+ The chipset code provides their own main() entry point.
+
+config VBOOT_DYNAMIC_WORK_BUFFER
+ bool "Vboot's work buffer is dynamically allocated."
+ default y if ARCH_ROMSTAGE_X86_32 && !SEPARATE_VERSTAGE
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ This option is used when there isn't enough pre-main memory
+ ram to allocate the vboot work buffer. That means vboot verification
+ is after memory init and requires main memory to back the work
+ buffer.
+
+config VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT
+ bool
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ This option ensures that the recovery request is not lost because of
+ reboots caused after vboot verification is run. e.g. reboots caused by
+ FSP components on Intel platforms.
+
+config VBOOT_OPROM_MATTERS
+ bool "Video option ROM matters (= can skip display init)"
+ default n
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ Set this option to indicate to vboot that this platform will skip its
+ display initialization on a normal (non-recovery, non-developer) boot.
+ Vboot calls this "oprom matters" because on x86 devices this
+ traditionally meant that the video option ROM will not be loaded, but
+ it works functionally the same for other platforms that can skip their
+ native display initialization code instead.
+
+config VBOOT_VERIFY_FIRMWARE
+ bool "Verify firmware with vboot."
+ default n
+ depends on HAVE_HARD_RESET
+ help
+ Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the components
+ of the firmware (stages, payload, etc).
+
diff --git a/src/vendorcode/google/vboot2/Makefile.inc b/src/vendorcode/google/vboot2/Makefile.inc
new file mode 100644
index 0000000..8fb1bc6
--- /dev/null
+++ b/src/vendorcode/google/vboot2/Makefile.inc
@@ -0,0 +1,118 @@
+##
+## 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.
+##
+
+libverstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
+verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
+
+bootblock-y += vboot_loader.c
+romstage-y += vboot_loader.c
+ramstage-y += vboot_loader.c
+verstage-y += vboot_loader.c
+postcar-y += vboot_loader.c
+
+bootblock-y += vboot_common.c
+verstage-y += vboot_common.c
+romstage-y += vboot_common.c
+ramstage-y += vboot_common.c
+postcar-y += vboot_common.c
+
+bootblock-y += recovery.c
+romstage-y += recovery.c
+ramstage-y += recovery.c
+verstage-y += recovery.c
+postcar-y += recovery.c
+
+bootblock-y += common.c
+libverstage-y += vboot_logic.c
+verstage-y += common.c
+verstage-y += verstage.c
+ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y)
+libverstage-y += secdata_mock.c
+else
+libverstage-y += antirollback.c
+endif
+romstage-y += vboot_handoff.c common.c
+
+ramstage-y += common.c
+postcar-y += common.c
+
+ifeq ($(CONFIG_SEPARATE_VERSTAGE),y)
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-verstage-y))
+else
+ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y)
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-bootblock-y))
+else
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y))
+endif
+endif # CONFIG_SEPARATE_VERSTAGE
+
+VB2_LIB = $(obj)/external/vboot_reference/vboot_fw20.a
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%, $(filter-out -I$(obj), $(filter-out -include $(src)/include/kconfig.h, $(CPPFLAGS_libverstage))))
+VBOOT_CFLAGS += $(CFLAGS_libverstage)
+VBOOT_CFLAGS += $(libverstage-c-ccopts)
+VBOOT_CFLAGS += -I$(abspath $(obj)) -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=$(abspath $(dir $(VB2_LIB))) \
+ V=$(V) \
+ fwlib20
+
+libverstage-srcs += $(VB2_LIB)
+
+ifeq ($(CONFIG_SEPARATE_VERSTAGE),y)
+cbfs-files-$(CONFIG_SEPARATE_VERSTAGE) += $(CONFIG_CBFS_PREFIX)/verstage
+$(CONFIG_CBFS_PREFIX)/verstage-file := $(objcbfs)/verstage.elf
+$(CONFIG_CBFS_PREFIX)/verstage-type := stage
+$(CONFIG_CBFS_PREFIX)/verstage-compression := $(CBFS_PRERAM_COMPRESS_FLAG)
+
+ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)
+$(CONFIG_CBFS_PREFIX)/verstage-options := -a 64 -S ".car.data"
+
+# If CAR does not support execution of code, verstage on x86 is expected to be
+# xip.
+ifneq ($(CONFIG_NO_XIP_EARLY_STAGES),y)
+$(CONFIG_CBFS_PREFIX)/verstage-options += --xip
+endif
+
+endif
+
+else
+ifeq ($(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK),y)
+bootblock-srcs += $(objgenerated)/libverstage.a
+else
+romstage-srcs += $(objgenerated)/libverstage.a
+endif
+endif # CONFIG_SEPARATE_VERSTAGE
+
+# Define a list of files that need to be in RO only.
+# All other files will be installed into RO and RW regions
+# Use $(sort) to cut down on extra spaces that would be translated to commas
+regions-for-file = $(subst $(spc),$(comma),$(sort \
+ $(if $(filter \
+ $(if $(filter y,$(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)),, \
+ %/romstage) \
+ mts \
+ %/verstage \
+ locales \
+ locale_%.bin \
+ font.bin \
+ vbgfx.bin \
+ ,$(1)),COREBOOT,COREBOOT FW_MAIN_A FW_MAIN_B)))
diff --git a/src/vendorcode/google/vboot2/antirollback.c b/src/vendorcode/google/vboot2/antirollback.c
new file mode 100644
index 0000000..a51e5d6
--- /dev/null
+++ b/src/vendorcode/google/vboot2/antirollback.c
@@ -0,0 +1,436 @@
+/* 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 <antirollback.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tpm_lite/tlcl.h>
+#include <vb2_api.h>
+#include <console/console.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)
+
+
+static uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
+
+uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
+ enum vb2_pcr_digest which_digest)
+{
+ uint8_t buffer[VB2_PCR_DIGEST_RECOMMENDED_SIZE];
+ uint32_t size = sizeof(buffer);
+ int rv;
+
+ rv = vb2api_get_pcr_digest(ctx, which_digest, buffer, &size);
+ if (rv != VB2_SUCCESS)
+ return rv;
+ if (size < TPM_PCR_DIGEST)
+ return VB2_ERROR_UNKNOWN;
+
+ return tlcl_extend(pcr, buffer, NULL);
+}
+
+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;
+}
+
+/*
+ * 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,
+};
+
+#if IS_ENABLED(CONFIG_TPM2)
+
+/* Nothing special in the TPM2 path yet. */
+static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
+{
+ return tlcl_write(index, data, length);
+}
+
+static uint32_t set_firmware_space(const void *firmware_blob)
+{
+ RETURN_ON_FAILURE(tlcl_define_space(FIRMWARE_NV_INDEX,
+ VB2_SECDATA_SIZE));
+ RETURN_ON_FAILURE(safe_write(FIRMWARE_NV_INDEX, firmware_blob,
+ VB2_SECDATA_SIZE));
+ return TPM_SUCCESS;
+}
+
+static uint32_t set_kernel_space(const void *kernel_blob)
+{
+ RETURN_ON_FAILURE(tlcl_define_space(KERNEL_NV_INDEX,
+ sizeof(secdata_kernel)));
+ RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX, kernel_blob,
+ sizeof(secdata_kernel)));
+ return TPM_SUCCESS;
+}
+
+static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
+{
+ RETURN_ON_FAILURE(tlcl_force_clear());
+ RETURN_ON_FAILURE(set_firmware_space(ctx->secdata));
+ RETURN_ON_FAILURE(set_kernel_space(secdata_kernel));
+ return TPM_SUCCESS;
+}
+
+uint32_t tpm_clear_and_reenable(void)
+{
+ VBDEBUG("TPM: Clear and re-enable\n");
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_lock_space_firmware(void)
+{
+ return tlcl_lock_nv_write(FIRMWARE_NV_INDEX);
+}
+
+#else
+
+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;
+}
+
+/**
+ * Like tlcl_write(), but checks for write errors due to hitting the 64-write
+ * limit and clears the TPM when that happens. This can only happen when the
+ * TPM is unowned, so it is OK to clear it (and we really have no choice).
+ * This is not expected to happen frequently, but it could happen.
+ */
+
+static 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;
+ }
+}
+
+/**
+ * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
+ * we hit the TPM write limit. This is even less likely to happen than with
+ * writes because we only define spaces once at initialization, but we'd
+ * rather be paranoid about this.
+ */
+static 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 _factory_initialize_tpm(struct vb2_context *ctx)
+{
+ TPM_PERMANENT_FLAGS pflags;
+ uint32_t 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));
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_lock_space_firmware(void)
+{
+ return tlcl_set_global_lock();
+}
+#endif
+
+uint32_t factory_initialize_tpm(struct vb2_context *ctx)
+{
+ uint32_t result;
+
+ /* Defines and sets vb2 secdata space */
+ vb2api_secdata_create(ctx);
+
+ 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 = _factory_initialize_tpm(ctx);
+ if (result != TPM_SUCCESS)
+ return result;
+
+ 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());
+
+ /* Handle special init for S3 resume path */
+ if (ctx->flags & VB2_CONTEXT_S3_RESUME) {
+ result = tlcl_resume();
+ if (result == TPM_E_INVALID_POSTINIT)
+ printk(BIOS_DEBUG, "TPM: Already initialized.\n");
+ return TPM_SUCCESS;
+ }
+
+#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);
+ ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ 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");
+ ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ 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);
+}
diff --git a/src/vendorcode/google/vboot2/common.c b/src/vendorcode/google/vboot2/common.c
new file mode 100644
index 0000000..11b2a0c
--- /dev/null
+++ b/src/vendorcode/google/vboot2/common.c
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+
+#include <assert.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <reset.h>
+#include <string.h>
+#include <vb2_api.h>
+#include "symbols.h"
+#include "vboot_common.h"
+#include "misc.h"
+
+struct selected_region {
+ uint32_t offset;
+ uint32_t size;
+};
+
+/*
+ * this is placed at the start of the vboot work buffer. selected_region is used
+ * for the verstage to return the location of the selected slot. buffer is used
+ * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
+ * stage boundaries.
+ */
+struct vb2_working_data {
+ struct selected_region selected_region;
+ /* offset of the buffer from the start of this struct */
+ uint32_t buffer_offset;
+ uint32_t buffer_size;
+};
+
+static const size_t vb_work_buf_size = 16 * KiB;
+
+static struct vb2_working_data * const vboot_get_working_data(void)
+{
+ if (IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER))
+ /* cbmem_add() does a cbmem_find() first. */
+ return cbmem_add(CBMEM_ID_VBOOT_WORKBUF, vb_work_buf_size);
+ else
+ return (struct vb2_working_data *)_vboot2_work;
+}
+
+static size_t vb2_working_data_size(void)
+{
+ if (IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER))
+ return vb_work_buf_size;
+ else
+ return _vboot2_work_size;
+}
+
+static struct selected_region *vb2_selected_region(void)
+{
+ struct selected_region *sel_reg = NULL;
+
+ /* Ramstage and postcar always uses cbmem as a source of truth. */
+ if (ENV_RAMSTAGE || ENV_POSTCAR)
+ sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
+ else if (ENV_ROMSTAGE) {
+ /* Try cbmem first. Fall back on working data if not found. */
+ sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
+
+ if (sel_reg == NULL) {
+ struct vb2_working_data *wd = vboot_get_working_data();
+ sel_reg = &wd->selected_region;
+ }
+ } else {
+ /* Stages such as bootblock and verstage use working data. */
+ struct vb2_working_data *wd = vboot_get_working_data();
+ sel_reg = &wd->selected_region;
+ }
+
+ return sel_reg;
+}
+
+void vb2_init_work_context(struct vb2_context *ctx)
+{
+ struct vb2_working_data *wd;
+ size_t work_size;
+
+ /* First initialize the working data region. */
+ work_size = vb2_working_data_size();
+ wd = vboot_get_working_data();
+ memset(wd, 0, work_size);
+
+ /*
+ * vboot prefers 16-byte alignment. This takes away 16 bytes
+ * from the VBOOT2_WORK region, but the vboot devs said that's okay.
+ */
+ wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
+ wd->buffer_size = work_size - wd->buffer_offset;
+
+ /* Initialize the vb2_context. */
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->workbuf = (void *)vb2_get_shared_data();
+ ctx->workbuf_size = wd->buffer_size;
+
+}
+
+struct vb2_shared_data *vb2_get_shared_data(void)
+{
+ struct vb2_working_data *wd = vboot_get_working_data();
+ return (void *)((uintptr_t)wd + wd->buffer_offset);
+}
+
+int vb2_get_selected_region(struct region *region)
+{
+ const struct selected_region *reg = vb2_selected_region();
+
+ if (reg == NULL)
+ return -1;
+
+ if (reg->offset == 0 && reg->size == 0)
+ return -1;
+
+ region->offset = reg->offset;
+ region->size = reg->size;
+
+ return 0;
+}
+
+void vb2_set_selected_region(const struct region *region)
+{
+ struct selected_region *reg = vb2_selected_region();
+
+ assert(reg != NULL);
+
+ reg->offset = region_offset(region);
+ reg->size = region_sz(region);
+}
+
+int vb2_is_slot_selected(void)
+{
+ const struct selected_region *reg = vb2_selected_region();
+
+ assert(reg != NULL);
+
+ return reg->size > 0;
+}
+
+void vb2_store_selected_region(void)
+{
+ const struct vb2_working_data *wd;
+ struct selected_region *sel_reg;
+
+ /* Always use the working data in this path since it's the object
+ * which has the result.. */
+ wd = vboot_get_working_data();
+
+ sel_reg = cbmem_add(CBMEM_ID_VBOOT_SEL_REG, sizeof(*sel_reg));
+
+ assert(sel_reg != NULL);
+
+ sel_reg->offset = wd->selected_region.offset;
+ sel_reg->size = wd->selected_region.size;
+}
+
+/*
+ * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
+ * verification doesn't happen until after cbmem is brought online.
+ * Therefore, the selected region contents would not be initialized
+ * so don't automatically add results when cbmem comes online.
+ */
+#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
+static void vb2_store_selected_region_cbmem(int unused)
+{
+ vb2_store_selected_region();
+}
+ROMSTAGE_CBMEM_INIT_HOOK(vb2_store_selected_region_cbmem)
+#endif
diff --git a/src/vendorcode/google/vboot2/misc.h b/src/vendorcode/google/vboot2/misc.h
new file mode 100644
index 0000000..29faa86
--- /dev/null
+++ b/src/vendorcode/google/vboot2/misc.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef __CHROMEOS_VBOOT2_MISC_H__
+#define __CHROMEOS_VBOOT2_MISC_H__
+
+#include "vboot_common.h"
+
+struct vb2_context;
+struct vb2_shared_data;
+
+void vboot_fill_handoff(void);
+
+void vb2_init_work_context(struct vb2_context *ctx);
+struct vb2_shared_data *vb2_get_shared_data(void);
+
+/* Returns 0 on success. < 0 on failure. */
+int vb2_get_selected_region(struct region *region);
+void vb2_set_selected_region(const struct region *region);
+int vb2_is_slot_selected(void);
+int vb2_logic_executed(void);
+
+/* Store the selected region in cbmem for later use. */
+void vb2_store_selected_region(void);
+
+void vb2_save_recovery_reason_vbnv(void);
+
+#endif /* __CHROMEOS_VBOOT2_MISC_H__ */
diff --git a/src/vendorcode/google/vboot2/recovery.c b/src/vendorcode/google/vboot2/recovery.c
new file mode 100644
index 0000000..3966db4
--- /dev/null
+++ b/src/vendorcode/google/vboot2/recovery.c
@@ -0,0 +1,157 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 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.
+ */
+
+#include <assert.h>
+#include <bootmode.h>
+#include <bootstate.h>
+#include <rules.h>
+#include <string.h>
+#include <vb2_api.h>
+#include <vendorcode/google/chromeos/vbnv.h>
+
+#include "misc.h"
+#include "vboot_common.h"
+
+static int vb2_get_recovery_reason_shared_data(void)
+{
+ /* Shared data does not exist for Ramstage and Post-CAR stage. */
+ if (ENV_RAMSTAGE || ENV_POSTCAR)
+ return 0;
+
+ struct vb2_shared_data *sd = vb2_get_shared_data();
+ assert(sd);
+ return sd->recovery_reason;
+}
+
+void vb2_save_recovery_reason_vbnv(void)
+{
+ if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT))
+ return;
+
+ int reason = vb2_get_recovery_reason_shared_data();
+ if (!reason)
+ return;
+
+ set_recovery_mode_into_vbnv(reason);
+}
+
+static void vb2_clear_recovery_reason_vbnv(void *unused)
+{
+ if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT))
+ return;
+
+ set_recovery_mode_into_vbnv(0);
+}
+
+/*
+ * Recovery reason stored in VBNV needs to be cleared before the state of VBNV
+ * is backed-up anywhere or jumping to the payload (whichever occurs
+ * first). Currently, vbnv_cmos.c backs up VBNV on POST_DEVICE. Thus, we need to
+ * make sure that the stored recovery reason is cleared off before that
+ * happens.
+ * IMPORTANT: Any reboot occurring after BS_DEV_INIT state will cause loss of
+ * recovery reason on reboot. Until now, we have seen reboots occuring on x86
+ * only in FSP stages which run before BS_DEV_INIT.
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT,
+ vb2_clear_recovery_reason_vbnv, NULL);
+
+/*
+ * Returns 0 for the stages where we know that cbmem does not come online.
+ * Even if this function returns 1 for romstage, depending upon the point in
+ * bootup, cbmem might not actually be online.
+ */
+static int cbmem_possibly_online(void)
+{
+ if (ENV_BOOTBLOCK)
+ return 0;
+
+ if (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Returns 1 if vboot is being used and currently in a stage which might have
+ * already executed vboot verification.
+ */
+static int vboot_possibly_executed(void)
+{
+ if (!IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE))
+ return 0;
+
+ if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) {
+ if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
+ return 0;
+ return 1;
+ }
+
+ if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) {
+ if (ENV_BOOTBLOCK)
+ return 0;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * vb2_check_recovery_request looks up different components to identify if there
+ * is a recovery request and returns appropriate reason code:
+ * 1. Checks if recovery mode is initiated by EC. If yes, returns
+ * VB2_RECOVERY_RO_MANUAL.
+ * 2. If CONFIG_CHROMEOS is enabled, checks if recovery request is present in
+ * VBNV and returns the code read from it.
+ * 3. Checks recovery request in handoff for stages post-cbmem.
+ * 4. For non-CBMEM stages, check if vboot verification is done and look-up
+ * selected region to identify if vboot_refence library has requested recovery
+ * path. If yes, return the reason code from shared data.
+ * 5. If nothing applies, return 0 indicating no recovery request.
+ */
+int vboot_check_recovery_request(void)
+{
+ int reason = 0;
+
+ /* EC-initiated recovery. */
+ if (get_recovery_mode_switch())
+ return VB2_RECOVERY_RO_MANUAL;
+
+ /* Recovery request in VBNV. */
+ if (IS_ENABLED(CONFIG_CHROMEOS) &&
+ (reason = get_recovery_mode_from_vbnv()) != 0)
+ return reason;
+
+ /*
+ * Check recovery flag in vboot_handoff for stages post CBMEM coming
+ * online. Since for some stages there is no way to know if cbmem has
+ * already come online, try looking up handoff anyways. If it fails,
+ * flow will fallback to looking up shared data.
+ */
+ if (cbmem_possibly_online() &&
+ ((reason = vboot_handoff_get_recovery_reason()) != 0))
+ return reason;
+
+ /*
+ * For stages where CBMEM might not be online, identify if vboot
+ * verification is already complete and no slot was selected
+ * i.e. recovery path was requested.
+ */
+ if (vboot_possibly_executed() && vb2_logic_executed() &&
+ !vb2_is_slot_selected())
+ return vb2_get_recovery_reason_shared_data();
+
+ return 0;
+}
diff --git a/src/vendorcode/google/vboot2/secdata_mock.c b/src/vendorcode/google/vboot2/secdata_mock.c
new file mode 100644
index 0000000..03616c1
--- /dev/null
+++ b/src/vendorcode/google/vboot2/secdata_mock.c
@@ -0,0 +1,38 @@
+/* Copyright (c) 2015 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 <antirollback.h>
+#include <stdlib.h>
+#include <vb2_api.h>
+
+uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
+ enum vb2_pcr_digest which_digest)
+{
+ return TPM_SUCCESS;
+}
+
+uint32_t tpm_clear_and_reenable(void)
+{
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
+{
+ vb2api_secdata_create(ctx);
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
+{
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_lock_space_firmware()
+{
+ return TPM_SUCCESS;
+}
diff --git a/src/vendorcode/google/vboot2/symbols.h b/src/vendorcode/google/vboot2/symbols.h
new file mode 100644
index 0000000..a11e474
--- /dev/null
+++ b/src/vendorcode/google/vboot2/symbols.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 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.
+ */
+
+#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
diff --git a/src/vendorcode/google/vboot2/vboot_common.c b/src/vendorcode/google/vboot2/vboot_common.c
new file mode 100644
index 0000000..854dff6
--- /dev/null
+++ b/src/vendorcode/google/vboot2/vboot_common.c
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#include <boot/coreboot_tables.h>
+#include <boot_device.h>
+#include <cbmem.h>
+#include <console/cbmem_console.h>
+#include <console/console.h>
+#include <fmap.h>
+#include <reset.h>
+#include <rules.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "vboot_common.h"
+
+int vboot_named_region_device(const char *name, struct region_device *rdev)
+{
+ return fmap_locate_area_as_rdev(name, rdev);
+}
+
+/* ========================== VBOOT HANDOFF APIs =========================== */
+int vboot_get_handoff_info(void **addr, uint32_t *size)
+{
+ /*
+ * vboot_handoff is present only after cbmem comes online. If we are in
+ * pre-ram stage, then bail out early.
+ */
+ if (ENV_BOOTBLOCK ||
+ (ENV_VERSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)))
+ return -1;
+
+ struct vboot_handoff *vboot_handoff;
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return -1;
+
+ *addr = vboot_handoff;
+
+ if (size)
+ *size = sizeof(*vboot_handoff);
+ return 0;
+}
+
+static int vboot_get_handoff_flag(uint32_t flag)
+{
+ struct vboot_handoff *vbho;
+
+ /*
+ * If vboot_handoff cannot be found, return default value of flag as 0.
+ */
+ if (vboot_get_handoff_info((void **)&vbho, NULL))
+ return 0;
+
+ return !!(vbho->init_params.out_flags & flag);
+}
+
+int vboot_handoff_skip_display_init(void)
+{
+ return !vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DISPLAY);
+}
+
+int vboot_handoff_check_developer_flag(void)
+{
+ return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DEVELOPER);
+}
+
+int vboot_handoff_check_recovery_flag(void)
+{
+ return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_RECOVERY);
+}
+
+int vboot_handoff_get_recovery_reason(void)
+{
+ struct vboot_handoff *vbho;
+ VbSharedDataHeader *sd;
+
+ if (vboot_get_handoff_info((void **)&vbho, NULL))
+ return 0;
+
+ sd = (VbSharedDataHeader *)vbho->shared_data;
+
+ return sd->recovery_reason;
+}
+
+/* ============================ VBOOT REBOOT ============================== */
+void __attribute__((weak)) vboot_platform_prepare_reboot(void)
+{
+}
+
+void vboot_reboot(void)
+{
+ if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
+ cbmem_dump_console();
+ vboot_platform_prepare_reboot();
+ hard_reset();
+ die("failed to reboot");
+}
diff --git a/src/vendorcode/google/vboot2/vboot_common.h b/src/vendorcode/google/vboot2/vboot_common.h
new file mode 100644
index 0000000..249d83a
--- /dev/null
+++ b/src/vendorcode/google/vboot2/vboot_common.h
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+#ifndef VBOOT_COMMON_H
+#define VBOOT_COMMON_H
+
+#include <commonlib/region.h>
+#include <stdint.h>
+#include <vboot_api.h>
+#include <vboot_struct.h>
+
+/* Locate vboot area by name. Returns 0 on success and -1 on error. */
+int vboot_named_region_device(const char *name, struct region_device *rdev);
+
+/*
+ * Function to check if there is a request to enter recovery mode. Returns
+ * reason code if request to enter recovery mode is present, otherwise 0.
+ */
+int vboot_check_recovery_request(void);
+
+/* ========================== VBOOT HANDOFF APIs =========================== */
+/*
+ * The vboot_handoff structure contains the data to be consumed by downstream
+ * firmware after firmware selection has been completed. Namely it provides
+ * vboot shared data as well as the flags from VbInit.
+ */
+struct vboot_handoff {
+ VbInitParams init_params;
+ uint32_t selected_firmware;
+ char shared_data[VB_SHARED_DATA_MIN_SIZE];
+} __attribute__((packed));
+
+/*
+ * vboot_get_handoff_info returns pointer to the vboot_handoff structure if
+ * available. vboot_handoff is available only after CBMEM comes online. If size
+ * is not NULL, size of the vboot_handoff structure is returned in it.
+ * Returns 0 on success and -1 on error.
+ */
+int vboot_get_handoff_info(void **addr, uint32_t *size);
+
+/*
+ * The following functions read vboot_handoff structure to obtain requested
+ * information. If vboot handoff is not available, 0 is returned by default.
+ * If vboot handoff is available:
+ * Returns 1 for flag if true
+ * Returns 0 for flag if false
+ * Returns value read for other fields
+ */
+int vboot_handoff_skip_display_init(void);
+int vboot_handoff_check_recovery_flag(void);
+int vboot_handoff_check_developer_flag(void);
+int vboot_handoff_get_recovery_reason(void);
+
+/* ============================ VBOOT REBOOT ============================== */
+/*
+ * vboot_reboot handles the reboot requests made by vboot_reference library. It
+ * allows the platform to run any preparation steps before the reboot and then
+ * does a hard reset.
+ */
+void vboot_reboot(void);
+
+/* Allow the platform to do any clean up work when vboot requests a reboot. */
+void vboot_platform_prepare_reboot(void);
+
+/* ============================ VBOOT RESUME ============================== */
+/*
+ * Save the provided hash digest to a secure location to check against in
+ * the resume path. Returns 0 on success, < 0 on error.
+ */
+int vboot_save_hash(void *digest, size_t digest_size);
+
+/*
+ * Retrieve the previously saved hash digest. Returns 0 on success,
+ * < 0 on error.
+ */
+int vboot_retrieve_hash(void *digest, size_t digest_size);
+
+/*
+ * Determine if the platform is resuming from suspend. Returns 0 when
+ * not resuming, > 0 if resuming, and < 0 on error.
+ */
+int vboot_platform_is_resuming(void);
+
+/* ============================= VERSTAGE ================================== */
+/*
+ * Main logic for verified boot. verstage() is the stage entry point
+ * while the verstage_main() is just the core logic.
+ */
+void verstage_main(void);
+void verstage(void);
+void verstage_mainboard_init(void);
+
+#endif /* VBOOT_COMMON_H */
diff --git a/src/vendorcode/google/vboot2/vboot_handoff.c b/src/vendorcode/google/vboot2/vboot_handoff.c
new file mode 100644
index 0000000..0b597f4
--- /dev/null
+++ b/src/vendorcode/google/vboot2/vboot_handoff.c
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+#include <arch/stages.h>
+#include <assert.h>
+#include <bootmode.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 <fmap.h>
+#include <stdlib.h>
+#include <timestamp.h>
+#define NEED_VB20_INTERNALS /* TODO: remove me! */
+#include <vb2_api.h>
+#include <vboot_struct.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+#include "misc.h"
+
+/**
+ * Sets vboot_handoff based on the information in vb2_shared_data
+ */
+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);
+ vb_sd->fw_version_tpm = vb2_sd->fw_version_secdata;
+
+ if (get_write_protect_state())
+ vb_sd->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED;
+ if (get_sw_write_protect_state())
+ vb_sd->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED;
+
+ if (vb2_sd->recovery_reason) {
+ vb_sd->firmware_index = 0xFF;
+ if (vb2_sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY)
+ 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 (IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH))
+ vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
+ if (IS_ENABLED(CONFIG_EC_SOFTWARE_SYNC))
+ vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
+ if (!IS_ENABLED(CONFIG_PHYSICAL_REC_SWITCH))
+ vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
+ if (IS_ENABLED(CONFIG_VBOOT_EC_SLOW_UPDATE))
+ vb_sd->flags |= VBSD_EC_SLOW_UPDATE;
+ if (IS_ENABLED(CONFIG_VBOOT_OPROM_MATTERS)) {
+ vb_sd->flags |= VBSD_OPROM_MATTERS;
+ /*
+ * Inform vboot if the display was enabled by dev/rec
+ * mode or was requested by vboot kernel phase.
+ */
+ if (*oflags & VB_INIT_OUT_ENABLE_DISPLAY
+#if IS_ENABLED(CONFIG_CHROMEOS)
+ || vboot_wants_oprom()
+#endif
+ ) {
+ vb_sd->flags |= VBSD_OPROM_LOADED;
+ *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
+ }
+ }
+
+ /* 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;
+}
+
+void vboot_fill_handoff(void)
+{
+ struct vboot_handoff *vh;
+ struct vb2_shared_data *sd;
+
+ sd = vb2_get_shared_data();
+ 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);
+
+ /*
+ * The recovery mode switch is cleared (typically backed by EC) here
+ * to allow multiple queries to get_recovery_mode_switch() and have
+ * them return consistent results during the verified boot path as well
+ * as dram initialization. x86 systems ignore the saved dram settings
+ * in the recovery path in order to start from a clean slate. Therefore
+ * clear the state here since this function is called when memory
+ * is known to be up.
+ */
+ clear_recovery_mode_switch();
+}
+
+/*
+ * For platforms that employ VBOOT_DYNAMIC_WORK_BUFFER, the vboot
+ * verification doesn't happen until after cbmem is brought online.
+ * Therefore, the vboot results would not be initialized so don't
+ * automatically add results when cbmem comes online.
+ */
+#if !IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)
+static void vb2_fill_handoff_cbmem(int unused)
+{
+ vboot_fill_handoff();
+}
+ROMSTAGE_CBMEM_INIT_HOOK(vb2_fill_handoff_cbmem)
+#endif
diff --git a/src/vendorcode/google/vboot2/vboot_loader.c b/src/vendorcode/google/vboot2/vboot_loader.c
new file mode 100644
index 0000000..b106e18
--- /dev/null
+++ b/src/vendorcode/google/vboot2/vboot_loader.c
@@ -0,0 +1,160 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/early_variables.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <rmodule.h>
+#include <rules.h>
+#include <string.h>
+
+#include "misc.h"
+#include "symbols.h"
+#include "vboot_common.h"
+
+/* The stage loading code is compiled and entered from multiple stages. The
+ * helper functions below attempt to provide more clarity on when certain
+ * code should be called. */
+
+static int verification_should_run(void)
+{
+ if (ENV_VERSTAGE && IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
+ return 1;
+
+ if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) {
+ if (ENV_ROMSTAGE &&
+ IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
+ return 1;
+ if (ENV_BOOTBLOCK &&
+ IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+ return 1;
+ }
+
+ return 0;
+}
+
+static int verstage_should_load(void)
+{
+ if (!IS_ENABLED(CONFIG_SEPARATE_VERSTAGE))
+ return 0;
+
+ if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
+ return 1;
+
+ if (ENV_BOOTBLOCK && IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+ return 1;
+
+ return 0;
+}
+
+static int vboot_executed CAR_GLOBAL;
+
+int vb2_logic_executed(void)
+{
+ /* If this stage is supposed to run the vboot logic ensure it has been
+ * executed. */
+ if (verification_should_run() && car_get_var(vboot_executed))
+ return 1;
+
+ /* If this stage is supposed to load verstage and verstage is returning
+ * back to the calling stage check that it has been executed. */
+ if (verstage_should_load() && IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
+ if (car_get_var(vboot_executed))
+ return 1;
+
+ /* Handle all other stages post vboot execution. */
+ if (!ENV_BOOTBLOCK) {
+ if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+ return 1;
+ if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) &&
+ !ENV_ROMSTAGE)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void vboot_prepare(void)
+{
+ if (verification_should_run()) {
+ verstage_main();
+ car_set_var(vboot_executed, 1);
+ vb2_save_recovery_reason_vbnv();
+ } else if (verstage_should_load()) {
+ struct cbfsf file;
+ struct prog verstage =
+ PROG_INIT(PROG_VERSTAGE,
+ CONFIG_CBFS_PREFIX "/verstage");
+
+ printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
+
+ /* load verstage from RO */
+ if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
+ die("failed to load verstage");
+
+ cbfs_file_data(prog_rdev(&verstage), &file);
+
+ if (cbfs_prog_stage_load(&verstage))
+ die("failed to load verstage");
+
+ /* verify and select a slot */
+ prog_run(&verstage);
+
+ /* This is not actually possible to hit this condition at
+ * runtime, but this provides a hint to the compiler for dead
+ * code elimination below. */
+ if (!IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
+ return;
+
+ car_set_var(vboot_executed, 1);
+ }
+
+ /*
+ * Fill in vboot cbmem objects before moving to ramstage so all
+ * downstream users have access to vboot results. This path only
+ * applies to platforms employing VBOOT_DYNAMIC_WORK_BUFFER because
+ * cbmem comes online prior to vboot verification taking place. For
+ * other platforms the vboot cbmem objects are initialized when
+ * cbmem comes online.
+ */
+ if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_VBOOT_DYNAMIC_WORK_BUFFER)) {
+ vb2_store_selected_region();
+ vboot_fill_handoff();
+ }
+}
+
+static int vboot_locate(struct cbfs_props *props)
+{
+ struct region selected_region;
+
+ /* Don't honor vboot results until the vboot logic has run. */
+ if (!vb2_logic_executed())
+ return -1;
+
+ if (vb2_get_selected_region(&selected_region))
+ return -1;
+
+ props->offset = region_offset(&selected_region);
+ props->size = region_sz(&selected_region);
+
+ return 0;
+}
+
+const struct cbfs_locator vboot_locator = {
+ .name = "VBOOT",
+ .prepare = vboot_prepare,
+ .locate = vboot_locate,
+};
diff --git a/src/vendorcode/google/vboot2/vboot_logic.c b/src/vendorcode/google/vboot2/vboot_logic.c
new file mode 100644
index 0000000..bbd7d7d
--- /dev/null
+++ b/src/vendorcode/google/vboot2/vboot_logic.c
@@ -0,0 +1,418 @@
+/*
+ * 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.
+ */
+
+#include <antirollback.h>
+#include <arch/exception.h>
+#include <assert.h>
+#include <bootmode.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <delay.h>
+#include <string.h>
+#include <timestamp.h>
+#include <vb2_api.h>
+#include <vendorcode/google/chromeos/vbnv.h>
+
+#include "misc.h"
+
+/* The max hash size to expect is for SHA512. */
+#define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
+
+#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);
+ do_printk_va_list(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 region_device rdev;
+ const char *name;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ name = "GBB";
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ name = "VBLOCK_A";
+ else
+ name = "VBLOCK_B";
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (vboot_named_region_device(name, &rdev))
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (rdev_readat(&rdev, buf, offset, size) != size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ return VB2_SUCCESS;
+}
+
+/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
+{
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+static int handle_digest_result(void *slot_hash, size_t slot_hash_sz)
+{
+ int is_resume;
+
+ /*
+ * Nothing to do since resuming on the platform doesn't require
+ * vboot verification again.
+ */
+ if (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT))
+ return 0;
+
+ /*
+ * Assume that if vboot doesn't start in bootblock verified
+ * RW memory init code is not employed. i.e. memory init code
+ * lives in RO CBFS.
+ */
+ if (!IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+ return 0;
+
+ is_resume = vboot_platform_is_resuming();
+
+ if (is_resume > 0) {
+ uint8_t saved_hash[VBOOT_MAX_HASH_SIZE];
+ const size_t saved_hash_sz = sizeof(saved_hash);
+
+ assert(slot_hash_sz == saved_hash_sz);
+
+ printk(BIOS_DEBUG, "Platform is resuming.\n");
+
+ if (vboot_retrieve_hash(saved_hash, saved_hash_sz)) {
+ printk(BIOS_ERR, "Couldn't retrieve saved hash.\n");
+ return -1;
+ }
+
+ if (memcmp(saved_hash, slot_hash, slot_hash_sz)) {
+ printk(BIOS_ERR, "Hash mismatch on resume.\n");
+ return -1;
+ }
+ } else if (is_resume < 0)
+ printk(BIOS_ERR, "Unable to determine if platform resuming.\n");
+
+ printk(BIOS_DEBUG, "Saving vboot hash.\n");
+
+ /* Always save the hash for the current boot. */
+ if (vboot_save_hash(slot_hash, slot_hash_sz)) {
+ printk(BIOS_ERR, "Error saving vboot hash.\n");
+ /* Though this is an error don't report it up since it could
+ * lead to a reboot loop. The consequence of this is that
+ * we will most likely fail resuming because of EC issues or
+ * the hash digest not matching. */
+ return 0;
+ }
+
+ return 0;
+}
+
+static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
+{
+ uint64_t load_ts;
+ uint32_t expected_size;
+ uint8_t block[TODO_BLOCK_SIZE];
+ uint8_t hash_digest[VBOOT_MAX_HASH_SIZE];
+ const size_t hash_digest_sz = sizeof(hash_digest);
+ size_t block_size = sizeof(block);
+ size_t offset;
+ int rv;
+
+ /* Clear the full digest so that any hash digests less than the
+ * max have trailing zeros. */
+ memset(hash_digest, 0, hash_digest_sz);
+
+ /*
+ * Since loading the firmware and calculating its hash is intertwined,
+ * we use this little trick to measure them separately and pretend it
+ * was first loaded and then hashed in one piece with the timestamps.
+ * (This split won't make sense with memory-mapped media like on x86.)
+ */
+ load_ts = timestamp_get();
+ timestamp_add(TS_START_HASH_BODY, load_ts);
+
+ expected_size = region_device_sz(fw_main);
+ offset = 0;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /*
+ * Honor vboot's RW slot size. The expected size is pulled out of
+ * the preamble and obtained through vb2api_init_hash() above. By
+ * creating sub region the RW slot portion of the boot media is
+ * limited.
+ */
+ if (rdev_chain(fw_main, fw_main, 0, expected_size)) {
+ printk(BIOS_ERR, "Unable to restrict CBFS size.\n");
+ return VB2_ERROR_UNKNOWN;
+ }
+
+ /* Extend over the body */
+ while (expected_size) {
+ uint64_t temp_ts;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ temp_ts = timestamp_get();
+ if (rdev_readat(fw_main, block, offset, block_size) < 0)
+ return VB2_ERROR_UNKNOWN;
+ load_ts += timestamp_get() - temp_ts;
+
+ rv = vb2api_extend_hash(ctx, block, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ timestamp_add(TS_DONE_LOADING, load_ts);
+ timestamp_add_now(TS_DONE_HASHING);
+
+ /* Check the result (with RSA signature verification) */
+ rv = vb2api_check_hash_get_digest(ctx, hash_digest, hash_digest_sz);
+ if (rv)
+ return rv;
+
+ timestamp_add_now(TS_END_HASH_BODY);
+
+ if (handle_digest_result(hash_digest, hash_digest_sz))
+ return VB2_ERROR_UNKNOWN;
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct region_device *fw_main)
+{
+ const char *name;
+
+ if (is_slot_a(ctx))
+ name = "FW_MAIN_A";
+ else
+ name = "FW_MAIN_B";
+
+ return vboot_named_region_device(name, fw_main);
+}
+
+/**
+ * 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) &&
+ IS_ENABLED(CONFIG_CHROMEOS)) {
+ 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;
+ }
+}
+
+static uint32_t extend_pcrs(struct vb2_context *ctx)
+{
+ return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
+ tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
+}
+
+/**
+ * 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.
+ */
+void verstage_main(void)
+{
+ struct vb2_context ctx;
+ struct region_device fw_main;
+ int rv;
+
+ timestamp_add_now(TS_START_VBOOT);
+
+ /* Set up context and work buffer */
+ vb2_init_work_context(&ctx);
+
+ /* Read nvdata from a non-volatile storage. */
+ if (IS_ENABLED(CONFIG_CHROMEOS))
+ read_vbnv(ctx.nvdata);
+
+ /* Set S3 resume flag if vboot should behave differently when selecting
+ * which slot to boot. This is only relevant to vboot if the platform
+ * does verification of memory init and thus must ensure it resumes with
+ * the same slot that it booted from. */
+ if (IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) &&
+ IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) &&
+ vboot_platform_is_resuming())
+ ctx.flags |= VB2_CONTEXT_S3_RESUME;
+
+ /* 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). */
+ timestamp_add_now(TS_START_TPMINIT);
+ antirollback_read_space_firmware(&ctx);
+ timestamp_add_now(TS_END_TPMINIT);
+
+ if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
+ get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+
+ if (get_recovery_mode_switch()) {
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
+ ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
+ }
+
+ if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
+
+ if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
+ ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
+
+ /* Do early init (set up secdata and NVRAM, load GBB) */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+
+ if (rv) {
+ /*
+ * If vb2api_fw_phase1 fails, check for return value.
+ * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
+ * into recovery mode.
+ * For any other error code, save context if needed and reboot.
+ */
+ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ extend_pcrs(&ctx); /* ignore failures */
+ timestamp_add_now(TS_END_VBOOT);
+ return;
+ }
+
+ printk(BIOS_INFO, "Reboot reqested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Determine which firmware slot to boot (based on NVRAM) */
+ 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 (verify its keyblock and preamble) */
+ printk(BIOS_INFO, "Phase 3\n");
+ timestamp_add_now(TS_START_VERIFY_SLOT);
+ rv = vb2api_fw_phase3(&ctx);
+ timestamp_add_now(TS_END_VERIFY_SLOT);
+ 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();
+ }
+
+ rv = extend_pcrs(&ctx);
+ if (rv) {
+ printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
+ save_if_needed(&ctx);
+ 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(region_device_region(&fw_main));
+ timestamp_add_now(TS_END_VBOOT);
+}
diff --git a/src/vendorcode/google/vboot2/verstage.c b/src/vendorcode/google/vboot2/verstage.c
new file mode 100644
index 0000000..45b3035
--- /dev/null
+++ b/src/vendorcode/google/vboot2/verstage.c
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/exception.h>
+#include <arch/hlt.h>
+#include <console/console.h>
+#include <program_loading.h>
+#include "vboot_common.h"
+
+void __attribute__((weak)) verstage_mainboard_init(void)
+{
+ /* Default empty implementation. */
+}
+
+void verstage(void)
+{
+ console_init();
+ exception_init();
+ verstage_mainboard_init();
+
+ if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
+ verstage_main();
+ } else {
+ run_romstage();
+ hlt();
+ }
+}
+
+#if !IS_ENABLED(CONFIG_CHIPSET_PROVIDES_VERSTAGE_MAIN_SYMBOL)
+/* This is for boards that rely on main() for an entry point of a stage. */
+void main(void) __attribute__((alias ("verstage")));
+#endif
More information about the coreboot-gerrit
mailing list