Difference between revisions of "SVC"

From Nintendo Switch Brew
Jump to navigation Jump to search
Line 933: Line 933:
  
 
== svcMapDeviceAddressSpaceByForce ==
 
== svcMapDeviceAddressSpaceByForce ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Device as Handle</code>
 +
|-
 +
| (In) W1 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X2 || u64 || <code>Device Map Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Device as Size</code>
 +
|-
 +
| (In) X4 || u64 || <code>Device as Addr</code>
 +
|-
 +
| (In) W5 || u64 || <code>Permissions</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
'''Description:''' Maps an attached device address space to an userspace address.
 
'''Description:''' Maps an attached device address space to an userspace address.
  
Line 940: Line 962:
  
 
== svcMapDeviceAddressSpaceAligned ==
 
== svcMapDeviceAddressSpaceAligned ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Device as Handle</code>
 +
|-
 +
| (In) W1 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X2 || u64 || <code>Device Map Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Device as Size</code>
 +
|-
 +
| (In) X4 || u64 || <code>Device as Addr</code>
 +
|-
 +
| (In) W5 || u64 || <code>Permissions</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
'''Description:''' Maps an attached device address space to an userspace address.
 
'''Description:''' Maps an attached device address space to an userspace address.
  
Line 945: Line 989:
  
 
== svcUnmapDeviceAddressSpace ==
 
== svcUnmapDeviceAddressSpace ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Device as Handle</code>
 +
|-
 +
| (In) W1 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X2 || u64 || <code>Device Map Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Device as Size</code>
 +
|-
 +
| (In) X4 || u64 || <code>Device as Addr</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
'''Description:''' Unmaps an attached device address space from an userspace address.
 
'''Description:''' Unmaps an attached device address space from an userspace address.
  
 
== svcMapProcessMemory ==
 
== svcMapProcessMemory ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X0 || u64 || <code>Src Addr</code>
 +
|-
 +
| (In) W1 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X2 || u64 || <code>Dest Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Size</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
Maps the src address from the supplied process handle into the current process.
 
Maps the src address from the supplied process handle into the current process.
  
Line 953: Line 1,035:
  
 
== svcUnmapProcessMemory ==
 
== svcUnmapProcessMemory ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X1 || u64 || <code>Dest Addr</code>
 +
|-
 +
