mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	ARM_Interface: added SaveContext and LoadContext functions for HLE thread switching
This commit is contained in:
		
							parent
							
								
									143bba2045
								
							
						
					
					
						commit
						49dc2ce8ac
					
				
					 4 changed files with 65 additions and 37 deletions
				
			
		|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -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: | ||||
| 
 | ||||
|     /**
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue