@@ -623,12 +623,12 @@ static int find_first_trigger_by_id(struct target *target, int unique_id)
623623
624624static unsigned int count_trailing_ones (riscv_reg_t reg )
625625{
626- assert ( sizeof (riscv_reg_t ) * 8 == 64 ) ;
627- for (unsigned int i = 0 ; i < 64 ; i ++ ) {
626+ const unsigned int riscv_reg_bits = sizeof (riscv_reg_t ) * CHAR_BIT ;
627+ for (unsigned int i = 0 ; i < riscv_reg_bits ; i ++ ) {
628628 if ((1 & (reg >> i )) == 0 )
629629 return i ;
630630 }
631- return 64 ;
631+ return riscv_reg_bits ;
632632}
633633
634634static int set_trigger (struct target * target , unsigned int idx , riscv_reg_t tdata1 , riscv_reg_t tdata2 )
@@ -1561,21 +1561,75 @@ int riscv_remove_watchpoint(struct target *target,
15611561 return ERROR_OK ;
15621562}
15631563
1564+ typedef enum {
1565+ M6_HIT_ERROR ,
1566+ M6_HIT_NOT_SUPPORTED ,
1567+ M6_NOT_HIT ,
1568+ M6_HIT_BEFORE ,
1569+ M6_HIT_AFTER ,
1570+ M6_HIT_IMM_AFTER
1571+ } mctrl6hitstatus ;
1572+
1573+ static mctrl6hitstatus check_mcontrol6_hit_status (struct target * target ,
1574+ riscv_reg_t tdata1 , uint64_t hit_mask )
1575+ {
1576+ const uint32_t hit0 = get_field (tdata1 , CSR_MCONTROL6_HIT0 );
1577+ const uint32_t hit1 = get_field (tdata1 , CSR_MCONTROL6_HIT1 );
1578+ const uint32_t hit_info = (hit1 << 1 ) | hit0 ;
1579+ if (hit_info == CSR_MCONTROL6_HIT0_BEFORE )
1580+ return M6_HIT_BEFORE ;
1581+
1582+ if (hit_info == CSR_MCONTROL6_HIT0_AFTER )
1583+ return M6_HIT_AFTER ;
1584+
1585+ if (hit_info == CSR_MCONTROL6_HIT0_IMMEDIATELY_AFTER )
1586+ return M6_HIT_IMM_AFTER ;
1587+
1588+ if (hit_info == CSR_MCONTROL6_HIT0_FALSE ) {
1589+ /* hit[1..0] equals 0, which can mean one of the following:
1590+ * - "hit" bits are supported and this trigger has not fired
1591+ * - "hit" bits are not supported on this trigger
1592+ * To distinguish these two cases, try writing all non-zero bit
1593+ * patterns to hit[1..0] to determine if the "hit" bits are supported:
1594+ */
1595+ riscv_reg_t tdata1_tests [] = {
1596+ set_field (tdata1 , CSR_MCONTROL6_HIT0 , 1 ),
1597+ set_field (tdata1 , CSR_MCONTROL6_HIT1 , 1 ),
1598+ set_field (tdata1 , CSR_MCONTROL6_HIT0 , 1 ) | field_value (CSR_MCONTROL6_HIT1 , 1 )
1599+ };
1600+ riscv_reg_t tdata1_test_rb ;
1601+ for (uint64_t i = 0 ; i < ARRAY_SIZE (tdata1_tests ); ++ i ) {
1602+ if (riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_tests [i ]) != ERROR_OK )
1603+ return M6_HIT_ERROR ;
1604+ if (riscv_reg_get (target , & tdata1_test_rb , GDB_REGNO_TDATA1 ) != ERROR_OK )
1605+ return M6_HIT_ERROR ;
1606+ if (tdata1_test_rb == tdata1_tests [i ]) {
1607+ if (riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_test_rb & ~hit_mask ) != ERROR_OK )
1608+ return M6_HIT_ERROR ;
1609+ return M6_NOT_HIT ;
1610+ }
1611+ }
1612+ }
1613+ return M6_HIT_NOT_SUPPORTED ;
1614+ }
1615+
15641616/**
15651617 * Look at the trigger hit bits to find out which trigger is the reason we're
15661618 * halted. Sets *unique_id to the unique ID of that trigger. If *unique_id is
15671619 * RISCV_TRIGGER_HIT_NOT_FOUND, no match was found.
15681620 */
15691621
1570- static int riscv_trigger_detect_hit_bits (struct target * target , int64_t * unique_id )
1622+ static int riscv_trigger_detect_hit_bits (struct target * target , int64_t * unique_id ,
1623+ bool * need_single_step )
15711624{
15721625 /* FIXME: this function assumes that we have only one trigger that can
15731626 * have hit bit set. Debug spec allows hit bit to bit set if a trigger has
15741627 * matched but did not fire. Such targets will receive erroneous results.
15751628 */
15761629
1577- // FIXME: Add hit bits support detection and caching
15781630 RISCV_INFO (r );
1631+ assert (need_single_step );
1632+ * need_single_step = false;
15791633
15801634 riscv_reg_t tselect ;
15811635 if (riscv_reg_get (target , & tselect , GDB_REGNO_TSELECT ) != ERROR_OK )
@@ -1601,9 +1655,21 @@ static int riscv_trigger_detect_hit_bits(struct target *target, int64_t *unique_
16011655 break ;
16021656 case CSR_TDATA1_TYPE_MCONTROL :
16031657 hit_mask = CSR_MCONTROL_HIT ;
1658+ * need_single_step = true;
16041659 break ;
16051660 case CSR_TDATA1_TYPE_MCONTROL6 :
16061661 hit_mask = CSR_MCONTROL6_HIT0 | CSR_MCONTROL6_HIT1 ;
1662+ if (r -> tinfo_version == CSR_TINFO_VERSION_0 ) {
1663+ * need_single_step = true;
1664+ } else if (r -> tinfo_version == RISCV_TINFO_VERSION_UNKNOWN
1665+ || r -> tinfo_version == CSR_TINFO_VERSION_1 ) {
1666+ mctrl6hitstatus hits_status = check_mcontrol6_hit_status (target ,
1667+ tdata1 , hit_mask );
1668+ if (hits_status == M6_HIT_ERROR )
1669+ return ERROR_FAIL ;
1670+ if (hits_status == M6_HIT_BEFORE || hits_status == M6_HIT_NOT_SUPPORTED )
1671+ * need_single_step = true;
1672+ }
16071673 break ;
16081674 case CSR_TDATA1_TYPE_ICOUNT :
16091675 hit_mask = CSR_ICOUNT_HIT ;
@@ -1622,8 +1688,9 @@ static int riscv_trigger_detect_hit_bits(struct target *target, int64_t *unique_
16221688 /* FIXME: this logic needs to be changed to ignore triggers that are not
16231689 * the last one in the chain. */
16241690 if (tdata1 & hit_mask ) {
1625- LOG_TARGET_DEBUG (target , "Trigger %u (unique_id=%" PRIi64 ") has hit bit set." ,
1626- i , r -> trigger_unique_id [i ]);
1691+ LOG_TARGET_DEBUG (target , "Trigger %u (unique_id=%" PRIi64
1692+ ") has hit bit set. (need_single_step=%s)" ,
1693+ i , r -> trigger_unique_id [i ], (* need_single_step ) ? "yes" : "no" );
16271694 if (riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1 & ~hit_mask ) != ERROR_OK )
16281695 return ERROR_FAIL ;
16291696
@@ -2285,13 +2352,15 @@ static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_r
22852352{
22862353 RISCV_INFO (r );
22872354 r -> trigger_hit = -1 ;
2355+ r -> need_single_step = false;
22882356 switch (halt_reason ) {
22892357 case RISCV_HALT_EBREAK :
22902358 target -> debug_reason = DBG_REASON_BREAKPOINT ;
22912359 break ;
22922360 case RISCV_HALT_TRIGGER :
22932361 target -> debug_reason = DBG_REASON_UNDEFINED ;
2294- if (riscv_trigger_detect_hit_bits (target , & r -> trigger_hit ) != ERROR_OK )
2362+ if (riscv_trigger_detect_hit_bits (target , & r -> trigger_hit ,
2363+ & r -> need_single_step ) != ERROR_OK )
22952364 return ERROR_FAIL ;
22962365 // FIXME: handle multiple hit bits
22972366 if (r -> trigger_hit != RISCV_TRIGGER_HIT_NOT_FOUND ) {
@@ -2553,10 +2622,19 @@ static int resume_prep(struct target *target, int current,
25532622 if (handle_breakpoints ) {
25542623 /* To be able to run off a trigger, we perform a step operation and then
25552624 * resume. If handle_breakpoints is true then step temporarily disables
2556- * pending breakpoints so we can safely perform the step. */
2557- if (old_or_new_riscv_step_impl (target , current , address , handle_breakpoints ,
2558- false /* callbacks are not called */ ) != ERROR_OK )
2559- return ERROR_FAIL ;
2625+ * pending breakpoints so we can safely perform the step.
2626+ *
2627+ * Two cases where single step is needed before resuming:
2628+ * 1. ebreak used in software breakpoint;
2629+ * 2. a trigger that is taken just before the instruction that triggered it is retired.
2630+ */
2631+ if (target -> debug_reason == DBG_REASON_BREAKPOINT
2632+ || (target -> debug_reason == DBG_REASON_WATCHPOINT
2633+ && r -> need_single_step )) {
2634+ if (old_or_new_riscv_step_impl (target , current , address , handle_breakpoints ,
2635+ false /* callbacks are not called */ ) != ERROR_OK )
2636+ return ERROR_FAIL ;
2637+ }
25602638 }
25612639
25622640 if (r -> get_hart_state ) {
@@ -5782,6 +5860,19 @@ int riscv_enumerate_triggers(struct target *target)
57825860 return ERROR_OK ;
57835861 }
57845862
5863+ /* Obtaining tinfo.version value once.
5864+ * No need to enumerate per-trigger.
5865+ * See https://github.com/riscv/riscv-debug-spec/pull/1081.
5866+ */
5867+ riscv_reg_t tinfo ;
5868+ if (riscv_reg_get (target , & tinfo , GDB_REGNO_TINFO ) == ERROR_OK ) {
5869+ r -> tinfo_version = get_field (tinfo , CSR_TINFO_VERSION );
5870+ LOG_TARGET_DEBUG (target , "Trigger tinfo.version = %d." , r -> tinfo_version );
5871+ } else {
5872+ r -> tinfo_version = RISCV_TINFO_VERSION_UNKNOWN ;
5873+ LOG_TARGET_DEBUG (target , "Trigger tinfo.version is unknown." );
5874+ }
5875+
57855876 unsigned int t = 0 ;
57865877 for (; t < ARRAY_SIZE (r -> trigger_tinfo ); ++ t ) {
57875878 result = check_if_trigger_exists (target , t );
0 commit comments