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
This commit is contained in:
parent
55e427b72b
commit
755c6a4caa
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue