From: Antonio Borneo Date: Tue, 26 May 2020 22:03:45 +0000 (+0200) Subject: target/cortex-m: enable C_DEBUGEN during examine X-Git-Tag: v0.11.0-rc1~253 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=37330f89d789e5b0a74aa14f7a7bfcfb4260abff target/cortex-m: enable C_DEBUGEN during examine Current code for Cortex M does not set C_DEBUGEN as soon as possible, (which means during target examine), but later-on either: 1) at command 'halt' (e.g. for 'gdb-attach' event); 2) at command 'soft_reset_halt'; 3) at commands 'reset', 'reset halt' or 'reset init'; 4) during polling, but only if the target: = enter in 'double fault', or = exit from a reset, or = halts (not possible if C_DEBUGEN is not set) Plus, if commands in 1) or 2) are executed before the very first poll of the target, the value of 'cortex_m->dcb_dhcsr' is used not initialized while writing it back in DCB_DHCSR. Another side effect of this situation is that it's possible to set a HW breakpoint with the target running, while C_DEBUGEN is not set. Accordingly to [1], C1.3.1 "Debug authentication": When DGBEN is LOW and DHCSR.S_HALT == 0: ... FPB breakpoints do not generate an entry to Debug state and, if no DebugMonitor exception is generated, will escalate to HardFault, Lockup, or be ignored. On STM32MP15x I get HW breakpoint ignored, while on STM32F411 I get HardFault. E.g. following these steps: - power-on a pre-flashed board that starts running the firmware; - connect openocd, without halting or resetting the board; - set a HW breakpoint to some address often executed; - wait, but the board doesn't halt ...; - type the command 'halt'; - if the Cortex-M has HardFault it would be visible and the fault is at the breakpoint address; - if no HardFault then type the command 'resume'; - wait and the board will finally halt at the HW breakpoint. A similar issue has been detected on Cortex-A code and fixed by commit bff87a7f28fb ("target/cortex_a: enable DSCR_HALT_DBG_MODE during examine"). Follow the same approach and set C_DEBUGEN during examine. Also, initialize 'cortex_m->dcb_dhcsr' during examine. [1] ARM DDI 0403E "ARM v7-M Architecture Reference Manual" Change-Id: I5b0b23403634f7dfce38f104bba9f59c33eb3e99 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5702 Tested-by: jenkins Reviewed-by: Andreas Fritiofson Reviewed-by: Tarek BOCHKATI Reviewed-by: Moritz Fischer --- diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index e540f8507b..d9bee0e53d 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2230,6 +2230,19 @@ int cortex_m_examine(struct target *target) armv7m->debug_ap->tar_autoincr_block = (1 << 10); } + /* Enable debug requests */ + retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr); + if (retval != ERROR_OK) + return retval; + if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { + uint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS); + + retval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL)); + if (retval != ERROR_OK) + return retval; + cortex_m->dcb_dhcsr = dhcsr; + } + /* Configure trace modules */ retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr); if (retval != ERROR_OK)