Properly handle held-in-reset targets. (#654)

* Properly handle held-in-reset targets.

1. Let OpenOCD continue into some pre-existing code that will periodically
   call examine() until it passes.
2. Fix crash in riscv_openocd_poll()
   When SMP is configured, it's not guaranteed that all targets have been
   examine()d when poll is called on one of them.

Change-Id: Ic6c1d217dc766ea69b67bb2e9a4898e37ee94927
Signed-off-by: Tim Newsome <tim@sifive.com>

* Actually poll for examine at least every 5s.

That's what the comment says the code is trying to do.

Change-Id: I34ff909a98f8aebb3c514e0f3ee403be7699c094
Signed-off-by: Tim Newsome <tim@sifive.com>

* Compact this error message a bit.

Reduces clutter when some targets haven't been properly examined yet.

Change-Id: Id865f191f0fbb48abece8b8558cc9fa2041a26df
Signed-off-by: Tim Newsome <tim@sifive.com>
This commit is contained in:
Tim Newsome 2021-10-21 17:08:49 -07:00 committed by GitHub
parent 857b5cec1b
commit a554e09e7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 32 deletions

View File

@ -652,10 +652,10 @@ static int dmi_op(struct target *target, uint32_t *data_in,
int result = dmi_op_timeout(target, data_in, dmi_busy_encountered, dmi_op,
address, data_out, riscv_command_timeout_sec, exec, ensure_success);
if (result == ERROR_TIMEOUT_REACHED) {
LOG_ERROR("DMI operation didn't complete in %d seconds. The target is "
LOG_ERROR("[%s] DMI operation didn't complete in %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);
target_name(target), riscv_command_timeout_sec);
return ERROR_FAIL;
}
return result;
@ -863,8 +863,8 @@ static uint32_t access_register_command(struct target *target, uint32_t number,
command = set_field(command, AC_ACCESS_REGISTER_AARSIZE, 3);
break;
default:
LOG_ERROR("%d-bit register %s not supported.", size,
gdb_regno_name(number));
LOG_ERROR("[%s] %d-bit register %s not supported.",
target_name(target), size, gdb_regno_name(number));
assert(0);
}
@ -1546,8 +1546,8 @@ static int examine(struct target *target)
return ERROR_FAIL;
}
if (get_field(dtmcontrol, DTM_DTMCS_VERSION) != 1) {
LOG_ERROR("Unsupported DTM version %d. (dtmcontrol=0x%x)",
get_field(dtmcontrol, DTM_DTMCS_VERSION), dtmcontrol);
LOG_ERROR("[%s] Unsupported DTM version %d. (dtmcontrol=0x%x)",
target_name(target), get_field(dtmcontrol, DTM_DTMCS_VERSION), dtmcontrol);
return ERROR_FAIL;
}
@ -1628,7 +1628,8 @@ static int examine(struct target *target)
info->datacount = get_field(abstractcs, DM_ABSTRACTCS_DATACOUNT);
info->progbufsize = get_field(abstractcs, DM_ABSTRACTCS_PROGBUFSIZE);
LOG_INFO("datacount=%d progbufsize=%d", info->datacount, info->progbufsize);
LOG_INFO("[%s] datacount=%d progbufsize=%d", target_name(target),
info->datacount, info->progbufsize);
RISCV_INFO(r);
r->impebreak = get_field(dmstatus, DM_DMSTATUS_IMPEBREAK);
@ -1685,7 +1686,8 @@ static int examine(struct target *target)
bool halted = riscv_is_halted(target);
if (!halted) {
if (riscv013_halt_go(target) != ERROR_OK) {
LOG_ERROR("Fatal: Hart %d failed to halt during examine()", r->current_hartid);
LOG_ERROR("[%s] Fatal: Hart %d failed to halt during examine()",
target_name(target), r->current_hartid);
return ERROR_FAIL;
}
}
@ -1727,7 +1729,7 @@ static int examine(struct target *target)
return ERROR_FAIL;
/* Display this as early as possible to help people who are using
* really slow simulators. */
* really slow simulators. */
LOG_DEBUG(" hart %d: XLEN=%d, misa=0x%" PRIx64, r->current_hartid, r->xlen,
r->misa);
@ -4193,9 +4195,8 @@ static int riscv013_halt_go(struct target *target)
if (dmi_read(target, &dmcontrol, DM_DMCONTROL) != ERROR_OK)
return ERROR_FAIL;
LOG_ERROR("unable to halt hart %d", r->current_hartid);
LOG_ERROR(" dmcontrol=0x%08x", dmcontrol);
LOG_ERROR(" dmstatus =0x%08x", dmstatus);
LOG_ERROR("[%s] Unable to halt hart %d. dmcontrol=0x%08x, dmstatus=0x%08x",
target_name(target), r->current_hartid, dmcontrol, dmstatus);
return ERROR_FAIL;
}

View File

@ -418,7 +418,8 @@ static struct target_type *get_target_type(struct target *target)
case 1:
return &riscv013_target;
default:
LOG_ERROR("Unsupported DTM version: %d", info->dtm_version);
LOG_ERROR("[%s] Unsupported DTM version: %d",
target_name(target), info->dtm_version);
return NULL;
}
}
@ -1108,10 +1109,9 @@ static int old_or_new_riscv_step(struct target *target, int current,
return riscv_openocd_step(target, current, address, handle_breakpoints);
}
static int riscv_examine(struct target *target)
{
LOG_DEBUG("riscv_examine()");
LOG_DEBUG("[%s]", target_name(target));
if (target_was_examined(target)) {
LOG_DEBUG("Target was already examined.");
return ERROR_OK;
@ -2079,7 +2079,8 @@ static enum riscv_poll_hart riscv_poll_hart(struct target *target, int hartid)
if (riscv_set_current_hartid(target, hartid) != ERROR_OK)
return RPH_ERROR;
LOG_DEBUG("polling hart %d, target->state=%d", hartid, target->state);
LOG_DEBUG("[%s] polling hart %d, target->state=%d", target_name(target),
hartid, target->state);
/* If OpenOCD thinks we're running but this hart is halted then it's time
* to raise an event. */
@ -2185,6 +2186,8 @@ int riscv_openocd_poll(struct target *target)
for (struct target_list *list = target->head; list;
list = list->next, i++) {
struct target *t = list->target;
if (!target_was_examined(t))
continue;
riscv_info_t *r = riscv_info(t);
enum riscv_poll_hart out = riscv_poll_hart(t, r->current_hartid);
switch (out) {
@ -4099,8 +4102,8 @@ int riscv_init_registers(struct target *target)
target->reg_cache->num_regs += entry->high - entry->low + 1;
}
LOG_DEBUG("create register cache for %d registers",
target->reg_cache->num_regs);
LOG_DEBUG("[%s] create register cache for %d registers",
target_name(target), target->reg_cache->num_regs);
target->reg_cache->reg_list =
calloc(target->reg_cache->num_regs, sizeof(struct reg));

View File

@ -751,6 +751,7 @@ int target_examine_one(struct target *target)
return retval;
}
LOG_USER("[%s] Target successfully examined.", target_name(target));
target_set_examined(target);
target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END);
@ -3021,9 +3022,6 @@ static int handle_target(void *priv)
is_jtag_poll_safe() && target;
target = target->next) {
if (!target_was_examined(target))
continue;
if (!target->tap->enabled)
continue;
@ -3040,10 +3038,9 @@ static int handle_target(void *priv)
retval = target_poll(target);
if (retval != ERROR_OK) {
/* 100ms polling interval. Increase interval between polling up to 5000ms */
if (target->backoff.times * polling_interval < 5000) {
target->backoff.times *= 2;
target->backoff.times++;
}
if (target->backoff.times * polling_interval < 5000)
target->backoff.times = MIN(target->backoff.times * 2 + 1,
5000 / polling_interval);
/* Tell GDB to halt the debugger. This allows the user to
* run monitor commands to handle the situation.
@ -3051,15 +3048,12 @@ static int handle_target(void *priv)
target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
}
if (target->backoff.times > 0) {
LOG_USER("Polling target %s failed, trying to reexamine", target_name(target));
LOG_DEBUG("[%s] Polling failed, trying to reexamine", target_name(target));
target_reset_examined(target);
retval = target_examine_one(target);
/* Target examination could have failed due to unstable connection,
* but we set the examined flag anyway to repoll it later */
if (retval != ERROR_OK) {
target_set_examined(target);
LOG_USER("Examination failed, GDB will be halted. Polling again in %dms",
target->backoff.times * polling_interval);
LOG_DEBUG("[%s] Examination failed, GDB will be halted. Polling again in %dms",
target_name(target), target->backoff.times * polling_interval);
return retval;
}
}

View File

@ -106,7 +106,7 @@ def main(args):
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('file', nargs='*', help='input file')
parser.add_argument('-o', '--output', help='output file', default=sys.stdout)
parser.add_argument('-w', '--window', type=int, default=100,
parser.add_argument('-w', '--window', type=int, default=400,
help='number of lines to consider when looking for repetitions')
args = parser.parse_args(args)