From f9986394dc98cf27708022487a5e5b1b8cc9f5b5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 15 Apr 2019 23:46:29 +0200 Subject: [PATCH] target/cortex_a: use extensively cortex_a_wait_dscr_bits() We have the function to wait for bits in dscr. Use it whenever possible. When the bit to test is DSCR_INSTR_COMP, use instead the wrapper function cortex_a_wait_instrcmpl(). Change-Id: I5c54c239a00f489712af448eb97752210b4b38b8 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5113 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/target/cortex_a.c | 110 +++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 71 deletions(-) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 587cbba0e..8d0e10013 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -70,6 +70,8 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint); static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *breakpoint); +static int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask, + uint32_t value, uint32_t *dscr); static int cortex_a_mmu(struct target *target, int *enabled); static int cortex_a_mmu_modify(struct target *target, int enable); static int cortex_a_virt2phys(struct target *target, @@ -250,21 +252,21 @@ static int cortex_a_wait_instrcmpl(struct target *target, uint32_t *dscr, bool f * Writes final value of DSCR into *dscr. Pass force to force always * reading DSCR at least once. */ struct armv7a_common *armv7a = target_to_armv7a(target); - int64_t then = timeval_ms(); - while ((*dscr & DSCR_INSTR_COMP) == 0 || force) { - force = false; - int retval = mem_ap_read_atomic_u32(armv7a->debug_ap, + int retval; + + if (force) { + retval = mem_ap_read_atomic_u32(armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, dscr); if (retval != ERROR_OK) { LOG_ERROR("Could not read DSCR register"); return retval; } - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for InstrCompl=1"); - return ERROR_FAIL; - } } - return ERROR_OK; + + retval = cortex_a_wait_dscr_bits(target, DSCR_INSTR_COMP, DSCR_INSTR_COMP, dscr); + if (retval != ERROR_OK) + LOG_ERROR("Error waiting for InstrCompl=1"); + return retval; } /* To reduce needless round-trips, pass in a pointer to the current @@ -293,19 +295,12 @@ static int cortex_a_exec_opcode(struct target *target, if (retval != ERROR_OK) return retval; - int64_t then = timeval_ms(); - do { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read DSCR register"); - return retval; - } - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for cortex_a_exec_opcode"); - return ERROR_FAIL; - } - } while ((dscr & DSCR_INSTR_COMP) == 0); /* Wait for InstrCompl bit to be set */ + /* Wait for InstrCompl bit to be set */ + retval = cortex_a_wait_instrcmpl(target, &dscr, true); + if (retval != ERROR_OK) { + LOG_ERROR("Error waiting for cortex_a_exec_opcode"); + return retval; + } if (dscr_p) *dscr_p = dscr; @@ -359,17 +354,11 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data, dscr = *dscr_p; /* Wait for DTRRXfull */ - int64_t then = timeval_ms(); - while ((dscr & DSCR_DTR_TX_FULL) == 0) { - retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap, - a->armv7a_common.debug_base + CPUDBG_DSCR, - &dscr); - if (retval != ERROR_OK) - return retval; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for read dcc"); - return ERROR_FAIL; - } + retval = cortex_a_wait_dscr_bits(a->armv7a_common.arm.target, + DSCR_DTR_TX_FULL, DSCR_DTR_TX_FULL, &dscr); + if (retval != ERROR_OK) { + LOG_ERROR("Error waiting for read dcc"); + return retval; } retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap, @@ -391,19 +380,10 @@ static int cortex_a_dpm_prepare(struct arm_dpm *dpm) int retval; /* set up invariant: INSTR_COMP is set after ever DPM operation */ - int64_t then = timeval_ms(); - for (;; ) { - retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap, - a->armv7a_common.debug_base + CPUDBG_DSCR, - &dscr); - if (retval != ERROR_OK) - return retval; - if ((dscr & DSCR_INSTR_COMP) != 0) - break; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for dpm prepare"); - return ERROR_FAIL; - } + retval = cortex_a_wait_instrcmpl(dpm->arm->target, &dscr, true); + if (retval != ERROR_OK) { + LOG_ERROR("Error waiting for dpm prepare"); + return retval; } /* this "should never happen" ... */ @@ -752,7 +732,7 @@ static int cortex_a_poll(struct target *target) static int cortex_a_halt(struct target *target) { - int retval = ERROR_OK; + int retval; uint32_t dscr; struct armv7a_common *armv7a = target_to_armv7a(target); @@ -765,18 +745,12 @@ static int cortex_a_halt(struct target *target) if (retval != ERROR_OK) return retval; - int64_t then = timeval_ms(); - for (;; ) { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - if ((dscr & DSCR_CORE_HALTED) != 0) - break; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for halt"); - return ERROR_FAIL; - } + dscr = 0; /* force read of dscr */ + retval = cortex_a_wait_dscr_bits(target, DSCR_CORE_HALTED, + DSCR_CORE_HALTED, &dscr); + if (retval != ERROR_OK) { + LOG_ERROR("Error waiting for halt"); + return retval; } target->debug_reason = DBG_REASON_DBGRQ; @@ -915,18 +889,12 @@ static int cortex_a_internal_restart(struct target *target) if (retval != ERROR_OK) return retval; - int64_t then = timeval_ms(); - for (;; ) { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - if ((dscr & DSCR_CORE_RESTARTED) != 0) - break; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for resume"); - return ERROR_FAIL; - } + dscr = 0; /* force read of dscr */ + retval = cortex_a_wait_dscr_bits(target, DSCR_CORE_RESTARTED, + DSCR_CORE_RESTARTED, &dscr); + if (retval != ERROR_OK) { + LOG_ERROR("Error waiting for resume"); + return retval; } target->debug_reason = DBG_REASON_NOTHALTED;