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))

-- 

Reply via email to