From 5550b48b620808e86bfc677cea810b50e4bd1b03 Mon Sep 17 00:00:00 2001 From: Fuzzy2319 Date: Sat, 25 Apr 2026 21:56:16 +0200 Subject: [PATCH 1/6] add:WIP svc --- include/nn/fs/fs_files.h | 10 ++-- include/nn/os.h | 2 +- include/nn/socket.h | 64 +++++++++++----------- include/nn/svc.h | 115 +++++++++++++++++++++++++++++++++++++++ include/nn/swkbd/swkbd.h | 4 +- include/nn/types.h | 17 +++++- include/nn/util.h | 4 +- 7 files changed, 171 insertions(+), 45 deletions(-) diff --git a/include/nn/fs/fs_files.h b/include/nn/fs/fs_files.h index 38af9323..1ab3bf77 100644 --- a/include/nn/fs/fs_files.h +++ b/include/nn/fs/fs_files.h @@ -38,7 +38,7 @@ void CloseFile(FileHandle handle); position: Position within the file to be read. size: How many bytes to read from file. */ -Result ReadFile(FileHandle handle, long position, void* buffer, ulong size); +Result ReadFile(FileHandle handle, long position, void* buffer, size size); /* Read file at a location, with additional options. @@ -56,7 +56,7 @@ Result ReadFile(FileHandle handle, long position, void* buffer, const ReadOption position: Position within the file to be read. size: How many bytes to read from file. */ -Result ReadFile(ulong* bytesRead, FileHandle handle, long position, void* buffer); +Result ReadFile(u64* bytesRead, FileHandle handle, long position, void* buffer); /* Read file at a location, with an output amount of bytes read, and additional options. @@ -66,7 +66,7 @@ Result ReadFile(ulong* bytesRead, FileHandle handle, long position, void* buffer size: How many bytes to read from file. option: Additional options for reading, see ReadOption. */ -Result ReadFile(ulong* bytesRead, FileHandle handle, long position, void* buffer, +Result ReadFile(u64* bytesRead, FileHandle handle, long position, void* buffer, const ReadOption& option); Result ReadFile(u64* outSize, FileHandle handle, s64 offset, void* buffer, u64 bufferSize, @@ -99,8 +99,8 @@ Result WriteFile(FileHandle handle, s64 position, void const* buffer, u64 size, */ Result FlushFile(FileHandle handle); -// Result GetSaveDataTimeStamp(nn::time::PosixTime *,ulong); -// Result GetSaveDataTimeStamp(nn::time::PosixTime*, nn::fs::SaveDataSpaceId, ulong); +// Result GetSaveDataTimeStamp(nn::time::PosixTime *,u64); +// Result GetSaveDataTimeStamp(nn::time::PosixTime*, nn::fs::SaveDataSpaceId, u64); Result GetFileTimeStampForDebug(nn::fs::FileTimeStamp*, const char*); Result DeleteFile(const char* path); diff --git a/include/nn/os.h b/include/nn/os.h index 6f27d49f..630e3c83 100644 --- a/include/nn/os.h +++ b/include/nn/os.h @@ -215,7 +215,7 @@ struct UserExceptionInfo { CpuRegister FAR; ///< Fault Address Register. }; -void SetUserExceptionHandler(void (*)(UserExceptionInfo*), void*, ulong, UserExceptionInfo*); +void SetUserExceptionHandler(void (*)(UserExceptionInfo*), void*, u64, UserExceptionInfo*); // OTHER void GenerateRandomBytes(void*, u64); diff --git a/include/nn/socket.h b/include/nn/socket.h index 54c7cd44..9b00a683 100644 --- a/include/nn/socket.h +++ b/include/nn/socket.h @@ -20,16 +20,16 @@ struct InAddr { // taken from https://switchbrew.org/wiki/Sockets_services#BsdBufferConfig struct BsdBufferConfig { - ulong tcp_tx_buf_size = 0x8000; ///< Size of the TCP transfer (send) buffer (initial or fixed). - ulong tcp_rx_buf_size = 0x10000; ///< Size of the TCP recieve buffer (initial or fixed). - ulong tcp_tx_buf_max_size = + size tcp_tx_buf_size = 0x8000; ///< Size of the TCP transfer (send) buffer (initial or fixed). + size tcp_rx_buf_size = 0x10000; ///< Size of the TCP recieve buffer (initial or fixed). + size tcp_tx_buf_max_size = 0x30000; ///< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the ///< buffer is fixed to its initial value. - ulong tcp_rx_buf_max_size = 0x30000; ///< Maximum size of the TCP receive buffer. If it is 0, - ///< the size of the buffer is fixed to its initial value. - ulong udp_tx_buf_size = + size tcp_rx_buf_max_size = 0x30000; ///< Maximum size of the TCP receive buffer. If it is 0, + ///< the size of the buffer is fixed to its initial value. + size udp_tx_buf_size = 0x2400; ///< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). - ulong udp_rx_buf_size = 0xA500; ///< Size of the UDP receive buffer (typically 0xA500 bytes). + size udp_rx_buf_size = 0xA500; ///< Size of the UDP receive buffer (typically 0xA500 bytes). int sb_efficiency = 4; ///< Number of buffers for each socket (standard values range from 1 to 8). }; @@ -39,8 +39,8 @@ struct Config { bool unkBool1 = false; // 0x4 bool isUseBsdS = false; // 0x5 void* pool; // 0x8 - ulong poolSize; // 0x10 - ulong allocPoolSize; // 0x18 + size poolSize; // 0x10 + size allocPoolSize; // 0x18 BsdBufferConfig bufferConfig; // 0x20-0x50 int concurLimit; // 0x54 int padding; @@ -48,10 +48,10 @@ struct Config { static_assert(sizeof(Config) == 0x60, "Config Size"); -s32 Recv(s32 socket, void* out, ulong outLen, s32 flags); -s32 RecvFrom(int, void*, ulong, int, sockaddr*, u32*); -s32 Send(s32 socket, const void* data, ulong dataLen, s32 flags); -s32 SendTo(int, const void*, ulong, int, const sockaddr*, u32); +s32 Recv(s32 socket, void* out, size outLen, s32 flags); +s32 RecvFrom(int, void*, size, int, sockaddr*, u32*); +s32 Send(s32 socket, const void* data, size dataLen, s32 flags); +s32 SendTo(int, const void*, size, int, const sockaddr*, u32); s32 Accept(int, sockaddr*, u32*); s32 Bind(int, const sockaddr*, u32); nn::Result Connect(s32 socket, const sockaddr* address, u32 addressLen); @@ -65,11 +65,11 @@ s32 Shutdown(int, int); s32 ShutdownAllSockets(bool); s32 Socket(s32 domain, s32 type, s32 protocol); s32 SocketExempt(int, int, int); -s32 Write(int, const void*, ulong); -s32 Read(int, void*, ulong); +s32 Write(int, const void*, u64); +s32 Read(int, void*, u64); Result Close(s32 socket); s32 Select(int, fd_set*, fd_set*, fd_set*, timeval*); -s32 Poll(pollfd*, ulong, int); +s32 Poll(pollfd*, u64, int); s32 Fcntl(int, int, ...); s32 InetPton(int, const char*, void*); const char* InetNtop(int af, const void* src, char* dst, u32 size); @@ -89,12 +89,12 @@ u32 InetNtohl(u32); s32 GetLastErrno(); void SetLastErrno(int); s32 RecvMsg(int, msghdr*, int); -s32 RecvMMsg(int, mmsghdr*, ulong, int, nn::TimeSpan*); +s32 RecvMMsg(int, mmsghdr*, u64, int, nn::TimeSpan*); s32 SendMsg(int, const msghdr*, int); -s32 SendMMsg(int, const mmsghdr*, ulong, int); -s32 Ioctl(int, u32, void*, ulong); +s32 SendMMsg(int, const mmsghdr*, u64, int); +s32 Ioctl(int, u32, void*, u64); s32 Open(const char*, int); -Result Initialize(void* pool, ulong poolSize, ulong allocPoolSize, int concurLimit); +Result Initialize(void* pool, u64 poolSize, u64 allocPoolSize, int concurLimit); Result Initialize(nn::socket::Config const&); s32 Finalize(); s32 GetAddrInfo(const char*, const char*, const addrinfo*, addrinfo**); @@ -115,19 +115,19 @@ s32 Cancel(int); s32 GetHErrno(); s32 HStrError(int); s32 GAIStrError(int); -s32 Sysctl(int*, ulong, void*, ulong*, void*, ulong); -s32 DuplicateSocket(int, ulong); -s32 GetResourceStatistics(ResourceStatistics*, ulong); +s32 Sysctl(int*, u64, void*, u64*, void*, u64); +s32 DuplicateSocket(int, u64); +s32 GetResourceStatistics(ResourceStatistics*, u64); } // namespace socket } // namespace nn extern "C" { -int nnsocketRecv(int socket, void* out, ulong outLen, int flags); -int nnsocketRecvFrom(int, void*, ulong, int, sockaddr*, u32*); -int nnsocketSend(int socket, const void* data, ulong dataLen, int flags); -int nnsocketSendTo(int, const void*, ulong, int, const sockaddr*, u32); +int nnsocketRecv(int socket, void* out, u64 outLen, int flags); +int nnsocketRecvFrom(int, void*, u64, int, sockaddr*, u32*); +int nnsocketSend(int socket, const void* data, u64 dataLen, int flags); +int nnsocketSendTo(int, const void*, u64, int, const sockaddr*, u32); int nnsocketAccept(int, sockaddr*, u32*); int nnsocketBind(int, const sockaddr*, u32); u32 nnsocketConnect(); // returns nn::Result @@ -143,7 +143,7 @@ int nnsocketWrite(int domain, int type, int protocol); int nnsocketRead(int, int, int); u32 nnsocketClose(); // returns nn::Result void nnsocketSelect(int, fd_set*, fd_set*, fd_set*, timeval*); -void nnsocketPoll(pollfd*, ulong, int); +void nnsocketPoll(pollfd*, u64, int); void nnsocketFcntl(int, int, ...); void nnsocketInetPton(int, const char*, void*); const char* nnsocketInetNtop(int af, const void* src, char* dst, u32 size); @@ -157,9 +157,9 @@ s32 nnsocketGetLastErrno(); void nnsocketSetLastErrno(int); s32 nnsocketRecvMsg(int, msghdr*, int); s32 nnsocketSendMsg(int, const msghdr*, int); -s32 nnsocketIoctl(int, u32, void*, ulong); +s32 nnsocketIoctl(int, u32, void*, u64); s32 nnsocketOpen(const char*, int); -u32 nnsocketInitialize(void* pool, ulong poolSize, ulong allocPoolSize, int concurLimit); +u32 nnsocketInitialize(void* pool, u64 poolSize, u64 allocPoolSize, int concurLimit); s32 nnsocketFinalize(); s32 nnsocketGetAddrInfo(const char*, const char*, const addrinfo*, addrinfo**); s32 nnsocketGetAddrInfoCancel(const char*, const char*, const addrinfo*, addrinfo**, int); @@ -180,6 +180,6 @@ s32 nnsocketCancel(int); s32 nnsocketGetHErrno(); s32 nnsocketHStrError(int); s32 nnsocketGAIStrError(int); -s32 nnsocketSysctl(int*, ulong, void*, ulong*, void*, ulong); -s32 nnsocketDuplicateSocket(int, ulong); +s32 nnsocketSysctl(int*, u64, void*, u64*, void*, u64); +s32 nnsocketDuplicateSocket(int, u64); } diff --git a/include/nn/svc.h b/include/nn/svc.h index 9d7f7ac9..8d87e92e 100644 --- a/include/nn/svc.h +++ b/include/nn/svc.h @@ -1,8 +1,29 @@ #pragma once #include +#include namespace nn::svc { +#define __aarch64__ // TODO: Remove + +#ifdef __aarch64__ +#define aarch aarch64 +#define lp lp64 +#define svc_instruction "svc" +#else +#ifdef __arm__ +#define aarch aarch32 +#define lp ilp32 +#define svc_instruction "swi" +#else +#error Unsupported Architecture +#endif +#endif + +inline __attribute__((always_inline)) void svc(u8 i) { + asm(svc_instruction " %[i]" ::[i] "i"(i)); +} + struct Handle { u32 handle; @@ -13,4 +34,98 @@ struct Handle { operator u32() const { return handle; } }; +enum class MemoryPermission { Read, Write, Execute, DontCare = 28 }; + +enum class MemoryType { + Free, + Io, + Static, + Code, + CodeData, + Normal, + Shared, + Alias, + AliasCode, + AliasCodeData, + Ipc, + Stack, + ThreadLocal, + Transferred, + SharedTransferred, + SharedCode, + Inaccessible, + NonSecureIpc, + NonDeviceIpc, + Kernel, + GeneratedCode, + CodeOut, + Coverage, + Insecure +}; + +enum class MemoryAttribute { + Locked, + IpcLocked, + DeviceShared, + Uncached, + PermissionLocked, + GpuSharable, + GpuShared +}; + +struct PageInfo {}; // TODO + +namespace lp { +struct MemoryInfo { + uintptr baseAddress; + size size; + MemoryType memoryType; + MemoryAttribute memoryAttribute; + MemoryPermission memoryPermission; + s32 ipcRefCount; + s32 deviceRefCount; +}; +} // namespace lp + +namespace aarch { + +#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) // TODO: find when lp namespace was introduced +namespace lp { +#endif + +Result SetHeapSize(uintptr* outHeapAddress, size heapSize); +Result SetMemoryPermission(uintptr address, size regionSize, MemoryPermission memoryPermission); +Result SetMemoryAttribute(uintptr address, size size, u32 mask, u32 attr); +Result MapMemory(uintptr dstAddress, uintptr srcAddress, size size); +Result UnmapMemory(uintptr dstAddress, uintptr srcAddress, size size); +Result QueryMemory(svc::lp::MemoryInfo* outMemoryInfo, PageInfo* outPageInfo, uintptr address); +void ExitProcess(); +Result CreateThread(Handle* outHandle, uintptr entryPointAddress, uintptr threadContextAddress, + uintptr stackAddress, s32 priority, s32 coreId); +Result StartThread(Handle Handle); +void ExitThread(); +void SleepThread(s64 ns); +Result GetThreadPriority(s32* outPriority, Handle handle); +Result SetThreadPriority(Handle handle, s32 priority); +Result GetThreadCoreMask(s32* outCoreId, u64* outAffinityMask, Handle handle); +Result SetThreadCoreMask(Handle handle, s32 coreId, u64 affinityMask); +s32 GetCurrentProcessorNumber(); +Result SignalEvent(Handle handle); +Result ClearEvent(Handle handle); +Result MapSharedMemory(Handle handle, uintptr address, size size, + MemoryPermission memoryPermission); +Result UnmapSharedMemory(Handle handle, uintptr address, size size); +Result CreateTransferMemory(Handle* outHandle, uintptr address, size size, + MemoryPermission memoryPermission); +Result CloseHandle(Handle handle); +Result ResetSignal(Handle handle); +Result WaitSynchronization(s32* outHandleIndex, const Handle* handles, u32 handleCount, + s64 timeoutNs); + +#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) +} // namespace lp +#endif + +} // namespace aarch + } // namespace nn::svc diff --git a/include/nn/swkbd/swkbd.h b/include/nn/swkbd/swkbd.h index ffb322b6..2b40db8e 100644 --- a/include/nn/swkbd/swkbd.h +++ b/include/nn/swkbd/swkbd.h @@ -159,8 +159,8 @@ class String { struct UserWord; // TODO contents missing -ulong GetRequiredWorkBufferSize(bool); -ulong GetRequiredStringBufferSize(); +u64 GetRequiredWorkBufferSize(bool); +u64 GetRequiredStringBufferSize(); nn::applet::ExitReason GetExitReason(); void MakePreset(KeyboardConfig*, Preset); void SetHeaderText(KeyboardConfig*, const char16_t*); diff --git a/include/nn/types.h b/include/nn/types.h index c4dc8f66..c092c3ea 100644 --- a/include/nn/types.h +++ b/include/nn/types.h @@ -8,17 +8,28 @@ using u8 = std::uint8_t; using u16 = std::uint16_t; using u32 = std::uint32_t; using u64 = std::uint64_t; +#ifdef __aarch64__ using u128 = __uint128_t; +#endif using s8 = std::int8_t; using s16 = std::int16_t; using s32 = std::int32_t; using s64 = std::int64_t; +#ifdef __aarch64__ +using s128 = __int128_t; +#endif using f32 = float; using f64 = double; +#ifdef __aarch64__ +using f128 = long double; +#endif using char16 = char16_t; -using size_t = std::size_t; -using ulong = u64; -using ptrdiff_t = std::ptrdiff_t; \ No newline at end of file +using char32 = char32_t; + +using ptrdiff = std::ptrdiff_t; +using uintptr = std::uintptr_t; +using intptr = std::intptr_t; +using size = std::size_t; diff --git a/include/nn/util.h b/include/nn/util.h index 3e2bc5f8..c0d75817 100644 --- a/include/nn/util.h +++ b/include/nn/util.h @@ -18,8 +18,8 @@ CharacterEncodingResult ConvertCharacterUtf8ToUtf32(u32* dest, char const* src); CharacterEncodingResult ConvertStringUtf16NativeToUtf8(char*, s32, u16 const*, s32); CharacterEncodingResult ConvertStringUtf8ToUtf16Native(u16*, s32, char const*, s32); -s32 SNPrintf(char* s, ulong n, const char* format, ...); -s32 VSNPrintf(char* s, ulong n, const char* format, va_list arg); +s32 SNPrintf(char* s, size n, const char* format, ...); +s32 VSNPrintf(char* s, size n, const char* format, va_list arg); void ReferSymbol(const void*); } // namespace util From 715f1d0c6aaf484f583a39f34bd9d5ac0003b055 Mon Sep 17 00:00:00 2001 From: Fuzzy2319 Date: Sun, 26 Apr 2026 19:12:58 +0200 Subject: [PATCH 2/6] add:WIP svc --- include/nn/svc.h | 247 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) diff --git a/include/nn/svc.h b/include/nn/svc.h index 8d87e92e..86f0ebe9 100644 --- a/include/nn/svc.h +++ b/include/nn/svc.h @@ -75,6 +75,121 @@ enum class MemoryAttribute { struct PageInfo {}; // TODO +enum class BreakReason {}; // TODO + +enum class InfoType { + CoreMask, + PriorityMask, + AliasRegionAddress, + AliasRegionSize, + HeapRegionAddress, + HeapRegionSize, + TotalMemorySize, + UsedMemorySize, + DebuggerAttached, + ResourceLimit, + IdleTickCount, + RandomEntropy, + AslrRegionAddress, + AslrRegionSize, + StackRegionAddress, + StackRegionSize, + SystemResourceSizeTotal, + SystemResourceSizeUsed, + ProgramId, + InitialProcessIdRange_LowerBound, + InitialProcessIdRange_UpperBound, + UserExceptionContextAddress, + TotalNonSystemMemorySize, + UsedNonSystemMemorySize, + IsApplication, + FreeThreadCount, + ThreadTickCount, + IsSvcPermitted, + IoRegionHint, + AliasRegionExtraSize, + RemoteRegionAddress, + RemoteRegionSize, + RemoteMemoryUsage, + RemoteMemoryUsagePeak, + ProcessPageSize, + TransferMemoryHint +}; + +enum class LimitableResource { + PhysicalMemoryMax, + ThreadCountMax, + EventCountMax, + TransferMemoryCountMax, + SessionCountMax +}; + +enum class ThreadActivity { None, Runnable }; + +enum class ProcessActivity { None, Runnable }; + +struct ThreadContext { + s8 padding[0xe8]; +}; // TODO + +enum class DumpInfoType {}; // TODO + +struct InterruptEvent {}; // TODO + +enum class InterruptEventType {}; // TODO + +enum class DeviceName { + AFI, + AVPC, + DC, + DCB, + HC, + HDA, + ISP2, + MSENCNVENC, + NV, + NV2, + PPCS, + SATA, + VI, + VIC, + XUSB_HOST, + XUSB_DEV, + TSEC, + PPCS1, + DC1, + SDMMC1A, + SDMMC2A, + SDMMC3A, + SDMMC4A, + ISP2B, + GPU, + GPUB, + PPCS2, + NVDEC, + APE, + SE, + NVJPG, + HC1, + SE1, + AXIAP, + ETR, + TSECB, + TSEC1, + TSECB1, + NVDEC1 +}; + +enum class HardwareBreakPointRegisterName {}; // TODO + +enum class DebugThreadParam { + DynamicPriority, + SchedulingStatus, + PreferredCpuCore, + CurrentCpuCore, + AffinityMask +}; + namespace lp { struct MemoryInfo { uintptr baseAddress; @@ -85,6 +200,24 @@ struct MemoryInfo { s32 ipcRefCount; s32 deviceRefCount; }; + +struct LastThreadContext { + u64 _0; + u64 _8; + u64 _10; + u64 _18; +}; // TODO + +struct PhysicalMemoryInfo { + u64 _0; + u64 _8; + u64 _10; +}; // TODO + +struct DebugEventInfo { + s8 padding[0x40]; +}; // TODO + } // namespace lp namespace aarch { @@ -121,6 +254,120 @@ Result CloseHandle(Handle handle); Result ResetSignal(Handle handle); Result WaitSynchronization(s32* outHandleIndex, const Handle* handles, u32 handleCount, s64 timeoutNs); +Result CancelSynchronization(Handle handle); +Result ArbitrateLock(Handle handle, uintptr address, u32 tag); +Result ArbitrateUnlock(uintptr address); +Result WaitProcessWideKeyAtomic(uintptr keyAddress, uintptr tagAddress, u32 tag, s64 timeoutNs); +Result SignalProcessWideKey(uintptr address, s32 value); +s64 GetSystemTick(); +Result ConnectToNamedPort(Handle* outHandle, const char* portName); +Result SendSyncRequestLight(Handle handle); +Result SendSyncRequest(Handle handle); +Result SendSyncRequestWithUserBuffer(uintptr address, size size, Handle handle); +Result SendAsyncRequestWithUserBuffer(Handle* outHandle, uintptr address, size size, Handle handle); +Result GetProcessId(u64* outProcessId, Handle handle); +Result GetThreadId(u64* outThreadId, Handle handle); +Result Break(BreakReason reason, u64, u64); +Result OutputDebugString(const char* message, size size); +void ReturnFromException(Result result); +Result GetInfo(u64* outInfo, InfoType infotype, Handle handle, u64 infoSubType); +void FlushEntireDataCache(); +Result FlushDataCache(uintptr address, size size); +Result MapPhysicalMemory(uintptr address, size size); +Result UnmapPhysicalMemory(uintptr address, size size); +Result GetLastThreadInfo(svc::lp::LastThreadContext* outContext, uintptr* outTlsAddress, + u32* outFlags); +Result GetResourceLimitLimitValue(s64* outLimit, Handle handle, LimitableResource resource); +Result GetResourceLimitCurrentValue(s64* outCurrentValue, Handle handle, + LimitableResource resource); +Result SetThreadActivity(Handle handle, ThreadActivity activity); +Result GetThreadContext3(ThreadContext* outThreadContext, Handle handle); +Result DumpInfo(DumpInfoType dumpInfoType, u64); +Result ReadWriteRegister(u32* outValue, uintptr registerAddress, u32 rwMask, u32 value); +Result SetProcessActivity(Handle handle, ProcessActivity activity); +Result CreateSharedMemory(Handle* outHandle, size size, MemoryPermission localMemoryPermission, + MemoryPermission remoteMemoryPermission); +Result MapTransferMemory(Handle handle, uintptr address, size size, + MemoryPermission memoryPermission); +Result UnmapTransferMemory(Handle handle, uintptr address, size size); +Result CreateInterruptEvent(Handle* outHandle, InterruptEvent interruptEvent, + InterruptEventType eventType); +Result QueryPhysicalAddress(svc::lp::PhysicalMemoryInfo* outPhysicalMemoryInfo, + uintptr virtualAddress); +Result QueryIoMapping(uintptr* outVirtualAddress, uintptr ioAddress, size size); +Result CreateDeviceAddressSpace(Handle* outHandle, uintptr startAddress, uintptr endAddress); +Result AttachDeviceAddressSpace(DeviceName deviceName, Handle handle); +Result DetachDeviceAddressSpace(DeviceName deviceName, Handle handle); +Result MapDeviceAddressSpaceByForce(Handle deviceAddressSpaceHandle, Handle processHandle, + uintptr processAddress, size size, uintptr deviceAddress, + MemoryPermission memoryPermission); +Result MapDeviceAddressSpaceAligned(Handle deviceAddressSpaceHandle, Handle processHandle, + uintptr processAddress, size size, uintptr deviceAddress, + MemoryPermission memoryPermission); +Result MapDeviceAddressSpace(size* outMappedSize, Handle deviceAddressSpaceHandle, + Handle processHandle, uintptr processAddress, size size, + uintptr deviceAddress, MemoryPermission memoryPermission); +Result UnmapDeviceAddressSpace(Handle deviceAddressSpaceHandle, Handle processHandle, + uintptr processAddress, size size, uintptr deviceAddress, + MemoryPermission memoryPermission); +Result InvalidateProcessDataCache(Handle handle, uintptr address, size size); +Result StoreProcessDataCache(Handle handle, uintptr address, size size); +Result FlushProcessDataCache(Handle handle, uintptr address, size size); +Result DebugActiveProcess(Handle handle, u64 processId); +Result BreakDebugProcess(Handle handle); +Result TerminateDebugProcess(Handle handle); +Result GetDebugEvent(svc::lp::DebugEventInfo* outDebugEventInfo, Handle handle); +Result ContinueDebugEvent(Handle handle, u32 flags, const u64* threadIds, u32 threadIdCount); +Result GetProcessList(u32* outProcessIdCount, u64* outProcessIds, u32 maxProcessIdCount); +Result GetThreadList(u32* outThreadIdCount, u64* outThreadIds, u32 maxThreadIdCount, Handle handle); +Result GetDebugThreadContext(ThreadContext* outThreadContext, Handle handle, u64 threadId, + u32 flags); +Result SetDebugThreadContext(Handle handle, u64 threadId, const ThreadContext& threadContext, + u32 flags); +Result QueryDebugProcessMemory(svc::lp::MemoryInfo* outMemoryInfo, PageInfo* outPageInfo, + Handle handle, uintptr address); +Result ReadDebugProcessMemory(uintptr bufferAddress, Handle handle, uintptr srcAddress, size size); +Result WriteDebugProcessMemory(Handle handle, uintptr bufferAddress, uintptr dstAddress, size size); +Result SetHardwareBreakPoint(HardwareBreakPointRegisterName registerName, u64 flags, u64 value); +Result GetDebugThreadParam(u64*, u32*, Handle handle, u64 threadId, DebugThreadParam param); +Result CreateSession(Handle* outServerHandle, Handle* outClientHandle, bool isLight, u64); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); +Result ArbitrateUnlock(uintptr address); #if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) } // namespace lp From a30029cd68a7f171e9362374986714fe1c4f2265 Mon Sep 17 00:00:00 2001 From: Fuzzy2319 Date: Thu, 30 Apr 2026 15:33:58 +0200 Subject: [PATCH 3/6] add:WIP svc --- include/nn/svc.h | 79 ++++++++++++++++++++++++---------------------- include/nn/types.h | 6 ---- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/include/nn/svc.h b/include/nn/svc.h index 86f0ebe9..f84020f2 100644 --- a/include/nn/svc.h +++ b/include/nn/svc.h @@ -190,6 +190,8 @@ enum class DebugThreadParam { AffinityMask }; +enum class ProcessInfoType { ProcessState }; + namespace lp { struct MemoryInfo { uintptr baseAddress; @@ -218,6 +220,17 @@ struct DebugEventInfo { s8 padding[0x40]; }; // TODO +struct CreateProcessParameter { + char _0[0xc]; + s32 _c; + s64 _10; + uintptr _18; + s32 _20; + s32 _24; + Handle _28; + s32 _2c; +}; // TODO + } // namespace lp namespace aarch { @@ -331,43 +344,35 @@ Result WriteDebugProcessMemory(Handle handle, uintptr bufferAddress, uintptr dst Result SetHardwareBreakPoint(HardwareBreakPointRegisterName registerName, u64 flags, u64 value); Result GetDebugThreadParam(u64*, u32*, Handle handle, u64 threadId, DebugThreadParam param); Result CreateSession(Handle* outServerHandle, Handle* outClientHandle, bool isLight, u64); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); -Result ArbitrateUnlock(uintptr address); +Result AcceptSession(Handle* outPortHandle, Handle sessionHandle); +Result ReplyAndReceiveLight(Handle handle); +Result ReplyAndReceive(s32* outHandleIndex, const Handle* handles, s32 handleCount, Handle handle, + s64 timeout); +Result ReplyAndReceiveWithUserBuffer(s32* outHandleIndex, uintptr bufferAddress, size bufferSize, + const Handle* handles, s32 handleCount, Handle handle, + s64 timeout); +Result CreateEvent(Handle* outWritableEventHandle, Handle* outReadableEventHandle); +void SleepSystem(); +Result CreatePort(Handle* outServerHandle, Handle* outClientHandle, s32 maxSessionCount, + bool isLight, u64); +Result ManageNamedPort(Handle* outServerHandle, const char* name, s32 maxSessionCount); +Result ConnectToPort(Handle* outSessionHandle, Handle handle); +Result SetProcessMemoryPermission(Handle handle, uintptr address, size size, + MemoryPermission memoryPermission); +Result MapProcessMemory(uintptr dstAddress, Handle handle, uintptr srcAddress, size size); +Result UnmapProcessMemory(uintptr dstAddress, Handle handle, uintptr srcAddress, size size); +Result QueryProcessMemory(svc::lp::MemoryInfo* outMemoryInfo, PageInfo* outPageInfo, Handle handle, + uintptr address); +Result MapProcessCodeMemory(Handle handle, uintptr dstAddress, uintptr srcAddress, size size); +Result UnmapProcessCodeMemory(Handle handle, uintptr dstAddress, uintptr srcAddress, size size); +Result CreateProcess(Handle* outHandle, const svc::lp::CreateProcessParameter& parameter, + const u32* capabilities, s32 capabilityCount); +Result StartProcess(Handle handle, s32 priority, s32 defaultCpuId, u64 stackSize); +Result TerminateProcess(Handle handle); +Result GetProcessInfo(s64* outProcessInfo, Handle handle, ProcessInfoType processInfoType); +Result CreateResourceLimit(Handle* outHandle); +Result SetResourceLimitLimitValue(Handle handle, LimitableResource resource, s64 value); +void CallSecureMonitor(); #if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) } // namespace lp diff --git a/include/nn/types.h b/include/nn/types.h index c092c3ea..27b309ba 100644 --- a/include/nn/types.h +++ b/include/nn/types.h @@ -8,23 +8,17 @@ using u8 = std::uint8_t; using u16 = std::uint16_t; using u32 = std::uint32_t; using u64 = std::uint64_t; -#ifdef __aarch64__ using u128 = __uint128_t; -#endif using s8 = std::int8_t; using s16 = std::int16_t; using s32 = std::int32_t; using s64 = std::int64_t; -#ifdef __aarch64__ using s128 = __int128_t; -#endif using f32 = float; using f64 = double; -#ifdef __aarch64__ using f128 = long double; -#endif using char16 = char16_t; using char32 = char32_t; From 16962ee22ec769c41248b3ac8cc774a5ab78746c Mon Sep 17 00:00:00 2001 From: Fuzzy2319 Date: Thu, 30 Apr 2026 16:46:37 +0200 Subject: [PATCH 4/6] fix:correct function signatures for arm32 --- include/nn/svc.h | 50 ++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/include/nn/svc.h b/include/nn/svc.h index f84020f2..fdfff9fd 100644 --- a/include/nn/svc.h +++ b/include/nn/svc.h @@ -265,7 +265,7 @@ Result CreateTransferMemory(Handle* outHandle, uintptr address, size size, MemoryPermission memoryPermission); Result CloseHandle(Handle handle); Result ResetSignal(Handle handle); -Result WaitSynchronization(s32* outHandleIndex, const Handle* handles, u32 handleCount, +Result WaitSynchronization(s32* outHandleIndex, const Handle* handles, s32 handleCount, s64 timeoutNs); Result CancelSynchronization(Handle handle); Result ArbitrateLock(Handle handle, uintptr address, u32 tag); @@ -280,7 +280,7 @@ Result SendSyncRequestWithUserBuffer(uintptr address, size size, Handle handle); Result SendAsyncRequestWithUserBuffer(Handle* outHandle, uintptr address, size size, Handle handle); Result GetProcessId(u64* outProcessId, Handle handle); Result GetThreadId(u64* outThreadId, Handle handle); -Result Break(BreakReason reason, u64, u64); +Result Break(BreakReason reason, uintptr, size); Result OutputDebugString(const char* message, size size); void ReturnFromException(Result result); Result GetInfo(u64* outInfo, InfoType infotype, Handle handle, u64 infoSubType); @@ -296,7 +296,7 @@ Result GetResourceLimitCurrentValue(s64* outCurrentValue, Handle handle, Result SetThreadActivity(Handle handle, ThreadActivity activity); Result GetThreadContext3(ThreadContext* outThreadContext, Handle handle); Result DumpInfo(DumpInfoType dumpInfoType, u64); -Result ReadWriteRegister(u32* outValue, uintptr registerAddress, u32 rwMask, u32 value); +Result ReadWriteRegister(u32* outValue, u64 registerAddress, u32 rwMask, u32 value); Result SetProcessActivity(Handle handle, ProcessActivity activity); Result CreateSharedMemory(Handle* outHandle, size size, MemoryPermission localMemoryPermission, MemoryPermission remoteMemoryPermission); @@ -307,32 +307,36 @@ Result CreateInterruptEvent(Handle* outHandle, InterruptEvent interruptEvent, InterruptEventType eventType); Result QueryPhysicalAddress(svc::lp::PhysicalMemoryInfo* outPhysicalMemoryInfo, uintptr virtualAddress); -Result QueryIoMapping(uintptr* outVirtualAddress, uintptr ioAddress, size size); -Result CreateDeviceAddressSpace(Handle* outHandle, uintptr startAddress, uintptr endAddress); +Result QueryIoMapping(uintptr* outVirtualAddress, u64 ioAddress, size size); +Result CreateDeviceAddressSpace(Handle* outHandle, u64 startAddress, u64 endAddress); Result AttachDeviceAddressSpace(DeviceName deviceName, Handle handle); Result DetachDeviceAddressSpace(DeviceName deviceName, Handle handle); Result MapDeviceAddressSpaceByForce(Handle deviceAddressSpaceHandle, Handle processHandle, - uintptr processAddress, size size, uintptr deviceAddress, + u64 processAddress, size size, u64 deviceAddress, MemoryPermission memoryPermission); Result MapDeviceAddressSpaceAligned(Handle deviceAddressSpaceHandle, Handle processHandle, - uintptr processAddress, size size, uintptr deviceAddress, + u64 processAddress, size size, u64 deviceAddress, MemoryPermission memoryPermission); Result MapDeviceAddressSpace(size* outMappedSize, Handle deviceAddressSpaceHandle, - Handle processHandle, uintptr processAddress, size size, - uintptr deviceAddress, MemoryPermission memoryPermission); + Handle processHandle, u64 processAddress, size size, u64 deviceAddress, + MemoryPermission memoryPermission); Result UnmapDeviceAddressSpace(Handle deviceAddressSpaceHandle, Handle processHandle, - uintptr processAddress, size size, uintptr deviceAddress, + u64 processAddress, size size, u64 deviceAddress, MemoryPermission memoryPermission); -Result InvalidateProcessDataCache(Handle handle, uintptr address, size size); -Result StoreProcessDataCache(Handle handle, uintptr address, size size); -Result FlushProcessDataCache(Handle handle, uintptr address, size size); +Result InvalidateProcessDataCache(Handle handle, u64 address, u64 size); +Result StoreProcessDataCache(Handle handle, u64 address, u64 size); +Result FlushProcessDataCache(Handle handle, u64 address, u64 size); Result DebugActiveProcess(Handle handle, u64 processId); Result BreakDebugProcess(Handle handle); Result TerminateDebugProcess(Handle handle); Result GetDebugEvent(svc::lp::DebugEventInfo* outDebugEventInfo, Handle handle); +#if NN_SDK_VER >= NN_MAKE_VER(3, 0, 0) Result ContinueDebugEvent(Handle handle, u32 flags, const u64* threadIds, u32 threadIdCount); -Result GetProcessList(u32* outProcessIdCount, u64* outProcessIds, u32 maxProcessIdCount); -Result GetThreadList(u32* outThreadIdCount, u64* outThreadIds, u32 maxThreadIdCount, Handle handle); +#else +Result ContinueDebugEvent(Handle handle, u32 flags, u64 threadId); +#endif +Result GetProcessList(s32* outProcessIdCount, u64* outProcessIds, s32 maxProcessIdCount); +Result GetThreadList(s32* outThreadIdCount, u64* outThreadIds, s32 maxThreadIdCount, Handle handle); Result GetDebugThreadContext(ThreadContext* outThreadContext, Handle handle, u64 threadId, u32 flags); Result SetDebugThreadContext(Handle handle, u64 threadId, const ThreadContext& threadContext, @@ -343,7 +347,7 @@ Result ReadDebugProcessMemory(uintptr bufferAddress, Handle handle, uintptr srcA Result WriteDebugProcessMemory(Handle handle, uintptr bufferAddress, uintptr dstAddress, size size); Result SetHardwareBreakPoint(HardwareBreakPointRegisterName registerName, u64 flags, u64 value); Result GetDebugThreadParam(u64*, u32*, Handle handle, u64 threadId, DebugThreadParam param); -Result CreateSession(Handle* outServerHandle, Handle* outClientHandle, bool isLight, u64); +Result CreateSession(Handle* outServerHandle, Handle* outClientHandle, bool isLight, uintptr); Result AcceptSession(Handle* outPortHandle, Handle sessionHandle); Result ReplyAndReceiveLight(Handle handle); Result ReplyAndReceive(s32* outHandleIndex, const Handle* handles, s32 handleCount, Handle handle, @@ -354,17 +358,17 @@ Result ReplyAndReceiveWithUserBuffer(s32* outHandleIndex, uintptr bufferAddress, Result CreateEvent(Handle* outWritableEventHandle, Handle* outReadableEventHandle); void SleepSystem(); Result CreatePort(Handle* outServerHandle, Handle* outClientHandle, s32 maxSessionCount, - bool isLight, u64); + bool isLight, uintptr); Result ManageNamedPort(Handle* outServerHandle, const char* name, s32 maxSessionCount); Result ConnectToPort(Handle* outSessionHandle, Handle handle); -Result SetProcessMemoryPermission(Handle handle, uintptr address, size size, +Result SetProcessMemoryPermission(Handle handle, u64 address, u64 size, MemoryPermission memoryPermission); -Result MapProcessMemory(uintptr dstAddress, Handle handle, uintptr srcAddress, size size); -Result UnmapProcessMemory(uintptr dstAddress, Handle handle, uintptr srcAddress, size size); +Result MapProcessMemory(uintptr dstAddress, Handle handle, u64 srcAddress, size size); +Result UnmapProcessMemory(uintptr dstAddress, Handle handle, u64 srcAddress, size size); Result QueryProcessMemory(svc::lp::MemoryInfo* outMemoryInfo, PageInfo* outPageInfo, Handle handle, - uintptr address); -Result MapProcessCodeMemory(Handle handle, uintptr dstAddress, uintptr srcAddress, size size); -Result UnmapProcessCodeMemory(Handle handle, uintptr dstAddress, uintptr srcAddress, size size); + u64 address); +Result MapProcessCodeMemory(Handle handle, u64 dstAddress, u64 srcAddress, u64 size); +Result UnmapProcessCodeMemory(Handle handle, u64 dstAddress, u64 srcAddress, u64 size); Result CreateProcess(Handle* outHandle, const svc::lp::CreateProcessParameter& parameter, const u32* capabilities, s32 capabilityCount); Result StartProcess(Handle handle, s32 priority, s32 defaultCpuId, u64 stackSize); From 605e5bd8bc4c25e11695873223eb53da20d2be1d Mon Sep 17 00:00:00 2001 From: Fuzzy2319 Date: Thu, 30 Apr 2026 16:57:26 +0200 Subject: [PATCH 5/6] update:remove debug stuff --- include/nn/svc.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/nn/svc.h b/include/nn/svc.h index fdfff9fd..a0ef2d91 100644 --- a/include/nn/svc.h +++ b/include/nn/svc.h @@ -4,8 +4,6 @@ #include namespace nn::svc { -#define __aarch64__ // TODO: Remove - #ifdef __aarch64__ #define aarch aarch64 #define lp lp64 @@ -234,11 +232,9 @@ struct CreateProcessParameter { } // namespace lp namespace aarch { - #if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) // TODO: find when lp namespace was introduced namespace lp { #endif - Result SetHeapSize(uintptr* outHeapAddress, size heapSize); Result SetMemoryPermission(uintptr address, size regionSize, MemoryPermission memoryPermission); Result SetMemoryAttribute(uintptr address, size size, u32 mask, u32 attr); @@ -377,11 +373,9 @@ Result GetProcessInfo(s64* outProcessInfo, Handle handle, ProcessInfoType proces Result CreateResourceLimit(Handle* outHandle); Result SetResourceLimitLimitValue(Handle handle, LimitableResource resource, s64 value); void CallSecureMonitor(); - #if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) } // namespace lp #endif - } // namespace aarch } // namespace nn::svc From c4484775b5d4877faa0d0f2e3c2fbfdc2480f044 Mon Sep 17 00:00:00 2001 From: Fuzzy2319 Date: Fri, 1 May 2026 12:30:25 +0200 Subject: [PATCH 6/6] fix:namespace && fix:enums --- include/nn/svc.h | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/include/nn/svc.h b/include/nn/svc.h index a0ef2d91..79334b2e 100644 --- a/include/nn/svc.h +++ b/include/nn/svc.h @@ -18,10 +18,6 @@ namespace nn::svc { #endif #endif -inline __attribute__((always_inline)) void svc(u8 i) { - asm(svc_instruction " %[i]" ::[i] "i"(i)); -} - struct Handle { u32 handle; @@ -32,7 +28,7 @@ struct Handle { operator u32() const { return handle; } }; -enum class MemoryPermission { Read, Write, Execute, DontCare = 28 }; +enum class MemoryPermission { Read = 1 << 0, Write = 1 << 1, Execute = 1 << 2, DontCare = 1 << 28 }; enum class MemoryType { Free, @@ -62,13 +58,13 @@ enum class MemoryType { }; enum class MemoryAttribute { - Locked, - IpcLocked, - DeviceShared, - Uncached, - PermissionLocked, - GpuSharable, - GpuShared + Locked = 1 << 0, + IpcLocked = 1 << 1, + DeviceShared = 1 << 2, + Uncached = 1 << 3, + PermissionLocked = 1 << 4, + GpuSharable = 1 << 5, + GpuShared = 1 << 6 }; struct PageInfo {}; // TODO @@ -95,8 +91,7 @@ enum class InfoType { SystemResourceSizeTotal, SystemResourceSizeUsed, ProgramId, - InitialProcessIdRange_LowerBound, - InitialProcessIdRange_UpperBound, + InitialProcessIdRange, UserExceptionContextAddress, TotalNonSystemMemorySize, UsedNonSystemMemorySize, @@ -222,7 +217,7 @@ struct CreateProcessParameter { char _0[0xc]; s32 _c; s64 _10; - uintptr _18; + u64 _18; s32 _20; s32 _24; Handle _28; @@ -232,7 +227,7 @@ struct CreateProcessParameter { } // namespace lp namespace aarch { -#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) // TODO: find when lp namespace was introduced +#ifdef __aarch64__ namespace lp { #endif Result SetHeapSize(uintptr* outHeapAddress, size heapSize); @@ -373,7 +368,7 @@ Result GetProcessInfo(s64* outProcessInfo, Handle handle, ProcessInfoType proces Result CreateResourceLimit(Handle* outHandle); Result SetResourceLimitLimitValue(Handle handle, LimitableResource resource, s64 value); void CallSecureMonitor(); -#if NN_SDK_VER >= NN_MAKE_VER(1, 0, 0) +#ifdef __aarch64__ } // namespace lp #endif } // namespace aarch