@@ -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 );
@@ -3645,9 +3649,8 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
36453649 }
36463650
36473651 /* 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 )
36513654 return ERROR_FAIL ;
36523655
36533656 /* Run algorithm */
@@ -4227,14 +4230,12 @@ static int riscv_openocd_step_impl(struct target *target, int current,
42274230 }
42284231
42294232 bool success = true;
4230- uint64_t current_mstatus ;
4233+ riscv_reg_t current_mstatus ;
42314234 RISCV_INFO (info );
42324235
42334236 if (info -> isrmask_mode == RISCV_ISRMASK_STEPONLY ) {
42344237 /* 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 ) {
42384239 success = false;
42394240 LOG_TARGET_ERROR (target , "Unable to disable interrupts." );
42404241 goto _exit ;
@@ -6001,50 +6002,35 @@ static int riscv_resume_go_all_harts(struct target *target)
60016002 return ERROR_OK ;
60026003}
60036004
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 )
60056006{
60066007 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 ;
60126013 }
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-
60286014 if (old_mstatus )
60296015 * old_mstatus = current_mstatus ;
6030-
6031- return ERROR_OK ;
6016+ return riscv_reg_set (target , GDB_REGNO_MSTATUS , current_mstatus & ~mstatus_ie_mask );
60326017}
60336018
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 )
60356020{
60366021 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 ;
60426027 }
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 ));
60486034}
60496035
60506036static int riscv_step_rtos_hart (struct target * target )
0 commit comments