// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/common_types.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_wrap.h" #include "core/hle/result.h" namespace Kernel::Svc { namespace { struct FunctionDef { using Func = void(Core::System&); u32 id; Func* func; const char* name; }; } // namespace static const FunctionDef SVC_Table_32[] = { {0x00, nullptr, "Unknown0"}, {0x01, SvcWrap32, "SetHeapSize32"}, {0x02, nullptr, "SetMemoryPermission32"}, {0x03, SvcWrap32, "SetMemoryAttribute32"}, {0x04, SvcWrap32, "MapMemory32"}, {0x05, SvcWrap32, "UnmapMemory32"}, {0x06, SvcWrap32, "QueryMemory32"}, {0x07, SvcWrap32, "ExitProcess32"}, {0x08, SvcWrap32, "CreateThread32"}, {0x09, SvcWrap32, "StartThread32"}, {0x0a, SvcWrap32, "ExitThread32"}, {0x0b, SvcWrap32, "SleepThread32"}, {0x0c, SvcWrap32, "GetThreadPriority32"}, {0x0d, SvcWrap32, "SetThreadPriority32"}, {0x0e, SvcWrap32, "GetThreadCoreMask32"}, {0x0f, SvcWrap32, "SetThreadCoreMask32"}, {0x10, SvcWrap32, "GetCurrentProcessorNumber32"}, {0x11, SvcWrap32, "SignalEvent32"}, {0x12, SvcWrap32, "ClearEvent32"}, {0x13, SvcWrap32, "MapSharedMemory32"}, {0x14, SvcWrap32, "UnmapSharedMemory32"}, {0x15, SvcWrap32, "CreateTransferMemory32"}, {0x16, SvcWrap32, "CloseHandle32"}, {0x17, SvcWrap32, "ResetSignal32"}, {0x18, SvcWrap32, "WaitSynchronization32"}, {0x19, SvcWrap32, "CancelSynchronization32"}, {0x1a, SvcWrap32, "ArbitrateLock32"}, {0x1b, SvcWrap32, "ArbitrateUnlock32"}, {0x1c, SvcWrap32, "WaitProcessWideKeyAtomic32"}, {0x1d, SvcWrap32, "SignalProcessWideKey32"}, {0x1e, SvcWrap32, "GetSystemTick32"}, {0x1f, SvcWrap32, "ConnectToNamedPort32"}, {0x20, nullptr, "SendSyncRequestLight32"}, {0x21, SvcWrap32, "SendSyncRequest32"}, {0x22, nullptr, "SendSyncRequestWithUserBuffer32"}, {0x23, nullptr, "SendAsyncRequestWithUserBuffer32"}, {0x24, SvcWrap32, "GetProcessId32"}, {0x25, SvcWrap32, "GetThreadId32"}, {0x26, SvcWrap32, "Break32"}, {0x27, SvcWrap32, "OutputDebugString32"}, {0x28, nullptr, "ReturnFromException32"}, {0x29, SvcWrap32, "GetInfo32"}, {0x2a, nullptr, "FlushEntireDataCache32"}, {0x2b, nullptr, "FlushDataCache32"}, {0x2c, SvcWrap32, "MapPhysicalMemory32"}, {0x2d, SvcWrap32, "UnmapPhysicalMemory32"}, {0x2e, nullptr, "GetDebugFutureThreadInfo32"}, {0x2f, nullptr, "GetLastThreadInfo32"}, {0x30, nullptr, "GetResourceLimitLimitValue32"}, {0x31, nullptr, "GetResourceLimitCurrentValue32"}, {0x32, SvcWrap32, "SetThreadActivity32"}, {0x33, SvcWrap32, "GetThreadContext32"}, {0x34, SvcWrap32, "WaitForAddress32"}, {0x35, SvcWrap32, "SignalToAddress32"}, {0x36, SvcWrap32, "SynchronizePreemptionState32"}, {0x37, nullptr, "GetResourceLimitPeakValue32"}, {0x38, nullptr, "Unknown38"}, {0x39, nullptr, "CreateIoPool32"}, {0x3a, nullptr, "CreateIoRegion32"}, {0x3b, nullptr, "Unknown3b"}, {0x3c, nullptr, "KernelDebug32"}, {0x3d, nullptr, "ChangeKernelTraceState32"}, {0x3e, nullptr, "Unknown3e"}, {0x3f, nullptr, "Unknown3f"}, {0x40, nullptr, "CreateSession32"}, {0x41, nullptr, "AcceptSession32"}, {0x42, nullptr, "ReplyAndReceiveLight32"}, {0x43, nullptr, "ReplyAndReceive32"}, {0x44, nullptr, "ReplyAndReceiveWithUserBuffer32"}, {0x45, SvcWrap32, "CreateEvent32"}, {0x46, nullptr, "MapIoRegion32"}, {0x47, nullptr, "UnmapIoRegion32"}, {0x48, nullptr, "MapPhysicalMemoryUnsafe32"}, {0x49, nullptr, "UnmapPhysicalMemoryUnsafe32"}, {0x4a, nullptr, "SetUnsafeLimit32"}, {0x4b, SvcWrap32, "CreateCodeMemory32"}, {0x4c, SvcWrap32, "ControlCodeMemory32"}, {0x4d, nullptr, "SleepSystem32"}, {0x4e, nullptr, "ReadWriteRegister32"}, {0x4f, nullptr, "SetProcessActivity32"}, {0x50, nullptr, "CreateSharedMemory32"}, {0x51, nullptr, "MapTransferMemory32"}, {0x52, nullptr, "UnmapTransferMemory32"}, {0x53, nullptr, "CreateInterruptEvent32"}, {0x54, nullptr, "QueryPhysicalAddress32"}, {0x55, nullptr, "QueryIoMapping32"}, {0x56, nullptr, "CreateDeviceAddressSpace32"}, {0x57, nullptr, "AttachDeviceAddressSpace32"}, {0x58, nullptr, "DetachDeviceAddressSpace32"}, {0x59, nullptr, "MapDeviceAddressSpaceByForce32"}, {0x5a, nullptr, "MapDeviceAddressSpaceAligned32"}, {0x5b, nullptr, "MapDeviceAddressSpace32"}, {0x5c, nullptr, "UnmapDeviceAddressSpace32"}, {0x5d, nullptr, "InvalidateProcessDataCache32"}, {0x5e, nullptr, "StoreProcessDataCache32"}, {0x5F, SvcWrap32, "FlushProcessDataCache32"}, {0x60, nullptr, "StoreProcessDataCache32"}, {0x61, nullptr, "BreakDebugProcess32"}, {0x62, nullptr, "TerminateDebugProcess32"}, {0x63, nullptr, "GetDebugEvent32"}, {0x64, nullptr, "ContinueDebugEvent32"}, {0x65, nullptr, "GetProcessList32"}, {0x66, nullptr, "GetThreadList"}, {0x67, nullptr, "GetDebugThreadContext32"}, {0x68, nullptr, "SetDebugThreadContext32"}, {0x69, nullptr, "QueryDebugProcessMemory32"}, {0x6A, nullptr, "ReadDebugProcessMemory32"}, {0x6B, nullptr, "WriteDebugProcessMemory32"}, {0x6C, nullptr, "SetHardwareBreakPoint32"}, {0x6D, nullptr, "GetDebugThreadParam32"}, {0x6E, nullptr, "Unknown6E"}, {0x6f, nullptr, "GetSystemInfo32"}, {0x70, nullptr, "CreatePort32"}, {0x71, nullptr, "ManageNamedPort32"}, {0x72, nullptr, "ConnectToPort32"}, {0x73, nullptr, "SetProcessMemoryPermission32"}, {0x74, nullptr, "MapProcessMemory32"}, {0x75, nullptr, "UnmapProcessMemory32"}, {0x76, nullptr, "QueryProcessMemory32"}, {0x77, nullptr, "MapProcessCodeMemory32"}, {0x78, nullptr, "UnmapProcessCodeMemory32"}, {0x79, nullptr, "CreateProcess32"}, {0x7A, nullptr, "StartProcess32"}, {0x7B, nullptr, "TerminateProcess32"}, {0x7C, nullptr, "GetProcessInfo32"}, {0x7D, nullptr, "CreateResourceLimit32"}, {0x7E, nullptr, "SetResourceLimitLimitValue32"}, {0x7F, nullptr, "CallSecureMonitor32"}, {0x80, nullptr, "Unknown"}, {0x81, nullptr, "Unknown"}, {0x82, nullptr, "Unknown"}, {0x83, nullptr, "Unknown"}, {0x84, nullptr, "Unknown"}, {0x85, nullptr, "Unknown"}, {0x86, nullptr, "Unknown"}, {0x87, nullptr, "Unknown"}, {0x88, nullptr, "Unknown"}, {0x89, nullptr, "Unknown"}, {0x8A, nullptr, "Unknown"}, {0x8B, nullptr, "Unknown"}, {0x8C, nullptr, "Unknown"}, {0x8D, nullptr, "Unknown"}, {0x8E, nullptr, "Unknown"}, {0x8F, nullptr, "Unknown"}, {0x90, nullptr, "Unknown"}, {0x91, nullptr, "Unknown"}, {0x92, nullptr, "Unknown"}, {0x93, nullptr, "Unknown"}, {0x94, nullptr, "Unknown"}, {0x95, nullptr, "Unknown"}, {0x96, nullptr, "Unknown"}, {0x97, nullptr, "Unknown"}, {0x98, nullptr, "Unknown"}, {0x99, nullptr, "Unknown"}, {0x9A, nullptr, "Unknown"}, {0x9B, nullptr, "Unknown"}, {0x9C, nullptr, "Unknown"}, {0x9D, nullptr, "Unknown"}, {0x9E, nullptr, "Unknown"}, {0x9F, nullptr, "Unknown"}, {0xA0, nullptr, "Unknown"}, {0xA1, nullptr, "Unknown"}, {0xA2, nullptr, "Unknown"}, {0xA3, nullptr, "Unknown"}, {0xA4, nullptr, "Unknown"}, {0xA5, nullptr, "Unknown"}, {0xA6, nullptr, "Unknown"}, {0xA7, nullptr, "Unknown"}, {0xA8, nullptr, "Unknown"}, {0xA9, nullptr, "Unknown"}, {0xAA, nullptr, "Unknown"}, {0xAB, nullptr, "Unknown"}, {0xAC, nullptr, "Unknown"}, {0xAD, nullptr, "Unknown"}, {0xAE, nullptr, "Unknown"}, {0xAF, nullptr, "Unknown"}, {0xB0, nullptr, "Unknown"}, {0xB1, nullptr, "Unknown"}, {0xB2, nullptr, "Unknown"}, {0xB3, nullptr, "Unknown"}, {0xB4, nullptr, "Unknown"}, {0xB5, nullptr, "Unknown"}, {0xB6, nullptr, "Unknown"}, {0xB7, nullptr, "Unknown"}, {0xB8, nullptr, "Unknown"}, {0xB9, nullptr, "Unknown"}, {0xBA, nullptr, "Unknown"}, {0xBB, nullptr, "Unknown"}, {0xBC, nullptr, "Unknown"}, {0xBD, nullptr, "Unknown"}, {0xBE, nullptr, "Unknown"}, {0xBF, nullptr, "Unknown"}, }; static const FunctionDef SVC_Table_64[] = { {0x00, nullptr, "Unknown0"}, {0x01, SvcWrap64, "SetHeapSize"}, {0x02, SvcWrap64, "SetMemoryPermission"}, {0x03, SvcWrap64, "SetMemoryAttribute"}, {0x04, SvcWrap64, "MapMemory"}, {0x05, SvcWrap64, "UnmapMemory"}, {0x06, SvcWrap64, "QueryMemory"}, {0x07, SvcWrap64, "ExitProcess"}, {0x08, SvcWrap64, "CreateThread"}, {0x09, SvcWrap64, "StartThread"}, {0x0A, SvcWrap64, "ExitThread"}, {0x0B, SvcWrap64, "SleepThread"}, {0x0C, SvcWrap64, "GetThreadPriority"}, {0x0D, SvcWrap64, "SetThreadPriority"}, {0x0E, SvcWrap64, "GetThreadCoreMask"}, {0x0F, SvcWrap64, "SetThreadCoreMask"}, {0x10, SvcWrap64, "GetCurrentProcessorNumber"}, {0x11, SvcWrap64, "SignalEvent"}, {0x12, SvcWrap64, "ClearEvent"}, {0x13, SvcWrap64, "MapSharedMemory"}, {0x14, SvcWrap64, "UnmapSharedMemory"}, {0x15, SvcWrap64, "CreateTransferMemory"}, {0x16, SvcWrap64, "CloseHandle"}, {0x17, SvcWrap64, "ResetSignal"}, {0x18, SvcWrap64, "WaitSynchronization"}, {0x19, SvcWrap64, "CancelSynchronization"}, {0x1A, SvcWrap64, "ArbitrateLock"}, {0x1B, SvcWrap64, "ArbitrateUnlock"}, {0x1C, SvcWrap64, "WaitProcessWideKeyAtomic"}, {0x1D, SvcWrap64, "SignalProcessWideKey"}, {0x1E, SvcWrap64, "GetSystemTick"}, {0x1F, SvcWrap64, "ConnectToNamedPort"}, {0x20, nullptr, "SendSyncRequestLight"}, {0x21, SvcWrap64, "SendSyncRequest"}, {0x22, nullptr, "SendSyncRequestWithUserBuffer"}, {0x23, nullptr, "SendAsyncRequestWithUserBuffer"}, {0x24, SvcWrap64, "GetProcessId"}, {0x25, SvcWrap64, "GetThreadId"}, {0x26, SvcWrap64, "Break"}, {0x27, SvcWrap64, "OutputDebugString"}, {0x28, nullptr, "ReturnFromException"}, {0x29, SvcWrap64, "GetInfo"}, {0x2A, nullptr, "FlushEntireDataCache"}, {0x2B, nullptr, "FlushDataCache"}, {0x2C, SvcWrap64, "MapPhysicalMemory"}, {0x2D, SvcWrap64, "UnmapPhysicalMemory"}, {0x2E, nullptr, "GetFutureThreadInfo"}, {0x2F, nullptr, "GetLastThreadInfo"}, {0x30, SvcWrap64, "GetResourceLimitLimitValue"}, {0x31, SvcWrap64, "GetResourceLimitCurrentValue"}, {0x32, SvcWrap64, "SetThreadActivity"}, {0x33, SvcWrap64, "GetThreadContext"}, {0x34, SvcWrap64, "WaitForAddress"}, {0x35, SvcWrap64, "SignalToAddress"}, {0x36, SvcWrap64, "SynchronizePreemptionState"}, {0x37, nullptr, "GetResourceLimitPeakValue"}, {0x38, nullptr, "Unknown38"}, {0x39, nullptr, "CreateIoPool"}, {0x3A, nullptr, "CreateIoRegion"}, {0x3B, nullptr, "Unknown3B"}, {0x3C, SvcWrap64, "KernelDebug"}, {0x3D, SvcWrap64, "ChangeKernelTraceState"}, {0x3E, nullptr, "Unknown3e"}, {0x3F, nullptr, "Unknown3f"}, {0x40, SvcWrap64, "CreateSession"}, {0x41, nullptr, "AcceptSession"}, {0x42, nullptr, "ReplyAndReceiveLight"}, {0x43, SvcWrap64, "ReplyAndReceive"}, {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, {0x45, SvcWrap64, "CreateEvent"}, {0x46, nullptr, "MapIoRegion"}, {0x47, nullptr, "UnmapIoRegion"}, {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, {0x49, nullptr, "UnmapPhysicalMemoryUnsafe"}, {0x4A, nullptr, "SetUnsafeLimit"}, {0x4B, SvcWrap64, "CreateCodeMemory"}, {0x4C, SvcWrap64, "ControlCodeMemory"}, {0x4D, nullptr, "SleepSystem"}, {0x4E, nullptr, "ReadWriteRegister"}, {0x4F, nullptr, "SetProcessActivity"}, {0x50, nullptr, "CreateSharedMemory"}, {0x51, nullptr, "MapTransferMemory"}, {0x52, nullptr, "UnmapTransferMemory"}, {0x53, nullptr, "CreateInterruptEvent"}, {0x54, nullptr, "QueryPhysicalAddress"}, {0x55, nullptr, "QueryIoMapping"}, {0x56, nullptr, "CreateDeviceAddressSpace"}, {0x57, nullptr, "AttachDeviceAddressSpace"}, {0x58, nullptr, "DetachDeviceAddressSpace"}, {0x59, nullptr, "MapDeviceAddressSpaceByForce"}, {0x5A, nullptr, "MapDeviceAddressSpaceAligned"}, {0x5B, nullptr, "MapDeviceAddressSpace"}, {0x5C, nullptr, "UnmapDeviceAddressSpace"}, {0x5D, nullptr, "InvalidateProcessDataCache"}, {0x5E, nullptr, "StoreProcessDataCache"}, {0x5F, nullptr, "FlushProcessDataCache"}, {0x60, nullptr, "DebugActiveProcess"}, {0x61, nullptr, "BreakDebugProcess"}, {0x62, nullptr, "TerminateDebugProcess"}, {0x63, nullptr, "GetDebugEvent"}, {0x64, nullptr, "ContinueDebugEvent"}, {0x65, SvcWrap64, "GetProcessList"}, {0x66, SvcWrap64, "GetThreadList"}, {0x67, nullptr, "GetDebugThreadContext"}, {0x68, nullptr, "SetDebugThreadContext"}, {0x69, nullptr, "QueryDebugProcessMemory"}, {0x6A, nullptr, "ReadDebugProcessMemory"}, {0x6B, nullptr, "WriteDebugProcessMemory"}, {0x6C, nullptr, "SetHardwareBreakPoint"}, {0x6D, nullptr, "GetDebugThreadParam"}, {0x6E, nullptr, "Unknown6E"}, {0x6F, nullptr, "GetSystemInfo"}, {0x70, nullptr, "CreatePort"}, {0x71, nullptr, "ManageNamedPort"}, {0x72, nullptr, "ConnectToPort"}, {0x73, SvcWrap64, "SetProcessMemoryPermission"}, {0x74, SvcWrap64, "MapProcessMemory"}, {0x75, SvcWrap64, "UnmapProcessMemory"}, {0x76, SvcWrap64, "QueryProcessMemory"}, {0x77, SvcWrap64, "MapProcessCodeMemory"}, {0x78, SvcWrap64, "UnmapProcessCodeMemory"}, {0x79, nullptr, "CreateProcess"}, {0x7A, nullptr, "StartProcess"}, {0x7B, nullptr, "TerminateProcess"}, {0x7C, SvcWrap64, "GetProcessInfo"}, {0x7D, SvcWrap64, "CreateResourceLimit"}, {0x7E, SvcWrap64, "SetResourceLimitLimitValue"}, {0x7F, nullptr, "CallSecureMonitor"}, {0x80, nullptr, "Unknown"}, {0x81, nullptr, "Unknown"}, {0x82, nullptr, "Unknown"}, {0x83, nullptr, "Unknown"}, {0x84, nullptr, "Unknown"}, {0x85, nullptr, "Unknown"}, {0x86, nullptr, "Unknown"}, {0x87, nullptr, "Unknown"}, {0x88, nullptr, "Unknown"}, {0x89, nullptr, "Unknown"}, {0x8A, nullptr, "Unknown"}, {0x8B, nullptr, "Unknown"}, {0x8C, nullptr, "Unknown"}, {0x8D, nullptr, "Unknown"}, {0x8E, nullptr, "Unknown"}, {0x8F, nullptr, "Unknown"}, {0x90, nullptr, "Unknown"}, {0x91, nullptr, "Unknown"}, {0x92, nullptr, "Unknown"}, {0x93, nullptr, "Unknown"}, {0x94, nullptr, "Unknown"}, {0x95, nullptr, "Unknown"}, {0x96, nullptr, "Unknown"}, {0x97, nullptr, "Unknown"}, {0x98, nullptr, "Unknown"}, {0x99, nullptr, "Unknown"}, {0x9A, nullptr, "Unknown"}, {0x9B, nullptr, "Unknown"}, {0x9C, nullptr, "Unknown"}, {0x9D, nullptr, "Unknown"}, {0x9E, nullptr, "Unknown"}, {0x9F, nullptr, "Unknown"}, {0xA0, nullptr, "Unknown"}, {0xA1, nullptr, "Unknown"}, {0xA2, nullptr, "Unknown"}, {0xA3, nullptr, "Unknown"}, {0xA4, nullptr, "Unknown"}, {0xA5, nullptr, "Unknown"}, {0xA6, nullptr, "Unknown"}, {0xA7, nullptr, "Unknown"}, {0xA8, nullptr, "Unknown"}, {0xA9, nullptr, "Unknown"}, {0xAA, nullptr, "Unknown"}, {0xAB, nullptr, "Unknown"}, {0xAC, nullptr, "Unknown"}, {0xAD, nullptr, "Unknown"}, {0xAE, nullptr, "Unknown"}, {0xAF, nullptr, "Unknown"}, {0xB0, nullptr, "Unknown"}, {0xB1, nullptr, "Unknown"}, {0xB2, nullptr, "Unknown"}, {0xB3, nullptr, "Unknown"}, {0xB4, nullptr, "Unknown"}, {0xB5, nullptr, "Unknown"}, {0xB6, nullptr, "Unknown"}, {0xB7, nullptr, "Unknown"}, {0xB8, nullptr, "Unknown"}, {0xB9, nullptr, "Unknown"}, {0xBA, nullptr, "Unknown"}, {0xBB, nullptr, "Unknown"}, {0xBC, nullptr, "Unknown"}, {0xBD, nullptr, "Unknown"}, {0xBE, nullptr, "Unknown"}, {0xBF, nullptr, "Unknown"}, }; static const FunctionDef* GetSVCInfo32(u32 func_num) { if (func_num >= std::size(SVC_Table_32)) { LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); return nullptr; } return &SVC_Table_32[func_num]; } static const FunctionDef* GetSVCInfo64(u32 func_num) { if (func_num >= std::size(SVC_Table_64)) { LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); return nullptr; } return &SVC_Table_64[func_num]; } void Call(Core::System& system, u32 immediate) { auto& kernel = system.Kernel(); kernel.EnterSVCProfile(); auto* thread = GetCurrentThreadPointer(kernel); thread->SetIsCallingSvc(); const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) : GetSVCInfo32(immediate); if (info) { if (info->func) { info->func(system); } else { LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name); } } else { LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate); } kernel.ExitSVCProfile(); } } // namespace Kernel::Svc