aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Borneo <borneo.antonio@gmail.com>2020-05-27 00:03:45 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2020-06-06 18:04:36 +0100
commit37330f89d789e5b0a74aa14f7a7bfcfb4260abff (patch)
tree1b1f8bd41f41979f85634903ef956c536a5dbd16
parent1fa66d3633862d824420fb90b5b63e41e415d70e (diff)
downloadriscv-openocd-37330f89d789e5b0a74aa14f7a7bfcfb4260abff.zip
riscv-openocd-37330f89d789e5b0a74aa14f7a7bfcfb4260abff.tar.gz
riscv-openocd-37330f89d789e5b0a74aa14f7a7bfcfb4260abff.tar.bz2
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 <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/5702 Tested-by: jenkins Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-by: Moritz Fischer <moritzf@google.com>
-rw-r--r--src/target/cortex_m.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index e540f85..d9bee0e 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)