@@ -623,12 +623,12 @@ static int find_first_trigger_by_id(struct target *target, int unique_id)
623
623
624
624
static unsigned int count_trailing_ones (riscv_reg_t reg )
625
625
{
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 ++ ) {
628
628
if ((1 & (reg >> i )) == 0 )
629
629
return i ;
630
630
}
631
- return 64 ;
631
+ return riscv_reg_bits ;
632
632
}
633
633
634
634
static int set_trigger (struct target * target , unsigned int idx , riscv_reg_t tdata1 , riscv_reg_t tdata2 )
@@ -1576,6 +1576,7 @@ static int riscv_trigger_detect_hit_bits(struct target *target, int64_t *unique_
1576
1576
1577
1577
// FIXME: Add hit bits support detection and caching
1578
1578
RISCV_INFO (r );
1579
+ r -> need_single_step = false;
1579
1580
1580
1581
riscv_reg_t tselect ;
1581
1582
if (riscv_reg_get (target , & tselect , GDB_REGNO_TSELECT ) != ERROR_OK )
@@ -1589,21 +1590,100 @@ static int riscv_trigger_detect_hit_bits(struct target *target, int64_t *unique_
1589
1590
if (riscv_reg_set (target , GDB_REGNO_TSELECT , i ) != ERROR_OK )
1590
1591
return ERROR_FAIL ;
1591
1592
1592
- uint64_t tdata1 ;
1593
+ uint64_t tdata1 , tdata1_test_rb ;
1593
1594
if (riscv_reg_get (target , & tdata1 , GDB_REGNO_TDATA1 ) != ERROR_OK )
1594
1595
return ERROR_FAIL ;
1595
1596
int type = get_field (tdata1 , CSR_TDATA1_TYPE (riscv_xlen (target )));
1596
1597
1597
1598
uint64_t hit_mask = 0 ;
1599
+ bool mcontrol_hit_not_supported = false;
1600
+ bool mcontrol6_hit_not_supported = false;
1598
1601
switch (type ) {
1599
1602
case CSR_TDATA1_TYPE_LEGACY :
1600
1603
/* Doesn't support hit bit. */
1601
1604
break ;
1602
1605
case CSR_TDATA1_TYPE_MCONTROL :
1603
1606
hit_mask = CSR_MCONTROL_HIT ;
1607
+ /* Check if mcontrol.hit is implemented */
1608
+ if ((tdata1 & hit_mask ) == 0 ) {
1609
+ uint64_t tdata1_test =
1610
+ set_field (tdata1 , CSR_MCONTROL_HIT , 1 );
1611
+ if (riscv_reg_set (target ,
1612
+ GDB_REGNO_TDATA1 , tdata1_test ) != ERROR_OK )
1613
+ return ERROR_FAIL ;
1614
+ if (riscv_reg_get (target ,
1615
+ & tdata1_test_rb , GDB_REGNO_TDATA1 ) != ERROR_OK )
1616
+ return ERROR_FAIL ;
1617
+ int tdata1_test_hit =
1618
+ get_field (tdata1_test , CSR_MCONTROL_HIT );
1619
+ int tdata1_test_rb_hit =
1620
+ get_field (tdata1_test_rb , CSR_MCONTROL_HIT );
1621
+ if (tdata1_test_hit != tdata1_test_rb_hit )
1622
+ mcontrol_hit_not_supported = true;
1623
+ if (riscv_reg_set (target , GDB_REGNO_TDATA1 ,
1624
+ tdata1_test & ~hit_mask ) != ERROR_OK )
1625
+ return ERROR_FAIL ;
1626
+ }
1627
+
1628
+ if (get_field (tdata1 , CSR_MCONTROL_TIMING )
1629
+ == CSR_MCONTROL_TIMING_BEFORE
1630
+ && (mcontrol_hit_not_supported || (tdata1 & hit_mask )))
1631
+ r -> need_single_step = true;
1604
1632
break ;
1605
1633
case CSR_TDATA1_TYPE_MCONTROL6 :
1606
1634
hit_mask = CSR_MCONTROL6_HIT0 | CSR_MCONTROL6_HIT1 ;
1635
+ int hit0 = get_field (tdata1 , CSR_MCONTROL6_HIT0 );
1636
+ int hit1 = get_field (tdata1 , CSR_MCONTROL6_HIT1 );
1637
+ int trigger_retired_info = (hit1 << 1 ) | hit0 ;
1638
+ /* Check if mcontrol6.hit0[1] is not implemented. */
1639
+ if (trigger_retired_info == 0 ) {
1640
+ for (unsigned int j = 0 ; j < 2 ; j ++ ) {
1641
+ uint64_t tdata1_test =
1642
+ set_field (tdata1 , CSR_MCONTROL6_HIT0 , j );
1643
+ for (unsigned int k = 0 ; k < 2 ; k ++ ) {
1644
+ tdata1_test =
1645
+ set_field (tdata1_test , CSR_MCONTROL6_HIT1 , k );
1646
+ if (riscv_reg_set (target ,
1647
+ GDB_REGNO_TDATA1 , tdata1_test ) != ERROR_OK )
1648
+ return ERROR_FAIL ;
1649
+ if (riscv_reg_get (target ,
1650
+ & tdata1_test_rb , GDB_REGNO_TDATA1 ) != ERROR_OK )
1651
+ return ERROR_FAIL ;
1652
+ int tdata1_test_hit0 =
1653
+ get_field (tdata1_test , CSR_MCONTROL6_HIT0 );
1654
+ int tdata1_test_rb_hit0 =
1655
+ get_field (tdata1_test_rb , CSR_MCONTROL6_HIT0 );
1656
+ int tdata1_test_hit1 =
1657
+ get_field (tdata1_test , CSR_MCONTROL6_HIT1 );
1658
+ int tdata1_test_rb_hit1 =
1659
+ get_field (tdata1_test_rb , CSR_MCONTROL6_HIT1 );
1660
+ int trigger_retired_test_info =
1661
+ (tdata1_test_hit1 << 1 ) | tdata1_test_hit0 ;
1662
+ int trigger_retired_test_rb_info =
1663
+ (tdata1_test_rb_hit1 << 1 ) | tdata1_test_rb_hit0 ;
1664
+ if (trigger_retired_test_info == 0 )
1665
+ continue ;
1666
+
1667
+ if (trigger_retired_test_info
1668
+ != trigger_retired_test_rb_info ) {
1669
+ mcontrol6_hit_not_supported = true;
1670
+ } else {
1671
+ mcontrol6_hit_not_supported = false;
1672
+ if (riscv_reg_set (target , GDB_REGNO_TDATA1 ,
1673
+ tdata1_test & ~hit_mask ) != ERROR_OK )
1674
+ return ERROR_FAIL ;
1675
+ goto done ;
1676
+ }
1677
+ }
1678
+ if (riscv_reg_set (target , GDB_REGNO_TDATA1 ,
1679
+ tdata1_test & ~hit_mask ) != ERROR_OK )
1680
+ return ERROR_FAIL ;
1681
+ }
1682
+ }
1683
+ done :
1684
+ if (mcontrol6_hit_not_supported
1685
+ || trigger_retired_info == CSR_MCONTROL6_HIT0_BEFORE )
1686
+ r -> need_single_step = true;
1607
1687
break ;
1608
1688
case CSR_TDATA1_TYPE_ICOUNT :
1609
1689
hit_mask = CSR_ICOUNT_HIT ;
@@ -2553,10 +2633,19 @@ static int resume_prep(struct target *target, int current,
2553
2633
if (handle_breakpoints ) {
2554
2634
/* To be able to run off a trigger, we perform a step operation and then
2555
2635
* 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 ;
2636
+ * pending breakpoints so we can safely perform the step.
2637
+ *
2638
+ * Two cases where single step is needed before resuming:
2639
+ * 1. ebreak used in software breakpoint;
2640
+ * 2. a trigger that is taken just before the instruction that triggered it is retired.
2641
+ */
2642
+ if (target -> debug_reason == DBG_REASON_BREAKPOINT
2643
+ || (target -> debug_reason == DBG_REASON_WATCHPOINT
2644
+ && r -> need_single_step )) {
2645
+ if (old_or_new_riscv_step_impl (target , current , address , handle_breakpoints ,
2646
+ false /* callbacks are not called */ ) != ERROR_OK )
2647
+ return ERROR_FAIL ;
2648
+ }
2560
2649
}
2561
2650
2562
2651
if (r -> get_hart_state ) {
0 commit comments