summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-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
-rw-r--r--src/core/core_cpu.cpp6
-rw-r--r--src/core/frontend/emu_window.h39
-rw-r--r--src/core/hle/kernel/client_port.h2
-rw-r--r--src/core/hle/kernel/client_session.h2
-rw-r--r--src/core/hle/kernel/process.h2
-rw-r--r--src/core/hle/kernel/readable_event.h2
-rw-r--r--src/core/hle/kernel/resource_limit.h2
-rw-r--r--src/core/hle/kernel/server_port.h2
-rw-r--r--src/core/hle/kernel/server_session.cpp9
-rw-r--r--src/core/hle/kernel/server_session.h2
-rw-r--r--src/core/hle/kernel/shared_memory.h2
-rw-r--r--src/core/hle/kernel/svc.cpp337
-rw-r--r--src/core/hle/kernel/svc.h6
-rw-r--r--src/core/hle/kernel/svc_wrap.h352
-rw-r--r--src/core/hle/kernel/thread.h2
-rw-r--r--src/core/hle/kernel/writable_event.h2
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp15
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp16
-rw-r--r--src/core/settings.h1
23 files changed, 473 insertions, 404 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};
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index e75741db0..ba63c3e61 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -55,13 +55,13 @@ Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_ba
55 : cpu_barrier{cpu_barrier}, core_timing{system.CoreTiming()}, core_index{core_index} { 55 : cpu_barrier{cpu_barrier}, core_timing{system.CoreTiming()}, core_index{core_index} {
56 if (Settings::values.use_cpu_jit) { 56 if (Settings::values.use_cpu_jit) {
57#ifdef ARCHITECTURE_x86_64 57#ifdef ARCHITECTURE_x86_64
58 arm_interface = std::make_unique<ARM_Dynarmic>(core_timing, exclusive_monitor, core_index); 58 arm_interface = std::make_unique<ARM_Dynarmic>(system, exclusive_monitor, core_index);
59#else 59#else
60 arm_interface = std::make_unique<ARM_Unicorn>(); 60 arm_interface = std::make_unique<ARM_Unicorn>(system);
61 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); 61 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
62#endif 62#endif
63 } else { 63 } else {
64 arm_interface = std::make_unique<ARM_Unicorn>(core_timing); 64 arm_interface = std::make_unique<ARM_Unicorn>(system);
65 } 65 }
66 66
67 scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface); 67 scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface);
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h
index d0bcb4660..70a522556 100644
--- a/src/core/frontend/emu_window.h
+++ b/src/core/frontend/emu_window.h
@@ -13,6 +13,23 @@
13namespace Core::Frontend { 13namespace Core::Frontend {
14 14
15/** 15/**
16 * Represents a graphics context that can be used for background computation or drawing. If the
17 * graphics backend doesn't require the context, then the implementation of these methods can be
18 * stubs
19 */
20class GraphicsContext {
21public:
22 /// Makes the graphics context current for the caller thread
23 virtual void MakeCurrent() = 0;
24
25 /// Releases (dunno if this is the "right" word) the context from the caller thread
26 virtual void DoneCurrent() = 0;
27
28 /// Swap buffers to display the next frame
29 virtual void SwapBuffers() = 0;
30};
31
32/**
16 * Abstraction class used to provide an interface between emulation code and the frontend 33 * Abstraction class used to provide an interface between emulation code and the frontend
17 * (e.g. SDL, QGLWidget, GLFW, etc...). 34 * (e.g. SDL, QGLWidget, GLFW, etc...).
18 * 35 *
@@ -30,7 +47,7 @@ namespace Core::Frontend {
30 * - DO NOT TREAT THIS CLASS AS A GUI TOOLKIT ABSTRACTION LAYER. That's not what it is. Please 47 * - DO NOT TREAT THIS CLASS AS A GUI TOOLKIT ABSTRACTION LAYER. That's not what it is. Please
31 * re-read the upper points again and think about it if you don't see this. 48 * re-read the upper points again and think about it if you don't see this.
32 */ 49 */
33class EmuWindow { 50class EmuWindow : public GraphicsContext {
34public: 51public:
35 /// Data structure to store emuwindow configuration 52 /// Data structure to store emuwindow configuration
36 struct WindowConfig { 53 struct WindowConfig {
@@ -40,17 +57,21 @@ public:
40 std::pair<unsigned, unsigned> min_client_area_size; 57 std::pair<unsigned, unsigned> min_client_area_size;
41 }; 58 };
42 59
43 /// Swap buffers to display the next frame
44 virtual void SwapBuffers() = 0;
45
46 /// Polls window events 60 /// Polls window events
47 virtual void PollEvents() = 0; 61 virtual void PollEvents() = 0;
48 62
49 /// Makes the graphics context current for the caller thread 63 /**
50 virtual void MakeCurrent() = 0; 64 * Returns a GraphicsContext that the frontend provides that is shared with the emu window. This
51 65 * context can be used from other threads for background graphics computation. If the frontend
52 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread 66 * is using a graphics backend that doesn't need anything specific to run on a different thread,
53 virtual void DoneCurrent() = 0; 67 * then it can use a stubbed implemenation for GraphicsContext.
68 *
69 * If the return value is null, then the core should assume that the frontend cannot provide a
70 * Shared Context
71 */
72 virtual std::unique_ptr<GraphicsContext> CreateSharedContext() const {
73 return nullptr;
74 }
54 75
55 /** 76 /**
56 * Signal that a touch pressed event has occurred (e.g. mouse click pressed) 77 * Signal that a touch pressed event has occurred (e.g. mouse click pressed)
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index 6cd607206..4921ad4f0 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -25,7 +25,7 @@ public:
25 return name; 25 return name;
26 } 26 }
27 27
28 static const HandleType HANDLE_TYPE = HandleType::ClientPort; 28 static constexpr HandleType HANDLE_TYPE = HandleType::ClientPort;
29 HandleType GetHandleType() const override { 29 HandleType GetHandleType() const override {
30 return HANDLE_TYPE; 30 return HANDLE_TYPE;
31 } 31 }
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index b1f39aad7..09cdff588 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -29,7 +29,7 @@ public:
29 return name; 29 return name;
30 } 30 }
31 31
32 static const HandleType HANDLE_TYPE = HandleType::ClientSession; 32 static constexpr HandleType HANDLE_TYPE = HandleType::ClientSession;
33 HandleType GetHandleType() const override { 33 HandleType GetHandleType() const override {
34 return HANDLE_TYPE; 34 return HANDLE_TYPE;
35 } 35 }
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index f060f2a3b..dda52f4c0 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -85,7 +85,7 @@ public:
85 return name; 85 return name;
86 } 86 }
87 87
88 static const HandleType HANDLE_TYPE = HandleType::Process; 88 static constexpr HandleType HANDLE_TYPE = HandleType::Process;
89 HandleType GetHandleType() const override { 89 HandleType GetHandleType() const override {
90 return HANDLE_TYPE; 90 return HANDLE_TYPE;
91 } 91 }
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h
index 2eb9dcbb7..84215f572 100644
--- a/src/core/hle/kernel/readable_event.h
+++ b/src/core/hle/kernel/readable_event.h
@@ -31,7 +31,7 @@ public:
31 return reset_type; 31 return reset_type;
32 } 32 }
33 33
34 static const HandleType HANDLE_TYPE = HandleType::ReadableEvent; 34 static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent;
35 HandleType GetHandleType() const override { 35 HandleType GetHandleType() const override {
36 return HANDLE_TYPE; 36 return HANDLE_TYPE;
37 } 37 }
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 70e09858a..2613a6bb5 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -41,7 +41,7 @@ public:
41 return GetTypeName(); 41 return GetTypeName();
42 } 42 }
43 43
44 static const HandleType HANDLE_TYPE = HandleType::ResourceLimit; 44 static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit;
45 HandleType GetHandleType() const override { 45 HandleType GetHandleType() const override {
46 return HANDLE_TYPE; 46 return HANDLE_TYPE;
47 } 47 }
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index fef573b71..dc88a1ebd 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -43,7 +43,7 @@ public:
43 return name; 43 return name;
44 } 44 }
45 45
46 static const HandleType HANDLE_TYPE = HandleType::ServerPort; 46 static constexpr HandleType HANDLE_TYPE = HandleType::ServerPort;
47 HandleType GetHandleType() const override { 47 HandleType GetHandleType() const override {
48 return HANDLE_TYPE; 48 return HANDLE_TYPE;
49 } 49 }
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index a6b2cf06a..696a82cd9 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -28,11 +28,9 @@ ServerSession::~ServerSession() {
28 // the emulated application. 28 // the emulated application.
29 29
30 // Decrease the port's connection count. 30 // Decrease the port's connection count.
31 if (parent->port) 31 if (parent->port) {
32 parent->port->ConnectionClosed(); 32 parent->port->ConnectionClosed();
33 33 }
34 // TODO(Subv): Wake up all the ClientSession's waiting threads and set
35 // the SendSyncRequest result to 0xC920181A.
36 34
37 parent->server = nullptr; 35 parent->server = nullptr;
38} 36}
@@ -74,9 +72,6 @@ void ServerSession::ClientDisconnected() {
74 handler->ClientDisconnected(this); 72 handler->ClientDisconnected(this);
75 } 73 }
76 74
77 // TODO(Subv): Force a wake up of all the ServerSession's waiting threads and set
78 // their WaitSynchronization result to 0xC920181A.
79
80 // Clean up the list of client threads with pending requests, they are unneeded now that the 75 // Clean up the list of client threads with pending requests, they are unneeded now that the
81 // client endpoint is closed. 76 // client endpoint is closed.
82 pending_requesting_threads.clear(); 77 pending_requesting_threads.clear();
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index 09b835ff8..738df30f8 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -46,7 +46,7 @@ public:
46 return name; 46 return name;
47 } 47 }
48 48
49 static const HandleType HANDLE_TYPE = HandleType::ServerSession; 49 static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession;
50 HandleType GetHandleType() const override { 50 HandleType GetHandleType() const override {
51 return HANDLE_TYPE; 51 return HANDLE_TYPE;
52 } 52 }
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 37e18c443..c2b6155e1 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -76,7 +76,7 @@ public:
76 return name; 76 return name;
77 } 77 }
78 78
79 static const HandleType HANDLE_TYPE = HandleType::SharedMemory; 79 static constexpr HandleType HANDLE_TYPE = HandleType::SharedMemory;
80 HandleType GetHandleType() const override { 80 HandleType GetHandleType() const override {
81 return HANDLE_TYPE; 81 return HANDLE_TYPE;
82 } 82 }
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 2fd07ab34..e5d4d6b55 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -131,16 +131,15 @@ enum class ResourceLimitValueType {
131 LimitValue, 131 LimitValue,
132}; 132};
133 133
134ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_type, 134ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
135 ResourceLimitValueType value_type) { 135 u32 resource_type, ResourceLimitValueType value_type) {
136 const auto type = static_cast<ResourceType>(resource_type); 136 const auto type = static_cast<ResourceType>(resource_type);
137 if (!IsValidResourceType(type)) { 137 if (!IsValidResourceType(type)) {
138 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); 138 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
139 return ERR_INVALID_ENUM_VALUE; 139 return ERR_INVALID_ENUM_VALUE;
140 } 140 }
141 141
142 const auto& kernel = Core::System::GetInstance().Kernel(); 142 const auto* const current_process = system.Kernel().CurrentProcess();
143 const auto* const current_process = kernel.CurrentProcess();
144 ASSERT(current_process != nullptr); 143 ASSERT(current_process != nullptr);
145 144
146 const auto resource_limit_object = 145 const auto resource_limit_object =
@@ -160,7 +159,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_ty
160} // Anonymous namespace 159} // Anonymous namespace
161 160
162/// Set the process heap to a given Size. It can both extend and shrink the heap. 161/// Set the process heap to a given Size. It can both extend and shrink the heap.
163static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { 162static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) {
164 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); 163 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
165 164
166 // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. 165 // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB.
@@ -175,7 +174,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
175 return ERR_INVALID_SIZE; 174 return ERR_INVALID_SIZE;
176 } 175 }
177 176
178 auto& vm_manager = Core::System::GetInstance().Kernel().CurrentProcess()->VMManager(); 177 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
179 const auto alloc_result = vm_manager.SetHeapSize(heap_size); 178 const auto alloc_result = vm_manager.SetHeapSize(heap_size);
180 if (alloc_result.Failed()) { 179 if (alloc_result.Failed()) {
181 return alloc_result.Code(); 180 return alloc_result.Code();
@@ -185,7 +184,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
185 return RESULT_SUCCESS; 184 return RESULT_SUCCESS;
186} 185}
187 186
188static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { 187static ResultCode SetMemoryPermission(Core::System& system, VAddr addr, u64 size, u32 prot) {
189 LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); 188 LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot);
190 189
191 if (!Common::Is4KBAligned(addr)) { 190 if (!Common::Is4KBAligned(addr)) {
@@ -217,7 +216,7 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
217 return ERR_INVALID_MEMORY_PERMISSIONS; 216 return ERR_INVALID_MEMORY_PERMISSIONS;
218 } 217 }
219 218
220 auto* const current_process = Core::CurrentProcess(); 219 auto* const current_process = system.Kernel().CurrentProcess();
221 auto& vm_manager = current_process->VMManager(); 220 auto& vm_manager = current_process->VMManager();
222 221
223 if (!vm_manager.IsWithinAddressSpace(addr, size)) { 222 if (!vm_manager.IsWithinAddressSpace(addr, size)) {
@@ -242,7 +241,8 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
242 return vm_manager.ReprotectRange(addr, size, converted_permissions); 241 return vm_manager.ReprotectRange(addr, size, converted_permissions);
243} 242}
244 243
245static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attribute) { 244static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask,
245 u32 attribute) {
246 LOG_DEBUG(Kernel_SVC, 246 LOG_DEBUG(Kernel_SVC,
247 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, 247 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
248 size, mask, attribute); 248 size, mask, attribute);
@@ -280,7 +280,7 @@ static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attr
280 return ERR_INVALID_COMBINATION; 280 return ERR_INVALID_COMBINATION;
281 } 281 }
282 282
283 auto& vm_manager = Core::CurrentProcess()->VMManager(); 283 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
284 if (!vm_manager.IsWithinAddressSpace(address, size)) { 284 if (!vm_manager.IsWithinAddressSpace(address, size)) {
285 LOG_ERROR(Kernel_SVC, 285 LOG_ERROR(Kernel_SVC,
286 "Given address (0x{:016X}) is outside the bounds of the address space.", address); 286 "Given address (0x{:016X}) is outside the bounds of the address space.", address);
@@ -291,11 +291,11 @@ static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attr
291} 291}
292 292
293/// Maps a memory range into a different range. 293/// Maps a memory range into a different range.
294static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 294static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
295 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 295 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
296 src_addr, size); 296 src_addr, size);
297 297
298 auto& vm_manager = Core::CurrentProcess()->VMManager(); 298 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
299 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); 299 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size);
300 300
301 if (result.IsError()) { 301 if (result.IsError()) {
@@ -306,11 +306,11 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
306} 306}
307 307
308/// Unmaps a region that was previously mapped with svcMapMemory 308/// Unmaps a region that was previously mapped with svcMapMemory
309static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 309static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
310 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 310 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
311 src_addr, size); 311 src_addr, size);
312 312
313 auto& vm_manager = Core::CurrentProcess()->VMManager(); 313 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
314 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); 314 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size);
315 315
316 if (result.IsError()) { 316 if (result.IsError()) {
@@ -321,7 +321,8 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
321} 321}
322 322
323/// Connect to an OS service given the port name, returns the handle to the port to out 323/// Connect to an OS service given the port name, returns the handle to the port to out
324static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { 324static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
325 VAddr port_name_address) {
325 if (!Memory::IsValidVirtualAddress(port_name_address)) { 326 if (!Memory::IsValidVirtualAddress(port_name_address)) {
326 LOG_ERROR(Kernel_SVC, 327 LOG_ERROR(Kernel_SVC,
327 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", 328 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}",
@@ -340,8 +341,8 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
340 341
341 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); 342 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
342 343
343 auto& kernel = Core::System::GetInstance().Kernel(); 344 auto& kernel = system.Kernel();
344 auto it = kernel.FindNamedPort(port_name); 345 const auto it = kernel.FindNamedPort(port_name);
345 if (!kernel.IsValidNamedPort(it)) { 346 if (!kernel.IsValidNamedPort(it)) {
346 LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); 347 LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
347 return ERR_NOT_FOUND; 348 return ERR_NOT_FOUND;
@@ -353,14 +354,14 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
353 CASCADE_RESULT(client_session, client_port->Connect()); 354 CASCADE_RESULT(client_session, client_port->Connect());
354 355
355 // Return the client session 356 // Return the client session
356 auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 357 auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
357 CASCADE_RESULT(*out_handle, handle_table.Create(client_session)); 358 CASCADE_RESULT(*out_handle, handle_table.Create(client_session));
358 return RESULT_SUCCESS; 359 return RESULT_SUCCESS;
359} 360}
360 361
361/// Makes a blocking IPC call to an OS service. 362/// Makes a blocking IPC call to an OS service.
362static ResultCode SendSyncRequest(Handle handle) { 363static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
363 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 364 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
364 SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle); 365 SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle);
365 if (!session) { 366 if (!session) {
366 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); 367 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
@@ -369,18 +370,18 @@ static ResultCode SendSyncRequest(Handle handle) {
369 370
370 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 371 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
371 372
372 Core::System::GetInstance().PrepareReschedule(); 373 system.PrepareReschedule();
373 374
374 // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server 375 // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server
375 // responds and cause a reschedule. 376 // responds and cause a reschedule.
376 return session->SendSyncRequest(GetCurrentThread()); 377 return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread());
377} 378}
378 379
379/// Get the ID for the specified thread. 380/// Get the ID for the specified thread.
380static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) { 381static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle thread_handle) {
381 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 382 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
382 383
383 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 384 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
384 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 385 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
385 if (!thread) { 386 if (!thread) {
386 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle); 387 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle);
@@ -392,10 +393,10 @@ static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) {
392} 393}
393 394
394/// Gets the ID of the specified process or a specified thread's owning process. 395/// Gets the ID of the specified process or a specified thread's owning process.
395static ResultCode GetProcessId(u64* process_id, Handle handle) { 396static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle handle) {
396 LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); 397 LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
397 398
398 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 399 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
399 const SharedPtr<Process> process = handle_table.Get<Process>(handle); 400 const SharedPtr<Process> process = handle_table.Get<Process>(handle);
400 if (process) { 401 if (process) {
401 *process_id = process->GetProcessID(); 402 *process_id = process->GetProcessID();
@@ -437,8 +438,8 @@ static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thr
437}; 438};
438 439
439/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 440/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
440static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, 441static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address,
441 s64 nano_seconds) { 442 u64 handle_count, s64 nano_seconds) {
442 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", 443 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
443 handles_address, handle_count, nano_seconds); 444 handles_address, handle_count, nano_seconds);
444 445
@@ -457,11 +458,11 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
457 return ERR_OUT_OF_RANGE; 458 return ERR_OUT_OF_RANGE;
458 } 459 }
459 460
460 auto* const thread = GetCurrentThread(); 461 auto* const thread = system.CurrentScheduler().GetCurrentThread();
461 462
462 using ObjectPtr = Thread::ThreadWaitObjects::value_type; 463 using ObjectPtr = Thread::ThreadWaitObjects::value_type;
463 Thread::ThreadWaitObjects objects(handle_count); 464 Thread::ThreadWaitObjects objects(handle_count);
464 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 465 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
465 466
466 for (u64 i = 0; i < handle_count; ++i) { 467 for (u64 i = 0; i < handle_count; ++i) {
467 const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); 468 const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
@@ -507,16 +508,16 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
507 thread->WakeAfterDelay(nano_seconds); 508 thread->WakeAfterDelay(nano_seconds);
508 thread->SetWakeupCallback(DefaultThreadWakeupCallback); 509 thread->SetWakeupCallback(DefaultThreadWakeupCallback);
509 510
510 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 511 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
511 512
512 return RESULT_TIMEOUT; 513 return RESULT_TIMEOUT;
513} 514}
514 515
515/// Resumes a thread waiting on WaitSynchronization 516/// Resumes a thread waiting on WaitSynchronization
516static ResultCode CancelSynchronization(Handle thread_handle) { 517static ResultCode CancelSynchronization(Core::System& system, Handle thread_handle) {
517 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); 518 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
518 519
519 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 520 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
520 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 521 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
521 if (!thread) { 522 if (!thread) {
522 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 523 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -531,8 +532,8 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
531} 532}
532 533
533/// Attempts to locks a mutex, creating it if it does not already exist 534/// Attempts to locks a mutex, creating it if it does not already exist
534static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, 535static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_handle,
535 Handle requesting_thread_handle) { 536 VAddr mutex_addr, Handle requesting_thread_handle) {
536 LOG_TRACE(Kernel_SVC, 537 LOG_TRACE(Kernel_SVC,
537 "called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, " 538 "called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, "
538 "requesting_current_thread_handle=0x{:08X}", 539 "requesting_current_thread_handle=0x{:08X}",
@@ -549,13 +550,13 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
549 return ERR_INVALID_ADDRESS; 550 return ERR_INVALID_ADDRESS;
550 } 551 }
551 552
552 auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 553 auto* const current_process = system.Kernel().CurrentProcess();
553 return current_process->GetMutex().TryAcquire(mutex_addr, holding_thread_handle, 554 return current_process->GetMutex().TryAcquire(mutex_addr, holding_thread_handle,
554 requesting_thread_handle); 555 requesting_thread_handle);
555} 556}
556 557
557/// Unlock a mutex 558/// Unlock a mutex
558static ResultCode ArbitrateUnlock(VAddr mutex_addr) { 559static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {
559 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); 560 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr);
560 561
561 if (Memory::IsKernelVirtualAddress(mutex_addr)) { 562 if (Memory::IsKernelVirtualAddress(mutex_addr)) {
@@ -569,7 +570,7 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
569 return ERR_INVALID_ADDRESS; 570 return ERR_INVALID_ADDRESS;
570 } 571 }
571 572
572 auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 573 auto* const current_process = system.Kernel().CurrentProcess();
573 return current_process->GetMutex().Release(mutex_addr); 574 return current_process->GetMutex().Release(mutex_addr);
574} 575}
575 576
@@ -592,7 +593,7 @@ struct BreakReason {
592}; 593};
593 594
594/// Break program execution 595/// Break program execution
595static void Break(u32 reason, u64 info1, u64 info2) { 596static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
596 BreakReason break_reason{reason}; 597 BreakReason break_reason{reason};
597 bool has_dumped_buffer{}; 598 bool has_dumped_buffer{};
598 599
@@ -670,22 +671,24 @@ static void Break(u32 reason, u64 info1, u64 info2) {
670 Debug_Emulated, 671 Debug_Emulated,
671 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", 672 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
672 reason, info1, info2); 673 reason, info1, info2);
674
673 handle_debug_buffer(info1, info2); 675 handle_debug_buffer(info1, info2);
674 Core::System::GetInstance() 676
675 .ArmInterface(static_cast<std::size_t>(GetCurrentThread()->GetProcessorID())) 677 auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
676 .LogBacktrace(); 678 const auto thread_processor_id = current_thread->GetProcessorID();
679 system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace();
677 ASSERT(false); 680 ASSERT(false);
678 681
679 Core::CurrentProcess()->PrepareForTermination(); 682 system.Kernel().CurrentProcess()->PrepareForTermination();
680 683
681 // Kill the current thread 684 // Kill the current thread
682 GetCurrentThread()->Stop(); 685 current_thread->Stop();
683 Core::System::GetInstance().PrepareReschedule(); 686 system.PrepareReschedule();
684 } 687 }
685} 688}
686 689
687/// Used to output a message on a debug hardware unit - does nothing on a retail unit 690/// Used to output a message on a debug hardware unit - does nothing on a retail unit
688static void OutputDebugString(VAddr address, u64 len) { 691static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr address, u64 len) {
689 if (len == 0) { 692 if (len == 0) {
690 return; 693 return;
691 } 694 }
@@ -696,7 +699,8 @@ static void OutputDebugString(VAddr address, u64 len) {
696} 699}
697 700
698/// Gets system/memory information for the current process 701/// Gets system/memory information for the current process
699static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { 702static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle,
703 u64 info_sub_id) {
700 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, 704 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
701 info_sub_id, handle); 705 info_sub_id, handle);
702 706
@@ -754,7 +758,8 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
754 return ERR_INVALID_ENUM_VALUE; 758 return ERR_INVALID_ENUM_VALUE;
755 } 759 }
756 760
757 const auto& current_process_handle_table = Core::CurrentProcess()->GetHandleTable(); 761 const auto& current_process_handle_table =
762 system.Kernel().CurrentProcess()->GetHandleTable();
758 const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle)); 763 const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle));
759 if (!process) { 764 if (!process) {
760 return ERR_INVALID_HANDLE; 765 return ERR_INVALID_HANDLE;
@@ -844,7 +849,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
844 return ERR_INVALID_COMBINATION; 849 return ERR_INVALID_COMBINATION;
845 } 850 }
846 851
847 Process* const current_process = Core::CurrentProcess(); 852 Process* const current_process = system.Kernel().CurrentProcess();
848 HandleTable& handle_table = current_process->GetHandleTable(); 853 HandleTable& handle_table = current_process->GetHandleTable();
849 const auto resource_limit = current_process->GetResourceLimit(); 854 const auto resource_limit = current_process->GetResourceLimit();
850 if (!resource_limit) { 855 if (!resource_limit) {
@@ -875,7 +880,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
875 return ERR_INVALID_COMBINATION; 880 return ERR_INVALID_COMBINATION;
876 } 881 }
877 882
878 *result = Core::CurrentProcess()->GetRandomEntropy(info_sub_id); 883 *result = system.Kernel().CurrentProcess()->GetRandomEntropy(info_sub_id);
879 return RESULT_SUCCESS; 884 return RESULT_SUCCESS;
880 885
881 case GetInfoType::PrivilegedProcessId: 886 case GetInfoType::PrivilegedProcessId:
@@ -892,15 +897,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
892 return ERR_INVALID_COMBINATION; 897 return ERR_INVALID_COMBINATION;
893 } 898 }
894 899
895 const auto thread = 900 const auto thread = system.Kernel().CurrentProcess()->GetHandleTable().Get<Thread>(
896 Core::CurrentProcess()->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); 901 static_cast<Handle>(handle));
897 if (!thread) { 902 if (!thread) {
898 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", 903 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
899 static_cast<Handle>(handle)); 904 static_cast<Handle>(handle));
900 return ERR_INVALID_HANDLE; 905 return ERR_INVALID_HANDLE;
901 } 906 }
902 907
903 const auto& system = Core::System::GetInstance();
904 const auto& core_timing = system.CoreTiming(); 908 const auto& core_timing = system.CoreTiming();
905 const auto& scheduler = system.CurrentScheduler(); 909 const auto& scheduler = system.CurrentScheduler();
906 const auto* const current_thread = scheduler.GetCurrentThread(); 910 const auto* const current_thread = scheduler.GetCurrentThread();
@@ -927,13 +931,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
927} 931}
928 932
929/// Sets the thread activity 933/// Sets the thread activity
930static ResultCode SetThreadActivity(Handle handle, u32 activity) { 934static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) {
931 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); 935 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity);
932 if (activity > static_cast<u32>(ThreadActivity::Paused)) { 936 if (activity > static_cast<u32>(ThreadActivity::Paused)) {
933 return ERR_INVALID_ENUM_VALUE; 937 return ERR_INVALID_ENUM_VALUE;
934 } 938 }
935 939
936 const auto* current_process = Core::CurrentProcess(); 940 const auto* current_process = system.Kernel().CurrentProcess();
937 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); 941 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
938 if (!thread) { 942 if (!thread) {
939 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); 943 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
@@ -950,7 +954,7 @@ static ResultCode SetThreadActivity(Handle handle, u32 activity) {
950 return ERR_INVALID_HANDLE; 954 return ERR_INVALID_HANDLE;
951 } 955 }
952 956
953 if (thread == GetCurrentThread()) { 957 if (thread == system.CurrentScheduler().GetCurrentThread()) {
954 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 958 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
955 return ERR_BUSY; 959 return ERR_BUSY;
956 } 960 }
@@ -960,10 +964,10 @@ static ResultCode SetThreadActivity(Handle handle, u32 activity) {
960} 964}
961 965
962/// Gets the thread context 966/// Gets the thread context
963static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { 967static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, Handle handle) {
964 LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); 968 LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
965 969
966 const auto* current_process = Core::CurrentProcess(); 970 const auto* current_process = system.Kernel().CurrentProcess();
967 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); 971 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
968 if (!thread) { 972 if (!thread) {
969 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); 973 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
@@ -980,7 +984,7 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
980 return ERR_INVALID_HANDLE; 984 return ERR_INVALID_HANDLE;
981 } 985 }
982 986
983 if (thread == GetCurrentThread()) { 987 if (thread == system.CurrentScheduler().GetCurrentThread()) {
984 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 988 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
985 return ERR_BUSY; 989 return ERR_BUSY;
986 } 990 }
@@ -1001,10 +1005,10 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
1001} 1005}
1002 1006
1003/// Gets the priority for the specified thread 1007/// Gets the priority for the specified thread
1004static ResultCode GetThreadPriority(u32* priority, Handle handle) { 1008static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle handle) {
1005 LOG_TRACE(Kernel_SVC, "called"); 1009 LOG_TRACE(Kernel_SVC, "called");
1006 1010
1007 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1011 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1008 const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); 1012 const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
1009 if (!thread) { 1013 if (!thread) {
1010 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); 1014 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
@@ -1016,7 +1020,7 @@ static ResultCode GetThreadPriority(u32* priority, Handle handle) {
1016} 1020}
1017 1021
1018/// Sets the priority for the specified thread 1022/// Sets the priority for the specified thread
1019static ResultCode SetThreadPriority(Handle handle, u32 priority) { 1023static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 priority) {
1020 LOG_TRACE(Kernel_SVC, "called"); 1024 LOG_TRACE(Kernel_SVC, "called");
1021 1025
1022 if (priority > THREADPRIO_LOWEST) { 1026 if (priority > THREADPRIO_LOWEST) {
@@ -1027,7 +1031,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
1027 return ERR_INVALID_THREAD_PRIORITY; 1031 return ERR_INVALID_THREAD_PRIORITY;
1028 } 1032 }
1029 1033
1030 const auto* const current_process = Core::CurrentProcess(); 1034 const auto* const current_process = system.Kernel().CurrentProcess();
1031 1035
1032 SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); 1036 SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
1033 if (!thread) { 1037 if (!thread) {
@@ -1037,18 +1041,18 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
1037 1041
1038 thread->SetPriority(priority); 1042 thread->SetPriority(priority);
1039 1043
1040 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1044 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1041 return RESULT_SUCCESS; 1045 return RESULT_SUCCESS;
1042} 1046}
1043 1047
1044/// Get which CPU core is executing the current thread 1048/// Get which CPU core is executing the current thread
1045static u32 GetCurrentProcessorNumber() { 1049static u32 GetCurrentProcessorNumber(Core::System& system) {
1046 LOG_TRACE(Kernel_SVC, "called"); 1050 LOG_TRACE(Kernel_SVC, "called");
1047 return GetCurrentThread()->GetProcessorID(); 1051 return system.CurrentScheduler().GetCurrentThread()->GetProcessorID();
1048} 1052}
1049 1053
1050static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, 1054static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
1051 u32 permissions) { 1055 u64 size, u32 permissions) {
1052 LOG_TRACE(Kernel_SVC, 1056 LOG_TRACE(Kernel_SVC,
1053 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", 1057 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
1054 shared_memory_handle, addr, size, permissions); 1058 shared_memory_handle, addr, size, permissions);
@@ -1082,7 +1086,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
1082 return ERR_INVALID_MEMORY_PERMISSIONS; 1086 return ERR_INVALID_MEMORY_PERMISSIONS;
1083 } 1087 }
1084 1088
1085 auto* const current_process = Core::CurrentProcess(); 1089 auto* const current_process = system.Kernel().CurrentProcess();
1086 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); 1090 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle);
1087 if (!shared_memory) { 1091 if (!shared_memory) {
1088 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", 1092 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}",
@@ -1100,7 +1104,8 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
1100 return shared_memory->Map(*current_process, addr, permissions_type, MemoryPermission::DontCare); 1104 return shared_memory->Map(*current_process, addr, permissions_type, MemoryPermission::DontCare);
1101} 1105}
1102 1106
1103static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { 1107static ResultCode UnmapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
1108 u64 size) {
1104 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", 1109 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
1105 shared_memory_handle, addr, size); 1110 shared_memory_handle, addr, size);
1106 1111
@@ -1125,7 +1130,7 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
1125 return ERR_INVALID_ADDRESS_STATE; 1130 return ERR_INVALID_ADDRESS_STATE;
1126 } 1131 }
1127 1132
1128 auto* const current_process = Core::CurrentProcess(); 1133 auto* const current_process = system.Kernel().CurrentProcess();
1129 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); 1134 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle);
1130 if (!shared_memory) { 1135 if (!shared_memory) {
1131 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", 1136 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}",
@@ -1143,10 +1148,11 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
1143 return shared_memory->Unmap(*current_process, addr, size); 1148 return shared_memory->Unmap(*current_process, addr, size);
1144} 1149}
1145 1150
1146static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_address, 1151static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
1147 Handle process_handle, VAddr address) { 1152 VAddr page_info_address, Handle process_handle,
1153 VAddr address) {
1148 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); 1154 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
1149 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1155 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1150 SharedPtr<Process> process = handle_table.Get<Process>(process_handle); 1156 SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
1151 if (!process) { 1157 if (!process) {
1152 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", 1158 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -1172,20 +1178,20 @@ static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_
1172 return RESULT_SUCCESS; 1178 return RESULT_SUCCESS;
1173} 1179}
1174 1180
1175static ResultCode QueryMemory(VAddr memory_info_address, VAddr page_info_address, 1181static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address,
1176 VAddr query_address) { 1182 VAddr page_info_address, VAddr query_address) {
1177 LOG_TRACE(Kernel_SVC, 1183 LOG_TRACE(Kernel_SVC,
1178 "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " 1184 "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, "
1179 "query_address=0x{:016X}", 1185 "query_address=0x{:016X}",
1180 memory_info_address, page_info_address, query_address); 1186 memory_info_address, page_info_address, query_address);
1181 1187
1182 return QueryProcessMemory(memory_info_address, page_info_address, CurrentProcess, 1188 return QueryProcessMemory(system, memory_info_address, page_info_address, CurrentProcess,
1183 query_address); 1189 query_address);
1184} 1190}
1185 1191
1186/// Exits the current process 1192/// Exits the current process
1187static void ExitProcess() { 1193static void ExitProcess(Core::System& system) {
1188 auto* current_process = Core::CurrentProcess(); 1194 auto* current_process = system.Kernel().CurrentProcess();
1189 1195
1190 LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); 1196 LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
1191 ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, 1197 ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running,
@@ -1194,20 +1200,20 @@ static void ExitProcess() {
1194 current_process->PrepareForTermination(); 1200 current_process->PrepareForTermination();
1195 1201
1196 // Kill the current thread 1202 // Kill the current thread
1197 GetCurrentThread()->Stop(); 1203 system.CurrentScheduler().GetCurrentThread()->Stop();
1198 1204
1199 Core::System::GetInstance().PrepareReschedule(); 1205 system.PrepareReschedule();
1200} 1206}
1201 1207
1202/// Creates a new thread 1208/// Creates a new thread
1203static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, 1209static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
1204 u32 priority, s32 processor_id) { 1210 VAddr stack_top, u32 priority, s32 processor_id) {
1205 LOG_TRACE(Kernel_SVC, 1211 LOG_TRACE(Kernel_SVC,
1206 "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " 1212 "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, "
1207 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", 1213 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
1208 entry_point, arg, stack_top, priority, processor_id, *out_handle); 1214 entry_point, arg, stack_top, priority, processor_id, *out_handle);
1209 1215
1210 auto* const current_process = Core::CurrentProcess(); 1216 auto* const current_process = system.Kernel().CurrentProcess();
1211 1217
1212 if (processor_id == THREADPROCESSORID_IDEAL) { 1218 if (processor_id == THREADPROCESSORID_IDEAL) {
1213 // Set the target CPU to the one specified by the process. 1219 // Set the target CPU to the one specified by the process.
@@ -1239,7 +1245,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
1239 } 1245 }
1240 1246
1241 const std::string name = fmt::format("thread-{:X}", entry_point); 1247 const std::string name = fmt::format("thread-{:X}", entry_point);
1242 auto& kernel = Core::System::GetInstance().Kernel(); 1248 auto& kernel = system.Kernel();
1243 CASCADE_RESULT(SharedPtr<Thread> thread, 1249 CASCADE_RESULT(SharedPtr<Thread> thread,
1244 Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top, 1250 Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top,
1245 *current_process)); 1251 *current_process));
@@ -1253,16 +1259,16 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
1253 thread->SetGuestHandle(*new_guest_handle); 1259 thread->SetGuestHandle(*new_guest_handle);
1254 *out_handle = *new_guest_handle; 1260 *out_handle = *new_guest_handle;
1255 1261
1256 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1262 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1257 1263
1258 return RESULT_SUCCESS; 1264 return RESULT_SUCCESS;
1259} 1265}
1260 1266
1261/// Starts the thread for the provided handle 1267/// Starts the thread for the provided handle
1262static ResultCode StartThread(Handle thread_handle) { 1268static ResultCode StartThread(Core::System& system, Handle thread_handle) {
1263 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 1269 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
1264 1270
1265 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1271 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1266 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1272 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1267 if (!thread) { 1273 if (!thread) {
1268 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 1274 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -1275,16 +1281,14 @@ static ResultCode StartThread(Handle thread_handle) {
1275 thread->ResumeFromWait(); 1281 thread->ResumeFromWait();
1276 1282
1277 if (thread->GetStatus() == ThreadStatus::Ready) { 1283 if (thread->GetStatus() == ThreadStatus::Ready) {
1278 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1284 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1279 } 1285 }
1280 1286
1281 return RESULT_SUCCESS; 1287 return RESULT_SUCCESS;
1282} 1288}
1283 1289
1284/// Called when a thread exits 1290/// Called when a thread exits
1285static void ExitThread() { 1291static void ExitThread(Core::System& system) {
1286 auto& system = Core::System::GetInstance();
1287
1288 LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); 1292 LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
1289 1293
1290 auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); 1294 auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
@@ -1294,7 +1298,7 @@ static void ExitThread() {
1294} 1298}
1295 1299
1296/// Sleep the current thread 1300/// Sleep the current thread
1297static void SleepThread(s64 nanoseconds) { 1301static void SleepThread(Core::System& system, s64 nanoseconds) {
1298 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); 1302 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
1299 1303
1300 enum class SleepType : s64 { 1304 enum class SleepType : s64 {
@@ -1303,7 +1307,6 @@ static void SleepThread(s64 nanoseconds) {
1303 YieldAndWaitForLoadBalancing = -2, 1307 YieldAndWaitForLoadBalancing = -2,
1304 }; 1308 };
1305 1309
1306 auto& system = Core::System::GetInstance();
1307 auto& scheduler = system.CurrentScheduler(); 1310 auto& scheduler = system.CurrentScheduler();
1308 auto* const current_thread = scheduler.GetCurrentThread(); 1311 auto* const current_thread = scheduler.GetCurrentThread();
1309 1312
@@ -1332,8 +1335,9 @@ static void SleepThread(s64 nanoseconds) {
1332} 1335}
1333 1336
1334/// Wait process wide key atomic 1337/// Wait process wide key atomic
1335static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, 1338static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_addr,
1336 Handle thread_handle, s64 nano_seconds) { 1339 VAddr condition_variable_addr, Handle thread_handle,
1340 s64 nano_seconds) {
1337 LOG_TRACE( 1341 LOG_TRACE(
1338 Kernel_SVC, 1342 Kernel_SVC,
1339 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", 1343 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}",
@@ -1353,7 +1357,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
1353 return ERR_INVALID_ADDRESS; 1357 return ERR_INVALID_ADDRESS;
1354 } 1358 }
1355 1359
1356 auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 1360 auto* const current_process = system.Kernel().CurrentProcess();
1357 const auto& handle_table = current_process->GetHandleTable(); 1361 const auto& handle_table = current_process->GetHandleTable();
1358 SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1362 SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1359 ASSERT(thread); 1363 ASSERT(thread);
@@ -1363,7 +1367,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
1363 return release_result; 1367 return release_result;
1364 } 1368 }
1365 1369
1366 SharedPtr<Thread> current_thread = GetCurrentThread(); 1370 SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
1367 current_thread->SetCondVarWaitAddress(condition_variable_addr); 1371 current_thread->SetCondVarWaitAddress(condition_variable_addr);
1368 current_thread->SetMutexWaitAddress(mutex_addr); 1372 current_thread->SetMutexWaitAddress(mutex_addr);
1369 current_thread->SetWaitHandle(thread_handle); 1373 current_thread->SetWaitHandle(thread_handle);
@@ -1374,19 +1378,20 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
1374 1378
1375 // Note: Deliberately don't attempt to inherit the lock owner's priority. 1379 // Note: Deliberately don't attempt to inherit the lock owner's priority.
1376 1380
1377 Core::System::GetInstance().CpuCore(current_thread->GetProcessorID()).PrepareReschedule(); 1381 system.CpuCore(current_thread->GetProcessorID()).PrepareReschedule();
1378 return RESULT_SUCCESS; 1382 return RESULT_SUCCESS;
1379} 1383}
1380 1384
1381/// Signal process wide key 1385/// Signal process wide key
1382static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { 1386static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_variable_addr,
1387 s32 target) {
1383 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", 1388 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
1384 condition_variable_addr, target); 1389 condition_variable_addr, target);
1385 1390
1386 const auto RetrieveWaitingThreads = [](std::size_t core_index, 1391 const auto RetrieveWaitingThreads = [&system](std::size_t core_index,
1387 std::vector<SharedPtr<Thread>>& waiting_threads, 1392 std::vector<SharedPtr<Thread>>& waiting_threads,
1388 VAddr condvar_addr) { 1393 VAddr condvar_addr) {
1389 const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); 1394 const auto& scheduler = system.Scheduler(core_index);
1390 const auto& thread_list = scheduler.GetThreadList(); 1395 const auto& thread_list = scheduler.GetThreadList();
1391 1396
1392 for (const auto& thread : thread_list) { 1397 for (const auto& thread : thread_list) {
@@ -1425,9 +1430,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1425 // liberate Cond Var Thread. 1430 // liberate Cond Var Thread.
1426 thread->SetCondVarWaitAddress(0); 1431 thread->SetCondVarWaitAddress(0);
1427 1432
1428 std::size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); 1433 const std::size_t current_core = system.CurrentCoreIndex();
1429 1434 auto& monitor = system.Monitor();
1430 auto& monitor = Core::System::GetInstance().Monitor();
1431 1435
1432 // Atomically read the value of the mutex. 1436 // Atomically read the value of the mutex.
1433 u32 mutex_val = 0; 1437 u32 mutex_val = 0;
@@ -1456,7 +1460,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1456 thread->SetLockOwner(nullptr); 1460 thread->SetLockOwner(nullptr);
1457 thread->SetMutexWaitAddress(0); 1461 thread->SetMutexWaitAddress(0);
1458 thread->SetWaitHandle(0); 1462 thread->SetWaitHandle(0);
1459 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1463 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1460 } else { 1464 } else {
1461 // Atomically signal that the mutex now has a waiting thread. 1465 // Atomically signal that the mutex now has a waiting thread.
1462 do { 1466 do {
@@ -1472,7 +1476,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1472 1476
1473 // The mutex is already owned by some other thread, make this thread wait on it. 1477 // The mutex is already owned by some other thread, make this thread wait on it.
1474 const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); 1478 const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
1475 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1479 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1476 auto owner = handle_table.Get<Thread>(owner_handle); 1480 auto owner = handle_table.Get<Thread>(owner_handle);
1477 ASSERT(owner); 1481 ASSERT(owner);
1478 ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar); 1482 ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar);
@@ -1487,14 +1491,17 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1487} 1491}
1488 1492
1489// Wait for an address (via Address Arbiter) 1493// Wait for an address (via Address Arbiter)
1490static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) { 1494static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type, s32 value,
1495 s64 timeout) {
1491 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}", 1496 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}",
1492 address, type, value, timeout); 1497 address, type, value, timeout);
1498
1493 // If the passed address is a kernel virtual address, return invalid memory state. 1499 // If the passed address is a kernel virtual address, return invalid memory state.
1494 if (Memory::IsKernelVirtualAddress(address)) { 1500 if (Memory::IsKernelVirtualAddress(address)) {
1495 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); 1501 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address);
1496 return ERR_INVALID_ADDRESS_STATE; 1502 return ERR_INVALID_ADDRESS_STATE;
1497 } 1503 }
1504
1498 // If the address is not properly aligned to 4 bytes, return invalid address. 1505 // If the address is not properly aligned to 4 bytes, return invalid address.
1499 if (!Common::IsWordAligned(address)) { 1506 if (!Common::IsWordAligned(address)) {
1500 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address); 1507 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address);
@@ -1502,20 +1509,22 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
1502 } 1509 }
1503 1510
1504 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type); 1511 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
1505 auto& address_arbiter = 1512 auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter();
1506 Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
1507 return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); 1513 return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
1508} 1514}
1509 1515
1510// Signals to an address (via Address Arbiter) 1516// Signals to an address (via Address Arbiter)
1511static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) { 1517static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, s32 value,
1518 s32 num_to_wake) {
1512 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}", 1519 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}",
1513 address, type, value, num_to_wake); 1520 address, type, value, num_to_wake);
1521
1514 // If the passed address is a kernel virtual address, return invalid memory state. 1522 // If the passed address is a kernel virtual address, return invalid memory state.
1515 if (Memory::IsKernelVirtualAddress(address)) { 1523 if (Memory::IsKernelVirtualAddress(address)) {
1516 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); 1524 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address);
1517 return ERR_INVALID_ADDRESS_STATE; 1525 return ERR_INVALID_ADDRESS_STATE;
1518 } 1526 }
1527
1519 // If the address is not properly aligned to 4 bytes, return invalid address. 1528 // If the address is not properly aligned to 4 bytes, return invalid address.
1520 if (!Common::IsWordAligned(address)) { 1529 if (!Common::IsWordAligned(address)) {
1521 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address); 1530 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address);
@@ -1523,16 +1532,15 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
1523 } 1532 }
1524 1533
1525 const auto signal_type = static_cast<AddressArbiter::SignalType>(type); 1534 const auto signal_type = static_cast<AddressArbiter::SignalType>(type);
1526 auto& address_arbiter = 1535 auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter();
1527 Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
1528 return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake); 1536 return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);
1529} 1537}
1530 1538
1531/// This returns the total CPU ticks elapsed since the CPU was powered-on 1539/// This returns the total CPU ticks elapsed since the CPU was powered-on
1532static u64 GetSystemTick() { 1540static u64 GetSystemTick(Core::System& system) {
1533 LOG_TRACE(Kernel_SVC, "called"); 1541 LOG_TRACE(Kernel_SVC, "called");
1534 1542
1535 auto& core_timing = Core::System::GetInstance().CoreTiming(); 1543 auto& core_timing = system.CoreTiming();
1536 const u64 result{core_timing.GetTicks()}; 1544 const u64 result{core_timing.GetTicks()};
1537 1545
1538 // Advance time to defeat dumb games that busy-wait for the frame to end. 1546 // Advance time to defeat dumb games that busy-wait for the frame to end.
@@ -1542,18 +1550,18 @@ static u64 GetSystemTick() {
1542} 1550}
1543 1551
1544/// Close a handle 1552/// Close a handle
1545static ResultCode CloseHandle(Handle handle) { 1553static ResultCode CloseHandle(Core::System& system, Handle handle) {
1546 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); 1554 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
1547 1555
1548 auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1556 auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1549 return handle_table.Close(handle); 1557 return handle_table.Close(handle);
1550} 1558}
1551 1559
1552/// Clears the signaled state of an event or process. 1560/// Clears the signaled state of an event or process.
1553static ResultCode ResetSignal(Handle handle) { 1561static ResultCode ResetSignal(Core::System& system, Handle handle) {
1554 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); 1562 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
1555 1563
1556 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1564 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1557 1565
1558 auto event = handle_table.Get<ReadableEvent>(handle); 1566 auto event = handle_table.Get<ReadableEvent>(handle);
1559 if (event) { 1567 if (event) {
@@ -1570,7 +1578,8 @@ static ResultCode ResetSignal(Handle handle) {
1570} 1578}
1571 1579
1572/// Creates a TransferMemory object 1580/// Creates a TransferMemory object
1573static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { 1581static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size,
1582 u32 permissions) {
1574 LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, 1583 LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size,
1575 permissions); 1584 permissions);
1576 1585
@@ -1598,7 +1607,7 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1598 return ERR_INVALID_MEMORY_PERMISSIONS; 1607 return ERR_INVALID_MEMORY_PERMISSIONS;
1599 } 1608 }
1600 1609
1601 auto& kernel = Core::System::GetInstance().Kernel(); 1610 auto& kernel = system.Kernel();
1602 auto transfer_mem_handle = TransferMemory::Create(kernel, addr, size, perms); 1611 auto transfer_mem_handle = TransferMemory::Create(kernel, addr, size, perms);
1603 1612
1604 auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 1613 auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
@@ -1611,7 +1620,8 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1611 return RESULT_SUCCESS; 1620 return RESULT_SUCCESS;
1612} 1621}
1613 1622
1614static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32 permission_raw) { 1623static ResultCode MapTransferMemory(Core::System& system, Handle handle, VAddr address, u64 size,
1624 u32 permission_raw) {
1615 LOG_DEBUG(Kernel_SVC, 1625 LOG_DEBUG(Kernel_SVC,
1616 "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}, permissions=0x{:08X}", 1626 "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}, permissions=0x{:08X}",
1617 handle, address, size, permission_raw); 1627 handle, address, size, permission_raw);
@@ -1645,7 +1655,7 @@ static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32
1645 return ERR_INVALID_STATE; 1655 return ERR_INVALID_STATE;
1646 } 1656 }
1647 1657
1648 const auto& kernel = Core::System::GetInstance().Kernel(); 1658 const auto& kernel = system.Kernel();
1649 const auto* const current_process = kernel.CurrentProcess(); 1659 const auto* const current_process = kernel.CurrentProcess();
1650 const auto& handle_table = current_process->GetHandleTable(); 1660 const auto& handle_table = current_process->GetHandleTable();
1651 1661
@@ -1667,7 +1677,8 @@ static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32
1667 return transfer_memory->MapMemory(address, size, permissions); 1677 return transfer_memory->MapMemory(address, size, permissions);
1668} 1678}
1669 1679
1670static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) { 1680static ResultCode UnmapTransferMemory(Core::System& system, Handle handle, VAddr address,
1681 u64 size) {
1671 LOG_DEBUG(Kernel_SVC, "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}", handle, 1682 LOG_DEBUG(Kernel_SVC, "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}", handle,
1672 address, size); 1683 address, size);
1673 1684
@@ -1692,7 +1703,7 @@ static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) {
1692 return ERR_INVALID_ADDRESS_STATE; 1703 return ERR_INVALID_ADDRESS_STATE;
1693 } 1704 }
1694 1705
1695 const auto& kernel = Core::System::GetInstance().Kernel(); 1706 const auto& kernel = system.Kernel();
1696 const auto* const current_process = kernel.CurrentProcess(); 1707 const auto* const current_process = kernel.CurrentProcess();
1697 const auto& handle_table = current_process->GetHandleTable(); 1708 const auto& handle_table = current_process->GetHandleTable();
1698 1709
@@ -1714,10 +1725,11 @@ static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) {
1714 return transfer_memory->UnmapMemory(address, size); 1725 return transfer_memory->UnmapMemory(address, size);
1715} 1726}
1716 1727
1717static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { 1728static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, u32* core,
1729 u64* mask) {
1718 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); 1730 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
1719 1731
1720 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1732 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1721 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1733 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1722 if (!thread) { 1734 if (!thread) {
1723 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 1735 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -1731,11 +1743,12 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask)
1731 return RESULT_SUCCESS; 1743 return RESULT_SUCCESS;
1732} 1744}
1733 1745
1734static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { 1746static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core,
1747 u64 mask) {
1735 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle, 1748 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle,
1736 mask, core); 1749 mask, core);
1737 1750
1738 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1751 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1739 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1752 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1740 if (!thread) { 1753 if (!thread) {
1741 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 1754 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -1780,8 +1793,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
1780 return RESULT_SUCCESS; 1793 return RESULT_SUCCESS;
1781} 1794}
1782 1795
1783static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, 1796static ResultCode CreateSharedMemory(Core::System& system, Handle* handle, u64 size,
1784 u32 remote_permissions) { 1797 u32 local_permissions, u32 remote_permissions) {
1785 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, 1798 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
1786 local_permissions, remote_permissions); 1799 local_permissions, remote_permissions);
1787 if (size == 0) { 1800 if (size == 0) {
@@ -1817,7 +1830,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
1817 return ERR_INVALID_MEMORY_PERMISSIONS; 1830 return ERR_INVALID_MEMORY_PERMISSIONS;
1818 } 1831 }
1819 1832
1820 auto& kernel = Core::System::GetInstance().Kernel(); 1833 auto& kernel = system.Kernel();
1821 auto process = kernel.CurrentProcess(); 1834 auto process = kernel.CurrentProcess();
1822 auto& handle_table = process->GetHandleTable(); 1835 auto& handle_table = process->GetHandleTable();
1823 auto shared_mem_handle = SharedMemory::Create(kernel, process, size, local_perms, remote_perms); 1836 auto shared_mem_handle = SharedMemory::Create(kernel, process, size, local_perms, remote_perms);
@@ -1826,10 +1839,10 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
1826 return RESULT_SUCCESS; 1839 return RESULT_SUCCESS;
1827} 1840}
1828 1841
1829static ResultCode CreateEvent(Handle* write_handle, Handle* read_handle) { 1842static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) {
1830 LOG_DEBUG(Kernel_SVC, "called"); 1843 LOG_DEBUG(Kernel_SVC, "called");
1831 1844
1832 auto& kernel = Core::System::GetInstance().Kernel(); 1845 auto& kernel = system.Kernel();
1833 const auto [readable_event, writable_event] = 1846 const auto [readable_event, writable_event] =
1834 WritableEvent::CreateEventPair(kernel, ResetType::Sticky, "CreateEvent"); 1847 WritableEvent::CreateEventPair(kernel, ResetType::Sticky, "CreateEvent");
1835 1848
@@ -1854,10 +1867,10 @@ static ResultCode CreateEvent(Handle* write_handle, Handle* read_handle) {
1854 return RESULT_SUCCESS; 1867 return RESULT_SUCCESS;
1855} 1868}
1856 1869
1857static ResultCode ClearEvent(Handle handle) { 1870static ResultCode ClearEvent(Core::System& system, Handle handle) {
1858 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 1871 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
1859 1872
1860 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1873 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1861 1874
1862 auto writable_event = handle_table.Get<WritableEvent>(handle); 1875 auto writable_event = handle_table.Get<WritableEvent>(handle);
1863 if (writable_event) { 1876 if (writable_event) {
@@ -1875,10 +1888,10 @@ static ResultCode ClearEvent(Handle handle) {
1875 return ERR_INVALID_HANDLE; 1888 return ERR_INVALID_HANDLE;
1876} 1889}
1877 1890
1878static ResultCode SignalEvent(Handle handle) { 1891static ResultCode SignalEvent(Core::System& system, Handle handle) {
1879 LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); 1892 LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle);
1880 1893
1881 HandleTable& handle_table = Core::CurrentProcess()->GetHandleTable(); 1894 HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1882 auto writable_event = handle_table.Get<WritableEvent>(handle); 1895 auto writable_event = handle_table.Get<WritableEvent>(handle);
1883 1896
1884 if (!writable_event) { 1897 if (!writable_event) {
@@ -1890,7 +1903,7 @@ static ResultCode SignalEvent(Handle handle) {
1890 return RESULT_SUCCESS; 1903 return RESULT_SUCCESS;
1891} 1904}
1892 1905
1893static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { 1906static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
1894 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); 1907 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type);
1895 1908
1896 // This function currently only allows retrieving a process' status. 1909 // This function currently only allows retrieving a process' status.
@@ -1898,7 +1911,7 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
1898 Status, 1911 Status,
1899 }; 1912 };
1900 1913
1901 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1914 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1902 const auto process = handle_table.Get<Process>(process_handle); 1915 const auto process = handle_table.Get<Process>(process_handle);
1903 if (!process) { 1916 if (!process) {
1904 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", 1917 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -1916,10 +1929,10 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
1916 return RESULT_SUCCESS; 1929 return RESULT_SUCCESS;
1917} 1930}
1918 1931
1919static ResultCode CreateResourceLimit(Handle* out_handle) { 1932static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) {
1920 LOG_DEBUG(Kernel_SVC, "called"); 1933 LOG_DEBUG(Kernel_SVC, "called");
1921 1934
1922 auto& kernel = Core::System::GetInstance().Kernel(); 1935 auto& kernel = system.Kernel();
1923 auto resource_limit = ResourceLimit::Create(kernel); 1936 auto resource_limit = ResourceLimit::Create(kernel);
1924 1937
1925 auto* const current_process = kernel.CurrentProcess(); 1938 auto* const current_process = kernel.CurrentProcess();
@@ -1934,11 +1947,11 @@ static ResultCode CreateResourceLimit(Handle* out_handle) {
1934 return RESULT_SUCCESS; 1947 return RESULT_SUCCESS;
1935} 1948}
1936 1949
1937static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_limit, 1950static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_value,
1938 u32 resource_type) { 1951 Handle resource_limit, u32 resource_type) {
1939 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); 1952 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
1940 1953
1941 const auto limit_value = RetrieveResourceLimitValue(resource_limit, resource_type, 1954 const auto limit_value = RetrieveResourceLimitValue(system, resource_limit, resource_type,
1942 ResourceLimitValueType::LimitValue); 1955 ResourceLimitValueType::LimitValue);
1943 if (limit_value.Failed()) { 1956 if (limit_value.Failed()) {
1944 return limit_value.Code(); 1957 return limit_value.Code();
@@ -1948,11 +1961,11 @@ static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_lim
1948 return RESULT_SUCCESS; 1961 return RESULT_SUCCESS;
1949} 1962}
1950 1963
1951static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit, 1964static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_value,
1952 u32 resource_type) { 1965 Handle resource_limit, u32 resource_type) {
1953 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); 1966 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
1954 1967
1955 const auto current_value = RetrieveResourceLimitValue(resource_limit, resource_type, 1968 const auto current_value = RetrieveResourceLimitValue(system, resource_limit, resource_type,
1956 ResourceLimitValueType::CurrentValue); 1969 ResourceLimitValueType::CurrentValue);
1957 if (current_value.Failed()) { 1970 if (current_value.Failed()) {
1958 return current_value.Code(); 1971 return current_value.Code();
@@ -1962,7 +1975,8 @@ static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_l
1962 return RESULT_SUCCESS; 1975 return RESULT_SUCCESS;
1963} 1976}
1964 1977
1965static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource_type, u64 value) { 1978static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit,
1979 u32 resource_type, u64 value) {
1966 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, 1980 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit,
1967 resource_type, value); 1981 resource_type, value);
1968 1982
@@ -1972,8 +1986,7 @@ static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource
1972 return ERR_INVALID_ENUM_VALUE; 1986 return ERR_INVALID_ENUM_VALUE;
1973 } 1987 }
1974 1988
1975 auto& kernel = Core::System::GetInstance().Kernel(); 1989 auto* const current_process = system.Kernel().CurrentProcess();
1976 auto* const current_process = kernel.CurrentProcess();
1977 ASSERT(current_process != nullptr); 1990 ASSERT(current_process != nullptr);
1978 1991
1979 auto resource_limit_object = 1992 auto resource_limit_object =
@@ -1997,8 +2010,8 @@ static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource
1997 return RESULT_SUCCESS; 2010 return RESULT_SUCCESS;
1998} 2011}
1999 2012
2000static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids, 2013static ResultCode GetProcessList(Core::System& system, u32* out_num_processes,
2001 u32 out_process_ids_size) { 2014 VAddr out_process_ids, u32 out_process_ids_size) {
2002 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", 2015 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
2003 out_process_ids, out_process_ids_size); 2016 out_process_ids, out_process_ids_size);
2004 2017
@@ -2010,7 +2023,7 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
2010 return ERR_OUT_OF_RANGE; 2023 return ERR_OUT_OF_RANGE;
2011 } 2024 }
2012 2025
2013 const auto& kernel = Core::System::GetInstance().Kernel(); 2026 const auto& kernel = system.Kernel();
2014 const auto& vm_manager = kernel.CurrentProcess()->VMManager(); 2027 const auto& vm_manager = kernel.CurrentProcess()->VMManager();
2015 const auto total_copy_size = out_process_ids_size * sizeof(u64); 2028 const auto total_copy_size = out_process_ids_size * sizeof(u64);
2016 2029
@@ -2034,8 +2047,8 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
2034 return RESULT_SUCCESS; 2047 return RESULT_SUCCESS;
2035} 2048}
2036 2049
2037ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thread_ids_size, 2050ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids,
2038 Handle debug_handle) { 2051 u32 out_thread_ids_size, Handle debug_handle) {
2039 // TODO: Handle this case when debug events are supported. 2052 // TODO: Handle this case when debug events are supported.
2040 UNIMPLEMENTED_IF(debug_handle != InvalidHandle); 2053 UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
2041 2054
@@ -2049,7 +2062,7 @@ ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thr
2049 return ERR_OUT_OF_RANGE; 2062 return ERR_OUT_OF_RANGE;
2050 } 2063 }
2051 2064
2052 const auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 2065 const auto* const current_process = system.Kernel().CurrentProcess();
2053 const auto& vm_manager = current_process->VMManager(); 2066 const auto& vm_manager = current_process->VMManager();
2054 const auto total_copy_size = out_thread_ids_size * sizeof(u64); 2067 const auto total_copy_size = out_thread_ids_size * sizeof(u64);
2055 2068
@@ -2076,7 +2089,7 @@ ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thr
2076 2089
2077namespace { 2090namespace {
2078struct FunctionDef { 2091struct FunctionDef {
2079 using Func = void(); 2092 using Func = void(Core::System&);
2080 2093
2081 u32 id; 2094 u32 id;
2082 Func* func; 2095 Func* func;
@@ -2225,7 +2238,7 @@ static const FunctionDef* GetSVCInfo(u32 func_num) {
2225 2238
2226MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); 2239MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
2227 2240
2228void CallSVC(u32 immediate) { 2241void CallSVC(Core::System& system, u32 immediate) {
2229 MICROPROFILE_SCOPE(Kernel_SVC); 2242 MICROPROFILE_SCOPE(Kernel_SVC);
2230 2243
2231 // Lock the global kernel mutex when we enter the kernel HLE. 2244 // Lock the global kernel mutex when we enter the kernel HLE.
@@ -2234,7 +2247,7 @@ void CallSVC(u32 immediate) {
2234 const FunctionDef* info = GetSVCInfo(immediate); 2247 const FunctionDef* info = GetSVCInfo(immediate);
2235 if (info) { 2248 if (info) {
2236 if (info->func) { 2249 if (info->func) {
2237 info->func(); 2250 info->func(system);
2238 } else { 2251 } else {
2239 LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name); 2252 LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
2240 } 2253 }
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h
index c37ae0f98..c5539ac1c 100644
--- a/src/core/hle/kernel/svc.h
+++ b/src/core/hle/kernel/svc.h
@@ -6,8 +6,12 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9namespace Core {
10class System;
11}
12
9namespace Kernel { 13namespace Kernel {
10 14
11void CallSVC(u32 immediate); 15void CallSVC(Core::System& system, u32 immediate);
12 16
13} // namespace Kernel 17} // namespace Kernel
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index b3733680f..b3690b5f3 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -11,278 +11,312 @@
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14static inline u64 Param(int n) { 14static inline u64 Param(const Core::System& system, int n) {
15 return Core::CurrentArmInterface().GetReg(n); 15 return system.CurrentArmInterface().GetReg(n);
16} 16}
17 17
18/** 18/**
19 * HLE a function return from the current ARM userland process 19 * HLE a function return from the current ARM userland process
20 * @param res Result to return 20 * @param system System context
21 * @param result Result to return
21 */ 22 */
22static inline void FuncReturn(u64 res) { 23static inline void FuncReturn(Core::System& system, u64 result) {
23 Core::CurrentArmInterface().SetReg(0, res); 24 system.CurrentArmInterface().SetReg(0, result);
24} 25}
25 26
26//////////////////////////////////////////////////////////////////////////////////////////////////// 27////////////////////////////////////////////////////////////////////////////////////////////////////
27// Function wrappers that return type ResultCode 28// Function wrappers that return type ResultCode
28 29
29template <ResultCode func(u64)> 30template <ResultCode func(Core::System&, u64)>
30void SvcWrap() { 31void SvcWrap(Core::System& system) {
31 FuncReturn(func(Param(0)).raw); 32 FuncReturn(system, func(system, Param(system, 0)).raw);
32} 33}
33 34
34template <ResultCode func(u32)> 35template <ResultCode func(Core::System&, u32)>
35void SvcWrap() { 36void SvcWrap(Core::System& system) {
36 FuncReturn(func(static_cast<u32>(Param(0))).raw); 37 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw);
37} 38}
38 39
39template <ResultCode func(u32, u32)> 40template <ResultCode func(Core::System&, u32, u32)>
40void SvcWrap() { 41void SvcWrap(Core::System& system) {
41 FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1))).raw); 42 FuncReturn(
43 system,
44 func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw);
42} 45}
43 46
44template <ResultCode func(u32*)> 47template <ResultCode func(Core::System&, u32*)>
45void SvcWrap() { 48void SvcWrap(Core::System& system) {
46 u32 param = 0; 49 u32 param = 0;
47 const u32 retval = func(&param).raw; 50 const u32 retval = func(system, &param).raw;
48 Core::CurrentArmInterface().SetReg(1, param); 51 system.CurrentArmInterface().SetReg(1, param);
49 FuncReturn(retval); 52 FuncReturn(system, retval);
50} 53}
51 54
52template <ResultCode func(u32*, u32)> 55template <ResultCode func(Core::System&, u32*, u32)>
53void SvcWrap() { 56void SvcWrap(Core::System& system) {
54 u32 param_1 = 0; 57 u32 param_1 = 0;
55 u32 retval = func(&param_1, static_cast<u32>(Param(1))).raw; 58 const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1))).raw;
56 Core::CurrentArmInterface().SetReg(1, param_1); 59 system.CurrentArmInterface().SetReg(1, param_1);
57 FuncReturn(retval); 60 FuncReturn(system, retval);
58} 61}
59 62
60template <ResultCode func(u32*, u32*)> 63template <ResultCode func(Core::System&, u32*, u32*)>
61void SvcWrap() { 64void SvcWrap(Core::System& system) {
62 u32 param_1 = 0; 65 u32 param_1 = 0;
63 u32 param_2 = 0; 66 u32 param_2 = 0;
64 const u32 retval = func(&param_1, &param_2).raw; 67 const u32 retval = func(system, &param_1, &param_2).raw;
65 68
66 auto& arm_interface = Core::CurrentArmInterface(); 69 auto& arm_interface = system.CurrentArmInterface();
67 arm_interface.SetReg(1, param_1); 70 arm_interface.SetReg(1, param_1);
68 arm_interface.SetReg(2, param_2); 71 arm_interface.SetReg(2, param_2);
69 72
70 FuncReturn(retval); 73 FuncReturn(system, retval);
71} 74}
72 75
73template <ResultCode func(u32*, u64)> 76template <ResultCode func(Core::System&, u32*, u64)>
74void SvcWrap() { 77void SvcWrap(Core::System& system) {
75 u32 param_1 = 0; 78 u32 param_1 = 0;
76 const u32 retval = func(&param_1, Param(1)).raw; 79 const u32 retval = func(system, &param_1, Param(system, 1)).raw;
77 Core::CurrentArmInterface().SetReg(1, param_1); 80 system.CurrentArmInterface().SetReg(1, param_1);
78 FuncReturn(retval); 81 FuncReturn(system, retval);
79} 82}
80 83
81template <ResultCode func(u32*, u64, u32)> 84template <ResultCode func(Core::System&, u32*, u64, u32)>
82void SvcWrap() { 85void SvcWrap(Core::System& system) {
83 u32 param_1 = 0; 86 u32 param_1 = 0;
84 const u32 retval = func(&param_1, Param(1), static_cast<u32>(Param(2))).raw; 87 const u32 retval =
85 Core::CurrentArmInterface().SetReg(1, param_1); 88 func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2))).raw;
86 FuncReturn(retval); 89
90 system.CurrentArmInterface().SetReg(1, param_1);
91 FuncReturn(system, retval);
87} 92}
88 93
89template <ResultCode func(u64*, u32)> 94template <ResultCode func(Core::System&, u64*, u32)>
90void SvcWrap() { 95void SvcWrap(Core::System& system) {
91 u64 param_1 = 0; 96 u64 param_1 = 0;
92 const u32 retval = func(&param_1, static_cast<u32>(Param(1))).raw; 97 const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1))).raw;
93 Core::CurrentArmInterface().SetReg(1, param_1); 98
94 FuncReturn(retval); 99 system.CurrentArmInterface().SetReg(1, param_1);
100 FuncReturn(system, retval);
95} 101}
96 102
97template <ResultCode func(u64, s32)> 103template <ResultCode func(Core::System&, u64, s32)>
98void SvcWrap() { 104void SvcWrap(Core::System& system) {
99 FuncReturn(func(Param(0), static_cast<s32>(Param(1))).raw); 105 FuncReturn(system, func(system, Param(system, 0), static_cast<s32>(Param(system, 1))).raw);
100} 106}
101 107
102template <ResultCode func(u64, u32)> 108template <ResultCode func(Core::System&, u64, u32)>
103void SvcWrap() { 109void SvcWrap(Core::System& system) {
104 FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw); 110 FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw);
105} 111}
106 112
107template <ResultCode func(u64*, u64)> 113template <ResultCode func(Core::System&, u64*, u64)>
108void SvcWrap() { 114void SvcWrap(Core::System& system) {
109 u64 param_1 = 0; 115 u64 param_1 = 0;
110 u32 retval = func(&param_1, Param(1)).raw; 116 const u32 retval = func(system, &param_1, Param(system, 1)).raw;
111 Core::CurrentArmInterface().SetReg(1, param_1); 117
112 FuncReturn(retval); 118 system.CurrentArmInterface().SetReg(1, param_1);
119 FuncReturn(system, retval);
113} 120}
114 121
115template <ResultCode func(u64*, u32, u32)> 122template <ResultCode func(Core::System&, u64*, u32, u32)>
116void SvcWrap() { 123void SvcWrap(Core::System& system) {
117 u64 param_1 = 0; 124 u64 param_1 = 0;
118 u32 retval = func(&param_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw; 125 const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1)),
119 Core::CurrentArmInterface().SetReg(1, param_1); 126 static_cast<u32>(Param(system, 2)))
120 FuncReturn(retval); 127 .raw;
128
129 system.CurrentArmInterface().SetReg(1, param_1);
130 FuncReturn(system, retval);
121} 131}
122 132
123template <ResultCode func(u32, u64)> 133template <ResultCode func(Core::System&, u32, u64)>
124void SvcWrap() { 134void SvcWrap(Core::System& system) {
125 FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw); 135 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw);
126} 136}
127 137
128template <ResultCode func(u32, u32, u64)> 138template <ResultCode func(Core::System&, u32, u32, u64)>
129void SvcWrap() { 139void SvcWrap(Core::System& system) {
130 FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1)), Param(2)).raw); 140 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)),
141 static_cast<u32>(Param(system, 1)), Param(system, 2))
142 .raw);
131} 143}
132 144
133template <ResultCode func(u32, u32*, u64*)> 145template <ResultCode func(Core::System&, u32, u32*, u64*)>
134void SvcWrap() { 146void SvcWrap(Core::System& system) {
135 u32 param_1 = 0; 147 u32 param_1 = 0;
136 u64 param_2 = 0; 148 u64 param_2 = 0;
137 ResultCode retval = func(static_cast<u32>(Param(2)), &param_1, &param_2); 149 const ResultCode retval = func(system, static_cast<u32>(Param(system, 2)), &param_1, &param_2);
138 Core::CurrentArmInterface().SetReg(1, param_1);
139 Core::CurrentArmInterface().SetReg(2, param_2);
140 FuncReturn(retval.raw);
141}
142 150
143template <ResultCode func(u64, u64, u32, u32)> 151 system.CurrentArmInterface().SetReg(1, param_1);
144void SvcWrap() { 152 system.CurrentArmInterface().SetReg(2, param_2);
145 FuncReturn( 153 FuncReturn(system, retval.raw);
146 func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw);
147} 154}
148 155
149template <ResultCode func(u64, u64, u32, u64)> 156template <ResultCode func(Core::System&, u64, u64, u32, u32)>
150void SvcWrap() { 157void SvcWrap(Core::System& system) {
151 FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2)), Param(3)).raw); 158 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
159 static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3)))
160 .raw);
152} 161}
153 162
154template <ResultCode func(u32, u64, u32)> 163template <ResultCode func(Core::System&, u64, u64, u32, u64)>
155void SvcWrap() { 164void SvcWrap(Core::System& system) {
156 FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw); 165 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
166 static_cast<u32>(Param(system, 2)), Param(system, 3))
167 .raw);
157} 168}
158 169
159template <ResultCode func(u64, u64, u64)> 170template <ResultCode func(Core::System&, u32, u64, u32)>
160void SvcWrap() { 171void SvcWrap(Core::System& system) {
161 FuncReturn(func(Param(0), Param(1), Param(2)).raw); 172 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
173 static_cast<u32>(Param(system, 2)))
174 .raw);
162} 175}
163 176
164template <ResultCode func(u64, u64, u32)> 177template <ResultCode func(Core::System&, u64, u64, u64)>
165void SvcWrap() { 178void SvcWrap(Core::System& system) {
166 FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2))).raw); 179 FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw);
167} 180}
168 181
169template <ResultCode func(u32, u64, u64, u32)> 182template <ResultCode func(Core::System&, u64, u64, u32)>
170void SvcWrap() { 183void SvcWrap(Core::System& system) {
171 FuncReturn( 184 FuncReturn(
172 func(static_cast<u32>(Param(0)), Param(1), Param(2), static_cast<u32>(Param(3))).raw); 185 system,
186 func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw);
187}
188
189template <ResultCode func(Core::System&, u32, u64, u64, u32)>
190void SvcWrap(Core::System& system) {
191 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
192 Param(system, 2), static_cast<u32>(Param(system, 3)))
193 .raw);
173} 194}
174 195
175template <ResultCode func(u32, u64, u64)> 196template <ResultCode func(Core::System&, u32, u64, u64)>
176void SvcWrap() { 197void SvcWrap(Core::System& system) {
177 FuncReturn(func(static_cast<u32>(Param(0)), Param(1), Param(2)).raw); 198 FuncReturn(
199 system,
200 func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw);
178} 201}
179 202
180template <ResultCode func(u32*, u64, u64, s64)> 203template <ResultCode func(Core::System&, u32*, u64, u64, s64)>
181void SvcWrap() { 204void SvcWrap(Core::System& system) {
182 u32 param_1 = 0; 205 u32 param_1 = 0;
183 ResultCode retval = 206 const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
184 func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))); 207 static_cast<s64>(Param(system, 3)))
185 Core::CurrentArmInterface().SetReg(1, param_1); 208 .raw;
186 FuncReturn(retval.raw); 209
210 system.CurrentArmInterface().SetReg(1, param_1);
211 FuncReturn(system, retval);
187} 212}
188 213
189template <ResultCode func(u64, u64, u32, s64)> 214template <ResultCode func(Core::System&, u64, u64, u32, s64)>
190void SvcWrap() { 215void SvcWrap(Core::System& system) {
191 FuncReturn( 216 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
192 func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))).raw); 217 static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3)))
218 .raw);
193} 219}
194 220
195template <ResultCode func(u64*, u64, u64, u64)> 221template <ResultCode func(Core::System&, u64*, u64, u64, u64)>
196void SvcWrap() { 222void SvcWrap(Core::System& system) {
197 u64 param_1 = 0; 223 u64 param_1 = 0;
198 u32 retval = func(&param_1, Param(1), Param(2), Param(3)).raw; 224 const u32 retval =
199 Core::CurrentArmInterface().SetReg(1, param_1); 225 func(system, &param_1, Param(system, 1), Param(system, 2), Param(system, 3)).raw;
200 FuncReturn(retval); 226
227 system.CurrentArmInterface().SetReg(1, param_1);
228 FuncReturn(system, retval);
201} 229}
202 230
203template <ResultCode func(u32*, u64, u64, u64, u32, s32)> 231template <ResultCode func(Core::System&, u32*, u64, u64, u64, u32, s32)>
204void SvcWrap() { 232void SvcWrap(Core::System& system) {
205 u32 param_1 = 0; 233 u32 param_1 = 0;
206 u32 retval = func(&param_1, Param(1), Param(2), Param(3), static_cast<u32>(Param(4)), 234 const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2), Param(system, 3),
207 static_cast<s32>(Param(5))) 235 static_cast<u32>(Param(system, 4)), static_cast<s32>(Param(system, 5)))
208 .raw; 236 .raw;
209 Core::CurrentArmInterface().SetReg(1, param_1); 237
210 FuncReturn(retval); 238 system.CurrentArmInterface().SetReg(1, param_1);
239 FuncReturn(system, retval);
211} 240}
212 241
213template <ResultCode func(u32*, u64, u64, u32)> 242template <ResultCode func(Core::System&, u32*, u64, u64, u32)>
214void SvcWrap() { 243void SvcWrap(Core::System& system) {
215 u32 param_1 = 0; 244 u32 param_1 = 0;
216 u32 retval = func(&param_1, Param(1), Param(2), static_cast<u32>(Param(3))).raw; 245 const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2),
217 Core::CurrentArmInterface().SetReg(1, param_1); 246 static_cast<u32>(Param(system, 3)))
218 FuncReturn(retval); 247 .raw;
248
249 system.CurrentArmInterface().SetReg(1, param_1);
250 FuncReturn(system, retval);
219} 251}
220 252
221template <ResultCode func(Handle*, u64, u32, u32)> 253template <ResultCode func(Core::System&, Handle*, u64, u32, u32)>
222void SvcWrap() { 254void SvcWrap(Core::System& system) {
223 u32 param_1 = 0; 255 u32 param_1 = 0;
224 u32 retval = 256 const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
225 func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw; 257 static_cast<u32>(Param(system, 3)))
226 Core::CurrentArmInterface().SetReg(1, param_1); 258 .raw;
227 FuncReturn(retval); 259
260 system.CurrentArmInterface().SetReg(1, param_1);
261 FuncReturn(system, retval);
228} 262}
229 263
230template <ResultCode func(u64, u32, s32, s64)> 264template <ResultCode func(Core::System&, u64, u32, s32, s64)>
231void SvcWrap() { 265void SvcWrap(Core::System& system) {
232 FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)), 266 FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)),
233 static_cast<s64>(Param(3))) 267 static_cast<s32>(Param(system, 2)), static_cast<s64>(Param(system, 3)))
234 .raw); 268 .raw);
235} 269}
236 270
237template <ResultCode func(u64, u32, s32, s32)> 271template <ResultCode func(Core::System&, u64, u32, s32, s32)>
238void SvcWrap() { 272void SvcWrap(Core::System& system) {
239 FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)), 273 FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)),
240 static_cast<s32>(Param(3))) 274 static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3)))
241 .raw); 275 .raw);
242} 276}
243 277
244//////////////////////////////////////////////////////////////////////////////////////////////////// 278////////////////////////////////////////////////////////////////////////////////////////////////////
245// Function wrappers that return type u32 279// Function wrappers that return type u32
246 280
247template <u32 func()> 281template <u32 func(Core::System&)>
248void SvcWrap() { 282void SvcWrap(Core::System& system) {
249 FuncReturn(func()); 283 FuncReturn(system, func(system));
250} 284}
251 285
252//////////////////////////////////////////////////////////////////////////////////////////////////// 286////////////////////////////////////////////////////////////////////////////////////////////////////
253// Function wrappers that return type u64 287// Function wrappers that return type u64
254 288
255template <u64 func()> 289template <u64 func(Core::System&)>
256void SvcWrap() { 290void SvcWrap(Core::System& system) {
257 FuncReturn(func()); 291 FuncReturn(system, func(system));
258} 292}
259 293
260//////////////////////////////////////////////////////////////////////////////////////////////////// 294////////////////////////////////////////////////////////////////////////////////////////////////////
261/// Function wrappers that return type void 295/// Function wrappers that return type void
262 296
263template <void func()> 297template <void func(Core::System&)>
264void SvcWrap() { 298void SvcWrap(Core::System& system) {
265 func(); 299 func(system);
266} 300}
267 301
268template <void func(s64)> 302template <void func(Core::System&, s64)>
269void SvcWrap() { 303void SvcWrap(Core::System& system) {
270 func(static_cast<s64>(Param(0))); 304 func(system, static_cast<s64>(Param(system, 0)));
271} 305}
272 306
273template <void func(u64, u64 len)> 307template <void func(Core::System&, u64, u64)>
274void SvcWrap() { 308void SvcWrap(Core::System& system) {
275 func(Param(0), Param(1)); 309 func(system, Param(system, 0), Param(system, 1));
276} 310}
277 311
278template <void func(u64, u64, u64)> 312template <void func(Core::System&, u64, u64, u64)>
279void SvcWrap() { 313void SvcWrap(Core::System& system) {
280 func(Param(0), Param(1), Param(2)); 314 func(system, Param(system, 0), Param(system, 1), Param(system, 2));
281} 315}
282 316
283template <void func(u32, u64, u64)> 317template <void func(Core::System&, u32, u64, u64)>
284void SvcWrap() { 318void SvcWrap(Core::System& system) {
285 func(static_cast<u32>(Param(0)), Param(1), Param(2)); 319 func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2));
286} 320}
287 321
288} // namespace Kernel 322} // namespace Kernel
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 73e5d1bb4..83c83e45a 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -106,7 +106,7 @@ public:
106 return "Thread"; 106 return "Thread";
107 } 107 }
108 108
109 static const HandleType HANDLE_TYPE = HandleType::Thread; 109 static constexpr HandleType HANDLE_TYPE = HandleType::Thread;
110 HandleType GetHandleType() const override { 110 HandleType GetHandleType() const override {
111 return HANDLE_TYPE; 111 return HANDLE_TYPE;
112 } 112 }
diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h
index c9068dd3d..d00c92a6b 100644
--- a/src/core/hle/kernel/writable_event.h
+++ b/src/core/hle/kernel/writable_event.h
@@ -37,7 +37,7 @@ public:
37 return name; 37 return name;
38 } 38 }
39 39
40 static const HandleType HANDLE_TYPE = HandleType::WritableEvent; 40 static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent;
41 HandleType GetHandleType() const override { 41 HandleType GetHandleType() const override {
42 return HANDLE_TYPE; 42 return HANDLE_TYPE;
43 } 43 }
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 657baddb8..0249b6992 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -115,11 +115,12 @@ private:
115 115
116 void Read(Kernel::HLERequestContext& ctx) { 116 void Read(Kernel::HLERequestContext& ctx) {
117 IPC::RequestParser rp{ctx}; 117 IPC::RequestParser rp{ctx};
118 const u64 unk = rp.Pop<u64>(); 118 const u64 option = rp.Pop<u64>();
119 const s64 offset = rp.Pop<s64>(); 119 const s64 offset = rp.Pop<s64>();
120 const s64 length = rp.Pop<s64>(); 120 const s64 length = rp.Pop<s64>();
121 121
122 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); 122 LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset,
123 length);
123 124
124 // Error checking 125 // Error checking
125 if (length < 0) { 126 if (length < 0) {
@@ -148,11 +149,12 @@ private:
148 149
149 void Write(Kernel::HLERequestContext& ctx) { 150 void Write(Kernel::HLERequestContext& ctx) {
150 IPC::RequestParser rp{ctx}; 151 IPC::RequestParser rp{ctx};
151 const u64 unk = rp.Pop<u64>(); 152 const u64 option = rp.Pop<u64>();
152 const s64 offset = rp.Pop<s64>(); 153 const s64 offset = rp.Pop<s64>();
153 const s64 length = rp.Pop<s64>(); 154 const s64 length = rp.Pop<s64>();
154 155
155 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); 156 LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset,
157 length);
156 158
157 // Error checking 159 // Error checking
158 if (length < 0) { 160 if (length < 0) {
@@ -250,10 +252,7 @@ private:
250 u64 next_entry_index = 0; 252 u64 next_entry_index = 0;
251 253
252 void Read(Kernel::HLERequestContext& ctx) { 254 void Read(Kernel::HLERequestContext& ctx) {
253 IPC::RequestParser rp{ctx}; 255 LOG_DEBUG(Service_FS, "called.");
254 const u64 unk = rp.Pop<u64>();
255
256 LOG_DEBUG(Service_FS, "called, unk=0x{:X}", unk);
257 256
258 // Calculate how many entries we can fit in the output buffer 257 // Calculate how many entries we can fit in the output buffer
259 const u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); 258 const u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index c7f5bbf28..3c5c53e24 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -21,12 +21,13 @@
21#include "core/hle/service/vi/display/vi_display.h" 21#include "core/hle/service/vi/display/vi_display.h"
22#include "core/hle/service/vi/layer/vi_layer.h" 22#include "core/hle/service/vi/layer/vi_layer.h"
23#include "core/perf_stats.h" 23#include "core/perf_stats.h"
24#include "core/settings.h"
24#include "video_core/renderer_base.h" 25#include "video_core/renderer_base.h"
25 26
26namespace Service::NVFlinger { 27namespace Service::NVFlinger {
27 28
28constexpr std::size_t SCREEN_REFRESH_RATE = 60; 29constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60);
29constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE); 30constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 30);
30 31
31NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_timing} { 32NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_timing} {
32 displays.emplace_back(0, "Default"); 33 displays.emplace_back(0, "Default");
@@ -36,13 +37,15 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t
36 displays.emplace_back(4, "Null"); 37 displays.emplace_back(4, "Null");
37 38
38 // Schedule the screen composition events 39 // Schedule the screen composition events
39 composition_event = 40 const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks;
40 core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, s64 cycles_late) { 41
42 composition_event = core_timing.RegisterEvent(
43 "ScreenComposition", [this, ticks](u64 userdata, s64 cycles_late) {
41 Compose(); 44 Compose();
42 this->core_timing.ScheduleEvent(frame_ticks - cycles_late, composition_event); 45 this->core_timing.ScheduleEvent(ticks - cycles_late, composition_event);
43 }); 46 });
44 47
45 core_timing.ScheduleEvent(frame_ticks, composition_event); 48 core_timing.ScheduleEvent(ticks, composition_event);
46} 49}
47 50
48NVFlinger::~NVFlinger() { 51NVFlinger::~NVFlinger() {
@@ -62,6 +65,7 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
62 const auto itr = 65 const auto itr =
63 std::find_if(displays.begin(), displays.end(), 66 std::find_if(displays.begin(), displays.end(),
64 [&](const VI::Display& display) { return display.GetName() == name; }); 67 [&](const VI::Display& display) { return display.GetName() == name; });
68
65 if (itr == displays.end()) { 69 if (itr == displays.end()) {
66 return {}; 70 return {};
67 } 71 }
diff --git a/src/core/settings.h b/src/core/settings.h
index d543eb32f..b84390745 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -393,6 +393,7 @@ struct Values {
393 bool use_disk_shader_cache; 393 bool use_disk_shader_cache;
394 bool use_accurate_gpu_emulation; 394 bool use_accurate_gpu_emulation;
395 bool use_asynchronous_gpu_emulation; 395 bool use_asynchronous_gpu_emulation;
396 bool force_30fps_mode;
396 397
397 float bg_red; 398 float bg_red;
398 float bg_green; 399 float bg_green;