Skip to content

Commit 62c0eb7

Browse files
committed
target/riscv: make sure target is halted when reset_halt is set
- 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 <jianghao.qian@hpmicro.com>
1 parent 88fe568 commit 62c0eb7

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
@@ -2924,22 +2924,50 @@ static int deassert_reset(struct target *target)
29242924
riscv_scan_set_delay(&info->learned_delays, RISCV_DELAY_BASE,
29252925
orig_base_delay);
29262926

2927-
/* Ack reset and clear DM_DMCONTROL_HALTREQ if previously set */
2927+
/* Ack reset with DM_DMCONTROL_HALTREQ for those MCUs which need a
2928+
* period of time to be halted after reset is released */
29282929
control = 0;
29292930
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
29302931
control = set_field(control, DM_DMCONTROL_ACKHAVERESET, 1);
2932+
control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0);
29312933
control = set_dmcontrol_hartsel(control, info->index);
29322934
result = dm_write(target, DM_DMCONTROL, control);
29332935
if (result != ERROR_OK)
29342936
return result;
29352937

29362938
if (target->reset_halt) {
2939+
/* Wait for all harts to halt for those MCUs mentioned above */
2940+
start = time(NULL);
2941+
do {
2942+
result = dmstatus_read(target, &dmstatus, true);
2943+
if (result != ERROR_OK)
2944+
return result;
2945+
2946+
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
2947+
LOG_TARGET_ERROR(target, "Hart didn't halt after reset in %ds; "
2948+
"dmstatus=0x%x (anyhalted=%s, allhalted=%s); "
2949+
"Increase the timeout with riscv set_command_timeout_sec.",
2950+
riscv_get_command_timeout_sec(), dmstatus,
2951+
get_field(dmstatus, DM_DMSTATUS_ANYHALTED) ? "true" : "false",
2952+
get_field(dmstatus, DM_DMSTATUS_ALLHALTED) ? "true" : "false");
2953+
return ERROR_TIMEOUT_REACHED;
2954+
}
2955+
} while (!get_field(dmstatus, DM_DMSTATUS_ALLHALTED));
29372956
target->state = TARGET_HALTED;
29382957
target->debug_reason = DBG_REASON_DBGRQ;
29392958
} else {
29402959
target->state = TARGET_RUNNING;
29412960
target->debug_reason = DBG_REASON_NOTHALTED;
29422961
}
2962+
2963+
/* clear DM_DMCONTROL_HALTREQ */
2964+
control = 0;
2965+
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
2966+
control = set_dmcontrol_hartsel(control, info->index);
2967+
result = dm_write(target, DM_DMCONTROL, control);
2968+
if (result != ERROR_OK)
2969+
return result;
2970+
29432971
info->dcsr_ebreak_is_set = dcsr_ebreak_config_equals_reset_value(target);
29442972
return ERROR_OK;
29452973
}

0 commit comments

Comments
 (0)