From 141b476a97952c193b37d12a0e6f45e1fa14ed3c Mon Sep 17 00:00:00 2001 From: mean Date: Sun, 1 Feb 2026 09:09:52 +0100 Subject: [PATCH] ARMv8-M: better handle faults through ICSR --- src/target/cortexm.c | 16 +++++++++++++++- src/target/cortexm.h | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 71b571b4fde..280163f71a2 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -864,7 +864,21 @@ static target_halt_reason_e cortexm_halt_poll(target_s *target, target_addr64_t priv->dcache_enabled = ccr & CORTEXM_CCR_DCACHE_ENABLE; priv->icache_enabled = ccr & CORTEXM_CCR_ICACHE_ENABLE; - if ((dfsr & CORTEXM_DFSR_VCATCH) && cortexm_fault_unwind(target)) + bool fault_state = false; + // the V8 may stop before actually executing the instruction + // so reading dfsr might not work. + // Instead, we check if there are pending faults on ICSR + // meaning we stopped while trying to execute a fault + // but maybe did not execute it + if ((target->target_options & CORTEXM_TOPT_FLAVOUR_V8M)) { + const uint32_t icsr = target_mem32_read32(target, CORTEXM_ICSR); + const uint32_t pending = CORTEXM_ICSR_VEC_PENDING(icsr); + // catch all pending faults + if (pending > 0U && pending < 8U) + fault_state = true; + } else + fault_state = (dfsr & CORTEXM_DFSR_VCATCH) != 0U; + if (fault_state && cortexm_fault_unwind(target)) return TARGET_HALT_FAULT; /* Remember if we stopped on a breakpoint */ diff --git a/src/target/cortexm.h b/src/target/cortexm.h index 41ea60828dc..b1e05b28be0 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -69,6 +69,9 @@ extern unsigned cortexm_wait_timeout; #define CORTEXM_DWT_MASK(i) (CORTEXM_DWT_BASE + 0x024U + (0x10U * (i))) #define CORTEXM_DWT_FUNC(i) (CORTEXM_DWT_BASE + 0x028U + (0x10U * (i))) +/* ARMv8 External Debug Fault Status Register */ +#define CORTEXM_EDFSR (CORTEXM_SCS_BASE + 0xf98U) +#define CORTEXM_ICSR (CORTEXM_SCS_BASE + 0xd04U) /* Application Interrupt and Reset Control Register (AIRCR) */ #define CORTEXM_AIRCR_VECTKEY (0x05faU << 16U) /* Bits 31:16 - Read as VECTKETSTAT, 0xfa05 */ @@ -188,6 +191,10 @@ extern unsigned cortexm_wait_timeout; #define CORTEXM_XPSR_THUMB (1U << 24U) #define CORTEXM_XPSR_EXCEPTION_MASK 0x0000001fU +/* ICSR for ARMv8-M, the exception are the same as IPSR */ +#define CORTEXM_ICSR_VEC_PENDING(x) (((x) >> 12U) & 0x1ffU) +#define CORTEXM_ICSR_VEC_ACTIVE(x) (((x) >> 0U) & 0x1ffU) + bool cortexm_attach(target_s *target); void cortexm_detach(target_s *target); void cortexm_halt_resume(target_s *target, bool step);