Message ID | 1431587199-15473-3-git-send-email-cyril.bur@au1.ibm.com |
---|---|
State | Changes Requested |
Headers | show |
This looks ok, my only concern is that changing flash_write -> flash_smart_write in pflash is likely to reduce pflash performance. Is there a way we could not make that change in pflash for the moment? I have an idea for how we could fix it properly, but that change would be easier to do if we had these patches applied. Signed-off-by: Alistair Popple <alistair@popple.id.au> Reviewed-by: Alistair Popple <alistair@popple.id.au> On Thu, 14 May 2015 17:06:39 Cyril Bur wrote: > Converted all the libflash calls to use the blocklevel interface, modified > all callers to libflash to use the blocklevel interface. > > This patch should introduce next to no functional change. > > Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com> > --- > core/flash.c | 35 ++++++++++--------- > external/pflash/Makefile | 2 +- > external/pflash/pflash.c | 33 +++++++++--------- > include/skiboot.h | 4 ++- > libflash/libffs.c | 52 ++++++++++++++--------------- > libflash/libffs.h | 7 ++-- > libflash/libflash.c | 83 > ++++++++++++++++++++++++++++------------------ libflash/libflash.h | > 25 +++++--------- > libflash/test/test-flash.c | 20 +++++------ > platforms/astbmc/pnor.c | 12 ++++--- > platforms/rhesus/rhesus.c | 11 +++--- > 11 files changed, 153 insertions(+), 131 deletions(-) > > diff --git a/core/flash.c b/core/flash.c > index 9018ecd..90dbac7 100644 > --- a/core/flash.c > +++ b/core/flash.c > @@ -22,12 +22,13 @@ > #include <device.h> > #include <libflash/libflash.h> > #include <libflash/libffs.h> > +#include <libflash/blocklevel.h> > #include <ecc.h> > > struct flash { > bool registered; > bool busy; > - struct flash_chip *chip; > + struct blocklevel_device *bl; > uint32_t size; > uint32_t block_size; > }; > @@ -108,7 +109,7 @@ static int flash_nvram_start_read(void *dst, uint32_t > src, uint32_t len) goto out; > } > > - rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len); > + rc = blocklevel_read(nvram_flash->bl, nvram_offset + src, dst, len); > > out: > unlock(&flash_lock); > @@ -137,7 +138,7 @@ static int flash_nvram_write(uint32_t dst, void *src, > uint32_t len) rc = OPAL_PARAMETER; > goto out; > } > - rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, len); > + rc = blocklevel_write(nvram_flash->bl, nvram_offset + dst, src, len); > > out: > unlock(&flash_lock); > @@ -250,7 +251,7 @@ static void setup_system_flash(struct flash *flash, > struct dt_node *node, flash_nvram_probe(flash, ffs); > } > > -int flash_register(struct flash_chip *chip, bool is_system_flash) > +int flash_register(struct blocklevel_device *bl, bool is_system_flash) > { > uint32_t size, block_size; > struct ffs_handle *ffs; > @@ -260,7 +261,7 @@ int flash_register(struct flash_chip *chip, bool > is_system_flash) unsigned int i; > int rc; > > - rc = flash_get_info(chip, &name, &size, &block_size); > + rc = blocklevel_get_info(bl, &name, &size, &block_size); > if (rc) > return rc; > > @@ -276,7 +277,7 @@ int flash_register(struct flash_chip *chip, bool > is_system_flash) flash = &flashes[i]; > flash->registered = true; > flash->busy = false; > - flash->chip = chip; > + flash->bl = bl; > flash->size = size; > flash->block_size = block_size; > break; > @@ -288,7 +289,7 @@ int flash_register(struct flash_chip *chip, bool > is_system_flash) return OPAL_RESOURCE; > } > > - rc = ffs_open_flash(chip, 0, flash->size, &ffs); > + rc = ffs_init(0, flash->size, bl, &ffs); > if (rc) { > prlog(PR_WARNING, "FLASH: No ffs info; " > "using raw device only\n"); > @@ -346,13 +347,17 @@ static int64_t opal_flash_op(enum flash_op op, > uint64_t id, uint64_t offset, > > switch (op) { > case FLASH_OP_READ: > - rc = flash_read(flash->chip, offset, (void *)buf, size); > + rc = blocklevel_read(flash->bl, offset, (void *)buf, size); > break; > case FLASH_OP_WRITE: > - rc = flash_write(flash->chip, offset, (void *)buf, size, false); > + /* > + * Note: blocklevel_write() uses flash_smart_write(), this call used to > + * be flash_write() > + */ > + rc = blocklevel_write(flash->bl, offset, (void *)buf, size); > break; > case FLASH_OP_ERASE: > - rc = flash_erase(flash->chip, offset, size); > + rc = blocklevel_erase(flash->bl, offset, size); > break; > default: > assert(0); > @@ -425,7 +430,7 @@ struct flash_hostboot_header { > }; > > /* start and total size include ECC */ > -static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid, > +static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t > subid, uint32_t *start, uint32_t *total_size, > bool *ecc) > { > @@ -444,7 +449,7 @@ static int flash_find_subpartition(struct flash_chip > *chip, uint32_t subid, partsize = BUFFER_SIZE_MINUS_ECC(*total_size); > > /* Get the TOC */ > - rc = flash_read_corrected(chip, *start, header, > + rc = flash_read_corrected(bl, *start, header, > FLASH_SUBPART_HEADER_SIZE, ecc); > if (rc) { > prerror("FLASH: flash subpartition TOC read failed %i\n", rc); > @@ -564,7 +569,7 @@ static int flash_load_resource(enum resource_id id, > uint32_t subid, goto out_unlock; > } > > - rc = ffs_open_flash(flash->chip, 0, flash->size, &ffs); > + rc = ffs_init(0, flash->size, flash->bl, &ffs); > if (rc) { > prerror("FLASH: Can't open ffs handle\n"); > goto out_unlock; > @@ -591,7 +596,7 @@ static int flash_load_resource(enum resource_id id, > uint32_t subid, > > /* Find the sub partition if required */ > if (subid != RESOURCE_SUBID_NONE) { > - rc = flash_find_subpartition(flash->chip, subid, &part_start, > + rc = flash_find_subpartition(flash->bl, subid, &part_start, > &part_size, &ecc); > if (rc) > goto out_free_ffs; > @@ -614,7 +619,7 @@ static int flash_load_resource(enum resource_id id, > uint32_t subid, goto out_free_ffs; > } > > - rc = flash_read_corrected(flash->chip, part_start, buf, size, ecc); > + rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc); > if (rc) { > prerror("FLASH: failed to read %s partition\n", name); > goto out_free_ffs; > diff --git a/external/pflash/Makefile b/external/pflash/Makefile > index c28e359..7771343 100644 > --- a/external/pflash/Makefile > +++ b/external/pflash/Makefile > @@ -14,7 +14,7 @@ endif > CFLAGS = -O2 -Wall -I. > LDFLAGS = -lrt > OBJS = pflash.o progress.o ast-sf-ctrl.o > -OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o > +OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o > libflash/blocklevel.o OBJS += $(ARCH_OBJS) > EXE = pflash > > diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c > index fb783a2..0958691 100644 > --- a/external/pflash/pflash.c > +++ b/external/pflash/pflash.c > @@ -16,6 +16,7 @@ > > #include <libflash/libflash.h> > #include <libflash/libffs.h> > +#include <libflash/blocklevel.h> > #include "progress.h" > #include "io.h" > #include "ast.h" > @@ -23,7 +24,7 @@ > > #define __aligned(x) __attribute__((aligned(x))) > > -#define PFLASH_VERSION "0.8.6" > +#define PFLASH_VERSION "0.8.7" > > static bool must_confirm = true; > static bool dummy_run; > @@ -36,8 +37,8 @@ static bool using_sfc; > #define FILE_BUF_SIZE 0x10000 > static uint8_t file_buf[FILE_BUF_SIZE] __aligned(0x1000); > > +static struct blocklevel_device *bl; > static struct spi_flash_ctrl *fl_ctrl; > -static struct flash_chip *fl_chip; > static struct ffs_handle *ffsh; > static uint32_t fl_total_size, fl_erase_granule; > static const char *fl_name; > @@ -84,7 +85,7 @@ static void print_flash_info(void) > return; > > if (!ffsh) { > - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); > + rc = ffs_init(0, fl_total_size, bl, &ffsh); > if (rc) { > fprintf(stderr, "Error %d opening ffs !\n", rc); > ffsh = NULL; > @@ -122,7 +123,7 @@ static void lookup_partition(const char *name) > > /* Open libffs if needed */ > if (!ffsh) { > - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); > + rc = ffs_init(0, fl_total_size, bl, &ffsh); > if (rc) { > fprintf(stderr, "Error %d opening ffs !\n", rc); > exit(1); > @@ -158,7 +159,7 @@ static void erase_chip(void) > return; > } > > - rc = flash_erase_chip(fl_chip); > + rc = flash_erase_chip(bl); > if (rc) { > fprintf(stderr, "Error %d erasing chip\n", rc); > exit(1); > @@ -185,7 +186,7 @@ static void erase_range(uint32_t start, uint32_t size, > bool will_program) while(size) { > /* If aligned to 64k and at least 64k, use 64k erase */ > if ((start & 0xffff) == 0 && size >= 0x10000) { > - rc = flash_erase(fl_chip, start, 0x10000); > + rc = blocklevel_erase(bl, start, 0x10000); > if (rc) { > fprintf(stderr, "Error %d erasing 0x%08x\n", > rc, start); > @@ -195,7 +196,7 @@ static void erase_range(uint32_t start, uint32_t size, > bool will_program) size -= 0x10000; > done += 0x10000; > } else { > - rc = flash_erase(fl_chip, start, 0x1000); > + rc = blocklevel_erase(bl, start, 0x1000); > if (rc) { > fprintf(stderr, "Error %d erasing 0x%08x\n", > rc, start); > @@ -252,7 +253,7 @@ static void program_file(const char *file, uint32_t > start, uint32_t size) len = size; > size -= len; > actual_size += len; > - rc = flash_write(fl_chip, start, file_buf, len, true); > + rc = blocklevel_write(bl, start, file_buf, len); > if (rc) { > if (rc == FLASH_ERR_VERIFY_FAILURE) > fprintf(stderr, "Verification failed for" > @@ -292,7 +293,7 @@ static void do_read_file(const char *file, uint32_t > start, uint32_t size) progress_init(size >> 8); > while(size) { > len = size > FILE_BUF_SIZE ? FILE_BUF_SIZE : size; > - rc = flash_read(fl_chip, start, file_buf, len); > + rc = blocklevel_read(bl, start, file_buf, len); > if (rc) { > fprintf(stderr, "Flash read error %d for" > " chunk at 0x%08x\n", rc, start); > @@ -318,7 +319,7 @@ static void enable_4B_addresses(void) > > printf("Switching to 4-bytes address mode\n"); > > - rc = flash_force_4b_mode(fl_chip, true); > + rc = flash_force_4b_mode(bl, true); > if (rc) { > fprintf(stderr, "Error %d enabling 4b mode\n", rc); > exit(1); > @@ -331,7 +332,7 @@ static void disable_4B_addresses(void) > > printf("Switching to 3-bytes address mode\n"); > > - rc = flash_force_4b_mode(fl_chip, false); > + rc = flash_force_4b_mode(bl, false); > if (rc) { > fprintf(stderr, "Error %d disabling 4b mode\n", rc); > exit(1); > @@ -342,7 +343,7 @@ static void flash_access_cleanup_bmc(void) > { > if (ffsh) > ffs_close(ffsh); > - flash_exit(fl_chip); > + flash_exit(bl); > ast_sf_close(fl_ctrl); > close_devs(); > } > @@ -362,7 +363,7 @@ static void flash_access_setup_bmc(bool use_lpc, bool > need_write) } > > /* Open flash chip */ > - rc = flash_init(fl_ctrl, &fl_chip); > + rc = flash_init(fl_ctrl, &bl); > if (rc) { > fprintf(stderr, "Failed to open flash chip\n"); > exit(1); > @@ -380,7 +381,7 @@ static void flash_access_cleanup_pnor(void) > > if (ffsh) > ffs_close(ffsh); > - flash_exit(fl_chip); > + flash_exit(bl); > #ifdef __powerpc__ > if (using_sfc) > sfc_close(fl_ctrl); > @@ -421,7 +422,7 @@ static void flash_access_setup_pnor(bool use_lpc, bool > use_sfc, bool need_write) #endif > > /* Open flash chip */ > - rc = flash_init(fl_ctrl, &fl_chip); > + rc = flash_init(fl_ctrl, &bl); > if (rc) { > fprintf(stderr, "Failed to open flash chip\n"); > exit(1); > @@ -698,7 +699,7 @@ int main(int argc, char *argv[]) > flash_access_setup_pnor(use_lpc, has_sfc, erase || program); > } > > - rc = flash_get_info(fl_chip, &fl_name, > + rc = blocklevel_get_info(bl, &fl_name, > &fl_total_size, &fl_erase_granule); > if (rc) { > fprintf(stderr, "Error %d getting flash info\n", rc); > diff --git a/include/skiboot.h b/include/skiboot.h > index 9751a31..aa92f68 100644 > --- a/include/skiboot.h > +++ b/include/skiboot.h > @@ -36,6 +36,8 @@ > #include <ccan/endian/endian.h> > #include <ccan/str/str.h> > > +#include <libflash/blocklevel.h> > + > #include <mem-map.h> > #include <op-panel.h> > #include <platform.h> > @@ -214,7 +216,7 @@ extern void occ_fsp_init(void); > > /* flash support */ > struct flash_chip; > -extern int flash_register(struct flash_chip *chip, bool is_system_flash); > +extern int flash_register(struct blocklevel_device *bl, bool > is_system_flash); extern int flash_start_preload_resource(enum resource_id > id, uint32_t subid, void *buf, size_t *len); > extern int flash_resource_loaded(enum resource_id id, uint32_t idx); > diff --git a/libflash/libffs.c b/libflash/libffs.c > index 2d05cc9..8a60bee 100644 > --- a/libflash/libffs.c > +++ b/libflash/libffs.c > @@ -41,6 +41,7 @@ struct ffs_handle { > uint32_t max_size; > void *cache; > uint32_t cached_size; > + struct blocklevel_device *bl; > }; > > static uint32_t ffs_checksum(void* data, size_t size) > @@ -71,31 +72,29 @@ static int ffs_check_convert_header(struct ffs_hdr *dst, > struct ffs_hdr *src) return 0; > } > > -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, > - uint32_t max_size, struct ffs_handle **ffs) > +int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device > *bl, + struct ffs_handle **ffs) > { > struct ffs_hdr hdr; > struct ffs_handle *f; > - uint32_t fl_size, erase_size; > + uint32_t total_size; > int rc; > > - if (!ffs) > + if (!ffs || !bl) > return FLASH_ERR_PARM_ERROR; > *ffs = NULL; > > - /* Grab some info about our flash chip */ > - rc = flash_get_info(chip, NULL, &fl_size, &erase_size); > + rc = blocklevel_get_info(bl, NULL, &total_size, NULL); > if (rc) { > - FL_ERR("FFS: Error %d retrieving flash info\n", rc); > - return rc; > - } > - if ((offset + max_size) < offset) > + FL_ERR("FFS: Error %d getting device total size", rc); > return FLASH_ERR_PARM_ERROR; > - if ((offset + max_size) > fl_size) > + } > + > + if ((offset + max_size) < offset || (offset + max_size) > total_size) > return FLASH_ERR_PARM_ERROR; > > /* Read flash header */ > - rc = flash_read(chip, offset, &hdr, sizeof(hdr)); > + rc = blocklevel_read(bl, offset, &hdr, sizeof(hdr)); > if (rc) { > FL_ERR("FFS: Error %d reading flash header\n", rc); > return rc; > @@ -106,17 +105,15 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t > offset, if (!f) > return FLASH_ERR_MALLOC_FAILED; > memset(f, 0, sizeof(*f)); > - f->type = ffs_type_flash; > f->flash_offset = offset; > - f->max_size = max_size ? max_size : (fl_size - offset); > - f->chip = chip; > + f->max_size = max_size; > + f->bl = bl; > > /* Convert and check flash header */ > rc = ffs_check_convert_header(&f->hdr, &hdr); > if (rc) { > FL_ERR("FFS: Error %d checking flash header\n", rc); > - free(f); > - return rc; > + goto out; > } > > /* > @@ -126,26 +123,26 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t > offset, f->cached_size = f->hdr.block_size * f->hdr.size; > FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size); > > - /* Align to erase size */ > - f->cached_size |= (erase_size - 1); > - f->cached_size &= ~(erase_size - 1); > - FL_DBG("FFS: Aligned to: 0x%x\n", f->cached_size); > - > /* Allocate cache */ > f->cache = malloc(f->cached_size); > if (!f->cache) { > - free(f); > - return FLASH_ERR_MALLOC_FAILED; > + rc = FLASH_ERR_MALLOC_FAILED; > + goto out; > } > > /* Read the cached map */ > - rc = flash_read(chip, offset, f->cache, f->cached_size); > + rc = blocklevel_read(bl, offset, f->cache, f->cached_size); > if (rc) { > FL_ERR("FFS: Error %d reading flash partition map\n", rc); > - free(f); > + goto out; > } > + > +out: > if (rc == 0) > *ffs = f; > + else > + free(f); > + > return rc; > } > > @@ -361,6 +358,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t > part_idx, ent->checksum = ffs_checksum(ent, FFS_ENTRY_SIZE_CSUM); > if (!ffs->chip) > return 0; > - return flash_smart_write(ffs->chip, offset, ent, FFS_ENTRY_SIZE); > + > + return blocklevel_write(ffs->bl, offset, ent, FFS_ENTRY_SIZE); > } > > diff --git a/libflash/libffs.h b/libflash/libffs.h > index dd58d28..a310172 100644 > --- a/libflash/libffs.h > +++ b/libflash/libffs.h > @@ -18,6 +18,7 @@ > > #include <libflash/libflash.h> > #include <libflash/ffs.h> > +#include <libflash/blocklevel.h> > > /* FFS handle, opaque */ > struct ffs_handle; > @@ -34,8 +35,10 @@ struct ffs_handle; > #define FFS_ERR_PART_NOT_FOUND 103 > #define FFS_ERR_BAD_ECC 104 > > -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, > - uint32_t max_size, struct ffs_handle **ffs); > +/* Init */ > + > +int ffs_init(uint32_t offset, uint32_t max_size, > + struct blocklevel_device *bl, struct ffs_handle **ffs); > > /* ffs_open_image is Linux only as it uses lseek, which skiboot does not > * implement */ > diff --git a/libflash/libflash.c b/libflash/libflash.c > index e43be4f..2af0c79 100644 > --- a/libflash/libflash.c > +++ b/libflash/libflash.c > @@ -20,6 +20,7 @@ > #include "libflash.h" > #include "libflash-priv.h" > #include "ecc.h" > +#include "blocklevel.h" > > #ifndef MIN > #define MIN(a, b) ((a) < (b) ? (a) : (b)) > @@ -45,6 +46,7 @@ struct flash_chip { > bool mode_4b; /* Flash currently in 4b mode */ > struct flash_req *cur_req; /* Current request */ > void *smart_buf; /* Buffer for smart writes */ > + struct blocklevel_device bl; > }; > > #ifndef __SKIBOOT__ > @@ -112,8 +114,9 @@ int fl_wren(struct spi_flash_ctrl *ct) > return FLASH_ERR_WREN_TIMEOUT; > } > > -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len) > +static int flash_read(struct blocklevel_device *bl, uint32_t pos, void > *buf, uint32_t len) { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > struct spi_flash_ctrl *ct = c->ctrl; > > /* XXX Add sanity/bound checking */ > @@ -138,7 +141,7 @@ int flash_read(struct flash_chip *c, uint32_t pos, void > *buf, uint32_t len) * This provides a wrapper around flash_read on ECCed > data > * len is length of data without ECC attached > */ > -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, > +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void > *buf, uint32_t len, bool ecc) > { > struct ecc64 *bufecc; > @@ -147,7 +150,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t > pos, void *buf, uint8_t ret; > > if (!ecc) > - return flash_read(c, pos, buf, len); > + return flash_read(bl, pos, buf, len); > > /* Copy the buffer in chunks */ > bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); > @@ -159,7 +162,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t > pos, void *buf, copylen = MIN(len, COPY_BUFFER_LENGTH); > > /* Read ECCed data from flash */ > - rc = flash_read(c, pos, bufecc, ECC_BUFFER_SIZE(copylen)); > + rc = flash_read(bl, pos, bufecc, ECC_BUFFER_SIZE(copylen)); > if (rc) > goto err; > > @@ -215,8 +218,9 @@ static void fl_get_best_erase(struct flash_chip *c, > uint32_t dst, uint32_t size, *cmd = CMD_BE; > } > > -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size) > +static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t > size) { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > struct spi_flash_ctrl *ct = c->ctrl; > uint32_t chunk; > uint8_t cmd; > @@ -262,8 +266,9 @@ int flash_erase(struct flash_chip *c, uint32_t dst, > uint32_t size) return 0; > } > > -int flash_erase_chip(struct flash_chip *c) > +int flash_erase_chip(struct blocklevel_device *bl) > { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > struct spi_flash_ctrl *ct = c->ctrl; > int rc; > > @@ -311,9 +316,10 @@ static int fl_wpage(struct flash_chip *c, uint32_t dst, > const void *src, return fl_sync_wait_idle(ct); > } > > -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, > +static int flash_write(struct blocklevel_device *bl, uint32_t dst, const > void *src, uint32_t size, bool verify) > { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > struct spi_flash_ctrl *ct = c->ctrl; > uint32_t todo = size; > uint32_t d = dst; > @@ -374,7 +380,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, > const void *src, chunk = sizeof(vbuf); > if (chunk > size) > chunk = size; > - rc = flash_read(c, dst, vbuf, chunk); > + rc = flash_read(bl, dst, vbuf, chunk); > if (rc) return rc; > if (memcmp(vbuf, src, chunk)) { > FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst); > @@ -387,7 +393,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, > const void *src, return 0; > } > > -int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void > *buf, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t > pos, const void *buf, uint32_t len, bool verify, bool ecc) > { > struct ecc64 *bufecc; > @@ -396,7 +402,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t > pos, const void *buf, uint8_t ret; > > if (!ecc) > - return flash_write(c, pos, buf, len, verify); > + return flash_write(bl, pos, buf, len, verify); > > /* Copy the buffer in chunks */ > bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); > @@ -415,7 +421,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t > pos, const void *buf, } > > /* Write ECCed data to the flash */ > - rc = flash_write(c, pos, bufecc, copylen, verify); > + rc = flash_write(bl, pos, bufecc, copylen, verify); > if (rc) > goto err; > > @@ -463,12 +469,12 @@ static enum sm_comp_res flash_smart_comp(struct > flash_chip *c, return is_same ? sm_no_change : sm_need_write; > } > > -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, > - uint32_t size) > +static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, > const void *src, uint32_t size) { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > uint32_t er_size = c->min_erase_mask + 1; > uint32_t end = dst + size; > - int rc; > + int rc; > > /* Some sanity checking */ > if (end <= dst || !size || end > c->tsize) { > @@ -489,7 +495,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t > dst, const void *src, off = dst & c->min_erase_mask; > FL_DBG("LIBFLASH: reading page 0x%08x..0x%08x...", > page, page + er_size); > - rc = flash_read(c, page, c->smart_buf, er_size); > + rc = flash_read(bl, page, c->smart_buf, er_size); > if (rc) { > FL_DBG(" error %d!\n", rc); > return rc; > @@ -510,7 +516,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t > dst, const void *src, case sm_need_write: > /* Just needs writing over */ > FL_DBG(" need write !\n"); > - rc = flash_write(c, dst, src, chunk, true); > + rc = flash_write(bl, dst, src, chunk, true); > if (rc) { > FL_DBG("LIBFLASH: Write error %d !\n", rc); > return rc; > @@ -518,14 +524,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t > dst, const void *src, break; > case sm_need_erase: > FL_DBG(" need erase !\n"); > - rc = flash_erase(c, page, er_size); > + rc = flash_erase(bl, page, er_size); > if (rc) { > FL_DBG("LIBFLASH: erase error %d !\n", rc); > return rc; > } > /* Then update the portion of the buffer and write the block */ > memcpy(c->smart_buf + off, src, chunk); > - rc = flash_write(c, page, c->smart_buf, er_size, true); > + rc = flash_write(bl, page, c->smart_buf, er_size, true); > if (rc) { > FL_DBG("LIBFLASH: write error %d !\n", rc); > return rc; > @@ -539,14 +545,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t > dst, const void *src, return 0; > } > > -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const > void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, > uint32_t dst, const void *src, uint32_t size, bool ecc) > { > struct ecc64 *buf; > int rc; > > if (!ecc) > - return flash_smart_write(c, dst, src, size); > + return flash_smart_write(bl, dst, src, size); > > buf = malloc(ECC_BUFFER_SIZE(size)); > if (!buf) > @@ -558,7 +564,7 @@ int flash_smart_write_corrected(struct flash_chip *c, > uint32_t dst, const void * goto out; > } > > - rc = flash_smart_write(c, dst, buf, ECC_BUFFER_SIZE(size)); > + rc = flash_smart_write(bl, dst, buf, ECC_BUFFER_SIZE(size)); > > out: > free(buf); > @@ -684,8 +690,9 @@ static int flash_set_4b(struct flash_chip *c, bool > enable) return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, > 0); } > > -int flash_force_4b_mode(struct flash_chip *c, bool enable_4b) > +int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b) > { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > struct spi_flash_ctrl *ct = c->ctrl; > int rc; > > @@ -776,24 +783,29 @@ static int flash_configure(struct flash_chip *c) > return 0; > } > > -int flash_get_info(struct flash_chip *chip, const char **name, > +static int flash_get_info(struct blocklevel_device *bl, const char **name, > uint32_t *total_size, uint32_t *erase_granule) > { > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > if (name) > - *name = chip->info.name; > + *name = c->info.name; > if (total_size) > - *total_size = chip->tsize; > + *total_size = c->tsize; > if (erase_granule) > - *erase_granule = chip->min_erase_mask + 1; > + *erase_granule = c->min_erase_mask + 1; > return 0; > } > > -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash) > +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl) > { > struct flash_chip *c; > int rc; > > - *flash = NULL; > + if (!bl) > + return FLASH_ERR_PARM_ERROR; > + > + *bl = NULL; > + > c = malloc(sizeof(struct flash_chip)); > if (!c) > return FLASH_ERR_MALLOC_FAILED; > @@ -814,18 +826,25 @@ int flash_init(struct spi_flash_ctrl *ctrl, struct > flash_chip **flash) rc = flash_configure(c); > if (rc) > FL_ERR("LIBFLASH: Flash configuration failed\n"); > - bail: > +bail: > if (rc) { > free(c); > return rc; > } > - *flash = c; > + > + c->bl.read = &flash_read; > + c->bl.write = &flash_smart_write; > + c->bl.erase = &flash_erase; > + c->bl.get_info = &flash_get_info; > + > + *bl = &(c->bl); > return 0; > } > > -void flash_exit(struct flash_chip *chip) > +void flash_exit(struct blocklevel_device *bl) > { > /* XXX Make sure we are idle etc... */ > - free(chip); > + if (bl) > + free(container_of(bl, struct flash_chip, bl)); > } > > diff --git a/libflash/libflash.h b/libflash/libflash.h > index 7ed65d0..30f984d 100644 > --- a/libflash/libflash.h > +++ b/libflash/libflash.h > @@ -18,6 +18,7 @@ > > #include <stdint.h> > #include <stdbool.h> > +#include <libflash/blocklevel.h> > > #ifdef __SKIBOOT__ > #include <skiboot.h> > @@ -59,18 +60,13 @@ extern bool libflash_debug; > struct flash_chip; > struct spi_flash_ctrl; > > -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash); > -void flash_exit(struct flash_chip *chip); > - > -int flash_get_info(struct flash_chip *chip, const char **name, > - uint32_t *total_size, uint32_t *erase_granule); > +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl); > +void flash_exit(struct blocklevel_device *bl); > > /* libflash sets the 4b mode automatically based on the flash > * size and controller capabilities but it can be overriden > */ > -int flash_force_4b_mode(struct flash_chip *chip, bool enable_4b); > - > -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t > len); +int flash_force_4b_mode(struct blocklevel_device *bl, bool > enable_4b); > > /* > * This provides a wapper around flash_read() on ECCed data. All params are > @@ -80,11 +76,8 @@ int flash_read(struct flash_chip *c, uint32_t pos, void > *buf, uint32_t len); * len is length of data without ecc attached therefore > this will read beyond * pos + len. > */ > -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, > +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void > *buf, uint32_t len, bool ecc); > -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size); > -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, > - uint32_t size, bool verify); > > /* > * This provides a wrapper around flash_write() on ECCed data. All params > are @@ -94,10 +87,8 @@ int flash_write(struct flash_chip *c, uint32_t dst, > const void *src, * size is length of data without ECC attached therefore > this will write beyond * dst + size. > */ > -int flash_write_corrected(struct flash_chip *c, uint32_t dst, const void > *src, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t > dst, const void *src, uint32_t size, bool verify, bool ecc); > -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, > - uint32_t size); > > /* > * This provides a wrapper around flash_smart_write() on ECCed data. All > @@ -107,12 +98,12 @@ int flash_smart_write(struct flash_chip *c, uint32_t > dst, const void *src, * size is length of data without ECC attached > therefore this will write beyond * dst + size. > */ > -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const > void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, > uint32_t dst, const void *src, uint32_t size, bool ecc); > > /* chip erase may not be supported by all chips/controllers, get ready > * for FLASH_ERR_CHIP_ER_NOT_SUPPORTED > */ > -int flash_erase_chip(struct flash_chip *c); > +int flash_erase_chip(struct blocklevel_device *bl); > > #endif /* __LIBFLASH_H */ > diff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c > index 4479b5a..cf2b3a5 100644 > --- a/libflash/test/test-flash.c > +++ b/libflash/test/test-flash.c > @@ -366,7 +366,7 @@ struct spi_flash_ctrl sim_ctrl = { > > int main(void) > { > - struct flash_chip *fl; > + struct blocklevel_device *bl; > uint32_t total_size, erase_granule; > const char *name; > uint16_t *test; > @@ -378,12 +378,12 @@ int main(void) > memset(sim_image, 0xff, sim_image_sz); > test = malloc(0x10000 * 2); > > - rc = flash_init(&sim_ctrl, &fl); > + rc = flash_init(&sim_ctrl, &bl); > if (rc) { > ERR("flash_init failed with err %d\n", rc); > exit(1); > } > - rc = flash_get_info(fl, &name, &total_size, &erase_granule); > + rc = flash_get_info(bl, &name, &total_size, &erase_granule); > if (rc) { > ERR("flash_get_info failed with err %d\n", rc); > exit(1); > @@ -395,13 +395,13 @@ int main(void) > > /* Write 64k of stuff at 0 and at 128k */ > printf("Writing test patterns...\n"); > - flash_smart_write(fl, 0, test, 0x10000); > - flash_smart_write(fl, 0x20000, test, 0x10000); > + flash_smart_write(bl, 0, test, 0x10000); > + flash_smart_write(bl, 0x20000, test, 0x10000); > > /* Write "Hello world" straddling the 64k boundary */ > #define HW "Hello World" > printf("Writing test string...\n"); > - flash_smart_write(fl, 0xfffc, HW, sizeof(HW)); > + flash_smart_write(bl, 0xfffc, HW, sizeof(HW)); > > /* Check result */ > if (memcmp(sim_image + 0xfffc, HW, sizeof(HW))) { > @@ -416,7 +416,7 @@ int main(void) > printf("Test pattern pass\n"); > > printf("Test ECC interfaces\n"); > - flash_smart_write_corrected(fl, 0, test, 0x10000, 1); > + flash_smart_write_corrected(bl, 0, test, 0x10000, 1); > ecc_test = (struct ecc64 *)sim_image; > test64 = (uint64_t *)test; > for (i = 0; i < 0x10000 / sizeof(*ecc_test); i++) { > @@ -433,7 +433,7 @@ int main(void) > printf("Test ECC interface pass\n"); > > printf("Test ECC erase\n"); > - if (flash_erase(fl, 0, 0x10000) != 0) { > + if (flash_erase(bl, 0, 0x10000) != 0) { > ERR("flash_erase didn't return 0\n"); > exit(1); > } > @@ -444,7 +444,7 @@ int main(void) > ERR("Data not properly cleared at %d\n", i); > exit(1); > } > - rc = flash_write(fl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); > + rc = flash_write(bl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); > if (rc || ecc_test[i].ecc != 0) { > ERR("Cleared data not correctly ECCed: 0x%02x (0x%016lx) expecting 0 at > %d\n", ecc_test[i].ecc, ecc_test[i].data, i); exit(1); > @@ -452,7 +452,7 @@ int main(void) > } > printf("Test ECC erase pass\n"); > > - flash_exit(fl); > + flash_exit(bl); > > return 0; > } > diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c > index d294c1f..634cb86 100644 > --- a/platforms/astbmc/pnor.c > +++ b/platforms/astbmc/pnor.c > @@ -20,6 +20,7 @@ > #include <opal.h> > #include <libflash/libflash.h> > #include <libflash/libffs.h> > +#include <libflash/blocklevel.h> > #include <ast.h> > > #include "astbmc.h" > @@ -27,7 +28,7 @@ > int pnor_init(void) > { > struct spi_flash_ctrl *pnor_ctrl; > - struct flash_chip *pnor_chip = NULL; > + struct blocklevel_device *bl; > int rc; > > /* Open controller and flash. If the LPC->AHB doesn't point to > @@ -44,19 +45,20 @@ int pnor_init(void) > prerror("PLAT: Failed to open PNOR flash controller\n"); > goto fail; > } > - rc = flash_init(pnor_ctrl, &pnor_chip); > + > + rc = flash_init(pnor_ctrl, &bl); > if (rc) { > prerror("PLAT: Failed to open init PNOR driver\n"); > goto fail; > } > > - rc = flash_register(pnor_chip, true); > + rc = flash_register(bl, true); > if (!rc) > return 0; > > fail: > - if (pnor_chip) > - flash_exit(pnor_chip); > + if (bl) > + flash_exit(bl); > if (pnor_ctrl) > ast_sf_close(pnor_ctrl); > > diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c > index 27e1c91..855d0e4 100644 > --- a/platforms/rhesus/rhesus.c > +++ b/platforms/rhesus/rhesus.c > @@ -22,6 +22,7 @@ > #include <opal.h> > #include <libflash/libflash.h> > #include <libflash/libffs.h> > +#include <libflash/blocklevel.h> > #include <sfc-ctrl.h> > #include <ec/config.h> > #include <ec/gpio.h> > @@ -118,7 +119,7 @@ static int64_t rhesus_power_down(uint64_t request > __unused) static int rhesus_pnor_init(void) > { > struct spi_flash_ctrl *pnor_ctrl; > - struct flash_chip *pnor_chip = NULL; > + struct blocklevel_device *bl; > int rc; > > /* Open controller, flash and ffs */ > @@ -127,19 +128,19 @@ static int rhesus_pnor_init(void) > prerror("PLAT: Failed to open PNOR flash controller\n"); > goto fail; > } > - rc = flash_init(pnor_ctrl, &pnor_chip); > + rc = flash_init(pnor_ctrl, &bl); > if (rc) { > prerror("PLAT: Failed to open init PNOR driver\n"); > goto fail; > } > > - rc = flash_register(pnor_chip, true); > + rc = flash_register(bl, true); > if (!rc) > return 0; > > fail: > - if (pnor_chip) > - flash_exit(pnor_chip); > + if (bl) > + flash_exit(bl); > if (pnor_ctrl) > sfc_close(pnor_ctrl);
On Thu, 2015-05-21 at 11:53 +1000, Alistair Popple wrote: > This looks ok, my only concern is that changing flash_write -> > flash_smart_write in pflash is likely to reduce pflash performance. Is there a > way we could not make that change in pflash for the moment? I have an idea for > how we could fix it properly, but that change would be easier to do if we had > these patches applied. > Agreed, however this all depends on if it is actually slower. I'll confirm that tomorrow, if it is, we'll leave flash_write() exposed for pflash. The solution from there would be to make flash_smart_write() smarter and ultimately wind up in blocklevel. > Signed-off-by: Alistair Popple <alistair@popple.id.au> > Reviewed-by: Alistair Popple <alistair@popple.id.au> > > On Thu, 14 May 2015 17:06:39 Cyril Bur wrote: > > Converted all the libflash calls to use the blocklevel interface, modified > > all callers to libflash to use the blocklevel interface. > > > > This patch should introduce next to no functional change. > > > > Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com> > > --- > > core/flash.c | 35 ++++++++++--------- > > external/pflash/Makefile | 2 +- > > external/pflash/pflash.c | 33 +++++++++--------- > > include/skiboot.h | 4 ++- > > libflash/libffs.c | 52 ++++++++++++++--------------- > > libflash/libffs.h | 7 ++-- > > libflash/libflash.c | 83 > > ++++++++++++++++++++++++++++------------------ libflash/libflash.h | > > 25 +++++--------- > > libflash/test/test-flash.c | 20 +++++------ > > platforms/astbmc/pnor.c | 12 ++++--- > > platforms/rhesus/rhesus.c | 11 +++--- > > 11 files changed, 153 insertions(+), 131 deletions(-) > > > > diff --git a/core/flash.c b/core/flash.c > > index 9018ecd..90dbac7 100644 > > --- a/core/flash.c > > +++ b/core/flash.c > > @@ -22,12 +22,13 @@ > > #include <device.h> > > #include <libflash/libflash.h> > > #include <libflash/libffs.h> > > +#include <libflash/blocklevel.h> > > #include <ecc.h> > > > > struct flash { > > bool registered; > > bool busy; > > - struct flash_chip *chip; > > + struct blocklevel_device *bl; > > uint32_t size; > > uint32_t block_size; > > }; > > @@ -108,7 +109,7 @@ static int flash_nvram_start_read(void *dst, uint32_t > > src, uint32_t len) goto out; > > } > > > > - rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len); > > + rc = blocklevel_read(nvram_flash->bl, nvram_offset + src, dst, len); > > > > out: > > unlock(&flash_lock); > > @@ -137,7 +138,7 @@ static int flash_nvram_write(uint32_t dst, void *src, > > uint32_t len) rc = OPAL_PARAMETER; > > goto out; > > } > > - rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, > len); > > + rc = blocklevel_write(nvram_flash->bl, nvram_offset + dst, src, len); > > > > out: > > unlock(&flash_lock); > > @@ -250,7 +251,7 @@ static void setup_system_flash(struct flash *flash, > > struct dt_node *node, flash_nvram_probe(flash, ffs); > > } > > > > -int flash_register(struct flash_chip *chip, bool is_system_flash) > > +int flash_register(struct blocklevel_device *bl, bool is_system_flash) > > { > > uint32_t size, block_size; > > struct ffs_handle *ffs; > > @@ -260,7 +261,7 @@ int flash_register(struct flash_chip *chip, bool > > is_system_flash) unsigned int i; > > int rc; > > > > - rc = flash_get_info(chip, &name, &size, &block_size); > > + rc = blocklevel_get_info(bl, &name, &size, &block_size); > > if (rc) > > return rc; > > > > @@ -276,7 +277,7 @@ int flash_register(struct flash_chip *chip, bool > > is_system_flash) flash = &flashes[i]; > > flash->registered = true; > > flash->busy = false; > > - flash->chip = chip; > > + flash->bl = bl; > > flash->size = size; > > flash->block_size = block_size; > > break; > > @@ -288,7 +289,7 @@ int flash_register(struct flash_chip *chip, bool > > is_system_flash) return OPAL_RESOURCE; > > } > > > > - rc = ffs_open_flash(chip, 0, flash->size, &ffs); > > + rc = ffs_init(0, flash->size, bl, &ffs); > > if (rc) { > > prlog(PR_WARNING, "FLASH: No ffs info; " > > "using raw device only\n"); > > @@ -346,13 +347,17 @@ static int64_t opal_flash_op(enum flash_op op, > > uint64_t id, uint64_t offset, > > > > switch (op) { > > case FLASH_OP_READ: > > - rc = flash_read(flash->chip, offset, (void *)buf, size); > > + rc = blocklevel_read(flash->bl, offset, (void *)buf, size); > > break; > > case FLASH_OP_WRITE: > > - rc = flash_write(flash->chip, offset, (void *)buf, size, > false); > > + /* > > + * Note: blocklevel_write() uses flash_smart_write(), this > call used to > > + * be flash_write() > > + */ > > + rc = blocklevel_write(flash->bl, offset, (void *)buf, size); > > break; > > case FLASH_OP_ERASE: > > - rc = flash_erase(flash->chip, offset, size); > > + rc = blocklevel_erase(flash->bl, offset, size); > > break; > > default: > > assert(0); > > @@ -425,7 +430,7 @@ struct flash_hostboot_header { > > }; > > > > /* start and total size include ECC */ > > -static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid, > > +static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t > > subid, uint32_t *start, uint32_t *total_size, > > bool *ecc) > > { > > @@ -444,7 +449,7 @@ static int flash_find_subpartition(struct flash_chip > > *chip, uint32_t subid, partsize = BUFFER_SIZE_MINUS_ECC(*total_size); > > > > /* Get the TOC */ > > - rc = flash_read_corrected(chip, *start, header, > > + rc = flash_read_corrected(bl, *start, header, > > FLASH_SUBPART_HEADER_SIZE, ecc); > > if (rc) { > > prerror("FLASH: flash subpartition TOC read failed %i\n", rc); > > @@ -564,7 +569,7 @@ static int flash_load_resource(enum resource_id id, > > uint32_t subid, goto out_unlock; > > } > > > > - rc = ffs_open_flash(flash->chip, 0, flash->size, &ffs); > > + rc = ffs_init(0, flash->size, flash->bl, &ffs); > > if (rc) { > > prerror("FLASH: Can't open ffs handle\n"); > > goto out_unlock; > > @@ -591,7 +596,7 @@ static int flash_load_resource(enum resource_id id, > > uint32_t subid, > > > > /* Find the sub partition if required */ > > if (subid != RESOURCE_SUBID_NONE) { > > - rc = flash_find_subpartition(flash->chip, subid, &part_start, > > + rc = flash_find_subpartition(flash->bl, subid, &part_start, > > &part_size, &ecc); > > if (rc) > > goto out_free_ffs; > > @@ -614,7 +619,7 @@ static int flash_load_resource(enum resource_id id, > > uint32_t subid, goto out_free_ffs; > > } > > > > - rc = flash_read_corrected(flash->chip, part_start, buf, size, ecc); > > + rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc); > > if (rc) { > > prerror("FLASH: failed to read %s partition\n", name); > > goto out_free_ffs; > > diff --git a/external/pflash/Makefile b/external/pflash/Makefile > > index c28e359..7771343 100644 > > --- a/external/pflash/Makefile > > +++ b/external/pflash/Makefile > > @@ -14,7 +14,7 @@ endif > > CFLAGS = -O2 -Wall -I. > > LDFLAGS = -lrt > > OBJS = pflash.o progress.o ast-sf-ctrl.o > > -OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o > > +OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o > > libflash/blocklevel.o OBJS += $(ARCH_OBJS) > > EXE = pflash > > > > diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c > > index fb783a2..0958691 100644 > > --- a/external/pflash/pflash.c > > +++ b/external/pflash/pflash.c > > @@ -16,6 +16,7 @@ > > > > #include <libflash/libflash.h> > > #include <libflash/libffs.h> > > +#include <libflash/blocklevel.h> > > #include "progress.h" > > #include "io.h" > > #include "ast.h" > > @@ -23,7 +24,7 @@ > > > > #define __aligned(x) __attribute__((aligned(x))) > > > > -#define PFLASH_VERSION "0.8.6" > > +#define PFLASH_VERSION "0.8.7" > > > > static bool must_confirm = true; > > static bool dummy_run; > > @@ -36,8 +37,8 @@ static bool using_sfc; > > #define FILE_BUF_SIZE 0x10000 > > static uint8_t file_buf[FILE_BUF_SIZE] __aligned(0x1000); > > > > +static struct blocklevel_device *bl; > > static struct spi_flash_ctrl *fl_ctrl; > > -static struct flash_chip *fl_chip; > > static struct ffs_handle *ffsh; > > static uint32_t fl_total_size, fl_erase_granule; > > static const char *fl_name; > > @@ -84,7 +85,7 @@ static void print_flash_info(void) > > return; > > > > if (!ffsh) { > > - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); > > + rc = ffs_init(0, fl_total_size, bl, &ffsh); > > if (rc) { > > fprintf(stderr, "Error %d opening ffs !\n", rc); > > ffsh = NULL; > > @@ -122,7 +123,7 @@ static void lookup_partition(const char *name) > > > > /* Open libffs if needed */ > > if (!ffsh) { > > - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); > > + rc = ffs_init(0, fl_total_size, bl, &ffsh); > > if (rc) { > > fprintf(stderr, "Error %d opening ffs !\n", rc); > > exit(1); > > @@ -158,7 +159,7 @@ static void erase_chip(void) > > return; > > } > > > > - rc = flash_erase_chip(fl_chip); > > + rc = flash_erase_chip(bl); > > if (rc) { > > fprintf(stderr, "Error %d erasing chip\n", rc); > > exit(1); > > @@ -185,7 +186,7 @@ static void erase_range(uint32_t start, uint32_t size, > > bool will_program) while(size) { > > /* If aligned to 64k and at least 64k, use 64k erase */ > > if ((start & 0xffff) == 0 && size >= 0x10000) { > > - rc = flash_erase(fl_chip, start, 0x10000); > > + rc = blocklevel_erase(bl, start, 0x10000); > > if (rc) { > > fprintf(stderr, "Error %d erasing 0x%08x\n", > > rc, start); > > @@ -195,7 +196,7 @@ static void erase_range(uint32_t start, uint32_t size, > > bool will_program) size -= 0x10000; > > done += 0x10000; > > } else { > > - rc = flash_erase(fl_chip, start, 0x1000); > > + rc = blocklevel_erase(bl, start, 0x1000); > > if (rc) { > > fprintf(stderr, "Error %d erasing 0x%08x\n", > > rc, start); > > @@ -252,7 +253,7 @@ static void program_file(const char *file, uint32_t > > start, uint32_t size) len = size; > > size -= len; > > actual_size += len; > > - rc = flash_write(fl_chip, start, file_buf, len, true); > > + rc = blocklevel_write(bl, start, file_buf, len); > > if (rc) { > > if (rc == FLASH_ERR_VERIFY_FAILURE) > > fprintf(stderr, "Verification failed for" > > @@ -292,7 +293,7 @@ static void do_read_file(const char *file, uint32_t > > start, uint32_t size) progress_init(size >> 8); > > while(size) { > > len = size > FILE_BUF_SIZE ? FILE_BUF_SIZE : size; > > - rc = flash_read(fl_chip, start, file_buf, len); > > + rc = blocklevel_read(bl, start, file_buf, len); > > if (rc) { > > fprintf(stderr, "Flash read error %d for" > > " chunk at 0x%08x\n", rc, start); > > @@ -318,7 +319,7 @@ static void enable_4B_addresses(void) > > > > printf("Switching to 4-bytes address mode\n"); > > > > - rc = flash_force_4b_mode(fl_chip, true); > > + rc = flash_force_4b_mode(bl, true); > > if (rc) { > > fprintf(stderr, "Error %d enabling 4b mode\n", rc); > > exit(1); > > @@ -331,7 +332,7 @@ static void disable_4B_addresses(void) > > > > printf("Switching to 3-bytes address mode\n"); > > > > - rc = flash_force_4b_mode(fl_chip, false); > > + rc = flash_force_4b_mode(bl, false); > > if (rc) { > > fprintf(stderr, "Error %d disabling 4b mode\n", rc); > > exit(1); > > @@ -342,7 +343,7 @@ static void flash_access_cleanup_bmc(void) > > { > > if (ffsh) > > ffs_close(ffsh); > > - flash_exit(fl_chip); > > + flash_exit(bl); > > ast_sf_close(fl_ctrl); > > close_devs(); > > } > > @@ -362,7 +363,7 @@ static void flash_access_setup_bmc(bool use_lpc, bool > > need_write) } > > > > /* Open flash chip */ > > - rc = flash_init(fl_ctrl, &fl_chip); > > + rc = flash_init(fl_ctrl, &bl); > > if (rc) { > > fprintf(stderr, "Failed to open flash chip\n"); > > exit(1); > > @@ -380,7 +381,7 @@ static void flash_access_cleanup_pnor(void) > > > > if (ffsh) > > ffs_close(ffsh); > > - flash_exit(fl_chip); > > + flash_exit(bl); > > #ifdef __powerpc__ > > if (using_sfc) > > sfc_close(fl_ctrl); > > @@ -421,7 +422,7 @@ static void flash_access_setup_pnor(bool use_lpc, bool > > use_sfc, bool need_write) #endif > > > > /* Open flash chip */ > > - rc = flash_init(fl_ctrl, &fl_chip); > > + rc = flash_init(fl_ctrl, &bl); > > if (rc) { > > fprintf(stderr, "Failed to open flash chip\n"); > > exit(1); > > @@ -698,7 +699,7 @@ int main(int argc, char *argv[]) > > flash_access_setup_pnor(use_lpc, has_sfc, erase || program); > > } > > > > - rc = flash_get_info(fl_chip, &fl_name, > > + rc = blocklevel_get_info(bl, &fl_name, > > &fl_total_size, &fl_erase_granule); > > if (rc) { > > fprintf(stderr, "Error %d getting flash info\n", rc); > > diff --git a/include/skiboot.h b/include/skiboot.h > > index 9751a31..aa92f68 100644 > > --- a/include/skiboot.h > > +++ b/include/skiboot.h > > @@ -36,6 +36,8 @@ > > #include <ccan/endian/endian.h> > > #include <ccan/str/str.h> > > > > +#include <libflash/blocklevel.h> > > + > > #include <mem-map.h> > > #include <op-panel.h> > > #include <platform.h> > > @@ -214,7 +216,7 @@ extern void occ_fsp_init(void); > > > > /* flash support */ > > struct flash_chip; > > -extern int flash_register(struct flash_chip *chip, bool is_system_flash); > > +extern int flash_register(struct blocklevel_device *bl, bool > > is_system_flash); extern int flash_start_preload_resource(enum resource_id > > id, uint32_t subid, void *buf, size_t *len); > > extern int flash_resource_loaded(enum resource_id id, uint32_t idx); > > diff --git a/libflash/libffs.c b/libflash/libffs.c > > index 2d05cc9..8a60bee 100644 > > --- a/libflash/libffs.c > > +++ b/libflash/libffs.c > > @@ -41,6 +41,7 @@ struct ffs_handle { > > uint32_t max_size; > > void *cache; > > uint32_t cached_size; > > + struct blocklevel_device *bl; > > }; > > > > static uint32_t ffs_checksum(void* data, size_t size) > > @@ -71,31 +72,29 @@ static int ffs_check_convert_header(struct ffs_hdr *dst, > > struct ffs_hdr *src) return 0; > > } > > > > -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, > > - uint32_t max_size, struct ffs_handle **ffs) > > +int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device > > *bl, + struct ffs_handle **ffs) > > { > > struct ffs_hdr hdr; > > struct ffs_handle *f; > > - uint32_t fl_size, erase_size; > > + uint32_t total_size; > > int rc; > > > > - if (!ffs) > > + if (!ffs || !bl) > > return FLASH_ERR_PARM_ERROR; > > *ffs = NULL; > > > > - /* Grab some info about our flash chip */ > > - rc = flash_get_info(chip, NULL, &fl_size, &erase_size); > > + rc = blocklevel_get_info(bl, NULL, &total_size, NULL); > > if (rc) { > > - FL_ERR("FFS: Error %d retrieving flash info\n", rc); > > - return rc; > > - } > > - if ((offset + max_size) < offset) > > + FL_ERR("FFS: Error %d getting device total size", rc); > > return FLASH_ERR_PARM_ERROR; > > - if ((offset + max_size) > fl_size) > > + } > > + > > + if ((offset + max_size) < offset || (offset + max_size) > total_size) > > return FLASH_ERR_PARM_ERROR; > > > > /* Read flash header */ > > - rc = flash_read(chip, offset, &hdr, sizeof(hdr)); > > + rc = blocklevel_read(bl, offset, &hdr, sizeof(hdr)); > > if (rc) { > > FL_ERR("FFS: Error %d reading flash header\n", rc); > > return rc; > > @@ -106,17 +105,15 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t > > offset, if (!f) > > return FLASH_ERR_MALLOC_FAILED; > > memset(f, 0, sizeof(*f)); > > - f->type = ffs_type_flash; > > f->flash_offset = offset; > > - f->max_size = max_size ? max_size : (fl_size - offset); > > - f->chip = chip; > > + f->max_size = max_size; > > + f->bl = bl; > > > > /* Convert and check flash header */ > > rc = ffs_check_convert_header(&f->hdr, &hdr); > > if (rc) { > > FL_ERR("FFS: Error %d checking flash header\n", rc); > > - free(f); > > - return rc; > > + goto out; > > } > > > > /* > > @@ -126,26 +123,26 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t > > offset, f->cached_size = f->hdr.block_size * f->hdr.size; > > FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size); > > > > - /* Align to erase size */ > > - f->cached_size |= (erase_size - 1); > > - f->cached_size &= ~(erase_size - 1); > > - FL_DBG("FFS: Aligned to: 0x%x\n", f->cached_size); > > - > > /* Allocate cache */ > > f->cache = malloc(f->cached_size); > > if (!f->cache) { > > - free(f); > > - return FLASH_ERR_MALLOC_FAILED; > > + rc = FLASH_ERR_MALLOC_FAILED; > > + goto out; > > } > > > > /* Read the cached map */ > > - rc = flash_read(chip, offset, f->cache, f->cached_size); > > + rc = blocklevel_read(bl, offset, f->cache, f->cached_size); > > if (rc) { > > FL_ERR("FFS: Error %d reading flash partition map\n", rc); > > - free(f); > > + goto out; > > } > > + > > +out: > > if (rc == 0) > > *ffs = f; > > + else > > + free(f); > > + > > return rc; > > } > > > > @@ -361,6 +358,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t > > part_idx, ent->checksum = ffs_checksum(ent, FFS_ENTRY_SIZE_CSUM); > > if (!ffs->chip) > > return 0; > > - return flash_smart_write(ffs->chip, offset, ent, FFS_ENTRY_SIZE); > > + > > + return blocklevel_write(ffs->bl, offset, ent, FFS_ENTRY_SIZE); > > } > > > > diff --git a/libflash/libffs.h b/libflash/libffs.h > > index dd58d28..a310172 100644 > > --- a/libflash/libffs.h > > +++ b/libflash/libffs.h > > @@ -18,6 +18,7 @@ > > > > #include <libflash/libflash.h> > > #include <libflash/ffs.h> > > +#include <libflash/blocklevel.h> > > > > /* FFS handle, opaque */ > > struct ffs_handle; > > @@ -34,8 +35,10 @@ struct ffs_handle; > > #define FFS_ERR_PART_NOT_FOUND 103 > > #define FFS_ERR_BAD_ECC 104 > > > > -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, > > - uint32_t max_size, struct ffs_handle **ffs); > > +/* Init */ > > + > > +int ffs_init(uint32_t offset, uint32_t max_size, > > + struct blocklevel_device *bl, struct ffs_handle **ffs); > > > > /* ffs_open_image is Linux only as it uses lseek, which skiboot does not > > * implement */ > > diff --git a/libflash/libflash.c b/libflash/libflash.c > > index e43be4f..2af0c79 100644 > > --- a/libflash/libflash.c > > +++ b/libflash/libflash.c > > @@ -20,6 +20,7 @@ > > #include "libflash.h" > > #include "libflash-priv.h" > > #include "ecc.h" > > +#include "blocklevel.h" > > > > #ifndef MIN > > #define MIN(a, b) ((a) < (b) ? (a) : (b)) > > @@ -45,6 +46,7 @@ struct flash_chip { > > bool mode_4b; /* Flash currently in 4b mode > */ > > struct flash_req *cur_req; /* Current request */ > > void *smart_buf; /* Buffer for smart writes */ > > + struct blocklevel_device bl; > > }; > > > > #ifndef __SKIBOOT__ > > @@ -112,8 +114,9 @@ int fl_wren(struct spi_flash_ctrl *ct) > > return FLASH_ERR_WREN_TIMEOUT; > > } > > > > -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len) > > +static int flash_read(struct blocklevel_device *bl, uint32_t pos, void > > *buf, uint32_t len) { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > struct spi_flash_ctrl *ct = c->ctrl; > > > > /* XXX Add sanity/bound checking */ > > @@ -138,7 +141,7 @@ int flash_read(struct flash_chip *c, uint32_t pos, void > > *buf, uint32_t len) * This provides a wrapper around flash_read on ECCed > > data > > * len is length of data without ECC attached > > */ > > -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, > > +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void > > *buf, uint32_t len, bool ecc) > > { > > struct ecc64 *bufecc; > > @@ -147,7 +150,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t > > pos, void *buf, uint8_t ret; > > > > if (!ecc) > > - return flash_read(c, pos, buf, len); > > + return flash_read(bl, pos, buf, len); > > > > /* Copy the buffer in chunks */ > > bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); > > @@ -159,7 +162,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t > > pos, void *buf, copylen = MIN(len, COPY_BUFFER_LENGTH); > > > > /* Read ECCed data from flash */ > > - rc = flash_read(c, pos, bufecc, ECC_BUFFER_SIZE(copylen)); > > + rc = flash_read(bl, pos, bufecc, ECC_BUFFER_SIZE(copylen)); > > if (rc) > > goto err; > > > > @@ -215,8 +218,9 @@ static void fl_get_best_erase(struct flash_chip *c, > > uint32_t dst, uint32_t size, *cmd = CMD_BE; > > } > > > > -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size) > > +static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t > > size) { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > struct spi_flash_ctrl *ct = c->ctrl; > > uint32_t chunk; > > uint8_t cmd; > > @@ -262,8 +266,9 @@ int flash_erase(struct flash_chip *c, uint32_t dst, > > uint32_t size) return 0; > > } > > > > -int flash_erase_chip(struct flash_chip *c) > > +int flash_erase_chip(struct blocklevel_device *bl) > > { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > struct spi_flash_ctrl *ct = c->ctrl; > > int rc; > > > > @@ -311,9 +316,10 @@ static int fl_wpage(struct flash_chip *c, uint32_t dst, > > const void *src, return fl_sync_wait_idle(ct); > > } > > > > -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, > > +static int flash_write(struct blocklevel_device *bl, uint32_t dst, const > > void *src, uint32_t size, bool verify) > > { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > struct spi_flash_ctrl *ct = c->ctrl; > > uint32_t todo = size; > > uint32_t d = dst; > > @@ -374,7 +380,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, > > const void *src, chunk = sizeof(vbuf); > > if (chunk > size) > > chunk = size; > > - rc = flash_read(c, dst, vbuf, chunk); > > + rc = flash_read(bl, dst, vbuf, chunk); > > if (rc) return rc; > > if (memcmp(vbuf, src, chunk)) { > > FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst); > > @@ -387,7 +393,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, > > const void *src, return 0; > > } > > > > -int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void > > *buf, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t > > pos, const void *buf, uint32_t len, bool verify, bool ecc) > > { > > struct ecc64 *bufecc; > > @@ -396,7 +402,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t > > pos, const void *buf, uint8_t ret; > > > > if (!ecc) > > - return flash_write(c, pos, buf, len, verify); > > + return flash_write(bl, pos, buf, len, verify); > > > > /* Copy the buffer in chunks */ > > bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); > > @@ -415,7 +421,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t > > pos, const void *buf, } > > > > /* Write ECCed data to the flash */ > > - rc = flash_write(c, pos, bufecc, copylen, verify); > > + rc = flash_write(bl, pos, bufecc, copylen, verify); > > if (rc) > > goto err; > > > > @@ -463,12 +469,12 @@ static enum sm_comp_res flash_smart_comp(struct > > flash_chip *c, return is_same ? sm_no_change : sm_need_write; > > } > > > > -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, > > - uint32_t size) > > +static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, > > const void *src, uint32_t size) { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > uint32_t er_size = c->min_erase_mask + 1; > > uint32_t end = dst + size; > > - int rc; > > + int rc; > > > > /* Some sanity checking */ > > if (end <= dst || !size || end > c->tsize) { > > @@ -489,7 +495,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > dst, const void *src, off = dst & c->min_erase_mask; > > FL_DBG("LIBFLASH: reading page 0x%08x..0x%08x...", > > page, page + er_size); > > - rc = flash_read(c, page, c->smart_buf, er_size); > > + rc = flash_read(bl, page, c->smart_buf, er_size); > > if (rc) { > > FL_DBG(" error %d!\n", rc); > > return rc; > > @@ -510,7 +516,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > dst, const void *src, case sm_need_write: > > /* Just needs writing over */ > > FL_DBG(" need write !\n"); > > - rc = flash_write(c, dst, src, chunk, true); > > + rc = flash_write(bl, dst, src, chunk, true); > > if (rc) { > > FL_DBG("LIBFLASH: Write error %d !\n", rc); > > return rc; > > @@ -518,14 +524,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > dst, const void *src, break; > > case sm_need_erase: > > FL_DBG(" need erase !\n"); > > - rc = flash_erase(c, page, er_size); > > + rc = flash_erase(bl, page, er_size); > > if (rc) { > > FL_DBG("LIBFLASH: erase error %d !\n", rc); > > return rc; > > } > > /* Then update the portion of the buffer and write the > block */ > > memcpy(c->smart_buf + off, src, chunk); > > - rc = flash_write(c, page, c->smart_buf, er_size, > true); > > + rc = flash_write(bl, page, c->smart_buf, er_size, > true); > > if (rc) { > > FL_DBG("LIBFLASH: write error %d !\n", rc); > > return rc; > > @@ -539,14 +545,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > dst, const void *src, return 0; > > } > > > > -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const > > void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, > > uint32_t dst, const void *src, uint32_t size, bool ecc) > > { > > struct ecc64 *buf; > > int rc; > > > > if (!ecc) > > - return flash_smart_write(c, dst, src, size); > > + return flash_smart_write(bl, dst, src, size); > > > > buf = malloc(ECC_BUFFER_SIZE(size)); > > if (!buf) > > @@ -558,7 +564,7 @@ int flash_smart_write_corrected(struct flash_chip *c, > > uint32_t dst, const void * goto out; > > } > > > > - rc = flash_smart_write(c, dst, buf, ECC_BUFFER_SIZE(size)); > > + rc = flash_smart_write(bl, dst, buf, ECC_BUFFER_SIZE(size)); > > > > out: > > free(buf); > > @@ -684,8 +690,9 @@ static int flash_set_4b(struct flash_chip *c, bool > > enable) return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, > > 0); } > > > > -int flash_force_4b_mode(struct flash_chip *c, bool enable_4b) > > +int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b) > > { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > struct spi_flash_ctrl *ct = c->ctrl; > > int rc; > > > > @@ -776,24 +783,29 @@ static int flash_configure(struct flash_chip *c) > > return 0; > > } > > > > -int flash_get_info(struct flash_chip *chip, const char **name, > > +static int flash_get_info(struct blocklevel_device *bl, const char **name, > > uint32_t *total_size, uint32_t *erase_granule) > > { > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > if (name) > > - *name = chip->info.name; > > + *name = c->info.name; > > if (total_size) > > - *total_size = chip->tsize; > > + *total_size = c->tsize; > > if (erase_granule) > > - *erase_granule = chip->min_erase_mask + 1; > > + *erase_granule = c->min_erase_mask + 1; > > return 0; > > } > > > > -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash) > > +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl) > > { > > struct flash_chip *c; > > int rc; > > > > - *flash = NULL; > > + if (!bl) > > + return FLASH_ERR_PARM_ERROR; > > + > > + *bl = NULL; > > + > > c = malloc(sizeof(struct flash_chip)); > > if (!c) > > return FLASH_ERR_MALLOC_FAILED; > > @@ -814,18 +826,25 @@ int flash_init(struct spi_flash_ctrl *ctrl, struct > > flash_chip **flash) rc = flash_configure(c); > > if (rc) > > FL_ERR("LIBFLASH: Flash configuration failed\n"); > > - bail: > > +bail: > > if (rc) { > > free(c); > > return rc; > > } > > - *flash = c; > > + > > + c->bl.read = &flash_read; > > + c->bl.write = &flash_smart_write; > > + c->bl.erase = &flash_erase; > > + c->bl.get_info = &flash_get_info; > > + > > + *bl = &(c->bl); > > return 0; > > } > > > > -void flash_exit(struct flash_chip *chip) > > +void flash_exit(struct blocklevel_device *bl) > > { > > /* XXX Make sure we are idle etc... */ > > - free(chip); > > + if (bl) > > + free(container_of(bl, struct flash_chip, bl)); > > } > > > > diff --git a/libflash/libflash.h b/libflash/libflash.h > > index 7ed65d0..30f984d 100644 > > --- a/libflash/libflash.h > > +++ b/libflash/libflash.h > > @@ -18,6 +18,7 @@ > > > > #include <stdint.h> > > #include <stdbool.h> > > +#include <libflash/blocklevel.h> > > > > #ifdef __SKIBOOT__ > > #include <skiboot.h> > > @@ -59,18 +60,13 @@ extern bool libflash_debug; > > struct flash_chip; > > struct spi_flash_ctrl; > > > > -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash); > > -void flash_exit(struct flash_chip *chip); > > - > > -int flash_get_info(struct flash_chip *chip, const char **name, > > - uint32_t *total_size, uint32_t *erase_granule); > > +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl); > > +void flash_exit(struct blocklevel_device *bl); > > > > /* libflash sets the 4b mode automatically based on the flash > > * size and controller capabilities but it can be overriden > > */ > > -int flash_force_4b_mode(struct flash_chip *chip, bool enable_4b); > > - > > -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t > > len); +int flash_force_4b_mode(struct blocklevel_device *bl, bool > > enable_4b); > > > > /* > > * This provides a wapper around flash_read() on ECCed data. All params are > > @@ -80,11 +76,8 @@ int flash_read(struct flash_chip *c, uint32_t pos, void > > *buf, uint32_t len); * len is length of data without ecc attached therefore > > this will read beyond * pos + len. > > */ > > -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, > > +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void > > *buf, uint32_t len, bool ecc); > > -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size); > > -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, > > - uint32_t size, bool verify); > > > > /* > > * This provides a wrapper around flash_write() on ECCed data. All params > > are @@ -94,10 +87,8 @@ int flash_write(struct flash_chip *c, uint32_t dst, > > const void *src, * size is length of data without ECC attached therefore > > this will write beyond * dst + size. > > */ > > -int flash_write_corrected(struct flash_chip *c, uint32_t dst, const void > > *src, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t > > dst, const void *src, uint32_t size, bool verify, bool ecc); > > -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, > > - uint32_t size); > > > > /* > > * This provides a wrapper around flash_smart_write() on ECCed data. All > > @@ -107,12 +98,12 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > dst, const void *src, * size is length of data without ECC attached > > therefore this will write beyond * dst + size. > > */ > > -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const > > void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, > > uint32_t dst, const void *src, uint32_t size, bool ecc); > > > > /* chip erase may not be supported by all chips/controllers, get ready > > * for FLASH_ERR_CHIP_ER_NOT_SUPPORTED > > */ > > -int flash_erase_chip(struct flash_chip *c); > > +int flash_erase_chip(struct blocklevel_device *bl); > > > > #endif /* __LIBFLASH_H */ > > diff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c > > index 4479b5a..cf2b3a5 100644 > > --- a/libflash/test/test-flash.c > > +++ b/libflash/test/test-flash.c > > @@ -366,7 +366,7 @@ struct spi_flash_ctrl sim_ctrl = { > > > > int main(void) > > { > > - struct flash_chip *fl; > > + struct blocklevel_device *bl; > > uint32_t total_size, erase_granule; > > const char *name; > > uint16_t *test; > > @@ -378,12 +378,12 @@ int main(void) > > memset(sim_image, 0xff, sim_image_sz); > > test = malloc(0x10000 * 2); > > > > - rc = flash_init(&sim_ctrl, &fl); > > + rc = flash_init(&sim_ctrl, &bl); > > if (rc) { > > ERR("flash_init failed with err %d\n", rc); > > exit(1); > > } > > - rc = flash_get_info(fl, &name, &total_size, &erase_granule); > > + rc = flash_get_info(bl, &name, &total_size, &erase_granule); > > if (rc) { > > ERR("flash_get_info failed with err %d\n", rc); > > exit(1); > > @@ -395,13 +395,13 @@ int main(void) > > > > /* Write 64k of stuff at 0 and at 128k */ > > printf("Writing test patterns...\n"); > > - flash_smart_write(fl, 0, test, 0x10000); > > - flash_smart_write(fl, 0x20000, test, 0x10000); > > + flash_smart_write(bl, 0, test, 0x10000); > > + flash_smart_write(bl, 0x20000, test, 0x10000); > > > > /* Write "Hello world" straddling the 64k boundary */ > > #define HW "Hello World" > > printf("Writing test string...\n"); > > - flash_smart_write(fl, 0xfffc, HW, sizeof(HW)); > > + flash_smart_write(bl, 0xfffc, HW, sizeof(HW)); > > > > /* Check result */ > > if (memcmp(sim_image + 0xfffc, HW, sizeof(HW))) { > > @@ -416,7 +416,7 @@ int main(void) > > printf("Test pattern pass\n"); > > > > printf("Test ECC interfaces\n"); > > - flash_smart_write_corrected(fl, 0, test, 0x10000, 1); > > + flash_smart_write_corrected(bl, 0, test, 0x10000, 1); > > ecc_test = (struct ecc64 *)sim_image; > > test64 = (uint64_t *)test; > > for (i = 0; i < 0x10000 / sizeof(*ecc_test); i++) { > > @@ -433,7 +433,7 @@ int main(void) > > printf("Test ECC interface pass\n"); > > > > printf("Test ECC erase\n"); > > - if (flash_erase(fl, 0, 0x10000) != 0) { > > + if (flash_erase(bl, 0, 0x10000) != 0) { > > ERR("flash_erase didn't return 0\n"); > > exit(1); > > } > > @@ -444,7 +444,7 @@ int main(void) > > ERR("Data not properly cleared at %d\n", i); > > exit(1); > > } > > - rc = flash_write(fl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); > > + rc = flash_write(bl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); > > if (rc || ecc_test[i].ecc != 0) { > > ERR("Cleared data not correctly ECCed: 0x%02x > (0x%016lx) expecting 0 at > > %d\n", ecc_test[i].ecc, ecc_test[i].data, i); exit(1); > > @@ -452,7 +452,7 @@ int main(void) > > } > > printf("Test ECC erase pass\n"); > > > > - flash_exit(fl); > > + flash_exit(bl); > > > > return 0; > > } > > diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c > > index d294c1f..634cb86 100644 > > --- a/platforms/astbmc/pnor.c > > +++ b/platforms/astbmc/pnor.c > > @@ -20,6 +20,7 @@ > > #include <opal.h> > > #include <libflash/libflash.h> > > #include <libflash/libffs.h> > > +#include <libflash/blocklevel.h> > > #include <ast.h> > > > > #include "astbmc.h" > > @@ -27,7 +28,7 @@ > > int pnor_init(void) > > { > > struct spi_flash_ctrl *pnor_ctrl; > > - struct flash_chip *pnor_chip = NULL; > > + struct blocklevel_device *bl; > > int rc; > > > > /* Open controller and flash. If the LPC->AHB doesn't point to > > @@ -44,19 +45,20 @@ int pnor_init(void) > > prerror("PLAT: Failed to open PNOR flash controller\n"); > > goto fail; > > } > > - rc = flash_init(pnor_ctrl, &pnor_chip); > > + > > + rc = flash_init(pnor_ctrl, &bl); > > if (rc) { > > prerror("PLAT: Failed to open init PNOR driver\n"); > > goto fail; > > } > > > > - rc = flash_register(pnor_chip, true); > > + rc = flash_register(bl, true); > > if (!rc) > > return 0; > > > > fail: > > - if (pnor_chip) > > - flash_exit(pnor_chip); > > + if (bl) > > + flash_exit(bl); > > if (pnor_ctrl) > > ast_sf_close(pnor_ctrl); > > > > diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c > > index 27e1c91..855d0e4 100644 > > --- a/platforms/rhesus/rhesus.c > > +++ b/platforms/rhesus/rhesus.c > > @@ -22,6 +22,7 @@ > > #include <opal.h> > > #include <libflash/libflash.h> > > #include <libflash/libffs.h> > > +#include <libflash/blocklevel.h> > > #include <sfc-ctrl.h> > > #include <ec/config.h> > > #include <ec/gpio.h> > > @@ -118,7 +119,7 @@ static int64_t rhesus_power_down(uint64_t request > > __unused) static int rhesus_pnor_init(void) > > { > > struct spi_flash_ctrl *pnor_ctrl; > > - struct flash_chip *pnor_chip = NULL; > > + struct blocklevel_device *bl; > > int rc; > > > > /* Open controller, flash and ffs */ > > @@ -127,19 +128,19 @@ static int rhesus_pnor_init(void) > > prerror("PLAT: Failed to open PNOR flash controller\n"); > > goto fail; > > } > > - rc = flash_init(pnor_ctrl, &pnor_chip); > > + rc = flash_init(pnor_ctrl, &bl); > > if (rc) { > > prerror("PLAT: Failed to open init PNOR driver\n"); > > goto fail; > > } > > > > - rc = flash_register(pnor_chip, true); > > + rc = flash_register(bl, true); > > if (!rc) > > return 0; > > > > fail: > > - if (pnor_chip) > > - flash_exit(pnor_chip); > > + if (bl) > > + flash_exit(bl); > > if (pnor_ctrl) > > sfc_close(pnor_ctrl); >
On Thu, 2015-05-21 at 17:31 +1000, Cyril Bur wrote: > On Thu, 2015-05-21 at 11:53 +1000, Alistair Popple wrote: > > This looks ok, my only concern is that changing flash_write -> > > flash_smart_write in pflash is likely to reduce pflash performance. Is there a > > way we could not make that change in pflash for the moment? I have an idea for > > how we could fix it properly, but that change would be easier to do if we had > > these patches applied. > > > > Agreed, however this all depends on if it is actually slower. I'll > confirm that tomorrow, if it is, we'll leave flash_write() exposed for > pflash. > So, to my surprise (top one is new pflash): # time /tmp/pflash -E -p /tmp/palmetto.pnor About to erase chip ! WARNING ! This will modify your HOST flash chip content ! Enter "yes" to confirm:yes Erasing... (may take a while !) done ! About to program "/tmp/palmetto.pnor" at 0x00000000..0x02000000 ! Programming & Verifying... [==================================================] 100% ETA:0s real 3m 1.11s user 2m 54.24s sys 0m 0.82s # time pflash -E -p /tmp/palmetto.pnor About to erase chip ! WARNING ! This will modify your HOST flash chip content ! Enter "yes" to confirm:yes Erasing... (may take a while !) done ! About to program "/tmp/palmetto.pnor" at 0x00000000..0x02000000 ! Programming & Verifying... [==================================================] 100% ETA:0s real 2m 59.80s user 2m 50.82s sys 0m 0.93s Makes 'no' difference. > The solution from there would be to make flash_smart_write() smarter and > ultimately wind up in blocklevel. > > > Signed-off-by: Alistair Popple <alistair@popple.id.au> > > Reviewed-by: Alistair Popple <alistair@popple.id.au> > > > > On Thu, 14 May 2015 17:06:39 Cyril Bur wrote: > > > Converted all the libflash calls to use the blocklevel interface, modified > > > all callers to libflash to use the blocklevel interface. > > > > > > This patch should introduce next to no functional change. > > > > > > Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com> > > > --- > > > core/flash.c | 35 ++++++++++--------- > > > external/pflash/Makefile | 2 +- > > > external/pflash/pflash.c | 33 +++++++++--------- > > > include/skiboot.h | 4 ++- > > > libflash/libffs.c | 52 ++++++++++++++--------------- > > > libflash/libffs.h | 7 ++-- > > > libflash/libflash.c | 83 > > > ++++++++++++++++++++++++++++------------------ libflash/libflash.h | > > > 25 +++++--------- > > > libflash/test/test-flash.c | 20 +++++------ > > > platforms/astbmc/pnor.c | 12 ++++--- > > > platforms/rhesus/rhesus.c | 11 +++--- > > > 11 files changed, 153 insertions(+), 131 deletions(-) > > > > > > diff --git a/core/flash.c b/core/flash.c > > > index 9018ecd..90dbac7 100644 > > > --- a/core/flash.c > > > +++ b/core/flash.c > > > @@ -22,12 +22,13 @@ > > > #include <device.h> > > > #include <libflash/libflash.h> > > > #include <libflash/libffs.h> > > > +#include <libflash/blocklevel.h> > > > #include <ecc.h> > > > > > > struct flash { > > > bool registered; > > > bool busy; > > > - struct flash_chip *chip; > > > + struct blocklevel_device *bl; > > > uint32_t size; > > > uint32_t block_size; > > > }; > > > @@ -108,7 +109,7 @@ static int flash_nvram_start_read(void *dst, uint32_t > > > src, uint32_t len) goto out; > > > } > > > > > > - rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len); > > > + rc = blocklevel_read(nvram_flash->bl, nvram_offset + src, dst, len); > > > > > > out: > > > unlock(&flash_lock); > > > @@ -137,7 +138,7 @@ static int flash_nvram_write(uint32_t dst, void *src, > > > uint32_t len) rc = OPAL_PARAMETER; > > > goto out; > > > } > > > - rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, > > len); > > > + rc = blocklevel_write(nvram_flash->bl, nvram_offset + dst, src, len); > > > > > > out: > > > unlock(&flash_lock); > > > @@ -250,7 +251,7 @@ static void setup_system_flash(struct flash *flash, > > > struct dt_node *node, flash_nvram_probe(flash, ffs); > > > } > > > > > > -int flash_register(struct flash_chip *chip, bool is_system_flash) > > > +int flash_register(struct blocklevel_device *bl, bool is_system_flash) > > > { > > > uint32_t size, block_size; > > > struct ffs_handle *ffs; > > > @@ -260,7 +261,7 @@ int flash_register(struct flash_chip *chip, bool > > > is_system_flash) unsigned int i; > > > int rc; > > > > > > - rc = flash_get_info(chip, &name, &size, &block_size); > > > + rc = blocklevel_get_info(bl, &name, &size, &block_size); > > > if (rc) > > > return rc; > > > > > > @@ -276,7 +277,7 @@ int flash_register(struct flash_chip *chip, bool > > > is_system_flash) flash = &flashes[i]; > > > flash->registered = true; > > > flash->busy = false; > > > - flash->chip = chip; > > > + flash->bl = bl; > > > flash->size = size; > > > flash->block_size = block_size; > > > break; > > > @@ -288,7 +289,7 @@ int flash_register(struct flash_chip *chip, bool > > > is_system_flash) return OPAL_RESOURCE; > > > } > > > > > > - rc = ffs_open_flash(chip, 0, flash->size, &ffs); > > > + rc = ffs_init(0, flash->size, bl, &ffs); > > > if (rc) { > > > prlog(PR_WARNING, "FLASH: No ffs info; " > > > "using raw device only\n"); > > > @@ -346,13 +347,17 @@ static int64_t opal_flash_op(enum flash_op op, > > > uint64_t id, uint64_t offset, > > > > > > switch (op) { > > > case FLASH_OP_READ: > > > - rc = flash_read(flash->chip, offset, (void *)buf, size); > > > + rc = blocklevel_read(flash->bl, offset, (void *)buf, size); > > > break; > > > case FLASH_OP_WRITE: > > > - rc = flash_write(flash->chip, offset, (void *)buf, size, > > false); > > > + /* > > > + * Note: blocklevel_write() uses flash_smart_write(), this > > call used to > > > + * be flash_write() > > > + */ > > > + rc = blocklevel_write(flash->bl, offset, (void *)buf, size); > > > break; > > > case FLASH_OP_ERASE: > > > - rc = flash_erase(flash->chip, offset, size); > > > + rc = blocklevel_erase(flash->bl, offset, size); > > > break; > > > default: > > > assert(0); > > > @@ -425,7 +430,7 @@ struct flash_hostboot_header { > > > }; > > > > > > /* start and total size include ECC */ > > > -static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid, > > > +static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t > > > subid, uint32_t *start, uint32_t *total_size, > > > bool *ecc) > > > { > > > @@ -444,7 +449,7 @@ static int flash_find_subpartition(struct flash_chip > > > *chip, uint32_t subid, partsize = BUFFER_SIZE_MINUS_ECC(*total_size); > > > > > > /* Get the TOC */ > > > - rc = flash_read_corrected(chip, *start, header, > > > + rc = flash_read_corrected(bl, *start, header, > > > FLASH_SUBPART_HEADER_SIZE, ecc); > > > if (rc) { > > > prerror("FLASH: flash subpartition TOC read failed %i\n", rc); > > > @@ -564,7 +569,7 @@ static int flash_load_resource(enum resource_id id, > > > uint32_t subid, goto out_unlock; > > > } > > > > > > - rc = ffs_open_flash(flash->chip, 0, flash->size, &ffs); > > > + rc = ffs_init(0, flash->size, flash->bl, &ffs); > > > if (rc) { > > > prerror("FLASH: Can't open ffs handle\n"); > > > goto out_unlock; > > > @@ -591,7 +596,7 @@ static int flash_load_resource(enum resource_id id, > > > uint32_t subid, > > > > > > /* Find the sub partition if required */ > > > if (subid != RESOURCE_SUBID_NONE) { > > > - rc = flash_find_subpartition(flash->chip, subid, &part_start, > > > + rc = flash_find_subpartition(flash->bl, subid, &part_start, > > > &part_size, &ecc); > > > if (rc) > > > goto out_free_ffs; > > > @@ -614,7 +619,7 @@ static int flash_load_resource(enum resource_id id, > > > uint32_t subid, goto out_free_ffs; > > > } > > > > > > - rc = flash_read_corrected(flash->chip, part_start, buf, size, ecc); > > > + rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc); > > > if (rc) { > > > prerror("FLASH: failed to read %s partition\n", name); > > > goto out_free_ffs; > > > diff --git a/external/pflash/Makefile b/external/pflash/Makefile > > > index c28e359..7771343 100644 > > > --- a/external/pflash/Makefile > > > +++ b/external/pflash/Makefile > > > @@ -14,7 +14,7 @@ endif > > > CFLAGS = -O2 -Wall -I. > > > LDFLAGS = -lrt > > > OBJS = pflash.o progress.o ast-sf-ctrl.o > > > -OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o > > > +OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o > > > libflash/blocklevel.o OBJS += $(ARCH_OBJS) > > > EXE = pflash > > > > > > diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c > > > index fb783a2..0958691 100644 > > > --- a/external/pflash/pflash.c > > > +++ b/external/pflash/pflash.c > > > @@ -16,6 +16,7 @@ > > > > > > #include <libflash/libflash.h> > > > #include <libflash/libffs.h> > > > +#include <libflash/blocklevel.h> > > > #include "progress.h" > > > #include "io.h" > > > #include "ast.h" > > > @@ -23,7 +24,7 @@ > > > > > > #define __aligned(x) __attribute__((aligned(x))) > > > > > > -#define PFLASH_VERSION "0.8.6" > > > +#define PFLASH_VERSION "0.8.7" > > > > > > static bool must_confirm = true; > > > static bool dummy_run; > > > @@ -36,8 +37,8 @@ static bool using_sfc; > > > #define FILE_BUF_SIZE 0x10000 > > > static uint8_t file_buf[FILE_BUF_SIZE] __aligned(0x1000); > > > > > > +static struct blocklevel_device *bl; > > > static struct spi_flash_ctrl *fl_ctrl; > > > -static struct flash_chip *fl_chip; > > > static struct ffs_handle *ffsh; > > > static uint32_t fl_total_size, fl_erase_granule; > > > static const char *fl_name; > > > @@ -84,7 +85,7 @@ static void print_flash_info(void) > > > return; > > > > > > if (!ffsh) { > > > - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); > > > + rc = ffs_init(0, fl_total_size, bl, &ffsh); > > > if (rc) { > > > fprintf(stderr, "Error %d opening ffs !\n", rc); > > > ffsh = NULL; > > > @@ -122,7 +123,7 @@ static void lookup_partition(const char *name) > > > > > > /* Open libffs if needed */ > > > if (!ffsh) { > > > - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); > > > + rc = ffs_init(0, fl_total_size, bl, &ffsh); > > > if (rc) { > > > fprintf(stderr, "Error %d opening ffs !\n", rc); > > > exit(1); > > > @@ -158,7 +159,7 @@ static void erase_chip(void) > > > return; > > > } > > > > > > - rc = flash_erase_chip(fl_chip); > > > + rc = flash_erase_chip(bl); > > > if (rc) { > > > fprintf(stderr, "Error %d erasing chip\n", rc); > > > exit(1); > > > @@ -185,7 +186,7 @@ static void erase_range(uint32_t start, uint32_t size, > > > bool will_program) while(size) { > > > /* If aligned to 64k and at least 64k, use 64k erase */ > > > if ((start & 0xffff) == 0 && size >= 0x10000) { > > > - rc = flash_erase(fl_chip, start, 0x10000); > > > + rc = blocklevel_erase(bl, start, 0x10000); > > > if (rc) { > > > fprintf(stderr, "Error %d erasing 0x%08x\n", > > > rc, start); > > > @@ -195,7 +196,7 @@ static void erase_range(uint32_t start, uint32_t size, > > > bool will_program) size -= 0x10000; > > > done += 0x10000; > > > } else { > > > - rc = flash_erase(fl_chip, start, 0x1000); > > > + rc = blocklevel_erase(bl, start, 0x1000); > > > if (rc) { > > > fprintf(stderr, "Error %d erasing 0x%08x\n", > > > rc, start); > > > @@ -252,7 +253,7 @@ static void program_file(const char *file, uint32_t > > > start, uint32_t size) len = size; > > > size -= len; > > > actual_size += len; > > > - rc = flash_write(fl_chip, start, file_buf, len, true); > > > + rc = blocklevel_write(bl, start, file_buf, len); > > > if (rc) { > > > if (rc == FLASH_ERR_VERIFY_FAILURE) > > > fprintf(stderr, "Verification failed for" > > > @@ -292,7 +293,7 @@ static void do_read_file(const char *file, uint32_t > > > start, uint32_t size) progress_init(size >> 8); > > > while(size) { > > > len = size > FILE_BUF_SIZE ? FILE_BUF_SIZE : size; > > > - rc = flash_read(fl_chip, start, file_buf, len); > > > + rc = blocklevel_read(bl, start, file_buf, len); > > > if (rc) { > > > fprintf(stderr, "Flash read error %d for" > > > " chunk at 0x%08x\n", rc, start); > > > @@ -318,7 +319,7 @@ static void enable_4B_addresses(void) > > > > > > printf("Switching to 4-bytes address mode\n"); > > > > > > - rc = flash_force_4b_mode(fl_chip, true); > > > + rc = flash_force_4b_mode(bl, true); > > > if (rc) { > > > fprintf(stderr, "Error %d enabling 4b mode\n", rc); > > > exit(1); > > > @@ -331,7 +332,7 @@ static void disable_4B_addresses(void) > > > > > > printf("Switching to 3-bytes address mode\n"); > > > > > > - rc = flash_force_4b_mode(fl_chip, false); > > > + rc = flash_force_4b_mode(bl, false); > > > if (rc) { > > > fprintf(stderr, "Error %d disabling 4b mode\n", rc); > > > exit(1); > > > @@ -342,7 +343,7 @@ static void flash_access_cleanup_bmc(void) > > > { > > > if (ffsh) > > > ffs_close(ffsh); > > > - flash_exit(fl_chip); > > > + flash_exit(bl); > > > ast_sf_close(fl_ctrl); > > > close_devs(); > > > } > > > @@ -362,7 +363,7 @@ static void flash_access_setup_bmc(bool use_lpc, bool > > > need_write) } > > > > > > /* Open flash chip */ > > > - rc = flash_init(fl_ctrl, &fl_chip); > > > + rc = flash_init(fl_ctrl, &bl); > > > if (rc) { > > > fprintf(stderr, "Failed to open flash chip\n"); > > > exit(1); > > > @@ -380,7 +381,7 @@ static void flash_access_cleanup_pnor(void) > > > > > > if (ffsh) > > > ffs_close(ffsh); > > > - flash_exit(fl_chip); > > > + flash_exit(bl); > > > #ifdef __powerpc__ > > > if (using_sfc) > > > sfc_close(fl_ctrl); > > > @@ -421,7 +422,7 @@ static void flash_access_setup_pnor(bool use_lpc, bool > > > use_sfc, bool need_write) #endif > > > > > > /* Open flash chip */ > > > - rc = flash_init(fl_ctrl, &fl_chip); > > > + rc = flash_init(fl_ctrl, &bl); > > > if (rc) { > > > fprintf(stderr, "Failed to open flash chip\n"); > > > exit(1); > > > @@ -698,7 +699,7 @@ int main(int argc, char *argv[]) > > > flash_access_setup_pnor(use_lpc, has_sfc, erase || program); > > > } > > > > > > - rc = flash_get_info(fl_chip, &fl_name, > > > + rc = blocklevel_get_info(bl, &fl_name, > > > &fl_total_size, &fl_erase_granule); > > > if (rc) { > > > fprintf(stderr, "Error %d getting flash info\n", rc); > > > diff --git a/include/skiboot.h b/include/skiboot.h > > > index 9751a31..aa92f68 100644 > > > --- a/include/skiboot.h > > > +++ b/include/skiboot.h > > > @@ -36,6 +36,8 @@ > > > #include <ccan/endian/endian.h> > > > #include <ccan/str/str.h> > > > > > > +#include <libflash/blocklevel.h> > > > + > > > #include <mem-map.h> > > > #include <op-panel.h> > > > #include <platform.h> > > > @@ -214,7 +216,7 @@ extern void occ_fsp_init(void); > > > > > > /* flash support */ > > > struct flash_chip; > > > -extern int flash_register(struct flash_chip *chip, bool is_system_flash); > > > +extern int flash_register(struct blocklevel_device *bl, bool > > > is_system_flash); extern int flash_start_preload_resource(enum resource_id > > > id, uint32_t subid, void *buf, size_t *len); > > > extern int flash_resource_loaded(enum resource_id id, uint32_t idx); > > > diff --git a/libflash/libffs.c b/libflash/libffs.c > > > index 2d05cc9..8a60bee 100644 > > > --- a/libflash/libffs.c > > > +++ b/libflash/libffs.c > > > @@ -41,6 +41,7 @@ struct ffs_handle { > > > uint32_t max_size; > > > void *cache; > > > uint32_t cached_size; > > > + struct blocklevel_device *bl; > > > }; > > > > > > static uint32_t ffs_checksum(void* data, size_t size) > > > @@ -71,31 +72,29 @@ static int ffs_check_convert_header(struct ffs_hdr *dst, > > > struct ffs_hdr *src) return 0; > > > } > > > > > > -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, > > > - uint32_t max_size, struct ffs_handle **ffs) > > > +int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device > > > *bl, + struct ffs_handle **ffs) > > > { > > > struct ffs_hdr hdr; > > > struct ffs_handle *f; > > > - uint32_t fl_size, erase_size; > > > + uint32_t total_size; > > > int rc; > > > > > > - if (!ffs) > > > + if (!ffs || !bl) > > > return FLASH_ERR_PARM_ERROR; > > > *ffs = NULL; > > > > > > - /* Grab some info about our flash chip */ > > > - rc = flash_get_info(chip, NULL, &fl_size, &erase_size); > > > + rc = blocklevel_get_info(bl, NULL, &total_size, NULL); > > > if (rc) { > > > - FL_ERR("FFS: Error %d retrieving flash info\n", rc); > > > - return rc; > > > - } > > > - if ((offset + max_size) < offset) > > > + FL_ERR("FFS: Error %d getting device total size", rc); > > > return FLASH_ERR_PARM_ERROR; > > > - if ((offset + max_size) > fl_size) > > > + } > > > + > > > + if ((offset + max_size) < offset || (offset + max_size) > total_size) > > > return FLASH_ERR_PARM_ERROR; > > > > > > /* Read flash header */ > > > - rc = flash_read(chip, offset, &hdr, sizeof(hdr)); > > > + rc = blocklevel_read(bl, offset, &hdr, sizeof(hdr)); > > > if (rc) { > > > FL_ERR("FFS: Error %d reading flash header\n", rc); > > > return rc; > > > @@ -106,17 +105,15 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t > > > offset, if (!f) > > > return FLASH_ERR_MALLOC_FAILED; > > > memset(f, 0, sizeof(*f)); > > > - f->type = ffs_type_flash; > > > f->flash_offset = offset; > > > - f->max_size = max_size ? max_size : (fl_size - offset); > > > - f->chip = chip; > > > + f->max_size = max_size; > > > + f->bl = bl; > > > > > > /* Convert and check flash header */ > > > rc = ffs_check_convert_header(&f->hdr, &hdr); > > > if (rc) { > > > FL_ERR("FFS: Error %d checking flash header\n", rc); > > > - free(f); > > > - return rc; > > > + goto out; > > > } > > > > > > /* > > > @@ -126,26 +123,26 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t > > > offset, f->cached_size = f->hdr.block_size * f->hdr.size; > > > FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size); > > > > > > - /* Align to erase size */ > > > - f->cached_size |= (erase_size - 1); > > > - f->cached_size &= ~(erase_size - 1); > > > - FL_DBG("FFS: Aligned to: 0x%x\n", f->cached_size); > > > - > > > /* Allocate cache */ > > > f->cache = malloc(f->cached_size); > > > if (!f->cache) { > > > - free(f); > > > - return FLASH_ERR_MALLOC_FAILED; > > > + rc = FLASH_ERR_MALLOC_FAILED; > > > + goto out; > > > } > > > > > > /* Read the cached map */ > > > - rc = flash_read(chip, offset, f->cache, f->cached_size); > > > + rc = blocklevel_read(bl, offset, f->cache, f->cached_size); > > > if (rc) { > > > FL_ERR("FFS: Error %d reading flash partition map\n", rc); > > > - free(f); > > > + goto out; > > > } > > > + > > > +out: > > > if (rc == 0) > > > *ffs = f; > > > + else > > > + free(f); > > > + > > > return rc; > > > } > > > > > > @@ -361,6 +358,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t > > > part_idx, ent->checksum = ffs_checksum(ent, FFS_ENTRY_SIZE_CSUM); > > > if (!ffs->chip) > > > return 0; > > > - return flash_smart_write(ffs->chip, offset, ent, FFS_ENTRY_SIZE); > > > + > > > + return blocklevel_write(ffs->bl, offset, ent, FFS_ENTRY_SIZE); > > > } > > > > > > diff --git a/libflash/libffs.h b/libflash/libffs.h > > > index dd58d28..a310172 100644 > > > --- a/libflash/libffs.h > > > +++ b/libflash/libffs.h > > > @@ -18,6 +18,7 @@ > > > > > > #include <libflash/libflash.h> > > > #include <libflash/ffs.h> > > > +#include <libflash/blocklevel.h> > > > > > > /* FFS handle, opaque */ > > > struct ffs_handle; > > > @@ -34,8 +35,10 @@ struct ffs_handle; > > > #define FFS_ERR_PART_NOT_FOUND 103 > > > #define FFS_ERR_BAD_ECC 104 > > > > > > -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, > > > - uint32_t max_size, struct ffs_handle **ffs); > > > +/* Init */ > > > + > > > +int ffs_init(uint32_t offset, uint32_t max_size, > > > + struct blocklevel_device *bl, struct ffs_handle **ffs); > > > > > > /* ffs_open_image is Linux only as it uses lseek, which skiboot does not > > > * implement */ > > > diff --git a/libflash/libflash.c b/libflash/libflash.c > > > index e43be4f..2af0c79 100644 > > > --- a/libflash/libflash.c > > > +++ b/libflash/libflash.c > > > @@ -20,6 +20,7 @@ > > > #include "libflash.h" > > > #include "libflash-priv.h" > > > #include "ecc.h" > > > +#include "blocklevel.h" > > > > > > #ifndef MIN > > > #define MIN(a, b) ((a) < (b) ? (a) : (b)) > > > @@ -45,6 +46,7 @@ struct flash_chip { > > > bool mode_4b; /* Flash currently in 4b mode > > */ > > > struct flash_req *cur_req; /* Current request */ > > > void *smart_buf; /* Buffer for smart writes */ > > > + struct blocklevel_device bl; > > > }; > > > > > > #ifndef __SKIBOOT__ > > > @@ -112,8 +114,9 @@ int fl_wren(struct spi_flash_ctrl *ct) > > > return FLASH_ERR_WREN_TIMEOUT; > > > } > > > > > > -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len) > > > +static int flash_read(struct blocklevel_device *bl, uint32_t pos, void > > > *buf, uint32_t len) { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > struct spi_flash_ctrl *ct = c->ctrl; > > > > > > /* XXX Add sanity/bound checking */ > > > @@ -138,7 +141,7 @@ int flash_read(struct flash_chip *c, uint32_t pos, void > > > *buf, uint32_t len) * This provides a wrapper around flash_read on ECCed > > > data > > > * len is length of data without ECC attached > > > */ > > > -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, > > > +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void > > > *buf, uint32_t len, bool ecc) > > > { > > > struct ecc64 *bufecc; > > > @@ -147,7 +150,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t > > > pos, void *buf, uint8_t ret; > > > > > > if (!ecc) > > > - return flash_read(c, pos, buf, len); > > > + return flash_read(bl, pos, buf, len); > > > > > > /* Copy the buffer in chunks */ > > > bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); > > > @@ -159,7 +162,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t > > > pos, void *buf, copylen = MIN(len, COPY_BUFFER_LENGTH); > > > > > > /* Read ECCed data from flash */ > > > - rc = flash_read(c, pos, bufecc, ECC_BUFFER_SIZE(copylen)); > > > + rc = flash_read(bl, pos, bufecc, ECC_BUFFER_SIZE(copylen)); > > > if (rc) > > > goto err; > > > > > > @@ -215,8 +218,9 @@ static void fl_get_best_erase(struct flash_chip *c, > > > uint32_t dst, uint32_t size, *cmd = CMD_BE; > > > } > > > > > > -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size) > > > +static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t > > > size) { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > struct spi_flash_ctrl *ct = c->ctrl; > > > uint32_t chunk; > > > uint8_t cmd; > > > @@ -262,8 +266,9 @@ int flash_erase(struct flash_chip *c, uint32_t dst, > > > uint32_t size) return 0; > > > } > > > > > > -int flash_erase_chip(struct flash_chip *c) > > > +int flash_erase_chip(struct blocklevel_device *bl) > > > { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > struct spi_flash_ctrl *ct = c->ctrl; > > > int rc; > > > > > > @@ -311,9 +316,10 @@ static int fl_wpage(struct flash_chip *c, uint32_t dst, > > > const void *src, return fl_sync_wait_idle(ct); > > > } > > > > > > -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, > > > +static int flash_write(struct blocklevel_device *bl, uint32_t dst, const > > > void *src, uint32_t size, bool verify) > > > { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > struct spi_flash_ctrl *ct = c->ctrl; > > > uint32_t todo = size; > > > uint32_t d = dst; > > > @@ -374,7 +380,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, > > > const void *src, chunk = sizeof(vbuf); > > > if (chunk > size) > > > chunk = size; > > > - rc = flash_read(c, dst, vbuf, chunk); > > > + rc = flash_read(bl, dst, vbuf, chunk); > > > if (rc) return rc; > > > if (memcmp(vbuf, src, chunk)) { > > > FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst); > > > @@ -387,7 +393,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, > > > const void *src, return 0; > > > } > > > > > > -int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void > > > *buf, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t > > > pos, const void *buf, uint32_t len, bool verify, bool ecc) > > > { > > > struct ecc64 *bufecc; > > > @@ -396,7 +402,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t > > > pos, const void *buf, uint8_t ret; > > > > > > if (!ecc) > > > - return flash_write(c, pos, buf, len, verify); > > > + return flash_write(bl, pos, buf, len, verify); > > > > > > /* Copy the buffer in chunks */ > > > bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); > > > @@ -415,7 +421,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t > > > pos, const void *buf, } > > > > > > /* Write ECCed data to the flash */ > > > - rc = flash_write(c, pos, bufecc, copylen, verify); > > > + rc = flash_write(bl, pos, bufecc, copylen, verify); > > > if (rc) > > > goto err; > > > > > > @@ -463,12 +469,12 @@ static enum sm_comp_res flash_smart_comp(struct > > > flash_chip *c, return is_same ? sm_no_change : sm_need_write; > > > } > > > > > > -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, > > > - uint32_t size) > > > +static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, > > > const void *src, uint32_t size) { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > uint32_t er_size = c->min_erase_mask + 1; > > > uint32_t end = dst + size; > > > - int rc; > > > + int rc; > > > > > > /* Some sanity checking */ > > > if (end <= dst || !size || end > c->tsize) { > > > @@ -489,7 +495,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > > dst, const void *src, off = dst & c->min_erase_mask; > > > FL_DBG("LIBFLASH: reading page 0x%08x..0x%08x...", > > > page, page + er_size); > > > - rc = flash_read(c, page, c->smart_buf, er_size); > > > + rc = flash_read(bl, page, c->smart_buf, er_size); > > > if (rc) { > > > FL_DBG(" error %d!\n", rc); > > > return rc; > > > @@ -510,7 +516,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > > dst, const void *src, case sm_need_write: > > > /* Just needs writing over */ > > > FL_DBG(" need write !\n"); > > > - rc = flash_write(c, dst, src, chunk, true); > > > + rc = flash_write(bl, dst, src, chunk, true); > > > if (rc) { > > > FL_DBG("LIBFLASH: Write error %d !\n", rc); > > > return rc; > > > @@ -518,14 +524,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > > dst, const void *src, break; > > > case sm_need_erase: > > > FL_DBG(" need erase !\n"); > > > - rc = flash_erase(c, page, er_size); > > > + rc = flash_erase(bl, page, er_size); > > > if (rc) { > > > FL_DBG("LIBFLASH: erase error %d !\n", rc); > > > return rc; > > > } > > > /* Then update the portion of the buffer and write the > > block */ > > > memcpy(c->smart_buf + off, src, chunk); > > > - rc = flash_write(c, page, c->smart_buf, er_size, > > true); > > > + rc = flash_write(bl, page, c->smart_buf, er_size, > > true); > > > if (rc) { > > > FL_DBG("LIBFLASH: write error %d !\n", rc); > > > return rc; > > > @@ -539,14 +545,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > > dst, const void *src, return 0; > > > } > > > > > > -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const > > > void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, > > > uint32_t dst, const void *src, uint32_t size, bool ecc) > > > { > > > struct ecc64 *buf; > > > int rc; > > > > > > if (!ecc) > > > - return flash_smart_write(c, dst, src, size); > > > + return flash_smart_write(bl, dst, src, size); > > > > > > buf = malloc(ECC_BUFFER_SIZE(size)); > > > if (!buf) > > > @@ -558,7 +564,7 @@ int flash_smart_write_corrected(struct flash_chip *c, > > > uint32_t dst, const void * goto out; > > > } > > > > > > - rc = flash_smart_write(c, dst, buf, ECC_BUFFER_SIZE(size)); > > > + rc = flash_smart_write(bl, dst, buf, ECC_BUFFER_SIZE(size)); > > > > > > out: > > > free(buf); > > > @@ -684,8 +690,9 @@ static int flash_set_4b(struct flash_chip *c, bool > > > enable) return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, > > > 0); } > > > > > > -int flash_force_4b_mode(struct flash_chip *c, bool enable_4b) > > > +int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b) > > > { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > struct spi_flash_ctrl *ct = c->ctrl; > > > int rc; > > > > > > @@ -776,24 +783,29 @@ static int flash_configure(struct flash_chip *c) > > > return 0; > > > } > > > > > > -int flash_get_info(struct flash_chip *chip, const char **name, > > > +static int flash_get_info(struct blocklevel_device *bl, const char **name, > > > uint32_t *total_size, uint32_t *erase_granule) > > > { > > > + struct flash_chip *c = container_of(bl, struct flash_chip, bl); > > > if (name) > > > - *name = chip->info.name; > > > + *name = c->info.name; > > > if (total_size) > > > - *total_size = chip->tsize; > > > + *total_size = c->tsize; > > > if (erase_granule) > > > - *erase_granule = chip->min_erase_mask + 1; > > > + *erase_granule = c->min_erase_mask + 1; > > > return 0; > > > } > > > > > > -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash) > > > +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl) > > > { > > > struct flash_chip *c; > > > int rc; > > > > > > - *flash = NULL; > > > + if (!bl) > > > + return FLASH_ERR_PARM_ERROR; > > > + > > > + *bl = NULL; > > > + > > > c = malloc(sizeof(struct flash_chip)); > > > if (!c) > > > return FLASH_ERR_MALLOC_FAILED; > > > @@ -814,18 +826,25 @@ int flash_init(struct spi_flash_ctrl *ctrl, struct > > > flash_chip **flash) rc = flash_configure(c); > > > if (rc) > > > FL_ERR("LIBFLASH: Flash configuration failed\n"); > > > - bail: > > > +bail: > > > if (rc) { > > > free(c); > > > return rc; > > > } > > > - *flash = c; > > > + > > > + c->bl.read = &flash_read; > > > + c->bl.write = &flash_smart_write; > > > + c->bl.erase = &flash_erase; > > > + c->bl.get_info = &flash_get_info; > > > + > > > + *bl = &(c->bl); > > > return 0; > > > } > > > > > > -void flash_exit(struct flash_chip *chip) > > > +void flash_exit(struct blocklevel_device *bl) > > > { > > > /* XXX Make sure we are idle etc... */ > > > - free(chip); > > > + if (bl) > > > + free(container_of(bl, struct flash_chip, bl)); > > > } > > > > > > diff --git a/libflash/libflash.h b/libflash/libflash.h > > > index 7ed65d0..30f984d 100644 > > > --- a/libflash/libflash.h > > > +++ b/libflash/libflash.h > > > @@ -18,6 +18,7 @@ > > > > > > #include <stdint.h> > > > #include <stdbool.h> > > > +#include <libflash/blocklevel.h> > > > > > > #ifdef __SKIBOOT__ > > > #include <skiboot.h> > > > @@ -59,18 +60,13 @@ extern bool libflash_debug; > > > struct flash_chip; > > > struct spi_flash_ctrl; > > > > > > -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash); > > > -void flash_exit(struct flash_chip *chip); > > > - > > > -int flash_get_info(struct flash_chip *chip, const char **name, > > > - uint32_t *total_size, uint32_t *erase_granule); > > > +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl); > > > +void flash_exit(struct blocklevel_device *bl); > > > > > > /* libflash sets the 4b mode automatically based on the flash > > > * size and controller capabilities but it can be overriden > > > */ > > > -int flash_force_4b_mode(struct flash_chip *chip, bool enable_4b); > > > - > > > -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t > > > len); +int flash_force_4b_mode(struct blocklevel_device *bl, bool > > > enable_4b); > > > > > > /* > > > * This provides a wapper around flash_read() on ECCed data. All params are > > > @@ -80,11 +76,8 @@ int flash_read(struct flash_chip *c, uint32_t pos, void > > > *buf, uint32_t len); * len is length of data without ecc attached therefore > > > this will read beyond * pos + len. > > > */ > > > -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, > > > +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void > > > *buf, uint32_t len, bool ecc); > > > -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size); > > > -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, > > > - uint32_t size, bool verify); > > > > > > /* > > > * This provides a wrapper around flash_write() on ECCed data. All params > > > are @@ -94,10 +87,8 @@ int flash_write(struct flash_chip *c, uint32_t dst, > > > const void *src, * size is length of data without ECC attached therefore > > > this will write beyond * dst + size. > > > */ > > > -int flash_write_corrected(struct flash_chip *c, uint32_t dst, const void > > > *src, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t > > > dst, const void *src, uint32_t size, bool verify, bool ecc); > > > -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, > > > - uint32_t size); > > > > > > /* > > > * This provides a wrapper around flash_smart_write() on ECCed data. All > > > @@ -107,12 +98,12 @@ int flash_smart_write(struct flash_chip *c, uint32_t > > > dst, const void *src, * size is length of data without ECC attached > > > therefore this will write beyond * dst + size. > > > */ > > > -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const > > > void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, > > > uint32_t dst, const void *src, uint32_t size, bool ecc); > > > > > > /* chip erase may not be supported by all chips/controllers, get ready > > > * for FLASH_ERR_CHIP_ER_NOT_SUPPORTED > > > */ > > > -int flash_erase_chip(struct flash_chip *c); > > > +int flash_erase_chip(struct blocklevel_device *bl); > > > > > > #endif /* __LIBFLASH_H */ > > > diff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c > > > index 4479b5a..cf2b3a5 100644 > > > --- a/libflash/test/test-flash.c > > > +++ b/libflash/test/test-flash.c > > > @@ -366,7 +366,7 @@ struct spi_flash_ctrl sim_ctrl = { > > > > > > int main(void) > > > { > > > - struct flash_chip *fl; > > > + struct blocklevel_device *bl; > > > uint32_t total_size, erase_granule; > > > const char *name; > > > uint16_t *test; > > > @@ -378,12 +378,12 @@ int main(void) > > > memset(sim_image, 0xff, sim_image_sz); > > > test = malloc(0x10000 * 2); > > > > > > - rc = flash_init(&sim_ctrl, &fl); > > > + rc = flash_init(&sim_ctrl, &bl); > > > if (rc) { > > > ERR("flash_init failed with err %d\n", rc); > > > exit(1); > > > } > > > - rc = flash_get_info(fl, &name, &total_size, &erase_granule); > > > + rc = flash_get_info(bl, &name, &total_size, &erase_granule); > > > if (rc) { > > > ERR("flash_get_info failed with err %d\n", rc); > > > exit(1); > > > @@ -395,13 +395,13 @@ int main(void) > > > > > > /* Write 64k of stuff at 0 and at 128k */ > > > printf("Writing test patterns...\n"); > > > - flash_smart_write(fl, 0, test, 0x10000); > > > - flash_smart_write(fl, 0x20000, test, 0x10000); > > > + flash_smart_write(bl, 0, test, 0x10000); > > > + flash_smart_write(bl, 0x20000, test, 0x10000); > > > > > > /* Write "Hello world" straddling the 64k boundary */ > > > #define HW "Hello World" > > > printf("Writing test string...\n"); > > > - flash_smart_write(fl, 0xfffc, HW, sizeof(HW)); > > > + flash_smart_write(bl, 0xfffc, HW, sizeof(HW)); > > > > > > /* Check result */ > > > if (memcmp(sim_image + 0xfffc, HW, sizeof(HW))) { > > > @@ -416,7 +416,7 @@ int main(void) > > > printf("Test pattern pass\n"); > > > > > > printf("Test ECC interfaces\n"); > > > - flash_smart_write_corrected(fl, 0, test, 0x10000, 1); > > > + flash_smart_write_corrected(bl, 0, test, 0x10000, 1); > > > ecc_test = (struct ecc64 *)sim_image; > > > test64 = (uint64_t *)test; > > > for (i = 0; i < 0x10000 / sizeof(*ecc_test); i++) { > > > @@ -433,7 +433,7 @@ int main(void) > > > printf("Test ECC interface pass\n"); > > > > > > printf("Test ECC erase\n"); > > > - if (flash_erase(fl, 0, 0x10000) != 0) { > > > + if (flash_erase(bl, 0, 0x10000) != 0) { > > > ERR("flash_erase didn't return 0\n"); > > > exit(1); > > > } > > > @@ -444,7 +444,7 @@ int main(void) > > > ERR("Data not properly cleared at %d\n", i); > > > exit(1); > > > } > > > - rc = flash_write(fl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); > > > + rc = flash_write(bl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); > > > if (rc || ecc_test[i].ecc != 0) { > > > ERR("Cleared data not correctly ECCed: 0x%02x > > (0x%016lx) expecting 0 at > > > %d\n", ecc_test[i].ecc, ecc_test[i].data, i); exit(1); > > > @@ -452,7 +452,7 @@ int main(void) > > > } > > > printf("Test ECC erase pass\n"); > > > > > > - flash_exit(fl); > > > + flash_exit(bl); > > > > > > return 0; > > > } > > > diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c > > > index d294c1f..634cb86 100644 > > > --- a/platforms/astbmc/pnor.c > > > +++ b/platforms/astbmc/pnor.c > > > @@ -20,6 +20,7 @@ > > > #include <opal.h> > > > #include <libflash/libflash.h> > > > #include <libflash/libffs.h> > > > +#include <libflash/blocklevel.h> > > > #include <ast.h> > > > > > > #include "astbmc.h" > > > @@ -27,7 +28,7 @@ > > > int pnor_init(void) > > > { > > > struct spi_flash_ctrl *pnor_ctrl; > > > - struct flash_chip *pnor_chip = NULL; > > > + struct blocklevel_device *bl; > > > int rc; > > > > > > /* Open controller and flash. If the LPC->AHB doesn't point to > > > @@ -44,19 +45,20 @@ int pnor_init(void) > > > prerror("PLAT: Failed to open PNOR flash controller\n"); > > > goto fail; > > > } > > > - rc = flash_init(pnor_ctrl, &pnor_chip); > > > + > > > + rc = flash_init(pnor_ctrl, &bl); > > > if (rc) { > > > prerror("PLAT: Failed to open init PNOR driver\n"); > > > goto fail; > > > } > > > > > > - rc = flash_register(pnor_chip, true); > > > + rc = flash_register(bl, true); > > > if (!rc) > > > return 0; > > > > > > fail: > > > - if (pnor_chip) > > > - flash_exit(pnor_chip); > > > + if (bl) > > > + flash_exit(bl); > > > if (pnor_ctrl) > > > ast_sf_close(pnor_ctrl); > > > > > > diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c > > > index 27e1c91..855d0e4 100644 > > > --- a/platforms/rhesus/rhesus.c > > > +++ b/platforms/rhesus/rhesus.c > > > @@ -22,6 +22,7 @@ > > > #include <opal.h> > > > #include <libflash/libflash.h> > > > #include <libflash/libffs.h> > > > +#include <libflash/blocklevel.h> > > > #include <sfc-ctrl.h> > > > #include <ec/config.h> > > > #include <ec/gpio.h> > > > @@ -118,7 +119,7 @@ static int64_t rhesus_power_down(uint64_t request > > > __unused) static int rhesus_pnor_init(void) > > > { > > > struct spi_flash_ctrl *pnor_ctrl; > > > - struct flash_chip *pnor_chip = NULL; > > > + struct blocklevel_device *bl; > > > int rc; > > > > > > /* Open controller, flash and ffs */ > > > @@ -127,19 +128,19 @@ static int rhesus_pnor_init(void) > > > prerror("PLAT: Failed to open PNOR flash controller\n"); > > > goto fail; > > > } > > > - rc = flash_init(pnor_ctrl, &pnor_chip); > > > + rc = flash_init(pnor_ctrl, &bl); > > > if (rc) { > > > prerror("PLAT: Failed to open init PNOR driver\n"); > > > goto fail; > > > } > > > > > > - rc = flash_register(pnor_chip, true); > > > + rc = flash_register(bl, true); > > > if (!rc) > > > return 0; > > > > > > fail: > > > - if (pnor_chip) > > > - flash_exit(pnor_chip); > > > + if (bl) > > > + flash_exit(bl); > > > if (pnor_ctrl) > > > sfc_close(pnor_ctrl); > > >
diff --git a/core/flash.c b/core/flash.c index 9018ecd..90dbac7 100644 --- a/core/flash.c +++ b/core/flash.c @@ -22,12 +22,13 @@ #include <device.h> #include <libflash/libflash.h> #include <libflash/libffs.h> +#include <libflash/blocklevel.h> #include <ecc.h> struct flash { bool registered; bool busy; - struct flash_chip *chip; + struct blocklevel_device *bl; uint32_t size; uint32_t block_size; }; @@ -108,7 +109,7 @@ static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len) goto out; } - rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len); + rc = blocklevel_read(nvram_flash->bl, nvram_offset + src, dst, len); out: unlock(&flash_lock); @@ -137,7 +138,7 @@ static int flash_nvram_write(uint32_t dst, void *src, uint32_t len) rc = OPAL_PARAMETER; goto out; } - rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, len); + rc = blocklevel_write(nvram_flash->bl, nvram_offset + dst, src, len); out: unlock(&flash_lock); @@ -250,7 +251,7 @@ static void setup_system_flash(struct flash *flash, struct dt_node *node, flash_nvram_probe(flash, ffs); } -int flash_register(struct flash_chip *chip, bool is_system_flash) +int flash_register(struct blocklevel_device *bl, bool is_system_flash) { uint32_t size, block_size; struct ffs_handle *ffs; @@ -260,7 +261,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash) unsigned int i; int rc; - rc = flash_get_info(chip, &name, &size, &block_size); + rc = blocklevel_get_info(bl, &name, &size, &block_size); if (rc) return rc; @@ -276,7 +277,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash) flash = &flashes[i]; flash->registered = true; flash->busy = false; - flash->chip = chip; + flash->bl = bl; flash->size = size; flash->block_size = block_size; break; @@ -288,7 +289,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash) return OPAL_RESOURCE; } - rc = ffs_open_flash(chip, 0, flash->size, &ffs); + rc = ffs_init(0, flash->size, bl, &ffs); if (rc) { prlog(PR_WARNING, "FLASH: No ffs info; " "using raw device only\n"); @@ -346,13 +347,17 @@ static int64_t opal_flash_op(enum flash_op op, uint64_t id, uint64_t offset, switch (op) { case FLASH_OP_READ: - rc = flash_read(flash->chip, offset, (void *)buf, size); + rc = blocklevel_read(flash->bl, offset, (void *)buf, size); break; case FLASH_OP_WRITE: - rc = flash_write(flash->chip, offset, (void *)buf, size, false); + /* + * Note: blocklevel_write() uses flash_smart_write(), this call used to + * be flash_write() + */ + rc = blocklevel_write(flash->bl, offset, (void *)buf, size); break; case FLASH_OP_ERASE: - rc = flash_erase(flash->chip, offset, size); + rc = blocklevel_erase(flash->bl, offset, size); break; default: assert(0); @@ -425,7 +430,7 @@ struct flash_hostboot_header { }; /* start and total size include ECC */ -static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid, +static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid, uint32_t *start, uint32_t *total_size, bool *ecc) { @@ -444,7 +449,7 @@ static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid, partsize = BUFFER_SIZE_MINUS_ECC(*total_size); /* Get the TOC */ - rc = flash_read_corrected(chip, *start, header, + rc = flash_read_corrected(bl, *start, header, FLASH_SUBPART_HEADER_SIZE, ecc); if (rc) { prerror("FLASH: flash subpartition TOC read failed %i\n", rc); @@ -564,7 +569,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid, goto out_unlock; } - rc = ffs_open_flash(flash->chip, 0, flash->size, &ffs); + rc = ffs_init(0, flash->size, flash->bl, &ffs); if (rc) { prerror("FLASH: Can't open ffs handle\n"); goto out_unlock; @@ -591,7 +596,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid, /* Find the sub partition if required */ if (subid != RESOURCE_SUBID_NONE) { - rc = flash_find_subpartition(flash->chip, subid, &part_start, + rc = flash_find_subpartition(flash->bl, subid, &part_start, &part_size, &ecc); if (rc) goto out_free_ffs; @@ -614,7 +619,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid, goto out_free_ffs; } - rc = flash_read_corrected(flash->chip, part_start, buf, size, ecc); + rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc); if (rc) { prerror("FLASH: failed to read %s partition\n", name); goto out_free_ffs; diff --git a/external/pflash/Makefile b/external/pflash/Makefile index c28e359..7771343 100644 --- a/external/pflash/Makefile +++ b/external/pflash/Makefile @@ -14,7 +14,7 @@ endif CFLAGS = -O2 -Wall -I. LDFLAGS = -lrt OBJS = pflash.o progress.o ast-sf-ctrl.o -OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o +OBJS += libflash/libflash.o libflash/libffs.o libflash/ecc.o libflash/blocklevel.o OBJS += $(ARCH_OBJS) EXE = pflash diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c index fb783a2..0958691 100644 --- a/external/pflash/pflash.c +++ b/external/pflash/pflash.c @@ -16,6 +16,7 @@ #include <libflash/libflash.h> #include <libflash/libffs.h> +#include <libflash/blocklevel.h> #include "progress.h" #include "io.h" #include "ast.h" @@ -23,7 +24,7 @@ #define __aligned(x) __attribute__((aligned(x))) -#define PFLASH_VERSION "0.8.6" +#define PFLASH_VERSION "0.8.7" static bool must_confirm = true; static bool dummy_run; @@ -36,8 +37,8 @@ static bool using_sfc; #define FILE_BUF_SIZE 0x10000 static uint8_t file_buf[FILE_BUF_SIZE] __aligned(0x1000); +static struct blocklevel_device *bl; static struct spi_flash_ctrl *fl_ctrl; -static struct flash_chip *fl_chip; static struct ffs_handle *ffsh; static uint32_t fl_total_size, fl_erase_granule; static const char *fl_name; @@ -84,7 +85,7 @@ static void print_flash_info(void) return; if (!ffsh) { - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); + rc = ffs_init(0, fl_total_size, bl, &ffsh); if (rc) { fprintf(stderr, "Error %d opening ffs !\n", rc); ffsh = NULL; @@ -122,7 +123,7 @@ static void lookup_partition(const char *name) /* Open libffs if needed */ if (!ffsh) { - rc = ffs_open_flash(fl_chip, 0, 0, &ffsh); + rc = ffs_init(0, fl_total_size, bl, &ffsh); if (rc) { fprintf(stderr, "Error %d opening ffs !\n", rc); exit(1); @@ -158,7 +159,7 @@ static void erase_chip(void) return; } - rc = flash_erase_chip(fl_chip); + rc = flash_erase_chip(bl); if (rc) { fprintf(stderr, "Error %d erasing chip\n", rc); exit(1); @@ -185,7 +186,7 @@ static void erase_range(uint32_t start, uint32_t size, bool will_program) while(size) { /* If aligned to 64k and at least 64k, use 64k erase */ if ((start & 0xffff) == 0 && size >= 0x10000) { - rc = flash_erase(fl_chip, start, 0x10000); + rc = blocklevel_erase(bl, start, 0x10000); if (rc) { fprintf(stderr, "Error %d erasing 0x%08x\n", rc, start); @@ -195,7 +196,7 @@ static void erase_range(uint32_t start, uint32_t size, bool will_program) size -= 0x10000; done += 0x10000; } else { - rc = flash_erase(fl_chip, start, 0x1000); + rc = blocklevel_erase(bl, start, 0x1000); if (rc) { fprintf(stderr, "Error %d erasing 0x%08x\n", rc, start); @@ -252,7 +253,7 @@ static void program_file(const char *file, uint32_t start, uint32_t size) len = size; size -= len; actual_size += len; - rc = flash_write(fl_chip, start, file_buf, len, true); + rc = blocklevel_write(bl, start, file_buf, len); if (rc) { if (rc == FLASH_ERR_VERIFY_FAILURE) fprintf(stderr, "Verification failed for" @@ -292,7 +293,7 @@ static void do_read_file(const char *file, uint32_t start, uint32_t size) progress_init(size >> 8); while(size) { len = size > FILE_BUF_SIZE ? FILE_BUF_SIZE : size; - rc = flash_read(fl_chip, start, file_buf, len); + rc = blocklevel_read(bl, start, file_buf, len); if (rc) { fprintf(stderr, "Flash read error %d for" " chunk at 0x%08x\n", rc, start); @@ -318,7 +319,7 @@ static void enable_4B_addresses(void) printf("Switching to 4-bytes address mode\n"); - rc = flash_force_4b_mode(fl_chip, true); + rc = flash_force_4b_mode(bl, true); if (rc) { fprintf(stderr, "Error %d enabling 4b mode\n", rc); exit(1); @@ -331,7 +332,7 @@ static void disable_4B_addresses(void) printf("Switching to 3-bytes address mode\n"); - rc = flash_force_4b_mode(fl_chip, false); + rc = flash_force_4b_mode(bl, false); if (rc) { fprintf(stderr, "Error %d disabling 4b mode\n", rc); exit(1); @@ -342,7 +343,7 @@ static void flash_access_cleanup_bmc(void) { if (ffsh) ffs_close(ffsh); - flash_exit(fl_chip); + flash_exit(bl); ast_sf_close(fl_ctrl); close_devs(); } @@ -362,7 +363,7 @@ static void flash_access_setup_bmc(bool use_lpc, bool need_write) } /* Open flash chip */ - rc = flash_init(fl_ctrl, &fl_chip); + rc = flash_init(fl_ctrl, &bl); if (rc) { fprintf(stderr, "Failed to open flash chip\n"); exit(1); @@ -380,7 +381,7 @@ static void flash_access_cleanup_pnor(void) if (ffsh) ffs_close(ffsh); - flash_exit(fl_chip); + flash_exit(bl); #ifdef __powerpc__ if (using_sfc) sfc_close(fl_ctrl); @@ -421,7 +422,7 @@ static void flash_access_setup_pnor(bool use_lpc, bool use_sfc, bool need_write) #endif /* Open flash chip */ - rc = flash_init(fl_ctrl, &fl_chip); + rc = flash_init(fl_ctrl, &bl); if (rc) { fprintf(stderr, "Failed to open flash chip\n"); exit(1); @@ -698,7 +699,7 @@ int main(int argc, char *argv[]) flash_access_setup_pnor(use_lpc, has_sfc, erase || program); } - rc = flash_get_info(fl_chip, &fl_name, + rc = blocklevel_get_info(bl, &fl_name, &fl_total_size, &fl_erase_granule); if (rc) { fprintf(stderr, "Error %d getting flash info\n", rc); diff --git a/include/skiboot.h b/include/skiboot.h index 9751a31..aa92f68 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -36,6 +36,8 @@ #include <ccan/endian/endian.h> #include <ccan/str/str.h> +#include <libflash/blocklevel.h> + #include <mem-map.h> #include <op-panel.h> #include <platform.h> @@ -214,7 +216,7 @@ extern void occ_fsp_init(void); /* flash support */ struct flash_chip; -extern int flash_register(struct flash_chip *chip, bool is_system_flash); +extern int flash_register(struct blocklevel_device *bl, bool is_system_flash); extern int flash_start_preload_resource(enum resource_id id, uint32_t subid, void *buf, size_t *len); extern int flash_resource_loaded(enum resource_id id, uint32_t idx); diff --git a/libflash/libffs.c b/libflash/libffs.c index 2d05cc9..8a60bee 100644 --- a/libflash/libffs.c +++ b/libflash/libffs.c @@ -41,6 +41,7 @@ struct ffs_handle { uint32_t max_size; void *cache; uint32_t cached_size; + struct blocklevel_device *bl; }; static uint32_t ffs_checksum(void* data, size_t size) @@ -71,31 +72,29 @@ static int ffs_check_convert_header(struct ffs_hdr *dst, struct ffs_hdr *src) return 0; } -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, - uint32_t max_size, struct ffs_handle **ffs) +int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl, + struct ffs_handle **ffs) { struct ffs_hdr hdr; struct ffs_handle *f; - uint32_t fl_size, erase_size; + uint32_t total_size; int rc; - if (!ffs) + if (!ffs || !bl) return FLASH_ERR_PARM_ERROR; *ffs = NULL; - /* Grab some info about our flash chip */ - rc = flash_get_info(chip, NULL, &fl_size, &erase_size); + rc = blocklevel_get_info(bl, NULL, &total_size, NULL); if (rc) { - FL_ERR("FFS: Error %d retrieving flash info\n", rc); - return rc; - } - if ((offset + max_size) < offset) + FL_ERR("FFS: Error %d getting device total size", rc); return FLASH_ERR_PARM_ERROR; - if ((offset + max_size) > fl_size) + } + + if ((offset + max_size) < offset || (offset + max_size) > total_size) return FLASH_ERR_PARM_ERROR; /* Read flash header */ - rc = flash_read(chip, offset, &hdr, sizeof(hdr)); + rc = blocklevel_read(bl, offset, &hdr, sizeof(hdr)); if (rc) { FL_ERR("FFS: Error %d reading flash header\n", rc); return rc; @@ -106,17 +105,15 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t offset, if (!f) return FLASH_ERR_MALLOC_FAILED; memset(f, 0, sizeof(*f)); - f->type = ffs_type_flash; f->flash_offset = offset; - f->max_size = max_size ? max_size : (fl_size - offset); - f->chip = chip; + f->max_size = max_size; + f->bl = bl; /* Convert and check flash header */ rc = ffs_check_convert_header(&f->hdr, &hdr); if (rc) { FL_ERR("FFS: Error %d checking flash header\n", rc); - free(f); - return rc; + goto out; } /* @@ -126,26 +123,26 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t offset, f->cached_size = f->hdr.block_size * f->hdr.size; FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size); - /* Align to erase size */ - f->cached_size |= (erase_size - 1); - f->cached_size &= ~(erase_size - 1); - FL_DBG("FFS: Aligned to: 0x%x\n", f->cached_size); - /* Allocate cache */ f->cache = malloc(f->cached_size); if (!f->cache) { - free(f); - return FLASH_ERR_MALLOC_FAILED; + rc = FLASH_ERR_MALLOC_FAILED; + goto out; } /* Read the cached map */ - rc = flash_read(chip, offset, f->cache, f->cached_size); + rc = blocklevel_read(bl, offset, f->cache, f->cached_size); if (rc) { FL_ERR("FFS: Error %d reading flash partition map\n", rc); - free(f); + goto out; } + +out: if (rc == 0) *ffs = f; + else + free(f); + return rc; } @@ -361,6 +358,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx, ent->checksum = ffs_checksum(ent, FFS_ENTRY_SIZE_CSUM); if (!ffs->chip) return 0; - return flash_smart_write(ffs->chip, offset, ent, FFS_ENTRY_SIZE); + + return blocklevel_write(ffs->bl, offset, ent, FFS_ENTRY_SIZE); } diff --git a/libflash/libffs.h b/libflash/libffs.h index dd58d28..a310172 100644 --- a/libflash/libffs.h +++ b/libflash/libffs.h @@ -18,6 +18,7 @@ #include <libflash/libflash.h> #include <libflash/ffs.h> +#include <libflash/blocklevel.h> /* FFS handle, opaque */ struct ffs_handle; @@ -34,8 +35,10 @@ struct ffs_handle; #define FFS_ERR_PART_NOT_FOUND 103 #define FFS_ERR_BAD_ECC 104 -int ffs_open_flash(struct flash_chip *chip, uint32_t offset, - uint32_t max_size, struct ffs_handle **ffs); +/* Init */ + +int ffs_init(uint32_t offset, uint32_t max_size, + struct blocklevel_device *bl, struct ffs_handle **ffs); /* ffs_open_image is Linux only as it uses lseek, which skiboot does not * implement */ diff --git a/libflash/libflash.c b/libflash/libflash.c index e43be4f..2af0c79 100644 --- a/libflash/libflash.c +++ b/libflash/libflash.c @@ -20,6 +20,7 @@ #include "libflash.h" #include "libflash-priv.h" #include "ecc.h" +#include "blocklevel.h" #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -45,6 +46,7 @@ struct flash_chip { bool mode_4b; /* Flash currently in 4b mode */ struct flash_req *cur_req; /* Current request */ void *smart_buf; /* Buffer for smart writes */ + struct blocklevel_device bl; }; #ifndef __SKIBOOT__ @@ -112,8 +114,9 @@ int fl_wren(struct spi_flash_ctrl *ct) return FLASH_ERR_WREN_TIMEOUT; } -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len) +static int flash_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; /* XXX Add sanity/bound checking */ @@ -138,7 +141,7 @@ int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len) * This provides a wrapper around flash_read on ECCed data * len is length of data without ECC attached */ -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len, bool ecc) { struct ecc64 *bufecc; @@ -147,7 +150,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, uint8_t ret; if (!ecc) - return flash_read(c, pos, buf, len); + return flash_read(bl, pos, buf, len); /* Copy the buffer in chunks */ bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); @@ -159,7 +162,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, copylen = MIN(len, COPY_BUFFER_LENGTH); /* Read ECCed data from flash */ - rc = flash_read(c, pos, bufecc, ECC_BUFFER_SIZE(copylen)); + rc = flash_read(bl, pos, bufecc, ECC_BUFFER_SIZE(copylen)); if (rc) goto err; @@ -215,8 +218,9 @@ static void fl_get_best_erase(struct flash_chip *c, uint32_t dst, uint32_t size, *cmd = CMD_BE; } -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size) +static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t size) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; uint32_t chunk; uint8_t cmd; @@ -262,8 +266,9 @@ int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size) return 0; } -int flash_erase_chip(struct flash_chip *c) +int flash_erase_chip(struct blocklevel_device *bl) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; int rc; @@ -311,9 +316,10 @@ static int fl_wpage(struct flash_chip *c, uint32_t dst, const void *src, return fl_sync_wait_idle(ct); } -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, +static int flash_write(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size, bool verify) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; uint32_t todo = size; uint32_t d = dst; @@ -374,7 +380,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, const void *src, chunk = sizeof(vbuf); if (chunk > size) chunk = size; - rc = flash_read(c, dst, vbuf, chunk); + rc = flash_read(bl, dst, vbuf, chunk); if (rc) return rc; if (memcmp(vbuf, src, chunk)) { FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst); @@ -387,7 +393,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, const void *src, return 0; } -int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void *buf, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t pos, const void *buf, uint32_t len, bool verify, bool ecc) { struct ecc64 *bufecc; @@ -396,7 +402,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void *buf, uint8_t ret; if (!ecc) - return flash_write(c, pos, buf, len, verify); + return flash_write(bl, pos, buf, len, verify); /* Copy the buffer in chunks */ bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH)); @@ -415,7 +421,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void *buf, } /* Write ECCed data to the flash */ - rc = flash_write(c, pos, bufecc, copylen, verify); + rc = flash_write(bl, pos, bufecc, copylen, verify); if (rc) goto err; @@ -463,12 +469,12 @@ static enum sm_comp_res flash_smart_comp(struct flash_chip *c, return is_same ? sm_no_change : sm_need_write; } -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, - uint32_t size) +static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); uint32_t er_size = c->min_erase_mask + 1; uint32_t end = dst + size; - int rc; + int rc; /* Some sanity checking */ if (end <= dst || !size || end > c->tsize) { @@ -489,7 +495,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, off = dst & c->min_erase_mask; FL_DBG("LIBFLASH: reading page 0x%08x..0x%08x...", page, page + er_size); - rc = flash_read(c, page, c->smart_buf, er_size); + rc = flash_read(bl, page, c->smart_buf, er_size); if (rc) { FL_DBG(" error %d!\n", rc); return rc; @@ -510,7 +516,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, case sm_need_write: /* Just needs writing over */ FL_DBG(" need write !\n"); - rc = flash_write(c, dst, src, chunk, true); + rc = flash_write(bl, dst, src, chunk, true); if (rc) { FL_DBG("LIBFLASH: Write error %d !\n", rc); return rc; @@ -518,14 +524,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, break; case sm_need_erase: FL_DBG(" need erase !\n"); - rc = flash_erase(c, page, er_size); + rc = flash_erase(bl, page, er_size); if (rc) { FL_DBG("LIBFLASH: erase error %d !\n", rc); return rc; } /* Then update the portion of the buffer and write the block */ memcpy(c->smart_buf + off, src, chunk); - rc = flash_write(c, page, c->smart_buf, er_size, true); + rc = flash_write(bl, page, c->smart_buf, er_size, true); if (rc) { FL_DBG("LIBFLASH: write error %d !\n", rc); return rc; @@ -539,14 +545,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, return 0; } -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size, bool ecc) { struct ecc64 *buf; int rc; if (!ecc) - return flash_smart_write(c, dst, src, size); + return flash_smart_write(bl, dst, src, size); buf = malloc(ECC_BUFFER_SIZE(size)); if (!buf) @@ -558,7 +564,7 @@ int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const void * goto out; } - rc = flash_smart_write(c, dst, buf, ECC_BUFFER_SIZE(size)); + rc = flash_smart_write(bl, dst, buf, ECC_BUFFER_SIZE(size)); out: free(buf); @@ -684,8 +690,9 @@ static int flash_set_4b(struct flash_chip *c, bool enable) return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, 0); } -int flash_force_4b_mode(struct flash_chip *c, bool enable_4b) +int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); struct spi_flash_ctrl *ct = c->ctrl; int rc; @@ -776,24 +783,29 @@ static int flash_configure(struct flash_chip *c) return 0; } -int flash_get_info(struct flash_chip *chip, const char **name, +static int flash_get_info(struct blocklevel_device *bl, const char **name, uint32_t *total_size, uint32_t *erase_granule) { + struct flash_chip *c = container_of(bl, struct flash_chip, bl); if (name) - *name = chip->info.name; + *name = c->info.name; if (total_size) - *total_size = chip->tsize; + *total_size = c->tsize; if (erase_granule) - *erase_granule = chip->min_erase_mask + 1; + *erase_granule = c->min_erase_mask + 1; return 0; } -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash) +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl) { struct flash_chip *c; int rc; - *flash = NULL; + if (!bl) + return FLASH_ERR_PARM_ERROR; + + *bl = NULL; + c = malloc(sizeof(struct flash_chip)); if (!c) return FLASH_ERR_MALLOC_FAILED; @@ -814,18 +826,25 @@ int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash) rc = flash_configure(c); if (rc) FL_ERR("LIBFLASH: Flash configuration failed\n"); - bail: +bail: if (rc) { free(c); return rc; } - *flash = c; + + c->bl.read = &flash_read; + c->bl.write = &flash_smart_write; + c->bl.erase = &flash_erase; + c->bl.get_info = &flash_get_info; + + *bl = &(c->bl); return 0; } -void flash_exit(struct flash_chip *chip) +void flash_exit(struct blocklevel_device *bl) { /* XXX Make sure we are idle etc... */ - free(chip); + if (bl) + free(container_of(bl, struct flash_chip, bl)); } diff --git a/libflash/libflash.h b/libflash/libflash.h index 7ed65d0..30f984d 100644 --- a/libflash/libflash.h +++ b/libflash/libflash.h @@ -18,6 +18,7 @@ #include <stdint.h> #include <stdbool.h> +#include <libflash/blocklevel.h> #ifdef __SKIBOOT__ #include <skiboot.h> @@ -59,18 +60,13 @@ extern bool libflash_debug; struct flash_chip; struct spi_flash_ctrl; -int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash); -void flash_exit(struct flash_chip *chip); - -int flash_get_info(struct flash_chip *chip, const char **name, - uint32_t *total_size, uint32_t *erase_granule); +int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl); +void flash_exit(struct blocklevel_device *bl); /* libflash sets the 4b mode automatically based on the flash * size and controller capabilities but it can be overriden */ -int flash_force_4b_mode(struct flash_chip *chip, bool enable_4b); - -int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len); +int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b); /* * This provides a wapper around flash_read() on ECCed data. All params are @@ -80,11 +76,8 @@ int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len); * len is length of data without ecc attached therefore this will read beyond * pos + len. */ -int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf, +int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len, bool ecc); -int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size); -int flash_write(struct flash_chip *c, uint32_t dst, const void *src, - uint32_t size, bool verify); /* * This provides a wrapper around flash_write() on ECCed data. All params are @@ -94,10 +87,8 @@ int flash_write(struct flash_chip *c, uint32_t dst, const void *src, * size is length of data without ECC attached therefore this will write beyond * dst + size. */ -int flash_write_corrected(struct flash_chip *c, uint32_t dst, const void *src, +int flash_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size, bool verify, bool ecc); -int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, - uint32_t size); /* * This provides a wrapper around flash_smart_write() on ECCed data. All @@ -107,12 +98,12 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src, * size is length of data without ECC attached therefore this will write beyond * dst + size. */ -int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const void *src, +int flash_smart_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size, bool ecc); /* chip erase may not be supported by all chips/controllers, get ready * for FLASH_ERR_CHIP_ER_NOT_SUPPORTED */ -int flash_erase_chip(struct flash_chip *c); +int flash_erase_chip(struct blocklevel_device *bl); #endif /* __LIBFLASH_H */ diff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c index 4479b5a..cf2b3a5 100644 --- a/libflash/test/test-flash.c +++ b/libflash/test/test-flash.c @@ -366,7 +366,7 @@ struct spi_flash_ctrl sim_ctrl = { int main(void) { - struct flash_chip *fl; + struct blocklevel_device *bl; uint32_t total_size, erase_granule; const char *name; uint16_t *test; @@ -378,12 +378,12 @@ int main(void) memset(sim_image, 0xff, sim_image_sz); test = malloc(0x10000 * 2); - rc = flash_init(&sim_ctrl, &fl); + rc = flash_init(&sim_ctrl, &bl); if (rc) { ERR("flash_init failed with err %d\n", rc); exit(1); } - rc = flash_get_info(fl, &name, &total_size, &erase_granule); + rc = flash_get_info(bl, &name, &total_size, &erase_granule); if (rc) { ERR("flash_get_info failed with err %d\n", rc); exit(1); @@ -395,13 +395,13 @@ int main(void) /* Write 64k of stuff at 0 and at 128k */ printf("Writing test patterns...\n"); - flash_smart_write(fl, 0, test, 0x10000); - flash_smart_write(fl, 0x20000, test, 0x10000); + flash_smart_write(bl, 0, test, 0x10000); + flash_smart_write(bl, 0x20000, test, 0x10000); /* Write "Hello world" straddling the 64k boundary */ #define HW "Hello World" printf("Writing test string...\n"); - flash_smart_write(fl, 0xfffc, HW, sizeof(HW)); + flash_smart_write(bl, 0xfffc, HW, sizeof(HW)); /* Check result */ if (memcmp(sim_image + 0xfffc, HW, sizeof(HW))) { @@ -416,7 +416,7 @@ int main(void) printf("Test pattern pass\n"); printf("Test ECC interfaces\n"); - flash_smart_write_corrected(fl, 0, test, 0x10000, 1); + flash_smart_write_corrected(bl, 0, test, 0x10000, 1); ecc_test = (struct ecc64 *)sim_image; test64 = (uint64_t *)test; for (i = 0; i < 0x10000 / sizeof(*ecc_test); i++) { @@ -433,7 +433,7 @@ int main(void) printf("Test ECC interface pass\n"); printf("Test ECC erase\n"); - if (flash_erase(fl, 0, 0x10000) != 0) { + if (flash_erase(bl, 0, 0x10000) != 0) { ERR("flash_erase didn't return 0\n"); exit(1); } @@ -444,7 +444,7 @@ int main(void) ERR("Data not properly cleared at %d\n", i); exit(1); } - rc = flash_write(fl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); + rc = flash_write(bl, i * sizeof(*ecc_test) + 8, &zero, 1, 0); if (rc || ecc_test[i].ecc != 0) { ERR("Cleared data not correctly ECCed: 0x%02x (0x%016lx) expecting 0 at %d\n", ecc_test[i].ecc, ecc_test[i].data, i); exit(1); @@ -452,7 +452,7 @@ int main(void) } printf("Test ECC erase pass\n"); - flash_exit(fl); + flash_exit(bl); return 0; } diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c index d294c1f..634cb86 100644 --- a/platforms/astbmc/pnor.c +++ b/platforms/astbmc/pnor.c @@ -20,6 +20,7 @@ #include <opal.h> #include <libflash/libflash.h> #include <libflash/libffs.h> +#include <libflash/blocklevel.h> #include <ast.h> #include "astbmc.h" @@ -27,7 +28,7 @@ int pnor_init(void) { struct spi_flash_ctrl *pnor_ctrl; - struct flash_chip *pnor_chip = NULL; + struct blocklevel_device *bl; int rc; /* Open controller and flash. If the LPC->AHB doesn't point to @@ -44,19 +45,20 @@ int pnor_init(void) prerror("PLAT: Failed to open PNOR flash controller\n"); goto fail; } - rc = flash_init(pnor_ctrl, &pnor_chip); + + rc = flash_init(pnor_ctrl, &bl); if (rc) { prerror("PLAT: Failed to open init PNOR driver\n"); goto fail; } - rc = flash_register(pnor_chip, true); + rc = flash_register(bl, true); if (!rc) return 0; fail: - if (pnor_chip) - flash_exit(pnor_chip); + if (bl) + flash_exit(bl); if (pnor_ctrl) ast_sf_close(pnor_ctrl); diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c index 27e1c91..855d0e4 100644 --- a/platforms/rhesus/rhesus.c +++ b/platforms/rhesus/rhesus.c @@ -22,6 +22,7 @@ #include <opal.h> #include <libflash/libflash.h> #include <libflash/libffs.h> +#include <libflash/blocklevel.h> #include <sfc-ctrl.h> #include <ec/config.h> #include <ec/gpio.h> @@ -118,7 +119,7 @@ static int64_t rhesus_power_down(uint64_t request __unused) static int rhesus_pnor_init(void) { struct spi_flash_ctrl *pnor_ctrl; - struct flash_chip *pnor_chip = NULL; + struct blocklevel_device *bl; int rc; /* Open controller, flash and ffs */ @@ -127,19 +128,19 @@ static int rhesus_pnor_init(void) prerror("PLAT: Failed to open PNOR flash controller\n"); goto fail; } - rc = flash_init(pnor_ctrl, &pnor_chip); + rc = flash_init(pnor_ctrl, &bl); if (rc) { prerror("PLAT: Failed to open init PNOR driver\n"); goto fail; } - rc = flash_register(pnor_chip, true); + rc = flash_register(bl, true); if (!rc) return 0; fail: - if (pnor_chip) - flash_exit(pnor_chip); + if (bl) + flash_exit(bl); if (pnor_ctrl) sfc_close(pnor_ctrl);
Converted all the libflash calls to use the blocklevel interface, modified all callers to libflash to use the blocklevel interface. This patch should introduce next to no functional change. Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com> --- core/flash.c | 35 ++++++++++--------- external/pflash/Makefile | 2 +- external/pflash/pflash.c | 33 +++++++++--------- include/skiboot.h | 4 ++- libflash/libffs.c | 52 ++++++++++++++--------------- libflash/libffs.h | 7 ++-- libflash/libflash.c | 83 ++++++++++++++++++++++++++++------------------ libflash/libflash.h | 25 +++++--------- libflash/test/test-flash.c | 20 +++++------ platforms/astbmc/pnor.c | 12 ++++--- platforms/rhesus/rhesus.c | 11 +++--- 11 files changed, 153 insertions(+), 131 deletions(-)