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.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
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue