diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2017-02-04 03:22:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-04 03:22:28 +0100 |
commit | a630fa287e178695b16887a56f7726ff97c91108 (patch) | |
tree | aa296dac492148a9b138beccd5d1b48c16e5ae88 /src | |
parent | Merge pull request #2509 from jfmherokiller/settingscastpatch (diff) | |
parent | arm_dynarmic: Update memory interface (diff) | |
download | yuzu-a630fa287e178695b16887a56f7726ff97c91108.tar yuzu-a630fa287e178695b16887a56f7726ff97c91108.tar.gz yuzu-a630fa287e178695b16887a56f7726ff97c91108.tar.bz2 yuzu-a630fa287e178695b16887a56f7726ff97c91108.tar.lz yuzu-a630fa287e178695b16887a56f7726ff97c91108.tar.xz yuzu-a630fa287e178695b16887a56f7726ff97c91108.tar.zst yuzu-a630fa287e178695b16887a56f7726ff97c91108.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 31 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 2 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_cp15.cpp | 88 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_cp15.h | 32 |
5 files changed, 140 insertions, 15 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 408d3a0cb..fa7878c65 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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 diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 9f25e3b00..7d2790b08 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -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) { diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 87ab53d81..834dc989e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -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; }; diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp new file mode 100644 index 000000000..b1fdce096 --- /dev/null +++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp @@ -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; +} diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.h b/src/core/arm/dynarmic/arm_dynarmic_cp15.h new file mode 100644 index 000000000..7fa54e14c --- /dev/null +++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.h @@ -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; +}; |