diff options
-rw-r--r-- | board/chromebook-x86/coreboot/coreboot.c | 8 | ||||
-rw-r--r-- | common/cmd_vboot_test.c | 14 | ||||
-rw-r--r-- | common/cmd_vboot_twostop.c | 51 | ||||
-rw-r--r-- | include/chromeos/firmware_storage.h | 12 | ||||
-rw-r--r-- | include/chromeos/gbb.h | 13 | ||||
-rw-r--r-- | include/configs/coreboot.h | 2 | ||||
-rw-r--r-- | lib/chromeos/firmware_storage_spi.c | 46 | ||||
-rw-r--r-- | lib/chromeos/gbb.c | 12 | ||||
-rw-r--r-- | lib/vbexport/load_firmware.c | 3 |
9 files changed, 133 insertions, 28 deletions
diff --git a/board/chromebook-x86/coreboot/coreboot.c b/board/chromebook-x86/coreboot/coreboot.c index dace515ea46..e633f3b4b27 100644 --- a/board/chromebook-x86/coreboot/coreboot.c +++ b/board/chromebook-x86/coreboot/coreboot.c @@ -144,16 +144,18 @@ static void handle_mrc_cache(void) return; } +#ifndef CONFIG_HARDWARE_MAPPED_SPI saved_entry = malloc(fme.length); if (!saved_entry) { printf("%s: failed to allocate %d bytes\n", __func__, fme.length); return; } +#endif - if (file.read(&file, fme.offset, fme.length, saved_entry)) { + if (file.read(&file, fme.offset, fme.length, BT_EXTRA saved_entry)) { printf("%s: failed to read %d bytes\n", __func__, fme.length); - free(saved_entry); + FREE_IF_NEEDED(saved_entry); return; } @@ -173,7 +175,7 @@ static void handle_mrc_cache(void) } else { printf("%s: cached storage match\n", __func__); } - free(saved_entry); + FREE_IF_NEEDED(saved_entry); } int misc_init_r(void) diff --git a/common/cmd_vboot_test.c b/common/cmd_vboot_test.c index 41963953aba..12e6c4ed591 100644 --- a/common/cmd_vboot_test.c +++ b/common/cmd_vboot_test.c @@ -51,10 +51,12 @@ static int do_vboot_test_fwrw(cmd_tbl_t *cmdtp, return cmd_usage(cmdtp); } +#ifndef CONFIG_HARDWARE_MAPPED_SPI /* Allocate the buffer and fill the target test pattern. */ original_buf = VbExMalloc(test_length); - target_buf = VbExMalloc(test_length); verify_buf = VbExMalloc(test_length); +#endif + target_buf = VbExMalloc(test_length); /* Fill the target test pattern. */ for (i = 0; i < test_length; i++) @@ -67,7 +69,8 @@ static int do_vboot_test_fwrw(cmd_tbl_t *cmdtp, } t0 = VbExGetTimer(); - if (file.read(&file, TEST_FW_START, test_length, original_buf)) { + if (file.read(&file, TEST_FW_START, + test_length, BT_EXTRA original_buf)) { VbExDebug("Failed to read firmware!\n"); goto out; } @@ -86,7 +89,8 @@ static int do_vboot_test_fwrw(cmd_tbl_t *cmdtp, ret = 1; } else { /* Read back and verify the data. */ - file.read(&file, TEST_FW_START, test_length, verify_buf); + file.read(&file, TEST_FW_START, test_length, + BT_EXTRA verify_buf); if (memcmp(target_buf, verify_buf, test_length) != 0) { VbExDebug("Verify failed. The target data wrote " "wrong.\n"); @@ -104,9 +108,11 @@ static int do_vboot_test_fwrw(cmd_tbl_t *cmdtp, out: file.close(&file); +#ifndef CONFIG_HARDWARE_MAPPED_SPI VbExFree(original_buf); - VbExFree(target_buf); VbExFree(verify_buf); +#endif + VbExFree(target_buf); if (ret == 0) VbExDebug("Read and write firmware test SUCCESS.\n"); diff --git a/common/cmd_vboot_twostop.c b/common/cmd_vboot_twostop.c index fe1fc54aec7..ff6e8c9473c 100644 --- a/common/cmd_vboot_twostop.c +++ b/common/cmd_vboot_twostop.c @@ -313,6 +313,7 @@ twostop_make_selection(struct twostop_fmap *fmap, firmware_storage_t *file, fparams.verification_size_A = fparams.verification_size_B = vlength; +#ifndef CONFIG_HARDWARE_MAPPED_SPI fparams.verification_block_A = memalign(CACHE_LINE_SIZE, vlength); if (!fparams.verification_block_A) { VBDEBUG(PREFIX "failed to allocate vblock A\n"); @@ -323,14 +324,14 @@ twostop_make_selection(struct twostop_fmap *fmap, firmware_storage_t *file, VBDEBUG(PREFIX "failed to allocate vblock B\n"); goto out; } - +#endif if (file->read(file, fmap->readwrite_a.vblock.offset, vlength, - fparams.verification_block_A)) { + BT_EXTRA fparams.verification_block_A)) { VBDEBUG(PREFIX "fail to read vblock A\n"); goto out; } if (file->read(file, fmap->readwrite_b.vblock.offset, vlength, - fparams.verification_block_B)) { + BT_EXTRA fparams.verification_block_B)) { VBDEBUG(PREFIX "fail to read vblock B\n"); goto out; } @@ -344,6 +345,7 @@ twostop_make_selection(struct twostop_fmap *fmap, firmware_storage_t *file, s.fw[0].size = fmap->readwrite_a.boot.length; s.fw[1].size = fmap->readwrite_b.boot.length; +#ifndef CONFIG_HARDWARE_MAPPED_SPI s.fw[0].cache = memalign(CACHE_LINE_SIZE, s.fw[0].size); if (!s.fw[0].cache) { VBDEBUG(PREFIX "failed to allocate cache A\n"); @@ -354,6 +356,7 @@ twostop_make_selection(struct twostop_fmap *fmap, firmware_storage_t *file, VBDEBUG(PREFIX "failed to allocate cache B\n"); goto out; } +#endif s.file = file; cparams->caller_context = &s; @@ -368,17 +371,17 @@ twostop_make_selection(struct twostop_fmap *fmap, firmware_storage_t *file, out: - free(fparams.verification_block_A); - free(fparams.verification_block_B); + FREE_IF_NEEDED(fparams.verification_block_A); + FREE_IF_NEEDED(fparams.verification_block_B); if (selection == VB_SELECT_FIRMWARE_A) { *fw_blob_ptr = s.fw[0].cache; *fw_size_ptr = s.fw[0].size; - free(s.fw[1].cache); + FREE_IF_NEEDED(s.fw[1].cache); } else if (selection == VB_SELECT_FIRMWARE_B) { *fw_blob_ptr = s.fw[1].cache; *fw_size_ptr = s.fw[1].size; - free(s.fw[0].cache); + FREE_IF_NEEDED(s.fw[0].cache); } return selection; @@ -394,7 +397,11 @@ twostop_select_and_set_main_firmware(struct twostop_fmap *fmap, uint32_t selection; uint32_t id_offset = 0, id_length = 0; int firmware_type; +#ifndef CONFIG_HARDWARE_MAPPED_SPI uint8_t firmware_id[ID_LEN]; +#else + uint8_t *firmware_id; +#endif VbCommonParams cparams; bootstage_mark(BOOTSTAGE_VBOOT_SELECT_AND_SET, @@ -440,7 +447,7 @@ twostop_select_and_set_main_firmware(struct twostop_fmap *fmap, if (file->read(file, id_offset, MIN(sizeof(firmware_id), id_length), - firmware_id)) { + BT_EXTRA firmware_id)) { VBDEBUG(PREFIX "failed to read active firmware id\n"); firmware_id[0] = '\0'; } @@ -493,12 +500,18 @@ twostop_jump(crossystem_data_t *cdata, void *fw_blob, uint32_t fw_size) static int twostop_init(struct twostop_fmap *fmap, firmware_storage_t *file, - void *gbb, crossystem_data_t *cdata, void *vb_shared_data) + void **gbbp, crossystem_data_t *cdata, void *vb_shared_data) { cros_gpio_t wpsw, recsw, devsw; - GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)gbb; - uint8_t hardware_id[ID_LEN], readonly_firmware_id[ID_LEN]; + GoogleBinaryBlockHeader *gbbh; + uint8_t hardware_id[ID_LEN]; +#ifndef CONFIG_HARDWARE_MAPPED_SPI + uint8_t readonly_firmware_id[ID_LEN]; +#else + uint8_t *readonly_firmware_id; +#endif int ret = -1; + void *gbb; bootstage_mark(BOOTSTAGE_VBOOT_TWOSTOP_INIT, "twostop_init"); if (cros_gpio_fetch(CROS_GPIO_WPSW, &wpsw) || @@ -527,18 +540,28 @@ twostop_init(struct twostop_fmap *fmap, firmware_storage_t *file, if (file->read(file, fmap->readonly.firmware_id.offset, MIN(sizeof(readonly_firmware_id), fmap->readonly.firmware_id.length), - readonly_firmware_id)) { + BT_EXTRA readonly_firmware_id)) { VBDEBUG(PREFIX "failed to read firmware ID\n"); readonly_firmware_id[0] = '\0'; } VBDEBUG(PREFIX "read-only firmware id: \"%s\"\n", readonly_firmware_id); /* Load basic parts of gbb blob */ +#ifdef CONFIG_HARDWARE_MAPPED_SPI + if (gbb_init(gbbp, file, fmap->readonly.gbb.offset)) { + VBDEBUG(PREFIX "failed to read gbb\n"); + goto out; + } + gbb = *gbbp; +#else + gbb = *gbbp; if (gbb_init(gbb, file, fmap->readonly.gbb.offset)) { VBDEBUG(PREFIX "failed to read gbb\n"); goto out; } +#endif + gbbh = (GoogleBinaryBlockHeader *)gbb; memcpy(hardware_id, gbb + gbbh->hwid_offset, MIN(sizeof(hardware_id), gbbh->hwid_size)); VBDEBUG(PREFIX "hardware id: \"%s\"\n", hardware_id); @@ -637,8 +660,10 @@ static int setup_gbb_and_cdata(void **gbb, crossystem_data_t **cdata, { size_t size; +#ifdef CONFIG_HARDWARE_MAPPED_SPI *gbb = fdt_decode_chromeos_alloc_region(gd->blob, "google-binary-block", &size); +#endif *cdata = fdt_decode_chromeos_alloc_region(gd->blob, "cros-system-data", &size); if (!*gbb || !*cdata) { @@ -680,7 +705,7 @@ twostop_boot(void) return VB_SELECT_ERROR; vb_shared_data = cdata->vb_shared_data; - if (twostop_init(&fmap, &file, gbb, cdata, vb_shared_data)) { + if (twostop_init(&fmap, &file, &gbb, cdata, vb_shared_data)) { VBDEBUG(PREFIX "failed to init twostop boot\n"); return VB_SELECT_ERROR; } diff --git a/include/chromeos/firmware_storage.h b/include/chromeos/firmware_storage.h index 2ef6e2b0348..e45819079bc 100644 --- a/include/chromeos/firmware_storage.h +++ b/include/chromeos/firmware_storage.h @@ -15,6 +15,16 @@ #include <chromeos/fdt_decode.h> +#ifndef CONFIG_HARDWARE_MAPPED_SPI +typedef void *read_buf_type; +#define BT_EXTRA +#define FREE_IF_NEEDED(p) free(p) +#else +typedef void **read_buf_type; +#define BT_EXTRA (read_buf_type) & +#define FREE_IF_NEEDED(p) +#endif + /** * These read or write [count] bytes starting from [offset] of storage into or * from the [buf]. @@ -27,7 +37,7 @@ */ typedef struct firmware_storage_t { int (*read)(struct firmware_storage_t *file, - uint32_t offset, uint32_t count, void *buf); + uint32_t offset, uint32_t count, read_buf_type buf); int (*write)(struct firmware_storage_t *file, uint32_t offset, uint32_t count, void *buf); int (*close)(struct firmware_storage_t *file); diff --git a/include/chromeos/gbb.h b/include/chromeos/gbb.h index 0d54f8fdd85..c3bc304b38e 100644 --- a/include/chromeos/gbb.h +++ b/include/chromeos/gbb.h @@ -24,8 +24,9 @@ * @param gbb_offset Offset of GBB in flashrom device * @return zero if this succeeds, non-zero if this fails */ -int gbb_init(void *gbb, firmware_storage_t *file, uint32_t gbb_offset); +int gbb_init(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset); +#ifndef CONFIG_HARDWARE_MAPPED_SPI /** * This loads the BMP block of GBB from flashrom. * @@ -34,7 +35,7 @@ int gbb_init(void *gbb, firmware_storage_t *file, uint32_t gbb_offset); * @param gbb_offset Offset of GBB in flashrom device * @return zero if this succeeds, non-zero if this fails */ -int gbb_read_bmp_block(void *gbb, +int gbb_read_bmp_block(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset); /* @@ -45,9 +46,15 @@ int gbb_read_bmp_block(void *gbb, * @param gbb_offset Offset of GBB in flashrom device * @return zero if this succeeds, non-zero if this fails */ -int gbb_read_recovery_key(void *gbb, +int gbb_read_recovery_key(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset); +#else + +#define gbb_read_bmp_block gbb_init +#define gbb_read_recovery_key gbb_init + +#endif /** * This is a sanity check of GBB blob. * diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index e76edce6d64..47f4634f3c3 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -318,6 +318,8 @@ #undef CONFIG_CMD_NET #endif +#define CONFIG_HARDWARE_MAPPED_SPI + /* Board specific late time init */ #define CONFIG_MISC_INIT_R diff --git a/lib/chromeos/firmware_storage_spi.c b/lib/chromeos/firmware_storage_spi.c index 26e01046db3..a2d80b585b0 100644 --- a/lib/chromeos/firmware_storage_spi.c +++ b/lib/chromeos/firmware_storage_spi.c @@ -47,19 +47,61 @@ static int border_check(struct spi_flash *flash, uint32_t offset, return 0; } +#ifdef CONFIG_HARDWARE_MAPPED_SPI + +#include <libfdt.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * When using hardware mapped SPI the offset passed to the file_read() + * function should be added to the base address of the SPI flash in the CPI + * memory. set_spi_flash_base() retrieves the flash chip base address from the + * flash map device tree section. + */ +static uint32_t spi_flash_base_addr; + +void set_spi_flash_base(void) +{ + int fmap_offset; + uint32_t *property; + int length; + const void *blob = gd->blob; + + fmap_offset = fdt_node_offset_by_compatible(blob, -1, + "chromeos,flashmap"); + if (fmap_offset < 0) { + VBDEBUG(PREFIX "chromeos,flashmap node is missing\n"); + return; + } + property = (uint32_t *)fdt_getprop(blob, fmap_offset, "reg", &length); + if (!property) { + VBDEBUG(PREFIX "reg property missing in flashmap!'\n"); + return; + } + spi_flash_base_addr = fdt32_to_cpu(property[0]); +} + +#endif + static int read_spi(firmware_storage_t *file, uint32_t offset, uint32_t count, - void *buf) + read_buf_type buf) { struct spi_flash *flash = file->context; if (border_check(flash, offset, count)) return -1; +#ifndef CONFIG_HARDWARE_MAPPED_SPI if (flash->read(flash, offset, count, buf)) { VBDEBUG(PREFIX "SPI read fail\n"); return -1; } - +#else + if (!spi_flash_base_addr) + set_spi_flash_base(); + *buf = (void *) (spi_flash_base_addr + offset); +#endif return 0; } diff --git a/lib/chromeos/gbb.c b/lib/chromeos/gbb.c index efadcd3037d..25d57413185 100644 --- a/lib/chromeos/gbb.c +++ b/lib/chromeos/gbb.c @@ -16,8 +16,9 @@ #define PREFIX "gbb: " -int gbb_init(void *gbb, firmware_storage_t *file, uint32_t gbb_offset) +int gbb_init(read_buf_type gbb, firmware_storage_t *file, uint32_t gbb_offset) { +#ifndef CONFIG_HARDWARE_MAPPED_SPI GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)gbb; if (file->read(file, gbb_offset, sizeof(*gbbh), gbbh)) { @@ -38,10 +39,18 @@ int gbb_init(void *gbb, firmware_storage_t *file, uint32_t gbb_offset) VBDEBUG(PREFIX "failed to read root key\n"); return 1; } +#else + if (file->read(file, gbb_offset, + sizeof(GoogleBinaryBlockHeader), gbb)) { + VBDEBUG(PREFIX "failed to read GBB header\n"); + return 1; + } +#endif return 0; } +#ifndef CONFIG_HARDWARE_MAPPED_SPI int gbb_read_bmp_block(void *gbb, firmware_storage_t *file, uint32_t gbb_offset) { GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)gbb; @@ -70,6 +79,7 @@ int gbb_read_recovery_key(void *gbb, return 0; } +#endif int gbb_check_integrity(uint8_t *gbb) { diff --git a/lib/vbexport/load_firmware.c b/lib/vbexport/load_firmware.c index 847418293e1..49b0215351a 100644 --- a/lib/vbexport/load_firmware.c +++ b/lib/vbexport/load_firmware.c @@ -49,7 +49,8 @@ VbError_t VbExHashFirmwareBody(VbCommonParams* cparams, uint32_t firmware_index) */ s->fw[i].size = firmware_body_size((uintptr_t)s->fw[i].vblock); - if (file->read(file, s->fw[i].offset, s->fw[i].size, s->fw[i].cache)) { + if (file->read(file, s->fw[i].offset, + s->fw[i].size, BT_EXTRA(s->fw[i].cache))) { VBDEBUG(PREFIX "fail to read firmware: %d\n", firmware_index); return 1; } |