@@ -294,6 +294,10 @@ static enum riscv_halt_reason riscv_halt_reason(struct target *target);
294
294
static void riscv_info_init (struct target * target , struct riscv_info * r );
295
295
static int riscv_step_rtos_hart (struct target * target );
296
296
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
+
297
301
static void riscv_sample_buf_maybe_add_timestamp (struct target * target , bool before )
298
302
{
299
303
RISCV_INFO (r );
@@ -3649,9 +3653,8 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
3649
3653
}
3650
3654
3651
3655
/* 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 )
3655
3658
return ERROR_FAIL ;
3656
3659
3657
3660
/* Run algorithm */
@@ -4231,14 +4234,12 @@ static int riscv_openocd_step_impl(struct target *target, bool current,
4231
4234
}
4232
4235
4233
4236
bool success = true;
4234
- uint64_t current_mstatus ;
4237
+ riscv_reg_t current_mstatus ;
4235
4238
RISCV_INFO (info );
4236
4239
4237
4240
if (info -> isrmask_mode == RISCV_ISRMASK_STEPONLY ) {
4238
4241
/* 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 ) {
4242
4243
success = false;
4243
4244
LOG_TARGET_ERROR (target , "Unable to disable interrupts." );
4244
4245
goto _exit ;
@@ -6005,50 +6006,35 @@ static int riscv_resume_go_all_harts(struct target *target)
6005
6006
return ERROR_OK ;
6006
6007
}
6007
6008
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 )
6009
6010
{
6010
6011
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 ;
6016
6017
}
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
-
6032
6018
if (old_mstatus )
6033
6019
* old_mstatus = current_mstatus ;
6034
-
6035
- return ERROR_OK ;
6020
+ return riscv_reg_set (target , GDB_REGNO_MSTATUS , current_mstatus & ~mstatus_ie_mask );
6036
6021
}
6037
6022
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 )
6039
6024
{
6040
6025
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 ;
6046
6031
}
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 ));
6052
6038
}
6053
6039
6054
6040
static int riscv_step_rtos_hart (struct target * target )
0 commit comments