@@ -294,6 +294,10 @@ static enum riscv_halt_reason riscv_halt_reason(struct target *target);
294294static void riscv_info_init (struct target * target , struct riscv_info * r );
295295static int riscv_step_rtos_hart (struct target * target );
296296
297+ static const riscv_reg_t mstatus_ie_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE ;
298+ static int riscv_interrupts_disable (struct target * target , riscv_reg_t * old_mstatus );
299+ static int riscv_interrupts_restore (struct target * target , riscv_reg_t old_mstatus );
300+
297301static void riscv_sample_buf_maybe_add_timestamp (struct target * target , bool before )
298302{
299303 RISCV_INFO (r );
@@ -3649,9 +3653,8 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
36493653 }
36503654
36513655 /* Disable Interrupts before attempting to run the algorithm. */
3652- uint64_t current_mstatus ;
3653- uint64_t irq_disabled_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE ;
3654- if (riscv_interrupts_disable (target , irq_disabled_mask , & current_mstatus ) != ERROR_OK )
3656+ riscv_reg_t current_mstatus ;
3657+ if (riscv_interrupts_disable (target , & current_mstatus ) != ERROR_OK )
36553658 return ERROR_FAIL ;
36563659
36573660 /* Run algorithm */
@@ -4231,14 +4234,12 @@ static int riscv_openocd_step_impl(struct target *target, bool current,
42314234 }
42324235
42334236 bool success = true;
4234- uint64_t current_mstatus ;
4237+ riscv_reg_t current_mstatus ;
42354238 RISCV_INFO (info );
42364239
42374240 if (info -> isrmask_mode == RISCV_ISRMASK_STEPONLY ) {
42384241 /* Disable Interrupts before stepping. */
4239- uint64_t irq_disabled_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE ;
4240- if (riscv_interrupts_disable (target , irq_disabled_mask ,
4241- & current_mstatus ) != ERROR_OK ) {
4242+ if (riscv_interrupts_disable (target , & current_mstatus ) != ERROR_OK ) {
42424243 success = false;
42434244 LOG_TARGET_ERROR (target , "Unable to disable interrupts." );
42444245 goto _exit ;
@@ -6005,50 +6006,35 @@ static int riscv_resume_go_all_harts(struct target *target)
60056006 return ERROR_OK ;
60066007}
60076008
6008- int riscv_interrupts_disable (struct target * target , uint64_t irq_mask , uint64_t * old_mstatus )
6009+ static int riscv_interrupts_disable (struct target * target , riscv_reg_t * old_mstatus )
60096010{
60106011 LOG_TARGET_DEBUG (target , "Disabling interrupts." );
6011- struct reg * reg_mstatus = register_get_by_name ( target -> reg_cache ,
6012- "mstatus" , true );
6013- if (! reg_mstatus ) {
6014- LOG_TARGET_ERROR (target , "Couldn't find mstatus!" );
6015- return ERROR_FAIL ;
6012+ riscv_reg_t current_mstatus ;
6013+ int ret = riscv_reg_get ( target , & current_mstatus , GDB_REGNO_MSTATUS );
6014+ if (ret != ERROR_OK ) {
6015+ LOG_TARGET_ERROR (target , "Failed to read mstatus!" );
6016+ return ret ;
60166017 }
6017-
6018- int retval = reg_mstatus -> type -> get (reg_mstatus );
6019- if (retval != ERROR_OK )
6020- return retval ;
6021-
6022- RISCV_INFO (info );
6023- uint8_t mstatus_bytes [8 ] = { 0 };
6024- uint64_t current_mstatus = buf_get_u64 (reg_mstatus -> value , 0 , reg_mstatus -> size );
6025- buf_set_u64 (mstatus_bytes , 0 , info -> xlen , set_field (current_mstatus ,
6026- irq_mask , 0 ));
6027-
6028- retval = reg_mstatus -> type -> set (reg_mstatus , mstatus_bytes );
6029- if (retval != ERROR_OK )
6030- return retval ;
6031-
60326018 if (old_mstatus )
60336019 * old_mstatus = current_mstatus ;
6034-
6035- return ERROR_OK ;
6020+ return riscv_reg_set (target , GDB_REGNO_MSTATUS , current_mstatus & ~mstatus_ie_mask );
60366021}
60376022
6038- int riscv_interrupts_restore (struct target * target , uint64_t old_mstatus )
6023+ static int riscv_interrupts_restore (struct target * target , riscv_reg_t old_mstatus )
60396024{
60406025 LOG_TARGET_DEBUG (target , "Restoring interrupts." );
6041- struct reg * reg_mstatus = register_get_by_name ( target -> reg_cache ,
6042- "mstatus" , true );
6043- if (! reg_mstatus ) {
6044- LOG_TARGET_ERROR (target , "Couldn't find mstatus!" );
6045- return ERROR_FAIL ;
6026+ riscv_reg_t current_mstatus ;
6027+ int ret = riscv_reg_get ( target , & current_mstatus , GDB_REGNO_MSTATUS );
6028+ if (ret != ERROR_OK ) {
6029+ LOG_TARGET_ERROR (target , "Failed to read mstatus!" );
6030+ return ret ;
60466031 }
6047-
6048- RISCV_INFO (info );
6049- uint8_t mstatus_bytes [8 ];
6050- buf_set_u64 (mstatus_bytes , 0 , info -> xlen , old_mstatus );
6051- return reg_mstatus -> type -> set (reg_mstatus , mstatus_bytes );
6032+ if ((current_mstatus & mstatus_ie_mask ) != 0 ) {
6033+ LOG_TARGET_WARNING (target , "Interrupt enable bits in mstatus changed during single-step." );
6034+ LOG_TARGET_WARNING (target , "OpenOCD might have affected the program when it restored the interrupt bits after single-step." );
6035+ LOG_TARGET_WARNING (target , "Hint: Use 'riscv set_maskisr off' to prevent OpenOCD from touching mstatus during single-step." );
6036+ }
6037+ return riscv_reg_set (target , GDB_REGNO_MSTATUS , current_mstatus | (old_mstatus & mstatus_ie_mask ));
60526038}
60536039
60546040static int riscv_step_rtos_hart (struct target * target )
0 commit comments