@@ -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 );
@@ -3645,9 +3649,8 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
3645
3649
}
3646
3650
3647
3651
/* Disable Interrupts before attempting to run the algorithm. */
3648
- uint64_t current_mstatus ;
3649
- uint64_t irq_disabled_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE ;
3650
- if (riscv_interrupts_disable (target , irq_disabled_mask , & current_mstatus ) != ERROR_OK )
3652
+ riscv_reg_t current_mstatus ;
3653
+ if (riscv_interrupts_disable (target , & current_mstatus ) != ERROR_OK )
3651
3654
return ERROR_FAIL ;
3652
3655
3653
3656
/* Run algorithm */
@@ -4227,14 +4230,12 @@ static int riscv_openocd_step_impl(struct target *target, int current,
4227
4230
}
4228
4231
4229
4232
bool success = true;
4230
- uint64_t current_mstatus ;
4233
+ riscv_reg_t current_mstatus ;
4231
4234
RISCV_INFO (info );
4232
4235
4233
4236
if (info -> isrmask_mode == RISCV_ISRMASK_STEPONLY ) {
4234
4237
/* Disable Interrupts before stepping. */
4235
- uint64_t irq_disabled_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE ;
4236
- if (riscv_interrupts_disable (target , irq_disabled_mask ,
4237
- & current_mstatus ) != ERROR_OK ) {
4238
+ if (riscv_interrupts_disable (target , & current_mstatus ) != ERROR_OK ) {
4238
4239
success = false;
4239
4240
LOG_TARGET_ERROR (target , "Unable to disable interrupts." );
4240
4241
goto _exit ;
@@ -6001,50 +6002,35 @@ static int riscv_resume_go_all_harts(struct target *target)
6001
6002
return ERROR_OK ;
6002
6003
}
6003
6004
6004
- int riscv_interrupts_disable (struct target * target , uint64_t irq_mask , uint64_t * old_mstatus )
6005
+ static int riscv_interrupts_disable (struct target * target , riscv_reg_t * old_mstatus )
6005
6006
{
6006
6007
LOG_TARGET_DEBUG (target , "Disabling interrupts." );
6007
- struct reg * reg_mstatus = register_get_by_name ( target -> reg_cache ,
6008
- "mstatus" , true );
6009
- if (! reg_mstatus ) {
6010
- LOG_TARGET_ERROR (target , "Couldn't find mstatus!" );
6011
- return ERROR_FAIL ;
6008
+ riscv_reg_t current_mstatus ;
6009
+ int ret = riscv_reg_get ( target , & current_mstatus , GDB_REGNO_MSTATUS );
6010
+ if (ret != ERROR_OK ) {
6011
+ LOG_TARGET_ERROR (target , "Failed to read mstatus!" );
6012
+ return ret ;
6012
6013
}
6013
-
6014
- int retval = reg_mstatus -> type -> get (reg_mstatus );
6015
- if (retval != ERROR_OK )
6016
- return retval ;
6017
-
6018
- RISCV_INFO (info );
6019
- uint8_t mstatus_bytes [8 ] = { 0 };
6020
- uint64_t current_mstatus = buf_get_u64 (reg_mstatus -> value , 0 , reg_mstatus -> size );
6021
- buf_set_u64 (mstatus_bytes , 0 , info -> xlen , set_field (current_mstatus ,
6022
- irq_mask , 0 ));
6023
-
6024
- retval = reg_mstatus -> type -> set (reg_mstatus , mstatus_bytes );
6025
- if (retval != ERROR_OK )
6026
- return retval ;
6027
-
6028
6014
if (old_mstatus )
6029
6015
* old_mstatus = current_mstatus ;
6030
-
6031
- return ERROR_OK ;
6016
+ return riscv_reg_set (target , GDB_REGNO_MSTATUS , current_mstatus & ~mstatus_ie_mask );
6032
6017
}
6033
6018
6034
- int riscv_interrupts_restore (struct target * target , uint64_t old_mstatus )
6019
+ static int riscv_interrupts_restore (struct target * target , riscv_reg_t old_mstatus )
6035
6020
{
6036
6021
LOG_TARGET_DEBUG (target , "Restoring interrupts." );
6037
- struct reg * reg_mstatus = register_get_by_name ( target -> reg_cache ,
6038
- "mstatus" , true );
6039
- if (! reg_mstatus ) {
6040
- LOG_TARGET_ERROR (target , "Couldn't find mstatus!" );
6041
- return ERROR_FAIL ;
6022
+ riscv_reg_t current_mstatus ;
6023
+ int ret = riscv_reg_get ( target , & current_mstatus , GDB_REGNO_MSTATUS );
6024
+ if (ret != ERROR_OK ) {
6025
+ LOG_TARGET_ERROR (target , "Failed to read mstatus!" );
6026
+ return ret ;
6042
6027
}
6043
-
6044
- RISCV_INFO (info );
6045
- uint8_t mstatus_bytes [8 ];
6046
- buf_set_u64 (mstatus_bytes , 0 , info -> xlen , old_mstatus );
6047
- return reg_mstatus -> type -> set (reg_mstatus , mstatus_bytes );
6028
+ if ((current_mstatus & mstatus_ie_mask ) != 0 ) {
6029
+ LOG_TARGET_WARNING (target , "Interrupt enable bits in mstatus changed during single-step." );
6030
+ LOG_TARGET_WARNING (target , "OpenOCD might have affected the program when it restored the interrupt bits after single-step." );
6031
+ LOG_TARGET_WARNING (target , "Hint: Use 'riscv set_maskisr off' to prevent OpenOCD from touching mstatus during single-step." );
6032
+ }
6033
+ return riscv_reg_set (target , GDB_REGNO_MSTATUS , current_mstatus | (old_mstatus & mstatus_ie_mask ));
6048
6034
}
6049
6035
6050
6036
static int riscv_step_rtos_hart (struct target * target )
0 commit comments