aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2018-03-30 15:24:16 -0700
committerTim Newsome <tim@sifive.com>2018-03-30 15:24:16 -0700
commit755c6a4caa8fb6f7aef54d9568533c60e889d6e0 (patch)
treed90a2e6bd045fa6e676c8f73a92e5e8d0f3d998b /src
parent55e427b72b2772f85510cf9e27d43175dd538e9c (diff)
downloadriscv-openocd-755c6a4caa8fb6f7aef54d9568533c60e889d6e0.zip
riscv-openocd-755c6a4caa8fb6f7aef54d9568533c60e889d6e0.tar.gz
riscv-openocd-755c6a4caa8fb6f7aef54d9568533c60e889d6e0.tar.bz2
Add wall clock timeout to dmi_op()
If the target is held in reset we'd keep adding more delays, and since those grow exponentially they'd get so huge it would take forever to exit out of the loop. Change-Id: Ieaab8b124c101fd1b12f81f905a6de22192ac662
Diffstat (limited to 'src')
-rw-r--r--src/target/riscv/riscv-013.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 337625a..4670569 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -490,8 +490,6 @@ static int dmi_op(struct target *target, uint32_t *data_in, int dmi_op,
dmi_status_t status;
uint32_t address_in;
- unsigned i = 0;
-
const char *op_name;
switch (dmi_op) {
case DMI_OP_NOP:
@@ -508,9 +506,10 @@ static int dmi_op(struct target *target, uint32_t *data_in, int dmi_op,
return ERROR_FAIL;
}
+ time_t start = time(NULL);
/* This first loop performs the request. Note that if for some reason this
* stays busy, it is actually due to the previous access. */
- for (i = 0; i < 256; i++) {
+ while (1) {
status = dmi_scan(target, NULL, NULL, dmi_op, address, data_out,
false);
if (status == DMI_STATUS_BUSY) {
@@ -521,6 +520,13 @@ static int dmi_op(struct target *target, uint32_t *data_in, int dmi_op,
LOG_ERROR("failed %s at 0x%x, status=%d", op_name, address, status);
return ERROR_FAIL;
}
+ if (time(NULL) - start > riscv_command_timeout_sec) {
+ LOG_ERROR("dmi.op is still busy after %d seconds. The target is "
+ "either really slow or broken. You could increase the "
+ "timeout with riscv set_command_timeout_sec.",
+ riscv_command_timeout_sec);
+ return ERROR_FAIL;
+ }
}
if (status != DMI_STATUS_SUCCESS) {
@@ -531,7 +537,7 @@ static int dmi_op(struct target *target, uint32_t *data_in, int dmi_op,
/* This second loop ensures the request succeeded, and gets back data.
* Note that NOP can result in a 'busy' result as well, but that would be
* noticed on the next DMI access we do. */
- for (i = 0; i < 256; i++) {
+ while (1) {
status = dmi_scan(target, &address_in, data_in, DMI_OP_NOP, address, 0,
false);
if (status == DMI_STATUS_BUSY) {
@@ -543,6 +549,13 @@ static int dmi_op(struct target *target, uint32_t *data_in, int dmi_op,
status);
return ERROR_FAIL;
}
+ if (time(NULL) - start > riscv_command_timeout_sec) {
+ LOG_ERROR("dmi.op is still busy after %d seconds. The target is "
+ "either really slow or broken. You could increase the "
+ "timeout with riscv set_command_timeout_sec.",
+ riscv_command_timeout_sec);
+ return ERROR_FAIL;
+ }
}
if (status != DMI_STATUS_SUCCESS) {
@@ -2745,7 +2758,7 @@ void riscv013_clear_abstract_error(struct target *target)
LOG_ERROR("abstractcs.busy is not going low after %d seconds "
"(abstractcs=0x%x). The target is either really slow or "
"broken. You could increase the timeout with riscv "
- "set_reset_timeout_sec.",
+ "set_command_timeout_sec.",
riscv_command_timeout_sec, abstractcs);
break;
}