Edward O'Callaghan has uploaded this change for review.

View Change

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;

To view, visit change 69959. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I9b1dc33fb8d3e98f26f7d4cd1fbb876c3c5580a2
Gerrit-Change-Number: 69959
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-MessageType: newchange