From 54db90cb0d1259f2659127bb984d01fbd64f47e6 Mon Sep 17 00:00:00 2001 From: mean Date: Sat, 30 Nov 2024 15:09:19 +0100 Subject: [PATCH] cortexm: add support for DWTv2 so that watchpoints work on Armv8-M (m33,...) --- src/target/cortexm.c | 32 +++++++++++++++++++++++++++----- src/target/cortexm.h | 7 +++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 7bc252044f6..25d5b5cf7c9 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -1062,6 +1062,25 @@ static uint32_t cortexm_dwt_func(target_s *target, target_breakwatch_e type) } } +static uint32_t cortexm_dwtv2_func(target_breakwatch_e type, size_t len) +{ + uint32_t value = CORTEXM_DWTv2_FUNC_ACTION_DEBUG_EVENT | CORTEXM_DWTv2_FUNC_LEN_VALUE(len); + switch (type) { + case TARGET_WATCH_WRITE: + value |= CORTEXM_DWTv2_FUNC_MATCH_WRITE; + break; + case TARGET_WATCH_READ: + value |= CORTEXM_DWTv2_FUNC_MATCH_READ; + break; + case TARGET_WATCH_ACCESS: + value |= CORTEXM_DWTv2_FUNC_MATCH_ACCESS; + break; + default: + return 0U; + } + return value; +} + static int cortexm_breakwatch_set(target_s *target, breakwatch_s *breakwatch) { cortexm_priv_s *priv = target->priv; @@ -1103,11 +1122,14 @@ static int cortexm_breakwatch_set(target_s *target, breakwatch_s *breakwatch) return -1; priv->base.watchpoints_mask |= 1U << i; - - target_mem32_write32(target, CORTEXM_DWT_COMP(i), val); - target_mem32_write32(target, CORTEXM_DWT_MASK(i), cortexm_dwt_mask(breakwatch->size)); - target_mem32_write32(target, CORTEXM_DWT_FUNC(i), cortexm_dwt_func(target, breakwatch->type)); - + if ((target->target_options & CORTEXM_TOPT_FLAVOUR_V8M)) { + target_mem32_write32(target, CORTEXM_DWT_COMP(i), val); + target_mem32_write32(target, CORTEXM_DWT_FUNC(i), cortexm_dwtv2_func(breakwatch->type, breakwatch->size)); + } else { + target_mem32_write32(target, CORTEXM_DWT_COMP(i), val); + target_mem32_write32(target, CORTEXM_DWT_MASK(i), cortexm_dwt_mask(breakwatch->size)); + target_mem32_write32(target, CORTEXM_DWT_FUNC(i), cortexm_dwt_func(target, breakwatch->type)); + } breakwatch->reserved[0] = i; return 0; default: diff --git a/src/target/cortexm.h b/src/target/cortexm.h index 7ee80e9f082..3dc9165a9d7 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -164,6 +164,13 @@ extern unsigned cortexm_wait_timeout; #define CORTEXM_DWT_FUNC_FUNC_READ (5U << 0U) #define CORTEXM_DWT_FUNC_FUNC_WRITE (6U << 0U) #define CORTEXM_DWT_FUNC_FUNC_ACCESS (7U << 0U) +/* Variant for DWTv2 */ +#define CORTEXM_DWTv2_FUNC_MATCH_READ (6U << 0U) +#define CORTEXM_DWTv2_FUNC_MATCH_WRITE (5U << 0U) +#define CORTEXM_DWTv2_FUNC_MATCH_ACCESS (4U << 0U) +#define CORTEXM_DWTv2_FUNC_ACTION_TRIGGER (0U << 4U) +#define CORTEXM_DWTv2_FUNC_ACTION_DEBUG_EVENT (1U << 4U) +#define CORTEXM_DWTv2_FUNC_LEN_VALUE(len) (((len) >> 1) << 10U) #define CORTEXM_XPSR_THUMB (1U << 24U) #define CORTEXM_XPSR_EXCEPTION_MASK 0x0000001fU