diff options
-rw-r--r-- | at45db.c | 5 | ||||
-rw-r--r-- | flashrom.c | 54 | ||||
-rw-r--r-- | include/chipdrivers.h | 4 | ||||
-rw-r--r-- | include/flash.h | 75 | ||||
-rw-r--r-- | sfdp.c | 2 | ||||
-rw-r--r-- | spi25.c | 8 | ||||
-rw-r--r-- | tests/chip.c | 7 |
7 files changed, 108 insertions, 47 deletions
@@ -80,9 +80,10 @@ static unsigned int at45db_get_sector_count(struct flashctx *flash) unsigned int i, j; unsigned int cnt = 0; for (i = 0; i < NUM_ERASEFUNCTIONS; i++) { - if (flash->chip->block_erasers[i].block_erase == SPI_ERASE_AT45DB_SECTOR) { + const struct block_eraser *const eraser = &flash->chip->block_erasers[i]; + if (eraser->block_erase == SPI_ERASE_AT45DB_SECTOR) { for (j = 0; j < NUM_ERASEREGIONS; j++) { - cnt += flash->chip->block_erasers[i].eraseblocks[j].count; + cnt += eraser->eraseblocks[j].count; } } } @@ -336,6 +336,57 @@ char *extract_programmer_param_str(const struct programmer_cfg *cfg, const char 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]; @@ -1099,7 +1150,8 @@ static int walk_eraseblocks(struct flashctx *const flashctx, msg_cdbg(", "); msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end); - ret = per_blockfn(flashctx, info, eraser->block_erase); + erasefunc_t *erase_func = lookup_erase_func_ptr(eraser); + ret = per_blockfn(flashctx, info, erase_func); if (ret) return ret; } diff --git a/include/chipdrivers.h b/include/chipdrivers.h index 470d1fe2..3b07afe3 100644 --- a/include/chipdrivers.h +++ b/include/chipdrivers.h @@ -52,8 +52,8 @@ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int b 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); -erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode); -uint8_t spi_get_opcode_from_erasefn(erasefunc_t *func); +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); int spi_nbyte_read(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize); diff --git a/include/flash.h b/include/flash.h index 03c1e2c6..238d0101 100644 --- a/include/flash.h +++ b/include/flash.h @@ -268,41 +268,44 @@ enum read_func { typedef int (read_func_t)(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int read_flash(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); -#define NO_BLOCK_ERASE_FUNC NULL -#define SPI_BLOCK_ERASE_EMULATION &spi_block_erase_emulation -#define SPI_BLOCK_ERASE_20 &spi_block_erase_20 -#define SPI_BLOCK_ERASE_21 &spi_block_erase_21 -#define SPI_BLOCK_ERASE_40 &spi_block_erase_40 -#define SPI_BLOCK_ERASE_50 &spi_block_erase_50 -#define SPI_BLOCK_ERASE_52 &spi_block_erase_52 -#define SPI_BLOCK_ERASE_53 &spi_block_erase_53 -#define SPI_BLOCK_ERASE_5C &spi_block_erase_5c -#define SPI_BLOCK_ERASE_60 &spi_block_erase_60 -#define SPI_BLOCK_ERASE_62 &spi_block_erase_62 -#define SPI_BLOCK_ERASE_81 &spi_block_erase_81 -#define SPI_BLOCK_ERASE_C4 &spi_block_erase_c4 -#define SPI_BLOCK_ERASE_C7 &spi_block_erase_c7 -#define SPI_BLOCK_ERASE_D7 &spi_block_erase_d7 -#define SPI_BLOCK_ERASE_D8 &spi_block_erase_d8 -#define SPI_BLOCK_ERASE_DB &spi_block_erase_db -#define SPI_BLOCK_ERASE_DC &spi_block_erase_dc -#define S25FL_BLOCK_ERASE &s25fl_block_erase -#define S25FS_BLOCK_ERASE_D8 &s25fs_block_erase_d8 -#define JEDEC_SECTOR_ERASE &erase_sector_jedec -#define JEDEC_BLOCK_ERASE &erase_block_jedec -#define JEDEC_CHIP_BLOCK_ERASE &erase_chip_block_jedec -#define OPAQUE_ERASE &erase_opaque -#define SPI_ERASE_AT45CS_SECTOR &spi_erase_at45cs_sector -#define SPI_ERASE_AT45DB_BLOCK &spi_erase_at45db_block -#define SPI_ERASE_AT45DB_CHIP &spi_erase_at45db_chip -#define SPI_ERASE_AT45DB_PAGE &spi_erase_at45db_page -#define SPI_ERASE_AT45DB_SECTOR &spi_erase_at45db_sector -#define ERASE_CHIP_28SF040 &erase_chip_28sf040 -#define ERASE_SECTOR_28SF040 &erase_sector_28sf040 -#define ERASE_BLOCK_82802AB &erase_block_82802ab -#define ERASE_SECTOR_49LFXXXC &erase_sector_49lfxxxc -#define STM50_SECTOR_ERASE &erase_sector_stm50 -#define EDI_CHIP_BLOCK_ERASE &edi_chip_block_erase +enum block_erase_func { + NO_BLOCK_ERASE_FUNC = 0, /* 0 indicates no block erase function set. */ + SPI_BLOCK_ERASE_EMULATION = 1, + SPI_BLOCK_ERASE_20, + SPI_BLOCK_ERASE_21, + SPI_BLOCK_ERASE_40, + SPI_BLOCK_ERASE_50, + SPI_BLOCK_ERASE_52, + SPI_BLOCK_ERASE_53, + SPI_BLOCK_ERASE_5C, + SPI_BLOCK_ERASE_60, + SPI_BLOCK_ERASE_62, + SPI_BLOCK_ERASE_81, + SPI_BLOCK_ERASE_C4, + SPI_BLOCK_ERASE_C7, + SPI_BLOCK_ERASE_D7, + SPI_BLOCK_ERASE_D8, + SPI_BLOCK_ERASE_DB, + SPI_BLOCK_ERASE_DC, + S25FL_BLOCK_ERASE, + S25FS_BLOCK_ERASE_D8, + JEDEC_SECTOR_ERASE, + JEDEC_BLOCK_ERASE, + JEDEC_CHIP_BLOCK_ERASE, + OPAQUE_ERASE, + SPI_ERASE_AT45CS_SECTOR, + SPI_ERASE_AT45DB_BLOCK, + SPI_ERASE_AT45DB_CHIP, + SPI_ERASE_AT45DB_PAGE, + SPI_ERASE_AT45DB_SECTOR, + ERASE_CHIP_28SF040, + ERASE_SECTOR_28SF040, + ERASE_BLOCK_82802AB, + ERASE_SECTOR_49LFXXXC, + STM50_SECTOR_ERASE, + EDI_CHIP_BLOCK_ERASE, + TEST_ERASE_INJECTOR, /* special case must come last. */ +}; struct flashchip { const char *vendor; @@ -366,7 +369,7 @@ struct flashchip { } eraseblocks[NUM_ERASEREGIONS]; /* a block_erase function should try to erase one block of size * 'blocklen' at address 'blockaddr' and return 0 on success. */ - int (*block_erase) (struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); + enum block_erase_func block_erase; } block_erasers[NUM_ERASEFUNCTIONS]; int (*printlock) (struct flashctx *flash); @@ -81,7 +81,7 @@ static int sfdp_add_uniform_eraser(struct flashchip *chip, uint8_t opcode, uint3 { int i; uint32_t total_size = chip->total_size * 1024; - erasefunc_t *erasefn = spi_get_erasefn_from_opcode(opcode); + enum block_erase_func erasefn = spi_get_erasefn_from_opcode(opcode); if (erasefn == NO_BLOCK_ERASE_FUNC || total_size == 0 || block_size == 0 || total_size % block_size != 0) { @@ -619,7 +619,7 @@ int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int b } static const struct { - erasefunc_t *func; + enum block_erase_func func; uint8_t opcode; } function_opcode_list[] = { {SPI_BLOCK_ERASE_20, 0x20}, @@ -639,7 +639,7 @@ static const struct { {SPI_BLOCK_ERASE_DC, 0xdc}, }; -erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode) +enum block_erase_func spi_get_erasefn_from_opcode(uint8_t opcode) { size_t i; for (i = 0; i < ARRAY_SIZE(function_opcode_list); i++) { @@ -651,14 +651,14 @@ erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode) return NO_BLOCK_ERASE_FUNC; } -uint8_t spi_get_opcode_from_erasefn(erasefunc_t *func) +uint8_t spi_get_opcode_from_erasefn(enum block_erase_func func) { size_t i; for (i = 0; i < ARRAY_SIZE(function_opcode_list); i++) { if (function_opcode_list[i].func == func) return function_opcode_list[i].opcode; } - msg_cinfo("%s: unknown erase function (0x%p). Please report " + msg_cinfo("%s: unknown erase function (0x%d). Please report " "this at flashrom@flashrom.org\n", __func__, func); return 0x00; //Assuming 0x00 is not a erase function opcode } diff --git a/tests/chip.c b/tests/chip.c index 579643c7..1d9cdc9c 100644 --- a/tests/chip.c +++ b/tests/chip.c @@ -148,6 +148,7 @@ static void teardown(struct flashrom_layout **layout) extern write_func_t *g_test_write_injector; extern read_func_t *g_test_read_injector; +extern erasefunc_t *g_test_erase_injector; static const struct flashchip chip_8MiB = { .vendor = "aklm", @@ -160,7 +161,7 @@ static const struct flashchip chip_8MiB = { {{ /* All blocks within total size of the chip. */ .eraseblocks = { {2 * MiB, 4} }, - .block_erase = block_erase_chip, + .block_erase = TEST_ERASE_INJECTOR, }}, }; @@ -208,6 +209,7 @@ void erase_chip_test_success(void **state) g_test_write_injector = write_chip; g_test_read_injector = read_chip; + g_test_erase_injector = block_erase_chip; struct flashrom_flashctx flashctx = { 0 }; struct flashrom_layout *layout; struct flashchip mock_chip = chip_8MiB; @@ -268,6 +270,7 @@ void read_chip_test_success(void **state) g_test_write_injector = write_chip; g_test_read_injector = read_chip; + g_test_erase_injector = block_erase_chip; struct flashrom_flashctx flashctx = { 0 }; struct flashrom_layout *layout; struct flashchip mock_chip = chip_8MiB; @@ -341,6 +344,7 @@ void write_chip_test_success(void **state) g_test_write_injector = write_chip; g_test_read_injector = read_chip; + g_test_erase_injector = block_erase_chip; struct flashrom_flashctx flashctx = { 0 }; struct flashrom_layout *layout; struct flashchip mock_chip = chip_8MiB; @@ -440,6 +444,7 @@ void verify_chip_test_success(void **state) g_test_write_injector = write_chip; g_test_read_injector = read_chip; + g_test_erase_injector = block_erase_chip; struct flashrom_flashctx flashctx = { 0 }; struct flashrom_layout *layout; struct flashchip mock_chip = chip_8MiB; |