Merge pull request #2518 from MerryMage/coproc
arm_dynarmic: Coprocessor support
This commit is contained in:
		
							
								
								
									
										2
									
								
								externals/dynarmic
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								externals/dynarmic
									
									
									
									
										vendored
									
									
								
							 Submodule externals/dynarmic updated: 36082087de...459d7d1baf
									
								
							
							
								
								
									
										2
									
								
								externals/nihstro
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								externals/nihstro
									
									
									
									
										vendored
									
									
								
							 Submodule externals/nihstro updated: 7e24743af2...26a0a04a45
									
								
							| @@ -2,6 +2,7 @@ set(SRCS | ||||
|             arm/disassembler/arm_disasm.cpp | ||||
|             arm/disassembler/load_symbol_map.cpp | ||||
|             arm/dynarmic/arm_dynarmic.cpp | ||||
|             arm/dynarmic/arm_dynarmic_cp15.cpp | ||||
|             arm/dyncom/arm_dyncom.cpp | ||||
|             arm/dyncom/arm_dyncom_dec.cpp | ||||
|             arm/dyncom/arm_dyncom_interpreter.cpp | ||||
| @@ -177,6 +178,7 @@ set(HEADERS | ||||
|             arm/disassembler/arm_disasm.h | ||||
|             arm/disassembler/load_symbol_map.h | ||||
|             arm/dynarmic/arm_dynarmic.h | ||||
|             arm/dynarmic/arm_dynarmic_cp15.h | ||||
|             arm/dyncom/arm_dyncom.h | ||||
|             arm/dyncom/arm_dyncom_dec.h | ||||
|             arm/dyncom/arm_dyncom_interpreter.h | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include "common/assert.h" | ||||
| #include "common/microprofile.h" | ||||
| #include "core/arm/dynarmic/arm_dynarmic.h" | ||||
| #include "core/arm/dynarmic/arm_dynarmic_cp15.h" | ||||
| #include "core/arm/dyncom/arm_dyncom_interpreter.h" | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
| @@ -39,28 +40,30 @@ static bool IsReadOnlyMemory(u32 vaddr) { | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| static Dynarmic::UserCallbacks GetUserCallbacks(ARMul_State* interpeter_state) { | ||||
| static Dynarmic::UserCallbacks GetUserCallbacks( | ||||
|     const std::shared_ptr<ARMul_State>& interpeter_state) { | ||||
|     Dynarmic::UserCallbacks user_callbacks{}; | ||||
|     user_callbacks.InterpreterFallback = &InterpreterFallback; | ||||
|     user_callbacks.user_arg = static_cast<void*>(interpeter_state); | ||||
|     user_callbacks.user_arg = static_cast<void*>(interpeter_state.get()); | ||||
|     user_callbacks.CallSVC = &SVC::CallSVC; | ||||
|     user_callbacks.IsReadOnlyMemory = &IsReadOnlyMemory; | ||||
|     user_callbacks.MemoryReadCode = &Memory::Read32; | ||||
|     user_callbacks.MemoryRead8 = &Memory::Read8; | ||||
|     user_callbacks.MemoryRead16 = &Memory::Read16; | ||||
|     user_callbacks.MemoryRead32 = &Memory::Read32; | ||||
|     user_callbacks.MemoryRead64 = &Memory::Read64; | ||||
|     user_callbacks.MemoryWrite8 = &Memory::Write8; | ||||
|     user_callbacks.MemoryWrite16 = &Memory::Write16; | ||||
|     user_callbacks.MemoryWrite32 = &Memory::Write32; | ||||
|     user_callbacks.MemoryWrite64 = &Memory::Write64; | ||||
|     user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; | ||||
|     user_callbacks.memory.ReadCode = &Memory::Read32; | ||||
|     user_callbacks.memory.Read8 = &Memory::Read8; | ||||
|     user_callbacks.memory.Read16 = &Memory::Read16; | ||||
|     user_callbacks.memory.Read32 = &Memory::Read32; | ||||
|     user_callbacks.memory.Read64 = &Memory::Read64; | ||||
|     user_callbacks.memory.Write8 = &Memory::Write8; | ||||
|     user_callbacks.memory.Write16 = &Memory::Write16; | ||||
|     user_callbacks.memory.Write32 = &Memory::Write32; | ||||
|     user_callbacks.memory.Write64 = &Memory::Write64; | ||||
|     user_callbacks.page_table = Memory::GetCurrentPageTablePointers(); | ||||
|     user_callbacks.coprocessors[15] = std::make_shared<DynarmicCP15>(interpeter_state); | ||||
|     return user_callbacks; | ||||
| } | ||||
|  | ||||
| ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) { | ||||
|     interpreter_state = std::make_unique<ARMul_State>(initial_mode); | ||||
|     jit = std::make_unique<Dynarmic::Jit>(GetUserCallbacks(interpreter_state.get())); | ||||
|     interpreter_state = std::make_shared<ARMul_State>(initial_mode); | ||||
|     jit = std::make_unique<Dynarmic::Jit>(GetUserCallbacks(interpreter_state)); | ||||
| } | ||||
|  | ||||
| void ARM_Dynarmic::SetPC(u32 pc) { | ||||
|   | ||||
| @@ -39,5 +39,5 @@ public: | ||||
|  | ||||
| private: | ||||
|     std::unique_ptr<Dynarmic::Jit> jit; | ||||
|     std::unique_ptr<ARMul_State> interpreter_state; | ||||
|     std::shared_ptr<ARMul_State> interpreter_state; | ||||
| }; | ||||
|   | ||||
							
								
								
									
										88
									
								
								src/core/arm/dynarmic/arm_dynarmic_cp15.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/core/arm/dynarmic/arm_dynarmic_cp15.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "core/arm/dynarmic/arm_dynarmic_cp15.h" | ||||
| #include "core/arm/skyeye_common/arm_regformat.h" | ||||
| #include "core/arm/skyeye_common/armstate.h" | ||||
|  | ||||
| using Callback = Dynarmic::Coprocessor::Callback; | ||||
| using CallbackOrAccessOneWord = Dynarmic::Coprocessor::CallbackOrAccessOneWord; | ||||
| using CallbackOrAccessTwoWords = Dynarmic::Coprocessor::CallbackOrAccessTwoWords; | ||||
|  | ||||
| DynarmicCP15::DynarmicCP15(const std::shared_ptr<ARMul_State>& state) : interpreter_state(state) {} | ||||
|  | ||||
| DynarmicCP15::~DynarmicCP15() = default; | ||||
|  | ||||
| boost::optional<Callback> DynarmicCP15::CompileInternalOperation(bool two, unsigned opc1, | ||||
|                                                                  CoprocReg CRd, CoprocReg CRn, | ||||
|                                                                  CoprocReg CRm, unsigned opc2) { | ||||
|     return boost::none; | ||||
| } | ||||
|  | ||||
| CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn, | ||||
|                                                          CoprocReg CRm, unsigned opc2) { | ||||
|     // TODO(merry): Privileged CP15 registers | ||||
|  | ||||
|     if (!two && CRn == CoprocReg::C7 && opc1 == 0 && CRm == CoprocReg::C5 && opc2 == 4) { | ||||
|         // This is a dummy write, we ignore the value written here. | ||||
|         return &interpreter_state->CP15[CP15_FLUSH_PREFETCH_BUFFER]; | ||||
|     } | ||||
|  | ||||
|     if (!two && CRn == CoprocReg::C7 && opc1 == 0 && CRm == CoprocReg::C10) { | ||||
|         switch (opc2) { | ||||
|         case 4: | ||||
|             // This is a dummy write, we ignore the value written here. | ||||
|             return &interpreter_state->CP15[CP15_DATA_SYNC_BARRIER]; | ||||
|         case 5: | ||||
|             // This is a dummy write, we ignore the value written here. | ||||
|             return &interpreter_state->CP15[CP15_DATA_MEMORY_BARRIER]; | ||||
|         default: | ||||
|             return boost::blank{}; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (!two && CRn == CoprocReg::C13 && opc1 == 0 && CRm == CoprocReg::C0 && opc2 == 2) { | ||||
|         return &interpreter_state->CP15[CP15_THREAD_UPRW]; | ||||
|     } | ||||
|  | ||||
|     return boost::blank{}; | ||||
| } | ||||
|  | ||||
| CallbackOrAccessTwoWords DynarmicCP15::CompileSendTwoWords(bool two, unsigned opc, CoprocReg CRm) { | ||||
|     return boost::blank{}; | ||||
| } | ||||
|  | ||||
| CallbackOrAccessOneWord DynarmicCP15::CompileGetOneWord(bool two, unsigned opc1, CoprocReg CRn, | ||||
|                                                         CoprocReg CRm, unsigned opc2) { | ||||
|     // TODO(merry): Privileged CP15 registers | ||||
|  | ||||
|     if (!two && CRn == CoprocReg::C13 && opc1 == 0 && CRm == CoprocReg::C0) { | ||||
|         switch (opc2) { | ||||
|         case 2: | ||||
|             return &interpreter_state->CP15[CP15_THREAD_UPRW]; | ||||
|         case 3: | ||||
|             return &interpreter_state->CP15[CP15_THREAD_URO]; | ||||
|         default: | ||||
|             return boost::blank{}; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return boost::blank{}; | ||||
| } | ||||
|  | ||||
| CallbackOrAccessTwoWords DynarmicCP15::CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) { | ||||
|     return boost::blank{}; | ||||
| } | ||||
|  | ||||
| boost::optional<Callback> DynarmicCP15::CompileLoadWords(bool two, bool long_transfer, | ||||
|                                                          CoprocReg CRd, | ||||
|                                                          boost::optional<u8> option) { | ||||
|     return boost::none; | ||||
| } | ||||
|  | ||||
| boost::optional<Callback> DynarmicCP15::CompileStoreWords(bool two, bool long_transfer, | ||||
|                                                           CoprocReg CRd, | ||||
|                                                           boost::optional<u8> option) { | ||||
|     return boost::none; | ||||
| } | ||||
							
								
								
									
										32
									
								
								src/core/arm/dynarmic/arm_dynarmic_cp15.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/core/arm/dynarmic/arm_dynarmic_cp15.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| // Copyright 2017 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include <memory> | ||||
| #include <dynarmic/coprocessor.h> | ||||
| #include "common/common_types.h" | ||||
|  | ||||
| struct ARMul_State; | ||||
|  | ||||
| class DynarmicCP15 final : public Dynarmic::Coprocessor { | ||||
| public: | ||||
|     explicit DynarmicCP15(const std::shared_ptr<ARMul_State>&); | ||||
|     ~DynarmicCP15() override; | ||||
|  | ||||
|     boost::optional<Callback> CompileInternalOperation(bool two, unsigned opc1, CoprocReg CRd, | ||||
|                                                        CoprocReg CRn, CoprocReg CRm, | ||||
|                                                        unsigned opc2) override; | ||||
|     CallbackOrAccessOneWord CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn, | ||||
|                                                CoprocReg CRm, unsigned opc2) override; | ||||
|     CallbackOrAccessTwoWords CompileSendTwoWords(bool two, unsigned opc, CoprocReg CRm) override; | ||||
|     CallbackOrAccessOneWord CompileGetOneWord(bool two, unsigned opc1, CoprocReg CRn, CoprocReg CRm, | ||||
|                                               unsigned opc2) override; | ||||
|     CallbackOrAccessTwoWords CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) override; | ||||
|     boost::optional<Callback> CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd, | ||||
|                                                boost::optional<u8> option) override; | ||||
|     boost::optional<Callback> CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd, | ||||
|                                                 boost::optional<u8> option) override; | ||||
|  | ||||
| private: | ||||
|     std::shared_ptr<ARMul_State> interpreter_state; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user