summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/flash.c9
-rw-r--r--external/gard/gard.c11
-rw-r--r--libflash/blocklevel.c24
-rw-r--r--libflash/blocklevel.h22
-rw-r--r--libflash/ecc.c15
-rw-r--r--libflash/ecc.h12
-rw-r--r--libflash/file.c14
-rw-r--r--libflash/libffs.c4
-rw-r--r--libflash/libflash.c14
-rw-r--r--libflash/test/test-blocklevel.c4
-rw-r--r--libflash/test/test-flash.c3
-rw-r--r--platforms/mambo/mambo.c12
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;
OpenPOWER on IntegriCloud