Attention is currently required from: Nikolai Artemiev.
Hello Nikolai Artemiev,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/flashrom/+/69517
to review the following change.
Change subject: flashrom.c: Supplement `chip->unlock()` calls with wp unlocking ......................................................................
flashrom.c: Supplement `chip->unlock()` calls with wp unlocking
The full writeprotect implementation has proper support and ability to unlock flash over spi25_statusreg.c. Therefore if the required bits are available for the given chip prefer proper writeprotect support instead of adhoc spi25_statusreg.c helpers.
BUG=b:237485865 BRANCH=none TEST=make
Change-Id: I74b3f5d3a17749ea60485b916b2d87467a5d8b2f CoAuthored-by: Nikolai Artemiev nartemiev@google.com Signed-off-by: Nikolai Artemiev nartemiev@google.com Signed-off-by: Edward O'Callaghan quasisec@google.com --- M flashrom.c M include/flash.h 2 files changed, 65 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/17/69517/1
diff --git a/flashrom.c b/flashrom.c index b1782d9..d422d98 100644 --- a/flashrom.c +++ b/flashrom.c @@ -1684,6 +1684,32 @@ return 0; }
+static int unlock_flash_wp(struct flashctx *const flash) +{ + struct flashrom_wp_cfg *unlocked_cfg = NULL; + + /* Save old WP config */ + if (flashrom_wp_cfg_new(&flash->old_wp_cfg) != FLASHROM_WP_OK) + return -1; + if (flashrom_wp_read_cfg(flash->old_wp_cfg, flash) != FLASHROM_WP_OK) + return -1; + + /* Disable WP */ + if (flashrom_wp_cfg_new(&unlocked_cfg) != FLASHROM_WP_OK) + return -1; + flashrom_wp_set_range(unlocked_cfg, 0, 0); + flashrom_wp_set_mode(unlocked_cfg, FLASHROM_WP_MODE_DISABLED); + + enum flashrom_wp_result ret = flashrom_wp_write_cfg(flash, unlocked_cfg); + + flashrom_wp_cfg_release(unlocked_cfg); + + if(ret != FLASHROM_WP_OK) + return -1; + + return 0; +} + int prepare_flash_access(struct flashctx *const flash, const bool read_it, const bool write_it, const bool erase_it, const bool verify_it) @@ -1706,10 +1732,16 @@ /* Initialize chip_restore_fn_count before chip unlock calls. */ flash->chip_restore_fn_count = 0;
- /* Given the existence of read locks, we want to unlock for read, - erase and write. */ - if (flash->chip->unlock) + /* Clear so we don't try to write back bad cfg in finalize_flash_access() */ + flash->old_wp_cfg = NULL; + + /* Given the existence of read locks, we want to unlock for read, erase and write. */ + if (flash->chip->decode_range != NO_DECODE_RANGE_FUNC) { + if (unlock_flash_wp(flash) < 0) + goto err_out; + } else if (flash->chip->unlock) { flash->chip->unlock(flash); + }
flash->address_high_byte = -1; flash->in_4ba_mode = false; @@ -1739,11 +1771,17 @@ return 0;
err_out: + flashrom_wp_cfg_release(flash->old_wp_cfg); return ret; }
void finalize_flash_access(struct flashctx *const flash) { + if (flash->old_wp_cfg) { + flashrom_wp_write_cfg(flash, flash->old_wp_cfg); + flashrom_wp_cfg_release(flash->old_wp_cfg); + flash->old_wp_cfg = NULL; + } deregister_chip_restore(flash); unmap_flash(flash); } diff --git a/include/flash.h b/include/flash.h index ea8e25b..4b448f1 100644 --- a/include/flash.h +++ b/include/flash.h @@ -460,6 +460,8 @@ chip_restore_fn_cb_t func; uint8_t status; } chip_restore_fn[MAX_CHIP_RESTORE_FUNCTIONS]; + struct flashrom_wp_cfg *old_wp_cfg; + /* Progress reporting */ flashrom_progress_callback *progress_callback; struct flashrom_progress *progress_state;