summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--at45db.c5
-rw-r--r--flashrom.c54
-rw-r--r--include/chipdrivers.h4
-rw-r--r--include/flash.h75
-rw-r--r--sfdp.c2
-rw-r--r--spi25.c8
-rw-r--r--tests/chip.c7
7 files changed, 108 insertions, 47 deletions
diff --git a/at45db.c b/at45db.c
index 53e15ec80..787733093 100644
--- a/at45db.c
+++ b/at45db.c
@@ -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;
}
}
}
diff --git a/flashrom.c b/flashrom.c
index 08e3969e0..815f489b2 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -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 470d1fe26..3b07afe31 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 03c1e2c69..238d0101e 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);
diff --git a/sfdp.c b/sfdp.c
index a09827dff..ccf840f43 100644
--- a/sfdp.c
+++ b/sfdp.c
@@ -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) {
diff --git a/spi25.c b/spi25.c
index fb9474840..da870be70 100644
--- a/spi25.c
+++ b/spi25.c
@@ -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 579643c78..1d9cdc9cf 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;