summaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
authorGravatar Lioncash2019-04-06 18:46:18 -0400
committerGravatar Lioncash2019-04-07 20:30:05 -0400
commitb117ca5fce0344997a09260d835b27dbd2602507 (patch)
treea351c981e559de4cb31142b4b7436a638511c0f3 /src/core/arm
parentMerge pull request #2300 from FernandoS27/null-shader (diff)
downloadyuzu-b117ca5fce0344997a09260d835b27dbd2602507.tar.gz
yuzu-b117ca5fce0344997a09260d835b27dbd2602507.tar.xz
yuzu-b117ca5fce0344997a09260d835b27dbd2602507.zip
kernel/svc: Deglobalize the supervisor call handlers
Adjusts the interface of the wrappers to take a system reference, which allows accessing a system instance without using the global accessors. This also allows getting rid of all global accessors within the supervisor call handling code. While this does make the wrappers themselves slightly more noisy, this will be further cleaned up in a follow-up. This eliminates the global system accessors in the current code while preserving the existing interface.
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp17
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h10
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp37
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h12
4 files changed, 37 insertions, 39 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 49145911b..dc96e35d5 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -14,6 +14,7 @@
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/core_timing_util.h" 15#include "core/core_timing_util.h"
16#include "core/gdbstub/gdbstub.h" 16#include "core/gdbstub/gdbstub.h"
17#include "core/hle/kernel/kernel.h"
17#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/svc.h" 19#include "core/hle/kernel/svc.h"
19#include "core/hle/kernel/vm_manager.h" 20#include "core/hle/kernel/vm_manager.h"
@@ -99,7 +100,7 @@ public:
99 } 100 }
100 101
101 void CallSVC(u32 swi) override { 102 void CallSVC(u32 swi) override {
102 Kernel::CallSVC(swi); 103 Kernel::CallSVC(parent.system, swi);
103 } 104 }
104 105
105 void AddTicks(u64 ticks) override { 106 void AddTicks(u64 ticks) override {
@@ -112,14 +113,14 @@ public:
112 // Always execute at least one tick. 113 // Always execute at least one tick.
113 amortized_ticks = std::max<u64>(amortized_ticks, 1); 114 amortized_ticks = std::max<u64>(amortized_ticks, 1);
114 115
115 parent.core_timing.AddTicks(amortized_ticks); 116 parent.system.CoreTiming().AddTicks(amortized_ticks);
116 num_interpreted_instructions = 0; 117 num_interpreted_instructions = 0;
117 } 118 }
118 u64 GetTicksRemaining() override { 119 u64 GetTicksRemaining() override {
119 return std::max(parent.core_timing.GetDowncount(), 0); 120 return std::max(parent.system.CoreTiming().GetDowncount(), 0);
120 } 121 }
121 u64 GetCNTPCT() override { 122 u64 GetCNTPCT() override {
122 return Timing::CpuCyclesToClockCycles(parent.core_timing.GetTicks()); 123 return Timing::CpuCyclesToClockCycles(parent.system.CoreTiming().GetTicks());
123 } 124 }
124 125
125 ARM_Dynarmic& parent; 126 ARM_Dynarmic& parent;
@@ -129,7 +130,7 @@ public:
129}; 130};
130 131
131std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { 132std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
132 auto* current_process = Core::CurrentProcess(); 133 auto* current_process = system.Kernel().CurrentProcess();
133 auto** const page_table = current_process->VMManager().page_table.pointers.data(); 134 auto** const page_table = current_process->VMManager().page_table.pointers.data();
134 135
135 Dynarmic::A64::UserConfig config; 136 Dynarmic::A64::UserConfig config;
@@ -171,10 +172,10 @@ void ARM_Dynarmic::Step() {
171 cb->InterpreterFallback(jit->GetPC(), 1); 172 cb->InterpreterFallback(jit->GetPC(), 1);
172} 173}
173 174
174ARM_Dynarmic::ARM_Dynarmic(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor, 175ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor,
175 std::size_t core_index) 176 std::size_t core_index)
176 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{core_timing}, 177 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
177 core_index{core_index}, core_timing{core_timing}, 178 core_index{core_index}, system{system},
178 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} { 179 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {
179 ThreadContext ctx{}; 180 ThreadContext ctx{};
180 inner_unicorn.SaveContext(ctx); 181 inner_unicorn.SaveContext(ctx);
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index d867c2a50..c1db254e8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -12,19 +12,15 @@
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 Core::Timing {
16class CoreTiming;
17}
18
19namespace Core { 15namespace Core {
20 16
21class ARM_Dynarmic_Callbacks; 17class ARM_Dynarmic_Callbacks;
22class DynarmicExclusiveMonitor; 18class DynarmicExclusiveMonitor;
19class System;
23 20
24class ARM_Dynarmic final : public ARM_Interface { 21class ARM_Dynarmic final : public ARM_Interface {
25public: 22public:
26 ARM_Dynarmic(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor, 23 ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor, std::size_t core_index);
27 std::size_t core_index);
28 ~ARM_Dynarmic() override; 24 ~ARM_Dynarmic() override;
29 25
30 void MapBackingMemory(VAddr address, std::size_t size, u8* memory, 26 void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
@@ -63,7 +59,7 @@ private:
63 ARM_Unicorn inner_unicorn; 59 ARM_Unicorn inner_unicorn;
64 60
65 std::size_t core_index; 61 std::size_t core_index;
66 Timing::CoreTiming& core_timing; 62 System& system;
67 DynarmicExclusiveMonitor& exclusive_monitor; 63 DynarmicExclusiveMonitor& exclusive_monitor;
68}; 64};
69 65
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 27309280c..4e07fe8b5 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -10,7 +10,6 @@
10#include "core/core.h" 10#include "core/core.h"
11#include "core/core_timing.h" 11#include "core/core_timing.h"
12#include "core/hle/kernel/svc.h" 12#include "core/hle/kernel/svc.h"
13#include "core/memory.h"
14 13
15namespace Core { 14namespace Core {
16 15
@@ -49,20 +48,6 @@ static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_
49 } 48 }
50} 49}
51 50
52static void InterruptHook(uc_engine* uc, u32 intNo, void* user_data) {
53 u32 esr{};
54 CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
55
56 auto ec = esr >> 26;
57 auto iss = esr & 0xFFFFFF;
58
59 switch (ec) {
60 case 0x15: // SVC
61 Kernel::CallSVC(iss);
62 break;
63 }
64}
65
66static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value, 51static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value,
67 void* user_data) { 52 void* user_data) {
68 ARM_Interface::ThreadContext ctx{}; 53 ARM_Interface::ThreadContext ctx{};
@@ -72,7 +57,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
72 return {}; 57 return {};
73} 58}
74 59
75ARM_Unicorn::ARM_Unicorn(Timing::CoreTiming& core_timing) : core_timing{core_timing} { 60ARM_Unicorn::ARM_Unicorn(System& system) : system{system} {
76 CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); 61 CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
77 62
78 auto fpv = 3 << 20; 63 auto fpv = 3 << 20;
@@ -177,7 +162,7 @@ void ARM_Unicorn::Run() {
177 if (GDBStub::IsServerEnabled()) { 162 if (GDBStub::IsServerEnabled()) {
178 ExecuteInstructions(std::max(4000000, 0)); 163 ExecuteInstructions(std::max(4000000, 0));
179 } else { 164 } else {
180 ExecuteInstructions(std::max(core_timing.GetDowncount(), 0)); 165 ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), 0));
181 } 166 }
182} 167}
183 168
@@ -190,7 +175,7 @@ MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
190void ARM_Unicorn::ExecuteInstructions(int num_instructions) { 175void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
191 MICROPROFILE_SCOPE(ARM_Jit_Unicorn); 176 MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
192 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); 177 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
193 core_timing.AddTicks(num_instructions); 178 system.CoreTiming().AddTicks(num_instructions);
194 if (GDBStub::IsServerEnabled()) { 179 if (GDBStub::IsServerEnabled()) {
195 if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) { 180 if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) {
196 uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address); 181 uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address);
@@ -273,4 +258,20 @@ void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) {
273 last_bkpt_hit = true; 258 last_bkpt_hit = true;
274} 259}
275 260
261void ARM_Unicorn::InterruptHook(uc_engine* uc, u32 int_no, void* user_data) {
262 u32 esr{};
263 CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
264
265 const auto ec = esr >> 26;
266 const auto iss = esr & 0xFFFFFF;
267
268 auto* const arm_instance = static_cast<ARM_Unicorn*>(user_data);
269
270 switch (ec) {
271 case 0x15: // SVC
272 Kernel::CallSVC(arm_instance->system, iss);
273 break;
274 }
275}
276
276} // namespace Core 277} // namespace Core
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index 1e44f0736..209fc16ad 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -9,15 +9,13 @@
9#include "core/arm/arm_interface.h" 9#include "core/arm/arm_interface.h"
10#include "core/gdbstub/gdbstub.h" 10#include "core/gdbstub/gdbstub.h"
11 11
12namespace Core::Timing {
13class CoreTiming;
14}
15
16namespace Core { 12namespace Core {
17 13
14class System;
15
18class ARM_Unicorn final : public ARM_Interface { 16class ARM_Unicorn final : public ARM_Interface {
19public: 17public:
20 explicit ARM_Unicorn(Timing::CoreTiming& core_timing); 18 explicit ARM_Unicorn(System& system);
21 ~ARM_Unicorn() override; 19 ~ARM_Unicorn() override;
22 20
23 void MapBackingMemory(VAddr address, std::size_t size, u8* memory, 21 void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
@@ -47,8 +45,10 @@ public:
47 void RecordBreak(GDBStub::BreakpointAddress bkpt); 45 void RecordBreak(GDBStub::BreakpointAddress bkpt);
48 46
49private: 47private:
48 static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data);
49
50 uc_engine* uc{}; 50 uc_engine* uc{};
51 Timing::CoreTiming& core_timing; 51 System& system;
52 GDBStub::BreakpointAddress last_bkpt{}; 52 GDBStub::BreakpointAddress last_bkpt{};
53 bool last_bkpt_hit = false; 53 bool last_bkpt_hit = false;
54}; 54};