@@ -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 )
@@ -1561,6 +1561,59 @@ int riscv_remove_watchpoint(struct target *target,
1561
1561
return ERROR_OK ;
1562
1562
}
1563
1563
1564
+ static bool mcontrol_hit_supported (struct target * target , riscv_reg_t tdata1 ,
1565
+ uint64_t hit_mask )
1566
+ {
1567
+ /* Check if mcontrol.hit is implemented */
1568
+ bool local_mcontrol_hit_not_supported = false;
1569
+ const riscv_reg_t tdata1_test = set_field (tdata1 , CSR_MCONTROL_HIT , 1 );
1570
+ riscv_reg_t tdata1_test_rb ;
1571
+ riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_test );
1572
+ riscv_reg_get (target , & tdata1_test_rb , GDB_REGNO_TDATA1 );
1573
+ int tdata1_test_hit = get_field (tdata1_test , CSR_MCONTROL_HIT );
1574
+ int tdata1_test_rb_hit = get_field (tdata1_test_rb , CSR_MCONTROL_HIT );
1575
+ if (tdata1_test_hit != tdata1_test_rb_hit ) {
1576
+ local_mcontrol_hit_not_supported = true;
1577
+ } else {
1578
+ /* mcontrol.hit is implemented, but not fired. */
1579
+ riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_test & ~hit_mask );
1580
+ }
1581
+ return local_mcontrol_hit_not_supported ;
1582
+ }
1583
+
1584
+ static bool mcontrol6_hit_supported (struct target * target , riscv_reg_t tdata1 ,
1585
+ uint64_t hit_mask , int trigger_hit_info )
1586
+ {
1587
+ bool local_mcontrol6_hit_not_supported = false;
1588
+ /* Check if mcontrol6.hit0[1] is implemented. */
1589
+ riscv_reg_t tdata1_hit0_test , tdata1_hit1_test , tdata1_test_rb ;
1590
+ tdata1_hit0_test = set_field (tdata1 , CSR_MCONTROL6_HIT0 , 1 );
1591
+ tdata1_hit1_test = set_field (tdata1 , CSR_MCONTROL6_HIT1 , 1 );
1592
+
1593
+ /* Check timing "before" support. */
1594
+ riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_hit0_test );
1595
+ riscv_reg_get (target , & tdata1_test_rb , GDB_REGNO_TDATA1 );
1596
+ if (tdata1_test_rb != tdata1_hit0_test ) {
1597
+ local_mcontrol6_hit_not_supported = true;
1598
+ } else {
1599
+ riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_test_rb & ~hit_mask );
1600
+ goto done ;
1601
+ }
1602
+
1603
+ /* Check timing "after" support. */
1604
+ riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_hit1_test );
1605
+ riscv_reg_get (target , & tdata1_test_rb , GDB_REGNO_TDATA1 );
1606
+ if (tdata1_test_rb != tdata1_hit1_test ) {
1607
+ local_mcontrol6_hit_not_supported = true;
1608
+ } else {
1609
+ local_mcontrol6_hit_not_supported = false;
1610
+ riscv_reg_set (target , GDB_REGNO_TDATA1 , tdata1_test_rb & ~hit_mask );
1611
+ }
1612
+ /* Ignore checking timing "imm after" support. */
1613
+ done :
1614
+ return local_mcontrol6_hit_not_supported ;
1615
+ }
1616
+
1564
1617
/**
1565
1618
* Look at the trigger hit bits to find out which trigger is the reason we're
1566
1619
* halted. Sets *unique_id to the unique ID of that trigger. If *unique_id is
@@ -1576,6 +1629,7 @@ static int riscv_trigger_detect_hit_bits(struct target *target, int64_t *unique_
1576
1629
1577
1630
// FIXME: Add hit bits support detection and caching
1578
1631
RISCV_INFO (r );
1632
+ r -> need_single_step = false;
1579
1633
1580
1634
riscv_reg_t tselect ;
1581
1635
if (riscv_reg_get (target , & tselect , GDB_REGNO_TSELECT ) != ERROR_OK )
@@ -1601,9 +1655,26 @@ static int riscv_trigger_detect_hit_bits(struct target *target, int64_t *unique_
1601
1655
break ;
1602
1656
case CSR_TDATA1_TYPE_MCONTROL :
1603
1657
hit_mask = CSR_MCONTROL_HIT ;
1658
+ bool mcontrol_hit_not_supported = false;
1659
+ if ((tdata1 & hit_mask ) == 0 )
1660
+ mcontrol_hit_not_supported = mcontrol_hit_supported (target , tdata1 , hit_mask );
1661
+ if (get_field (tdata1 , CSR_MCONTROL_TIMING ) == CSR_MCONTROL_TIMING_BEFORE
1662
+ && (mcontrol_hit_not_supported || (tdata1 & hit_mask )))
1663
+ r -> need_single_step = true;
1604
1664
break ;
1605
1665
case CSR_TDATA1_TYPE_MCONTROL6 :
1606
1666
hit_mask = CSR_MCONTROL6_HIT0 | CSR_MCONTROL6_HIT1 ;
1667
+ bool mcontrol6_hit_not_supported = false;
1668
+ int hit0 = get_field (tdata1 , CSR_MCONTROL6_HIT0 );
1669
+ int hit1 = get_field (tdata1 , CSR_MCONTROL6_HIT1 );
1670
+ int trigger_hit_info = (hit1 << 1 ) | hit0 ;
1671
+ if (trigger_hit_info == CSR_MCONTROL6_HIT0_FALSE ) {
1672
+ mcontrol6_hit_not_supported = mcontrol6_hit_supported (target , tdata1 ,
1673
+ hit_mask , trigger_hit_info );
1674
+ }
1675
+ if (mcontrol6_hit_not_supported
1676
+ || trigger_hit_info == CSR_MCONTROL6_HIT0_BEFORE )
1677
+ r -> need_single_step = true;
1607
1678
break ;
1608
1679
case CSR_TDATA1_TYPE_ICOUNT :
1609
1680
hit_mask = CSR_ICOUNT_HIT ;
@@ -2553,10 +2624,19 @@ static int resume_prep(struct target *target, int current,
2553
2624
if (handle_breakpoints ) {
2554
2625
/* To be able to run off a trigger, we perform a step operation and then
2555
2626
* 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 ;
2627
+ * pending breakpoints so we can safely perform the step.
2628
+ *
2629
+ * Two cases where single step is needed before resuming:
2630
+ * 1. ebreak used in software breakpoint;
2631
+ * 2. a trigger that is taken just before the instruction that triggered it is retired.
2632
+ */
2633
+ if (target -> debug_reason == DBG_REASON_BREAKPOINT
2634
+ || (target -> debug_reason == DBG_REASON_WATCHPOINT
2635
+ && r -> need_single_step )) {
2636
+ if (old_or_new_riscv_step_impl (target , current , address , handle_breakpoints ,
2637
+ false /* callbacks are not called */ ) != ERROR_OK )
2638
+ return ERROR_FAIL ;
2639
+ }
2560
2640
}
2561
2641
2562
2642
if (r -> get_hart_state ) {
0 commit comments