diff options
Diffstat (limited to 'src/core')
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 | ||
| 131 | std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { | 132 | std::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 | ||
| 174 | ARM_Dynarmic::ARM_Dynarmic(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor, | 175 | ARM_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 | ||
| 15 | namespace Core::Timing { | ||
| 16 | class CoreTiming; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Core { | 15 | namespace Core { |
| 20 | 16 | ||
| 21 | class ARM_Dynarmic_Callbacks; | 17 | class ARM_Dynarmic_Callbacks; |
| 22 | class DynarmicExclusiveMonitor; | 18 | class DynarmicExclusiveMonitor; |
| 19 | class System; | ||
| 23 | 20 | ||
| 24 | class ARM_Dynarmic final : public ARM_Interface { | 21 | class ARM_Dynarmic final : public ARM_Interface { |
| 25 | public: | 22 | public: |
| 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 | ||
| 15 | namespace Core { | 14 | namespace Core { |
| 16 | 15 | ||
| @@ -49,20 +48,6 @@ static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_ | |||
| 49 | } | 48 | } |
| 50 | } | 49 | } |
| 51 | 50 | ||
| 52 | static void InterruptHook(uc_engine* uc, u32 intNo, void* user_data) { | ||
| 53 | u32 esr{}; | ||
| 54 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr)); | ||
| 55 | |||
| 56 | auto ec = esr >> 26; | ||
| 57 | auto iss = esr & 0xFFFFFF; | ||
| 58 | |||
| 59 | switch (ec) { | ||
| 60 | case 0x15: // SVC | ||
| 61 | Kernel::CallSVC(iss); | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value, | 51 | static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value, |
| 67 | void* user_data) { | 52 | void* user_data) { |
| 68 | ARM_Interface::ThreadContext ctx{}; | 53 | ARM_Interface::ThreadContext ctx{}; |
| @@ -72,7 +57,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si | |||
| 72 | return {}; | 57 | return {}; |
| 73 | } | 58 | } |
| 74 | 59 | ||
| 75 | ARM_Unicorn::ARM_Unicorn(Timing::CoreTiming& core_timing) : core_timing{core_timing} { | 60 | ARM_Unicorn::ARM_Unicorn(System& system) : system{system} { |
| 76 | CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); | 61 | CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); |
| 77 | 62 | ||
| 78 | auto fpv = 3 << 20; | 63 | auto fpv = 3 << 20; |
| @@ -177,7 +162,7 @@ void ARM_Unicorn::Run() { | |||
| 177 | if (GDBStub::IsServerEnabled()) { | 162 | if (GDBStub::IsServerEnabled()) { |
| 178 | ExecuteInstructions(std::max(4000000, 0)); | 163 | ExecuteInstructions(std::max(4000000, 0)); |
| 179 | } else { | 164 | } else { |
| 180 | ExecuteInstructions(std::max(core_timing.GetDowncount(), 0)); | 165 | ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), 0)); |
| 181 | } | 166 | } |
| 182 | } | 167 | } |
| 183 | 168 | ||
| @@ -190,7 +175,7 @@ MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64)); | |||
| 190 | void ARM_Unicorn::ExecuteInstructions(int num_instructions) { | 175 | void ARM_Unicorn::ExecuteInstructions(int num_instructions) { |
| 191 | MICROPROFILE_SCOPE(ARM_Jit_Unicorn); | 176 | MICROPROFILE_SCOPE(ARM_Jit_Unicorn); |
| 192 | CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); | 177 | CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); |
| 193 | core_timing.AddTicks(num_instructions); | 178 | system.CoreTiming().AddTicks(num_instructions); |
| 194 | if (GDBStub::IsServerEnabled()) { | 179 | if (GDBStub::IsServerEnabled()) { |
| 195 | if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) { | 180 | if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) { |
| 196 | uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address); | 181 | uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address); |
| @@ -273,4 +258,20 @@ void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) { | |||
| 273 | last_bkpt_hit = true; | 258 | last_bkpt_hit = true; |
| 274 | } | 259 | } |
| 275 | 260 | ||
| 261 | void ARM_Unicorn::InterruptHook(uc_engine* uc, u32 int_no, void* user_data) { | ||
| 262 | u32 esr{}; | ||
| 263 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr)); | ||
| 264 | |||
| 265 | const auto ec = esr >> 26; | ||
| 266 | const auto iss = esr & 0xFFFFFF; | ||
| 267 | |||
| 268 | auto* const arm_instance = static_cast<ARM_Unicorn*>(user_data); | ||
| 269 | |||
| 270 | switch (ec) { | ||
| 271 | case 0x15: // SVC | ||
| 272 | Kernel::CallSVC(arm_instance->system, iss); | ||
| 273 | break; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 276 | } // namespace Core | 277 | } // namespace Core |
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index 1e44f0736..209fc16ad 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h | |||
| @@ -9,15 +9,13 @@ | |||
| 9 | #include "core/arm/arm_interface.h" | 9 | #include "core/arm/arm_interface.h" |
| 10 | #include "core/gdbstub/gdbstub.h" | 10 | #include "core/gdbstub/gdbstub.h" |
| 11 | 11 | ||
| 12 | namespace Core::Timing { | ||
| 13 | class CoreTiming; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace Core { | 12 | namespace Core { |
| 17 | 13 | ||
| 14 | class System; | ||
| 15 | |||
| 18 | class ARM_Unicorn final : public ARM_Interface { | 16 | class ARM_Unicorn final : public ARM_Interface { |
| 19 | public: | 17 | public: |
| 20 | explicit ARM_Unicorn(Timing::CoreTiming& core_timing); | 18 | explicit ARM_Unicorn(System& system); |
| 21 | ~ARM_Unicorn() override; | 19 | ~ARM_Unicorn() override; |
| 22 | 20 | ||
| 23 | void MapBackingMemory(VAddr address, std::size_t size, u8* memory, | 21 | void MapBackingMemory(VAddr address, std::size_t size, u8* memory, |
| @@ -47,8 +45,10 @@ public: | |||
| 47 | void RecordBreak(GDBStub::BreakpointAddress bkpt); | 45 | void RecordBreak(GDBStub::BreakpointAddress bkpt); |
| 48 | 46 | ||
| 49 | private: | 47 | private: |
| 48 | static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data); | ||
| 49 | |||
| 50 | uc_engine* uc{}; | 50 | uc_engine* uc{}; |
| 51 | Timing::CoreTiming& core_timing; | 51 | System& system; |
| 52 | GDBStub::BreakpointAddress last_bkpt{}; | 52 | GDBStub::BreakpointAddress last_bkpt{}; |
| 53 | bool last_bkpt_hit = false; | 53 | bool last_bkpt_hit = false; |
| 54 | }; | 54 | }; |
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 @@ | |||
| 13 | namespace Core::Frontend { | 13 | namespace 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 | */ | ||
| 20 | class GraphicsContext { | ||
| 21 | public: | ||
| 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 | */ |
| 33 | class EmuWindow { | 50 | class EmuWindow : public GraphicsContext { |
| 34 | public: | 51 | public: |
| 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 | ||
| 134 | ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_type, | 134 | ResultVal<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. |
| 163 | static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { | 162 | static 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 | ||
| 188 | static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | 187 | static 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 | ||
| 245 | static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attribute) { | 244 | static 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. |
| 294 | static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | 294 | static 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 |
| 309 | static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | 309 | static 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 |
| 324 | static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { | 324 | static 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. |
| 362 | static ResultCode SendSyncRequest(Handle handle) { | 363 | static 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. |
| 380 | static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) { | 381 | static 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. |
| 395 | static ResultCode GetProcessId(u64* process_id, Handle handle) { | 396 | static 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 |
| 440 | static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, | 441 | static 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 |
| 516 | static ResultCode CancelSynchronization(Handle thread_handle) { | 517 | static 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 |
| 534 | static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, | 535 | static 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 |
| 558 | static ResultCode ArbitrateUnlock(VAddr mutex_addr) { | 559 | static 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 |
| 595 | static void Break(u32 reason, u64 info1, u64 info2) { | 596 | static 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 |
| 688 | static void OutputDebugString(VAddr address, u64 len) { | 691 | static 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 |
| 699 | static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { | 702 | static 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 |
| 930 | static ResultCode SetThreadActivity(Handle handle, u32 activity) { | 934 | static 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 |
| 963 | static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { | 967 | static 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 |
| 1004 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { | 1008 | static 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 |
| 1019 | static ResultCode SetThreadPriority(Handle handle, u32 priority) { | 1023 | static 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 |
| 1045 | static u32 GetCurrentProcessorNumber() { | 1049 | static 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 | ||
| 1050 | static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, | 1054 | static 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 | ||
| 1103 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { | 1107 | static 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 | ||
| 1146 | static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_address, | 1151 | static 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 | ||
| 1175 | static ResultCode QueryMemory(VAddr memory_info_address, VAddr page_info_address, | 1181 | static 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 |
| 1187 | static void ExitProcess() { | 1193 | static 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 |
| 1203 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, | 1209 | static 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 |
| 1262 | static ResultCode StartThread(Handle thread_handle) { | 1268 | static 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 |
| 1285 | static void ExitThread() { | 1291 | static 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 |
| 1297 | static void SleepThread(s64 nanoseconds) { | 1301 | static 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 |
| 1335 | static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, | 1338 | static 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 |
| 1382 | static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { | 1386 | static 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) |
| 1490 | static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) { | 1494 | static 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) |
| 1511 | static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) { | 1517 | static 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 |
| 1532 | static u64 GetSystemTick() { | 1540 | static 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 |
| 1545 | static ResultCode CloseHandle(Handle handle) { | 1553 | static 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. |
| 1553 | static ResultCode ResetSignal(Handle handle) { | 1561 | static 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 |
| 1573 | static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { | 1581 | static 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 | ||
| 1614 | static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32 permission_raw) { | 1623 | static 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 | ||
| 1670 | static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) { | 1680 | static 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 | ||
| 1717 | static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { | 1728 | static 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 | ||
| 1734 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | 1746 | static 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 | ||
| 1783 | static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, | 1796 | static 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 | ||
| 1829 | static ResultCode CreateEvent(Handle* write_handle, Handle* read_handle) { | 1842 | static 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 | ||
| 1857 | static ResultCode ClearEvent(Handle handle) { | 1870 | static 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 | ||
| 1878 | static ResultCode SignalEvent(Handle handle) { | 1891 | static 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 | ||
| 1893 | static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { | 1906 | static 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 | ||
| 1919 | static ResultCode CreateResourceLimit(Handle* out_handle) { | 1932 | static 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 | ||
| 1937 | static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_limit, | 1950 | static 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 | ||
| 1951 | static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit, | 1964 | static 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 | ||
| 1965 | static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource_type, u64 value) { | 1978 | static 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 | ||
| 2000 | static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids, | 2013 | static 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 | ||
| 2037 | ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thread_ids_size, | 2050 | ResultCode 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 | ||
| 2077 | namespace { | 2090 | namespace { |
| 2078 | struct FunctionDef { | 2091 | struct 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 | ||
| 2226 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | 2239 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); |
| 2227 | 2240 | ||
| 2228 | void CallSVC(u32 immediate) { | 2241 | void 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 | ||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace Kernel { | 13 | namespace Kernel { |
| 10 | 14 | ||
| 11 | void CallSVC(u32 immediate); | 15 | void 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 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | static inline u64 Param(int n) { | 14 | static 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 | */ |
| 22 | static inline void FuncReturn(u64 res) { | 23 | static 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 | ||
| 29 | template <ResultCode func(u64)> | 30 | template <ResultCode func(Core::System&, u64)> |
| 30 | void SvcWrap() { | 31 | void SvcWrap(Core::System& system) { |
| 31 | FuncReturn(func(Param(0)).raw); | 32 | FuncReturn(system, func(system, Param(system, 0)).raw); |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | template <ResultCode func(u32)> | 35 | template <ResultCode func(Core::System&, u32)> |
| 35 | void SvcWrap() { | 36 | void 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 | ||
| 39 | template <ResultCode func(u32, u32)> | 40 | template <ResultCode func(Core::System&, u32, u32)> |
| 40 | void SvcWrap() { | 41 | void 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 | ||
| 44 | template <ResultCode func(u32*)> | 47 | template <ResultCode func(Core::System&, u32*)> |
| 45 | void SvcWrap() { | 48 | void SvcWrap(Core::System& system) { |
| 46 | u32 param = 0; | 49 | u32 param = 0; |
| 47 | const u32 retval = func(¶m).raw; | 50 | const u32 retval = func(system, ¶m).raw; |
| 48 | Core::CurrentArmInterface().SetReg(1, param); | 51 | system.CurrentArmInterface().SetReg(1, param); |
| 49 | FuncReturn(retval); | 52 | FuncReturn(system, retval); |
| 50 | } | 53 | } |
| 51 | 54 | ||
| 52 | template <ResultCode func(u32*, u32)> | 55 | template <ResultCode func(Core::System&, u32*, u32)> |
| 53 | void SvcWrap() { | 56 | void SvcWrap(Core::System& system) { |
| 54 | u32 param_1 = 0; | 57 | u32 param_1 = 0; |
| 55 | u32 retval = func(¶m_1, static_cast<u32>(Param(1))).raw; | 58 | const u32 retval = func(system, ¶m_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 | ||
| 60 | template <ResultCode func(u32*, u32*)> | 63 | template <ResultCode func(Core::System&, u32*, u32*)> |
| 61 | void SvcWrap() { | 64 | void 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(¶m_1, ¶m_2).raw; | 67 | const u32 retval = func(system, ¶m_1, ¶m_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 | ||
| 73 | template <ResultCode func(u32*, u64)> | 76 | template <ResultCode func(Core::System&, u32*, u64)> |
| 74 | void SvcWrap() { | 77 | void SvcWrap(Core::System& system) { |
| 75 | u32 param_1 = 0; | 78 | u32 param_1 = 0; |
| 76 | const u32 retval = func(¶m_1, Param(1)).raw; | 79 | const u32 retval = func(system, ¶m_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 | ||
| 81 | template <ResultCode func(u32*, u64, u32)> | 84 | template <ResultCode func(Core::System&, u32*, u64, u32)> |
| 82 | void SvcWrap() { | 85 | void SvcWrap(Core::System& system) { |
| 83 | u32 param_1 = 0; | 86 | u32 param_1 = 0; |
| 84 | const u32 retval = func(¶m_1, Param(1), static_cast<u32>(Param(2))).raw; | 87 | const u32 retval = |
| 85 | Core::CurrentArmInterface().SetReg(1, param_1); | 88 | func(system, ¶m_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 | ||
| 89 | template <ResultCode func(u64*, u32)> | 94 | template <ResultCode func(Core::System&, u64*, u32)> |
| 90 | void SvcWrap() { | 95 | void SvcWrap(Core::System& system) { |
| 91 | u64 param_1 = 0; | 96 | u64 param_1 = 0; |
| 92 | const u32 retval = func(¶m_1, static_cast<u32>(Param(1))).raw; | 97 | const u32 retval = func(system, ¶m_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 | ||
| 97 | template <ResultCode func(u64, s32)> | 103 | template <ResultCode func(Core::System&, u64, s32)> |
| 98 | void SvcWrap() { | 104 | void 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 | ||
| 102 | template <ResultCode func(u64, u32)> | 108 | template <ResultCode func(Core::System&, u64, u32)> |
| 103 | void SvcWrap() { | 109 | void 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 | ||
| 107 | template <ResultCode func(u64*, u64)> | 113 | template <ResultCode func(Core::System&, u64*, u64)> |
| 108 | void SvcWrap() { | 114 | void SvcWrap(Core::System& system) { |
| 109 | u64 param_1 = 0; | 115 | u64 param_1 = 0; |
| 110 | u32 retval = func(¶m_1, Param(1)).raw; | 116 | const u32 retval = func(system, ¶m_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 | ||
| 115 | template <ResultCode func(u64*, u32, u32)> | 122 | template <ResultCode func(Core::System&, u64*, u32, u32)> |
| 116 | void SvcWrap() { | 123 | void SvcWrap(Core::System& system) { |
| 117 | u64 param_1 = 0; | 124 | u64 param_1 = 0; |
| 118 | u32 retval = func(¶m_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw; | 125 | const u32 retval = func(system, ¶m_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 | ||
| 123 | template <ResultCode func(u32, u64)> | 133 | template <ResultCode func(Core::System&, u32, u64)> |
| 124 | void SvcWrap() { | 134 | void 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 | ||
| 128 | template <ResultCode func(u32, u32, u64)> | 138 | template <ResultCode func(Core::System&, u32, u32, u64)> |
| 129 | void SvcWrap() { | 139 | void 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 | ||
| 133 | template <ResultCode func(u32, u32*, u64*)> | 145 | template <ResultCode func(Core::System&, u32, u32*, u64*)> |
| 134 | void SvcWrap() { | 146 | void 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)), ¶m_1, ¶m_2); | 149 | const ResultCode retval = func(system, static_cast<u32>(Param(system, 2)), ¶m_1, ¶m_2); |
| 138 | Core::CurrentArmInterface().SetReg(1, param_1); | ||
| 139 | Core::CurrentArmInterface().SetReg(2, param_2); | ||
| 140 | FuncReturn(retval.raw); | ||
| 141 | } | ||
| 142 | 150 | ||
| 143 | template <ResultCode func(u64, u64, u32, u32)> | 151 | system.CurrentArmInterface().SetReg(1, param_1); |
| 144 | void 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 | ||
| 149 | template <ResultCode func(u64, u64, u32, u64)> | 156 | template <ResultCode func(Core::System&, u64, u64, u32, u32)> |
| 150 | void SvcWrap() { | 157 | void 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 | ||
| 154 | template <ResultCode func(u32, u64, u32)> | 163 | template <ResultCode func(Core::System&, u64, u64, u32, u64)> |
| 155 | void SvcWrap() { | 164 | void 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 | ||
| 159 | template <ResultCode func(u64, u64, u64)> | 170 | template <ResultCode func(Core::System&, u32, u64, u32)> |
| 160 | void SvcWrap() { | 171 | void 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 | ||
| 164 | template <ResultCode func(u64, u64, u32)> | 177 | template <ResultCode func(Core::System&, u64, u64, u64)> |
| 165 | void SvcWrap() { | 178 | void 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 | ||
| 169 | template <ResultCode func(u32, u64, u64, u32)> | 182 | template <ResultCode func(Core::System&, u64, u64, u32)> |
| 170 | void SvcWrap() { | 183 | void 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 | |||
| 189 | template <ResultCode func(Core::System&, u32, u64, u64, u32)> | ||
| 190 | void 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 | ||
| 175 | template <ResultCode func(u32, u64, u64)> | 196 | template <ResultCode func(Core::System&, u32, u64, u64)> |
| 176 | void SvcWrap() { | 197 | void 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 | ||
| 180 | template <ResultCode func(u32*, u64, u64, s64)> | 203 | template <ResultCode func(Core::System&, u32*, u64, u64, s64)> |
| 181 | void SvcWrap() { | 204 | void SvcWrap(Core::System& system) { |
| 182 | u32 param_1 = 0; | 205 | u32 param_1 = 0; |
| 183 | ResultCode retval = | 206 | const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), |
| 184 | func(¶m_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 | ||
| 189 | template <ResultCode func(u64, u64, u32, s64)> | 214 | template <ResultCode func(Core::System&, u64, u64, u32, s64)> |
| 190 | void SvcWrap() { | 215 | void 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 | ||
| 195 | template <ResultCode func(u64*, u64, u64, u64)> | 221 | template <ResultCode func(Core::System&, u64*, u64, u64, u64)> |
| 196 | void SvcWrap() { | 222 | void SvcWrap(Core::System& system) { |
| 197 | u64 param_1 = 0; | 223 | u64 param_1 = 0; |
| 198 | u32 retval = func(¶m_1, Param(1), Param(2), Param(3)).raw; | 224 | const u32 retval = |
| 199 | Core::CurrentArmInterface().SetReg(1, param_1); | 225 | func(system, ¶m_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 | ||
| 203 | template <ResultCode func(u32*, u64, u64, u64, u32, s32)> | 231 | template <ResultCode func(Core::System&, u32*, u64, u64, u64, u32, s32)> |
| 204 | void SvcWrap() { | 232 | void SvcWrap(Core::System& system) { |
| 205 | u32 param_1 = 0; | 233 | u32 param_1 = 0; |
| 206 | u32 retval = func(¶m_1, Param(1), Param(2), Param(3), static_cast<u32>(Param(4)), | 234 | const u32 retval = func(system, ¶m_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 | ||
| 213 | template <ResultCode func(u32*, u64, u64, u32)> | 242 | template <ResultCode func(Core::System&, u32*, u64, u64, u32)> |
| 214 | void SvcWrap() { | 243 | void SvcWrap(Core::System& system) { |
| 215 | u32 param_1 = 0; | 244 | u32 param_1 = 0; |
| 216 | u32 retval = func(¶m_1, Param(1), Param(2), static_cast<u32>(Param(3))).raw; | 245 | const u32 retval = func(system, ¶m_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 | ||
| 221 | template <ResultCode func(Handle*, u64, u32, u32)> | 253 | template <ResultCode func(Core::System&, Handle*, u64, u32, u32)> |
| 222 | void SvcWrap() { | 254 | void SvcWrap(Core::System& system) { |
| 223 | u32 param_1 = 0; | 255 | u32 param_1 = 0; |
| 224 | u32 retval = | 256 | const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), |
| 225 | func(¶m_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 | ||
| 230 | template <ResultCode func(u64, u32, s32, s64)> | 264 | template <ResultCode func(Core::System&, u64, u32, s32, s64)> |
| 231 | void SvcWrap() { | 265 | void 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 | ||
| 237 | template <ResultCode func(u64, u32, s32, s32)> | 271 | template <ResultCode func(Core::System&, u64, u32, s32, s32)> |
| 238 | void SvcWrap() { | 272 | void 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 | ||
| 247 | template <u32 func()> | 281 | template <u32 func(Core::System&)> |
| 248 | void SvcWrap() { | 282 | void 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 | ||
| 255 | template <u64 func()> | 289 | template <u64 func(Core::System&)> |
| 256 | void SvcWrap() { | 290 | void 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 | ||
| 263 | template <void func()> | 297 | template <void func(Core::System&)> |
| 264 | void SvcWrap() { | 298 | void SvcWrap(Core::System& system) { |
| 265 | func(); | 299 | func(system); |
| 266 | } | 300 | } |
| 267 | 301 | ||
| 268 | template <void func(s64)> | 302 | template <void func(Core::System&, s64)> |
| 269 | void SvcWrap() { | 303 | void SvcWrap(Core::System& system) { |
| 270 | func(static_cast<s64>(Param(0))); | 304 | func(system, static_cast<s64>(Param(system, 0))); |
| 271 | } | 305 | } |
| 272 | 306 | ||
| 273 | template <void func(u64, u64 len)> | 307 | template <void func(Core::System&, u64, u64)> |
| 274 | void SvcWrap() { | 308 | void SvcWrap(Core::System& system) { |
| 275 | func(Param(0), Param(1)); | 309 | func(system, Param(system, 0), Param(system, 1)); |
| 276 | } | 310 | } |
| 277 | 311 | ||
| 278 | template <void func(u64, u64, u64)> | 312 | template <void func(Core::System&, u64, u64, u64)> |
| 279 | void SvcWrap() { | 313 | void 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 | ||
| 283 | template <void func(u32, u64, u64)> | 317 | template <void func(Core::System&, u32, u64, u64)> |
| 284 | void SvcWrap() { | 318 | void 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 | ||
| 26 | namespace Service::NVFlinger { | 27 | namespace Service::NVFlinger { |
| 27 | 28 | ||
| 28 | constexpr std::size_t SCREEN_REFRESH_RATE = 60; | 29 | constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60); |
| 29 | constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE); | 30 | constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 30); |
| 30 | 31 | ||
| 31 | NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_timing} { | 32 | NVFlinger::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 | ||
| 48 | NVFlinger::~NVFlinger() { | 51 | NVFlinger::~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; |