Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9447
-gerrit
commit 01c7fbbaad7f5e6b6ab1af7a6ba0591021d24d6f
Author: Randall Spangler <rspangler(a)chromium.org>
Date: Thu Dec 4 12:58:54 2014 -0800
vboot: Remove unused 2lib header path
Before the change to use vb2_api.h, coreboot needed to know where to
find the vboot2 header files. Now those are all included by
vb2_api.h, so coreboot doesn't need to know about
firmware/2lib/include (and in fact, the 2lib directory is about to go
away).
BUG=chromium:423882
BRANCH=none
TEST=emerge-veyron_pinky coreboot
Original-Change-Id: I7f69ca9cf8d45c325219efceca0cb8d1340f7736
Original-Signed-off-by: Randall Spangler <rspangler(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/233223
Original-Reviewed-by: Daisuke Nojiri <dnojiri(a)chromium.org>
(cherry picked from commit b4d4a2da1c8b5a5f8f8da51f009227d3a616b096)
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Change-Id: I4006f38835ea0f927142a8133bc24caaf2b7a214
---
src/vendorcode/google/chromeos/Makefile.inc | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index 0908b45..649e1fd 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -52,5 +52,4 @@ endif
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
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9444
-gerrit
commit 06eb1bf47da16d66e0ac6f203142c8ad6d866855
Author: Daisuke Nojiri <dnojiri(a)chromium.org>
Date: Thu Nov 13 11:35:52 2014 -0800
vboot: add physical recovery switch support
PHYSICAL_REC_SWITCH is set n by default and y for panther and stumpy.
BUG=none
BRANCH=ToT
TEST=Built nyan_blaze using vboot1/2. Built falco, lumpy, nyan,
blaze, parrot, rambi, samus, storm, pinky with default configuration.
panther and stumpy are not tested because they currently don't build on ToT.
Original-Change-Id: Ic45f78708aaa7e485d2ab459fd1948524edb412f
Original-Signed-off-by: Daisuke Nojiri <dnojiri(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/227940
Original-Reviewed-on: https://chromium-review.googlesource.com/229602
Original-Reviewed-by: Randall Spangler <rspangler(a)chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
(cherry picked from commit edb2ba347b48887ffe450586af0351e384faad59)
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Change-Id: I277f665cd4f3e1c21745cdc5c7a2cfe148661abe
---
src/mainboard/google/panther/Kconfig | 1 +
src/mainboard/samsung/stumpy/Kconfig | 1 +
src/vendorcode/google/chromeos/Kconfig | 6 ++++++
src/vendorcode/google/chromeos/vboot1/vboot_loader.c | 4 ++--
src/vendorcode/google/chromeos/vboot2/vboot_handoff.c | 5 +++--
5 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/mainboard/google/panther/Kconfig b/src/mainboard/google/panther/Kconfig
index 607b690..5f2efb9 100644
--- a/src/mainboard/google/panther/Kconfig
+++ b/src/mainboard/google/panther/Kconfig
@@ -18,6 +18,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select EXTERNAL_MRC_BLOB
select MONOTONIC_TIMER_MSR
select INTEL_INT15
+ select PHYSICAL_REC_SWITCH
config VBOOT_RAMSTAGE_INDEX
hex
diff --git a/src/mainboard/samsung/stumpy/Kconfig b/src/mainboard/samsung/stumpy/Kconfig
index 1b65eae..3f39e70 100644
--- a/src/mainboard/samsung/stumpy/Kconfig
+++ b/src/mainboard/samsung/stumpy/Kconfig
@@ -11,6 +11,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select NORTHBRIDGE_INTEL_SANDYBRIDGE
select SOUTHBRIDGE_INTEL_BD82X6X
select SUPERIO_ITE_IT8772F
+ select PHYSICAL_REC_SWITCH
# LPC47N207 selected for external LPC card
# not on board, should be made selectable.
select SUPERIO_SMSC_LPC47N207
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 29252a6..cb15d13 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -159,6 +159,12 @@ config NO_TPM_RESUME
boards, booting Windows will break if the TPM resume command
is sent during an S3 resume.
+config PHYSICAL_REC_SWITCH
+ bool "Physical recovery switch is present"
+ default n
+ help
+ Whether this platform has a physical recovery switch
+
source src/vendorcode/google/chromeos/vboot1/Kconfig
source src/vendorcode/google/chromeos/vboot2/Kconfig
diff --git a/src/vendorcode/google/chromeos/vboot1/vboot_loader.c b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
index 0353a3a..97ca902 100644
--- a/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
@@ -226,10 +226,10 @@ static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
*iflags |= VB_INIT_FLAG_SW_WP_ENABLED;
if (CONFIG_VIRTUAL_DEV_SWITCH)
*iflags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
- if (CONFIG_EC_SOFTWARE_SYNC) {
+ if (CONFIG_EC_SOFTWARE_SYNC)
*iflags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC;
+ if (!CONFIG_PHYSICAL_REC_SWITCH)
*iflags |= VB_INIT_FLAG_VIRTUAL_REC_SWITCH;
- }
if (CONFIG_VBOOT_EC_SLOW_UPDATE)
*iflags |= VB_INIT_FLAG_EC_SLOW_UPDATE;
if (CONFIG_VBOOT_OPROM_MATTERS) {
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
index 326a9bb..2dadffa 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -104,10 +104,11 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
/* TODO: Set these in depthcharge */
if (CONFIG_VIRTUAL_DEV_SWITCH)
vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
- if (CONFIG_EC_SOFTWARE_SYNC) {
+ if (CONFIG_EC_SOFTWARE_SYNC)
vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
+ if (!CONFIG_PHYSICAL_REC_SWITCH)
vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
- }
+
/* In vboot1, VBSD_FWB_TRIED is
* set only if B is booted as explicitly requested. Therefore, if B is
* booted because A was found bad, the flag should not be set. It's
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9445
-gerrit
commit 7e1f8e43ffa4ce51e90a2c64bd737e28a1f4113a
Author: Julius Werner <jwerner(a)chromium.org>
Date: Mon Dec 1 13:11:52 2014 -0800
vboot2: Reduce minimum required work buffer size
Apparently our initial submission of 16K was a little too generous for
the vboot2 work buffer, and I hear that we should also be well within
bounds for 12K. This patch reduces the minimum asserted by memlayout so
some of our low-mem boards can get a few more kilobytes back for
discretionary spending. Also changes the required minimum alignment to 8
since that's what the current vboot code aligns it to anyway, and add a
warning comment to make it clearer that this is a dangerous number
people should not be playing with lightly.
BRANCH=None
BUG=None
TEST=Built and booted on Pinky.
Original-Change-Id: Iae9c74050500a315c90f5d5517427d755ac1dfea
Original-Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/232613
Original-Reviewed-by: Randall Spangler <rspangler(a)chromium.org>
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
(cherry picked from commit 64e972f10363451cd544fdf8642bd484463703bc)
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Change-Id: I362b8c33cf79534bb76bd7acda44d467563fe133
---
src/vendorcode/google/chromeos/vboot2/memlayout.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/vendorcode/google/chromeos/vboot2/memlayout.h b/src/vendorcode/google/chromeos/vboot2/memlayout.h
index 9e19200..7903dd2 100644
--- a/src/vendorcode/google/chromeos/vboot2/memlayout.h
+++ b/src/vendorcode/google/chromeos/vboot2/memlayout.h
@@ -22,9 +22,12 @@
#ifndef __CHROMEOS_VBOOT2_MEMLAYOUT_H
#define __CHROMEOS_VBOOT2_MEMLAYOUT_H
+/* Careful: required work buffer size depends on RW properties such as key size
+ * and algorithm -- what works for you might stop working after an update. Do
+ * NOT lower the asserted minimum without consulting vboot devs (rspangler)! */
#define VBOOT2_WORK(addr, size) \
- REGION(vboot2_work, addr, size, 4) \
- _ = ASSERT(size >= 16K, "vboot2 work buffer must be at least 16K!");
+ REGION(vboot2_work, addr, size, 8) \
+ _ = ASSERT(size >= 12K, "vboot2 work buffer must be at least 12K!");
#ifdef __VERSTAGE__
#define VERSTAGE(addr, sz) \
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9433
-gerrit
commit a26bfb7ef27cb9130b571839349ead67c10e3fe1
Author: Daisuke Nojiri <dnojiri(a)chromium.org>
Date: Fri Oct 10 10:51:06 2014 -0700
vboot: move vboot files to designated directory
This moves vboot1 and vboot2 files to their designated directory. Common
code stays in vendorcode/google/chromeos.
BUG=none
BRANCH=none
TEST=built cosmos, veyron_pinky, rush_ryu, nyan_blaze, samus, parrot,
lumpy, daisy_spring, and storm.
Signed-off-by: Daisuke Nojiri <dnojiri(a)chromium.org>
Original-Change-Id: Ia9fb41ba30930b79b222269acfade7ef44b23626
Original-Reviewed-on: https://chromium-review.googlesource.com/222874
Original-Reviewed-by: Daisuke Nojiri <dnojiri(a)chromium.org>
Original-Commit-Queue: Daisuke Nojiri <dnojiri(a)chromium.org>
Original-Tested-by: Daisuke Nojiri <dnojiri(a)chromium.org>
(cherry picked from commit cbfef9ad40776d890e2149b9db788fe0b387d210)
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Change-Id: Ia73696accfd93cc14ca83516fa77f87331faef51
---
src/mainboard/google/nyan_blaze/romstage.c | 2 +-
src/mainboard/google/veyron_pinky/romstage.c | 2 +-
src/soc/marvell/bg4cd/include/soc/memlayout.ld | 2 +-
src/soc/nvidia/tegra124/include/soc/memlayout.ld | 2 +-
.../tegra132/include/soc/memlayout_vboot2.ld | 2 +-
src/soc/rockchip/rk3288/include/soc/memlayout.ld | 2 +-
src/vendorcode/google/chromeos/Kconfig | 47 +--
src/vendorcode/google/chromeos/Makefile.inc | 97 +----
src/vendorcode/google/chromeos/antirollback.c | 329 ----------------
src/vendorcode/google/chromeos/chromeos.c | 183 +--------
src/vendorcode/google/chromeos/chromeos.h | 99 +----
src/vendorcode/google/chromeos/memlayout.h | 47 ---
src/vendorcode/google/chromeos/symbols.h | 32 --
src/vendorcode/google/chromeos/vboot1/Kconfig | 34 ++
src/vendorcode/google/chromeos/vboot1/Makefile.inc | 74 ++++
.../google/chromeos/vboot1/vboot_loader.c | 416 +++++++++++++++++++++
.../google/chromeos/vboot1/vboot_wrapper.c | 266 +++++++++++++
src/vendorcode/google/chromeos/vboot2/Kconfig | 43 +++
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 60 +++
.../google/chromeos/vboot2/antirollback.c | 329 ++++++++++++++++
src/vendorcode/google/chromeos/vboot2/common.c | 70 ++++
src/vendorcode/google/chromeos/vboot2/memlayout.h | 47 +++
src/vendorcode/google/chromeos/vboot2/misc.h | 72 ++++
src/vendorcode/google/chromeos/vboot2/symbols.h | 32 ++
.../google/chromeos/vboot2/vboot_handoff.c | 175 +++++++++
src/vendorcode/google/chromeos/vboot2/verstage.c | 252 +++++++++++++
src/vendorcode/google/chromeos/vboot2/verstage.ld | 58 +++
src/vendorcode/google/chromeos/vboot2/verstub.c | 97 +++++
src/vendorcode/google/chromeos/vboot_common.c | 122 ++++++
src/vendorcode/google/chromeos/vboot_common.h | 55 +++
src/vendorcode/google/chromeos/vboot_handoff.c | 174 ---------
src/vendorcode/google/chromeos/vboot_handoff.h | 11 +
src/vendorcode/google/chromeos/vboot_loader.c | 416 ---------------------
src/vendorcode/google/chromeos/vboot_wrapper.c | 266 -------------
src/vendorcode/google/chromeos/verstage.c | 251 -------------
src/vendorcode/google/chromeos/verstage.ld | 58 ---
src/vendorcode/google/chromeos/verstub.c | 96 -----
37 files changed, 2242 insertions(+), 2078 deletions(-)
diff --git a/src/mainboard/google/nyan_blaze/romstage.c b/src/mainboard/google/nyan_blaze/romstage.c
index 034a929..c9510d6 100644
--- a/src/mainboard/google/nyan_blaze/romstage.c
+++ b/src/mainboard/google/nyan_blaze/romstage.c
@@ -96,7 +96,7 @@ static void __attribute__((noinline)) romstage(void)
early_mainboard_init();
#if CONFIG_VBOOT2_VERIFY_FIRMWARE
- entry = vboot_load_ramstage();
+ entry = vboot2_load_ramstage();
#else
early_mainboard_init();
vboot_verify_firmware(romstage_handoff_find_or_add());
diff --git a/src/mainboard/google/veyron_pinky/romstage.c b/src/mainboard/google/veyron_pinky/romstage.c
index 38166ed..b050228 100644
--- a/src/mainboard/google/veyron_pinky/romstage.c
+++ b/src/mainboard/google/veyron_pinky/romstage.c
@@ -117,7 +117,7 @@ void main(void)
#endif
#if IS_ENABLED(CONFIG_VBOOT_VERIFY_FIRMWARE)
- void *entry = vboot_load_ramstage();
+ void *entry = vboot2_load_ramstage();
if (entry != NULL)
stage_exit(entry);
#endif
diff --git a/src/soc/marvell/bg4cd/include/soc/memlayout.ld b/src/soc/marvell/bg4cd/include/soc/memlayout.ld
index 45cf395..21c8f74 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 0d9e772..c8db5c5 100644
--- a/src/soc/nvidia/tegra124/include/soc/memlayout.ld
+++ b/src/soc/nvidia/tegra124/include/soc/memlayout.ld
@@ -18,7 +18,7 @@
*/
#include <memlayout.h>
-#include <vendorcode/google/chromeos/memlayout.h>
+#include <vendorcode/google/chromeos/vboot2/memlayout.h>
#include <arch/header.ld>
diff --git a/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld b/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld
index 8743268..1709392 100644
--- a/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld
+++ b/src/soc/nvidia/tegra132/include/soc/memlayout_vboot2.ld
@@ -18,7 +18,7 @@
*/
#include <memlayout.h>
-#include <vendorcode/google/chromeos/memlayout.h>
+#include <vendorcode/google/chromeos/vboot2/memlayout.h>
#include <arch/header.ld>
diff --git a/src/soc/rockchip/rk3288/include/soc/memlayout.ld b/src/soc/rockchip/rk3288/include/soc/memlayout.ld
index 2ddb6a6..922e2f8 100644
--- a/src/soc/rockchip/rk3288/include/soc/memlayout.ld
+++ b/src/soc/rockchip/rk3288/include/soc/memlayout.ld
@@ -18,7 +18,7 @@
*/
#include <memlayout.h>
-#include <vendorcode/google/chromeos/memlayout.h>
+#include <vendorcode/google/chromeos/vboot2/memlayout.h>
#include <arch/header.ld>
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 8826a14..62a415b 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -94,22 +94,6 @@ config FLASHMAP_OFFSET
help
Offset of flash map in firmware image
-config VBOOT_VERIFY_FIRMWARE
- bool "Verify firmware with vboot."
- default n
- select RELOCATABLE_MODULES
- help
- Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
- and boot loader.
-
-config VBOOT2_VERIFY_FIRMWARE
- bool "Firmware Verification with vboot2"
- default n
- depends on CHROMEOS && HAVE_HARD_RESET
- help
- Enabling VBOOT2_VERIFY_FIRMWARE will use vboot2 to verify the romstage
- and boot loader.
-
config EC_SOFTWARE_SYNC
bool "Enable EC software sync"
default n
@@ -141,16 +125,6 @@ config VIRTUAL_DEV_SWITCH
help
Whether this platform has a virtual developer switch.
-config RETURN_FROM_VERSTAGE
- bool "return from verstage"
- default n
- depends on VBOOT2_VERIFY_FIRMWARE
- help
- If this is set, the verstage returns back to the bootblock instead of
- exits to the romstage so that the verstage space can be reused by the
- romstage. Useful if a ram space is too small to fit both the verstage
- and the romstage.
-
# These VBOOT_X_INDEX are the position of X in FW_MAIN_A/B region. The index
# table is created by cros_bundle_firmware at build time based on the positions
# of the blobs listed in fmap.dts and stored at the top of FW_MAIN_A/B region.
@@ -164,14 +138,6 @@ config VBOOT_BOOT_LOADER_INDEX
This is the index of the bootloader component in the verified
firmware block.
-config VBOOT_ROMSTAGE_INDEX
- hex
- default 2
- depends on VBOOT2_VERIFY_FIRMWARE
- help
- This is the index of the romstage component in the verified
- firmware block.
-
config VBOOT_RAMSTAGE_INDEX
hex "Ramstage component index"
default 1
@@ -180,14 +146,6 @@ config VBOOT_RAMSTAGE_INDEX
This is the index of the ramstage component in the verified
firmware block.
-config VBOOT_REFCODE_INDEX
- hex "Reference code firmware index"
- default 1
- depends on VBOOT_VERIFY_FIRMWARE
- help
- This is the index of the reference code component in the verified
- firmware block.
-
config NO_TPM_RESUME
bool
default n
@@ -196,5 +154,8 @@ config NO_TPM_RESUME
boards, booting Windows will break if the TPM resume command
is sent during an S3 resume.
-endif
+source src/vendorcode/google/chromeos/vboot1/Kconfig
+source src/vendorcode/google/chromeos/vboot2/Kconfig
+
+endif # CHROMEOS
endmenu
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index f43a87e..cc50d2f 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -37,101 +37,8 @@ else
CFLAGS_common += -DMOCK_TPM=0
endif
-ifeq ($(CONFIG_VBOOT_VERIFY_FIRMWARE),y)
-romstage-y += vboot_helper.c
-ramstage-y += vboot_helper.c
-romstage-y += vboot_loader.c
-rmodules_$(ARCH-romstage-y)-y += vboot_wrapper.c
-
-ifneq ($(CONFIG_SPI_FLASH_MEMORY_MAPPED),y)
-VBOOT_MAKEFLAGS = REGION_READ=1
-endif
-
-VB_LIB = $(obj)/external/vboot_reference/vboot_fw.a
-# Currently, vboot comes into picture only during the romstage, thus
-# is compiled for being used in romstage only. Since, we are splitting
-# up all components in one of the three stages of coreboot, vboot seems
-# most logical to fall under the romstage. Thus, all references to arch
-# and other compiler stuff for vboot is using the romstage arch.
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-romstage-y))
-VB_SOURCE := vboot_reference
-
-# Add the vboot include paths.
-CPPFLAGS_common += -I$(VB_SOURCE)/firmware/include
-
-VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vbootstub.elf
-VBOOT_STUB = $(VBOOT_STUB_ELF).rmod
-
-# Dependency for the vboot rmodules. Ordering matters.
-VBOOT_STUB_DEPS += $(obj)/vendorcode/google/chromeos/vboot_wrapper.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules_$(ARCH-romstage-y).o
-VBOOT_STUB_DEPS += $(VB_LIB)
-# Remove the '-include' option since that will break vboot's build and ensure
-# vboot_reference can get to coreboot's include files.
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_romstage) $(CPPFLAGS_romstage)))
-VBOOT_CFLAGS += -DVBOOT_DEBUG
-VBOOT_CFLAGS += $(rmodules_$(ARCH-ROMSTAGE-y)-c-ccopts)
-
-# Link the vbootstub module with a 64KiB-byte heap.
-$(eval $(call rmodule_link,$(VBOOT_STUB_ELF), $(VBOOT_STUB_DEPS), 0x10000,$(ARCH-romstage-y)))
-
-# Build vboot library without the default includes from coreboot proper.
-$(VB_LIB):
- @printf " MAKE $(subst $(obj)/,,$(@))\n"
- $(Q)$(MAKE) -C $(VB_SOURCE) \
- CC="$(CC_romstage)" \
- CFLAGS="$(VBOOT_CFLAGS)" \
- $(VBOOT_MAKEFLAGS) \
- FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
- BUILD=$(top)/$(dir $(VB_LIB)) \
- V=$(V) \
- fwlib
-
-endif
-
-ifeq ($(CONFIG_VBOOT2_VERIFY_FIRMWARE),y)
VB_SOURCE := vboot_reference
+subdirs-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot1
+subdirs-$(CONFIG_VBOOT2_VERIFY_FIRMWARE) += vboot2
CPPFLAGS_common += -I$(VB_SOURCE)/firmware/2lib/include
CPPFLAGS_common += -I$(VB_SOURCE)/firmware/include
-
-verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
-
-ifeq ($(CONFIG_RETURN_FROM_VERSTAGE),y)
-bootblock-y += verstub.c chromeos.c
-else
-verstage-y += verstub.c
-endif
-verstage-y += verstage.c fmap.c chromeos.c
-verstage-y += antirollback.c
-verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += vbnv_cmos.c
-verstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c
-verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c
-romstage-y += vboot_handoff.c
-
-verstage-y += verstage.ld
-
-VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
-VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
-VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage) $(CPPFLAGS_verstage)))
-VBOOT_CFLAGS += $(verstage-c-ccopts)
-VBOOT_CFLAGS += -include $(top)/src/include/kconfig.h -Wno-missing-prototypes
-VBOOT_CFLAGS += -DVBOOT_DEBUG
-
-$(VB2_LIB): $(obj)/config.h
- @printf " MAKE $(subst $(obj)/,,$(@))\n"
- $(Q)$(MAKE) -C $(VB_SOURCE) \
- CC="$(CC_verstage)" \
- CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \
- FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
- BUILD=$(top)/$(dir $(VB2_LIB)) \
- V=$(V) \
- fwlib2
-
-VERSTAGE_ELF = $(objcbfs)/verstage.elf
-cbfs-files-y += $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage
-fallback/verstage-file = $(VERSTAGE_ELF)
-fallback/verstage-type = stage
-fallback/verstage-compression = none
-endif # CONFIG_VBOOT2_VERIFY_FIRMWARE
diff --git a/src/vendorcode/google/chromeos/antirollback.c b/src/vendorcode/google/chromeos/antirollback.c
deleted file mode 100644
index bb547b5..0000000
--- a/src/vendorcode/google/chromeos/antirollback.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Functions for querying, manipulating and locking rollback indices
- * stored in the TPM NVRAM.
- */
-
-#include <2api.h>
-#include <2sysincludes.h>
-#include <antirollback.h>
-#include <tpm_lite/tlcl.h>
-#include <tpm_lite/tss_constants.h>
-
-#ifndef offsetof
-#define offsetof(A,B) __builtin_offsetof(A,B)
-#endif
-
-#ifdef FOR_TEST
-#include <stdio.h>
-#define VBDEBUG(format, args...) printf(format, ## args)
-#else
-#include <console/console.h>
-#define VBDEBUG(format, args...) \
- printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
-#endif
-
-#define RETURN_ON_FAILURE(tpm_cmd) do { \
- uint32_t result_; \
- if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
- VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
- "\n", (int)result_); \
- return result_; \
- } \
- } while (0)
-
-uint32_t tpm_clear_and_reenable(void)
-{
- VBDEBUG("TPM: Clear and re-enable\n");
- RETURN_ON_FAILURE(tlcl_force_clear());
- RETURN_ON_FAILURE(tlcl_set_enable());
- RETURN_ON_FAILURE(tlcl_set_deactivated(0));
-
- return TPM_SUCCESS;
-}
-
-uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
- uint32_t result = tlcl_write(index, data, length);
- if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
- return tlcl_write(index, data, length);
- } else {
- return result;
- }
-}
-
-uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
- uint32_t result = tlcl_define_space(index, perm, size);
- if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
- return tlcl_define_space(index, perm, size);
- } else {
- return result;
- }
-}
-
-static uint32_t read_space_firmware(struct vb2_context *ctx)
-{
- int attempts = 3;
-
- while (attempts--) {
- RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
- VB2_SECDATA_SIZE));
-
- if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
- return TPM_SUCCESS;
-
- VBDEBUG("TPM: %s() - bad CRC\n", __func__);
- }
-
- VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
- return TPM_E_CORRUPTED_STATE;
-}
-
-static uint32_t write_secdata(uint32_t index,
- const uint8_t *secdata,
- uint32_t len)
-{
- uint8_t sd[32];
- uint32_t rv;
- int attempts = 3;
-
- if (len > sizeof(sd)) {
- VBDEBUG("TPM: %s() - data is too large\n", __func__);
- return TPM_E_WRITE_FAILURE;
- }
-
- while (attempts--) {
- rv = safe_write(index, secdata, len);
- /* Can't write, not gonna try again */
- if (rv != TPM_SUCCESS)
- return rv;
-
- /* Read it back to be sure it got the right values. */
- rv = tlcl_read(index, sd, len);
- if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
- return rv;
-
- VBDEBUG("TPM: %s() failed. trying again\n", __func__);
- /* Try writing it again. Maybe it was garbled on the way out. */
- }
-
- VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
-
- return TPM_E_CORRUPTED_STATE;
-}
-
-uint32_t factory_initialize_tpm(struct vb2_context *ctx)
-{
- TPM_PERMANENT_FLAGS pflags;
- uint32_t result;
- /* this is derived from rollback_index.h of vboot_reference. see struct
- * RollbackSpaceKernel for details. */
- static const uint8_t secdata_kernel[] = {
- 0x02,
- 0x4C, 0x57, 0x52, 0x47,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- 0xE8,
- };
-
- VBDEBUG("TPM: factory initialization\n");
-
- /*
- * Do a full test. This only happens the first time the device is
- * turned on in the factory, so performance is not an issue. This is
- * almost certainly not necessary, but it gives us more confidence
- * about some code paths below that are difficult to
- * test---specifically the ones that set lifetime flags, and are only
- * executed once per physical TPM.
- */
- result = tlcl_self_test_full();
- if (result != TPM_SUCCESS)
- return result;
-
- result = tlcl_get_permanent_flags(&pflags);
- if (result != TPM_SUCCESS)
- return result;
-
- /*
- * TPM may come from the factory without physical presence finalized.
- * Fix if necessary.
- */
- VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
- pflags.physicalPresenceLifetimeLock);
- if (!pflags.physicalPresenceLifetimeLock) {
- VBDEBUG("TPM: Finalizing physical presence\n");
- RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
- }
-
- /*
- * The TPM will not enforce the NV authorization restrictions until the
- * execution of a TPM_NV_DefineSpace with the handle of
- * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
- * exist. */
- VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
- if (!pflags.nvLocked) {
- VBDEBUG("TPM: Enabling NV locking\n");
- RETURN_ON_FAILURE(tlcl_set_nv_locked());
- }
-
- /* Clear TPM owner, in case the TPM is already owned for some reason. */
- VBDEBUG("TPM: Clearing owner\n");
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
-
- /* Define the backup space. No need to initialize it, though. */
- RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX,
- TPM_NV_PER_PPWRITE,
- VB2_NVDATA_SIZE));
-
- /* Define and initialize the kernel space */
- RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
- TPM_NV_PER_PPWRITE,
- sizeof(secdata_kernel)));
- RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
- secdata_kernel,
- sizeof(secdata_kernel)));
-
- /* Defines and sets vb2 secdata space */
- vb2api_secdata_create(ctx);
- RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
- TPM_NV_PER_GLOBALLOCK |
- TPM_NV_PER_PPWRITE,
- VB2_SECDATA_SIZE));
- RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
- ctx->secdata,
- VB2_SECDATA_SIZE));
-
- VBDEBUG("TPM: factory initialization successful\n");
-
- return TPM_SUCCESS;
-}
-
-/*
- * SetupTPM starts the TPM and establishes the root of trust for the
- * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
- * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
- * general we cannot easily distinguish the kind of failure, so our strategy is
- * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
- * again, which executes (almost) the same sequence of operations. There is a
- * good chance that, if recovery mode was entered because of a TPM failure, the
- * failure will repeat itself. (In general this is impossible to guarantee
- * because we have no way of creating the exact TPM initial state at the
- * previous boot.) In recovery mode, we ignore the failure and continue, thus
- * giving the recovery kernel a chance to fix things (that's why we don't set
- * bGlobalLock). The choice is between a knowingly insecure device and a
- * bricked device.
- *
- * As a side note, observe that we go through considerable hoops to avoid using
- * the STCLEAR permissions for the index spaces. We do this to avoid writing
- * to the TPM flashram at every reboot or wake-up, because of concerns about
- * the durability of the NVRAM.
- */
-uint32_t setup_tpm(struct vb2_context *ctx)
-{
- uint8_t disable;
- uint8_t deactivated;
- uint32_t result;
-
- RETURN_ON_FAILURE(tlcl_lib_init());
-
-#ifdef TEGRA_SOFT_REBOOT_WORKAROUND
- result = tlcl_startup();
- if (result == TPM_E_INVALID_POSTINIT) {
- /*
- * Some prototype hardware doesn't reset the TPM on a CPU
- * reset. We do a hard reset to get around this.
- */
- VBDEBUG("TPM: soft reset detected\n", result);
- return TPM_E_MUST_REBOOT;
- } else if (result != TPM_SUCCESS) {
- VBDEBUG("TPM: tlcl_startup returned %08x\n", result);
- return result;
- }
-#else
- RETURN_ON_FAILURE(tlcl_startup());
-#endif
-
- /*
- * Some TPMs start the self test automatically at power on. In that case
- * we don't need to call ContinueSelfTest. On some (other) TPMs,
- * continue_self_test may block. In that case, we definitely don't want
- * to call it here. For TPMs in the intersection of these two sets, we
- * are screwed. (In other words: TPMs that require manually starting the
- * self-test AND block will have poor performance until we split
- * tlcl_send_receive() into send() and receive(), and have a state
- * machine to control setup.)
- *
- * This comment is likely to become obsolete in the near future, so
- * don't trust it. It may have not been updated.
- */
-#ifdef TPM_MANUAL_SELFTEST
-#ifdef TPM_BLOCKING_CONTINUESELFTEST
-#warning "lousy TPM!"
-#endif
- RETURN_ON_FAILURE(tlcl_continue_self_test());
-#endif
- result = tlcl_assert_physical_presence();
- if (result != TPM_SUCCESS) {
- /*
- * It is possible that the TPM was delivered with the physical
- * presence command disabled. This tries enabling it, then
- * tries asserting PP again.
- */
- RETURN_ON_FAILURE(tlcl_physical_presence_cmd_enable());
- RETURN_ON_FAILURE(tlcl_assert_physical_presence());
- }
-
- /* Check that the TPM is enabled and activated. */
- RETURN_ON_FAILURE(tlcl_get_flags(&disable, &deactivated, NULL));
- if (disable || deactivated) {
- VBDEBUG("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
- disable, deactivated);
- RETURN_ON_FAILURE(tlcl_set_enable());
- RETURN_ON_FAILURE(tlcl_set_deactivated(0));
- VBDEBUG("TPM: Must reboot to re-enable\n");
- return TPM_E_MUST_REBOOT;
- }
-
- VBDEBUG("TPM: SetupTPM() succeeded\n");
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
-{
- uint32_t rv;
-
- rv = setup_tpm(ctx);
- if (rv)
- return rv;
-
- /* Read the firmware space. */
- rv = read_space_firmware(ctx);
- if (rv == TPM_E_BADINDEX) {
- /*
- * This seems the first time we've run. Initialize the TPM.
- */
- VBDEBUG("TPM: Not initialized yet.\n");
- RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
- } else if (rv != TPM_SUCCESS) {
- VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
- //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
- return TPM_E_CORRUPTED_STATE;
- }
-
- return TPM_SUCCESS;
-}
-
-uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
-{
- return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
-}
-
-uint32_t antirollback_lock_space_firmware()
-{
- return tlcl_set_global_lock();
-}
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index c4d651a..437e128 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -20,18 +20,11 @@
#include <stddef.h>
#include <string.h>
#include "chromeos.h"
-#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-#include "fmap.h"
-#include "symbols.h"
-#include "vboot_handoff.h"
-#include <reset.h>
-#endif
#include <boot/coreboot_tables.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
static int vboot_enable_developer(void)
{
struct vboot_handoff *vbho;
@@ -58,10 +51,18 @@ static int vboot_enable_recovery(void)
return !!(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_RECOVERY);
}
-#else
-static inline int vboot_enable_developer(void) { return 0; }
-static inline int vboot_enable_recovery(void) { return 0; }
-#endif
+
+int vboot_skip_display_init(void)
+{
+ struct vboot_handoff *vbho;
+
+ vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vbho == NULL)
+ return 0;
+
+ return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
+}
int developer_mode_enabled(void)
{
@@ -92,22 +93,6 @@ int __attribute__((weak)) clear_recovery_mode_switch(void)
return 0;
}
-int vboot_skip_display_init(void)
-{
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
- struct vboot_handoff *vbho;
-
- vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vbho == NULL)
- return 0;
-
- return !(vbho->init_params.out_flags & VB_INIT_OUT_ENABLE_DISPLAY);
-#else
- return 0;
-#endif
-}
-
#ifdef __ROMSTAGE__
void __attribute__((weak)) save_chromeos_gpios(void)
{
@@ -120,147 +105,3 @@ int __attribute((weak)) vboot_get_sw_write_protect(void)
return 0;
}
#endif
-
-#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-void vboot_locate_region(const char *name, struct vboot_region *region)
-{
- region->size = find_fmap_entry(name, (void **)®ion->offset_addr);
-}
-
-void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest)
-{
- if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- if (dest != NULL)
- return memcpy(dest, (void *)offset_addr, size);
- else
- return (void *)offset_addr;
- } else {
- struct cbfs_media default_media, *media = &default_media;
- void *cache;
-
- init_default_cbfs_media(media);
- media->open(media);
- if (dest != NULL) {
- cache = dest;
- if (media->read(media, dest, offset_addr, size) != size)
- cache = NULL;
- } else {
- cache = media->map(media, offset_addr, size);
- if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS)
- cache = NULL;
- }
- media->close(media);
- return cache;
- }
-}
-
-int vboot_get_handoff_info(void **addr, uint32_t *size)
-{
- struct vboot_handoff *vboot_handoff;
-
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return -1;
-
- *addr = vboot_handoff;
- *size = sizeof(*vboot_handoff);
- return 0;
-}
-
-/* This will leak a mapping of a fw region */
-struct vboot_components *vboot_locate_components(struct vboot_region *region)
-{
- size_t req_size;
- struct vboot_components *vbc;
-
- req_size = sizeof(*vbc);
- req_size += sizeof(struct vboot_component_entry) *
- MAX_PARSED_FW_COMPONENTS;
-
- vbc = vboot_get_region(region->offset_addr, req_size, NULL);
- if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
- vbc = NULL;
-
- return vbc;
-}
-
-void *vboot_get_payload(int *len)
-{
- struct vboot_handoff *vboot_handoff;
- struct firmware_component *fwc;
-
- vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
-
- if (vboot_handoff == NULL)
- return NULL;
-
- if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid boot loader index: %d\n",
- CONFIG_VBOOT_BOOT_LOADER_INDEX);
- return NULL;
- }
-
- fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX];
-
- /* If payload size is zero fall back to cbfs path. */
- if (fwc->size == 0)
- return NULL;
-
- if (len != NULL)
- *len = fwc->size;
-
- printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n",
- fwc->size, fwc->address);
-
- /* This will leak a mapping. */
- return vboot_get_region(fwc->address, fwc->size, NULL);
-}
-#endif
-
-#if CONFIG_VBOOT2_VERIFY_FIRMWARE
-void *vboot_load_stage(int stage_index,
- struct vboot_region *fw_main,
- struct vboot_components *fw_info)
-{
- struct cbfs_media default_media, *media = &default_media;
- uintptr_t fc_addr;
- uint32_t fc_size;
- void *entry;
-
- if (stage_index >= fw_info->num_components) {
- printk(BIOS_INFO, "invalid stage index\n");
- return NULL;
- }
-
- fc_addr = fw_main->offset_addr + fw_info->entries[stage_index].offset;
- fc_size = fw_info->entries[stage_index].size;
- if (fc_size == 0 ||
- fc_addr + fc_size > fw_main->offset_addr + fw_main->size) {
- printk(BIOS_INFO, "invalid stage address or size\n");
- return NULL;
- }
-
- init_default_cbfs_media(media);
-
- /* we're making cbfs access offset outside of the region managed by
- * cbfs. this works because cbfs_load_stage_by_offset does not check
- * the offset. */
- entry = cbfs_load_stage_by_offset(media, fc_addr);
- if (entry == (void *)-1)
- entry = NULL;
- return entry;
-}
-
-struct vb2_working_data * const vboot_get_working_data(void)
-{
- return (struct vb2_working_data *)_vboot2_work;
-}
-
-void vboot_reboot(void)
-{
- hard_reset();
- die("failed to reboot");
-}
-
-#endif
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index ed6c75b..5ba5457 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -23,6 +23,8 @@
#include <stddef.h>
#include <stdint.h>
#include <bootmode.h>
+#include "vboot_common.h"
+#include "vboot2/misc.h"
/*for mainboard use only*/
void setup_chromeos_gpios(void);
@@ -47,54 +49,14 @@ static inline void elog_add_boot_reason(void) { return; }
struct romstage_handoff;
-/* TODO(shawnn): Remove these CONFIGs and define default weak functions
- * that can be overridden in the platform / MB code. */
#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
-struct vboot_region {
- uintptr_t offset_addr;
- int32_t size;
-};
-
-/*
- * The vboot handoff structure keeps track of a maximum number of firmware
- * components in the verfieid RW area of flash. This is not a restriction on
- * the number of components packed in a firmware block. It's only the maximum
- * number of parsed firmware components (address and size) included in the
- * handoff structure.
- */
-#define MAX_PARSED_FW_COMPONENTS 5
-
-/* The FW areas consist of multiple components. At the beginning of
- * each area is the number of total compoments as well as the size and
- * offset for each component. One needs to caculate the total size of the
- * signed firmware region based off of the embedded metadata. */
-struct vboot_component_entry {
- uint32_t offset;
- uint32_t size;
-} __attribute__((packed));
-
-struct vboot_components {
- uint32_t num_components;
- struct vboot_component_entry entries[0];
-} __attribute__((packed));
-
-void vboot_locate_region(const char *name, struct vboot_region *region);
-
-struct vboot_components *vboot_locate_components(struct vboot_region *region);
-
-/*
- * This is a dual purpose routine. If dest is non-NULL the region at
- * offset_addr will be read into the area pointed to by dest. If dest
- * is NULL,the region will be mapped to a memory location. NULL is
- * returned on error else the location of the requested region.
- */
-void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest);
/* Returns 0 on success < 0 on error. */
int vboot_get_handoff_info(void **addr, uint32_t *size);
int vboot_enable_developer(void);
int vboot_enable_recovery(void);
int vboot_skip_display_init(void);
-#else
+void *vboot_get_payload(int *len);
+#else /* CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE */
static inline void vboot_verify_firmware(struct romstage_handoff *h) {}
static inline void *vboot_get_payload(int *len) { return NULL; }
static inline int vboot_get_handoff_info(void **addr, uint32_t *size)
@@ -121,55 +83,4 @@ static inline void chromeos_ram_oops_init(chromeos_acpi_t *chromeos) {}
static inline void chromeos_reserve_ram_oops(struct device *dev, int idx) {}
#endif /* CONFIG_CHROMEOS_RAMOOPS */
-void vboot2_verify_firmware(void);
-
-#if CONFIG_VBOOT2_VERIFY_FIRMWARE
-void *vboot_load_ramstage(void);
-void verstage_main(void);
-void *vboot_load_stage(int stage_index,
- struct vboot_region *fw_main,
- struct vboot_components *fw_info);
-void vboot_reboot(void);
-
-/*
- * this is placed at the start of the vboot work buffer. selected_region is used
- * for the verstage to return the location of the selected slot. buffer is used
- * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
- * stage boundaries.
- */
-struct vb2_working_data {
- uint32_t selected_region_offset;
- uint32_t selected_region_size;
- uint64_t buffer_size;
- uint64_t buffer;
-};
-
-struct vb2_working_data * const vboot_get_working_data(void);
-
-static inline void vb2_get_selected_region(struct vb2_working_data *wd,
- struct vboot_region *region)
-{
- region->offset_addr = wd->selected_region_offset;
- region->size = wd->selected_region_size;
-}
-
-static inline void vb2_set_selected_region(struct vb2_working_data *wd,
- struct vboot_region *region)
-{
- wd->selected_region_offset = region->offset_addr;
- wd->selected_region_size = region->size;
-}
-
-static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
-{
- return wd->selected_region_size > 0;
-}
-
-static inline int vboot_is_readonly_path(struct vb2_working_data *wd)
-{
- return wd->selected_region_size == 0;
-}
-
-#endif /* CONFIG_VBOOT2_VERIFY_FIRMWARE */
-
-#endif
+#endif /* __CHROMEOS_H__ */
diff --git a/src/vendorcode/google/chromeos/memlayout.h b/src/vendorcode/google/chromeos/memlayout.h
deleted file mode 100644
index 468f746..0000000
--- a/src/vendorcode/google/chromeos/memlayout.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* This file contains macro definitions for memlayout.ld linker scripts. */
-
-#ifndef __CHROMEOS_MEMLAYOUT_H
-#define __CHROMEOS_MEMLAYOUT_H
-
-#define VBOOT2_WORK(addr, size) \
- REGION(vboot2_work, addr, size, 4) \
- _ = ASSERT(size >= 16K, "vboot2 work buffer must be at least 16K!");
-
-#ifdef __VERSTAGE__
- #define VERSTAGE(addr, sz) \
- SET_COUNTER(VERSTAGE, addr) \
- _ = ASSERT(_everstage - _verstage <= sz, \
- STR(Verstage exceeded its allotted size! (sz))); \
- INCLUDE "vendorcode/google/chromeos/verstage.verstage.ld"
-#else
- #define VERSTAGE(addr, sz) \
- SET_COUNTER(VERSTAGE, addr) \
- . += sz;
-#endif
-
-#ifdef __VERSTAGE__
- #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) VERSTAGE(addr, size)
-#else
- #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) ROMSTAGE(addr, size)
-#endif
-
-#endif /* __CHROMEOS_MEMLAYOUT_H */
diff --git a/src/vendorcode/google/chromeos/symbols.h b/src/vendorcode/google/chromeos/symbols.h
deleted file mode 100644
index 21169f0..0000000
--- a/src/vendorcode/google/chromeos/symbols.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
- */
-
-#ifndef __CHROMEOS_SYMBOLS_H
-#define __CHROMEOS_SYMBOLS_H
-
-extern u8 _vboot2_work[];
-extern u8 _evboot2_work[];
-#define _vboot2_work_size (_evboot2_work - _vboot2_work)
-
-/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */
-extern u8 _verstage[];
-extern u8 _everstage[];
-#define _verstage_size (_everstage - _verstage)
-
-#endif /* __CHROMEOS_SYMBOLS_H */
diff --git a/src/vendorcode/google/chromeos/vboot1/Kconfig b/src/vendorcode/google/chromeos/vboot1/Kconfig
new file mode 100644
index 0000000..0102869
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/Kconfig
@@ -0,0 +1,34 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config VBOOT_VERIFY_FIRMWARE
+ bool "Verify firmware with vboot."
+ default n
+ depends on CHROMEOS
+ select RELOCATABLE_MODULES
+ help
+ Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
+ and boot loader.
+
+config VBOOT_REFCODE_INDEX
+ hex "Reference code firmware index"
+ default 1
+ depends on VBOOT_VERIFY_FIRMWARE
+ help
+ This is the index of the reference code component in the verified
+ firmware block.
diff --git a/src/vendorcode/google/chromeos/vboot1/Makefile.inc b/src/vendorcode/google/chromeos/vboot1/Makefile.inc
new file mode 100644
index 0000000..a2d42b4
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/Makefile.inc
@@ -0,0 +1,74 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+ramstage-y += ../vboot_common.c
+romstage-y += vboot_loader.c ../vboot_common.c
+rmodules_$(ARCH-ROMSTAGE-y)-y += vboot_wrapper.c ../vboot_common.c
+
+ifneq ($(CONFIG_SPI_FLASH_MEMORY_MAPPED),y)
+VBOOT_MAKEFLAGS = REGION_READ=1
+endif
+
+VB_LIB = $(obj)/external/vboot_reference/vboot_fw.a
+# Currently, vboot comes into picture only during the romstage, thus
+# is compiled for being used in romstage only. Since, we are splitting
+# up all components in one of the three stages of coreboot, vboot seems
+# most logical to fall under the romstage. Thus, all references to arch
+# and other compiler stuff for vboot is using the romstage arch.
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-ROMSTAGE-y))
+
+VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vboot1/vbootstub.elf
+VBOOT_STUB = $(VBOOT_STUB_ELF).rmod
+
+# Dependency for the vboot rmodules. Ordering matters.
+VBOOT_STUB_DEPS += $(obj)/vendorcode/google/chromeos/vboot1/vboot_wrapper.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/lib/memcmp.rmodules_$(ARCH-ROMSTAGE-y).o
+ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32),y)
+VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memset.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/arch/x86/lib/memcpy.rmodules_$(ARCH-ROMSTAGE-y).o
+endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM),y)
+VBOOT_STUB_DEPS += $(obj)/arch/arm/memset.rmodules_$(ARCH-ROMSTAGE-y).o
+VBOOT_STUB_DEPS += $(obj)/arch/arm/memcpy.rmodules_$(ARCH-ROMSTAGE-y).o
+endif
+ifeq ($(CONFIG_ARCH_ROMSTAGE_ARM64),y)
+VBOOT_STUB_DEPS += $(obj)/lib/memset.rmodules.o
+VBOOT_STUB_DEPS += $(obj)/lib/memcpy.rmodules.o
+endif
+VBOOT_STUB_DEPS += $(VB_LIB)
+# Remove the '-include' option since that will break vboot's build and ensure
+# vboot_reference can get to coreboot's include files.
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_romstage)))
+VBOOT_CFLAGS += -DVBOOT_DEBUG
+VBOOT_CFLAGS += $(rmodules_$(ARCH-ROMSTAGE-y)-c-ccopts)
+
+# Link the vbootstub module with a 64KiB-byte heap.
+$(eval $(call rmodule_link,$(VBOOT_STUB_ELF), $(VBOOT_STUB_DEPS), 0x10000,$(ARCH-ROMSTAGE-y)))
+
+# Build vboot library without the default includes from coreboot proper.
+$(VB_LIB):
+ @printf " MAKE $(subst $(obj)/,,$(@))\n"
+ $(Q)FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
+ CC="$(CC_romstage)" \
+ CFLAGS="$(VBOOT_CFLAGS)" \
+ $(MAKE) -C $(VB_SOURCE) \
+ $(VBOOT_MAKEFLAGS) \
+ BUILD=$(top)/$(dir $(VB_LIB)) \
+ V=$(V) \
+ fwlib
diff --git a/src/vendorcode/google/chromeos/vboot1/vboot_loader.c b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
new file mode 100644
index 0000000..0353a3a
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_loader.c
@@ -0,0 +1,416 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/stages.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <program_loading.h>
+#include <tpm.h>
+#include <reset.h>
+#include <romstage_handoff.h>
+#include <rmodule.h>
+#include <string.h>
+#include <stdlib.h>
+#include <timestamp.h>
+#include "../chromeos.h"
+#include "../vboot_context.h"
+#include "../vboot_handoff.h"
+
+#define TEMP_CBMEM_ID_VBOOT 0xffffffff
+#define TEMP_CBMEM_ID_VBLOCKS 0xfffffffe
+
+static void vboot_run_stub(struct vboot_context *context)
+{
+ struct rmod_stage_load rmod_stage = {
+ .cbmem_id = TEMP_CBMEM_ID_VBOOT,
+ .name = CONFIG_CBFS_PREFIX "/vboot",
+ };
+ void (*entry)(struct vboot_context *context);
+
+ if (rmodule_stage_load_from_cbfs(&rmod_stage)) {
+ printk(BIOS_DEBUG, "Could not load vboot stub.\n");
+ goto out;
+ }
+
+ entry = rmod_stage.entry;
+
+ /* Call stub. */
+ entry(context);
+
+out:
+ /* Tear down the region no longer needed. */
+ if (rmod_stage.cbmem_entry != NULL)
+ cbmem_entry_remove(rmod_stage.cbmem_entry);
+}
+
+/* Helper routines for the vboot stub. */
+static void log_msg(const char *fmt, va_list args)
+{
+ do_vtxprintf(fmt, args);
+}
+
+static void fatal_error(void)
+{
+ printk(BIOS_ERR, "vboot encountered fatal error. Resetting.\n");
+ hard_reset();
+}
+
+static int fw_region_size(struct vboot_region *r)
+{
+ struct vboot_components *fw_info;
+ int32_t size;
+ int i;
+
+ fw_info = vboot_locate_components(r);
+ if (fw_info == NULL)
+ return -1;
+
+ if (fw_info->num_components > MAX_PARSED_FW_COMPONENTS)
+ return -1;
+
+ size = sizeof(*fw_info);
+ size += sizeof(struct vboot_component_entry) * fw_info->num_components;
+
+ for (i = 0; i < fw_info->num_components; i++)
+ size += ALIGN(fw_info->entries[i].size, sizeof(uint32_t));
+
+ /* Check that size of comopnents does not exceed the region's size. */
+ if (size > r->size)
+ return -1;
+
+ /* Update region with the correct size. */
+ r->size = size;
+
+ return 0;
+}
+
+static int vboot_fill_params(struct vboot_context *ctx)
+{
+ VbCommonParams *cparams;
+ VbSelectFirmwareParams *fparams;
+
+ if (fw_region_size(&ctx->fw_a))
+ return -1;
+
+ if (fw_region_size(&ctx->fw_b))
+ return -1;
+
+ cparams = ctx->cparams;
+ fparams = ctx->fparams;
+
+ cparams->gbb_size = ctx->gbb.size;
+ fparams->verification_size_A = ctx->vblock_a.size;
+ fparams->verification_size_B = ctx->vblock_b.size;
+
+ if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ /* Get memory-mapped pointers to the regions. */
+ cparams->gbb_data = vboot_get_region(ctx->gbb.offset_addr,
+ ctx->gbb.size, NULL);
+ fparams->verification_block_A =
+ vboot_get_region(ctx->vblock_a.offset_addr,
+ ctx->vblock_a.size, NULL);
+ fparams->verification_block_B =
+ vboot_get_region(ctx->vblock_b.offset_addr,
+ ctx->vblock_b.size, NULL);
+ } else {
+ /*
+ * Copy the vblock info into a buffer in cbmem. The gbb will
+ * be read using VbExRegionRead().
+ */
+ char *dest;
+ size_t vblck_sz;
+
+ vblck_sz = ctx->vblock_a.size + ctx->vblock_b.size;
+ ctx->vblocks = cbmem_entry_add(TEMP_CBMEM_ID_VBLOCKS, vblck_sz);
+ if (ctx->vblocks == NULL)
+ return -1;
+ dest = cbmem_entry_start(ctx->vblocks);
+ if (vboot_get_region(ctx->vblock_a.offset_addr,
+ ctx->vblock_a.size, dest) == NULL)
+ return -1;
+ fparams->verification_block_A = (void *)dest;
+ dest += ctx->vblock_a.size;
+ if (vboot_get_region(ctx->vblock_b.offset_addr,
+ ctx->vblock_b.size, dest) == NULL)
+ return -1;
+ fparams->verification_block_B = (void *)dest;
+ }
+
+ return 0;
+}
+
+static void fill_handoff(struct vboot_context *context)
+{
+ struct vboot_components *fw_info;
+ struct vboot_region *region;
+ int i;
+
+ /* Fix up the handoff structure. */
+ context->handoff->selected_firmware =
+ context->fparams->selected_firmware;
+
+ /* Parse out the components for downstream consumption. */
+ if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_A)
+ region = &context->fw_a;
+ else if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_B)
+ region = &context->fw_b;
+ else
+ return;
+
+ fw_info = vboot_locate_components(region);
+ if (fw_info == NULL)
+ return;
+
+ for (i = 0; i < fw_info->num_components; i++) {
+ context->handoff->components[i].address =
+ region->offset_addr + fw_info->entries[i].offset;
+ context->handoff->components[i].size = fw_info->entries[i].size;
+ }
+}
+
+static void vboot_clean_up(struct vboot_context *context)
+{
+ if (context->vblocks != NULL)
+ cbmem_entry_remove(context->vblocks);
+}
+
+static void reset(void)
+{
+ hard_reset();
+}
+
+static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
+{
+ VbCommonParams cparams;
+ VbSelectFirmwareParams fparams;
+ struct vboot_context context;
+ uint32_t *iflags;
+
+ vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
+
+ memset(&cparams, 0, sizeof(cparams));
+ memset(&fparams, 0, sizeof(fparams));
+ memset(&context, 0, sizeof(context));
+
+ iflags = &vboot_handoff->init_params.flags;
+ if (get_developer_mode_switch())
+ *iflags |= VB_INIT_FLAG_DEV_SWITCH_ON;
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ *iflags |= VB_INIT_FLAG_REC_BUTTON_PRESSED;
+ }
+ if (get_write_protect_state())
+ *iflags |= VB_INIT_FLAG_WP_ENABLED;
+ if (vboot_get_sw_write_protect())
+ *iflags |= VB_INIT_FLAG_SW_WP_ENABLED;
+ if (CONFIG_VIRTUAL_DEV_SWITCH)
+ *iflags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
+ if (CONFIG_EC_SOFTWARE_SYNC) {
+ *iflags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC;
+ *iflags |= VB_INIT_FLAG_VIRTUAL_REC_SWITCH;
+ }
+ if (CONFIG_VBOOT_EC_SLOW_UPDATE)
+ *iflags |= VB_INIT_FLAG_EC_SLOW_UPDATE;
+ if (CONFIG_VBOOT_OPROM_MATTERS) {
+ *iflags |= VB_INIT_FLAG_OPROM_MATTERS;
+ /* Will load VGA option rom during this boot */
+ if (developer_mode_enabled() || recovery_mode_enabled() ||
+ vboot_wants_oprom()) {
+ *iflags |= VB_INIT_FLAG_OPROM_LOADED;
+ }
+ }
+
+ context.handoff = vboot_handoff;
+ context.cparams = &cparams;
+ context.fparams = &fparams;
+
+ cparams.shared_data_blob = &vboot_handoff->shared_data[0];
+ cparams.shared_data_size = VB_SHARED_DATA_MIN_SIZE;
+ cparams.caller_context = &context;
+
+ vboot_locate_region("GBB", &context.gbb);
+ vboot_locate_region("VBLOCK_A", &context.vblock_a);
+ vboot_locate_region("VBLOCK_B", &context.vblock_b);
+ vboot_locate_region("FW_MAIN_A", &context.fw_a);
+ vboot_locate_region("FW_MAIN_B", &context.fw_b);
+
+ /* Check all fmap entries. */
+ if (context.fw_a.size < 0 || context.fw_b.size < 0 ||
+ context.vblock_a.size < 0 || context.vblock_b.size < 0 ||
+ context.gbb.size < 0) {
+ printk(BIOS_DEBUG, "Not all fmap entries found for vboot.\n");
+ return;
+ }
+
+ /* Fill in vboot parameters. */
+ if (vboot_fill_params(&context)) {
+ vboot_clean_up(&context);
+ return;
+ }
+
+ /* Initialize callbacks. */
+ context.read_vbnv = &read_vbnv;
+ context.save_vbnv = &save_vbnv;
+ context.tis_init = &tis_init;
+ context.tis_open = &tis_open;
+ context.tis_close = &tis_close;
+ context.tis_sendrecv = &tis_sendrecv;
+ context.log_msg = &log_msg;
+ context.fatal_error = &fatal_error;
+ context.get_region = &vboot_get_region;
+ context.reset = &reset;
+
+ vboot_run_stub(&context);
+
+ fill_handoff(&context);
+
+ vboot_clean_up(&context);
+}
+
+#if CONFIG_RELOCATABLE_RAMSTAGE
+static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
+ const struct cbmem_entry **cbmem_entry)
+{
+ struct vboot_handoff *vboot_handoff;
+ struct cbfs_stage *stage;
+ const struct firmware_component *fwc;
+ struct rmod_stage_load rmod_load = {
+ .cbmem_id = cbmem_id,
+ .name = name,
+ };
+
+ timestamp_add_now(TS_START_VBOOT);
+
+ vboot_handoff = cbmem_add(CBMEM_ID_VBOOT_HANDOFF,
+ sizeof(*vboot_handoff));
+
+ if (vboot_handoff == NULL) {
+ printk(BIOS_DEBUG, "Could not add vboot_handoff structure.\n");
+ return NULL;
+ }
+
+ memset(vboot_handoff, 0, sizeof(*vboot_handoff));
+
+ vboot_invoke_wrapper(vboot_handoff);
+
+ timestamp_add_now(TS_END_VBOOT);
+
+ /* Take RO firmware path since no RW area was selected. */
+ if (vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_A &&
+ vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_B) {
+ printk(BIOS_DEBUG, "No RW firmware selected: 0x%08x\n",
+ vboot_handoff->selected_firmware);
+ return NULL;
+ }
+
+ if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid ramstage index: %d\n",
+ CONFIG_VBOOT_RAMSTAGE_INDEX);
+ return NULL;
+ }
+
+ /* Check for invalid address. */
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
+ if (fwc->address == 0) {
+ printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
+ return NULL;
+ }
+
+ printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
+ fwc->address, fwc->size);
+
+ stage = (void *)fwc->address;
+
+ if (rmodule_stage_load(&rmod_load, stage)) {
+ vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
+ printk(BIOS_DEBUG, "Could not load ramstage region.\n");
+ return NULL;
+ }
+
+ *cbmem_entry = rmod_load.cbmem_entry;
+
+ return rmod_load.entry;
+}
+#else /* CONFIG_RELOCATABLE_RAMSTAGE */
+static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
+ struct romstage_handoff *handoff)
+{
+ struct cbfs_stage *stage;
+ const struct firmware_component *fwc;
+
+ if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid ramstage index: %d\n",
+ CONFIG_VBOOT_RAMSTAGE_INDEX);
+ return;
+ }
+
+ /* Check for invalid address. */
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
+ if (fwc->address == 0) {
+ printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
+ fwc->address, fwc->size);
+
+ /* This will leak a mapping. */
+ stage = vboot_get_region(fwc->address, fwc->size, NULL);
+
+ if (stage == NULL) {
+ printk(BIOS_DEBUG, "Unable to get RW ramstage region.\n");
+ return;
+ }
+
+ timestamp_add_now(TS_START_COPYRAM);
+
+ /* Stages rely the below clearing so that the bss is initialized. */
+ memset((void *) (uintptr_t) stage->load, 0, stage->memlen);
+
+ if (cbfs_decompress(stage->compression,
+ ((unsigned char *) stage) +
+ sizeof(struct cbfs_stage),
+ (void *) (uintptr_t) stage->load,
+ stage->len))
+ return;
+
+ timestamp_add_now(TS_END_COPYRAM);
+
+#if CONFIG_ARCH_X86
+ __asm__ volatile (
+ "movl $0, %%ebp\n"
+ "jmp *%%edi\n"
+ :: "D"(stage->entry)
+ );
+#elif CONFIG_ARCH_ARM
+ stage_exit((void *)(uintptr_t)stage->entry);
+#endif
+}
+#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
+
+
+const struct ramstage_loader_ops vboot_ramstage_loader = {
+ .name = "VBOOT",
+ .load = vboot_load_ramstage,
+};
diff --git a/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c b/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c
new file mode 100644
index 0000000..5b9dbbb
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot1/vboot_wrapper.c
@@ -0,0 +1,266 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <console/vtxprintf.h>
+#if CONFIG_ARCH_X86
+#include <cpu/x86/tsc.h>
+#else
+#include <timer.h>
+#endif
+#include <rmodule.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../vboot_context.h"
+#include "../vboot_handoff.h"
+
+/* Keep a global context pointer around for the callbacks to use. */
+static struct vboot_context *gcontext;
+
+static void vboot_wrapper(void *arg)
+{
+ VbError_t res;
+ struct vboot_context *context;
+
+ context = arg;
+ gcontext = context;
+
+ VbExDebug("Calling VbInit()\n");
+ res = VbInit(context->cparams, &context->handoff->init_params);
+ VbExDebug("VbInit() returned 0x%08x\n", res);
+
+ if (res != VBERROR_SUCCESS) {
+ if(res == VBERROR_TPM_REBOOT_REQUIRED) {
+ VbExDebug("TPM Reboot Required. Proceeding reboot.\n");
+ gcontext->reset();
+ }
+ return;
+ }
+
+ VbExDebug("Calling VbSelectFirmware()\n");
+ res = VbSelectFirmware(context->cparams, context->fparams);
+ VbExDebug("VbSelectFirmware() returned 0x%08x\n", res);
+
+ if (res != VBERROR_SUCCESS)
+ return;
+}
+
+void VbExError(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ gcontext->log_msg(format, args);
+ va_end(args);
+
+ gcontext->fatal_error();
+}
+
+void VbExDebug(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ gcontext->log_msg(format, args);
+ va_end(args);
+}
+
+uint64_t VbExGetTimer(void)
+{
+#if CONFIG_ARCH_X86
+ return rdtscll();
+#else
+ struct mono_time mt;
+ timer_monotonic_get(&mt);
+ return mt.microseconds;
+#endif
+}
+
+VbError_t VbExNvStorageRead(uint8_t *buf)
+{
+ gcontext->read_vbnv(buf);
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExNvStorageWrite(const uint8_t *buf)
+{
+ gcontext->save_vbnv(buf);
+ return VBERROR_SUCCESS;
+}
+
+extern char _heap[];
+extern char _eheap[];
+static char *heap_current;
+static int heap_size;
+
+void *VbExMalloc(size_t size)
+{
+ void *ptr;
+
+ if (heap_current == NULL) {
+ heap_current = &_heap[0];
+ heap_size = &_eheap[0] - &_heap[0];
+ VbExDebug("vboot heap: %p 0x%08x bytes\n",
+ heap_current, heap_size);
+ }
+
+ if (heap_size < size) {
+ VbExError("vboot heap request cannot be fulfilled. "
+ "0x%08x available, 0x%08x requested\n",
+ heap_size, size);
+ }
+
+ ptr = heap_current;
+ heap_size -= size;
+ heap_current += size;
+
+ return ptr;
+}
+
+void VbExFree(void *ptr)
+{
+ /* Leak all memory. */
+}
+
+/* vboot doesn't expose these through the vboot_api.h, but they are needed.
+ * coreboot requires declarations so provide them to avoid compiler errors. */
+int Memcmp(const void *src1, const void *src2, size_t n);
+void *Memcpy(void *dest, const void *src, uint64_t n);
+void *Memset(void *dest, const uint8_t c, uint64_t n);
+
+int Memcmp(const void *src1, const void *src2, size_t n)
+{
+ return memcmp(src1, src2, n);
+}
+
+void *Memcpy(void *dest, const void *src, uint64_t n)
+{
+ return memcpy(dest, src, n);
+}
+
+void *Memset(void *dest, const uint8_t c, uint64_t n)
+{
+ return memset(dest, c, n);
+}
+
+static inline size_t get_hash_block_size(size_t requested_size)
+{
+ if (!IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ const size_t block_size = 64 * 1024;
+ if (requested_size > block_size)
+ return block_size;
+ }
+ return requested_size;
+}
+
+VbError_t VbExHashFirmwareBody(VbCommonParams *cparams, uint32_t firmware_index)
+{
+ uint8_t *data;
+ struct vboot_region *region;
+ struct vboot_context *ctx;
+ size_t data_size;
+ uintptr_t offset_addr;
+
+ ctx = cparams->caller_context;
+
+ switch (firmware_index) {
+ case VB_SELECT_FIRMWARE_A:
+ region = &ctx->fw_a;
+ break;
+ case VB_SELECT_FIRMWARE_B:
+ region = &ctx->fw_b;
+ break;
+ default:
+ return VBERROR_UNKNOWN;
+ }
+
+ data_size = region->size;
+ offset_addr = region->offset_addr;
+ while (data_size) {
+ size_t block_size;
+
+ block_size = get_hash_block_size(data_size);
+ data = ctx->get_region(offset_addr, block_size, NULL);
+ if (data == NULL)
+ return VBERROR_UNKNOWN;
+ VbUpdateFirmwareBodyHash(cparams, data, block_size);
+
+ data_size -= block_size;
+ offset_addr += block_size;
+ }
+
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExTpmInit(void)
+{
+ if (gcontext->tis_init())
+ return VBERROR_UNKNOWN;
+ return VbExTpmOpen();
+}
+
+VbError_t VbExTpmClose(void)
+{
+ if (gcontext->tis_close())
+ return VBERROR_UNKNOWN;
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExTpmOpen(void)
+{
+ if (gcontext->tis_open())
+ return VBERROR_UNKNOWN;
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length,
+ uint8_t *response, uint32_t *response_length)
+{
+ size_t len = *response_length;
+ if (gcontext->tis_sendrecv(request, request_length, response, &len))
+ return VBERROR_UNKNOWN;
+ /* check 64->32bit overflow and (re)check response buffer overflow */
+ if (len > *response_length)
+ return VBERROR_UNKNOWN;
+ *response_length = len;
+ return VBERROR_SUCCESS;
+}
+
+#if !CONFIG_SPI_FLASH_MEMORY_MAPPED
+VbError_t VbExRegionRead(VbCommonParams *cparams,
+ enum vb_firmware_region region, uint32_t offset,
+ uint32_t size, void *buf)
+{
+ struct vboot_context *ctx;
+ VbExDebug("VbExRegionRead: offset=%x size=%x, buf=%p\n",
+ offset, size, buf);
+ ctx = cparams->caller_context;
+
+ if (region == VB_REGION_GBB) {
+ if (offset + size > cparams->gbb_size)
+ return VBERROR_REGION_READ_INVALID;
+ offset += ctx->gbb.offset_addr;
+ if (ctx->get_region(offset, size, buf) == NULL)
+ return VBERROR_REGION_READ_INVALID;
+ return VBERROR_SUCCESS;
+ }
+
+ return VBERROR_UNSUPPORTED_REGION;
+}
+#endif /* CONFIG_SPI_FLASH_MEMORY_MAPPED */
+
+RMODULE_ENTRY(vboot_wrapper);
diff --git a/src/vendorcode/google/chromeos/vboot2/Kconfig b/src/vendorcode/google/chromeos/vboot2/Kconfig
new file mode 100644
index 0000000..20d2f1f
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/Kconfig
@@ -0,0 +1,43 @@
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+config VBOOT2_VERIFY_FIRMWARE
+ bool "Firmware Verification with vboot2"
+ default n
+ depends on CHROMEOS && HAVE_HARD_RESET
+ help
+ Enabling VBOOT2_VERIFY_FIRMWARE will use vboot2 to verify the romstage
+ and boot loader.
+
+config RETURN_FROM_VERSTAGE
+ bool "return from verstage"
+ default n
+ depends on VBOOT2_VERIFY_FIRMWARE
+ help
+ If this is set, the verstage returns back to the bootblock instead of
+ exits to the romstage so that the verstage space can be reused by the
+ romstage. Useful if a ram space is too small to fit both the verstage
+ and the romstage.
+
+config VBOOT_ROMSTAGE_INDEX
+ hex
+ default 2
+ depends on VBOOT2_VERIFY_FIRMWARE
+ help
+ This is the index of the romstage component in the verified
+ firmware block.
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
new file mode 100644
index 0000000..3c07a51
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -0,0 +1,60 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+verstage-generic-ccopts += -D__PRE_RAM__ -D__VERSTAGE__
+
+ramstage-y += ../vboot_common.c
+romstage-y += ../vboot_common.c
+
+ifeq ($(CONFIG_RETURN_FROM_VERSTAGE),y)
+bootblock-y += common.c verstub.c ../chromeos.c ../vboot_common.c
+else
+verstage-y += verstub.c
+endif
+verstage-y += verstage.c ../fmap.c ../chromeos.c ../vboot_common.c
+verstage-y += antirollback.c common.c
+verstage-$(CONFIG_CHROMEOS_VBNV_CMOS) += ../vbnv_cmos.c
+verstage-$(CONFIG_CHROMEOS_VBNV_EC) += ../vbnv_ec.c
+verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += ../vbnv_flash.c
+romstage-y += vboot_handoff.c common.c
+
+verstage-y += verstage.ld
+
+VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
+VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
+VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage)))
+VBOOT_CFLAGS += $(verstage-c-ccopts)
+VBOOT_CFLAGS += -include $(top)/src/include/kconfig.h -Wno-missing-prototypes
+VBOOT_CFLAGS += -DVBOOT_DEBUG
+
+$(VB2_LIB): $(obj)/config.h
+ @printf " MAKE $(subst $(obj)/,,$(@))\n"
+ $(Q)FIRMWARE_ARCH=$(VB_FIRMWARE_ARCH) \
+ CC="$(CC_verstage)" \
+ CFLAGS="$(VBOOT_CFLAGS)" VBOOT2="y" \
+ $(MAKE) -C $(VB_SOURCE) \
+ BUILD=$(top)/$(dir $(VB2_LIB)) \
+ V=$(V) \
+ fwlib2
+
+VERSTAGE_ELF = $(objcbfs)/verstage.elf
+cbfs-files-y += $(call strip_quotes,$(CONFIG_CBFS_PREFIX))/verstage
+fallback/verstage-file = $(VERSTAGE_ELF)
+fallback/verstage-type = stage
+fallback/verstage-compression = none
diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
new file mode 100644
index 0000000..bb547b5
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/antirollback.c
@@ -0,0 +1,329 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Functions for querying, manipulating and locking rollback indices
+ * stored in the TPM NVRAM.
+ */
+
+#include <2api.h>
+#include <2sysincludes.h>
+#include <antirollback.h>
+#include <tpm_lite/tlcl.h>
+#include <tpm_lite/tss_constants.h>
+
+#ifndef offsetof
+#define offsetof(A,B) __builtin_offsetof(A,B)
+#endif
+
+#ifdef FOR_TEST
+#include <stdio.h>
+#define VBDEBUG(format, args...) printf(format, ## args)
+#else
+#include <console/console.h>
+#define VBDEBUG(format, args...) \
+ printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
+#endif
+
+#define RETURN_ON_FAILURE(tpm_cmd) do { \
+ uint32_t result_; \
+ if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
+ VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
+ "\n", (int)result_); \
+ return result_; \
+ } \
+ } while (0)
+
+uint32_t tpm_clear_and_reenable(void)
+{
+ VBDEBUG("TPM: Clear and re-enable\n");
+ RETURN_ON_FAILURE(tlcl_force_clear());
+ RETURN_ON_FAILURE(tlcl_set_enable());
+ RETURN_ON_FAILURE(tlcl_set_deactivated(0));
+
+ return TPM_SUCCESS;
+}
+
+uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
+{
+ uint32_t result = tlcl_write(index, data, length);
+ if (result == TPM_E_MAXNVWRITES) {
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl_write(index, data, length);
+ } else {
+ return result;
+ }
+}
+
+uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ uint32_t result = tlcl_define_space(index, perm, size);
+ if (result == TPM_E_MAXNVWRITES) {
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl_define_space(index, perm, size);
+ } else {
+ return result;
+ }
+}
+
+static uint32_t read_space_firmware(struct vb2_context *ctx)
+{
+ int attempts = 3;
+
+ while (attempts--) {
+ RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
+ VB2_SECDATA_SIZE));
+
+ if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
+ return TPM_SUCCESS;
+
+ VBDEBUG("TPM: %s() - bad CRC\n", __func__);
+ }
+
+ VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
+ return TPM_E_CORRUPTED_STATE;
+}
+
+static uint32_t write_secdata(uint32_t index,
+ const uint8_t *secdata,
+ uint32_t len)
+{
+ uint8_t sd[32];
+ uint32_t rv;
+ int attempts = 3;
+
+ if (len > sizeof(sd)) {
+ VBDEBUG("TPM: %s() - data is too large\n", __func__);
+ return TPM_E_WRITE_FAILURE;
+ }
+
+ while (attempts--) {
+ rv = safe_write(index, secdata, len);
+ /* Can't write, not gonna try again */
+ if (rv != TPM_SUCCESS)
+ return rv;
+
+ /* Read it back to be sure it got the right values. */
+ rv = tlcl_read(index, sd, len);
+ if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
+ return rv;
+
+ VBDEBUG("TPM: %s() failed. trying again\n", __func__);
+ /* Try writing it again. Maybe it was garbled on the way out. */
+ }
+
+ VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
+
+ return TPM_E_CORRUPTED_STATE;
+}
+
+uint32_t factory_initialize_tpm(struct vb2_context *ctx)
+{
+ TPM_PERMANENT_FLAGS pflags;
+ uint32_t result;
+ /* this is derived from rollback_index.h of vboot_reference. see struct
+ * RollbackSpaceKernel for details. */
+ static const uint8_t secdata_kernel[] = {
+ 0x02,
+ 0x4C, 0x57, 0x52, 0x47,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xE8,
+ };
+
+ VBDEBUG("TPM: factory initialization\n");
+
+ /*
+ * Do a full test. This only happens the first time the device is
+ * turned on in the factory, so performance is not an issue. This is
+ * almost certainly not necessary, but it gives us more confidence
+ * about some code paths below that are difficult to
+ * test---specifically the ones that set lifetime flags, and are only
+ * executed once per physical TPM.
+ */
+ result = tlcl_self_test_full();
+ if (result != TPM_SUCCESS)
+ return result;
+
+ result = tlcl_get_permanent_flags(&pflags);
+ if (result != TPM_SUCCESS)
+ return result;
+
+ /*
+ * TPM may come from the factory without physical presence finalized.
+ * Fix if necessary.
+ */
+ VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
+ pflags.physicalPresenceLifetimeLock);
+ if (!pflags.physicalPresenceLifetimeLock) {
+ VBDEBUG("TPM: Finalizing physical presence\n");
+ RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
+ }
+
+ /*
+ * The TPM will not enforce the NV authorization restrictions until the
+ * execution of a TPM_NV_DefineSpace with the handle of
+ * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
+ * exist. */
+ VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
+ if (!pflags.nvLocked) {
+ VBDEBUG("TPM: Enabling NV locking\n");
+ RETURN_ON_FAILURE(tlcl_set_nv_locked());
+ }
+
+ /* Clear TPM owner, in case the TPM is already owned for some reason. */
+ VBDEBUG("TPM: Clearing owner\n");
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+
+ /* Define the backup space. No need to initialize it, though. */
+ RETURN_ON_FAILURE(safe_define_space(BACKUP_NV_INDEX,
+ TPM_NV_PER_PPWRITE,
+ VB2_NVDATA_SIZE));
+
+ /* Define and initialize the kernel space */
+ RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
+ TPM_NV_PER_PPWRITE,
+ sizeof(secdata_kernel)));
+ RETURN_ON_FAILURE(write_secdata(KERNEL_NV_INDEX,
+ secdata_kernel,
+ sizeof(secdata_kernel)));
+
+ /* Defines and sets vb2 secdata space */
+ vb2api_secdata_create(ctx);
+ RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
+ TPM_NV_PER_GLOBALLOCK |
+ TPM_NV_PER_PPWRITE,
+ VB2_SECDATA_SIZE));
+ RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
+ ctx->secdata,
+ VB2_SECDATA_SIZE));
+
+ VBDEBUG("TPM: factory initialization successful\n");
+
+ return TPM_SUCCESS;
+}
+
+/*
+ * SetupTPM starts the TPM and establishes the root of trust for the
+ * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
+ * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
+ * general we cannot easily distinguish the kind of failure, so our strategy is
+ * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
+ * again, which executes (almost) the same sequence of operations. There is a
+ * good chance that, if recovery mode was entered because of a TPM failure, the
+ * failure will repeat itself. (In general this is impossible to guarantee
+ * because we have no way of creating the exact TPM initial state at the
+ * previous boot.) In recovery mode, we ignore the failure and continue, thus
+ * giving the recovery kernel a chance to fix things (that's why we don't set
+ * bGlobalLock). The choice is between a knowingly insecure device and a
+ * bricked device.
+ *
+ * As a side note, observe that we go through considerable hoops to avoid using
+ * the STCLEAR permissions for the index spaces. We do this to avoid writing
+ * to the TPM flashram at every reboot or wake-up, because of concerns about
+ * the durability of the NVRAM.
+ */
+uint32_t setup_tpm(struct vb2_context *ctx)
+{
+ uint8_t disable;
+ uint8_t deactivated;
+ uint32_t result;
+
+ RETURN_ON_FAILURE(tlcl_lib_init());
+
+#ifdef TEGRA_SOFT_REBOOT_WORKAROUND
+ result = tlcl_startup();
+ if (result == TPM_E_INVALID_POSTINIT) {
+ /*
+ * Some prototype hardware doesn't reset the TPM on a CPU
+ * reset. We do a hard reset to get around this.
+ */
+ VBDEBUG("TPM: soft reset detected\n", result);
+ return TPM_E_MUST_REBOOT;
+ } else if (result != TPM_SUCCESS) {
+ VBDEBUG("TPM: tlcl_startup returned %08x\n", result);
+ return result;
+ }
+#else
+ RETURN_ON_FAILURE(tlcl_startup());
+#endif
+
+ /*
+ * Some TPMs start the self test automatically at power on. In that case
+ * we don't need to call ContinueSelfTest. On some (other) TPMs,
+ * continue_self_test may block. In that case, we definitely don't want
+ * to call it here. For TPMs in the intersection of these two sets, we
+ * are screwed. (In other words: TPMs that require manually starting the
+ * self-test AND block will have poor performance until we split
+ * tlcl_send_receive() into send() and receive(), and have a state
+ * machine to control setup.)
+ *
+ * This comment is likely to become obsolete in the near future, so
+ * don't trust it. It may have not been updated.
+ */
+#ifdef TPM_MANUAL_SELFTEST
+#ifdef TPM_BLOCKING_CONTINUESELFTEST
+#warning "lousy TPM!"
+#endif
+ RETURN_ON_FAILURE(tlcl_continue_self_test());
+#endif
+ result = tlcl_assert_physical_presence();
+ if (result != TPM_SUCCESS) {
+ /*
+ * It is possible that the TPM was delivered with the physical
+ * presence command disabled. This tries enabling it, then
+ * tries asserting PP again.
+ */
+ RETURN_ON_FAILURE(tlcl_physical_presence_cmd_enable());
+ RETURN_ON_FAILURE(tlcl_assert_physical_presence());
+ }
+
+ /* Check that the TPM is enabled and activated. */
+ RETURN_ON_FAILURE(tlcl_get_flags(&disable, &deactivated, NULL));
+ if (disable || deactivated) {
+ VBDEBUG("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
+ disable, deactivated);
+ RETURN_ON_FAILURE(tlcl_set_enable());
+ RETURN_ON_FAILURE(tlcl_set_deactivated(0));
+ VBDEBUG("TPM: Must reboot to re-enable\n");
+ return TPM_E_MUST_REBOOT;
+ }
+
+ VBDEBUG("TPM: SetupTPM() succeeded\n");
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
+{
+ uint32_t rv;
+
+ rv = setup_tpm(ctx);
+ if (rv)
+ return rv;
+
+ /* Read the firmware space. */
+ rv = read_space_firmware(ctx);
+ if (rv == TPM_E_BADINDEX) {
+ /*
+ * This seems the first time we've run. Initialize the TPM.
+ */
+ VBDEBUG("TPM: Not initialized yet.\n");
+ RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
+ } else if (rv != TPM_SUCCESS) {
+ VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
+ //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
+ return TPM_E_CORRUPTED_STATE;
+ }
+
+ return TPM_SUCCESS;
+}
+
+uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
+{
+ return write_secdata(FIRMWARE_NV_INDEX, ctx->secdata, VB2_SECDATA_SIZE);
+}
+
+uint32_t antirollback_lock_space_firmware()
+{
+ return tlcl_set_global_lock();
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/common.c b/src/vendorcode/google/chromeos/vboot2/common.c
new file mode 100644
index 0000000..178e8b5
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/common.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbfs.h>
+#include <console/console.h>
+#include <reset.h>
+#include "../chromeos.h"
+#include "../vboot_handoff.h"
+#include "misc.h"
+#include "symbols.h"
+
+void *vboot_load_stage(int stage_index,
+ struct vboot_region *fw_main,
+ struct vboot_components *fw_info)
+{
+ struct cbfs_media default_media, *media = &default_media;
+ uintptr_t fc_addr;
+ uint32_t fc_size;
+ void *entry;
+
+ if (stage_index >= fw_info->num_components) {
+ printk(BIOS_INFO, "invalid stage index\n");
+ return NULL;
+ }
+
+ fc_addr = fw_main->offset_addr + fw_info->entries[stage_index].offset;
+ fc_size = fw_info->entries[stage_index].size;
+ if (fc_size == 0 ||
+ fc_addr + fc_size > fw_main->offset_addr + fw_main->size) {
+ printk(BIOS_INFO, "invalid stage address or size\n");
+ return NULL;
+ }
+
+ init_default_cbfs_media(media);
+
+ /* we're making cbfs access offset outside of the region managed by
+ * cbfs. this works because cbfs_load_stage_by_offset does not check
+ * the offset. */
+ entry = cbfs_load_stage_by_offset(media, fc_addr);
+ if (entry == (void *)-1)
+ entry = NULL;
+ return entry;
+}
+
+struct vb2_working_data * const vboot_get_working_data(void)
+{
+ return (struct vb2_working_data *)_vboot2_work;
+}
+
+void vboot_reboot(void)
+{
+ hard_reset();
+ die("failed to reboot");
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/memlayout.h b/src/vendorcode/google/chromeos/vboot2/memlayout.h
new file mode 100644
index 0000000..9e19200
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/memlayout.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __CHROMEOS_VBOOT2_MEMLAYOUT_H
+#define __CHROMEOS_VBOOT2_MEMLAYOUT_H
+
+#define VBOOT2_WORK(addr, size) \
+ REGION(vboot2_work, addr, size, 4) \
+ _ = ASSERT(size >= 16K, "vboot2 work buffer must be at least 16K!");
+
+#ifdef __VERSTAGE__
+ #define VERSTAGE(addr, sz) \
+ SET_COUNTER(VERSTAGE, addr) \
+ _ = ASSERT(_everstage - _verstage <= sz, \
+ STR(Verstage exceeded its allotted size! (sz))); \
+ INCLUDE "vendorcode/google/chromeos/vboot2/verstage.verstage.ld"
+#else
+ #define VERSTAGE(addr, sz) \
+ SET_COUNTER(VERSTAGE, addr) \
+ . += sz;
+#endif
+
+#ifdef __VERSTAGE__
+ #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) VERSTAGE(addr, size)
+#else
+ #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) ROMSTAGE(addr, size)
+#endif
+
+#endif /* __CHROMEOS_VBOOT2_MEMLAYOUT_H */
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
new file mode 100644
index 0000000..cae302b
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CHROMEOS_VBOOT2_MISC_H__
+#define __CHROMEOS_VBOOT2_MISC_H__
+
+#include "../vboot_common.h"
+
+void vboot2_verify_firmware(void);
+void *vboot2_load_ramstage(void);
+void verstage_main(void);
+void *vboot_load_stage(int stage_index,
+ struct vboot_region *fw_main,
+ struct vboot_components *fw_info);
+void vboot_reboot(void);
+
+/*
+ * this is placed at the start of the vboot work buffer. selected_region is used
+ * for the verstage to return the location of the selected slot. buffer is used
+ * by the vboot2 core. Keep the struct cpu architecture agnostic as it crosses
+ * stage boundaries.
+ */
+struct vb2_working_data {
+ uint32_t selected_region_offset;
+ uint32_t selected_region_size;
+ uint64_t buffer_size;
+ uint64_t buffer;
+};
+
+struct vb2_working_data * const vboot_get_working_data(void);
+
+static inline void vb2_get_selected_region(struct vb2_working_data *wd,
+ struct vboot_region *region)
+{
+ region->offset_addr = wd->selected_region_offset;
+ region->size = wd->selected_region_size;
+}
+
+static inline void vb2_set_selected_region(struct vb2_working_data *wd,
+ struct vboot_region *region)
+{
+ wd->selected_region_offset = region->offset_addr;
+ wd->selected_region_size = region->size;
+}
+
+static inline int vboot_is_slot_selected(struct vb2_working_data *wd)
+{
+ return wd->selected_region_size > 0;
+}
+
+static inline int vboot_is_readonly_path(struct vb2_working_data *wd)
+{
+ return wd->selected_region_size == 0;
+}
+
+#endif /* __CHROMEOS_VBOOT2_MISC_H__ */
diff --git a/src/vendorcode/google/chromeos/vboot2/symbols.h b/src/vendorcode/google/chromeos/vboot2/symbols.h
new file mode 100644
index 0000000..fda7114
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/symbols.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __CHROMEOS_VBOOT2_SYMBOLS_H
+#define __CHROMEOS_VBOOT2_SYMBOLS_H
+
+extern u8 _vboot2_work[];
+extern u8 _evboot2_work[];
+#define _vboot2_work_size (_evboot2_work - _vboot2_work)
+
+/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */
+extern u8 _verstage[];
+extern u8 _everstage[];
+#define _verstage_size (_everstage - _verstage)
+
+#endif /* __CHROMEOS_VBOOT2_SYMBOLS_H */
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
new file mode 100644
index 0000000..a8573d0
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c
@@ -0,0 +1,175 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <2recovery_reasons.h>
+#include <2struct.h>
+#include <arch/stages.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <stdlib.h>
+#include <timestamp.h>
+#include <vboot_struct.h>
+#include "../chromeos.h"
+#include "../fmap.h"
+#include "../vboot_handoff.h"
+#include "misc.h"
+
+static void *load_ramstage(struct vboot_handoff *vboot_handoff,
+ struct vboot_region *fw_main)
+{
+ struct vboot_components *fw_info;
+ int i;
+
+ fw_info = vboot_locate_components(fw_main);
+ if (fw_info == NULL)
+ die("failed to locate firmware components\n");
+
+ /* these offset & size are used to load a rw boot loader */
+ for (i = 0; i < fw_info->num_components; i++) {
+ vboot_handoff->components[i].address =
+ fw_main->offset_addr + fw_info->entries[i].offset;
+ vboot_handoff->components[i].size = fw_info->entries[i].size;
+ }
+
+ return vboot_load_stage(CONFIG_VBOOT_RAMSTAGE_INDEX, fw_main, fw_info);
+}
+
+/**
+ * Sets vboot_handoff based on the information in vb2_shared_data
+ *
+ * TODO: Read wp switch to set VBSD_BOOT_FIRMWARE_WP_ENABLED
+ */
+static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
+ struct vb2_shared_data *vb2_sd)
+{
+ VbSharedDataHeader *vb_sd =
+ (VbSharedDataHeader *)vboot_handoff->shared_data;
+ uint32_t *oflags = &vboot_handoff->init_params.out_flags;
+
+ vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
+
+ vboot_handoff->selected_firmware = vb2_sd->fw_slot;
+
+ vb_sd->firmware_index = vb2_sd->fw_slot;
+
+ vb_sd->magic = VB_SHARED_DATA_MAGIC;
+ vb_sd->struct_version = VB_SHARED_DATA_VERSION;
+ vb_sd->struct_size = sizeof(VbSharedDataHeader);
+ vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE;
+ vb_sd->data_used = sizeof(VbSharedDataHeader);
+
+ if (vb2_sd->recovery_reason) {
+ vb_sd->firmware_index = 0xFF;
+ if (vb2_sd->recovery_reason == VB2_RECOVERY_RO_MANUAL)
+ vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
+ *oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
+ *oflags |= VB_INIT_OUT_CLEAR_RAM;
+ *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
+ *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
+ }
+ if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) {
+ *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER;
+ *oflags |= VB_INIT_OUT_CLEAR_RAM;
+ *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
+ *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
+ vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
+ vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
+ }
+ /* TODO: Set these in depthcharge */
+ if (CONFIG_VIRTUAL_DEV_SWITCH)
+ vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
+ if (CONFIG_EC_SOFTWARE_SYNC) {
+ vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
+ vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
+ }
+ /* In vboot1, VBSD_FWB_TRIED is
+ * set only if B is booted as explicitly requested. Therefore, if B is
+ * booted because A was found bad, the flag should not be set. It's
+ * better not to touch it if we can only ambiguously control it. */
+ /* if (vb2_sd->fw_slot)
+ vb_sd->flags |= VBSD_FWB_TRIED; */
+
+ /* copy kernel subkey if it's found */
+ if (vb2_sd->workbuf_preamble_size) {
+ struct vb2_fw_preamble *fp;
+ uintptr_t dst, src;
+ printk(BIOS_INFO, "Copying FW preamble\n");
+ fp = (struct vb2_fw_preamble *)((uintptr_t)vb2_sd +
+ vb2_sd->workbuf_preamble_offset);
+ src = (uintptr_t)&fp->kernel_subkey +
+ fp->kernel_subkey.key_offset;
+ dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
+ assert(dst + fp->kernel_subkey.key_size <=
+ (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
+ memcpy((void *)dst, (void *)src,
+ fp->kernel_subkey.key_size);
+ vb_sd->data_used += fp->kernel_subkey.key_size;
+ vb_sd->kernel_subkey.key_offset =
+ dst - (uintptr_t)&vb_sd->kernel_subkey;
+ vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
+ vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
+ vb_sd->kernel_subkey.key_version =
+ fp->kernel_subkey.key_version;
+ }
+
+ vb_sd->recovery_reason = vb2_sd->recovery_reason;
+}
+
+/**
+ * Load ramstage and return the entry point
+ */
+void *vboot2_load_ramstage(void)
+{
+ struct vboot_handoff *vh;
+ struct vb2_shared_data *sd;
+ struct vboot_region fw_main;
+ struct vb2_working_data *wd = vboot_get_working_data();
+
+ sd = (struct vb2_shared_data *)(uintptr_t)wd->buffer;
+ sd->workbuf_hash_offset = 0;
+ sd->workbuf_hash_size = 0;
+
+ printk(BIOS_INFO, "creating vboot_handoff structure\n");
+ vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
+ if (vh == NULL)
+ /* we don't need to failover gracefully here because this
+ * shouldn't happen with the image that has passed QA. */
+ die("failed to allocate vboot_handoff structure\n");
+
+ memset(vh, 0, sizeof(*vh));
+
+ /* needed until we finish transtion to vboot2 for kernel verification */
+ fill_vboot_handoff(vh, sd);
+
+ if (vboot_is_readonly_path(wd))
+ /* we're on recovery path. continue to ro-ramstage. */
+ return NULL;
+
+ printk(BIOS_INFO,
+ "loading ramstage from Slot %c\n", sd->fw_slot ? 'B' : 'A');
+ vb2_get_selected_region(wd, &fw_main);
+
+ return load_ramstage(vh, &fw_main);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
new file mode 100644
index 0000000..572e161
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -0,0 +1,252 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <2api.h>
+#include <2struct.h>
+#include <antirollback.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <string.h>
+
+#include "../chromeos.h"
+#include "misc.h"
+
+#define TODO_BLOCK_SIZE 1024
+
+static int is_slot_a(struct vb2_context *ctx)
+{
+ return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
+}
+
+/* exports */
+
+void vb2ex_printf(const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ printk(BIOS_INFO, "VB2:%s() ", func);
+ va_start(args, fmt);
+ vprintk(BIOS_INFO, fmt, args);
+ va_end(args);
+
+ return;
+}
+
+int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
+{
+ uint32_t rv;
+ printk(BIOS_INFO, "Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
+}
+
+int vb2ex_read_resource(struct vb2_context *ctx,
+ enum vb2_resource_index index,
+ uint32_t offset,
+ void *buf,
+ uint32_t size)
+{
+ struct vboot_region region;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ vboot_locate_region("GBB", ®ion);
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ vboot_locate_region("VBLOCK_A", ®ion);
+ else
+ vboot_locate_region("VBLOCK_B", ®ion);
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (offset + size > region.size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (vboot_get_region(region.offset_addr + offset, size, buf) == NULL)
+ return VB2_ERROR_UNKNOWN;
+
+ return VB2_SUCCESS;
+}
+
+static int hash_body(struct vb2_context *ctx, struct vboot_region *fw_main)
+{
+ uint32_t expected_size;
+ MAYBE_STATIC uint8_t block[TODO_BLOCK_SIZE];
+ size_t block_size = sizeof(block);
+ uintptr_t offset;
+ int rv;
+
+ expected_size = fw_main->size;
+ offset = fw_main->offset_addr;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /* Extend over the body */
+ while (expected_size) {
+ void *b;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ b = vboot_get_region(offset, block_size, block);
+ if (b == NULL)
+ return VB2_ERROR_UNKNOWN;
+ rv = vb2api_extend_hash(ctx, b, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ /* Check the result */
+ rv = vb2api_check_hash(ctx);
+ if (rv)
+ return rv;
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct vboot_region *fw_main)
+{
+ if (is_slot_a(ctx))
+ vboot_locate_region("FW_MAIN_A", fw_main);
+ else
+ vboot_locate_region("FW_MAIN_B", fw_main);
+
+ if (fw_main->size < 0)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * Save non-volatile and/or secure data if needed.
+ */
+static void save_if_needed(struct vb2_context *ctx)
+{
+ if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving nvdata\n");
+ save_vbnv(ctx->nvdata);
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+ if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving secdata\n");
+ antirollback_write_space_firmware(ctx);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
+ }
+}
+
+/**
+ * Verify and select the firmware in the RW image
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
+#if CONFIG_RETURN_FROM_VERSTAGE
+void main(void)
+#else
+void verstage_main(void)
+#endif /* CONFIG_RETURN_FROM_VERSTAGE */
+{
+ struct vb2_context ctx;
+ struct vboot_region fw_main;
+ struct vb2_working_data *wd = vboot_get_working_data();
+ int rv;
+
+ /* Set up context and work buffer */
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = (uint8_t *)(uintptr_t)wd->buffer;
+ ctx.workbuf_size = wd->buffer_size;
+
+ /* Read nvdata from a non-volatile storage */
+ read_vbnv(ctx.nvdata);
+
+ /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
+ * check the return value here because vb2api_fw_phase1 will catch
+ * invalid secdata and tell us what to do (=reboot). */
+ antirollback_read_space_firmware(&ctx);
+
+ if (get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ }
+
+ /* Do early init */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ /* If we need recovery mode, leave firmware selection now */
+ save_if_needed(&ctx);
+ return;
+ }
+
+ /* Determine which firmware slot to boot */
+ printk(BIOS_INFO, "Phase 2\n");
+ rv = vb2api_fw_phase2(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Try that slot */
+ printk(BIOS_INFO, "Phase 3\n");
+ rv = vb2api_fw_phase3(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Phase 4\n");
+ rv = locate_firmware(&ctx, &fw_main);
+ if (rv)
+ die("Failed to read FMAP to locate firmware");
+
+ rv = hash_body(&ctx, &fw_main);
+ save_if_needed(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ vboot_reboot();
+ }
+
+ /* Lock TPM */
+ rv = antirollback_lock_space_firmware();
+ if (rv) {
+ printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
+ vb2_set_selected_region(wd, &fw_main);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.ld b/src/vendorcode/google/chromeos/vboot2/verstage.ld
new file mode 100644
index 0000000..c7fd646
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.ld
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file is included inside a SECTIONS block */
+
+.text . : {
+ _program = .;
+ _verstage = .;
+ *(.text._start);
+ *(.text.stage_entry);
+ *(.text);
+ *(.text.*);
+} : to_load
+
+.data . : {
+ *(.rodata);
+ *(.rodata.*);
+ *(.data);
+ *(.data.*);
+ . = ALIGN(8);
+}
+
+.bss . : {
+ . = ALIGN(8);
+ _bss = .;
+ *(.bss)
+ *(.bss.*)
+ *(.sbss)
+ *(.sbss.*)
+ _ebss = .;
+ _everstage = .;
+ _eprogram = .;
+}
+
+/* Discard the sections we don't need/want */
+/DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.eh_frame);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstub.c b/src/vendorcode/google/chromeos/vboot2/verstub.c
new file mode 100644
index 0000000..e8faa07
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/verstub.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/stages.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <string.h>
+#include "../chromeos.h"
+#include "misc.h"
+#include "symbols.h"
+
+static struct vb2_working_data *init_vb2_working_data(void)
+{
+ struct vb2_working_data *wd;
+
+ wd = vboot_get_working_data();
+ memset(wd, 0, _vboot2_work_size);
+ /* 8-byte alignment for ARMv7 */
+ wd->buffer = ALIGN_UP((uintptr_t)&wd[1], 8);
+ wd->buffer_size = _vboot2_work_size + (uintptr_t)wd
+ - (uintptr_t)wd->buffer;
+
+ return wd;
+}
+
+/**
+ * Verify a slot and jump to the next stage
+ *
+ * This could be either part of the (1) bootblock or the (2) verstage, depending
+ * on CONFIG_RETURN_FROM_VERSTAGE.
+ *
+ * 1) It jumps to the verstage and comes back, then, loads the romstage over the
+ * verstage space and exits to it. (note the cbfs cache is trashed on return
+ * from the verstage.)
+ *
+ * 2) We're already in the verstage. Verify firmware, then load the romstage and
+ * exits to it.
+ */
+void vboot2_verify_firmware(void)
+{
+ void *entry;
+ struct vb2_working_data *wd;
+
+ wd = init_vb2_working_data();
+
+#if CONFIG_RETURN_FROM_VERSTAGE
+ /* load verstage from RO */
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
+ CONFIG_CBFS_PREFIX "/verstage");
+ if (entry == (void *)-1)
+ die("failed to load verstage");
+
+ /* verify and select a slot */
+ stage_exit(entry);
+#else
+ verstage_main();
+#endif /* CONFIG_RETURN_FROM_VERSTAGE */
+
+ /* jump to the selected slot */
+ entry = NULL;
+ if (vboot_is_slot_selected(wd)) {
+ /* RW A or B */
+ struct vboot_region fw_main;
+ struct vboot_components *fw_info;
+ vb2_get_selected_region(wd, &fw_main);
+ fw_info = vboot_locate_components(&fw_main);
+ if (fw_info == NULL)
+ die("failed to locate firmware components\n");
+ entry = vboot_load_stage(CONFIG_VBOOT_ROMSTAGE_INDEX,
+ &fw_main, fw_info);
+ } else if (vboot_is_readonly_path(wd)) {
+ /* RO */
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
+ CONFIG_CBFS_PREFIX "/romstage");
+ }
+
+ if (entry != NULL && entry != (void *)-1)
+ stage_exit(entry);
+
+ die("failed to exit from stage\n");
+}
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
new file mode 100644
index 0000000..b2893d9
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot_common.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <boot/coreboot_tables.h>
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include "chromeos.h"
+#include "vboot_common.h"
+
+void vboot_locate_region(const char *name, struct vboot_region *region)
+{
+ region->size = find_fmap_entry(name, (void **)®ion->offset_addr);
+}
+
+void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest)
+{
+ if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
+ if (dest != NULL)
+ return memcpy(dest, (void *)offset_addr, size);
+ else
+ return (void *)offset_addr;
+ } else {
+ struct cbfs_media default_media, *media = &default_media;
+ void *cache;
+
+ init_default_cbfs_media(media);
+ media->open(media);
+ if (dest != NULL) {
+ cache = dest;
+ if (media->read(media, dest, offset_addr, size) != size)
+ cache = NULL;
+ } else {
+ cache = media->map(media, offset_addr, size);
+ if (cache == CBFS_MEDIA_INVALID_MAP_ADDRESS)
+ cache = NULL;
+ }
+ media->close(media);
+ return cache;
+ }
+}
+
+int vboot_get_handoff_info(void **addr, uint32_t *size)
+{
+ struct vboot_handoff *vboot_handoff;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return -1;
+
+ *addr = vboot_handoff;
+ *size = sizeof(*vboot_handoff);
+ return 0;
+}
+
+/* This will leak a mapping of a fw region */
+struct vboot_components *vboot_locate_components(struct vboot_region *region)
+{
+ size_t req_size;
+ struct vboot_components *vbc;
+
+ req_size = sizeof(*vbc);
+ req_size += sizeof(struct vboot_component_entry) *
+ MAX_PARSED_FW_COMPONENTS;
+
+ vbc = vboot_get_region(region->offset_addr, req_size, NULL);
+ if (vbc && vbc->num_components > MAX_PARSED_FW_COMPONENTS)
+ vbc = NULL;
+
+ return vbc;
+}
+
+void *vboot_get_payload(int *len)
+{
+ struct vboot_handoff *vboot_handoff;
+ struct firmware_component *fwc;
+
+ vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vboot_handoff == NULL)
+ return NULL;
+
+ if (CONFIG_VBOOT_BOOT_LOADER_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid boot loader index: %d\n",
+ CONFIG_VBOOT_BOOT_LOADER_INDEX);
+ return NULL;
+ }
+
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_BOOT_LOADER_INDEX];
+
+ /* If payload size is zero fall back to cbfs path. */
+ if (fwc->size == 0)
+ return NULL;
+
+ if (len != NULL)
+ *len = fwc->size;
+
+ printk(BIOS_DEBUG, "Booting 0x%x byte verified payload at 0x%08x.\n",
+ fwc->size, fwc->address);
+
+ /* This will leak a mapping. */
+ return vboot_get_region(fwc->address, fwc->size, NULL);
+}
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
new file mode 100644
index 0000000..c6c9b50
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef VBOOT_COMMON_H
+#define VBOOT_COMMON_H
+
+#include <stdint.h>
+
+struct vboot_region {
+ uintptr_t offset_addr;
+ int32_t size;
+};
+
+/* The FW areas consist of multiple components. At the beginning of
+ * each area is the number of total compoments as well as the size and
+ * offset for each component. One needs to caculate the total size of the
+ * signed firmware region based off of the embedded metadata. */
+struct vboot_component_entry {
+ uint32_t offset;
+ uint32_t size;
+} __attribute__((packed));
+
+struct vboot_components {
+ uint32_t num_components;
+ struct vboot_component_entry entries[0];
+} __attribute__((packed));
+
+void vboot_locate_region(const char *name, struct vboot_region *region);
+
+struct vboot_components *vboot_locate_components(struct vboot_region *region);
+
+/*
+ * This is a dual purpose routine. If dest is non-NULL the region at
+ * offset_addr will be read into the area pointed to by dest. If dest
+ * is NULL,the region will be mapped to a memory location. NULL is
+ * returned on error else the location of the requested region.
+ */
+void *vboot_get_region(uintptr_t offset_addr, size_t size, void *dest);
+
+#endif /* VBOOT_COMMON_H */
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot_handoff.c
deleted file mode 100644
index f929a59..0000000
--- a/src/vendorcode/google/chromeos/vboot_handoff.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Google, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <2recovery_reasons.h>
-#include <2struct.h>
-#include <arch/stages.h>
-#include <assert.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <stdlib.h>
-#include <timestamp.h>
-#include "chromeos.h"
-#include "fmap.h"
-#include "vboot_handoff.h"
-#include <vboot_struct.h>
-
-static void *load_ramstage(struct vboot_handoff *vboot_handoff,
- struct vboot_region *fw_main)
-{
- struct vboot_components *fw_info;
- int i;
-
- fw_info = vboot_locate_components(fw_main);
- if (fw_info == NULL)
- die("failed to locate firmware components\n");
-
- /* these offset & size are used to load a rw boot loader */
- for (i = 0; i < fw_info->num_components; i++) {
- vboot_handoff->components[i].address =
- fw_main->offset_addr + fw_info->entries[i].offset;
- vboot_handoff->components[i].size = fw_info->entries[i].size;
- }
-
- return vboot_load_stage(CONFIG_VBOOT_RAMSTAGE_INDEX, fw_main, fw_info);
-}
-
-/**
- * Sets vboot_handoff based on the information in vb2_shared_data
- *
- * TODO: Read wp switch to set VBSD_BOOT_FIRMWARE_WP_ENABLED
- */
-static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
- struct vb2_shared_data *vb2_sd)
-{
- VbSharedDataHeader *vb_sd =
- (VbSharedDataHeader *)vboot_handoff->shared_data;
- uint32_t *oflags = &vboot_handoff->init_params.out_flags;
-
- vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
-
- vboot_handoff->selected_firmware = vb2_sd->fw_slot;
-
- vb_sd->firmware_index = vb2_sd->fw_slot;
-
- vb_sd->magic = VB_SHARED_DATA_MAGIC;
- vb_sd->struct_version = VB_SHARED_DATA_VERSION;
- vb_sd->struct_size = sizeof(VbSharedDataHeader);
- vb_sd->data_size = VB_SHARED_DATA_MIN_SIZE;
- vb_sd->data_used = sizeof(VbSharedDataHeader);
-
- if (vb2_sd->recovery_reason) {
- vb_sd->firmware_index = 0xFF;
- if (vb2_sd->recovery_reason == VB2_RECOVERY_RO_MANUAL)
- vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
- *oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
- *oflags |= VB_INIT_OUT_CLEAR_RAM;
- *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
- *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
- }
- if (vb2_sd->flags & VB2_SD_DEV_MODE_ENABLED) {
- *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER;
- *oflags |= VB_INIT_OUT_CLEAR_RAM;
- *oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
- *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE;
- vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
- vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
- }
- /* TODO: Set these in depthcharge */
- if (CONFIG_VIRTUAL_DEV_SWITCH)
- vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
- if (CONFIG_EC_SOFTWARE_SYNC) {
- vb_sd->flags |= VBSD_EC_SOFTWARE_SYNC;
- vb_sd->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL;
- }
- /* In vboot1, VBSD_FWB_TRIED is
- * set only if B is booted as explicitly requested. Therefore, if B is
- * booted because A was found bad, the flag should not be set. It's
- * better not to touch it if we can only ambiguously control it. */
- /* if (vb2_sd->fw_slot)
- vb_sd->flags |= VBSD_FWB_TRIED; */
-
- /* copy kernel subkey if it's found */
- if (vb2_sd->workbuf_preamble_size) {
- struct vb2_fw_preamble *fp;
- uintptr_t dst, src;
- printk(BIOS_INFO, "Copying FW preamble\n");
- fp = (struct vb2_fw_preamble *)( (uintptr_t)vb2_sd +
- vb2_sd->workbuf_preamble_offset);
- src = (uintptr_t)&fp->kernel_subkey +
- fp->kernel_subkey.key_offset;
- dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
- assert(dst + fp->kernel_subkey.key_size <=
- (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
- memcpy((void *)dst, (void *)src,
- fp->kernel_subkey.key_size);
- vb_sd->data_used += fp->kernel_subkey.key_size;
- vb_sd->kernel_subkey.key_offset =
- dst - (uintptr_t)&vb_sd->kernel_subkey;
- vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
- vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
- vb_sd->kernel_subkey.key_version =
- fp->kernel_subkey.key_version;
- }
-
- vb_sd->recovery_reason = vb2_sd->recovery_reason;
-}
-
-/**
- * Load ramstage and return the entry point
- */
-void *vboot_load_ramstage(void)
-{
- struct vboot_handoff *vh;
- struct vb2_shared_data *sd;
- struct vboot_region fw_main;
- struct vb2_working_data *wd = vboot_get_working_data();
-
- sd = (struct vb2_shared_data *)(uintptr_t)wd->buffer;
- sd->workbuf_hash_offset = 0;
- sd->workbuf_hash_size = 0;
-
- printk(BIOS_INFO, "creating vboot_handoff structure\n");
- vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
- if (vh == NULL)
- /* we don't need to failover gracefully here because this
- * shouldn't happen with the image that has passed QA. */
- die("failed to allocate vboot_handoff structure\n");
-
- memset(vh, 0, sizeof(*vh));
-
- /* needed until we finish transtion to vboot2 for kernel verification */
- fill_vboot_handoff(vh, sd);
-
- if (vboot_is_readonly_path(wd))
- /* we're on recovery path. continue to ro-ramstage. */
- return NULL;
-
- printk(BIOS_INFO,
- "loading ramstage from Slot %c\n", sd->fw_slot ? 'B' : 'A');
- vb2_get_selected_region(wd, &fw_main);
-
- return load_ramstage(vh, &fw_main);
-}
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.h b/src/vendorcode/google/chromeos/vboot_handoff.h
index b001743..e6b2d69 100644
--- a/src/vendorcode/google/chromeos/vboot_handoff.h
+++ b/src/vendorcode/google/chromeos/vboot_handoff.h
@@ -19,9 +19,20 @@
#ifndef VBOOT_HANDOFF_H
#define VBOOT_HANDOFF_H
+
#include <vboot_api.h>
#include <vboot_struct.h>
#include "chromeos.h"
+#include "vboot_common.h"
+
+/*
+ * The vboot handoff structure keeps track of a maximum number of firmware
+ * components in the verfieid RW area of flash. This is not a restriction on
+ * the number of components packed in a firmware block. It's only the maximum
+ * number of parsed firmware components (address and size) included in the
+ * handoff structure.
+ */
+#define MAX_PARSED_FW_COMPONENTS 5
struct firmware_component {
uint32_t address;
diff --git a/src/vendorcode/google/chromeos/vboot_loader.c b/src/vendorcode/google/chromeos/vboot_loader.c
deleted file mode 100644
index d13608c..0000000
--- a/src/vendorcode/google/chromeos/vboot_loader.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Google, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/stages.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <program_loading.h>
-#include <tpm.h>
-#include <reset.h>
-#include <romstage_handoff.h>
-#include <rmodule.h>
-#include <string.h>
-#include <stdlib.h>
-#include <timestamp.h>
-#include "chromeos.h"
-#include "vboot_context.h"
-#include "vboot_handoff.h"
-
-#define TEMP_CBMEM_ID_VBOOT 0xffffffff
-#define TEMP_CBMEM_ID_VBLOCKS 0xfffffffe
-
-static void vboot_run_stub(struct vboot_context *context)
-{
- struct rmod_stage_load rmod_stage = {
- .cbmem_id = TEMP_CBMEM_ID_VBOOT,
- .name = CONFIG_CBFS_PREFIX "/vboot",
- };
- void (*entry)(struct vboot_context *context);
-
- if (rmodule_stage_load_from_cbfs(&rmod_stage)) {
- printk(BIOS_DEBUG, "Could not load vboot stub.\n");
- goto out;
- }
-
- entry = rmod_stage.entry;
-
- /* Call stub. */
- entry(context);
-
-out:
- /* Tear down the region no longer needed. */
- if (rmod_stage.cbmem_entry != NULL)
- cbmem_entry_remove(rmod_stage.cbmem_entry);
-}
-
-/* Helper routines for the vboot stub. */
-static void log_msg(const char *fmt, va_list args)
-{
- do_vtxprintf(fmt, args);
-}
-
-static void fatal_error(void)
-{
- printk(BIOS_ERR, "vboot encountered fatal error. Resetting.\n");
- hard_reset();
-}
-
-static int fw_region_size(struct vboot_region *r)
-{
- struct vboot_components *fw_info;
- int32_t size;
- int i;
-
- fw_info = vboot_locate_components(r);
- if (fw_info == NULL)
- return -1;
-
- if (fw_info->num_components > MAX_PARSED_FW_COMPONENTS)
- return -1;
-
- size = sizeof(*fw_info);
- size += sizeof(struct vboot_component_entry) * fw_info->num_components;
-
- for (i = 0; i < fw_info->num_components; i++)
- size += ALIGN(fw_info->entries[i].size, sizeof(uint32_t));
-
- /* Check that size of comopnents does not exceed the region's size. */
- if (size > r->size)
- return -1;
-
- /* Update region with the correct size. */
- r->size = size;
-
- return 0;
-}
-
-static int vboot_fill_params(struct vboot_context *ctx)
-{
- VbCommonParams *cparams;
- VbSelectFirmwareParams *fparams;
-
- if (fw_region_size(&ctx->fw_a))
- return -1;
-
- if (fw_region_size(&ctx->fw_b))
- return -1;
-
- cparams = ctx->cparams;
- fparams = ctx->fparams;
-
- cparams->gbb_size = ctx->gbb.size;
- fparams->verification_size_A = ctx->vblock_a.size;
- fparams->verification_size_B = ctx->vblock_b.size;
-
- if (IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- /* Get memory-mapped pointers to the regions. */
- cparams->gbb_data = vboot_get_region(ctx->gbb.offset_addr,
- ctx->gbb.size, NULL);
- fparams->verification_block_A =
- vboot_get_region(ctx->vblock_a.offset_addr,
- ctx->vblock_a.size, NULL);
- fparams->verification_block_B =
- vboot_get_region(ctx->vblock_b.offset_addr,
- ctx->vblock_b.size, NULL);
- } else {
- /*
- * Copy the vblock info into a buffer in cbmem. The gbb will
- * be read using VbExRegionRead().
- */
- char *dest;
- size_t vblck_sz;
-
- vblck_sz = ctx->vblock_a.size + ctx->vblock_b.size;
- ctx->vblocks = cbmem_entry_add(TEMP_CBMEM_ID_VBLOCKS, vblck_sz);
- if (ctx->vblocks == NULL)
- return -1;
- dest = cbmem_entry_start(ctx->vblocks);
- if (vboot_get_region(ctx->vblock_a.offset_addr,
- ctx->vblock_a.size, dest) == NULL)
- return -1;
- fparams->verification_block_A = (void *)dest;
- dest += ctx->vblock_a.size;
- if (vboot_get_region(ctx->vblock_b.offset_addr,
- ctx->vblock_b.size, dest) == NULL)
- return -1;
- fparams->verification_block_B = (void *)dest;
- }
-
- return 0;
-}
-
-static void fill_handoff(struct vboot_context *context)
-{
- struct vboot_components *fw_info;
- struct vboot_region *region;
- int i;
-
- /* Fix up the handoff structure. */
- context->handoff->selected_firmware =
- context->fparams->selected_firmware;
-
- /* Parse out the components for downstream consumption. */
- if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_A)
- region = &context->fw_a;
- else if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_B)
- region = &context->fw_b;
- else
- return;
-
- fw_info = vboot_locate_components(region);
- if (fw_info == NULL)
- return;
-
- for (i = 0; i < fw_info->num_components; i++) {
- context->handoff->components[i].address =
- region->offset_addr + fw_info->entries[i].offset;
- context->handoff->components[i].size = fw_info->entries[i].size;
- }
-}
-
-static void vboot_clean_up(struct vboot_context *context)
-{
- if (context->vblocks != NULL)
- cbmem_entry_remove(context->vblocks);
-}
-
-static void reset(void)
-{
- hard_reset();
-}
-
-static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
-{
- VbCommonParams cparams;
- VbSelectFirmwareParams fparams;
- struct vboot_context context;
- uint32_t *iflags;
-
- vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
-
- memset(&cparams, 0, sizeof(cparams));
- memset(&fparams, 0, sizeof(fparams));
- memset(&context, 0, sizeof(context));
-
- iflags = &vboot_handoff->init_params.flags;
- if (get_developer_mode_switch())
- *iflags |= VB_INIT_FLAG_DEV_SWITCH_ON;
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- *iflags |= VB_INIT_FLAG_REC_BUTTON_PRESSED;
- }
- if (get_write_protect_state())
- *iflags |= VB_INIT_FLAG_WP_ENABLED;
- if (vboot_get_sw_write_protect())
- *iflags |= VB_INIT_FLAG_SW_WP_ENABLED;
- if (CONFIG_VIRTUAL_DEV_SWITCH)
- *iflags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
- if (CONFIG_EC_SOFTWARE_SYNC) {
- *iflags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC;
- *iflags |= VB_INIT_FLAG_VIRTUAL_REC_SWITCH;
- }
- if (CONFIG_VBOOT_EC_SLOW_UPDATE)
- *iflags |= VB_INIT_FLAG_EC_SLOW_UPDATE;
- if (CONFIG_VBOOT_OPROM_MATTERS) {
- *iflags |= VB_INIT_FLAG_OPROM_MATTERS;
- /* Will load VGA option rom during this boot */
- if (developer_mode_enabled() || recovery_mode_enabled() ||
- vboot_wants_oprom()) {
- *iflags |= VB_INIT_FLAG_OPROM_LOADED;
- }
- }
-
- context.handoff = vboot_handoff;
- context.cparams = &cparams;
- context.fparams = &fparams;
-
- cparams.shared_data_blob = &vboot_handoff->shared_data[0];
- cparams.shared_data_size = VB_SHARED_DATA_MIN_SIZE;
- cparams.caller_context = &context;
-
- vboot_locate_region("GBB", &context.gbb);
- vboot_locate_region("VBLOCK_A", &context.vblock_a);
- vboot_locate_region("VBLOCK_B", &context.vblock_b);
- vboot_locate_region("FW_MAIN_A", &context.fw_a);
- vboot_locate_region("FW_MAIN_B", &context.fw_b);
-
- /* Check all fmap entries. */
- if (context.fw_a.size < 0 || context.fw_b.size < 0 ||
- context.vblock_a.size < 0 || context.vblock_b.size < 0 ||
- context.gbb.size < 0) {
- printk(BIOS_DEBUG, "Not all fmap entries found for vboot.\n");
- return;
- }
-
- /* Fill in vboot parameters. */
- if (vboot_fill_params(&context)) {
- vboot_clean_up(&context);
- return;
- }
-
- /* Initialize callbacks. */
- context.read_vbnv = &read_vbnv;
- context.save_vbnv = &save_vbnv;
- context.tis_init = &tis_init;
- context.tis_open = &tis_open;
- context.tis_close = &tis_close;
- context.tis_sendrecv = &tis_sendrecv;
- context.log_msg = &log_msg;
- context.fatal_error = &fatal_error;
- context.get_region = &vboot_get_region;
- context.reset = &reset;
-
- vboot_run_stub(&context);
-
- fill_handoff(&context);
-
- vboot_clean_up(&context);
-}
-
-#if CONFIG_RELOCATABLE_RAMSTAGE
-static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
- const struct cbmem_entry **cbmem_entry)
-{
- struct vboot_handoff *vboot_handoff;
- struct cbfs_stage *stage;
- const struct firmware_component *fwc;
- struct rmod_stage_load rmod_load = {
- .cbmem_id = cbmem_id,
- .name = name,
- };
-
- timestamp_add_now(TS_START_VBOOT);
-
- vboot_handoff = cbmem_add(CBMEM_ID_VBOOT_HANDOFF,
- sizeof(*vboot_handoff));
-
- if (vboot_handoff == NULL) {
- printk(BIOS_DEBUG, "Could not add vboot_handoff structure.\n");
- return NULL;
- }
-
- memset(vboot_handoff, 0, sizeof(*vboot_handoff));
-
- vboot_invoke_wrapper(vboot_handoff);
-
- timestamp_add_now(TS_END_VBOOT);
-
- /* Take RO firmware path since no RW area was selected. */
- if (vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_A &&
- vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_B) {
- printk(BIOS_DEBUG, "No RW firmware selected: 0x%08x\n",
- vboot_handoff->selected_firmware);
- return NULL;
- }
-
- if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid ramstage index: %d\n",
- CONFIG_VBOOT_RAMSTAGE_INDEX);
- return NULL;
- }
-
- /* Check for invalid address. */
- fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
- if (fwc->address == 0) {
- printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
- return NULL;
- }
-
- printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
- fwc->address, fwc->size);
-
- stage = (void *)fwc->address;
-
- if (rmodule_stage_load(&rmod_load, stage)) {
- vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
- printk(BIOS_DEBUG, "Could not load ramstage region.\n");
- return NULL;
- }
-
- *cbmem_entry = rmod_load.cbmem_entry;
-
- return rmod_load.entry;
-}
-#else /* CONFIG_RELOCATABLE_RAMSTAGE */
-static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
- struct romstage_handoff *handoff)
-{
- struct cbfs_stage *stage;
- const struct firmware_component *fwc;
-
- if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
- printk(BIOS_ERR, "Invalid ramstage index: %d\n",
- CONFIG_VBOOT_RAMSTAGE_INDEX);
- return;
- }
-
- /* Check for invalid address. */
- fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
- if (fwc->address == 0) {
- printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
- return;
- }
-
- printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
- fwc->address, fwc->size);
-
- /* This will leak a mapping. */
- stage = vboot_get_region(fwc->address, fwc->size, NULL);
-
- if (stage == NULL) {
- printk(BIOS_DEBUG, "Unable to get RW ramstage region.\n");
- return;
- }
-
- timestamp_add_now(TS_START_COPYRAM);
-
- /* Stages rely the below clearing so that the bss is initialized. */
- memset((void *) (uintptr_t) stage->load, 0, stage->memlen);
-
- if (cbfs_decompress(stage->compression,
- ((unsigned char *) stage) +
- sizeof(struct cbfs_stage),
- (void *) (uintptr_t) stage->load,
- stage->len))
- return;
-
- timestamp_add_now(TS_END_COPYRAM);
-
-#if CONFIG_ARCH_X86
- __asm__ volatile (
- "movl $0, %%ebp\n"
- "jmp *%%edi\n"
- :: "D"(stage->entry)
- );
-#elif CONFIG_ARCH_ARM
- stage_exit((void *)(uintptr_t)stage->entry);
-#endif
-}
-#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
-
-
-const struct ramstage_loader_ops vboot_ramstage_loader = {
- .name = "VBOOT",
- .load = vboot_load_ramstage,
-};
diff --git a/src/vendorcode/google/chromeos/vboot_wrapper.c b/src/vendorcode/google/chromeos/vboot_wrapper.c
deleted file mode 100644
index dd6065c..0000000
--- a/src/vendorcode/google/chromeos/vboot_wrapper.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Google, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <console/vtxprintf.h>
-#if CONFIG_ARCH_X86
-#include <cpu/x86/tsc.h>
-#else
-#include <timer.h>
-#endif
-#include <rmodule.h>
-#include <stdlib.h>
-#include <string.h>
-#include "vboot_context.h"
-#include "vboot_handoff.h"
-
-/* Keep a global context pointer around for the callbacks to use. */
-static struct vboot_context *gcontext;
-
-static void vboot_wrapper(void *arg)
-{
- VbError_t res;
- struct vboot_context *context;
-
- context = arg;
- gcontext = context;
-
- VbExDebug("Calling VbInit()\n");
- res = VbInit(context->cparams, &context->handoff->init_params);
- VbExDebug("VbInit() returned 0x%08x\n", res);
-
- if (res != VBERROR_SUCCESS) {
- if(res == VBERROR_TPM_REBOOT_REQUIRED) {
- VbExDebug("TPM Reboot Required. Proceeding reboot.\n");
- gcontext->reset();
- }
- return;
- }
-
- VbExDebug("Calling VbSelectFirmware()\n");
- res = VbSelectFirmware(context->cparams, context->fparams);
- VbExDebug("VbSelectFirmware() returned 0x%08x\n", res);
-
- if (res != VBERROR_SUCCESS)
- return;
-}
-
-void VbExError(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- gcontext->log_msg(format, args);
- va_end(args);
-
- gcontext->fatal_error();
-}
-
-void VbExDebug(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- gcontext->log_msg(format, args);
- va_end(args);
-}
-
-uint64_t VbExGetTimer(void)
-{
-#if CONFIG_ARCH_X86
- return rdtscll();
-#else
- struct mono_time mt;
- timer_monotonic_get(&mt);
- return mt.microseconds;
-#endif
-}
-
-VbError_t VbExNvStorageRead(uint8_t *buf)
-{
- gcontext->read_vbnv(buf);
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExNvStorageWrite(const uint8_t *buf)
-{
- gcontext->save_vbnv(buf);
- return VBERROR_SUCCESS;
-}
-
-extern char _heap[];
-extern char _eheap[];
-static char *heap_current;
-static int heap_size;
-
-void *VbExMalloc(size_t size)
-{
- void *ptr;
-
- if (heap_current == NULL) {
- heap_current = &_heap[0];
- heap_size = &_eheap[0] - &_heap[0];
- VbExDebug("vboot heap: %p 0x%08x bytes\n",
- heap_current, heap_size);
- }
-
- if (heap_size < size) {
- VbExError("vboot heap request cannot be fulfilled. "
- "0x%08x available, 0x%08x requested\n",
- heap_size, size);
- }
-
- ptr = heap_current;
- heap_size -= size;
- heap_current += size;
-
- return ptr;
-}
-
-void VbExFree(void *ptr)
-{
- /* Leak all memory. */
-}
-
-/* vboot doesn't expose these through the vboot_api.h, but they are needed.
- * coreboot requires declarations so provide them to avoid compiler errors. */
-int Memcmp(const void *src1, const void *src2, size_t n);
-void *Memcpy(void *dest, const void *src, uint64_t n);
-void *Memset(void *dest, const uint8_t c, uint64_t n);
-
-int Memcmp(const void *src1, const void *src2, size_t n)
-{
- return memcmp(src1, src2, n);
-}
-
-void *Memcpy(void *dest, const void *src, uint64_t n)
-{
- return memcpy(dest, src, n);
-}
-
-void *Memset(void *dest, const uint8_t c, uint64_t n)
-{
- return memset(dest, c, n);
-}
-
-static inline size_t get_hash_block_size(size_t requested_size)
-{
- if (!IS_ENABLED(CONFIG_SPI_FLASH_MEMORY_MAPPED)) {
- const size_t block_size = 64 * 1024;
- if (requested_size > block_size)
- return block_size;
- }
- return requested_size;
-}
-
-VbError_t VbExHashFirmwareBody(VbCommonParams *cparams, uint32_t firmware_index)
-{
- uint8_t *data;
- struct vboot_region *region;
- struct vboot_context *ctx;
- size_t data_size;
- uintptr_t offset_addr;
-
- ctx = cparams->caller_context;
-
- switch (firmware_index) {
- case VB_SELECT_FIRMWARE_A:
- region = &ctx->fw_a;
- break;
- case VB_SELECT_FIRMWARE_B:
- region = &ctx->fw_b;
- break;
- default:
- return VBERROR_UNKNOWN;
- }
-
- data_size = region->size;
- offset_addr = region->offset_addr;
- while (data_size) {
- size_t block_size;
-
- block_size = get_hash_block_size(data_size);
- data = ctx->get_region(offset_addr, block_size, NULL);
- if (data == NULL)
- return VBERROR_UNKNOWN;
- VbUpdateFirmwareBodyHash(cparams, data, block_size);
-
- data_size -= block_size;
- offset_addr += block_size;
- }
-
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExTpmInit(void)
-{
- if (gcontext->tis_init())
- return VBERROR_UNKNOWN;
- return VbExTpmOpen();
-}
-
-VbError_t VbExTpmClose(void)
-{
- if (gcontext->tis_close())
- return VBERROR_UNKNOWN;
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExTpmOpen(void)
-{
- if (gcontext->tis_open())
- return VBERROR_UNKNOWN;
- return VBERROR_SUCCESS;
-}
-
-VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length,
- uint8_t *response, uint32_t *response_length)
-{
- size_t len = *response_length;
- if (gcontext->tis_sendrecv(request, request_length, response, &len))
- return VBERROR_UNKNOWN;
- /* check 64->32bit overflow and (re)check response buffer overflow */
- if (len > *response_length)
- return VBERROR_UNKNOWN;
- *response_length = len;
- return VBERROR_SUCCESS;
-}
-
-#if !CONFIG_SPI_FLASH_MEMORY_MAPPED
-VbError_t VbExRegionRead(VbCommonParams *cparams,
- enum vb_firmware_region region, uint32_t offset,
- uint32_t size, void *buf)
-{
- struct vboot_context *ctx;
- VbExDebug("VbExRegionRead: offset=%x size=%x, buf=%p\n",
- offset, size, buf);
- ctx = cparams->caller_context;
-
- if (region == VB_REGION_GBB) {
- if (offset + size > cparams->gbb_size)
- return VBERROR_REGION_READ_INVALID;
- offset += ctx->gbb.offset_addr;
- if (ctx->get_region(offset, size, buf) == NULL)
- return VBERROR_REGION_READ_INVALID;
- return VBERROR_SUCCESS;
- }
-
- return VBERROR_UNSUPPORTED_REGION;
-}
-#endif /* CONFIG_SPI_FLASH_MEMORY_MAPPED */
-
-RMODULE_ENTRY(vboot_wrapper);
diff --git a/src/vendorcode/google/chromeos/verstage.c b/src/vendorcode/google/chromeos/verstage.c
deleted file mode 100644
index 1b42bb6..0000000
--- a/src/vendorcode/google/chromeos/verstage.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <2api.h>
-#include <2struct.h>
-#include <antirollback.h>
-#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <string.h>
-
-#include "chromeos.h"
-
-#define TODO_BLOCK_SIZE 1024
-
-static int is_slot_a(struct vb2_context *ctx)
-{
- return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
-}
-
-/* exports */
-
-void vb2ex_printf(const char *func, const char *fmt, ...)
-{
- va_list args;
-
- printk(BIOS_INFO, "VB2:%s() ", func);
- va_start(args, fmt);
- vprintk(BIOS_INFO, fmt, args);
- va_end(args);
-
- return;
-}
-
-int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
-{
- uint32_t rv;
- printk(BIOS_INFO, "Clearing TPM owner\n");
- rv = tpm_clear_and_reenable();
- if (rv)
- return VB2_ERROR_EX_TPM_CLEAR_OWNER;
- return VB2_SUCCESS;
-}
-
-int vb2ex_read_resource(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- void *buf,
- uint32_t size)
-{
- struct vboot_region region;
-
- switch (index) {
- case VB2_RES_GBB:
- vboot_locate_region("GBB", ®ion);
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- vboot_locate_region("VBLOCK_A", ®ion);
- else
- vboot_locate_region("VBLOCK_B", ®ion);
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (offset + size > region.size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (vboot_get_region(region.offset_addr + offset, size, buf) == NULL)
- return VB2_ERROR_UNKNOWN;
-
- return VB2_SUCCESS;
-}
-
-static int hash_body(struct vb2_context *ctx, struct vboot_region *fw_main)
-{
- uint32_t expected_size;
- MAYBE_STATIC uint8_t block[TODO_BLOCK_SIZE];
- size_t block_size = sizeof(block);
- uintptr_t offset;
- int rv;
-
- expected_size = fw_main->size;
- offset = fw_main->offset_addr;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /* Extend over the body */
- while (expected_size) {
- void *b;
- if (block_size > expected_size)
- block_size = expected_size;
-
- b = vboot_get_region(offset, block_size, block);
- if (b == NULL)
- return VB2_ERROR_UNKNOWN;
- rv = vb2api_extend_hash(ctx, b, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- /* Check the result */
- rv = vb2api_check_hash(ctx);
- if (rv)
- return rv;
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct vboot_region *fw_main)
-{
- if (is_slot_a(ctx))
- vboot_locate_region("FW_MAIN_A", fw_main);
- else
- vboot_locate_region("FW_MAIN_B", fw_main);
-
- if (fw_main->size < 0)
- return 1;
-
- return 0;
-}
-
-/**
- * Save non-volatile and/or secure data if needed.
- */
-static void save_if_needed(struct vb2_context *ctx)
-{
- if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
- printk(BIOS_INFO, "Saving nvdata\n");
- save_vbnv(ctx->nvdata);
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- }
- if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
- printk(BIOS_INFO, "Saving secdata\n");
- antirollback_write_space_firmware(ctx);
- ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
- }
-}
-
-/**
- * Verify and select the firmware in the RW image
- *
- * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
- * when per-stage verification is ready.
- */
-#if CONFIG_RETURN_FROM_VERSTAGE
-void main(void)
-#else
-void verstage_main(void)
-#endif /* CONFIG_RETURN_FROM_VERSTAGE */
-{
- struct vb2_context ctx;
- struct vboot_region fw_main;
- struct vb2_working_data *wd = vboot_get_working_data();
- int rv;
-
- /* Set up context and work buffer */
- memset(&ctx, 0, sizeof(ctx));
- ctx.workbuf = (uint8_t *)(uintptr_t)wd->buffer;
- ctx.workbuf_size = wd->buffer_size;
-
- /* Read nvdata from a non-volatile storage */
- read_vbnv(ctx.nvdata);
-
- /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
- * check the return value here because vb2api_fw_phase1 will catch
- * invalid secdata and tell us what to do (=reboot). */
- antirollback_read_space_firmware(&ctx);
-
- if (get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- }
-
- /* Do early init */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- /* If we need recovery mode, leave firmware selection now */
- save_if_needed(&ctx);
- return;
- }
-
- /* Determine which firmware slot to boot */
- printk(BIOS_INFO, "Phase 2\n");
- rv = vb2api_fw_phase2(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Try that slot */
- printk(BIOS_INFO, "Phase 3\n");
- rv = vb2api_fw_phase3(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Phase 4\n");
- rv = locate_firmware(&ctx, &fw_main);
- if (rv)
- die("Failed to read FMAP to locate firmware");
-
- rv = hash_body(&ctx, &fw_main);
- save_if_needed(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- vboot_reboot();
- }
-
- /* Lock TPM */
- rv = antirollback_lock_space_firmware();
- if (rv) {
- printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
- vb2_set_selected_region(wd, &fw_main);
-}
diff --git a/src/vendorcode/google/chromeos/verstage.ld b/src/vendorcode/google/chromeos/verstage.ld
deleted file mode 100644
index c7fd646..0000000
--- a/src/vendorcode/google/chromeos/verstage.ld
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* This file is included inside a SECTIONS block */
-
-.text . : {
- _program = .;
- _verstage = .;
- *(.text._start);
- *(.text.stage_entry);
- *(.text);
- *(.text.*);
-} : to_load
-
-.data . : {
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- . = ALIGN(8);
-}
-
-.bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- _everstage = .;
- _eprogram = .;
-}
-
-/* Discard the sections we don't need/want */
-/DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
-}
diff --git a/src/vendorcode/google/chromeos/verstub.c b/src/vendorcode/google/chromeos/verstub.c
deleted file mode 100644
index eb91c22..0000000
--- a/src/vendorcode/google/chromeos/verstub.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/stages.h>
-#include <cbfs.h>
-#include <console/console.h>
-#include <string.h>
-#include "chromeos.h"
-#include "symbols.h"
-
-static struct vb2_working_data *init_vb2_working_data(void)
-{
- struct vb2_working_data *wd;
-
- wd = vboot_get_working_data();
- memset(wd, 0, _vboot2_work_size);
- /* 8-byte alignment for ARMv7 */
- wd->buffer = ALIGN_UP((uintptr_t)&wd[1], 8);
- wd->buffer_size = _vboot2_work_size + (uintptr_t)wd
- - (uintptr_t)wd->buffer;
-
- return wd;
-}
-
-/**
- * Verify a slot and jump to the next stage
- *
- * This could be either part of the (1) bootblock or the (2) verstage, depending
- * on CONFIG_RETURN_FROM_VERSTAGE.
- *
- * 1) It jumps to the verstage and comes back, then, loads the romstage over the
- * verstage space and exits to it. (note the cbfs cache is trashed on return
- * from the verstage.)
- *
- * 2) We're already in the verstage. Verify firmware, then load the romstage and
- * exits to it.
- */
-void vboot2_verify_firmware(void)
-{
- void *entry;
- struct vb2_working_data *wd;
-
- wd = init_vb2_working_data();
-
-#if CONFIG_RETURN_FROM_VERSTAGE
- /* load verstage from RO */
- entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
- CONFIG_CBFS_PREFIX "/verstage");
- if (entry == (void *)-1)
- die("failed to load verstage");
-
- /* verify and select a slot */
- stage_exit(entry);
-#else
- verstage_main();
-#endif /* CONFIG_RETURN_FROM_VERSTAGE */
-
- /* jump to the selected slot */
- entry = NULL;
- if (vboot_is_slot_selected(wd)) {
- /* RW A or B */
- struct vboot_region fw_main;
- struct vboot_components *fw_info;
- vb2_get_selected_region(wd, &fw_main);
- fw_info = vboot_locate_components(&fw_main);
- if (fw_info == NULL)
- die("failed to locate firmware components\n");
- entry = vboot_load_stage(CONFIG_VBOOT_ROMSTAGE_INDEX,
- &fw_main, fw_info);
- } else if (vboot_is_readonly_path(wd)) {
- /* RO */
- entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA,
- CONFIG_CBFS_PREFIX "/romstage");
- }
-
- if (entry != NULL && entry != (void *)-1)
- stage_exit(entry);
-
- die("failed to exit from stage\n");
-}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9435
-gerrit
commit 708809c498c3b496f41644998d84685a25fa8be5
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Thu Oct 23 16:02:51 2014 -0700
chromeos: Add a function to copy VPD WiFi calibration data to CBMEM
This patch adds functions looking in the VPD for WiFi calibration
data, and if found, copying the calibration blobs into CBMEM.
Two possible key names templates are used: wifi_base64_calibrationX
and wifi_calibrationX, where X is replaced by the WiFi interface
number. Up to four interfaces can be provisioned.
The calibration data will be retrieved from CBMEM by the bootloader
and placed into the device tree before starting the kernel.
The structure of the WiFi calibration data CBMEM entry is defined
locally: it is a concatenation of the blob names and their contents.
Each blob is padded as necessary to make sure that the size divisible
by four.
To make sure that the exactly required amount of memory is allocated
for the CBMEM entry, the function first scans the VPD, caching the
information about the available blobs and calculating their combined
size.
Then the required size CBMEM entry is allocates and the blobs are
copied into it.
BRANCH=storm
BUG=chrome-os-partner:32611
TEST=when this function is called, and the VPD includes calibration
data blobs, the WIFI entry shows up in the list of CBMEM entries
reported by coreboot.
Original-Change-Id: Ibe02dc36ff6254e3b9ad0a5bd2696ca29e1b2be3
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/225271
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
(cherry picked from commit 9fe185ae5fdc1a896bf892b498bff27a3462caeb)
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Change-Id: Ia60f0c5c84decf9854426c4f0cb88f8ccee69046
---
src/vendorcode/google/chromeos/Makefile.inc | 2 +-
src/vendorcode/google/chromeos/chromeos.h | 2 +
src/vendorcode/google/chromeos/vpd_calibration.c | 197 +++++++++++++++++++++++
3 files changed, 200 insertions(+), 1 deletion(-)
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index cc50d2f..10a1545 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -29,7 +29,7 @@ ramstage-y += fmap.c
ramstage-$(CONFIG_CHROMEOS_RAMOOPS) += ramoops.c
smm-y += fmap.c
romstage-y += vpd_decode.c cros_vpd.c
-ramstage-y += vpd_decode.c cros_vpd.c
+ramstage-y += vpd_decode.c cros_vpd.c vpd_calibration.c
ifeq ($(MOCK_TPM),1)
CFLAGS_common += -DMOCK_TPM=1
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index 5ba5457..13a4fe3 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -83,4 +83,6 @@ 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 cbmem_add_vpd_calibration_data(void);
+
#endif /* __CHROMEOS_H__ */
diff --git a/src/vendorcode/google/chromeos/vpd_calibration.c b/src/vendorcode/google/chromeos/vpd_calibration.c
new file mode 100644
index 0000000..3bfd843
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vpd_calibration.c
@@ -0,0 +1,197 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <string.h>
+
+#include <vendorcode/google/chromeos/chromeos.h>
+#include <vendorcode/google/chromeos/cros_vpd.h>
+
+/*
+ * This file provides functions looking in the VPD for WiFi calibration data,
+ * and if found, copying the calibration blobs into CBMEM.
+ *
+ * Per interface calibration data is stored in the VPD in opaque blobs. The
+ * keys of the blobs follow one of two possible patterns:
+ * "wifi_base64_calibration<N>" or "wifi_calibration<N>", where <N> is the
+ * interface number.
+ *
+ * This function accommodates up to 4 interfaces. All calibration blobs found
+ * in the VPD are packed into a single CBMEM entry as describe by the
+ * structures below:
+ */
+
+/* This structure describes a single calibration data blob */
+struct calibration_blob {
+ uint32_t blob_size; /* Total size. rounded up to fall on a 4 byte
+ boundary. */
+ uint32_t key_size; /* Size of the name of this entry, \0 included. */
+ uint32_t value_size; /* Size of the value of this entry */
+ /* Zero terminated name(key) goes here, immediately followed by value */
+};
+
+/*
+ * This is the structure of the CBMEM entry containing WiFi calibration blobs.
+ * It starts with the total size (header size included) followed by an
+ * arbitrary number of concatenated 4 byte aligned calibration blobs.
+ */
+struct calibration_entry {
+ uint32_t size;
+ struct calibration_blob entries[0]; /* A varialble size container. */
+};
+
+
+#define MAX_WIFI_INTERFACE_COUNT 4
+
+/*
+ * Structure of the cache to keep information about calibration blobs present
+ * in the VPD, one cache entry per VPD blob.
+ *
+ * Maintaing the cache allows to scan the VPD once, determine the CBMEM entry
+ * memory requirements, then allocate as much room as necessary and fill it
+ * up.
+ */
+struct vpd_blob_cache_t {
+ /* The longest name template must fit with an extra character. */
+ char key_name[40];
+ const void *value_pointer;
+ unsigned blob_size;
+ unsigned key_size;
+ unsigned value_size;
+};
+
+static const char * const templates[] = {
+ "wifi_base64_calibrationX",
+ "wifi_calibrationX"
+};
+
+/*
+ * Scan the VPD for WiFi calibration data, checking for all possible key names
+ * and caching discovered blobs.
+ *
+ * Return the sum of sizes of all blobs, as stored in CBMEM.
+ */
+static size_t fill_up_entries_cache(struct vpd_blob_cache_t *cache,
+ size_t max_entries, size_t *filled_entries)
+{
+ int i;
+ int cbmem_entry_size = 0;
+ size_t used_entries = 0;
+
+
+ for (i = 0;
+ (i < ARRAY_SIZE(templates)) && (used_entries < max_entries);
+ i++) {
+ int j;
+ const int index_location = strlen(templates[i]) - 1;
+ const int key_length = index_location + 2;
+
+ if (key_length > sizeof(cache->key_name))
+ continue;
+
+ for (j = 0; j < MAX_WIFI_INTERFACE_COUNT; j++) {
+ const void *payload;
+ int payload_size;
+
+ strcpy(cache->key_name, templates[i]);
+ cache->key_name[index_location] = j + '0';
+
+ payload = cros_vpd_find(cache->key_name, &payload_size);
+ if (!payload)
+ continue;
+
+ cache->value_pointer = payload;
+ cache->key_size = key_length;
+ cache->value_size = payload_size;
+ cache->blob_size =
+ ALIGN(sizeof(struct calibration_blob) +
+ cache->key_size +
+ cache->value_size, 4);
+ cbmem_entry_size += cache->blob_size;
+
+ used_entries++;
+ if (used_entries == max_entries)
+ break;
+
+ cache++;
+ }
+ }
+
+ *filled_entries = used_entries;
+ return cbmem_entry_size;
+}
+
+void cbmem_add_vpd_calibration_data(void)
+{
+ size_t cbmem_entry_size, filled_entries;
+ struct calibration_entry *cbmem_entry;
+ struct calibration_blob *cal_blob;
+ int i;
+ /*
+ * Allocate one more cache entry than max required, to make sure that
+ * the last entry can be identified by the key size of zero.
+ */
+ struct vpd_blob_cache_t vpd_blob_cache[ARRAY_SIZE(templates) *
+ MAX_WIFI_INTERFACE_COUNT];
+
+ cbmem_entry_size = fill_up_entries_cache(vpd_blob_cache,
+ ARRAY_SIZE(vpd_blob_cache),
+ &filled_entries);
+
+ if (!cbmem_entry_size)
+ return; /* No calibration data found in the VPD. */
+
+ cbmem_entry_size += sizeof(struct calibration_entry);
+ cbmem_entry = cbmem_add(CBMEM_ID_WIFI_CALIBRATION, cbmem_entry_size);
+ if (!cbmem_entry) {
+ printk(BIOS_ERR, "%s: no room in cbmem to add %zd bytes\n",
+ __func__, cbmem_entry_size);
+ return;
+ }
+
+ cbmem_entry->size = cbmem_entry_size;
+
+ /* Copy cached data into the CBMEM entry. */
+ cal_blob = cbmem_entry->entries;
+
+ for (i = 0; i < filled_entries; i++) {
+ /* Use this as a pointer to the current cache entry. */
+ struct vpd_blob_cache_t *cache = vpd_blob_cache + i;
+ char *pointer;
+
+ cal_blob->blob_size = cache->blob_size;
+ cal_blob->key_size = cache->key_size;
+ cal_blob->value_size = cache->value_size;
+
+ /* copy the key */
+ pointer = (char *)(cal_blob + 1);
+ memcpy(pointer, cache->key_name, cache->key_size);
+
+ /* and the value */
+ pointer += cache->key_size;
+ memcpy(pointer, cache->value_pointer, cache->value_size);
+
+ printk(BIOS_INFO, "%s: added %s to CBMEM\n",
+ __func__, cache->key_name);
+
+ cal_blob = (struct calibration_blob *)
+ ((char *)cal_blob + cal_blob->blob_size);
+ }
+}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9434
-gerrit
commit b3c1cdfa20baf430ccd39c47450f3e73197bffe1
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Wed Oct 22 17:39:24 2014 -0700
chromeos: add another VPD access API
The new API allows to find VPD objects in the VPD cache. There is no
need for the caller to allocate or free the per object memory.
The existing API (cros_vpd_gets) now uses the new function as well.
BRANCH=storm
BUG=chrome-os-partner:32611
TEST=verified that MAC addresses still show up in the device tree on
the booted storm device
Original-Change-Id: I6c0b11bb844d6235930124d642da632319142d88
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/225258
Original-Reviewed-by: Hung-Te Lin <hungte(a)chromium.org>
(cherry picked from commit 99a34344448a5521cee8ad3918aefb1fde28417d)
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Change-Id: Ia1da362b12389a18a784ac3c8195127e91bb8d00
---
src/vendorcode/google/chromeos/cros_vpd.c | 26 +++++++++++++++++++++-----
src/vendorcode/google/chromeos/cros_vpd.h | 16 ++++++++++++++++
2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/src/vendorcode/google/chromeos/cros_vpd.c b/src/vendorcode/google/chromeos/cros_vpd.c
index df2b5bf..c0e4830 100644
--- a/src/vendorcode/google/chromeos/cros_vpd.c
+++ b/src/vendorcode/google/chromeos/cros_vpd.c
@@ -99,7 +99,7 @@ static int vpd_gets_callback(const uint8_t *key, int32_t key_len,
return VPD_FAIL;
}
-char *cros_vpd_gets(const char *key, char *buffer, int size)
+const void *cros_vpd_find(const char *key, int *size)
{
uint8_t *vpd_address = NULL;
int32_t vpd_size = 0;
@@ -121,10 +121,26 @@ char *cros_vpd_gets(const char *key, char *buffer, int size)
if (!arg.matched)
return NULL;
- if (size < arg.value_len + 1)
- size = arg.value_len + 1;
- memcpy(buffer, arg.value, size - 1);
- buffer[size - 1] = '\0';
+ *size = arg.value_len;
+ return arg.value;
+}
+
+char *cros_vpd_gets(const char *key, char *buffer, int size)
+{
+ const void *string_address;
+ int string_size;
+
+ string_address = cros_vpd_find(key, &string_size);
+
+ if (!string_address)
+ return NULL;
+
+ if (size > (string_size + 1)) {
+ strcpy(buffer, string_address);
+ } else {
+ memcpy(buffer, string_address, size - 1);
+ buffer[size - 1] = '\0';
+ }
return buffer;
}
diff --git a/src/vendorcode/google/chromeos/cros_vpd.h b/src/vendorcode/google/chromeos/cros_vpd.h
index 674dbf6..19658c2 100644
--- a/src/vendorcode/google/chromeos/cros_vpd.h
+++ b/src/vendorcode/google/chromeos/cros_vpd.h
@@ -18,4 +18,20 @@
*/
char *cros_vpd_gets(const char *key, char *buffer, int size);
+/*
+ * Find VPD value by key.
+ *
+ * Searches for a VPD entry in the VPD cache. If found, places the size of the
+ * entry into '*size' and returns the pointer to the entry data.
+ *
+ * This function presumes that VPD is cached in DRAM (which is the case in the
+ * current implementation) and as such returns the pointer into the cache. The
+ * user is not supposed to modify the data, and does not have to free the
+ * memory.
+ *
+ * Returns NULL if key is not found.
+ */
+
+const void *cros_vpd_find(const char *key, int *size);
+
#endif /* __CROS_VPD_H__ */