// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include "common/common_types.h" #include "core/arm/arm_interface.h" #include "core/core.h" #include "core/hle/kernel/svc_types.h" #include "core/hle/result.h" namespace Kernel { static inline u64 Param(const Core::System& system, int n) { return system.CurrentArmInterface().GetReg(n); } static inline u32 Param32(const Core::System& system, int n) { return static_cast(system.CurrentArmInterface().GetReg(n)); } /** * HLE a function return from the current ARM userland process * @param system System context * @param result Result to return */ static inline void FuncReturn(Core::System& system, u64 result) { system.CurrentArmInterface().SetReg(0, result); } static inline void FuncReturn32(Core::System& system, u32 result) { system.CurrentArmInterface().SetReg(0, (u64)result); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type Result template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0)).raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1)).raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0))).raw); } template void SvcWrap64(Core::System& system) { FuncReturn( system, func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1))).raw); } // Used by SetThreadActivity template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1))) .raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1), Param(system, 2), Param(system, 3)) .raw); } // Used by MapProcessMemory and UnmapProcessMemory template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast(Param(system, 1)), Param(system, 2), Param(system, 3)) .raw); } // Used by ControlCodeMemory template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), Param(system, 2), Param(system, 3), static_cast(Param(system, 4))) .raw); } template void SvcWrap64(Core::System& system) { u32 param = 0; const u32 retval = func(system, ¶m).raw; system.CurrentArmInterface().SetReg(1, param); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast(Param(system, 1))).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u32 param_1 = 0; u32 param_2 = 0; const u32 retval = func(system, ¶m_1, ¶m_2).raw; auto& arm_interface = system.CurrentArmInterface(); arm_interface.SetReg(1, param_1); arm_interface.SetReg(2, param_2); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast(Param(system, 2))).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast(Param(system, 1))).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast(Param(system, 1))).raw); } template void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast(Param(system, 1)), static_cast(Param(system, 2))) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by GetResourceLimitLimitValue. template void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast(Param(system, 1)), static_cast(Param(system, 2))) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1)).raw); } // Used by SetResourceLimitLimitValue template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), Param(system, 2)) .raw); } // Used by SetThreadCoreMask template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), Param(system, 2)) .raw); } // Used by GetThreadCoreMask template void SvcWrap64(Core::System& system) { s32 param_1 = 0; u64 param_2 = 0; const Result retval = func(system, static_cast(Param(system, 2)), ¶m_1, ¶m_2); system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); FuncReturn(system, retval.raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast(Param(system, 2)), Param(system, 3)) .raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1), static_cast(Param(system, 2))) .raw); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw); } template void SvcWrap64(Core::System& system) { FuncReturn( system, func(system, Param(system, 0), Param(system, 1), static_cast(Param(system, 2))).raw); } // Used by SetMemoryPermission template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast(Param(system, 2))) .raw); } // Used by MapSharedMemory template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1), Param(system, 2), static_cast(Param(system, 3))) .raw); } template void SvcWrap64(Core::System& system) { FuncReturn( system, func(system, static_cast(Param(system, 0)), Param(system, 1), Param(system, 2)).raw); } // Used by WaitSynchronization template void SvcWrap64(Core::System& system) { s32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw); } // Used by GetInfo template void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast(Param(system, 2)), Param(system, 3)) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), Param(system, 3), static_cast(Param(system, 4)), static_cast(Param(system, 5))) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by CreateTransferMemory template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), static_cast(Param(system, 3))) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by CreateCodeMemory template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2)).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by CreateSession template void SvcWrap64(Core::System& system) { Handle param_1 = 0; Handle param_2 = 0; const u32 retval = func(system, ¶m_1, ¶m_2, static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); FuncReturn(system, retval); } // Used by WaitForAddress template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw); } // Used by SignalToAddress template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type u32 template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system)); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type u64 template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system)); } //////////////////////////////////////////////////////////////////////////////////////////////////// /// Function wrappers that return type void template void SvcWrap64(Core::System& system) { func(system); } template void SvcWrap64(Core::System& system) { func(system, static_cast(Param(system, 0))); } template void SvcWrap64(Core::System& system) { func(system, static_cast(Param(system, 0)), Param(system, 1), Param(system, 2), Param(system, 3)); } template void SvcWrap64(Core::System& system) { func(system, static_cast(Param(system, 0))); } template void SvcWrap64(Core::System& system) { func(system, Param(system, 0), static_cast(Param(system, 1))); } template void SvcWrap64(Core::System& system) { func(system, Param(system, 0), Param(system, 1)); } template void SvcWrap64(Core::System& system) { func(system, Param(system, 0), Param(system, 1), Param(system, 2)); } template void SvcWrap64(Core::System& system) { func(system, static_cast(Param(system, 0)), Param(system, 1), Param(system, 2)); } // Used by QueryMemory32, ArbitrateLock32 template void SvcWrap32(Core::System& system) { FuncReturn32(system, func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw); } // Used by Break32 template void SvcWrap32(Core::System& system) { func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)); } // Used by ExitProcess32, ExitThread32 template void SvcWrap32(Core::System& system) { func(system); } // Used by GetCurrentProcessorNumber32 template void SvcWrap32(Core::System& system) { FuncReturn32(system, func(system)); } // Used by SleepThread32 template void SvcWrap32(Core::System& system) { func(system, Param32(system, 0), Param32(system, 1)); } // Used by CreateThread32 template void SvcWrap32(Core::System& system) { Handle param_1 = 0; const u32 retval = func(system, ¶m_1, Param32(system, 0), Param32(system, 1), Param32(system, 2), Param32(system, 3), Param32(system, 4)) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by GetInfo32 template void SvcWrap32(Core::System& system) { u32 param_1 = 0; u32 param_2 = 0; const u32 retval = func(system, ¶m_1, ¶m_2, Param32(system, 0), Param32(system, 1), Param32(system, 2), Param32(system, 3)) .raw; system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); FuncReturn(system, retval); } // Used by GetThreadPriority32, ConnectToNamedPort32 template void SvcWrap32(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param32(system, 1)).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by GetThreadId32 template void SvcWrap32(Core::System& system) { u32 param_1 = 0; u32 param_2 = 0; const u32 retval = func(system, ¶m_1, ¶m_2, Param32(system, 1)).raw; system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); FuncReturn(system, retval); } // Used by GetSystemTick32 template void SvcWrap32(Core::System& system) { u32 param_1 = 0; u32 param_2 = 0; func(system, ¶m_1, ¶m_2); system.CurrentArmInterface().SetReg(0, param_1); system.CurrentArmInterface().SetReg(1, param_2); } // Used by CreateEvent32 template void SvcWrap32(Core::System& system) { Handle param_1 = 0; Handle param_2 = 0; const u32 retval = func(system, ¶m_1, ¶m_2).raw; system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); FuncReturn(system, retval); } // Used by GetThreadId32 template void SvcWrap32(Core::System& system) { u32 param_1 = 0; u32 param_2 = 0; u32 param_3 = 0; const u32 retval = func(system, Param32(system, 2), ¶m_1, ¶m_2, ¶m_3).raw; system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); system.CurrentArmInterface().SetReg(3, param_3); FuncReturn(system, retval); } // Used by GetThreadCoreMask32 template void SvcWrap32(Core::System& system) { s32 param_1 = 0; u32 param_2 = 0; u32 param_3 = 0; const u32 retval = func(system, Param32(system, 2), ¶m_1, ¶m_2, ¶m_3).raw; system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(2, param_2); system.CurrentArmInterface().SetReg(3, param_3); FuncReturn(system, retval); } // Used by SignalProcessWideKey32 template void SvcWrap32(Core::System& system) { func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1))); } // Used by SetThreadActivity32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1))) .raw; FuncReturn(system, retval); } // Used by SetThreadPriority32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1))).raw; FuncReturn(system, retval); } // Used by SetMemoryAttribute32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; FuncReturn(system, retval); } // Used by MapSharedMemory32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; FuncReturn(system, retval); } // Used by SetThreadCoreMask32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; FuncReturn(system, retval); } // Used by WaitProcessWideKeyAtomic32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3)), static_cast(Param(system, 4))) .raw; FuncReturn(system, retval); } // Used by WaitForAddress32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3)), static_cast(Param(system, 4))) .raw; FuncReturn(system, retval); } // Used by SignalToAddress32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, static_cast(Param(system, 0)), static_cast(Param(system, 1)), static_cast(Param(system, 2)), static_cast(Param(system, 3))) .raw; FuncReturn(system, retval); } // Used by SendSyncRequest32, ArbitrateUnlock32 template void SvcWrap32(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0))).raw); } // Used by CreateTransferMemory32 template void SvcWrap32(Core::System& system) { Handle handle = 0; const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), static_cast(Param32(system, 3))) .raw; system.CurrentArmInterface().SetReg(1, handle); FuncReturn(system, retval); } // Used by WaitSynchronization32 template void SvcWrap32(Core::System& system) { s32 param_1 = 0; const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2), Param32(system, 3), ¶m_1) .raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); } // Used by CreateCodeMemory32 template void SvcWrap32(Core::System& system) { Handle handle = 0; const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2)).raw; system.CurrentArmInterface().SetReg(1, handle); FuncReturn(system, retval); } // Used by ControlCodeMemory32 template void SvcWrap32(Core::System& system) { const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param(system, 2), Param(system, 4), static_cast(Param32(system, 6))) .raw; FuncReturn(system, retval); } } // namespace Kernel