@@ -919,19 +919,21 @@ void ExceptionReturn(uc_engine *uc, uint32_t ret_pc) {
919919 // We are coming from Handler Mode (which always uses SP_main) and
920920 // return to Thread Mode which uses SP_process. Switch to SP_process
921921 uint32_t new_SPSEL_now_psp = 1 ;
922- uint32_t SP_process , SP_main ;
923- uc_reg_read (uc , UC_ARM_REG_SP , & SP_main );
924- uc_reg_read (uc , UC_ARM_REG_OTHER_SP , & SP_process );
925-
926- // Back up SP_main
927- uc_reg_write (uc , UC_ARM_REG_OTHER_SP , & SP_main );
928- uc_reg_write (uc , UC_ARM_REG_SP , & SP_process );
929-
930- // Switch the CPU state to indicate the new SPSEL state
931- // 1. In pstate register
932- uc_reg_write (uc , UC_ARM_REG_SPSEL , & new_SPSEL_now_psp );
933- // 2. In cached spsel field
934- uc_reg_write (uc , UC_ARM_REG_CURR_SP_MODE_IS_PSP , & new_SPSEL_now_psp );
922+ uint32_t SP_control ;
923+ // Get SP_control. If control[1]=1, then we are in SP_process; Else, we are in SP_MSP.
924+ uc_reg_read (uc , UC_ARM_REG_CONTROL , & SP_control );
925+ if (SP_control & 0x2 != 0x2 ){
926+ // When in SP_process, Back up SP_main
927+ // set Control[1]=1;
928+ SP_control ^= 0x2 ;
929+ uc_reg_write (uc , UC_ARM_REG_CONTROL , & SP_control );
930+
931+ // Switch the CPU state to indicate the new SPSEL state
932+ // 1. In pstate register
933+ uc_reg_write (uc , UC_ARM_REG_SPSEL , & new_SPSEL_now_psp );
934+ // 2. In cached spsel field
935+ uc_reg_write (uc , UC_ARM_REG_CURR_SP_MODE_IS_PSP , & new_SPSEL_now_psp );
936+ }
935937 }
936938 }
937939
@@ -1035,16 +1037,14 @@ static void ExceptionEntry(uc_engine *uc, bool is_tail_chained, bool skip_instru
10351037 // We are coming from Thread mode in case we are not tail-chained and had no previously active IRQ
10361038 new_lr |= NVIC_INTERRUPT_ENTRY_LR_THREADMODE_FLAG ;
10371039
1038- if (GET_CURR_SP_MODE_IS_PSP ()) {
1039- // We are coming from Thread Mode which uses SP_process. Switch it to SP_main
1040+ uint32_t SP_control ;
1041+ uc_reg_read (uc , UC_ARM_REG_CONTROL , & SP_control );
1042+ if (SP_control & 0x2 == 0x2 ){
1043+ // We are coming from Thread Mode which uses SP_process. Switch it to SP_main
10401044 uint32_t new_SPSEL_not_psp = 0 ;
1041- uint32_t SP_process , SP_main ;
1042- uc_reg_read (uc , UC_ARM_REG_SP , & SP_process );
1043- uc_reg_read (uc , UC_ARM_REG_OTHER_SP , & SP_main );
1044-
1045- // Back up SP_process
1046- uc_reg_write (uc , UC_ARM_REG_OTHER_SP , & SP_process );
1047- uc_reg_write (uc , UC_ARM_REG_SP , & SP_main );
1045+ // set Control[1]=0;
1046+ SP_control ^= 0x2 ;
1047+ uc_reg_write (uc , UC_ARM_REG_CONTROL , & SP_control );
10481048
10491049 // Switch the CPU state to indicate the new SPSEL state
10501050 // 1. In pstate register
0 commit comments