diff options
-rw-r--r-- | core/flash.c | 9 | ||||
-rw-r--r-- | external/gard/gard.c | 11 | ||||
-rw-r--r-- | libflash/blocklevel.c | 24 | ||||
-rw-r--r-- | libflash/blocklevel.h | 22 | ||||
-rw-r--r-- | libflash/ecc.c | 15 | ||||
-rw-r--r-- | libflash/ecc.h | 12 | ||||
-rw-r--r-- | libflash/file.c | 14 | ||||
-rw-r--r-- | libflash/libffs.c | 4 | ||||
-rw-r--r-- | libflash/libflash.c | 14 | ||||
-rw-r--r-- | libflash/test/test-blocklevel.c | 4 | ||||
-rw-r--r-- | libflash/test/test-flash.c | 3 | ||||
-rw-r--r-- | platforms/mambo/mambo.c | 12 |
12 files changed, 81 insertions, 63 deletions
diff --git a/core/flash.c b/core/flash.c index e9c1f7d1..da435a0f 100644 --- a/core/flash.c +++ b/core/flash.c @@ -29,7 +29,7 @@ struct flash { struct list_node list; bool busy; struct blocklevel_device *bl; - uint32_t size; + uint64_t size; uint32_t block_size; int id; }; @@ -192,7 +192,7 @@ static struct dt_node *flash_add_dt_node(struct flash *flash, int id) flash_node = dt_new_addr(opal_node, "flash", id); dt_add_property_strings(flash_node, "compatible", "ibm,opal-flash"); dt_add_property_cells(flash_node, "ibm,opal-id", id); - dt_add_property_cells(flash_node, "reg", 0, flash->size); + dt_add_property_u64(flash_node, "reg", flash->size); dt_add_property_cells(flash_node, "ibm,flash-block-size", flash->block_size); @@ -256,7 +256,8 @@ static int num_flashes(void) int flash_register(struct blocklevel_device *bl, bool is_system_flash) { - uint32_t size, block_size; + uint64_t size; + uint32_t block_size; struct ffs_handle *ffs; struct dt_node *node; struct flash *flash; @@ -268,7 +269,7 @@ int flash_register(struct blocklevel_device *bl, bool is_system_flash) return rc; prlog(PR_INFO, "FLASH: registering flash device %s " - "(size 0x%x, blocksize 0x%x)\n", + "(size 0x%llx, blocksize 0x%x)\n", name ?: "(unnamed)", size, block_size); lock(&flash_lock); diff --git a/external/gard/gard.c b/external/gard/gard.c index 9da7496f..7ec52d80 100644 --- a/external/gard/gard.c +++ b/external/gard/gard.c @@ -575,6 +575,7 @@ int main(int argc, char **argv) const char *action, *progname; char *filename = NULL; struct gard_ctx _ctx, *ctx; + uint64_t bl_size; int rc, i = 0; bool part = 0; bool ecc = 0; @@ -643,10 +644,18 @@ int main(int argc, char **argv) goto out_free; } - rc = blocklevel_get_info(ctx->bl, NULL, &(ctx->f_size), NULL); + rc = blocklevel_get_info(ctx->bl, NULL, &bl_size, NULL); if (rc) goto out; + if (bl_size > UINT_MAX) { + fprintf(stderr, "MTD device bigger than %i: size:%lu\n", + UINT_MAX, bl_size); + rc = EXIT_FAILURE; + goto out; + } + ctx->f_size = bl_size; + if (!part) { rc = ffs_init(0, ctx->f_size, ctx->bl, &ctx->ffs, 1); if (rc) diff --git a/libflash/blocklevel.c b/libflash/blocklevel.c index 95911941..9f02ee11 100644 --- a/libflash/blocklevel.c +++ b/libflash/blocklevel.c @@ -20,6 +20,7 @@ #include <stdbool.h> #include <errno.h> #include <string.h> +#include <inttypes.h> #include <libflash/errors.h> @@ -33,7 +34,7 @@ * 0 - The region is not ECC protected * -1 - Partially protected */ -static int ecc_protected(struct blocklevel_device *bl, uint32_t pos, uint32_t len) +static int ecc_protected(struct blocklevel_device *bl, uint64_t pos, uint64_t len) { int i; @@ -77,11 +78,11 @@ static int release(struct blocklevel_device *bl) return rc; } -int blocklevel_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len) +int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len) { int rc; struct ecc64 *buffer; - uint32_t ecc_len = ecc_buffer_size(len); + uint64_t ecc_len = ecc_buffer_size(len); if (!bl || !bl->read || !buf) { errno = EINVAL; @@ -120,11 +121,11 @@ out: return rc; } -int blocklevel_write(struct blocklevel_device *bl, uint32_t pos, const void *buf, uint32_t len) +int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len) { int rc; struct ecc64 *buffer; - uint32_t ecc_len = ecc_buffer_size(len); + uint64_t ecc_len = ecc_buffer_size(len); if (!bl || !bl->write || !buf) { errno = EINVAL; @@ -162,7 +163,7 @@ out: return rc; } -int blocklevel_erase(struct blocklevel_device *bl, uint32_t pos, uint32_t len) +int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len) { int rc; if (!bl || !bl->erase) { @@ -172,7 +173,7 @@ int blocklevel_erase(struct blocklevel_device *bl, uint32_t pos, uint32_t len) /* Programmer may be making a horrible mistake without knowing it */ if (len & bl->erase_mask) { - fprintf(stderr, "blocklevel_erase: len (0x%08x) is not erase block (0x%08x) aligned\n", + fprintf(stderr, "blocklevel_erase: len (0x%"PRIu64") is not erase block (0x%08x) aligned\n", len, bl->erase_mask + 1); return FLASH_ERR_ERASE_BOUNDARY; } @@ -188,7 +189,7 @@ int blocklevel_erase(struct blocklevel_device *bl, uint32_t pos, uint32_t len) return rc; } -int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint32_t *total_size, +int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_t *total_size, uint32_t *erase_granule) { int rc; @@ -224,9 +225,10 @@ int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint32_ * returns 0 for b * returns 1 for c */ -static int blocklevel_flashcmp(const void *flash_buf, const void *mem_buf, uint32_t len) +static int blocklevel_flashcmp(const void *flash_buf, const void *mem_buf, uint64_t len) { - int i, same = true; + uint64_t i; + int same = true; const uint8_t *f_buf, *m_buf; f_buf = flash_buf; @@ -242,7 +244,7 @@ static int blocklevel_flashcmp(const void *flash_buf, const void *mem_buf, uint3 return same ? 0 : 1; } -int blocklevel_smart_write(struct blocklevel_device *bl, uint32_t pos, const void *buf, uint32_t len) +int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len) { uint32_t erase_size; const void *write_buf = buf; diff --git a/libflash/blocklevel.h b/libflash/blocklevel.h index e9eb32a6..ddec1dd9 100644 --- a/libflash/blocklevel.h +++ b/libflash/blocklevel.h @@ -20,8 +20,8 @@ #include <stdbool.h> struct bl_prot_range { - uint32_t start; - uint32_t len; + uint64_t start; + uint64_t len; }; struct blocklevel_range { @@ -42,10 +42,10 @@ struct blocklevel_device { void *priv; int (*reacquire)(struct blocklevel_device *bl); int (*release)(struct blocklevel_device *bl); - int (*read)(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len); - int (*write)(struct blocklevel_device *bl, uint32_t pos, const void *buf, uint32_t len); - int (*erase)(struct blocklevel_device *bl, uint32_t pos, uint32_t len); - int (*get_info)(struct blocklevel_device *bl, const char **name, uint32_t *total_size, + int (*read)(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len); + int (*write)(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len); + int (*erase)(struct blocklevel_device *bl, uint64_t pos, uint64_t len); + int (*get_info)(struct blocklevel_device *bl, const char **name, uint64_t *total_size, uint32_t *erase_granule); /* @@ -58,10 +58,10 @@ struct blocklevel_device { struct blocklevel_range ecc_prot; }; -int blocklevel_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len); -int blocklevel_write(struct blocklevel_device *bl, uint32_t pos, const void *buf, uint32_t len); -int blocklevel_erase(struct blocklevel_device *bl, uint32_t pos, uint32_t len); -int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint32_t *total_size, +int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len); +int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len); +int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len); +int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_t *total_size, uint32_t *erase_granule); /* @@ -72,7 +72,7 @@ int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint32_ * or slower than the just using blocklevel_erase/write calls. * directly. */ -int blocklevel_smart_write(struct blocklevel_device *bl, uint32_t pos, const void *buf, uint32_t len); +int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len); /* Implemented in software at this level */ int blocklevel_ecc_protect(struct blocklevel_device *bl, uint32_t start, uint32_t len); diff --git a/libflash/ecc.c b/libflash/ecc.c index 9cd6ad20..0be80b1f 100644 --- a/libflash/ecc.c +++ b/libflash/ecc.c @@ -17,6 +17,7 @@ /* This is based on the hostboot ecc code */ #include <stdint.h> +#include <inttypes.h> #include <ccan/endian/endian.h> @@ -181,7 +182,7 @@ static inline uint64_t eccflipbit(uint64_t data, uint8_t bit) * @retval: 0 - success * @retfal: other - fail */ -int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint32_t len) +int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint64_t len) { beint64_t data; uint8_t ecc; @@ -190,8 +191,8 @@ int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint32_t len) if (len & 0x7) { /* TODO: we could probably handle this */ - FL_ERR("ECC data length must be 8 byte aligned length:%i\n", - len); + FL_ERR("ECC data length must be 8 byte aligned length:%" PRIx64 "\n", + len); return -1; } @@ -232,15 +233,15 @@ int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint32_t len) * @retval: 0 - success * @retfal: other - fail */ -int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint32_t len) +int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint64_t len) { struct ecc64 ecc_word; - uint32_t i; + uint64_t i; if (len & 0x7) { /* TODO: we could probably handle this */ - FL_ERR("Data to add ECC bytes to must be 8 byte aligned length: %i\n", - len); + FL_ERR("Data to add ECC bytes to must be 8 byte aligned length: %" + PRIx64 "\n", len); return -1; } diff --git a/libflash/ecc.h b/libflash/ecc.h index 1e147243..804b3522 100644 --- a/libflash/ecc.h +++ b/libflash/ecc.h @@ -27,9 +27,9 @@ struct ecc64 { uint8_t ecc; } __attribute__((__packed__)); -extern int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint32_t len); +extern int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint64_t len); -extern int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint32_t len); +extern int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint64_t len); /* * Calculate the size of a buffer if ECC is added @@ -43,22 +43,22 @@ extern int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint32_t len); #define BYTES_PER_ECC 8 -static inline uint32_t ecc_size(uint32_t len) +static inline uint64_t ecc_size(uint64_t len) { return ALIGN_UP(len, BYTES_PER_ECC) >> 3; } -static inline uint32_t ecc_buffer_size(uint32_t len) +static inline uint64_t ecc_buffer_size(uint64_t len) { return ALIGN_UP(len, BYTES_PER_ECC) + ecc_size(len); } -static inline int ecc_buffer_size_check(uint32_t len) +static inline int ecc_buffer_size_check(uint64_t len) { return len % (BYTES_PER_ECC + 1); } -static inline uint32_t ecc_buffer_size_minus_ecc(uint32_t len) +static inline uint64_t ecc_buffer_size_minus_ecc(uint64_t len) { return len * BYTES_PER_ECC / (BYTES_PER_ECC + 1); } diff --git a/libflash/file.c b/libflash/file.c index 478bc132..946726c2 100644 --- a/libflash/file.c +++ b/libflash/file.c @@ -59,7 +59,7 @@ static int file_reacquire(struct blocklevel_device *bl) return 0; } -static int file_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len) +static int file_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len) { struct file_data *file_data = container_of(bl, struct file_data, bl); int rc, count = 0; @@ -81,8 +81,8 @@ static int file_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint return 0; } -static int file_write(struct blocklevel_device *bl, uint32_t dst, const void *src, - uint32_t len) +static int file_write(struct blocklevel_device *bl, uint64_t dst, const void *src, + uint64_t len) { struct file_data *file_data = container_of(bl, struct file_data, bl); int rc, count = 0; @@ -111,7 +111,7 @@ static int file_write(struct blocklevel_device *bl, uint32_t dst, const void *sr * Also, erasing flash leaves all the bits set to 1. This may be expected * by higher level functions so this function should also emulate that */ -static int file_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t len) +static int file_erase(struct blocklevel_device *bl, uint64_t dst, uint64_t len) { unsigned long long int d = ULLONG_MAX; int i = 0; @@ -127,7 +127,7 @@ static int file_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t len) return 0; } -static int mtd_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t len) +static int mtd_erase(struct blocklevel_device *bl, uint64_t dst, uint64_t len) { struct file_data *file_data = container_of(bl, struct file_data, bl); struct erase_info_user erase_info = { @@ -177,7 +177,7 @@ static int get_info_name(struct file_data *file_data, char **name) static int mtd_get_info(struct blocklevel_device *bl, const char **name, - uint32_t *total_size, uint32_t *erase_granule) + uint64_t *total_size, uint32_t *erase_granule) { struct file_data *file_data = container_of(bl, struct file_data, bl); struct mtd_info_user mtd_info; @@ -204,7 +204,7 @@ static int mtd_get_info(struct blocklevel_device *bl, const char **name, } static int file_get_info(struct blocklevel_device *bl, const char **name, - uint32_t *total_size, uint32_t *erase_granule) + uint64_t *total_size, uint32_t *erase_granule) { struct file_data *file_data = container_of(bl, struct file_data, bl); struct stat st; diff --git a/libflash/libffs.c b/libflash/libffs.c index 8134962c..65c3fbea 100644 --- a/libflash/libffs.c +++ b/libflash/libffs.c @@ -78,7 +78,7 @@ int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl, struct ffs_hdr hdr; struct ffs_hdr blank_hdr; struct ffs_handle *f; - uint32_t total_size; + uint64_t total_size; int rc, i; if (!ffs || !bl) @@ -90,6 +90,8 @@ int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl, FL_ERR("FFS: Error %d retrieving flash info\n", rc); return rc; } + if (total_size > UINT_MAX) + return FLASH_ERR_VERIFY_FAILURE; if ((offset + max_size) < offset) return FLASH_ERR_PARM_ERROR; diff --git a/libflash/libflash.c b/libflash/libflash.c index d3e594a1..cf679a55 100644 --- a/libflash/libflash.c +++ b/libflash/libflash.c @@ -16,6 +16,7 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <inttypes.h> #include "libflash.h" #include "libflash-priv.h" @@ -124,7 +125,7 @@ int fl_wren(struct spi_flash_ctrl *ct) return FLASH_ERR_WREN_TIMEOUT; } -static int flash_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len) +static int flash_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len) { struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; @@ -228,7 +229,7 @@ static void fl_get_best_erase(struct flash_chip *c, uint32_t dst, uint32_t size, *cmd = CMD_BE; } -static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t size) +static int flash_erase(struct blocklevel_device *bl, uint64_t dst, uint64_t size) { struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; @@ -244,7 +245,8 @@ static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t size if ((dst | size) & c->min_erase_mask) return FLASH_ERR_ERASE_BOUNDARY; - FL_DBG("LIBFLASH: Erasing 0x%08x..0%08x...\n", dst, dst + size); + FL_DBG("LIBFLASH: Erasing 0x%" PRIx64"..0%" PRIx64 "...\n", + dst, dst + size); /* Use controller erase if supported */ if (ct->erase) @@ -479,7 +481,7 @@ static enum sm_comp_res flash_smart_comp(struct flash_chip *c, return is_same ? sm_no_change : sm_need_write; } -static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size) +static int flash_smart_write(struct blocklevel_device *bl, uint64_t dst, const void *src, uint64_t size) { struct flash_chip *c = container_of(bl, struct flash_chip, bl); uint32_t er_size = c->min_erase_mask + 1; @@ -492,7 +494,7 @@ static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, const v return FLASH_ERR_PARM_ERROR; } - FL_DBG("LIBFLASH: Smart writing to 0x%08x..0%08x...\n", + FL_DBG("LIBFLASH: Smart writing to 0x%" PRIx64 "..0%" PRIx64 "...\n", dst, dst + size); /* As long as we have something to write ... */ @@ -792,7 +794,7 @@ static int flash_configure(struct flash_chip *c) } static int flash_get_info(struct blocklevel_device *bl, const char **name, - uint32_t *total_size, uint32_t *erase_granule) + uint64_t *total_size, uint32_t *erase_granule) { struct flash_chip *c = container_of(bl, struct flash_chip, bl); if (name) diff --git a/libflash/test/test-blocklevel.c b/libflash/test/test-blocklevel.c index ef5d9b5c..95669dc3 100644 --- a/libflash/test/test-blocklevel.c +++ b/libflash/test/test-blocklevel.c @@ -171,8 +171,8 @@ int main(void) for (i = 0; i < bl->ecc_prot.n_prot - 1; i++) { if (bl->ecc_prot.prot[i].start + bl->ecc_prot.prot[i].len == bl->ecc_prot.prot[i + 1].start || bl->ecc_prot.prot[i + 1].start + bl->ecc_prot.prot[i + 1].len == bl->ecc_prot.prot[i].start) { - ERR("Problem with protection range merge code, region starting at 0x%08x for 0x%08x appears " - "to touch region 0x%08x for 0x%08x\n", bl->ecc_prot.prot[i].start, bl->ecc_prot.prot[i].len, + ERR("Problem with protection range merge code, region starting at 0x%08lx for 0x%08lx appears " + "to touch region 0x%lx for 0x%lx\n", bl->ecc_prot.prot[i].start, bl->ecc_prot.prot[i].len, bl->ecc_prot.prot[i + 1].start, bl->ecc_prot.prot[i + 1].len); return 1; } diff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c index c93aef5d..3f77d6f3 100644 --- a/libflash/test/test-flash.c +++ b/libflash/test/test-flash.c @@ -367,7 +367,8 @@ struct spi_flash_ctrl sim_ctrl = { int main(void) { struct blocklevel_device *bl; - uint32_t total_size, erase_granule; + uint64_t total_size; + uint32_t erase_granule; const char *name; uint16_t *test; struct ecc64 *ecc_test; diff --git a/platforms/mambo/mambo.c b/platforms/mambo/mambo.c index 3c1d546a..066f7481 100644 --- a/platforms/mambo/mambo.c +++ b/platforms/mambo/mambo.c @@ -117,8 +117,8 @@ struct bogus_disk_info { int id; }; -static int bogus_disk_read(struct blocklevel_device *bl, uint32_t pos, void *buf, - uint32_t len) +static int bogus_disk_read(struct blocklevel_device *bl, uint64_t pos, void *buf, + uint64_t len) { struct bogus_disk_info *bdi = bl->priv; int rc; @@ -140,8 +140,8 @@ static int bogus_disk_read(struct blocklevel_device *bl, uint32_t pos, void *buf return rc; } -static int bogus_disk_write(struct blocklevel_device *bl, uint32_t pos, - const void *buf, uint32_t len) +static int bogus_disk_write(struct blocklevel_device *bl, uint64_t pos, + const void *buf, uint64_t len) { struct bogus_disk_info *bdi = bl->priv; @@ -154,13 +154,13 @@ static int bogus_disk_write(struct blocklevel_device *bl, uint32_t pos, } static int bogus_disk_erase(struct blocklevel_device *bl __unused, - uint32_t pos __unused, uint32_t len __unused) + uint64_t pos __unused, uint64_t len __unused) { return 0; /* NOP */ } static int bogus_disk_get_info(struct blocklevel_device *bl, const char **name, - uint32_t *total_size, uint32_t *erase_granule) + uint64_t *total_size, uint32_t *erase_granule) { struct bogus_disk_info *bdi = bl->priv; |