diff options
author | Tom Wai-Hong Tam <waihong@chromium.org> | 2011-07-15 16:55:21 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-08-29 10:59:02 -0700 |
commit | f4fe2e2dc3cba81df463b21159924b5707ce5607 (patch) | |
tree | c1287cac8d23d92841d191971cdcf63775a7190b | |
parent | 98660ae72f5916737d389374d0846741ffeff833 (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.c | 5 | ||||
-rw-r--r-- | include/vboot/global_data.h | 12 | ||||
-rw-r--r-- | lib/vboot/bootstub_entry.c | 6 | ||||
-rw-r--r-- | lib/vboot/global_data.c | 107 |
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; } |