mirror of
https://github.com/openocd-org/openocd.git
synced 2025-10-14 19:48:47 +08:00
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 6554d176e9
("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 <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/8981
Tested-by: jenkins
This commit is contained in:
@@ -152,6 +152,9 @@
|
|||||||
/* this flag indicates that programming should be done in quad-word
|
/* this flag indicates that programming should be done in quad-word
|
||||||
* the default programming word size is double-word */
|
* the default programming word size is double-word */
|
||||||
#define F_QUAD_WORD_PROG BIT(4)
|
#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 ******************************************************/
|
/* end of STM32L4 flags ******************************************************/
|
||||||
|
|
||||||
|
|
||||||
@@ -500,7 +503,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
|
|||||||
.num_revs = ARRAY_SIZE(stm32u53_u54xx_revs),
|
.num_revs = ARRAY_SIZE(stm32u53_u54xx_revs),
|
||||||
.device_str = "STM32U535/U545",
|
.device_str = "STM32U535/U545",
|
||||||
.max_flash_size_kb = 512,
|
.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,
|
.flash_regs_base = 0x40022000,
|
||||||
.fsize_addr = 0x0BFA07A0,
|
.fsize_addr = 0x0BFA07A0,
|
||||||
.otp_base = 0x0BFA0000,
|
.otp_base = 0x0BFA0000,
|
||||||
@@ -692,7 +696,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
|
|||||||
.num_revs = ARRAY_SIZE(stm32u59_u5axx_revs),
|
.num_revs = ARRAY_SIZE(stm32u59_u5axx_revs),
|
||||||
.device_str = "STM32U59/U5Axx",
|
.device_str = "STM32U59/U5Axx",
|
||||||
.max_flash_size_kb = 4096,
|
.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,
|
.flash_regs_base = 0x40022000,
|
||||||
.fsize_addr = 0x0BFA07A0,
|
.fsize_addr = 0x0BFA07A0,
|
||||||
.otp_base = 0x0BFA0000,
|
.otp_base = 0x0BFA0000,
|
||||||
@@ -704,7 +709,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
|
|||||||
.num_revs = ARRAY_SIZE(stm32u57_u58xx_revs),
|
.num_revs = ARRAY_SIZE(stm32u57_u58xx_revs),
|
||||||
.device_str = "STM32U57/U58xx",
|
.device_str = "STM32U57/U58xx",
|
||||||
.max_flash_size_kb = 2048,
|
.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,
|
.flash_regs_base = 0x40022000,
|
||||||
.fsize_addr = 0x0BFA07A0,
|
.fsize_addr = 0x0BFA07A0,
|
||||||
.otp_base = 0x0BFA0000,
|
.otp_base = 0x0BFA0000,
|
||||||
@@ -716,7 +722,8 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
|
|||||||
.num_revs = ARRAY_SIZE(stm32u5f_u5gxx_revs),
|
.num_revs = ARRAY_SIZE(stm32u5f_u5gxx_revs),
|
||||||
.device_str = "STM32U5F/U5Gxx",
|
.device_str = "STM32U5F/U5Gxx",
|
||||||
.max_flash_size_kb = 4096,
|
.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,
|
.flash_regs_base = 0x40022000,
|
||||||
.fsize_addr = 0x0BFA07A0,
|
.fsize_addr = 0x0BFA07A0,
|
||||||
.otp_base = 0x0BFA0000,
|
.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;
|
int wrp_end = wrpxy->last - wrpxy->offset;
|
||||||
|
|
||||||
uint32_t wrp_value = (wrp_start & stm32l4_info->wrpxxr_mask) | ((wrp_end & stm32l4_info->wrpxxr_mask) << 16);
|
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);
|
return stm32l4_write_option(bank, stm32l4_info->flash_regs[wrpxy->reg_idx], wrp_value, 0xffffffff);
|
||||||
}
|
}
|
||||||
|
@@ -69,6 +69,9 @@
|
|||||||
#define FLASH_U5_DUALBANK BIT(21)
|
#define FLASH_U5_DUALBANK BIT(21)
|
||||||
#define FLASH_TZEN BIT(31)
|
#define FLASH_TZEN BIT(31)
|
||||||
|
|
||||||
|
/* FLASH_WRPxyR register bits */
|
||||||
|
#define FLASH_WRPXYR_UNLOCK BIT(31)
|
||||||
|
|
||||||
/* FLASH secure block based bank 1/2 register offsets */
|
/* FLASH secure block based bank 1/2 register offsets */
|
||||||
#define FLASH_SECBB1(X) (0x80 + 4 * (X - 1))
|
#define FLASH_SECBB1(X) (0x80 + 4 * (X - 1))
|
||||||
#define FLASH_SECBB2(X) (0xA0 + 4 * (X - 1))
|
#define FLASH_SECBB2(X) (0xA0 + 4 * (X - 1))
|
||||||
|
Reference in New Issue
Block a user