SVC
Id | Description |
---|---|
0x1 | ControlMemory(Handle*, unsigned int Addr0, unsigned int Addr1, unsigned int Size, unsigned int MemoryType, unsigned int Permissions) |
0x2 | QueryMemory(MemInfo *Info, unsigned int *Out, unsigned int Addr) |
0x3 | ExitProcess() |
0x4 | GetProcessAffinityMask |
0x5 | SetProcessAffinityMask |
0x6 | GetProcessIdealProcessor(unsigned int *IdealProcessor, Handle KProcess) |
0x7 | SetProcessIdealProcessor(Handle KProcess, unsigned int IdealProcessor) |
0x8 | CreateThread(Handle*, Entrypoint, Entrypoint_Param, Unk, ThreadPriority, ResLimit) |
0x9 | ExitThread() |
0xA | SleepThread |
0xB | GetThreadPriority |
0xC | SetThreadPriority |
0xD | GetThreadAffinityMask |
0xE | SetThreadAffinityMask |
0xF | GetThreadIdealProcessor |
0x10 | SetThreadIdealProcessor |
0x11 | GetCurrentProcessorNumber |
0x12 | Run(KProcess handle, unsigned int *buf) (This starts the main() thread. Buf+0 is main-thread priority, Buf+4 is main-thread stack-size.) |
0x13 | CreateMutex |
0x14 | ReleaseMutex(Handle KMutex) |
0x15 | CreateSemaphore |
0x16 | ReleaseSemaphore |
0x17 | CreateEvent(Handle *KEvent, unsigned char Unk) |
0x18 | SignalEvent(Handle KEvent) |
0x19 | ClearEvent |
0x1A | CreateTimer |
0x1B | SetTimer |
0x1C | CancelTimer |
0x1D | ClearTimer |
0x1E | CreateMemoryBlock |
0x1F | MapMemoryBlock(Handle, unsigned int Addr, unsigned int Permissions, unsigned int Unk) |
0x20 | UnmapMemoryBlock |
0x21 | CreateAddressArbiter |
0x22 | ArbitrateAddress |
0x23 | CloseHandle(Handle) |
0x24 | WaitSynchronization1 |
0x25 | WaitSynchronization2 |
0x26 | SignalAndWait |
0x27 | DuplicateHandle |
0x28 | GetSystemTick |
0x29 | GetHandleInfo |
0x2A | GetSystemInfo |
0x2B | GetProcessInfo(unsigned long long *Output, Handle KProcess, unsigned int Type) |
0x2C | GetThreadInfo |
0x2D | ConnectToPort(Handle*, char *PortName) |
0x2E | SendSyncRequest1 (Stubbed) |
0x2F | SendSyncRequest2 (Stubbed) |
0x30 | SendSyncRequest3 (Stubbed) |
0x31 | SendSyncRequest4 (Stubbed) |
0x32 | SendSyncRequest |
0x33 | OpenProcess(Handle *KProcess, unsigned int ProcessId) |
0x34 | OpenThread |
0x35 | GetProcessId(unsigned int *ProcessId, Handle KProcess) |
0x36 | GetProcessIdOfThread |
0x37 | GetThreadId |
0x38 | GetResourceLimit(Handle*, Handle KProcess) |
0x39 | GetResourceLimitLimitValues |
0x3A | GetResourceLimitCurrentValues |
0x3B | GetThreadContext (Stubbed) |
0x3C | Break(BreakReason) |
0x3D | OutputDebugString(void const, int) (Does nothing on non-debug units) |
0x3E | ControlPerformanceCounter(unsigned long long, int, unsigned int, unsigned long long) |
0x47 | CreatePort |
0x48 | CreateSessionToPort |
0x49 | CreateSession |
0x4A | AcceptSession |
0x4B | ReplyAndReceive1 (Stubbed) |
0x4C | ReplyAndReceive2 (Stubbed) |
0x4D | ReplyAndReceive3 (Stubbed) |
0x4E | ReplyAndReceive4 (Stubbed) |
0x4F | ReplyAndReceive |
0x50 | BindInterrupt(Interrupt, Handle, int, bool) |
0x51 | UnbindInterrupt(Interrupt, Handle) |
0x52 | InvalidateProcessDataCache(Handle, void*, unsigned int) |
0x53 | StoreProcessDataCache(Handle process, void const* addr, unsigned int size) |
0x54 | FlushProcessDataCache(Handle, void const*, unsigned int) |
0x55 | StartInterProcessDma(Handle* out, Handle dstProcess, void* dst, Handle srcProcess, const void* src, size_t size, const DmaConfig& config ) |
0x56 | StopDma(Handle) |
0x57 | GetDmaState(DmaState*, Handle) |
0x58 | RestartDma(nn::Handle, void *, void const*, unsigned int, signed char) |
0x60 | DebugActiveProcess(Handle*, unsigned int ProcessID) |
0x61 | BreakDebugProcess(Handle) |
0x62 | TerminateDebugProcess(Handle) |
0x63 | GetProcessDebugEvent(DebugEventInfo*, Handle) |
0x64 | ContinueDebugEvent(Handle, unsigned int) |
0x65 | GetProcessList(int*, unsigned int*, int) |
0x66 | GetThreadList(int*, unsigned int*, int, Handle) |
0x67 | GetDebugThreadContext(ThreadContext*, Handle, unsigned int, unsigned int) |
0x68 | SetDebugThreadContext(Handle, unsigned int, ThreadContext const&, unsigned int) |
0x69 | QueryDebugProcessMemory(MemoryInfo*, PageInfo*, Handle, unsigned int) |
0x6A | ReadProcessMemory(void*, Handle, unsigned int, unsigned int) |
0x6B | WriteProcessMemory(Handle, void const*, unsigned int, unsigned int) |
0x6C | SetHardwareBreakPoint(int, unsigned int, unsigned int) |
0x6D | GetDebugThreadParam(long long *, int *, nn::Handle, unsigned int, nn::dmnt::DebugThreadParam) (Disabled on regular kernel) |
0x70 | ControlProcessMemory(Handle KProcess, unsigned int Addr0, unsigned int Addr1, unsigned int Size, unsigned int Type, unsigned int Permissions) |
0x71 | MapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr) |
0x72 | UnmapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr) |
0x73 | ? |
0x74 | Stubbed on regular kernel |
0x75 | ? |
0x76 | TerminateProcess(Handle) |
0x77 | (Handle KProcess, Handle KResourceLimit) |
0x78 | CreateResourceLimit(Handle *KResourceLimit) |
0x79 | ? |
0x7A | DisableExecuteNever(unsigned int Addr, unsigned int Size) (Stubbed for regular kernel) |
0x7C | ? |
0x7D | QueryProcessMemory(MemInfo *Info, unsigned int *Out, Handle KProcess, unsigned int Addr) |
0xFF | Debug related (The Syscall access control mask doesn't apply for this SVC) |
Each process can only use SVCs which are enabled in the exheader for this process. The ARM11 kernel SVC handler checks whether the SVC is enabled in the syscall access control mask stored on the SVC-mode stack. When a process context switch is done, the syscall mask is loaded from the KProcess object and is written to the SVC-mode stack.
Each process has a separate handle-table, the size of this table is stored in the exheader. The handles in a handle-table can't be used in the context of other processes, since those handles don't exist in other handle-tables.
Calling svcBreak on retail will only terminate the process which called this SVC. Using CloseHandle() with a KThread handle will terminate the specified thread.
ControlMemory and MapMemoryBlock can be used to map memory pages, these two SVCs only support mapping execute-never R/W pages. The input permissions parameter for these SVCs must be <=3, where value zero is used when un-mapping memory. Bitmask 0xf00 for ControlMemory parameter MemoryType is the memory-type, when this is zero the memory-type is loaded from the kernel flags stored in the exheader ARM11 kernel descriptors, for the process using the SVC. The low 8-bits are the type: 1 is for un-mapping memory, 3 for mapping memory. Type4 is used to mirror the RW memory at Addr1, to Addr0. Type4 will return an error if Addr1 is located in read-only memory. Addr1 is not used for type1 and type3.
ControlProcessMemory maps memory in the specified process, this is the only SVC which allows mapping executable memory. Format of the permissions field for memory mapping SVCs: bit0=R, bit1=W, bit2=X. This SVC can also be used to change the page permissions of already mapped memory.
MapProcessMemory maps RW memory starting at address 0x00100000 in the specified KProcess, at the specified StartAddr in the current process. MapProcessMemory then maps 0x08000000 in the specified process, to StartAddr+0x7f00000 in the current process. UnmapProcessMemory unmaps the memory which was mapped by MapProcessMemory.
DebugActiveProcess is used to attach to a process for debugging. This SVC can only be used when the target process' ARM11 descriptors stored in the exheader have the kernel flag for "Enable debug" set. Otherwise when that flag is clear, the kernel flags for the process using this SVC must have the "Force debug" flag set.