diff options
| author | 2019-04-06 18:46:18 -0400 | |
|---|---|---|
| committer | 2019-04-07 20:30:05 -0400 | |
| commit | b117ca5fce0344997a09260d835b27dbd2602507 (patch) | |
| tree | a351c981e559de4cb31142b4b7436a638511c0f3 /src/core/arm/unicorn | |
| parent | Merge pull request #2300 from FernandoS27/null-shader (diff) | |
| download | yuzu-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/unicorn')
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 37 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.h | 12 |
2 files changed, 25 insertions, 24 deletions
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 | ||
| 15 | namespace Core { | 14 | namespace 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 | ||
| 52 | static 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 | |||
| 66 | static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value, | 51 | static 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 | ||
| 75 | ARM_Unicorn::ARM_Unicorn(Timing::CoreTiming& core_timing) : core_timing{core_timing} { | 60 | ARM_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)); | |||
| 190 | void ARM_Unicorn::ExecuteInstructions(int num_instructions) { | 175 | void 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 | ||
| 261 | void 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 | ||
| 12 | namespace Core::Timing { | ||
| 13 | class CoreTiming; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Core { | 12 | namespace Core { |
| 17 | 13 | ||
| 14 | class System; | ||
| 15 | |||
| 18 | class ARM_Unicorn final : public ARM_Interface { | 16 | class ARM_Unicorn final : public ARM_Interface { |
| 19 | public: | 17 | public: |
| 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 | ||
| 49 | private: | 47 | private: |
| 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 | }; |