summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward O'Callaghan <quasisec@google.com>2022-08-29 10:36:21 +1000
committerEdward O'Callaghan <quasisec@chromium.org>2022-11-11 13:04:07 +0000
commit3bba710d98b60eba7ebbae0869fd58f7dc987afd (patch)
tree0a5fc97c3edad996c21b4c66828dd366e9d0792f
parent3c44e12a287ce9a91cf97c3303bf4222f63d25c7 (diff)
downloadflashrom-3bba710d98b60eba7ebbae0869fd58f7dc987afd.tar.gz
flashrom-3bba710d98b60eba7ebbae0869fd58f7dc987afd.tar.bz2
flashrom-3bba710d98b60eba7ebbae0869fd58f7dc987afd.zip
tree/: Convert flashchip erase_block func ptr to enumerate
This forges the way for flashchips.c to be pure declarative data and lookup functions for dispatch to be pure. This means that the flashchips data could be extracted out to be agnostic data of the flashrom code and algorithms. Change-Id: I02ae7e4c67c5bf34ec2fd7ffe4af8a2aba6fd5e5 Signed-off-by: Edward O'Callaghan <quasisec@google.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/69133 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Anastasia Klimchuk <aklm@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-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;