summaryrefslogtreecommitdiff
path: root/src/core/arm/dynarmic
diff options
context:
space:
mode:
authorGravatar MerryMage2018-07-03 14:28:46 +0100
committerGravatar MerryMage2018-07-22 15:55:17 +0100
commit0b1c2e5505c6478ef10e65c0b002eeb242e15540 (patch)
tree187eeabceb451d3cd89b3f0fd47412a7a9e57015 /src/core/arm/dynarmic
parentMerge pull request #765 from lioncash/file (diff)
downloadyuzu-0b1c2e5505c6478ef10e65c0b002eeb242e15540.tar.gz
yuzu-0b1c2e5505c6478ef10e65c0b002eeb242e15540.tar.xz
yuzu-0b1c2e5505c6478ef10e65c0b002eeb242e15540.zip
Implement exclusive monitor
Diffstat (limited to 'src/core/arm/dynarmic')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp67
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h30
2 files changed, 89 insertions, 8 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 5d7efc9b6..83c09db2b 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -102,18 +102,28 @@ public:
102 u64 tpidr_el0 = 0; 102 u64 tpidr_el0 = 0;
103}; 103};
104 104
105std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_Callbacks>& cb) { 105std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() {
106 const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data(); 106 const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data();
107 107
108 Dynarmic::A64::UserConfig config; 108 Dynarmic::A64::UserConfig config;
109
110 // Callbacks
109 config.callbacks = cb.get(); 111 config.callbacks = cb.get();
112
113 // Memory
114 config.page_table = reinterpret_cast<void**>(page_table);
115 config.page_table_address_space_bits = Memory::ADDRESS_SPACE_BITS;
116 config.silently_mirror_page_table = false;
117
118 // Multi-process state
119 config.processor_id = core_index;
120 config.global_monitor = &exclusive_monitor->monitor;
121
122 // System registers
110 config.tpidrro_el0 = &cb->tpidrro_el0; 123 config.tpidrro_el0 = &cb->tpidrro_el0;
111 config.tpidr_el0 = &cb->tpidr_el0; 124 config.tpidr_el0 = &cb->tpidr_el0;
112 config.dczid_el0 = 4; 125 config.dczid_el0 = 4;
113 config.ctr_el0 = 0x8444c004; 126 config.ctr_el0 = 0x8444c004;
114 config.page_table = reinterpret_cast<void**>(page_table);
115 config.page_table_address_space_bits = Memory::ADDRESS_SPACE_BITS;
116 config.silently_mirror_page_table = false;
117 127
118 return std::make_unique<Dynarmic::A64::Jit>(config); 128 return std::make_unique<Dynarmic::A64::Jit>(config);
119} 129}
@@ -128,8 +138,11 @@ void ARM_Dynarmic::Step() {
128 cb->InterpreterFallback(jit->GetPC(), 1); 138 cb->InterpreterFallback(jit->GetPC(), 1);
129} 139}
130 140
131ARM_Dynarmic::ARM_Dynarmic() 141ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index)
132 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) { 142 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)),
143 jit(MakeJit()), exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(
144 exclusive_monitor)},
145 core_index{core_index} {
133 ARM_Interface::ThreadContext ctx; 146 ARM_Interface::ThreadContext ctx;
134 inner_unicorn.SaveContext(ctx); 147 inner_unicorn.SaveContext(ctx);
135 LoadContext(ctx); 148 LoadContext(ctx);
@@ -237,6 +250,46 @@ void ARM_Dynarmic::ClearExclusiveState() {
237} 250}
238 251
239void ARM_Dynarmic::PageTableChanged() { 252void ARM_Dynarmic::PageTableChanged() {
240 jit = MakeJit(cb); 253 jit = MakeJit();
241 current_page_table = Memory::GetCurrentPageTable(); 254 current_page_table = Memory::GetCurrentPageTable();
242} 255}
256
257DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(size_t core_count) : monitor(core_count) {}
258DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
259
260void DynarmicExclusiveMonitor::SetExclusive(size_t core_index, u64 addr) {
261 // Size doesn't actually matter.
262 monitor.Mark(core_index, addr, 16);
263}
264
265void DynarmicExclusiveMonitor::ClearExclusive() {
266 monitor.Clear();
267}
268
269bool DynarmicExclusiveMonitor::ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) {
270 return monitor.DoExclusiveOperation(core_index, vaddr, 1,
271 [&] { Memory::Write8(vaddr, value); });
272}
273
274bool DynarmicExclusiveMonitor::ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) {
275 return monitor.DoExclusiveOperation(core_index, vaddr, 2,
276 [&] { Memory::Write16(vaddr, value); });
277}
278
279bool DynarmicExclusiveMonitor::ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) {
280 return monitor.DoExclusiveOperation(core_index, vaddr, 4,
281 [&] { Memory::Write32(vaddr, value); });
282}
283
284bool DynarmicExclusiveMonitor::ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) {
285 return monitor.DoExclusiveOperation(core_index, vaddr, 8,
286 [&] { Memory::Write64(vaddr, value); });
287}
288
289bool DynarmicExclusiveMonitor::ExclusiveWrite128(size_t core_index, u64 vaddr,
290 std::array<std::uint64_t, 2> value) {
291 return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] {
292 Memory::Write64(vaddr, value[0]);
293 Memory::Write64(vaddr, value[1]);
294 });
295}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index a9891ac4f..0fa8b417c 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -6,15 +6,18 @@
6 6
7#include <memory> 7#include <memory>
8#include <dynarmic/A64/a64.h> 8#include <dynarmic/A64/a64.h>
9#include <dynarmic/A64/exclusive_monitor.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"
12#include "core/arm/exclusive_monitor.h"
11#include "core/arm/unicorn/arm_unicorn.h" 13#include "core/arm/unicorn/arm_unicorn.h"
12 14
13class ARM_Dynarmic_Callbacks; 15class ARM_Dynarmic_Callbacks;
16class DynarmicExclusiveMonitor;
14 17
15class ARM_Dynarmic final : public ARM_Interface { 18class ARM_Dynarmic final : public ARM_Interface {
16public: 19public:
17 ARM_Dynarmic(); 20 ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index);
18 ~ARM_Dynarmic(); 21 ~ARM_Dynarmic();
19 22
20 void MapBackingMemory(VAddr address, size_t size, u8* memory, 23 void MapBackingMemory(VAddr address, size_t size, u8* memory,
@@ -47,10 +50,35 @@ public:
47 void PageTableChanged() override; 50 void PageTableChanged() override;
48 51
49private: 52private:
53 std::unique_ptr<Dynarmic::A64::Jit> MakeJit();
54
50 friend class ARM_Dynarmic_Callbacks; 55 friend class ARM_Dynarmic_Callbacks;
51 std::unique_ptr<ARM_Dynarmic_Callbacks> cb; 56 std::unique_ptr<ARM_Dynarmic_Callbacks> cb;
52 std::unique_ptr<Dynarmic::A64::Jit> jit; 57 std::unique_ptr<Dynarmic::A64::Jit> jit;
53 ARM_Unicorn inner_unicorn; 58 ARM_Unicorn inner_unicorn;
54 59
60 size_t core_index;
61 std::shared_ptr<DynarmicExclusiveMonitor> exclusive_monitor;
62
55 Memory::PageTable* current_page_table = nullptr; 63 Memory::PageTable* current_page_table = nullptr;
56}; 64};
65
66class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
67public:
68 explicit DynarmicExclusiveMonitor(size_t core_count);
69 ~DynarmicExclusiveMonitor();
70
71 void SetExclusive(size_t core_index, u64 addr) override;
72 void ClearExclusive() override;
73
74 bool ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) override;
75 bool ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) override;
76 bool ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) override;
77 bool ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) override;
78 bool ExclusiveWrite128(size_t core_index, u64 vaddr,
79 std::array<std::uint64_t, 2> value) override;
80
81private:
82 friend class ARM_Dynarmic;
83 Dynarmic::A64::ExclusiveMonitor monitor;
84};