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 <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/5113 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>bscan_optimization
parent
d870ecf5ff
commit
f9986394dc
|
@ -70,6 +70,8 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target,
|
||||||
struct breakpoint *breakpoint);
|
struct breakpoint *breakpoint);
|
||||||
static int cortex_a_unset_breakpoint(struct target *target,
|
static int cortex_a_unset_breakpoint(struct target *target,
|
||||||
struct breakpoint *breakpoint);
|
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(struct target *target, int *enabled);
|
||||||
static int cortex_a_mmu_modify(struct target *target, int enable);
|
static int cortex_a_mmu_modify(struct target *target, int enable);
|
||||||
static int cortex_a_virt2phys(struct target *target,
|
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
|
* Writes final value of DSCR into *dscr. Pass force to force always
|
||||||
* reading DSCR at least once. */
|
* reading DSCR at least once. */
|
||||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||||
int64_t then = timeval_ms();
|
int retval;
|
||||||
while ((*dscr & DSCR_INSTR_COMP) == 0 || force) {
|
|
||||||
force = false;
|
if (force) {
|
||||||
int retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
||||||
armv7a->debug_base + CPUDBG_DSCR, dscr);
|
armv7a->debug_base + CPUDBG_DSCR, dscr);
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("Could not read DSCR register");
|
LOG_ERROR("Could not read DSCR register");
|
||||||
return retval;
|
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
|
/* 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)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
int64_t then = timeval_ms();
|
/* Wait for InstrCompl bit to be set */
|
||||||
do {
|
retval = cortex_a_wait_instrcmpl(target, &dscr, true);
|
||||||
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
|
||||||
armv7a->debug_base + CPUDBG_DSCR, &dscr);
|
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("Could not read DSCR register");
|
LOG_ERROR("Error waiting for cortex_a_exec_opcode");
|
||||||
return retval;
|
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 */
|
|
||||||
|
|
||||||
if (dscr_p)
|
if (dscr_p)
|
||||||
*dscr_p = dscr;
|
*dscr_p = dscr;
|
||||||
|
@ -359,17 +354,11 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
|
||||||
dscr = *dscr_p;
|
dscr = *dscr_p;
|
||||||
|
|
||||||
/* Wait for DTRRXfull */
|
/* Wait for DTRRXfull */
|
||||||
int64_t then = timeval_ms();
|
retval = cortex_a_wait_dscr_bits(a->armv7a_common.arm.target,
|
||||||
while ((dscr & DSCR_DTR_TX_FULL) == 0) {
|
DSCR_DTR_TX_FULL, DSCR_DTR_TX_FULL, &dscr);
|
||||||
retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
|
if (retval != ERROR_OK) {
|
||||||
a->armv7a_common.debug_base + CPUDBG_DSCR,
|
LOG_ERROR("Error waiting for read dcc");
|
||||||
&dscr);
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
return retval;
|
||||||
if (timeval_ms() > then + 1000) {
|
|
||||||
LOG_ERROR("Timeout waiting for read dcc");
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
|
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;
|
int retval;
|
||||||
|
|
||||||
/* set up invariant: INSTR_COMP is set after ever DPM operation */
|
/* set up invariant: INSTR_COMP is set after ever DPM operation */
|
||||||
int64_t then = timeval_ms();
|
retval = cortex_a_wait_instrcmpl(dpm->arm->target, &dscr, true);
|
||||||
for (;; ) {
|
if (retval != ERROR_OK) {
|
||||||
retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
|
LOG_ERROR("Error waiting for dpm prepare");
|
||||||
a->armv7a_common.debug_base + CPUDBG_DSCR,
|
|
||||||
&dscr);
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
return retval;
|
||||||
if ((dscr & DSCR_INSTR_COMP) != 0)
|
|
||||||
break;
|
|
||||||
if (timeval_ms() > then + 1000) {
|
|
||||||
LOG_ERROR("Timeout waiting for dpm prepare");
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this "should never happen" ... */
|
/* this "should never happen" ... */
|
||||||
|
@ -752,7 +732,7 @@ static int cortex_a_poll(struct target *target)
|
||||||
|
|
||||||
static int cortex_a_halt(struct target *target)
|
static int cortex_a_halt(struct target *target)
|
||||||
{
|
{
|
||||||
int retval = ERROR_OK;
|
int retval;
|
||||||
uint32_t dscr;
|
uint32_t dscr;
|
||||||
struct armv7a_common *armv7a = target_to_armv7a(target);
|
struct armv7a_common *armv7a = target_to_armv7a(target);
|
||||||
|
|
||||||
|
@ -765,18 +745,12 @@ static int cortex_a_halt(struct target *target)
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
int64_t then = timeval_ms();
|
dscr = 0; /* force read of dscr */
|
||||||
for (;; ) {
|
retval = cortex_a_wait_dscr_bits(target, DSCR_CORE_HALTED,
|
||||||
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
DSCR_CORE_HALTED, &dscr);
|
||||||
armv7a->debug_base + CPUDBG_DSCR, &dscr);
|
if (retval != ERROR_OK) {
|
||||||
if (retval != ERROR_OK)
|
LOG_ERROR("Error waiting for halt");
|
||||||
return retval;
|
return retval;
|
||||||
if ((dscr & DSCR_CORE_HALTED) != 0)
|
|
||||||
break;
|
|
||||||
if (timeval_ms() > then + 1000) {
|
|
||||||
LOG_ERROR("Timeout waiting for halt");
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target->debug_reason = DBG_REASON_DBGRQ;
|
target->debug_reason = DBG_REASON_DBGRQ;
|
||||||
|
@ -915,18 +889,12 @@ static int cortex_a_internal_restart(struct target *target)
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
int64_t then = timeval_ms();
|
dscr = 0; /* force read of dscr */
|
||||||
for (;; ) {
|
retval = cortex_a_wait_dscr_bits(target, DSCR_CORE_RESTARTED,
|
||||||
retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
|
DSCR_CORE_RESTARTED, &dscr);
|
||||||
armv7a->debug_base + CPUDBG_DSCR, &dscr);
|
if (retval != ERROR_OK) {
|
||||||
if (retval != ERROR_OK)
|
LOG_ERROR("Error waiting for resume");
|
||||||
return retval;
|
return retval;
|
||||||
if ((dscr & DSCR_CORE_RESTARTED) != 0)
|
|
||||||
break;
|
|
||||||
if (timeval_ms() > then + 1000) {
|
|
||||||
LOG_ERROR("Timeout waiting for resume");
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target->debug_reason = DBG_REASON_NOTHALTED;
|
target->debug_reason = DBG_REASON_NOTHALTED;
|
||||||
|
|
Loading…
Reference in New Issue