Merge pull request #2360 from lioncash/svc-global

kernel/svc: Deglobalize the supervisor call handlers
This commit is contained in:
bunnei 2019-04-11 21:50:05 -04:00 committed by GitHub
commit 83a2fb3c3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 419 additions and 370 deletions

View File

@ -14,6 +14,7 @@
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/core_timing_util.h" #include "core/core_timing_util.h"
#include "core/gdbstub/gdbstub.h" #include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc.h"
#include "core/hle/kernel/vm_manager.h" #include "core/hle/kernel/vm_manager.h"
@ -99,7 +100,7 @@ public:
} }
void CallSVC(u32 swi) override { void CallSVC(u32 swi) override {
Kernel::CallSVC(swi); Kernel::CallSVC(parent.system, swi);
} }
void AddTicks(u64 ticks) override { void AddTicks(u64 ticks) override {
@ -112,14 +113,14 @@ public:
// Always execute at least one tick. // Always execute at least one tick.
amortized_ticks = std::max<u64>(amortized_ticks, 1); amortized_ticks = std::max<u64>(amortized_ticks, 1);
parent.core_timing.AddTicks(amortized_ticks); parent.system.CoreTiming().AddTicks(amortized_ticks);
num_interpreted_instructions = 0; num_interpreted_instructions = 0;
} }
u64 GetTicksRemaining() override { u64 GetTicksRemaining() override {
return std::max(parent.core_timing.GetDowncount(), 0); return std::max(parent.system.CoreTiming().GetDowncount(), 0);
} }
u64 GetCNTPCT() override { u64 GetCNTPCT() override {
return Timing::CpuCyclesToClockCycles(parent.core_timing.GetTicks()); return Timing::CpuCyclesToClockCycles(parent.system.CoreTiming().GetTicks());
} }
ARM_Dynarmic& parent; ARM_Dynarmic& parent;
@ -129,7 +130,7 @@ public:
}; };
std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
auto* current_process = Core::CurrentProcess(); auto* current_process = system.Kernel().CurrentProcess();
auto** const page_table = current_process->VMManager().page_table.pointers.data(); auto** const page_table = current_process->VMManager().page_table.pointers.data();
Dynarmic::A64::UserConfig config; Dynarmic::A64::UserConfig config;
@ -171,10 +172,10 @@ void ARM_Dynarmic::Step() {
cb->InterpreterFallback(jit->GetPC(), 1); cb->InterpreterFallback(jit->GetPC(), 1);
} }
ARM_Dynarmic::ARM_Dynarmic(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor, ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor,
std::size_t core_index) std::size_t core_index)
: cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{core_timing}, : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
core_index{core_index}, core_timing{core_timing}, core_index{core_index}, system{system},
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} { exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {
ThreadContext ctx{}; ThreadContext ctx{};
inner_unicorn.SaveContext(ctx); inner_unicorn.SaveContext(ctx);

View File

@ -12,19 +12,15 @@
#include "core/arm/exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
#include "core/arm/unicorn/arm_unicorn.h" #include "core/arm/unicorn/arm_unicorn.h"
namespace Core::Timing {
class CoreTiming;
}
namespace Core { namespace Core {
class ARM_Dynarmic_Callbacks; class ARM_Dynarmic_Callbacks;
class DynarmicExclusiveMonitor; class DynarmicExclusiveMonitor;
class System;
class ARM_Dynarmic final : public ARM_Interface { class ARM_Dynarmic final : public ARM_Interface {
public: public:
ARM_Dynarmic(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor, ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor, std::size_t core_index);
std::size_t core_index);
~ARM_Dynarmic() override; ~ARM_Dynarmic() override;
void MapBackingMemory(VAddr address, std::size_t size, u8* memory, void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
@ -63,7 +59,7 @@ private:
ARM_Unicorn inner_unicorn; ARM_Unicorn inner_unicorn;
std::size_t core_index; std::size_t core_index;
Timing::CoreTiming& core_timing; System& system;
DynarmicExclusiveMonitor& exclusive_monitor; DynarmicExclusiveMonitor& exclusive_monitor;
}; };

View File

@ -10,7 +10,6 @@
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc.h"
#include "core/memory.h"
namespace Core { namespace Core {
@ -49,20 +48,6 @@ static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_
} }
} }
static void InterruptHook(uc_engine* uc, u32 intNo, void* user_data) {
u32 esr{};
CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
auto ec = esr >> 26;
auto iss = esr & 0xFFFFFF;
switch (ec) {
case 0x15: // SVC
Kernel::CallSVC(iss);
break;
}
}
static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value, static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value,
void* user_data) { void* user_data) {
ARM_Interface::ThreadContext ctx{}; ARM_Interface::ThreadContext ctx{};
@ -72,7 +57,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
return {}; return {};
} }
ARM_Unicorn::ARM_Unicorn(Timing::CoreTiming& core_timing) : core_timing{core_timing} { ARM_Unicorn::ARM_Unicorn(System& system) : system{system} {
CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
auto fpv = 3 << 20; auto fpv = 3 << 20;
@ -177,7 +162,7 @@ void ARM_Unicorn::Run() {
if (GDBStub::IsServerEnabled()) { if (GDBStub::IsServerEnabled()) {
ExecuteInstructions(std::max(4000000, 0)); ExecuteInstructions(std::max(4000000, 0));
} else { } else {
ExecuteInstructions(std::max(core_timing.GetDowncount(), 0)); ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), 0));
} }
} }
@ -190,7 +175,7 @@ MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
void ARM_Unicorn::ExecuteInstructions(int num_instructions) { void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
MICROPROFILE_SCOPE(ARM_Jit_Unicorn); MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
core_timing.AddTicks(num_instructions); system.CoreTiming().AddTicks(num_instructions);
if (GDBStub::IsServerEnabled()) { if (GDBStub::IsServerEnabled()) {
if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) { if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) {
uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address); uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address);
@ -273,4 +258,20 @@ void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) {
last_bkpt_hit = true; last_bkpt_hit = true;
} }
void ARM_Unicorn::InterruptHook(uc_engine* uc, u32 int_no, void* user_data) {
u32 esr{};
CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
const auto ec = esr >> 26;
const auto iss = esr & 0xFFFFFF;
auto* const arm_instance = static_cast<ARM_Unicorn*>(user_data);
switch (ec) {
case 0x15: // SVC
Kernel::CallSVC(arm_instance->system, iss);
break;
}
}
} // namespace Core } // namespace Core

