Consider 4BA support when filtering erase functions
When we decide which erase functions to use, we need to know exactly
which functions are supported by the used programmer. We missed that
some programmers can't send 4-byte adddresses. As we already have a
feature flag for this, check it right away for all 4BA erase opcodes.
This affects mostly rare combinations of external programmers with
modern 4BA flash chips. For instance early versions of the Dediprog
SF100.
Tests confirmed that this fixes the combination of a first protocol
generation SF100 with a Winbond W25Q256JV.
Change-Id: I51da2832a6a703058da57cdc0335b214653453ed
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/99
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: Nico Huber <nico.h@gmx.de>
diff --git a/flashprog.c b/flashprog.c
index 096453e..8babb86 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -858,10 +858,13 @@
}
if (flash->chip->bustype == BUS_SPI) {
- const uint8_t *opcode = spi_get_opcode_from_erasefn(eraser.block_erase);
+ bool native_4ba;
int i;
+
+ const uint8_t *opcode = spi_get_opcode_from_erasefn(eraser.block_erase, &native_4ba);
for (i = 0; opcode[i]; i++) {
- if (!flash->mst->spi.probe_opcode(flash, opcode[i])) {
+ if ((native_4ba && !spi_master_4ba(flash)) ||
+ !flash->mst->spi.probe_opcode(flash, opcode[i])) {
if (log)
msg_cdbg("block erase function and layout found "
"but SPI master doesn't support the function. ");
diff --git a/include/chipdrivers.h b/include/chipdrivers.h
index 792eb08..31afc84 100644
--- a/include/chipdrivers.h
+++ b/include/chipdrivers.h
@@ -53,7 +53,7 @@
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 *spi25_get_erasefn_from_opcode(uint8_t opcode);
-const uint8_t *spi_get_opcode_from_erasefn(erasefunc_t *func);
+const uint8_t *spi_get_opcode_from_erasefn(erasefunc_t *func, bool *native_4ba);
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/spi.c b/spi.c
index 6e61f53..ddf76f5 100644
--- a/spi.c
+++ b/spi.c
@@ -173,37 +173,41 @@
static const struct {
erasefunc_t *func;
uint8_t opcode[3];
+ bool native_4ba;
} function_opcode_list[] = {
- {spi_block_erase_20, {0x20}},
- {spi_block_erase_21, {0x21}},
- {spi_block_erase_50, {0x50}},
- {spi_block_erase_52, {0x52}},
- {spi_block_erase_53, {0x53}},
- {spi_block_erase_5c, {0x5c}},
- {spi_block_erase_60, {0x60}},
- {spi_block_erase_62, {0x62}},
- {spi_block_erase_81, {0x81}},
- {spi_block_erase_c4, {0xc4}},
- {spi_block_erase_c7, {0xc7}},
- {spi_block_erase_d7, {0xd7}},
- {spi_block_erase_d8, {0xd8}},
- {spi_block_erase_db, {0xdb}},
- {spi_block_erase_dc, {0xdc}},
+ {spi_block_erase_20, {0x20}, false},
+ {spi_block_erase_21, {0x21}, true},
+ {spi_block_erase_50, {0x50}, false},
+ {spi_block_erase_52, {0x52}, false},
+ {spi_block_erase_53, {0x53}, true},
+ {spi_block_erase_5c, {0x5c}, true},
+ {spi_block_erase_60, {0x60}, false},
+ {spi_block_erase_62, {0x62}, false},
+ {spi_block_erase_81, {0x81}, false},
+ {spi_block_erase_c4, {0xc4}, false},
+ {spi_block_erase_c7, {0xc7}, false},
+ {spi_block_erase_d7, {0xd7}, false},
+ {spi_block_erase_d8, {0xd8}, false},
+ {spi_block_erase_db, {0xdb}, false},
+ {spi_block_erase_dc, {0xdc}, true},
//AT45CS1282
- {spi_erase_at45cs_sector, {0x50, 0x7c, 0}},
+ {spi_erase_at45cs_sector, {0x50, 0x7c, 0}, false},
//AT45DB**
- {spi_erase_at45db_page, {0x81}},
- {spi_erase_at45db_block, {0x50}},
- {spi_erase_at45db_sector, {0x7c}},
- {spi_erase_at45db_chip, {0xc7}},
+ {spi_erase_at45db_page, {0x81}, false},
+ {spi_erase_at45db_block, {0x50}, false},
+ {spi_erase_at45db_sector, {0x7c}, false},
+ {spi_erase_at45db_chip, {0xc7}, false},
};
-const uint8_t *spi_get_opcode_from_erasefn(erasefunc_t *func)
+const uint8_t *spi_get_opcode_from_erasefn(erasefunc_t *func, bool *native_4ba)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(function_opcode_list); i++) {
- if (function_opcode_list[i].func == func)
+ if (function_opcode_list[i].func == func) {
+ if (native_4ba)
+ *native_4ba = function_opcode_list[i].native_4ba;
return function_opcode_list[i].opcode;
+ }
}
msg_cinfo("%s: unknown erase function (0x%p). Please report "
"this at flashprog@flashprog.org\n", __func__, func);