aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2018-06-25 13:12:44 -0700
committerTim Newsome <tim@sifive.com>2018-11-19 12:50:58 -0800
commit0ed1606c76c58014ad8ed54048ad53ad6770624c (patch)
tree5d6a670c5099983b129ebd4cb9c6aee4392b0467
parent66adc90a84458a9c47e2966aac3d3bb85f5d9d70 (diff)
downloadriscv-openocd-haltreq.zip
riscv-openocd-haltreq.tar.gz
riscv-openocd-haltreq.tar.bz2
Set haltreq when we're halted.haltreq
I'd missed a case when a hart halts almost instantly after resume Change-Id: I68cbb04c16e1443aa318faa2d30475c61c71701f
-rw-r--r--src/target/riscv/riscv-013.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 9a2a6c3..f0561eb 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -414,7 +414,7 @@ static void select_dmi(struct target *target)
jtag_add_ir_scan(target->tap, &field, TAP_IDLE);
}
-static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
+static int dtmcontrol_scan(struct target *target, uint32_t *in, uint32_t out)
{
struct scan_field field;
uint8_t in_value[4];
@@ -438,13 +438,22 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
return retval;
}
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCS: 0x%x -> 0x%x", out, in);
+ uint32_t dtmcontrol = buf_get_u32(field.in_value, 0, 32);
+ LOG_DEBUG("DTMCS: 0x%x -> 0x%x", out, dtmcontrol);
- return in;
+ if (dtmcontrol == 0) {
+ LOG_ERROR("TDO seems to be stuck low; target might be held in "
+ "reset, or there might be a connection failure");
+ return ERROR_FAIL;
+ }
+
+ if (in)
+ *in = dtmcontrol;
+
+ return ERROR_OK;
}
-static void increase_dmi_busy_delay(struct target *target)
+static int increase_dmi_busy_delay(struct target *target)
{
riscv013_info_t *info = get_info(target);
info->dmi_busy_delay += info->dmi_busy_delay / 10 + 1;
@@ -452,7 +461,7 @@ static void increase_dmi_busy_delay(struct target *target)
info->dtmcontrol_idle, info->dmi_busy_delay,
info->ac_busy_delay);
- dtmcontrol_scan(target, DTM_DTMCS_DMIRESET);
+ return dtmcontrol_scan(target, NULL, DTM_DTMCS_DMIRESET | DTM_DTMCS_DMIHARDRESET);
}
/**
@@ -577,13 +586,6 @@ static int dmi_op_timeout(struct target *target, uint32_t *data_in, int dmi_op,
LOG_ERROR("TDO seems to be stuck high; target might be held in "
"reset, or there might be a connection failure");
return ERROR_FAIL;
- } else if (dmi_op == DMI_OP_READ && address != 0 && status == 0 &&
- address_in == 0 && *data_in == 0) {
- /* On read ops we should at least get back the address as non-zero.
- * */
- LOG_ERROR("TDO seems to be stuck low; target might be held in "
- "reset, or there might be a connection failure");
- return ERROR_FAIL;
} else if (status == DMI_STATUS_BUSY) {
increase_dmi_busy_delay(target);
} else if (status == DMI_STATUS_SUCCESS) {
@@ -1372,7 +1374,9 @@ static int examine(struct target *target)
{
/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */
- uint32_t dtmcontrol = dtmcontrol_scan(target, 0);
+ uint32_t dtmcontrol;
+ if (dtmcontrol_scan(target, &dtmcontrol, 0) != ERROR_OK)
+ return ERROR_FAIL;
LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol);
LOG_DEBUG(" dmireset=%d", get_field(dtmcontrol, DTM_DTMCS_DMIRESET));
LOG_DEBUG(" idle=%d", get_field(dtmcontrol, DTM_DTMCS_IDLE));
@@ -3451,8 +3455,13 @@ static int riscv013_step_or_resume_current_hart(struct target *target, bool step
if (step && get_field(dmstatus, DMI_DMSTATUS_ALLHALTED) == 0)
continue;
+ if (get_field(dmstatus, DMI_DMSTATUS_ANYHALTED)) {
+ dmcontrol |= DMI_DMCONTROL_HALTREQ;
+ info->really_halted[r->current_hartid] = true;
+ } else {
+ info->really_halted[r->current_hartid] = false;
+ }
dmi_write(target, DMI_DMCONTROL, dmcontrol);
- info->really_halted[r->current_hartid] = false;
return ERROR_OK;
}