diff options
Diffstat (limited to 'src')
28 files changed, 593 insertions, 429 deletions
diff --git a/src/mainboard/google/nyan_blaze/romstage.c b/src/mainboard/google/nyan_blaze/romstage.c index 034a929944..c9510d627e 100644 --- a/src/mainboard/google/nyan_blaze/romstage.c +++ b/src/mainboard/google/nyan_blaze/romstage.c @@ -96,7 +96,7 @@ static void __attribute__((noinline)) romstage(void) early_mainboard_init(); #if CONFIG_VBOOT2_VERIFY_FIRMWARE - entry = vboot_load_ramstage(); + entry = vboot2_load_ramstage(); #else early_mainboard_init(); vboot_verify_firmware(romstage_handoff_find_or_add()); diff --git a/src/mainboard/google/veyron_pinky/romstage.c b/src/mainboard/google/veyron_pinky/romstage.c index 38166eda3f..b050228b5f 100644 --- a/src/mainboard/google/veyron_pinky/romstage.c +++ b/src/mainboard/google/veyron_pinky/romstage.c @@ -117,7 +117,7 @@ void main(void) #endif #if IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE) - void *entry = vboot_load_ramstage(); + void *entry = vboot2_load_ramstage(); if (entry != NULL) stage_exit(entry); #endif diff --git a/src/soc/marvell/bg4cd/include/soc/memlayout.ld b/src/soc/marvell/bg4cd/include/soc/memlayout.ld index 45cf3950c3..21c8f74ccc 100644 --- a/src/soc/marvell/bg4cd/include/soc/memlayout.ld +++ b/src/soc/marvell/bg4cd/include/soc/memlayout.ld @@ -18,7 +18,7 @@ */ #include <memlayout.h> -#include <vendorcode/google/chromeos/memlayout.h> +#include <vendorcode/google/chromeos/vboot2/memlayout.h> #include <arch/header.ld> diff --git a/src/soc/nvidia/tegra124/include/soc/memlayout.ld b/src/soc/nvidia/tegra124/include/soc/memlayout.ld index 0d9e772d41..c8db5c535b 100644 --- a/src/soc/nvidia/tegra124/include/soc/memlayout.ld +++ b/src/soc/nvidia/tegra124/include/soc/memlayout.ld @@ -18,7 +18,7 @@ */ #include <memlayout.h> -#include <vendorcode/google/chromeos/memlayout.h> +#include <vendorcode/google/chromeos/vboot2/memlayout.h> #include <arch/header.ld> diff --git a/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld b/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld index 8743268492..1709392d13 100644 --- a/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld +++ b/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld @@ -18,7 +18,7 @@ */ #include <memlayout.h> -#include <vendorcode/google/chromeos/memlayout.h> +#include <vendorcode/google/chromeos/vboot2/memlayout.h> #include <arch/header.ld> diff --git a/src/soc/rockchip/rk3288/include/soc/memlayout.ld b/src/soc/rockchip/rk3288/include/soc/memlayout.ld index 2ddb6a6077..922e2f8784 100644 --- a/src/soc/rockchip/rk3288/include/soc/memlayout.ld +++ b/src/soc/rockchip/rk3288/include/soc/memlayout.ld @@ -18,7 +18,7 @@ */ #include <memlayout.h> -#include <vendorcode/google/chromeos/memlayout.h> +#include <vendorcode/google/chromeos/vboot2/memlayout.h> #include <arch/header.ld> diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig index 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 **)®ion->offset_addr); -} - -void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest) -{ - if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) { - if (dest != NULL) - return memcpy(dest, (void *)offset_addr, size); - else - return (void *)offset_addr; - } else { - struct cbfs_media default_media, *media = &default_media; - void *cache; - - init_default_cbfs_media(media); - media->open(media); - if (dest != NULL) { - cache = dest; - if (media->read(media, dest, offset_addr, size) != size) - cache = NULL; - } else { - cache = media->map(media, offset_addr, size); - if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS) - cache = NULL; - } - media->close(media); - return cache; - } -} - -int vboot_get_handoff_info(void **addr, uint32_t *size) -{ - struct vboot_handoff *vboot_handoff; - - vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - - if (vboot_handoff == NULL) - return -1; - - *addr = vboot_handoff; - *size = sizeof(*vboot_handoff); - return 0; -} - -/* This will leak a mapping of a fw region */ -struct vboot_components *vboot_locate_components(struct vboot_region *region) -{ - size_t req_size; - struct vboot_components *vbc; - - req_size = sizeof(*vbc); - req_size += sizeof(struct vboot_component_entry) * - MAX_PARSED_FW_COMPONENTS; - - vbc = vboot_get_region(region->offset_addr, req_size, NULL); - if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS) - vbc = NULL; - - return vbc; -} - -void *vboot_get_payload(int *len) -{ - struct vboot_handoff *vboot_handoff; - struct firmware_component *fwc; - - vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - - if (vboot_handoff == NULL) - return NULL; - - if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) { - printk(BIOS_ERR, "Invalid boot loader index: %d\n", - CONFIG_VBOOT_BOOT_LOADER_INDEX); - return NULL; - } - - fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX]; - - /* If payload size is zero fall back to cbfs path. */ - if (fwc->size == 0) - return NULL; - - if (len != NULL) - *len = fwc->size; - - printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n", - fwc->size, fwc->address); - - /* This will leak a mapping. */ - return vboot_get_region(fwc->address, fwc->size, NULL); -} -#endif - -#if CONFIG_VBOOT2_VERIFY_FIRMWARE -void *vboot_load_stage(int stage_index, - struct vboot_region *fw_main, - struct vboot_components *fw_info) -{ - struct cbfs_media default_media, *media = &default_media; - uintptr_t fc_addr; - uint32_t fc_size; - void *entry; - - if (stage_index >= fw_info->num_components) { - printk(BIOS_INFO, "invalid stage index\n"); - return NULL; - } - - fc_addr = fw_main->offset_addr + fw_info->entries[stage_index].offset; - fc_size = fw_info->entries[stage_index].size; - if (fc_size == 0 || - fc_addr + fc_size > fw_main->offset_addr + fw_main->size) { - printk(BIOS_INFO, "invalid stage address or size\n"); - return NULL; - } - - init_default_cbfs_media(media); - - /* we're making cbfs access offset outside of the region managed by - * cbfs. this works because cbfs_load_stage_by_offset does not check - * the offset. */ - entry = cbfs_load_stage_by_offset(media, fc_addr); - if (entry == (void *)-1) - entry = NULL; - return entry; -} - -struct vb2_working_data * const vboot_get_working_data(void) -{ - return (struct vb2_working_data *)_vboot2_work; -} - -void vboot_reboot(void) -{ - hard_reset(); - die("failed to reboot"); -} - -#endif diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h index 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 **)®ion->offset_addr); +} + +void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest) +{ + if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) { + if (dest != NULL) + return memcpy(dest, (void *)offset_addr, size); + else + return (void *)offset_addr; + } else { + struct cbfs_media default_media, *media = &default_media; + void *cache; + + init_default_cbfs_media(media); + media->open(media); + if (dest != NULL) { + cache = dest; + if (media->read(media, dest, offset_addr, size) != size) + cache = NULL; + } else { + cache = media->map(media, offset_addr, size); + if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS) + cache = NULL; + } + media->close(media); + return cache; + } +} + +int vboot_get_handoff_info(void **addr, uint32_t *size) +{ + struct vboot_handoff *vboot_handoff; + + vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); + + if (vboot_handoff == NULL) + return -1; + + *addr = vboot_handoff; + *size = sizeof(*vboot_handoff); + return 0; +} + +/* This will leak a mapping of a fw region */ +struct vboot_components *vboot_locate_components(struct vboot_region *region) +{ + size_t req_size; + struct vboot_components *vbc; + + req_size = sizeof(*vbc); + req_size += sizeof(struct vboot_component_entry) * + MAX_PARSED_FW_COMPONENTS; + + vbc = vboot_get_region(region->offset_addr, req_size, NULL); + if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS) + vbc = NULL; + + return vbc; +} + +void *vboot_get_payload(int *len) +{ + struct vboot_handoff *vboot_handoff; + struct firmware_component *fwc; + + vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); + + if (vboot_handoff == NULL) + return NULL; + + if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) { + printk(BIOS_ERR, "Invalid boot loader index: %d\n", + CONFIG_VBOOT_BOOT_LOADER_INDEX); + return NULL; + } + + fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX]; + + /* If payload size is zero fall back to cbfs path. */ + if (fwc->size == 0) + return NULL; + + if (len != NULL) + *len = fwc->size; + + printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n", + fwc->size, fwc->address); + + /* This will leak a mapping. */ + return vboot_get_region(fwc->address, fwc->size, NULL); +} diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h new file mode 100644 index 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; |