summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/arm/arm_interface.h3
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp22
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h10
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp4
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h1
-rw-r--r--src/core/memory.cpp5
6 files changed, 39 insertions, 6 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index ccd43f431..2aa017a54 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -41,6 +41,9 @@ public:
41 /// Clear all instruction cache 41 /// Clear all instruction cache
42 virtual void ClearInstructionCache() = 0; 42 virtual void ClearInstructionCache() = 0;
43 43
44 /// Notify CPU emulation that page tables have changed
45 virtual void PageTableChanged() = 0;
46
44 /** 47 /**
45 * Set the Program Counter to an address 48 * Set the Program Counter to an address
46 * @param addr Address to set PC to 49 * @param addr Address to set PC to
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 34c5aa381..42ae93ae8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -41,7 +41,7 @@ static bool IsReadOnlyMemory(u32 vaddr) {
41} 41}
42 42
43static Dynarmic::UserCallbacks GetUserCallbacks( 43static Dynarmic::UserCallbacks GetUserCallbacks(
44 const std::shared_ptr<ARMul_State>& interpeter_state) { 44 const std::shared_ptr<ARMul_State>& interpeter_state, Memory::PageTable* current_page_table) {
45 Dynarmic::UserCallbacks user_callbacks{}; 45 Dynarmic::UserCallbacks user_callbacks{};
46 user_callbacks.InterpreterFallback = &InterpreterFallback; 46 user_callbacks.InterpreterFallback = &InterpreterFallback;
47 user_callbacks.user_arg = static_cast<void*>(interpeter_state.get()); 47 user_callbacks.user_arg = static_cast<void*>(interpeter_state.get());
@@ -56,16 +56,14 @@ static Dynarmic::UserCallbacks GetUserCallbacks(
56 user_callbacks.memory.Write16 = &Memory::Write16; 56 user_callbacks.memory.Write16 = &Memory::Write16;
57 user_callbacks.memory.Write32 = &Memory::Write32; 57 user_callbacks.memory.Write32 = &Memory::Write32;
58 user_callbacks.memory.Write64 = &Memory::Write64; 58 user_callbacks.memory.Write64 = &Memory::Write64;
59 // TODO(Subv): Re-add the page table pointers once dynarmic supports switching page tables at 59 user_callbacks.page_table = &current_page_table->pointers;
60 // runtime.
61 user_callbacks.page_table = nullptr;
62 user_callbacks.coprocessors[15] = std::make_shared<DynarmicCP15>(interpeter_state); 60 user_callbacks.coprocessors[15] = std::make_shared<DynarmicCP15>(interpeter_state);
63 return user_callbacks; 61 return user_callbacks;
64} 62}
65 63
66ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) { 64ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) {
67 interpreter_state = std::make_shared<ARMul_State>(initial_mode); 65 interpreter_state = std::make_shared<ARMul_State>(initial_mode);
68 jit = std::make_unique<Dynarmic::Jit>(GetUserCallbacks(interpreter_state)); 66 PageTableChanged();
69} 67}
70 68
71void ARM_Dynarmic::SetPC(u32 pc) { 69void ARM_Dynarmic::SetPC(u32 pc) {
@@ -136,6 +134,7 @@ void ARM_Dynarmic::AddTicks(u64 ticks) {
136MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); 134MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
137 135
138void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { 136void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
137 ASSERT(Memory::GetCurrentPageTable() == current_page_table);
139 MICROPROFILE_SCOPE(ARM_Jit); 138 MICROPROFILE_SCOPE(ARM_Jit);
140 139
141 std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions)); 140 std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions));
@@ -178,3 +177,16 @@ void ARM_Dynarmic::PrepareReschedule() {
178void ARM_Dynarmic::ClearInstructionCache() { 177void ARM_Dynarmic::ClearInstructionCache() {
179 jit->ClearCache(); 178 jit->ClearCache();
180} 179}
180
181void ARM_Dynarmic::PageTableChanged() {
182 current_page_table = Memory::GetCurrentPageTable();
183
184 auto iter = jits.find(current_page_table);
185 if (iter != jits.end()) {
186 jit = iter->second.get();
187 return;
188 }
189
190 jit = new Dynarmic::Jit(GetUserCallbacks(interpreter_state, current_page_table));
191 jits.emplace(current_page_table, std::unique_ptr<Dynarmic::Jit>(jit));
192}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index 834dc989e..96148a1a5 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -4,12 +4,17 @@
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
14namespace Memory {
15struct PageTable;
16} // namespace Memory
17
13class ARM_Dynarmic final : public ARM_Interface { 18class ARM_Dynarmic final : public ARM_Interface {
14public: 19public:
15 ARM_Dynarmic(PrivilegeMode initial_mode); 20 ARM_Dynarmic(PrivilegeMode initial_mode);
@@ -36,8 +41,11 @@ public:
36 void ExecuteInstructions(int num_instructions) override; 41 void ExecuteInstructions(int num_instructions) override;
37 42
38 void ClearInstructionCache() override; 43 void ClearInstructionCache() override;
44 void PageTableChanged() override;
39 45
40private: 46private:
41 std::unique_ptr<Dynarmic::Jit> jit; 47 Dynarmic::Jit* jit = nullptr;
48 Memory::PageTable* current_page_table = nullptr;
49 std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::Jit>> jits;
42 std::shared_ptr<ARMul_State> interpreter_state; 50 std::shared_ptr<ARMul_State> interpreter_state;
43}; 51};
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 81f9bf99e..da955c9b9 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -25,6 +25,10 @@ void ARM_DynCom::ClearInstructionCache() {
25 trans_cache_buf_top = 0; 25 trans_cache_buf_top = 0;
26} 26}
27 27
28void ARM_DynCom::PageTableChanged() {
29 ClearInstructionCache();
30}
31
28void ARM_DynCom::SetPC(u32 pc) { 32void ARM_DynCom::SetPC(u32 pc) {
29 state->Reg[15] = pc; 33 state->Reg[15] = pc;
30} 34}
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
index 62c174f3c..0ae535671 100644
--- a/src/core/arm/dyncom/arm_dyncom.h
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -16,6 +16,7 @@ public:
16 ~ARM_DynCom(); 16 ~ARM_DynCom();
17 17
18 void ClearInstructionCache() override; 18 void ClearInstructionCache() override;
19 void PageTableChanged() override;
19 20
20 void SetPC(u32 pc) override; 21 void SetPC(u32 pc) override;
21 u32 GetPC() const override; 22 u32 GetPC() const override;
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 67ba732ad..a6b5f6c99 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -9,6 +9,8 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "common/swap.h" 11#include "common/swap.h"
12#include "core/arm/arm_interface.h"
13#include "core/core.h"
12#include "core/hle/kernel/memory.h" 14#include "core/hle/kernel/memory.h"
13#include "core/hle/kernel/process.h" 15#include "core/hle/kernel/process.h"
14#include "core/hle/lock.h" 16#include "core/hle/lock.h"
@@ -26,6 +28,9 @@ static PageTable* current_page_table = nullptr;
26 28
27void SetCurrentPageTable(PageTable* page_table) { 29void SetCurrentPageTable(PageTable* page_table) {
28 current_page_table = page_table; 30 current_page_table = page_table;
31 if (Core::System::GetInstance().IsPoweredOn()) {
32 Core::CPU().PageTableChanged();
33 }
29} 34}
30 35
31PageTable* GetCurrentPageTable() { 36PageTable* GetCurrentPageTable() {