View File

@ -9,15 +9,13 @@
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/gdbstub/gdbstub.h" #include "core/gdbstub/gdbstub.h"
namespace Core::Timing {
class CoreTiming;
}
namespace Core { namespace Core {
class System;
class ARM_Unicorn final : public ARM_Interface { class ARM_Unicorn final : public ARM_Interface {
public: public:
explicit ARM_Unicorn(Timing::CoreTiming& core_timing); explicit ARM_Unicorn(System& system);
~ARM_Unicorn() override; ~ARM_Unicorn() override;
void MapBackingMemory(VAddr address, std::size_t size, u8* memory, void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
@ -47,8 +45,10 @@ public:
void RecordBreak(GDBStub::BreakpointAddress bkpt); void RecordBreak(GDBStub::BreakpointAddress bkpt);
private: private:
static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data);
uc_engine* uc{}; uc_engine* uc{};
Timing::CoreTiming& core_timing; System& system;
GDBStub::BreakpointAddress last_bkpt{}; GDBStub::BreakpointAddress last_bkpt{};
bool last_bkpt_hit = false; bool last_bkpt_hit = false;
}; };

View File

@ -55,13 +55,13 @@ Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_ba
: cpu_barrier{cpu_barrier}, core_timing{system.CoreTiming()}, core_index{core_index} { : cpu_barrier{cpu_barrier}, core_timing{system.CoreTiming()}, core_index{core_index} {
if (Settings::values.use_cpu_jit) { if (Settings::values.use_cpu_jit) {
#ifdef ARCHITECTURE_x86_64 #ifdef ARCHITECTURE_x86_64
arm_interface = std::make_unique<ARM_Dynarmic>(core_timing, exclusive_monitor, core_index); arm_interface = std::make_unique<ARM_Dynarmic>(system, exclusive_monitor, core_index);
#else #else
arm_interface = std::make_unique<ARM_Unicorn>(); arm_interface = std::make_unique<ARM_Unicorn>(system);
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
#endif #endif
} else { } else {
arm_interface = std::make_unique<ARM_Unicorn>(core_timing); arm_interface = std::make_unique<ARM_Unicorn>(system);
} }
scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface); scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface);

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,12 @@
#include "common/common_types.h" #include "common/common_types.h"
namespace Core {
class System;
}
namespace Kernel { namespace Kernel {
void CallSVC(u32 immediate); void CallSVC(Core::System& system, u32 immediate);
} // namespace Kernel } // namespace Kernel

View File

@ -11,278 +11,312 @@
namespace Kernel { namespace Kernel {
static inline u64 Param(int n) { static inline u64 Param(const Core::System& system, int n) {
return Core::CurrentArmInterface().GetReg(n); return system.CurrentArmInterface().GetReg(n);
} }
/** /**
* HLE a function return from the current ARM userland process * HLE a function return from the current ARM userland process
* @param res Result to return * @param system System context
* @param result Result to return
*/ */
static inline void FuncReturn(u64 res) { static inline void FuncReturn(Core::System& system, u64 result) {
Core::CurrentArmInterface().SetReg(0, res); system.CurrentArmInterface().SetReg(0, result);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Function wrappers that return type ResultCode // Function wrappers that return type ResultCode
template <ResultCode func(u64)> template <ResultCode func(Core::System&, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(Param(0)).raw); FuncReturn(system, func(system, Param(system, 0)).raw);
} }
template <ResultCode func(u32)> template <ResultCode func(Core::System&, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(static_cast<u32>(Param(0))).raw); FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw);
} }
template <ResultCode func(u32, u32)> template <ResultCode func(Core::System&, u32, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1))).raw); FuncReturn(
system,
func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw);
} }
template <ResultCode func(u32*)> template <ResultCode func(Core::System&, u32*)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param = 0; u32 param = 0;
const u32 retval = func(&param).raw; const u32 retval = func(system, &param).raw;
Core::CurrentArmInterface().SetReg(1, param); system.CurrentArmInterface().SetReg(1, param);
FuncReturn(retval); FuncReturn(system, retval);
} }
template <ResultCode func(u32*, u32)> template <ResultCode func(Core::System&, u32*, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = func(&param_1, static_cast<u32>(Param(1))).raw; const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1))).raw;
Core::CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(system, retval);
} }
template <ResultCode func(u32*, u32*)> template <ResultCode func(Core::System&, u32*, u32*)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
u32 param_2 = 0; u32 param_2 = 0;
const u32 retval = func(&param_1, &param_2).raw; const u32 retval = func(system, &param_1, &param_2).raw;
auto& arm_interface = Core::CurrentArmInterface(); auto& arm_interface = system.CurrentArmInterface();
arm_interface.SetReg(1, param_1); arm_interface.SetReg(1, param_1);
arm_interface.SetReg(2, param_2); arm_interface.SetReg(2, param_2);
FuncReturn(retval); FuncReturn(system, retval);
} }
template <ResultCode func(u32*, u64)> template <ResultCode func(Core::System&, u32*, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
const u32 retval = func(&param_1, Param(1)).raw; const u32 retval = func(system, &param_1, Param(system, 1)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(system, retval);
} }
template <ResultCode func(u32*, u64, u32)> template <ResultCode func(Core::System&, u32*, u64, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
const u32 retval = func(&param_1, Param(1), static_cast<u32>(Param(2))).raw; const u32 retval =
Core::CurrentArmInterface().SetReg(1, param_1); func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2))).raw;
FuncReturn(retval);
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u64*, u32)> template <ResultCode func(Core::System&, u64*, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u64 param_1 = 0; u64 param_1 = 0;
const u32 retval = func(&param_1, static_cast<u32>(Param(1))).raw; const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1))).raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u64, s32)> template <ResultCode func(Core::System&, u64, s32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(Param(0), static_cast<s32>(Param(1))).raw); FuncReturn(system, func(system, Param(system, 0), static_cast<s32>(Param(system, 1))).raw);
} }
template <ResultCode func(u64, u32)> template <ResultCode func(Core::System&, u64, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw); FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw);
} }
template <ResultCode func(u64*, u64)> template <ResultCode func(Core::System&, u64*, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u64 param_1 = 0; u64 param_1 = 0;
u32 retval = func(&param_1, Param(1)).raw; const u32 retval = func(system, &param_1, Param(system, 1)).raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u64*, u32, u32)> template <ResultCode func(Core::System&, u64*, u32, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u64 param_1 = 0; u64 param_1 = 0;
u32 retval = func(&param_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw; const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1)),
Core::CurrentArmInterface().SetReg(1, param_1); static_cast<u32>(Param(system, 2)))
FuncReturn(retval); .raw;
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u32, u64)> template <ResultCode func(Core::System&, u32, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw); FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw);
} }
template <ResultCode func(u32, u32, u64)> template <ResultCode func(Core::System&, u32, u32, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1)), Param(2)).raw); FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)),
static_cast<u32>(Param(system, 1)), Param(system, 2))
.raw);
} }
template <ResultCode func(u32, u32*, u64*)> template <ResultCode func(Core::System&, u32, u32*, u64*)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
u64 param_2 = 0; u64 param_2 = 0;
ResultCode retval = func(static_cast<u32>(Param(2)), &param_1, &param_2); const ResultCode retval = func(system, static_cast<u32>(Param(system, 2)), &param_1, &param_2);
Core::CurrentArmInterface().SetReg(1, param_1);
Core::CurrentArmInterface().SetReg(2, param_2); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval.raw); system.CurrentArmInterface().SetReg(2, param_2);
FuncReturn(system, retval.raw);
} }
template <ResultCode func(u64, u64, u32, u32)> template <ResultCode func(Core::System&, u64, u64, u32, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3)))
.raw);
}
template <ResultCode func(Core::System&, u64, u64, u32, u64)>
void SvcWrap(Core::System& system) {
FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
static_cast<u32>(Param(system, 2)), Param(system, 3))
.raw);
}
template <ResultCode func(Core::System&, u32, u64, u32)>
void SvcWrap(Core::System& system) {
FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
static_cast<u32>(Param(system, 2)))
.raw);
}
template <ResultCode func(Core::System&, u64, u64, u64)>
void SvcWrap(Core::System& system) {
FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw);
}
template <ResultCode func(Core::System&, u64, u64, u32)>
void SvcWrap(Core::System& system) {
FuncReturn( FuncReturn(
func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw); system,
func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw);
} }
template <ResultCode func(u64, u64, u32, u64)> template <ResultCode func(Core::System&, u32, u64, u64, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2)), Param(3)).raw); FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
Param(system, 2), static_cast<u32>(Param(system, 3)))
.raw);
} }
template <ResultCode func(u32, u64, u32)> template <ResultCode func(Core::System&, u32, u64, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw);
}
template <ResultCode func(u64, u64, u64)>
void SvcWrap() {
FuncReturn(func(Param(0), Param(1), Param(2)).raw);
}
template <ResultCode func(u64, u64, u32)>
void SvcWrap() {
FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2))).raw);
}
template <ResultCode func(u32, u64, u64, u32)>
void SvcWrap() {
FuncReturn( FuncReturn(
func(static_cast<u32>(Param(0)), Param(1), Param(2), static_cast<u32>(Param(3))).raw); system,
func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw);
} }
template <ResultCode func(u32, u64, u64)> template <ResultCode func(Core::System&, u32*, u64, u64, s64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(static_cast<u32>(Param(0)), Param(1), Param(2)).raw);
}
template <ResultCode func(u32*, u64, u64, s64)>
void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
ResultCode retval = const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))); static_cast<s64>(Param(system, 3)))
Core::CurrentArmInterface().SetReg(1, param_1); .raw;
FuncReturn(retval.raw);
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u64, u64, u32, s64)> template <ResultCode func(Core::System&, u64, u64, u32, s64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn( FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))).raw); static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3)))
.raw);
} }
template <ResultCode func(u64*, u64, u64, u64)> template <ResultCode func(Core::System&, u64*, u64, u64, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u64 param_1 = 0; u64 param_1 = 0;
u32 retval = func(&param_1, Param(1), Param(2), Param(3)).raw; const u32 retval =
Core::CurrentArmInterface().SetReg(1, param_1); func(system, &param_1, Param(system, 1), Param(system, 2), Param(system, 3)).raw;
FuncReturn(retval);
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u32*, u64, u64, u64, u32, s32)> template <ResultCode func(Core::System&, u32*, u64, u64, u64, u32, s32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = func(&param_1, Param(1), Param(2), Param(3), static_cast<u32>(Param(4)), const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2), Param(system, 3),
static_cast<s32>(Param(5))) static_cast<u32>(Param(system, 4)), static_cast<s32>(Param(system, 5)))
.raw; .raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u32*, u64, u64, u32)> template <ResultCode func(Core::System&, u32*, u64, u64, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = func(&param_1, Param(1), Param(2), static_cast<u32>(Param(3))).raw; const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2),
Core::CurrentArmInterface().SetReg(1, param_1); static_cast<u32>(Param(system, 3)))
FuncReturn(retval); .raw;
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(Handle*, u64, u32, u32)> template <ResultCode func(Core::System&, Handle*, u64, u32, u32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw; static_cast<u32>(Param(system, 3)))
Core::CurrentArmInterface().SetReg(1, param_1); .raw;
FuncReturn(retval);
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
} }
template <ResultCode func(u64, u32, s32, s64)> template <ResultCode func(Core::System&, u64, u32, s32, s64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)), FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)),
static_cast<s64>(Param(3))) static_cast<s32>(Param(system, 2)), static_cast<s64>(Param(system, 3)))
.raw); .raw);
} }
template <ResultCode func(u64, u32, s32, s32)> template <ResultCode func(Core::System&, u64, u32, s32, s32)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)), FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)),
static_cast<s32>(Param(3))) static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3)))
.raw); .raw);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Function wrappers that return type u32 // Function wrappers that return type u32
template <u32 func()> template <u32 func(Core::System&)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func()); FuncReturn(system, func(system));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Function wrappers that return type u64 // Function wrappers that return type u64
template <u64 func()> template <u64 func(Core::System&)>
void SvcWrap() { void SvcWrap(Core::System& system) {
FuncReturn(func()); FuncReturn(system, func(system));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
/// Function wrappers that return type void /// Function wrappers that return type void
template <void func()> template <void func(Core::System&)>
void SvcWrap() { void SvcWrap(Core::System& system) {
func(); func(system);
} }
template <void func(s64)> template <void func(Core::System&, s64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
func(static_cast<s64>(Param(0))); func(system, static_cast<s64>(Param(system, 0)));
} }
template <void func(u64, u64 len)> template <void func(Core::System&, u64, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
func(Param(0), Param(1)); func(system, Param(system, 0), Param(system, 1));
} }
template <void func(u64, u64, u64)> template <void func(Core::System&, u64, u64, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
func(Param(0), Param(1), Param(2)); func(system, Param(system, 0), Param(system, 1), Param(system, 2));
} }
template <void func(u32, u64, u64)> template <void func(Core::System&, u32, u64, u64)>
void SvcWrap() { void SvcWrap(Core::System& system) {
func(static_cast<u32>(Param(0)), Param(1), Param(2)); func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2));
} }
} // namespace Kernel } // namespace Kernel