aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei <ericbunnie@gmail.com>2014-05-20 18:50:16 -0400
committerGravatar bunnei <ericbunnie@gmail.com>2014-05-20 18:50:16 -0400
commit49dc2ce8ac4fc37a008fa28e0771c8c74c576b05 (patch)
tree1640b629267273cb6afe73e7923833072ad55d7d /src/core
parent143bba20453036f0a4bcc74dad10d99605a84732 (diff)
ARM_Interface: added SaveContext and LoadContext functions for HLE thread switching
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/arm_interface.h16
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp36
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h12
-rw-r--r--src/core/hle/kernel/thread.cpp38
4 files changed, 65 insertions, 37 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 5c382ebb..52bc8211 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -7,6 +7,8 @@
#include "common/common.h"
#include "common/common_types.h"
+#include "core/hle/svc.h"
+
/// Generic ARM11 CPU interface
class ARM_Interface : NonCopyable {
public:
@@ -75,6 +77,18 @@ public:
*/
virtual u64 GetTicks() const = 0;
+ /**
+ * Saves the current CPU context
+ * @param ctx Thread context to save
+ */
+ virtual void SaveContext(ThreadContext& ctx) = 0;
+
+ /**
+ * Loads a CPU context
+ * @param ctx Thread context to load
+ */
+ virtual void LoadContext(const ThreadContext& ctx) = 0;
+
/// Getter for m_num_instructions
u64 GetNumInstructions() {
return m_num_instructions;
@@ -90,6 +104,6 @@ protected:
private:
- u64 m_num_instructions; ///< Number of instructions executed
+ u64 m_num_instructions; ///< Number of instructions executed
};
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index c21ff046..b8c46cdf 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) {
m_state->NumInstrsToExecute = num_instructions;
ARMul_Emulate32(m_state);
}
+
+/**
+ * Saves the current CPU context
+ * @param ctx Thread context to save
+ * @todo Do we need to save Reg[15] and NextInstr?
+ */
+void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
+ memcpy(ctx.cpu_registers, m_state->Reg, sizeof(ctx.cpu_registers));
+ memcpy(ctx.fpu_registers, m_state->ExtReg, sizeof(ctx.fpu_registers));
+
+ ctx.sp = m_state->Reg[13];
+ ctx.lr = m_state->Reg[14];
+ ctx.pc = m_state->pc;
+ ctx.cpsr = m_state->Cpsr;
+
+ ctx.fpscr = m_state->VFP[1];
+ ctx.fpexc = m_state->VFP[2];
+}
+
+/**
+ * Loads a CPU context
+ * @param ctx Thread context to load
+ * @param Do we need to load Reg[15] and NextInstr?
+ */
+void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
+ memcpy(m_state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
+ memcpy(m_state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
+
+ m_state->Reg[13] = ctx.sp;
+ m_state->Reg[14] = ctx.lr;
+ m_state->pc = ctx.pc;
+ m_state->Cpsr = ctx.cpsr;
+
+ m_state->VFP[1] = ctx.fpscr;
+ m_state->VFP[2] = ctx.fpexc;
+}
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 474ba3e4..15240568 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -60,6 +60,18 @@ public:
*/
u64 GetTicks() const;
+ /**
+ * Saves the current CPU context
+ * @param ctx Thread context to save
+ */
+ void SaveContext(ThreadContext& ctx);
+
+ /**
+ * Loads a CPU context
+ * @param ctx Thread context to load
+ */
+ void LoadContext(const ThreadContext& ctx);
+
protected:
/**
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 136fff02..b3d306c5 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -98,46 +98,12 @@ inline void __SetCurrentThread(Thread* t) {
/// Saves the current CPU context
void __KernelSaveContext(ThreadContext& ctx) {
- ctx.cpu_registers[0] = Core::g_app_core->GetReg(0);
- ctx.cpu_registers[1] = Core::g_app_core->GetReg(1);
- ctx.cpu_registers[2] = Core::g_app_core->GetReg(2);
- ctx.cpu_registers[3] = Core::g_app_core->GetReg(3);
- ctx.cpu_registers[4] = Core::g_app_core->GetReg(4);
- ctx.cpu_registers[5] = Core::g_app_core->GetReg(5);
- ctx.cpu_registers[6] = Core::g_app_core->GetReg(6);
- ctx.cpu_registers[7] = Core::g_app_core->GetReg(7);
- ctx.cpu_registers[8] = Core::g_app_core->GetReg(8);
- ctx.cpu_registers[9] = Core::g_app_core->GetReg(9);
- ctx.cpu_registers[10] = Core::g_app_core->GetReg(10);
- ctx.cpu_registers[11] = Core::g_app_core->GetReg(11);
- ctx.cpu_registers[12] = Core::g_app_core->GetReg(12);
- ctx.sp = Core::g_app_core->GetReg(13);
- ctx.lr = Core::g_app_core->GetReg(14);
- ctx.pc = Core::g_app_core->GetPC();
- ctx.cpsr = Core::g_app_core->GetCPSR();
+ Core::g_app_core->SaveContext(ctx);
}
/// Loads a CPU context
void __KernelLoadContext(const ThreadContext& ctx) {
- Core::g_app_core->SetReg(0, ctx.cpu_registers[0]);
- Core::g_app_core->SetReg(1, ctx.cpu_registers[1]);
- Core::g_app_core->SetReg(2, ctx.cpu_registers[2]);
- Core::g_app_core->SetReg(3, ctx.cpu_registers[3]);
- Core::g_app_core->SetReg(4, ctx.cpu_registers[4]);
- Core::g_app_core->SetReg(5, ctx.cpu_registers[5]);
- Core::g_app_core->SetReg(6, ctx.cpu_registers[6]);
- Core::g_app_core->SetReg(7, ctx.cpu_registers[7]);
- Core::g_app_core->SetReg(8, ctx.cpu_registers[8]);
- Core::g_app_core->SetReg(9, ctx.cpu_registers[9]);
- Core::g_app_core->SetReg(10, ctx.cpu_registers[10]);
- Core::g_app_core->SetReg(11, ctx.cpu_registers[11]);
- Core::g_app_core->SetReg(12, ctx.cpu_registers[12]);
- Core::g_app_core->SetReg(13, ctx.sp);
- Core::g_app_core->SetReg(14, ctx.lr);
- //Core::g_app_core->SetReg(15, ctx.pc);
-
- Core::g_app_core->SetPC(ctx.pc);
- Core::g_app_core->SetCPSR(ctx.cpsr);
+ Core::g_app_core->LoadContext(ctx);
}
/// Resets a thread