mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-03-29 07:00:01 -06:00
core: svc: Add better logging to svc failures (#1948)
This commit is contained in:
parent
7e58ac5bcf
commit
f14f095e72
@ -2218,67 +2218,69 @@ Result SVC::ControlProcess(Handle process_handle, u32 process_OP, u32 varg2, u32
|
||||
// SVCs that couldn't be profiled.
|
||||
const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{0x00, nullptr, "Unknown", 0},
|
||||
{0x01, &SVC::Wrap<&SVC::ControlMemory>, "ControlMemory", 1000},
|
||||
{0x02, &SVC::Wrap<&SVC::QueryMemory>, "QueryMemory", 1000},
|
||||
{0x01, &SVC::Wrap<&SVC::ControlMemory, 0x01>, "ControlMemory", 1000},
|
||||
{0x02, &SVC::Wrap<&SVC::QueryMemory, 0x02>, "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},
|
||||
{0x08, &SVC::Wrap<&SVC::CreateThread, 0x08>, "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},
|
||||
{0x0A, &SVC::Wrap<&SVC::SleepThread, 0x0A>, "SleepThread", 946},
|
||||
{0x0B, &SVC::Wrap<&SVC::GetThreadPriority, 0x0B>, "GetThreadPriority", 616},
|
||||
{0x0C, &SVC::Wrap<&SVC::SetThreadPriority, 0x0C>, "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},
|
||||
{0x13, &SVC::Wrap<&SVC::CreateMutex, 0x13>, "CreateMutex", 1000},
|
||||
{0x14, &SVC::Wrap<&SVC::ReleaseMutex, 0x14>, "ReleaseMutex", 1324},
|
||||
{0x15, &SVC::Wrap<&SVC::CreateSemaphore, 0x15>, "CreateSemaphore", 1000},
|
||||
{0x16, &SVC::Wrap<&SVC::ReleaseSemaphore, 0x16>, "ReleaseSemaphore", 2713},
|
||||
{0x17, &SVC::Wrap<&SVC::CreateEvent, 0x17>, "CreateEvent", 4329},
|
||||
{0x18, &SVC::Wrap<&SVC::SignalEvent, 0x18>, "SignalEvent", 3285},
|
||||
{0x19, &SVC::Wrap<&SVC::ClearEvent, 0x19>, "ClearEvent", 1389},
|
||||
{0x1A, &SVC::Wrap<&SVC::CreateTimer, 0x1A>, "CreateTimer", 1000},
|
||||
{0x1B, &SVC::Wrap<&SVC::SetTimer, 0x1B>, "SetTimer", 5163},
|
||||
{0x1C, &SVC::Wrap<&SVC::CancelTimer, 0x1C>, "CancelTimer", 1000},
|
||||
{0x1D, &SVC::Wrap<&SVC::ClearTimer, 0x1D>, "ClearTimer", 1000},
|
||||
{0x1E, &SVC::Wrap<&SVC::CreateMemoryBlock, 0x1E>, "CreateMemoryBlock", 1000},
|
||||
{0x1F, &SVC::Wrap<&SVC::MapMemoryBlock, 0x1F>, "MapMemoryBlock", 1000},
|
||||
{0x20, &SVC::Wrap<&SVC::UnmapMemoryBlock, 0x20>, "UnmapMemoryBlock", 1000},
|
||||
{0x21, &SVC::Wrap<&SVC::CreateAddressArbiter, 0x21>, "CreateAddressArbiter", 1000},
|
||||
{0x22, &SVC::Wrap<&SVC::ArbitrateAddress, 0x22>, "ArbitrateAddress", 5664},
|
||||
{0x23, &SVC::Wrap<&SVC::CloseHandle, 0x23>, "CloseHandle", 2937},
|
||||
{0x24, &SVC::Wrap<&SVC::WaitSynchronization1, 0x24>, "WaitSynchronization1", 4005},
|
||||
{0x25, &SVC::Wrap<&SVC::WaitSynchronizationN, 0x25>, "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},
|
||||
{0x27, &SVC::Wrap<&SVC::DuplicateHandle, 0x27>, "DuplicateHandle", 1000},
|
||||
{0x28, &SVC::Wrap<&SVC::GetSystemTick, 0x28>, "GetSystemTick", 340},
|
||||
{0x29, &SVC::Wrap<&SVC::GetHandleInfo, 0x29>, "GetHandleInfo", 1000},
|
||||
{0x2A, &SVC::Wrap<&SVC::GetSystemInfo, 0x2A>, "GetSystemInfo", 1000},
|
||||
{0x2B, &SVC::Wrap<&SVC::GetProcessInfo, 0x2B>, "GetProcessInfo", 1510},
|
||||
{0x2C, &SVC::Wrap<&SVC::GetThreadInfo, 0x2C>, "GetThreadInfo", 1000},
|
||||
{0x2D, &SVC::Wrap<&SVC::ConnectToPort, 0x2D>, "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},
|
||||
{0x32, &SVC::Wrap<&SVC::SendSyncRequest, 0x32>, "SendSyncRequest", 5825},
|
||||
{0x33, &SVC::Wrap<&SVC::OpenProcess, 0x33>, "OpenProcess", 1000},
|
||||
{0x34, &SVC::Wrap<&SVC::OpenThread, 0x34>, "OpenThread", 1000},
|
||||
{0x35, &SVC::Wrap<&SVC::GetProcessId, 0x35>, "GetProcessId", 1000},
|
||||
{0x36, &SVC::Wrap<&SVC::GetProcessIdOfThread, 0x36>, "GetProcessIdOfThread", 1000},
|
||||
{0x37, &SVC::Wrap<&SVC::GetThreadId, 0x37>, "GetThreadId", 677},
|
||||
{0x38, &SVC::Wrap<&SVC::GetResourceLimit, 0x38>, "GetResourceLimit", 1000},
|
||||
{0x39, &SVC::Wrap<&SVC::GetResourceLimitLimitValues, 0x39>, "GetResourceLimitLimitValues",
|
||||
1000},
|
||||
{0x3A, &SVC::Wrap<&SVC::GetResourceLimitCurrentValues, 0x3A>, "GetResourceLimitCurrentValues",
|
||||
1000},
|
||||
{0x3B, nullptr, "GetThreadContext", 1000},
|
||||
{0x3C, &SVC::Wrap<&SVC::Break>, "Break", 1000},
|
||||
{0x3D, &SVC::Wrap<&SVC::OutputDebugString>, "OutputDebugString", 1000},
|
||||
{0x3C, &SVC::Wrap<&SVC::Break, 0x3C>, "Break", 1000},
|
||||
{0x3D, &SVC::Wrap<&SVC::OutputDebugString, 0x3D>, "OutputDebugString", 1000},
|
||||
{0x3E, nullptr, "ControlPerformanceCounter", 1000},
|
||||
{0x3F, nullptr, "Unknown", 1000},
|
||||
{0x40, nullptr, "Unknown", 1000},
|
||||
@ -2288,20 +2290,20 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{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},
|
||||
{0x47, &SVC::Wrap<&SVC::CreatePort, 0x47>, "CreatePort", 1000},
|
||||
{0x48, &SVC::Wrap<&SVC::CreateSessionToPort, 0x48>, "CreateSessionToPort", 5122},
|
||||
{0x49, &SVC::Wrap<&SVC::CreateSession, 0x49>, "CreateSession", 3492},
|
||||
{0x4A, &SVC::Wrap<&SVC::AcceptSession, 0x4A>, "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},
|
||||
{0x4F, &SVC::Wrap<&SVC::ReplyAndReceive, 0x4F>, "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},
|
||||
{0x52, &SVC::Wrap<&SVC::InvalidateProcessDataCache, 0x52>, "InvalidateProcessDataCache", 9609},
|
||||
{0x53, &SVC::Wrap<&SVC::StoreProcessDataCache, 0x53>, "StoreProcessDataCache", 7174},
|
||||
{0x54, &SVC::Wrap<&SVC::FlushProcessDataCache, 0x54>, "FlushProcessDataCache", 9084},
|
||||
{0x55, nullptr, "StartInterProcessDma", 9146},
|
||||
{0x56, nullptr, "StopDma", 1163},
|
||||
{0x57, nullptr, "GetDmaState", 2222},
|
||||
@ -2318,7 +2320,7 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{0x62, nullptr, "TerminateDebugProcess", 1000},
|
||||
{0x63, nullptr, "GetProcessDebugEvent", 1000},
|
||||
{0x64, nullptr, "ContinueDebugEvent", 1000},
|
||||
{0x65, &SVC::Wrap<&SVC::GetProcessList>, "GetProcessList", 1000},
|
||||
{0x65, &SVC::Wrap<&SVC::GetProcessList, 0x65>, "GetProcessList", 1000},
|
||||
{0x66, nullptr, "GetThreadList", 1000},
|
||||
{0x67, nullptr, "GetDebugThreadContext", 1000},
|
||||
{0x68, nullptr, "SetDebugThreadContext", 1000},
|
||||
@ -2335,14 +2337,15 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{0x73, nullptr, "CreateCodeSet", 1000},
|
||||
{0x74, nullptr, "RandomStub", 1000},
|
||||
{0x75, nullptr, "CreateProcess", 1000},
|
||||
{0x76, &SVC::Wrap<&SVC::TerminateProcess>, "TerminateProcess", 1000},
|
||||
{0x76, &SVC::Wrap<&SVC::TerminateProcess, 0x76>, "TerminateProcess", 1000},
|
||||
{0x77, nullptr, "SetProcessResourceLimits", 1000},
|
||||
{0x78, nullptr, "CreateResourceLimit", 1000},
|
||||
{0x79, &SVC::Wrap<&SVC::SetResourceLimitLimitValues>, "SetResourceLimitLimitValues", 1000},
|
||||
{0x79, &SVC::Wrap<&SVC::SetResourceLimitLimitValues, 0x79>, "SetResourceLimitLimitValues",
|
||||
1000},
|
||||
{0x7A, nullptr, "AddCodeSegment", 1000},
|
||||
{0x7B, nullptr, "Backdoor", 1000},
|
||||
{0x7C, &SVC::Wrap<&SVC::KernelSetState>, "KernelSetState", 1000},
|
||||
{0x7D, &SVC::Wrap<&SVC::QueryProcessMemory>, "QueryProcessMemory", 1000},
|
||||
{0x7C, &SVC::Wrap<&SVC::KernelSetState, 0x7C>, "KernelSetState", 1000},
|
||||
{0x7D, &SVC::Wrap<&SVC::QueryProcessMemory, 0x7D>, "QueryProcessMemory", 1000},
|
||||
// Custom SVCs
|
||||
{0x7E, nullptr, "Unused", 1000},
|
||||
{0x7F, nullptr, "Unused", 1000},
|
||||
@ -2362,13 +2365,13 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{0x8D, nullptr, "Unused", 1000},
|
||||
{0x8E, nullptr, "Unused", 1000},
|
||||
{0x8F, nullptr, "Unused", 1000},
|
||||
{0x90, &SVC::Wrap<&SVC::ConvertVaToPa>, "ConvertVaToPa", 1000},
|
||||
{0x90, &SVC::Wrap<&SVC::ConvertVaToPa, 0x90>, "ConvertVaToPa", 1000},
|
||||
{0x91, nullptr, "FlushDataCacheRange", 1000},
|
||||
{0x92, nullptr, "FlushEntireDataCache", 1000},
|
||||
{0x93, &SVC::Wrap<&SVC::InvalidateInstructionCacheRange>, "InvalidateInstructionCacheRange",
|
||||
1000},
|
||||
{0x94, &SVC::Wrap<&SVC::InvalidateEntireInstructionCache>, "InvalidateEntireInstructionCache",
|
||||
1000},
|
||||
{0x93, &SVC::Wrap<&SVC::InvalidateInstructionCacheRange, 0x93>,
|
||||
"InvalidateInstructionCacheRange", 1000},
|
||||
{0x94, &SVC::Wrap<&SVC::InvalidateEntireInstructionCache, 0x94>,
|
||||
"InvalidateEntireInstructionCache", 1000},
|
||||
{0x95, nullptr, "Unused", 1000},
|
||||
{0x96, nullptr, "Unused", 1000},
|
||||
{0x97, nullptr, "Unused", 1000},
|
||||
@ -2380,8 +2383,8 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{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},
|
||||
{0xA0, &SVC::Wrap<&SVC::MapProcessMemoryEx, 0xA0>, "MapProcessMemoryEx", 1000},
|
||||
{0xA1, &SVC::Wrap<&SVC::UnmapProcessMemoryEx, 0xA1>, "UnmapProcessMemoryEx", 1000},
|
||||
{0xA2, nullptr, "ControlMemoryEx", 1000},
|
||||
{0xA3, nullptr, "ControlMemoryUnsafe", 1000},
|
||||
{0xA4, nullptr, "Unused", 1000},
|
||||
@ -2399,7 +2402,7 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{0xB0, nullptr, "ControlService", 1000},
|
||||
{0xB1, nullptr, "CopyHandle", 1000},
|
||||
{0xB2, nullptr, "TranslateHandle", 1000},
|
||||
{0xB3, &SVC::Wrap<&SVC::ControlProcess>, "ControlProcess", 1000},
|
||||
{0xB3, &SVC::Wrap<&SVC::ControlProcess, 0xB3>, "ControlProcess", 1000},
|
||||
}};
|
||||
|
||||
const SVC::FunctionDef* SVC::GetSVCInfo(u32 func_num) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2014 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -21,9 +21,9 @@ namespace Kernel {
|
||||
template <typename Context>
|
||||
class SVCWrapper {
|
||||
protected:
|
||||
template <auto F>
|
||||
template <auto F, int ID = 0xFF>
|
||||
void Wrap() {
|
||||
WrapHelper<decltype(F)>::Call(*static_cast<Context*>(this), F);
|
||||
WrapHelper<decltype(F)>::Call(*static_cast<Context*>(this), F, ID);
|
||||
};
|
||||
|
||||
private:
|
||||
@ -249,18 +249,18 @@ private:
|
||||
// T is the current param to do I/O.
|
||||
// Ts are params whose I/O is not handled yet.
|
||||
template <typename... Us>
|
||||
static void Call(Context& context, SVCT svc, Us... u) {
|
||||
static void Call(Context& context, SVCT svc, int id, Us... u) {
|
||||
static_assert(std::is_same_v<SVCT, R (Context::*)(Us..., T, Ts...)>);
|
||||
constexpr std::size_t current_param_index = sizeof...(Us);
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
using OutputT = std::remove_pointer_t<T>;
|
||||
OutputT output;
|
||||
WrapPass<SVCT, R, Ts...>::Call(context, svc, u..., &output);
|
||||
WrapPass<SVCT, R, Ts...>::Call(context, svc, id, u..., &output);
|
||||
SetParam<current_param_index, OutputT, R, Us..., T, Ts...>(context, output);
|
||||
} else {
|
||||
T input;
|
||||
GetParam<current_param_index, T, R, Us..., T, Ts...>(context, input);
|
||||
WrapPass<SVCT, R, Ts...>::Call(context, svc, u..., input);
|
||||
WrapPass<SVCT, R, Ts...>::Call(context, svc, id, u..., input);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -269,7 +269,7 @@ private:
|
||||
struct WrapPass<SVCT, R /*empty for T, Ts...*/> {
|
||||
// Call function R(Context::svc)(Us...) and transfer the return value to registers
|
||||
template <typename... Us>
|
||||
static void Call(Context& context, SVCT svc, Us... u) {
|
||||
static void Call(Context& context, SVCT svc, [[maybe_unused]] int id, Us... u) {
|
||||
static_assert(std::is_same_v<SVCT, R (Context::*)(Us...)>);
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
(context.*svc)(u...);
|
||||
@ -284,16 +284,18 @@ private:
|
||||
struct WrapPass<SVCT, Result /*empty for T, Ts...*/> {
|
||||
// Call function R(Context::svc)(Us...) and transfer the return value to registers
|
||||
template <typename... Us>
|
||||
static void Call(Context& context, SVCT svc, Us... u) {
|
||||
static void Call(Context& context, SVCT svc, int id, Us... u) {
|
||||
static_assert(std::is_same_v<SVCT, Result (Context::*)(Us...)>);
|
||||
if constexpr (std::is_void_v<Result>) {
|
||||
(context.*svc)(u...);
|
||||
} else {
|
||||
Result r = (context.*svc)(u...);
|
||||
if (r.IsError()) {
|
||||
LOG_ERROR(Kernel_SVC, "level={} summary={} module={} description={}",
|
||||
r.level.ExtractValue(r.raw), r.summary.ExtractValue(r.raw),
|
||||
r.module.ExtractValue(r.raw), r.description.ExtractValue(r.raw));
|
||||
LOG_ERROR(
|
||||
Kernel_SVC,
|
||||
"svc=0x{:02X} raw=0x{:08X} level={} summary={} module={} description={}",
|
||||
id, r.raw, r.level.ExtractValue(r.raw), r.summary.ExtractValue(r.raw),
|
||||
r.module.ExtractValue(r.raw), r.description.ExtractValue(r.raw));
|
||||
}
|
||||
SetParam<INDEX_RETURN, Result, Result, Us...>(context, r);
|
||||
}
|
||||
@ -305,8 +307,8 @@ private:
|
||||
|
||||
template <typename R, typename... T>
|
||||
struct WrapHelper<R (Context::*)(T...)> {
|
||||
static void Call(Context& context, R (Context::*svc)(T...)) {
|
||||
WrapPass<decltype(svc), R, T...>::Call(context, svc /*Empty for Us*/);
|
||||
static void Call(Context& context, R (Context::*svc)(T...), int id) {
|
||||
WrapPass<decltype(svc), R, T...>::Call(context, svc, id /*Empty for Us*/);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user