@@ -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