summaryrefslogtreecommitdiff
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
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>
-rw-r--r--common/cmd_vbexport_test.c5
-rw-r--r--include/vboot/global_data.h12
-rw-r--r--lib/vboot/bootstub_entry.c6
-rw-r--r--lib/vboot/global_data.c107
4 files changed, 114 insertions, 16 deletions
diff --git a/common/cmd_vbexport_test.c b/common/cmd_vbexport_test.c
index 32baf434520..7da84a09933 100644
--- a/common/cmd_vbexport_test.c
+++ b/common/cmd_vbexport_test.c
@@ -370,6 +370,11 @@ static uint8_t *read_gbb_from_firmware(void)
return NULL;
}
+ if (load_bmpblk_in_gbb(global, &file)) {
+ VbExDebug("Failed to load BMP Block in GBB!\n");
+ return NULL;
+ }
+
if (file.close(&file)) {
VbExDebug("Failed to close firmware device!\n");
}
diff --git a/include/vboot/global_data.h b/include/vboot/global_data.h
index 6431ff68892..c40aa000af7 100644
--- a/include/vboot/global_data.h
+++ b/include/vboot/global_data.h
@@ -39,13 +39,19 @@ typedef struct {
crossystem_data_t cdata_blob;
} vb_global_t;
-/* Get vboot global data pointer. */
+/* Gets vboot global data pointer. */
vb_global_t *get_vboot_global(void);
-/* Initialize vboot global data. It also loads the GBB data from SPI. */
+/* Initializes vboot global data. It also loads the GBB data from SPI. */
int init_vboot_global(vb_global_t *global, firmware_storage_t *file);
-/* Check if vboot global data valid or not. */
+/* Checks if vboot global data valid or not. */
int is_vboot_global_valid(vb_global_t *global);
+/* Loads the BMP block in GBB from firmware. */
+int load_bmpblk_in_gbb(vb_global_t *global, firmware_storage_t *file);
+
+/* Loads the recovery key in GBB from firmware. */
+int load_reckey_in_gbb(vb_global_t *global, firmware_storage_t *file);
+
#endif /* VBOOT_GLOBAL_DATA_H */
diff --git a/lib/vboot/bootstub_entry.c b/lib/vboot/bootstub_entry.c
index dc12101ea81..bd98d1dbd11 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 290bcad1cb1..e1e76373a51 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;
}