summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/cmd_cros_onestop_firmware.c8
-rw-r--r--common/cmd_vbexport_test.c2
-rw-r--r--common/cmd_vboot_test.c14
-rw-r--r--include/chromeos/firmware_storage.h61
-rw-r--r--lib/chromeos/Makefile1
-rw-r--r--lib/chromeos/firmware_storage.c95
-rw-r--r--lib/chromeos/firmware_storage_onestop.c233
-rw-r--r--lib/chromeos/firmware_storage_spi.c139
-rw-r--r--lib/chromeos/onestop.c8
-rw-r--r--lib/vbexport/load_firmware.c31
-rw-r--r--lib/vboot/bootstub_entry.c8
-rw-r--r--lib/vboot/global_data.c4
12 files changed, 195 insertions, 409 deletions
diff --git a/common/cmd_cros_onestop_firmware.c b/common/cmd_cros_onestop_firmware.c
index ca617a95445..91c4aca11fe 100644
--- a/common/cmd_cros_onestop_firmware.c
+++ b/common/cmd_cros_onestop_firmware.c
@@ -160,7 +160,7 @@ static uint32_t init_internal_state_bottom_half(firmware_storage_t *file,
*dev_mode = 1;
}
- if (firmware_storage_read(file,
+ if (file->read(file,
fmap->onestop_layout.fwid.offset,
fmap->onestop_layout.fwid.length,
frid)) {
@@ -225,7 +225,7 @@ static uint32_t init_internal_state(firmware_storage_t *file,
VBDEBUG(PREFIX "open firmware storage fail\n");
return VBNV_RECOVERY_RO_SHARED_DATA;
}
- if (firmware_storage_read(file,
+ if (file->read(file,
fmap->readonly.gbb.offset,
fmap->readonly.gbb.length,
_state.gbb_data)) {
@@ -289,7 +289,7 @@ static uint32_t load_kernel_subkey_a(firmware_storage_t *file,
struct RSAPublicKey *data_key;
VBDEBUG(PREFIX "reading kernel subkey A\n");
- if (firmware_storage_read(file,
+ if (file->read(file,
fmap->onestop_layout.vblock.offset,
fmap->onestop_layout.vblock.length,
key_block)) {
@@ -499,7 +499,7 @@ static uint32_t rewritable_boot_init(firmware_storage_t *file,
crossystem_data_t *first_stage_cdata;
int w;
- if (firmware_storage_read(file,
+ if (file->read(file,
fmap->onestop_layout.fwid.offset,
fmap->onestop_layout.fwid.length,
fwid)) {
diff --git a/common/cmd_vbexport_test.c b/common/cmd_vbexport_test.c
index b355d061fc9..32baf434520 100644
--- a/common/cmd_vbexport_test.c
+++ b/common/cmd_vbexport_test.c
@@ -370,7 +370,7 @@ static uint8_t *read_gbb_from_firmware(void)
return NULL;
}
- if (firmware_storage_close(&file)) {
+ if (file.close(&file)) {
VbExDebug("Failed to close firmware device!\n");
}
diff --git a/common/cmd_vboot_test.c b/common/cmd_vboot_test.c
index 99def07c8e5..11788afe731 100644
--- a/common/cmd_vboot_test.c
+++ b/common/cmd_vboot_test.c
@@ -41,20 +41,17 @@ static int do_vboot_test_fwrw(cmd_tbl_t *cmdtp,
return 1;
}
- if (firmware_storage_read(&file, TEST_FW_START, TEST_FW_LENGTH,
- original_buf)) {
+ if (file.read(&file, TEST_FW_START, TEST_FW_LENGTH, original_buf)) {
VbExDebug("Failed to read firmware!\n");
return 1;
}
- if (firmware_storage_write(&file, TEST_FW_START, TEST_FW_LENGTH,
- target_buf)) {
+ if (file.write(&file, TEST_FW_START, TEST_FW_LENGTH, target_buf)) {
VbExDebug("Failed to write firmware!\n");
ret = 1;
} else {
/* Read back and verify the data. */
- firmware_storage_read(&file, TEST_FW_START, TEST_FW_LENGTH,
- verify_buf);
+ file.read(&file, TEST_FW_START, TEST_FW_LENGTH, verify_buf);
if (memcmp(target_buf, verify_buf, TEST_FW_LENGTH) != 0) {
VbExDebug("Verify failed. The target data wrote "
"wrong.\n");
@@ -63,10 +60,9 @@ static int do_vboot_test_fwrw(cmd_tbl_t *cmdtp,
}
/* Write the original data back. */
- firmware_storage_write(&file, TEST_FW_START, TEST_FW_LENGTH,
- original_buf);
+ file.write(&file, TEST_FW_START, TEST_FW_LENGTH, original_buf);
- firmware_storage_close(&file);
+ file.close(&file);
if (ret == 0)
VbExDebug("Read and write firmware test SUCCESS.\n");
diff --git a/include/chromeos/firmware_storage.h b/include/chromeos/firmware_storage.h
index 7c9c71362f0..9ded8904ba3 100644
--- a/include/chromeos/firmware_storage.h
+++ b/include/chromeos/firmware_storage.h
@@ -14,29 +14,25 @@
#define CHROMEOS_FIRMWARE_STORAGE_H_
#include <chromeos/fdt_decode.h>
-#include <linux/types.h>
-enum whence_t { SEEK_SET, SEEK_CUR, SEEK_END };
-
-/*
- * The semantic (argument and return value) is similar with system
- * call lseek(2), read(2) and write(2), except that file descriptor
- * is replaced by [context].
+/**
+ * These read or write [count] bytes starting from [offset] of storage into or
+ * from the [buf].
+ *
+ * @param file is the device you access
+ * @param offset is where on the device you access
+ * @param count is the amount of data in byte you access
+ * @param buf is the data that these functions read from or write to
+ * @return 0 if it succeeds, non-zero if it fails
*/
-typedef struct {
- off_t (*seek)(void *context, off_t offset, enum whence_t whence);
- ssize_t (*read)(void *context, void *buf, size_t count);
- ssize_t (*write)(void *context, const void *buf, size_t count);
- int (*close)(void *context);
-
- /**
- * This locks the storage device, i.e., enables write protect.
- *
- * @return 0 if it succeeds, non-zero if it fails
- */
- int (*lock_device)(void *context);
-
- void *context;
+typedef struct firmware_storage_t {
+ int (*read)(struct firmware_storage_t *file,
+ uint32_t offset, uint32_t count, void *buf);
+ int (*write)(struct firmware_storage_t *file,
+ uint32_t offset, uint32_t count, void *buf);
+ int (*close)(struct firmware_storage_t *file);
+
+ void *context; /* device driver's private data */
} firmware_storage_t;
/**
@@ -50,27 +46,4 @@ int firmware_storage_open_spi(firmware_storage_t *file);
int firmware_storage_open_onestop(firmware_storage_t *file,
struct fdt_twostop_fmap *fmap);
-/**
- * These read or write [count] bytes starting from [offset] of storage into or
- * from the [buf]. These are really wrappers of file->{seek,read,write}.
- *
- * @param file - storage device you access
- * @param offset - where on the device you access
- * @param count - the amount of data in byte you access
- * @param buf - the data that these functions read from or write to
- * @return 0 if it succeeds, non-zero if it fails
- */
-int firmware_storage_read(firmware_storage_t *file,
- const off_t offset, const size_t count, void *buf);
-int firmware_storage_write(firmware_storage_t *file,
- const off_t offset, const size_t count, const void *buf);
-
-/**
- * This close SPI flash device
- *
- * @param file - the closed SPI flash device
- * @return 0 if it succeeds, non-zero if it fails
- */
-int firmware_storage_close(firmware_storage_t *file);
-
#endif /* CHROMEOS_FIRMWARE_STORAGE_H_ */
diff --git a/lib/chromeos/Makefile b/lib/chromeos/Makefile
index 957eccbd6c2..21c996a0f1d 100644
--- a/lib/chromeos/Makefile
+++ b/lib/chromeos/Makefile
@@ -15,7 +15,6 @@ LIB = $(obj)libchromeos.a
COBJS-$(CONFIG_CHROMEOS) += cmdline_updater.o
COBJS-$(CONFIG_CHROMEOS) += crossystem_data.o
COBJS-$(CONFIG_CHROMEOS) += fdt_decode.o
-COBJS-$(CONFIG_CHROMEOS) += firmware_storage.o
COBJS-$(CONFIG_CHROMEOS) += firmware_storage_onestop.o
COBJS-$(CONFIG_CHROMEOS) += firmware_storage_spi.o
COBJS-$(CONFIG_CHROMEOS) += load_kernel_helper.o
diff --git a/lib/chromeos/firmware_storage.c b/lib/chromeos/firmware_storage.c
deleted file mode 100644
index 1b7b1556b86..00000000000
--- a/lib/chromeos/firmware_storage.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- */
-
-#include <common.h>
-#include <chromeos/common.h>
-#include <chromeos/firmware_storage.h>
-
-#define PREFIX "firmware_storage: "
-
-int firmware_storage_read(firmware_storage_t *file,
- const off_t offset, const size_t count, void *buf)
-{
- ssize_t size;
- size_t remain;
-
- VBDEBUG(PREFIX "read(offset=%08x, count=%08x, buffer=%p)\n",
- (int)offset, (int)count, buf);
-
- if (file->seek(file->context, offset, SEEK_SET) < 0) {
- VBDEBUG(PREFIX "seek to address 0x%08lx fail\n", offset);
- return -1;
- }
-
- size = 0;
- remain = count;
- while (remain > 0 &&
- (size = file->read(file->context, buf, remain)) > 0) {
- remain -= size;
- buf += size;
- }
-
- if (size < 0) {
- VBDEBUG(PREFIX "an error occur when read firmware: %u\n", size);
- return -1;
- }
-
- if (remain > 0) {
- VBDEBUG(PREFIX "cannot read all data: %u\n", remain);
- return -1;
- }
-
- return 0;
-}
-
-int firmware_storage_write(firmware_storage_t *file,
- const off_t offset, const size_t count, const void *buf)
-{
- ssize_t size;
- size_t remain;
-
- VBDEBUG(PREFIX "write(offset=%08x, count=%08x, buffer=%p)\n",
- (int)offset, (int)count, buf);
-
- if (file->seek(file->context, offset, SEEK_SET) < 0) {
- VBDEBUG(PREFIX "seek to address 0x%08lx fail\n", offset);
- return -1;
- }
-
- size = 0;
- remain = count;
- while (remain > 0 &&
- (size = file->write(file->context, buf, remain)) > 0) {
- remain -= size;
- buf += size;
- }
-
- if (size < 0) {
- VBDEBUG(PREFIX "an error occur when write firmware: %d\n", size);
- return -1;
- }
-
- if (remain > 0) {
- VBDEBUG(PREFIX "cannot write all data: %u\n", remain);
- return -1;
- }
-
- return 0;
-}
-
-int firmware_storage_close(firmware_storage_t *file)
-{
- if (file->close(file->context) < 0) {
- VBDEBUG(PREFIX "failed to close firmware\n");
- return -1;
- }
-
- return 0;
-}
diff --git a/lib/chromeos/firmware_storage_onestop.c b/lib/chromeos/firmware_storage_onestop.c
index 8170cc8de9d..2c4a2bd5a6d 100644
--- a/lib/chromeos/firmware_storage_onestop.c
+++ b/lib/chromeos/firmware_storage_onestop.c
@@ -28,8 +28,6 @@ struct context {
int section;
firmware_storage_t spi_file;
struct mmc *mmc;
- lbaint_t start_block;
- off_t offset_in_block;
};
static int within_entry(const struct fdt_fmap_entry *e, uint32_t offset)
@@ -37,10 +35,8 @@ static int within_entry(const struct fdt_fmap_entry *e, uint32_t offset)
return e->offset <= offset && offset < e->offset + e->length;
}
-static int get_section(struct context *cxt, off_t offset)
+static int get_section(const struct fdt_twostop_fmap *fmap, off_t offset)
{
- const struct fdt_twostop_fmap *fmap = cxt->fmap;;
-
if (within_entry(&fmap->readonly.readonly, offset))
return SECTION_RO;
else if (within_entry(&fmap->readwrite_a.readwrite_a, offset))
@@ -51,160 +47,166 @@ static int get_section(struct context *cxt, off_t offset)
return -1;
}
-static void set_block_lba(struct context *cxt, off_t offset)
+static void set_start_block_and_offset(const struct fdt_twostop_fmap *fmap,
+ int section, uint32_t offset,
+ uint32_t *start_block_ptr, uint32_t *offset_in_block_ptr)
{
- const struct fdt_twostop_fmap *fmap = cxt->fmap;;
- const off_t min_offset = MIN(fmap->readwrite_a.rw_a_onestop.offset,
- fmap->readwrite_b.rw_b_onestop.offset);
- const off_t max_offset = MAX(fmap->readwrite_a.rw_a_onestop.offset,
- fmap->readwrite_b.rw_b_onestop.offset);
-
- cxt->start_block = CHROMEOS_RW_FIRMWARE_START_LBA;
- if (offset >= max_offset)
- cxt->start_block +=
+ /* TODO load starting LBA from fdt */
+ *start_block_ptr = CHROMEOS_RW_FIRMWARE_START_LBA;
+ if (section == SECTION_RW_B)
+ *start_block_ptr +=
(fmap->onestop_layout.onestop_layout.length >> 9);
- if (offset >= max_offset)
- cxt->offset_in_block = offset - max_offset;
- else
- cxt->offset_in_block = offset - min_offset;
+ *offset_in_block_ptr = offset - ((section == SECTION_RW_A) ?
+ fmap->readwrite_a.readwrite_a.offset :
+ fmap->readwrite_b.readwrite_b.offset);
- cxt->start_block += (cxt->offset_in_block >> 9);
- cxt->offset_in_block &= 0x1ff;
+ *start_block_ptr += (*offset_in_block_ptr >> 9);
+ *offset_in_block_ptr &= 0x1ff;
}
-static off_t seek_onestop(void *context, off_t offset, enum whence_t whence)
-{
- struct context *cxt = context;
- int section;
+static int read_mmc(struct mmc *mmc,
+ uint32_t start_block, uint32_t offset_in_block,
+ uint32_t offset, uint32_t count, void *buf);
+static int write_mmc(struct mmc *mmc,
+ uint32_t start_block, uint32_t offset_in_block,
+ uint32_t offset, uint32_t count, void *buf);
- VBDEBUG(PREFIX "seek(offset=%08x, whence=%d)\n", (int)offset, whence);
+static int read_onestop(struct firmware_storage_t *file,
+ uint32_t offset, uint32_t count, void *buf)
+{
+ struct context *cxt = file->context;
+ int section = get_section(cxt->fmap, offset);
+ uint32_t start_block = 0, offset_in_block = 0;
- /* TODO support other SEEK_* operation */
- if (whence != SEEK_SET) {
- VBDEBUG(PREFIX "only support SEEK_SET for now\n");
- return -1;
- }
+ VBDEBUG(PREFIX "read(offset=%08x, count=%08x, buffer=%p)\n",
+ offset, count, buf);
- section = get_section(cxt, offset);
- if (section < 0) {
- VBDEBUG(PREFIX "offset is not in any section\n");
+ if (section < 0)
return -1;
+ else if (section == SECTION_RO)
+ return cxt->spi_file.read(&cxt->spi_file, offset, count, buf);
+ else {
+ set_start_block_and_offset(cxt->fmap, section, offset,
+ &start_block, &offset_in_block);
+ return read_mmc(cxt->mmc, start_block, offset_in_block,
+ offset, count, buf);
}
+}
- cxt->section = section;
- if (cxt->section == SECTION_RO)
- return cxt->spi_file.seek(cxt->spi_file.context, offset, whence);
-
- set_block_lba(cxt, offset);
+static int write_onestop(struct firmware_storage_t *file,
+ uint32_t offset, uint32_t count, void *buf)
+{
+ struct context *cxt = file->context;
+ int section = get_section(cxt->fmap, offset);
+ uint32_t start_block = 0, offset_in_block = 0;
- VBDEBUG(PREFIX "seek: section = %d, block = %08llx, offset = %08x\n",
- cxt->section,
- (uint64_t)cxt->start_block,
- (int)cxt->offset_in_block);
+ VBDEBUG(PREFIX "write(offset=%08x, count=%08x, buffer=%p)\n",
+ offset, count, buf);
- return cxt->offset_in_block;
+ if (section < 0)
+ return -1;
+ else if (section == SECTION_RO)
+ return cxt->spi_file.write(&cxt->spi_file, offset, count, buf);
+ else {
+ set_start_block_and_offset(cxt->fmap, section, offset,
+ &start_block, &offset_in_block);
+ return write_mmc(cxt->mmc, start_block, offset_in_block,
+ offset, count, buf);
+ }
}
-static ssize_t read_onestop(void *context, void *buf, size_t count)
+static int read_mmc(struct mmc *mmc,
+ uint32_t start_block, uint32_t offset_in_block,
+ uint32_t offset, uint32_t count, void *buf)
{
- struct context *cxt = context;
uint32_t n_block;
- size_t n_byte_read;
+ size_t n_byte;
uint8_t *residual;
- VBDEBUG(PREFIX "read(count=%08x, buffer=%p)\n", (int)count, buf);
-
- if (cxt->section == SECTION_RO)
- return cxt->spi_file.read(cxt->spi_file.context, buf, count);
-
residual = memalign(CACHE_LINE_SIZE, 512);
- n_byte_read = 0;
+ n_byte = 0;
- if (cxt->offset_in_block) {
- n_byte_read = MIN(512 - cxt->offset_in_block, count);
- cxt->mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
- cxt->start_block, 1, residual);
- memcpy(buf, residual + cxt->offset_in_block, n_byte_read);
+ if (offset_in_block) {
+ n_byte = MIN(512 - offset_in_block, count);
+ mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
+ start_block, 1, residual);
+ memcpy(buf, residual + offset_in_block, n_byte);
}
- cxt->offset_in_block += n_byte_read;
- if (cxt->offset_in_block == 512) {
- cxt->start_block++;
- cxt->offset_in_block = 0;
+ offset_in_block += n_byte;
+ if (offset_in_block == 512) {
+ start_block++;
+ offset_in_block = 0;
}
- while (count > n_byte_read && (n_block = (count - n_byte_read) >> 9)) {
- n_block = cxt->mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
- cxt->start_block, n_block, buf + n_byte_read);
- cxt->start_block += n_block;
- n_byte_read += (n_block << 9);
+ while (count > n_byte && (n_block = (count - n_byte) >> 9)) {
+ n_block = mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
+ start_block, n_block, buf + n_byte);
+ start_block += n_block;
+ n_byte += (n_block << 9);
}
- if (count > n_byte_read) {
- cxt->mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
- cxt->start_block, 1, residual);
- memcpy(buf + n_byte_read, residual, count - n_byte_read);
- cxt->offset_in_block = count - n_byte_read;
+ if (count > n_byte) {
+ mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
+ start_block, 1, residual);
+ memcpy(buf + n_byte, residual, count - n_byte);
+ offset_in_block = count - n_byte;
}
free(residual);
- return count;
+ return 0;
}
-static ssize_t write_onestop(void *context, const void *buf, size_t count)
+static int write_mmc(struct mmc *mmc,
+ uint32_t start_block, uint32_t offset_in_block,
+ uint32_t offset, uint32_t count, void *buf)
{
- struct context *cxt = context;
uint32_t n_block;
- size_t n_byte_write;
+ size_t n_byte;
uint8_t *residual;
- VBDEBUG(PREFIX "write(count=%08x, buffer=%p)\n", (int)count, buf);
-
- if (cxt->section == SECTION_RO)
- return cxt->spi_file.write(cxt->spi_file.context, buf, count);
-
residual = memalign(CACHE_LINE_SIZE, 512);
- n_byte_write = 0;
-
- if (cxt->offset_in_block) {
- n_byte_write = MIN(512 - cxt->offset_in_block, count);
- cxt->mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
- cxt->start_block, 1, residual);
- memcpy(residual + cxt->offset_in_block, buf, n_byte_write);
- cxt->mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
- cxt->start_block, 1, residual);
+ n_byte = 0;
+
+ if (offset_in_block) {
+ n_byte = MIN(512 - offset_in_block, count);
+ mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
+ start_block, 1, residual);
+ memcpy(residual + offset_in_block, buf, n_byte);
+ mmc->block_dev.block_write(MMC_INTERNAL_DEVICE,
+ start_block, 1, residual);
}
- cxt->offset_in_block += n_byte_write;
- if (cxt->offset_in_block == 512) {
- cxt->start_block++;
- cxt->offset_in_block = 0;
+ offset_in_block += n_byte;
+ if (offset_in_block == 512) {
+ start_block++;
+ offset_in_block = 0;
}
- while (count > n_byte_write && (n_block = (count - n_byte_write) >> 9)) {
- n_block = cxt->mmc->block_dev.block_write(MMC_INTERNAL_DEVICE,
- cxt->start_block, n_block, buf + n_byte_write);
- cxt->start_block += n_block;
- n_byte_write += (n_block << 9);
+ while (count > n_byte && (n_block = (count - n_byte) >> 9)) {
+ n_block = mmc->block_dev.block_write(MMC_INTERNAL_DEVICE,
+ start_block, n_block, buf + n_byte);
+ start_block += n_block;
+ n_byte += (n_block << 9);
}
- if (count > n_byte_write) {
- cxt->mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
- cxt->start_block, 1, residual);
- memcpy(residual, buf + n_byte_write, count - n_byte_write);
- cxt->mmc->block_dev.block_write(MMC_INTERNAL_DEVICE,
- cxt->start_block, 1, residual);
- cxt->offset_in_block = count - n_byte_write;
+ if (count > n_byte) {
+ mmc->block_dev.block_read(MMC_INTERNAL_DEVICE,
+ start_block, 1, residual);
+ memcpy(residual, buf + n_byte, count - n_byte);
+ mmc->block_dev.block_write(MMC_INTERNAL_DEVICE,
+ start_block, 1, residual);
+ offset_in_block = count - n_byte;
}
free(residual);
- return count;
+ return 0;
}
-static int close_onestop(void *context)
+static int close_onestop(firmware_storage_t *file)
{
- struct context *cxt = context;
+ struct context *cxt = file->context;
int ret;
ret = cxt->spi_file.close(cxt->spi_file.context);
@@ -213,12 +215,6 @@ static int close_onestop(void *context)
return ret;
}
-static int lock_onestop(void *context)
-{
- /* TODO Implement lock device */
- return 0;
-}
-
int firmware_storage_open_onestop(firmware_storage_t *file,
struct fdt_twostop_fmap *fmap)
{
@@ -243,15 +239,10 @@ int firmware_storage_open_onestop(firmware_storage_t *file,
}
mmc_init(cxt->mmc);
- cxt->start_block = 0;
- cxt->offset_in_block = 0;
-
- file->seek = seek_onestop;
file->read = read_onestop;
file->write = write_onestop;
file->close = close_onestop;
- file->lock_device = lock_onestop;
- file->context = (void*) cxt;
+ file->context = (void *)cxt;
return 0;
}
diff --git a/lib/chromeos/firmware_storage_spi.c b/lib/chromeos/firmware_storage_spi.c
index 7102bb72195..26e01046db3 100644
--- a/lib/chromeos/firmware_storage_spi.c
+++ b/lib/chromeos/firmware_storage_spi.c
@@ -25,76 +25,42 @@
# define CONFIG_SF_DEFAULT_MODE SPI_MODE_3
#endif
-struct context_t {
- struct spi_flash *flash;
- u32 offset;
-};
-
-static off_t seek_spi(void *context, off_t offset, enum whence_t whence)
-{
- struct context_t *cxt = context;
- u32 next_offset;
-
- if (whence == SEEK_SET)
- next_offset = offset;
- else if (whence == SEEK_CUR)
- next_offset = cxt->offset + offset;
- else if (whence == SEEK_END)
- next_offset = cxt->flash->size + offset;
- else {
- VBDEBUG(PREFIX "unknown whence value: %d\n", whence);
- return -1;
- }
-
- if (next_offset < 0) {
- VBDEBUG(PREFIX "negative offset: %d\n", next_offset);
- return -1;
- }
-
- if (next_offset > cxt->flash->size) {
- VBDEBUG(PREFIX "offset overflow: 0x%08x > 0x%08x\n",
- next_offset, cxt->flash->size);
- return -1;
- }
-
- cxt->offset = next_offset;
- return cxt->offset;
-}
-
/*
* Check the right-exclusive range [offset:offset+*count_ptr), and adjust
* value pointed by <count_ptr> to form a valid range when needed.
*
* Return 0 if it is possible to form a valid range. and non-zero if not.
*/
-static int border_check(struct spi_flash *flash, u32 offset,
- size_t *count_ptr)
+static int border_check(struct spi_flash *flash, uint32_t offset,
+ uint32_t count)
{
if (offset >= flash->size) {
VBDEBUG(PREFIX "at EOF\n");
return -1;
}
- if (offset + *count_ptr > flash->size)
- *count_ptr = flash->size - offset;
+ if (offset + count > flash->size) {
+ VBDEBUG(PREFIX "exceed range\n");
+ return -1;
+ }
return 0;
}
-static ssize_t read_spi(void *context, void *buf, size_t count)
+static int read_spi(firmware_storage_t *file, uint32_t offset, uint32_t count,
+ void *buf)
{
- struct context_t *cxt = context;
+ struct spi_flash *flash = file->context;
- if (border_check(cxt->flash, cxt->offset, &count))
+ if (border_check(flash, offset, count))
return -1;
- if (cxt->flash->read(cxt->flash, cxt->offset, count, buf)) {
+ if (flash->read(flash, offset, count, buf)) {
VBDEBUG(PREFIX "SPI read fail\n");
return -1;
}
- cxt->offset += count;
- return count;
+ return 0;
}
/*
@@ -111,7 +77,7 @@ static ssize_t read_spi(void *context, void *buf, size_t count)
* After alignment adjustment, both offset and length will be multiple of
* SECTOR_SIZE, and will be larger than or equal to the original range.
*/
-static void align_to_sector(size_t *offset_ptr, size_t *length_ptr)
+static void align_to_sector(uint32_t *offset_ptr, uint32_t *length_ptr)
{
VBDEBUG(PREFIX "before adjustment\n");
VBDEBUG(PREFIX "offset: 0x%x\n", *offset_ptr);
@@ -133,55 +99,51 @@ static void align_to_sector(size_t *offset_ptr, size_t *length_ptr)
VBDEBUG(PREFIX "length: 0x%x\n", *length_ptr);
}
-static ssize_t write_spi(void *context, const void *buf, size_t count)
+static int write_spi(firmware_storage_t *file, uint32_t offset, uint32_t count,
+ void *buf)
{
- struct context_t *cxt = context;
- struct spi_flash *flash = cxt->flash;
+ struct spi_flash *flash = file->context;
uint8_t static_buf[SECTOR_SIZE];
uint8_t *backup_buf;
- ssize_t ret = -1;
- size_t offset, length, tmp;
- int status;
-
- /* We will erase <length> bytes starting from <offset> */
- offset = cxt->offset;
- length = count;
- align_to_sector(&offset, &length);
-
- tmp = length;
- if (border_check(flash, offset, &tmp))
- return -1;
- if (tmp != length) {
- VBDEBUG(PREFIX "cannot erase range [%08x:%08x]: %08x\n",
- offset, offset + length, offset + tmp);
+ uint32_t k, n;
+ int status, ret = -1;
+
+ /* We will erase <n> bytes starting from <k> */
+ k = offset;
+ n = count;
+ align_to_sector(&k, &n);
+
+ VBDEBUG(PREFIX "offset: 0x%08x\n", offset);
+ VBDEBUG(PREFIX "adjusted offset: 0x%08x\n", k);
+ if (k > offset) {
+ VBDEBUG(PREFIX "align incorrect: %08x > %08x\n", k, offset);
return -1;
}
- backup_buf = length > sizeof(static_buf) ? malloc(length) : static_buf;
+ if (border_check(flash, k, n))
+ return -1;
+
+ backup_buf = n > sizeof(static_buf) ? malloc(n) : static_buf;
- if ((status = flash->read(flash, offset, length, backup_buf))) {
+ if ((status = flash->read(flash, k, n, backup_buf))) {
VBDEBUG(PREFIX "cannot backup data: %d\n", status);
goto EXIT;
}
- if ((status = flash->erase(flash, offset, length))) {
+ if ((status = flash->erase(flash, k, n))) {
VBDEBUG(PREFIX "SPI erase fail: %d\n", status);
goto EXIT;
}
- VBDEBUG(PREFIX "cxt->offset: 0x%08x\n", cxt->offset);
- VBDEBUG(PREFIX "offset: 0x%08x\n", offset);
-
/* combine data we want to write and backup data */
- memcpy(backup_buf + (cxt->offset - offset), buf, count);
+ memcpy(backup_buf + (offset - k), buf, count);
- if (flash->write(flash, offset, length, backup_buf)) {
+ if (flash->write(flash, k, n, backup_buf)) {
VBDEBUG(PREFIX "SPI write fail\n");
goto EXIT;
}
- cxt->offset += count;
- ret = count;
+ ret = 0;
EXIT:
if (backup_buf != static_buf)
@@ -190,19 +152,10 @@ EXIT:
return ret;
}
-static int close_spi(void *context)
+static int close_spi(firmware_storage_t *file)
{
- struct context_t *cxt = context;
-
- spi_flash_free(cxt->flash);
- free(cxt);
-
- return 0;
-}
-
-static int lock_spi(void *context)
-{
- /* TODO Implement lock device */
+ struct spi_flash *flash = file->context;
+ spi_flash_free(flash);
return 0;
}
@@ -212,23 +165,17 @@ int firmware_storage_open_spi(firmware_storage_t *file)
const unsigned int cs = 0;
const unsigned int max_hz = CONFIG_SF_DEFAULT_SPEED;
const unsigned int spi_mode = CONFIG_SF_DEFAULT_MODE;
- struct context_t *cxt;
+ struct spi_flash *flash;
- cxt = malloc(sizeof(*cxt));
- cxt->offset = 0;
- cxt->flash = spi_flash_probe(bus, cs, max_hz, spi_mode);
- if (!cxt->flash) {
+ if (!(flash = spi_flash_probe(bus, cs, max_hz, spi_mode))) {
VBDEBUG(PREFIX "fail to init SPI flash at %u:%u\n", bus, cs);
- free(cxt);
return -1;
}
- file->seek = seek_spi;
file->read = read_spi;
file->write = write_spi;
file->close = close_spi;
- file->lock_device = lock_spi;
- file->context = (void*) cxt;
+ file->context = (void *)flash;
return 0;
}
diff --git a/lib/chromeos/onestop.c b/lib/chromeos/onestop.c
index d5e7a2277fd..41274ca35bc 100644
--- a/lib/chromeos/onestop.c
+++ b/lib/chromeos/onestop.c
@@ -47,8 +47,8 @@ int GetFirmwareBody(LoadFirmwareParams *params, uint64_t index)
return 1;
}
- if (firmware_storage_read(s->file, s->fwinfo[i].offset,
- s->fwinfo[i].size, s->fwinfo[i].fwbody)) {
+ if (s->file->read(s->file, s->fwinfo[i].offset, s->fwinfo[i].size,
+ s->fwinfo[i].fwbody)) {
VBDEBUG(PREFIX "fail to read firmware body: %d\n", i);
return 1;
}
@@ -89,7 +89,7 @@ uint32_t boot_rw_firmware(firmware_storage_t *file,
internal.fwinfo[1].fwbody = memalign(CACHE_LINE_SIZE,
fmap->onestop_layout.fwbody.length);
- if (firmware_storage_read(file,
+ if (file->read(file,
fmap->readwrite_a.rw_a_onestop.offset +
fmap->onestop_layout.vblock.offset,
fmap->onestop_layout.vblock.length,
@@ -97,7 +97,7 @@ uint32_t boot_rw_firmware(firmware_storage_t *file,
VBDEBUG(PREFIX "fail to read vblock A\n");
return VBNV_RECOVERY_RO_INVALID_RW;
}
- if (firmware_storage_read(file,
+ if (file->read(file,
fmap->readwrite_b.rw_b_onestop.offset +
fmap->onestop_layout.vblock.offset,
fmap->onestop_layout.vblock.length,
diff --git a/lib/vbexport/load_firmware.c b/lib/vbexport/load_firmware.c
index bf39c661e46..748a3e8e699 100644
--- a/lib/vbexport/load_firmware.c
+++ b/lib/vbexport/load_firmware.c
@@ -17,9 +17,6 @@
#define PREFIX "load_firmware: "
-/* Amount of bytes we read each time we call read() */
-#define BLOCK_SIZE 512
-
VbError_t VbExHashFirmwareBody(VbCommonParams* cparams,
uint32_t firmware_index)
{
@@ -27,8 +24,6 @@ VbError_t VbExHashFirmwareBody(VbCommonParams* cparams,
firmware_storage_t *file = cache->file;
firmware_info_t *info;
int index;
- uint8_t *buffer;
- size_t leftover, n, got_n;
if (firmware_index != VB_SELECT_FIRMWARE_A &&
firmware_index != VB_SELECT_FIRMWARE_B) {
@@ -39,33 +34,13 @@ VbError_t VbExHashFirmwareBody(VbCommonParams* cparams,
index = (firmware_index == VB_SELECT_FIRMWARE_A ? 0 : 1);
info = &cache->infos[index];
- buffer = info->buffer;
- if (file->seek(file->context, info->offset, SEEK_SET)
- < 0) {
- VbExDebug(PREFIX "seek to firmware data failed\n");
+ if (file->read(file, info->offset, info->size, info->buffer)) {
+ VbExDebug(PREFIX "fail to read firmware body: %d\n", index);
return 1;
}
- /*
- * This loop feeds firmware body into VbUpdateFirmwareBodyHash.
- * Variable leftover keeps the remaining number of bytes.
- */
- for (leftover = info->size; leftover > 0; leftover -= n, buffer += n) {
- n = min(BLOCK_SIZE, leftover);
- got_n = file->read(file->context, buffer, n);
- if (got_n != n) {
- VbExDebug(PREFIX "an error has occured "
- "while reading firmware: %d\n", n);
- return 1;
- }
-
- /*
- * See vboot_reference/firmware/include/vboot_api.h for
- * documentation of this function.
- */
- VbUpdateFirmwareBodyHash(cparams, buffer, n);
- }
+ VbUpdateFirmwareBodyHash(cparams, info->buffer, info->size);
return 0;
}
diff --git a/lib/vboot/bootstub_entry.c b/lib/vboot/bootstub_entry.c
index 94ab1a7f095..a420d7353a7 100644
--- a/lib/vboot/bootstub_entry.c
+++ b/lib/vboot/bootstub_entry.c
@@ -50,14 +50,14 @@ static int read_verification_block(firmware_storage_t *file,
void *vblock;
/* read key block header */
- if (firmware_storage_read(file, vblock_offset, sizeof(kbh), &kbh)) {
+ if (file->read(file, vblock_offset, sizeof(kbh), &kbh)) {
VbExDebug(PREFIX "Failed to read key block!\n");
return -1;
}
key_block_size = kbh.key_block_size;
/* read firmware preamble header */
- if (firmware_storage_read(file, vblock_offset + key_block_size,
+ if (file->read(file, vblock_offset + key_block_size,
sizeof(fph), &fph)) {
VbExDebug(PREFIX "Failed to read preamble!\n");
return -1;
@@ -66,7 +66,7 @@ static int read_verification_block(firmware_storage_t *file,
vblock = VbExMalloc(vblock_size);
- if (firmware_storage_read(file, vblock_offset, vblock_size, vblock)) {
+ if (file->read(file, vblock_offset, vblock_size, vblock)) {
VbExDebug(PREFIX "Failed to read verification block!\n");
VbExFree(vblock);
return -1;
@@ -237,7 +237,7 @@ void bootstub_entry(void)
* The above VbSelectFirmware still needs firmware storage file.
* So don't close until here.
*/
- if (firmware_storage_close(&file))
+ if (file.close(&file))
VbExError(PREFIX "Failed to close firmware device!\n");
/* Handle the VbSelectFirmware() results */
diff --git a/lib/vboot/global_data.c b/lib/vboot/global_data.c
index 97407d5c3d5..63fd7ba0bf0 100644
--- a/lib/vboot/global_data.c
+++ b/lib/vboot/global_data.c
@@ -41,7 +41,7 @@ int init_vboot_global(vb_global_t *global, firmware_storage_t *file)
/* Load GBB from SPI */
global->gbb_size = CONFIG_LENGTH_GBB;
- if (firmware_storage_read(file, CONFIG_OFFSET_GBB,
+ if (file->read(file, CONFIG_OFFSET_GBB,
CONFIG_LENGTH_GBB, global->gbb_data)) {
VbExDebug(PREFIX "Failed to read GBB!\n");
return 1;
@@ -62,7 +62,7 @@ int init_vboot_global(vb_global_t *global, firmware_storage_t *file)
developer_sw = is_developer_mode_gpio_asserted(
polarity_developer_sw);
- if (firmware_storage_read(file, CONFIG_OFFSET_RO_FRID,
+ if (file->read(file, CONFIG_OFFSET_RO_FRID,
CONFIG_LENGTH_RO_FRID, frid)) {
VbExDebug(PREFIX "Failed to read frid!\n");
return 1;