Anastasia Klimchuk has submitted this change. ( https://review.coreboot.org/c/flashrom/+/58570 )
Change subject: spi25_statusreg,flashchips: add SR2 read/write support ......................................................................
spi25_statusreg,flashchips: add SR2 read/write support
This patch adds support for reading and writing the second status register and enables it on a limited set of flash chips.
Chip support for RDSR2/WRSR2/extended WRSR is represented using feature flags to be consistent with how other SPI capabilities are represented.
BUG=b:195381327,b:153800563 BRANCH=none TEST=flashrom -{r,w,E} TEST=flashrom --wp-{enable,disable,range,list,status} at end of patch series TEST=logged SR2 read/write values during wp commands
Change-Id: I34a503b0958e8f2f22a2a993a6ea529eb46b41db Signed-off-by: Nikolai Artemiev nartemiev@google.com Reviewed-on: https://review.coreboot.org/c/flashrom/+/58570 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Anastasia Klimchuk aklm@chromium.org Reviewed-by: Nico Huber nico.h@gmx.de --- M flash.h M flashchips.c M spi.h M spi25_statusreg.c 4 files changed, 53 insertions(+), 3 deletions(-)
Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved Anastasia Klimchuk: Looks good to me, approved
diff --git a/flash.h b/flash.h index f1a8b34..cd40fa3 100644 --- a/flash.h +++ b/flash.h @@ -140,6 +140,9 @@ #define FEATURE_ERASED_ZERO (1 << 17) #define FEATURE_NO_ERASE (1 << 18)
+#define FEATURE_WRSR_EXT (1 << 19) +#define FEATURE_WRSR2 (1 << 20) + #define ERASED_VALUE(flash) (((flash)->chip->feature_bits & FEATURE_ERASED_ZERO) ? 0x00 : 0xff)
enum test_state { diff --git a/flashchips.c b/flashchips.c index 21eeb39..9e10b5d 100644 --- a/flashchips.c +++ b/flashchips.c @@ -6317,7 +6317,7 @@ .total_size = 16384, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_WRSR_EXT, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -6706,7 +6706,8 @@ .model_id = GIGADEVICE_GD25Q256D, .total_size = 32768, .page_size = 256, - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_WREN, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_WREN | + FEATURE_WRSR_EXT | FEATURE_WRSR2, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -6754,7 +6755,7 @@ .total_size = 4096, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */ - .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_WRSR2, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, diff --git a/spi.h b/spi.h index 09da579..845b6c2 100644 --- a/spi.h +++ b/spi.h @@ -131,6 +131,11 @@ #define JEDEC_RDSR_OUTSIZE 0x01 #define JEDEC_RDSR_INSIZE 0x01
+/* Read Status Register 2 */ +#define JEDEC_RDSR2 0x35 +#define JEDEC_RDSR2_OUTSIZE 0x01 +#define JEDEC_RDSR2_INSIZE 0x01 + /* Status Register Bits */ #define SPI_SR_WIP (0x01 << 0) #define SPI_SR_WEL (0x01 << 1) @@ -146,6 +151,12 @@ #define JEDEC_WRSR 0x01 #define JEDEC_WRSR_OUTSIZE 0x02 #define JEDEC_WRSR_INSIZE 0x00 +#define JEDEC_WRSR_EXT_OUTSIZE 0x03 + +/* Write Status Register 2 */ +#define JEDEC_WRSR2 0x31 +#define JEDEC_WRSR2_OUTSIZE 0x02 +#define JEDEC_WRSR2_INSIZE 0x00
/* Enter 4-byte Address Mode */ #define JEDEC_ENTER_4_BYTE_ADDR_MODE 0xB7 diff --git a/spi25_statusreg.c b/spi25_statusreg.c index 0d7bc25..31d6c76 100644 --- a/spi25_statusreg.c +++ b/spi25_statusreg.c @@ -101,6 +101,33 @@ write_cmd[1] = value; write_cmd_len = JEDEC_WRSR_OUTSIZE; break; + case STATUS2: + if (feature_bits & FEATURE_WRSR2) { + write_cmd[0] = JEDEC_WRSR2; + write_cmd[1] = value; + write_cmd_len = JEDEC_WRSR2_OUTSIZE; + break; + } + if (feature_bits & FEATURE_WRSR_EXT) { + /* + * Writing SR2 with an extended WRSR command requires + * writing SR1 along with SR2, so just read SR1 and + * write it back + */ + uint8_t sr1; + + if (spi_read_register(flash, STATUS1, &sr1)) { + msg_cerr("Writing SR2 failed: failed to read SR1 for writeback.\n"); + return 1; + } + write_cmd[0] = JEDEC_WRSR; + write_cmd[1] = sr1; + write_cmd[2] = value; + write_cmd_len = JEDEC_WRSR_EXT_OUTSIZE; + break; + } + msg_cerr("Cannot write SR2: unsupported by chip\n"); + return 1; default: msg_cerr("Cannot write register: unknown register\n"); return 1; @@ -122,12 +149,20 @@
int spi_read_register(const struct flashctx *flash, enum flash_reg reg, uint8_t *value) { + int feature_bits = flash->chip->feature_bits; uint8_t read_cmd;
switch (reg) { case STATUS1: read_cmd = JEDEC_RDSR; break; + case STATUS2: + if (feature_bits & (FEATURE_WRSR_EXT | FEATURE_WRSR2)) { + read_cmd = JEDEC_RDSR2; + break; + } + msg_cerr("Cannot read SR2: unsupported by chip\n"); + return 1; default: msg_cerr("Cannot read register: unknown register\n"); return 1;
29 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one.