@@ -3014,22 +3014,50 @@ static int deassert_reset(struct target *target)
3014
3014
riscv_scan_set_delay (& info -> learned_delays , RISCV_DELAY_BASE ,
3015
3015
orig_base_delay );
3016
3016
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 */
3018
3019
control = 0 ;
3019
3020
control = set_field (control , DM_DMCONTROL_DMACTIVE , 1 );
3020
3021
control = set_field (control , DM_DMCONTROL_ACKHAVERESET , 1 );
3022
+ control = set_field (control , DM_DMCONTROL_HALTREQ , target -> reset_halt ? 1 : 0 );
3021
3023
control = set_dmcontrol_hartsel (control , info -> index );
3022
3024
result = dm_write (target , DM_DMCONTROL , control );
3023
3025
if (result != ERROR_OK )
3024
3026
return result ;
3025
3027
3026
3028
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 ));
3027
3046
target -> state = TARGET_HALTED ;
3028
3047
target -> debug_reason = DBG_REASON_DBGRQ ;
3029
3048
} else {
3030
3049
target -> state = TARGET_RUNNING ;
3031
3050
target -> debug_reason = DBG_REASON_NOTHALTED ;
3032
3051
}
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
+
3033
3061
info -> dcsr_ebreak_is_set = dcsr_ebreak_config_equals_reset_value (target );
3034
3062
return ERROR_OK ;
3035
3063
}
0 commit comments