3737
3838#define RISCV_TRIGGER_HIT_NOT_FOUND ((int64_t)-1)
3939
40+ #define RISCV_HALT_GROUP_REPOLL_LIMIT 5
41+
4042static uint8_t ir_dtmcontrol [4 ] = {DTMCONTROL };
4143struct scan_field select_dtmcontrol = {
4244 .in_value = NULL ,
@@ -4025,6 +4027,8 @@ int riscv_openocd_poll(struct target *target)
40254027{
40264028 LOG_TARGET_DEBUG (target , "Polling all harts." );
40274029
4030+ struct riscv_info * i = riscv_info (target );
4031+
40284032 struct list_head * targets ;
40294033
40304034 OOCD_LIST_HEAD (single_target_list );
@@ -4046,6 +4050,7 @@ int riscv_openocd_poll(struct target *target)
40464050 unsigned int should_resume = 0 ;
40474051 unsigned int halted = 0 ;
40484052 unsigned int running = 0 ;
4053+ unsigned int cause_groups = 0 ;
40494054 struct target_list * entry ;
40504055 foreach_smp_target (entry , targets ) {
40514056 struct target * t = entry -> target ;
@@ -4093,6 +4098,59 @@ int riscv_openocd_poll(struct target *target)
40934098 LOG_TARGET_DEBUG (target , "resume all" );
40944099 riscv_resume (target , true, 0 , 0 , 0 , false);
40954100 } else if (halted && running ) {
4101+ LOG_TARGET_DEBUG (target , "SMP group is in inconsistent state: %u halted, %u running" ,
4102+ halted , running );
4103+
4104+ /* The SMP group is in an inconsistent state - some harts in the group have halted
4105+ * whereas others are running. The reasons for that (and corresponding
4106+ * OpenOCD actions) could be:
4107+ * 1) The targets are in the process of halting due to halt groups
4108+ * but not all of them halted --> poll again so that the halt reason of every
4109+ * hart can be accurately determined (e.g. semihosting).
4110+ * 2) The targets do not support halt groups --> OpenOCD must halt
4111+ * the remaining harts by a standard halt request.
4112+ * 3) The hart states got out of sync for some other unknown reason (problem?). -->
4113+ * Same as previous - try to halt the harts by a standard halt request
4114+ * to get them back in sync. */
4115+
4116+ /* Detect if the harts are just in the process of halting due to a halt group */
4117+ foreach_smp_target (entry , targets )
4118+ {
4119+ struct target * t = entry -> target ;
4120+ if (t -> state == TARGET_HALTED ) {
4121+ riscv_reg_t dcsr ;
4122+ if (riscv_reg_get (t , & dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
4123+ return ERROR_FAIL ;
4124+ if (get_field (dcsr , CSR_DCSR_CAUSE ) == CSR_DCSR_CAUSE_GROUP )
4125+ cause_groups ++ ;
4126+ else
4127+ /* This hart has halted due to something else than a halt group.
4128+ * Don't continue checking the rest - exit early. */
4129+ break ;
4130+ }
4131+ }
4132+ /* Condition: halted == cause_groups
4133+ *
4134+ * This condition indicates a paradox where:
4135+ * - All currently halted harts show CSR_DCSR_CAUSE_GROUP
4136+ * - However, no individual hart can be identified as the actual initiator of the halt condition
4137+ *
4138+ * Poll again so that the true halt reason can be discovered (e.g. CSR_DCSR_CAUSE_EBREAK) */
4139+ if (halted == cause_groups ) {
4140+ LOG_TARGET_DEBUG (target , "The harts appear to just be in the process of halting due to a halt group." );
4141+ if (i -> halt_group_repoll_count < RISCV_HALT_GROUP_REPOLL_LIMIT ) {
4142+ /* Wait a little, then re-poll. */
4143+ i -> halt_group_repoll_count ++ ;
4144+ alive_sleep (10 );
4145+ LOG_TARGET_DEBUG (target , "Re-polling the state of the SMP group." );
4146+ return riscv_openocd_poll (target );
4147+ }
4148+ /* We have already re-polled multiple times but the halt group is still inconsistent. */
4149+ LOG_TARGET_DEBUG (target , "Re-polled the SMP group %d times it is still not in a consistent state." ,
4150+ RISCV_HALT_GROUP_REPOLL_LIMIT );
4151+ }
4152+
4153+ /* Halting the whole SMP group to bring it in sync. */
40964154 LOG_TARGET_DEBUG (target , "halt all; halted=%d" ,
40974155 halted );
40984156 riscv_halt (target );
@@ -4110,6 +4168,8 @@ int riscv_openocd_poll(struct target *target)
41104168 }
41114169 }
41124170
4171+ i -> halt_group_repoll_count = 0 ;
4172+
41134173 /* Call tick() for every hart. What happens in tick() is opaque to this
41144174 * layer. The reason it's outside the previous loop is that at this point
41154175 * the state of every hart has settled, so any side effects happening in
0 commit comments