From 3a6d88f4385886298ae0362ee8543725599fdd80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Iwanicki?= Date: Thu, 23 Oct 2025 10:07:11 +0200 Subject: [PATCH] flashrom.c: move `can_change_target_regions` check below wp unlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should check if target regions are writable after trying to unlock them, not before. Tested on PC Engines APU4A: ``` $ ./flashrom -p internal -c W25Q64BV/W25Q64CV/W25Q64FV --wp-status (...) Protection range: start=0x00400000 length=0x00400000 (upper 1/2) Protection mode: hardware ``` Before this PR trying to write wp protected region: ``` $ ./flashrom -p internal -c W25Q64BV/W25Q64CV/W25Q64FV -l \ <(echo -e '00300000:00500000 wp\n') -i wp -w image.bin ``` Failed with: ``` cannot fully update wp region (0x300000..0x500000) due to chip's write-protection ``` With this change: ``` Using region: "wp". coreboot table found at 0x7ecc2000. Found chipset "AMD FCH". Enabling flash write... OK. Found Winbond flash chip "W25Q64BV/W25Q64CV/W25Q64FV" (8192 kB, SPI) mapped at physical address 0x00000000ff800000. Reading old flash chip contents... done. Updating flash chip contents... Region [0x00300000 - 0x00500000] is not sector aligned! Extending end boundaries by 0x00000fff bytes, from 0x00500000 -> 0x00500fff Erase/write done from 300000 to 500fff ``` Change-Id: I624d2b6427e7d5e25d11c16035c7c7ce040e5163 Signed-off-by: MichaƂ Iwanicki Reviewed-on: https://review.coreboot.org/c/flashrom/+/89689 Tested-by: build bot (Jenkins) Reviewed-by: Anastasia Klimchuk Reviewed-by: Sergii Dmytruk --- flashrom.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/flashrom.c b/flashrom.c index 100fc480a..b6f52fa55 100644 --- a/flashrom.c +++ b/flashrom.c @@ -1900,13 +1900,6 @@ int prepare_flash_access(struct flashctx *const flash, return 1; } - if ((write_it || erase_it) && !flash->flags.force) { - if (!can_change_target_regions(flash)) { - msg_cerr("At least one target region is not fully writable. Aborting.\n"); - return 1; - } - } - if (map_flash(flash) != 0) return 1; @@ -1930,6 +1923,13 @@ int prepare_flash_access(struct flashctx *const flash, if (ret && bp_func) bp_func(flash); + if ((write_it || erase_it) && !flash->flags.force) { + if (!can_change_target_regions(flash)) { + msg_cerr("At least one target region is not fully writable. Aborting.\n"); + return 1; + } + } + flash->address_high_byte = -1; flash->in_4ba_mode = false;