This is an automated email from Gerrit. "Antonio Borneo <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9505
-- gerrit commit aabe989e18373db9d7c99322fad659219ed91991 Author: Antonio Borneo <[email protected]> Date: Wed Mar 11 17:28:12 2026 +0100 cortex_a: fix the address of the instruction hitting a watchpoint While some old device like Cortex-R5 still rely on not-precise watchpoints (what ARM call "asynchronous" watchpoints in DDI 0406C.d), new devices like Cortex-A7 only hit precise "synchronous" watchpoint. For the old implementations, rely on WFAR register to recover the address of the load/store instruction that hit the watchpoint. For new devices, take the address from the PC at debug entry. Move the modified code after the read of the CPU registers at debug entry. Change-Id: Ie78a8ba6cb38c07cfa2b0c6cd6daf345318de4c1 Signed-off-by: Antonio Borneo <[email protected]> diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 2efbcce0c9..dab0f8e1dd 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -32,6 +32,7 @@ * Cortex-A9(tm) TRM, ARM DDI 0407F * * Cortex-A4(tm) TRM, ARM DDI 0363E * * Cortex-A15(tm)TRM, ARM DDI 0438C * + * Architecture Reference Manual, ARMv7-A and ARMv7-R, ARM DDI 0406C.d * * * ***************************************************************************/ @@ -1060,18 +1061,6 @@ static int cortex_a_debug_entry(struct target *target) /* Examine debug reason */ arm_dpm_report_dscr(&armv7a->dpm, cortex_a->cpudbg_dscr); - /* save address of instruction that triggered the watchpoint? */ - if (target->debug_reason == DBG_REASON_WATCHPOINT) { - uint32_t wfar; - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_WFAR, - &wfar); - if (retval != ERROR_OK) - return retval; - arm_dpm_report_wfar(&armv7a->dpm, wfar); - } - /* First load register accessible through core debug port */ retval = arm_dpm_read_current_registers(&armv7a->dpm); if (retval != ERROR_OK) @@ -1084,6 +1073,29 @@ static int cortex_a_debug_entry(struct target *target) return retval; } + /* save address of instruction that triggered the watchpoint? */ + if (target->debug_reason == DBG_REASON_WATCHPOINT) { + /* + * On v7.1 Debug architecture or on synchronous (precise) watchpoints, + * WFAR is not used. Take the instruction address from halted PC. + * See ARM DDI 0406C.d chapter chapter C5.2.2 "Effect of entering Debug + * state on CP15 registers and the DBGWFAR". + */ + if (((armv7a->dpm.didr >> 16) & 0xf) > 4 || + DSCR_ENTRY(cortex_a->cpudbg_dscr) == DSCR_ENTRY_PRECISE_WATCHPT) { + armv7a->dpm.wp_addr = buf_get_u32(arm->pc->value, 0, 32);; + } else { + uint32_t wfar; + + retval = mem_ap_read_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_WFAR, + &wfar); + if (retval != ERROR_OK) + return retval; + arm_dpm_report_wfar(&armv7a->dpm, wfar); + } + } + #if 0 /* TODO, Move this */ uint32_t cp15_control_register, cp15_cacr, cp15_nacr; --
