summaryrefslogtreecommitdiff
path: root/src/vendorcode
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode')
-rw-r--r--src/vendorcode/google/chromeos/Kconfig47
-rw-r--r--src/vendorcode/google/chromeos/Makefile.inc97
-rw-r--r--src/vendorcode/google/chromeos/chromeos.c183
-rw-r--r--src/vendorcode/google/chromeos/chromeos.h99
-rw-r--r--src/vendorcode/google/chromeos/vboot1/Kconfig34
-rw-r--r--src/vendorcode/google/chromeos/vboot1/Makefile.inc74
-rw-r--r--src/vendorcode/google/chromeos/vboot1/vboot_loader.c (renamed from src/vendorcode/google/chromeos/vboot_loader.c)6
-rw-r--r--src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c (renamed from src/vendorcode/google/chromeos/vboot_wrapper.c)4
-rw-r--r--src/vendorcode/google/chromeos/vboot2/Kconfig43
-rw-r--r--src/vendorcode/google/chromeos/vboot2/Makefile.inc60
-rw-r--r--src/vendorcode/google/chromeos/vboot2/antirollback.c (renamed from src/vendorcode/google/chromeos/antirollback.c)0
-rw-r--r--src/vendorcode/google/chromeos/vboot2/common.c70
-rw-r--r--src/vendorcode/google/chromeos/vboot2/memlayout.h (renamed from src/vendorcode/google/chromeos/memlayout.h)8
-rw-r--r--src/vendorcode/google/chromeos/vboot2/misc.h72
-rw-r--r--src/vendorcode/google/chromeos/vboot2/symbols.h (renamed from src/vendorcode/google/chromeos/symbols.h)6
-rw-r--r--src/vendorcode/google/chromeos/vboot2/vboot_handoff.c (renamed from src/vendorcode/google/chromeos/vboot_handoff.c)11
-rw-r--r--src/vendorcode/google/chromeos/vboot2/verstage.c (renamed from src/vendorcode/google/chromeos/verstage.c)3
-rw-r--r--src/vendorcode/google/chromeos/vboot2/verstage.ld (renamed from src/vendorcode/google/chromeos/verstage.ld)0
-rw-r--r--src/vendorcode/google/chromeos/vboot2/verstub.c (renamed from src/vendorcode/google/chromeos/verstub.c)5
-rw-r--r--src/vendorcode/google/chromeos/vboot_common.c122
-rw-r--r--src/vendorcode/google/chromeos/vboot_common.h55
-rw-r--r--src/vendorcode/google/chromeos/vboot_handoff.h11
22 files changed, 587 insertions, 423 deletions
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 8826a148e8..62a415b813 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -94,22 +94,6 @@ config FLASHMAP_OFFSET
help
Offset of flash map in firmware image
-config VBOOT_VERIFY_FIRMWARE
- bool "Verify firmware with vboot."
- default n
- select RELOCATABLE_MODULES
- help
- Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
- and boot loader.
-
-config VBOOT2_VERIFY_FIRMWARE
- bool "Firmware Verification with vboot2"
- default n
- depends on CHROMEOS && HAVE_HARD_RESET
- help
- Enabling VBOOT2_VERIFY_FIRMWARE will use vboot2 to verify the romstage
- and boot loader.
-
config EC_SOFTWARE_SYNC
bool "Enable EC software sync"
default n
@@ -141,16 +125,6 @@ config VIRTUAL_DEV_SWITCH
help
Whether this platform has a virtual developer switch.
-config RETURN_FROM_VERSTAGE
- bool "return from verstage"
- default n
- depends on VBOOT2_VERIFY_FIRMWARE
- help
- If this is set, the verstage returns back to the bootblock instead of
- exits to the romstage so that the verstage space can be reused by the
- romstage. Useful if a ram space is too small to fit both the verstage
- and the romstage.
-
# These VBOOT_X_INDEX are the position of X in FW_MAIN_A/B region. The index
# table is created by cros_bundle_firmware at build time based on the positions
# of the blobs listed in fmap.dts and stored at the top of FW_MAIN_A/B region.
@@ -164,14 +138,6 @@ config VBOOT_BOOT_LOADER_INDEX
This is the index of the bootloader component in the verified
firmware block.
-config VBOOT_ROMSTAGE_INDEX
- hex
- default 2
- depends on VBOOT2_VERIFY_FIRMWARE
- help
- This is the index of the romstage component in the verified
- firmware block.
-
config VBOOT_RAMSTAGE_INDEX
hex "Ramstage component index"
default 1
@@ -180,14 +146,6 @@ config VBOOT_RAMSTAGE_INDEX
This is the index of the ramstage component in the verified
firmware block.
-config VBOOT_REFCODE_INDEX
- hex "Reference code firmware index"
- default 1
- depends on VBOOT_VERIFY_FIRMWARE
- help
- This is the index of the reference code component in the verified
- firmware block.
-
config NO_TPM_RESUME
bool
default n
@@ -196,5 +154,8 @@ config NO_TPM_RESUME
boards, booting Windows will break if the TPM resume command
is sent during an S3 resume.
-endif
+source src/vendorcode/google/chromeos/vboot1/Kconfig
+source src/vendorcode/google/chromeos/vboot2/Kconfig
+
+endif # CHROMEOS
endmenu
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index da1db8bc4d..fbd12fbad2 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -37,101 +37,8 @@ else
CFLAGS_common += -DMOCK_TPM=0
endif
-ifeq ($(CONFIG_VBOOT_VERIFY_FIRMWARE),y)
-romstage-y += vboot_helper.c
-ramstage-y += vboot_helper.c
-romstage-y += vboot_loader.c
-rmodules_$(ARCH-romstage-y)-y += vboot_wrapper.c
-
-ifneq ($(CONFIG_SPI_FLASH_MEMORY_MAPPED),y)
-VBOOT_MAKEFLAGS = REGION_READ=1
-endif
-
-VB_LIB = $(obj)/external/vboot_reference/vboot_fw.a
-# Currently, vboot comes into picture only during the romstage, thus
-# is compiled for being used in romstage only. Since, we are splitting
-# up all components in one of the three stages of coreboot, vboot seems
-# most logical to fall under the romstage. Thus, all references to arch
-# and other compiler stuff for vboot is using the romstage arch.
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y))
-VB_SOURCE := vboot_reference
-
-# Add the vboot include paths.
-CPPFLAGS_common += -I$(VB_SOURCE)/firmware/include
-
-VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vbootstub.elf
-VBOOT_STUB = $(VBOOT_STUB_ELF).rmod
-
-# Dependency for the vboot rmodules. Ordering matters.
-VBOOT_STUB_DEPS += $(obj)/vendorcode/google/chromeos/vboot_wrapper.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(VB_LIB)
-# Remove the '-include' option since that will break vboot's build and ensure
-# vboot_reference can get to coreboot's include files.
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_romstage) $(CPPFLAGS_romstage)))
-VBOOT_CFLAGS += -DVBOOT_DEBUG
-VBOOT_CFLAGS += $(rmodules_$(ARCH-ROMSTAGE-y)-c-ccopts)
-
-# Link the vbootstub module with a 64KiB-byte heap.
-$(eval $(call rmodule_link,$(VBOOT_STUB_ELF), $(VBOOT_STUB_DEPS), 0x10000,$(ARCH-romstage-y)))
-
-# Build vboot library without the default includes from coreboot proper.
-$(VB_LIB):
- @printf " MAKE $(subst $(obj)/,,$(@))\n"
- $(Q)$(MAKE) -C $(VB_SOURCE) \
- CC="$(CC_romstage)" \
- CFLAGS="$(VBOOT_CFLAGS)" \
- $(VBOOT_MAKEFLAGS) \
- FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
- BUILD=$(top)/$(dir $(VB_LIB)) \
- V=$(V) \
- fwlib
-
-endif
-
-ifeq ($(CONFIG_VBOOT2_VERIFY_FIRMWARE),y)
VB_SOURCE := vboot_reference
+subdirs-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot1
+subdirs-$(CONFIG_VBOOT2_VERIFY_FIRMWARE) += vboot2
CPPFLAGS_common += -I$(VB_SOURCE)/firmware/2lib/include
CPPFLAGS_common += -I$(VB_SOURCE)/firmware/include
-
-verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
-
-ifeq ($(CONFIG_RETURN_FROM_VERSTAGE),y)
-bootblock-y += verstub.c chromeos.c
-else
-verstage-y += verstub.c
-endif
-verstage-y += verstage.c fmap.c chromeos.c
-verstage-y += antirollback.c
-verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c
-verstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c
-verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c
-romstage-y += vboot_handoff.c
-
-verstage-y += verstage.ld
-
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
-VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage) $(CPPFLAGS_verstage)))
-VBOOT_CFLAGS += $(verstage-c-ccopts)
-VBOOT_CFLAGS += -include $(top)/src/include/kconfig.h -Wno-missing-prototypes
-VBOOT_CFLAGS += -DVBOOT_DEBUG
-
-$(VB2_LIB): $(obj)/config.h
- @printf " MAKE $(subst $(obj)/,,$(@))\n"
- $(Q)$(MAKE) -C $(VB_SOURCE) \
- CC="$(CC_verstage)" \
- CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \
- FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
- BUILD=$(top)/$(dir $(VB2_LIB)) \
- V=$(V) \
- fwlib2
-
-VERSTAGE_ELF = $(objcbfs)/verstage.elf
-cbfs-files-y += $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage
-fallback/verstage-file = $(VERSTAGE_ELF)
-fallback/verstage-type = stage
-fallback/verstage-compression = none
-endif # CONFIG_VBOOT2_VERIFY_FIRMWARE
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index c4d651a29b..437e128e7b 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -20,18 +20,11 @@
#include <stddef.h>
#include <string.h>
#include "chromeos.h"
-#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-#include "fmap.h"
-#include "symbols.h"
-#include "vboot_handoff.h"
-#include <reset.h>
-#endif
#include <boot/coreboot_tables.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
static int vboot_enable_developer(void)
{
struct vboot_handoff *vbho;
@@ -58,10 +51,18 @@ static int vboot_enable_recovery(void)
return !!(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_RECOVERY);
}
-#else
-static inline int vboot_enable_developer(void) { return 0; }
-static inline int vboot_enable_recovery(void) { return 0; }
-#endif
+
+int vboot_skip_display_init(void)
+{
+ struct vboot_handoff *vbho;
+
+ vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vbho == NULL)
+ return 0;
+
+ return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
+}
int developer_mode_enabled(void)
{
@@ -92,22 +93,6 @@ int __attribute__((weak)) clear_recovery_mode_switch(void)
return 0;
}
-int vboot_skip_display_init(void)
-{
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
- struct vboot_handoff *vbho;
-
- vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vbho == NULL)
- return 0;
-
- return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
-#else
- return 0;
-#endif
-}
-
#ifdef __ROMSTAGE__
void __attribute__((weak)) save_chromeos_gpios(void)
{
@@ -120,147 +105,3 @@ int __attribute((weak)) vboot_get_sw_write_protect(void)
return 0;
}
#endif
-
-#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-void vboot_locate_region(const char *name, struct vboot_region *region)
-{
- region->size = find_fmap_entry(name, (void **)&region->offset_addr);
-}
-
-void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest)
-{
- if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- if (dest != NULL)
- return memcpy(dest, (void *)offset_addr, size);
- else
- return (void *)offset_addr;
- } else {
- struct cbfs_media default_media, *media = &default_media;
- void *cache;
-
- init_default_cbfs_media(media);
- media->open(media);
- if (dest != NULL) {
- cache = dest;
- if (media->read(media, dest, offset_addr, size) != size)
- cache = NULL;
- } else {
- cache = media->map(media, offset_addr, size);
- if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS)
- cache = NULL;
- }
- media->close(media);
- return cache;
- }
-}
-
-int vboot_get_handoff_info(void **addr, uint32_t *size)
-{
- struct vboot_handoff *vboot_handoff;
-
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return -1;
-
- *addr = vboot_handoff;
- *size = sizeof(*vboot_handoff);
- return 0;
-}
-
-/* This will leak a mapping of a fw region */
-struct vboot_components *vboot_locate_components(struct vboot_region *region)
-{
- size_t req_size;
- struct vboot_components *vbc;
-
- req_size = sizeof(*vbc);
- req_size += sizeof(struct vboot_component_entry) *
- MAX_PARSED_FW_COMPONENTS;
-
- vbc = vboot_get_region(region->offset_addr, req_size, NULL);
- if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
- vbc = NULL;
-
- return vbc;
-}
-
-void *vboot_get_payload(int *len)
-{
- struct vboot_handoff *vboot_handoff;
- struct firmware_component *fwc;
-
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return NULL;
-
- if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid boot loader index: %d\n",
- CONFIG_VBOOT_BOOT_LOADER_INDEX);
- return NULL;
- }
-
- fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX];
-
- /* If payload size is zero fall back to cbfs path. */
- if (fwc->size == 0)
- return NULL;
-
- if (len != NULL)
- *len = fwc->size;
-
- printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n",
- fwc->size, fwc->address);
-
- /* This will leak a mapping. */
- return vboot_get_region(fwc->address, fwc->size, NULL);
-}
-#endif
-
-#if CONFIG_VBOOT2_VERIFY_FIRMWARE
-void *vboot_load_stage(int stage_index,
- struct vboot_region *fw_main,
- struct vboot_components *fw_info)
-{
- struct cbfs_media default_media, *media = &default_media;
- uintptr_t fc_addr;
- uint32_t fc_size;
- void *entry;
-
- if (stage_index >= fw_info->num_components) {
- printk(BIOS_INFO, "invalid stage index\n");
- return NULL;
- }
-
- fc_addr = fw_main->offset_addr + fw_info->entries[stage_index].offset;
- fc_size = fw_info->entries[stage_index].size;
- if (fc_size == 0 ||
- fc_addr + fc_size > fw_main->offset_addr + fw_main->size) {
- printk(BIOS_INFO, "invalid stage address or size\n");
- return NULL;
- }
-
- init_default_cbfs_media(media);
-
- /* we're making cbfs access offset outside of the region managed by
- * cbfs. this works because cbfs_load_stage_by_offset does not check
- * the offset. */
- entry = cbfs_load_stage_by_offset(media, fc_addr);
- if (entry == (void *)-1)
- entry = NULL;
- return entry;
-}
-
-struct vb2_working_data * const vboot_get_working_data(void)
-{
- return (struct vb2_working_data *)_vboot2_work;
-}
-
-void vboot_reboot(void)
-{
- hard_reset();
- die("failed to reboot");
-}
-
-#endif
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index ed6c75bd57..5ba54571a5 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -23,6 +23,8 @@
#include <stddef.h>
#include <stdint.h>
#include <bootmode.h>
+#include "vboot_common.h"
+#include "vboot2/misc.h"
/*for mainboard use only*/
void setup_chromeos_gpios(void);
@@ -47,54 +49,14 @@ static inline void elog_add_boot_reason(void) { return; }
struct romstage_handoff;
-/* TODO(shawnn): Remove these CONFIGs and define default weak functions
- * that can be overridden in the platform / MB code. */
#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-struct vboot_region {
- uintptr_t offset_addr;
- int32_t size;
-};
-
-/*
- * The vboot handoff structure keeps track of a maximum number of firmware
- * components in the verfieid RW area of flash. This is not a restriction on
- * the number of components packed in a firmware block. It's only the maximum
- * number of parsed firmware components (address and size) included in the
- * handoff structure.
- */
-#define MAX_PARSED_FW_COMPONENTS 5
-
-/* The FW areas consist of multiple components. At the beginning of
- * each area is the number of total compoments as well as the size and
- * offset for each component. One needs to caculate the total size of the
- * signed firmware region based off of the embedded metadata. */
-struct vboot_component_entry {
- uint32_t offset;
- uint32_t size;
-} __attribute__((packed));
-
-struct vboot_components {
- uint32_t num_components;
- struct vboot_component_entry entries[0];
-} __attribute__((packed));
-
-void vboot_locate_region(const char *name, struct vboot_region *region);
-
-struct vboot_components *vboot_locate_components(struct vboot_region *region);
-
-/*
- * This is a dual purpose routine. If dest is non-NULL the region at
- * offset_addr will be read into the area pointed to by dest. If dest
- * is NULL,the region will be mapped to a memory location. NULL is
- * returned on error else the location of the requested region.
- */
-void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest);
/* Returns 0 on success < 0 on error. */
int vboot_get_handoff_info(void **addr, uint32_t *size);
int vboot_enable_developer(void);
int vboot_enable_recovery(void);
int vboot_skip_display_init(void);
-#else
+void *vboot_get_payload(int *len);
+#else /* CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE */
static inline void vboot_verify_firmware(struct romstage_handoff *h) {}
static inline void *vboot_get_payload(int *len) { return NULL; }
static inline int vboot_get_handoff_info(void **addr, uint32_t *size)
@@ -121,55 +83,4 @@ static inline void chromeos_ram_oops_init(chromeos_acpi_t *chromeos) {}
static inline void chromeos_reserve_ram_oops(struct device *dev, int idx) {}
#endif /* CONFIG_CHROMEOS_RAMOOPS */
-void vboot2_verify_firmware(void);
-
-#if CONFIG_VBOOT2_VERIFY_FIRMWARE
-void *vboot_load_ramstage(void);
-void verstage_main(void);
-void *vboot_load_stage(int stage_index,
- struct vboot_region *fw_main,
- struct vboot_components *fw_info);
-void vboot_reboot(void);
-
-/*
- * this is placed at the start of the vboot work buffer. selected_region is used
- * for the verstage to return the location of the selected slot. buffer is used
- * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
- * stage boundaries.
- */
-struct vb2_working_data {
- uint32_t selected_region_offset;
- uint32_t selected_region_size;
- uint64_t buffer_size;
- uint64_t buffer;
-};
-
-struct vb2_working_data * const vboot_get_working_data(void);
-
-static inline void vb2_get_selected_region(struct vb2_working_data *wd,
- struct vboot_region *region)
-{
- region->offset_addr = wd->selected_region_offset;
- region->size = wd->selected_region_size;
-}
-
-static inline void vb2_set_selected_region(struct vb2_working_data *wd,
- struct vboot_region *region)
-{
- wd->selected_region_offset = region->offset_addr;
- wd->selected_region_size = region->size;
-}
-
-static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
-{
- return wd->selected_region_size > 0;
-}
-
-static inline int vboot_is_readonly_path(struct vb2_working_data *wd)
-{
- return wd->selected_region_size == 0;
-}
-
-#endif /* CONFIG_VBOOT2_VERIFY_FIRMWARE */
-
-#endif
+#endif /* __CHROMEOS_H__ */
diff --git a/src/vendorcode/google/chromeos/vboot1/Kconfig b/src/vendorcode/google/chromeos/vboot1/Kconfig
new file mode 100644
index 0000000000..0102869797
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/Kconfig
@@ -0,0 +1,34 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config VBOOT_VERIFY_FIRMWARE
+ bool "Verify firmware with vboot."
+ default n
+ depends on CHROMEOS
+ select RELOCATABLE_MODULES
+ help
+ Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
+ and boot loader.
+
+config VBOOT_REFCODE_INDEX
+ hex "Reference code firmware index"
+ default 1
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ This is the index of the reference code component in the verified
+ firmware block.
diff --git a/src/vendorcode/google/chromeos/vboot1/Makefile.inc b/src/vendorcode/google/chromeos/vboot1/Makefile.inc
new file mode 100644
index 0000000000..a2d42b45f3
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/Makefile.inc
@@ -0,0 +1,74 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+ramstage-y += ../vboot_common.c
+romstage-y += vboot_loader.c ../vboot_common.c
+rmodules_$(ARCH-ROMSTAGE-y)-y += vboot_wrapper.c ../vboot_common.c
+
+ifneq ($(CONFIG_SPI_FLASH_MEMORY_MAPPED),y)
+VBOOT_MAKEFLAGS = REGION_READ=1
+endif
+
+VB_LIB = $(obj)/external/vboot_reference/vboot_fw.a
+# Currently, vboot comes into picture only during the romstage, thus
+# is compiled for being used in romstage only. Since, we are splitting
+# up all components in one of the three stages of coreboot, vboot seems
+# most logical to fall under the romstage. Thus, all references to arch
+# and other compiler stuff for vboot is using the romstage arch.
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-ROMSTAGE-y))
+
+VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vboot1/vbootstub.elf
+VBOOT_STUB = $(VBOOT_STUB_ELF).rmod
+
+# Dependency for the vboot rmodules. Ordering matters.
+VBOOT_STUB_DEPS += $(obj)/vendorcode/google/chromeos/vboot1/vboot_wrapper.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules_$(ARCH-ROMSTAGE-y).o
+ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32),y)
+VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules_$(ARCH-ROMSTAGE-y).o
+endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM),y)
+VBOOT_STUB_DEPS += $(obj)/arch/arm/memset.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/arch/arm/memcpy.rmodules_$(ARCH-ROMSTAGE-y).o
+endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM64),y)
+VBOOT_STUB_DEPS += $(obj)/lib/memset.rmodules.o
+VBOOT_STUB_DEPS += $(obj)/lib/memcpy.rmodules.o
+endif
+VBOOT_STUB_DEPS += $(VB_LIB)
+# Remove the '-include' option since that will break vboot's build and ensure
+# vboot_reference can get to coreboot's include files.
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_romstage)))
+VBOOT_CFLAGS += -DVBOOT_DEBUG
+VBOOT_CFLAGS += $(rmodules_$(ARCH-ROMSTAGE-y)-c-ccopts)
+
+# Link the vbootstub module with a 64KiB-byte heap.
+$(eval $(call rmodule_link,$(VBOOT_STUB_ELF), $(VBOOT_STUB_DEPS), 0x10000,$(ARCH-ROMSTAGE-y)))
+
+# Build vboot library without the default includes from coreboot proper.
+$(VB_LIB):
+ @printf " MAKE $(subst $(obj)/,,$(@))\n"
+ $(Q)FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
+ CC="$(CC_romstage)" \
+ CFLAGS="$(VBOOT_CFLAGS)" \
+ $(MAKE) -C $(VB_SOURCE) \
+ $(VBOOT_MAKEFLAGS) \
+ BUILD=$(top)/$(dir $(VB_LIB)) \
+ V=$(V) \
+ fwlib
diff --git a/src/vendorcode/google/chromeos/vboot_loader.c b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
index d13608c50e..0353a3a08e 100644
--- a/src/vendorcode/google/chromeos/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
@@ -33,9 +33,9 @@
#include <string.h>
#include <stdlib.h>
#include <timestamp.h>
-#include "chromeos.h"
-#include "vboot_context.h"
-#include "vboot_handoff.h"
+#include "../chromeos.h"
+#include "../vboot_context.h"
+#include "../vboot_handoff.h"
#define TEMP_CBMEM_ID_VBOOT 0xffffffff
#define TEMP_CBMEM_ID_VBLOCKS 0xfffffffe
diff --git a/src/vendorcode/google/chromeos/vboot_wrapper.c b/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c
index dd6065cb81..5b9dbbbb31 100644
--- a/src/vendorcode/google/chromeos/vboot_wrapper.c
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c
@@ -25,8 +25,8 @@
#include <rmodule.h>
#include <stdlib.h>
#include <string.h>
-#include "vboot_context.h"
-#include "vboot_handoff.h"
+#include "../vboot_context.h"
+#include "../vboot_handoff.h"
/* Keep a global context pointer around for the callbacks to use. */
static struct vboot_context *gcontext;
diff --git a/src/vendorcode/google/chromeos/vboot2/Kconfig b/src/vendorcode/google/chromeos/vboot2/Kconfig
new file mode 100644
index 0000000000..20d2f1fc85
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/Kconfig
@@ -0,0 +1,43 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config VBOOT2_VERIFY_FIRMWARE
+ bool "Firmware Verification with vboot2"
+ default n
+ depends on CHROMEOS && HAVE_HARD_RESET
+ help
+ Enabling VBOOT2_VERIFY_FIRMWARE will use vboot2 to verify the romstage
+ and boot loader.
+
+config RETURN_FROM_VERSTAGE
+ bool "return from verstage"
+ default n
+ depends on VBOOT2_VERIFY_FIRMWARE
+ help
+ If this is set, the verstage returns back to the bootblock instead of
+ exits to the romstage so that the verstage space can be reused by the
+ romstage. Useful if a ram space is too small to fit both the verstage
+ and the romstage.
+
+config VBOOT_ROMSTAGE_INDEX
+ hex
+ default 2
+ depends on VBOOT2_VERIFY_FIRMWARE
+ help
+ This is the index of the romstage component in the verified
+ firmware block.
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
new file mode 100644
index 0000000000..3c07a5129e
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -0,0 +1,60 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
+
+ramstage-y += ../vboot_common.c
+romstage-y += ../vboot_common.c
+
+ifeq ($(CONFIG_RETURN_FROM_VERSTAGE),y)
+bootblock-y += common.c verstub.c ../chromeos.c ../vboot_common.c
+else
+verstage-y += verstub.c
+endif
+verstage-y += verstage.c ../fmap.c ../chromeos.c ../vboot_common.c
+verstage-y += antirollback.c common.c
+verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += ../vbnv_cmos.c
+verstage-$(CONFIG_CHROMEOS_VBNV_EC) += ../vbnv_ec.c
+verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += ../vbnv_flash.c
+romstage-y += vboot_handoff.c common.c
+
+verstage-y += verstage.ld
+
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
+VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage)))
+VBOOT_CFLAGS += $(verstage-c-ccopts)
+VBOOT_CFLAGS += -include $(top)/src/include/kconfig.h -Wno-missing-prototypes
+VBOOT_CFLAGS += -DVBOOT_DEBUG
+
+$(VB2_LIB): $(obj)/config.h
+ @printf " MAKE $(subst $(obj)/,,$(@))\n"
+ $(Q)FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
+ CC="$(CC_verstage)" \
+ CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \
+ $(MAKE) -C $(VB_SOURCE) \
+ BUILD=$(top)/$(dir $(VB2_LIB)) \
+ V=$(V) \
+ fwlib2
+
+VERSTAGE_ELF = $(objcbfs)/verstage.elf
+cbfs-files-y += $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage
+fallback/verstage-file = $(VERSTAGE_ELF)
+fallback/verstage-type = stage
+fallback/verstage-compression = none
diff --git a/src/vendorcode/google/chromeos/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
index bb547b51bc..bb547b51bc 100644
--- a/src/vendorcode/google/chromeos/antirollback.c
+++ b/src/vendorcode/google/chromeos/vboot2/antirollback.c
diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c
new file mode 100644
index 0000000000..178e8b53f1
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/common.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbfs.h>
+#include <console/console.h>
+#include <reset.h>
+#include "../chromeos.h"
+#include "../vboot_handoff.h"
+#include "misc.h"
+#include "symbols.h"
+
+void *vboot_load_stage(int stage_index,
+ struct vboot_region *fw_main,
+ struct vboot_components *fw_info)
+{
+ struct cbfs_media default_media, *media = &default_media;
+ uintptr_t fc_addr;
+ uint32_t fc_size;
+ void *entry;
+
+ if (stage_index >= fw_info->num_components) {
+ printk(BIOS_INFO, "invalid stage index\n");
+ return NULL;
+ }
+
+ fc_addr = fw_main->offset_addr + fw_info->entries[stage_index].offset;
+ fc_size = fw_info->entries[stage_index].size;
+ if (fc_size == 0 ||
+ fc_addr + fc_size > fw_main->offset_addr + fw_main->size) {
+ printk(BIOS_INFO, "invalid stage address or size\n");
+ return NULL;
+ }
+
+ init_default_cbfs_media(media);
+
+ /* we're making cbfs access offset outside of the region managed by
+ * cbfs. this works because cbfs_load_stage_by_offset does not check
+ * the offset. */
+ entry = cbfs_load_stage_by_offset(media, fc_addr);
+ if (entry == (void *)-1)
+ entry = NULL;
+ return entry;
+}
+
+struct vb2_working_data * const vboot_get_working_data(void)
+{
+ return (struct vb2_working_data *)_vboot2_work;
+}
+
+void vboot_reboot(void)
+{
+ hard_reset();
+ die("failed to reboot");
+}
diff --git a/src/vendorcode/google/chromeos/memlayout.h b/src/vendorcode/google/chromeos/vboot2/memlayout.h
index 468f746775..9e1920039d 100644
--- a/src/vendorcode/google/chromeos/memlayout.h
+++ b/src/vendorcode/google/chromeos/vboot2/memlayout.h
@@ -19,8 +19,8 @@
/* This file contains macro definitions for memlayout.ld linker scripts. */
-#ifndef __CHROMEOS_MEMLAYOUT_H
-#define __CHROMEOS_MEMLAYOUT_H
+#ifndef __CHROMEOS_VBOOT2_MEMLAYOUT_H
+#define __CHROMEOS_VBOOT2_MEMLAYOUT_H
#define VBOOT2_WORK(addr, size) \
REGION(vboot2_work, addr, size, 4) \
@@ -31,7 +31,7 @@
SET_COUNTER(VERSTAGE, addr) \
_ = ASSERT(_everstage - _verstage <= sz, \
STR(Verstage exceeded its allotted size! (sz))); \
- INCLUDE "vendorcode/google/chromeos/verstage.verstage.ld"
+ INCLUDE "vendorcode/google/chromeos/vboot2/verstage.verstage.ld"
#else
#define VERSTAGE(addr, sz) \
SET_COUNTER(VERSTAGE, addr) \
@@ -44,4 +44,4 @@
#define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) ROMSTAGE(addr, size)
#endif
-#endif /* __CHROMEOS_MEMLAYOUT_H */
+#endif /* __CHROMEOS_VBOOT2_MEMLAYOUT_H */
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
new file mode 100644
index 0000000000..cae302bc1f
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CHROMEOS_VBOOT2_MISC_H__
+#define __CHROMEOS_VBOOT2_MISC_H__
+
+#include "../vboot_common.h"
+
+void vboot2_verify_firmware(void);
+void *vboot2_load_ramstage(void);
+void verstage_main(void);
+void *vboot_load_stage(int stage_index,
+ struct vboot_region *fw_main,
+ struct vboot_components *fw_info);
+void vboot_reboot(void);
+
+/*
+ * this is placed at the start of the vboot work buffer. selected_region is used
+ * for the verstage to return the location of the selected slot. buffer is used
+ * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
+ * stage boundaries.
+ */
+struct vb2_working_data {
+ uint32_t selected_region_offset;
+ uint32_t selected_region_size;
+ uint64_t buffer_size;
+ uint64_t buffer;
+};
+
+struct vb2_working_data * const vboot_get_working_data(void);
+
+static inline void vb2_get_selected_region(struct vb2_working_data *wd,
+ struct vboot_region *region)
+{
+ region->offset_addr = wd->selected_region_offset;
+ region->size = wd->selected_region_size;
+}
+
+static inline void vb2_set_selected_region(struct vb2_working_data *wd,
+ struct vboot_region *region)
+{
+ wd->selected_region_offset = region->offset_addr;
+ wd->selected_region_size = region->size;
+}
+
+static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
+{
+ return wd->selected_region_size > 0;
+}
+
+static inline int vboot_is_readonly_path(struct vb2_working_data *wd)
+{
+ return wd->selected_region_size == 0;
+}
+
+#endif /* __CHROMEOS_VBOOT2_MISC_H__ */
diff --git a/src/vendorcode/google/chromeos/symbols.h b/src/vendorcode/google/chromeos/vboot2/symbols.h
index 21169f0b3a..fda7114853 100644
--- a/src/vendorcode/google/chromeos/symbols.h
+++ b/src/vendorcode/google/chromeos/vboot2/symbols.h
@@ -17,8 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
*/
-#ifndef __CHROMEOS_SYMBOLS_H
-#define __CHROMEOS_SYMBOLS_H
+#ifndef __CHROMEOS_VBOOT2_SYMBOLS_H
+#define __CHROMEOS_VBOOT2_SYMBOLS_H
extern u8 _vboot2_work[];
extern u8 _evboot2_work[];
@@ -29,4 +29,4 @@ extern u8 _verstage[];
extern u8 _everstage[];
#define _verstage_size (_everstage - _verstage)
-#endif /* __CHROMEOS_SYMBOLS_H */
+#endif /* __CHROMEOS_VBOOT2_SYMBOLS_H */
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
index f929a59a29..a8573d0c88 100644
--- a/src/vendorcode/google/chromeos/vboot_handoff.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -30,10 +30,11 @@
#include <console/vtxprintf.h>
#include <stdlib.h>
#include <timestamp.h>
-#include "chromeos.h"
-#include "fmap.h"
-#include "vboot_handoff.h"
#include <vboot_struct.h>
+#include "../chromeos.h"
+#include "../fmap.h"
+#include "../vboot_handoff.h"
+#include "misc.h"
static void *load_ramstage(struct vboot_handoff *vboot_handoff,
struct vboot_region *fw_main)
@@ -115,7 +116,7 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
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 +
+ 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;
@@ -139,7 +140,7 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
/**
* Load ramstage and return the entry point
*/
-void *vboot_load_ramstage(void)
+void *vboot2_load_ramstage(void)
{
struct vboot_handoff *vh;
struct vb2_shared_data *sd;
diff --git a/src/vendorcode/google/chromeos/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
index 1b42bb6830..572e161825 100644
--- a/src/vendorcode/google/chromeos/verstage.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -24,7 +24,8 @@
#include <console/vtxprintf.h>
#include <string.h>
-#include "chromeos.h"
+#include "../chromeos.h"
+#include "misc.h"
#define TODO_BLOCK_SIZE 1024
diff --git a/src/vendorcode/google/chromeos/verstage.ld b/src/vendorcode/google/chromeos/vboot2/verstage.ld
index c7fd6462a3..c7fd6462a3 100644
--- a/src/vendorcode/google/chromeos/verstage.ld
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.ld
diff --git a/src/vendorcode/google/chromeos/verstub.c b/src/vendorcode/google/chromeos/vboot2/verstub.c
index eb91c22977..e8faa071c5 100644
--- a/src/vendorcode/google/chromeos/verstub.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstub.c
@@ -21,7 +21,8 @@
#include <cbfs.h>
#include <console/console.h>
#include <string.h>
-#include "chromeos.h"
+#include "../chromeos.h"
+#include "misc.h"
#include "symbols.h"
static struct vb2_working_data *init_vb2_working_data(void)
@@ -33,7 +34,7 @@ static struct vb2_working_data *init_vb2_working_data(void)
/* 8-byte alignment for ARMv7 */
wd->buffer = ALIGN_UP((uintptr_t)&wd[1], 8);
wd->buffer_size = _vboot2_work_size + (uintptr_t)wd
- - (uintptr_t)wd->buffer;
+ - (uintptr_t)wd->buffer;
return wd;
}
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
new file mode 100644
index 0000000000..b2893d9fa9
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot_common.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <boot/coreboot_tables.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include "chromeos.h"
+#include "vboot_common.h"
+
+void vboot_locate_region(const char *name, struct vboot_region *region)
+{
+ region->size = find_fmap_entry(name, (void **)&region->offset_addr);
+}
+
+void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest)
+{
+ if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ if (dest != NULL)
+ return memcpy(dest, (void *)offset_addr, size);
+ else
+ return (void *)offset_addr;
+ } else {
+ struct cbfs_media default_media, *media = &default_media;
+ void *cache;
+
+ init_default_cbfs_media(media);
+ media->open(media);
+ if (dest != NULL) {
+ cache = dest;
+ if (media->read(media, dest, offset_addr, size) != size)
+ cache = NULL;
+ } else {
+ cache = media->map(media, offset_addr, size);
+ if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS)
+ cache = NULL;
+ }
+ media->close(media);
+ return cache;
+ }
+}
+
+int vboot_get_handoff_info(void **addr, uint32_t *size)
+{
+ struct vboot_handoff *vboot_handoff;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return -1;
+
+ *addr = vboot_handoff;
+ *size = sizeof(*vboot_handoff);
+ return 0;
+}
+
+/* This will leak a mapping of a fw region */
+struct vboot_components *vboot_locate_components(struct vboot_region *region)
+{
+ size_t req_size;
+ struct vboot_components *vbc;
+
+ req_size = sizeof(*vbc);
+ req_size += sizeof(struct vboot_component_entry) *
+ MAX_PARSED_FW_COMPONENTS;
+
+ vbc = vboot_get_region(region->offset_addr, req_size, NULL);
+ if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
+ vbc = NULL;
+
+ return vbc;
+}
+
+void *vboot_get_payload(int *len)
+{
+ struct vboot_handoff *vboot_handoff;
+ struct firmware_component *fwc;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return NULL;
+
+ if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid boot loader index: %d\n",
+ CONFIG_VBOOT_BOOT_LOADER_INDEX);
+ return NULL;
+ }
+
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX];
+
+ /* If payload size is zero fall back to cbfs path. */
+ if (fwc->size == 0)
+ return NULL;
+
+ if (len != NULL)
+ *len = fwc->size;
+
+ printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n",
+ fwc->size, fwc->address);
+
+ /* This will leak a mapping. */
+ return vboot_get_region(fwc->address, fwc->size, NULL);
+}
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
new file mode 100644
index 0000000000..c6c9b50419
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef VBOOT_COMMON_H
+#define VBOOT_COMMON_H
+
+#include <stdint.h>
+
+struct vboot_region {
+ uintptr_t offset_addr;
+ int32_t size;
+};
+
+/* The FW areas consist of multiple components. At the beginning of
+ * each area is the number of total compoments as well as the size and
+ * offset for each component. One needs to caculate the total size of the
+ * signed firmware region based off of the embedded metadata. */
+struct vboot_component_entry {
+ uint32_t offset;
+ uint32_t size;
+} __attribute__((packed));
+
+struct vboot_components {
+ uint32_t num_components;
+ struct vboot_component_entry entries[0];
+} __attribute__((packed));
+
+void vboot_locate_region(const char *name, struct vboot_region *region);
+
+struct vboot_components *vboot_locate_components(struct vboot_region *region);
+
+/*
+ * This is a dual purpose routine. If dest is non-NULL the region at
+ * offset_addr will be read into the area pointed to by dest. If dest
+ * is NULL,the region will be mapped to a memory location. NULL is
+ * returned on error else the location of the requested region.
+ */
+void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest);
+
+#endif /* VBOOT_COMMON_H */
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.h b/src/vendorcode/google/chromeos/vboot_handoff.h
index b0017438ac..e6b2d6931d 100644
--- a/src/vendorcode/google/chromeos/vboot_handoff.h
+++ b/src/vendorcode/google/chromeos/vboot_handoff.h
@@ -19,9 +19,20 @@
#ifndef VBOOT_HANDOFF_H
#define VBOOT_HANDOFF_H
+
#include <vboot_api.h>
#include <vboot_struct.h>
#include "chromeos.h"
+#include "vboot_common.h"
+
+/*
+ * The vboot handoff structure keeps track of a maximum number of firmware
+ * components in the verfieid RW area of flash. This is not a restriction on
+ * the number of components packed in a firmware block. It's only the maximum
+ * number of parsed firmware components (address and size) included in the
+ * handoff structure.
+ */
+#define MAX_PARSED_FW_COMPONENTS 5
struct firmware_component {
uint32_t address;