summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2014-05-20 18:50:16 -0400
committerGravatar bunnei2014-05-20 18:50:16 -0400
commit49dc2ce8ac4fc37a008fa28e0771c8c74c576b05 (patch)
tree1640b629267273cb6afe73e7923833072ad55d7d /src/core
parentrenamed "syscall" module to "svc" (more accurate naming) (diff)
downloadyuzu-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/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 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
11class ARM_Interface : NonCopyable { 13class ARM_Interface : NonCopyable {
12public: 14public:
@@ -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
91private: 105private:
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 */
110void 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 */
128void 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
63protected: 75protected:
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
100void __KernelSaveContext(ThreadContext& ctx) { 100void __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
121void __KernelLoadContext(const ThreadContext& ctx) { 105void __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