@@ -919,19 +919,21 @@ void ExceptionReturn(uc_engine *uc, uint32_t ret_pc) {
919
919
// We are coming from Handler Mode (which always uses SP_main) and
920
920
// return to Thread Mode which uses SP_process. Switch to SP_process
921
921
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
+ }
935
937
}
936
938
}
937
939
@@ -1035,16 +1037,14 @@ static void ExceptionEntry(uc_engine *uc, bool is_tail_chained, bool skip_instru
1035
1037
// We are coming from Thread mode in case we are not tail-chained and had no previously active IRQ
1036
1038
new_lr |= NVIC_INTERRUPT_ENTRY_LR_THREADMODE_FLAG ;
1037
1039
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
1040
1044
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 );
1048
1048
1049
1049
// Switch the CPU state to indicate the new SPSEL state
1050
1050
// 1. In pstate register
0 commit comments