diff options
| author | 2015-02-12 23:18:40 -0500 | |
|---|---|---|
| committer | 2015-02-12 23:18:40 -0500 | |
| commit | 9b69079c835352fd7727e89624accb5115d35d36 (patch) | |
| tree | 9b1f0a7cf06bde6cbaac3230fbdbba824e7fcdfc /src | |
| parent | Merge pull request #568 from lioncash/assert (diff) | |
| parent | dyncom: Switch the app and system cores into the correct mode at initialization (diff) | |
| download | yuzu-9b69079c835352fd7727e89624accb5115d35d36.tar.gz yuzu-9b69079c835352fd7727e89624accb5115d35d36.tar.xz yuzu-9b69079c835352fd7727e89624accb5115d35d36.zip | |
Merge pull request #569 from lioncash/modeswitch
Dyncom: Correctly set the ARM modes on dyncom initialization.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.cpp | 17 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_run.cpp | 17 | ||||
| -rw-r--r-- | src/core/arm/interpreter/arminit.cpp | 7 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 4 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.cpp | 5 | ||||
| -rw-r--r-- | src/core/core.cpp | 9 |
7 files changed, 28 insertions, 33 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index c4af85242..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,29 +16,29 @@ 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()); |
| 23 | ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); | ||
| 22 | 24 | ||
| 23 | state->abort_model = ABORT_BASE_RESTORED; | 25 | state->abort_model = ABORT_BASE_RESTORED; |
| 24 | state->cpu = (cpu_config_t*)&s_arm11_cpu_info; | 26 | state->cpu = (cpu_config_t*)&s_arm11_cpu_info; |
| 25 | state->bigendSig = LOW; | ||
| 26 | 27 | ||
| 27 | ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); | 28 | state->bigendSig = LOW; |
| 28 | state->lateabtSig = LOW; | 29 | state->lateabtSig = LOW; |
| 30 | state->NirqSig = HIGH; | ||
| 29 | 31 | ||
| 30 | // Reset the core to initial state | 32 | // Reset the core to initial state |
| 31 | ARMul_CoProInit(state.get()); | ||
| 32 | ARMul_Reset(state.get()); | 33 | ARMul_Reset(state.get()); |
| 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 | ||
| 36 | state->Reg[15] = 0x00000000; | 37 | // Switch to the desired privilege mode. |
| 37 | state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack | 38 | switch_mode(state.get(), initial_mode); |
| 38 | state->NirqSig = HIGH; | ||
| 39 | 39 | ||
| 40 | VFPInit(state.get()); // Initialize the VFP | 40 | state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack |
| 41 | state->Reg[15] = 0x00000000; | ||
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | ARM_DynCom::~ARM_DynCom() { | 44 | ARM_DynCom::~ARM_DynCom() { |
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 | } |
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp index 0c0ce6c91..d3174c9a0 100644 --- a/src/core/arm/interpreter/arminit.cpp +++ b/src/core/arm/interpreter/arminit.cpp | |||
| @@ -64,10 +64,9 @@ void ARMul_SelectProcessor(ARMul_State* state, unsigned properties) | |||
| 64 | state->is_pxa27x = (properties & ARM_PXA27X_Prop) != 0; | 64 | state->is_pxa27x = (properties & ARM_PXA27X_Prop) != 0; |
| 65 | state->is_v7 = (properties & ARM_v7_Prop) != 0; | 65 | state->is_v7 = (properties & ARM_v7_Prop) != 0; |
| 66 | 66 | ||
| 67 | /* Only initialse the coprocessor support once we | 67 | // Only initialse the coprocessor support once we |
| 68 | know what kind of chip we are dealing with. */ | 68 | // know what kind of chip we are dealing with. |
| 69 | //ARMul_CoProInit (state); | 69 | ARMul_CoProInit(state); |
| 70 | |||
| 71 | } | 70 | } |
| 72 | 71 | ||
| 73 | /***************************************************************************\ | 72 | /***************************************************************************\ |
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 02f54f385..dc2256a35 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h | |||
| @@ -270,7 +270,7 @@ enum { | |||
| 270 | * Mode and Bank Constants * | 270 | * Mode and Bank Constants * |
| 271 | \***************************************************************************/ | 271 | \***************************************************************************/ |
| 272 | 272 | ||
| 273 | enum { | 273 | enum PrivilegeMode { |
| 274 | USER32MODE = 16, | 274 | USER32MODE = 16, |
| 275 | FIQ32MODE = 17, | 275 | FIQ32MODE = 17, |
| 276 | IRQ32MODE = 18, | 276 | IRQ32MODE = 18, |
| @@ -288,7 +288,7 @@ enum { | |||
| 288 | ABORTBANK = 4, | 288 | ABORTBANK = 4, |
| 289 | UNDEFBANK = 5, | 289 | UNDEFBANK = 5, |
| 290 | DUMMYBANK = 6, | 290 | DUMMYBANK = 6, |
| 291 | SYSTEMBANK = USERBANK | 291 | SYSTEMBANK = 7 |
| 292 | }; | 292 | }; |
| 293 | 293 | ||
| 294 | /***************************************************************************\ | 294 | /***************************************************************************\ |
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index 1cf146c53..6f22923bb 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp | |||
| @@ -26,8 +26,6 @@ | |||
| 26 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" | 26 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" |
| 27 | #include "core/arm/skyeye_common/vfp/vfp.h" | 27 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 28 | 28 | ||
| 29 | //ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ | ||
| 30 | |||
| 31 | unsigned VFPInit(ARMul_State* state) | 29 | unsigned VFPInit(ARMul_State* state) |
| 32 | { | 30 | { |
| 33 | state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | | 31 | state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | |
| @@ -35,9 +33,6 @@ unsigned VFPInit(ARMul_State* state) | |||
| 35 | state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0; | 33 | state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0; |
| 36 | state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0; | 34 | state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0; |
| 37 | 35 | ||
| 38 | //persistent_state = state; | ||
| 39 | /* Reset only specify VFP_FPEXC_EN = '0' */ | ||
| 40 | |||
| 41 | return 0; | 36 | return 0; |
| 42 | } | 37 | } |
| 43 | 38 | ||
diff --git a/src/core/core.cpp b/src/core/core.cpp index 63be27be2..15787bc17 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -56,11 +56,10 @@ void Stop() { | |||
| 56 | 56 | ||
| 57 | /// Initialize the core | 57 | /// Initialize the core |
| 58 | int Init() { | 58 | int Init() { |
| 59 | LOG_DEBUG(Core, "initialized OK"); | 59 | g_sys_core = new ARM_DynCom(USER32MODE); |
| 60 | 60 | g_app_core = new ARM_DynCom(USER32MODE); | |
| 61 | g_sys_core = new ARM_DynCom(); | ||
| 62 | g_app_core = new ARM_DynCom(); | ||
| 63 | 61 | ||
| 62 | LOG_DEBUG(Core, "Initialized OK"); | ||
| 64 | return 0; | 63 | return 0; |
| 65 | } | 64 | } |
| 66 | 65 | ||
| @@ -68,7 +67,7 @@ void Shutdown() { | |||
| 68 | delete g_app_core; | 67 | delete g_app_core; |
| 69 | delete g_sys_core; | 68 | delete g_sys_core; |
| 70 | 69 | ||
| 71 | LOG_DEBUG(Core, "shutdown OK"); | 70 | LOG_DEBUG(Core, "Shutdown OK"); |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 74 | } // namespace | 73 | } // namespace |