ARM_Interface: added SaveContext and LoadContext functions for HLE thread switching
This commit is contained in:
parent
143bba2045
commit
49dc2ce8ac
|
@ -7,6 +7,8 @@
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
#include "core/hle/svc.h"
|
||||||
|
|
||||||
/// Generic ARM11 CPU interface
|
/// Generic ARM11 CPU interface
|
||||||
class ARM_Interface : NonCopyable {
|
class ARM_Interface : NonCopyable {
|
||||||
public:
|
public:
|
||||||
|
@ -75,6 +77,18 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual u64 GetTicks() const = 0;
|
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
|
/// Getter for m_num_instructions
|
||||||
u64 GetNumInstructions() {
|
u64 GetNumInstructions() {
|
||||||
return m_num_instructions;
|
return m_num_instructions;
|
||||||
|
@ -90,6 +104,6 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
u64 m_num_instructions; ///< Number of instructions executed
|
u64 m_num_instructions; ///< Number of instructions executed
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,3 +101,39 @@ void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
|
||||||
m_state->NumInstrsToExecute = num_instructions;
|
m_state->NumInstrsToExecute = num_instructions;
|
||||||
ARMul_Emulate32(m_state);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,18 @@ public:
|
||||||
*/
|
*/
|
||||||
u64 GetTicks() const;
|
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:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -98,46 +98,12 @@ inline void __SetCurrentThread(Thread* t) {
|
||||||
|
|
||||||
/// Saves the current CPU context
|
/// Saves the current CPU context
|
||||||
void __KernelSaveContext(ThreadContext& ctx) {
|
void __KernelSaveContext(ThreadContext& ctx) {
|
||||||
ctx.cpu_registers[0] = Core::g_app_core->GetReg(0);
|
Core::g_app_core->SaveContext(ctx);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads a CPU context
|
/// Loads a CPU context
|
||||||
void __KernelLoadContext(const ThreadContext& ctx) {
|
void __KernelLoadContext(const ThreadContext& ctx) {
|
||||||
Core::g_app_core->SetReg(0, ctx.cpu_registers[0]);
|
Core::g_app_core->LoadContext(ctx);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets a thread
|
/// Resets a thread
|
||||||
|
|
Reference in New Issue