summaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
authorGravatar bunnei2019-11-28 11:43:17 -0500
committerGravatar GitHub2019-11-28 11:43:17 -0500
commite3ee017e91ef4d713f1af8cb60c5157e40d43f18 (patch)
treee0a5b47cac1d548599b8ceba7f71b40746fe6b48 /src/core/arm
parentMerge pull request #3171 from lioncash/internal-link (diff)
parentcore/memory; Migrate over SetCurrentPageTable() to the Memory class (diff)
downloadyuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.gz
yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.xz
yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.zip
Merge pull request #3169 from lioncash/memory
core/memory: Deglobalize memory management code
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/arm_interface.cpp27
-rw-r--r--src/core/arm/arm_interface.h8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp48
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h8
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp2
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h1
6 files changed, 53 insertions, 41 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 372612c9b..7e846ddd5 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -13,7 +13,6 @@
13#include "core/memory.h" 13#include "core/memory.h"
14 14
15namespace Core { 15namespace Core {
16
17namespace { 16namespace {
18 17
19constexpr u64 ELF_DYNAMIC_TAG_NULL = 0; 18constexpr u64 ELF_DYNAMIC_TAG_NULL = 0;
@@ -61,15 +60,15 @@ static_assert(sizeof(ELFSymbol) == 0x18, "ELFSymbol has incorrect size.");
61 60
62using Symbols = std::vector<std::pair<ELFSymbol, std::string>>; 61using Symbols = std::vector<std::pair<ELFSymbol, std::string>>;
63 62
64Symbols GetSymbols(VAddr text_offset) { 63Symbols GetSymbols(VAddr text_offset, Memory::Memory& memory) {
65 const auto mod_offset = text_offset + Memory::Read32(text_offset + 4); 64 const auto mod_offset = text_offset + memory.Read32(text_offset + 4);
66 65
67 if (mod_offset < text_offset || (mod_offset & 0b11) != 0 || 66 if (mod_offset < text_offset || (mod_offset & 0b11) != 0 ||
68 Memory::Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) { 67 memory.Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) {
69 return {}; 68 return {};
70 } 69 }
71 70
72 const auto dynamic_offset = Memory::Read32(mod_offset + 0x4) + mod_offset; 71 const auto dynamic_offset = memory.Read32(mod_offset + 0x4) + mod_offset;
73 72
74 VAddr string_table_offset{}; 73 VAddr string_table_offset{};
75 VAddr symbol_table_offset{}; 74 VAddr symbol_table_offset{};
@@ -77,8 +76,8 @@ Symbols GetSymbols(VAddr text_offset) {
77 76
78 VAddr dynamic_index = dynamic_offset; 77 VAddr dynamic_index = dynamic_offset;
79 while (true) { 78 while (true) {
80 const auto tag = Memory::Read64(dynamic_index); 79 const u64 tag = memory.Read64(dynamic_index);
81 const auto value = Memory::Read64(dynamic_index + 0x8); 80 const u64 value = memory.Read64(dynamic_index + 0x8);
82 dynamic_index += 0x10; 81 dynamic_index += 0x10;
83 82
84 if (tag == ELF_DYNAMIC_TAG_NULL) { 83 if (tag == ELF_DYNAMIC_TAG_NULL) {
@@ -106,11 +105,11 @@ Symbols GetSymbols(VAddr text_offset) {
106 VAddr symbol_index = symbol_table_address; 105 VAddr symbol_index = symbol_table_address;
107 while (symbol_index < string_table_address) { 106 while (symbol_index < string_table_address) {
108 ELFSymbol symbol{}; 107 ELFSymbol symbol{};
109 Memory::ReadBlock(symbol_index, &symbol, sizeof(ELFSymbol)); 108 memory.ReadBlock(symbol_index, &symbol, sizeof(ELFSymbol));
110 109
111 VAddr string_offset = string_table_address + symbol.name_index; 110 VAddr string_offset = string_table_address + symbol.name_index;
112 std::string name; 111 std::string name;
113 for (u8 c = Memory::Read8(string_offset); c != 0; c = Memory::Read8(++string_offset)) { 112 for (u8 c = memory.Read8(string_offset); c != 0; c = memory.Read8(++string_offset)) {
114 name += static_cast<char>(c); 113 name += static_cast<char>(c);
115 } 114 }
116 115
@@ -142,28 +141,28 @@ constexpr u64 SEGMENT_BASE = 0x7100000000ull;
142 141
143std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { 142std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
144 std::vector<BacktraceEntry> out; 143 std::vector<BacktraceEntry> out;
144 auto& memory = system.Memory();
145 145
146 auto fp = GetReg(29); 146 auto fp = GetReg(29);
147 auto lr = GetReg(30); 147 auto lr = GetReg(30);
148
149 while (true) { 148 while (true) {
150 out.push_back({"", 0, lr, 0}); 149 out.push_back({"", 0, lr, 0});
151 if (!fp) { 150 if (!fp) {
152 break; 151 break;
153 } 152 }
154 lr = Memory::Read64(fp + 8) - 4; 153 lr = memory.Read64(fp + 8) - 4;
155 fp = Memory::Read64(fp); 154 fp = memory.Read64(fp);
156 } 155 }
157 156
158 std::map<VAddr, std::string> modules; 157 std::map<VAddr, std::string> modules;
159 auto& loader{System::GetInstance().GetAppLoader()}; 158 auto& loader{system.GetAppLoader()};
160 if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) { 159 if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) {
161 return {}; 160 return {};
162 } 161 }
163 162
164 std::map<std::string, Symbols> symbols; 163 std::map<std::string, Symbols> symbols;
165 for (const auto& module : modules) { 164 for (const auto& module : modules) {
166 symbols.insert_or_assign(module.second, GetSymbols(module.first)); 165 symbols.insert_or_assign(module.second, GetSymbols(module.first, memory));
167 } 166 }
168 167
169 for (auto& entry : out) { 168 for (auto& entry : out) {
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 45e94e625..47b964eb7 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -17,11 +17,13 @@ enum class VMAPermission : u8;
17} 17}
18 18
19namespace Core { 19namespace Core {
20class System;
20 21
21/// Generic ARMv8 CPU interface 22/// Generic ARMv8 CPU interface
22class ARM_Interface : NonCopyable { 23class ARM_Interface : NonCopyable {
23public: 24public:
24 virtual ~ARM_Interface() {} 25 explicit ARM_Interface(System& system_) : system{system_} {}
26 virtual ~ARM_Interface() = default;
25 27
26 struct ThreadContext { 28 struct ThreadContext {
27 std::array<u64, 31> cpu_registers; 29 std::array<u64, 31> cpu_registers;
@@ -163,6 +165,10 @@ public:
163 /// fp+0 : pointer to previous frame record 165 /// fp+0 : pointer to previous frame record
164 /// fp+8 : value of lr for frame 166 /// fp+8 : value of lr for frame
165 void LogBacktrace() const; 167 void LogBacktrace() const;
168
169protected:
170 /// System context that this ARM interface is running under.
171 System& system;
166}; 172};
167 173
168} // namespace Core 174} // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index a0705b2b8..f8c7f0efd 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -28,36 +28,38 @@ public:
28 explicit ARM_Dynarmic_Callbacks(ARM_Dynarmic& parent) : parent(parent) {} 28 explicit ARM_Dynarmic_Callbacks(ARM_Dynarmic& parent) : parent(parent) {}
29 29
30 u8 MemoryRead8(u64 vaddr) override { 30 u8 MemoryRead8(u64 vaddr) override {
31 return Memory::Read8(vaddr); 31 return parent.system.Memory().Read8(vaddr);
32 } 32 }
33 u16 MemoryRead16(u64 vaddr) override { 33 u16 MemoryRead16(u64 vaddr) override {
34 return Memory::Read16(vaddr); 34 return parent.system.Memory().Read16(vaddr);
35 } 35 }
36 u32 MemoryRead32(u64 vaddr) override { 36 u32 MemoryRead32(u64 vaddr) override {
37 return Memory::Read32(vaddr); 37 return parent.system.Memory().Read32(vaddr);
38 } 38 }
39 u64 MemoryRead64(u64 vaddr) override { 39 u64 MemoryRead64(u64 vaddr) override {
40 return Memory::Read64(vaddr); 40 return parent.system.Memory().Read64(vaddr);
41 } 41 }
42 Vector MemoryRead128(u64 vaddr) override { 42 Vector MemoryRead128(u64 vaddr) override {
43 return {Memory::Read64(vaddr), Memory::Read64(vaddr + 8)}; 43 auto& memory = parent.system.Memory();
44 return {memory.Read64(vaddr), memory.Read64(vaddr + 8)};
44 } 45 }
45 46
46 void MemoryWrite8(u64 vaddr, u8 value) override { 47 void MemoryWrite8(u64 vaddr, u8 value) override {
47 Memory::Write8(vaddr, value); 48 parent.system.Memory().Write8(vaddr, value);
48 } 49 }
49 void MemoryWrite16(u64 vaddr, u16 value) override { 50 void MemoryWrite16(u64 vaddr, u16 value) override {
50 Memory::Write16(vaddr, value); 51 parent.system.Memory().Write16(vaddr, value);
51 } 52 }
52 void MemoryWrite32(u64 vaddr, u32 value) override { 53 void MemoryWrite32(u64 vaddr, u32 value) override {
53 Memory::Write32(vaddr, value); 54 parent.system.Memory().Write32(vaddr, value);
54 } 55 }
55 void MemoryWrite64(u64 vaddr, u64 value) override { 56 void MemoryWrite64(u64 vaddr, u64 value) override {
56 Memory::Write64(vaddr, value); 57 parent.system.Memory().Write64(vaddr, value);
57 } 58 }
58 void MemoryWrite128(u64 vaddr, Vector value) override { 59 void MemoryWrite128(u64 vaddr, Vector value) override {
59 Memory::Write64(vaddr, value[0]); 60 auto& memory = parent.system.Memory();
60 Memory::Write64(vaddr + 8, value[1]); 61 memory.Write64(vaddr, value[0]);
62 memory.Write64(vaddr + 8, value[1]);
61 } 63 }
62 64
63 void InterpreterFallback(u64 pc, std::size_t num_instructions) override { 65 void InterpreterFallback(u64 pc, std::size_t num_instructions) override {
@@ -171,9 +173,10 @@ void ARM_Dynarmic::Step() {
171 173
172ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor, 174ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor,
173 std::size_t core_index) 175 std::size_t core_index)
174 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system}, 176 : ARM_Interface{system},
175 core_index{core_index}, system{system}, 177 cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
176 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} 178 core_index{core_index}, exclusive_monitor{
179 dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
177 180
178ARM_Dynarmic::~ARM_Dynarmic() = default; 181ARM_Dynarmic::~ARM_Dynarmic() = default;
179 182
@@ -264,7 +267,9 @@ void ARM_Dynarmic::PageTableChanged(Common::PageTable& page_table,
264 jit = MakeJit(page_table, new_address_space_size_in_bits); 267 jit = MakeJit(page_table, new_address_space_size_in_bits);
265} 268}
266 269
267DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(std::size_t core_count) : monitor(core_count) {} 270DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count)
271 : monitor(core_count), memory{memory_} {}
272
268DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; 273DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
269 274
270void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) { 275void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) {
@@ -277,29 +282,28 @@ void DynarmicExclusiveMonitor::ClearExclusive() {
277} 282}
278 283
279bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { 284bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) {
280 return monitor.DoExclusiveOperation(core_index, vaddr, 1, 285 return monitor.DoExclusiveOperation(core_index, vaddr, 1, [&] { memory.Write8(vaddr, value); });
281 [&] { Memory::Write8(vaddr, value); });
282} 286}
283 287
284bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { 288bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) {
285 return monitor.DoExclusiveOperation(core_index, vaddr, 2, 289 return monitor.DoExclusiveOperation(core_index, vaddr, 2,
286 [&] { Memory::Write16(vaddr, value); }); 290 [&] { memory.Write16(vaddr, value); });
287} 291}
288 292
289bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { 293bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) {
290 return monitor.DoExclusiveOperation(core_index, vaddr, 4, 294 return monitor.DoExclusiveOperation(core_index, vaddr, 4,
291 [&] { Memory::Write32(vaddr, value); }); 295 [&] { memory.Write32(vaddr, value); });
292} 296}
293 297
294bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { 298bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) {
295 return monitor.DoExclusiveOperation(core_index, vaddr, 8, 299 return monitor.DoExclusiveOperation(core_index, vaddr, 8,
296 [&] { Memory::Write64(vaddr, value); }); 300 [&] { memory.Write64(vaddr, value); });
297} 301}
298 302
299bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { 303bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) {
300 return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] { 304 return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] {
301 Memory::Write64(vaddr + 0, value[0]); 305 memory.Write64(vaddr + 0, value[0]);
302 Memory::Write64(vaddr + 8, value[1]); 306 memory.Write64(vaddr + 8, value[1]);
303 }); 307 });
304} 308}
305 309
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index 504d46c68..9cd475cfb 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -12,6 +12,10 @@
12#include "core/arm/exclusive_monitor.h" 12#include "core/arm/exclusive_monitor.h"
13#include "core/arm/unicorn/arm_unicorn.h" 13#include "core/arm/unicorn/arm_unicorn.h"
14 14
15namespace Memory {
16class Memory;
17}
18
15namespace Core { 19namespace Core {
16 20
17class ARM_Dynarmic_Callbacks; 21class ARM_Dynarmic_Callbacks;
@@ -58,13 +62,12 @@ private:
58 ARM_Unicorn inner_unicorn; 62 ARM_Unicorn inner_unicorn;
59 63
60 std::size_t core_index; 64 std::size_t core_index;
61 System& system;
62 DynarmicExclusiveMonitor& exclusive_monitor; 65 DynarmicExclusiveMonitor& exclusive_monitor;
63}; 66};
64 67
65class DynarmicExclusiveMonitor final : public ExclusiveMonitor { 68class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
66public: 69public:
67 explicit DynarmicExclusiveMonitor(std::size_t core_count); 70 explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count);
68 ~DynarmicExclusiveMonitor() override; 71 ~DynarmicExclusiveMonitor() override;
69 72
70 void SetExclusive(std::size_t core_index, VAddr addr) override; 73 void SetExclusive(std::size_t core_index, VAddr addr) override;
@@ -79,6 +82,7 @@ public:
79private: 82private:
80 friend class ARM_Dynarmic; 83 friend class ARM_Dynarmic;
81 Dynarmic::A64::ExclusiveMonitor monitor; 84 Dynarmic::A64::ExclusiveMonitor monitor;
85 Memory::Memory& memory;
82}; 86};
83 87
84} // namespace Core 88} // namespace Core
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 9698172db..48182c99a 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -60,7 +60,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
60 return false; 60 return false;
61} 61}
62 62
63ARM_Unicorn::ARM_Unicorn(System& system) : system{system} { 63ARM_Unicorn::ARM_Unicorn(System& system) : ARM_Interface{system} {
64 CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); 64 CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
65 65
66 auto fpv = 3 << 20; 66 auto fpv = 3 << 20;
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index b39426ea0..3c5b155f9 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -45,7 +45,6 @@ private:
45 static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data); 45 static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data);
46 46
47 uc_engine* uc{}; 47 uc_engine* uc{};
48 System& system;
49 GDBStub::BreakpointAddress last_bkpt{}; 48 GDBStub::BreakpointAddress last_bkpt{};
50 bool last_bkpt_hit = false; 49 bool last_bkpt_hit = false;
51}; 50};