diff options
-rw-r--r-- | common/cmd_cros_onestop_firmware.c | 8 | ||||
-rw-r--r-- | common/cmd_vbexport_test.c | 2 | ||||
-rw-r--r-- | common/cmd_vboot_test.c | 14 | ||||
-rw-r--r-- | include/chromeos/firmware_storage.h | 61 | ||||
-rw-r--r-- | lib/chromeos/Makefile | 1 | ||||
-rw-r--r-- | lib/chromeos/firmware_storage.c | 95 | ||||
-rw-r--r-- | lib/chromeos/firmware_storage_onestop.c | 233 | ||||
-rw-r--r-- | lib/chromeos/firmware_storage_spi.c | 139 | ||||
-rw-r--r-- | lib/chromeos/onestop.c | 8 | ||||
-rw-r--r-- | lib/vbexport/load_firmware.c | 31 | ||||
-rw-r--r-- | lib/vboot/bootstub_entry.c | 8 | ||||
-rw-r--r-- | lib/vboot/global_data.c | 4 |
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; |