diff options
| author | 2017-10-09 23:56:20 -0400 | |
|---|---|---|
| committer | 2017-10-09 23:56:20 -0400 | |
| commit | b1d5db1cf60344b6b081c9d03cb6ccc3264326cd (patch) | |
| tree | fde377c4ba3c0f92c032e6f5ec8627aae37270ef /src/core/arm/dynarmic | |
| parent | loader: Various improvements for NSO/NRO loaders. (diff) | |
| parent | Merge pull request #2996 from MerryMage/split-travis (diff) | |
| download | yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.tar.gz yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.tar.xz yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.zip | |
Merge remote-tracking branch 'upstream/master' into nx
# Conflicts:
# src/core/CMakeLists.txt
# src/core/arm/dynarmic/arm_dynarmic.cpp
# src/core/arm/dyncom/arm_dyncom.cpp
# src/core/hle/kernel/process.cpp
# src/core/hle/kernel/thread.cpp
# src/core/hle/kernel/thread.h
# src/core/hle/kernel/vm_manager.cpp
# src/core/loader/3dsx.cpp
# src/core/loader/elf.cpp
# src/core/loader/ncch.cpp
# src/core/memory.cpp
# src/core/memory.h
# src/core/memory_setup.h
Diffstat (limited to 'src/core/arm/dynarmic')
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 93 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 17 |
2 files changed, 48 insertions, 62 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 0ea1d76e4..6dcab5bab 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -16,24 +16,6 @@ | |||
| 16 | 16 | ||
| 17 | static void InterpreterFallback(u64 pc, Dynarmic::Jit* jit, void* user_arg) { | 17 | static void InterpreterFallback(u64 pc, Dynarmic::Jit* jit, void* user_arg) { |
| 18 | UNIMPLEMENTED_MSG("InterpreterFallback for ARM64 JIT does not exist!"); | 18 | UNIMPLEMENTED_MSG("InterpreterFallback for ARM64 JIT does not exist!"); |
| 19 | //ARMul_State* state = static_cast<ARMul_State*>(user_arg); | ||
| 20 | |||
| 21 | //state->Reg = jit->Regs(); | ||
| 22 | //state->Cpsr = jit->Cpsr(); | ||
| 23 | //state->Reg[15] = static_cast<u32>(pc); | ||
| 24 | //state->ExtReg = jit->ExtRegs(); | ||
| 25 | //state->VFP[VFP_FPSCR] = jit->Fpscr(); | ||
| 26 | //state->NumInstrsToExecute = 1; | ||
| 27 | |||
| 28 | //InterpreterMainLoop(state); | ||
| 29 | |||
| 30 | //bool is_thumb = (state->Cpsr & (1 << 5)) != 0; | ||
| 31 | //state->Reg[15] &= (is_thumb ? 0xFFFFFFFE : 0xFFFFFFFC); | ||
| 32 | |||
| 33 | //jit->Regs() = state->Reg; | ||
| 34 | //jit->Cpsr() = state->Cpsr; | ||
| 35 | //jit->ExtRegs() = state->ExtReg; | ||
| 36 | //jit->SetFpscr(state->VFP[VFP_FPSCR]); | ||
| 37 | } | 19 | } |
| 38 | 20 | ||
| 39 | static bool IsReadOnlyMemory(u64 vaddr) { | 21 | static bool IsReadOnlyMemory(u64 vaddr) { |
| @@ -73,11 +55,10 @@ void MemoryWrite64(const u64 addr, const u64 data) { | |||
| 73 | Memory::Write64(static_cast<VAddr>(addr), data); | 55 | Memory::Write64(static_cast<VAddr>(addr), data); |
| 74 | } | 56 | } |
| 75 | 57 | ||
| 76 | static Dynarmic::UserCallbacks GetUserCallbacks( | 58 | static Dynarmic::UserCallbacks GetUserCallbacks(ARM_Dynarmic* this_) { |
| 77 | const std::shared_ptr<ARMul_State>& interpeter_state) { | ||
| 78 | Dynarmic::UserCallbacks user_callbacks{}; | 59 | Dynarmic::UserCallbacks user_callbacks{}; |
| 79 | //user_callbacks.InterpreterFallback = &InterpreterFallback; | 60 | user_callbacks.InterpreterFallback = &InterpreterFallback; |
| 80 | //user_callbacks.user_arg = static_cast<void*>(interpeter_state.get()); | 61 | user_callbacks.user_arg = static_cast<void*>(this_); |
| 81 | user_callbacks.CallSVC = &SVC::CallSVC; | 62 | user_callbacks.CallSVC = &SVC::CallSVC; |
| 82 | user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; | 63 | user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; |
| 83 | user_callbacks.memory.ReadCode = &MemoryRead32; | 64 | user_callbacks.memory.ReadCode = &MemoryRead32; |
| @@ -90,13 +71,13 @@ static Dynarmic::UserCallbacks GetUserCallbacks( | |||
| 90 | user_callbacks.memory.Write32 = &MemoryWrite32; | 71 | user_callbacks.memory.Write32 = &MemoryWrite32; |
| 91 | user_callbacks.memory.Write64 = &MemoryWrite64; | 72 | user_callbacks.memory.Write64 = &MemoryWrite64; |
| 92 | //user_callbacks.page_table = Memory::GetCurrentPageTablePointers(); | 73 | //user_callbacks.page_table = Memory::GetCurrentPageTablePointers(); |
| 93 | user_callbacks.coprocessors[15] = std::make_shared<DynarmicCP15>(interpeter_state); | ||
| 94 | return user_callbacks; | 74 | return user_callbacks; |
| 95 | } | 75 | } |
| 96 | 76 | ||
| 97 | ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) { | 77 | ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) { |
| 98 | interpreter_state = std::make_shared<ARMul_State>(initial_mode); | 78 | } |
| 99 | jit = std::make_unique<Dynarmic::Jit>(GetUserCallbacks(interpreter_state), Dynarmic::Arch::ARM64); | 79 | |
| 80 | void ARM_Dynarmic::MapBackingMemory(VAddr address, size_t size, u8* memory, Kernel::VMAPermission perms) { | ||
| 100 | } | 81 | } |
| 101 | 82 | ||
| 102 | void ARM_Dynarmic::SetPC(u64 pc) { | 83 | void ARM_Dynarmic::SetPC(u64 pc) { |
| @@ -115,30 +96,26 @@ void ARM_Dynarmic::SetReg(int index, u64 value) { | |||
| 115 | jit->Regs64()[index] = value; | 96 | jit->Regs64()[index] = value; |
| 116 | } | 97 | } |
| 117 | 98 | ||
| 99 | const u128& ARM_Dynarmic::GetExtReg(int index) const { | ||
| 100 | return jit->ExtRegs64()[index]; | ||
| 101 | } | ||
| 102 | |||
| 103 | void ARM_Dynarmic::SetExtReg(int index, u128& value) { | ||
| 104 | jit->ExtRegs64()[index] = value; | ||
| 105 | } | ||
| 106 | |||
| 118 | u32 ARM_Dynarmic::GetVFPReg(int index) const { | 107 | u32 ARM_Dynarmic::GetVFPReg(int index) const { |
| 119 | return jit->ExtRegs()[index]; | 108 | return {}; |
| 120 | } | 109 | } |
| 121 | 110 | ||
| 122 | void ARM_Dynarmic::SetVFPReg(int index, u32 value) { | 111 | void ARM_Dynarmic::SetVFPReg(int index, u32 value) { |
| 123 | jit->ExtRegs()[index] = value; | ||
| 124 | } | 112 | } |
| 125 | 113 | ||
| 126 | u32 ARM_Dynarmic::GetVFPSystemReg(VFPSystemRegister reg) const { | 114 | u32 ARM_Dynarmic::GetVFPSystemReg(VFPSystemRegister reg) const { |
| 127 | if (reg == VFP_FPSCR) { | 115 | return {}; |
| 128 | return jit->Fpscr(); | ||
| 129 | } | ||
| 130 | |||
| 131 | // Dynarmic does not implement and/or expose other VFP registers, fallback to interpreter state | ||
| 132 | return interpreter_state->VFP[reg]; | ||
| 133 | } | 116 | } |
| 134 | 117 | ||
| 135 | void ARM_Dynarmic::SetVFPSystemReg(VFPSystemRegister reg, u32 value) { | 118 | void ARM_Dynarmic::SetVFPSystemReg(VFPSystemRegister reg, u32 value) { |
| 136 | if (reg == VFP_FPSCR) { | ||
| 137 | jit->SetFpscr(value); | ||
| 138 | } | ||
| 139 | |||
| 140 | // Dynarmic does not implement and/or expose other VFP registers, fallback to interpreter state | ||
| 141 | interpreter_state->VFP[reg] = value; | ||
| 142 | } | 119 | } |
| 143 | 120 | ||
| 144 | u32 ARM_Dynarmic::GetCPSR() const { | 121 | u32 ARM_Dynarmic::GetCPSR() const { |
| @@ -150,11 +127,10 @@ void ARM_Dynarmic::SetCPSR(u32 cpsr) { | |||
| 150 | } | 127 | } |
| 151 | 128 | ||
| 152 | u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) { | 129 | u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) { |
| 153 | return interpreter_state->CP15[reg]; | 130 | return {}; |
| 154 | } | 131 | } |
| 155 | 132 | ||
| 156 | void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) { | 133 | void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) { |
| 157 | interpreter_state->CP15[reg] = value; | ||
| 158 | } | 134 | } |
| 159 | 135 | ||
| 160 | VAddr ARM_Dynarmic::GetTlsAddress() const { | 136 | VAddr ARM_Dynarmic::GetTlsAddress() const { |
| @@ -165,51 +141,39 @@ void ARM_Dynarmic::SetTlsAddress(VAddr address) { | |||
| 165 | jit->TlsAddr() = address; | 141 | jit->TlsAddr() = address; |
| 166 | } | 142 | } |
| 167 | 143 | ||
| 168 | void ARM_Dynarmic::AddTicks(u64 ticks) { | ||
| 169 | down_count -= ticks; | ||
| 170 | if (down_count < 0) { | ||
| 171 | CoreTiming::Advance(); | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); | 144 | MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); |
| 176 | 145 | ||
| 177 | void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { | 146 | void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { |
| 147 | ASSERT(Memory::GetCurrentPageTable() == current_page_table); | ||
| 178 | MICROPROFILE_SCOPE(ARM_Jit); | 148 | MICROPROFILE_SCOPE(ARM_Jit); |
| 179 | 149 | ||
| 180 | unsigned ticks_executed = jit->Run(1 /*static_cast<unsigned>(num_instructions)*/); | 150 | std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions)); |
| 181 | 151 | ||
| 182 | AddTicks(ticks_executed); | 152 | CoreTiming::AddTicks(ticks_executed); |
| 183 | } | 153 | } |
| 184 | 154 | ||
| 185 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { | 155 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { |
| 186 | memcpy(ctx.cpu_registers, jit->Regs64().data(), sizeof(ctx.cpu_registers)); | 156 | memcpy(ctx.cpu_registers, jit->Regs64().data(), sizeof(ctx.cpu_registers)); |
| 187 | //memcpy(ctx.fpu_registers, jit->ExtRegs().data(), sizeof(ctx.fpu_registers)); | 157 | memcpy(ctx.fpu_registers, jit->ExtRegs64().data(), sizeof(ctx.fpu_registers)); |
| 188 | 158 | ||
| 189 | ctx.lr = jit->Regs64()[30]; | 159 | ctx.lr = jit->Regs64()[30]; |
| 190 | ctx.sp = jit->Regs64()[31]; | 160 | ctx.sp = jit->Regs64()[31]; |
| 191 | ctx.pc = jit->Regs64()[32]; | 161 | ctx.pc = jit->Regs64()[32]; |
| 192 | ctx.cpsr = jit->Cpsr(); | 162 | ctx.cpsr = jit->Cpsr(); |
| 193 | 163 | ||
| 194 | ctx.fpscr = jit->Fpscr(); | ||
| 195 | ctx.fpexc = interpreter_state->VFP[VFP_FPEXC]; | ||
| 196 | |||
| 197 | // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT | 164 | // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT |
| 198 | ctx.tls_address = jit->TlsAddr(); | 165 | ctx.tls_address = jit->TlsAddr(); |
| 199 | } | 166 | } |
| 200 | 167 | ||
| 201 | void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) { | 168 | void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) { |
| 202 | memcpy(jit->Regs64().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers)); | 169 | memcpy(jit->Regs64().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers)); |
| 203 | //memcpy(jit->ExtRegs().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers)); | 170 | memcpy(jit->ExtRegs64().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers)); |
| 204 | 171 | ||
| 205 | jit->Regs64()[30] = ctx.lr; | 172 | jit->Regs64()[30] = ctx.lr; |
| 206 | jit->Regs64()[31] = ctx.sp; | 173 | jit->Regs64()[31] = ctx.sp; |
| 207 | jit->Regs64()[32] = ctx.pc; | 174 | jit->Regs64()[32] = ctx.pc; |
| 208 | jit->Cpsr() = ctx.cpsr; | 175 | jit->Cpsr() = ctx.cpsr; |
| 209 | 176 | ||
| 210 | jit->SetFpscr(ctx.fpscr); | ||
| 211 | interpreter_state->VFP[VFP_FPEXC] = ctx.fpexc; | ||
| 212 | |||
| 213 | // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT | 177 | // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT |
| 214 | jit->TlsAddr() = ctx.tls_address; | 178 | jit->TlsAddr() = ctx.tls_address; |
| 215 | } | 179 | } |
| @@ -223,3 +187,16 @@ void ARM_Dynarmic::PrepareReschedule() { | |||
| 223 | void ARM_Dynarmic::ClearInstructionCache() { | 187 | void ARM_Dynarmic::ClearInstructionCache() { |
| 224 | jit->ClearCache(); | 188 | jit->ClearCache(); |
| 225 | } | 189 | } |
| 190 | |||
| 191 | void ARM_Dynarmic::PageTableChanged() { | ||
| 192 | current_page_table = Memory::GetCurrentPageTable(); | ||
| 193 | |||
| 194 | auto iter = jits.find(current_page_table); | ||
| 195 | if (iter != jits.end()) { | ||
| 196 | jit = iter->second.get(); | ||
| 197 | return; | ||
| 198 | } | ||
| 199 | |||
| 200 | jit = new Dynarmic::Jit(GetUserCallbacks(this), Dynarmic::Arch::ARM64); | ||
| 201 | jits.emplace(current_page_table, std::unique_ptr<Dynarmic::Jit>(jit)); | ||
| 202 | } | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index fcdc1c0e0..6567359b0 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -4,20 +4,29 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <map> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 8 | #include <dynarmic/dynarmic.h> | 9 | #include <dynarmic/dynarmic.h> |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "core/arm/arm_interface.h" | 11 | #include "core/arm/arm_interface.h" |
| 11 | #include "core/arm/skyeye_common/armstate.h" | 12 | #include "core/arm/skyeye_common/armstate.h" |
| 12 | 13 | ||
| 14 | namespace Memory { | ||
| 15 | struct PageTable; | ||
| 16 | } // namespace Memory | ||
| 17 | |||
| 13 | class ARM_Dynarmic final : public ARM_Interface { | 18 | class ARM_Dynarmic final : public ARM_Interface { |
| 14 | public: | 19 | public: |
| 15 | ARM_Dynarmic(PrivilegeMode initial_mode); | 20 | ARM_Dynarmic(PrivilegeMode initial_mode); |
| 16 | 21 | ||
| 22 | void MapBackingMemory(VAddr address, size_t size, u8* memory, Kernel::VMAPermission perms) override; | ||
| 23 | |||
| 17 | void SetPC(u64 pc) override; | 24 | void SetPC(u64 pc) override; |
| 18 | u64 GetPC() const override; | 25 | u64 GetPC() const override; |
| 19 | u64 GetReg(int index) const override; | 26 | u64 GetReg(int index) const override; |
| 20 | void SetReg(int index, u64 value) override; | 27 | void SetReg(int index, u64 value) override; |
| 28 | const u128& GetExtReg(int index) const override; | ||
| 29 | void SetExtReg(int index, u128& value) override; | ||
| 21 | u32 GetVFPReg(int index) const override; | 30 | u32 GetVFPReg(int index) const override; |
| 22 | void SetVFPReg(int index, u32 value) override; | 31 | void SetVFPReg(int index, u32 value) override; |
| 23 | u32 GetVFPSystemReg(VFPSystemRegister reg) const override; | 32 | u32 GetVFPSystemReg(VFPSystemRegister reg) const override; |
| @@ -29,8 +38,6 @@ public: | |||
| 29 | VAddr GetTlsAddress() const override; | 38 | VAddr GetTlsAddress() const override; |
| 30 | void SetTlsAddress(VAddr address) override; | 39 | void SetTlsAddress(VAddr address) override; |
| 31 | 40 | ||
| 32 | void AddTicks(u64 ticks) override; | ||
| 33 | |||
| 34 | void SaveContext(ThreadContext& ctx) override; | 41 | void SaveContext(ThreadContext& ctx) override; |
| 35 | void LoadContext(const ThreadContext& ctx) override; | 42 | void LoadContext(const ThreadContext& ctx) override; |
| 36 | 43 | ||
| @@ -38,8 +45,10 @@ public: | |||
| 38 | void ExecuteInstructions(int num_instructions) override; | 45 | void ExecuteInstructions(int num_instructions) override; |
| 39 | 46 | ||
| 40 | void ClearInstructionCache() override; | 47 | void ClearInstructionCache() override; |
| 48 | void PageTableChanged() override; | ||
| 41 | 49 | ||
| 42 | private: | 50 | private: |
| 43 | std::unique_ptr<Dynarmic::Jit> jit; | 51 | Dynarmic::Jit* jit = nullptr; |
| 44 | std::shared_ptr<ARMul_State> interpreter_state; | 52 | Memory::PageTable* current_page_table = nullptr; |
| 53 | std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::Jit>> jits; | ||
| 45 | }; | 54 | }; |