| (In) X2 || u64 || <code>Src Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Size</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
Unmaps what was mapped by [[#svcMapProcessMemory]].
 
Unmaps what was mapped by [[#svcMapProcessMemory]].
  
 
== svcQueryProcessMemory ==
 
== svcQueryProcessMemory ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X0 || u64 || <code>Meminfo Pointer</code>
 +
|-
 +
| (In) W2 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X3 || u64 || <code>Addr</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|-
 +
| (Out) W1 || PageInfo || <code>Page Info</code>
 +
|}
 +
</div>
 +
 
Equivalent to [[#svcQueryMemory]] except takes a process handle.
 
Equivalent to [[#svcQueryMemory]] except takes a process handle.
  
 
== svcMapProcessCodeMemory ==
 
== svcMapProcessCodeMemory ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X1 || u64 || <code>Dest Addr</code>
 +
|-
 +
| (In) X2 || u64 || <code>Src Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Size</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
Takes a process handle, and maps normal heap in that process as executable code in that process. Used when loading NROs.
 
Takes a process handle, and maps normal heap in that process as executable code in that process. Used when loading NROs.
  
 
== svcUnmapProcessCodeMemory ==
 
== svcUnmapProcessCodeMemory ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Process Handle</code>
 +
|-
 +
| (In) X1 || u64 || <code>Dest Addr</code>
 +
|-
 +
| (In) X2 || u64 || <code>Src Addr</code>
 +
|-
 +
| (In) X3 || u64 || <code>Size</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|}
 +
</div>
 +
 
Unmaps what was mapped by [[#svcMapProcessCodeMemory]].
 
Unmaps what was mapped by [[#svcMapProcessCodeMemory]].
  
 
== svcCreateProcess ==
 
== svcCreateProcess ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X1 || u64 || <code>ProcInfo Pointer</code>
 +
|-
 +
| (In) X2 || u64 || <code>Capabilities Pointer</code>
 +
|-
 +
| (In) X3 || u64 || <code>Capibility Num</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|-
 +
| (Out) W1 || u64 || <code>Process Handle</code>
 +
|}
 +
</div>
 +
 
Takes a [[#CreateProcessInfo]] as input.
 
Takes a [[#CreateProcessInfo]] as input.
  
 
== svcGetProcessInfo ==
 
== svcGetProcessInfo ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || u64 || <code>Process Handle</code>
 +
|-
 +
| (Out) W0 || [[#Result]] || <code>Ret</code>
 +
|-
 +
| (Out) W1 || [[#ProcessState|| <code>Process State</code>
 +
|}
 +
</div>
 +
 
Returns an enum with value 0-7.
 
Returns an enum with value 0-7.
  

Revision as of 11:49, 14 October 2017


System calls

Id Name In Out
0x1 #svcSetHeapSize W1=size W0=result, X1=outaddr
0x2 #svcSetMemoryPermission X0=addr, X1=size, W2=prot W0=result
0x3 #svcSetMemoryAttribute X0=addr, X1=size, W2=state0, W3=state1 W0=result
0x4 #svcMapMemory X0=dstaddr, X1=srcaddr, X2=size W0=result
0x5 #svcUnmapMemory X0=dstaddr, X1=srcaddr, X2=size W0=result
0x6 #svcQueryMemory X0=MemoryInfo*, X2=addr W0=result, W1=PageInfo
0x7 #svcExitProcess None
0x8 #svcCreateThread X1=entry, X2=arg, X3=stacktop, W4=prio, W5=processor_id W0=result, W1=handle
0x9 #svcStartThread W0=thread_handle W0=result
0xA #svcExitThread None
0xB #svcSleepThread X0=nano W0=result
0xC #svcGetThreadPriority W1=thread_handle W0=result, W1=prio
0xD #svcSetThreadPriority W0=thread_handle, W1=prio W0=result
0xE #svcGetThreadCoreMask W2=thread_handle W0=result, W1=out, X2=out
0xF #svcSetThreadCoreMask W0=thread_handle, W1=in, X2=in2 W0=result
0x10 #svcGetCurrentProcessorNumber None W0/X0=cpuid
0x11 svcSignalEvent W0=wevent_handle W0=result
0x12 svcClearEvent W0=wevent_or_revent_handle W0=result
0x13 #svcMapSharedMemory W0=shmem_handle, X1=addr, X2=size, W3=perm W0=result
0x14 svcUnmapSharedMemory W0=shmem_handle, X1=addr, X2=size W0=result
0x15 #svcCreateTransferMemory X1=addr, X2=size, W3=perm W0=result, W1=tmem_handle
0x16 svcCloseHandle W0=handle W0=result
0x17 svcResetSignal W0=revent_or_process_handle W0=result
0x18 #svcWaitSynchronization X1=handles_ptr, W2=num_handles. X3=timeout W0=result, W1=handle_idx
0x19 svcCancelSynchronization W0=thread_handle W0=result
0x1A svcArbitrateLock W0=cur_thread_handle, X1=ptr, W2=req_thread_handle
0x1B svcArbitrateUnlock X0=ptr
0x1C svcWaitProcessWideKeyAtomic X0=ptr0, X1=ptr, W2=thread_handle, X3=timeout W0=result
0x1D svcSignalProcessWideKey X0=ptr, W1=value W0=result
0x1E svcGetSystemTick None X0={value of cntpct_el0}
0x1F svcConnectToNamedPort X1=port_name_str W0=result, W1=handle
0x20 svcSendSyncRequestLight W0=light_session_handle, X1=? W0=result
0x21 svcSendSyncRequest X0=normal_session_handle W0=result
0x22 #svcSendSyncRequestWithUserBuffer X0=cmdbufptr, X1=size, X2=handle W0=result
0x23 svcSendAsyncRequestWithUserBuffer X1=cmdbufptr, X2=size, X3=handle W0=result, W1=event_handle
0x24 svcGetProcessId W0=thread_or_process_or_debug_handle W0=result, X1=pid
0x25 svcGetThreadId W0=thread_handle W0=result, X1=out
0x26 svcBreak X0,X1,X2=info ?
0x27 svcOutputDebugString X0=str, X1=size W0=result
0x28 svcReturnFromException X0=result
0x29 #svcGetInfo X1=info_id, X2=handle, X3=info_sub_id W0=result, X1=out
0x2A svcFlushEntireDataCache None None
0x2B svcFlushDataCache X0=addr, X1=size W0=result
0x2C [3.0.0+] svcMapPhysicalMemory
0x2D [3.0.0+] svcUnmapPhysicalMemory
0x2F svcGetLastThreadInfo None W0=result, W1,W2,W3,W4=unk, W5=truncated_u64, W6=bool
0x30 svcGetResourceLimitLimitValue W1=reslimit_handle, W2=#LimitableResource W0=result, X1=value
0x31 svcGetResourceLimitCurrentValue W1=reslimit_handle, W2=#LimitableResource W0=result, X1=value
0x32 svcSetThreadActivity W0=thread_handle, W1=bool W0=result
0x33 svcGetThreadContext3 W0=thread_handle, W1=#ThreadContext* W0=result
0x3C svcDumpInfo
0x40 svcCreateSession W2=is_light, X3=? W0=result, W1=client_handle, W2=server_handle
0x41 svcAcceptSession W1=port_handle W0=result, W1=session_handle
0x42 svcReplyAndReceiveLight W0=light_session_handle W0=result, W1,W2,W3,W4,W5,W6,W7=out
0x43 svcReplyAndReceive X1=ptr_handles, W2=num_handles, X3=replytarget_handle(0=none), X4=timeout W0=result, W1=handle_idx
0x44 svcReplyAndReceiveWithUserBuffer X1=buf, X2=sz, X3=ptr_handles, W4=num_handles, X5=replytarget_handle(0=none), X6=timeout W0=result, W1=handle_idx
0x45 svcCreateEvent None W0=result, W1=client_handle ?, W2=server_handle ?
0x4D svcSleepSystem None None
0x4E #svcReadWriteRegister X1=reg_addr, W2=rw_mask, W3=in_val W0=result, W1=out_val
0x4F svcSetProcessActivity W0=process_handle, W1=bool W0=result
0x50 #svcCreateSharedMemory W1=size, W2=myperm, W3=otherperm W0=result, W1=shmem_handle
0x51 #svcMapTransferMemory X0=tmem_handle, X1=addr, X2=size, W3=perm W0=result
0x52 #svcUnmapTransferMemory W0=tmemhandle, X1=addr, X2=size W0=result
0x53 svcCreateInterruptEvent X1=irq_id, W2=flag W0=result, W1=handle
0x54 #svcQueryPhysicalAddress X1=addr W0=result, X1=out0, X2=out1, X3=out2
0x55 #svcQueryIoMapping X1=physaddr, X2=size W0=result, X1=virtaddr
0x56 #svcCreateDeviceAddressSpace X1=dev_as_start_addr, X2=dev_as_end_addr W0=result, W1=dev_as_handle
0x57 #svcAttachDeviceAddressSpace W0=device, X1=dev_as_handle W0=result
0x58 #svcDetachDeviceAddressSpace W0=device, X1=dev_as_handle W0=result
0x59 #svcMapDeviceAddressSpaceByForce W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr, W5=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 W0=result
0x5B svcMapDeviceAddressSpace
0x5C #svcUnmapDeviceAddressSpace W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr W0=result
0x5D svcInvalidateProcessDataCache W0=process_handle, X1=addr, X2=size W0=size
0x5E svcStoreProcessDataCache W0=process_handle, X1=addr, X2=size W0=size
0x5F svcFlushProcessDataCache W0=process_handle, X1=addr, X2=size W0=size
0x60 svcDebugActiveProcess X1=pid W0=result, W1=debug_handle
0x61 svcBreakDebugProcess W0=debug_handle W0=result
0x62 svcTerminateDebugProcess W0=debug_handle W0=result
0x63 svcGetDebugEvent X0=DebugEventInfo*, W1=debug_handle W0=result
0x64 svcContinueDebugEvent W0=debug_handle, W1=flags, X2=? W0=result
0x65 svcGetProcessList 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
0x67 svcGetDebugThreadContext X0=ThreadContext*, X1=debug_handle, X2=?, W3=? W0=result
0x68 svcSetDebugThreadContext
0x69 svcQueryDebugProcessMemory 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
0x6B svcWriteDebugProcessMemory X0=debug_handle, X1=buffer*, X2=dst_addr, X3=size W0=result
0x6C svcSetHardwareBreakPoint
0x6D svcGetDebugThreadParam X2=debug_handle, X3=thread_id, W4=DebugThreadParam W0=result, X1=out0, W2=out1
0x70 svcCreatePort
0x71 svcManageNamedPort X1=name_ptr, W2=max_sessions(?) W0=result, W1=serverport_handle
0x72 svcConnectToPort W1=clientport_handle W0=result, W1=session_handle
0x73 svcSetProcessMemoryPermission X0=addr, X1=size, W2=perm W0=result
0x74 #svcMapProcessMemory X0=srcaddr, W1=process_handle, X2=dstaddr, X3=size W0=result
0x75 #svcUnmapProcessMemory W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size W0=result
0x76 #svcQueryProcessMemory X0=meminfo_ptr, W2=process_handle, X3=addr W0=result, W1=pageinfo
0x77 #svcMapProcessCodeMemory W0=process_handle, X2=dstaddr, X2=srcaddr, X3=size W0=result
0x78 #svcUnmapProcessCodeMemory W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size W0=result
0x79 #svcCreateProcess 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 W0=result
0x7B svcTerminateProcess W0=process_handle W0=result
0x7C #svcGetProcessInfo W0=process_handle W0=result, X1=#ProcessState
0x7D svcCreateResourceLimit None W0=result, W1=reslimit_handle
0x7E svcSetResourceLimitLimitValue W0=reslimit_handle, W1=#LimitableResource, X2=value W0=result
0x7F svcCallSecureMonitor

svcSetHeapSize

Argument Type Name
(In) W1 u64 Size
(Out) W0 #Result Ret
(Out) X1 u64 OutAddr

Description: Set the process heap to a given Size. It can both extend and shrink the heap.

Size must be a multiple of 0x2000000.

On success, the heap base-address (which is fixed by kernel, aslr'd) is written to OutAddr.

[2.0.0+] Size must be less than 0x18000000.

svcSetMemoryPermission

Argument Type Name
(In) X0 u64 Addr
(In) X1 u64 Size
(In) W2 u64 Prot
(Out) W0 #Result Ret

Description: Change permission of page-aligned memory region.

Bit2 of permission (exec) is not allowed. Setting write-only is not allowed either (bit1).

This can be used to move back and forth between ---, r-- and rw-.

svcSetMemoryAttribute

Argument Type Name
(In) X0 u64 Addr
(In) X1 u64 Size
(In) W2 u64 State0
(In) W3 u64 State1
(Out) W0 #Result Ret

Description: Change attribute of page-aligned memory region.

This is used to turn on/off caching for a given memory area. Useful when talking to devices such as the GPU.

What happens "under the hood" is the "Memory Attribute Indirection Register" index is changed from 2 to 3 in the MMU descriptor.

State0 State1 Action
0 0 Clear bit3 in #MemoryAttribute.
8 0 Clear bit3 in #MemoryAttribute.
8 8 Set bit3 in #MemoryAttribute.

svcMapMemory

Argument Type Name
(In) X0 u64 Dst
(In) X1 u64 Src
(In) X2 u64 Size
(Out) W0 #Result Ret

Description: Maps a memory range into a different range.

Mainly used for adding guard pages around stack.

Source range gets reprotected to --- (it can no longer be accessed), and bit0 is set in the source #MemoryAttribute.

If dstaddr >= LowerTreshold, the dst-range is enforced to be within the process' "MapRegion". Code can get the range of this region from #svcGetInfo id0=2,3.

In this case, the mapped memory will have state 0x5C3C0B.

As long as (dstaddr+size) < LowerThreshold, then you can map anywhere but the mapped memory will have state 0x482907 instead.

LowerTreshold is 0x80000000 for 36-bit address spaces, and 0x40000000 for 32-bit ones.

[2.0.0+] Support for the 0x482907 mappings outside the "MapRegion" were removed.

svcUnmapMemory

Argument Type Name
(In) X0 u64 Dst
(In) X1 u64 Src
(In) X2 u64 Size
(Out) W0 #Result Ret

Description: Unmaps a region that was previously mapped with #svcMapMemory.

It's possible to unmap ranges partially, you don't need to unmap the entire range "in one go".

The srcaddr/dstaddr must match what was given when the pages were originally mapped.

svcQueryMemory

Argument Type Name
(In) X0 MemoryInfo* Mem Info
(In) X2 u64 Addr
(Out) W0 #Result Ret
(Out) W1 PageInfo Page Info

Description: Query information about an address. Will always fetch the lowest page-aligned mapping that contains the provided address.

Outputs a #MemoryInfo struct.

svcExitProcess

Argument Type Name
(In) None
(Out) None

Description: Exits the current process.

svcCreateThread

Argument Type Name
(In) X1 u64 Entry
(In) X2 u64 Arg
(In) X3 u64 Stack Top
(In) W4 u64 Priority
(In) W5 u64 Processor ID
(Out) W0 #Result Ret
(Out) W1 Handle Handle

Description: Create a thread in the current process.

Processor_id must be 0,1,2,3 or -2, where -2 uses the default cpuid for process.

svcStartThread

Argument Type Name
(In) W0 u64 Handle
(Out) None

Description: Starts the thread for the provided handle.

svcExitThread

Argument Type Name
(In) None
(Out) None

Description: Exits the current thread.

svcSleepThread

Argument Type Name
(In) X1 u64 Nano
(Out) W0 #Result Ret

Description: Sleep for a specified amount of time, or yield thread.

Setting nano=0 means "yield thread".

svcGetThreadPriority

Argument Type Name
(In) W1 u64 Handle
(Out) W0 #Result Ret
(Out) W1 u64 Priority

Description: Get priority of provided thread handle.

svcSetThreadPriority

Argument Type Name
(In) W0 u64 Handle
(In) W1 u64 Priority
(Out) W0 #Result Ret

Description: Set priority of provided thread handle.

Priority is a number 0-0x3F. Lower value means higher priority.

svcGetThreadCoreMask

Argument Type Name
(In) W2 u64 Handle
(Out) W0 #Result Ret
(Out) W1 u64 Out
(Out) X2 u64 Out

Description: Get affinity mask of provided thread handle.

svcSetThreadCoreMask

Argument Type Name
(In) W0 u64 Handle
(In) W1 u64 In
(In) X2 u64 In
(Out) W0 #Result Ret

Description: Set affinity mask of provided thread handle.

svcGetCurrentProcessorNumber

Argument Type Name
(In) None
(Out) W0/X0 u64 CPU ID

Description: Get which cpu is executing the current thread.

Cpu-id is an integer in the range 0-3.

svcMapSharedMemory

Argument Type Name
(In) W0 u64 Mem Block Handle
(In) X1 u64 Addr
(In) X2 u64 Size
(In) W3 u64 Permissions
(Out) W0 #Result Ret

Maps the block supplied by the handle. The required permissions are different for the process that created the handle and all other processes.

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.

svcCreateTransferMemory

Argument Type Name
(In) X1 u64 Addr
(In) X2 u64 Size
(In) W3 u64 Permissions
(Out) W0 #Result Ret
(Out) W1 u64 Handle

This one reprotects the src block with perms you give it. It also sets bit0 into #MemoryAttribute.

Executable bit perm not allowed.

Closing all handles automatically causes the bit0 in #MemoryAttribute to clear, and the permission to reset.

svcWaitSynchronization

Argument Type Name
(In) X1 u64 Handles Pointer
(In) W2 u64 Number of Handles
(In) X3 u64 Timeout
(Out) W0 #Result Ret
(Out) W1 u64 Handle Index

Works with num_handles <= 0x40, error on num_handles == 0.

Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.

svcSendSyncRequestWithUserBuffer

Argument Type Name
(In) X0 u64 Command Buffer Pointer
(In) X1 u64 Size
(In) X2 u64 Handle
(Out) W0 #Result Ret

Size must be 0x1000-aligned.

svcBreak

Argument Type Name
(In) X0 u64
(In) X1 u64
(In) X2 u64 Info
(Out) ? ? ?

When used on retail where inx0 bit31 is clear, the system will throw a fatal-error. Otherwise when bit31 is set, it will return 0.

svcGetInfo

Argument Type Name
(In) X1 u64 Info ID
(In) X2 u64 Handle
(In) X3 u64 Info Sub ID
(Out) W0 #Result Ret
(Out) X1 u64 Out
Handle type Id0 Id1 Description
Process 0 0 AllowedCpuIdBitmask
Process 1 0 AllowedThreadPrioBitmask
Process 2 0 ReservedMapRegionBaseAddress
Process 3 0 ReservedMapRegionSize
Process 4 0 ReservedHeapRegionBaseAddress
Process 5 0 ReservedHeapRegionSize
Process 6 0 TotalMemoryUsage
Process 7 0 TotalHeapUsage
Zero 8 0 IsCurrentProcessBeingDebugged
Zero 9 0 Returns ResourceLimit handle for current process. Used by PM.
Zero 10 -1, {current coreid} Unknown. Output data changes each time this SVC is used. Global and core-specific tick-count?
Zero 11 0-3 RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
Process 12 0 [2.0.0+] AddressSpaceStart
Process 13 0 [2.0.0+] AddressSpaceSize
Process 14 0 [2.0.0+] NewReservedRegionStartAddr
Process 15 0 [2.0.0+] NewReservedRegionSize
Process 18 0 [3.0.0+] Title-id.
Thread 0xF0000002 0 Performance counter related.

svcDumpInfo

Argument Type Name
(In) None
(Out) None

Does nothing, just returns with registers set to all-zero.

svcReadWriteRegister

Argument Type Name
(In) X1 u64 Reg Addr
(In) W2 u64 RW Mask
(In) W3 u64 In Value
(Out) W0 #Result Ret
(Out) W1 u64 Out Value

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.

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).

svcCreateSharedMemory

Argument Type Name
(In) W1 u64 Size
(In) W2 u64 My Permissions
(In) W3 u64 Other Permissions
(Out) W0 #Result Ret
(Out) W1 u64 Shared Memory Handle

Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.

svcMapTransferMemory

Argument Type Name
(In) X0 u64 Transfer Mem Handle
(In) X1 u64 Addr
(In) X2 u64 Size
(In) W3 u64 Permissions
(Out) W0 #Result Ret

The newly mapped pages will have #MemoryState type 0xE.

You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error.

svcUnmapTransferMemory

Argument Type Name
(In) X0 u64 Transfer Mem Handle
(In) X1 u64 Addr
(In) X2 u64 Size
(Out) W0 #Result Ret

Size must match size given in map syscall, otherwise there's an invalid-size error.

svcQueryPhysicalAddress

Argument Type Name
(In) X1 u64 Addr
(Out) W0 #Result Ret
(Out) X1 u64 Out0
(Out) X2 u64 Out1
(Out) X3 u64 Out2

The inverse operation of #svcQueryIoMapping.

svcQueryIoMapping

Argument Type Name
(In) X1 u64 Physical Address
(In) X2 u64 Size
(Out) W0 #Result Ret
(Out) X1 u64 Virtual Address

Description: Returns a virtual address mapped to a given IO range.

svcCreateDeviceAddressSpace

Argument Type Name
(In) X1 u64 Device as Start Addr
(In) X2 u64 Device as End Addr
(Out) W0 #Result Ret
(Out) W1 u64 Device as Handle

Description: Creates a virtual address space for binding device address spaces and returns a handle.

dev_as_start_addr is normally set to 0 and dev_as_end_addr is normally set to 0xFFFFFFFF.

svcAttachDeviceAddressSpace

Argument Type Name
(In) W0 u64 Device
(In) X1 u64 Device as Handle
(Out) W0 #Result Ret

Description: Attaches a device address space to a device.

svcDetachDeviceAddressSpace

Argument Type Name
(In) W0 u64 Device
(In) X1 u64 Device as Handle
(Out) W0 #Result Ret

Description: Detaches a device address space from a device.

svcMapDeviceAddressSpaceByForce

Argument Type Name
(In) W0 u64 Device as Handle
(In) W1 u64 Process Handle
(In) X2 u64 Device Map Addr
(In) X3 u64 Device as Size
(In) X4 u64 Device as Addr
(In) W5 u64 Permissions
(Out) W0 #Result Ret

Description: 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 #svcCreateDeviceAddressSpace).

The userspace destination address must have the MapDeviceAllowed bit set. Bit IsDeviceMapped will be set after mapping.

svcMapDeviceAddressSpaceAligned

Argument Type Name
(In) W0 u64 Device as Handle
(In) W1 u64 Process Handle
(In) X2 u64 Device Map Addr
(In) X3 u64 Device as Size
(In) X4 u64 Device as Addr
(In) W5 u64 Permissions
(Out) W0 #Result Ret

Description: Maps an attached device address space to an userspace address.

Same as #svcMapDeviceAddressSpaceByForce, but the userspace destination address must have the MapDeviceAlignedAllowed bit set instead.

svcUnmapDeviceAddressSpace

Argument Type Name
(In) W0 u64 Device as Handle
(In) W1 u64 Process Handle
(In) X2 u64 Device Map Addr
(In) X3 u64 Device as Size
(In) X4 u64 Device as Addr
(Out) W0 #Result Ret

Description: Unmaps an attached device address space from an userspace address.

svcMapProcessMemory

Argument Type Name
(In) X0 u64 Src Addr
(In) W1 u64 Process Handle
(In) X2 u64 Dest Addr
(In) X3 u64 Size
(Out) W0 #Result Ret

Maps the src address from the supplied process handle into the current process.

This allows mapping code and rodata with RW- permission.

svcUnmapProcessMemory

Argument Type Name
(In) W0 u64 Process Handle
(In) X1 u64 Dest Addr
(In) X2 u64 Src Addr
(In) X3 u64 Size
(Out) W0 #Result Ret

Unmaps what was mapped by #svcMapProcessMemory.

svcQueryProcessMemory

Argument Type Name
(In) X0 u64 Meminfo Pointer
(In) W2 u64 Process Handle
(In) X3 u64 Addr
(Out) W0 #Result Ret
(Out) W1 PageInfo Page Info

Equivalent to #svcQueryMemory except takes a process handle.

svcMapProcessCodeMemory

Argument Type Name
(In) W0 u64 Process Handle
(In) X1 u64 Dest Addr
(In) X2 u64 Src Addr
(In) X3 u64 Size
(Out) W0 #Result Ret

Takes a process handle, and maps normal heap in that process as executable code in that process. Used when loading NROs.

svcUnmapProcessCodeMemory

Argument Type Name
(In) W0 u64 Process Handle
(In) X1 u64 Dest Addr
(In) X2 u64 Src Addr
(In) X3 u64 Size
(Out) W0 #Result Ret

Unmaps what was mapped by #svcMapProcessCodeMemory.

svcCreateProcess

Argument Type Name
(In) X1 u64 ProcInfo Pointer
(In) X2 u64 Capabilities Pointer
(In) X3 u64 Capibility Num
(Out) W0 #Result Ret
(Out) W1 u64 Process Handle

Takes a #CreateProcessInfo as input.

svcGetProcessInfo

Argument Type Name
(In) W0 u64 Process Handle
(Out) W0 #Result Ret
(Out) W1 [[#ProcessState Process State

Returns an enum with value 0-7.

Debugging

[2.0.0+] Exactly 6 debug SVCs require that IsDebugMode is non-zero. Error 0x4201 is returned otherwise.

  • svcBreakDebugProcess
  • svcContinueDebugEvent
  • svcWriteDebugProcessMemory
  • svcSetDebugThreadContext
  • svcTerminateDebugProcess
  • svcSetHardwareBreakPoint

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.

Structures

DeviceName

Value Name
0 DeviceName_AFI
1 DeviceName_AVPC
2 DeviceName_DC
3 DeviceName_DCB
4 DeviceName_HC
5 DeviceName_HDA
6 DeviceName_ISP2
7 DeviceName_MSENCNVENC
8 DeviceName_NV
9 DeviceName_NV2
10 DeviceName_PPCS
11 DeviceName_SATA
12 DeviceName_VI
13 DeviceName_VIC
14 DeviceName_XUSB_HOST
15 DeviceName_XUSB_DEV
16 DeviceName_TSEC
17 DeviceName_PPCS1
18 DeviceName_DC1
19 DeviceName_SDMMC1A
20 DeviceName_SDMMC2A
21 DeviceName_SDMMC3A
22 DeviceName_SDMMC4A
23 DeviceName_ISP2B
24 DeviceName_GPU
25 DeviceName_GPUB
26 DeviceName_PPCS2
27 DeviceName_NVDEC
28 DeviceName_APE
29 DeviceName_SE
30 DeviceName_NVJPG
31 DeviceName_HC1
32 DeviceName_SE1
33 DeviceName_AXIAP
34 DeviceName_ETR
35 DeviceName_TSECB
36 DeviceName_TSEC1
37 DeviceName_TSECB1
38 DeviceName_NVDEC1

LimitableResource

Value Name
0 LimitableResource_Memory
1 LimitableResource_Threads
2 LimitableResource_Events
3 LimitableResource_TransferMemories
4 LimitableResource_Sessions

CreateProcessInfo

Offset Length Bits Description
0 12 ProcessName (doesn't have to be null-terminated)
0xC 4
0x10 8 TitleId
0x18 8 CodeAddr
0x20 4 CodeNumPages
0x24 4 MmuFlags
Bit0 Is64bit
Bit3-1 #AddressSpaceType
Bit4
Bit5 EnableAslr
Bit6 IsSystem
0x28 4 ResourceLimitHandle
0x2C 4

AddressSpaceType

Type Name Width Description
0 Normal_32Bit 32
1 Normal_36Bit 36
2 WithoutMap_32Bit 32 Appears to be missing map region [?]
3 [2.0.0+] Normal_39Bit 39

MemoryInfo

Offset Length Description
0 8 BaseAddress
8 8 Size
0x10 4 MemoryType: lower 8 bits of #MemoryState
0x14 4 #MemoryAttribute
0x18 4 Permission (bit0: R, bit1: W, bit2: X)
0x1C 4 DeviceRefCount
0x20 4 IpcRefCount
0x24 4 Padding: always zero

MemoryAttribute

Bits Description
0 IsBorrowed
1 IsIpcMapped: when IpcRefCount > 0.
2 IsDeviceMapped: when DeviceRefCount > 0.
3 IsUncached

MemoryState

Bits Description
7-0 Type
8 PermissionChangeAllowed
9 IsUserWritable [?]
10 IpcSendAllowed_Type0
11 IpcSendAllowed_Type3
12 IpcSendAllowed_Type1
14 ProcessPermissionChangeAllowed
15 MapAllowed
16 UnmapProcessCodeMemoryAllowed
17 TransferMemoryAllowed
19 MapDeviceAllowed (#svcMapDeviceAddressSpace and #svcMapDeviceAddressSpaceByForce)
20 MapDeviceAlignedAllowed
21 IpcBufferAllowed
22 IsPoolAllocated/IsReferenceCounted
23 MapProcessAllowed
24 AttributeChangeAllowed
Value Type Meaning
0x00000000 Unmapped
0x00002001 IO Mapped by kernel capability parsing in #svcCreateProcess.
0x00042002 Normal Mapped by kernel capability parsing in #svcCreateProcess.
0x00DC7E03 Code static Mapped during #svcCreateProcess.
0x01FEBD04 Code Transition from 0xDC7E03 performed by #svcSetProcessMemoryPermission.
0x017EBD05 Heap Mapped using #svcSetHeapSize.
0x00402006 Shared memory block Mapped using #svcMapSharedMemory.
0x00482907 [1.0.0] Weird mapped memory Mapped using #svcMapMemory.
0x00DD7E08 Module code static Mapped using #svcMapProcessCodeMemory.
0x01FFBD09 Module code mutable Transition from 0xDD7E08 performed by #svcSetProcessMemoryPermission.
0x005C3C0A IPC buffers IPC buffers with descriptor flags=0.
0x005C3C0B Mapped memory Mapped using #svcMapMemory.
0x0040200C Thread local storage Mapped during #svcCreateThread.
0x015C3C0D Isolated transfer memory Mapped using #svcMapTransferMemory when the owning process has perm=0.
0x005C380E Transfer memory Mapped using #svcMapTransferMemory when the owning process has perm!=0.
0x0040380F Process memory Mapped using #svcMapProcessMemory.
0x00000010 Reserved
0x005C3811 IPC buffers IPC buffers with descriptor flags=1.
0x004C2812 IPC buffers IPC buffers with descriptor flags=3.
0x00002013 Kernel per-thread stack Mapped in kernel during #svcCreateThread.

Exception handling

There is userland code for handling exceptions, however this doesn't seem to be executed on retail mode.

When a usermode exception occurs, it jumps to the main code binary entrypoint (main_binary_address + 0 == _start).

During normal boot _start is invoked with X0=0 and X1=main_thread_handle (triggering normal crt0 setup). During an usermode exception _start is invoked with X0=exception_info0_ptr and X1=exception_info1_ptr instead.

The _start method determines whether to boot normally or handle an exception if X0 is set to 0 or not.