Edward O'Callaghan has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/48134 )
Change subject: opaque: Implement opaque master hookable {read,write}_status callbacks ......................................................................
opaque: Implement opaque master hookable {read,write}_status callbacks
This allows for opaque masters to hook their own bespoke R/W primatives for status register manipulation. This is a pre-requirement to allow for ichspi to allow for write-protect support.
BUG=b:174432470 TEST=builds
Change-Id: I6fd8ba151dba2d0deb4b1dd86ba708d4fd3caeb9 Signed-off-by: Edward O'Callaghan quasisec@google.com --- M chipdrivers.h M flashchips.c M opaque.c M programmer.h M spi25_statusreg.c 5 files changed, 36 insertions(+), 11 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/34/48134/1
diff --git a/chipdrivers.h b/chipdrivers.h index cf03811..64a1d73 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -113,6 +113,8 @@ int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int write_opaque(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); +uint8_t read_status_opaque(const struct flashctx *flash); +int write_status_opaque(const struct flashctx *flash, int status);
/* at45db.c */ int probe_spi_at45db(struct flashctx *flash); diff --git a/flashchips.c b/flashchips.c index c4ba4c6..e7b13a3 100644 --- a/flashchips.c +++ b/flashchips.c @@ -18930,6 +18930,8 @@ }, .write = write_opaque, .read = read_opaque, + .read_status = read_status_opaque, + .write_status = write_status_opaque, },
{ diff --git a/opaque.c b/opaque.c index 276934f..de89181 100644 --- a/opaque.c +++ b/opaque.c @@ -46,6 +46,20 @@ return flash->mst->opaque.erase(flash, blockaddr, blocklen); }
+uint8_t read_status_opaque(const struct flashctx *flash) +{ + if (flash->mst->opaque.read_status) + return flash->mst->opaque.read_status(flash); + return 1; +} + +int write_status_opaque(const struct flashctx *flash, int status) +{ + if (flash->mst->opaque.write_status) + return flash->mst->opaque.write_status(flash, status); + return 1; +} + int register_opaque_master(const struct opaque_master *mst) { struct registered_master rmst; diff --git a/programmer.h b/programmer.h index c93bf83..888c62c 100644 --- a/programmer.h +++ b/programmer.h @@ -722,6 +722,8 @@ int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int (*write) (struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int (*erase) (struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); + uint8_t (*read_status) (const struct flashctx *flash); + int (*write_status) (const struct flashctx *flash, int status); const void *data; }; int register_opaque_master(const struct opaque_master *mst); diff --git a/spi25_statusreg.c b/spi25_statusreg.c index 34f9ad4..a6d8676 100644 --- a/spi25_statusreg.c +++ b/spi25_statusreg.c @@ -83,11 +83,15 @@ "EWSR is needed\n"); feature_bits |= FEATURE_WRSR_EWSR; } - if (feature_bits & FEATURE_WRSR_WREN) - ret = spi_write_status_register_flag(flash, status, JEDEC_WREN); - if (ret && (feature_bits & FEATURE_WRSR_EWSR)) - ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR); - return ret; + if (flash->chip->write_status) { + ret = flash->chip->write_status(flash, status); + } else { + if (feature_bits & FEATURE_WRSR_WREN) + ret = spi_write_status_register_flag(flash, status, JEDEC_WREN); + if (ret && (feature_bits & FEATURE_WRSR_EWSR)) + ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR); + } + return ret; }
uint8_t spi_read_status_register(const struct flashctx *flash) @@ -95,16 +99,17 @@ static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR }; /* FIXME: No workarounds for driver/hardware bugs in generic code. */ unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */ - int ret; + int ret = 0;
/* Read Status Register */ - ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr); - if (ret) { + if (flash->chip->read_status) + readarr[0] = flash->chip->read_status(flash); + else + ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr); + if (ret) msg_cerr("RDSR failed!\n"); - /* FIXME: We should propagate the error. */ - return 0; - }
+ /* FIXME: We should propagate the error. */ return readarr[0]; }