mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 15:09:58 +01:00
kernel: Improve SVC handling timings
This commit is contained in:
parent
ad97506867
commit
a974fc4ac8
@ -490,6 +490,7 @@ private:
|
||||
u32 id;
|
||||
Func func;
|
||||
const char* name;
|
||||
u32 cycles;
|
||||
};
|
||||
|
||||
static const std::array<FunctionDef, 180> 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::FunctionDef, 180> 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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user