Bill XIE has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/84253?usp=email )
Change subject: ichspi: Restore Sector erase opcode after send command ......................................................................
ichspi: Restore Sector erase opcode after send command
ich_spi_send_command() and ich_spi_send_multicommand() used to overwrite the "Sector erase" opcode with the opcode for command via reprogram_opcode_on_the_fly(), but not restore it, causing the "Sector erase" opcode may get lost after sending commands, leaving only "Bulk erase" opcode which erase the whole chip available.
Now, restore_se_opcode() is introduced to restore the "Sector erase" opcode if it is overwritten, and ich_spi_send_command() and ich_spi_send_multicommand() will call it before returning.
Fix:https://ticket.coreboot.org/issues/556
Change-Id: I3fc831fc072e2af9265835cb2f71bf8c222c6a64 Signed-off-by: persmule persmule@hardenedlinux.org --- M ichspi.c 1 file changed, 27 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/53/84253/1
diff --git a/ichspi.c b/ichspi.c index d01f2f3..e4aabf0 100644 --- a/ichspi.c +++ b/ichspi.c @@ -1140,10 +1140,18 @@ } }
-static int ich_spi_send_command(const struct flashctx *flash, unsigned int writecnt, - unsigned int readcnt, - const unsigned char *writearr, - unsigned char *readarr) +/* Restore the "Sector erase" opcode if it has been overwritten */ +static void restore_se_opcode(void) +{ + if (find_opcode(curopcodes, JEDEC_SE) == -1) + reprogram_opcode_on_the_fly(JEDEC_SE, JEDEC_SE_OUTSIZE, JEDEC_SE_INSIZE); +} + +/* Internal operation to send command */ +static int _ich_spi_send_command(const struct flashctx *flash, unsigned int writecnt, + unsigned int readcnt, + const unsigned char *writearr, + unsigned char *readarr) { int result; int opcode_index = -1; @@ -1269,6 +1277,17 @@ return result; }
+static int ich_spi_send_command(const struct flashctx *flash, unsigned int writecnt, + unsigned int readcnt, + const unsigned char *writearr, + unsigned char *readarr) +{ + int result = _ich_spi_send_command(flash, writecnt, readcnt, writearr, readarr); + /* Restore the "Sector erase" opcode before returning */ + restore_se_opcode(); + return result; +} + #define MAX_FD_REGIONS 16 struct fd_region { const char* name; @@ -1811,12 +1830,14 @@ * preoppos matched, this is a normal opcode. */ } - ret = ich_spi_send_command(flash, cmds->writecnt, cmds->readcnt, - cmds->writearr, cmds->readarr); + ret = _ich_spi_send_command(flash, cmds->writecnt, cmds->readcnt, + cmds->writearr, cmds->readarr); /* Reset the type of all opcodes to non-atomic. */ for (i = 0; i < 8; i++) curopcodes->opcode[i].atomic = 0; } + /* Restore the "Sector erase" opcode before returning */ + restore_se_opcode(); return ret; }