Attention is currently required from: Damien Zammit. Hello Damien Zammit,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/flashrom/+/62983
to review the following change.
Change subject: Prepare for IFD check_access support ......................................................................
Prepare for IFD check_access support
Based off work in collaboration with Damien Zammit.
The following is intended to allow flashrom to query the spi or opaque master for access permissions before attempting to access a given region. This comes up in cases such as the ichspi driver where the CSME can deny regions access.
Change-Id: If7bdcac2a4109efbc70abc2d6ae0561f39449004 Signed-off-by: Damien Zammit damien@zamaudio.com Signed-off-by: Edward O'Callaghan quasisec@google.com --- M chipdrivers.h M flash.h M flashrom.c M opaque.c M programmer.h M spi.c M spi.h 7 files changed, 31 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/83/62983/1
diff --git a/chipdrivers.h b/chipdrivers.h index c223534..1a4e617 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -115,6 +115,7 @@ 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); +int check_access_opaque(const struct flashctx *flash, unsigned int start, unsigned int len, int write);
/* at45db.c */ int probe_spi_at45db(struct flashctx *flash); diff --git a/flash.h b/flash.h index f63aa5d..9882fb6 100644 --- a/flash.h +++ b/flash.h @@ -267,6 +267,7 @@ int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); uint8_t (*read_status) (const struct flashctx *flash); int (*write_status) (const struct flashctx *flash, int status); + int (*check_access) (const struct flashctx *flash, unsigned int start, unsigned int len, int write); struct voltage { uint16_t min; uint16_t max; diff --git a/flashrom.c b/flashrom.c index ac61259..8266be9 100644 --- a/flashrom.c +++ b/flashrom.c @@ -1060,11 +1060,22 @@ { const struct flashrom_layout *const layout = get_layout(flashctx); const struct romentry *entry = NULL; + int ret;
while ((entry = layout_next_included(layout, entry))) { const chipoff_t region_start = entry->start; const chipsize_t region_len = entry->end - entry->start + 1;
+ if (flashctx->mst->buses_supported & BUS_PROG) { + ret = check_access_opaque(flashctx, region_start, region_len, 0); + if (!ret) + continue; + } else if (flashctx->mst->buses_supported & BUS_SPI) { + ret = check_access_spi(flashctx, region_start, region_len, 0); + if (!ret) + continue; + } + if (flashctx->chip->read(flashctx, buffer + region_start, region_start, region_len)) return 1; } diff --git a/opaque.c b/opaque.c index 7704ec7..8633a16 100644 --- a/opaque.c +++ b/opaque.c @@ -46,6 +46,13 @@ return flash->mst->opaque.erase(flash, blockaddr, blocklen); }
+int check_access_opaque(const struct flashctx *flash, unsigned int start, unsigned int len, int write) +{ + if (flash->mst->opaque.check_access) + return flash->mst->opaque.check_access(flash, start, len, write); + return 1; +} + int register_opaque_master(const struct opaque_master *mst, void *data) { struct registered_master rmst = {0}; diff --git a/programmer.h b/programmer.h index c79422c..2a5f2a9 100644 --- a/programmer.h +++ b/programmer.h @@ -312,6 +312,7 @@ int (*read)(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int (*write_256)(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int (*write_aai)(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); + int (*check_access)(const struct flashctx *flash, unsigned int start, unsigned int len, int write); int (*shutdown)(void *data); void *data; }; @@ -322,6 +323,7 @@ int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); +int check_access_spi(const struct flashctx *flash, unsigned int start, unsigned int len, int write); int register_spi_master(const struct spi_master *mst, void *data);
/* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */ @@ -402,6 +404,7 @@ 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); + int (*check_access) (const struct flashctx *flash, unsigned int start, unsigned int len, int write); int (*shutdown)(void *data); void *data; }; diff --git a/spi.c b/spi.c index f2e91c4..6c640fd 100644 --- a/spi.c +++ b/spi.c @@ -131,6 +131,13 @@ return flash->mst->spi.write_aai(flash, buf, start, len); }
+int check_access_spi(const struct flashctx *flash, unsigned int start, unsigned int len, int write) +{ + if (flash->mst->spi.check_access) + return flash->mst->spi.check_access(flash, start, len, write); + return 1; +} + int register_spi_master(const struct spi_master *mst, void *data) { struct registered_master rmst = {0}; diff --git a/spi.h b/spi.h index 845b6c2..93c8aa1 100644 --- a/spi.h +++ b/spi.h @@ -208,6 +208,7 @@ #define SPI_INVALID_LENGTH -4 #define SPI_FLASHROM_BUG -5 #define SPI_PROGRAMMER_ERROR -6 +#define SPI_ACCESS_DENIED -7
void clear_spi_id_cache(void);