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/+/8959

-- gerrit

commit 6136cd82f0c4b7a220097674be4e4a24e6b7b780
Author: Tomas Vanek <van...@fbl.cz>
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 <van...@fbl.cz>

diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index ba9d83d79f..5fddfb91c8 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -2562,6 +2562,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_ERROR("ARMv8M set secure: DSCSR read failed");
+               return retval;
+       }
+       if (!(dscsr & DSCSR_CDS)) {
+               if (ssec) {
+                       ssec->dscsr_dirty = true;
+                       ssec->dscsr = dscsr;
+               }
+               LOG_DEBUG("Setting Current Domain Secure in DSCSR");
+               retval = target_write_u32(target, DCB_DSCSR, DSCSR_CDS);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("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_ERROR("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_ERROR("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_ERROR("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_ERROR("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_ERROR("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_ERROR("ARMv8M security restore: SAU_CTRL write 
failed");
+                       return retval;
+               }
+               ssec->sau_ctrl_dirty = false;
+       }
+
+       if (ssec->dscsr_dirty) {
+               LOG_DEBUG("Restoring Current Domain Security in DSCSR");
+               retval = target_write_u32(target, DCB_DSCSR, ssec->dscsr & 
~DSCSR_CDSKEY);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("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 144f24560c..82b2c1ecde 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 */

-- 

Reply via email to