From: openocd-gerrit <ope...@us...> - 2025-06-29 07:41:32
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via c4fb64e76c526799fc43f72fe2cdd4606c8b9b52 (commit) via f547e55076e847889387904c6a0803e742aeb36d (commit) from ce3bf664c81569b2eb457f676814eade9d464141 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c4fb64e76c526799fc43f72fe2cdd4606c8b9b52 Author: Tomas Vanek <va...@fb...> Date: Wed Jun 18 09:44:03 2025 +0200 flash/nor/rp2xxx: save security state over target algo RP2040 and RP2350 flash driver runs a ROM API target algorithm in probe to setup QSPI command interface. The Cortex-M33 core of RP2350 has to be in secure mode with SAU and MPU switched off to ensure ROM API call working properly. Especially after the flash probe (used in gdb-attach event) we need to completely restore the original security state to allow 'resume' or gdb 'continue' without injecting strange errors to application code. Use cortex_m support to set secure mode and to restore it back. Fixes: commit ea775d49fc71 ("flash/nor/rp2040: add RP2350 support") Change-Id: I72096bfecbb45a8aa4d3a7a37ad140532b3b00b2 Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/8960 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index 85c591104..fa13ec527 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -209,6 +209,8 @@ struct rp2xxx_flash_bank { bool size_override; struct flash_device spi_dev; /* detected model of SPI flash */ unsigned int sfdp_dummy, sfdp_dummy_detect; + + struct cortex_m_saved_security saved_security; }; #ifndef LOG_ROM_SYMBOL_DEBUG @@ -630,23 +632,12 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2xxx_flash_bank // run in the Secure state, so flip the state now before attempting to // execute any code on the core. int retval; - uint32_t dscsr; - retval = target_read_u32(target, DCB_DSCSR, &dscsr); + retval = cortex_m_set_secure(target, &priv->saved_security); if (retval != ERROR_OK) { - LOG_ERROR("RP2350 init ARM core: DSCSR read failed"); + LOG_ERROR("RP2350 init ARM core: set secure mode failed"); return retval; } - LOG_DEBUG("DSCSR: 0x%08" PRIx32, dscsr); - if (!(dscsr & DSCSR_CDS)) { - LOG_DEBUG("Setting Current Domain Secure in DSCSR"); - retval = target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); - if (retval != ERROR_OK) { - LOG_ERROR("RP2350 init ARM core: DSCSR read failed"); - return retval; - } - } - if (!priv->stack) { LOG_ERROR("No stack for flash programming code"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -840,6 +831,15 @@ static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2xxx_fla driver state. Best to clean up our allocations manually after completing each flash call, so we know to make fresh ones next time. */ LOG_DEBUG("Cleaning up after flash operations"); + + if (IS_RP2350(priv->id)) { + /* TODO: restore ACCESSCTRL */ + if (is_arm(target_to_arm(target))) { + int retval = cortex_m_security_restore(target, &priv->saved_security); + if (retval != ERROR_OK) + LOG_WARNING("RP2xxx: security state was not restored properly. Debug 'resume' will probably fail, use 'reset' instead"); + } + } if (priv->stack) { target_free_working_area(target, priv->stack); priv->stack = 0; commit f547e55076e847889387904c6a0803e742aeb36d Author: Tomas Vanek <va...@fb...> Date: Tue Jun 17 16:23:12 2025 +0200 target/cortex_m: introduce security manipulation routines Running target algorithms on ARMv8M may require core in secure mode with SAU and MPU off (as set after reset). cortex_m_set_secure() forces this mode with optional save of the previous state. cortex_m_security_restore() restores previously saved state. Change-Id: Ia71826db47ee7b0557eaffd55244ce13eacbcb4b Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/8959 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 8eaf70f60..0501a5b2f 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2563,6 +2563,112 @@ static bool cortex_m_has_tz(struct target *target) return (dauthstatus & DAUTHSTATUS_SID_MASK) != 0; } +int cortex_m_set_secure(struct target *target, struct cortex_m_saved_security *ssec) +{ + if (ssec) { + ssec->dscsr_dirty = false; + ssec->sau_ctrl_dirty = false; + ssec->mpu_ctrl_dirty = false; + } + + if (!cortex_m_has_tz(target)) + return ERROR_OK; + + uint32_t dscsr; + int retval = target_read_u32(target, DCB_DSCSR, &dscsr); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: DSCSR read failed"); + return retval; + } + if (!(dscsr & DSCSR_CDS)) { + if (ssec) { + ssec->dscsr_dirty = true; + ssec->dscsr = dscsr; + } + LOG_TARGET_DEBUG(target, "Setting Current Domain Secure in DSCSR"); + retval = target_write_u32(target, DCB_DSCSR, DSCSR_CDS); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: DSCSR write failed"); + return retval; + } + } + + uint32_t sau_ctrl; + retval = target_read_u32(target, SAU_CTRL, &sau_ctrl); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: SAU_CTRL read failed"); + return retval; + } + if (sau_ctrl & SAU_CTRL_ENABLE) { + if (ssec) { + ssec->sau_ctrl_dirty = true; + ssec->sau_ctrl = sau_ctrl; + } + retval = target_write_u32(target, SAU_CTRL, sau_ctrl & ~SAU_CTRL_ENABLE); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: SAU_CTRL write failed"); + return retval; + } + } + + uint32_t mpu_ctrl; + retval = target_read_u32(target, MPU_CTRL, &mpu_ctrl); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: MPU_CTRL read failed"); + return retval; + } + if (mpu_ctrl & MPU_CTRL_ENABLE) { + if (ssec) { + ssec->mpu_ctrl_dirty = true; + ssec->mpu_ctrl = mpu_ctrl; + } + retval = target_write_u32(target, MPU_CTRL, mpu_ctrl & ~MPU_CTRL_ENABLE); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: MPU_CTRL write failed"); + return retval; + } + } + return ERROR_OK; +} + +int cortex_m_security_restore(struct target *target, struct cortex_m_saved_security *ssec) +{ + int retval; + if (!cortex_m_has_tz(target)) + return ERROR_OK; + + if (!ssec) + return ERROR_OK; + + if (ssec->mpu_ctrl_dirty) { + retval = target_write_u32(target, MPU_CTRL, ssec->mpu_ctrl); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M security restore: MPU_CTRL write failed"); + return retval; + } + ssec->mpu_ctrl_dirty = false; + } + + if (ssec->sau_ctrl_dirty) { + retval = target_write_u32(target, SAU_CTRL, ssec->sau_ctrl); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M security restore: SAU_CTRL write failed"); + return retval; + } + ssec->sau_ctrl_dirty = false; + } + + if (ssec->dscsr_dirty) { + LOG_TARGET_DEBUG(target, "Restoring Current Domain Security in DSCSR"); + retval = target_write_u32(target, DCB_DSCSR, ssec->dscsr & ~DSCSR_CDSKEY); + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "ARMv8M set secure: DSCSR write failed"); + return retval; + } + ssec->dscsr_dirty = false; + } + return ERROR_OK; +} #define MVFR0 0xE000EF40 #define MVFR0_SP_MASK 0x000000F0 diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 144f24560..82b2c1ecd 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -167,6 +167,8 @@ struct cortex_m_part_info { #define NVIC_DFSR 0xE000ED30 #define NVIC_MMFAR 0xE000ED34 #define NVIC_BFAR 0xE000ED38 +#define MPU_CTRL 0xE000ED94 +#define SAU_CTRL 0xE000EDD0 #define NVIC_SFSR 0xE000EDE4 #define NVIC_SFAR 0xE000EDE8 @@ -184,6 +186,9 @@ struct cortex_m_part_info { #define DFSR_VCATCH 8 #define DFSR_EXTERNAL 16 +#define MPU_CTRL_ENABLE BIT(0) +#define SAU_CTRL_ENABLE BIT(0) + #define FPCR_CODE 0 #define FPCR_LITERAL 1 #define FPCR_REPLACE_REMAP (0ul << 30) @@ -264,6 +269,15 @@ struct cortex_m_common { bool incorrect_halt_erratum; }; +struct cortex_m_saved_security { + bool dscsr_dirty; + uint32_t dscsr; + bool sau_ctrl_dirty; + uint32_t sau_ctrl; + bool mpu_ctrl_dirty; + uint32_t mpu_ctrl; +}; + static inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m) { return cortex_m->common_magic == CORTEX_M_COMMON_MAGIC; @@ -341,4 +355,17 @@ void cortex_m_deinit_target(struct target *target); int cortex_m_profiling(struct target *target, uint32_t *samples, uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); +/** + * Forces Cortex-M core to the basic secure context with SAU and MPU off + * @param ssec pointer to save previous security state or NULL + * @returns error code or ERROR_OK if secure mode was set or is not applicable + * (not ARMv8M with security extension) + */ +int cortex_m_set_secure(struct target *target, struct cortex_m_saved_security *ssec); + +/** + * Restores saved security context to MPU_CTRL, SAU_CTRL and DSCSR + */ +int cortex_m_security_restore(struct target *target, struct cortex_m_saved_security *ssec); + #endif /* OPENOCD_TARGET_CORTEX_M_H */ ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2xxx.c | 26 ++++++------ src/target/cortex_m.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ src/target/cortex_m.h | 27 +++++++++++++ 3 files changed, 146 insertions(+), 13 deletions(-) hooks/post-receive -- Main OpenOCD repository |