Nikolai Artemiev has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/58476 )
Change subject: [RFC] spi25_statusreg, flashchips: add SR2 read/write support ......................................................................
[RFC] 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.
Support for each of the specific SR2-related commands is represented using new feature flags. This may not be an ideal representation, but it should be fairly easy to swap out for a better one.
BUG=b:195381327,b:153800563 TEST=logged SPI values, ran writeprotect commands that read/wrote SR2 BRANCH=none
Signed-off-by: Nikolai Artemiev nartemiev@google.com
with '#' will be ignored, and an empty message aborts the commit.
Change-Id: Icc2dea15763bde6c5da1e13d30040069f4f6d585 --- M flash.h M flashchips.c M spi25_statusreg.c 3 files changed, 39 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/76/58476/1
diff --git a/flash.h b/flash.h index c3f99c9..ccae05d 100644 --- a/flash.h +++ b/flash.h @@ -142,6 +142,12 @@ #define FEATURE_ERASED_ZERO (1 << 17) #define FEATURE_NO_ERASE (1 << 18)
+#define FEATURE_WRSR_EXT_SR2 (1 << 19) +#define FEATURE_WRSR2_31H (1 << 20) +#define FEATURE_RDSR2_35H (1 << 21) +#define FEATURE_RDCR1_15H (1 << 22) + + #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 434c46d..0d0a8e2 100644 --- a/flashchips.c +++ b/flashchips.c @@ -6317,7 +6317,8 @@ .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_SR2 | FEATURE_RDSR2_35H, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -6754,7 +6755,8 @@ .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_31H | FEATURE_RDSR2_35H, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, @@ -6866,7 +6868,8 @@ .total_size = 8192, .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_SR2 | FEATURE_RDSR2_35H, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, diff --git a/spi25_statusreg.c b/spi25_statusreg.c index 8e8eead..0eb2af4 100644 --- a/spi25_statusreg.c +++ b/spi25_statusreg.c @@ -91,6 +91,26 @@ write_cmd[1] = value; write_cmd_len = 2; } + else if (reg == STATUS2) { + if (feature_bits & FEATURE_WRSR_EXT_SR2) { + /* 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)) + return 1; + + write_cmd[0] = JEDEC_WRSR; + write_cmd[1] = sr1; + write_cmd[2] = value; + write_cmd_len = 3; + } + else if (feature_bits & FEATURE_WRSR2_31H) { + write_cmd[0] = 0x31; + write_cmd[1] = value; + write_cmd_len = 2; + } + } if(write_cmd_len == 0) { msg_cerr("Cannot write register: not supported by chip\n"); return 1; @@ -112,11 +132,18 @@
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;
if (reg == STATUS1) { read_cmd = JEDEC_RDSR; } + else if (reg == STATUS2 && (feature_bits & FEATURE_RDSR2_35H)) { + read_cmd = 0x35; + } + else if (reg == CONFIG1 && (feature_bits & FEATURE_RDCR1_15H)) { + read_cmd = 0x15; + } else { msg_cerr("Cannot read register: not supported by chip\n"); return 1;