target/cortex_a: enable DSCR_HALT_DBG_MODE during examine
Arm architecture reference manual DDI0406C reports at page 2024 in table C3-1 the processor behaviour on debug events depending on the debug-mode (none, monitor or halt), mode selected through the bits MDBGen and HDBGen in DSCR register. The halt request is served independently from the debug-mode. Thus it's useless to enable the halt debug-mode in cortex_a_halt() by setting the bit HDBGen (macro DSCR_HALT_DBG_MODE). On the other side, halting for a breakpoint, a watchpoint or a vector catch requires being in halt debug-mode. Today HDBGen is set only in cortex_a_halt(), so we are forced to halt the core at least once before it can be halted for hitting a breakpoint/watchpoint/vector-catch. This is annoying since there is no need to halt the target to set a HW breakpoint. Move in cortex_a_init_debug_access() the selection of the halt debug-mode, so the mode is set during examine. To prevent a misconfigured hardware breakpoint/watchpoint/vector catch to halt the target when OpenOCD has already quit, return to debug-mode none at OpenOCD exit. Change-Id: I68a1c51de3572ca1b89e90caf7eb20374268e926 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/4783 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
This commit is contained in:
parent
322d2fa12c
commit
bff87a7f28
|
@ -202,6 +202,7 @@ static int cortex_a_mmu_modify(struct target *target, int enable)
|
||||||
static int cortex_a_init_debug_access(struct target *target)
|
static int cortex_a_init_debug_access(struct target *target)
|
||||||
{
|
{
|
||||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||||
|
uint32_t dscr;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* lock memory-mapped access to debug registers to prevent
|
/* lock memory-mapped access to debug registers to prevent
|
||||||
|
@ -231,6 +232,16 @@ static int cortex_a_init_debug_access(struct target *target)
|
||||||
|
|
||||||
/* Resync breakpoint registers */
|
/* Resync breakpoint registers */
|
||||||
|
|
||||||
|
/* Enable halt for breakpoint, watchpoint and vector catch */
|
||||||
|
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
||||||
|
armv7a->debug_base + CPUDBG_DSCR, &dscr);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
return retval;
|
||||||
|
retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
|
||||||
|
armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
|
return retval;
|
||||||
|
|
||||||
/* Since this is likely called from init or reset, update target state information*/
|
/* Since this is likely called from init or reset, update target state information*/
|
||||||
return cortex_a_poll(target);
|
return cortex_a_poll(target);
|
||||||
}
|
}
|
||||||
|
@ -769,19 +780,6 @@ static int cortex_a_halt(struct target *target)
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/*
|
|
||||||
* enter halting debug mode
|
|
||||||
*/
|
|
||||||
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
|
||||||
armv7a->debug_base + CPUDBG_DSCR, &dscr);
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
|
|
||||||
armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
int64_t then = timeval_ms();
|
int64_t then = timeval_ms();
|
||||||
for (;; ) {
|
for (;; ) {
|
||||||
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
||||||
|
@ -2889,7 +2887,20 @@ static int cortex_r4_target_create(struct target *target, Jim_Interp *interp)
|
||||||
static void cortex_a_deinit_target(struct target *target)
|
static void cortex_a_deinit_target(struct target *target)
|
||||||
{
|
{
|
||||||
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
|
||||||
struct arm_dpm *dpm = &cortex_a->armv7a_common.dpm;
|
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
|
||||||
|
struct arm_dpm *dpm = &armv7a->dpm;
|
||||||
|
uint32_t dscr;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (target_was_examined(target)) {
|
||||||
|
/* Disable halt for breakpoint, watchpoint and vector catch */
|
||||||
|
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
||||||
|
armv7a->debug_base + CPUDBG_DSCR, &dscr);
|
||||||
|
if (retval == ERROR_OK)
|
||||||
|
mem_ap_write_atomic_u32(armv7a->debug_ap,
|
||||||
|
armv7a->debug_base + CPUDBG_DSCR,
|
||||||
|
dscr & ~DSCR_HALT_DBG_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
free(cortex_a->brp_list);
|
free(cortex_a->brp_list);
|
||||||
free(dpm->dbp);
|
free(dpm->dbp);
|
||||||
|
|
Loading…
Reference in New Issue