Skip to content

Commit eb48606

Browse files
committed
target/riscv: make sure target is halted when reset_halt is set | riscv-collab#1214
1 parent 76a673e commit eb48606

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/target/riscv/riscv-013.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3014,22 +3014,50 @@ static int deassert_reset(struct target *target)
30143014
riscv_scan_set_delay(&info->learned_delays, RISCV_DELAY_BASE,
30153015
orig_base_delay);
30163016

3017-
/* Ack reset and clear DM_DMCONTROL_HALTREQ if previously set */
3017+
/* Ack reset with DM_DMCONTROL_HALTREQ for those MCUs which need a
3018+
* period of time to be halted after reset is released */
30183019
control = 0;
30193020
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
30203021
control = set_field(control, DM_DMCONTROL_ACKHAVERESET, 1);
3022+
control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0);
30213023
control = set_dmcontrol_hartsel(control, info->index);
30223024
result = dm_write(target, DM_DMCONTROL, control);
30233025
if (result != ERROR_OK)
30243026
return result;
30253027

30263028
if (target->reset_halt) {
3029+
/* Wait for all harts to halt for those MCUs mentioned above */
3030+
time_t halt_start = time(NULL);
3031+
do {
3032+
result = dmstatus_read(target, &dmstatus, true);
3033+
if (result != ERROR_OK)
3034+
return result;
3035+
3036+
if (time(NULL) - halt_start > riscv_get_command_timeout_sec()) {
3037+
LOG_TARGET_ERROR(target, "Hart didn't halt after reset in %ds; "
3038+
"dmstatus=0x%x (anyhalted=%s, allhalted=%s); "
3039+
"Increase the timeout with riscv set_command_timeout_sec.",
3040+
riscv_get_command_timeout_sec(), dmstatus,
3041+
get_field(dmstatus, DM_DMSTATUS_ANYHALTED) ? "true" : "false",
3042+
get_field(dmstatus, DM_DMSTATUS_ALLHALTED) ? "true" : "false");
3043+
return ERROR_TIMEOUT_REACHED;
3044+
}
3045+
} while (!get_field(dmstatus, DM_DMSTATUS_ALLHALTED));
30273046
target->state = TARGET_HALTED;
30283047
target->debug_reason = DBG_REASON_DBGRQ;
30293048
} else {
30303049
target->state = TARGET_RUNNING;
30313050
target->debug_reason = DBG_REASON_NOTHALTED;
30323051
}
3052+
3053+
/* clear DM_DMCONTROL_HALTREQ */
3054+
control = 0;
3055+
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
3056+
control = set_dmcontrol_hartsel(control, info->index);
3057+
result = dm_write(target, DM_DMCONTROL, control);
3058+
if (result != ERROR_OK)
3059+
return result;
3060+
30333061
info->dcsr_ebreak_is_set = dcsr_ebreak_config_equals_reset_value(target);
30343062
return ERROR_OK;
30353063
}

0 commit comments

Comments
 (0)