aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authorAndreas Fritiofson <andreas.fritiofson@gmail.com>2021-11-08 18:09:56 +0100
committerTomas Vanek <vanekt@fbl.cz>2021-11-18 21:13:19 +0000
commitcaa16981364d747c1c71edaf156e8a4faa83b02b (patch)
treedb98fe5c42c4e237012c2a93e9d5607de44a57a2 /src/target
parent88f429ead019fd6df96ec15f0d897385f3cef0d0 (diff)
downloadriscv-openocd-caa16981364d747c1c71edaf156e8a4faa83b02b.zip
riscv-openocd-caa16981364d747c1c71edaf156e8a4faa83b02b.tar.gz
riscv-openocd-caa16981364d747c1c71edaf156e8a4faa83b02b.tar.bz2
cortex_m: Restore fast register reads if no polling is needed
If the target is in a state where S_REGRDY polling is necessary (slow clock, low power state...?), OpenOCD will continue to use the slow path even if the condition is temporary and the target at a later point would be capable of fast reads again. Revert to fast reads if a full register dump can be made without need for polling any of the registers; presumably it will succeed the next time too. Change-Id: I557f0d90b7ce6f9d81aa409b6400fc9c83d16008 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/6678 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Diffstat (limited to 'src/target')
-rw-r--r--src/target/cortex_m.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 82d5eff..721cf0a 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -183,6 +183,7 @@ static int cortex_m_load_core_reg_u32(struct target *target,
cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);
if (cortex_m->dcb_dhcsr & S_REGRDY)
break;
+ cortex_m->slow_register_read = true; /* Polling (still) needed. */
if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) {
LOG_ERROR("Timeout waiting for DCRDR transfer ready");
return ERROR_TIMEOUT_REACHED;
@@ -204,9 +205,14 @@ static int cortex_m_load_core_reg_u32(struct target *target,
static int cortex_m_slow_read_all_regs(struct target *target)
{
+ struct cortex_m_common *cortex_m = target_to_cm(target);
struct armv7m_common *armv7m = target_to_armv7m(target);
const unsigned int num_regs = armv7m->arm.core_cache->num_regs;
+ /* Opportunistically restore fast read, it'll revert to slow
+ * if any register needed polling in cortex_m_load_core_reg_u32(). */
+ cortex_m->slow_register_read = false;
+
for (unsigned int reg_id = 0; reg_id < num_regs; reg_id++) {
struct reg *r = &armv7m->arm.core_cache->reg_list[reg_id];
if (r->exist) {
@@ -215,6 +221,10 @@ static int cortex_m_slow_read_all_regs(struct target *target)
return retval;
}
}
+
+ if (!cortex_m->slow_register_read)
+ LOG_DEBUG("Switching back to fast register reads");
+
return ERROR_OK;
}