Skip to content

Commit

Permalink
target/riscv: make sure target is halted when reset_halt is set
Browse files Browse the repository at this point in the history
- some MCU will need certain period of time to be halted after ndmreset
  is issued, so in deassert_reset, it needs to make sure MCU is halted
  before clearing DM_DMCONTROL_HALTREQ.

Change-Id: I6d7ef7b9b33aff65cb996968fb28cd62e3e1fb16
Signed-off-by: Ryan QIAN <[email protected]>
  • Loading branch information
jhqian committed Jan 27, 2025
1 parent 88fe568 commit 73d5899
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -2928,18 +2928,47 @@ static int deassert_reset(struct target *target)
control = 0;
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
control = set_field(control, DM_DMCONTROL_ACKHAVERESET, 1);
/* Ack reset with DM_DMCONTROL_HALTREQ for those MCUs which need a
* period of time to be halted after reset is released */
control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0);
control = set_dmcontrol_hartsel(control, info->index);
result = dm_write(target, DM_DMCONTROL, control);
if (result != ERROR_OK)
return result;

if (target->reset_halt) {
/* Wait for all harts to halt for those MCUs mentioned above */
start = time(NULL);
do {
result = dmstatus_read(target, &dmstatus, true);
if (result != ERROR_OK)
return result;

if (time(NULL) - start > riscv_get_command_timeout_sec()) {
LOG_TARGET_ERROR(target, "Hart didn't halt after reset in %ds; "
"dmstatus=0x%x (anyhalted=%s, allhalted=%s); "
"Increase the timeout with riscv set_command_timeout_sec.",
riscv_get_command_timeout_sec(), dmstatus,
get_field(dmstatus, DM_DMSTATUS_ANYHALTED) ? "true" : "false",
get_field(dmstatus, DM_DMSTATUS_ALLHALTED) ? "true" : "false");
return ERROR_TIMEOUT_REACHED;
}
} while (!get_field(dmstatus, DM_DMSTATUS_ALLHALTED));
target->state = TARGET_HALTED;
target->debug_reason = DBG_REASON_DBGRQ;
} else {
target->state = TARGET_RUNNING;
target->debug_reason = DBG_REASON_NOTHALTED;
}

/* clear DM_DMCONTROL_HALTREQ */
control = 0;
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
control = set_dmcontrol_hartsel(control, info->index);
result = dm_write(target, DM_DMCONTROL, control);
if (result != ERROR_OK)
return result;

info->dcsr_ebreak_is_set = dcsr_ebreak_config_equals_reset_value(target);
return ERROR_OK;
}
Expand Down

0 comments on commit 73d5899

Please sign in to comment.