@@ -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 )
@@ -2278,6 +2279,67 @@ derive_debug_reason_without_hitbit(const struct target *target, riscv_reg_t dpc)
2278
2279
}
2279
2280
return DBG_REASON_WATCHPOINT ;
2280
2281
}
2282
+
2283
+ static bool check_single_step_needed_in_hit_supported_case (struct target * target ,
2284
+ uint32_t unique_id )
2285
+ {
2286
+ RISCV_INFO (r );
2287
+ riscv_reg_t tselect ;
2288
+ if (riscv_reg_get (target , & tselect , GDB_REGNO_TSELECT ) != ERROR_OK )
2289
+ return ERROR_FAIL ;
2290
+ if (riscv_reg_set (target , GDB_REGNO_TSELECT , unique_id ) != ERROR_OK )
2291
+ return ERROR_FAIL ;
2292
+ riscv_reg_t tdata1 ;
2293
+ if (riscv_reg_get (target , & tdata1 , GDB_REGNO_TDATA1 ) != ERROR_OK )
2294
+ return ERROR_FAIL ;
2295
+ int type = get_field (tdata1 , CSR_TDATA1_TYPE (riscv_xlen (target )));
2296
+ if (type == CSR_TDATA1_TYPE_MCONTROL ) {
2297
+ if (get_field (tdata1 , CSR_MCONTROL_TIMING ) == CSR_MCONTROL_TIMING_BEFORE )
2298
+ r -> need_single_step = true;
2299
+ } else if (type == CSR_TDATA1_TYPE_MCONTROL6 ) {
2300
+ int hit0 = get_field (tdata1 , CSR_MCONTROL6_HIT0 );
2301
+ int hit1 = get_field (tdata1 , CSR_MCONTROL6_HIT1 );
2302
+ int trigger_retired_info = (hit1 << 1 ) | hit0 ;
2303
+ if (trigger_retired_info == CSR_MCONTROL6_HIT0_BEFORE )
2304
+ r -> need_single_step = true;
2305
+ } else {
2306
+ r -> need_single_step = false;
2307
+ }
2308
+ if (riscv_reg_set (target , GDB_REGNO_TSELECT , tselect ) != ERROR_OK )
2309
+ return ERROR_FAIL ;
2310
+ return r -> need_single_step ;
2311
+ }
2312
+
2313
+ static bool check_single_step_needed_in_hit_unsupported_case (struct target * target )
2314
+ {
2315
+ RISCV_INFO (r );
2316
+ r -> need_single_step = false;
2317
+ riscv_reg_t tselect ;
2318
+ if (riscv_reg_get (target , & tselect , GDB_REGNO_TSELECT ) != ERROR_OK )
2319
+ return ERROR_FAIL ;
2320
+
2321
+ for (unsigned int i = 0 ; i < r -> trigger_count ; i ++ ) {
2322
+ if (riscv_reg_set (target , GDB_REGNO_TSELECT , i ) != ERROR_OK )
2323
+ return ERROR_FAIL ;
2324
+
2325
+ uint64_t tdata1 ;
2326
+ if (riscv_reg_get (target , & tdata1 , GDB_REGNO_TDATA1 ) != ERROR_OK )
2327
+ return ERROR_FAIL ;
2328
+ int type = get_field (tdata1 , CSR_TDATA1_TYPE (riscv_xlen (target )));
2329
+ if (type == CSR_TDATA1_TYPE_MCONTROL ) {
2330
+ if (get_field (tdata1 , CSR_MCONTROL_TIMING ) == CSR_MCONTROL_TIMING_BEFORE )
2331
+ r -> need_single_step = true;
2332
+ } else if (type == CSR_TDATA1_TYPE_MCONTROL6 ) {
2333
+ r -> need_single_step = true;
2334
+ }
2335
+ }
2336
+ if (riscv_reg_set (target , GDB_REGNO_TSELECT , tselect ) != ERROR_OK )
2337
+ return ERROR_FAIL ;
2338
+
2339
+ return r -> need_single_step ;
2340
+ }
2341
+
2342
+
2281
2343
/**
2282
2344
* Set OpenOCD's generic debug reason from the RISC-V halt reason.
2283
2345
*/
@@ -2319,6 +2381,7 @@ static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_r
2319
2381
LOG_TARGET_DEBUG (target ,
2320
2382
"Watchpoint with unique_id = %" PRIu32 " owns the trigger." ,
2321
2383
wp -> unique_id );
2384
+ r -> need_single_step = check_single_step_needed_in_hit_supported_case (target , wp -> unique_id );
2322
2385
}
2323
2386
}
2324
2387
}
@@ -2336,6 +2399,7 @@ static int set_debug_reason(struct target *target, enum riscv_halt_reason halt_r
2336
2399
* breakpoints and hope for the best)
2337
2400
*/
2338
2401
target -> debug_reason = derive_debug_reason_without_hitbit (target , dpc );
2402
+ r -> need_single_step = check_single_step_needed_in_hit_unsupported_case (target );
2339
2403
}
2340
2404
break ;
2341
2405
case RISCV_HALT_INTERRUPT :
@@ -2553,10 +2617,19 @@ static int resume_prep(struct target *target, int current,
2553
2617
if (handle_breakpoints ) {
2554
2618
/* To be able to run off a trigger, we perform a step operation and then
2555
2619
* 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 ;
2620
+ * pending breakpoints so we can safely perform the step.
2621
+ *
2622
+ * Two cases where single step is needed before resuming:
2623
+ * 1. ebreak used in software breakpoint;
2624
+ * 2. a trigger that is taken just before the instruction that triggered it is retired.
2625
+ */
2626
+ if (target -> debug_reason == DBG_REASON_BREAKPOINT
2627
+ || (target -> debug_reason == DBG_REASON_WATCHPOINT
2628
+ && r -> need_single_step )) {
2629
+ if (old_or_new_riscv_step_impl (target , current , address , handle_breakpoints ,
2630
+ false /* callbacks are not called */ ) != ERROR_OK )
2631
+ return ERROR_FAIL ;
2632
+ }
2560
2633
}
2561
2634
2562
2635
if (r -> get_hart_state ) {
0 commit comments