Changes

Jump to navigation Jump to search
4,306 bytes added ,  20:37, 2 January 2020
Page cleanup - part 2
Line 5: Line 5:  
! Id || Name || In || Out
 
! Id || Name || In || Out
 
|-
 
|-
|  0x1 || [[#svcSetHeapSize]] || ||
+
|  0x1 || [[#SetHeapSize]] || ||
 
|-
 
|-
|  0x2 || [[#svcSetMemoryPermission]] || ||
+
|  0x2 || [[#SetMemoryPermission]] || ||
 
|-
 
|-
|  0x3 || [[#svcSetMemoryAttribute]] || ||
+
|  0x3 || [[#SetMemoryAttribute]] || ||
 
|-
 
|-
|  0x4 || [[#svcMapMemory]] || ||
+
|  0x4 || [[#MapMemory]] || ||
 
|-
 
|-
|  0x5 || [[#svcUnmapMemory]] || ||
+
|  0x5 || [[#UnmapMemory]] || ||
 
|-
 
|-
|  0x6 || [[#svcQueryMemory]] || ||
+
|  0x6 || [[#QueryMemory]] || ||
 
|-
 
|-
|  0x7 || [[#svcExitProcess]] || ||
+
|  0x7 || [[#ExitProcess]] || ||
 
|-
 
|-
|  0x8 || [[#svcCreateThread]] || ||
+
|  0x8 || [[#CreateThread]] || ||
 
|-
 
|-
|  0x9 || [[#svcStartThread]] || ||
+
|  0x9 || [[#StartThread]] || ||
 
|-
 
|-
|  0xA || [[#svcExitThread]] || ||
+
|  0xA || [[#ExitThread]] || ||
 
|-
 
|-
|  0xB || [[#svcSleepThread]] || ||
+
|  0xB || [[#SleepThread]] || ||
 
|-
 
|-
|  0xC || [[#svcGetThreadPriority]] || ||
+
|  0xC || [[#GetThreadPriority]] || ||
 
|-
 
|-
|  0xD || [[#svcSetThreadPriority]] || ||
+
|  0xD || [[#SetThreadPriority]] || ||
 
|-
 
|-
|  0xE || [[#svcGetThreadCoreMask]] || ||
+
|  0xE || [[#GetThreadCoreMask]] || ||
 
|-
 
|-
|  0xF || [[#svcSetThreadCoreMask]] || ||
+
|  0xF || [[#SetThreadCoreMask]] || ||
 
|-
 
|-
| 0x10 || [[#svcGetCurrentProcessorNumber]] || ||
+
| 0x10 || [[#GetCurrentProcessorNumber]] || ||
 
|-
 
|-
| 0x11 || [[#svcSignalEvent]] || ||
+
| 0x11 || [[#SignalEvent]] || ||
 
|-
 
|-
| 0x12 || [[#svcClearEvent]] || ||
+
| 0x12 || [[#ClearEvent]] || ||
 
|-
 
|-
| 0x13 || [[#svcMapSharedMemory]] || ||
+
| 0x13 || [[#MapSharedMemory]] || ||
 
|-
 
|-
| 0x14 || [[#svcUnmapSharedMemory]] || ||
+
| 0x14 || [[#UnmapSharedMemory]] || ||
 
|-
 
|-
| 0x15 || [[#svcCreateTransferMemory]] || ||
+
| 0x15 || [[#CreateTransferMemory]] || ||
 
|-
 
|-
| 0x16 || [[#svcCloseHandle]] || ||
+
| 0x16 || [[#CloseHandle]] || ||
 
|-
 
|-
| 0x17 || [[#svcResetSignal]] || ||
+
| 0x17 || [[#ResetSignal]] || ||
 
|-
 
|-
| 0x18 || [[#svcWaitSynchronization]] || ||
+
| 0x18 || [[#WaitSynchronization]] || ||
 
|-
 
|-
| 0x19 || [[#svcCancelSynchronization]] || ||
+
| 0x19 || [[#CancelSynchronization]] || ||
 
|-
 
|-
| 0x1A || [[#svcArbitrateLock]] || ||
+
| 0x1A || [[#ArbitrateLock]] || ||
 
|-
 
|-
| 0x1B || [[#svcArbitrateUnlock]] || ||
+
| 0x1B || [[#ArbitrateUnlock]] || ||
 
|-
 
|-
| 0x1C || [[#svcWaitProcessWideKeyAtomic]] || ||
+
| 0x1C || [[#WaitProcessWideKeyAtomic]] || ||
 
|-
 
|-
| 0x1D || [[#svcSignalProcessWideKey]] || ||
+
| 0x1D || [[#SignalProcessWideKey]] || ||
 
|-
 
|-
| 0x1E || [[#svcGetSystemTick]] || ||
+
| 0x1E || [[#GetSystemTick]] || ||
 
|-
 
|-
| 0x1F || [[#svcConnectToNamedPort]] || ||
+
| 0x1F || [[#ConnectToNamedPort]] || ||
 
|-
 
|-
| 0x20 || [[#svcSendSyncRequestLight]] || ||
+
| 0x20 || [[#SendSyncRequestLight]] || ||
 
|-
 
|-
| 0x21 || [[#svcSendSyncRequest]] || ||
+
| 0x21 || [[#SendSyncRequest]] || ||
 
|-
 
|-
| 0x22 || [[#svcSendSyncRequestWithUserBuffer]] || ||
+
| 0x22 || [[#SendSyncRequestWithUserBuffer]] || ||
 
|-
 
|-
| 0x23 || svcSendAsyncRequestWithUserBuffer || X1=cmdbufptr, X2=size, X3=handle || W0=result, W1=revent_handle
+
| 0x23 || [[#SendAsyncRequestWithUserBuffer]] || ||
 
|-
 
|-
| 0x24 || svcGetProcessId || W1=thread_or_process_or_debug_handle || W0=result, X1=pid
+
| 0x24 || [[#GetProcessId]] || ||
R0=result, R1=pid_lower32, R2=pid_upper32
   
|-
 
|-
| 0x25 || svcGetThreadId || W1=thread_handle || W0=result, X1=out
+
| 0x25 || [[#GetThreadId]] || ||
R0=result, R1=out_lower32, R2=out_upper32
   
|-
 
|-
| 0x26 || [[#svcBreak]] || ||
+
| 0x26 || [[#Break]] || ||
 
|-
 
|-
| 0x27 || svcOutputDebugString || X0=str, X1=size || W0=result
+
| 0x27 || [[#OutputDebugString]] || ||
 
|-
 
|-
| 0x28 || svcReturnFromException || X0=result ||  
+
| 0x28 || [[#ReturnFromException]] || ||
 
|-
 
|-
| 0x29 || [[#svcGetInfo]] || ||
+
| 0x29 || [[#GetInfo]] || ||
 
|-
 
|-
| 0x2A || svcFlushEntireDataCache || None || None
+
| 0x2A || [[#FlushEntireDataCache]] || ||  
 
|-
 
|-
| 0x2B || svcFlushDataCache || X0=addr, X1=size || W0=result
+
| 0x2B || [[#FlushDataCache]] || ||
 
|-
 
|-
| 0x2C || [3.0.0+] [[#svcMapPhysicalMemory]] || X0=addr, X1=size || W0=result
+
| 0x2C || [3.0.0+] [[#MapPhysicalMemory]] || ||  
 
|-
 
|-
| 0x2D || [3.0.0+] svcUnmapPhysicalMemory || X0=addr, X1=size || W0=result
+
| 0x2D || [3.0.0+] [[#UnmapPhysicalMemory]] || ||
 
|-
 
|-
| 0x2E || [5.0.0+] svcGetFutureThreadInfo || X3=timeout
+
| 0x2E || [5.0.0+] [[#GetFutureThreadInfo]] || ||
R0=timeout_lower32, R1=timeout_upper32
  −
|| W0=result, bunch of crap
   
|-
 
|-
| 0x2F || svcGetLastThreadInfo || None || W0=result, W1,W2,W3,W4=unk, W5=truncated_u64, W6=bool
+
| 0x2F || [[#GetLastThreadInfo]] || ||
 
|-
 
|-
| 0x30 || svcGetResourceLimitLimitValue || W1=reslimit_handle, W2=[[#LimitableResource]] || W0=result, X1=value
+
| 0x30 || [[#GetResourceLimitLimitValue]] || ||
R0=result, R1=value_lower32, R2=value_upper32
   
|-
 
|-
| 0x31 || svcGetResourceLimitCurrentValue || W1=reslimit_handle, W2=[[#LimitableResource]] || W0=result, X1=value
+
| 0x31 || [[#GetResourceLimitCurrentValue]] || ||
R0=result, R1=value_lower32, R2=value_upper32
   
|-
 
|-
| 0x32 || svcSetThreadActivity || W0=thread_handle, W1=bool || W0=result
+
| 0x32 || [[#SetThreadActivity]] || ||
 
|-
 
|-
| 0x33 || svcGetThreadContext3 || X0=[[#ThreadContext]]*, W1=thread_handle || W0=result
+
| 0x33 || [[#GetThreadContext3]] || ||
 
|-
 
|-
| 0x34 || [4.0.0+] svcWaitForAddress || X0=ptr, W1=[[#ArbitrationType]], X2=value, X3=timeout
+
| 0x34 || [4.0.0+] [[#WaitForAddress]] || ||
R0=ptr, R1=[[#ArbitrationType]], R2=value, R3=timeout_lower32, R4=timeout_upper32
  −
||
   
|-
 
|-
| 0x35 || [4.0.0+] svcSignalToAddress || X0=ptr, W1=[[#SignalType]], X2=value, W3=num_to_signal ||
+
| 0x35 || [4.0.0+] [[#SignalToAddress]] || ||
 
|-
 
|-
| 0x36 || [8.0.0+] svcSynchronizePreemptionState || None || W0=result
+
| 0x36 || [8.0.0+] [[#SynchronizePreemptionState]] || ||
 
|- style="border-top: double"
 
|- style="border-top: double"
| 0x3C || [4.0.0+] svcKernelDebug ([1.0.0-3.0.2] [[#svcDumpInfo]]) || ||
+
| 0x3C || [4.0.0+] [[#KernelDebug]] ([1.0.0-3.0.2] [[#DumpInfo]]) || ||
 
|-
 
|-
| 0x3D || [4.0.0+] svcChangeKernelTraceState || ||
+
| 0x3D || [4.0.0+] [[#ChangeKernelTraceState]] || ||
 
|- style="border-top: double"
 
|- style="border-top: double"
| 0x40 || svcCreateSession || W2=is_light, X3=name_ptr || W0=result, W1=server_handle, W2=client_handle
+
| 0x40 || [[#CreateSession]] || ||
 
|-
 
|-
| 0x41 || [[#svcAcceptSession]] || W1=port_handle || W0=result, W1=session_handle
+
| 0x41 || [[#AcceptSession]] || ||
 
|-
 
|-
| 0x42 || svcReplyAndReceiveLight || W0=light_session_handle || W0=result, W1,W2,W3,W4,W5,W6,W7=out
+
| 0x42 || [[#ReplyAndReceiveLight]] || ||
 
|-
 
|-
| 0x43 || [[#svcReplyAndReceive]] || X1=ptr_handles, W2=num_handles, X3=replytarget_handle(0=none), X4=timeout
+
| 0x43 || [[#ReplyAndReceive]] || ||
R0=timeout_lower32, R1=ptr_handles, R2=num_handles, R3=replytarget_handle(0=none), R4=timeout_upper32
  −
|| W0=result, W1=handle_idx
   
|-
 
|-
| 0x44 || svcReplyAndReceiveWithUserBuffer|| X1=buf, X2=sz, X3=ptr_handles, W4=num_handles, X5=replytarget_handle(0=none), X6=timeout
+
| 0x44 || [[#ReplyAndReceiveWithUserBuffer]] || ||
R0=num_handles, R1=buf, R2=sz, R3=ptr_handles, R4=replytarget_handle(0=none), R5=timeout_lower32, R6=timeout_upper32
  −
|| W0=result, W1=handle_idx
   
|-
 
|-
| 0x45 || svcCreateEvent || None || W0=result, W1=wevent_handle, W2=revent_handle
+
| 0x45 || [[#CreateEvent]] || ||
 
|- style="border-top: double"
 
|- style="border-top: double"
| 0x48 || [5.0.0+] [[#svcMapPhysicalMemoryUnsafe]] || X0=addr, X1=size || W0=result
+
| 0x48 || [5.0.0+] [[#MapPhysicalMemoryUnsafe]] || ||
 
|-
 
|-
| 0x49 || [5.0.0+] svcUnmapPhysicalMemoryUnsafe || X0=addr, X1=size || W0=result
+
| 0x49 || [5.0.0+] [[#UnmapPhysicalMemoryUnsafe]] || ||
 
|-
 
|-
| 0x4A || [5.0.0+] svcSetUnsafeLimit || X0=size || W0=result
+
| 0x4A || [5.0.0+] [[#SetUnsafeLimit]] || ||
 
|-
 
|-
| 0x4B || [4.0.0+] [[#svcCreateCodeMemory]] || X1=addr, X2=size || W0=result, W1=code_memory_handle
+
| 0x4B || [4.0.0+] [[#CreateCodeMemory]] || ||
 
|-
 
|-
| 0x4C || [4.0.0+] [[#svcControlCodeMemory]] || W0=code_memory_handle, W1=[[#CodeMemoryOperation]], X2=dstaddr, X3=size, W4=perm
+
| 0x4C || [4.0.0+] [[#ControlCodeMemory]] || ||
R0=code_memory_handle, R1=[[#CodeMemoryOperation]], R2=dstaddr_lower32, R3=dstaddr_upper32, R4=size_lower32, R5=size_upper32, R6=perm
  −
|| W0=result
   
|-
 
|-
| 0x4D || svcSleepSystem || None || None
+
| 0x4D || [[#SleepSystem]] ||||
 
|-
 
|-
| 0x4E || [[#svcReadWriteRegister]] || X1=reg_addr, W2=rw_mask, W3=in_val
+
| 0x4E || [[#ReadWriteRegister]] || ||
R0=rw_mask, R1=in_val, R2=reg_addr_lower32, R3=reg_addr_upper32
  −
|| W0=result, W1=out_val
   
|-
 
|-
| 0x4F || svcSetProcessActivity || W0=process_handle, W1=bool || W0=result
+
| 0x4F || [[#SetProcessActivity]] || ||
 
|-
 
|-
| 0x50 || [[#svcCreateSharedMemory]] || W1=size, W2=myperm, W3=otherperm || W0=result, W1=shmem_handle
+
| 0x50 || [[#CreateSharedMemory]] || ||
 
|-
 
|-
| 0x51 || [[#svcMapTransferMemory]] || X0=tmem_handle, X1=addr, X2=size, W3=perm || W0=result
+
| 0x51 || [[#MapTransferMemory]] || ||
 
|-
 
|-
| 0x52 || [[#svcUnmapTransferMemory]] || W0=tmemhandle, X1=addr, X2=size || W0=result
+
| 0x52 || [[#UnmapTransferMemory]] || ||
 
|-
 
|-
| 0x53 || [[#svcCreateInterruptEvent]] || X1=irq_num, W2=flag || W0=result, W1=handle
+
| 0x53 || [[#CreateInterruptEvent]] || ||
 
|-
 
|-
| 0x54 || [[#svcQueryPhysicalAddress]] || X1=addr || W0=result, X1=physaddr, X2=baseaddr, X3=size
+
| 0x54 || [[#QueryPhysicalAddress]] || ||
 
|-
 
|-
| 0x55 || [[#svcQueryIoMapping]] || X1=physaddr, X2=size
+
| 0x55 || [[#QueryIoMapping]] || ||
R0=size, R2=physaddr_lower32, R3=physaddr_upper32
  −
|| W0=result, X1=virtaddr
   
|-
 
|-
| 0x56 || [[#svcCreateDeviceAddressSpace]] || X1=dev_as_start_addr, X2=dev_as_end_addr
+
| 0x56 || [[#CreateDeviceAddressSpace]] || ||
R0=dev_as_end_addr_lower32, R1=dev_as_end_addr_upper32, R2=dev_as_start_addr_lower32, R3=dev_as_start_addr_upper32
  −
|| W0=result, W1=dev_as_handle
   
|-
 
|-
| 0x57 || [[#svcAttachDeviceAddressSpace]] || W0=device, X1=dev_as_handle || W0=result
+
| 0x57 || [[#AttachDeviceAddressSpace]] || ||
 
|-
 
|-
| 0x58 || [[#svcDetachDeviceAddressSpace]] || W0=device, X1=dev_as_handle || W0=result
+
| 0x58 || [[#DetachDeviceAddressSpace]] || ||
 
|-
 
|-
| 0x59 || [[#svcMapDeviceAddressSpaceByForce]] || W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr, W5=perm
+
| 0x59 || [[#MapDeviceAddressSpaceByForce]] || ||
R0=dev_as_handle, R1=proc_handle, R2=dev_map_addr_lower32, R3=dev_map_addr_upper32, R4=rev_as_size, R5=dev_as_addr_lower32, R6=dev_as_addr_upper32, R7=perm
  −
|| W0=result
   
|-
 
|-
| 0x5A || [[#svcMapDeviceAddressSpaceAligned]] || W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr, W5=perm
+
| 0x5A || [[#MapDeviceAddressSpaceAligned]] || ||
R0=dev_as_handle, R1=proc_handle, R2=dev_map_addr_lower32, R3=dev_map_addr_upper32, R4=rev_as_size, R5=dev_as_addr_lower32, R6=dev_as_addr_upper32, R7=perm
  −
|| W0=result
   
|-
 
|-
| 0x5B || svcMapDeviceAddressSpace || W1=dev_as_handle, W2=proc_handle, X3=dev_map_addr, X4=dev_as_size, X5=dev_as_addr, W6=perm
+
| 0x5B || [[#MapDeviceAddressSpace]] || ||
R0=dev_map_addr_lower32, R1=dev_as_handle, R2=proc_handle, R3=dev_map_addr_upper32, R4=dev_as_size, R5=dev_as_addr_lower32, R6=dev_as_addr_upper32, R7=perm
  −
|| W0=result, X1=mapped_size
  −
R0=result, R1=mapped_size
   
|-
 
|-
| 0x5C || [[#svcUnmapDeviceAddressSpace]] || W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr
+
| 0x5C || [[#UnmapDeviceAddressSpace]] || ||
R0=dev_as_handle, R1=proc_handle, R2=dev_map_addr_lower32, R3=dev_map_addr_upper32, R4=dev_as_size, R5=dev_as_addr_lower32, R6=dev_as_addr_upper32
  −
|| W0=result
   
|-
 
|-
| 0x5D || svcInvalidateProcessDataCache || W0=process_handle, X1=addr, X2=size
+
| 0x5D || InvalidateProcessDataCache || W0=process_handle, X1=addr, X2=size
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 
|| W0=size
 
|| W0=size
 
|-
 
|-
| 0x5E || svcStoreProcessDataCache || W0=process_handle, X1=addr, X2=size
+
| 0x5E || StoreProcessDataCache || W0=process_handle, X1=addr, X2=size
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 
|| W0=size
 
|| W0=size
 
|-
 
|-
| 0x5F || svcFlushProcessDataCache || W0=process_handle, X1=addr, X2=size
+
| 0x5F || FlushProcessDataCache || W0=process_handle, X1=addr, X2=size
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 
|| W0=size
 
|| W0=size
 
|-
 
|-
| 0x60 || svcDebugActiveProcess || X1=pid
+
| 0x60 || DebugActiveProcess || X1=pid
 
R2=pid_lower32, R3=pid_upper32
 
R2=pid_lower32, R3=pid_upper32
 
|| W0=result, W1=debug_handle
 
|| W0=result, W1=debug_handle
 
|-
 
|-
| 0x61 || svcBreakDebugProcess || W0=debug_handle || W0=result
+
| 0x61 || BreakDebugProcess || W0=debug_handle || W0=result
 
|-
 
|-
| 0x62 || svcTerminateDebugProcess || W0=debug_handle || W0=result
+
| 0x62 || TerminateDebugProcess || W0=debug_handle || W0=result
 
|-
 
|-
| 0x63 || svcGetDebugEvent || X0=[[#DebugEventInfo]]*, W1=debug_handle || W0=result
+
| 0x63 || GetDebugEvent || X0=[[#DebugEventInfo]]*, W1=debug_handle || W0=result
 
|-
 
|-
| 0x64 || [[#svcContinueDebugEvent]] || [1.0.0-2.3.0] W0=debug_handle, W1=[[#ContinueDebugFlagsOld]], X2=thread_id
+
| 0x64 || [[#ContinueDebugEvent]] || [1.0.0-2.3.0] W0=debug_handle, W1=[[#ContinueDebugFlagsOld]], X2=thread_id
 
R0=debug_handle, R1=[[#ContinueDebugFlagsOld]], R2=thread_id_lower32, R3=thread_id_upper32
 
R0=debug_handle, R1=[[#ContinueDebugFlagsOld]], R2=thread_id_lower32, R3=thread_id_upper32
   Line 228: Line 199:  
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x65 || [[#svcGetProcessList]] || X1=pids_out_ptr, W2=max_out || W0=result, W1=num_out  
+
| 0x65 || [[#GetProcessList]] || X1=pids_out_ptr, W2=max_out || W0=result, W1=num_out  
 
|-
 
|-
| 0x66 || svcGetThreadList || X1=tids_out_ptr, W2=max_out, W3=debug_handle_or_zero || W0=result, X1=num_out
+
| 0x66 || GetThreadList || X1=tids_out_ptr, W2=max_out, W3=debug_handle_or_zero || W0=result, X1=num_out
 
|-
 
|-
| 0x67 || svcGetDebugThreadContext || X0=ThreadContext*, X1=debug_handle, X2=thread_id, W3=[[#ThreadContextFlags]]
+
| 0x67 || GetDebugThreadContext || X0=ThreadContext*, X1=debug_handle, X2=thread_id, W3=[[#ThreadContextFlags]]
 
R0=ThreadContext*, R1=debug_handle, R2=thread_id_lower32, R3=thread_id_upper32, R4=[[#ThreadContextFlags]]
 
R0=ThreadContext*, R1=debug_handle, R2=thread_id_lower32, R3=thread_id_upper32, R4=[[#ThreadContextFlags]]
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x68 || svcSetDebugThreadContext || W0=debug_handle, X1=thread_id, X2=ThreadContext*, W3=[[#ThreadContextFlags]]
+
| 0x68 || SetDebugThreadContext || W0=debug_handle, X1=thread_id, X2=ThreadContext*, W3=[[#ThreadContextFlags]]
 
R0=debug_handle, R1=ThreadContext*, R2=thread_id_lower32, R3=thread_id_upper32, R4=[[#ThreadContextFlags]]
 
R0=debug_handle, R1=ThreadContext*, R2=thread_id_lower32, R3=thread_id_upper32, R4=[[#ThreadContextFlags]]
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x69 || svcQueryDebugProcessMemory || X0=[[#MemoryInfo]]*, X2=debug_handle, X3=addr || W0=result, W1=PageInfo
+
| 0x69 || QueryDebugProcessMemory || X0=[[#MemoryInfo]]*, X2=debug_handle, X3=addr || W0=result, W1=PageInfo
 
|-
 
|-
| 0x6A || svcReadDebugProcessMemory || X0=buffer*, X1=debug_handle, X2=src_addr, X3=size || W0=result
+
| 0x6A || ReadDebugProcessMemory || X0=buffer*, X1=debug_handle, X2=src_addr, X3=size || W0=result
 
|-
 
|-
| 0x6B || svcWriteDebugProcessMemory || X0=debug_handle, X1=buffer*, X2=dst_addr, X3=size || W0=result
+
| 0x6B || WriteDebugProcessMemory || X0=debug_handle, X1=buffer*, X2=dst_addr, X3=size || W0=result
 
|-
 
|-
| 0x6C || [[#svcSetHardwareBreakPoint]] || W0=HardwareBreakpointId, X1=watchpoint_flags/breakpoint_flags, X2=watchpoint_value/debug_handle
+
| 0x6C || [[#SetHardwareBreakPoint]] || W0=HardwareBreakpointId, X1=watchpoint_flags/breakpoint_flags, X2=watchpoint_value/debug_handle
 
R0=HardwareBreakpointId, R1=value_lower32, R2=flags_lower32, R3=flags_upper32, R4=value_upper32
 
R0=HardwareBreakpointId, R1=value_lower32, R2=flags_lower32, R3=flags_upper32, R4=value_upper32
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x6D || svcGetDebugThreadParam || X2=debug_handle, X3=thread_id, W4=[[#DebugThreadParam]]
+
| 0x6D || GetDebugThreadParam || X2=debug_handle, X3=thread_id, W4=[[#DebugThreadParam]]
 
R0=thread_id_lower32, R1=thread_id_upper32, R2=debug_handle, R3=[[#DebugThreadParam]]
 
R0=thread_id_lower32, R1=thread_id_upper32, R2=debug_handle, R3=[[#DebugThreadParam]]
 
|| W0=result, X1=out0, W2=out1
 
|| W0=result, X1=out0, W2=out1
 
R0=result, R1=out0_lower32, R2=out0_upper32, R3=out1
 
R0=result, R1=out0_lower32, R2=out0_upper32, R3=out1
 
|- style="border-top: double"
 
|- style="border-top: double"
| 0x6F || [5.0.0+] [[#svcGetSystemInfo]] || X1=info_id, X2=handle, X3=info_sub_id
+
| 0x6F || [5.0.0+] [[#GetSystemInfo]] || X1=info_id, X2=handle, X3=info_sub_id
 
R1=info_sub_id_lower32, R2=info_id, R3=handle, R4=info_sub_id_upper32
 
R1=info_sub_id_lower32, R2=info_id, R3=handle, R4=info_sub_id_upper32
 
|| W0=result, X1=out
 
|| W0=result, X1=out
 
R0=result, R1=out_lower32, R2=out_upper32
 
R0=result, R1=out_lower32, R2=out_upper32
 
|-
 
|-
| 0x70 || svcCreatePort || W2=max_sessions, W3=is_light, X4=name_ptr
+
| 0x70 || CreatePort || W2=max_sessions, W3=is_light, X4=name_ptr
 
R0=name_ptr, R2=max_sessions, R3=is_light
 
R0=name_ptr, R2=max_sessions, R3=is_light
 
|| W0=result, W1=serverport_handle, W2=clientport_handle
 
|| W0=result, W1=serverport_handle, W2=clientport_handle
 
|-
 
|-
| 0x71 || svcManageNamedPort || X1=name_ptr, W2=max_sessions || W0=result, W1=serverport_handle
+
| 0x71 || ManageNamedPort || X1=name_ptr, W2=max_sessions || W0=result, W1=serverport_handle
 
|-
 
|-
| 0x72 || svcConnectToPort || W1=clientport_handle || W0=result, W1=session_handle
+
| 0x72 || ConnectToPort || W1=clientport_handle || W0=result, W1=session_handle
 
|-
 
|-
| 0x73 || [[#svcSetProcessMemoryPermission]] || W0=process_handle, X1=addr, X2=size, W3=perm
+
| 0x73 || [[#SetProcessMemoryPermission]] || W0=process_handle, X1=addr, X2=size, W3=perm
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32, R5=perm
 
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32, R5=perm
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x74 || [[#svcMapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
+
| 0x74 || [[#MapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
 
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
 
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x75 || [[#svcUnmapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
+
| 0x75 || [[#UnmapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
 
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
 
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x76 || [[#svcQueryProcessMemory]] || X0=meminfo_ptr, W2=process_handle, X3=addr
+
| 0x76 || [[#QueryProcessMemory]] || X0=meminfo_ptr, W2=process_handle, X3=addr
 
R0=meminfo_ptr, R1=addr_lower32, R2=process_handle, R3=addr_upper32
 
R0=meminfo_ptr, R1=addr_lower32, R2=process_handle, R3=addr_upper32
 
|| W0=result, W1=pageinfo
 
|| W0=result, W1=pageinfo
 
|-
 
|-
| 0x77 || [[#svcMapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size
+
| 0x77 || [[#MapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size
 
R0=process_handle, R1=srcaddr_lower32, R2=dstaddr_lower32, R3=dstaddr_upper32, R4=srcaddr_lower32, R5=size_lower32, R6=size_upper32
 
R0=process_handle, R1=srcaddr_lower32, R2=dstaddr_lower32, R3=dstaddr_upper32, R4=srcaddr_lower32, R5=size_lower32, R6=size_upper32
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x78 || [[#svcUnmapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size
+
| 0x78 || [[#UnmapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size
 
R0=process_handle, R1=srcaddr_lower32, R2=dstaddr_lower32, R3=dstaddr_upper32, R4=srcaddr_lower32, R5=size_lower32, R6=size_upper32
 
R0=process_handle, R1=srcaddr_lower32, R2=dstaddr_lower32, R3=dstaddr_upper32, R4=srcaddr_lower32, R5=size_lower32, R6=size_upper32
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x79 || [[#svcCreateProcess]] || X1=procinfo_ptr, X2=caps_ptr, W3=cap_num ||  W0=result, W1=process_handle
+
| 0x79 || [[#CreateProcess]] || X1=procinfo_ptr, X2=caps_ptr, W3=cap_num ||  W0=result, W1=process_handle
 
|-
 
|-
| 0x7A || svcStartProcess || W0=process_handle, W1=main_thread_prio, W2=default_cpuid, W3=main_thread_stacksz
+
| 0x7A || StartProcess || W0=process_handle, W1=main_thread_prio, W2=default_cpuid, W3=main_thread_stacksz
 
R0=process_handle, R1=main_thread_prio, R2=default_cpuid, R3=main_thread_stacksz_lower32, R4=main_thread_stacksz_upper32
 
R0=process_handle, R1=main_thread_prio, R2=default_cpuid, R3=main_thread_stacksz_lower32, R4=main_thread_stacksz_upper32
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x7B || svcTerminateProcess || W0=process_handle || W0=result
+
| 0x7B || TerminateProcess || W0=process_handle || W0=result
 
|-
 
|-
| 0x7C || [[#svcGetProcessInfo]] || W0=process_handle, W1=[[#ProcessInfoType]]
+
| 0x7C || [[#GetProcessInfo]] || W0=process_handle, W1=[[#ProcessInfoType]]
 
R1=process_handle, R2=[[#ProcessInfoType]]
 
R1=process_handle, R2=[[#ProcessInfoType]]
 
|| W0=result, X1=[[#ProcessState]]
 
|| W0=result, X1=[[#ProcessState]]
 
R0=result, R1=[[#ProcessState]]_lower32, R2=[[#ProcessState]]_upper32
 
R0=result, R1=[[#ProcessState]]_lower32, R2=[[#ProcessState]]_upper32
 
|-
 
|-
| 0x7D || svcCreateResourceLimit || None || W0=result, W1=reslimit_handle  
+
| 0x7D || CreateResourceLimit || None || W0=result, W1=reslimit_handle  
 
|-
 
|-
| 0x7E || svcSetResourceLimitLimitValue || W0=reslimit_handle, W1=[[#LimitableResource]], X2=value
+
| 0x7E || SetResourceLimitLimitValue || W0=reslimit_handle, W1=[[#LimitableResource]], X2=value
 
R0=reslimit_handle, R1=[[#LimitableResource]], R2=value_lower32, R3=value_upper32
 
R0=reslimit_handle, R1=[[#LimitableResource]], R2=value_lower32, R3=value_upper32
 
|| W0=result
 
|| W0=result
 
|-
 
|-
| 0x7F || [[#svcCallSecureMonitor]] || X0=smc_sub_id, X1,X2,X3,X4,X5,X6,X7=smc_args
+
| 0x7F || [[#CallSecureMonitor]] || X0=smc_sub_id, X1,X2,X3,X4,X5,X6,X7=smc_args
 
R0=smc_sub_id, R1, R2, R3=smc_args
 
R0=smc_sub_id, R1, R2, R3=smc_args
 
|| X0,X1,X2,X3,X4,X5,X6,X7=result
 
|| X0,X1,X2,X3,X4,X5,X6,X7=result
Line 317: Line 288:  
|}
 
|}
   −
== svcSetHeapSize ==
+
== SetHeapSize ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 325: Line 296:  
| (In) W1 || u64 || Size
 
| (In) W1 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) X1 || u64 || OutAddr
 
| (Out) X1 || u64 || OutAddr
Line 354: Line 325:  
'''0x10801:''' Memory resource limit reached.
 
'''0x10801:''' Memory resource limit reached.
   −
== svcSetMemoryPermission ==
+
== SetMemoryPermission ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 366: Line 337:  
| (In) W2 || [[#Permission]] || Prot
 
| (In) W2 || [[#Permission]] || Prot
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 391: Line 362:  
'''0xCE01:''' Kernel resource exhausted.
 
'''0xCE01:''' Kernel resource exhausted.
   −
== svcSetMemoryAttribute ==
+
== SetMemoryAttribute ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 405: Line 376:  
| (In) W3 || u32 || State1
 
| (In) W3 || u32 || State1
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 425: Line 396:  
|}
 
|}
   −
== svcMapMemory ==
+
== MapMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 437: Line 408:  
| (In) X2 || u64 || Size
 
| (In) X2 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 451: Line 422:  
[2.0.0+] This can only be used to map into the Stack region.
 
[2.0.0+] This can only be used to map into the Stack region.
   −
Code can get the range of the Alias region from [[#svcGetInfo]] id0=2,3, and on 2.0.0+ the range of the Stack region via [[#svcGetInfo]] id0=14, 15 (on 1.0.0, the Stack region had hardcoded limits).
+
Code can get the range of the Alias region from [[#GetInfo]] id0=2,3, and on 2.0.0+ the range of the Stack region via [[#GetInfo]] id0=14, 15 (on 1.0.0, the Stack region had hardcoded limits).
    
When mapped into the Alias region, the mapped memory will have state 0x482907.
 
When mapped into the Alias region, the mapped memory will have state 0x482907.
Line 457: Line 428:  
When mapped into the Stack region, the mapped memory will have state 0x5C3C0B.
 
When mapped into the Stack region, the mapped memory will have state 0x5C3C0B.
   −
== svcUnmapMemory ==
+
== UnmapMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 469: Line 440:  
| (In) X2 || u64 || Size
 
| (In) X2 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
Unmaps a region that was previously mapped with [[#svcMapMemory]].
+
Unmaps a region that was previously mapped with [[#MapMemory]].
    
It's possible to unmap ranges partially, you don't need to unmap the entire range "in one go".
 
It's possible to unmap ranges partially, you don't need to unmap the entire range "in one go".
Line 479: Line 450:  
The srcaddr/dstaddr must match what was given when the pages were originally mapped.
 
The srcaddr/dstaddr must match what was given when the pages were originally mapped.
   −
== svcQueryMemory ==
+
== QueryMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 489: Line 460:  
| (In) X2 || void* || Addr
 
| (In) X2 || void* || Addr
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) W1 || PageInfo || PageInfo
 
| (Out) W1 || PageInfo || PageInfo
Line 499: Line 470:  
Outputs a [[#MemoryInfo]] struct.
 
Outputs a [[#MemoryInfo]] struct.
   −
== svcExitProcess ==
+
== ExitProcess ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 513: Line 484:  
Exits the current process.
 
Exits the current process.
   −
== svcCreateThread ==
+
== CreateThread ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 529: Line 500:  
| (In) W5 || R4 || u32 || ProcessorId
 
| (In) W5 || R4 || u32 || ProcessorId
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) W1 || R1 || Handle<Thread> || Handle
 
| (Out) W1 || R1 || Handle<Thread> || Handle
Line 539: Line 510:  
Processor_id must be 0,1,2,3 or -2, where -2 uses the default cpuid for process.
 
Processor_id must be 0,1,2,3 or -2, where -2 uses the default cpuid for process.
   −
== svcStartThread ==
+
== StartThread ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 553: Line 524:  
Starts the thread for the provided handle.
 
Starts the thread for the provided handle.
   −
== svcExitThread ==
+
== ExitThread ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 567: Line 538:  
Exits the current thread.
 
Exits the current thread.
   −
== svcSleepThread ==
+
== SleepThread ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 574: Line 545:  
|-
 
|-
 
| (In) X0 || R0, R1 || s64 || Nanoseconds
 
| (In) X0 || R0, R1 || s64 || Nanoseconds
|-
   
|}
 
|}
 
</div>
 
</div>
Line 595: Line 565:  
</div>
 
</div>
   −
== svcGetThreadPriority ==
+
== GetThreadPriority ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 603: Line 573:  
| (In) W1|| Handle<Thread> || Handle
 
| (In) W1|| Handle<Thread> || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) W1 || u64 || Priority
 
| (Out) W1 || u64 || Priority
Line 611: Line 581:  
Gets the priority of provided thread handle.
 
Gets the priority of provided thread handle.
   −
== svcSetThreadPriority ==
+
== SetThreadPriority ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 621: Line 591:  
| (In) W1|| u32 || Priority
 
| (In) W1|| u32 || Priority
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 629: Line 599:  
Priority is a number 0-0x3F. Lower value means higher priority.
 
Priority is a number 0-0x3F. Lower value means higher priority.
   −
== svcGetThreadCoreMask ==
+
== GetThreadCoreMask ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 637: Line 607:  
| (In) W2 || R2 || Handle<Thread> || Handle
 
| (In) W2 || R2 || Handle<Thread> || Handle
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W1 || R1 || u32 || Out0
+
| (Out) W1 || R1 || u32 || CoreMask0
 
|-
 
|-
| (Out) X2 || R2, R3 || u64 || Out1
+
| (Out) X2 || R2, R3 || u64 || CoreMask1
 
|}
 
|}
 
</div>
 
</div>
Line 647: Line 617:  
Gets the affinity mask of provided thread handle.
 
Gets the affinity mask of provided thread handle.
   −
== svcSetThreadCoreMask ==
+
== SetThreadCoreMask ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 655: Line 625:  
| (In) W0 || R0 || Handle<Thread> || Handle
 
| (In) W0 || R0 || Handle<Thread> || Handle
 
|-
 
|-
| (In) W1 || R1 || u32 || In0
+
| (In) W1 || R1 || u32 || CoreMask0
 
|-
 
|-
| (In) X2 || R2, R3 || u64 || In1
+
| (In) X2 || R2, R3 || u64 || CoreMask1
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 665: Line 635:  
Sets the affinity mask of provided thread handle.
 
Sets the affinity mask of provided thread handle.
   −
== svcGetCurrentProcessorNumber ==
+
== GetCurrentProcessorNumber ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 681: Line 651:  
CpuId is an integer in the range 0-3.
 
CpuId is an integer in the range 0-3.
   −
== svcSignalEvent ==
+
== SignalEvent ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 697: Line 667:  
Will wake up any thread currently waiting on this event. Can potentially trigger a reschedule.
 
Will wake up any thread currently waiting on this event. Can potentially trigger a reschedule.
   −
Any calls to [[#svcWaitSynchronization]] on this handle will return immediately, until the event's signaled state is reset.
+
Any calls to [[#WaitSynchronization]] on this handle will return immediately, until the event's signaled state is reset.
    
=== Result codes ===
 
=== Result codes ===
Line 704: Line 674:  
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a WritableEvent.
 
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a WritableEvent.
   −
== svcClearEvent ==
+
== ClearEvent ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 710: Line 680:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || Handle<WritableEvent or ReadableEvent> || Event
+
| (In) W0 || Handle<WritableEvent> or Handle<ReadableEvent> || Event
 
|-
 
|-
 
| (Out) X0 || [[#Result]] || Result
 
| (Out) X0 || [[#Result]] || Result
Line 725: Line 695:  
'''0xFA01:''' The handle was not in a signaled state.
 
'''0xFA01:''' The handle was not in a signaled state.
   −
== svcMapSharedMemory ==
+
== MapSharedMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 739: Line 709:  
| (In) W3 || [[#Permission]] || Permissions
 
| (In) W3 || [[#Permission]] || Permissions
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 747: Line 717:  
Increases reference count for the KSharedMemory object. Thus in order to release the memory associated with the object, all handles to it must be closed and all mappings must be unmapped.
 
Increases reference count for the KSharedMemory object. Thus in order to release the memory associated with the object, all handles to it must be closed and all mappings must be unmapped.
   −
== svcUnmapSharedMemory ==
+
== UnmapSharedMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 759: Line 729:  
| (In) X2 || u64 || Size
 
| (In) X2 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcCreateTransferMemory ==
+
== CreateTransferMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 775: Line 745:  
| (In) W3 || [[#Permission]] || Permissions
 
| (In) W3 || [[#Permission]] || Permissions
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) W1 || Handle<TransferMemory> || Handle
 
| (Out) W1 || Handle<TransferMemory> || Handle
Line 787: Line 757:  
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
 
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
   −
== svcCloseHandle ==
+
== CloseHandle ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 795: Line 765:  
| (In) W0 || Handle || Handle
 
| (In) W0 || Handle || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcResetSignal ==
+
== ResetSignal ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 807: Line 777:  
| (In) W0 || Handle<ReadableEvent> or Handle<Process> || Handle
 
| (In) W0 || Handle<ReadableEvent> or Handle<Process> || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
Resets the signal on the given handle, ensuring future calls to [[#svcWaitSynchronization]] on this handle will sleep until the handle is signaled again. If the handle is a ReadableEvent, this is equivalent to calling svcClearEvent() on the handle.
+
Resets the signal on the given handle, ensuring future calls to [[#WaitSynchronization]] on this handle will sleep until the handle is signaled again. If the handle is a ReadableEvent, this is equivalent to calling ClearEvent() on the handle.
   −
If the handle is a Process, it will clear the signaled state (which is set when the process changes [[#ProcessState]]. Once the process enters the Exited state, calling svcResetSignal on the process will no longer have an effect (the process is permanently signaled), and the syscall will return 0xFA01.
+
If the handle is a Process, it will clear the signaled state (which is set when the process changes [[#ProcessState]]. Once the process enters the Exited state, calling ResetSignal on the process will no longer have an effect (the process is permanently signaled), and the syscall will return 0xFA01.
    
=== Result codes ===
 
=== Result codes ===
Line 822: Line 792:  
'''0xFA01:''' The handle was not signaled, or the process is in exited state, causing it to be permanently signaled.
 
'''0xFA01:''' The handle was not signaled, or the process is in exited state, causing it to be permanently signaled.
   −
== svcWaitSynchronization ==
+
== WaitSynchronization ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 834: Line 804:  
| (In) X3 || R0, R3 || u64 || Timeout
 
| (In) X3 || R0, R3 || u64 || Timeout
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) W1 || R1 || u64 || HandleIndex
 
| (Out) W1 || R1 || u64 || HandleIndex
Line 847: Line 817:     
=== Object types ===
 
=== Object types ===
'''KDebug:''' signals when there is a new [[#DebugEventInfo|DebugEvent]] (retrievable via [[#svcGetDebugEvent]]).
+
'''KDebug:''' signals when there is a new [[#DebugEventInfo|DebugEvent]] (retrievable via [[#GetDebugEvent]]).
    
'''KClientPort:''' signals when the number of sessions is less than the maximum allowed.
 
'''KClientPort:''' signals when the number of sessions is less than the maximum allowed.
   −
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#svcGetProcessInfo]]).
+
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#GetProcessInfo]]).
   −
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via svcSignalEvent.
+
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via SignalEvent.
   −
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#svcAcceptSession|accepted]].
+
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#AcceptSession|accepted]].
   −
'''KServerSession:''' signals when there is an incoming message waiting to be [[#svcReplyAndReceive|received]] or the pipe is closed.
+
'''KServerSession:''' signals when there is an incoming message waiting to be [[#ReplyAndReceive|received]] or the pipe is closed.
    
'''KThread:''' signals when the thread has exited.
 
'''KThread:''' signals when the thread has exited.
Line 872: Line 842:  
'''0xea01:''' Timeout. Returned when no objects have been signaled within the timeout. Handle index is not updated.
 
'''0xea01:''' Timeout. Returned when no objects have been signaled within the timeout. Handle index is not updated.
   −
'''0xec01:''' Interrupted. Returned when another thread uses [[#svcCancelSynchronization]] to cancel this thread. Handle index is not updated.
+
'''0xec01:''' Interrupted. Returned when another thread uses [[#CancelSynchronization]] to cancel this thread. Handle index is not updated.
    
'''0xee01:''' Too many handles. Returned when the number of handles passed is > 0x40.
 
'''0xee01:''' Too many handles. Returned when the number of handles passed is > 0x40.
   −
== svcCancelSynchronization ==
+
== CancelSynchronization ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 884: Line 854:  
| (In) W0 || Handle<Thread> || Handle
 
| (In) W0 || Handle<Thread> || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
If the referenced thread is currently in a synchronization call ([[#svcWaitSynchronization]], [[#svcReplyAndReceive]] or [[#svcReplyAndReceiveLight]]), that call will be interrupted and return 0xec01.
+
If the referenced thread is currently in a synchronization call ([[#WaitSynchronization]], [[#ReplyAndReceive]] or [[#ReplyAndReceiveLight]]), that call will be interrupted and return 0xec01.
 
If that thread is not currently executing such a synchronization call, the next call to a synchronization call will return 0xec01.
 
If that thread is not currently executing such a synchronization call, the next call to a synchronization call will return 0xec01.
   Line 898: Line 868:  
'''0xe401:''' Invalid handle. The handle given was either invalid or not a thread handle.
 
'''0xe401:''' Invalid handle. The handle given was either invalid or not a thread handle.
   −
== svcArbitrateLock ==
+
== ArbitrateLock ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 910: Line 880:  
| (In) W2 || u32 || Tag
 
| (In) W2 || u32 || Tag
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>                                   
 
</div>                                   
   −
== svcArbitrateUnlock ==
+
== ArbitrateUnlock ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 922: Line 892:  
| (In) X0 || void* || Addr
 
| (In) X0 || void* || Addr
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcWaitProcessWideKeyAtomic ==
+
== WaitProcessWideKeyAtomic ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 940: Line 910:  
| (In) X3 || R3, R4 || u64 || Timeout
 
| (In) X3 || R3, R4 || u64 || Timeout
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcSignalProcessWideKey ==
+
== SignalProcessWideKey ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 954: Line 924:  
| (In) W1 || u32 || Value
 
| (In) W1 || u32 || Value
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcGetSystemTick ==
+
== GetSystemTick ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 974: Line 944:  
Official sw reads cntpct_el0 directly from usermode without using this SVC. [[ExeFS|sdk-nso]] has this SVC, but it's not known to be called anywhere.
 
Official sw reads cntpct_el0 directly from usermode without using this SVC. [[ExeFS|sdk-nso]] has this SVC, but it's not known to be called anywhere.
   −
== svcConnectToNamedPort ==
+
== ConnectToNamedPort ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 980: Line 950:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || char* || Name
+
| (In) X1 || char* || PortName
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
 
| (Out) W1 || Handle<Session> || Handle
 
| (Out) W1 || Handle<Session> || Handle
Line 988: Line 958:  
</div>
 
</div>
   −
== svcSendSyncRequestLight ==
+
== SendSyncRequestLight ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 996: Line 966:  
| (In) W0 || Handle<Session> || Handle
 
| (In) W0 || Handle<Session> || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcSendSyncRequest ==
+
== SendSyncRequest ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,008: Line 978:  
| (In) W0 || Handle<Session> || Handle
 
| (In) W0 || Handle<Session> || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
== svcSendSyncRequestWithUserBuffer ==
+
== SendSyncRequestWithUserBuffer ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,024: Line 994:  
| (In) W2 || Handle<Session> || Handle
 
| (In) W2 || Handle<Session> || Handle
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
Line 1,041: Line 1,011:  
'''0xe401:''' Handles does not exist, or handle is not an instance of KClientSession.
 
'''0xe401:''' Handles does not exist, or handle is not an instance of KClientSession.
   −
== svcBreak ==
+
== SendAsyncRequestWithUserBuffer ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,047: Line 1,017:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || u64 || Break Reason
+
| (In) X1 || void* || CmdPtr
 +
|-
 +
| (In) X2 || u64 || Size
 
|-
 
|-
| (In) X1 || u64 ||
+
| (In) W3 || Handle<Session> || Handle
 
|-
 
|-
| (In) X2 || u64 || Info
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W0 || Result || 0 (Success)
+
| (Out) W1 || Handle<ReadableEvent> || Event
 
|}
 
|}
 
</div>
 
</div>
   −
If the process is attached, report the Break event. Then, if svcContinueDebugEvent didn't apply IgnoreException on the thread: if TPIDR_EL0 is 0, adjust ELR_EL1 to retry to svc instruction (and set TPIDR_EL0 to 1).
+
Size and CmdPtr must be 0x1000-aligned.
   −
Otherwise, if bit31 in reason isn't set, perform crash reporting (see Exception Handling section below), if it doesn't terminate the process adjust ELR_EL1 as well.
+
|-
 
+
| 0x23 || || X1=cmdbufptr, X2=size, X3=handle || W0=result, W1=revent_handle
Otherwise just return 0.
+
|-
   −
== svcGetInfo ==
+
== GetProcessId ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,069: Line 1,041:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) W1 || R1 || u32 || InfoId
+
| (In) W1 || R1 || Handle<Process> || Handle
 
|-
 
|-
| (In) W2 || R2 || Handle || Handle
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (In) X3 || R0, R3 || u64 || InfoSubId
+
| (Out) X1 || R1, R2 || u64 || ProcessId
|-
  −
| (Out) W0 || R0 || [[#Result]] || Ret
  −
|-
  −
| (Out) X1 || R1, R2 || u64 || Out
   
|}
 
|}
 
</div>
 
</div>
   −
{| class=wikitable
+
== GetThreadId ==
! Handle type || Id0 || Id1 || Description
+
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 0 || 0 || AllowedCpuIdBitmask
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| Process || 1 || 0 || AllowedThreadPrioBitmask
+
| (In) W1 || R1 || Handle<Thread> || Handle
 
|-
 
|-
| Process || 2 || 0 || AliasRegionBaseAddr
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| Process || 3 || 0 || AliasRegionSize
+
| (Out) X1 || R1, R2 || u64 || ThreadId
 +
|}
 +
</div>
 +
 
 +
== Break ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 4 || 0 || HeapRegionBaseAddr
+
! Argument || Type || Name
 
|-
 
|-
| Process || 5 || 0 || HeapRegionSize
+
| (In) X0 || u64 || Break Reason
 
|-
 
|-
| Process || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
+
| (In) X1 || u64 ||
 
|-
 
|-
| Process || 7 || 0 || TotalMemoryUsage. Total used size of codebin memory + main-thread stack + allocated heap.
+
| (In) X2 || u64 || Info
 
|-
 
|-
| Zero    || 8 || 0 || IsCurrentProcessBeingDebugged
+
| (Out) W0 || [[#Result]] || 0 (Success)
 +
|}
 +
</div>
 +
 
 +
If the process is attached, report the Break event. Then, if ContinueDebugEvent didn't apply IgnoreException on the thread: if TPIDR_EL0 is 0, adjust ELR_EL1 to retry to svc instruction (and set TPIDR_EL0 to 1).
 +
 
 +
Otherwise, if bit31 in reason isn't set, perform crash reporting (see Exception Handling section below), if it doesn't terminate the process adjust ELR_EL1 as well.
 +
 
 +
Otherwise just return 0.
 +
 
 +
== OutputDebugString ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Zero    || 9 || 0 || Returns ResourceLimit handle for current process. Used by [[Process_Manager_services|PM]].
+
! Argument || Type || Name
 
|-
 
|-
| Zero    || 10 || -1, {current coreid} || IdleTickCount
+
| (In) X0 || char* || String
 
|-
 
|-
| Zero    || 11 || 0-3 || RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
+
| (In) X1 || u64 || Size
 
|-
 
|-
| Process || 12 || 0 || [2.0.0+] AddressSpaceBaseAddr
+
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
== ReturnFromException ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 13 || 0 || [2.0.0+] AddressSpaceSize
+
! Argument || Type || Name
 
|-
 
|-
| Process || 14 || 0 || [2.0.0+] StackRegionBaseAddr
+
| (Out) X0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
== GetInfo ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 15 || 0 || [2.0.0+] StackRegionSize
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| Process || 16 || 0 || [3.0.0+] PersonalMmHeapSize
+
| (In) W1 || R1 || u32 || InfoId0
 
|-
 
|-
| Process || 17 || 0 || [3.0.0+] PersonalMmHeapUsage
+
| (In) W2 || R2 || Handle || Handle
 
|-
 
|-
| Process || 18 || 0 || [3.0.0+] TitleId
+
| (In) X3 || R0, R3 || u64 || InfoId1
 
|-
 
|-
| Zero    || 19 || 0 || [4.0.0-4.1.0] PrivilegedProcessId_LowerBound
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| Zero    || 19 || 1 || [4.0.0-4.1.0] PrivilegedProcessId_UpperBound
+
| (Out) X1 || R1, R2 || u64 || Out
 +
|}
 +
</div>
 +
 
 +
{| class=wikitable
 +
! Handle type || InfoId0 || InfoId1 || Description
 
|-
 
|-
| Process || 20 || 0 || [5.0.0+] UserExceptionContextAddr
+
| Process || 0 || 0 || AllowedCpuIdBitmask
 
|-
 
|-
| Process || 21 || 0 || [6.0.0+] TotalMemoryAvailableWithoutMmHeap
+
| Process || 1 || 0 || AllowedThreadPrioBitmask
 
|-
 
|-
| Process || 22 || 0 || [6.0.0+] TotalMemoryUsedWithoutMmHeap
+
| Process || 2 || 0 || AliasRegionBaseAddr
 
|-
 
|-
| Process || 23 || 0 || [9.0.0+] IsApplication
+
| Process || 3 || 0 || AliasRegionSize
 
|-
 
|-
| Thread  || 0xF0000002 || 0-3, -1 || Thread Ticks. When 0-3 are passed, gets specific core CPU ticks spent on thread. When -1 is passed, gets total CPU ticks spent on thread.
+
| Process || 4 || 0 || HeapRegionBaseAddr
|}
+
|-
 
+
| Process || 5 || 0 || HeapRegionSize
== svcMapPhysicalMemory ==
+
|-
This is like svcSetHeapSize except you can allocate heap at any address you'd like.
+
| Process || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
 
  −
Uses current process pool partition.
  −
 
  −
== svcDumpInfo ==
  −
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Argument || Type || Name
+
| Process || 7 || 0 || TotalMemoryUsage. Total used size of codebin memory + main-thread stack + allocated heap.
 
|-
 
|-
| (In) None || ||  
+
| Zero    || 8 || 0 || IsCurrentProcessBeingDebugged
 
|-
 
|-
| (Out) None || ||
+
| Zero    || 9 || 0 || Returns ResourceLimit handle for current process. Used by [[Process_Manager_services|PM]].
|}
  −
</div>
  −
 
  −
Does nothing, just returns with registers set to all-zero.
  −
 
  −
== svcAcceptSession ==
  −
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Argument || Type || Name
+
| Zero    || 10 || -1, {current coreid} || IdleTickCount
 
|-
 
|-
| (In) W1 || Handle<Port> || Port
+
| Zero    || 11 || 0-3 || RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
 
|-
 
|-
| (Out) W0 || [[#Result]] || Result
+
| Process || 12 || 0 || [2.0.0+] AddressSpaceBaseAddr
 
|-
 
|-
| (Out) W1 || Handle<ServerSession> || Session
+
| Process || 13 || 0 || [2.0.0+] AddressSpaceSize
|}
+
|-
</div>
+
| Process || 14 || 0 || [2.0.0+] StackRegionBaseAddr
 
+
|-
=== Result codes ===
+
| Process || 15 || 0 || [2.0.0+] StackRegionSize
'''0xf201:''' No session waiting to be accepted
+
|-
 
+
| Process || 16 || 0 || [3.0.0+] PersonalMmHeapSize
== svcReplyAndReceive ==
+
|-
<div style="display: inline-block;">
+
| Process || 17 || 0 || [3.0.0+] PersonalMmHeapUsage
{| class="wikitable" border="1"
+
|-
 +
| Process || 18 || 0 || [3.0.0+] TitleId
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
| Zero    || 19 || 0 || [4.0.0-4.1.0] PrivilegedProcessId_LowerBound
 
|-
 
|-
| (In) W1 || R1 || *Handle<Port or ServerSession> || Handles
+
| Zero    || 19 || 1 || [4.0.0-4.1.0] PrivilegedProcessId_UpperBound
 
|-
 
|-
| (In) W2 || R2 || u32 || NumHandles
+
| Process || 20 || 0 || [5.0.0+] UserExceptionContextAddr
 
|-
 
|-
| (In) W3 || R3 || Handle<ServerSession> || ReplyTarget
+
| Process || 21 || 0 || [6.0.0+] TotalMemoryAvailableWithoutMmHeap
 
|-
 
|-
| (In) X4 || R0, R4 || u64 (nanoseconds) || Timeout
+
| Process || 22 || 0 || [6.0.0+] TotalMemoryUsedWithoutMmHeap
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Result
+
| Process || 23 || 0 || [9.0.0+] IsApplication
 
|-
 
|-
| (Out) W1 || R1 || u32 || HandleIndex
+
| Thread  || 0xF0000002 || 0-3, -1 || Thread Ticks. When 0-3 are passed, gets specific core CPU ticks spent on thread. When -1 is passed, gets total CPU ticks spent on thread.
 
|}
 
|}
</div>
     −
If ReplyTarget is not zero, a reply from the TLS will be sent to that session.
+
== FlushEntireDataCache ==
Then it will wait until either of the passed sessions has an incoming message, is closed, a passed port has an incoming connection, or the timeout expires.
+
<div style="display: inline-block;">
If there is an incoming message, it is copied to the TLS.
+
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) None || ||
 +
|-
 +
| (Out) None || ||
 +
|}
 +
</div>
 +
 
 +
== FlushDataCache ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X0 || u64 || Address
 +
|-
 +
| (In) X1 || u64 || Size
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
   −
If ReplyTarget is zero, the TLS should contain a blank message. If this message has a C descriptor, the buffer it points to will be used as the pointer buffer. See [[IPC_Marshalling#IPC_buffers]]. Note that a pointer buffer cannot be specified if ReplyTarget is not zero.
+
== MapPhysicalMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X0 || u64 || Address
 +
|-
 +
| (In) X1 || u64 || Size
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
   −
After being validated, passed handles will be enumerated in order; even if a session has been closed, if one that appears earlier in the list has an incoming message, it will take priority and a result code of 0x0 will be returned.
+
Acts like [[#SetHeapSize]] except you can allocate heap at any address you'd like.
   −
=== Result codes ===
+
Uses current process pool partition.
'''0x0:''' Success. Either a session has an incoming message or a port has an incoming connection. HandleIndex is set appropriately.
     −
'''0xea01:''' Timeout. No handles were signalled before the timeout expired. HandleIndex is not updated.
+
== UnmapPhysicalMemory ==
 
  −
'''0xf601:''' Port remote dead. One of the sessions has been closed. HandleIndex is set appropriately.
  −
 
  −
== svcMapPhysicalMemoryUnsafe ==
  −
Same as [[#svcMapPhysicalMemory]] except it always uses pool partition 0.
  −
 
  −
== svcCreateCodeMemory ==
  −
Takes an address range with backing memory to create the code memory object.
  −
 
  −
The memory is initially memset to 0xFF after being locked.
  −
 
  −
== svcControlCodeMemory ==
  −
Maps the backing memory for a Code memory object into the current process.
  −
 
  −
For [[#CodeMemoryOperation|CodeMemoryOperation_MapOwner]], memory permission must be RW-.
  −
 
  −
For [[#CodeMemoryOperation|CodeMemoryOperation_MapSlave]], memory permission must be R-- or R-X.
  −
 
  −
Operations [[#CodeMemoryOperation|CodeMemoryOperation_UnmapOwner/CodeMemoryOperation_UnmapSlave]] unmap memory that was previously mapped this way.
  −
 
  −
This allows one "secure JIT" process to map the code memory as RW-, and the other "slave" process to map it R-X.
  −
 
  −
[5.0.0+] Error 0xE401 is now returned when the process owner of the Code memory object is the same as the current process.
  −
 
  −
== svcReadWriteRegister ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || R2, R3 || u64 || RegAddr
+
| (In) X0 || u64 || Address
 
|-
 
|-
| (In) W2 || R0 || u64 || RwMask
+
| (In) X1 || u64 || Size
 
|-
 
|-
| (In) W3 || R1 || u64 || InValue
+
| (Out) W0 || [[#Result]] || Result
|-
+
|}
| (Out) W0 || R0 || [[#Result]] || Ret
  −
|-
  −
| (Out) W1 || R1 || u64 || OutValue
  −
|}
   
</div>
 
</div>
   −
Read/write IO registers with a hardcoded whitelist. Input address is physical-address and must be aligned to 4.
+
== GetFutureThreadInfo ==
 
  −
rw_mask is 0 for reading and 0xffffffff for writing. You can also write individual bits by using a mask value.
  −
 
  −
You can only write to registers inside physical pages 0x70019000 (MC), 0x7001C000 (MC0), 0x7001D000 (MC1), and they all share the same whitelist.
  −
 
  −
The whitelist is same for writing as for reading.
  −
 
  −
The whitelist is:
  −
 
  −
0x054, 0x090, 0x094, 0x098, 0x09c, 0x0a0, 0x0a4, 0x0a8, 0x0ac, 0x0b0, 0x0b4, 0x0b8, 0x0bc, 0x0c0, 0x0c4, 0x0c8, 0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x0e0, 0x100, 0x108, 0x10c, 0x118, 0x11c, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, 0x158, 0x15c, 0x164, 0x168, 0x16c, 0x170, 0x174, 0x178, 0x17c, 0x200, 0x204, 0x2e4, 0x2e8, 0x2ec, 0x2f4, 0x2f8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37c, 0x380, 0x390, 0x394, 0x398, 0x3ac, 0x3b8, 0x3bc, 0x3c0, 0x3c4, 0x3d8, 0x3e8, 0x41c, 0x420, 0x424, 0x428, 0x42c, 0x430, 0x44c, 0x47c, 0x480, 0x484, 0x50c, 0x554, 0x558, 0x55c, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69c, 0x6a0, 0x6a4, 0x6c0, 0x6c4, 0x6f0, 0x6f4, 0x960, 0x970, 0x974, 0xa20, 0xa24, 0xb88, 0xb8c, 0xbc4, 0xbc8, 0xbcc, 0xbd0, 0xbd4, 0xbd8, 0xbdc, 0xbe0, 0xbe4, 0xbe8, 0xbec, 0xc00, 0xc5c, 0xcac
  −
 
  −
[2.0.0+] Whitelist was extended with 0x4c4, 0x4c8, 0x4cc, 0x584, 0x588, 0x58c.
  −
 
  −
[2.0.0+] The IO registers in range 0x7000E400 (PMC) size 0xC00 skip the whitelist, and do a TrustZone call using [[SMC]] Id1 0xC3000008(ReadWriteRegister).
  −
 
  −
[4.0.0+] Access to the Memory Controller (0x70019000) also uses smcReadWriteRegister.
  −
 
  −
Here is the whitelist imposed by that SMC, relative to the start of the PMC registers:
  −
 
  −
0x000, 0x00c, 0x010, 0x014, 0x01c, 0x020, 0x02c, 0x030, 0x034, 0x038, 0x03c, 0x040, 0x044, 0x048, 0x0dc, 0x0e0, 0x0e4, 0x160, 0x164, 0x168, 0x170, 0x1a8, 0x1b8, 0x1bc, 0x1c0, 0x1c4, 0x1c8, 0x2b4, 0x2d4, 0x440, 0x4d8
  −
 
  −
Here is the whitelist imposed by smcReadWriteRegister (checked in addition to the whitelist in svcReadWriteRegister), relative to the start of the MC registers:
  −
 
  −
0x000, 0x004, 0x008, 0x00C, 0x010, 0x01C, 0x020, 0x030, 0x034, 0x050, 0x054, 0x090, 0x094, 0x098, 0x09C, 0x0A0, 0x0A4, 0x0A8, 0x0AC, 0x0B0, 0x0B4, 0x0B8, 0x0BC, 0x0C0, 0x0C4, 0x0C8, 0x0D0, 0x0D4, 0x0D8, 0x0DC, 0x0E0, 0x100, 0x108, 0x10C, 0x118, 0x11C, 0x124, 0x128, 0x12C, 0x130, 0x134, 0x138, 0x13C, 0x158, 0x15C, 0x164, 0x168, 0x16C, 0x170, 0x174, 0x178, 0x17C, 0x200, 0x204, 0x238, 0x240, 0x244, 0x250, 0x254, 0x258, 0x264, 0x268, 0x26C, 0x270, 0x274, 0x280, 0x284, 0x288, 0x28C, 0x294, 0x2E4, 0x2E8, 0x2EC, 0x2F4, 0x2F8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37C, 0x380, 0x390, 0x394, 0x398, 0x3AC, 0x3B8, 0x3BC, 0x3C0, 0x3C4, 0x3D8, 0x3E8, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430, 0x44C, 0x47C, 0x480, 0x484, 0x4C4, 0x4C8, 0x4CC, 0x50C, 0x554, 0x558, 0x55C, 0x584, 0x588, 0x58C, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69C, 0x6A0, 0x6A4, 0x6C0, 0x6C4, 0x6F0, 0x6F4, 0x960, 0x970, 0x974, 0x9B8, 0xA20, 0xA24, 0xA88, 0xA94, 0xA98, 0xA9C, 0xAA0, 0xAA4, 0xAA8, 0xAAC, 0xAB0, 0xAB4, 0xAB8, 0xABC, 0xAC0, 0xAC4, 0xAC8, 0xACC, 0xAD0, 0xAD4, 0xAD8, 0xADC, 0xAE0, 0xB88, 0xB8C, 0xBC4, 0xBC8, 0xBCC, 0xBD0, 0xBD4, 0xBD8, 0xBDC, 0xBE0, 0xBE4, 0xBE8, 0xBEC, 0xC00, 0xC5C, 0xCAC
  −
 
  −
== svcCreateSharedMemory ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X3 || R0, R1 || u64 || Timeout
 
|-
 
|-
| (In) W1 || u64 || Size
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (In) W2 || [[#Permission]] || LocalPerm
+
| (Out) X1 || u64 || LastThreadContextParam0
 
|-
 
|-
| (In) W3 || [[#Permission]] || RemotePerm
+
| (Out) X2 || u64 || LastThreadContextParam1
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) X3 || u64 || LastThreadContextParam2
 
|-
 
|-
| (Out) W1 || Handle<SharedMemory> || MemHandle
+
| (Out) X4 || u64 || LastThreadContextParam3
 +
|-
 +
| (Out) X5 || u64 ||
 +
|-
 +
| (Out) W6 || u32 ||
 
|}
 
|}
 
</div>
 
</div>
   −
Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.
+
== GetLastThreadInfo ==
 
  −
Allocates memory from the current process' pool partition.
  −
 
  −
== svcMapTransferMemory ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,301: Line 1,271:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || Handle<TransferMemory> || MemHandle
+
| (In) None || ||  
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|-
 +
| (Out) X1 || u64 || LastThreadContextParam0
 +
|-
 +
| (Out) X2 || u64 || LastThreadContextParam1
 
|-
 
|-
| (In) X1 || void* || Addr
+
| (Out) X3 || u64 || LastThreadContextParam2
 
|-
 
|-
| (In) X2 || u64 || Size
+
| (Out) X4 || u64 || LastThreadContextParam3
 
|-
 
|-
| (In) W3 || [[#Permission]] || Permissions
+
| (Out) X5 || u64 ||
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W6 || u32 ||
 
|}
 
|}
 
</div>
 
</div>
   −
The newly mapped pages will have [[#MemoryState]] type 0xE.
+
== GetResourceLimitLimitValue ==
 
  −
You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error.
  −
 
  −
== svcUnmapTransferMemory ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || Handle<TransferMemory> || MemHandle
+
| (In) W1 || R1 || Handle<ResourceLimit> || Handle
 
|-
 
|-
| (In) X1 || void* || Addr
+
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
 
|-
 
|-
| (In) X2 || u64 || Size
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) X1 || R1, R2 || u64 || LimitValue
 
|}
 
|}
 
</div>
 
</div>
   −
Size must match size given in map syscall, otherwise there's an invalid-size error.
+
== GetResourceLimitCurrentValue ==
 
  −
== svcCreateInterruptEvent ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X1 || u64 || IrqNum
+
| (In) W1 || R1 || Handle<ResourceLimit> || Handle
 
|-
 
|-
| (In) W2 || bool || Flags
+
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W1 || Handle<ReadableEvent> || ReadableEventHandle
+
| (Out) X1 || R1, R2 || u64 || CurrentValue
 
|}
 
|}
 
</div>
 
</div>
   −
Creates an event handle for the given IRQ number. Waiting on this handle will wait until the IRQ is triggered. The flags argument configures the triggering. If it is false, the IRQ is active HIGH level sensitive, if it is true it is rising-edge sensitive.
+
== SetThreadActivity ==
 
  −
=== Result codes ===
  −
'''0x0:''' Success.
  −
 
  −
'''0xF001:''' Flags was > 1
  −
 
  −
'''0xF201:''' IRQ above 0x3FF or outside the [[NPDM#Kernel_Access_Control|IRQ access mask]] was given.
  −
 
  −
'''0xCE01:''' A SlabHeap was exhausted (too many interrupts created).
  −
 
  −
'''0xF401:''' IRQ already has an event registered.
  −
 
  −
'''0xD201:''' The handle table is full. Try closing some handles.
  −
 
  −
== svcQueryPhysicalAddress ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,372: Line 1,327:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || u64 || Addr
+
| (In) W0 || Handle<Thread> || ThreadHandle
 +
|-
 +
| (In) W1 || ThreadActivity || ThreadActivity
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
== GetThreadContext3 ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| (Out) W0 || [[#Result]]|| Ret
+
! Argument || Type || Name
 
|-
 
|-
| (Out) X1 || u64 || PhysAddr
+
| (In) X0 || [[#ThreadContext]]* || ThreadContext
 
|-
 
|-
| (Out) X2 || u64 || BaseAddr
+
| (In) W1 || Handle<Thread> || ThreadHandle
 
|-
 
|-
| (Out) X3 || u64 || Size
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
Queries the physical address of a virtual address. Will always fetch the lowest page-aligned mapping that contains the provided physical address.
+
== WaitForAddress ==
 
  −
The returned BaseAddr is the virtual address of that page-aligned mapping, while PhysAddr is the physical address of that page. Size is the amount of continuous physical memory in that mapping.
  −
 
  −
== svcQueryIoMapping ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,394: Line 1,355:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X1 || R2, R3 || u64 || PhysAddr
+
| (In) X0 || R0 || u64 || Address
 +
|-
 +
| (In) W1 || R1 || [[#ArbitrationType]] || ArbitrationType
 
|-
 
|-
| (In) X2 || R0 || u64 || Size
+
| (In) W2 || R2 || u32 || Value
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (In) X3 || R3, R4 || u64 || Timeout
 
|-
 
|-
| (Out) X1 || R1 || void* || VirtAddr
+
| (Out) None || || ||
 
|}
 
|}
 
</div>
 
</div>
   −
Returns a virtual address mapped to a given IO range.
+
== SignalToAddress ==
 
  −
== svcCreateDeviceAddressSpace ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,412: Line 1,373:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X1 || R2, R3 || u64 || StartAddr
+
| (In) X0 || R0 || u64 || Address
 +
|-
 +
| (In) W1 || R1 || [[#SignalType]] || SignalType
 
|-
 
|-
| (In) X2 || R0, R1 || u64 || EndAddr
+
| (In) W2 || R2 || u32 || Value
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (In) W3 || R3 || u32 || NumToSignal
 
|-
 
|-
| (Out) W1 || R1 || Handle<DeviceAddressSpace> || AddressSpaceHandle
+
| (Out) None || || ||
 
|}
 
|}
 
</div>
 
</div>
   −
Creates a virtual address space for binding device address spaces and returns a handle.
+
== SynchronizePreemptionState ==
 
  −
StartAddr is normally set to 0 and EndAddr is normally set to 0xFFFFFFFF.
  −
 
  −
== svcAttachDeviceAddressSpace ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,432: Line 1,391:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || [[#DeviceName]] || DeviceId
+
| (In) None || ||  
 
|-
 
|-
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (Out) W0 || [[#Result]] || Result
|-
  −
| (Out) W0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
Attaches a device address space to a [[#DeviceName|device]].
+
== DumpInfo ==
 
  −
== svcDetachDeviceAddressSpace ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,448: Line 1,403:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || [[#DeviceName]] || DeviceId
+
| (In) X0 || DumpInfoType || DumpInfoType
 
|-
 
|-
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (In) X1 || u64 ||  
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
Detaches a device address space from a [[#DeviceName|device]].
+
Stubbed in retail kernel.
 +
 
 +
[4.0.0+] This function was removed and replaced by [[#KernelDebug]].
   −
== svcMapDeviceAddressSpaceByForce ==
+
== KernelDebug ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (In) W0 || KernelDebugType || KernelDebugType
 
|-
 
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
+
| (In) X1 || u64 ||  
 
|-
 
|-
| (In) X2 || R2, R3 || void* || SrcAddr
+
| (In) X2 || u64 ||  
 +
|-
 +
| (In) X3 || u64 ||  
 
|-
 
|-
| (In) X3 || R4 || u64 || DeviceAsSize
+
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Stubbed in retail kernel.
 +
 
 +
== ChangeKernelTraceState ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
+
! Argument || Type || Name
 
|-
 
|-
| (In) W5 || R7 || [[#Permission]] || Permissions
+
| (In) W0 || KernelTraceState || KernelTraceState
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
Maps an attached device address space to an userspace address.
+
Stubbed in retail kernel.
 
  −
dev_map_addr is the userspace destination address, while dev_as_addr is the source address between dev_as_start_addr and dev_as_end_addr (passed to [[#svcCreateDeviceAddressSpace]]).
     −
The userspace destination address must have the [[SVC#MemoryState|MapDeviceAllowed]] bit set. Bit [[SVC#MemoryAttribute|IsDeviceMapped]] will be set after mapping.
+
== CreateSession ==
 
  −
== svcMapDeviceAddressSpaceAligned ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
|-
  −
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
   
|-
 
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
+
| (In) W2 || bool || IsLight
 
|-
 
|-
| (In) X2 || R2, R3 || void* || SrcAddr
+
| (In) X3 || u64 || Name
 
|-
 
|-
| (In) X3 || R4 || u64 || DeviceAsSize
+
| (Out) W0 || [[#Result]] || Result
|-
  −
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
   
|-
 
|-
| (In) W5 || R7 || [[#Permission]] || Permissions
+
| (Out) W1 || Handle<ServerSession> || ServerHandle
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W2 || Handle<ClientSession> || ClientHandle
 
|}
 
|}
 
</div>
 
</div>
   −
Maps an attached device address space to an userspace address.
+
== AcceptSession ==
 
  −
Same as [[#svcMapDeviceAddressSpaceByForce]], but the userspace destination address must have the [[SVC#MemoryState|MapDeviceAlignedAllowed]] bit set instead.
  −
 
  −
== svcUnmapDeviceAddressSpace ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (In) W1 || Handle<Port> || Port
 
|-
 
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
| (In) X2 || R2, R3 || void* || SrcAddr
+
| (Out) W1 || Handle<ServerSession> || Session
|-
  −
| (In) X3 || R4 || u64 || DeviceAsSize
  −
|-
  −
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
  −
|-
  −
| (Out) W0 || R0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
Unmaps an attached device address space from an userspace address.
+
=== Result codes ===
 +
'''0xf201:''' No session waiting to be accepted
   −
== svcContinueDebugEvent ==
+
== ReplyAndReceiveLight ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! [1.0.0-2.3.0] Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || R0 || Handle<Debug> || DebugHandle
+
| (In) W0 || Handle<Port> or Handle<ServerSession> || Handle
 
|-
 
|-
| (In) W1 || R1 || [[#ContinueDebugFlagsOld]] || DebugFlags
+
| (Out) W0 || [[#Result]] || Result
|-
  −
| (In) X2 || R2, R3 || u64 || ThreadId
  −
|-
  −
| (Out) W0 || R0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
<div style="display: inline-block; vertical-align:top;">
+
== ReplyAndReceive ==
 +
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! [3.0.0+] Argument64 || Argument32 || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) W0 || R0 || Handle<Debug> || DebugHandle
+
| (In) W1 || R1 || Handle<Port>* or Handle<ServerSession>* || Handles
 
|-
 
|-
| (In) W1 || R1 || [[#ContinueDebugFlags]] || DebugFlags
+
| (In) W2 || R2 || u32 || NumHandles
 
|-
 
|-
| (In) X2 || R2 || u64* || ThreadIdList
+
| (In) W3 || R3 || Handle<ServerSession> || ReplyTarget
 +
|-
 +
| (In) X4 || R0, R4 || u64 || Timeout
 
|-
 
|-
| (In) X3 || R3 || size_t || NumTids (max 64 - 0 means "all threads")
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W1 || R1 || u32 || HandleIndex
 
|}
 
|}
 
</div>
 
</div>
 +
 +
If ReplyTarget is not zero, a reply from the TLS will be sent to that session.
 +
Then it will wait until either of the passed sessions has an incoming message, is closed, a passed port has an incoming connection, or the timeout expires.
 +
If there is an incoming message, it is copied to the TLS.
 +
 +
If ReplyTarget is zero, the TLS should contain a blank message. If this message has a C descriptor, the buffer it points to will be used as the pointer buffer. See [[IPC_Marshalling#IPC_buffers]]. Note that a pointer buffer cannot be specified if ReplyTarget is not zero.
 +
 +
After being validated, passed handles will be enumerated in order; even if a session has been closed, if one that appears earlier in the list has an incoming message, it will take priority and a result code of 0x0 will be returned.
    
=== Result codes ===
 
=== Result codes ===
'''0x0:''' Success. The process has been resumed.
+
'''0x0:''' Success. Either a session has an incoming message or a port has an incoming connection. HandleIndex is set appropriately.
   −
'''0xe401:''' Invalid debug handle.
+
'''0xea01:''' Timeout. No handles were signalled before the timeout expired. HandleIndex is not updated.
   −
'''0xf401:''' Process has debug events queued or is already running.
+
'''0xf601:''' Port remote dead. One of the sessions has been closed. HandleIndex is set appropriately.
   −
== svcGetProcessList ==
+
== ReplyAndReceiveWithUserBuffer ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,580: Line 1,537:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X1 || R1 || u64* || PidBuffer
+
| (In) X1 || R1 || u64 || Address
 +
|-
 +
| (In) X2 || R2 || u64 || Size
 +
|-
 +
| (In) X3 || R3 || Handle<Port>* or Handle<ServerSession>* || Handles
 +
|-
 +
| (In) W4 || R0 || u32 || NumHandles
 +
|-
 +
| (In) W5 || R4 || Handle<ServerSession> || ReplyTarget
 
|-
 
|-
| (In) X2 || R2 || size_t || PidBufferSize
+
| (In) X6 || R5, R6 || u64 || Timeout
 
|-
 
|-
| (Out) X0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) X1 || R1 || size_t || NumProcesses
+
| (Out) W1 || R1 || u32 || HandleIndex
 
|}
 
|}
 
</div>
 
</div>
   −
Fills the provided array with the pids of currently living processes. A process "lives" so long as it is currently running or a handle to it still exists.
+
== CreateEvent ==
 
+
<div style="display: inline-block;">
It returns the total number of processes currently alive. If this number is bigger than the size of PidBuffer, the user won't have all the pids.
+
{| class="wikitable" border="1"
 
  −
=== Result codes ===
  −
'''0x0:''' Success.
  −
 
  −
'''0xd401:''' The provided buffer is outside the process address space.
  −
 
  −
'''0xe601:''' copyToUser failed. The provided buffer is not user-accessible.
  −
 
  −
'''0xee01:''' The provided buffer size is too big. Max value is 0xFFFFFFF.
  −
 
  −
== svcSetHardwareBreakPoint ==
  −
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || R0 || u32 || hardware_breakpoint_id
+
| (In) None || ||
 
|-
 
|-
| (In) X1 || R2, R3 || u64 || flags
+
| (Out) W0 || [[#Result]] || Result
 
|-
 
|-
| (In) X2 || R1, R4 || u64 || value
+
| (Out) W1 || Handle<WritableEvent> || WritableEvent
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W2 || Handle<ReadableEvent> || ReadableEvent
 
|}
 
|}
 
</div>
 
</div>
   −
Sets one of the AArch64 hardware breakpoints. The nintendo switch has 6 hardware breakpoints, and 4 hardware watchpoints. The syscall has two behaviors depending on the value of hardware_breakpoint_id:
+
== MapPhysicalMemoryUnsafe ==
 
  −
If hardware_breakpoint_id < 0x10, then it sets one of the AArch64 hardware breakpoints. Flags will go to DBGBCRn_EL1, and value to DBGBVRn_EL1. The only flags the user is allowed to set are those in the bitmask 0x7F01E1. Furthermore, the kernel will or it with 0x4004, in order to set various security flags to guarantee the watchpoints only triggers for code in EL0. If the user asks for a Breakpoint Type of ContextIDR match, the kernel shall use the given debug_handle to set DBGBVRn_EL1 to the ContextID of the debugged process.
  −
 
  −
If hardware_breakpoint_id is between 0x10 and 0x20 (exclusive), then it sets one of the AArch64 hardware watchpoints. Flags will go to DBGWCRn_EL1, and the value to DBGWVRn_EL1. The only flags the user is allowed to set are those in the bitmask 0xFF0F1FF9. Furthermore, the kernel will or it with 0x104004. This will set various security flags, and set the watchpoint type to be a Linked Watchpoint. This means that you need to link it to a Linked ContextIDR breakpoint. Check the ARM documentation for more information.
  −
 
  −
Note that hardware_breakpoint_id 0 to 4 match only to Virtual Address, while hardware_breakpoint_id 5 and 6 match against either Virtual Address, ContextID, or VMID. As such, if you are configuring a breakpoint to link for a watchpoint, make sure you use hardware_breakpoint_id 5 or 6.
  −
 
  −
For more documentation for hardware breakpoints, check out the AArch64 documentation for the [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488h/way1382455558968.html DBGBCRn_EL1 register] and the [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0488h/way1382455560629.html DBGWCRn_EL1 register]
  −
 
  −
== svcGetSystemInfo ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,635: Line 1,577:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || u64 || InfoId
+
| (In) X0 || u64 || Address
 
|-
 
|-
| (In) W2 || Handle || Handle
+
| (In) X1 || u64 || Size
 
|-
 
|-
| (In) X3 || u64 || InfoSubId
+
| (Out) W0 || [[#Result]] || Result
|-
+
|}
| (Out) W0 || [[#Result]] || Ret
  −
|-
  −
| (Out) X1 || u64 || Out
  −
|}
   
</div>
 
</div>
   −
{| class=wikitable
+
Same as [[#MapPhysicalMemory]] except it always uses pool partition 0.
! Handle type || Id0 || Id1 || Description
+
 
 +
== UnmapPhysicalMemoryUnsafe ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Zero    || 0 || 0 || TotalMemorySize_Application
+
! Argument || Type || Name
 
|-
 
|-
| Zero    || 0 || 1 || TotalMemorySize_Applet
+
| (In) X0 || u64 || Address
 
|-
 
|-
| Zero    || 0 || 2 || TotalMemorySize_System
+
| (In) X1 || u64 || Size
 
|-
 
|-
| Zero    || 0 || 3 || TotalMemorySize_SystemUnsafe
+
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
== SetUnsafeLimit ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Zero    || 1 || 0 || CurrentMemorySize_Application
+
! Argument || Type || Name
 
|-
 
|-
| Zero    || 1 || 1 || CurrentMemorySize_Applet
+
| (In) X0 || u64 || Limit
 
|-
 
|-
| Zero    || 1 || 2 || CurrentMemorySize_System
+
| (Out) W0 || [[#Result]] || Result
|-
  −
| Zero    || 1 || 3 || CurrentMemorySize_SystemUnsafe
  −
|-
  −
| Zero    || 2 || 0 || PrivilegedProcessId_LowerBound
  −
|-
  −
| Zero    || 2 || 1 || PrivilegedProcessId_UpperBound
   
|}
 
|}
 +
</div>
   −
== svcSetProcessMemoryPermission ==
+
== CreateCodeMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || R0 || Handle<Process> || ProcessHandle
+
| (In) X1 || u64 || Address
 
|-
 
|-
| (In) X1 || R2, R3 || u64 || Addr
+
| (In) X2 || u64 || Size
 
|-
 
|-
| (In) X2 || R1, R4 || u64 || Size
+
| (Out) W0 || [[#Result]] || Result
|-
  −
| (In) W3 || R5 || void* || Perm
   
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W1 || Handle<CodeMemory> || Handle
 
|}
 
|}
 
</div>
 
</div>
   −
This sets the memory permissions for the specified memory with the supplied process handle.
+
Takes an address range with backing memory to create the code memory object.
   −
This throws an error(0xD801) when the input perm is >0x5, hence -WX and RWX are not allowed.
+
The memory is initially memset to 0xFF after being locked.
   −
== svcMapProcessMemory ==
+
== ControlCodeMemory ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,699: Line 1,639:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || R0 || u64 || DstAddr
+
| (In) W0 || R0 || Handle<CodeMemory> || Handle
 +
|-
 +
| (In) W1 || R1 || [[#CodeMemoryOperation]] || CodeMemoryOperation
 
|-
 
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
+
| (In) X2 || R2, R3 || u64 || Address
 
|-
 
|-
| (In) X2 || R2, R3 || void* || SrcAddr
+
| (In) X3 || R4, R5 || u64 || Size
 
|-
 
|-
| (In) X3 || R4 || u64 || Size
+
| (In) W4 || R6 || MemoryPermission || Permission
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|}
 
|}
 
</div>
 
</div>
   −
Maps the src address from the supplied process handle into the current process.
+
Maps the backing memory for a Code memory object into the current process.
 +
 
 +
For [[#CodeMemoryOperation|CodeMemoryOperation_MapOwner]], memory permission must be RW-.
 +
 
 +
For [[#CodeMemoryOperation|CodeMemoryOperation_MapSlave]], memory permission must be R-- or R-X.
 +
 
 +
Operations [[#CodeMemoryOperation|CodeMemoryOperation_UnmapOwner/CodeMemoryOperation_UnmapSlave]] unmap memory that was previously mapped this way.
 +
 
 +
This allows one "secure JIT" process to map the code memory as RW-, and the other "slave" process to map it R-X.
   −
This allows mapping code and rodata with RW- permission.
+
[5.0.0+] Error 0xE401 is now returned when the process owner of the Code memory object is the same as the current process.
   −
== svcUnmapProcessMemory ==
+
== SleepSystem ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || R0 || void* || DstAddr
+
| (In) None || ||  
 
|-
 
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
+
| (Out) None || ||  
|-
  −
| (In) X2 || R2, R3 || u64 || SrcAddr
  −
|-
  −
| (In) X3 || R4 || u64 || Size
  −
|-
  −
| (Out) W0 || R0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
Unmaps what was mapped by [[#svcMapProcessMemory]].
+
== ReadWriteRegister ==
 
  −
== svcQueryProcessMemory ==
   
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,741: Line 1,683:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || R0 || [[#MemoryInfo]]* || MemInfoPtr
+
| (In) X1 || R2, R3 || u64 || RegAddr
 
|-
 
|-
| (In) W2 || R2 || Handle<Process> || ProcessHandle
+
| (In) W2 || R0 || u64 || RwMask
 
|-
 
|-
| (In) X3 || R1, R3 || u64 || Addr
+
| (In) W3 || R1 || u64 || InValue
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W1 || R1 || PageInfo || PageInfo
+
| (Out) W1 || R1 || u64 || OutValue
 
|}
 
|}
 
</div>
 
</div>
   −
Equivalent to [[#svcQueryMemory]] except takes a process handle.
+
Read/write IO registers with a hardcoded whitelist. Input address is physical-address and must be aligned to 4.
 +
 
 +
rw_mask is 0 for reading and 0xffffffff for writing. You can also write individual bits by using a mask value.
 +
 
 +
You can only write to registers inside physical pages 0x70019000 (MC), 0x7001C000 (MC0), 0x7001D000 (MC1), and they all share the same whitelist.
   −
== svcMapProcessCodeMemory ==
+
The whitelist is same for writing as for reading.
<div style="display: inline-block;">
+
 
{| class="wikitable" border="1"
+
The whitelist is:
|-
+
 
! Argument64 || Argument32 || Type || Name
+
0x054, 0x090, 0x094, 0x098, 0x09c, 0x0a0, 0x0a4, 0x0a8, 0x0ac, 0x0b0, 0x0b4, 0x0b8, 0x0bc, 0x0c0, 0x0c4, 0x0c8, 0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x0e0, 0x100, 0x108, 0x10c, 0x118, 0x11c, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, 0x158, 0x15c, 0x164, 0x168, 0x16c, 0x170, 0x174, 0x178, 0x17c, 0x200, 0x204, 0x2e4, 0x2e8, 0x2ec, 0x2f4, 0x2f8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37c, 0x380, 0x390, 0x394, 0x398, 0x3ac, 0x3b8, 0x3bc, 0x3c0, 0x3c4, 0x3d8, 0x3e8, 0x41c, 0x420, 0x424, 0x428, 0x42c, 0x430, 0x44c, 0x47c, 0x480, 0x484, 0x50c, 0x554, 0x558, 0x55c, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69c, 0x6a0, 0x6a4, 0x6c0, 0x6c4, 0x6f0, 0x6f4, 0x960, 0x970, 0x974, 0xa20, 0xa24, 0xb88, 0xb8c, 0xbc4, 0xbc8, 0xbcc, 0xbd0, 0xbd4, 0xbd8, 0xbdc, 0xbe0, 0xbe4, 0xbe8, 0xbec, 0xc00, 0xc5c, 0xcac
|-
+
 
| (In) W0 || R0 || Handle<Process> || ProcessHandle
+
[2.0.0+] Whitelist was extended with 0x4c4, 0x4c8, 0x4cc, 0x584, 0x588, 0x58c.
|-
+
 
| (In) X1 || R2, R3 || u64 || DstAddr
+
[2.0.0+] The IO registers in range 0x7000E400 (PMC) size 0xC00 skip the whitelist, and do a TrustZone call using [[SMC#ReadWriteRegister|ReadWriteRegister]].
|-
+
 
| (In) X2 || R1, R4 || u64 || SrcAddr
+
[4.0.0+] Access to the Memory Controller (0x70019000) also uses smcReadWriteRegister.
|-
+
 
| (In) X3 || R5, R6 || u64 || Size
+
Here is the whitelist imposed by that SMC, relative to the start of the PMC registers:
|-
+
 
| (Out) W0 || R0 || [[#Result]] || Ret
+
0x000, 0x00c, 0x010, 0x014, 0x01c, 0x020, 0x02c, 0x030, 0x034, 0x038, 0x03c, 0x040, 0x044, 0x048, 0x0dc, 0x0e0, 0x0e4, 0x160, 0x164, 0x168, 0x170, 0x1a8, 0x1b8, 0x1bc, 0x1c0, 0x1c4, 0x1c8, 0x2b4, 0x2d4, 0x440, 0x4d8
|}
+
 
</div>
+
Here is the whitelist imposed by the SMC [[SMC#ReadWriteRegister|ReadWriteRegister]] (checked in addition to the whitelist in the ReadWriteRegister SVC), relative to the start of the MC registers:
 +
 
 +
0x000, 0x004, 0x008, 0x00C, 0x010, 0x01C, 0x020, 0x030, 0x034, 0x050, 0x054, 0x090, 0x094, 0x098, 0x09C, 0x0A0, 0x0A4, 0x0A8, 0x0AC, 0x0B0, 0x0B4, 0x0B8, 0x0BC, 0x0C0, 0x0C4, 0x0C8, 0x0D0, 0x0D4, 0x0D8, 0x0DC, 0x0E0, 0x100, 0x108, 0x10C, 0x118, 0x11C, 0x124, 0x128, 0x12C, 0x130, 0x134, 0x138, 0x13C, 0x158, 0x15C, 0x164, 0x168, 0x16C, 0x170, 0x174, 0x178, 0x17C, 0x200, 0x204, 0x238, 0x240, 0x244, 0x250, 0x254, 0x258, 0x264, 0x268, 0x26C, 0x270, 0x274, 0x280, 0x284, 0x288, 0x28C, 0x294, 0x2E4, 0x2E8, 0x2EC, 0x2F4, 0x2F8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37C, 0x380, 0x390, 0x394, 0x398, 0x3AC, 0x3B8, 0x3BC, 0x3C0, 0x3C4, 0x3D8, 0x3E8, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430, 0x44C, 0x47C, 0x480, 0x484, 0x4C4, 0x4C8, 0x4CC, 0x50C, 0x554, 0x558, 0x55C, 0x584, 0x588, 0x58C, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69C, 0x6A0, 0x6A4, 0x6C0, 0x6C4, 0x6F0, 0x6F4, 0x960, 0x970, 0x974, 0x9B8, 0xA20, 0xA24, 0xA88, 0xA94, 0xA98, 0xA9C, 0xAA0, 0xAA4, 0xAA8, 0xAAC, 0xAB0, 0xAB4, 0xAB8, 0xABC, 0xAC0, 0xAC4, 0xAC8, 0xACC, 0xAD0, 0xAD4, 0xAD8, 0xADC, 0xAE0, 0xB88, 0xB8C, 0xBC4, 0xBC8, 0xBCC, 0xBD0, 0xBD4, 0xBD8, 0xBDC, 0xBE0, 0xBE4, 0xBE8, 0xBEC, 0xC00, 0xC5C, 0xCAC
 +
 
 +
== SetProcessActivity ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || Handle<Process> ||
 +
|-
 +
| (In) W1 || ProcessActivity || ProcessActivity
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
== CreateSharedMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W1 || u64 || Size
 +
|-
 +
| (In) W2 || MemoryPermission || LocalPerm
 +
|-
 +
| (In) W3 || MemoryPermission || RemotePerm
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|-
 +
| (Out) W1 || Handle<SharedMemory> || MemHandle
 +
|}
 +
</div>
 +
 
 +
Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.
 +
 
 +
Allocates memory from the current process' pool partition.
 +
 
 +
== MapTransferMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X0 || Handle<TransferMemory> || MemHandle
 +
|-
 +
| (In) X1 || void* || Addr
 +
|-
 +
| (In) X2 || u64 || Size
 +
|-
 +
| (In) W3 || MemoryPermission || Permission
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
The newly mapped pages will have [[#MemoryState]] type 0xE.
 +
 
 +
You must pass same size and permissions as given in [[#CreateTransferMemory]], otherwise error.
 +
 
 +
== UnmapTransferMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X0 || Handle<TransferMemory> || MemHandle
 +
|-
 +
| (In) X1 || void* || Addr
 +
|-
 +
| (In) X2 || u64 || Size
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Size must match size given in map syscall, otherwise there's an invalid-size error.
 +
 
 +
== CreateInterruptEvent ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X1 || u64 || IrqNum
 +
|-
 +
| (In) W2 || bool || Flags
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|-
 +
| (Out) W1 || Handle<ReadableEvent> || ReadableEventHandle
 +
|}
 +
</div>
 +
 
 +
Creates an event handle for the given IRQ number. Waiting on this handle will wait until the IRQ is triggered. The flags argument configures the triggering. If it is false, the IRQ is active HIGH level sensitive, if it is true it is rising-edge sensitive.
 +
 
 +
=== Result codes ===
 +
'''0x0:''' Success.
 +
 
 +
'''0xF001:''' Flags was > 1
 +
 
 +
'''0xF201:''' IRQ above 0x3FF or outside the [[NPDM#Kernel_Access_Control|IRQ access mask]] was given.
 +
 
 +
'''0xCE01:''' A SlabHeap was exhausted (too many interrupts created).
 +
 
 +
'''0xF401:''' IRQ already has an event registered.
 +
 
 +
'''0xD201:''' The handle table is full. Try closing some handles.
 +
 
 +
== QueryPhysicalAddress ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X1 || u64 || Addr
 +
|-
 +
| (Out) W0 || [[#Result]]|| Result
 +
|-
 +
| (Out) X1 || u64 || PhysAddr
 +
|-
 +
| (Out) X2 || u64 || BaseAddr
 +
|-
 +
| (Out) X3 || u64 || Size
 +
|}
 +
</div>
 +
 
 +
Queries the physical address of a virtual address. Will always fetch the lowest page-aligned mapping that contains the provided physical address.
 +
 
 +
The returned BaseAddr is the virtual address of that page-aligned mapping, while PhysAddr is the physical address of that page. Size is the amount of continuous physical memory in that mapping.
 +
 
 +
== QueryIoMapping ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X1 || R2, R3 || u64 || PhysAddr
 +
|-
 +
| (In) X2 || R0 || u64 || Size
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|-
 +
| (Out) X1 || R1 || void* || VirtAddr
 +
|}
 +
</div>
 +
 
 +
Returns a virtual address mapped to a given IO range.
 +
 
 +
== CreateDeviceAddressSpace ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X1 || R2, R3 || u64 || StartAddr
 +
|-
 +
| (In) X2 || R0, R1 || u64 || EndAddr
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|-
 +
| (Out) W1 || R1 || Handle<DeviceAddressSpace> || AddressSpaceHandle
 +
|}
 +
</div>
 +
 
 +
Creates a virtual address space for binding device address spaces and returns a handle.
 +
 
 +
StartAddr is normally set to 0 and EndAddr is normally set to 0xFFFFFFFF.
 +
 
 +
== AttachDeviceAddressSpace ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || [[#DeviceName]] || DeviceId
 +
|-
 +
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Attaches a device address space to a [[#DeviceName|device]].
 +
 
 +
== DetachDeviceAddressSpace ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || [[#DeviceName]] || DeviceId
 +
|-
 +
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Detaches a device address space from a [[#DeviceName|device]].
 +
 
 +
== MapDeviceAddressSpaceByForce ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X2 || R2, R3 || void* || SrcAddr
 +
|-
 +
| (In) X3 || R4 || u64 || DeviceAsSize
 +
|-
 +
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
 +
|-
 +
| (In) W5 || R7 || MemoryPermission || Permissions
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Maps an attached device address space to an userspace address.
 +
 
 +
dev_map_addr is the userspace destination address, while dev_as_addr is the source address between dev_as_start_addr and dev_as_end_addr (passed to [[#CreateDeviceAddressSpace]]).
 +
 
 +
The userspace destination address must have the [[SVC#MemoryState|MapDeviceAllowed]] bit set. Bit [[SVC#MemoryAttribute|IsDeviceMapped]] will be set after mapping.
 +
 
 +
== MapDeviceAddressSpaceAligned ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X2 || R2, R3 || void* || SrcAddr
 +
|-
 +
| (In) X3 || R4 || u64 || DeviceAsSize
 +
|-
 +
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
 +
|-
 +
| (In) W5 || R7 || MemoryPermission || Permission
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Maps an attached device address space to an userspace address.
 +
 
 +
Same as [[#MapDeviceAddressSpaceByForce]], but the userspace destination address must have the [[SVC#MemoryState|MapDeviceAlignedAllowed]] bit set instead.
 +
 
 +
== MapDeviceAddressSpace ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W1 || R1 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (In) W2 || R2 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X3 || R0, R3 || u64 || SrcAddr
 +
|-
 +
| (In) X4 || R4 || u64 || DeviceAsSize
 +
|-
 +
| (In) X5 || R5, R6 || u64 || DeviceAsAddr
 +
|-
 +
| (In) W6 || R7 || MemoryPermission || Permission
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|-
 +
| (Out) X1 || R1 || u64 || MappedSize
 +
|}
 +
</div>
 +
 
 +
== UnmapDeviceAddressSpace ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X2 || R2, R3 || void* || SrcAddr
 +
|-
 +
| (In) X3 || R4 || u64 || DeviceAsSize
 +
|-
 +
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Unmaps an attached device address space from an userspace address.
 +
 
 +
== ContinueDebugEvent ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! [1.0.0-2.3.0] Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<Debug> || DebugHandle
 +
|-
 +
| (In) W1 || R1 || [[#ContinueDebugFlagsOld]] || DebugFlags
 +
|-
 +
| (In) X2 || R2, R3 || u64 || ThreadId
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
<div style="display: inline-block; vertical-align:top;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! [3.0.0+] Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<Debug> || DebugHandle
 +
|-
 +
| (In) W1 || R1 || [[#ContinueDebugFlags]] || DebugFlags
 +
|-
 +
| (In) X2 || R2 || u64* || ThreadIdList
 +
|-
 +
| (In) X3 || R3 || size_t || NumTids (max 64 - 0 means "all threads")
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Ret
 +
|}
 +
</div>
 +
 
 +
=== Result codes ===
 +
'''0x0:''' Success. The process has been resumed.
 +
 
 +
'''0xe401:''' Invalid debug handle.
 +
 
 +
'''0xf401:''' Process has debug events queued or is already running.
 +
 
 +
== GetProcessList ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X1 || R1 || u64* || PidBuffer
 +
|-
 +
| (In) X2 || R2 || size_t || PidBufferSize
 +
|-
 +
| (Out) X0 || R0 || [[#Result]] || Result
 +
|-
 +
| (Out) X1 || R1 || size_t || NumProcesses
 +
|}
 +
</div>
 +
 
 +
Fills the provided array with the pids of currently living processes. A process "lives" so long as it is currently running or a handle to it still exists.
 +
 
 +
It returns the total number of processes currently alive. If this number is bigger than the size of PidBuffer, the user won't have all the pids.
 +
 
 +
=== Result codes ===
 +
'''0x0:''' Success.
 +
 
 +
'''0xd401:''' The provided buffer is outside the process address space.
 +
 
 +
'''0xe601:''' copyToUser failed. The provided buffer is not user-accessible.
 +
 
 +
'''0xee01:''' The provided buffer size is too big. Max value is 0xFFFFFFF.
 +
 
 +
== SetHardwareBreakPoint ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || u32 || Id
 +
|-
 +
| (In) X1 || R2, R3 || u64 || Flags
 +
|-
 +
| (In) X2 || R1, R4 || u64 || Value
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Sets one of the AArch64 hardware breakpoints. The nintendo switch has 6 hardware breakpoints, and 4 hardware watchpoints. The syscall has two behaviors depending on the value of hardware_breakpoint_id:
 +
 
 +
If hardware_breakpoint_id < 0x10, then it sets one of the AArch64 hardware breakpoints. Flags will go to DBGBCRn_EL1, and value to DBGBVRn_EL1. The only flags the user is allowed to set are those in the bitmask 0x7F01E1. Furthermore, the kernel will or it with 0x4004, in order to set various security flags to guarantee the watchpoints only triggers for code in EL0. If the user asks for a Breakpoint Type of ContextIDR match, the kernel shall use the given debug_handle to set DBGBVRn_EL1 to the ContextID of the debugged process.
 +
 
 +
If hardware_breakpoint_id is between 0x10 and 0x20 (exclusive), then it sets one of the AArch64 hardware watchpoints. Flags will go to DBGWCRn_EL1, and the value to DBGWVRn_EL1. The only flags the user is allowed to set are those in the bitmask 0xFF0F1FF9. Furthermore, the kernel will or it with 0x104004. This will set various security flags, and set the watchpoint type to be a Linked Watchpoint. This means that you need to link it to a Linked ContextIDR breakpoint. Check the ARM documentation for more information.
 +
 
 +
Note that hardware_breakpoint_id 0 to 4 match only to Virtual Address, while hardware_breakpoint_id 5 and 6 match against either Virtual Address, ContextID, or VMID. As such, if you are configuring a breakpoint to link for a watchpoint, make sure you use hardware_breakpoint_id 5 or 6.
 +
 
 +
For more documentation for hardware breakpoints, check out the AArch64 documentation for the [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488h/way1382455558968.html DBGBCRn_EL1 register] and the [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0488h/way1382455560629.html DBGWCRn_EL1 register]
 +
 
 +
== GetSystemInfo ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X1 || u64 || InfoId
 +
|-
 +
| (In) W2 || Handle || Handle
 +
|-
 +
| (In) X3 || u64 || InfoSubId
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|-
 +
| (Out) X1 || u64 || Out
 +
|}
 +
</div>
 +
 
 +
{| class=wikitable
 +
! Handle type || Id0 || Id1 || Description
 +
|-
 +
| Zero    || 0 || 0 || TotalMemorySize_Application
 +
|-
 +
| Zero    || 0 || 1 || TotalMemorySize_Applet
 +
|-
 +
| Zero    || 0 || 2 || TotalMemorySize_System
 +
|-
 +
| Zero    || 0 || 3 || TotalMemorySize_SystemUnsafe
 +
|-
 +
| Zero    || 1 || 0 || CurrentMemorySize_Application
 +
|-
 +
| Zero    || 1 || 1 || CurrentMemorySize_Applet
 +
|-
 +
| Zero    || 1 || 2 || CurrentMemorySize_System
 +
|-
 +
| Zero    || 1 || 3 || CurrentMemorySize_SystemUnsafe
 +
|-
 +
| Zero    || 2 || 0 || PrivilegedProcessId_LowerBound
 +
|-
 +
| Zero    || 2 || 1 || PrivilegedProcessId_UpperBound
 +
|}
 +
 
 +
== SetProcessMemoryPermission ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X1 || R2, R3 || u64 || Addr
 +
|-
 +
| (In) X2 || R1, R4 || u64 || Size
 +
|-
 +
| (In) W3 || R5 || void* || Perm
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
This sets the memory permissions for the specified memory with the supplied process handle.
 +
 
 +
This throws an error(0xD801) when the input perm is >0x5, hence -WX and RWX are not allowed.
 +
 
 +
== MapProcessMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X0 || R0 || u64 || DstAddr
 +
|-
 +
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X2 || R2, R3 || void* || SrcAddr
 +
|-
 +
| (In) X3 || R4 || u64 || Size
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Maps the src address from the supplied process handle into the current process.
 +
 
 +
This allows mapping code and rodata with RW- permission.
 +
 
 +
== UnmapProcessMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X0 || R0 || void* || DstAddr
 +
|-
 +
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X2 || R2, R3 || u64 || SrcAddr
 +
|-
 +
| (In) X3 || R4 || u64 || Size
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Unmaps what was mapped by [[#MapProcessMemory]].
 +
 
 +
== QueryProcessMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X0 || R0 || [[#MemoryInfo]]* || MemInfoPtr
 +
|-
 +
| (In) W2 || R2 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X3 || R1, R3 || u64 || Addr
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|-
 +
| (Out) W1 || R1 || PageInfo || PageInfo
 +
|}
 +
</div>
 +
 
 +
Equivalent to [[#QueryMemory]] except takes a process handle.
 +
 
 +
== MapProcessCodeMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X1 || R2, R3 || u64 || DstAddr
 +
|-
 +
| (In) X2 || R1, R4 || u64 || SrcAddr
 +
|-
 +
| (In) X3 || R5, R6 || u64 || Size
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Takes a process handle, and maps normal heap in that process as executable code in that process. Used when loading NROs. This does not support using the current-process handle alias.
 +
 
 +
== UnmapProcessCodeMemory ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 +
|-
 +
| (In) X1 || R2, R3 || u64 || DstAddr
 +
|-
 +
| (In) X2 || R1, R4 || u64 || SrcAddr
 +
|-
 +
| (In) X3 || R5, R6 || u64 || Size
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Result
 +
|}
 +
</div>
 +
 
 +
Unmaps what was mapped by [[#MapProcessCodeMemory]].
 +
 
 +
== CreateProcess ==
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X1 || [[#CreateProcessInfo]]* || InfoPtr
 +
|-
 +
| (In) X2 || u32* || CapabilitiesPtr
 +
|-
 +
| (In) X3 || u64 || CapabilitiesNum
 +
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|-
 +
| (Out) W1 || Handle<Process> || ProcessHandle
 +
|}
 +
</div>
 +
 
 +
Takes a [[#CreateProcessInfo]] as input.
 +
CapabilitiesPtr points to an array of [[NPDM#Kernel_Access_Control|kernel capabilities]].
 +
CapabilitiesNum is a number of capabilities in the CapabilitiesPtr array (number of element, not number of bytes).
 +
 
 +
=== Result codes ===
 +
'''0x0:''' Success.
 +
 
 +
'''0xCA01:''' Attempted to map more code pages than available in address space.
 +
 
 +
'''0xCC01:''' Provided CodeAddr is invalid (make sure it's in range?)
 +
 
 +
'''0xE401:''' The resource handle passed is invalid.
   −
Takes a process handle, and maps normal heap in that process as executable code in that process. Used when loading NROs. This does not support using the current-process handle alias.
+
'''0xE601:''' Attempt to copy procinfo from user-supplied pointer failed. Attempt to copy capabilities_num from user-supplied pointer failed.
   −
== svcUnmapProcessCodeMemory ==
+
'''0xE801:''' Attempted to create a 32-bit process with a 36-bit address space.
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
  −
|-
  −
! Argument64 || Argument32 || Type || Name
  −
|-
  −
| (In) W0 || R0 || Handle<Process> || ProcessHandle
  −
|-
  −
| (In) X1 || R2, R3 || u64 || DstAddr
  −
|-
  −
| (In) X2 || R1, R4 || u64 || SrcAddr
  −
|-
  −
| (In) X3 || R5, R6 || u64 || Size
  −
|-
  −
| (Out) W0 || R0 || [[#Result]] || Ret
  −
|}
  −
</div>
     −
Unmaps what was mapped by [[#svcMapProcessCodeMemory]].
+
'''0xF001:''' Unused bits are set in mmuflags. Unknown address space type used.
   −
== svcCreateProcess ==
+
== GetProcessInfo ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X1 || [[#CreateProcessInfo]]* || InfoPtr
+
| (In) W0 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X2 || u32* || CapabilitiesPtr
+
| (In) W1 || R2 || [[#ProcessInfoType]] || InfoType
 
|-
 
|-
| (In) X3 || u64 || CapabilitiesNum
+
| (Out) W0 || R0 || [[#Result]] || Result
|-
  −
| (Out) W0 || [[#Result]] || Ret
  −
|-
  −
| (Out) W1 || Handle<Process> || ProcessHandle
  −
|}
  −
</div>
  −
 
  −
Takes a [[#CreateProcessInfo]] as input.
  −
CapabilitiesPtr points to an array of [[NPDM#Kernel_Access_Control|kernel capabilities]].
  −
CapabilitiesNum is a number of capabilities in the CapabilitiesPtr array (number of element, not number of bytes).
  −
 
  −
=== Result codes ===
  −
'''0x0:''' Success.
  −
 
  −
'''0xCA01:''' Attempted to map more code pages than available in address space.
  −
 
  −
'''0xCC01:''' Provided CodeAddr is invalid (make sure it's in range?)
  −
 
  −
'''0xE401:''' The resource handle passed is invalid.
  −
 
  −
'''0xE601:''' Attempt to copy procinfo from user-supplied pointer failed. Attempt to copy capabilities_num from user-supplied pointer failed.
  −
 
  −
'''0xE801:''' Attempted to create a 32-bit process with a 36-bit address space.
  −
 
  −
'''0xF001:''' Unused bits are set in mmuflags. Unknown address space type used.
  −
 
  −
== svcGetProcessInfo ==
  −
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
  −
|-
  −
! Argument64 || Argument32 || Type || Name
  −
|-
  −
| (In) W0 || R1 || Handle<Process> || ProcessHandle
  −
|-
  −
| (In) W1 || R2 || [[#ProcessInfoType]] || InfoType
  −
|-
  −
| (Out) W0 || R0 || [[#Result]] || Ret
   
|-
 
|-
 
| (Out) X1 || R1, R2 || [[#ProcessState]] || State
 
| (Out) X1 || R1, R2 || [[#ProcessState]] || State
Line 1,850: Line 2,336:  
Returns an enum with value 0-7.
 
Returns an enum with value 0-7.
   −
== svcCallSecureMonitor ==
+
== CallSecureMonitor ==
 
<div style="display: inline-block;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,876: Line 2,362:  
== Debugging ==
 
== Debugging ==
 
[2.0.0+] Exactly 6 debug SVCs require that [[SPL_services#GetConfig|IsDebugMode]] is non-zero. Error 0x4201 is returned otherwise.
 
[2.0.0+] Exactly 6 debug SVCs require that [[SPL_services#GetConfig|IsDebugMode]] is non-zero. Error 0x4201 is returned otherwise.
* svcBreakDebugProcess
+
* BreakDebugProcess
* svcContinueDebugEvent
+
* ContinueDebugEvent
* svcWriteDebugProcessMemory
+
* WriteDebugProcessMemory
* svcSetDebugThreadContext
+
* SetDebugThreadContext
* svcTerminateDebugProcess
+
* TerminateDebugProcess
* svcSetHardwareBreakPoint
+
* SetHardwareBreakPoint
   −
svcDebugActiveProcess stops execution of the target process, the normal method for resuming it requires svcContinueDebugEvent(see above). Closing the debug handle also results in execution being resumed.
+
DebugActiveProcess stops execution of the target process, the normal method for resuming it requires ContinueDebugEvent(see above). Closing the debug handle also results in execution being resumed.
    
= Enum/Structures =
 
= Enum/Structures =
Line 1,905: Line 2,391:  
! Value || Name
 
! Value || Name
 
|-
 
|-
| 0 || DeviceName_AFI
+
| 0 || AFI
 
|-
 
|-
| 1 || DeviceName_AVPC
+
| 1 || AVPC
 
|-
 
|-
| 2 || DeviceName_DC
+
| 2 || DC
 
|-
 
|-
| 3 || DeviceName_DCB
+
| 3 || DCB
 
|-
 
|-
| 4 || DeviceName_HC
+
| 4 || HC
 
|-
 
|-
| 5 || DeviceName_HDA
+
| 5 || HDA
 
|-
 
|-
| 6 || DeviceName_ISP2
+
| 6 || ISP2
 
|-
 
|-
| 7 || DeviceName_MSENCNVENC
+
| 7 || MSENCNVENC
 
|-
 
|-
| 8 || DeviceName_NV
+
| 8 || NV
 
|-
 
|-
| 9 || DeviceName_NV2
+
| 9 || NV2
 
|-
 
|-
| 10 || DeviceName_PPCS
+
| 10 || PPCS
 
|-
 
|-
| 11 || DeviceName_SATA
+
| 11 || SATA
 
|-
 
|-
| 12 || DeviceName_VI
+
| 12 || VI
 
|-
 
|-
| 13 || DeviceName_VIC
+
| 13 || VIC
 
|-
 
|-
| 14 || DeviceName_XUSB_HOST
+
| 14 || XUSB_HOST
 
|-
 
|-
| 15 || DeviceName_XUSB_DEV
+
| 15 || XUSB_DEV
 
|-
 
|-
| 16 || DeviceName_TSEC
+
| 16 || TSEC
 
|-
 
|-
| 17 || DeviceName_PPCS1
+
| 17 || PPCS1
 
|-
 
|-
| 18 || DeviceName_DC1
+
| 18 || DC1
 
|-
 
|-
| 19 || DeviceName_SDMMC1A
+
| 19 || SDMMC1A
 
|-
 
|-
| 20 || DeviceName_SDMMC2A
+
| 20 || SDMMC2A
 
|-
 
|-
| 21 || DeviceName_SDMMC3A
+
| 21 || SDMMC3A
 
|-
 
|-
| 22 || DeviceName_SDMMC4A
+
| 22 || SDMMC4A
 
|-
 
|-
| 23 || DeviceName_ISP2B
+
| 23 || ISP2B
 
|-
 
|-
| 24 || DeviceName_GPU
+
| 24 || GPU
 
|-
 
|-
| 25 || DeviceName_GPUB
+
| 25 || GPUB
 
|-
 
|-
| 26 || DeviceName_PPCS2
+
| 26 || PPCS2
 
|-
 
|-
| 27 || DeviceName_NVDEC
+
| 27 || NVDEC
 
|-
 
|-
| 28 || DeviceName_APE
+
| 28 || APE
 
|-
 
|-
| 29 || DeviceName_SE
+
| 29 || SE
 
|-
 
|-
| 30 || DeviceName_NVJPG
+
| 30 || NVJPG
 
|-
 
|-
| 31 || DeviceName_HC1
+
| 31 || HC1
 
|-
 
|-
| 32 || DeviceName_SE1
+
| 32 || SE1
 
|-
 
|-
| 33 || DeviceName_AXIAP
+
| 33 || AXIAP
 
|-
 
|-
| 34 || DeviceName_ETR
+
| 34 || ETR
 
|-
 
|-
| 35 || DeviceName_TSECB
+
| 35 || TSECB
 
|-
 
|-
| 36 || DeviceName_TSEC1
+
| 36 || TSEC1
 
|-
 
|-
| 37 || DeviceName_TSECB1
+
| 37 || TSECB1
 
|-
 
|-
| 38 || DeviceName_NVDEC1
+
| 38 || NVDEC1
 
|}
 
|}
   Line 1,988: Line 2,474:  
! Value || Name
 
! Value || Name
 
|-
 
|-
| 0 || CodeMemoryOperation_MapOwner
+
| 0 || MapOwner
 
|-
 
|-
| 1 || CodeMemoryOperation_MapSlave
+
| 1 || MapSlave
 
|-
 
|-
| 2 || CodeMemoryOperation_UnmapOwner
+
| 2 || UnmapOwner
 
|-
 
|-
| 3 || CodeMemoryOperation_UnmapSlave
+
| 3 || UnmapSlave
 
|}
 
|}
   Line 2,001: Line 2,487:  
! Value || Name || Note
 
! Value || Name || Note
 
|-
 
|-
| 0 || LimitableResource_Memory || Bytes of memory a process may allocate.
+
| 0 || Memory || Bytes of memory a process may allocate.
 
|-
 
|-
| 1 || LimitableResource_Threads || Amount of threads a process can create.
+
| 1 || Threads || Amount of threads a process can create.
 
|-
 
|-
| 2 || LimitableResource_Events || Amount of events a process can create through svcCreateEvent or svcSendAsyncRequestWithUserBuffer.
+
| 2 || Events || Amount of events a process can create through [[#CreateEvent]] or [[#SendAsyncRequestWithUserBuffer]].
 
|-
 
|-
| 3 || LimitableResource_TransferMemories || Amount of TransferMemory a process can create through svcCreateTransferMemory.
+
| 3 || TransferMemories || Amount of TransferMemory a process can create through [[#CreateTransferMemory]].
 
|-
 
|-
| 4 || LimitableResource_Sessions || Amount of session a process can create through svcCreateSession, svcConnectToPort or svcConnectToNamedPort.
+
| 4 || Sessions || Amount of session a process can create through [[#CreateSession]], [[#ConnectToPort]] or [[#ConnectToNamedPort]].
 
|}
 
|}
   Line 2,016: Line 2,502:  
! Value || Name
 
! Value || Name
 
|-
 
|-
| 0 || [[#ProcessState|ProcessInfoType_ProcessState]]
+
| 0 || [[#ProcessState|ProcessState]]
|-
   
|}
 
|}
   Line 2,024: Line 2,509:  
! Value || Name || Notes
 
! Value || Name || Notes
 
|-
 
|-
| 0 || ProcessState_Created ||
+
| 0 || Created ||
 
|-
 
|-
| 1 || ProcessState_CreatedAttached ||
+
| 1 || CreatedAttached ||
 
|-
 
|-
| 2 || ProcessState_Started ||
+
| 2 || Started ||
 
|-
 
|-
| 3 || ProcessState_Crashed || Processes will not enter this state unless they were created with [[#CreateProcessInfo|EnableDebug]].
+
| 3 || Crashed || Processes will not enter this state unless they were created with [[#CreateProcessInfo|EnableDebug]].
 
|-
 
|-
| 4 || ProcessState_StartedAttached ||
+
| 4 || StartedAttached ||
 
|-
 
|-
| 5 || ProcessState_Exiting ||
+
| 5 || Exiting ||
 
|-
 
|-
| 6 || ProcessState_Exited ||
+
| 6 || Exited ||
 
|-
 
|-
| 7 || ProcessState_DebugSuspended ||
+
| 7 || DebugSuspended ||
 
|}
 
|}
   Line 2,045: Line 2,530:  
! Value || Name
 
! Value || Name
 
|-
 
|-
| 0 || DebugThreadParam_DynamicPriority
+
| 0 || DynamicPriority
 
|-
 
|-
| 1 || DebugThreadParam_SchedulingStatus
+
| 1 || SchedulingStatus
 
|-
 
|-
| 2 || DebugThreadParam_PreferredCpuCore
+
| 2 || PreferredCpuCore
 
|-
 
|-
| 3 || DebugThreadParam_CurrentCpuCore
+
| 3 || CurrentCpuCore
 
|-
 
|-
| 4 || DebugThreadParam_AffinityMask
+
| 4 || AffinityMask
 
|}
 
|}
    
Dynamic priority: output in out2
 
Dynamic priority: output in out2
   −
Scheduling status: out1 contains bit0: is debug-suspended, bit1: is user-suspended (svcSetThreadActivity 1 or svcSetProcessActivity 1).
+
Scheduling status: out1 contains bit0: is debug-suspended, bit1: is user-suspended ([[#SetThreadActivity]] 1 or [[#SetProcessActivity]] 1).
 
Out2 contains {suspended, idle, running, terminating} => {5, 0, 1, 4}
 
Out2 contains {suspended, idle, running, terminating} => {5, 0, 1, 4}
   −
DebugThreadParam_PreferredCpuCore: output in out2
+
PreferredCpuCore: output in out2
   −
DebugThreadParam_CurrentCpuCore: output in out2
+
CurrentCpuCore: output in out2
   −
DebugThreadParam_AffinityMask: output in out1
+
AffinityMask: output in out1
    
== CreateProcessInfo ==
 
== CreateProcessInfo ==
Line 2,168: Line 2,653:  
! Bits || Description || Meaning
 
! Bits || Description || Meaning
 
|-
 
|-
| 7-0 || Type ||  
+
| 7-0 || [[#MemoryType]] ||  
 
|-
 
|-
| 8 || [[#svcSetMemoryPermission|PermissionChangeAllowed]] ||
+
| 8 || [[#SetMemoryPermission|PermissionChangeAllowed]] ||
 
|-
 
|-
| 9 || ForceReadWritableByDebugSyscalls || Allows using [[#svcWriteDebugProcessMemory]] on segments mapped read-only.
+
| 9 || ForceReadWritableByDebugSyscalls || Allows using [[#WriteDebugProcessMemory]] on segments mapped read-only.
 
|-
 
|-
 
| 10 || IpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=0.
 
| 10 || IpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=0.
Line 2,180: Line 2,665:  
| 12 || NonSecureIpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=3.
 
| 12 || NonSecureIpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=3.
 
|-
 
|-
| 14 || [[#svcSetProcessMemoryPermission|ProcessPermissionChangeAllowed]] ||
+
| 14 || [[#SetProcessMemoryPermission|ProcessPermissionChangeAllowed]] ||
 
|-
 
|-
| 15 || [[#svcMapMemory|MapAllowed]] ||
+
| 15 || [[#MapMemory|MapAllowed]] ||
 
|-
 
|-
| 16 || [[#svcUnmapProcessCodeMemory|UnmapProcessCodeMemoryAllowed]] ||
+
| 16 || [[#UnmapProcessCodeMemory|UnmapProcessCodeMemoryAllowed]] ||
 
|-
 
|-
| 17 || [[#svcCreateTransferMemory|TransferMemoryAllowed]] ||
+
| 17 || [[#CreateTransferMemory|TransferMemoryAllowed]] ||
 
|-
 
|-
| 18 || [[#svcQueryPhysicalAddress|QueryPhysicalAddressAllowed]] ||
+
| 18 || [[#QueryPhysicalAddress|QueryPhysicalAddressAllowed]] ||
 
|-
 
|-
| 19 || MapDeviceAllowed ([[#svcMapDeviceAddressSpace]] and [[#svcMapDeviceAddressSpaceByForce]]) ||
+
| 19 || MapDeviceAllowed ([[#MapDeviceAddressSpace]] and [[#MapDeviceAddressSpaceByForce]]) ||
 
|-
 
|-
| 20 || [[#svcMapDeviceAddressSpaceAligned|MapDeviceAlignedAllowed]] ||
+
| 20 || [[#MapDeviceAddressSpaceAligned|MapDeviceAlignedAllowed]] ||
 
|-
 
|-
| 21 || [[#svcSendSyncRequestWithUserBuffer|IpcBufferAllowed]] ||
+
| 21 || [[#SendSyncRequestWithUserBuffer|IpcBufferAllowed]] ||
 
|-
 
|-
 
| 22 || IsPoolAllocated/IsReferenceCounted || The physical memory blocks backing this region are refcounted.
 
| 22 || IsPoolAllocated/IsReferenceCounted || The physical memory blocks backing this region are refcounted.
 
|-
 
|-
| 23 || [[#svcMapProcessMemory|MapProcessAllowed]] ||
+
| 23 || [[#MapProcessMemory|MapProcessAllowed]] ||
 
|-
 
|-
| 24 || [[#svcSetMemoryAttribute|AttributeChangeAllowed]] ||
+
| 24 || [[#SetMemoryAttribute|AttributeChangeAllowed]] ||
 
|-
 
|-
| 25 || [4.0.0+] [[#svcCreateCodeMemory|CodeMemoryAllowed]] ||
+
| 25 || [4.0.0+] [[#CreateCodeMemory|CodeMemoryAllowed]] ||
 
|}
 
|}
    +
=== MemoryType ===
 
{| class=wikitable
 
{| class=wikitable
 
! Value || Type || Meaning
 
! Value || Type || Meaning
 
|-
 
|-
| 0x00000000 || MemoryType_Unmapped ||
+
| 0x00000000 || Unmapped ||
 
|-
 
|-
| 0x00002001 || MemoryType_Io || Mapped by kernel capability parsing in [[#svcCreateProcess]].  
+
| 0x00002001 || Io || Mapped by kernel capability parsing in [[#CreateProcess]].  
 
|-
 
|-
| 0x00042002 || MemoryType_Normal || Mapped by kernel capability parsing in [[#svcCreateProcess]].
+
| 0x00042002 || Normal || Mapped by kernel capability parsing in [[#CreateProcess]].
 
|-
 
|-
| 0x00DC7E03 || MemoryType_CodeStatic || Mapped during [[#svcCreateProcess]].
+
| 0x00DC7E03 || CodeStatic || Mapped during [[#CreateProcess]].
 
|-
 
|-
 
| [1.0.0+]
 
| [1.0.0+]
Line 2,223: Line 2,709:     
0x03FEBD04
 
0x03FEBD04
|| MemoryType_CodeMutable || Transition from 0xDC7E03 performed by [[#svcSetProcessMemoryPermission]].
+
|| CodeMutable || Transition from 0xDC7E03 performed by [[#SetProcessMemoryPermission]].
 
|-
 
|-
 
| [1.0.0+]
 
| [1.0.0+]
Line 2,231: Line 2,717:     
0x037EBD05
 
0x037EBD05
|| MemoryType_Heap || Mapped using [[#svcSetHeapSize]].
+
|| Heap || Mapped using [[#SetHeapSize]].
 
|-
 
|-
| 0x00402006 || MemoryType_SharedMemory || Mapped using [[#svcMapSharedMemory]].
+
| 0x00402006 || SharedMemory || Mapped using [[#MapSharedMemory]].
 
|-
 
|-
| 0x00482907 || [1.0.0] MemoryType_Alias || Mapped using [[#svcMapMemory]].
+
| 0x00482907 || [1.0.0] Alias || Mapped using [[#MapMemory]].
 
|-
 
|-
| 0x00DD7E08 || MemoryType_ModuleCodeStatic || Mapped using [[#svcMapProcessCodeMemory]].
+
| 0x00DD7E08 || ModuleCodeStatic || Mapped using [[#MapProcessCodeMemory]].
 
|-
 
|-
 
| [1.0.0+]
 
| [1.0.0+]
Line 2,246: Line 2,732:     
0x03FFBD09
 
0x03FFBD09
|| MemoryType_ModuleCodeMutable || Transition from 0xDD7E08 performed by [[#svcSetProcessMemoryPermission]].
+
|| ModuleCodeMutable || Transition from 0xDD7E08 performed by [[#SetProcessMemoryPermission]].
 
|-
 
|-
| 0x005C3C0A || [[IPC_Marshalling|MemoryType_Ipc]] || IPC buffers with descriptor flags=0.
+
| 0x005C3C0A || [[IPC_Marshalling|Ipc]] || IPC buffers with descriptor flags=0.
 
|-
 
|-
| 0x005C3C0B || MemoryType_Stack || Mapped using [[#svcMapMemory]].
+
| 0x005C3C0B || Stack || Mapped using [[#MapMemory]].
 
|-
 
|-
| 0x0040200C || [[Thread Local Storage|MemoryType_ThreadLocal]] || Mapped during [[#svcCreateThread]].
+
| 0x0040200C || [[Thread Local Storage|ThreadLocal]] || Mapped during [[#CreateThread]].
 
|-
 
|-
| 0x015C3C0D || MemoryType_TransferMemoryIsolated || Mapped using [[#svcMapTransferMemory]] when the owning process has perm=0.
+
| 0x015C3C0D || TransferMemoryIsolated || Mapped using [[#MapTransferMemory]] when the owning process has perm=0.
 
|-
 
|-
| 0x005C380E || MemoryType_TransferMemory || Mapped using [[#svcMapTransferMemory]] when the owning process has perm!=0.
+
| 0x005C380E || TransferMemory || Mapped using [[#MapTransferMemory]] when the owning process has perm!=0.
 
|-
 
|-
| 0x0040380F || MemoryType_ProcessMemory || Mapped using [[#svcMapProcessMemory]].
+
| 0x0040380F || ProcessMemory || Mapped using [[#MapProcessMemory]].
 
|-
 
|-
| 0x00000010 || MemoryType_Reserved ||
+
| 0x00000010 || Reserved ||
 
|-
 
|-
| 0x005C3811 || [[IPC_Marshalling|MemoryType_NonSecureIpc]] || IPC buffers with descriptor flags=1.
+
| 0x005C3811 || [[IPC_Marshalling|NonSecureIpc]] || IPC buffers with descriptor flags=1.
 
|-
 
|-
| 0x004C2812 || [[IPC_Marshalling|MemoryType_NonDeviceIpc]] || IPC buffers with descriptor flags=3.
+
| 0x004C2812 || [[IPC_Marshalling|NonDeviceIpc]] || IPC buffers with descriptor flags=3.
 
|-
 
|-
| 0x00002013 || MemoryType_KernelStack || Mapped in kernel during [[#svcCreateThread]].
+
| 0x00002013 || KernelStack || Mapped in kernel during [[#CreateThread]].
 
|-
 
|-
| 0x00402214 || [4.0.0+] MemoryType_CodeReadOnly || Mapped in kernel during [[#svcControlCodeMemory]].
+
| 0x00402214 || [4.0.0+] CodeReadOnly || Mapped in kernel during [[#ControlCodeMemory]].
 
|-
 
|-
| 0x00402015 || [4.0.0+] MemoryType_CodeWritable || Mapped in kernel during [[#svcControlCodeMemory]].
+
| 0x00402015 || [4.0.0+] CodeWritable || Mapped in kernel during [[#ControlCodeMemory]].
 
|}
 
|}
   Line 2,282: Line 2,768:  
|-
 
|-
 
| 0x2 || WaitIfEqual
 
| 0x2 || WaitIfEqual
|-
   
|}
 
|}
   Line 2,294: Line 2,779:  
|-
 
|-
 
| 0x2 || SignalAndModifyBasedOnWaitingThreadCountIfEqual
 
| 0x2 || SignalAndModifyBasedOnWaitingThreadCountIfEqual
|-
   
|}
 
|}
    
== ContinueDebugFlagsOld ==
 
== ContinueDebugFlagsOld ==
 
[1.0.0-2.3.0]
 
[1.0.0-2.3.0]
   
{| class=wikitable
 
{| class=wikitable
 
! Bit || Bitmask || Description
 
! Bit || Bitmask || Description
Line 2,312: Line 2,795:  
== ContinueDebugFlags ==
 
== ContinueDebugFlags ==
 
[3.0.0+]
 
[3.0.0+]
   
{| class=wikitable
 
{| class=wikitable
 
! Bit || Bitmask || Description
 
! Bit || Bitmask || Description
Line 2,396: Line 2,878:  
! Value || Name
 
! Value || Name
 
|-
 
|-
| 0 || DebugEvent_AttachProcess
+
| 0 || AttachProcess
 
|-
 
|-
| 1 || DebugEvent_AttachThread
+
| 1 || AttachThread
 
|-
 
|-
| 2 || DebugEvent_ExitProcess
+
| 2 || ExitProcess
 
|-
 
|-
| 3 || DebugEvent_ExitThread
+
| 3 || ExitThread
 
|-
 
|-
| 4 || DebugEvent_Exception
+
| 4 || Exception
 
|}
 
|}
   Line 2,411: Line 2,893:  
! Value || Name
 
! Value || Name
 
|-
 
|-
| 0 || Exception_Trap (*)
+
| 0 || Trap (*)
 
|-
 
|-
| 1 || Exception_InstructionAbort
+
| 1 || InstructionAbort
 
|-
 
|-
| 2 || Exception_DataAbortMisc (**)
+
| 2 || DataAbortMisc (**)
 
|-
 
|-
| 3 || Exception_PcSpAlignmentFault
+
| 3 || PcSpAlignmentFault
 
|-
 
|-
| 4 || Exception_DebuggerAttached
+
| 4 || DebuggerAttached
 
|-
 
|-
| 5 || Exception_BreakPoint
+
| 5 || BreakPoint
 
|-
 
|-
| 6 || Exception_UserBreak
+
| 6 || UserBreak
 
|-
 
|-
| 7 || Exception_DebuggerBreak
+
| 7 || DebuggerBreak
 
|-
 
|-
| 8 || Exception_BadSvcId
+
| 8 || BadSvcId
 
|-
 
|-
| 9 || Exception_SError [not in 1.0.0]
+
| 9 || [2.0.0+] SError
 
|}
 
|}
   Line 2,500: Line 2,982:  
if EnableDebug is set, and depending on the process state (more than one crash per process isn't permitted) it may signal itself with ProcessState_Crashed so that PM asks NS to start creport so that creport attaches to it and reports the crashes. Otherwise, just terminate.
 
if EnableDebug is set, and depending on the process state (more than one crash per process isn't permitted) it may signal itself with ProcessState_Crashed so that PM asks NS to start creport so that creport attaches to it and reports the crashes. Otherwise, just terminate.
   −
Userland reporting path and svcReturnFromException:
+
Userland reporting path and [[#ReturnFromException]]:
    
TLS region start (A64):
 
TLS region start (A64):
   
{| class=wikitable
 
{| class=wikitable
 
! Offset || Length || Description
 
! Offset || Length || Description
Line 2,513: Line 2,994:     
ExceptionFrameA64:
 
ExceptionFrameA64:
   
{| class=wikitable
 
{| class=wikitable
 
! Offset || Length || Description
 
! Offset || Length || Description
Line 2,537: Line 3,017:     
TLS region start (A32):
 
TLS region start (A32):
   
{| class=wikitable
 
{| class=wikitable
 
! Offset || Length || Description
 
! Offset || Length || Description
Line 2,582: Line 3,061:  
| 0x103 || Misaligned SP
 
| 0x103 || Misaligned SP
 
|-
 
|-
| 0x106 || SError [not in 1.0.0?]
+
| 0x106 || [2.0.0+] SError
 
|-
 
|-
 
| 0x301 || Bad SVC
 
| 0x301 || Bad SVC
Line 2,594: Line 3,073:  
(During normal app boot the process is invoked with X0=0 and X1=main_thread_handle. The crt0 of retail apps determines whether to boot normally or handle an exception if X0 is set to 0 or not)
 
(During normal app boot the process is invoked with X0=0 and X1=main_thread_handle. The crt0 of retail apps determines whether to boot normally or handle an exception if X0 is set to 0 or not)
   −
The application is supposed to promptly update the contents of elr_el1 to a user handler (and any other regs it sees fit) and call svcReturnFromException (error code) to call that handler. The latter is then expected to promptly abort the program.
+
The application is supposed to promptly update the contents of elr_el1 to a user handler (and any other regs it sees fit) and call [[#ReturnFromException]] (error code) to call that handler. The latter is then expected to promptly abort the program.
   −
svcReturnFromException updates the contents of the kernel stack frame with what the user provided in the TLS structure, sets TPIDR_EL0 to 1, then:
+
[[#ReturnFromException]] updates the contents of the kernel stack frame with what the user provided in the TLS structure, sets TPIDR_EL0 to 1, then:
 
* if the provided error code is 0, gracefully pivots and returns from exception
 
* if the provided error code is 0, gracefully pivots and returns from exception
 
* if it is not, replays the exception and pass it to the KDebug (see above). One can pass 0x10001 to prevent process termination. If the process is attached, this also prevents crash-collection/termination (different from the exception handler behavior)
 
* if it is not, replays the exception and pass it to the KDebug (see above). One can pass 0x10001 to prevent process termination. If the process is attached, this also prevents crash-collection/termination (different from the exception handler behavior)
Line 2,602: Line 3,081:  
If an exception occurs from the above user handler, the entire exception handling process will repeat with the new exception.
 
If an exception occurs from the above user handler, the entire exception handling process will repeat with the new exception.
   −
Note that if a thread that wasn't faulting calls svcReturnFromException, it signals an "invalid syscall" exception
+
Note that if a thread that wasn't faulting calls [[#ReturnFromException]], it signals an "invalid syscall" exception
    
Note that [[SMC|IsDebugMode]] is not used during exception-handling, except for enabling printing a message to UART-A. This UART code causes a system-hang on retail (likely due to a loop that doesn't exit). This printing doesn't seem to run when the process is attached for debugging?
 
Note that [[SMC|IsDebugMode]] is not used during exception-handling, except for enabling printing a message to UART-A. This UART code causes a system-hang on retail (likely due to a loop that doesn't exit). This printing doesn't seem to run when the process is attached for debugging?

Navigation menu