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 ,
@@ -3722,6 +3724,8 @@ int riscv_openocd_poll(struct target *target)
37223724{
37233725 LOG_TARGET_DEBUG (target , "Polling all harts." );
37243726
3727+ struct riscv_info * i = riscv_info (target );
3728+
37253729 struct list_head * targets ;
37263730
37273731 LIST_HEAD (single_target_list );
@@ -3743,6 +3747,7 @@ int riscv_openocd_poll(struct target *target)
37433747 unsigned int should_resume = 0 ;
37443748 unsigned int halted = 0 ;
37453749 unsigned int running = 0 ;
3750+ unsigned int cause_groups = 0 ;
37463751 struct target_list * entry ;
37473752 foreach_smp_target (entry , targets ) {
37483753 struct target * t = entry -> target ;
@@ -3790,6 +3795,59 @@ int riscv_openocd_poll(struct target *target)
37903795 LOG_TARGET_DEBUG (target , "resume all" );
37913796 riscv_resume (target , true, 0 , 0 , 0 , false);
37923797 } else if (halted && running ) {
3798+ LOG_TARGET_DEBUG (target , "SMP group is in inconsistent state: %u halted, %u running" ,
3799+ halted , running );
3800+
3801+ /* The SMP group is in an inconsistent state - some harts in the group have halted
3802+ * whereas others are running. The reasons for that (and corresponding
3803+ * OpenOCD actions) could be:
3804+ * 1) The targets are in the process of halting due to halt groups
3805+ * but not all of them halted --> poll again so that the halt reason of every
3806+ * hart can be accurately determined (e.g. semihosting).
3807+ * 2) The targets do not support halt groups --> OpenOCD must halt
3808+ * the remaining harts by a standard halt request.
3809+ * 3) The hart states got out of sync for some other unknown reason (problem?). -->
3810+ * Same as previous - try to halt the harts by a standard halt request
3811+ * to get them back in sync. */
3812+
3813+ /* Detect if the harts are just in the process of halting due to a halt group */
3814+ foreach_smp_target (entry , targets )
3815+ {
3816+ struct target * t = entry -> target ;
3817+ if (t -> state == TARGET_HALTED ) {
3818+ riscv_reg_t dcsr ;
3819+ if (riscv_reg_get (t , & dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
3820+ return ERROR_FAIL ;
3821+ if (get_field (dcsr , CSR_DCSR_CAUSE ) == CSR_DCSR_CAUSE_GROUP )
3822+ cause_groups ++ ;
3823+ else
3824+ /* This hart has halted due to something else than a halt group.
3825+ * Don't continue checking the rest - exit early. */
3826+ break ;
3827+ }
3828+ }
3829+ /* Condition: halted == cause_groups
3830+ *
3831+ * This condition indicates a paradox where:
3832+ * - All currently halted harts show CSR_DCSR_CAUSE_GROUP
3833+ * - However, no individual hart can be identified as the actual initiator of the halt condition
3834+ *
3835+ * Poll again so that the true halt reason can be discovered (e.g. CSR_DCSR_CAUSE_EBREAK) */
3836+ if (halted == cause_groups ) {
3837+ LOG_TARGET_DEBUG (target , "The harts appear to just be in the process of halting due to a halt group." );
3838+ if (i -> halt_group_repoll_count < RISCV_HALT_GROUP_REPOLL_LIMIT ) {
3839+ /* Wait a little, then re-poll. */
3840+ i -> halt_group_repoll_count ++ ;
3841+ alive_sleep (10 );
3842+ LOG_TARGET_DEBUG (target , "Re-polling the state of the SMP group." );
3843+ return riscv_openocd_poll (target );
3844+ }
3845+ /* We have already re-polled multiple times but the halt group is still inconsistent. */
3846+ LOG_TARGET_DEBUG (target , "Re-polled the SMP group %d times it is still not in a consistent state." ,
3847+ RISCV_HALT_GROUP_REPOLL_LIMIT );
3848+ }
3849+
3850+ /* Halting the whole SMP group to bring it in sync. */
37933851 LOG_TARGET_DEBUG (target , "halt all; halted=%d" ,
37943852 halted );
37953853 riscv_halt (target );
@@ -3807,6 +3865,8 @@ int riscv_openocd_poll(struct target *target)
38073865 }
38083866 }
38093867
3868+ i -> halt_group_repoll_count = 0 ;
3869+
38103870 /* Call tick() for every hart. What happens in tick() is opaque to this
38113871 * layer. The reason it's outside the previous loop is that at this point
38123872 * the state of every hart has settled, so any side effects happening in
0 commit comments