summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Wai-Hong Tam <waihong@chromium.org>2011-07-15 16:55:21 +0800
committerSimon Glass <sjg@chromium.org>2011-08-29 10:59:02 -0700
commitf4fe2e2dc3cba81df463b21159924b5707ce5607 (patch)
treec1287cac8d23d92841d191971cdcf63775a7190b /lib
parent98660ae72f5916737d389374d0846741ffeff833 (diff)
CHROMIUM: Partially load GBB when needed.
This CL is to make the firmware just load a minimal part of GBB: the header, HWID (required by crossystem data), and rootkey (required by verifying firmware). When VbInit() returns VB_INIT_OUT_ENABLE_DISPLAY, firmware then continues to load the BMP Block. When it returns VB_INIT_OUT_ENABLE_RECOVERY, firmware loads the recovery key. We profiled this change. It totally gains 142ms of boot time on Seaboard. Loads entired GBB in RO normal boot: 2,349,330 bootm_start Loads minimal required part of GBB in RO normal boot: 2,207,288 bootm_start BUG=chromium-os:17700 TEST=build chromeos_seaboard_vboot without error; success to boot normal path; when developer switch on, bmp showed; when recovery button pressed, bmp showed; run "vbexport_test display" to show bmps. Change-Id: I8d1d8b5676505b05328cfea6a1ff35d1048dc131 Reviewed-on: http://gerrit.chromium.org/gerrit/4287 Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Tom Wai-Hong Tam <waihong@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/vboot/bootstub_entry.c6
-rw-r--r--lib/vboot/global_data.c107
2 files changed, 100 insertions, 13 deletions
diff --git a/lib/vboot/bootstub_entry.c b/lib/vboot/bootstub_entry.c
index dc12101ea8..bd98d1dbd1 100644
--- a/lib/vboot/bootstub_entry.c
+++ b/lib/vboot/bootstub_entry.c
@@ -274,6 +274,12 @@ void bootstub_entry(void)
/* Handle the VbInit() results */
if (iparams.out_flags & VB_INIT_OUT_CLEAR_RAM)
clear_ram_not_in_use();
+ if (iparams.out_flags & VB_INIT_OUT_ENABLE_DISPLAY)
+ if (load_bmpblk_in_gbb(global, &file))
+ VbExError(PREFIX "Failed to load BMP Block!\n");
+ if (iparams.out_flags & VB_INIT_OUT_ENABLE_RECOVERY)
+ if (load_reckey_in_gbb(global, &file))
+ VbExError(PREFIX "Failed to load recovery key!\n");
/* Call VbSelectFirmware() */
cparams.caller_context = &cache;
diff --git a/lib/vboot/global_data.c b/lib/vboot/global_data.c
index 290bcad1cb..e1e76373a5 100644
--- a/lib/vboot/global_data.c
+++ b/lib/vboot/global_data.c
@@ -10,10 +10,13 @@
#include <common.h>
#include <fdt_decode.h>
-#include <vboot_api.h>
+#include <chromeos/common.h>
#include <chromeos/cros_gpio.h>
#include <vboot/global_data.h>
+#include <gbb_header.h>
+#include <vboot_api.h>
+
#define PREFIX "global_data: "
DECLARE_GLOBAL_DATA_PTR;
@@ -26,6 +29,85 @@ vb_global_t *get_vboot_global(void)
return (vb_global_t *)(VBGLOBAL_BASE);
}
+/*
+ * Loads the minimal required part of GBB from firmware, including:
+ * - header,
+ * - hwid (required by crossystem data,
+ * - rootkey (required by VbLoadFirmware() to verify firmware).
+ */
+static int load_minimal_gbb(firmware_storage_t *file, uint32_t source,
+ void *gbb_base)
+{
+ GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)gbb_base;
+
+ if (file->read(file, source, sizeof(*gbb), gbb)) {
+ VBDEBUG(PREFIX "Failed to read GBB header!\n");
+ return 1;
+ }
+
+ if (file->read(file, source + gbb->hwid_offset, gbb->hwid_size,
+ gbb_base + gbb->hwid_offset)) {
+ VBDEBUG(PREFIX "Failed to read HWID in GBB!\n");
+ return 1;
+ }
+
+ if (file->read(file, source + gbb->rootkey_offset, gbb->rootkey_size,
+ gbb_base + gbb->rootkey_offset)) {
+ VBDEBUG(PREFIX "Failed to read Root Key in GBB!\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Loads the BMP block in GBB from firmware. */
+int load_bmpblk_in_gbb(vb_global_t *global, firmware_storage_t *file)
+{
+ void *fdt_ptr = (void *)gd->blob;
+ struct fdt_twostop_fmap fmap;
+ GoogleBinaryBlockHeader *gbb =
+ (GoogleBinaryBlockHeader *)global->gbb_data;
+
+ if (fdt_decode_twostop_fmap(fdt_ptr, &fmap)) {
+ VBDEBUG(PREFIX "Failed to load fmap config from fdt!\n");
+ return 1;
+ }
+
+ if (file->read(file,
+ fmap.readonly.gbb.offset + gbb->bmpfv_offset,
+ gbb->bmpfv_size,
+ global->gbb_data + gbb->bmpfv_offset)) {
+ VBDEBUG(PREFIX "Failed to read BMP Block in GBB!\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Loads the recovery key in GBB from firmware. */
+int load_reckey_in_gbb(vb_global_t *global, firmware_storage_t *file)
+{
+ void *fdt_ptr = (void *)gd->blob;
+ struct fdt_twostop_fmap fmap;
+ GoogleBinaryBlockHeader *gbb =
+ (GoogleBinaryBlockHeader *)global->gbb_data;
+
+ if (fdt_decode_twostop_fmap(fdt_ptr, &fmap)) {
+ VBDEBUG(PREFIX "Failed to load fmap config from fdt!\n");
+ return 1;
+ }
+
+ if (file->read(file,
+ fmap.readonly.gbb.offset + gbb->recovery_key_offset,
+ gbb->recovery_key_size,
+ global->gbb_data + gbb->recovery_key_offset)) {
+ VBDEBUG(PREFIX "Failed to read Recovery Key in GBB!\n");
+ return 1;
+ }
+
+ return 0;
+}
+
int init_vboot_global(vb_global_t *global, firmware_storage_t *file)
{
void *fdt_ptr = (void *)gd->blob;
@@ -38,54 +120,53 @@ int init_vboot_global(vb_global_t *global, firmware_storage_t *file)
memcpy(global->signature, VBGLOBAL_SIGNATURE,
VBGLOBAL_SIGNATURE_SIZE);
- /* Get GPIO status */
+ /* Gets GPIO status */
if (cros_gpio_fetch(CROS_GPIO_WPSW, fdt_ptr, &wpsw) ||
cros_gpio_fetch(CROS_GPIO_RECSW, fdt_ptr, &recsw) ||
cros_gpio_fetch(CROS_GPIO_DEVSW, fdt_ptr, &devsw)) {
- VbExDebug(PREFIX "Failed to fetch GPIO!\n");
+ VBDEBUG(PREFIX "Failed to fetch GPIO!\n");
return 1;
}
if (fdt_decode_twostop_fmap(fdt_ptr, &fmap)) {
- VbExDebug(PREFIX "Failed to load fmap config from fdt!\n");
+ VBDEBUG(PREFIX "Failed to load fmap config from fdt!\n");
return 1;
}
- /* Load GBB from SPI */
+ /* Loads a minimal required part of GBB from SPI */
if (fmap.readonly.gbb.length > GBB_MAX_LENGTH) {
- VbExDebug(PREFIX "The GBB size declared in FDT is too big!\n");
+ VBDEBUG(PREFIX "The GBB size declared in FDT is too big!\n");
return 1;
}
global->gbb_size = fmap.readonly.gbb.length;
- if (file->read(file,
+ if (load_minimal_gbb(file,
fmap.readonly.gbb.offset,
- fmap.readonly.gbb.length,
global->gbb_data)) {
- VbExDebug(PREFIX "Failed to read GBB!\n");
+ VBDEBUG(PREFIX "Failed to read GBB!\n");
return 1;
}
if (fmap.readonly.firmware_id.length > ID_LEN) {
- VbExDebug(PREFIX "The FWID size declared in FDT is too big!\n");
+ VBDEBUG(PREFIX "The FWID size declared in FDT is too big!\n");
return 1;
}
if (file->read(file,
fmap.readonly.firmware_id.offset,
fmap.readonly.firmware_id.length,
frid)) {
- VbExDebug(PREFIX "Failed to read frid!\n");
+ VBDEBUG(PREFIX "Failed to read frid!\n");
return 1;
}
if (VbExNvStorageRead(nvraw)) {
- VbExDebug(PREFIX "Failed to read NvStorage!\n");
+ VBDEBUG(PREFIX "Failed to read NvStorage!\n");
return 1;
}
if (crossystem_data_init(&global->cdata_blob, frid,
fmap.readonly.fmap.offset, global->gbb_data, nvraw,
&wpsw, &recsw, &devsw)) {
- VbExDebug(PREFIX "Failed to init crossystem data!\n");
+ VBDEBUG(PREFIX "Failed to init crossystem data!\n");
return 1;
}