diff options
| author | 2015-02-12 15:11:39 -0500 | |
|---|---|---|
| committer | 2015-02-12 21:54:28 -0500 | |
| commit | b7fac494cdda9efb65168b116b1673af4ab9f242 (patch) | |
| tree | 54eed2ab999ddb5063a5f0b52a72b27c8159cb44 /src/core/arm/dyncom | |
| parent | dyncom: Clean up the constructor (diff) | |
| download | yuzu-b7fac494cdda9efb65168b116b1673af4ab9f242.tar.gz yuzu-b7fac494cdda9efb65168b116b1673af4ab9f242.tar.xz yuzu-b7fac494cdda9efb65168b116b1673af4ab9f242.zip | |
dyncom: Switch the app and system cores into the correct mode at initialization
Diffstat (limited to 'src/core/arm/dyncom')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.cpp | 6 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_run.cpp | 17 |
3 files changed, 15 insertions, 10 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 6a95ede24..bbcbbdd2b 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "core/arm/dyncom/arm_dyncom.h" | 8 | #include "core/arm/dyncom/arm_dyncom.h" |
| 9 | #include "core/arm/dyncom/arm_dyncom_interpreter.h" | 9 | #include "core/arm/dyncom/arm_dyncom_interpreter.h" |
| 10 | #include "core/arm/dyncom/arm_dyncom_run.h" | ||
| 10 | 11 | ||
| 11 | #include "core/core.h" | 12 | #include "core/core.h" |
| 12 | #include "core/core_timing.h" | 13 | #include "core/core_timing.h" |
| @@ -15,7 +16,7 @@ const static cpu_config_t s_arm11_cpu_info = { | |||
| 15 | "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE | 16 | "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | ARM_DynCom::ARM_DynCom() { | 19 | ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { |
| 19 | state = std::unique_ptr<ARMul_State>(new ARMul_State); | 20 | state = std::unique_ptr<ARMul_State>(new ARMul_State); |
| 20 | 21 | ||
| 21 | ARMul_NewState(state.get()); | 22 | ARMul_NewState(state.get()); |
| @@ -33,6 +34,9 @@ ARM_DynCom::ARM_DynCom() { | |||
| 33 | state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext | 34 | state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext |
| 34 | state->Emulate = RUN; | 35 | state->Emulate = RUN; |
| 35 | 36 | ||
| 37 | // Switch to the desired privilege mode. | ||
| 38 | switch_mode(state.get(), initial_mode); | ||
| 39 | |||
| 36 | state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack | 40 | state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack |
| 37 | state->Reg[15] = 0x00000000; | 41 | state->Reg[15] = 0x00000000; |
| 38 | } | 42 | } |
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 9e2dda843..213cac1ad 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | class ARM_DynCom final : virtual public ARM_Interface { | 14 | class ARM_DynCom final : virtual public ARM_Interface { |
| 15 | public: | 15 | public: |
| 16 | ARM_DynCom(); | 16 | ARM_DynCom(PrivilegeMode initial_mode); |
| 17 | ~ARM_DynCom(); | 17 | ~ARM_DynCom(); |
| 18 | 18 | ||
| 19 | void SetPC(u32 pc) override; | 19 | void SetPC(u32 pc) override; |
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp index 15677da27..d79e3e4b2 100644 --- a/src/core/arm/dyncom/arm_dyncom_run.cpp +++ b/src/core/arm/dyncom/arm_dyncom_run.cpp | |||
| @@ -2,9 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <assert.h> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/arm/skyeye_common/armdefs.h" | 5 | #include "core/arm/skyeye_common/armdefs.h" |
| 9 | 6 | ||
| 10 | void switch_mode(arm_core_t *core, uint32_t mode) { | 7 | void switch_mode(arm_core_t *core, uint32_t mode) { |
| @@ -13,6 +10,7 @@ void switch_mode(arm_core_t *core, uint32_t mode) { | |||
| 13 | 10 | ||
| 14 | if (mode != USERBANK) { | 11 | if (mode != USERBANK) { |
| 15 | switch (core->Mode) { | 12 | switch (core->Mode) { |
| 13 | case SYSTEM32MODE: // Shares registers with user mode | ||
| 16 | case USER32MODE: | 14 | case USER32MODE: |
| 17 | core->Reg_usr[0] = core->Reg[13]; | 15 | core->Reg_usr[0] = core->Reg[13]; |
| 18 | core->Reg_usr[1] = core->Reg[14]; | 16 | core->Reg_usr[1] = core->Reg[14]; |
| @@ -42,7 +40,6 @@ void switch_mode(arm_core_t *core, uint32_t mode) { | |||
| 42 | core->Reg_firq[1] = core->Reg[14]; | 40 | core->Reg_firq[1] = core->Reg[14]; |
| 43 | core->Spsr[FIQBANK] = core->Spsr_copy; | 41 | core->Spsr[FIQBANK] = core->Spsr_copy; |
| 44 | break; | 42 | break; |
| 45 | |||
| 46 | } | 43 | } |
| 47 | 44 | ||
| 48 | switch (mode) { | 45 | switch (mode) { |
| @@ -81,11 +78,15 @@ void switch_mode(arm_core_t *core, uint32_t mode) { | |||
| 81 | core->Spsr_copy = core->Spsr[FIQBANK]; | 78 | core->Spsr_copy = core->Spsr[FIQBANK]; |
| 82 | core->Bank = FIQBANK; | 79 | core->Bank = FIQBANK; |
| 83 | break; | 80 | break; |
| 84 | 81 | case SYSTEM32MODE: // Shares registers with user mode. | |
| 82 | core->Reg[13] = core->Reg_usr[0]; | ||
| 83 | core->Reg[14] = core->Reg_usr[1]; | ||
| 84 | core->Bank = SYSTEMBANK; | ||
| 85 | break; | ||
| 85 | } | 86 | } |
| 87 | |||
| 88 | // Set the mode bits in the APSR | ||
| 89 | core->Cpsr = (core->Cpsr & ~core->Mode) | mode; | ||
| 86 | core->Mode = mode; | 90 | core->Mode = mode; |
| 87 | } else { | ||
| 88 | LOG_CRITICAL(Core_ARM11, "user mode"); | ||
| 89 | exit(-2); | ||
| 90 | } | 91 | } |
| 91 | } | 92 | } |