diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index cbdc3fd61..c0bd6540b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -490,6 +490,7 @@ private: u32 id; Func func; const char* name; + u32 cycles; }; static const std::array SVC_Table; @@ -1641,11 +1642,7 @@ void SVC::SleepThread(s64 nanoseconds) { /// This returns the total CPU ticks elapsed since the CPU was powered-on s64 SVC::GetSystemTick() { // TODO: Use globalTicks here? - s64 result = system.GetRunningCore().GetTimer().GetTicks(); - // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end. - // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b - system.GetRunningCore().GetTimer().AddTicks(150); - return result; + return system.GetRunningCore().GetTimer().GetTicks(); } // Returns information of the specified handle @@ -2179,188 +2176,204 @@ Result SVC::ControlProcess(Handle process_handle, u32 process_OP, u32 varg2, u32 } } +// Array of SVC handlers, and the cycles it takes to process them. +// The cycles have been obtained from real hardware using a +// custom svc profiler and doing an average. +// TODO(PabloMK7): +// 1. Use a better profiling technique. The profiler used +// did not handle context switching well, so cycle +// counts are not very accurate. Manual adjustments +// had to be done which may not fully reflect how +// real hardware works. +// 2. Figure out timings for barely used SVCs. The profile +// method involved running several commercial applications +// which do not use all SVCs. A custom homebrew app will +// need to be used. For now, 1000 cycles are assumed for +// SVCs that couldn't be profiled. const std::array SVC::SVC_Table{{ - {0x00, nullptr, "Unknown"}, - {0x01, &SVC::Wrap<&SVC::ControlMemory>, "ControlMemory"}, - {0x02, &SVC::Wrap<&SVC::QueryMemory>, "QueryMemory"}, - {0x03, &SVC::ExitProcess, "ExitProcess"}, - {0x04, nullptr, "GetProcessAffinityMask"}, - {0x05, nullptr, "SetProcessAffinityMask"}, - {0x06, nullptr, "GetProcessIdealProcessor"}, - {0x07, nullptr, "SetProcessIdealProcessor"}, - {0x08, &SVC::Wrap<&SVC::CreateThread>, "CreateThread"}, - {0x09, &SVC::ExitThread, "ExitThread"}, - {0x0A, &SVC::Wrap<&SVC::SleepThread>, "SleepThread"}, - {0x0B, &SVC::Wrap<&SVC::GetThreadPriority>, "GetThreadPriority"}, - {0x0C, &SVC::Wrap<&SVC::SetThreadPriority>, "SetThreadPriority"}, - {0x0D, nullptr, "GetThreadAffinityMask"}, - {0x0E, nullptr, "SetThreadAffinityMask"}, - {0x0F, nullptr, "GetThreadIdealProcessor"}, - {0x10, nullptr, "SetThreadIdealProcessor"}, - {0x11, nullptr, "GetCurrentProcessorNumber"}, - {0x12, nullptr, "Run"}, - {0x13, &SVC::Wrap<&SVC::CreateMutex>, "CreateMutex"}, - {0x14, &SVC::Wrap<&SVC::ReleaseMutex>, "ReleaseMutex"}, - {0x15, &SVC::Wrap<&SVC::CreateSemaphore>, "CreateSemaphore"}, - {0x16, &SVC::Wrap<&SVC::ReleaseSemaphore>, "ReleaseSemaphore"}, - {0x17, &SVC::Wrap<&SVC::CreateEvent>, "CreateEvent"}, - {0x18, &SVC::Wrap<&SVC::SignalEvent>, "SignalEvent"}, - {0x19, &SVC::Wrap<&SVC::ClearEvent>, "ClearEvent"}, - {0x1A, &SVC::Wrap<&SVC::CreateTimer>, "CreateTimer"}, - {0x1B, &SVC::Wrap<&SVC::SetTimer>, "SetTimer"}, - {0x1C, &SVC::Wrap<&SVC::CancelTimer>, "CancelTimer"}, - {0x1D, &SVC::Wrap<&SVC::ClearTimer>, "ClearTimer"}, - {0x1E, &SVC::Wrap<&SVC::CreateMemoryBlock>, "CreateMemoryBlock"}, - {0x1F, &SVC::Wrap<&SVC::MapMemoryBlock>, "MapMemoryBlock"}, - {0x20, &SVC::Wrap<&SVC::UnmapMemoryBlock>, "UnmapMemoryBlock"}, - {0x21, &SVC::Wrap<&SVC::CreateAddressArbiter>, "CreateAddressArbiter"}, - {0x22, &SVC::Wrap<&SVC::ArbitrateAddress>, "ArbitrateAddress"}, - {0x23, &SVC::Wrap<&SVC::CloseHandle>, "CloseHandle"}, - {0x24, &SVC::Wrap<&SVC::WaitSynchronization1>, "WaitSynchronization1"}, - {0x25, &SVC::Wrap<&SVC::WaitSynchronizationN>, "WaitSynchronizationN"}, - {0x26, nullptr, "SignalAndWait"}, - {0x27, &SVC::Wrap<&SVC::DuplicateHandle>, "DuplicateHandle"}, - {0x28, &SVC::Wrap<&SVC::GetSystemTick>, "GetSystemTick"}, - {0x29, &SVC::Wrap<&SVC::GetHandleInfo>, "GetHandleInfo"}, - {0x2A, &SVC::Wrap<&SVC::GetSystemInfo>, "GetSystemInfo"}, - {0x2B, &SVC::Wrap<&SVC::GetProcessInfo>, "GetProcessInfo"}, - {0x2C, &SVC::Wrap<&SVC::GetThreadInfo>, "GetThreadInfo"}, - {0x2D, &SVC::Wrap<&SVC::ConnectToPort>, "ConnectToPort"}, - {0x2E, nullptr, "SendSyncRequest1"}, - {0x2F, nullptr, "SendSyncRequest2"}, - {0x30, nullptr, "SendSyncRequest3"}, - {0x31, nullptr, "SendSyncRequest4"}, - {0x32, &SVC::Wrap<&SVC::SendSyncRequest>, "SendSyncRequest"}, - {0x33, &SVC::Wrap<&SVC::OpenProcess>, "OpenProcess"}, - {0x34, &SVC::Wrap<&SVC::OpenThread>, "OpenThread"}, - {0x35, &SVC::Wrap<&SVC::GetProcessId>, "GetProcessId"}, - {0x36, &SVC::Wrap<&SVC::GetProcessIdOfThread>, "GetProcessIdOfThread"}, - {0x37, &SVC::Wrap<&SVC::GetThreadId>, "GetThreadId"}, - {0x38, &SVC::Wrap<&SVC::GetResourceLimit>, "GetResourceLimit"}, - {0x39, &SVC::Wrap<&SVC::GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"}, - {0x3A, &SVC::Wrap<&SVC::GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, - {0x3B, nullptr, "GetThreadContext"}, - {0x3C, &SVC::Wrap<&SVC::Break>, "Break"}, - {0x3D, &SVC::Wrap<&SVC::OutputDebugString>, "OutputDebugString"}, - {0x3E, nullptr, "ControlPerformanceCounter"}, - {0x3F, nullptr, "Unknown"}, - {0x40, nullptr, "Unknown"}, - {0x41, nullptr, "Unknown"}, - {0x42, nullptr, "Unknown"}, - {0x43, nullptr, "Unknown"}, - {0x44, nullptr, "Unknown"}, - {0x45, nullptr, "Unknown"}, - {0x46, nullptr, "Unknown"}, - {0x47, &SVC::Wrap<&SVC::CreatePort>, "CreatePort"}, - {0x48, &SVC::Wrap<&SVC::CreateSessionToPort>, "CreateSessionToPort"}, - {0x49, &SVC::Wrap<&SVC::CreateSession>, "CreateSession"}, - {0x4A, &SVC::Wrap<&SVC::AcceptSession>, "AcceptSession"}, - {0x4B, nullptr, "ReplyAndReceive1"}, - {0x4C, nullptr, "ReplyAndReceive2"}, - {0x4D, nullptr, "ReplyAndReceive3"}, - {0x4E, nullptr, "ReplyAndReceive4"}, - {0x4F, &SVC::Wrap<&SVC::ReplyAndReceive>, "ReplyAndReceive"}, - {0x50, nullptr, "BindInterrupt"}, - {0x51, nullptr, "UnbindInterrupt"}, - {0x52, &SVC::Wrap<&SVC::InvalidateProcessDataCache>, "InvalidateProcessDataCache"}, - {0x53, &SVC::Wrap<&SVC::StoreProcessDataCache>, "StoreProcessDataCache"}, - {0x54, &SVC::Wrap<&SVC::FlushProcessDataCache>, "FlushProcessDataCache"}, - {0x55, nullptr, "StartInterProcessDma"}, - {0x56, nullptr, "StopDma"}, - {0x57, nullptr, "GetDmaState"}, - {0x58, nullptr, "RestartDma"}, - {0x59, nullptr, "SetGpuProt"}, - {0x5A, nullptr, "SetWifiEnabled"}, - {0x5B, nullptr, "Unknown"}, - {0x5C, nullptr, "Unknown"}, - {0x5D, nullptr, "Unknown"}, - {0x5E, nullptr, "Unknown"}, - {0x5F, nullptr, "Unknown"}, - {0x60, nullptr, "DebugActiveProcess"}, - {0x61, nullptr, "BreakDebugProcess"}, - {0x62, nullptr, "TerminateDebugProcess"}, - {0x63, nullptr, "GetProcessDebugEvent"}, - {0x64, nullptr, "ContinueDebugEvent"}, - {0x65, &SVC::Wrap<&SVC::GetProcessList>, "GetProcessList"}, - {0x66, nullptr, "GetThreadList"}, - {0x67, nullptr, "GetDebugThreadContext"}, - {0x68, nullptr, "SetDebugThreadContext"}, - {0x69, nullptr, "QueryDebugProcessMemory"}, - {0x6A, nullptr, "ReadProcessMemory"}, - {0x6B, nullptr, "WriteProcessMemory"}, - {0x6C, nullptr, "SetHardwareBreakPoint"}, - {0x6D, nullptr, "GetDebugThreadParam"}, - {0x6E, nullptr, "Unknown"}, - {0x6F, nullptr, "Unknown"}, - {0x70, nullptr, "ControlProcessMemory"}, - {0x71, nullptr, "MapProcessMemory"}, - {0x72, nullptr, "UnmapProcessMemory"}, - {0x73, nullptr, "CreateCodeSet"}, - {0x74, nullptr, "RandomStub"}, - {0x75, nullptr, "CreateProcess"}, - {0x76, &SVC::Wrap<&SVC::TerminateProcess>, "TerminateProcess"}, - {0x77, nullptr, "SetProcessResourceLimits"}, - {0x78, nullptr, "CreateResourceLimit"}, - {0x79, &SVC::Wrap<&SVC::SetResourceLimitLimitValues>, "SetResourceLimitLimitValues"}, - {0x7A, nullptr, "AddCodeSegment"}, - {0x7B, nullptr, "Backdoor"}, - {0x7C, &SVC::Wrap<&SVC::KernelSetState>, "KernelSetState"}, - {0x7D, &SVC::Wrap<&SVC::QueryProcessMemory>, "QueryProcessMemory"}, + {0x00, nullptr, "Unknown", 0}, + {0x01, &SVC::Wrap<&SVC::ControlMemory>, "ControlMemory", 1000}, + {0x02, &SVC::Wrap<&SVC::QueryMemory>, "QueryMemory", 1000}, + {0x03, &SVC::ExitProcess, "ExitProcess", 1000}, + {0x04, nullptr, "GetProcessAffinityMask", 1000}, + {0x05, nullptr, "SetProcessAffinityMask", 1000}, + {0x06, nullptr, "GetProcessIdealProcessor", 1000}, + {0x07, nullptr, "SetProcessIdealProcessor", 1000}, + {0x08, &SVC::Wrap<&SVC::CreateThread>, "CreateThread", 5214}, + {0x09, &SVC::ExitThread, "ExitThread", 1000}, + {0x0A, &SVC::Wrap<&SVC::SleepThread>, "SleepThread", 946}, + {0x0B, &SVC::Wrap<&SVC::GetThreadPriority>, "GetThreadPriority", 616}, + {0x0C, &SVC::Wrap<&SVC::SetThreadPriority>, "SetThreadPriority", 1812}, + {0x0D, nullptr, "GetThreadAffinityMask", 1000}, + {0x0E, nullptr, "SetThreadAffinityMask", 1000}, + {0x0F, nullptr, "GetThreadIdealProcessor", 1000}, + {0x10, nullptr, "SetThreadIdealProcessor", 1000}, + {0x11, nullptr, "GetCurrentProcessorNumber", 1000}, + {0x12, nullptr, "Run", 1000}, + {0x13, &SVC::Wrap<&SVC::CreateMutex>, "CreateMutex", 1000}, + {0x14, &SVC::Wrap<&SVC::ReleaseMutex>, "ReleaseMutex", 1324}, + {0x15, &SVC::Wrap<&SVC::CreateSemaphore>, "CreateSemaphore", 1000}, + {0x16, &SVC::Wrap<&SVC::ReleaseSemaphore>, "ReleaseSemaphore", 2713}, + {0x17, &SVC::Wrap<&SVC::CreateEvent>, "CreateEvent", 4329}, + {0x18, &SVC::Wrap<&SVC::SignalEvent>, "SignalEvent", 3285}, + {0x19, &SVC::Wrap<&SVC::ClearEvent>, "ClearEvent", 1389}, + {0x1A, &SVC::Wrap<&SVC::CreateTimer>, "CreateTimer", 1000}, + {0x1B, &SVC::Wrap<&SVC::SetTimer>, "SetTimer", 5163}, + {0x1C, &SVC::Wrap<&SVC::CancelTimer>, "CancelTimer", 1000}, + {0x1D, &SVC::Wrap<&SVC::ClearTimer>, "ClearTimer", 1000}, + {0x1E, &SVC::Wrap<&SVC::CreateMemoryBlock>, "CreateMemoryBlock", 1000}, + {0x1F, &SVC::Wrap<&SVC::MapMemoryBlock>, "MapMemoryBlock", 1000}, + {0x20, &SVC::Wrap<&SVC::UnmapMemoryBlock>, "UnmapMemoryBlock", 1000}, + {0x21, &SVC::Wrap<&SVC::CreateAddressArbiter>, "CreateAddressArbiter", 1000}, + {0x22, &SVC::Wrap<&SVC::ArbitrateAddress>, "ArbitrateAddress", 5664}, + {0x23, &SVC::Wrap<&SVC::CloseHandle>, "CloseHandle", 2937}, + {0x24, &SVC::Wrap<&SVC::WaitSynchronization1>, "WaitSynchronization1", 4005}, + {0x25, &SVC::Wrap<&SVC::WaitSynchronizationN>, "WaitSynchronizationN", 6918}, + {0x26, nullptr, "SignalAndWait", 1000}, + {0x27, &SVC::Wrap<&SVC::DuplicateHandle>, "DuplicateHandle", 1000}, + {0x28, &SVC::Wrap<&SVC::GetSystemTick>, "GetSystemTick", 340}, + {0x29, &SVC::Wrap<&SVC::GetHandleInfo>, "GetHandleInfo", 1000}, + {0x2A, &SVC::Wrap<&SVC::GetSystemInfo>, "GetSystemInfo", 1000}, + {0x2B, &SVC::Wrap<&SVC::GetProcessInfo>, "GetProcessInfo", 1510}, + {0x2C, &SVC::Wrap<&SVC::GetThreadInfo>, "GetThreadInfo", 1000}, + {0x2D, &SVC::Wrap<&SVC::ConnectToPort>, "ConnectToPort", 1000}, + {0x2E, nullptr, "SendSyncRequest1", 1000}, + {0x2F, nullptr, "SendSyncRequest2", 1000}, + {0x30, nullptr, "SendSyncRequest3", 1000}, + {0x31, nullptr, "SendSyncRequest4", 1000}, + {0x32, &SVC::Wrap<&SVC::SendSyncRequest>, "SendSyncRequest", 5825}, + {0x33, &SVC::Wrap<&SVC::OpenProcess>, "OpenProcess", 1000}, + {0x34, &SVC::Wrap<&SVC::OpenThread>, "OpenThread", 1000}, + {0x35, &SVC::Wrap<&SVC::GetProcessId>, "GetProcessId", 1000}, + {0x36, &SVC::Wrap<&SVC::GetProcessIdOfThread>, "GetProcessIdOfThread", 1000}, + {0x37, &SVC::Wrap<&SVC::GetThreadId>, "GetThreadId", 677}, + {0x38, &SVC::Wrap<&SVC::GetResourceLimit>, "GetResourceLimit", 1000}, + {0x39, &SVC::Wrap<&SVC::GetResourceLimitLimitValues>, "GetResourceLimitLimitValues", 1000}, + {0x3A, &SVC::Wrap<&SVC::GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues", 1000}, + {0x3B, nullptr, "GetThreadContext", 1000}, + {0x3C, &SVC::Wrap<&SVC::Break>, "Break", 1000}, + {0x3D, &SVC::Wrap<&SVC::OutputDebugString>, "OutputDebugString", 1000}, + {0x3E, nullptr, "ControlPerformanceCounter", 1000}, + {0x3F, nullptr, "Unknown", 1000}, + {0x40, nullptr, "Unknown", 1000}, + {0x41, nullptr, "Unknown", 1000}, + {0x42, nullptr, "Unknown", 1000}, + {0x43, nullptr, "Unknown", 1000}, + {0x44, nullptr, "Unknown", 1000}, + {0x45, nullptr, "Unknown", 1000}, + {0x46, nullptr, "Unknown", 1000}, + {0x47, &SVC::Wrap<&SVC::CreatePort>, "CreatePort", 1000}, + {0x48, &SVC::Wrap<&SVC::CreateSessionToPort>, "CreateSessionToPort", 5122}, + {0x49, &SVC::Wrap<&SVC::CreateSession>, "CreateSession", 3492}, + {0x4A, &SVC::Wrap<&SVC::AcceptSession>, "AcceptSession", 1842}, + {0x4B, nullptr, "ReplyAndReceive1", 1000}, + {0x4C, nullptr, "ReplyAndReceive2", 1000}, + {0x4D, nullptr, "ReplyAndReceive3", 1000}, + {0x4E, nullptr, "ReplyAndReceive4", 1000}, + {0x4F, &SVC::Wrap<&SVC::ReplyAndReceive>, "ReplyAndReceive", 8762}, + {0x50, nullptr, "BindInterrupt", 1000}, + {0x51, nullptr, "UnbindInterrupt", 1000}, + {0x52, &SVC::Wrap<&SVC::InvalidateProcessDataCache>, "InvalidateProcessDataCache", 9609}, + {0x53, &SVC::Wrap<&SVC::StoreProcessDataCache>, "StoreProcessDataCache", 7174}, + {0x54, &SVC::Wrap<&SVC::FlushProcessDataCache>, "FlushProcessDataCache", 9084}, + {0x55, nullptr, "StartInterProcessDma", 9146}, + {0x56, nullptr, "StopDma", 1163}, + {0x57, nullptr, "GetDmaState", 2222}, + {0x58, nullptr, "RestartDma", 8096}, + {0x59, nullptr, "SetGpuProt", 356}, + {0x5A, nullptr, "SetWifiEnabled", 1000}, + {0x5B, nullptr, "Unknown", 1000}, + {0x5C, nullptr, "Unknown", 1000}, + {0x5D, nullptr, "Unknown", 1000}, + {0x5E, nullptr, "Unknown", 1000}, + {0x5F, nullptr, "Unknown", 1000}, + {0x60, nullptr, "DebugActiveProcess", 1000}, + {0x61, nullptr, "BreakDebugProcess", 1000}, + {0x62, nullptr, "TerminateDebugProcess", 1000}, + {0x63, nullptr, "GetProcessDebugEvent", 1000}, + {0x64, nullptr, "ContinueDebugEvent", 1000}, + {0x65, &SVC::Wrap<&SVC::GetProcessList>, "GetProcessList", 1000}, + {0x66, nullptr, "GetThreadList", 1000}, + {0x67, nullptr, "GetDebugThreadContext", 1000}, + {0x68, nullptr, "SetDebugThreadContext", 1000}, + {0x69, nullptr, "QueryDebugProcessMemory", 1000}, + {0x6A, nullptr, "ReadProcessMemory", 1000}, + {0x6B, nullptr, "WriteProcessMemory", 1000}, + {0x6C, nullptr, "SetHardwareBreakPoint", 1000}, + {0x6D, nullptr, "GetDebugThreadParam", 1000}, + {0x6E, nullptr, "Unknown", 1000}, + {0x6F, nullptr, "Unknown", 1000}, + {0x70, nullptr, "ControlProcessMemory", 1000}, + {0x71, nullptr, "MapProcessMemory", 1000}, + {0x72, nullptr, "UnmapProcessMemory", 1000}, + {0x73, nullptr, "CreateCodeSet", 1000}, + {0x74, nullptr, "RandomStub", 1000}, + {0x75, nullptr, "CreateProcess", 1000}, + {0x76, &SVC::Wrap<&SVC::TerminateProcess>, "TerminateProcess", 1000}, + {0x77, nullptr, "SetProcessResourceLimits", 1000}, + {0x78, nullptr, "CreateResourceLimit", 1000}, + {0x79, &SVC::Wrap<&SVC::SetResourceLimitLimitValues>, "SetResourceLimitLimitValues", 1000}, + {0x7A, nullptr, "AddCodeSegment", 1000}, + {0x7B, nullptr, "Backdoor", 1000}, + {0x7C, &SVC::Wrap<&SVC::KernelSetState>, "KernelSetState", 1000}, + {0x7D, &SVC::Wrap<&SVC::QueryProcessMemory>, "QueryProcessMemory", 1000}, // Custom SVCs - {0x7E, nullptr, "Unused"}, - {0x7F, nullptr, "Unused"}, - {0x80, nullptr, "CustomBackdoor"}, - {0x81, nullptr, "Unused"}, - {0x82, nullptr, "Unused"}, - {0x83, nullptr, "Unused"}, - {0x84, nullptr, "Unused"}, - {0x85, nullptr, "Unused"}, - {0x86, nullptr, "Unused"}, - {0x87, nullptr, "Unused"}, - {0x88, nullptr, "Unused"}, - {0x89, nullptr, "Unused"}, - {0x8A, nullptr, "Unused"}, - {0x8B, nullptr, "Unused"}, - {0x8C, nullptr, "Unused"}, - {0x8D, nullptr, "Unused"}, - {0x8E, nullptr, "Unused"}, - {0x8F, nullptr, "Unused"}, - {0x90, &SVC::Wrap<&SVC::ConvertVaToPa>, "ConvertVaToPa"}, - {0x91, nullptr, "FlushDataCacheRange"}, - {0x92, nullptr, "FlushEntireDataCache"}, - {0x93, &SVC::Wrap<&SVC::InvalidateInstructionCacheRange>, "InvalidateInstructionCacheRange"}, - {0x94, &SVC::Wrap<&SVC::InvalidateEntireInstructionCache>, "InvalidateEntireInstructionCache"}, - {0x95, nullptr, "Unused"}, - {0x96, nullptr, "Unused"}, - {0x97, nullptr, "Unused"}, - {0x98, nullptr, "Unused"}, - {0x99, nullptr, "Unused"}, - {0x9A, nullptr, "Unused"}, - {0x9B, nullptr, "Unused"}, - {0x9C, nullptr, "Unused"}, - {0x9D, nullptr, "Unused"}, - {0x9E, nullptr, "Unused"}, - {0x9F, nullptr, "Unused"}, - {0xA0, &SVC::Wrap<&SVC::MapProcessMemoryEx>, "MapProcessMemoryEx"}, - {0xA1, &SVC::Wrap<&SVC::UnmapProcessMemoryEx>, "UnmapProcessMemoryEx"}, - {0xA2, nullptr, "ControlMemoryEx"}, - {0xA3, nullptr, "ControlMemoryUnsafe"}, - {0xA4, nullptr, "Unused"}, - {0xA5, nullptr, "Unused"}, - {0xA6, nullptr, "Unused"}, - {0xA7, nullptr, "Unused"}, - {0xA8, nullptr, "Unused"}, - {0xA9, nullptr, "Unused"}, - {0xAA, nullptr, "Unused"}, - {0xAB, nullptr, "Unused"}, - {0xAC, nullptr, "Unused"}, - {0xAD, nullptr, "Unused"}, - {0xAE, nullptr, "Unused"}, - {0xAF, nullptr, "Unused"}, - {0xB0, nullptr, "ControlService"}, - {0xB1, nullptr, "CopyHandle"}, - {0xB2, nullptr, "TranslateHandle"}, - {0xB3, &SVC::Wrap<&SVC::ControlProcess>, "ControlProcess"}, + {0x7E, nullptr, "Unused", 1000}, + {0x7F, nullptr, "Unused", 1000}, + {0x80, nullptr, "CustomBackdoor", 1000}, + {0x81, nullptr, "Unused", 1000}, + {0x82, nullptr, "Unused", 1000}, + {0x83, nullptr, "Unused", 1000}, + {0x84, nullptr, "Unused", 1000}, + {0x85, nullptr, "Unused", 1000}, + {0x86, nullptr, "Unused", 1000}, + {0x87, nullptr, "Unused", 1000}, + {0x88, nullptr, "Unused", 1000}, + {0x89, nullptr, "Unused", 1000}, + {0x8A, nullptr, "Unused", 1000}, + {0x8B, nullptr, "Unused", 1000}, + {0x8C, nullptr, "Unused", 1000}, + {0x8D, nullptr, "Unused", 1000}, + {0x8E, nullptr, "Unused", 1000}, + {0x8F, nullptr, "Unused", 1000}, + {0x90, &SVC::Wrap<&SVC::ConvertVaToPa>, "ConvertVaToPa", 1000}, + {0x91, nullptr, "FlushDataCacheRange", 1000}, + {0x92, nullptr, "FlushEntireDataCache", 1000}, + {0x93, &SVC::Wrap<&SVC::InvalidateInstructionCacheRange>, "InvalidateInstructionCacheRange", + 1000}, + {0x94, &SVC::Wrap<&SVC::InvalidateEntireInstructionCache>, "InvalidateEntireInstructionCache", + 1000}, + {0x95, nullptr, "Unused", 1000}, + {0x96, nullptr, "Unused", 1000}, + {0x97, nullptr, "Unused", 1000}, + {0x98, nullptr, "Unused", 1000}, + {0x99, nullptr, "Unused", 1000}, + {0x9A, nullptr, "Unused", 1000}, + {0x9B, nullptr, "Unused", 1000}, + {0x9C, nullptr, "Unused", 1000}, + {0x9D, nullptr, "Unused", 1000}, + {0x9E, nullptr, "Unused", 1000}, + {0x9F, nullptr, "Unused", 1000}, + {0xA0, &SVC::Wrap<&SVC::MapProcessMemoryEx>, "MapProcessMemoryEx", 1000}, + {0xA1, &SVC::Wrap<&SVC::UnmapProcessMemoryEx>, "UnmapProcessMemoryEx", 1000}, + {0xA2, nullptr, "ControlMemoryEx", 1000}, + {0xA3, nullptr, "ControlMemoryUnsafe", 1000}, + {0xA4, nullptr, "Unused", 1000}, + {0xA5, nullptr, "Unused", 1000}, + {0xA6, nullptr, "Unused", 1000}, + {0xA7, nullptr, "Unused", 1000}, + {0xA8, nullptr, "Unused", 1000}, + {0xA9, nullptr, "Unused", 1000}, + {0xAA, nullptr, "Unused", 1000}, + {0xAB, nullptr, "Unused", 1000}, + {0xAC, nullptr, "Unused", 1000}, + {0xAD, nullptr, "Unused", 1000}, + {0xAE, nullptr, "Unused", 1000}, + {0xAF, nullptr, "Unused", 1000}, + {0xB0, nullptr, "ControlService", 1000}, + {0xB1, nullptr, "CopyHandle", 1000}, + {0xB2, nullptr, "TranslateHandle", 1000}, + {0xB3, &SVC::Wrap<&SVC::ControlProcess>, "ControlProcess", 1000}, }}; const SVC::FunctionDef* SVC::GetSVCInfo(u32 func_num) { @@ -2387,6 +2400,7 @@ void SVC::CallSVC(u32 immediate) { LOG_TRACE(Kernel_SVC, "calling {}", info->name); if (info) { if (info->func) { + system.GetRunningCore().GetTimer().AddTicks(info->cycles); (this->*(info->func))(); } else { LOG_ERROR(Kernel_SVC, "unimplemented SVC function {:02X} {}(..)", info->id, info->name);