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:
parent
857b5cec1b
commit
a554e09e7c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue