diff options
67 files changed, 7614 insertions, 1627 deletions
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index 32c1b1cb3..9133f5388 100644 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp @@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) { std::vector<std::string> device_list; cubeb* ctx; +#ifdef _WIN32 + auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); return {}; } +#ifdef _WIN32 + if (SUCCEEDED(com_init_result)) { + CoUninitialize(); + } +#endif + auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT}; cubeb_device_collection collection; if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) { @@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) { u32 GetCubebLatency() { cubeb* ctx; +#ifdef _WIN32 + auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); // Return a large latency so we choose SDL instead. return 10000u; } +#ifdef _WIN32 + if (SUCCEEDED(com_init_result)) { + CoUninitialize(); + } +#endif + cubeb_stream_params params{}; params.rate = TargetSampleRate; params.channels = 2; diff --git a/src/common/settings.h b/src/common/settings.h index 64db66f37..6d27dd5ee 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -488,6 +488,7 @@ struct Values { Setting<bool> enable_raw_input{false, "enable_raw_input"}; Setting<bool> controller_navigation{true, "controller_navigation"}; Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"}; + Setting<bool> enable_procon_driver{false, "enable_procon_driver"}; SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"}; SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f16072e6c..8ef1fcaa8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -310,6 +310,7 @@ add_library(core STATIC hle/kernel/svc/svc_event.cpp hle/kernel/svc/svc_exception.cpp hle/kernel/svc/svc_info.cpp + hle/kernel/svc/svc_insecure_memory.cpp hle/kernel/svc/svc_interrupt_event.cpp hle/kernel/svc/svc_io_pool.cpp hle/kernel/svc/svc_ipc.cpp diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 7d62d030e..c40771c97 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -5,6 +5,7 @@ #include <array> #include <span> +#include <string> #include <vector> #include <dynarmic/interface/halt_reason.h> diff --git a/src/core/hle/kernel/k_capabilities.cpp b/src/core/hle/kernel/k_capabilities.cpp index 64f1d7371..2907cc6e3 100644 --- a/src/core/hle/kernel/k_capabilities.cpp +++ b/src/core/hle/kernel/k_capabilities.cpp @@ -203,23 +203,23 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) { Result KCapabilities::MapRegion_(const u32 cap, KPageTable* page_table) { // Map each region into the process's page table. - R_RETURN(ProcessMapRegionCapability( + return ProcessMapRegionCapability( cap, [](KMemoryRegionType region_type, KMemoryPermission perm) -> Result { // R_RETURN(page_table->MapRegion(region_type, perm)); UNIMPLEMENTED(); R_SUCCEED(); - })); + }); } Result KCapabilities::CheckMapRegion(KernelCore& kernel, const u32 cap) { // Check that each region has a physical backing store. - R_RETURN(ProcessMapRegionCapability( + return ProcessMapRegionCapability( cap, [&](KMemoryRegionType region_type, KMemoryPermission perm) -> Result { R_UNLESS(kernel.MemoryLayout().GetPhysicalMemoryRegionTree().FindFirstDerived( region_type) != nullptr, ResultOutOfRange); R_SUCCEED(); - })); + }); } Result KCapabilities::SetInterruptPairCapability(const u32 cap) { diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index fb2ba4c6b..fb8e7933e 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -3,6 +3,7 @@ #pragma once +#include <condition_variable> #include <cstddef> #include <memory> #include <mutex> diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4cb6f40a0..4ef57356e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1,449 +1,4435 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/common_types.h" +// This file is automatically generated using svc_generator.py. + +#include <type_traits> + +#include "core/arm/arm_interface.h" +#include "core/core.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>, "SetHeapSize32"}, - {0x02, nullptr, "SetMemoryPermission32"}, - {0x03, SvcWrap32<SetMemoryAttribute32>, "SetMemoryAttribute32"}, - {0x04, SvcWrap32<MapMemory32>, "MapMemory32"}, - {0x05, SvcWrap32<UnmapMemory32>, "UnmapMemory32"}, - {0x06, SvcWrap32<QueryMemory32>, "QueryMemory32"}, - {0x07, SvcWrap32<ExitProcess32>, "ExitProcess32"}, - {0x08, SvcWrap32<CreateThread32>, "CreateThread32"}, - {0x09, SvcWrap32<StartThread32>, "StartThread32"}, - {0x0a, SvcWrap32<ExitThread32>, "ExitThread32"}, - {0x0b, SvcWrap32<SleepThread32>, "SleepThread32"}, - {0x0c, SvcWrap32<GetThreadPriority32>, "GetThreadPriority32"}, - {0x0d, SvcWrap32<SetThreadPriority32>, "SetThreadPriority32"}, - {0x0e, SvcWrap32<GetThreadCoreMask32>, "GetThreadCoreMask32"}, - {0x0f, SvcWrap32<SetThreadCoreMask32>, "SetThreadCoreMask32"}, - {0x10, SvcWrap32<GetCurrentProcessorNumber32>, "GetCurrentProcessorNumber32"}, - {0x11, SvcWrap32<SignalEvent32>, "SignalEvent32"}, - {0x12, SvcWrap32<ClearEvent32>, "ClearEvent32"}, - {0x13, SvcWrap32<MapSharedMemory32>, "MapSharedMemory32"}, - {0x14, SvcWrap32<UnmapSharedMemory32>, "UnmapSharedMemory32"}, - {0x15, SvcWrap32<CreateTransferMemory32>, "CreateTransferMemory32"}, - {0x16, SvcWrap32<CloseHandle32>, "CloseHandle32"}, - {0x17, SvcWrap32<ResetSignal32>, "ResetSignal32"}, - {0x18, SvcWrap32<WaitSynchronization32>, "WaitSynchronization32"}, - {0x19, SvcWrap32<CancelSynchronization32>, "CancelSynchronization32"}, - {0x1a, SvcWrap32<ArbitrateLock32>, "ArbitrateLock32"}, - {0x1b, SvcWrap32<ArbitrateUnlock32>, "ArbitrateUnlock32"}, - {0x1c, SvcWrap32<WaitProcessWideKeyAtomic32>, "WaitProcessWideKeyAtomic32"}, - {0x1d, SvcWrap32<SignalProcessWideKey32>, "SignalProcessWideKey32"}, - {0x1e, SvcWrap32<GetSystemTick32>, "GetSystemTick32"}, - {0x1f, SvcWrap32<ConnectToNamedPort32>, "ConnectToNamedPort32"}, - {0x20, nullptr, "SendSyncRequestLight32"}, - {0x21, SvcWrap32<SendSyncRequest32>, "SendSyncRequest32"}, - {0x22, nullptr, "SendSyncRequestWithUserBuffer32"}, - {0x23, nullptr, "SendAsyncRequestWithUserBuffer32"}, - {0x24, SvcWrap32<GetProcessId32>, "GetProcessId32"}, - {0x25, SvcWrap32<GetThreadId32>, "GetThreadId32"}, - {0x26, SvcWrap32<Break32>, "Break32"}, - {0x27, SvcWrap32<OutputDebugString32>, "OutputDebugString32"}, - {0x28, nullptr, "ReturnFromException32"}, - {0x29, SvcWrap32<GetInfo32>, "GetInfo32"}, - {0x2a, nullptr, "FlushEntireDataCache32"}, - {0x2b, nullptr, "FlushDataCache32"}, - {0x2c, SvcWrap32<MapPhysicalMemory32>, "MapPhysicalMemory32"}, - {0x2d, SvcWrap32<UnmapPhysicalMemory32>, "UnmapPhysicalMemory32"}, - {0x2e, nullptr, "GetDebugFutureThreadInfo32"}, - {0x2f, nullptr, "GetLastThreadInfo32"}, - {0x30, nullptr, "GetResourceLimitLimitValue32"}, - {0x31, nullptr, "GetResourceLimitCurrentValue32"}, - {0x32, SvcWrap32<SetThreadActivity32>, "SetThreadActivity32"}, - {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"}, - {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"}, - {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"}, - {0x36, SvcWrap32<SynchronizePreemptionState>, "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>, "CreateEvent32"}, - {0x46, nullptr, "MapIoRegion32"}, - {0x47, nullptr, "UnmapIoRegion32"}, - {0x48, nullptr, "MapPhysicalMemoryUnsafe32"}, - {0x49, nullptr, "UnmapPhysicalMemoryUnsafe32"}, - {0x4a, nullptr, "SetUnsafeLimit32"}, - {0x4b, SvcWrap32<CreateCodeMemory32>, "CreateCodeMemory32"}, - {0x4c, SvcWrap32<ControlCodeMemory32>, "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>, "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>, "SetHeapSize"}, - {0x02, SvcWrap64<SetMemoryPermission>, "SetMemoryPermission"}, - {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, - {0x04, SvcWrap64<MapMemory>, "MapMemory"}, - {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, - {0x06, SvcWrap64<QueryMemory>, "QueryMemory"}, - {0x07, SvcWrap64<ExitProcess>, "ExitProcess"}, - {0x08, SvcWrap64<CreateThread>, "CreateThread"}, - {0x09, SvcWrap64<StartThread>, "StartThread"}, - {0x0A, SvcWrap64<ExitThread>, "ExitThread"}, - {0x0B, SvcWrap64<SleepThread>, "SleepThread"}, - {0x0C, SvcWrap64<GetThreadPriority>, "GetThreadPriority"}, - {0x0D, SvcWrap64<SetThreadPriority>, "SetThreadPriority"}, - {0x0E, SvcWrap64<GetThreadCoreMask>, "GetThreadCoreMask"}, - {0x0F, SvcWrap64<SetThreadCoreMask>, "SetThreadCoreMask"}, - {0x10, SvcWrap64<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"}, - {0x11, SvcWrap64<SignalEvent>, "SignalEvent"}, - {0x12, SvcWrap64<ClearEvent>, "ClearEvent"}, - {0x13, SvcWrap64<MapSharedMemory>, "MapSharedMemory"}, - {0x14, SvcWrap64<UnmapSharedMemory>, "UnmapSharedMemory"}, - {0x15, SvcWrap64<CreateTransferMemory>, "CreateTransferMemory"}, - {0x16, SvcWrap64<CloseHandle>, "CloseHandle"}, - {0x17, SvcWrap64<ResetSignal>, "ResetSignal"}, - {0x18, SvcWrap64<WaitSynchronization>, "WaitSynchronization"}, - {0x19, SvcWrap64<CancelSynchronization>, "CancelSynchronization"}, - {0x1A, SvcWrap64<ArbitrateLock>, "ArbitrateLock"}, - {0x1B, SvcWrap64<ArbitrateUnlock>, "ArbitrateUnlock"}, - {0x1C, SvcWrap64<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"}, - {0x1D, SvcWrap64<SignalProcessWideKey>, "SignalProcessWideKey"}, - {0x1E, SvcWrap64<GetSystemTick>, "GetSystemTick"}, - {0x1F, SvcWrap64<ConnectToNamedPort>, "ConnectToNamedPort"}, - {0x20, nullptr, "SendSyncRequestLight"}, - {0x21, SvcWrap64<SendSyncRequest>, "SendSyncRequest"}, - {0x22, nullptr, "SendSyncRequestWithUserBuffer"}, - {0x23, nullptr, "SendAsyncRequestWithUserBuffer"}, - {0x24, SvcWrap64<GetProcessId>, "GetProcessId"}, - {0x25, SvcWrap64<GetThreadId>, "GetThreadId"}, - {0x26, SvcWrap64<Break>, "Break"}, - {0x27, SvcWrap64<OutputDebugString>, "OutputDebugString"}, - {0x28, nullptr, "ReturnFromException"}, - {0x29, SvcWrap64<GetInfo>, "GetInfo"}, - {0x2A, nullptr, "FlushEntireDataCache"}, - {0x2B, nullptr, "FlushDataCache"}, - {0x2C, SvcWrap64<MapPhysicalMemory>, "MapPhysicalMemory"}, - {0x2D, SvcWrap64<UnmapPhysicalMemory>, "UnmapPhysicalMemory"}, - {0x2E, nullptr, "GetFutureThreadInfo"}, - {0x2F, nullptr, "GetLastThreadInfo"}, - {0x30, SvcWrap64<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, - {0x31, SvcWrap64<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"}, - {0x32, SvcWrap64<SetThreadActivity>, "SetThreadActivity"}, - {0x33, SvcWrap64<GetThreadContext>, "GetThreadContext"}, - {0x34, SvcWrap64<WaitForAddress>, "WaitForAddress"}, - {0x35, SvcWrap64<SignalToAddress>, "SignalToAddress"}, - {0x36, SvcWrap64<SynchronizePreemptionState>, "SynchronizePreemptionState"}, - {0x37, nullptr, "GetResourceLimitPeakValue"}, - {0x38, nullptr, "Unknown38"}, - {0x39, nullptr, "CreateIoPool"}, - {0x3A, nullptr, "CreateIoRegion"}, - {0x3B, nullptr, "Unknown3B"}, - {0x3C, SvcWrap64<KernelDebug>, "KernelDebug"}, - {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, - {0x3E, nullptr, "Unknown3e"}, - {0x3F, nullptr, "Unknown3f"}, - {0x40, SvcWrap64<CreateSession>, "CreateSession"}, - {0x41, nullptr, "AcceptSession"}, - {0x42, nullptr, "ReplyAndReceiveLight"}, - {0x43, SvcWrap64<ReplyAndReceive>, "ReplyAndReceive"}, - {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, - {0x45, SvcWrap64<CreateEvent>, "CreateEvent"}, - {0x46, nullptr, "MapIoRegion"}, - {0x47, nullptr, "UnmapIoRegion"}, - {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, - {0x49, nullptr, "UnmapPhysicalMemoryUnsafe"}, - {0x4A, nullptr, "SetUnsafeLimit"}, - {0x4B, SvcWrap64<CreateCodeMemory>, "CreateCodeMemory"}, - {0x4C, SvcWrap64<ControlCodeMemory>, "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>, "GetProcessList"}, - {0x66, SvcWrap64<GetThreadList>, "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>, "SetProcessMemoryPermission"}, - {0x74, SvcWrap64<MapProcessMemory>, "MapProcessMemory"}, - {0x75, SvcWrap64<UnmapProcessMemory>, "UnmapProcessMemory"}, - {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, - {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"}, - {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, - {0x79, nullptr, "CreateProcess"}, - {0x7A, nullptr, "StartProcess"}, - {0x7B, nullptr, "TerminateProcess"}, - {0x7C, SvcWrap64<GetProcessInfo>, "GetProcessInfo"}, - {0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"}, - {0x7E, SvcWrap64<SetResourceLimitLimitValue>, "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; + +static uint32_t GetReg32(Core::System& system, int n) { + return static_cast<uint32_t>(system.CurrentArmInterface().GetReg(n)); +} + +static void SetReg32(Core::System& system, int n, uint32_t result) { + system.CurrentArmInterface().SetReg(n, static_cast<uint64_t>(result)); +} + +static uint64_t GetReg64(Core::System& system, int n) { + return system.CurrentArmInterface().GetReg(n); +} + +static void SetReg64(Core::System& system, int n, uint64_t result) { + system.CurrentArmInterface().SetReg(n, result); +} + +// Like bit_cast, but handles the case when the source and dest +// are differently-sized. +template <typename To, typename From> + requires(std::is_trivial_v<To> && std::is_trivially_copyable_v<From>) +static To Convert(const From& from) { + To to{}; + + if constexpr (sizeof(To) >= sizeof(From)) { + std::memcpy(&to, &from, sizeof(From)); + } else { + std::memcpy(&to, &from, sizeof(To)); + } + + return to; +} + +// clang-format off +static_assert(sizeof(ArbitrationType) == 4); +static_assert(sizeof(BreakReason) == 4); +static_assert(sizeof(CodeMemoryOperation) == 4); +static_assert(sizeof(DebugThreadParam) == 4); +static_assert(sizeof(DeviceName) == 4); +static_assert(sizeof(HardwareBreakPointRegisterName) == 4); +static_assert(sizeof(Handle) == 4); +static_assert(sizeof(InfoType) == 4); +static_assert(sizeof(InterruptType) == 4); +static_assert(sizeof(IoPoolType) == 4); +static_assert(sizeof(KernelDebugType) == 4); +static_assert(sizeof(KernelTraceState) == 4); +static_assert(sizeof(LimitableResource) == 4); +static_assert(sizeof(MemoryMapping) == 4); +static_assert(sizeof(MemoryPermission) == 4); +static_assert(sizeof(PageInfo) == 4); +static_assert(sizeof(ProcessActivity) == 4); +static_assert(sizeof(ProcessInfoType) == 4); +static_assert(sizeof(Result) == 4); +static_assert(sizeof(SignalType) == 4); +static_assert(sizeof(SystemInfoType) == 4); +static_assert(sizeof(ThreadActivity) == 4); +static_assert(sizeof(ilp32::LastThreadContext) == 16); +static_assert(sizeof(ilp32::PhysicalMemoryInfo) == 16); +static_assert(sizeof(ilp32::SecureMonitorArguments) == 32); +static_assert(sizeof(lp64::LastThreadContext) == 32); +static_assert(sizeof(lp64::PhysicalMemoryInfo) == 24); +static_assert(sizeof(lp64::SecureMonitorArguments) == 64); +static_assert(sizeof(bool) == 1); +static_assert(sizeof(int32_t) == 4); +static_assert(sizeof(int64_t) == 8); +static_assert(sizeof(uint32_t) == 4); +static_assert(sizeof(uint64_t) == 8); + +static void SvcWrap_SetHeapSize64From32(Core::System& system) { + Result ret{}; + + uintptr_t out_address{}; + uint32_t size{}; + + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = SetHeapSize64From32(system, &out_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_address)); +} + +static void SvcWrap_SetMemoryPermission64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + MemoryPermission perm{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + perm = Convert<MemoryPermission>(GetReg32(system, 2)); + + ret = SetMemoryPermission64From32(system, address, size, perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SetMemoryAttribute64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + uint32_t mask{}; + uint32_t attr{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + mask = Convert<uint32_t>(GetReg32(system, 2)); + attr = Convert<uint32_t>(GetReg32(system, 3)); + + ret = SetMemoryAttribute64From32(system, address, size, mask, attr); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t dst_address{}; + uint32_t src_address{}; + uint32_t size{}; + + dst_address = Convert<uint32_t>(GetReg32(system, 0)); + src_address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + ret = MapMemory64From32(system, dst_address, src_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t dst_address{}; + uint32_t src_address{}; + uint32_t size{}; + + dst_address = Convert<uint32_t>(GetReg32(system, 0)); + src_address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + ret = UnmapMemory64From32(system, dst_address, src_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_QueryMemory64From32(Core::System& system) { + Result ret{}; + + PageInfo out_page_info{}; + uint32_t out_memory_info{}; + uint32_t address{}; + + out_memory_info = Convert<uint32_t>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 2)); + + ret = QueryMemory64From32(system, out_memory_info, &out_page_info, address); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_page_info)); +} + +static void SvcWrap_ExitProcess64From32(Core::System& system) { + ExitProcess64From32(system); +} + +static void SvcWrap_CreateThread64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint32_t func{}; + uint32_t arg{}; + uint32_t stack_bottom{}; + int32_t priority{}; + int32_t core_id{}; + + func = Convert<uint32_t>(GetReg32(system, 1)); + arg = Convert<uint32_t>(GetReg32(system, 2)); + stack_bottom = Convert<uint32_t>(GetReg32(system, 3)); + priority = Convert<int32_t>(GetReg32(system, 0)); + core_id = Convert<int32_t>(GetReg32(system, 4)); + + ret = CreateThread64From32(system, &out_handle, func, arg, stack_bottom, priority, core_id); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_StartThread64From32(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = StartThread64From32(system, thread_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ExitThread64From32(Core::System& system) { + ExitThread64From32(system); +} + +static void SvcWrap_SleepThread64From32(Core::System& system) { + int64_t ns{}; + + std::array<uint32_t, 2> ns_gather{}; + ns_gather[0] = GetReg32(system, 0); + ns_gather[1] = GetReg32(system, 1); + ns = Convert<int64_t>(ns_gather); + + SleepThread64From32(system, ns); +} + +static void SvcWrap_GetThreadPriority64From32(Core::System& system) { + Result ret{}; + + int32_t out_priority{}; + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = GetThreadPriority64From32(system, &out_priority, thread_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_priority)); +} + +static void SvcWrap_SetThreadPriority64From32(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + int32_t priority{}; + + thread_handle = Convert<Handle>(GetReg32(system, 0)); + priority = Convert<int32_t>(GetReg32(system, 1)); + + ret = SetThreadPriority64From32(system, thread_handle, priority); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetThreadCoreMask64From32(Core::System& system) { + Result ret{}; + + int32_t out_core_id{}; + uint64_t out_affinity_mask{}; + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg32(system, 2)); + + ret = GetThreadCoreMask64From32(system, &out_core_id, &out_affinity_mask, thread_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_core_id)); + auto out_affinity_mask_scatter = Convert<std::array<uint32_t, 2>>(out_affinity_mask); + SetReg32(system, 2, out_affinity_mask_scatter[0]); + SetReg32(system, 3, out_affinity_mask_scatter[1]); +} + +static void SvcWrap_SetThreadCoreMask64From32(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + int32_t core_id{}; + uint64_t affinity_mask{}; + + thread_handle = Convert<Handle>(GetReg32(system, 0)); + core_id = Convert<int32_t>(GetReg32(system, 1)); + std::array<uint32_t, 2> affinity_mask_gather{}; + affinity_mask_gather[0] = GetReg32(system, 2); + affinity_mask_gather[1] = GetReg32(system, 3); + affinity_mask = Convert<uint64_t>(affinity_mask_gather); + + ret = SetThreadCoreMask64From32(system, thread_handle, core_id, affinity_mask); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetCurrentProcessorNumber64From32(Core::System& system) { + int32_t ret{}; + + ret = GetCurrentProcessorNumber64From32(system); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SignalEvent64From32(Core::System& system) { + Result ret{}; + + Handle event_handle{}; + + event_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = SignalEvent64From32(system, event_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ClearEvent64From32(Core::System& system) { + Result ret{}; + + Handle event_handle{}; + + event_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = ClearEvent64From32(system, event_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapSharedMemory64From32(Core::System& system) { + Result ret{}; + + Handle shmem_handle{}; + uint32_t address{}; + uint32_t size{}; + MemoryPermission map_perm{}; + + shmem_handle = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + map_perm = Convert<MemoryPermission>(GetReg32(system, 3)); + + ret = MapSharedMemory64From32(system, shmem_handle, address, size, map_perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapSharedMemory64From32(Core::System& system) { + Result ret{}; + + Handle shmem_handle{}; + uint32_t address{}; + uint32_t size{}; + + shmem_handle = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + ret = UnmapSharedMemory64From32(system, shmem_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_CreateTransferMemory64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint32_t address{}; + uint32_t size{}; + MemoryPermission map_perm{}; + + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + map_perm = Convert<MemoryPermission>(GetReg32(system, 3)); + + ret = CreateTransferMemory64From32(system, &out_handle, address, size, map_perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_CloseHandle64From32(Core::System& system) { + Result ret{}; + + Handle handle{}; + + handle = Convert<Handle>(GetReg32(system, 0)); + + ret = CloseHandle64From32(system, handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ResetSignal64From32(Core::System& system) { + Result ret{}; + + Handle handle{}; + + handle = Convert<Handle>(GetReg32(system, 0)); + + ret = ResetSignal64From32(system, handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_WaitSynchronization64From32(Core::System& system) { + Result ret{}; + + int32_t out_index{}; + uint32_t handles{}; + int32_t num_handles{}; + int64_t timeout_ns{}; + + handles = Convert<uint32_t>(GetReg32(system, 1)); + num_handles = Convert<int32_t>(GetReg32(system, 2)); + std::array<uint32_t, 2> timeout_ns_gather{}; + timeout_ns_gather[0] = GetReg32(system, 0); + timeout_ns_gather[1] = GetReg32(system, 3); + timeout_ns = Convert<int64_t>(timeout_ns_gather); + + ret = WaitSynchronization64From32(system, &out_index, handles, num_handles, timeout_ns); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_index)); +} + +static void SvcWrap_CancelSynchronization64From32(Core::System& system) { + Result ret{}; + + Handle handle{}; + + handle = Convert<Handle>(GetReg32(system, 0)); + + ret = CancelSynchronization64From32(system, handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ArbitrateLock64From32(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + uint32_t address{}; + uint32_t tag{}; + + thread_handle = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + tag = Convert<uint32_t>(GetReg32(system, 2)); + + ret = ArbitrateLock64From32(system, thread_handle, address, tag); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ArbitrateUnlock64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + + ret = ArbitrateUnlock64From32(system, address); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_WaitProcessWideKeyAtomic64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t cv_key{}; + uint32_t tag{}; + int64_t timeout_ns{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + cv_key = Convert<uint32_t>(GetReg32(system, 1)); + tag = Convert<uint32_t>(GetReg32(system, 2)); + std::array<uint32_t, 2> timeout_ns_gather{}; + timeout_ns_gather[0] = GetReg32(system, 3); + timeout_ns_gather[1] = GetReg32(system, 4); + timeout_ns = Convert<int64_t>(timeout_ns_gather); + + ret = WaitProcessWideKeyAtomic64From32(system, address, cv_key, tag, timeout_ns); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SignalProcessWideKey64From32(Core::System& system) { + uint32_t cv_key{}; + int32_t count{}; + + cv_key = Convert<uint32_t>(GetReg32(system, 0)); + count = Convert<int32_t>(GetReg32(system, 1)); + + SignalProcessWideKey64From32(system, cv_key, count); +} + +static void SvcWrap_GetSystemTick64From32(Core::System& system) { + int64_t ret{}; + + ret = GetSystemTick64From32(system); + + auto ret_scatter = Convert<std::array<uint32_t, 2>>(ret); + SetReg32(system, 0, ret_scatter[0]); + SetReg32(system, 1, ret_scatter[1]); +} + +static void SvcWrap_ConnectToNamedPort64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint32_t name{}; + + name = Convert<uint32_t>(GetReg32(system, 1)); + + ret = ConnectToNamedPort64From32(system, &out_handle, name); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_SendSyncRequest64From32(Core::System& system) { + Result ret{}; + + Handle session_handle{}; + + session_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = SendSyncRequest64From32(system, session_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SendSyncRequestWithUserBuffer64From32(Core::System& system) { + Result ret{}; + + uint32_t message_buffer{}; + uint32_t message_buffer_size{}; + Handle session_handle{}; + + message_buffer = Convert<uint32_t>(GetReg32(system, 0)); + message_buffer_size = Convert<uint32_t>(GetReg32(system, 1)); + session_handle = Convert<Handle>(GetReg32(system, 2)); + + ret = SendSyncRequestWithUserBuffer64From32(system, message_buffer, message_buffer_size, session_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SendAsyncRequestWithUserBuffer64From32(Core::System& system) { + Result ret{}; + + Handle out_event_handle{}; + uint32_t message_buffer{}; + uint32_t message_buffer_size{}; + Handle session_handle{}; + + message_buffer = Convert<uint32_t>(GetReg32(system, 1)); + message_buffer_size = Convert<uint32_t>(GetReg32(system, 2)); + session_handle = Convert<Handle>(GetReg32(system, 3)); + + ret = SendAsyncRequestWithUserBuffer64From32(system, &out_event_handle, message_buffer, message_buffer_size, session_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_event_handle)); +} + +static void SvcWrap_GetProcessId64From32(Core::System& system) { + Result ret{}; + + uint64_t out_process_id{}; + Handle process_handle{}; + + process_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = GetProcessId64From32(system, &out_process_id, process_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_process_id_scatter = Convert<std::array<uint32_t, 2>>(out_process_id); + SetReg32(system, 1, out_process_id_scatter[0]); + SetReg32(system, 2, out_process_id_scatter[1]); +} + +static void SvcWrap_GetThreadId64From32(Core::System& system) { + Result ret{}; + + uint64_t out_thread_id{}; + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = GetThreadId64From32(system, &out_thread_id, thread_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_thread_id_scatter = Convert<std::array<uint32_t, 2>>(out_thread_id); + SetReg32(system, 1, out_thread_id_scatter[0]); + SetReg32(system, 2, out_thread_id_scatter[1]); +} + +static void SvcWrap_Break64From32(Core::System& system) { + BreakReason break_reason{}; + uint32_t arg{}; + uint32_t size{}; + + break_reason = Convert<BreakReason>(GetReg32(system, 0)); + arg = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + Break64From32(system, break_reason, arg, size); +} + +static void SvcWrap_OutputDebugString64From32(Core::System& system) { + Result ret{}; + + uint32_t debug_str{}; + uint32_t len{}; + + debug_str = Convert<uint32_t>(GetReg32(system, 0)); + len = Convert<uint32_t>(GetReg32(system, 1)); + + ret = OutputDebugString64From32(system, debug_str, len); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ReturnFromException64From32(Core::System& system) { + Result result{}; + + result = Convert<Result>(GetReg32(system, 0)); + + ReturnFromException64From32(system, result); +} + +static void SvcWrap_GetInfo64From32(Core::System& system) { + Result ret{}; + + uint64_t out{}; + InfoType info_type{}; + Handle handle{}; + uint64_t info_subtype{}; + + info_type = Convert<InfoType>(GetReg32(system, 1)); + handle = Convert<Handle>(GetReg32(system, 2)); + std::array<uint32_t, 2> info_subtype_gather{}; + info_subtype_gather[0] = GetReg32(system, 0); + info_subtype_gather[1] = GetReg32(system, 3); + info_subtype = Convert<uint64_t>(info_subtype_gather); + + ret = GetInfo64From32(system, &out, info_type, handle, info_subtype); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_scatter = Convert<std::array<uint32_t, 2>>(out); + SetReg32(system, 1, out_scatter[0]); + SetReg32(system, 2, out_scatter[1]); +} + +static void SvcWrap_FlushEntireDataCache64From32(Core::System& system) { + FlushEntireDataCache64From32(system); +} + +static void SvcWrap_FlushDataCache64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = FlushDataCache64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapPhysicalMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = MapPhysicalMemory64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapPhysicalMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = UnmapPhysicalMemory64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetDebugFutureThreadInfo64From32(Core::System& system) { + Result ret{}; + + ilp32::LastThreadContext out_context{}; + uint64_t out_thread_id{}; + Handle debug_handle{}; + int64_t ns{}; + + debug_handle = Convert<Handle>(GetReg32(system, 2)); + std::array<uint32_t, 2> ns_gather{}; + ns_gather[0] = GetReg32(system, 0); + ns_gather[1] = GetReg32(system, 1); + ns = Convert<int64_t>(ns_gather); + + ret = GetDebugFutureThreadInfo64From32(system, &out_context, &out_thread_id, debug_handle, ns); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_context_scatter = Convert<std::array<uint32_t, 4>>(out_context); + SetReg32(system, 1, out_context_scatter[0]); + SetReg32(system, 2, out_context_scatter[1]); + SetReg32(system, 3, out_context_scatter[2]); + SetReg32(system, 4, out_context_scatter[3]); + auto out_thread_id_scatter = Convert<std::array<uint32_t, 2>>(out_thread_id); + SetReg32(system, 5, out_thread_id_scatter[0]); + SetReg32(system, 6, out_thread_id_scatter[1]); +} + +static void SvcWrap_GetLastThreadInfo64From32(Core::System& system) { + Result ret{}; + + ilp32::LastThreadContext out_context{}; + uintptr_t out_tls_address{}; + uint32_t out_flags{}; + + ret = GetLastThreadInfo64From32(system, &out_context, &out_tls_address, &out_flags); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_context_scatter = Convert<std::array<uint32_t, 4>>(out_context); + SetReg32(system, 1, out_context_scatter[0]); + SetReg32(system, 2, out_context_scatter[1]); + SetReg32(system, 3, out_context_scatter[2]); + SetReg32(system, 4, out_context_scatter[3]); + SetReg32(system, 5, Convert<uint32_t>(out_tls_address)); + SetReg32(system, 6, Convert<uint32_t>(out_flags)); +} + +static void SvcWrap_GetResourceLimitLimitValue64From32(Core::System& system) { + Result ret{}; + + int64_t out_limit_value{}; + Handle resource_limit_handle{}; + LimitableResource which{}; + + resource_limit_handle = Convert<Handle>(GetReg32(system, 1)); + which = Convert<LimitableResource>(GetReg32(system, 2)); + + ret = GetResourceLimitLimitValue64From32(system, &out_limit_value, resource_limit_handle, which); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_limit_value_scatter = Convert<std::array<uint32_t, 2>>(out_limit_value); + SetReg32(system, 1, out_limit_value_scatter[0]); + SetReg32(system, 2, out_limit_value_scatter[1]); +} + +static void SvcWrap_GetResourceLimitCurrentValue64From32(Core::System& system) { + Result ret{}; + + int64_t out_current_value{}; + Handle resource_limit_handle{}; + LimitableResource which{}; + + resource_limit_handle = Convert<Handle>(GetReg32(system, 1)); + which = Convert<LimitableResource>(GetReg32(system, 2)); + + ret = GetResourceLimitCurrentValue64From32(system, &out_current_value, resource_limit_handle, which); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_current_value_scatter = Convert<std::array<uint32_t, 2>>(out_current_value); + SetReg32(system, 1, out_current_value_scatter[0]); + SetReg32(system, 2, out_current_value_scatter[1]); +} + +static void SvcWrap_SetThreadActivity64From32(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + ThreadActivity thread_activity{}; + + thread_handle = Convert<Handle>(GetReg32(system, 0)); + thread_activity = Convert<ThreadActivity>(GetReg32(system, 1)); + + ret = SetThreadActivity64From32(system, thread_handle, thread_activity); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetThreadContext364From32(Core::System& system) { + Result ret{}; + + uint32_t out_context{}; + Handle thread_handle{}; + + out_context = Convert<uint32_t>(GetReg32(system, 0)); + thread_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = GetThreadContext364From32(system, out_context, thread_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_WaitForAddress64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + ArbitrationType arb_type{}; + int32_t value{}; + int64_t timeout_ns{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + arb_type = Convert<ArbitrationType>(GetReg32(system, 1)); + value = Convert<int32_t>(GetReg32(system, 2)); + std::array<uint32_t, 2> timeout_ns_gather{}; + timeout_ns_gather[0] = GetReg32(system, 3); + timeout_ns_gather[1] = GetReg32(system, 4); + timeout_ns = Convert<int64_t>(timeout_ns_gather); + + ret = WaitForAddress64From32(system, address, arb_type, value, timeout_ns); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SignalToAddress64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + SignalType signal_type{}; + int32_t value{}; + int32_t count{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + signal_type = Convert<SignalType>(GetReg32(system, 1)); + value = Convert<int32_t>(GetReg32(system, 2)); + count = Convert<int32_t>(GetReg32(system, 3)); + + ret = SignalToAddress64From32(system, address, signal_type, value, count); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SynchronizePreemptionState64From32(Core::System& system) { + SynchronizePreemptionState64From32(system); +} + +static void SvcWrap_GetResourceLimitPeakValue64From32(Core::System& system) { + Result ret{}; + + int64_t out_peak_value{}; + Handle resource_limit_handle{}; + LimitableResource which{}; + + resource_limit_handle = Convert<Handle>(GetReg32(system, 1)); + which = Convert<LimitableResource>(GetReg32(system, 2)); + + ret = GetResourceLimitPeakValue64From32(system, &out_peak_value, resource_limit_handle, which); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_peak_value_scatter = Convert<std::array<uint32_t, 2>>(out_peak_value); + SetReg32(system, 1, out_peak_value_scatter[0]); + SetReg32(system, 2, out_peak_value_scatter[1]); +} + +static void SvcWrap_CreateIoPool64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + IoPoolType which{}; + + which = Convert<IoPoolType>(GetReg32(system, 1)); + + ret = CreateIoPool64From32(system, &out_handle, which); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_CreateIoRegion64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + Handle io_pool{}; + uint64_t physical_address{}; + uint32_t size{}; + MemoryMapping mapping{}; + MemoryPermission perm{}; + + io_pool = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> physical_address_gather{}; + physical_address_gather[0] = GetReg32(system, 2); + physical_address_gather[1] = GetReg32(system, 3); + physical_address = Convert<uint64_t>(physical_address_gather); + size = Convert<uint32_t>(GetReg32(system, 0)); + mapping = Convert<MemoryMapping>(GetReg32(system, 4)); + perm = Convert<MemoryPermission>(GetReg32(system, 5)); + + ret = CreateIoRegion64From32(system, &out_handle, io_pool, physical_address, size, mapping, perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_KernelDebug64From32(Core::System& system) { + KernelDebugType kern_debug_type{}; + uint64_t arg0{}; + uint64_t arg1{}; + uint64_t arg2{}; + + kern_debug_type = Convert<KernelDebugType>(GetReg32(system, 0)); + std::array<uint32_t, 2> arg0_gather{}; + arg0_gather[0] = GetReg32(system, 2); + arg0_gather[1] = GetReg32(system, 3); + arg0 = Convert<uint64_t>(arg0_gather); + std::array<uint32_t, 2> arg1_gather{}; + arg1_gather[0] = GetReg32(system, 1); + arg1_gather[1] = GetReg32(system, 4); + arg1 = Convert<uint64_t>(arg1_gather); + std::array<uint32_t, 2> arg2_gather{}; + arg2_gather[0] = GetReg32(system, 5); + arg2_gather[1] = GetReg32(system, 6); + arg2 = Convert<uint64_t>(arg2_gather); + + KernelDebug64From32(system, kern_debug_type, arg0, arg1, arg2); +} + +static void SvcWrap_ChangeKernelTraceState64From32(Core::System& system) { + KernelTraceState kern_trace_state{}; + + kern_trace_state = Convert<KernelTraceState>(GetReg32(system, 0)); + + ChangeKernelTraceState64From32(system, kern_trace_state); +} + +static void SvcWrap_CreateSession64From32(Core::System& system) { + Result ret{}; + + Handle out_server_session_handle{}; + Handle out_client_session_handle{}; + bool is_light{}; + uint32_t name{}; + + is_light = Convert<bool>(GetReg32(system, 2)); + name = Convert<uint32_t>(GetReg32(system, 3)); + + ret = CreateSession64From32(system, &out_server_session_handle, &out_client_session_handle, is_light, name); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_server_session_handle)); + SetReg32(system, 2, Convert<uint32_t>(out_client_session_handle)); +} + +static void SvcWrap_AcceptSession64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + Handle port{}; + + port = Convert<Handle>(GetReg32(system, 1)); + + ret = AcceptSession64From32(system, &out_handle, port); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_ReplyAndReceive64From32(Core::System& system) { + Result ret{}; + + int32_t out_index{}; + uint32_t handles{}; + int32_t num_handles{}; + Handle reply_target{}; + int64_t timeout_ns{}; + + handles = Convert<uint32_t>(GetReg32(system, 1)); + num_handles = Convert<int32_t>(GetReg32(system, 2)); + reply_target = Convert<Handle>(GetReg32(system, 3)); + std::array<uint32_t, 2> timeout_ns_gather{}; + timeout_ns_gather[0] = GetReg32(system, 0); + timeout_ns_gather[1] = GetReg32(system, 4); + timeout_ns = Convert<int64_t>(timeout_ns_gather); + + ret = ReplyAndReceive64From32(system, &out_index, handles, num_handles, reply_target, timeout_ns); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_index)); +} + +static void SvcWrap_ReplyAndReceiveWithUserBuffer64From32(Core::System& system) { + Result ret{}; + + int32_t out_index{}; + uint32_t message_buffer{}; + uint32_t message_buffer_size{}; + uint32_t handles{}; + int32_t num_handles{}; + Handle reply_target{}; + int64_t timeout_ns{}; + + message_buffer = Convert<uint32_t>(GetReg32(system, 1)); + message_buffer_size = Convert<uint32_t>(GetReg32(system, 2)); + handles = Convert<uint32_t>(GetReg32(system, 3)); + num_handles = Convert<int32_t>(GetReg32(system, 0)); + reply_target = Convert<Handle>(GetReg32(system, 4)); + std::array<uint32_t, 2> timeout_ns_gather{}; + timeout_ns_gather[0] = GetReg32(system, 5); + timeout_ns_gather[1] = GetReg32(system, 6); + timeout_ns = Convert<int64_t>(timeout_ns_gather); + + ret = ReplyAndReceiveWithUserBuffer64From32(system, &out_index, message_buffer, message_buffer_size, handles, num_handles, reply_target, timeout_ns); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_index)); +} + +static void SvcWrap_CreateEvent64From32(Core::System& system) { + Result ret{}; + + Handle out_write_handle{}; + Handle out_read_handle{}; + + ret = CreateEvent64From32(system, &out_write_handle, &out_read_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_write_handle)); + SetReg32(system, 2, Convert<uint32_t>(out_read_handle)); +} + +static void SvcWrap_MapIoRegion64From32(Core::System& system) { + Result ret{}; + + Handle io_region{}; + uint32_t address{}; + uint32_t size{}; + MemoryPermission perm{}; + + io_region = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + perm = Convert<MemoryPermission>(GetReg32(system, 3)); + + ret = MapIoRegion64From32(system, io_region, address, size, perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapIoRegion64From32(Core::System& system) { + Result ret{}; + + Handle io_region{}; + uint32_t address{}; + uint32_t size{}; + + io_region = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + ret = UnmapIoRegion64From32(system, io_region, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapPhysicalMemoryUnsafe64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = MapPhysicalMemoryUnsafe64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapPhysicalMemoryUnsafe64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = UnmapPhysicalMemoryUnsafe64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SetUnsafeLimit64From32(Core::System& system) { + Result ret{}; + + uint32_t limit{}; + + limit = Convert<uint32_t>(GetReg32(system, 0)); + + ret = SetUnsafeLimit64From32(system, limit); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_CreateCodeMemory64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + ret = CreateCodeMemory64From32(system, &out_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_ControlCodeMemory64From32(Core::System& system) { + Result ret{}; + + Handle code_memory_handle{}; + CodeMemoryOperation operation{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission perm{}; + + code_memory_handle = Convert<Handle>(GetReg32(system, 0)); + operation = Convert<CodeMemoryOperation>(GetReg32(system, 1)); + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 2); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 4); + size_gather[1] = GetReg32(system, 5); + size = Convert<uint64_t>(size_gather); + perm = Convert<MemoryPermission>(GetReg32(system, 6)); + + ret = ControlCodeMemory64From32(system, code_memory_handle, operation, address, size, perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SleepSystem64From32(Core::System& system) { + SleepSystem64From32(system); +} + +static void SvcWrap_ReadWriteRegister64From32(Core::System& system) { + Result ret{}; + + uint32_t out_value{}; + uint64_t address{}; + uint32_t mask{}; + uint32_t value{}; + + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 2); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + mask = Convert<uint32_t>(GetReg32(system, 0)); + value = Convert<uint32_t>(GetReg32(system, 1)); + + ret = ReadWriteRegister64From32(system, &out_value, address, mask, value); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_value)); +} + +static void SvcWrap_SetProcessActivity64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + ProcessActivity process_activity{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + process_activity = Convert<ProcessActivity>(GetReg32(system, 1)); + + ret = SetProcessActivity64From32(system, process_handle, process_activity); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_CreateSharedMemory64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint32_t size{}; + MemoryPermission owner_perm{}; + MemoryPermission remote_perm{}; + + size = Convert<uint32_t>(GetReg32(system, 1)); + owner_perm = Convert<MemoryPermission>(GetReg32(system, 2)); + remote_perm = Convert<MemoryPermission>(GetReg32(system, 3)); + + ret = CreateSharedMemory64From32(system, &out_handle, size, owner_perm, remote_perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_MapTransferMemory64From32(Core::System& system) { + Result ret{}; + + Handle trmem_handle{}; + uint32_t address{}; + uint32_t size{}; + MemoryPermission owner_perm{}; + + trmem_handle = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + owner_perm = Convert<MemoryPermission>(GetReg32(system, 3)); + + ret = MapTransferMemory64From32(system, trmem_handle, address, size, owner_perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapTransferMemory64From32(Core::System& system) { + Result ret{}; + + Handle trmem_handle{}; + uint32_t address{}; + uint32_t size{}; + + trmem_handle = Convert<Handle>(GetReg32(system, 0)); + address = Convert<uint32_t>(GetReg32(system, 1)); + size = Convert<uint32_t>(GetReg32(system, 2)); + + ret = UnmapTransferMemory64From32(system, trmem_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_CreateInterruptEvent64From32(Core::System& system) { + Result ret{}; + + Handle out_read_handle{}; + int32_t interrupt_id{}; + InterruptType interrupt_type{}; + + interrupt_id = Convert<int32_t>(GetReg32(system, 1)); + interrupt_type = Convert<InterruptType>(GetReg32(system, 2)); + + ret = CreateInterruptEvent64From32(system, &out_read_handle, interrupt_id, interrupt_type); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_read_handle)); +} + +static void SvcWrap_QueryPhysicalAddress64From32(Core::System& system) { + Result ret{}; + + ilp32::PhysicalMemoryInfo out_info{}; + uint32_t address{}; + + address = Convert<uint32_t>(GetReg32(system, 1)); + + ret = QueryPhysicalAddress64From32(system, &out_info, address); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_info_scatter = Convert<std::array<uint32_t, 4>>(out_info); + SetReg32(system, 1, out_info_scatter[0]); + SetReg32(system, 2, out_info_scatter[1]); + SetReg32(system, 3, out_info_scatter[2]); + SetReg32(system, 4, out_info_scatter[3]); +} + +static void SvcWrap_QueryIoMapping64From32(Core::System& system) { + Result ret{}; + + uintptr_t out_address{}; + uintptr_t out_size{}; + uint64_t physical_address{}; + uint32_t size{}; + + std::array<uint32_t, 2> physical_address_gather{}; + physical_address_gather[0] = GetReg32(system, 2); + physical_address_gather[1] = GetReg32(system, 3); + physical_address = Convert<uint64_t>(physical_address_gather); + size = Convert<uint32_t>(GetReg32(system, 0)); + + ret = QueryIoMapping64From32(system, &out_address, &out_size, physical_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_address)); + SetReg32(system, 2, Convert<uint32_t>(out_size)); +} + +static void SvcWrap_CreateDeviceAddressSpace64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t das_address{}; + uint64_t das_size{}; + + std::array<uint32_t, 2> das_address_gather{}; + das_address_gather[0] = GetReg32(system, 2); + das_address_gather[1] = GetReg32(system, 3); + das_address = Convert<uint64_t>(das_address_gather); + std::array<uint32_t, 2> das_size_gather{}; + das_size_gather[0] = GetReg32(system, 0); + das_size_gather[1] = GetReg32(system, 1); + das_size = Convert<uint64_t>(das_size_gather); + + ret = CreateDeviceAddressSpace64From32(system, &out_handle, das_address, das_size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_AttachDeviceAddressSpace64From32(Core::System& system) { + Result ret{}; + + DeviceName device_name{}; + Handle das_handle{}; + + device_name = Convert<DeviceName>(GetReg32(system, 0)); + das_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = AttachDeviceAddressSpace64From32(system, device_name, das_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_DetachDeviceAddressSpace64From32(Core::System& system) { + Result ret{}; + + DeviceName device_name{}; + Handle das_handle{}; + + device_name = Convert<DeviceName>(GetReg32(system, 0)); + das_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = DetachDeviceAddressSpace64From32(system, device_name, das_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapDeviceAddressSpaceByForce64From32(Core::System& system) { + Result ret{}; + + Handle das_handle{}; + Handle process_handle{}; + uint64_t process_address{}; + uint32_t size{}; + uint64_t device_address{}; + uint32_t option{}; + + das_handle = Convert<Handle>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> process_address_gather{}; + process_address_gather[0] = GetReg32(system, 2); + process_address_gather[1] = GetReg32(system, 3); + process_address = Convert<uint64_t>(process_address_gather); + size = Convert<uint32_t>(GetReg32(system, 4)); + std::array<uint32_t, 2> device_address_gather{}; + device_address_gather[0] = GetReg32(system, 5); + device_address_gather[1] = GetReg32(system, 6); + device_address = Convert<uint64_t>(device_address_gather); + option = Convert<uint32_t>(GetReg32(system, 7)); + + ret = MapDeviceAddressSpaceByForce64From32(system, das_handle, process_handle, process_address, size, device_address, option); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapDeviceAddressSpaceAligned64From32(Core::System& system) { + Result ret{}; + + Handle das_handle{}; + Handle process_handle{}; + uint64_t process_address{}; + uint32_t size{}; + uint64_t device_address{}; + uint32_t option{}; + + das_handle = Convert<Handle>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> process_address_gather{}; + process_address_gather[0] = GetReg32(system, 2); + process_address_gather[1] = GetReg32(system, 3); + process_address = Convert<uint64_t>(process_address_gather); + size = Convert<uint32_t>(GetReg32(system, 4)); + std::array<uint32_t, 2> device_address_gather{}; + device_address_gather[0] = GetReg32(system, 5); + device_address_gather[1] = GetReg32(system, 6); + device_address = Convert<uint64_t>(device_address_gather); + option = Convert<uint32_t>(GetReg32(system, 7)); + + ret = MapDeviceAddressSpaceAligned64From32(system, das_handle, process_handle, process_address, size, device_address, option); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapDeviceAddressSpace64From32(Core::System& system) { + Result ret{}; + + Handle das_handle{}; + Handle process_handle{}; + uint64_t process_address{}; + uint32_t size{}; + uint64_t device_address{}; + + das_handle = Convert<Handle>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> process_address_gather{}; + process_address_gather[0] = GetReg32(system, 2); + process_address_gather[1] = GetReg32(system, 3); + process_address = Convert<uint64_t>(process_address_gather); + size = Convert<uint32_t>(GetReg32(system, 4)); + std::array<uint32_t, 2> device_address_gather{}; + device_address_gather[0] = GetReg32(system, 5); + device_address_gather[1] = GetReg32(system, 6); + device_address = Convert<uint64_t>(device_address_gather); + + ret = UnmapDeviceAddressSpace64From32(system, das_handle, process_handle, process_address, size, device_address); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_InvalidateProcessDataCache64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 2); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 1); + size_gather[1] = GetReg32(system, 4); + size = Convert<uint64_t>(size_gather); + + ret = InvalidateProcessDataCache64From32(system, process_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_StoreProcessDataCache64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 2); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 1); + size_gather[1] = GetReg32(system, 4); + size = Convert<uint64_t>(size_gather); + + ret = StoreProcessDataCache64From32(system, process_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_FlushProcessDataCache64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 2); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 1); + size_gather[1] = GetReg32(system, 4); + size = Convert<uint64_t>(size_gather); + + ret = FlushProcessDataCache64From32(system, process_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_DebugActiveProcess64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t process_id{}; + + std::array<uint32_t, 2> process_id_gather{}; + process_id_gather[0] = GetReg32(system, 2); + process_id_gather[1] = GetReg32(system, 3); + process_id = Convert<uint64_t>(process_id_gather); + + ret = DebugActiveProcess64From32(system, &out_handle, process_id); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_BreakDebugProcess64From32(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + + debug_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = BreakDebugProcess64From32(system, debug_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_TerminateDebugProcess64From32(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + + debug_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = TerminateDebugProcess64From32(system, debug_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetDebugEvent64From32(Core::System& system) { + Result ret{}; + + uint32_t out_info{}; + Handle debug_handle{}; + + out_info = Convert<uint32_t>(GetReg32(system, 0)); + debug_handle = Convert<Handle>(GetReg32(system, 1)); + + ret = GetDebugEvent64From32(system, out_info, debug_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_ContinueDebugEvent64From32(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + uint32_t flags{}; + uint32_t thread_ids{}; + int32_t num_thread_ids{}; + + debug_handle = Convert<Handle>(GetReg32(system, 0)); + flags = Convert<uint32_t>(GetReg32(system, 1)); + thread_ids = Convert<uint32_t>(GetReg32(system, 2)); + num_thread_ids = Convert<int32_t>(GetReg32(system, 3)); + + ret = ContinueDebugEvent64From32(system, debug_handle, flags, thread_ids, num_thread_ids); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetProcessList64From32(Core::System& system) { + Result ret{}; + + int32_t out_num_processes{}; + uint32_t out_process_ids{}; + int32_t max_out_count{}; + + out_process_ids = Convert<uint32_t>(GetReg32(system, 1)); + max_out_count = Convert<int32_t>(GetReg32(system, 2)); + + ret = GetProcessList64From32(system, &out_num_processes, out_process_ids, max_out_count); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_num_processes)); +} + +static void SvcWrap_GetThreadList64From32(Core::System& system) { + Result ret{}; + + int32_t out_num_threads{}; + uint32_t out_thread_ids{}; + int32_t max_out_count{}; + Handle debug_handle{}; + + out_thread_ids = Convert<uint32_t>(GetReg32(system, 1)); + max_out_count = Convert<int32_t>(GetReg32(system, 2)); + debug_handle = Convert<Handle>(GetReg32(system, 3)); + + ret = GetThreadList64From32(system, &out_num_threads, out_thread_ids, max_out_count, debug_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_num_threads)); +} + +static void SvcWrap_GetDebugThreadContext64From32(Core::System& system) { + Result ret{}; + + uint32_t out_context{}; + Handle debug_handle{}; + uint64_t thread_id{}; + uint32_t context_flags{}; + + out_context = Convert<uint32_t>(GetReg32(system, 0)); + debug_handle = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> thread_id_gather{}; + thread_id_gather[0] = GetReg32(system, 2); + thread_id_gather[1] = GetReg32(system, 3); + thread_id = Convert<uint64_t>(thread_id_gather); + context_flags = Convert<uint32_t>(GetReg32(system, 4)); + + ret = GetDebugThreadContext64From32(system, out_context, debug_handle, thread_id, context_flags); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SetDebugThreadContext64From32(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + uint64_t thread_id{}; + uint32_t context{}; + uint32_t context_flags{}; + + debug_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> thread_id_gather{}; + thread_id_gather[0] = GetReg32(system, 2); + thread_id_gather[1] = GetReg32(system, 3); + thread_id = Convert<uint64_t>(thread_id_gather); + context = Convert<uint32_t>(GetReg32(system, 1)); + context_flags = Convert<uint32_t>(GetReg32(system, 4)); + + ret = SetDebugThreadContext64From32(system, debug_handle, thread_id, context, context_flags); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_QueryDebugProcessMemory64From32(Core::System& system) { + Result ret{}; + + PageInfo out_page_info{}; + uint32_t out_memory_info{}; + Handle process_handle{}; + uint32_t address{}; + + out_memory_info = Convert<uint32_t>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 2)); + address = Convert<uint32_t>(GetReg32(system, 3)); + + ret = QueryDebugProcessMemory64From32(system, out_memory_info, &out_page_info, process_handle, address); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_page_info)); +} + +static void SvcWrap_ReadDebugProcessMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t buffer{}; + Handle debug_handle{}; + uint32_t address{}; + uint32_t size{}; + + buffer = Convert<uint32_t>(GetReg32(system, 0)); + debug_handle = Convert<Handle>(GetReg32(system, 1)); + address = Convert<uint32_t>(GetReg32(system, 2)); + size = Convert<uint32_t>(GetReg32(system, 3)); + + ret = ReadDebugProcessMemory64From32(system, buffer, debug_handle, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_WriteDebugProcessMemory64From32(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + uint32_t buffer{}; + uint32_t address{}; + uint32_t size{}; + + debug_handle = Convert<Handle>(GetReg32(system, 0)); + buffer = Convert<uint32_t>(GetReg32(system, 1)); + address = Convert<uint32_t>(GetReg32(system, 2)); + size = Convert<uint32_t>(GetReg32(system, 3)); + + ret = WriteDebugProcessMemory64From32(system, debug_handle, buffer, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SetHardwareBreakPoint64From32(Core::System& system) { + Result ret{}; + + HardwareBreakPointRegisterName name{}; + uint64_t flags{}; + uint64_t value{}; + + name = Convert<HardwareBreakPointRegisterName>(GetReg32(system, 0)); + std::array<uint32_t, 2> flags_gather{}; + flags_gather[0] = GetReg32(system, 2); + flags_gather[1] = GetReg32(system, 3); + flags = Convert<uint64_t>(flags_gather); + std::array<uint32_t, 2> value_gather{}; + value_gather[0] = GetReg32(system, 1); + value_gather[1] = GetReg32(system, 4); + value = Convert<uint64_t>(value_gather); + + ret = SetHardwareBreakPoint64From32(system, name, flags, value); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetDebugThreadParam64From32(Core::System& system) { + Result ret{}; + + uint64_t out_64{}; + uint32_t out_32{}; + Handle debug_handle{}; + uint64_t thread_id{}; + DebugThreadParam param{}; + + debug_handle = Convert<Handle>(GetReg32(system, 2)); + std::array<uint32_t, 2> thread_id_gather{}; + thread_id_gather[0] = GetReg32(system, 0); + thread_id_gather[1] = GetReg32(system, 1); + thread_id = Convert<uint64_t>(thread_id_gather); + param = Convert<DebugThreadParam>(GetReg32(system, 3)); + + ret = GetDebugThreadParam64From32(system, &out_64, &out_32, debug_handle, thread_id, param); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_64_scatter = Convert<std::array<uint32_t, 2>>(out_64); + SetReg32(system, 1, out_64_scatter[0]); + SetReg32(system, 2, out_64_scatter[1]); + SetReg32(system, 3, Convert<uint32_t>(out_32)); +} + +static void SvcWrap_GetSystemInfo64From32(Core::System& system) { + Result ret{}; + + uint64_t out{}; + SystemInfoType info_type{}; + Handle handle{}; + uint64_t info_subtype{}; + + info_type = Convert<SystemInfoType>(GetReg32(system, 1)); + handle = Convert<Handle>(GetReg32(system, 2)); + std::array<uint32_t, 2> info_subtype_gather{}; + info_subtype_gather[0] = GetReg32(system, 0); + info_subtype_gather[1] = GetReg32(system, 3); + info_subtype = Convert<uint64_t>(info_subtype_gather); + + ret = GetSystemInfo64From32(system, &out, info_type, handle, info_subtype); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_scatter = Convert<std::array<uint32_t, 2>>(out); + SetReg32(system, 1, out_scatter[0]); + SetReg32(system, 2, out_scatter[1]); +} + +static void SvcWrap_CreatePort64From32(Core::System& system) { + Result ret{}; + + Handle out_server_handle{}; + Handle out_client_handle{}; + int32_t max_sessions{}; + bool is_light{}; + uint32_t name{}; + + max_sessions = Convert<int32_t>(GetReg32(system, 2)); + is_light = Convert<bool>(GetReg32(system, 3)); + name = Convert<uint32_t>(GetReg32(system, 0)); + + ret = CreatePort64From32(system, &out_server_handle, &out_client_handle, max_sessions, is_light, name); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_server_handle)); + SetReg32(system, 2, Convert<uint32_t>(out_client_handle)); +} + +static void SvcWrap_ManageNamedPort64From32(Core::System& system) { + Result ret{}; + + Handle out_server_handle{}; + uint32_t name{}; + int32_t max_sessions{}; + + name = Convert<uint32_t>(GetReg32(system, 1)); + max_sessions = Convert<int32_t>(GetReg32(system, 2)); + + ret = ManageNamedPort64From32(system, &out_server_handle, name, max_sessions); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_server_handle)); +} + +static void SvcWrap_ConnectToPort64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + Handle port{}; + + port = Convert<Handle>(GetReg32(system, 1)); + + ret = ConnectToPort64From32(system, &out_handle, port); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_SetProcessMemoryPermission64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission perm{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 2); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 1); + size_gather[1] = GetReg32(system, 4); + size = Convert<uint64_t>(size_gather); + perm = Convert<MemoryPermission>(GetReg32(system, 5)); + + ret = SetProcessMemoryPermission64From32(system, process_handle, address, size, perm); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapProcessMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t dst_address{}; + Handle process_handle{}; + uint64_t src_address{}; + uint32_t size{}; + + dst_address = Convert<uint32_t>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> src_address_gather{}; + src_address_gather[0] = GetReg32(system, 2); + src_address_gather[1] = GetReg32(system, 3); + src_address = Convert<uint64_t>(src_address_gather); + size = Convert<uint32_t>(GetReg32(system, 4)); + + ret = MapProcessMemory64From32(system, dst_address, process_handle, src_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapProcessMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t dst_address{}; + Handle process_handle{}; + uint64_t src_address{}; + uint32_t size{}; + + dst_address = Convert<uint32_t>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 1)); + std::array<uint32_t, 2> src_address_gather{}; + src_address_gather[0] = GetReg32(system, 2); + src_address_gather[1] = GetReg32(system, 3); + src_address = Convert<uint64_t>(src_address_gather); + size = Convert<uint32_t>(GetReg32(system, 4)); + + ret = UnmapProcessMemory64From32(system, dst_address, process_handle, src_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_QueryProcessMemory64From32(Core::System& system) { + Result ret{}; + + PageInfo out_page_info{}; + uint32_t out_memory_info{}; + Handle process_handle{}; + uint64_t address{}; + + out_memory_info = Convert<uint32_t>(GetReg32(system, 0)); + process_handle = Convert<Handle>(GetReg32(system, 2)); + std::array<uint32_t, 2> address_gather{}; + address_gather[0] = GetReg32(system, 1); + address_gather[1] = GetReg32(system, 3); + address = Convert<uint64_t>(address_gather); + + ret = QueryProcessMemory64From32(system, out_memory_info, &out_page_info, process_handle, address); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_page_info)); +} + +static void SvcWrap_MapProcessCodeMemory64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t dst_address{}; + uint64_t src_address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> dst_address_gather{}; + dst_address_gather[0] = GetReg32(system, 2); + dst_address_gather[1] = GetReg32(system, 3); + dst_address = Convert<uint64_t>(dst_address_gather); + std::array<uint32_t, 2> src_address_gather{}; + src_address_gather[0] = GetReg32(system, 1); + src_address_gather[1] = GetReg32(system, 4); + src_address = Convert<uint64_t>(src_address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 5); + size_gather[1] = GetReg32(system, 6); + size = Convert<uint64_t>(size_gather); + + ret = MapProcessCodeMemory64From32(system, process_handle, dst_address, src_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapProcessCodeMemory64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t dst_address{}; + uint64_t src_address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + std::array<uint32_t, 2> dst_address_gather{}; + dst_address_gather[0] = GetReg32(system, 2); + dst_address_gather[1] = GetReg32(system, 3); + dst_address = Convert<uint64_t>(dst_address_gather); + std::array<uint32_t, 2> src_address_gather{}; + src_address_gather[0] = GetReg32(system, 1); + src_address_gather[1] = GetReg32(system, 4); + src_address = Convert<uint64_t>(src_address_gather); + std::array<uint32_t, 2> size_gather{}; + size_gather[0] = GetReg32(system, 5); + size_gather[1] = GetReg32(system, 6); + size = Convert<uint64_t>(size_gather); + + ret = UnmapProcessCodeMemory64From32(system, process_handle, dst_address, src_address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_CreateProcess64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint32_t parameters{}; + uint32_t caps{}; + int32_t num_caps{}; + + parameters = Convert<uint32_t>(GetReg32(system, 1)); + caps = Convert<uint32_t>(GetReg32(system, 2)); + num_caps = Convert<int32_t>(GetReg32(system, 3)); + + ret = CreateProcess64From32(system, &out_handle, parameters, caps, num_caps); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_StartProcess64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + int32_t priority{}; + int32_t core_id{}; + uint64_t main_thread_stack_size{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + priority = Convert<int32_t>(GetReg32(system, 1)); + core_id = Convert<int32_t>(GetReg32(system, 2)); + std::array<uint32_t, 2> main_thread_stack_size_gather{}; + main_thread_stack_size_gather[0] = GetReg32(system, 3); + main_thread_stack_size_gather[1] = GetReg32(system, 4); + main_thread_stack_size = Convert<uint64_t>(main_thread_stack_size_gather); + + ret = StartProcess64From32(system, process_handle, priority, core_id, main_thread_stack_size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_TerminateProcess64From32(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + + process_handle = Convert<Handle>(GetReg32(system, 0)); + + ret = TerminateProcess64From32(system, process_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_GetProcessInfo64From32(Core::System& system) { + Result ret{}; + + int64_t out_info{}; + Handle process_handle{}; + ProcessInfoType info_type{}; + + process_handle = Convert<Handle>(GetReg32(system, 1)); + info_type = Convert<ProcessInfoType>(GetReg32(system, 2)); + + ret = GetProcessInfo64From32(system, &out_info, process_handle, info_type); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + auto out_info_scatter = Convert<std::array<uint32_t, 2>>(out_info); + SetReg32(system, 1, out_info_scatter[0]); + SetReg32(system, 2, out_info_scatter[1]); +} + +static void SvcWrap_CreateResourceLimit64From32(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + + ret = CreateResourceLimit64From32(system, &out_handle); + + SetReg32(system, 0, Convert<uint32_t>(ret)); + SetReg32(system, 1, Convert<uint32_t>(out_handle)); +} + +static void SvcWrap_SetResourceLimitLimitValue64From32(Core::System& system) { + Result ret{}; + + Handle resource_limit_handle{}; + LimitableResource which{}; + int64_t limit_value{}; + + resource_limit_handle = Convert<Handle>(GetReg32(system, 0)); + which = Convert<LimitableResource>(GetReg32(system, 1)); + std::array<uint32_t, 2> limit_value_gather{}; + limit_value_gather[0] = GetReg32(system, 2); + limit_value_gather[1] = GetReg32(system, 3); + limit_value = Convert<int64_t>(limit_value_gather); + + ret = SetResourceLimitLimitValue64From32(system, resource_limit_handle, which, limit_value); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_MapInsecureMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = MapInsecureMemory64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_UnmapInsecureMemory64From32(Core::System& system) { + Result ret{}; + + uint32_t address{}; + uint32_t size{}; + + address = Convert<uint32_t>(GetReg32(system, 0)); + size = Convert<uint32_t>(GetReg32(system, 1)); + + ret = UnmapInsecureMemory64From32(system, address, size); + + SetReg32(system, 0, Convert<uint32_t>(ret)); +} + +static void SvcWrap_SetHeapSize64(Core::System& system) { + Result ret{}; + + uintptr_t out_address{}; + uint64_t size{}; + + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = SetHeapSize64(system, &out_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_address)); +} + +static void SvcWrap_SetMemoryPermission64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + MemoryPermission perm{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + perm = Convert<MemoryPermission>(GetReg64(system, 2)); + + ret = SetMemoryPermission64(system, address, size, perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SetMemoryAttribute64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + uint32_t mask{}; + uint32_t attr{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + mask = Convert<uint32_t>(GetReg64(system, 2)); + attr = Convert<uint32_t>(GetReg64(system, 3)); + + ret = SetMemoryAttribute64(system, address, size, mask, attr); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapMemory64(Core::System& system) { + Result ret{}; + + uint64_t dst_address{}; + uint64_t src_address{}; + uint64_t size{}; + + dst_address = Convert<uint64_t>(GetReg64(system, 0)); + src_address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = MapMemory64(system, dst_address, src_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapMemory64(Core::System& system) { + Result ret{}; + + uint64_t dst_address{}; + uint64_t src_address{}; + uint64_t size{}; + + dst_address = Convert<uint64_t>(GetReg64(system, 0)); + src_address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = UnmapMemory64(system, dst_address, src_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_QueryMemory64(Core::System& system) { + Result ret{}; + + PageInfo out_page_info{}; + uint64_t out_memory_info{}; + uint64_t address{}; + + out_memory_info = Convert<uint64_t>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 2)); + + ret = QueryMemory64(system, out_memory_info, &out_page_info, address); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_page_info)); +} + +static void SvcWrap_ExitProcess64(Core::System& system) { + ExitProcess64(system); +} + +static void SvcWrap_CreateThread64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t func{}; + uint64_t arg{}; + uint64_t stack_bottom{}; + int32_t priority{}; + int32_t core_id{}; + + func = Convert<uint64_t>(GetReg64(system, 1)); + arg = Convert<uint64_t>(GetReg64(system, 2)); + stack_bottom = Convert<uint64_t>(GetReg64(system, 3)); + priority = Convert<int32_t>(GetReg64(system, 4)); + core_id = Convert<int32_t>(GetReg64(system, 5)); + + ret = CreateThread64(system, &out_handle, func, arg, stack_bottom, priority, core_id); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_StartThread64(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = StartThread64(system, thread_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ExitThread64(Core::System& system) { + ExitThread64(system); +} + +static void SvcWrap_SleepThread64(Core::System& system) { + int64_t ns{}; + + ns = Convert<int64_t>(GetReg64(system, 0)); + + SleepThread64(system, ns); +} + +static void SvcWrap_GetThreadPriority64(Core::System& system) { + Result ret{}; + + int32_t out_priority{}; + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = GetThreadPriority64(system, &out_priority, thread_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_priority)); +} + +static void SvcWrap_SetThreadPriority64(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + int32_t priority{}; + + thread_handle = Convert<Handle>(GetReg64(system, 0)); + priority = Convert<int32_t>(GetReg64(system, 1)); + + ret = SetThreadPriority64(system, thread_handle, priority); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetThreadCoreMask64(Core::System& system) { + Result ret{}; + + int32_t out_core_id{}; + uint64_t out_affinity_mask{}; + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg64(system, 2)); + + ret = GetThreadCoreMask64(system, &out_core_id, &out_affinity_mask, thread_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_core_id)); + SetReg64(system, 2, Convert<uint64_t>(out_affinity_mask)); +} + +static void SvcWrap_SetThreadCoreMask64(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + int32_t core_id{}; + uint64_t affinity_mask{}; + + thread_handle = Convert<Handle>(GetReg64(system, 0)); + core_id = Convert<int32_t>(GetReg64(system, 1)); + affinity_mask = Convert<uint64_t>(GetReg64(system, 2)); + + ret = SetThreadCoreMask64(system, thread_handle, core_id, affinity_mask); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetCurrentProcessorNumber64(Core::System& system) { + int32_t ret{}; + + ret = GetCurrentProcessorNumber64(system); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SignalEvent64(Core::System& system) { + Result ret{}; + + Handle event_handle{}; + + event_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = SignalEvent64(system, event_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ClearEvent64(Core::System& system) { + Result ret{}; + + Handle event_handle{}; + + event_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = ClearEvent64(system, event_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapSharedMemory64(Core::System& system) { + Result ret{}; + + Handle shmem_handle{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission map_perm{}; + + shmem_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + map_perm = Convert<MemoryPermission>(GetReg64(system, 3)); + + ret = MapSharedMemory64(system, shmem_handle, address, size, map_perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapSharedMemory64(Core::System& system) { + Result ret{}; + + Handle shmem_handle{}; + uint64_t address{}; + uint64_t size{}; + + shmem_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = UnmapSharedMemory64(system, shmem_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_CreateTransferMemory64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission map_perm{}; + + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + map_perm = Convert<MemoryPermission>(GetReg64(system, 3)); + + ret = CreateTransferMemory64(system, &out_handle, address, size, map_perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_CloseHandle64(Core::System& system) { + Result ret{}; + + Handle handle{}; + + handle = Convert<Handle>(GetReg64(system, 0)); + + ret = CloseHandle64(system, handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ResetSignal64(Core::System& system) { + Result ret{}; + + Handle handle{}; + + handle = Convert<Handle>(GetReg64(system, 0)); + + ret = ResetSignal64(system, handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_WaitSynchronization64(Core::System& system) { + Result ret{}; + + int32_t out_index{}; + uint64_t handles{}; + int32_t num_handles{}; + int64_t timeout_ns{}; + + handles = Convert<uint64_t>(GetReg64(system, 1)); + num_handles = Convert<int32_t>(GetReg64(system, 2)); + timeout_ns = Convert<int64_t>(GetReg64(system, 3)); + + ret = WaitSynchronization64(system, &out_index, handles, num_handles, timeout_ns); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_index)); +} + +static void SvcWrap_CancelSynchronization64(Core::System& system) { + Result ret{}; + + Handle handle{}; + + handle = Convert<Handle>(GetReg64(system, 0)); + + ret = CancelSynchronization64(system, handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ArbitrateLock64(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + uint64_t address{}; + uint32_t tag{}; + + thread_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + tag = Convert<uint32_t>(GetReg64(system, 2)); + + ret = ArbitrateLock64(system, thread_handle, address, tag); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ArbitrateUnlock64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + + ret = ArbitrateUnlock64(system, address); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_WaitProcessWideKeyAtomic64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t cv_key{}; + uint32_t tag{}; + int64_t timeout_ns{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + cv_key = Convert<uint64_t>(GetReg64(system, 1)); + tag = Convert<uint32_t>(GetReg64(system, 2)); + timeout_ns = Convert<int64_t>(GetReg64(system, 3)); + + ret = WaitProcessWideKeyAtomic64(system, address, cv_key, tag, timeout_ns); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SignalProcessWideKey64(Core::System& system) { + uint64_t cv_key{}; + int32_t count{}; + + cv_key = Convert<uint64_t>(GetReg64(system, 0)); + count = Convert<int32_t>(GetReg64(system, 1)); + + SignalProcessWideKey64(system, cv_key, count); +} + +static void SvcWrap_GetSystemTick64(Core::System& system) { + int64_t ret{}; + + ret = GetSystemTick64(system); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ConnectToNamedPort64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t name{}; + + name = Convert<uint64_t>(GetReg64(system, 1)); + + ret = ConnectToNamedPort64(system, &out_handle, name); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_SendSyncRequest64(Core::System& system) { + Result ret{}; + + Handle session_handle{}; + + session_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = SendSyncRequest64(system, session_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SendSyncRequestWithUserBuffer64(Core::System& system) { + Result ret{}; + + uint64_t message_buffer{}; + uint64_t message_buffer_size{}; + Handle session_handle{}; + + message_buffer = Convert<uint64_t>(GetReg64(system, 0)); + message_buffer_size = Convert<uint64_t>(GetReg64(system, 1)); + session_handle = Convert<Handle>(GetReg64(system, 2)); + + ret = SendSyncRequestWithUserBuffer64(system, message_buffer, message_buffer_size, session_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SendAsyncRequestWithUserBuffer64(Core::System& system) { + Result ret{}; + + Handle out_event_handle{}; + uint64_t message_buffer{}; + uint64_t message_buffer_size{}; + Handle session_handle{}; + + message_buffer = Convert<uint64_t>(GetReg64(system, 1)); + message_buffer_size = Convert<uint64_t>(GetReg64(system, 2)); + session_handle = Convert<Handle>(GetReg64(system, 3)); + + ret = SendAsyncRequestWithUserBuffer64(system, &out_event_handle, message_buffer, message_buffer_size, session_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_event_handle)); +} + +static void SvcWrap_GetProcessId64(Core::System& system) { + Result ret{}; + + uint64_t out_process_id{}; + Handle process_handle{}; + + process_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = GetProcessId64(system, &out_process_id, process_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_process_id)); +} + +static void SvcWrap_GetThreadId64(Core::System& system) { + Result ret{}; + + uint64_t out_thread_id{}; + Handle thread_handle{}; + + thread_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = GetThreadId64(system, &out_thread_id, thread_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_thread_id)); +} + +static void SvcWrap_Break64(Core::System& system) { + BreakReason break_reason{}; + uint64_t arg{}; + uint64_t size{}; + + break_reason = Convert<BreakReason>(GetReg64(system, 0)); + arg = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + Break64(system, break_reason, arg, size); +} + +static void SvcWrap_OutputDebugString64(Core::System& system) { + Result ret{}; + + uint64_t debug_str{}; + uint64_t len{}; + + debug_str = Convert<uint64_t>(GetReg64(system, 0)); + len = Convert<uint64_t>(GetReg64(system, 1)); + + ret = OutputDebugString64(system, debug_str, len); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ReturnFromException64(Core::System& system) { + Result result{}; + + result = Convert<Result>(GetReg64(system, 0)); + + ReturnFromException64(system, result); +} + +static void SvcWrap_GetInfo64(Core::System& system) { + Result ret{}; + + uint64_t out{}; + InfoType info_type{}; + Handle handle{}; + uint64_t info_subtype{}; + + info_type = Convert<InfoType>(GetReg64(system, 1)); + handle = Convert<Handle>(GetReg64(system, 2)); + info_subtype = Convert<uint64_t>(GetReg64(system, 3)); + + ret = GetInfo64(system, &out, info_type, handle, info_subtype); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out)); +} + +static void SvcWrap_FlushEntireDataCache64(Core::System& system) { + FlushEntireDataCache64(system); +} + +static void SvcWrap_FlushDataCache64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = FlushDataCache64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapPhysicalMemory64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = MapPhysicalMemory64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapPhysicalMemory64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = UnmapPhysicalMemory64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetDebugFutureThreadInfo64(Core::System& system) { + Result ret{}; + + lp64::LastThreadContext out_context{}; + uint64_t out_thread_id{}; + Handle debug_handle{}; + int64_t ns{}; + + debug_handle = Convert<Handle>(GetReg64(system, 2)); + ns = Convert<int64_t>(GetReg64(system, 3)); + + ret = GetDebugFutureThreadInfo64(system, &out_context, &out_thread_id, debug_handle, ns); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + auto out_context_scatter = Convert<std::array<uint64_t, 4>>(out_context); + SetReg64(system, 1, out_context_scatter[0]); + SetReg64(system, 2, out_context_scatter[1]); + SetReg64(system, 3, out_context_scatter[2]); + SetReg64(system, 4, out_context_scatter[3]); + SetReg64(system, 5, Convert<uint64_t>(out_thread_id)); +} + +static void SvcWrap_GetLastThreadInfo64(Core::System& system) { + Result ret{}; + + lp64::LastThreadContext out_context{}; + uintptr_t out_tls_address{}; + uint32_t out_flags{}; + + ret = GetLastThreadInfo64(system, &out_context, &out_tls_address, &out_flags); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + auto out_context_scatter = Convert<std::array<uint64_t, 4>>(out_context); + SetReg64(system, 1, out_context_scatter[0]); + SetReg64(system, 2, out_context_scatter[1]); + SetReg64(system, 3, out_context_scatter[2]); + SetReg64(system, 4, out_context_scatter[3]); + SetReg64(system, 5, Convert<uint64_t>(out_tls_address)); + SetReg64(system, 6, Convert<uint64_t>(out_flags)); +} + +static void SvcWrap_GetResourceLimitLimitValue64(Core::System& system) { + Result ret{}; + + int64_t out_limit_value{}; + Handle resource_limit_handle{}; + LimitableResource which{}; + + resource_limit_handle = Convert<Handle>(GetReg64(system, 1)); + which = Convert<LimitableResource>(GetReg64(system, 2)); + + ret = GetResourceLimitLimitValue64(system, &out_limit_value, resource_limit_handle, which); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_limit_value)); +} + +static void SvcWrap_GetResourceLimitCurrentValue64(Core::System& system) { + Result ret{}; + + int64_t out_current_value{}; + Handle resource_limit_handle{}; + LimitableResource which{}; + + resource_limit_handle = Convert<Handle>(GetReg64(system, 1)); + which = Convert<LimitableResource>(GetReg64(system, 2)); + + ret = GetResourceLimitCurrentValue64(system, &out_current_value, resource_limit_handle, which); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_current_value)); +} + +static void SvcWrap_SetThreadActivity64(Core::System& system) { + Result ret{}; + + Handle thread_handle{}; + ThreadActivity thread_activity{}; + + thread_handle = Convert<Handle>(GetReg64(system, 0)); + thread_activity = Convert<ThreadActivity>(GetReg64(system, 1)); + + ret = SetThreadActivity64(system, thread_handle, thread_activity); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetThreadContext364(Core::System& system) { + Result ret{}; + + uint64_t out_context{}; + Handle thread_handle{}; + + out_context = Convert<uint64_t>(GetReg64(system, 0)); + thread_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = GetThreadContext364(system, out_context, thread_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_WaitForAddress64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + ArbitrationType arb_type{}; + int32_t value{}; + int64_t timeout_ns{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + arb_type = Convert<ArbitrationType>(GetReg64(system, 1)); + value = Convert<int32_t>(GetReg64(system, 2)); + timeout_ns = Convert<int64_t>(GetReg64(system, 3)); + + ret = WaitForAddress64(system, address, arb_type, value, timeout_ns); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SignalToAddress64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + SignalType signal_type{}; + int32_t value{}; + int32_t count{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + signal_type = Convert<SignalType>(GetReg64(system, 1)); + value = Convert<int32_t>(GetReg64(system, 2)); + count = Convert<int32_t>(GetReg64(system, 3)); + + ret = SignalToAddress64(system, address, signal_type, value, count); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SynchronizePreemptionState64(Core::System& system) { + SynchronizePreemptionState64(system); +} + +static void SvcWrap_GetResourceLimitPeakValue64(Core::System& system) { + Result ret{}; + + int64_t out_peak_value{}; + Handle resource_limit_handle{}; + LimitableResource which{}; + + resource_limit_handle = Convert<Handle>(GetReg64(system, 1)); + which = Convert<LimitableResource>(GetReg64(system, 2)); + + ret = GetResourceLimitPeakValue64(system, &out_peak_value, resource_limit_handle, which); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_peak_value)); +} + +static void SvcWrap_CreateIoPool64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + IoPoolType which{}; + + which = Convert<IoPoolType>(GetReg64(system, 1)); + + ret = CreateIoPool64(system, &out_handle, which); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_CreateIoRegion64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + Handle io_pool{}; + uint64_t physical_address{}; + uint64_t size{}; + MemoryMapping mapping{}; + MemoryPermission perm{}; + + io_pool = Convert<Handle>(GetReg64(system, 1)); + physical_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + mapping = Convert<MemoryMapping>(GetReg64(system, 4)); + perm = Convert<MemoryPermission>(GetReg64(system, 5)); + + ret = CreateIoRegion64(system, &out_handle, io_pool, physical_address, size, mapping, perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_KernelDebug64(Core::System& system) { + KernelDebugType kern_debug_type{}; + uint64_t arg0{}; + uint64_t arg1{}; + uint64_t arg2{}; + + kern_debug_type = Convert<KernelDebugType>(GetReg64(system, 0)); + arg0 = Convert<uint64_t>(GetReg64(system, 1)); + arg1 = Convert<uint64_t>(GetReg64(system, 2)); + arg2 = Convert<uint64_t>(GetReg64(system, 3)); + + KernelDebug64(system, kern_debug_type, arg0, arg1, arg2); +} + +static void SvcWrap_ChangeKernelTraceState64(Core::System& system) { + KernelTraceState kern_trace_state{}; + + kern_trace_state = Convert<KernelTraceState>(GetReg64(system, 0)); + + ChangeKernelTraceState64(system, kern_trace_state); +} + +static void SvcWrap_CreateSession64(Core::System& system) { + Result ret{}; + + Handle out_server_session_handle{}; + Handle out_client_session_handle{}; + bool is_light{}; + uint64_t name{}; + + is_light = Convert<bool>(GetReg64(system, 2)); + name = Convert<uint64_t>(GetReg64(system, 3)); + + ret = CreateSession64(system, &out_server_session_handle, &out_client_session_handle, is_light, name); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_server_session_handle)); + SetReg64(system, 2, Convert<uint64_t>(out_client_session_handle)); +} + +static void SvcWrap_AcceptSession64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + Handle port{}; + + port = Convert<Handle>(GetReg64(system, 1)); + + ret = AcceptSession64(system, &out_handle, port); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_ReplyAndReceive64(Core::System& system) { + Result ret{}; + + int32_t out_index{}; + uint64_t handles{}; + int32_t num_handles{}; + Handle reply_target{}; + int64_t timeout_ns{}; + + handles = Convert<uint64_t>(GetReg64(system, 1)); + num_handles = Convert<int32_t>(GetReg64(system, 2)); + reply_target = Convert<Handle>(GetReg64(system, 3)); + timeout_ns = Convert<int64_t>(GetReg64(system, 4)); + + ret = ReplyAndReceive64(system, &out_index, handles, num_handles, reply_target, timeout_ns); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_index)); +} + +static void SvcWrap_ReplyAndReceiveWithUserBuffer64(Core::System& system) { + Result ret{}; + + int32_t out_index{}; + uint64_t message_buffer{}; + uint64_t message_buffer_size{}; + uint64_t handles{}; + int32_t num_handles{}; + Handle reply_target{}; + int64_t timeout_ns{}; + + message_buffer = Convert<uint64_t>(GetReg64(system, 1)); + message_buffer_size = Convert<uint64_t>(GetReg64(system, 2)); + handles = Convert<uint64_t>(GetReg64(system, 3)); + num_handles = Convert<int32_t>(GetReg64(system, 4)); + reply_target = Convert<Handle>(GetReg64(system, 5)); + timeout_ns = Convert<int64_t>(GetReg64(system, 6)); + + ret = ReplyAndReceiveWithUserBuffer64(system, &out_index, message_buffer, message_buffer_size, handles, num_handles, reply_target, timeout_ns); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_index)); +} + +static void SvcWrap_CreateEvent64(Core::System& system) { + Result ret{}; + + Handle out_write_handle{}; + Handle out_read_handle{}; + + ret = CreateEvent64(system, &out_write_handle, &out_read_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_write_handle)); + SetReg64(system, 2, Convert<uint64_t>(out_read_handle)); +} + +static void SvcWrap_MapIoRegion64(Core::System& system) { + Result ret{}; + + Handle io_region{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission perm{}; + + io_region = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + perm = Convert<MemoryPermission>(GetReg64(system, 3)); + + ret = MapIoRegion64(system, io_region, address, size, perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapIoRegion64(Core::System& system) { + Result ret{}; + + Handle io_region{}; + uint64_t address{}; + uint64_t size{}; + + io_region = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = UnmapIoRegion64(system, io_region, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapPhysicalMemoryUnsafe64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = MapPhysicalMemoryUnsafe64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapPhysicalMemoryUnsafe64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = UnmapPhysicalMemoryUnsafe64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SetUnsafeLimit64(Core::System& system) { + Result ret{}; + + uint64_t limit{}; + + limit = Convert<uint64_t>(GetReg64(system, 0)); + + ret = SetUnsafeLimit64(system, limit); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_CreateCodeMemory64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = CreateCodeMemory64(system, &out_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_ControlCodeMemory64(Core::System& system) { + Result ret{}; + + Handle code_memory_handle{}; + CodeMemoryOperation operation{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission perm{}; + + code_memory_handle = Convert<Handle>(GetReg64(system, 0)); + operation = Convert<CodeMemoryOperation>(GetReg64(system, 1)); + address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + perm = Convert<MemoryPermission>(GetReg64(system, 4)); + + ret = ControlCodeMemory64(system, code_memory_handle, operation, address, size, perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SleepSystem64(Core::System& system) { + SleepSystem64(system); +} + +static void SvcWrap_ReadWriteRegister64(Core::System& system) { + Result ret{}; + + uint32_t out_value{}; + uint64_t address{}; + uint32_t mask{}; + uint32_t value{}; + + address = Convert<uint64_t>(GetReg64(system, 1)); + mask = Convert<uint32_t>(GetReg64(system, 2)); + value = Convert<uint32_t>(GetReg64(system, 3)); + + ret = ReadWriteRegister64(system, &out_value, address, mask, value); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_value)); +} + +static void SvcWrap_SetProcessActivity64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + ProcessActivity process_activity{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + process_activity = Convert<ProcessActivity>(GetReg64(system, 1)); + + ret = SetProcessActivity64(system, process_handle, process_activity); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_CreateSharedMemory64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t size{}; + MemoryPermission owner_perm{}; + MemoryPermission remote_perm{}; + + size = Convert<uint64_t>(GetReg64(system, 1)); + owner_perm = Convert<MemoryPermission>(GetReg64(system, 2)); + remote_perm = Convert<MemoryPermission>(GetReg64(system, 3)); + + ret = CreateSharedMemory64(system, &out_handle, size, owner_perm, remote_perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_MapTransferMemory64(Core::System& system) { + Result ret{}; + + Handle trmem_handle{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission owner_perm{}; + + trmem_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + owner_perm = Convert<MemoryPermission>(GetReg64(system, 3)); + + ret = MapTransferMemory64(system, trmem_handle, address, size, owner_perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapTransferMemory64(Core::System& system) { + Result ret{}; + + Handle trmem_handle{}; + uint64_t address{}; + uint64_t size{}; + + trmem_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = UnmapTransferMemory64(system, trmem_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_CreateInterruptEvent64(Core::System& system) { + Result ret{}; + + Handle out_read_handle{}; + int32_t interrupt_id{}; + InterruptType interrupt_type{}; + + interrupt_id = Convert<int32_t>(GetReg64(system, 1)); + interrupt_type = Convert<InterruptType>(GetReg64(system, 2)); + + ret = CreateInterruptEvent64(system, &out_read_handle, interrupt_id, interrupt_type); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_read_handle)); +} + +static void SvcWrap_QueryPhysicalAddress64(Core::System& system) { + Result ret{}; + + lp64::PhysicalMemoryInfo out_info{}; + uint64_t address{}; + + address = Convert<uint64_t>(GetReg64(system, 1)); + + ret = QueryPhysicalAddress64(system, &out_info, address); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + auto out_info_scatter = Convert<std::array<uint64_t, 3>>(out_info); + SetReg64(system, 1, out_info_scatter[0]); + SetReg64(system, 2, out_info_scatter[1]); + SetReg64(system, 3, out_info_scatter[2]); +} + +static void SvcWrap_QueryIoMapping64(Core::System& system) { + Result ret{}; + + uintptr_t out_address{}; + uintptr_t out_size{}; + uint64_t physical_address{}; + uint64_t size{}; + + physical_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = QueryIoMapping64(system, &out_address, &out_size, physical_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_address)); + SetReg64(system, 2, Convert<uint64_t>(out_size)); +} + +static void SvcWrap_CreateDeviceAddressSpace64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t das_address{}; + uint64_t das_size{}; + + das_address = Convert<uint64_t>(GetReg64(system, 1)); + das_size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = CreateDeviceAddressSpace64(system, &out_handle, das_address, das_size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_AttachDeviceAddressSpace64(Core::System& system) { + Result ret{}; + + DeviceName device_name{}; + Handle das_handle{}; + + device_name = Convert<DeviceName>(GetReg64(system, 0)); + das_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = AttachDeviceAddressSpace64(system, device_name, das_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_DetachDeviceAddressSpace64(Core::System& system) { + Result ret{}; + + DeviceName device_name{}; + Handle das_handle{}; + + device_name = Convert<DeviceName>(GetReg64(system, 0)); + das_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = DetachDeviceAddressSpace64(system, device_name, das_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapDeviceAddressSpaceByForce64(Core::System& system) { + Result ret{}; + + Handle das_handle{}; + Handle process_handle{}; + uint64_t process_address{}; + uint64_t size{}; + uint64_t device_address{}; + uint32_t option{}; + + das_handle = Convert<Handle>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 1)); + process_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + device_address = Convert<uint64_t>(GetReg64(system, 4)); + option = Convert<uint32_t>(GetReg64(system, 5)); + + ret = MapDeviceAddressSpaceByForce64(system, das_handle, process_handle, process_address, size, device_address, option); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapDeviceAddressSpaceAligned64(Core::System& system) { + Result ret{}; + + Handle das_handle{}; + Handle process_handle{}; + uint64_t process_address{}; + uint64_t size{}; + uint64_t device_address{}; + uint32_t option{}; + + das_handle = Convert<Handle>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 1)); + process_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + device_address = Convert<uint64_t>(GetReg64(system, 4)); + option = Convert<uint32_t>(GetReg64(system, 5)); + + ret = MapDeviceAddressSpaceAligned64(system, das_handle, process_handle, process_address, size, device_address, option); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapDeviceAddressSpace64(Core::System& system) { + Result ret{}; + + Handle das_handle{}; + Handle process_handle{}; + uint64_t process_address{}; + uint64_t size{}; + uint64_t device_address{}; + + das_handle = Convert<Handle>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 1)); + process_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + device_address = Convert<uint64_t>(GetReg64(system, 4)); + + ret = UnmapDeviceAddressSpace64(system, das_handle, process_handle, process_address, size, device_address); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_InvalidateProcessDataCache64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = InvalidateProcessDataCache64(system, process_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_StoreProcessDataCache64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = StoreProcessDataCache64(system, process_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_FlushProcessDataCache64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + + ret = FlushProcessDataCache64(system, process_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_DebugActiveProcess64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t process_id{}; + + process_id = Convert<uint64_t>(GetReg64(system, 1)); + + ret = DebugActiveProcess64(system, &out_handle, process_id); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_BreakDebugProcess64(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + + debug_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = BreakDebugProcess64(system, debug_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_TerminateDebugProcess64(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + + debug_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = TerminateDebugProcess64(system, debug_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetDebugEvent64(Core::System& system) { + Result ret{}; + + uint64_t out_info{}; + Handle debug_handle{}; + + out_info = Convert<uint64_t>(GetReg64(system, 0)); + debug_handle = Convert<Handle>(GetReg64(system, 1)); + + ret = GetDebugEvent64(system, out_info, debug_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_ContinueDebugEvent64(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + uint32_t flags{}; + uint64_t thread_ids{}; + int32_t num_thread_ids{}; + + debug_handle = Convert<Handle>(GetReg64(system, 0)); + flags = Convert<uint32_t>(GetReg64(system, 1)); + thread_ids = Convert<uint64_t>(GetReg64(system, 2)); + num_thread_ids = Convert<int32_t>(GetReg64(system, 3)); + + ret = ContinueDebugEvent64(system, debug_handle, flags, thread_ids, num_thread_ids); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetProcessList64(Core::System& system) { + Result ret{}; + + int32_t out_num_processes{}; + uint64_t out_process_ids{}; + int32_t max_out_count{}; + + out_process_ids = Convert<uint64_t>(GetReg64(system, 1)); + max_out_count = Convert<int32_t>(GetReg64(system, 2)); + + ret = GetProcessList64(system, &out_num_processes, out_process_ids, max_out_count); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_num_processes)); +} + +static void SvcWrap_GetThreadList64(Core::System& system) { + Result ret{}; + + int32_t out_num_threads{}; + uint64_t out_thread_ids{}; + int32_t max_out_count{}; + Handle debug_handle{}; + + out_thread_ids = Convert<uint64_t>(GetReg64(system, 1)); + max_out_count = Convert<int32_t>(GetReg64(system, 2)); + debug_handle = Convert<Handle>(GetReg64(system, 3)); + + ret = GetThreadList64(system, &out_num_threads, out_thread_ids, max_out_count, debug_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_num_threads)); +} + +static void SvcWrap_GetDebugThreadContext64(Core::System& system) { + Result ret{}; + + uint64_t out_context{}; + Handle debug_handle{}; + uint64_t thread_id{}; + uint32_t context_flags{}; + + out_context = Convert<uint64_t>(GetReg64(system, 0)); + debug_handle = Convert<Handle>(GetReg64(system, 1)); + thread_id = Convert<uint64_t>(GetReg64(system, 2)); + context_flags = Convert<uint32_t>(GetReg64(system, 3)); + + ret = GetDebugThreadContext64(system, out_context, debug_handle, thread_id, context_flags); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SetDebugThreadContext64(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + uint64_t thread_id{}; + uint64_t context{}; + uint32_t context_flags{}; + + debug_handle = Convert<Handle>(GetReg64(system, 0)); + thread_id = Convert<uint64_t>(GetReg64(system, 1)); + context = Convert<uint64_t>(GetReg64(system, 2)); + context_flags = Convert<uint32_t>(GetReg64(system, 3)); + + ret = SetDebugThreadContext64(system, debug_handle, thread_id, context, context_flags); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_QueryDebugProcessMemory64(Core::System& system) { + Result ret{}; + + PageInfo out_page_info{}; + uint64_t out_memory_info{}; + Handle process_handle{}; + uint64_t address{}; + + out_memory_info = Convert<uint64_t>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 2)); + address = Convert<uint64_t>(GetReg64(system, 3)); + + ret = QueryDebugProcessMemory64(system, out_memory_info, &out_page_info, process_handle, address); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_page_info)); +} + +static void SvcWrap_ReadDebugProcessMemory64(Core::System& system) { + Result ret{}; + + uint64_t buffer{}; + Handle debug_handle{}; + uint64_t address{}; + uint64_t size{}; + + buffer = Convert<uint64_t>(GetReg64(system, 0)); + debug_handle = Convert<Handle>(GetReg64(system, 1)); + address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = ReadDebugProcessMemory64(system, buffer, debug_handle, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_WriteDebugProcessMemory64(Core::System& system) { + Result ret{}; + + Handle debug_handle{}; + uint64_t buffer{}; + uint64_t address{}; + uint64_t size{}; + + debug_handle = Convert<Handle>(GetReg64(system, 0)); + buffer = Convert<uint64_t>(GetReg64(system, 1)); + address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = WriteDebugProcessMemory64(system, debug_handle, buffer, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_SetHardwareBreakPoint64(Core::System& system) { + Result ret{}; + + HardwareBreakPointRegisterName name{}; + uint64_t flags{}; + uint64_t value{}; + + name = Convert<HardwareBreakPointRegisterName>(GetReg64(system, 0)); + flags = Convert<uint64_t>(GetReg64(system, 1)); + value = Convert<uint64_t>(GetReg64(system, 2)); + + ret = SetHardwareBreakPoint64(system, name, flags, value); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetDebugThreadParam64(Core::System& system) { + Result ret{}; + + uint64_t out_64{}; + uint32_t out_32{}; + Handle debug_handle{}; + uint64_t thread_id{}; + DebugThreadParam param{}; + + debug_handle = Convert<Handle>(GetReg64(system, 2)); + thread_id = Convert<uint64_t>(GetReg64(system, 3)); + param = Convert<DebugThreadParam>(GetReg64(system, 4)); + + ret = GetDebugThreadParam64(system, &out_64, &out_32, debug_handle, thread_id, param); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_64)); + SetReg64(system, 2, Convert<uint64_t>(out_32)); +} + +static void SvcWrap_GetSystemInfo64(Core::System& system) { + Result ret{}; + + uint64_t out{}; + SystemInfoType info_type{}; + Handle handle{}; + uint64_t info_subtype{}; + + info_type = Convert<SystemInfoType>(GetReg64(system, 1)); + handle = Convert<Handle>(GetReg64(system, 2)); + info_subtype = Convert<uint64_t>(GetReg64(system, 3)); + + ret = GetSystemInfo64(system, &out, info_type, handle, info_subtype); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out)); +} + +static void SvcWrap_CreatePort64(Core::System& system) { + Result ret{}; + + Handle out_server_handle{}; + Handle out_client_handle{}; + int32_t max_sessions{}; + bool is_light{}; + uint64_t name{}; + + max_sessions = Convert<int32_t>(GetReg64(system, 2)); + is_light = Convert<bool>(GetReg64(system, 3)); + name = Convert<uint64_t>(GetReg64(system, 4)); + + ret = CreatePort64(system, &out_server_handle, &out_client_handle, max_sessions, is_light, name); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_server_handle)); + SetReg64(system, 2, Convert<uint64_t>(out_client_handle)); +} + +static void SvcWrap_ManageNamedPort64(Core::System& system) { + Result ret{}; + + Handle out_server_handle{}; + uint64_t name{}; + int32_t max_sessions{}; + + name = Convert<uint64_t>(GetReg64(system, 1)); + max_sessions = Convert<int32_t>(GetReg64(system, 2)); + + ret = ManageNamedPort64(system, &out_server_handle, name, max_sessions); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_server_handle)); +} + +static void SvcWrap_ConnectToPort64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + Handle port{}; + + port = Convert<Handle>(GetReg64(system, 1)); + + ret = ConnectToPort64(system, &out_handle, port); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_SetProcessMemoryPermission64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t address{}; + uint64_t size{}; + MemoryPermission perm{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + address = Convert<uint64_t>(GetReg64(system, 1)); + size = Convert<uint64_t>(GetReg64(system, 2)); + perm = Convert<MemoryPermission>(GetReg64(system, 3)); + + ret = SetProcessMemoryPermission64(system, process_handle, address, size, perm); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapProcessMemory64(Core::System& system) { + Result ret{}; + + uint64_t dst_address{}; + Handle process_handle{}; + uint64_t src_address{}; + uint64_t size{}; + + dst_address = Convert<uint64_t>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 1)); + src_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = MapProcessMemory64(system, dst_address, process_handle, src_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapProcessMemory64(Core::System& system) { + Result ret{}; + + uint64_t dst_address{}; + Handle process_handle{}; + uint64_t src_address{}; + uint64_t size{}; + + dst_address = Convert<uint64_t>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 1)); + src_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = UnmapProcessMemory64(system, dst_address, process_handle, src_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_QueryProcessMemory64(Core::System& system) { + Result ret{}; + + PageInfo out_page_info{}; + uint64_t out_memory_info{}; + Handle process_handle{}; + uint64_t address{}; + + out_memory_info = Convert<uint64_t>(GetReg64(system, 0)); + process_handle = Convert<Handle>(GetReg64(system, 2)); + address = Convert<uint64_t>(GetReg64(system, 3)); + + ret = QueryProcessMemory64(system, out_memory_info, &out_page_info, process_handle, address); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_page_info)); +} + +static void SvcWrap_MapProcessCodeMemory64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t dst_address{}; + uint64_t src_address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + dst_address = Convert<uint64_t>(GetReg64(system, 1)); + src_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = MapProcessCodeMemory64(system, process_handle, dst_address, src_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapProcessCodeMemory64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + uint64_t dst_address{}; + uint64_t src_address{}; + uint64_t size{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + dst_address = Convert<uint64_t>(GetReg64(system, 1)); + src_address = Convert<uint64_t>(GetReg64(system, 2)); + size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = UnmapProcessCodeMemory64(system, process_handle, dst_address, src_address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_CreateProcess64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + uint64_t parameters{}; + uint64_t caps{}; + int32_t num_caps{}; + + parameters = Convert<uint64_t>(GetReg64(system, 1)); + caps = Convert<uint64_t>(GetReg64(system, 2)); + num_caps = Convert<int32_t>(GetReg64(system, 3)); + + ret = CreateProcess64(system, &out_handle, parameters, caps, num_caps); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_StartProcess64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + int32_t priority{}; + int32_t core_id{}; + uint64_t main_thread_stack_size{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + priority = Convert<int32_t>(GetReg64(system, 1)); + core_id = Convert<int32_t>(GetReg64(system, 2)); + main_thread_stack_size = Convert<uint64_t>(GetReg64(system, 3)); + + ret = StartProcess64(system, process_handle, priority, core_id, main_thread_stack_size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_TerminateProcess64(Core::System& system) { + Result ret{}; + + Handle process_handle{}; + + process_handle = Convert<Handle>(GetReg64(system, 0)); + + ret = TerminateProcess64(system, process_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_GetProcessInfo64(Core::System& system) { + Result ret{}; + + int64_t out_info{}; + Handle process_handle{}; + ProcessInfoType info_type{}; + + process_handle = Convert<Handle>(GetReg64(system, 1)); + info_type = Convert<ProcessInfoType>(GetReg64(system, 2)); + + ret = GetProcessInfo64(system, &out_info, process_handle, info_type); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_info)); +} + +static void SvcWrap_CreateResourceLimit64(Core::System& system) { + Result ret{}; + + Handle out_handle{}; + + ret = CreateResourceLimit64(system, &out_handle); + + SetReg64(system, 0, Convert<uint64_t>(ret)); + SetReg64(system, 1, Convert<uint64_t>(out_handle)); +} + +static void SvcWrap_SetResourceLimitLimitValue64(Core::System& system) { + Result ret{}; + + Handle resource_limit_handle{}; + LimitableResource which{}; + int64_t limit_value{}; + + resource_limit_handle = Convert<Handle>(GetReg64(system, 0)); + which = Convert<LimitableResource>(GetReg64(system, 1)); + limit_value = Convert<int64_t>(GetReg64(system, 2)); + + ret = SetResourceLimitLimitValue64(system, resource_limit_handle, which, limit_value); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_MapInsecureMemory64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = MapInsecureMemory64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void SvcWrap_UnmapInsecureMemory64(Core::System& system) { + Result ret{}; + + uint64_t address{}; + uint64_t size{}; + + address = Convert<uint64_t>(GetReg64(system, 0)); + size = Convert<uint64_t>(GetReg64(system, 1)); + + ret = UnmapInsecureMemory64(system, address, size); + + SetReg64(system, 0, Convert<uint64_t>(ret)); +} + +static void Call32(Core::System& system, u32 imm) { + switch (static_cast<SvcId>(imm)) { + case SvcId::SetHeapSize: + return SvcWrap_SetHeapSize64From32(system); + case SvcId::SetMemoryPermission: + return SvcWrap_SetMemoryPermission64From32(system); + case SvcId::SetMemoryAttribute: + return SvcWrap_SetMemoryAttribute64From32(system); + case SvcId::MapMemory: + return SvcWrap_MapMemory64From32(system); + case SvcId::UnmapMemory: + return SvcWrap_UnmapMemory64From32(system); + case SvcId::QueryMemory: + return SvcWrap_QueryMemory64From32(system); + case SvcId::ExitProcess: + return SvcWrap_ExitProcess64From32(system); + case SvcId::CreateThread: + return SvcWrap_CreateThread64From32(system); + case SvcId::StartThread: + return SvcWrap_StartThread64From32(system); + case SvcId::ExitThread: + return SvcWrap_ExitThread64From32(system); + case SvcId::SleepThread: + return SvcWrap_SleepThread64From32(system); + case SvcId::GetThreadPriority: + return SvcWrap_GetThreadPriority64From32(system); + case SvcId::SetThreadPriority: + return SvcWrap_SetThreadPriority64From32(system); + case SvcId::GetThreadCoreMask: + return SvcWrap_GetThreadCoreMask64From32(system); + case SvcId::SetThreadCoreMask: + return SvcWrap_SetThreadCoreMask64From32(system); + case SvcId::GetCurrentProcessorNumber: + return SvcWrap_GetCurrentProcessorNumber64From32(system); + case SvcId::SignalEvent: + return SvcWrap_SignalEvent64From32(system); + case SvcId::ClearEvent: + return SvcWrap_ClearEvent64From32(system); + case SvcId::MapSharedMemory: + return SvcWrap_MapSharedMemory64From32(system); + case SvcId::UnmapSharedMemory: + return SvcWrap_UnmapSharedMemory64From32(system); + case SvcId::CreateTransferMemory: + return SvcWrap_CreateTransferMemory64From32(system); + case SvcId::CloseHandle: + return SvcWrap_CloseHandle64From32(system); + case SvcId::ResetSignal: + return SvcWrap_ResetSignal64From32(system); + case SvcId::WaitSynchronization: + return SvcWrap_WaitSynchronization64From32(system); + case SvcId::CancelSynchronization: + return SvcWrap_CancelSynchronization64From32(system); + case SvcId::ArbitrateLock: + return SvcWrap_ArbitrateLock64From32(system); + case SvcId::ArbitrateUnlock: + return SvcWrap_ArbitrateUnlock64From32(system); + case SvcId::WaitProcessWideKeyAtomic: + return SvcWrap_WaitProcessWideKeyAtomic64From32(system); + case SvcId::SignalProcessWideKey: + return SvcWrap_SignalProcessWideKey64From32(system); + case SvcId::GetSystemTick: + return SvcWrap_GetSystemTick64From32(system); + case SvcId::ConnectToNamedPort: + return SvcWrap_ConnectToNamedPort64From32(system); + case SvcId::SendSyncRequestLight: + return SvcWrap_SendSyncRequestLight64From32(system); + case SvcId::SendSyncRequest: + return SvcWrap_SendSyncRequest64From32(system); + case SvcId::SendSyncRequestWithUserBuffer: + return SvcWrap_SendSyncRequestWithUserBuffer64From32(system); + case SvcId::SendAsyncRequestWithUserBuffer: + return SvcWrap_SendAsyncRequestWithUserBuffer64From32(system); + case SvcId::GetProcessId: + return SvcWrap_GetProcessId64From32(system); + case SvcId::GetThreadId: + return SvcWrap_GetThreadId64From32(system); + case SvcId::Break: + return SvcWrap_Break64From32(system); + case SvcId::OutputDebugString: + return SvcWrap_OutputDebugString64From32(system); + case SvcId::ReturnFromException: + return SvcWrap_ReturnFromException64From32(system); + case SvcId::GetInfo: + return SvcWrap_GetInfo64From32(system); + case SvcId::FlushEntireDataCache: + return SvcWrap_FlushEntireDataCache64From32(system); + case SvcId::FlushDataCache: + return SvcWrap_FlushDataCache64From32(system); + case SvcId::MapPhysicalMemory: + return SvcWrap_MapPhysicalMemory64From32(system); + case SvcId::UnmapPhysicalMemory: + return SvcWrap_UnmapPhysicalMemory64From32(system); + case SvcId::GetDebugFutureThreadInfo: + return SvcWrap_GetDebugFutureThreadInfo64From32(system); + case SvcId::GetLastThreadInfo: + return SvcWrap_GetLastThreadInfo64From32(system); + case SvcId::GetResourceLimitLimitValue: + return SvcWrap_GetResourceLimitLimitValue64From32(system); + case SvcId::GetResourceLimitCurrentValue: + return SvcWrap_GetResourceLimitCurrentValue64From32(system); + case SvcId::SetThreadActivity: + return SvcWrap_SetThreadActivity64From32(system); + case SvcId::GetThreadContext3: + return SvcWrap_GetThreadContext364From32(system); + case SvcId::WaitForAddress: + return SvcWrap_WaitForAddress64From32(system); + case SvcId::SignalToAddress: + return SvcWrap_SignalToAddress64From32(system); + case SvcId::SynchronizePreemptionState: + return SvcWrap_SynchronizePreemptionState64From32(system); + case SvcId::GetResourceLimitPeakValue: + return SvcWrap_GetResourceLimitPeakValue64From32(system); + case SvcId::CreateIoPool: + return SvcWrap_CreateIoPool64From32(system); + case SvcId::CreateIoRegion: + return SvcWrap_CreateIoRegion64From32(system); + case SvcId::KernelDebug: + return SvcWrap_KernelDebug64From32(system); + case SvcId::ChangeKernelTraceState: + return SvcWrap_ChangeKernelTraceState64From32(system); + case SvcId::CreateSession: + return SvcWrap_CreateSession64From32(system); + case SvcId::AcceptSession: + return SvcWrap_AcceptSession64From32(system); + case SvcId::ReplyAndReceiveLight: + return SvcWrap_ReplyAndReceiveLight64From32(system); + case SvcId::ReplyAndReceive: + return SvcWrap_ReplyAndReceive64From32(system); + case SvcId::ReplyAndReceiveWithUserBuffer: + return SvcWrap_ReplyAndReceiveWithUserBuffer64From32(system); + case SvcId::CreateEvent: + return SvcWrap_CreateEvent64From32(system); + case SvcId::MapIoRegion: + return SvcWrap_MapIoRegion64From32(system); + case SvcId::UnmapIoRegion: + return SvcWrap_UnmapIoRegion64From32(system); + case SvcId::MapPhysicalMemoryUnsafe: + return SvcWrap_MapPhysicalMemoryUnsafe64From32(system); + case SvcId::UnmapPhysicalMemoryUnsafe: + return SvcWrap_UnmapPhysicalMemoryUnsafe64From32(system); + case SvcId::SetUnsafeLimit: + return SvcWrap_SetUnsafeLimit64From32(system); + case SvcId::CreateCodeMemory: + return SvcWrap_CreateCodeMemory64From32(system); + case SvcId::ControlCodeMemory: + return SvcWrap_ControlCodeMemory64From32(system); + case SvcId::SleepSystem: + return SvcWrap_SleepSystem64From32(system); + case SvcId::ReadWriteRegister: + return SvcWrap_ReadWriteRegister64From32(system); + case SvcId::SetProcessActivity: + return SvcWrap_SetProcessActivity64From32(system); + case SvcId::CreateSharedMemory: + return SvcWrap_CreateSharedMemory64From32(system); + case SvcId::MapTransferMemory: + return SvcWrap_MapTransferMemory64From32(system); + case SvcId::UnmapTransferMemory: + return SvcWrap_UnmapTransferMemory64From32(system); + case SvcId::CreateInterruptEvent: + return SvcWrap_CreateInterruptEvent64From32(system); + case SvcId::QueryPhysicalAddress: + return SvcWrap_QueryPhysicalAddress64From32(system); + case SvcId::QueryIoMapping: + return SvcWrap_QueryIoMapping64From32(system); + case SvcId::CreateDeviceAddressSpace: + return SvcWrap_CreateDeviceAddressSpace64From32(system); + case SvcId::AttachDeviceAddressSpace: + return SvcWrap_AttachDeviceAddressSpace64From32(system); + case SvcId::DetachDeviceAddressSpace: + return SvcWrap_DetachDeviceAddressSpace64From32(system); + case SvcId::MapDeviceAddressSpaceByForce: + return SvcWrap_MapDeviceAddressSpaceByForce64From32(system); + case SvcId::MapDeviceAddressSpaceAligned: + return SvcWrap_MapDeviceAddressSpaceAligned64From32(system); + case SvcId::UnmapDeviceAddressSpace: + return SvcWrap_UnmapDeviceAddressSpace64From32(system); + case SvcId::InvalidateProcessDataCache: + return SvcWrap_InvalidateProcessDataCache64From32(system); + case SvcId::StoreProcessDataCache: + return SvcWrap_StoreProcessDataCache64From32(system); + case SvcId::FlushProcessDataCache: + return SvcWrap_FlushProcessDataCache64From32(system); + case SvcId::DebugActiveProcess: + return SvcWrap_DebugActiveProcess64From32(system); + case SvcId::BreakDebugProcess: + return SvcWrap_BreakDebugProcess64From32(system); + case SvcId::TerminateDebugProcess: + return SvcWrap_TerminateDebugProcess64From32(system); + case SvcId::GetDebugEvent: + return SvcWrap_GetDebugEvent64From32(system); + case SvcId::ContinueDebugEvent: + return SvcWrap_ContinueDebugEvent64From32(system); + case SvcId::GetProcessList: + return SvcWrap_GetProcessList64From32(system); + case SvcId::GetThreadList: + return SvcWrap_GetThreadList64From32(system); + case SvcId::GetDebugThreadContext: + return SvcWrap_GetDebugThreadContext64From32(system); + case SvcId::SetDebugThreadContext: + return SvcWrap_SetDebugThreadContext64From32(system); + case SvcId::QueryDebugProcessMemory: + return SvcWrap_QueryDebugProcessMemory64From32(system); + case SvcId::ReadDebugProcessMemory: + return SvcWrap_ReadDebugProcessMemory64From32(system); + case SvcId::WriteDebugProcessMemory: + return SvcWrap_WriteDebugProcessMemory64From32(system); + case SvcId::SetHardwareBreakPoint: + return SvcWrap_SetHardwareBreakPoint64From32(system); + case SvcId::GetDebugThreadParam: + return SvcWrap_GetDebugThreadParam64From32(system); + case SvcId::GetSystemInfo: + return SvcWrap_GetSystemInfo64From32(system); + case SvcId::CreatePort: + return SvcWrap_CreatePort64From32(system); + case SvcId::ManageNamedPort: + return SvcWrap_ManageNamedPort64From32(system); + case SvcId::ConnectToPort: + return SvcWrap_ConnectToPort64From32(system); + case SvcId::SetProcessMemoryPermission: + return SvcWrap_SetProcessMemoryPermission64From32(system); + case SvcId::MapProcessMemory: + return SvcWrap_MapProcessMemory64From32(system); + case SvcId::UnmapProcessMemory: + return SvcWrap_UnmapProcessMemory64From32(system); + case SvcId::QueryProcessMemory: + return SvcWrap_QueryProcessMemory64From32(system); + case SvcId::MapProcessCodeMemory: + return SvcWrap_MapProcessCodeMemory64From32(system); + case SvcId::UnmapProcessCodeMemory: + return SvcWrap_UnmapProcessCodeMemory64From32(system); + case SvcId::CreateProcess: + return SvcWrap_CreateProcess64From32(system); + case SvcId::StartProcess: + return SvcWrap_StartProcess64From32(system); + case SvcId::TerminateProcess: + return SvcWrap_TerminateProcess64From32(system); + case SvcId::GetProcessInfo: + return SvcWrap_GetProcessInfo64From32(system); + case SvcId::CreateResourceLimit: + return SvcWrap_CreateResourceLimit64From32(system); + case SvcId::SetResourceLimitLimitValue: + return SvcWrap_SetResourceLimitLimitValue64From32(system); + case SvcId::CallSecureMonitor: + return SvcWrap_CallSecureMonitor64From32(system); + case SvcId::MapInsecureMemory: + return SvcWrap_MapInsecureMemory64From32(system); + case SvcId::UnmapInsecureMemory: + return SvcWrap_UnmapInsecureMemory64From32(system); + default: + LOG_CRITICAL(Kernel_SVC, "Unknown SVC {:x}!", imm); + break; } - 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; +static void Call64(Core::System& system, u32 imm) { + switch (static_cast<SvcId>(imm)) { + case SvcId::SetHeapSize: + return SvcWrap_SetHeapSize64(system); + case SvcId::SetMemoryPermission: + return SvcWrap_SetMemoryPermission64(system); + case SvcId::SetMemoryAttribute: + return SvcWrap_SetMemoryAttribute64(system); + case SvcId::MapMemory: + return SvcWrap_MapMemory64(system); + case SvcId::UnmapMemory: + return SvcWrap_UnmapMemory64(system); + case SvcId::QueryMemory: + return SvcWrap_QueryMemory64(system); + case SvcId::ExitProcess: + return SvcWrap_ExitProcess64(system); + case SvcId::CreateThread: + return SvcWrap_CreateThread64(system); + case SvcId::StartThread: + return SvcWrap_StartThread64(system); + case SvcId::ExitThread: + return SvcWrap_ExitThread64(system); + case SvcId::SleepThread: + return SvcWrap_SleepThread64(system); + case SvcId::GetThreadPriority: + return SvcWrap_GetThreadPriority64(system); + case SvcId::SetThreadPriority: + return SvcWrap_SetThreadPriority64(system); + case SvcId::GetThreadCoreMask: + return SvcWrap_GetThreadCoreMask64(system); + case SvcId::SetThreadCoreMask: + return SvcWrap_SetThreadCoreMask64(system); + case SvcId::GetCurrentProcessorNumber: + return SvcWrap_GetCurrentProcessorNumber64(system); + case SvcId::SignalEvent: + return SvcWrap_SignalEvent64(system); + case SvcId::ClearEvent: + return SvcWrap_ClearEvent64(system); + case SvcId::MapSharedMemory: + return SvcWrap_MapSharedMemory64(system); + case SvcId::UnmapSharedMemory: + return SvcWrap_UnmapSharedMemory64(system); + case SvcId::CreateTransferMemory: + return SvcWrap_CreateTransferMemory64(system); + case SvcId::CloseHandle: + return SvcWrap_CloseHandle64(system); + case SvcId::ResetSignal: + return SvcWrap_ResetSignal64(system); + case SvcId::WaitSynchronization: + return SvcWrap_WaitSynchronization64(system); + case SvcId::CancelSynchronization: + return SvcWrap_CancelSynchronization64(system); + case SvcId::ArbitrateLock: + return SvcWrap_ArbitrateLock64(system); + case SvcId::ArbitrateUnlock: + return SvcWrap_ArbitrateUnlock64(system); + case SvcId::WaitProcessWideKeyAtomic: + return SvcWrap_WaitProcessWideKeyAtomic64(system); + case SvcId::SignalProcessWideKey: + return SvcWrap_SignalProcessWideKey64(system); + case SvcId::GetSystemTick: + return SvcWrap_GetSystemTick64(system); + case SvcId::ConnectToNamedPort: + return SvcWrap_ConnectToNamedPort64(system); + case SvcId::SendSyncRequestLight: + return SvcWrap_SendSyncRequestLight64(system); + case SvcId::SendSyncRequest: + return SvcWrap_SendSyncRequest64(system); + case SvcId::SendSyncRequestWithUserBuffer: + return SvcWrap_SendSyncRequestWithUserBuffer64(system); + case SvcId::SendAsyncRequestWithUserBuffer: + return SvcWrap_SendAsyncRequestWithUserBuffer64(system); + case SvcId::GetProcessId: + return SvcWrap_GetProcessId64(system); + case SvcId::GetThreadId: + return SvcWrap_GetThreadId64(system); + case SvcId::Break: + return SvcWrap_Break64(system); + case SvcId::OutputDebugString: + return SvcWrap_OutputDebugString64(system); + case SvcId::ReturnFromException: + return SvcWrap_ReturnFromException64(system); + case SvcId::GetInfo: + return SvcWrap_GetInfo64(system); + case SvcId::FlushEntireDataCache: + return SvcWrap_FlushEntireDataCache64(system); + case SvcId::FlushDataCache: + return SvcWrap_FlushDataCache64(system); + case SvcId::MapPhysicalMemory: + return SvcWrap_MapPhysicalMemory64(system); + case SvcId::UnmapPhysicalMemory: + return SvcWrap_UnmapPhysicalMemory64(system); + case SvcId::GetDebugFutureThreadInfo: + return SvcWrap_GetDebugFutureThreadInfo64(system); + case SvcId::GetLastThreadInfo: + return SvcWrap_GetLastThreadInfo64(system); + case SvcId::GetResourceLimitLimitValue: + return SvcWrap_GetResourceLimitLimitValue64(system); + case SvcId::GetResourceLimitCurrentValue: + return SvcWrap_GetResourceLimitCurrentValue64(system); + case SvcId::SetThreadActivity: + return SvcWrap_SetThreadActivity64(system); + case SvcId::GetThreadContext3: + return SvcWrap_GetThreadContext364(system); + case SvcId::WaitForAddress: + return SvcWrap_WaitForAddress64(system); + case SvcId::SignalToAddress: + return SvcWrap_SignalToAddress64(system); + case SvcId::SynchronizePreemptionState: + return SvcWrap_SynchronizePreemptionState64(system); + case SvcId::GetResourceLimitPeakValue: + return SvcWrap_GetResourceLimitPeakValue64(system); + case SvcId::CreateIoPool: + return SvcWrap_CreateIoPool64(system); + case SvcId::CreateIoRegion: + return SvcWrap_CreateIoRegion64(system); + case SvcId::KernelDebug: + return SvcWrap_KernelDebug64(system); + case SvcId::ChangeKernelTraceState: + return SvcWrap_ChangeKernelTraceState64(system); + case SvcId::CreateSession: + return SvcWrap_CreateSession64(system); + case SvcId::AcceptSession: + return SvcWrap_AcceptSession64(system); + case SvcId::ReplyAndReceiveLight: + return SvcWrap_ReplyAndReceiveLight64(system); + case SvcId::ReplyAndReceive: + return SvcWrap_ReplyAndReceive64(system); + case SvcId::ReplyAndReceiveWithUserBuffer: + return SvcWrap_ReplyAndReceiveWithUserBuffer64(system); + case SvcId::CreateEvent: + return SvcWrap_CreateEvent64(system); + case SvcId::MapIoRegion: + return SvcWrap_MapIoRegion64(system); + case SvcId::UnmapIoRegion: + return SvcWrap_UnmapIoRegion64(system); + case SvcId::MapPhysicalMemoryUnsafe: + return SvcWrap_MapPhysicalMemoryUnsafe64(system); + case SvcId::UnmapPhysicalMemoryUnsafe: + return SvcWrap_UnmapPhysicalMemoryUnsafe64(system); + case SvcId::SetUnsafeLimit: + return SvcWrap_SetUnsafeLimit64(system); + case SvcId::CreateCodeMemory: + return SvcWrap_CreateCodeMemory64(system); + case SvcId::ControlCodeMemory: + return SvcWrap_ControlCodeMemory64(system); + case SvcId::SleepSystem: + return SvcWrap_SleepSystem64(system); + case SvcId::ReadWriteRegister: + return SvcWrap_ReadWriteRegister64(system); + case SvcId::SetProcessActivity: + return SvcWrap_SetProcessActivity64(system); + case SvcId::CreateSharedMemory: + return SvcWrap_CreateSharedMemory64(system); + case SvcId::MapTransferMemory: + return SvcWrap_MapTransferMemory64(system); + case SvcId::UnmapTransferMemory: + return SvcWrap_UnmapTransferMemory64(system); + case SvcId::CreateInterruptEvent: + return SvcWrap_CreateInterruptEvent64(system); + case SvcId::QueryPhysicalAddress: + return SvcWrap_QueryPhysicalAddress64(system); + case SvcId::QueryIoMapping: + return SvcWrap_QueryIoMapping64(system); + case SvcId::CreateDeviceAddressSpace: + return SvcWrap_CreateDeviceAddressSpace64(system); + case SvcId::AttachDeviceAddressSpace: + return SvcWrap_AttachDeviceAddressSpace64(system); + case SvcId::DetachDeviceAddressSpace: + return SvcWrap_DetachDeviceAddressSpace64(system); + case SvcId::MapDeviceAddressSpaceByForce: + return SvcWrap_MapDeviceAddressSpaceByForce64(system); + case SvcId::MapDeviceAddressSpaceAligned: + return SvcWrap_MapDeviceAddressSpaceAligned64(system); + case SvcId::UnmapDeviceAddressSpace: + return SvcWrap_UnmapDeviceAddressSpace64(system); + case SvcId::InvalidateProcessDataCache: + return SvcWrap_InvalidateProcessDataCache64(system); + case SvcId::StoreProcessDataCache: + return SvcWrap_StoreProcessDataCache64(system); + case SvcId::FlushProcessDataCache: + return SvcWrap_FlushProcessDataCache64(system); + case SvcId::DebugActiveProcess: + return SvcWrap_DebugActiveProcess64(system); + case SvcId::BreakDebugProcess: + return SvcWrap_BreakDebugProcess64(system); + case SvcId::TerminateDebugProcess: + return SvcWrap_TerminateDebugProcess64(system); + case SvcId::GetDebugEvent: + return SvcWrap_GetDebugEvent64(system); + case SvcId::ContinueDebugEvent: + return SvcWrap_ContinueDebugEvent64(system); + case SvcId::GetProcessList: + return SvcWrap_GetProcessList64(system); + case SvcId::GetThreadList: + return SvcWrap_GetThreadList64(system); + case SvcId::GetDebugThreadContext: + return SvcWrap_GetDebugThreadContext64(system); + case SvcId::SetDebugThreadContext: + return SvcWrap_SetDebugThreadContext64(system); + case SvcId::QueryDebugProcessMemory: + return SvcWrap_QueryDebugProcessMemory64(system); + case SvcId::ReadDebugProcessMemory: + return SvcWrap_ReadDebugProcessMemory64(system); + case SvcId::WriteDebugProcessMemory: + return SvcWrap_WriteDebugProcessMemory64(system); + case SvcId::SetHardwareBreakPoint: + return SvcWrap_SetHardwareBreakPoint64(system); + case SvcId::GetDebugThreadParam: + return SvcWrap_GetDebugThreadParam64(system); + case SvcId::GetSystemInfo: + return SvcWrap_GetSystemInfo64(system); + case SvcId::CreatePort: + return SvcWrap_CreatePort64(system); + case SvcId::ManageNamedPort: + return SvcWrap_ManageNamedPort64(system); + case SvcId::ConnectToPort: + return SvcWrap_ConnectToPort64(system); + case SvcId::SetProcessMemoryPermission: + return SvcWrap_SetProcessMemoryPermission64(system); + case SvcId::MapProcessMemory: + return SvcWrap_MapProcessMemory64(system); + case SvcId::UnmapProcessMemory: + return SvcWrap_UnmapProcessMemory64(system); + case SvcId::QueryProcessMemory: + return SvcWrap_QueryProcessMemory64(system); + case SvcId::MapProcessCodeMemory: + return SvcWrap_MapProcessCodeMemory64(system); + case SvcId::UnmapProcessCodeMemory: + return SvcWrap_UnmapProcessCodeMemory64(system); + case SvcId::CreateProcess: + return SvcWrap_CreateProcess64(system); + case SvcId::StartProcess: + return SvcWrap_StartProcess64(system); + case SvcId::TerminateProcess: + return SvcWrap_TerminateProcess64(system); + case SvcId::GetProcessInfo: + return SvcWrap_GetProcessInfo64(system); + case SvcId::CreateResourceLimit: + return SvcWrap_CreateResourceLimit64(system); + case SvcId::SetResourceLimitLimitValue: + return SvcWrap_SetResourceLimitLimitValue64(system); + case SvcId::CallSecureMonitor: + return SvcWrap_CallSecureMonitor64(system); + case SvcId::MapInsecureMemory: + return SvcWrap_MapInsecureMemory64(system); + case SvcId::UnmapInsecureMemory: + return SvcWrap_UnmapInsecureMemory64(system); + default: + LOG_CRITICAL(Kernel_SVC, "Unknown SVC {:x}!", imm); + break; } - return &SVC_Table_64[func_num]; } +// clang-format on -void Call(Core::System& system, u32 immediate) { +void Call(Core::System& system, u32 imm) { 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); - } + if (system.CurrentProcess()->Is64BitProcess()) { + Call64(system, imm); } else { - LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate); + Call32(system, imm); } kernel.ExitSVCProfile(); diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index b599f9a3d..36e619959 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h @@ -1,172 +1,536 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#pragma once +// This file is automatically generated using svc_generator.py. -#include "common/common_types.h" -#include "core/hle/kernel/svc_types.h" -#include "core/hle/result.h" +#pragma once namespace Core { class System; } -namespace Kernel::Svc { +#include "common/common_types.h" +#include "core/hle/kernel/svc_types.h" +#include "core/hle/result.h" -void Call(Core::System& system, u32 immediate); +namespace Kernel::Svc { -Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size); -Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, MemoryPermission perm); -Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, u32 attr); -Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size); -Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size); -Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, - VAddr query_address); +// clang-format off +Result SetHeapSize(Core::System& system, uintptr_t* out_address, uint64_t size); +Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm); +Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr); +Result MapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result UnmapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address); void ExitProcess(Core::System& system); -Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, - VAddr stack_bottom, u32 priority, s32 core_id); +Result CreateThread(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id); Result StartThread(Core::System& system, Handle thread_handle); void ExitThread(Core::System& system); -void SleepThread(Core::System& system, s64 nanoseconds); -Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle); -Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority); -Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, - u64* out_affinity_mask); -Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, - u64 affinity_mask); -u32 GetCurrentProcessorNumber(Core::System& system); +void SleepThread(Core::System& system, int64_t ns); +Result GetThreadPriority(Core::System& system, int32_t* out_priority, Handle thread_handle); +Result SetThreadPriority(Core::System& system, Handle thread_handle, int32_t priority); +Result GetThreadCoreMask(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle); +Result SetThreadCoreMask(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask); +int32_t GetCurrentProcessorNumber(Core::System& system); Result SignalEvent(Core::System& system, Handle event_handle); Result ClearEvent(Core::System& system, Handle event_handle); -Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size, - MemoryPermission map_perm); -Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size); -Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, - MemoryPermission map_perm); +Result MapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm); +Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size); +Result CreateTransferMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm); Result CloseHandle(Core::System& system, Handle handle); Result ResetSignal(Core::System& system, Handle handle); -Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, - s64 nano_seconds); +Result WaitSynchronization(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns); Result CancelSynchronization(Core::System& system, Handle handle); -Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag); -Result ArbitrateUnlock(Core::System& system, VAddr address); -Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag, - s64 timeout_ns); -void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count); -u64 GetSystemTick(Core::System& system); -Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address); -Result SendSyncRequest(Core::System& system, Handle handle); -Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle); -Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle); -void Break(Core::System& system, u32 reason, u64 info1, u64 info2); -void OutputDebugString(Core::System& system, VAddr address, u64 len); -Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u64 info_sub_id); -Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size); -Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size); -Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, - Handle resource_limit_handle, LimitableResource which); -Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, - Handle resource_limit_handle, LimitableResource which); -Result SetThreadActivity(Core::System& system, Handle thread_handle, - ThreadActivity thread_activity); -Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle); -Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value, - s64 timeout_ns); -Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value, - s32 count); +Result ArbitrateLock(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag); +Result ArbitrateUnlock(Core::System& system, uint64_t address); +Result WaitProcessWideKeyAtomic(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns); +void SignalProcessWideKey(Core::System& system, uint64_t cv_key, int32_t count); +int64_t GetSystemTick(Core::System& system); +Result ConnectToNamedPort(Core::System& system, Handle* out_handle, uint64_t name); +Result SendSyncRequest(Core::System& system, Handle session_handle); +Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle); +Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle); +Result GetProcessId(Core::System& system, uint64_t* out_process_id, Handle process_handle); +Result GetThreadId(Core::System& system, uint64_t* out_thread_id, Handle thread_handle); +void Break(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size); +Result OutputDebugString(Core::System& system, uint64_t debug_str, uint64_t len); +void ReturnFromException(Core::System& system, Result result); +Result GetInfo(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype); +void FlushEntireDataCache(Core::System& system); +Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size); +Result MapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size); +Result UnmapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size); +Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns); +Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags); +Result GetResourceLimitLimitValue(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which); +Result GetResourceLimitCurrentValue(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which); +Result SetThreadActivity(Core::System& system, Handle thread_handle, ThreadActivity thread_activity); +Result GetThreadContext3(Core::System& system, uint64_t out_context, Handle thread_handle); +Result WaitForAddress(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns); +Result SignalToAddress(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count); void SynchronizePreemptionState(Core::System& system); -void KernelDebug(Core::System& system, u32 kernel_debug_type, u64 param1, u64 param2, u64 param3); -void ChangeKernelTraceState(Core::System& system, u32 trace_state); -Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u32 is_light, - u64 name); -Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s32 num_handles, - Handle reply_target, s64 timeout_ns); -Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read); -Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size); -Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, - VAddr address, size_t size, MemoryPermission perm); -Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids, - u32 out_process_ids_size); -Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, - u32 out_thread_ids_size, Handle debug_handle); -Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address, - u64 size, MemoryPermission perm); -Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, - VAddr src_address, u64 size); -Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, - VAddr src_address, u64 size); -Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, - Handle process_handle, VAddr address); -Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, - u64 src_address, u64 size); -Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, - u64 src_address, u64 size); -Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type); +Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which); +Result CreateIoPool(Core::System& system, Handle* out_handle, IoPoolType which); +Result CreateIoRegion(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm); +void KernelDebug(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2); +void ChangeKernelTraceState(Core::System& system, KernelTraceState kern_trace_state); +Result CreateSession(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name); +Result AcceptSession(Core::System& system, Handle* out_handle, Handle port); +Result ReplyAndReceive(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns); +Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns); +Result CreateEvent(Core::System& system, Handle* out_write_handle, Handle* out_read_handle); +Result MapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm); +Result UnmapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size); +Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size); +Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size); +Result SetUnsafeLimit(Core::System& system, uint64_t limit); +Result CreateCodeMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size); +Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm); +void SleepSystem(Core::System& system); +Result ReadWriteRegister(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value); +Result SetProcessActivity(Core::System& system, Handle process_handle, ProcessActivity process_activity); +Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm); +Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm); +Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size); +Result CreateInterruptEvent(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type); +Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address); +Result QueryIoMapping(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint64_t size); +Result CreateDeviceAddressSpace(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size); +Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle); +Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle); +Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option); +Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option); +Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address); +Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result FlushProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id); +Result BreakDebugProcess(Core::System& system, Handle debug_handle); +Result TerminateDebugProcess(Core::System& system, Handle debug_handle); +Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle); +Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids); +Result GetProcessList(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count); +Result GetThreadList(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle); +Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags); +Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags); +Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address); +Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size); +Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size); +Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value); +Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param); +Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype); +Result CreatePort(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name); +Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions); +Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port); +Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm); +Result MapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size); +Result UnmapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size); +Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address); +Result MapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps); +Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size); +Result TerminateProcess(Core::System& system, Handle process_handle); +Result GetProcessInfo(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type); Result CreateResourceLimit(Core::System& system, Handle* out_handle); -Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, - LimitableResource which, u64 limit_value); - -// - -Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size); -Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, u32 attr); -Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size); -Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size); -Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address, - u32 query_address); -void ExitProcess32(Core::System& system); -Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, u32 entry_point, - u32 arg, u32 stack_top, s32 processor_id); -Result StartThread32(Core::System& system, Handle thread_handle); -void ExitThread32(Core::System& system); -void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high); -Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle); -Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority); -Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, - u32* out_affinity_mask_low, u32* out_affinity_mask_high); -Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, - u32 affinity_mask_low, u32 affinity_mask_high); -u32 GetCurrentProcessorNumber32(Core::System& system); -Result SignalEvent32(Core::System& system, Handle event_handle); -Result ClearEvent32(Core::System& system, Handle event_handle); -Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size, - MemoryPermission map_perm); -Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size); -Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, - MemoryPermission map_perm); -Result CloseHandle32(Core::System& system, Handle handle); -Result ResetSignal32(Core::System& system, Handle handle); -Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, - s32 num_handles, u32 timeout_high, s32* index); -Result CancelSynchronization32(Core::System& system, Handle handle); -Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag); -Result ArbitrateUnlock32(Core::System& system, u32 address); -Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, - u32 timeout_ns_low, u32 timeout_ns_high); -void SignalProcessWideKey32(Core::System& system, u32 cv_key, s32 count); -void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high); -Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, u32 port_name_address); -Result SendSyncRequest32(Core::System& system, Handle handle); -Result GetProcessId32(Core::System& system, u32* out_process_id_low, u32* out_process_id_high, - Handle handle); -Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high, - Handle thread_handle); -void Break32(Core::System& system, u32 reason, u32 info1, u32 info2); -void OutputDebugString32(Core::System& system, u32 address, u32 len); -Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, - u32 info_id, u32 handle, u32 sub_id_high); -Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size); -Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size); -Result SetThreadActivity32(Core::System& system, Handle thread_handle, - ThreadActivity thread_activity); -Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle); -Result WaitForAddress32(Core::System& system, u32 address, ArbitrationType arb_type, s32 value, - u32 timeout_ns_low, u32 timeout_ns_high); -Result SignalToAddress32(Core::System& system, u32 address, SignalType signal_type, s32 value, - s32 count); -Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read); -Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size); -Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation, - u64 address, u64 size, MemoryPermission perm); -Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, u64 size); +Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value); +Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size); +Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size); + +Result SetHeapSize64From32(Core::System& system, uintptr_t* out_address, uint32_t size); +Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, MemoryPermission perm); +Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, uint32_t mask, uint32_t attr); +Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size); +Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size); +Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, uint32_t address); +void ExitProcess64From32(Core::System& system); +Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg, uint32_t stack_bottom, int32_t priority, int32_t core_id); +Result StartThread64From32(Core::System& system, Handle thread_handle); +void ExitThread64From32(Core::System& system); +void SleepThread64From32(Core::System& system, int64_t ns); +Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority, Handle thread_handle); +Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority); +Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle); +Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask); +int32_t GetCurrentProcessorNumber64From32(Core::System& system); +Result SignalEvent64From32(Core::System& system, Handle event_handle); +Result ClearEvent64From32(Core::System& system, Handle event_handle); +Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size, MemoryPermission map_perm); +Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size); +Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size, MemoryPermission map_perm); +Result CloseHandle64From32(Core::System& system, Handle handle); +Result ResetSignal64From32(Core::System& system, Handle handle); +Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, int64_t timeout_ns); +Result CancelSynchronization64From32(Core::System& system, Handle handle); +Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address, uint32_t tag); +Result ArbitrateUnlock64From32(Core::System& system, uint32_t address); +Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key, uint32_t tag, int64_t timeout_ns); +void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count); +int64_t GetSystemTick64From32(Core::System& system); +Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name); +Result SendSyncRequest64From32(Core::System& system, Handle session_handle); +Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle); +Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle); +Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle); +Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle); +void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size); +Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len); +void ReturnFromException64From32(Core::System& system, Result result); +Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype); +void FlushEntireDataCache64From32(Core::System& system); +Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size); +Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size); +Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size); +Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns); +Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags); +Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which); +Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which); +Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, ThreadActivity thread_activity); +Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle); +Result WaitForAddress64From32(Core::System& system, uint32_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns); +Result SignalToAddress64From32(Core::System& system, uint32_t address, SignalType signal_type, int32_t value, int32_t count); +void SynchronizePreemptionState64From32(Core::System& system); +Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which); +Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType which); +Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint32_t size, MemoryMapping mapping, MemoryPermission perm); +void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2); +void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state); +Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint32_t name); +Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port); +Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns); +Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index, uint32_t message_buffer, uint32_t message_buffer_size, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns); +Result CreateEvent64From32(Core::System& system, Handle* out_write_handle, Handle* out_read_handle); +Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size, MemoryPermission perm); +Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size); +Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size); +Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size); +Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit); +Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size); +Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm); +void SleepSystem64From32(Core::System& system); +Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value); +Result SetProcessActivity64From32(Core::System& system, Handle process_handle, ProcessActivity process_activity); +Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size, MemoryPermission owner_perm, MemoryPermission remote_perm); +Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size, MemoryPermission owner_perm); +Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size); +Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type); +Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, uint32_t address); +Result QueryIoMapping64From32(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint32_t size); +Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size); +Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle); +Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle); +Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option); +Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option); +Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address); +Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id); +Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle); +Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle); +Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle); +Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags, uint32_t thread_ids, int32_t num_thread_ids); +Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes, uint32_t out_process_ids, int32_t max_out_count); +Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads, uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle); +Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags); +Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id, uint32_t context, uint32_t context_flags); +Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint32_t address); +Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle, uint32_t address, uint32_t size); +Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer, uint32_t address, uint32_t size); +Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value); +Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param); +Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype); +Result CreatePort64From32(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint32_t name); +Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name, int32_t max_sessions); +Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port); +Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm); +Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size); +Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size); +Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address); +Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters, uint32_t caps, int32_t num_caps); +Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size); +Result TerminateProcess64From32(Core::System& system, Handle process_handle); +Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type); +Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle); +Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value); +Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size); +Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size); + +Result SetHeapSize64(Core::System& system, uintptr_t* out_address, uint64_t size); +Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm); +Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr); +Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address); +void ExitProcess64(Core::System& system); +Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id); +Result StartThread64(Core::System& system, Handle thread_handle); +void ExitThread64(Core::System& system); +void SleepThread64(Core::System& system, int64_t ns); +Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle); +Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority); +Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle); +Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask); +int32_t GetCurrentProcessorNumber64(Core::System& system); +Result SignalEvent64(Core::System& system, Handle event_handle); +Result ClearEvent64(Core::System& system, Handle event_handle); +Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm); +Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size); +Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm); +Result CloseHandle64(Core::System& system, Handle handle); +Result ResetSignal64(Core::System& system, Handle handle); +Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns); +Result CancelSynchronization64(Core::System& system, Handle handle); +Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag); +Result ArbitrateUnlock64(Core::System& system, uint64_t address); +Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns); +void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count); +int64_t GetSystemTick64(Core::System& system); +Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name); +Result SendSyncRequest64(Core::System& system, Handle session_handle); +Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle); +Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle); +Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle); +Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle); +void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size); +Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len); +void ReturnFromException64(Core::System& system, Result result); +Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype); +void FlushEntireDataCache64(Core::System& system); +Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size); +Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size); +Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size); +Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns); +Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags); +Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which); +Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which); +Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity); +Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle); +Result WaitForAddress64(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns); +Result SignalToAddress64(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count); +void SynchronizePreemptionState64(Core::System& system); +Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which); +Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType which); +Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm); +void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2); +void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state); +Result CreateSession64(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name); +Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port); +Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns); +Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns); +Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle); +Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm); +Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size); +Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size); +Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size); +Result SetUnsafeLimit64(Core::System& system, uint64_t limit); +Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size); +Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm); +void SleepSystem64(Core::System& system); +Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value); +Result SetProcessActivity64(Core::System& system, Handle process_handle, ProcessActivity process_activity); +Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm); +Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm); +Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size); +Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type); +Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address); +Result QueryIoMapping64(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint64_t size); +Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size); +Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle); +Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle); +Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option); +Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option); +Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address); +Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size); +Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id); +Result BreakDebugProcess64(Core::System& system, Handle debug_handle); +Result TerminateDebugProcess64(Core::System& system, Handle debug_handle); +Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle); +Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids); +Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count); +Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle); +Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags); +Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags); +Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address); +Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size); +Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size); +Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value); +Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param); +Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype); +Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name); +Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions); +Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port); +Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm); +Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size); +Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size); +Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address); +Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size); +Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps); +Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size); +Result TerminateProcess64(Core::System& system, Handle process_handle); +Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type); +Result CreateResourceLimit64(Core::System& system, Handle* out_handle); +Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value); +Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size); +Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size); + +enum class SvcId : u32 { + SetHeapSize = 0x1, + SetMemoryPermission = 0x2, + SetMemoryAttribute = 0x3, + MapMemory = 0x4, + UnmapMemory = 0x5, + QueryMemory = 0x6, + ExitProcess = 0x7, + CreateThread = 0x8, + StartThread = 0x9, + ExitThread = 0xa, + SleepThread = 0xb, + GetThreadPriority = 0xc, + SetThreadPriority = 0xd, + GetThreadCoreMask = 0xe, + SetThreadCoreMask = 0xf, + GetCurrentProcessorNumber = 0x10, + SignalEvent = 0x11, + ClearEvent = 0x12, + MapSharedMemory = 0x13, + UnmapSharedMemory = 0x14, + CreateTransferMemory = 0x15, + CloseHandle = 0x16, + ResetSignal = 0x17, + WaitSynchronization = 0x18, + CancelSynchronization = 0x19, + ArbitrateLock = 0x1a, + ArbitrateUnlock = 0x1b, + WaitProcessWideKeyAtomic = 0x1c, + SignalProcessWideKey = 0x1d, + GetSystemTick = 0x1e, + ConnectToNamedPort = 0x1f, + SendSyncRequestLight = 0x20, + SendSyncRequest = 0x21, + SendSyncRequestWithUserBuffer = 0x22, + SendAsyncRequestWithUserBuffer = 0x23, + GetProcessId = 0x24, + GetThreadId = 0x25, + Break = 0x26, + OutputDebugString = 0x27, + ReturnFromException = 0x28, + GetInfo = 0x29, + FlushEntireDataCache = 0x2a, + FlushDataCache = 0x2b, + MapPhysicalMemory = 0x2c, + UnmapPhysicalMemory = 0x2d, + GetDebugFutureThreadInfo = 0x2e, + GetLastThreadInfo = 0x2f, + GetResourceLimitLimitValue = 0x30, + GetResourceLimitCurrentValue = 0x31, + SetThreadActivity = 0x32, + GetThreadContext3 = 0x33, + WaitForAddress = 0x34, + SignalToAddress = 0x35, + SynchronizePreemptionState = 0x36, + GetResourceLimitPeakValue = 0x37, + CreateIoPool = 0x39, + CreateIoRegion = 0x3a, + KernelDebug = 0x3c, + ChangeKernelTraceState = 0x3d, + CreateSession = 0x40, + AcceptSession = 0x41, + ReplyAndReceiveLight = 0x42, + ReplyAndReceive = 0x43, + ReplyAndReceiveWithUserBuffer = 0x44, + CreateEvent = 0x45, + MapIoRegion = 0x46, + UnmapIoRegion = 0x47, + MapPhysicalMemoryUnsafe = 0x48, + UnmapPhysicalMemoryUnsafe = 0x49, + SetUnsafeLimit = 0x4a, + CreateCodeMemory = 0x4b, + ControlCodeMemory = 0x4c, + SleepSystem = 0x4d, + ReadWriteRegister = 0x4e, + SetProcessActivity = 0x4f, + CreateSharedMemory = 0x50, + MapTransferMemory = 0x51, + UnmapTransferMemory = 0x52, + CreateInterruptEvent = 0x53, + QueryPhysicalAddress = 0x54, + QueryIoMapping = 0x55, + CreateDeviceAddressSpace = 0x56, + AttachDeviceAddressSpace = 0x57, + DetachDeviceAddressSpace = 0x58, + MapDeviceAddressSpaceByForce = 0x59, + MapDeviceAddressSpaceAligned = 0x5a, + UnmapDeviceAddressSpace = 0x5c, + InvalidateProcessDataCache = 0x5d, + StoreProcessDataCache = 0x5e, + FlushProcessDataCache = 0x5f, + DebugActiveProcess = 0x60, + BreakDebugProcess = 0x61, + TerminateDebugProcess = 0x62, + GetDebugEvent = 0x63, + ContinueDebugEvent = 0x64, + GetProcessList = 0x65, + GetThreadList = 0x66, + GetDebugThreadContext = 0x67, + SetDebugThreadContext = 0x68, + QueryDebugProcessMemory = 0x69, + ReadDebugProcessMemory = 0x6a, + WriteDebugProcessMemory = 0x6b, + SetHardwareBreakPoint = 0x6c, + GetDebugThreadParam = 0x6d, + GetSystemInfo = 0x6f, + CreatePort = 0x70, + ManageNamedPort = 0x71, + ConnectToPort = 0x72, + SetProcessMemoryPermission = 0x73, + MapProcessMemory = 0x74, + UnmapProcessMemory = 0x75, + QueryProcessMemory = 0x76, + MapProcessCodeMemory = 0x77, + UnmapProcessCodeMemory = 0x78, + CreateProcess = 0x79, + StartProcess = 0x7a, + TerminateProcess = 0x7b, + GetProcessInfo = 0x7c, + CreateResourceLimit = 0x7d, + SetResourceLimitLimitValue = 0x7e, + CallSecureMonitor = 0x7f, + MapInsecureMemory = 0x90, + UnmapInsecureMemory = 0x91, +}; +// clang-format on + +// Custom ABI. +Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args); +Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args); +Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args); + +Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args); +Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args); +Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args); + +void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args); +void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args); +void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args); + +// Defined in svc_light_ipc.cpp. +void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system); +void SvcWrap_ReplyAndReceiveLight64(Core::System& system); + +void SvcWrap_SendSyncRequestLight64From32(Core::System& system); +void SvcWrap_SendSyncRequestLight64(Core::System& system); + +// Defined in svc_secure_monitor_call.cpp. +void SvcWrap_CallSecureMonitor64From32(Core::System& system); +void SvcWrap_CallSecureMonitor64(Core::System& system); + +// Perform a supervisor call by index. +void Call(Core::System& system, u32 imm); } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_activity.cpp b/src/core/hle/kernel/svc/svc_activity.cpp index 8774a5c98..1dcdb7a15 100644 --- a/src/core/hle/kernel/svc/svc_activity.cpp +++ b/src/core/hle/kernel/svc/svc_activity.cpp @@ -36,9 +36,30 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle, return ResultSuccess; } -Result SetThreadActivity32(Core::System& system, Handle thread_handle, +Result SetProcessActivity(Core::System& system, Handle process_handle, + ProcessActivity process_activity) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity) { return SetThreadActivity(system, thread_handle, thread_activity); } +Result SetProcessActivity64(Core::System& system, Handle process_handle, + ProcessActivity process_activity) { + return SetProcessActivity(system, process_handle, process_activity); +} + +Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, + ThreadActivity thread_activity) { + return SetThreadActivity(system, thread_handle, thread_activity); +} + +Result SetProcessActivity64From32(Core::System& system, Handle process_handle, + ProcessActivity process_activity) { + return SetProcessActivity(system, process_handle, process_activity); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_address_arbiter.cpp b/src/core/hle/kernel/svc/svc_address_arbiter.cpp index 842107726..e6a5d2ae5 100644 --- a/src/core/hle/kernel/svc/svc_address_arbiter.cpp +++ b/src/core/hle/kernel/svc/svc_address_arbiter.cpp @@ -75,12 +75,6 @@ Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_t return system.Kernel().CurrentProcess()->WaitAddressArbiter(address, arb_type, value, timeout); } -Result WaitForAddress32(Core::System& system, u32 address, ArbitrationType arb_type, s32 value, - u32 timeout_ns_low, u32 timeout_ns_high) { - const auto timeout = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); - return WaitForAddress(system, address, arb_type, value, timeout); -} - // Signals to an address (via Address Arbiter) Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value, s32 count) { @@ -105,9 +99,24 @@ Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_ty count); } -Result SignalToAddress32(Core::System& system, u32 address, SignalType signal_type, s32 value, +Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value, + s64 timeout_ns) { + return WaitForAddress(system, address, arb_type, value, timeout_ns); +} + +Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value, s32 count) { return SignalToAddress(system, address, signal_type, value, count); } +Result WaitForAddress64From32(Core::System& system, u32 address, ArbitrationType arb_type, + s32 value, s64 timeout_ns) { + return WaitForAddress(system, address, arb_type, value, timeout_ns); +} + +Result SignalToAddress64From32(Core::System& system, u32 address, SignalType signal_type, s32 value, + s32 count) { + return SignalToAddress(system, address, signal_type, value, count); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_address_translation.cpp b/src/core/hle/kernel/svc/svc_address_translation.cpp index 299e22ae6..c25e144cd 100644 --- a/src/core/hle/kernel/svc/svc_address_translation.cpp +++ b/src/core/hle/kernel/svc/svc_address_translation.cpp @@ -2,5 +2,49 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, + uint64_t address) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result QueryIoMapping(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, + uint64_t physical_address, uint64_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, + uint64_t address) { + R_RETURN(QueryPhysicalAddress(system, out_info, address)); +} + +Result QueryIoMapping64(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, + uint64_t physical_address, uint64_t size) { + R_RETURN(QueryIoMapping(system, out_address, out_size, physical_address, size)); +} + +Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, + uint32_t address) { + lp64::PhysicalMemoryInfo info{}; + R_TRY(QueryPhysicalAddress(system, std::addressof(info), address)); + + *out_info = { + .physical_address = info.physical_address, + .virtual_address = static_cast<u32>(info.virtual_address), + .size = static_cast<u32>(info.size), + }; + R_SUCCEED(); +} + +Result QueryIoMapping64From32(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, + uint64_t physical_address, uint32_t size) { + R_RETURN(QueryIoMapping(system, reinterpret_cast<uintptr_t*>(out_address), + reinterpret_cast<uintptr_t*>(out_size), physical_address, size)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_cache.cpp b/src/core/hle/kernel/svc/svc_cache.cpp index 42167d35b..b5404760e 100644 --- a/src/core/hle/kernel/svc/svc_cache.cpp +++ b/src/core/hle/kernel/svc/svc_cache.cpp @@ -9,7 +9,28 @@ namespace Kernel::Svc { -Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, u64 size) { +void FlushEntireDataCache(Core::System& system) { + UNIMPLEMENTED(); +} + +Result FlushDataCache(Core::System& system, VAddr address, size_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 address, u64 size) { // Validate address/size. R_UNLESS(size > 0, ResultInvalidSize); R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory); @@ -28,4 +49,50 @@ Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 R_RETURN(system.Memory().FlushDataCache(*process, address, size)); } +void FlushEntireDataCache64(Core::System& system) { + FlushEntireDataCache(system); +} + +Result FlushDataCache64(Core::System& system, VAddr address, size_t size) { + R_RETURN(FlushDataCache(system, address, size)); +} + +Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size)); +} + +Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + R_RETURN(StoreProcessDataCache(system, process_handle, address, size)); +} + +Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + R_RETURN(FlushProcessDataCache(system, process_handle, address, size)); +} + +void FlushEntireDataCache64From32(Core::System& system) { + return FlushEntireDataCache(system); +} + +Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(FlushDataCache(system, address, size)); +} + +Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle, + uint64_t address, uint64_t size) { + R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size)); +} + +Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + R_RETURN(StoreProcessDataCache(system, process_handle, address, size)); +} + +Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size) { + R_RETURN(FlushProcessDataCache(system, process_handle, address, size)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp index 4cb21e101..ec256b757 100644 --- a/src/core/hle/kernel/svc/svc_code_memory.cpp +++ b/src/core/hle/kernel/svc/svc_code_memory.cpp @@ -63,12 +63,9 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t return ResultSuccess; } -Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) { - return CreateCodeMemory(system, out, address, size); -} - -Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, - VAddr address, size_t size, MemoryPermission perm) { +Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, + CodeMemoryOperation operation, VAddr address, size_t size, + MemoryPermission perm) { LOG_TRACE(Kernel_SVC, "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, " @@ -90,7 +87,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 op // This enables homebrew usage of these SVCs for JIT. // Perform the operation. - switch (static_cast<CodeMemoryOperation>(operation)) { + switch (operation) { case CodeMemoryOperation::Map: { // Check that the region is in range. R_UNLESS( @@ -146,9 +143,26 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 op return ResultSuccess; } -Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation, - u64 address, u64 size, MemoryPermission perm) { - return ControlCodeMemory(system, code_memory_handle, operation, address, size, perm); +Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address, + uint64_t size) { + R_RETURN(CreateCodeMemory(system, out_handle, address, size)); +} + +Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle, + CodeMemoryOperation operation, uint64_t address, uint64_t size, + MemoryPermission perm) { + R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm)); +} + +Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, + uint32_t size) { + R_RETURN(CreateCodeMemory(system, out_handle, address, size)); +} + +Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle, + CodeMemoryOperation operation, uint64_t address, uint64_t size, + MemoryPermission perm) { + R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_condition_variable.cpp b/src/core/hle/kernel/svc/svc_condition_variable.cpp index d6cfc87c5..b59a33e68 100644 --- a/src/core/hle/kernel/svc/svc_condition_variable.cpp +++ b/src/core/hle/kernel/svc/svc_condition_variable.cpp @@ -47,12 +47,6 @@ Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_ke address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout); } -Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, - u32 timeout_ns_low, u32 timeout_ns_high) { - const auto timeout_ns = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); - return WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns); -} - /// Signal process wide key void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) { LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count); @@ -62,7 +56,21 @@ void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) { Common::AlignDown(cv_key, sizeof(u32)), count); } -void SignalProcessWideKey32(Core::System& system, u32 cv_key, s32 count) { +Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key, + uint32_t tag, int64_t timeout_ns) { + R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns)); +} + +void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count) { + SignalProcessWideKey(system, cv_key, count); +} + +Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key, + uint32_t tag, int64_t timeout_ns) { + R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns)); +} + +void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count) { SignalProcessWideKey(system, cv_key, count); } diff --git a/src/core/hle/kernel/svc/svc_debug.cpp b/src/core/hle/kernel/svc/svc_debug.cpp index 299e22ae6..a14050fa7 100644 --- a/src/core/hle/kernel/svc/svc_debug.cpp +++ b/src/core/hle/kernel/svc/svc_debug.cpp @@ -2,5 +2,193 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result BreakDebugProcess(Core::System& system, Handle debug_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result TerminateDebugProcess(Core::System& system, Handle debug_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags, + uint64_t user_thread_ids, int32_t num_thread_ids) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle, + uint64_t thread_id, uint32_t context_flags) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id, + uint64_t user_context, uint32_t context_flags) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info, + PageInfo* out_page_info, Handle debug_handle, uintptr_t address) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ReadDebugProcessMemory(Core::System& system, uintptr_t buffer, Handle debug_handle, + uintptr_t address, size_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uintptr_t buffer, + uintptr_t address, size_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name, + uint64_t flags, uint64_t value) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32, + Handle debug_handle, uint64_t thread_id, DebugThreadParam param) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id) { + R_RETURN(DebugActiveProcess(system, out_handle, process_id)); +} + +Result BreakDebugProcess64(Core::System& system, Handle debug_handle) { + R_RETURN(BreakDebugProcess(system, debug_handle)); +} + +Result TerminateDebugProcess64(Core::System& system, Handle debug_handle) { + R_RETURN(TerminateDebugProcess(system, debug_handle)); +} + +Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle) { + R_RETURN(GetDebugEvent(system, out_info, debug_handle)); +} + +Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags, + uint64_t thread_ids, int32_t num_thread_ids) { + R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids)); +} + +Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle, + uint64_t thread_id, uint32_t context_flags) { + R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags)); +} + +Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id, + uint64_t context, uint32_t context_flags) { + R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags)); +} + +Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info, + PageInfo* out_page_info, Handle debug_handle, uint64_t address) { + R_RETURN( + QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address)); +} + +Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle, + uint64_t address, uint64_t size) { + R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size)); +} + +Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer, + uint64_t address, uint64_t size) { + R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size)); +} + +Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name, + uint64_t flags, uint64_t value) { + R_RETURN(SetHardwareBreakPoint(system, name, flags, value)); +} + +Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32, + Handle debug_handle, uint64_t thread_id, DebugThreadParam param) { + R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param)); +} + +Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id) { + R_RETURN(DebugActiveProcess(system, out_handle, process_id)); +} + +Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle) { + R_RETURN(BreakDebugProcess(system, debug_handle)); +} + +Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle) { + R_RETURN(TerminateDebugProcess(system, debug_handle)); +} + +Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle) { + R_RETURN(GetDebugEvent(system, out_info, debug_handle)); +} + +Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags, + uint32_t thread_ids, int32_t num_thread_ids) { + R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids)); +} + +Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context, + Handle debug_handle, uint64_t thread_id, + uint32_t context_flags) { + R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags)); +} + +Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id, + uint32_t context, uint32_t context_flags) { + R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags)); +} + +Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info, + PageInfo* out_page_info, Handle debug_handle, + uint32_t address) { + R_RETURN( + QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address)); +} + +Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle, + uint32_t address, uint32_t size) { + R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size)); +} + +Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer, + uint32_t address, uint32_t size) { + R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size)); +} + +Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name, + uint64_t flags, uint64_t value) { + R_RETURN(SetHardwareBreakPoint(system, name, flags, value)); +} + +Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32, + Handle debug_handle, uint64_t thread_id, + DebugThreadParam param) { + R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp index 486e62cc4..d4bf062d1 100644 --- a/src/core/hle/kernel/svc/svc_debug_string.cpp +++ b/src/core/hle/kernel/svc/svc_debug_string.cpp @@ -8,18 +8,22 @@ namespace Kernel::Svc { /// Used to output a message on a debug hardware unit - does nothing on a retail unit -void OutputDebugString(Core::System& system, VAddr address, u64 len) { - if (len == 0) { - return; - } +Result OutputDebugString(Core::System& system, VAddr address, u64 len) { + R_SUCCEED_IF(len == 0); std::string str(len, '\0'); system.Memory().ReadBlock(address, str.data(), str.size()); LOG_DEBUG(Debug_Emulated, "{}", str); + + R_SUCCEED(); +} + +Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len) { + R_RETURN(OutputDebugString(system, debug_str, len)); } -void OutputDebugString32(Core::System& system, u32 address, u32 len) { - OutputDebugString(system, address, len); +Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len) { + R_RETURN(OutputDebugString(system, debug_str, len)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_device_address_space.cpp b/src/core/hle/kernel/svc/svc_device_address_space.cpp index 299e22ae6..cdc453c35 100644 --- a/src/core/hle/kernel/svc/svc_device_address_space.cpp +++ b/src/core/hle/kernel/svc/svc_device_address_space.cpp @@ -1,6 +1,253 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/alignment.h" +#include "common/scope_exit.h" +#include "core/core.h" +#include "core/hle/kernel/k_device_address_space.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/svc.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +constexpr inline u64 DeviceAddressSpaceAlignMask = (1ULL << 22) - 1; + +constexpr bool IsProcessAndDeviceAligned(uint64_t process_address, uint64_t device_address) { + return (process_address & DeviceAddressSpaceAlignMask) == + (device_address & DeviceAddressSpaceAlignMask); +} + +Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_address, + uint64_t das_size) { + // Validate input. + R_UNLESS(Common::IsAligned(das_address, PageSize), ResultInvalidMemoryRegion); + R_UNLESS(Common::IsAligned(das_size, PageSize), ResultInvalidMemoryRegion); + R_UNLESS(das_size > 0, ResultInvalidMemoryRegion); + R_UNLESS((das_address < das_address + das_size), ResultInvalidMemoryRegion); + + // Create the device address space. + KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel()); + R_UNLESS(das != nullptr, ResultOutOfResource); + SCOPE_EXIT({ das->Close(); }); + + // Initialize the device address space. + R_TRY(das->Initialize(das_address, das_size)); + + // Register the device address space. + KDeviceAddressSpace::Register(system.Kernel(), das); + + // Add to the handle table. + R_TRY(system.CurrentProcess()->GetHandleTable().Add(out, das)); + + R_SUCCEED(); +} + +Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) { + // Get the device address space. + KScopedAutoObject das = + system.CurrentProcess()->GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle); + R_UNLESS(das.IsNotNull(), ResultInvalidHandle); + + // Attach. + R_RETURN(das->Attach(device_name)); +} + +Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) { + // Get the device address space. + KScopedAutoObject das = + system.CurrentProcess()->GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle); + R_UNLESS(das.IsNotNull(), ResultInvalidHandle); + + // Detach. + R_RETURN(das->Detach(device_name)); +} + +constexpr bool IsValidDeviceMemoryPermission(MemoryPermission device_perm) { + switch (device_perm) { + case MemoryPermission::Read: + case MemoryPermission::Write: + case MemoryPermission::ReadWrite: + return true; + default: + return false; + } +} + +Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle, + uint64_t process_address, size_t size, uint64_t device_address, + u32 option) { + // Decode the option. + const MapDeviceAddressSpaceOption option_pack{option}; + const auto device_perm = option_pack.permission; + const auto reserved = option_pack.reserved; + + // Validate input. + R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); + R_UNLESS(size > 0, ResultInvalidSize); + R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory); + R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion); + R_UNLESS((process_address == static_cast<uintptr_t>(process_address)), + ResultInvalidCurrentMemory); + R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission); + R_UNLESS(reserved == 0, ResultInvalidEnumValue); + + // Get the device address space. + KScopedAutoObject das = + system.CurrentProcess()->GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle); + R_UNLESS(das.IsNotNull(), ResultInvalidHandle); + + // Get the process. + KScopedAutoObject process = + system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); + R_UNLESS(process.IsNotNull(), ResultInvalidHandle); + + // Validate that the process address is within range. + auto& page_table = process->PageTable(); + R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); + + // Map. + R_RETURN( + das->MapByForce(std::addressof(page_table), process_address, size, device_address, option)); +} + +Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle, + uint64_t process_address, size_t size, uint64_t device_address, + u32 option) { + // Decode the option. + const MapDeviceAddressSpaceOption option_pack{option}; + const auto device_perm = option_pack.permission; + const auto reserved = option_pack.reserved; + + // Validate input. + R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress); + R_UNLESS(IsProcessAndDeviceAligned(process_address, device_address), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); + R_UNLESS(size > 0, ResultInvalidSize); + R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory); + R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion); + R_UNLESS((process_address == static_cast<uintptr_t>(process_address)), + ResultInvalidCurrentMemory); + R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission); + R_UNLESS(reserved == 0, ResultInvalidEnumValue); + + // Get the device address space. + KScopedAutoObject das = + system.CurrentProcess()->GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle); + R_UNLESS(das.IsNotNull(), ResultInvalidHandle); + + // Get the process. + KScopedAutoObject process = + system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); + R_UNLESS(process.IsNotNull(), ResultInvalidHandle); + + // Validate that the process address is within range. + auto& page_table = process->PageTable(); + R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); + + // Map. + R_RETURN( + das->MapAligned(std::addressof(page_table), process_address, size, device_address, option)); +} + +Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle, + uint64_t process_address, size_t size, uint64_t device_address) { + // Validate input. + R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress); + R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); + R_UNLESS(size > 0, ResultInvalidSize); + R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory); + R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion); + R_UNLESS((process_address == static_cast<uintptr_t>(process_address)), + ResultInvalidCurrentMemory); + + // Get the device address space. + KScopedAutoObject das = + system.CurrentProcess()->GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle); + R_UNLESS(das.IsNotNull(), ResultInvalidHandle); + + // Get the process. + KScopedAutoObject process = + system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); + R_UNLESS(process.IsNotNull(), ResultInvalidHandle); + + // Validate that the process address is within range. + auto& page_table = process->PageTable(); + R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); + + R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address)); +} + +Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, + uint64_t das_size) { + R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size)); +} + +Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) { + R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle)); +} + +Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) { + R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle)); +} + +Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle, + Handle process_handle, uint64_t process_address, + uint64_t size, uint64_t device_address, u32 option) { + R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size, + device_address, option)); +} + +Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle, + Handle process_handle, uint64_t process_address, + uint64_t size, uint64_t device_address, u32 option) { + R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size, + device_address, option)); +} + +Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle, + uint64_t process_address, uint64_t size, uint64_t device_address) { + R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size, + device_address)); +} + +Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, + uint64_t das_address, uint64_t das_size) { + R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size)); +} + +Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, + Handle das_handle) { + R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle)); +} + +Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, + Handle das_handle) { + R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle)); +} + +Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle, + Handle process_handle, uint64_t process_address, + uint32_t size, uint64_t device_address, u32 option) { + R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size, + device_address, option)); +} + +Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle, + Handle process_handle, uint64_t process_address, + uint32_t size, uint64_t device_address, u32 option) { + R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size, + device_address, option)); +} + +Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle, + Handle process_handle, uint64_t process_address, + uint32_t size, uint64_t device_address) { + R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size, + device_address)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_event.cpp b/src/core/hle/kernel/svc/svc_event.cpp index 885f02f50..e8fb9efbc 100644 --- a/src/core/hle/kernel/svc/svc_event.cpp +++ b/src/core/hle/kernel/svc/svc_event.cpp @@ -24,10 +24,6 @@ Result SignalEvent(Core::System& system, Handle event_handle) { return event->Signal(); } -Result SignalEvent32(Core::System& system, Handle event_handle) { - return SignalEvent(system, event_handle); -} - Result ClearEvent(Core::System& system, Handle event_handle) { LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); @@ -55,10 +51,6 @@ Result ClearEvent(Core::System& system, Handle event_handle) { return ResultInvalidHandle; } -Result ClearEvent32(Core::System& system, Handle event_handle) { - return ClearEvent(system, event_handle); -} - Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { LOG_DEBUG(Kernel_SVC, "called"); @@ -104,8 +96,29 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { return ResultSuccess; } -Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { - return CreateEvent(system, out_write, out_read); +Result SignalEvent64(Core::System& system, Handle event_handle) { + R_RETURN(SignalEvent(system, event_handle)); +} + +Result ClearEvent64(Core::System& system, Handle event_handle) { + R_RETURN(ClearEvent(system, event_handle)); +} + +Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle) { + R_RETURN(CreateEvent(system, out_write_handle, out_read_handle)); +} + +Result SignalEvent64From32(Core::System& system, Handle event_handle) { + R_RETURN(SignalEvent(system, event_handle)); +} + +Result ClearEvent64From32(Core::System& system, Handle event_handle) { + R_RETURN(ClearEvent(system, event_handle)); +} + +Result CreateEvent64From32(Core::System& system, Handle* out_write_handle, + Handle* out_read_handle) { + R_RETURN(CreateEvent(system, out_write_handle, out_read_handle)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index fb9f133c1..c2782908d 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp @@ -12,10 +12,10 @@ namespace Kernel::Svc { /// Break program execution -void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { +void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { BreakReason break_reason = - static_cast<BreakReason>(reason & ~static_cast<u32>(BreakReason::NotificationOnlyFlag)); - bool notification_only = (reason & static_cast<u32>(BreakReason::NotificationOnlyFlag)) != 0; + reason & static_cast<BreakReason>(~BreakReason::NotificationOnlyFlag); + bool notification_only = True(reason & BreakReason::NotificationOnlyFlag); bool has_dumped_buffer{}; std::vector<u8> debug_buffer; @@ -90,9 +90,9 @@ void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { break; } - system.GetReporter().SaveSvcBreakReport(reason, notification_only, info1, info2, - has_dumped_buffer ? std::make_optional(debug_buffer) - : std::nullopt); + system.GetReporter().SaveSvcBreakReport( + static_cast<u32>(reason), notification_only, info1, info2, + has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt); if (!notification_only) { LOG_CRITICAL( @@ -114,8 +114,24 @@ void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { } } -void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { - Break(system, reason, info1, info2); +void ReturnFromException(Core::System& system, Result result) { + UNIMPLEMENTED(); +} + +void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size) { + Break(system, break_reason, arg, size); +} + +void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size) { + Break(system, break_reason, arg, size); +} + +void ReturnFromException64(Core::System& system, Result result) { + ReturnFromException(system, result); +} + +void ReturnFromException64From32(Core::System& system, Result result) { + ReturnFromException(system, result); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index df5dd85a4..75097c7f9 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp @@ -10,11 +10,12 @@ namespace Kernel::Svc { /// Gets system/memory information for the current process -Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u64 info_sub_id) { +Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle handle, + u64 info_sub_id) { LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, info_sub_id, handle); - const auto info_id_type = static_cast<InfoType>(info_id); + u32 info_id = static_cast<u32>(info_id_type); switch (info_id_type) { case InfoType::CoreMask: @@ -267,16 +268,30 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6 } } -Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, - u32 info_id, u32 handle, u32 sub_id_high) { - const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)}; - u64 res_value{}; +Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, + uint64_t info_subtype) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, + uint64_t info_subtype) { + R_RETURN(GetInfo(system, out, info_type, handle, info_subtype)); +} - const Result result{GetInfo(system, &res_value, info_id, handle, sub_id)}; - *result_high = static_cast<u32>(res_value >> 32); - *result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max()); +Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, + uint64_t info_subtype) { + R_RETURN(GetSystemInfo(system, out, info_type, handle, info_subtype)); +} + +Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, + uint64_t info_subtype) { + R_RETURN(GetInfo(system, out, info_type, handle, info_subtype)); +} - return result; +Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type, + Handle handle, uint64_t info_subtype) { + R_RETURN(GetSystemInfo(system, out, info_type, handle, info_subtype)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_insecure_memory.cpp b/src/core/hle/kernel/svc/svc_insecure_memory.cpp new file mode 100644 index 000000000..79882685d --- /dev/null +++ b/src/core/hle/kernel/svc/svc_insecure_memory.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" + +namespace Kernel::Svc { + +Result MapInsecureMemory(Core::System& system, uintptr_t address, size_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result UnmapInsecureMemory(Core::System& system, uintptr_t address, size_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size) { + R_RETURN(MapInsecureMemory(system, address, size)); +} + +Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size) { + R_RETURN(UnmapInsecureMemory(system, address, size)); +} + +Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(MapInsecureMemory(system, address, size)); +} + +Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(UnmapInsecureMemory(system, address, size)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_interrupt_event.cpp b/src/core/hle/kernel/svc/svc_interrupt_event.cpp index 299e22ae6..768b30a1f 100644 --- a/src/core/hle/kernel/svc/svc_interrupt_event.cpp +++ b/src/core/hle/kernel/svc/svc_interrupt_event.cpp @@ -2,5 +2,24 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result CreateInterruptEvent(Core::System& system, Handle* out, int32_t interrupt_id, + InterruptType type) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, + InterruptType interrupt_type) { + R_RETURN(CreateInterruptEvent(system, out_read_handle, interrupt_id, interrupt_type)); +} + +Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, + int32_t interrupt_id, InterruptType interrupt_type) { + R_RETURN(CreateInterruptEvent(system, out_read_handle, interrupt_id, interrupt_type)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_io_pool.cpp b/src/core/hle/kernel/svc/svc_io_pool.cpp index 299e22ae6..33f3d69bf 100644 --- a/src/core/hle/kernel/svc/svc_io_pool.cpp +++ b/src/core/hle/kernel/svc/svc_io_pool.cpp @@ -2,5 +2,70 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result CreateIoPool(Core::System& system, Handle* out, IoPoolType pool_type) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result CreateIoRegion(Core::System& system, Handle* out, Handle io_pool_handle, uint64_t phys_addr, + size_t size, MemoryMapping mapping, MemoryPermission perm) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result MapIoRegion(Core::System& system, Handle io_region_handle, uintptr_t address, size_t size, + MemoryPermission map_perm) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result UnmapIoRegion(Core::System& system, Handle io_region_handle, uintptr_t address, + size_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType pool_type) { + R_RETURN(CreateIoPool(system, out_handle, pool_type)); +} + +Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool, + uint64_t physical_address, uint64_t size, MemoryMapping mapping, + MemoryPermission perm) { + R_RETURN(CreateIoRegion(system, out_handle, io_pool, physical_address, size, mapping, perm)); +} + +Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size, + MemoryPermission perm) { + R_RETURN(MapIoRegion(system, io_region, address, size, perm)); +} + +Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size) { + R_RETURN(UnmapIoRegion(system, io_region, address, size)); +} + +Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType pool_type) { + R_RETURN(CreateIoPool(system, out_handle, pool_type)); +} + +Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool, + uint64_t physical_address, uint32_t size, MemoryMapping mapping, + MemoryPermission perm) { + R_RETURN(CreateIoRegion(system, out_handle, io_pool, physical_address, size, mapping, perm)); +} + +Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size, + MemoryPermission perm) { + R_RETURN(MapIoRegion(system, io_region, address, size, perm)); +} + +Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, + uint32_t size) { + R_RETURN(UnmapIoRegion(system, io_region, address, size)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index dbb68e89a..97ce49dde 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp @@ -24,20 +24,37 @@ Result SendSyncRequest(Core::System& system, Handle handle) { return session->SendSyncRequest(); } -Result SendSyncRequest32(Core::System& system, Handle handle) { - return SendSyncRequest(system, handle); +Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer, + uint64_t message_buffer_size, Handle session_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); } -Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s32 num_handles, +Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle, + uint64_t message_buffer, uint64_t message_buffer_size, + Handle session_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_addr, s32 num_handles, Handle reply_target, s64 timeout_ns) { auto& kernel = system.Kernel(); auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable(); + R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); + R_UNLESS(system.Memory().IsValidVirtualAddressRange( + handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), + ResultInvalidPointer); + + std::vector<Handle> handles(num_handles); + system.Memory().ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); + // Convert handle list to object table. std::vector<KSynchronizationObject*> objs(num_handles); - R_UNLESS( - handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles), - ResultInvalidHandle); + R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), + num_handles), + ResultInvalidHandle); // Ensure handles are closed when we're done. SCOPE_EXIT({ @@ -86,4 +103,72 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s3 } } +Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index, + uint64_t message_buffer, uint64_t message_buffer_size, + uint64_t handles, int32_t num_handles, Handle reply_target, + int64_t timeout_ns) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SendSyncRequest64(Core::System& system, Handle session_handle) { + R_RETURN(SendSyncRequest(system, session_handle)); +} + +Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer, + uint64_t message_buffer_size, Handle session_handle) { + R_RETURN( + SendSyncRequestWithUserBuffer(system, message_buffer, message_buffer_size, session_handle)); +} + +Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle, + uint64_t message_buffer, uint64_t message_buffer_size, + Handle session_handle) { + R_RETURN(SendAsyncRequestWithUserBuffer(system, out_event_handle, message_buffer, + message_buffer_size, session_handle)); +} + +Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles, + int32_t num_handles, Handle reply_target, int64_t timeout_ns) { + R_RETURN(ReplyAndReceive(system, out_index, handles, num_handles, reply_target, timeout_ns)); +} + +Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index, + uint64_t message_buffer, uint64_t message_buffer_size, + uint64_t handles, int32_t num_handles, Handle reply_target, + int64_t timeout_ns) { + R_RETURN(ReplyAndReceiveWithUserBuffer(system, out_index, message_buffer, message_buffer_size, + handles, num_handles, reply_target, timeout_ns)); +} + +Result SendSyncRequest64From32(Core::System& system, Handle session_handle) { + R_RETURN(SendSyncRequest(system, session_handle)); +} + +Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer, + uint32_t message_buffer_size, Handle session_handle) { + R_RETURN( + SendSyncRequestWithUserBuffer(system, message_buffer, message_buffer_size, session_handle)); +} + +Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle, + uint32_t message_buffer, uint32_t message_buffer_size, + Handle session_handle) { + R_RETURN(SendAsyncRequestWithUserBuffer(system, out_event_handle, message_buffer, + message_buffer_size, session_handle)); +} + +Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles, + int32_t num_handles, Handle reply_target, int64_t timeout_ns) { + R_RETURN(ReplyAndReceive(system, out_index, handles, num_handles, reply_target, timeout_ns)); +} + +Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index, + uint32_t message_buffer, uint32_t message_buffer_size, + uint32_t handles, int32_t num_handles, + Handle reply_target, int64_t timeout_ns) { + R_RETURN(ReplyAndReceiveWithUserBuffer(system, out_index, message_buffer, message_buffer_size, + handles, num_handles, reply_target, timeout_ns)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_kernel_debug.cpp b/src/core/hle/kernel/svc/svc_kernel_debug.cpp index 454255e7a..cee048279 100644 --- a/src/core/hle/kernel/svc/svc_kernel_debug.cpp +++ b/src/core/hle/kernel/svc/svc_kernel_debug.cpp @@ -5,15 +5,31 @@ namespace Kernel::Svc { -void KernelDebug([[maybe_unused]] Core::System& system, [[maybe_unused]] u32 kernel_debug_type, - [[maybe_unused]] u64 param1, [[maybe_unused]] u64 param2, - [[maybe_unused]] u64 param3) { +void KernelDebug(Core::System& system, KernelDebugType kernel_debug_type, u64 arg0, u64 arg1, + u64 arg2) { // Intentionally do nothing, as this does nothing in released kernel binaries. } -void ChangeKernelTraceState([[maybe_unused]] Core::System& system, - [[maybe_unused]] u32 trace_state) { +void ChangeKernelTraceState(Core::System& system, KernelTraceState trace_state) { // Intentionally do nothing, as this does nothing in released kernel binaries. } +void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, + uint64_t arg1, uint64_t arg2) { + KernelDebug(system, kern_debug_type, arg0, arg1, arg2); +} + +void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state) { + ChangeKernelTraceState(system, kern_trace_state); +} + +void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, + uint64_t arg1, uint64_t arg2) { + KernelDebug(system, kern_debug_type, arg0, arg1, arg2); +} + +void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state) { + ChangeKernelTraceState(system, kern_trace_state); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_light_ipc.cpp b/src/core/hle/kernel/svc/svc_light_ipc.cpp index 299e22ae6..b76ce984c 100644 --- a/src/core/hle/kernel/svc/svc_light_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_light_ipc.cpp @@ -1,6 +1,73 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/arm/arm_interface.h" +#include "core/core.h" #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SendSyncRequestLight64(Core::System& system, Handle session_handle, u32* args) { + R_RETURN(SendSyncRequestLight(system, session_handle, args)); +} + +Result ReplyAndReceiveLight64(Core::System& system, Handle session_handle, u32* args) { + R_RETURN(ReplyAndReceiveLight(system, session_handle, args)); +} + +Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, u32* args) { + R_RETURN(SendSyncRequestLight(system, session_handle, args)); +} + +Result ReplyAndReceiveLight64From32(Core::System& system, Handle session_handle, u32* args) { + R_RETURN(ReplyAndReceiveLight(system, session_handle, args)); +} + +// Custom ABI implementation for light IPC. + +template <typename F> +static void SvcWrap_LightIpc(Core::System& system, F&& cb) { + auto& core = system.CurrentArmInterface(); + std::array<u32, 7> arguments{}; + + Handle session_handle = static_cast<Handle>(core.GetReg(0)); + for (int i = 0; i < 7; i++) { + arguments[i] = static_cast<u32>(core.GetReg(i + 1)); + } + + Result ret = cb(system, session_handle, arguments.data()); + + core.SetReg(0, ret.raw); + for (int i = 0; i < 7; i++) { + core.SetReg(i + 1, arguments[i]); + } +} + +void SvcWrap_SendSyncRequestLight64(Core::System& system) { + SvcWrap_LightIpc(system, SendSyncRequestLight64); +} + +void SvcWrap_ReplyAndReceiveLight64(Core::System& system) { + SvcWrap_LightIpc(system, ReplyAndReceiveLight64); +} + +void SvcWrap_SendSyncRequestLight64From32(Core::System& system) { + SvcWrap_LightIpc(system, SendSyncRequestLight64From32); +} + +void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system) { + SvcWrap_LightIpc(system, ReplyAndReceiveLight64From32); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_lock.cpp b/src/core/hle/kernel/svc/svc_lock.cpp index 45f2a6553..7005ac30b 100644 --- a/src/core/hle/kernel/svc/svc_lock.cpp +++ b/src/core/hle/kernel/svc/svc_lock.cpp @@ -27,10 +27,6 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag); } -Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag) { - return ArbitrateLock(system, thread_handle, address, tag); -} - /// Unlock a mutex Result ArbitrateUnlock(Core::System& system, VAddr address) { LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); @@ -50,8 +46,21 @@ Result ArbitrateUnlock(Core::System& system, VAddr address) { return system.Kernel().CurrentProcess()->SignalToAddress(address); } -Result ArbitrateUnlock32(Core::System& system, u32 address) { - return ArbitrateUnlock(system, address); +Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag) { + R_RETURN(ArbitrateLock(system, thread_handle, address, tag)); +} + +Result ArbitrateUnlock64(Core::System& system, uint64_t address) { + R_RETURN(ArbitrateUnlock(system, address)); +} + +Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address, + uint32_t tag) { + R_RETURN(ArbitrateLock(system, thread_handle, address, tag)); +} + +Result ArbitrateUnlock64From32(Core::System& system, uint32_t address) { + R_RETURN(ArbitrateUnlock(system, address)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp index f78b1239b..21f818da6 100644 --- a/src/core/hle/kernel/svc/svc_memory.cpp +++ b/src/core/hle/kernel/svc/svc_memory.cpp @@ -144,10 +144,6 @@ Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mas return page_table.SetMemoryAttribute(address, size, mask, attr); } -Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, u32 attr) { - return SetMemoryAttribute(system, address, size, mask, attr); -} - /// Maps a memory range into a different range. Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, @@ -163,10 +159,6 @@ Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) return page_table.MapMemory(dst_addr, src_addr, size); } -Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { - return MapMemory(system, dst_addr, src_addr, size); -} - /// Unmaps a region that was previously mapped with svcMapMemory Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, @@ -182,8 +174,44 @@ Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 siz return page_table.UnmapMemory(dst_addr, src_addr, size); } -Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { - return UnmapMemory(system, dst_addr, src_addr, size); +Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, + MemoryPermission perm) { + R_RETURN(SetMemoryPermission(system, address, size, perm)); +} + +Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, + uint32_t attr) { + R_RETURN(SetMemoryAttribute(system, address, size, mask, attr)); +} + +Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, + uint64_t size) { + R_RETURN(MapMemory(system, dst_address, src_address, size)); +} + +Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, + uint64_t size) { + R_RETURN(UnmapMemory(system, dst_address, src_address, size)); +} + +Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, + MemoryPermission perm) { + R_RETURN(SetMemoryPermission(system, address, size, perm)); +} + +Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, + uint32_t mask, uint32_t attr) { + R_RETURN(SetMemoryAttribute(system, address, size, mask, attr)); +} + +Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, + uint32_t size) { + R_RETURN(MapMemory(system, dst_address, src_address, size)); +} + +Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, + uint32_t size) { + R_RETURN(UnmapMemory(system, dst_address, src_address, size)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp index 0fc262203..8d00e1fc3 100644 --- a/src/core/hle/kernel/svc/svc_physical_memory.cpp +++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp @@ -21,13 +21,6 @@ Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { return ResultSuccess; } -Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) { - VAddr temp_heap_addr{}; - const Result result{SetHeapSize(system, &temp_heap_addr, heap_size)}; - *heap_addr = static_cast<u32>(temp_heap_addr); - return result; -} - /// Maps memory at a desired address Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); @@ -77,10 +70,6 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { return page_table.MapPhysicalMemory(addr, size); } -Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { - return MapPhysicalMemory(system, addr, size); -} - /// Unmaps memory previously mapped via MapPhysicalMemory Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); @@ -130,8 +119,67 @@ Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { return page_table.UnmapPhysicalMemory(addr, size); } -Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { - return UnmapPhysicalMemory(system, addr, size); +Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SetUnsafeLimit(Core::System& system, uint64_t limit) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size) { + R_RETURN(SetHeapSize(system, out_address, size)); +} + +Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size) { + R_RETURN(MapPhysicalMemory(system, address, size)); +} + +Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size) { + R_RETURN(UnmapPhysicalMemory(system, address, size)); +} + +Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size) { + R_RETURN(MapPhysicalMemoryUnsafe(system, address, size)); +} + +Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size) { + R_RETURN(UnmapPhysicalMemoryUnsafe(system, address, size)); +} + +Result SetUnsafeLimit64(Core::System& system, uint64_t limit) { + R_RETURN(SetUnsafeLimit(system, limit)); +} + +Result SetHeapSize64From32(Core::System& system, uintptr_t* out_address, uint32_t size) { + R_RETURN(SetHeapSize(system, out_address, size)); +} + +Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(MapPhysicalMemory(system, address, size)); +} + +Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(UnmapPhysicalMemory(system, address, size)); +} + +Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(MapPhysicalMemoryUnsafe(system, address, size)); +} + +Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size) { + R_RETURN(UnmapPhysicalMemoryUnsafe(system, address, size)); +} + +Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit) { + R_RETURN(SetUnsafeLimit(system, limit)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index cdfe0dd16..2e5d228bb 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp @@ -63,9 +63,60 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_add return ResultSuccess; } -Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, u32 port_name_address) { +Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, + int32_t max_sessions, bool is_light, uintptr_t name) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, + int32_t max_sessions) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) { + R_RETURN(ConnectToNamedPort(system, out_handle, name)); +} + +Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, + int32_t max_sessions, bool is_light, uint64_t name) { + R_RETURN( + CreatePort(system, out_server_handle, out_client_handle, max_sessions, is_light, name)); +} + +Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name, + int32_t max_sessions) { + R_RETURN(ManageNamedPort(system, out_server_handle, name, max_sessions)); +} + +Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port) { + R_RETURN(ConnectToPort(system, out_handle, port)); +} + +Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name) { + R_RETURN(ConnectToNamedPort(system, out_handle, name)); +} + +Result CreatePort64From32(Core::System& system, Handle* out_server_handle, + Handle* out_client_handle, int32_t max_sessions, bool is_light, + uint32_t name) { + R_RETURN( + CreatePort(system, out_server_handle, out_client_handle, max_sessions, is_light, name)); +} + +Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name, + int32_t max_sessions) { + R_RETURN(ManageNamedPort(system, out_server_handle, name, max_sessions)); +} - return ConnectToNamedPort(system, out_handle, port_name_address); +Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port) { + R_RETURN(ConnectToPort(system, out_handle, port)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_power_management.cpp b/src/core/hle/kernel/svc/svc_power_management.cpp index 299e22ae6..f605a0317 100644 --- a/src/core/hle/kernel/svc/svc_power_management.cpp +++ b/src/core/hle/kernel/svc/svc_power_management.cpp @@ -2,5 +2,20 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +void SleepSystem(Core::System& system) { + UNIMPLEMENTED(); +} + +void SleepSystem64(Core::System& system) { + return SleepSystem(system); +} + +void SleepSystem64From32(Core::System& system) { + return SleepSystem(system); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp index d6c8b4561..d2c20aad2 100644 --- a/src/core/hle/kernel/svc/svc_process.cpp +++ b/src/core/hle/kernel/svc/svc_process.cpp @@ -18,10 +18,6 @@ void ExitProcess(Core::System& system) { system.Exit(); } -void ExitProcess32(Core::System& system) { - ExitProcess(system); -} - /// Gets the ID of the specified process or a specified thread's owning process. Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); @@ -54,17 +50,8 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { return ResultSuccess; } -Result GetProcessId32(Core::System& system, u32* out_process_id_low, u32* out_process_id_high, - Handle handle) { - u64 out_process_id{}; - const auto result = GetProcessId(system, &out_process_id, handle); - *out_process_id_low = static_cast<u32>(out_process_id); - *out_process_id_high = static_cast<u32>(out_process_id >> 32); - return result; -} - -Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids, - u32 out_process_ids_size) { +Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_process_ids, + int32_t out_process_ids_size) { LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", out_process_ids, out_process_ids_size); @@ -89,7 +76,8 @@ Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_pr auto& memory = system.Memory(); const auto& process_list = kernel.GetProcessList(); const auto num_processes = process_list.size(); - const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); + const auto copy_amount = + std::min(static_cast<std::size_t>(out_process_ids_size), num_processes); for (std::size_t i = 0; i < copy_amount; ++i) { memory.Write64(out_process_ids, process_list[i]->GetProcessID()); @@ -100,8 +88,9 @@ Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_pr return ResultSuccess; } -Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { - LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); +Result GetProcessInfo(Core::System& system, s64* out, Handle process_handle, + ProcessInfoType info_type) { + LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, info_type); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); @@ -111,14 +100,95 @@ Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 return ResultInvalidHandle; } - const auto info_type = static_cast<ProcessInfoType>(type); if (info_type != ProcessInfoType::ProcessState) { - LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead", type); + LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead", + info_type); return ResultInvalidEnumValue; } - *out = static_cast<u64>(process->GetState()); + *out = static_cast<s64>(process->GetState()); return ResultSuccess; } +Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, + int32_t num_caps) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, + uint64_t main_thread_stack_size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result TerminateProcess(Core::System& system, Handle process_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +void ExitProcess64(Core::System& system) { + ExitProcess(system); +} + +Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle) { + R_RETURN(GetProcessId(system, out_process_id, process_handle)); +} + +Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, + int32_t max_out_count) { + R_RETURN(GetProcessList(system, out_num_processes, out_process_ids, max_out_count)); +} + +Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, + int32_t num_caps) { + R_RETURN(CreateProcess(system, out_handle, parameters, caps, num_caps)); +} + +Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority, + int32_t core_id, uint64_t main_thread_stack_size) { + R_RETURN(StartProcess(system, process_handle, priority, core_id, main_thread_stack_size)); +} + +Result TerminateProcess64(Core::System& system, Handle process_handle) { + R_RETURN(TerminateProcess(system, process_handle)); +} + +Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle, + ProcessInfoType info_type) { + R_RETURN(GetProcessInfo(system, out_info, process_handle, info_type)); +} + +void ExitProcess64From32(Core::System& system) { + ExitProcess(system); +} + +Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle) { + R_RETURN(GetProcessId(system, out_process_id, process_handle)); +} + +Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes, + uint32_t out_process_ids, int32_t max_out_count) { + R_RETURN(GetProcessList(system, out_num_processes, out_process_ids, max_out_count)); +} + +Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters, + uint32_t caps, int32_t num_caps) { + R_RETURN(CreateProcess(system, out_handle, parameters, caps, num_caps)); +} + +Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority, + int32_t core_id, uint64_t main_thread_stack_size) { + R_RETURN(StartProcess(system, process_handle, priority, core_id, main_thread_stack_size)); +} + +Result TerminateProcess64From32(Core::System& system, Handle process_handle) { + R_RETURN(TerminateProcess(system, process_handle)); +} + +Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle, + ProcessInfoType info_type) { + R_RETURN(GetProcessInfo(system, out_info, process_handle, info_type)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp index b6ac43af2..dbe24e139 100644 --- a/src/core/hle/kernel/svc/svc_process_memory.cpp +++ b/src/core/hle/kernel/svc/svc_process_memory.cpp @@ -271,4 +271,54 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d KPageTable::ICacheInvalidationStrategy::InvalidateAll); } +Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address, + uint64_t size, MemoryPermission perm) { + R_RETURN(SetProcessMemoryPermission(system, process_handle, address, size, perm)); +} + +Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, + uint64_t src_address, uint64_t size) { + R_RETURN(MapProcessMemory(system, dst_address, process_handle, src_address, size)); +} + +Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, + uint64_t src_address, uint64_t size) { + R_RETURN(UnmapProcessMemory(system, dst_address, process_handle, src_address, size)); +} + +Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, + uint64_t src_address, uint64_t size) { + R_RETURN(MapProcessCodeMemory(system, process_handle, dst_address, src_address, size)); +} + +Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, + uint64_t src_address, uint64_t size) { + R_RETURN(UnmapProcessCodeMemory(system, process_handle, dst_address, src_address, size)); +} + +Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle, + uint64_t address, uint64_t size, MemoryPermission perm) { + R_RETURN(SetProcessMemoryPermission(system, process_handle, address, size, perm)); +} + +Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, + uint64_t src_address, uint32_t size) { + R_RETURN(MapProcessMemory(system, dst_address, process_handle, src_address, size)); +} + +Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, + uint64_t src_address, uint32_t size) { + R_RETURN(UnmapProcessMemory(system, dst_address, process_handle, src_address, size)); +} + +Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle, + uint64_t dst_address, uint64_t src_address, uint64_t size) { + R_RETURN(MapProcessCodeMemory(system, process_handle, dst_address, src_address, size)); +} + +Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle, + uint64_t dst_address, uint64_t src_address, uint64_t size) { + R_RETURN(UnmapProcessCodeMemory(system, process_handle, dst_address, src_address, size)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_processor.cpp b/src/core/hle/kernel/svc/svc_processor.cpp index 8561cf74f..7602ce6c0 100644 --- a/src/core/hle/kernel/svc/svc_processor.cpp +++ b/src/core/hle/kernel/svc/svc_processor.cpp @@ -9,12 +9,16 @@ namespace Kernel::Svc { /// Get which CPU core is executing the current thread -u32 GetCurrentProcessorNumber(Core::System& system) { +int32_t GetCurrentProcessorNumber(Core::System& system) { LOG_TRACE(Kernel_SVC, "called"); - return static_cast<u32>(system.CurrentPhysicalCore().CoreIndex()); + return static_cast<int32_t>(system.CurrentPhysicalCore().CoreIndex()); } -u32 GetCurrentProcessorNumber32(Core::System& system) { +int32_t GetCurrentProcessorNumber64(Core::System& system) { + return GetCurrentProcessorNumber(system); +} + +int32_t GetCurrentProcessorNumber64From32(Core::System& system) { return GetCurrentProcessorNumber(system); } diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp index aac3b2eca..db140a341 100644 --- a/src/core/hle/kernel/svc/svc_query_memory.cpp +++ b/src/core/hle/kernel/svc/svc_query_memory.cpp @@ -7,24 +7,20 @@ namespace Kernel::Svc { -Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, +Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, VAddr query_address) { LOG_TRACE(Kernel_SVC, - "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " + "called, out_memory_info=0x{:016X}, " "query_address=0x{:016X}", - memory_info_address, page_info_address, query_address); + out_memory_info, query_address); - return QueryProcessMemory(system, memory_info_address, page_info_address, CurrentProcess, + // Query memory is just QueryProcessMemory on the current process. + return QueryProcessMemory(system, out_memory_info, out_page_info, CurrentProcess, query_address); } -Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address, - u32 query_address) { - return QueryMemory(system, memory_info_address, page_info_address, query_address); -} - -Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, - Handle process_handle, VAddr address) { +Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, + Handle process_handle, uint64_t address) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); @@ -37,19 +33,33 @@ Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr auto& memory{system.Memory()}; const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; - memory.Write64(memory_info_address + 0x00, memory_info.base_address); - memory.Write64(memory_info_address + 0x08, memory_info.size); - memory.Write32(memory_info_address + 0x10, static_cast<u32>(memory_info.state) & 0xff); - memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attribute)); - memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.permission)); - memory.Write32(memory_info_address + 0x1c, memory_info.ipc_count); - memory.Write32(memory_info_address + 0x20, memory_info.device_count); - memory.Write32(memory_info_address + 0x24, 0); + memory.WriteBlock(out_memory_info, &memory_info, sizeof(memory_info)); + + //! This is supposed to be part of the QueryInfo call. + *out_page_info = {}; + + R_SUCCEED(); +} + +Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, + uint64_t address) { + R_RETURN(QueryMemory(system, out_memory_info, out_page_info, address)); +} - // Page info appears to be currently unused by the kernel and is always set to zero. - memory.Write32(page_info_address, 0); +Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, + Handle process_handle, uint64_t address) { + R_RETURN(QueryProcessMemory(system, out_memory_info, out_page_info, process_handle, address)); +} + +Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, + uint32_t address) { + R_RETURN(QueryMemory(system, out_memory_info, out_page_info, address)); +} - return ResultSuccess; +Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info, + PageInfo* out_page_info, Handle process_handle, + uint64_t address) { + R_RETURN(QueryProcessMemory(system, out_memory_info, out_page_info, process_handle, address)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_register.cpp b/src/core/hle/kernel/svc/svc_register.cpp index 299e22ae6..b883e6618 100644 --- a/src/core/hle/kernel/svc/svc_register.cpp +++ b/src/core/hle/kernel/svc/svc_register.cpp @@ -2,5 +2,26 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result ReadWriteRegister(Core::System& system, uint32_t* out, uint64_t address, uint32_t mask, + uint32_t value) { + *out = 0; + + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address, + uint32_t mask, uint32_t value) { + R_RETURN(ReadWriteRegister(system, out_value, address, mask, value)); +} + +Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address, + uint32_t mask, uint32_t value) { + R_RETURN(ReadWriteRegister(system, out_value, address, mask, value)); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_resource_limit.cpp b/src/core/hle/kernel/svc/svc_resource_limit.cpp index 679ba10fa..ebc886028 100644 --- a/src/core/hle/kernel/svc/svc_resource_limit.cpp +++ b/src/core/hle/kernel/svc/svc_resource_limit.cpp @@ -32,7 +32,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) { return ResultSuccess; } -Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, +Result GetResourceLimitLimitValue(Core::System& system, s64* out_limit_value, Handle resource_limit_handle, LimitableResource which) { LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, which); @@ -52,7 +52,7 @@ Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, return ResultSuccess; } -Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, +Result GetResourceLimitCurrentValue(Core::System& system, s64* out_current_value, Handle resource_limit_handle, LimitableResource which) { LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, which); @@ -73,7 +73,7 @@ Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value } Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, - LimitableResource which, u64 limit_value) { + LimitableResource which, s64 limit_value) { LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", resource_limit_handle, which, limit_value); @@ -92,4 +92,58 @@ Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_ha return ResultSuccess; } +Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value, + Handle resource_limit_handle, LimitableResource which) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, + Handle resource_limit_handle, LimitableResource which) { + R_RETURN(GetResourceLimitLimitValue(system, out_limit_value, resource_limit_handle, which)); +} + +Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, + Handle resource_limit_handle, LimitableResource which) { + R_RETURN(GetResourceLimitCurrentValue(system, out_current_value, resource_limit_handle, which)); +} + +Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value, + Handle resource_limit_handle, LimitableResource which) { + R_RETURN(GetResourceLimitPeakValue(system, out_peak_value, resource_limit_handle, which)); +} + +Result CreateResourceLimit64(Core::System& system, Handle* out_handle) { + R_RETURN(CreateResourceLimit(system, out_handle)); +} + +Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle, + LimitableResource which, int64_t limit_value) { + R_RETURN(SetResourceLimitLimitValue(system, resource_limit_handle, which, limit_value)); +} + +Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, + Handle resource_limit_handle, LimitableResource which) { + R_RETURN(GetResourceLimitLimitValue(system, out_limit_value, resource_limit_handle, which)); +} + +Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, + Handle resource_limit_handle, LimitableResource which) { + R_RETURN(GetResourceLimitCurrentValue(system, out_current_value, resource_limit_handle, which)); +} + +Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value, + Handle resource_limit_handle, LimitableResource which) { + R_RETURN(GetResourceLimitPeakValue(system, out_peak_value, resource_limit_handle, which)); +} + +Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle) { + R_RETURN(CreateResourceLimit(system, out_handle)); +} + +Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle, + LimitableResource which, int64_t limit_value) { + R_RETURN(SetResourceLimitLimitValue(system, resource_limit_handle, which, limit_value)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp b/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp index 299e22ae6..20f6ec643 100644 --- a/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp +++ b/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp @@ -1,6 +1,53 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/core.h" +#include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/svc.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args) { + UNIMPLEMENTED(); +} + +void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args) { + CallSecureMonitor(system, args); +} + +void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args) { + // CallSecureMonitor64From32 is not supported. + UNIMPLEMENTED_MSG("CallSecureMonitor64From32"); +} + +// Custom ABI for CallSecureMonitor. + +void SvcWrap_CallSecureMonitor64(Core::System& system) { + auto& core = system.CurrentPhysicalCore().ArmInterface(); + lp64::SecureMonitorArguments args{}; + for (int i = 0; i < 8; i++) { + args.r[i] = core.GetReg(i); + } + + CallSecureMonitor64(system, &args); + + for (int i = 0; i < 8; i++) { + core.SetReg(i, args.r[i]); + } +} + +void SvcWrap_CallSecureMonitor64From32(Core::System& system) { + auto& core = system.CurrentPhysicalCore().ArmInterface(); + ilp32::SecureMonitorArguments args{}; + for (int i = 0; i < 8; i++) { + args.r[i] = static_cast<u32>(core.GetReg(i)); + } + + CallSecureMonitor64From32(system, &args); + + for (int i = 0; i < 8; i++) { + core.SetReg(i, args.r[i]); + } +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_session.cpp b/src/core/hle/kernel/svc/svc_session.cpp index dac8ce33c..0deb61b62 100644 --- a/src/core/hle/kernel/svc/svc_session.cpp +++ b/src/core/hle/kernel/svc/svc_session.cpp @@ -90,14 +90,39 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien } // namespace -Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u32 is_light, +Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, bool is_light, u64 name) { if (is_light) { // return CreateSession<KLightSession>(system, out_server, out_client, name); - return ResultUnknown; + return ResultNotImplemented; } else { return CreateSession<KSession>(system, out_server, out_client, name); } } +Result AcceptSession(Core::System& system, Handle* out_handle, Handle port_handle) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result CreateSession64(Core::System& system, Handle* out_server_session_handle, + Handle* out_client_session_handle, bool is_light, uint64_t name) { + R_RETURN(CreateSession(system, out_server_session_handle, out_client_session_handle, is_light, + name)); +} + +Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port) { + R_RETURN(AcceptSession(system, out_handle, port)); +} + +Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle, + Handle* out_client_session_handle, bool is_light, uint32_t name) { + R_RETURN(CreateSession(system, out_server_session_handle, out_client_session_handle, is_light, + name)); +} + +Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port) { + R_RETURN(AcceptSession(system, out_handle, port)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_shared_memory.cpp b/src/core/hle/kernel/svc/svc_shared_memory.cpp index d465bcbe7..40d6260e3 100644 --- a/src/core/hle/kernel/svc/svc_shared_memory.cpp +++ b/src/core/hle/kernel/svc/svc_shared_memory.cpp @@ -67,11 +67,6 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, return ResultSuccess; } -Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size, - Svc::MemoryPermission map_perm) { - return MapSharedMemory(system, shmem_handle, address, size, map_perm); -} - Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size) { // Validate the address/size. R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); @@ -99,8 +94,40 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr addres return ResultSuccess; } -Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size) { - return UnmapSharedMemory(system, shmem_handle, address, size); +Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size, + MemoryPermission owner_perm, MemoryPermission remote_perm) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, + MemoryPermission map_perm) { + R_RETURN(MapSharedMemory(system, shmem_handle, address, size, map_perm)); +} + +Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, + uint64_t size) { + R_RETURN(UnmapSharedMemory(system, shmem_handle, address, size)); +} + +Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size, + MemoryPermission owner_perm, MemoryPermission remote_perm) { + R_RETURN(CreateSharedMemory(system, out_handle, size, owner_perm, remote_perm)); +} + +Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, + uint32_t size, MemoryPermission map_perm) { + R_RETURN(MapSharedMemory(system, shmem_handle, address, size, map_perm)); +} + +Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, + uint32_t size) { + R_RETURN(UnmapSharedMemory(system, shmem_handle, address, size)); +} + +Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size, + MemoryPermission owner_perm, MemoryPermission remote_perm) { + R_RETURN(CreateSharedMemory(system, out_handle, size, owner_perm, remote_perm)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 1bf6a612a..e516a3800 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp @@ -20,10 +20,6 @@ Result CloseHandle(Core::System& system, Handle handle) { return ResultSuccess; } -Result CloseHandle32(Core::System& system, Handle handle) { - return CloseHandle(system, handle); -} - /// Clears the signaled state of an event or process. Result ResetSignal(Core::System& system, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); @@ -52,10 +48,6 @@ Result ResetSignal(Core::System& system, Handle handle) { return ResultInvalidHandle; } -Result ResetSignal32(Core::System& system, Handle handle) { - return ResetSignal(system, handle); -} - /// Wait for the given handles to synchronize, timeout after the specified nanoseconds Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, s64 nano_seconds) { @@ -93,12 +85,6 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre nano_seconds); } -Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, - s32 num_handles, u32 timeout_high, s32* index) { - const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; - return WaitSynchronization(system, index, handles_address, num_handles, nano_seconds); -} - /// Resumes a thread waiting on WaitSynchronization Result CancelSynchronization(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); @@ -113,10 +99,6 @@ Result CancelSynchronization(Core::System& system, Handle handle) { return ResultSuccess; } -Result CancelSynchronization32(Core::System& system, Handle handle) { - return CancelSynchronization(system, handle); -} - void SynchronizePreemptionState(Core::System& system) { auto& kernel = system.Kernel(); @@ -136,4 +118,46 @@ void SynchronizePreemptionState(Core::System& system) { } } +Result CloseHandle64(Core::System& system, Handle handle) { + R_RETURN(CloseHandle(system, handle)); +} + +Result ResetSignal64(Core::System& system, Handle handle) { + R_RETURN(ResetSignal(system, handle)); +} + +Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles, + int32_t num_handles, int64_t timeout_ns) { + R_RETURN(WaitSynchronization(system, out_index, handles, num_handles, timeout_ns)); +} + +Result CancelSynchronization64(Core::System& system, Handle handle) { + R_RETURN(CancelSynchronization(system, handle)); +} + +void SynchronizePreemptionState64(Core::System& system) { + SynchronizePreemptionState(system); +} + +Result CloseHandle64From32(Core::System& system, Handle handle) { + R_RETURN(CloseHandle(system, handle)); +} + +Result ResetSignal64From32(Core::System& system, Handle handle) { + R_RETURN(ResetSignal(system, handle)); +} + +Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles, + int32_t num_handles, int64_t timeout_ns) { + R_RETURN(WaitSynchronization(system, out_index, handles, num_handles, timeout_ns)); +} + +Result CancelSynchronization64From32(Core::System& system, Handle handle) { + R_RETURN(CancelSynchronization(system, handle)); +} + +void SynchronizePreemptionState64From32(Core::System& system) { + SynchronizePreemptionState(system); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index dd9f8e8b1..3e325c998 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -20,7 +20,7 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) { /// Creates a new thread Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, - VAddr stack_bottom, u32 priority, s32 core_id) { + VAddr stack_bottom, s32 priority, s32 core_id) { LOG_DEBUG(Kernel_SVC, "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, " "priority=0x{:08X}, core_id=0x{:08X}", @@ -91,11 +91,6 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, return ResultSuccess; } -Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, u32 entry_point, - u32 arg, u32 stack_top, s32 processor_id) { - return CreateThread(system, out_handle, entry_point, arg, stack_top, priority, processor_id); -} - /// Starts the thread for the provided handle Result StartThread(Core::System& system, Handle thread_handle) { LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); @@ -115,10 +110,6 @@ Result StartThread(Core::System& system, Handle thread_handle) { return ResultSuccess; } -Result StartThread32(Core::System& system, Handle thread_handle) { - return StartThread(system, thread_handle); -} - /// Called when a thread exits void ExitThread(Core::System& system) { LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); @@ -129,10 +120,6 @@ void ExitThread(Core::System& system) { system.Kernel().UnregisterInUseObject(current_thread); } -void ExitThread32(Core::System& system) { - ExitThread(system); -} - /// Sleep the current thread void SleepThread(Core::System& system, s64 nanoseconds) { auto& kernel = system.Kernel(); @@ -160,13 +147,8 @@ void SleepThread(Core::System& system, s64 nanoseconds) { } } -void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high) { - const auto nanoseconds = static_cast<s64>(u64{nanoseconds_low} | (u64{nanoseconds_high} << 32)); - SleepThread(system, nanoseconds); -} - /// Gets the thread context -Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle) { +Result GetThreadContext3(Core::System& system, VAddr out_context, Handle thread_handle) { LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, thread_handle); @@ -223,12 +205,8 @@ Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_h return ResultSuccess; } -Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle) { - return GetThreadContext(system, out_context, thread_handle); -} - /// Gets the priority for the specified thread -Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) { +Result GetThreadPriority(Core::System& system, s32* out_priority, Handle handle) { LOG_TRACE(Kernel_SVC, "called"); // Get the thread from its handle. @@ -241,12 +219,8 @@ Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) return ResultSuccess; } -Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle) { - return GetThreadPriority(system, out_priority, handle); -} - /// Sets the priority for the specified thread -Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { +Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priority) { // Get the current process. KProcess& process = *system.Kernel().CurrentProcess(); @@ -264,12 +238,8 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priorit return ResultSuccess; } -Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { - return SetThreadPriority(system, thread_handle, priority); -} - -Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, - u32 out_thread_ids_size, Handle debug_handle) { +Result GetThreadList(Core::System& system, s32* out_num_threads, VAddr out_thread_ids, + s32 out_thread_ids_size, Handle debug_handle) { // TODO: Handle this case when debug events are supported. UNIMPLEMENTED_IF(debug_handle != InvalidHandle); @@ -296,7 +266,7 @@ Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_threa auto& memory = system.Memory(); const auto& thread_list = current_process->GetThreadList(); const auto num_threads = thread_list.size(); - const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); + const auto copy_amount = std::min(static_cast<std::size_t>(out_thread_ids_size), num_threads); auto list_iter = thread_list.cbegin(); for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { @@ -308,8 +278,8 @@ Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_threa return ResultSuccess; } -Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, - u64* out_affinity_mask) { +Result GetThreadCoreMask(Core::System& system, s32* out_core_id, u64* out_affinity_mask, + Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); // Get the thread from its handle. @@ -323,15 +293,6 @@ Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_co return ResultSuccess; } -Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, - u32* out_affinity_mask_low, u32* out_affinity_mask_high) { - u64 out_affinity_mask{}; - const auto result = GetThreadCoreMask(system, thread_handle, out_core_id, &out_affinity_mask); - *out_affinity_mask_high = static_cast<u32>(out_affinity_mask >> 32); - *out_affinity_mask_low = static_cast<u32>(out_affinity_mask); - return result; -} - Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, u64 affinity_mask) { // Determine the core id/affinity mask. @@ -364,12 +325,6 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id return ResultSuccess; } -Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, - u32 affinity_mask_low, u32 affinity_mask_high) { - const auto affinity_mask = u64{affinity_mask_low} | (u64{affinity_mask_high} << 32); - return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); -} - /// Get the ID for the specified thread. Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { // Get the thread from its handle. @@ -382,15 +337,101 @@ Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handl return ResultSuccess; } -Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high, - Handle thread_handle) { - u64 out_thread_id{}; - const Result result{GetThreadId(system, &out_thread_id, thread_handle)}; +Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, + uint64_t stack_bottom, int32_t priority, int32_t core_id) { + R_RETURN(CreateThread(system, out_handle, func, arg, stack_bottom, priority, core_id)); +} + +Result StartThread64(Core::System& system, Handle thread_handle) { + R_RETURN(StartThread(system, thread_handle)); +} + +void ExitThread64(Core::System& system) { + return ExitThread(system); +} + +void SleepThread64(Core::System& system, int64_t ns) { + return SleepThread(system, ns); +} + +Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle) { + R_RETURN(GetThreadPriority(system, out_priority, thread_handle)); +} + +Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority) { + R_RETURN(SetThreadPriority(system, thread_handle, priority)); +} + +Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, + Handle thread_handle) { + R_RETURN(GetThreadCoreMask(system, out_core_id, out_affinity_mask, thread_handle)); +} + +Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id, + uint64_t affinity_mask) { + R_RETURN(SetThreadCoreMask(system, thread_handle, core_id, affinity_mask)); +} + +Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle) { + R_RETURN(GetThreadId(system, out_thread_id, thread_handle)); +} + +Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle) { + R_RETURN(GetThreadContext3(system, out_context, thread_handle)); +} - *out_thread_id_low = static_cast<u32>(out_thread_id >> 32); - *out_thread_id_high = static_cast<u32>(out_thread_id & std::numeric_limits<u32>::max()); +Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, + int32_t max_out_count, Handle debug_handle) { + R_RETURN(GetThreadList(system, out_num_threads, out_thread_ids, max_out_count, debug_handle)); +} + +Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg, + uint32_t stack_bottom, int32_t priority, int32_t core_id) { + R_RETURN(CreateThread(system, out_handle, func, arg, stack_bottom, priority, core_id)); +} + +Result StartThread64From32(Core::System& system, Handle thread_handle) { + R_RETURN(StartThread(system, thread_handle)); +} + +void ExitThread64From32(Core::System& system) { + return ExitThread(system); +} + +void SleepThread64From32(Core::System& system, int64_t ns) { + return SleepThread(system, ns); +} + +Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority, + Handle thread_handle) { + R_RETURN(GetThreadPriority(system, out_priority, thread_handle)); +} + +Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority) { + R_RETURN(SetThreadPriority(system, thread_handle, priority)); +} + +Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id, + uint64_t* out_affinity_mask, Handle thread_handle) { + R_RETURN(GetThreadCoreMask(system, out_core_id, out_affinity_mask, thread_handle)); +} + +Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id, + uint64_t affinity_mask) { + R_RETURN(SetThreadCoreMask(system, thread_handle, core_id, affinity_mask)); +} + +Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle) { + R_RETURN(GetThreadId(system, out_thread_id, thread_handle)); +} + +Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle) { + R_RETURN(GetThreadContext3(system, out_context, thread_handle)); +} - return result; +Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads, + uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle) { + R_RETURN(GetThreadList(system, out_num_threads, out_thread_ids, max_out_count, debug_handle)); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_thread_profiler.cpp b/src/core/hle/kernel/svc/svc_thread_profiler.cpp index 299e22ae6..40de7708b 100644 --- a/src/core/hle/kernel/svc/svc_thread_profiler.cpp +++ b/src/core/hle/kernel/svc/svc_thread_profiler.cpp @@ -2,5 +2,59 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" -namespace Kernel::Svc {} // namespace Kernel::Svc +namespace Kernel::Svc { + +Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, + uint64_t* out_thread_id, Handle debug_handle, int64_t ns) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, + uint64_t* out_tls_address, uint32_t* out_flags) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, + uint64_t* out_thread_id, Handle debug_handle, int64_t ns) { + R_RETURN(GetDebugFutureThreadInfo(system, out_context, out_thread_id, debug_handle, ns)); +} + +Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, + uint64_t* out_tls_address, uint32_t* out_flags) { + R_RETURN(GetLastThreadInfo(system, out_context, out_tls_address, out_flags)); +} + +Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, + uint64_t* out_thread_id, Handle debug_handle, int64_t ns) { + lp64::LastThreadContext context{}; + R_TRY( + GetDebugFutureThreadInfo(system, std::addressof(context), out_thread_id, debug_handle, ns)); + + *out_context = { + .fp = static_cast<u32>(context.fp), + .sp = static_cast<u32>(context.sp), + .lr = static_cast<u32>(context.lr), + .pc = static_cast<u32>(context.pc), + }; + R_SUCCEED(); +} + +Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, + uint64_t* out_tls_address, uint32_t* out_flags) { + lp64::LastThreadContext context{}; + R_TRY(GetLastThreadInfo(system, std::addressof(context), out_tls_address, out_flags)); + + *out_context = { + .fp = static_cast<u32>(context.fp), + .sp = static_cast<u32>(context.sp), + .lr = static_cast<u32>(context.lr), + .pc = static_cast<u32>(context.pc), + }; + R_SUCCEED(); +} + +} // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_tick.cpp b/src/core/hle/kernel/svc/svc_tick.cpp index e9b4fd5a6..561336482 100644 --- a/src/core/hle/kernel/svc/svc_tick.cpp +++ b/src/core/hle/kernel/svc/svc_tick.cpp @@ -9,7 +9,7 @@ namespace Kernel::Svc { /// This returns the total CPU ticks elapsed since the CPU was powered-on -u64 GetSystemTick(Core::System& system) { +int64_t GetSystemTick(Core::System& system) { LOG_TRACE(Kernel_SVC, "called"); auto& core_timing = system.CoreTiming(); @@ -21,13 +21,15 @@ u64 GetSystemTick(Core::System& system) { core_timing.AddTicks(400U); } - return result; + return static_cast<int64_t>(result); } -void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) { - const auto time = GetSystemTick(system); - *time_low = static_cast<u32>(time); - *time_high = static_cast<u32>(time >> 32); +int64_t GetSystemTick64(Core::System& system) { + return GetSystemTick(system); +} + +int64_t GetSystemTick64From32(Core::System& system) { + return GetSystemTick(system); } } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp index b14ae24a1..a4c040e49 100644 --- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp +++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp @@ -72,8 +72,46 @@ Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u6 return ResultSuccess; } -Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, - MemoryPermission map_perm) { - return CreateTransferMemory(system, out, address, size, map_perm); +Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, + MemoryPermission owner_perm) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); } + +Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, + uint64_t size) { + UNIMPLEMENTED(); + R_THROW(ResultNotImplemented); +} + +Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, + uint64_t size, MemoryPermission owner_perm) { + R_RETURN(MapTransferMemory(system, trmem_handle, address, size, owner_perm)); +} + +Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, + uint64_t size) { + R_RETURN(UnmapTransferMemory(system, trmem_handle, address, size)); +} + +Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address, + uint64_t size, MemoryPermission map_perm) { + R_RETURN(CreateTransferMemory(system, out_handle, address, size, map_perm)); +} + +Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, + uint32_t size, MemoryPermission owner_perm) { + R_RETURN(MapTransferMemory(system, trmem_handle, address, size, owner_perm)); +} + +Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, + uint32_t size) { + R_RETURN(UnmapTransferMemory(system, trmem_handle, address, size)); +} + +Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, + uint32_t size, MemoryPermission map_perm) { + R_RETURN(CreateTransferMemory(system, out_handle, address, size, map_perm)); +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc_generator.py b/src/core/hle/kernel/svc_generator.py new file mode 100644 index 000000000..b0a5707ec --- /dev/null +++ b/src/core/hle/kernel/svc_generator.py @@ -0,0 +1,716 @@ +# SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +# SPDX-License-Identifier: GPL-2.0-or-later + +# Raw SVC definitions from the kernel. +# +# Avoid modifying the prototypes; see below for how to customize generation +# for a given typename. +SVCS = [ + [0x01, "Result SetHeapSize(Address* out_address, Size size);"], + [0x02, "Result SetMemoryPermission(Address address, Size size, MemoryPermission perm);"], + [0x03, "Result SetMemoryAttribute(Address address, Size size, uint32_t mask, uint32_t attr);"], + [0x04, "Result MapMemory(Address dst_address, Address src_address, Size size);"], + [0x05, "Result UnmapMemory(Address dst_address, Address src_address, Size size);"], + [0x06, "Result QueryMemory(Address out_memory_info, PageInfo* out_page_info, Address address);"], + [0x07, "void ExitProcess();"], + [0x08, "Result CreateThread(Handle* out_handle, ThreadFunc func, Address arg, Address stack_bottom, int32_t priority, int32_t core_id);"], + [0x09, "Result StartThread(Handle thread_handle);"], + [0x0A, "void ExitThread();"], + [0x0B, "void SleepThread(int64_t ns);"], + [0x0C, "Result GetThreadPriority(int32_t* out_priority, Handle thread_handle);"], + [0x0D, "Result SetThreadPriority(Handle thread_handle, int32_t priority);"], + [0x0E, "Result GetThreadCoreMask(int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);"], + [0x0F, "Result SetThreadCoreMask(Handle thread_handle, int32_t core_id, uint64_t affinity_mask);"], + [0x10, "int32_t GetCurrentProcessorNumber();"], + [0x11, "Result SignalEvent(Handle event_handle);"], + [0x12, "Result ClearEvent(Handle event_handle);"], + [0x13, "Result MapSharedMemory(Handle shmem_handle, Address address, Size size, MemoryPermission map_perm);"], + [0x14, "Result UnmapSharedMemory(Handle shmem_handle, Address address, Size size);"], + [0x15, "Result CreateTransferMemory(Handle* out_handle, Address address, Size size, MemoryPermission map_perm);"], + [0x16, "Result CloseHandle(Handle handle);"], + [0x17, "Result ResetSignal(Handle handle);"], + [0x18, "Result WaitSynchronization(int32_t* out_index, Address handles, int32_t num_handles, int64_t timeout_ns);"], + [0x19, "Result CancelSynchronization(Handle handle);"], + [0x1A, "Result ArbitrateLock(Handle thread_handle, Address address, uint32_t tag);"], + [0x1B, "Result ArbitrateUnlock(Address address);"], + [0x1C, "Result WaitProcessWideKeyAtomic(Address address, Address cv_key, uint32_t tag, int64_t timeout_ns);"], + [0x1D, "void SignalProcessWideKey(Address cv_key, int32_t count);"], + [0x1E, "int64_t GetSystemTick();"], + [0x1F, "Result ConnectToNamedPort(Handle* out_handle, Address name);"], + [0x20, "Result SendSyncRequestLight(Handle session_handle);"], + [0x21, "Result SendSyncRequest(Handle session_handle);"], + [0x22, "Result SendSyncRequestWithUserBuffer(Address message_buffer, Size message_buffer_size, Handle session_handle);"], + [0x23, "Result SendAsyncRequestWithUserBuffer(Handle* out_event_handle, Address message_buffer, Size message_buffer_size, Handle session_handle);"], + [0x24, "Result GetProcessId(uint64_t* out_process_id, Handle process_handle);"], + [0x25, "Result GetThreadId(uint64_t* out_thread_id, Handle thread_handle);"], + [0x26, "void Break(BreakReason break_reason, Address arg, Size size);"], + [0x27, "Result OutputDebugString(Address debug_str, Size len);"], + [0x28, "void ReturnFromException(Result result);"], + [0x29, "Result GetInfo(uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);"], + [0x2A, "void FlushEntireDataCache();"], + [0x2B, "Result FlushDataCache(Address address, Size size);"], + [0x2C, "Result MapPhysicalMemory(Address address, Size size);"], + [0x2D, "Result UnmapPhysicalMemory(Address address, Size size);"], + [0x2E, "Result GetDebugFutureThreadInfo(LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);"], + [0x2F, "Result GetLastThreadInfo(LastThreadContext* out_context, Address* out_tls_address, uint32_t* out_flags);"], + [0x30, "Result GetResourceLimitLimitValue(int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);"], + [0x31, "Result GetResourceLimitCurrentValue(int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);"], + [0x32, "Result SetThreadActivity(Handle thread_handle, ThreadActivity thread_activity);"], + [0x33, "Result GetThreadContext3(Address out_context, Handle thread_handle);"], + [0x34, "Result WaitForAddress(Address address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);"], + [0x35, "Result SignalToAddress(Address address, SignalType signal_type, int32_t value, int32_t count);"], + [0x36, "void SynchronizePreemptionState();"], + [0x37, "Result GetResourceLimitPeakValue(int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);"], + + [0x39, "Result CreateIoPool(Handle* out_handle, IoPoolType which);"], + [0x3A, "Result CreateIoRegion(Handle* out_handle, Handle io_pool, PhysicalAddress physical_address, Size size, MemoryMapping mapping, MemoryPermission perm);"], + + [0x3C, "void KernelDebug(KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);"], + [0x3D, "void ChangeKernelTraceState(KernelTraceState kern_trace_state);"], + + [0x40, "Result CreateSession(Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, Address name);"], + [0x41, "Result AcceptSession(Handle* out_handle, Handle port);"], + [0x42, "Result ReplyAndReceiveLight(Handle handle);"], + [0x43, "Result ReplyAndReceive(int32_t* out_index, Address handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);"], + [0x44, "Result ReplyAndReceiveWithUserBuffer(int32_t* out_index, Address message_buffer, Size message_buffer_size, Address handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);"], + [0x45, "Result CreateEvent(Handle* out_write_handle, Handle* out_read_handle);"], + [0x46, "Result MapIoRegion(Handle io_region, Address address, Size size, MemoryPermission perm);"], + [0x47, "Result UnmapIoRegion(Handle io_region, Address address, Size size);"], + [0x48, "Result MapPhysicalMemoryUnsafe(Address address, Size size);"], + [0x49, "Result UnmapPhysicalMemoryUnsafe(Address address, Size size);"], + [0x4A, "Result SetUnsafeLimit(Size limit);"], + [0x4B, "Result CreateCodeMemory(Handle* out_handle, Address address, Size size);"], + [0x4C, "Result ControlCodeMemory(Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);"], + [0x4D, "void SleepSystem();"], + [0x4E, "Result ReadWriteRegister(uint32_t* out_value, PhysicalAddress address, uint32_t mask, uint32_t value);"], + [0x4F, "Result SetProcessActivity(Handle process_handle, ProcessActivity process_activity);"], + [0x50, "Result CreateSharedMemory(Handle* out_handle, Size size, MemoryPermission owner_perm, MemoryPermission remote_perm);"], + [0x51, "Result MapTransferMemory(Handle trmem_handle, Address address, Size size, MemoryPermission owner_perm);"], + [0x52, "Result UnmapTransferMemory(Handle trmem_handle, Address address, Size size);"], + [0x53, "Result CreateInterruptEvent(Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);"], + [0x54, "Result QueryPhysicalAddress(PhysicalMemoryInfo* out_info, Address address);"], + [0x55, "Result QueryIoMapping(Address* out_address, Size* out_size, PhysicalAddress physical_address, Size size);"], + [0x56, "Result CreateDeviceAddressSpace(Handle* out_handle, uint64_t das_address, uint64_t das_size);"], + [0x57, "Result AttachDeviceAddressSpace(DeviceName device_name, Handle das_handle);"], + [0x58, "Result DetachDeviceAddressSpace(DeviceName device_name, Handle das_handle);"], + [0x59, "Result MapDeviceAddressSpaceByForce(Handle das_handle, Handle process_handle, uint64_t process_address, Size size, uint64_t device_address, uint32_t option);"], + [0x5A, "Result MapDeviceAddressSpaceAligned(Handle das_handle, Handle process_handle, uint64_t process_address, Size size, uint64_t device_address, uint32_t option);"], + [0x5C, "Result UnmapDeviceAddressSpace(Handle das_handle, Handle process_handle, uint64_t process_address, Size size, uint64_t device_address);"], + [0x5D, "Result InvalidateProcessDataCache(Handle process_handle, uint64_t address, uint64_t size);"], + [0x5E, "Result StoreProcessDataCache(Handle process_handle, uint64_t address, uint64_t size);"], + [0x5F, "Result FlushProcessDataCache(Handle process_handle, uint64_t address, uint64_t size);"], + [0x60, "Result DebugActiveProcess(Handle* out_handle, uint64_t process_id);"], + [0x61, "Result BreakDebugProcess(Handle debug_handle);"], + [0x62, "Result TerminateDebugProcess(Handle debug_handle);"], + [0x63, "Result GetDebugEvent(Address out_info, Handle debug_handle);"], + [0x64, "Result ContinueDebugEvent(Handle debug_handle, uint32_t flags, Address thread_ids, int32_t num_thread_ids);"], + [0x65, "Result GetProcessList(int32_t* out_num_processes, Address out_process_ids, int32_t max_out_count);"], + [0x66, "Result GetThreadList(int32_t* out_num_threads, Address out_thread_ids, int32_t max_out_count, Handle debug_handle);"], + [0x67, "Result GetDebugThreadContext(Address out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);"], + [0x68, "Result SetDebugThreadContext(Handle debug_handle, uint64_t thread_id, Address context, uint32_t context_flags);"], + [0x69, "Result QueryDebugProcessMemory(Address out_memory_info, PageInfo* out_page_info, Handle process_handle, Address address);"], + [0x6A, "Result ReadDebugProcessMemory(Address buffer, Handle debug_handle, Address address, Size size);"], + [0x6B, "Result WriteDebugProcessMemory(Handle debug_handle, Address buffer, Address address, Size size);"], + [0x6C, "Result SetHardwareBreakPoint(HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);"], + [0x6D, "Result GetDebugThreadParam(uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);"], + + [0x6F, "Result GetSystemInfo(uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);"], + [0x70, "Result CreatePort(Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, Address name);"], + [0x71, "Result ManageNamedPort(Handle* out_server_handle, Address name, int32_t max_sessions);"], + [0x72, "Result ConnectToPort(Handle* out_handle, Handle port);"], + [0x73, "Result SetProcessMemoryPermission(Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);"], + [0x74, "Result MapProcessMemory(Address dst_address, Handle process_handle, uint64_t src_address, Size size);"], + [0x75, "Result UnmapProcessMemory(Address dst_address, Handle process_handle, uint64_t src_address, Size size);"], + [0x76, "Result QueryProcessMemory(Address out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);"], + [0x77, "Result MapProcessCodeMemory(Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);"], + [0x78, "Result UnmapProcessCodeMemory(Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);"], + [0x79, "Result CreateProcess(Handle* out_handle, Address parameters, Address caps, int32_t num_caps);"], + [0x7A, "Result StartProcess(Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);"], + [0x7B, "Result TerminateProcess(Handle process_handle);"], + [0x7C, "Result GetProcessInfo(int64_t* out_info, Handle process_handle, ProcessInfoType info_type);"], + [0x7D, "Result CreateResourceLimit(Handle* out_handle);"], + [0x7E, "Result SetResourceLimitLimitValue(Handle resource_limit_handle, LimitableResource which, int64_t limit_value);"], + [0x7F, "void CallSecureMonitor(SecureMonitorArguments args);"], + + [0x90, "Result MapInsecureMemory(Address address, Size size);"], + [0x91, "Result UnmapInsecureMemory(Address address, Size size);"], +] + +# These use a custom ABI, and therefore require custom wrappers +SKIP_WRAPPERS = { + 0x20: "SendSyncRequestLight", + 0x42: "ReplyAndReceiveLight", + 0x7F: "CallSecureMonitor", +} + +BIT_32 = 0 +BIT_64 = 1 + +REG_SIZES = [4, 8] +SUFFIX_NAMES = ["64From32", "64"] +TYPE_SIZES = { + # SVC types + "ArbitrationType": 4, + "BreakReason": 4, + "CodeMemoryOperation": 4, + "DebugThreadParam": 4, + "DeviceName": 4, + "HardwareBreakPointRegisterName": 4, + "Handle": 4, + "InfoType": 4, + "InterruptType": 4, + "IoPoolType": 4, + "KernelDebugType": 4, + "KernelTraceState": 4, + "LimitableResource": 4, + "MemoryMapping": 4, + "MemoryPermission": 4, + "PageInfo": 4, + "ProcessActivity": 4, + "ProcessInfoType": 4, + "Result": 4, + "SignalType": 4, + "SystemInfoType": 4, + "ThreadActivity": 4, + + # Arch-specific types + "ilp32::LastThreadContext": 16, + "ilp32::PhysicalMemoryInfo": 16, + "ilp32::SecureMonitorArguments": 32, + "lp64::LastThreadContext": 32, + "lp64::PhysicalMemoryInfo": 24, + "lp64::SecureMonitorArguments": 64, + + # Generic types + "bool": 1, + "int32_t": 4, + "int64_t": 8, + "uint32_t": 4, + "uint64_t": 8, + "void": 0, +} + +TYPE_REPLACEMENTS = { + "Address": ["uint32_t", "uint64_t"], + "LastThreadContext": ["ilp32::LastThreadContext", "lp64::LastThreadContext"], + "PhysicalAddress": ["uint64_t", "uint64_t"], + "PhysicalMemoryInfo": ["ilp32::PhysicalMemoryInfo", "lp64::PhysicalMemoryInfo"], + "SecureMonitorArguments": ["ilp32::SecureMonitorArguments", "lp64::SecureMonitorArguments"], + "Size": ["uint32_t", "uint64_t"], + "ThreadFunc": ["uint32_t", "uint64_t"], +} + +# Statically verify that the hardcoded sizes match the intended +# sizes in C++. +def emit_size_check(): + lines = [] + + for type, size in TYPE_SIZES.items(): + if type != "void": + lines.append(f"static_assert(sizeof({type}) == {size});") + + return "\n".join(lines) + + +# Replaces a type with an arch-specific one, if it exists. +def substitute_type(name, bitness): + if name in TYPE_REPLACEMENTS: + return TYPE_REPLACEMENTS[name][bitness] + else: + return name + + +class Argument: + def __init__(self, type_name, var_name, is_output, is_outptr, is_address): + self.type_name = type_name + self.var_name = var_name + self.is_output = is_output + self.is_outptr = is_outptr + self.is_address = is_address + + +# Parses C-style string declarations for SVCs. +def parse_declaration(declaration, bitness): + return_type, rest = declaration.split(" ", 1) + func_name, rest = rest.split("(", 1) + arg_names, rest = rest.split(")", 1) + argument_types = [] + + return_type = substitute_type(return_type, bitness) + assert return_type in TYPE_SIZES, f"Unknown type '{return_type}'" + + if arg_names: + for arg_name in arg_names.split(", "): + type_name, var_name = arg_name.replace("*", "").split(" ", 1) + + # All outputs must contain out_ in the name. + is_output = var_name == "out" or var_name.find("out_") != -1 + + # User-pointer outputs are not written to registers. + is_outptr = is_output and arg_name.find("*") == -1 + + # Special handling is performed for output addresses to avoid awkwardness + # in conversion for the 32-bit equivalents. + is_address = is_output and not is_outptr and \ + type_name in ["Address", "Size"] + type_name = substitute_type(type_name, bitness) + + assert type_name in TYPE_SIZES, f"Unknown type '{type_name}'" + + argument_types.append( + Argument(type_name, var_name, is_output, is_outptr, is_address)) + + return (return_type, func_name, argument_types) + + +class RegisterAllocator: + def __init__(self, num_regs, byte_size, parameter_count): + self.registers = {} + self.num_regs = num_regs + self.byte_size = byte_size + self.parameter_count = parameter_count + + # Mark the given register as allocated, for use in layout + # calculation if the NGRN exceeds the ABI parameter count. + def allocate(self, i): + assert i not in self.registers, f"Register R{i} already allocated" + self.registers[i] = True + return i + + # Calculate the next available location for a register; + # the NGRN has exceeded the ABI parameter count. + def allocate_first_free(self): + for i in range(0, self.num_regs): + if i in self.registers: + continue + + self.allocate(i) + return i + + assert False, "No registers available" + + # Add a single register at the given NGRN. + # If the index exceeds the ABI parameter count, try to find a + # location to add it. Returns the output location and increment. + def add_single(self, ngrn): + if ngrn >= self.parameter_count: + return (self.allocate_first_free(), 0) + else: + return (self.allocate(ngrn), 1) + + # Add registers at the given NGRN for a data type of + # the given size. Returns the output locations and increment. + def add(self, ngrn, data_size, align=True): + if data_size <= self.byte_size: + r, i = self.add_single(ngrn) + return ([r], i) + + regs = [] + inc = ngrn % 2 if align else 0 + remaining_size = data_size + while remaining_size > 0: + r, i = self.add_single(ngrn + inc) + regs.append(r) + inc += i + remaining_size -= self.byte_size + + return (regs, inc) + + +def reg_alloc(bitness): + if bitness == 0: + # aapcs32: 4 4-byte registers + return RegisterAllocator(8, 4, 4) + elif bitness == 1: + # aapcs64: 8 8-byte registers + return RegisterAllocator(8, 8, 8) + + +# Converts a parsed SVC declaration into register lists for +# the return value, outputs, and inputs. +def get_registers(parse_result, bitness): + output_alloc = reg_alloc(bitness) + input_alloc = reg_alloc(bitness) + return_type, _, arguments = parse_result + + return_write = [] + output_writes = [] + input_reads = [] + + input_ngrn = 0 + output_ngrn = 0 + + # Run the input calculation. + for arg in arguments: + if arg.is_output and not arg.is_outptr: + input_ngrn += 1 + continue + + regs, increment = input_alloc.add( + input_ngrn, TYPE_SIZES[arg.type_name], align=True) + input_reads.append([arg.type_name, arg.var_name, regs]) + input_ngrn += increment + + # Include the return value if this SVC returns a value. + if return_type != "void": + regs, increment = output_alloc.add( + output_ngrn, TYPE_SIZES[return_type], align=False) + return_write.append([return_type, regs]) + output_ngrn += increment + + # Run the output calculation. + for arg in arguments: + if not arg.is_output or arg.is_outptr: + continue + + regs, increment = output_alloc.add( + output_ngrn, TYPE_SIZES[arg.type_name], align=False) + output_writes.append( + [arg.type_name, arg.var_name, regs, arg.is_address]) + output_ngrn += increment + + return (return_write, output_writes, input_reads) + + +# Collects possibly multiple source registers into the named C++ value. +def emit_gather(sources, name, type_name, reg_size): + get_fn = f"GetReg{reg_size*8}" + + if len(sources) == 1: + s, = sources + line = f"{name} = Convert<{type_name}>({get_fn}(system, {s}));" + return [line] + + var_type = f"std::array<uint{reg_size*8}_t, {len(sources)}>" + lines = [ + f"{var_type} {name}_gather{{}};" + ] + for i in range(0, len(sources)): + lines.append( + f"{name}_gather[{i}] = {get_fn}(system, {sources[i]});") + + lines.append(f"{name} = Convert<{type_name}>({name}_gather);") + return lines + + +# Produces one or more statements which assign the named C++ value +# into possibly multiple registers. +def emit_scatter(destinations, name, reg_size): + set_fn = f"SetReg{reg_size*8}" + reg_type = f"uint{reg_size*8}_t" + + if len(destinations) == 1: + d, = destinations + line = f"{set_fn}(system, {d}, Convert<{reg_type}>({name}));" + return [line] + + var_type = f"std::array<{reg_type}, {len(destinations)}>" + lines = [ + f"auto {name}_scatter = Convert<{var_type}>({name});" + ] + + for i in range(0, len(destinations)): + lines.append( + f"{set_fn}(system, {destinations[i]}, {name}_scatter[{i}]);") + + return lines + + +def emit_lines(lines, indent=' '): + output_lines = [] + first = True + for line in lines: + if line and not first: + output_lines.append(indent + line) + else: + output_lines.append(line) + first = False + + return "\n".join(output_lines) + + +# Emit a C++ function to wrap a guest SVC. +def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size): + return_write, output_writes, input_reads = register_info + lines = [ + f"static void SvcWrap_{wrapped_fn}{suffix}(Core::System& system) {{" + ] + + # Get everything ready. + for return_type, _ in return_write: + lines.append(f"{return_type} ret{{}};") + if return_write: + lines.append("") + + for output_type, var_name, _, is_address in output_writes: + output_type = "uintptr_t" if is_address else output_type + lines.append(f"{output_type} {var_name}{{}};") + for input_type, var_name, _ in input_reads: + lines.append(f"{input_type} {var_name}{{}};") + + if output_writes or input_reads: + lines.append("") + + for input_type, var_name, sources in input_reads: + lines += emit_gather(sources, var_name, input_type, byte_size) + if input_reads: + lines.append("") + + # Build the call. + call_arguments = ["system"] + for arg in arguments: + if arg.is_output and not arg.is_outptr: + call_arguments.append(f"&{arg.var_name}") + else: + call_arguments.append(arg.var_name) + + line = "" + if return_write: + line += "ret = " + + line += f"{wrapped_fn}{suffix}({', '.join(call_arguments)});" + lines.append(line) + + if return_write or output_writes: + lines.append("") + + # Write back the return value and outputs. + for _, destinations in return_write: + lines += emit_scatter(destinations, "ret", byte_size) + for _, var_name, destinations, _ in output_writes: + lines += emit_scatter(destinations, var_name, byte_size) + + # Finish. + return emit_lines(lines) + "\n}" + + +COPYRIGHT = """\ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// This file is automatically generated using svc_generator.py. +""" + +PROLOGUE_H = """ +#pragma once + +namespace Core { +class System; +} + +#include "common/common_types.h" +#include "core/hle/kernel/svc_types.h" +#include "core/hle/result.h" + +namespace Kernel::Svc { + +// clang-format off +""" + +EPILOGUE_H = """ +// clang-format on + +// Custom ABI. +Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args); +Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args); +Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args); + +Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args); +Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args); +Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args); + +void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args); +void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args); +void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args); + +// Defined in svc_light_ipc.cpp. +void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system); +void SvcWrap_ReplyAndReceiveLight64(Core::System& system); + +void SvcWrap_SendSyncRequestLight64From32(Core::System& system); +void SvcWrap_SendSyncRequestLight64(Core::System& system); + +// Defined in svc_secure_monitor_call.cpp. +void SvcWrap_CallSecureMonitor64From32(Core::System& system); +void SvcWrap_CallSecureMonitor64(Core::System& system); + +// Perform a supervisor call by index. +void Call(Core::System& system, u32 imm); + +} // namespace Kernel::Svc +""" + +PROLOGUE_CPP = """ +#include <type_traits> + +#include "core/arm/arm_interface.h" +#include "core/core.h" +#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/svc.h" + +namespace Kernel::Svc { + +static uint32_t GetReg32(Core::System& system, int n) { + return static_cast<uint32_t>(system.CurrentArmInterface().GetReg(n)); +} + +static void SetReg32(Core::System& system, int n, uint32_t result) { + system.CurrentArmInterface().SetReg(n, static_cast<uint64_t>(result)); +} + +static uint64_t GetReg64(Core::System& system, int n) { + return system.CurrentArmInterface().GetReg(n); +} + +static void SetReg64(Core::System& system, int n, uint64_t result) { + system.CurrentArmInterface().SetReg(n, result); +} + +// Like bit_cast, but handles the case when the source and dest +// are differently-sized. +template <typename To, typename From> + requires(std::is_trivial_v<To> && std::is_trivially_copyable_v<From>) +static To Convert(const From& from) { + To to{}; + + if constexpr (sizeof(To) >= sizeof(From)) { + std::memcpy(&to, &from, sizeof(From)); + } else { + std::memcpy(&to, &from, sizeof(To)); + } + + return to; +} + +// clang-format off +""" + +EPILOGUE_CPP = """ +// clang-format on + +void Call(Core::System& system, u32 imm) { + auto& kernel = system.Kernel(); + kernel.EnterSVCProfile(); + + if (system.CurrentProcess()->Is64BitProcess()) { + Call64(system, imm); + } else { + Call32(system, imm); + } + + kernel.ExitSVCProfile(); +} + +} // namespace Kernel::Svc +""" + + +def emit_call(bitness, names, suffix): + bit_size = REG_SIZES[bitness]*8 + indent = " " + lines = [ + f"static void Call{bit_size}(Core::System& system, u32 imm) {{", + f"{indent}switch (static_cast<SvcId>(imm)) {{" + ] + + for _, name in names: + lines.append(f"{indent}case SvcId::{name}:") + lines.append(f"{indent*2}return SvcWrap_{name}{suffix}(system);") + + lines.append(f"{indent}default:") + lines.append( + f"{indent*2}LOG_CRITICAL(Kernel_SVC, \"Unknown SVC {{:x}}!\", imm);") + lines.append(f"{indent*2}break;") + lines.append(f"{indent}}}") + lines.append("}") + + return "\n".join(lines) + + +def build_fn_declaration(return_type, name, arguments): + arg_list = ["Core::System& system"] + for arg in arguments: + type_name = "uintptr_t" if arg.is_address else arg.type_name + pointer = "*" if arg.is_output and not arg.is_outptr else "" + arg_list.append(f"{type_name}{pointer} {arg.var_name}") + + return f"{return_type} {name}({', '.join(arg_list)});" + + +def build_enum_declarations(): + lines = ["enum class SvcId : u32 {"] + indent = " " + + for imm, decl in SVCS: + _, name, _ = parse_declaration(decl, BIT_64) + lines.append(f"{indent}{name} = {hex(imm)},") + + lines.append("};") + return "\n".join(lines) + + +def main(): + arch_fw_declarations = [[], []] + svc_fw_declarations = [] + wrapper_fns = [] + names = [] + + for imm, decl in SVCS: + return_type, name, arguments = parse_declaration(decl, BIT_64) + + if imm not in SKIP_WRAPPERS: + svc_fw_declarations.append( + build_fn_declaration(return_type, name, arguments)) + + names.append([imm, name]) + + for bitness in range(2): + byte_size = REG_SIZES[bitness] + suffix = SUFFIX_NAMES[bitness] + + for imm, decl in SVCS: + if imm in SKIP_WRAPPERS: + continue + + parse_result = parse_declaration(decl, bitness) + return_type, name, arguments = parse_result + + register_info = get_registers(parse_result, bitness) + wrapper_fns.append( + emit_wrapper(name, suffix, register_info, arguments, byte_size)) + arch_fw_declarations[bitness].append( + build_fn_declaration(return_type, name + suffix, arguments)) + + call_32 = emit_call(BIT_32, names, SUFFIX_NAMES[BIT_32]) + call_64 = emit_call(BIT_64, names, SUFFIX_NAMES[BIT_64]) + enum_decls = build_enum_declarations() + + with open("svc.h", "w") as f: + f.write(COPYRIGHT) + f.write(PROLOGUE_H) + f.write("\n".join(svc_fw_declarations)) + f.write("\n\n") + f.write("\n".join(arch_fw_declarations[BIT_32])) + f.write("\n\n") + f.write("\n".join(arch_fw_declarations[BIT_64])) + f.write("\n\n") + f.write(enum_decls) + f.write(EPILOGUE_H) + + with open("svc.cpp", "w") as f: + f.write(COPYRIGHT) + f.write(PROLOGUE_CPP) + f.write(emit_size_check()) + f.write("\n\n") + f.write("\n\n".join(wrapper_fns)) + f.write("\n\n") + f.write(call_32) + f.write("\n\n") + f.write(call_64) + f.write(EPILOGUE_CPP) + + print(f"Done (emitted {len(names)} definitions)") + + +if __name__ == "__main__": + main() diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h index b7ca53085..e1ad78607 100644 --- a/src/core/hle/kernel/svc_results.h +++ b/src/core/hle/kernel/svc_results.h @@ -11,6 +11,7 @@ namespace Kernel { constexpr Result ResultOutOfSessions{ErrorModule::Kernel, 7}; constexpr Result ResultInvalidArgument{ErrorModule::Kernel, 14}; +constexpr Result ResultNotImplemented{ErrorModule::Kernel, 33}; constexpr Result ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; constexpr Result ResultTerminationRequested{ErrorModule::Kernel, 59}; constexpr Result ResultInvalidSize{ErrorModule::Kernel, 101}; diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index e90c35601..542c13461 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -168,6 +168,7 @@ enum class BreakReason : u32 { NotificationOnlyFlag = 0x80000000, }; +DECLARE_ENUM_FLAG_OPERATORS(BreakReason); enum class DebugEvent : u32 { CreateProcess = 0, @@ -596,6 +597,11 @@ enum class ProcessInfoType : u32 { ProcessState = 0, }; +enum class ProcessActivity : u32 { + Runnable, + Paused, +}; + struct CreateProcessParameter { std::array<char, 12> name; u32 version; @@ -611,4 +617,9 @@ static_assert(sizeof(CreateProcessParameter) == 0x30); constexpr size_t NumSupervisorCalls = 0xC0; using SvcAccessFlagSet = std::bitset<NumSupervisorCalls>; +enum class InitialProcessIdRangeInfo : u64 { + Minimum = 0, + Maximum = 1, +}; + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc_version.h b/src/core/hle/kernel/svc_version.h index e4f47b34b..3eb95aa7b 100644 --- a/src/core/hle/kernel/svc_version.h +++ b/src/core/hle/kernel/svc_version.h @@ -35,11 +35,11 @@ constexpr inline u32 EncodeKernelVersion(u32 major, u32 minor) { } constexpr inline u32 GetKernelMajorVersion(u32 encoded) { - return std::bit_cast<decltype(KernelVersion::major_version)>(encoded).Value(); + return decltype(KernelVersion::major_version)::ExtractValue(encoded); } constexpr inline u32 GetKernelMinorVersion(u32 encoded) { - return std::bit_cast<decltype(KernelVersion::minor_version)>(encoded).Value(); + return decltype(KernelVersion::minor_version)::ExtractValue(encoded); } // Nintendo doesn't support programs targeting SVC versions < 3.0. diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h deleted file mode 100644 index 052be40dd..000000000 --- a/src/core/hle/kernel/svc_wrap.h +++ /dev/null @@ -1,733 +0,0 @@ -// 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" -#include "core/memory.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<u32>(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 <Result func(Core::System&, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0)).raw); -} - -template <Result func(Core::System&, u64, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), Param(system, 1)).raw); -} - -template <Result func(Core::System&, u32)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); -} - -template <Result func(Core::System&, u32, u32)> -void SvcWrap64(Core::System& system) { - FuncReturn( - system, - func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw); -} - -// Used by SetThreadActivity -template <Result func(Core::System&, Handle, Svc::ThreadActivity)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), - static_cast<Svc::ThreadActivity>(Param(system, 1))) - .raw); -} - -template <Result func(Core::System&, u32, u64, u64, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), - Param(system, 2), Param(system, 3)) - .raw); -} - -// Used by MapProcessMemory and UnmapProcessMemory -template <Result func(Core::System&, u64, u32, u64, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)), - Param(system, 2), Param(system, 3)) - .raw); -} - -// Used by ControlCodeMemory -template <Result func(Core::System&, Handle, u32, VAddr, size_t, Svc::MemoryPermission)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), - static_cast<u32>(Param(system, 1)), Param(system, 2), Param(system, 3), - static_cast<Svc::MemoryPermission>(Param(system, 4))) - .raw); -} - -template <Result func(Core::System&, u32*)> -void SvcWrap64(Core::System& system) { - u32 param = 0; - const u32 retval = func(system, ¶m).raw; - system.CurrentArmInterface().SetReg(1, param); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u32*, u32)> -void SvcWrap64(Core::System& system) { - u32 param_1 = 0; - const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u32*, u32*)> -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 <Result func(Core::System&, u32*, u64)> -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 <Result func(Core::System&, u32*, u64, u32)> -void SvcWrap64(Core::System& system) { - u32 param_1 = 0; - const u32 retval = - func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2))).raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u64*, u32)> -void SvcWrap64(Core::System& system) { - u64 param_1 = 0; - const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u64, u32)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw); -} - -template <Result func(Core::System&, u64*, u64)> -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 <Result func(Core::System&, u64*, u32, u32)> -void SvcWrap64(Core::System& system) { - u64 param_1 = 0; - const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1)), - static_cast<u32>(Param(system, 2))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -// Used by GetResourceLimitLimitValue. -template <Result func(Core::System&, u64*, Handle, Svc::LimitableResource)> -void SvcWrap64(Core::System& system) { - u64 param_1 = 0; - const u32 retval = func(system, ¶m_1, static_cast<Handle>(Param(system, 1)), - static_cast<Svc::LimitableResource>(Param(system, 2))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u32, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); -} - -// Used by SetResourceLimitLimitValue -template <Result func(Core::System&, Handle, Svc::LimitableResource, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), - static_cast<Svc::LimitableResource>(Param(system, 1)), Param(system, 2)) - .raw); -} - -// Used by SetThreadCoreMask -template <Result func(Core::System&, Handle, s32, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), - static_cast<s32>(Param(system, 1)), Param(system, 2)) - .raw); -} - -// Used by GetThreadCoreMask -template <Result func(Core::System&, Handle, s32*, u64*)> -void SvcWrap64(Core::System& system) { - s32 param_1 = 0; - u64 param_2 = 0; - const Result retval = func(system, static_cast<u32>(Param(system, 2)), ¶m_1, ¶m_2); - - system.CurrentArmInterface().SetReg(1, param_1); - system.CurrentArmInterface().SetReg(2, param_2); - FuncReturn(system, retval.raw); -} - -template <Result func(Core::System&, u64, u64, u32, u32)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), Param(system, 1), - static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) - .raw); -} - -template <Result func(Core::System&, u64, u64, u32, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), Param(system, 1), - static_cast<u32>(Param(system, 2)), Param(system, 3)) - .raw); -} - -template <Result func(Core::System&, u32, u64, u32)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), - static_cast<u32>(Param(system, 2))) - .raw); -} - -template <Result func(Core::System&, u64, u64, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw); -} - -template <Result func(Core::System&, u64, u64, u32)> -void SvcWrap64(Core::System& system) { - FuncReturn( - system, - func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw); -} - -// Used by SetMemoryPermission -template <Result func(Core::System&, u64, u64, Svc::MemoryPermission)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), Param(system, 1), - static_cast<Svc::MemoryPermission>(Param(system, 2))) - .raw); -} - -// Used by MapSharedMemory -template <Result func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), Param(system, 1), - Param(system, 2), static_cast<Svc::MemoryPermission>(Param(system, 3))) - .raw); -} - -template <Result func(Core::System&, u32, u64, u64)> -void SvcWrap64(Core::System& system) { - FuncReturn( - system, - func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw); -} - -// Used by WaitSynchronization -template <Result func(Core::System&, s32*, u64, s32, s64)> -void SvcWrap64(Core::System& system) { - s32 param_1 = 0; - const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<s32>(Param(system, 2)), - static_cast<s64>(Param(system, 3))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u64, u64, u32, s64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, Param(system, 0), Param(system, 1), - static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) - .raw); -} - -// Used by GetInfo -template <Result func(Core::System&, u64*, u64, Handle, u64)> -void SvcWrap64(Core::System& system) { - u64 param_1 = 0; - const u32 retval = func(system, ¶m_1, Param(system, 1), - static_cast<Handle>(Param(system, 2)), Param(system, 3)) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -template <Result func(Core::System&, u32*, u64, u64, u64, u32, s32)> -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<u32>(Param(system, 4)), static_cast<s32>(Param(system, 5))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -// Used by CreateTransferMemory -template <Result func(Core::System&, Handle*, u64, u64, Svc::MemoryPermission)> -void SvcWrap64(Core::System& system) { - u32 param_1 = 0; - const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), - static_cast<Svc::MemoryPermission>(Param(system, 3))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -// Used by CreateCodeMemory -template <Result func(Core::System&, Handle*, VAddr, size_t)> -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 <Result func(Core::System&, Handle*, u64, u32, u32)> -void SvcWrap64(Core::System& system) { - u32 param_1 = 0; - const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), - static_cast<u32>(Param(system, 3))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -// Used by CreateSession -template <Result func(Core::System&, Handle*, Handle*, u32, u64)> -void SvcWrap64(Core::System& system) { - Handle param_1 = 0; - Handle param_2 = 0; - const u32 retval = func(system, ¶m_1, ¶m_2, static_cast<u32>(Param(system, 2)), - static_cast<u32>(Param(system, 3))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - system.CurrentArmInterface().SetReg(2, param_2); - FuncReturn(system, retval); -} - -// Used by ReplyAndReceive -template <Result func(Core::System&, s32*, Handle*, s32, Handle, s64)> -void SvcWrap64(Core::System& system) { - s32 param_1 = 0; - s32 num_handles = static_cast<s32>(Param(system, 2)); - - std::vector<Handle> handles(num_handles); - system.Memory().ReadBlock(Param(system, 1), handles.data(), num_handles * sizeof(Handle)); - - const u32 retval = func(system, ¶m_1, handles.data(), num_handles, - static_cast<s32>(Param(system, 3)), static_cast<s64>(Param(system, 4))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - -// Used by WaitForAddress -template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, - func(system, Param(system, 0), static_cast<Svc::ArbitrationType>(Param(system, 1)), - static_cast<s32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) - .raw); -} - -// Used by SignalToAddress -template <Result func(Core::System&, u64, Svc::SignalType, s32, s32)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, - func(system, Param(system, 0), static_cast<Svc::SignalType>(Param(system, 1)), - static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3))) - .raw); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Function wrappers that return type u32 - -template <u32 func(Core::System&)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Function wrappers that return type u64 - -template <u64 func(Core::System&)> -void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -/// Function wrappers that return type void - -template <void func(Core::System&)> -void SvcWrap64(Core::System& system) { - func(system); -} - -template <void func(Core::System&, u32)> -void SvcWrap64(Core::System& system) { - func(system, static_cast<u32>(Param(system, 0))); -} - -template <void func(Core::System&, u32, u64, u64, u64)> -void SvcWrap64(Core::System& system) { - func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2), - Param(system, 3)); -} - -template <void func(Core::System&, s64)> -void SvcWrap64(Core::System& system) { - func(system, static_cast<s64>(Param(system, 0))); -} - -template <void func(Core::System&, u64, s32)> -void SvcWrap64(Core::System& system) { - func(system, Param(system, 0), static_cast<s32>(Param(system, 1))); -} - -template <void func(Core::System&, u64, u64)> -void SvcWrap64(Core::System& system) { - func(system, Param(system, 0), Param(system, 1)); -} - -template <void func(Core::System&, u64, u64, u64)> -void SvcWrap64(Core::System& system) { - func(system, Param(system, 0), Param(system, 1), Param(system, 2)); -} - -template <void func(Core::System&, u32, u64, u64)> -void SvcWrap64(Core::System& system) { - func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)); -} - -// Used by QueryMemory32, ArbitrateLock32 -template <Result func(Core::System&, u32, u32, u32)> -void SvcWrap32(Core::System& system) { - FuncReturn32(system, - func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw); -} - -// Used by Break32 -template <void func(Core::System&, u32, u32, u32)> -void SvcWrap32(Core::System& system) { - func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)); -} - -// Used by ExitProcess32, ExitThread32 -template <void func(Core::System&)> -void SvcWrap32(Core::System& system) { - func(system); -} - -// Used by GetCurrentProcessorNumber32 -template <u32 func(Core::System&)> -void SvcWrap32(Core::System& system) { - FuncReturn32(system, func(system)); -} - -// Used by SleepThread32 -template <void func(Core::System&, u32, u32)> -void SvcWrap32(Core::System& system) { - func(system, Param32(system, 0), Param32(system, 1)); -} - -// Used by CreateThread32 -template <Result func(Core::System&, Handle*, u32, u32, u32, u32, s32)> -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 <Result func(Core::System&, u32*, u32*, u32, u32, u32, u32)> -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 <Result func(Core::System&, u32*, u32)> -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 <Result func(Core::System&, u32*, u32*, u32)> -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 func(Core::System&, u32*, u32*)> -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 <Result func(Core::System&, Handle*, Handle*)> -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 <Result func(Core::System&, Handle, u32*, u32*, u32*)> -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 <Result func(Core::System&, Handle, s32*, u32*, u32*)> -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 func(Core::System&, u32, s32)> -void SvcWrap32(Core::System& system) { - func(system, static_cast<u32>(Param(system, 0)), static_cast<s32>(Param(system, 1))); -} - -// Used by SetThreadActivity32 -template <Result func(Core::System&, Handle, Svc::ThreadActivity)> -void SvcWrap32(Core::System& system) { - const u32 retval = func(system, static_cast<Handle>(Param(system, 0)), - static_cast<Svc::ThreadActivity>(Param(system, 1))) - .raw; - FuncReturn(system, retval); -} - -// Used by SetThreadPriority32 -template <Result func(Core::System&, Handle, u32)> -void SvcWrap32(Core::System& system) { - const u32 retval = - func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw; - FuncReturn(system, retval); -} - -// Used by SetMemoryAttribute32 -template <Result func(Core::System&, Handle, u32, u32, u32)> -void SvcWrap32(Core::System& system) { - const u32 retval = - func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1)), - static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) - .raw; - FuncReturn(system, retval); -} - -// Used by MapSharedMemory32 -template <Result func(Core::System&, Handle, u32, u32, Svc::MemoryPermission)> -void SvcWrap32(Core::System& system) { - const u32 retval = func(system, static_cast<Handle>(Param(system, 0)), - static_cast<u32>(Param(system, 1)), static_cast<u32>(Param(system, 2)), - static_cast<Svc::MemoryPermission>(Param(system, 3))) - .raw; - FuncReturn(system, retval); -} - -// Used by SetThreadCoreMask32 -template <Result func(Core::System&, Handle, s32, u32, u32)> -void SvcWrap32(Core::System& system) { - const u32 retval = - func(system, static_cast<Handle>(Param(system, 0)), static_cast<s32>(Param(system, 1)), - static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) - .raw; - FuncReturn(system, retval); -} - -// Used by WaitProcessWideKeyAtomic32 -template <Result func(Core::System&, u32, u32, Handle, u32, u32)> -void SvcWrap32(Core::System& system) { - const u32 retval = - func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), - static_cast<Handle>(Param(system, 2)), static_cast<u32>(Param(system, 3)), - static_cast<u32>(Param(system, 4))) - .raw; - FuncReturn(system, retval); -} - -// Used by WaitForAddress32 -template <Result func(Core::System&, u32, Svc::ArbitrationType, s32, u32, u32)> -void SvcWrap32(Core::System& system) { - const u32 retval = func(system, static_cast<u32>(Param(system, 0)), - static_cast<Svc::ArbitrationType>(Param(system, 1)), - static_cast<s32>(Param(system, 2)), static_cast<u32>(Param(system, 3)), - static_cast<u32>(Param(system, 4))) - .raw; - FuncReturn(system, retval); -} - -// Used by SignalToAddress32 -template <Result func(Core::System&, u32, Svc::SignalType, s32, s32)> -void SvcWrap32(Core::System& system) { - const u32 retval = func(system, static_cast<u32>(Param(system, 0)), - static_cast<Svc::SignalType>(Param(system, 1)), - static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3))) - .raw; - FuncReturn(system, retval); -} - -// Used by SendSyncRequest32, ArbitrateUnlock32 -template <Result func(Core::System&, u32)> -void SvcWrap32(Core::System& system) { - FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); -} - -// Used by CreateTransferMemory32 -template <Result func(Core::System&, Handle*, u32, u32, Svc::MemoryPermission)> -void SvcWrap32(Core::System& system) { - Handle handle = 0; - const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), - static_cast<Svc::MemoryPermission>(Param32(system, 3))) - .raw; - system.CurrentArmInterface().SetReg(1, handle); - FuncReturn(system, retval); -} - -// Used by WaitSynchronization32 -template <Result func(Core::System&, u32, u32, s32, u32, s32*)> -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 <Result func(Core::System&, Handle*, u32, u32)> -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 <Result func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)> -void SvcWrap32(Core::System& system) { - const u32 retval = - func(system, Param32(system, 0), Param32(system, 1), Param(system, 2), Param(system, 4), - static_cast<Svc::MemoryPermission>(Param32(system, 6))) - .raw; - - FuncReturn(system, retval); -} - -// Used by Invalidate/Store/FlushProcessDataCache32 -template <Result func(Core::System&, Handle, u64, u64)> -void SvcWrap32(Core::System& system) { - const u64 address = (Param(system, 3) << 32) | Param(system, 2); - const u64 size = (Param(system, 4) << 32) | Param(system, 1); - FuncReturn32(system, func(system, Param32(system, 0), address, size).raw); -} - -} // namespace Kernel diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 513ea485a..80eba22e8 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -758,12 +758,20 @@ Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const { return hid_core.GetSupportedStyleTag(); } -void Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { +Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { + constexpr std::size_t max_number_npad_ids = 0xa; const auto length = data.size(); ASSERT(length > 0 && (length % sizeof(u32)) == 0); + const std::size_t elements = length / sizeof(u32); + + if (elements > max_number_npad_ids) { + return InvalidArraySize; + } + supported_npad_id_types.clear(); - supported_npad_id_types.resize(length / sizeof(u32)); + supported_npad_id_types.resize(elements); std::memcpy(supported_npad_id_types.data(), data.data(), length); + return ResultSuccess; } void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 1f7d33459..02cc00920 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -96,7 +96,7 @@ public: void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); Core::HID::NpadStyleTag GetSupportedStyleSet() const; - void SetSupportedNpadIdTypes(std::span<const u8> data); + Result SetSupportedNpadIdTypes(std::span<const u8> data); void GetSupportedNpadIdTypes(u32* data, std::size_t max_length); std::size_t GetSupportedNpadIdTypesSize() const; diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 76208e9a4..9585bdaf0 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -18,6 +18,7 @@ constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601}; constexpr Result NpadIsSameType{ErrorModule::HID, 602}; constexpr Result InvalidNpadId{ErrorModule::HID, 709}; constexpr Result NpadNotConnected{ErrorModule::HID, 710}; +constexpr Result InvalidArraySize{ErrorModule::HID, 715}; constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302}; } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index f15f1a6bb..ac2c0c76d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -1025,13 +1025,13 @@ void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; - applet_resource->GetController<Controller_NPad>(HidController::NPad) - .SetSupportedNpadIdTypes(ctx.ReadBuffer()); + const auto result = applet_resource->GetController<Controller_NPad>(HidController::NPad) + .SetSupportedNpadIdTypes(ctx.ReadBuffer()); LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) { diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp index 4fcfb4510..afc33db57 100644 --- a/src/input_common/drivers/joycon.cpp +++ b/src/input_common/drivers/joycon.cpp @@ -16,7 +16,7 @@ namespace InputCommon { Joycons::Joycons(const std::string& input_engine_) : InputEngine(input_engine_) { // Avoid conflicting with SDL driver - if (!Settings::values.enable_joycon_driver) { + if (!Settings::values.enable_joycon_driver && !Settings::values.enable_procon_driver) { return; } LOG_INFO(Input, "Joycon driver Initialization started"); @@ -46,6 +46,12 @@ void Joycons::Reset() { } device->Stop(); } + for (const auto& device : pro_controller) { + if (!device) { + continue; + } + device->Stop(); + } SDL_hid_exit(); } @@ -61,6 +67,11 @@ void Joycons::Setup() { PreSetController(GetIdentifier(port, Joycon::ControllerType::Right)); device = std::make_shared<Joycon::JoyconDriver>(port++); } + port = 0; + for (auto& device : pro_controller) { + PreSetController(GetIdentifier(port, Joycon::ControllerType::Pro)); + device = std::make_shared<Joycon::JoyconDriver>(port++); + } scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); }); } @@ -116,6 +127,9 @@ bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const { // Check if device already exist switch (type) { case Joycon::ControllerType::Left: + if (!Settings::values.enable_joycon_driver) { + return false; + } for (const auto& device : left_joycons) { if (is_handle_identical(device)) { return false; @@ -123,12 +137,25 @@ bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const { } break; case Joycon::ControllerType::Right: + if (!Settings::values.enable_joycon_driver) { + return false; + } for (const auto& device : right_joycons) { if (is_handle_identical(device)) { return false; } } break; + case Joycon::ControllerType::Pro: + if (!Settings::values.enable_procon_driver) { + return false; + } + for (const auto& device : pro_controller) { + if (is_handle_identical(device)) { + return false; + } + } + break; default: return false; } @@ -199,6 +226,14 @@ std::shared_ptr<Joycon::JoyconDriver> Joycons::GetNextFreeHandle( return *unconnected_device; } } + if (type == Joycon::ControllerType::Pro) { + const auto unconnected_device = std::ranges::find_if( + pro_controller, [](auto& device) { return !device->IsConnected(); }); + + if (unconnected_device != pro_controller.end()) { + return *unconnected_device; + } + } return nullptr; } @@ -409,6 +444,15 @@ std::shared_ptr<Joycon::JoyconDriver> Joycons::GetHandle(PadIdentifier identifie } } + if (type == Joycon::ControllerType::Pro) { + const auto matching_device = std::ranges::find_if( + pro_controller, [is_handle_active](auto& device) { return is_handle_active(device); }); + + if (matching_device != pro_controller.end()) { + return *matching_device; + } + } + return nullptr; } @@ -455,6 +499,9 @@ std::vector<Common::ParamPackage> Joycons::GetInputDevices() const { for (const auto& controller : right_joycons) { add_entry(controller); } + for (const auto& controller : pro_controller) { + add_entry(controller); + } // List dual joycon pairs for (std::size_t i = 0; i < MaxSupportedControllers; i++) { diff --git a/src/input_common/drivers/joycon.h b/src/input_common/drivers/joycon.h index 2149ab7fd..473ba1b9e 100644 --- a/src/input_common/drivers/joycon.h +++ b/src/input_common/drivers/joycon.h @@ -106,6 +106,7 @@ private: // Joycon types are split by type to ease supporting dualjoycon configurations std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> left_joycons{}; std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> right_joycons{}; + std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> pro_controller{}; }; } // namespace InputCommon diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index d975eb815..88cacd615 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -343,6 +343,14 @@ void SDLDriver::InitJoystick(int joystick_index) { } } + if (Settings::values.enable_procon_driver) { + if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) { + LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); + SDL_JoystickClose(sdl_joystick); + return; + } + } + std::scoped_lock lock{joystick_map_mutex}; if (joystick_map.find(guid) == joystick_map.end()) { auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); @@ -465,13 +473,19 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); - // Disable hidapi drivers for switch controllers when the custom joycon driver is enabled + // Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled if (Settings::values.enable_joycon_driver) { SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0"); } else { SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); } - SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1"); + + // Disable hidapi drivers for pro controllers when the custom joycon driver is enabled + if (Settings::values.enable_procon_driver) { + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0"); + } else { + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1"); + } // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native // driver on Linux. diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index 8f94c9f45..e65b6b845 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp @@ -543,9 +543,10 @@ void JoyconDriver::SetCallbacks(const JoyconCallbacks& callbacks) { DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, ControllerType& controller_type) { - static constexpr std::array<std::pair<u32, ControllerType>, 2> supported_devices{ + static constexpr std::array<std::pair<u32, ControllerType>, 6> supported_devices{ std::pair<u32, ControllerType>{0x2006, ControllerType::Left}, {0x2007, ControllerType::Right}, + {0x2009, ControllerType::Pro}, }; constexpr u16 nintendo_vendor_id = 0x057e; diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp index 1b006e811..c3c2281bb 100644 --- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp @@ -310,12 +310,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile if (runtime_info.force_early_z) { header += "layout(early_fragment_tests)in;"; } - if (info.uses_sample_id) { - header += "in int gl_SampleID;"; - } - if (info.stores_sample_mask) { - header += "out int gl_SampleMask[];"; - } break; case Stage::Compute: stage_name = "cs"; diff --git a/src/tests/video_core/buffer_base.cpp b/src/tests/video_core/buffer_base.cpp index 1275cca24..734dbf4b6 100644 --- a/src/tests/video_core/buffer_base.cpp +++ b/src/tests/video_core/buffer_base.cpp @@ -538,7 +538,7 @@ TEST_CASE("BufferBase: Cached write downloads") { int num = 0; buffer.ForEachDownloadRangeAndClear(c, WORD, [&](u64 offset, u64 size) { ++num; }); buffer.ForEachUploadRange(c, WORD, [&](u64 offset, u64 size) { ++num; }); - REQUIRE(num == 1); + REQUIRE(num == 0); REQUIRE(!buffer.IsRegionCpuModified(c + PAGE, PAGE)); REQUIRE(!buffer.IsRegionGpuModified(c + PAGE, PAGE)); buffer.FlushCachedWrites(); diff --git a/src/video_core/buffer_cache/buffer_base.h b/src/video_core/buffer_cache/buffer_base.h index c47b7d866..92d77eef2 100644 --- a/src/video_core/buffer_cache/buffer_base.h +++ b/src/video_core/buffer_cache/buffer_base.h @@ -430,7 +430,7 @@ private: if (query_begin >= SizeBytes() || size < 0) { return; } - [[maybe_unused]] u64* const untracked_words = Array<Type::Untracked>(); + u64* const untracked_words = Array<Type::Untracked>(); u64* const state_words = Array<type>(); const u64 query_end = query_begin + std::min(static_cast<u64>(size), SizeBytes()); u64* const words_begin = state_words + query_begin / BYTES_PER_WORD; @@ -483,7 +483,7 @@ private: NotifyRasterizer<true>(word_index, current_bits, ~u64{0}); } // Exclude CPU modified pages when visiting GPU pages - const u64 word = current_word; + const u64 word = current_word & ~(type == Type::GPU ? untracked_words[word_index] : 0); u64 page = page_begin; page_begin = 0; @@ -531,7 +531,7 @@ private: [[nodiscard]] bool IsRegionModified(u64 offset, u64 size) const noexcept { static_assert(type != Type::Untracked); - [[maybe_unused]] const u64* const untracked_words = Array<Type::Untracked>(); + const u64* const untracked_words = Array<Type::Untracked>(); const u64* const state_words = Array<type>(); const u64 num_query_words = size / BYTES_PER_WORD + 1; const u64 word_begin = offset / BYTES_PER_WORD; @@ -539,7 +539,8 @@ private: const u64 page_limit = Common::DivCeil(offset + size, BYTES_PER_PAGE); u64 page_index = (offset / BYTES_PER_PAGE) % PAGES_PER_WORD; for (u64 word_index = word_begin; word_index < word_end; ++word_index, page_index = 0) { - const u64 word = state_words[word_index]; + const u64 off_word = type == Type::GPU ? untracked_words[word_index] : 0; + const u64 word = state_words[word_index] & ~off_word; if (word == 0) { continue; } @@ -563,7 +564,7 @@ private: [[nodiscard]] std::pair<u64, u64> ModifiedRegion(u64 offset, u64 size) const noexcept { static_assert(type != Type::Untracked); - [[maybe_unused]] const u64* const untracked_words = Array<Type::Untracked>(); + const u64* const untracked_words = Array<Type::Untracked>(); const u64* const state_words = Array<type>(); const u64 num_query_words = size / BYTES_PER_WORD + 1; const u64 word_begin = offset / BYTES_PER_WORD; @@ -573,7 +574,8 @@ private: u64 begin = std::numeric_limits<u64>::max(); u64 end = 0; for (u64 word_index = word_begin; word_index < word_end; ++word_index) { - const u64 word = state_words[word_index]; + const u64 off_word = type == Type::GPU ? untracked_words[word_index] : 0; + const u64 word = state_words[word_index] & ~off_word; if (word == 0) { continue; } diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index f91bb5a1d..baedc4424 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -548,31 +548,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { static_vector<VkVertexInputBindingDescription, 32> vertex_bindings; static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors; static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes; - if (key.state.dynamic_vertex_input) { - const size_t num_vertex_arrays = std::min( - key.state.attributes.size(), static_cast<size_t>(device.GetMaxVertexInputBindings())); - for (size_t index = 0; index < num_vertex_arrays; ++index) { - const u32 type = key.state.DynamicAttributeType(index); - if (!stage_infos[0].loads.Generic(index) || type == 0) { - continue; - } - vertex_attributes.push_back({ - .location = static_cast<u32>(index), - .binding = 0, - .format = type == 1 ? VK_FORMAT_R32_SFLOAT - : type == 2 ? VK_FORMAT_R32_SINT - : VK_FORMAT_R32_UINT, - .offset = 0, - }); - } - if (!vertex_attributes.empty()) { - vertex_bindings.push_back({ - .binding = 0, - .stride = 4, - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }); - } - } else { + if (!key.state.dynamic_vertex_input) { const size_t num_vertex_arrays = std::min( Maxwell::NumVertexArrays, static_cast<size_t>(device.GetMaxVertexInputBindings())); for (size_t index = 0; index < num_vertex_arrays; ++index) { diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 35fef506a..31209fb2e 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -441,6 +441,7 @@ void Config::ReadControlValues() { Settings::values.mouse_panning = false; ReadBasicSetting(Settings::values.mouse_panning_sensitivity); ReadBasicSetting(Settings::values.enable_joycon_driver); + ReadBasicSetting(Settings::values.enable_procon_driver); ReadBasicSetting(Settings::values.tas_enable); ReadBasicSetting(Settings::values.tas_loop); @@ -1141,6 +1142,7 @@ void Config::SaveControlValues() { WriteGlobalSetting(Settings::values.motion_enabled); WriteBasicSetting(Settings::values.enable_raw_input); WriteBasicSetting(Settings::values.enable_joycon_driver); + WriteBasicSetting(Settings::values.enable_procon_driver); WriteBasicSetting(Settings::values.keyboard_enabled); WriteBasicSetting(Settings::values.emulate_analog_keyboard); WriteBasicSetting(Settings::values.mouse_panning_sensitivity); diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 77b976e74..8d81322f3 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -139,6 +139,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() { Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked(); Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked(); + Settings::values.enable_procon_driver = ui->enable_procon_driver->isChecked(); } void ConfigureInputAdvanced::LoadConfiguration() { @@ -174,6 +175,7 @@ void ConfigureInputAdvanced::LoadConfiguration() { ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue()); ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue()); + ui->enable_procon_driver->setChecked(Settings::values.enable_procon_driver.GetValue()); UpdateUIEnabled(); } diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 75d96d3ab..0eb2b34bc 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2712,6 +2712,22 @@ </widget> </item> <item row="6" column="0"> + <widget class="QCheckBox" name="enable_procon_driver"> + <property name="toolTip"> + <string>Requires restarting yuzu</string> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>23</height> + </size> + </property> + <property name="text"> + <string>Enable direct Pro Controller driver [EXPERIMENTAL]</string> + </property> + </widget> + </item> + <item row="7" column="0"> <widget class="QCheckBox" name="mouse_panning"> <property name="minimumSize"> <size> @@ -2724,7 +2740,7 @@ </property> </widget> </item> - <item row="6" column="2"> + <item row="7" column="2"> <widget class="QSpinBox" name="mouse_panning_sensitivity"> <property name="toolTip"> <string>Mouse sensitivity</string> @@ -2746,14 +2762,14 @@ </property> </widget> </item> - <item row="7" column="0"> + <item row="8" column="0"> <widget class="QLabel" name="motion_touch"> <property name="text"> <string>Motion / Touch</string> </property> </widget> </item> - <item row="7" column="2"> + <item row="8" column="2"> <widget class="QPushButton" name="buttonMotionTouch"> <property name="text"> <string>Configure</string> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f28268e9b..c278d8dab 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -805,6 +805,8 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, layout.screen.GetHeight() / scale_ratio); web_browser_view.move(layout.screen.left / scale_ratio, (layout.screen.top / scale_ratio) + menuBar()->height()); + web_browser_view.setZoomFactor(static_cast<qreal>(layout.screen.GetWidth() / scale_ratio) / + static_cast<qreal>(Layout::ScreenUndocked::Width)); web_browser_view.setFocus(); web_browser_view.show(); diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 9c34cdc6e..3b6dce296 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -178,6 +178,7 @@ void Config::ReadValues() { ReadSetting("ControlsGeneral", Settings::values.enable_raw_input); ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver); + ReadSetting("ControlsGeneral", Settings::values.enable_procon_driver); ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard); ReadSetting("ControlsGeneral", Settings::values.vibration_enabled); ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations); |