This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8981
-- gerrit commit 765e6e1a47c328f42856b1191c54482c204b00a7 Author: Tomas Vanek <van...@fbl.cz> Date: Thu Jul 3 06:52:29 2025 +0200 flash/nor/stm32l4x: fix permanent write protection on STM32U5 Unlike other devices supported by this driver STM32U5 devices have a new UNLOCK bit in FLASH_WRP1AR, WRP1BR, WRP2AR, WRP2BR registers. Writing zero to this bit makes the write protection block permanent with no way to unprotect. Commit 6554d176e926 ("flash/stm32l4x: support STM32U59/U5Ax devices") and later commits with additional U5 devices lack support for the UNLOCK bit and therefore makes write protection permanent without warning. Introduce the new bit flag F_WRP_HAS_LOCK and mark U5 devices by it. Set UNLOCK bit in stm32l4_write_one_wrpxy() if F_WRP_HAS_LOCK is set. Change-Id: I26b97d855e094a21540e3377f367520683af2eac Signed-off-by: Tomas Vanek <van...@fbl.cz> diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index f16333201b..8001aaf006 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -152,6 +152,9 @@ /* this flag indicates that programming should be done in quad-word * the default programming word size is double-word */ #define F_QUAD_WORD_PROG BIT(4) +/* the registers WRPxyR have UNLOCK bit - writing zero locks the write + * protection region permanently! */ +#define F_WRP_HAS_LOCK BIT(5) /* end of STM32L4 flags ******************************************************/ @@ -500,7 +503,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .num_revs = ARRAY_SIZE(stm32u53_u54xx_revs), .device_str = "STM32U535/U545", .max_flash_size_kb = 512, - .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS, + .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ + | F_HAS_L5_FLASH_REGS | F_WRP_HAS_LOCK, .flash_regs_base = 0x40022000, .fsize_addr = 0x0BFA07A0, .otp_base = 0x0BFA0000, @@ -692,7 +696,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .num_revs = ARRAY_SIZE(stm32u59_u5axx_revs), .device_str = "STM32U59/U5Axx", .max_flash_size_kb = 4096, - .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS, + .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ + | F_HAS_L5_FLASH_REGS | F_WRP_HAS_LOCK, .flash_regs_base = 0x40022000, .fsize_addr = 0x0BFA07A0, .otp_base = 0x0BFA0000, @@ -704,7 +709,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .num_revs = ARRAY_SIZE(stm32u57_u58xx_revs), .device_str = "STM32U57/U58xx", .max_flash_size_kb = 2048, - .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS, + .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ + | F_HAS_L5_FLASH_REGS | F_WRP_HAS_LOCK, .flash_regs_base = 0x40022000, .fsize_addr = 0x0BFA07A0, .otp_base = 0x0BFA0000, @@ -716,7 +722,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .num_revs = ARRAY_SIZE(stm32u5f_u5gxx_revs), .device_str = "STM32U5F/U5Gxx", .max_flash_size_kb = 4096, - .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS, + .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ + | F_HAS_L5_FLASH_REGS | F_WRP_HAS_LOCK, .flash_regs_base = 0x40022000, .fsize_addr = 0x0BFA07A0, .otp_base = 0x0BFA0000, @@ -1287,6 +1294,8 @@ static int stm32l4_write_one_wrpxy(struct flash_bank *bank, struct stm32l4_wrp * int wrp_end = wrpxy->last - wrpxy->offset; uint32_t wrp_value = (wrp_start & stm32l4_info->wrpxxr_mask) | ((wrp_end & stm32l4_info->wrpxxr_mask) << 16); + if (stm32l4_info->part_info->flags & F_WRP_HAS_LOCK) + wrp_value |= FLASH_WRPXYR_UNLOCK; return stm32l4_write_option(bank, stm32l4_info->flash_regs[wrpxy->reg_idx], wrp_value, 0xffffffff); } diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h index 07b3615a24..1f4f2344f9 100644 --- a/src/flash/nor/stm32l4x.h +++ b/src/flash/nor/stm32l4x.h @@ -69,6 +69,9 @@ #define FLASH_U5_DUALBANK BIT(21) #define FLASH_TZEN BIT(31) +/* FLASH_WRPxyR register bits */ +#define FLASH_WRPXYR_UNLOCK BIT(31) + /* FLASH secure block based bank 1/2 register offsets */ #define FLASH_SECBB1(X) (0x80 + 4 * (X - 1)) #define FLASH_SECBB2(X) (0xA0 + 4 * (X - 1)) --