summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/chromebook-x86/coreboot/coreboot.c8
-rw-r--r--common/cmd_vboot_test.c14
-rw-r--r--common/cmd_vboot_twostop.c51
-rw-r--r--include/chromeos/firmware_storage.h12
-rw-r--r--include/chromeos/gbb.h13
-rw-r--r--include/configs/coreboot.h2
-rw-r--r--lib/chromeos/firmware_storage_spi.c46
-rw-r--r--lib/chromeos/gbb.c12
-rw-r--r--lib/vbexport/load_firmware.c3
9 files changed, 133 insertions, 28 deletions
diff --git a/board/chromebook-x86/coreboot/coreboot.c b/board/chromebook-x86/coreboot/coreboot.c
index dace515ea4..e633f3b4b2 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 41963953ab..12e6c4ed59 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 fe1fc54aec..ff6e8c9473 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 2ef6e2b034..e45819079b 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 0d54f8fdd8..c3bc304b38 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 e76edce6d6..47f4634f3c 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 26e01046db..a2d80b585b 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 efadcd3037..25d5741318 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 847418293e..49b0215351 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;
}