diff options
| author | 2014-05-20 18:50:16 -0400 | |
|---|---|---|
| committer | 2014-05-20 18:50:16 -0400 | |
| commit | 49dc2ce8ac4fc37a008fa28e0771c8c74c576b05 (patch) | |
| tree | 1640b629267273cb6afe73e7923833072ad55d7d /src | |
| parent | renamed "syscall" module to "svc" (more accurate naming) (diff) | |
| download | yuzu-49dc2ce8ac4fc37a008fa28e0771c8c74c576b05.tar.gz yuzu-49dc2ce8ac4fc37a008fa28e0771c8c74c576b05.tar.xz yuzu-49dc2ce8ac4fc37a008fa28e0771c8c74c576b05.zip | |
ARM_Interface: added SaveContext and LoadContext functions for HLE thread switching
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/arm_interface.h | 16 | ||||
| -rw-r--r-- | src/core/arm/interpreter/arm_interpreter.cpp | 36 | ||||
| -rw-r--r-- | src/core/arm/interpreter/arm_interpreter.h | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 38 |
4 files changed, 65 insertions, 37 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 5c382ebbd..52bc82115 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include "common/common.h" | 7 | #include "common/common.h" |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | #include "core/hle/svc.h" | ||
| 11 | |||
| 10 | /// Generic ARM11 CPU interface | 12 | /// Generic ARM11 CPU interface |
| 11 | class ARM_Interface : NonCopyable { | 13 | class ARM_Interface : NonCopyable { |
| 12 | public: | 14 | public: |
| @@ -75,6 +77,18 @@ public: | |||
| 75 | */ | 77 | */ |
| 76 | virtual u64 GetTicks() const = 0; | 78 | virtual u64 GetTicks() const = 0; |
| 77 | 79 | ||
| 80 | /** | ||
| 81 | * Saves the current CPU context | ||
| 82 | * @param ctx Thread context to save | ||
| 83 | */ | ||
| 84 | virtual void SaveContext(ThreadContext& ctx) = 0; | ||
| 85 | |||
| 86 | /** | ||
| 87 | * Loads a CPU context | ||
| 88 | * @param ctx Thread context to load | ||
| 89 | */ | ||
| 90 | virtual void LoadContext(const ThreadContext& ctx) = 0; | ||
| 91 | |||
| 78 | /// Getter for m_num_instructions | 92 | /// Getter for m_num_instructions |
| 79 | u64 GetNumInstructions() { | 93 | u64 GetNumInstructions() { |
| 80 | return m_num_instructions; | 94 | return m_num_instructions; |
| @@ -90,6 +104,6 @@ protected: | |||
| 90 | 104 | ||
| 91 | private: | 105 | private: |
| 92 | 106 | ||
| 93 | u64 m_num_instructions; ///< Number of instructions executed | 107 | u64 m_num_instructions; ///< Number of instructions executed |
| 94 | 108 | ||
| 95 | }; | 109 | }; |
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp index c21ff0464..b8c46cdfc 100644 --- a/src/core/arm/interpreter/arm_interpreter.cpp +++ b/src/core/arm/interpreter/arm_interpreter.cpp | |||
| @@ -101,3 +101,39 @@ void ARM_Interpreter::ExecuteInstructions(int num_instructions) { | |||
| 101 | m_state->NumInstrsToExecute = num_instructions; | 101 | m_state->NumInstrsToExecute = num_instructions; |
| 102 | ARMul_Emulate32(m_state); | 102 | ARMul_Emulate32(m_state); |
| 103 | } | 103 | } |
| 104 | |||
| 105 | /** | ||
| 106 | * Saves the current CPU context | ||
| 107 | * @param ctx Thread context to save | ||
| 108 | * @todo Do we need to save Reg[15] and NextInstr? | ||
| 109 | */ | ||
| 110 | void ARM_Interpreter::SaveContext(ThreadContext& ctx) { | ||
| 111 | memcpy(ctx.cpu_registers, m_state->Reg, sizeof(ctx.cpu_registers)); | ||
| 112 | memcpy(ctx.fpu_registers, m_state->ExtReg, sizeof(ctx.fpu_registers)); | ||
| 113 | |||
| 114 | ctx.sp = m_state->Reg[13]; | ||
| 115 | ctx.lr = m_state->Reg[14]; | ||
| 116 | ctx.pc = m_state->pc; | ||
| 117 | ctx.cpsr = m_state->Cpsr; | ||
| 118 | |||
| 119 | ctx.fpscr = m_state->VFP[1]; | ||
| 120 | ctx.fpexc = m_state->VFP[2]; | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Loads a CPU context | ||
| 125 | * @param ctx Thread context to load | ||
| 126 | * @param Do we need to load Reg[15] and NextInstr? | ||
| 127 | */ | ||
| 128 | void ARM_Interpreter::LoadContext(const ThreadContext& ctx) { | ||
| 129 | memcpy(m_state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); | ||
| 130 | memcpy(m_state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); | ||
| 131 | |||
| 132 | m_state->Reg[13] = ctx.sp; | ||
| 133 | m_state->Reg[14] = ctx.lr; | ||
| 134 | m_state->pc = ctx.pc; | ||
| 135 | m_state->Cpsr = ctx.cpsr; | ||
| 136 | |||
| 137 | m_state->VFP[1] = ctx.fpscr; | ||
| 138 | m_state->VFP[2] = ctx.fpexc; | ||
| 139 | } | ||
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h index 474ba3e45..15240568c 100644 --- a/src/core/arm/interpreter/arm_interpreter.h +++ b/src/core/arm/interpreter/arm_interpreter.h | |||
| @@ -60,6 +60,18 @@ public: | |||
| 60 | */ | 60 | */ |
| 61 | u64 GetTicks() const; | 61 | u64 GetTicks() const; |
| 62 | 62 | ||
| 63 | /** | ||
| 64 | * Saves the current CPU context | ||
| 65 | * @param ctx Thread context to save | ||
| 66 | */ | ||
| 67 | void SaveContext(ThreadContext& ctx); | ||
| 68 | |||
| 69 | /** | ||
| 70 | * Loads a CPU context | ||
| 71 | * @param ctx Thread context to load | ||
| 72 | */ | ||
| 73 | void LoadContext(const ThreadContext& ctx); | ||
| 74 | |||
| 63 | protected: | 75 | protected: |
| 64 | 76 | ||
| 65 | /** | 77 | /** |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 136fff021..b3d306c53 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -98,46 +98,12 @@ inline void __SetCurrentThread(Thread* t) { | |||
| 98 | 98 | ||
| 99 | /// Saves the current CPU context | 99 | /// Saves the current CPU context |
| 100 | void __KernelSaveContext(ThreadContext& ctx) { | 100 | void __KernelSaveContext(ThreadContext& ctx) { |
| 101 | ctx.cpu_registers[0] = Core::g_app_core->GetReg(0); | 101 | Core::g_app_core->SaveContext(ctx); |
| 102 | ctx.cpu_registers[1] = Core::g_app_core->GetReg(1); | ||
| 103 | ctx.cpu_registers[2] = Core::g_app_core->GetReg(2); | ||
| 104 | ctx.cpu_registers[3] = Core::g_app_core->GetReg(3); | ||
| 105 | ctx.cpu_registers[4] = Core::g_app_core->GetReg(4); | ||
| 106 | ctx.cpu_registers[5] = Core::g_app_core->GetReg(5); | ||
| 107 | ctx.cpu_registers[6] = Core::g_app_core->GetReg(6); | ||
| 108 | ctx.cpu_registers[7] = Core::g_app_core->GetReg(7); | ||
| 109 | ctx.cpu_registers[8] = Core::g_app_core->GetReg(8); | ||
| 110 | ctx.cpu_registers[9] = Core::g_app_core->GetReg(9); | ||
| 111 | ctx.cpu_registers[10] = Core::g_app_core->GetReg(10); | ||
| 112 | ctx.cpu_registers[11] = Core::g_app_core->GetReg(11); | ||
| 113 | ctx.cpu_registers[12] = Core::g_app_core->GetReg(12); | ||
| 114 | ctx.sp = Core::g_app_core->GetReg(13); | ||
| 115 | ctx.lr = Core::g_app_core->GetReg(14); | ||
| 116 | ctx.pc = Core::g_app_core->GetPC(); | ||
| 117 | ctx.cpsr = Core::g_app_core->GetCPSR(); | ||
| 118 | } | 102 | } |
| 119 | 103 | ||
| 120 | /// Loads a CPU context | 104 | /// Loads a CPU context |
| 121 | void __KernelLoadContext(const ThreadContext& ctx) { | 105 | void __KernelLoadContext(const ThreadContext& ctx) { |
| 122 | Core::g_app_core->SetReg(0, ctx.cpu_registers[0]); | 106 | Core::g_app_core->LoadContext(ctx); |
| 123 | Core::g_app_core->SetReg(1, ctx.cpu_registers[1]); | ||
| 124 | Core::g_app_core->SetReg(2, ctx.cpu_registers[2]); | ||
| 125 | Core::g_app_core->SetReg(3, ctx.cpu_registers[3]); | ||
| 126 | Core::g_app_core->SetReg(4, ctx.cpu_registers[4]); | ||
| 127 | Core::g_app_core->SetReg(5, ctx.cpu_registers[5]); | ||
| 128 | Core::g_app_core->SetReg(6, ctx.cpu_registers[6]); | ||
| 129 | Core::g_app_core->SetReg(7, ctx.cpu_registers[7]); | ||
| 130 | Core::g_app_core->SetReg(8, ctx.cpu_registers[8]); | ||
| 131 | Core::g_app_core->SetReg(9, ctx.cpu_registers[9]); | ||
| 132 | Core::g_app_core->SetReg(10, ctx.cpu_registers[10]); | ||
| 133 | Core::g_app_core->SetReg(11, ctx.cpu_registers[11]); | ||
| 134 | Core::g_app_core->SetReg(12, ctx.cpu_registers[12]); | ||
| 135 | Core::g_app_core->SetReg(13, ctx.sp); | ||
| 136 | Core::g_app_core->SetReg(14, ctx.lr); | ||
| 137 | //Core::g_app_core->SetReg(15, ctx.pc); | ||
| 138 | |||
| 139 | Core::g_app_core->SetPC(ctx.pc); | ||
| 140 | Core::g_app_core->SetCPSR(ctx.cpsr); | ||
| 141 | } | 107 | } |
| 142 | 108 | ||
| 143 | /// Resets a thread | 109 | /// Resets a thread |