Edward O'Callaghan has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/69959 )
Change subject: block erase WIP ......................................................................
block erase WIP
The idea here is to bring about modularity in the erasure stack by moving lookups into its own module.
Change-Id: I9b1dc33fb8d3e98f26f7d4cd1fbb876c3c5580a2 Signed-off-by: Edward O'Callaghan quasisec@google.com --- M flashrom.c M include/chipdrivers.h M spi25.c 3 files changed, 81 insertions(+), 81 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/59/69959/1
diff --git a/flashrom.c b/flashrom.c index 2489ea3..9057b31 100644 --- a/flashrom.c +++ b/flashrom.c @@ -338,57 +338,6 @@ return extract_param(&cfg->params, param_name, ","); }
-/* special unit-test hook */ -erasefunc_t *g_test_erase_injector; - -static erasefunc_t *lookup_erase_func_ptr(const struct block_eraser *const eraser) -{ - switch (eraser->block_erase) { - case SPI_BLOCK_ERASE_EMULATION: return &spi_block_erase_emulation; - case SPI_BLOCK_ERASE_20: return &spi_block_erase_20; - case SPI_BLOCK_ERASE_21: return &spi_block_erase_21; - case SPI_BLOCK_ERASE_40: return NULL; // FIXME unhandled &spi_block_erase_40; - case SPI_BLOCK_ERASE_50: return &spi_block_erase_50; - case SPI_BLOCK_ERASE_52: return &spi_block_erase_52; - case SPI_BLOCK_ERASE_53: return &spi_block_erase_53; - case SPI_BLOCK_ERASE_5C: return &spi_block_erase_5c; - case SPI_BLOCK_ERASE_60: return &spi_block_erase_60; - case SPI_BLOCK_ERASE_62: return &spi_block_erase_62; - case SPI_BLOCK_ERASE_81: return &spi_block_erase_81; - case SPI_BLOCK_ERASE_C4: return &spi_block_erase_c4; - case SPI_BLOCK_ERASE_C7: return &spi_block_erase_c7; - case SPI_BLOCK_ERASE_D7: return &spi_block_erase_d7; - case SPI_BLOCK_ERASE_D8: return &spi_block_erase_d8; - case SPI_BLOCK_ERASE_DB: return &spi_block_erase_db; - case SPI_BLOCK_ERASE_DC: return &spi_block_erase_dc; - case S25FL_BLOCK_ERASE: return &s25fl_block_erase; - case S25FS_BLOCK_ERASE_D8: return &s25fs_block_erase_d8; - case JEDEC_SECTOR_ERASE: return &erase_sector_jedec; // TODO rename to &jedec_sector_erase; - case JEDEC_BLOCK_ERASE: return &erase_block_jedec; // TODO rename to &jedec_block_erase; - case JEDEC_CHIP_BLOCK_ERASE: return &erase_chip_block_jedec; // TODO rename to &jedec_chip_block_erase; - case OPAQUE_ERASE: return &erase_opaque; // TODO rename to &opqaue_erase; - case SPI_ERASE_AT45CS_SECTOR: return &spi_erase_at45cs_sector; - case SPI_ERASE_AT45DB_BLOCK: return &spi_erase_at45db_block; - case SPI_ERASE_AT45DB_CHIP: return &spi_erase_at45db_chip; - case SPI_ERASE_AT45DB_PAGE: return &spi_erase_at45db_page; - case SPI_ERASE_AT45DB_SECTOR: return &spi_erase_at45db_sector; - case ERASE_CHIP_28SF040: return &erase_chip_28sf040; - case ERASE_SECTOR_28SF040: return &erase_sector_28sf040; - case ERASE_BLOCK_82802AB: return &erase_block_82802ab; - case ERASE_SECTOR_49LFXXXC: return &erase_sector_49lfxxxc; - case STM50_SECTOR_ERASE: return &erase_sector_stm50; // TODO rename to &stm50_sector_erase; - case EDI_CHIP_BLOCK_ERASE: return &edi_chip_block_erase; - case TEST_ERASE_INJECTOR: return g_test_erase_injector; - /* default: total function, 0 indicates no erase function set. - * We explicitly do not want a default catch-all case in the switch - * to ensure unhandled enum's are compiler warnings. - */ - case NO_BLOCK_ERASE_FUNC: return NULL; - }; - - return NULL; -} - static int check_block_eraser(const struct flashctx *flash, int k, int log) { struct block_eraser eraser = flash->chip->block_erasers[k]; diff --git a/include/chipdrivers.h b/include/chipdrivers.h index 9c9a94c..c5a0acb 100644 --- a/include/chipdrivers.h +++ b/include/chipdrivers.h @@ -22,6 +22,8 @@
#include "flash.h" /* for chipaddr and flashctx */
+erasefunc_t *lookup_erase_func_ptr(const struct block_eraser *const eraser); + /* spi.c */ int spi_aai_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int spi_chip_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); @@ -37,21 +39,6 @@ int probe_spi_at25f(struct flashctx *flash); int spi_write_enable(struct flashctx *flash); int spi_write_disable(struct flashctx *flash); -int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_53(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen); enum block_erase_func spi_get_erasefn_from_opcode(uint8_t opcode); uint8_t spi_get_opcode_from_erasefn(enum block_erase_func func); int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); diff --git a/spi25.c b/spi25.c index da870be..79ac01f 100644 --- a/spi25.c +++ b/spi25.c @@ -492,7 +492,7 @@ return spi_simple_write_cmd(flash, JEDEC_CE_C7, 1000 * 1000); }
-int spi_block_erase_52(struct flashctx *flash, unsigned int addr, +static int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 100-4000ms, so wait in 100ms steps. */ @@ -502,7 +502,7 @@ /* Block size is usually * 32M (one die) for Micron */ -int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 240-480s, so wait in 500ms steps. */ return spi_write_cmd(flash, JEDEC_BE_C4, false, addr, NULL, 0, 500 * 1000); @@ -513,7 +513,7 @@ * 32k for SST * 4-32k non-uniform for EON */ -int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, +static int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 100-4000ms, so wait in 100ms steps. */ @@ -523,7 +523,7 @@ /* Block size is usually * 4k for PMC */ -int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, +static int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 100-4000ms, so wait in 100ms steps. */ @@ -531,7 +531,7 @@ }
/* Page erase (usually 256B blocks) */ -int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This takes up to 20ms usually (on worn out devices up to the 0.5s range), so wait in 1ms steps. */ @@ -539,26 +539,26 @@ }
/* Sector size is usually 4k, though Macronix eliteflash has 64k */ -int spi_block_erase_20(struct flashctx *flash, unsigned int addr, +static int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 15-800ms, so wait in 10ms steps. */ return spi_write_cmd(flash, JEDEC_SE, false, addr, NULL, 0, 10 * 1000); }
-int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 10ms, so wait in 1ms steps. */ return spi_write_cmd(flash, JEDEC_BE_50, false, addr, NULL, 0, 1 * 1000); }
-int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 8ms, so wait in 1ms steps. */ return spi_write_cmd(flash, JEDEC_BE_81, false, addr, NULL, 0, 1 * 1000); }
-int spi_block_erase_60(struct flashctx *flash, unsigned int addr, +static int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { @@ -569,7 +569,7 @@ return spi_chip_erase_60(flash); }
-int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", @@ -579,7 +579,7 @@ return spi_chip_erase_62(flash); }
-int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, +static int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { @@ -591,33 +591,84 @@ }
/* Erase 4 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ -int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 15-800ms, so wait in 10ms steps. */ return spi_write_cmd(flash, 0x21, true, addr, NULL, 0, 10 * 1000); }
/* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ -int spi_block_erase_53(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_53(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0x53, true, addr, NULL, 0, 100 * 1000); }
/* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ -int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0x5c, true, addr, NULL, 0, 100 * 1000); }
/* Erase 64 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ -int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +static int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0xdc, true, addr, NULL, 0, 100 * 1000); }
+/* special unit-test hook */ +erasefunc_t *g_test_erase_injector; + +erasefunc_t *lookup_erase_func_ptr(const struct block_eraser *const eraser) +{ + switch (eraser->block_erase) { + case SPI_BLOCK_ERASE_EMULATION: return &spi_block_erase_emulation; + case SPI_BLOCK_ERASE_20: return &spi_block_erase_20; + case SPI_BLOCK_ERASE_21: return &spi_block_erase_21; + case SPI_BLOCK_ERASE_40: return NULL; // FIXME unhandled &spi_block_erase_40; + case SPI_BLOCK_ERASE_50: return &spi_block_erase_50; + case SPI_BLOCK_ERASE_52: return &spi_block_erase_52; + case SPI_BLOCK_ERASE_53: return &spi_block_erase_53; + case SPI_BLOCK_ERASE_5C: return &spi_block_erase_5c; + case SPI_BLOCK_ERASE_60: return &spi_block_erase_60; + case SPI_BLOCK_ERASE_62: return &spi_block_erase_62; + case SPI_BLOCK_ERASE_81: return &spi_block_erase_81; + case SPI_BLOCK_ERASE_C4: return &spi_block_erase_c4; + case SPI_BLOCK_ERASE_C7: return &spi_block_erase_c7; + case SPI_BLOCK_ERASE_D7: return &spi_block_erase_d7; + case SPI_BLOCK_ERASE_D8: return &spi_block_erase_d8; + case SPI_BLOCK_ERASE_DB: return &spi_block_erase_db; + case SPI_BLOCK_ERASE_DC: return &spi_block_erase_dc; + case S25FL_BLOCK_ERASE: return &s25fl_block_erase; + case S25FS_BLOCK_ERASE_D8: return &s25fs_block_erase_d8; + case JEDEC_SECTOR_ERASE: return &erase_sector_jedec; // TODO rename to &jedec_sector_erase; + case JEDEC_BLOCK_ERASE: return &erase_block_jedec; // TODO rename to &jedec_block_erase; + case JEDEC_CHIP_BLOCK_ERASE: return &erase_chip_block_jedec; // TODO rename to &jedec_chip_block_erase; + case OPAQUE_ERASE: return &erase_opaque; // TODO rename to &opqaue_erase; + case SPI_ERASE_AT45CS_SECTOR: return &spi_erase_at45cs_sector; + case SPI_ERASE_AT45DB_BLOCK: return &spi_erase_at45db_block; + case SPI_ERASE_AT45DB_CHIP: return &spi_erase_at45db_chip; + case SPI_ERASE_AT45DB_PAGE: return &spi_erase_at45db_page; + case SPI_ERASE_AT45DB_SECTOR: return &spi_erase_at45db_sector; + case ERASE_CHIP_28SF040: return &erase_chip_28sf040; + case ERASE_SECTOR_28SF040: return &erase_sector_28sf040; + case ERASE_BLOCK_82802AB: return &erase_block_82802ab; + case ERASE_SECTOR_49LFXXXC: return &erase_sector_49lfxxxc; + case STM50_SECTOR_ERASE: return &erase_sector_stm50; // TODO rename to &stm50_sector_erase; + case EDI_CHIP_BLOCK_ERASE: return &edi_chip_block_erase; + case TEST_ERASE_INJECTOR: return g_test_erase_injector; + /* default: total function, 0 indicates no erase function set. + * We explicitly do not want a default catch-all case in the switch + * to ensure unhandled enum's are compiler warnings. + */ + case NO_BLOCK_ERASE_FUNC: return NULL; + }; + + return NULL; +} + static const struct { enum block_erase_func func; uint8_t opcode;