Changes

Jump to navigation Jump to search
7,780 bytes added ,  10:03, 2 October 2019
We were lied to. Based on 5.0.0 info.
Line 44: Line 44:  
| 0x10 || [[#svcGetCurrentProcessorNumber]] || None || W0/X0=cpuid
 
| 0x10 || [[#svcGetCurrentProcessorNumber]] || None || W0/X0=cpuid
 
|-
 
|-
| 0x11 || svcSignalEvent || W0=wevent_handle || W0=result
+
| 0x11 || [[#svcSignalEvent]] || W0=wevent_handle || W0=result
 
|-
 
|-
| 0x12 || svcClearEvent || W0=wevent_or_revent_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
 
| 0x13 || [[#svcMapSharedMemory]] || W0=shmem_handle, X1=addr, X2=size, W3=perm || W0=result
Line 56: Line 56:  
| 0x16 || svcCloseHandle || W0=handle || W0=result
 
| 0x16 || svcCloseHandle || W0=handle || W0=result
 
|-
 
|-
| 0x17 || svcResetSignal || W0=revent_or_process_handle || W0=result
+
| 0x17 || [[#svcResetSignal]] || W0=revent_or_process_handle || W0=result
 
|-
 
|-
 
| 0x18 || [[#svcWaitSynchronization]] || X1=handles_ptr, W2=num_handles, X3=timeout
 
| 0x18 || [[#svcWaitSynchronization]] || X1=handles_ptr, W2=num_handles, X3=timeout
Line 184: Line 184:  
| 0x53 || [[#svcCreateInterruptEvent]] || X1=irq_num, W2=flag || W0=result, W1=handle
 
| 0x53 || [[#svcCreateInterruptEvent]] || X1=irq_num, W2=flag || W0=result, W1=handle
 
|-
 
|-
| 0x54 || [[#svcQueryPhysicalAddress]] || X1=addr || W0=result, X1=physaddr, X2=kerneladdr, X3=size
+
| 0x54 || [[#svcQueryPhysicalAddress]] || X1=addr || W0=result, X1=physaddr, X2=baseaddr, X3=size
 
|-
 
|-
| 0x55 || [[#svcQueryIoMapping]] || X1=physaddr, X2=size || W0=result, X1=virtaddr
+
| 0x55 || [[#svcQueryIoMapping]] || X1=physaddr, X2=size
 +
R0=size, R2=physaddr_lower32, R3=physaddr_upper32
 +
|| W0=result, X1=virtaddr
 
|-
 
|-
| 0x56 || [[#svcCreateDeviceAddressSpace]] || X1=dev_as_start_addr, X2=dev_as_end_addr || W0=result, W1=dev_as_handle
+
| 0x56 || [[#svcCreateDeviceAddressSpace]] || X1=dev_as_start_addr, X2=dev_as_end_addr
 +
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 || [[#svcAttachDeviceAddressSpace]] || W0=device, X1=dev_as_handle || W0=result
Line 194: Line 198:  
| 0x58 || [[#svcDetachDeviceAddressSpace]] || 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  
+
| 0x59 || [[#svcMapDeviceAddressSpaceByForce]] || W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr, W5=perm
 +
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 || 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
 +
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 || ||  
+
| 0x5B || svcMapDeviceAddressSpace || W1=dev_as_handle, W2=proc_handle, X3=dev_map_addr, X4=dev_as_size, X5=dev_as_addr, W6=perm
 +
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 || W0=result
+
| 0x5C || [[#svcUnmapDeviceAddressSpace]] || W0=dev_as_handle, W1=proc_handle, X2=dev_map_addr, X3=dev_as_size, X4=dev_as_addr
 +
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 || W0=size
+
| 0x5D || svcInvalidateProcessDataCache || W0=process_handle, X1=addr, X2=size
 +
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 +
|| W0=size
 
|-
 
|-
| 0x5E || svcStoreProcessDataCache || W0=process_handle, X1=addr, X2=size || W0=size
+
| 0x5E || svcStoreProcessDataCache || W0=process_handle, X1=addr, X2=size
 +
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 +
|| W0=size
 
|-
 
|-
| 0x5F || svcFlushProcessDataCache || W0=process_handle, X1=addr, X2=size || W0=size
+
| 0x5F || svcFlushProcessDataCache || W0=process_handle, X1=addr, X2=size
 +
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32
 +
|| W0=size
 
|-
 
|-
| 0x60 || svcDebugActiveProcess || X1=pid || W0=result, W1=debug_handle
+
| 0x60 || svcDebugActiveProcess || X1=pid
 +
R2=pid_lower32, R3=pid_upper32
 +
|| W0=result, W1=debug_handle
 
|-
 
|-
 
| 0x61 || svcBreakDebugProcess || W0=debug_handle || W0=result
 
| 0x61 || svcBreakDebugProcess || W0=debug_handle || W0=result
Line 224: Line 245:  
| 0x66 || svcGetThreadList || X1=tids_out_ptr, W2=max_out, W3=debug_handle_or_zero || W0=result, X1=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=thread_id, W3=[[#ThreadContextFlags]] || W0=result
+
| 0x67 || svcGetDebugThreadContext || 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]]
 +
|| W0=result
 
|-
 
|-
| 0x68 || svcSetDebugThreadContext || W0=debug_handle, X1=thread_id, X2=ThreadContext*, W3=[[#ThreadContextFlags]] || W0=result
+
| 0x68 || svcSetDebugThreadContext || 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]]
 +
|| W0=result
 
|-
 
|-
 
| 0x69 || svcQueryDebugProcessMemory || X0=[[#MemoryInfo]]*, X2=debug_handle, X3=addr || W0=result, W1=PageInfo
 
| 0x69 || svcQueryDebugProcessMemory || X0=[[#MemoryInfo]]*, X2=debug_handle, X3=addr || W0=result, W1=PageInfo
Line 234: Line 259:  
| 0x6B || svcWriteDebugProcessMemory || X0=debug_handle, X1=buffer*, X2=dst_addr, X3=size || W0=result
 
| 0x6B || svcWriteDebugProcessMemory || 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 || [[#svcSetHardwareBreakPoint]] || 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
 +
|| W0=result
 
|-
 
|-
| 0x6D || svcGetDebugThreadParam || X2=debug_handle, X3=thread_id, W4=[[#DebugThreadParam]] || W0=result, X1=out0, W2=out1
+
| 0x6D || svcGetDebugThreadParam || X2=debug_handle, X3=thread_id, W4=[[#DebugThreadParam]]
 +
R0=thread_id_lower32, R1=thread_id_upper32, R2=debug_handle, R3=[[#DebugThreadParam]]
 +
|| W0=result, X1=out0, W2=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 || W0=result, X1=out
+
| 0x6F || [5.0.0+] [[#svcGetSystemInfo]] || X1=info_id, X2=handle, X3=info_sub_id
 +
R1=info_sub_id_lower32, R2=info_id, R3=handle, R4=info_sub_id_upper32
 +
|| W0=result, X1=out
 +
R0=result, R1=out_lower32, R2=out_upper32
 
|-
 
|-
| 0x70 || svcCreatePort || W2=max_sessions, W3=is_light, X4=name_ptr || W0=result, W1=serverport_handle, W2=clientport_handle
+
| 0x70 || svcCreatePort || W2=max_sessions, W3=is_light, X4=name_ptr
 +
R0=name_ptr, R2=max_sessions, R3=is_light
 +
|| W0=result, W1=serverport_handle, W2=clientport_handle
 
|-
 
|-
 
| 0x71 || svcManageNamedPort || X1=name_ptr, W2=max_sessions || W0=result, W1=serverport_handle
 
| 0x71 || svcManageNamedPort || X1=name_ptr, W2=max_sessions || W0=result, W1=serverport_handle
Line 246: Line 281:  
| 0x72 || svcConnectToPort || W1=clientport_handle || W0=result, W1=session_handle
 
| 0x72 || svcConnectToPort || W1=clientport_handle || W0=result, W1=session_handle
 
|-
 
|-
| 0x73 || [[#svcSetProcessMemoryPermission]] || W0=process_handle, X1=addr, X2=size, W3=perm || W0=result
+
| 0x73 || [[#svcSetProcessMemoryPermission]] || 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
 +
|| W0=result
 
|-
 
|-
| 0x74 || [[#svcMapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size || W0=result
+
| 0x74 || [[#svcMapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
 +
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
 +
|| W0=result
 
|-
 
|-
| 0x75 || [[#svcUnmapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size || W0=result
+
| 0x75 || [[#svcUnmapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
 +
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
 +
|| W0=result
 
|-
 
|-
| 0x76 || [[#svcQueryProcessMemory]] || X0=meminfo_ptr, W2=process_handle, X3=addr || W0=result, W1=pageinfo
+
| 0x76 || [[#svcQueryProcessMemory]] || X0=meminfo_ptr, W2=process_handle, X3=addr
 +
R0=meminfo_ptr, R1=addr_lower32, R2=process_handle, R3=addr_upper32
 +
|| W0=result, W1=pageinfo
 
|-
 
|-
| 0x77 || [[#svcMapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size || W0=result
+
| 0x77 || [[#svcMapProcessCodeMemory]] || 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
 +
|| W0=result
 
|-
 
|-
| 0x78 || [[#svcUnmapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size || W0=result
+
| 0x78 || [[#svcUnmapProcessCodeMemory]] || 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
 +
|| W0=result
 
|-
 
|-
 
| 0x79 || [[#svcCreateProcess]] || X1=procinfo_ptr, X2=caps_ptr, W3=cap_num ||  W0=result, W1=process_handle
 
| 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
+
| 0x7A || svcStartProcess || 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
 +
|| W0=result
 
|-
 
|-
 
| 0x7B || svcTerminateProcess || W0=process_handle || W0=result
 
| 0x7B || svcTerminateProcess || W0=process_handle || W0=result
 
|-
 
|-
| 0x7C || [[#svcGetProcessInfo]] || W0=process_handle, W1=[[#ProcessInfoType]] || W0=result, X1=[[#ProcessState]]
+
| 0x7C || [[#svcGetProcessInfo]] || W0=process_handle, W1=[[#ProcessInfoType]]
 +
R1=process_handle, R2=[[#ProcessInfoType]]
 +
|| W0=result, X1=[[#ProcessState]]
 +
R0=result, R1=[[#ProcessState]]_lower32, R2=[[#ProcessState]]_upper32
 
|-
 
|-
 
| 0x7D || svcCreateResourceLimit || None || W0=result, W1=reslimit_handle  
 
| 0x7D || svcCreateResourceLimit || None || W0=result, W1=reslimit_handle  
 
|-
 
|-
| 0x7E || svcSetResourceLimitLimitValue || W0=reslimit_handle, W1=[[#LimitableResource]], X2=value || W0=result
+
| 0x7E || svcSetResourceLimitLimitValue || W0=reslimit_handle, W1=[[#LimitableResource]], X2=value
 +
R0=reslimit_handle, R1=[[#LimitableResource]], R2=value_lower32, R3=value_upper32
 +
|| W0=result
 
|-
 
|-
| 0x7F || [[#svcCallSecureMonitor]] || X0=smc_sub_id, X1,X2,X3,X4,X5,X6,X7=smc_args || X0,X1,X2,X3,X4,X5,X6,X7=result
+
| 0x7F || [[#svcCallSecureMonitor]] || X0=smc_sub_id, X1,X2,X3,X4,X5,X6,X7=smc_args
 +
R0=smc_sub_id, R1, R2, R3=smc_args
 +
|| X0,X1,X2,X3,X4,X5,X6,X7=result
 +
R0,R1,R2,R3=result
 
|}
 
|}
   Line 291: Line 348:  
Size must be a multiple of 0x200000 (2MB).
 
Size must be a multiple of 0x200000 (2MB).
   −
On success, the heap base-address (which is fixed by kernel, aslr'd) is written to OutAddr.
+
On success, the heap base-address (which is fixed by kernel, aslr'd, and always in the Heap memory region) is written to OutAddr.
   −
Uses current process pool partition.
+
Uses current process pool partition. The memory allocated counts towards the caller's process Memory ResourceLimit.
    
[2.0.0+] Size must be less than or equal to 4GB.
 
[2.0.0+] Size must be less than or equal to 4GB.
 +
 +
=== Result codes ===
 +
 +
'''0x0:''' Success.
 +
 +
'''0xCA01:''' Invalid size passed. It's either bigger than 4GB, or misaligned.
 +
 +
'''0xD001:''' Size is bigger than the Heap Region size.
 +
 +
'''0xCE01:''' KMemoryBlockAllocator slab allocator exhausted.
 +
 +
'''0xD401:''' The memory region is in an invalid state. Likely because a mapping was made in the heap region.
 +
 +
'''0x10801:''' Memory resource limit reached.
    
== svcSetMemoryPermission ==
 
== svcSetMemoryPermission ==
Line 320: Line 391:  
This can be used to move back and forth between ---, r-- and rw-.
 
This can be used to move back and forth between ---, r-- and rw-.
   −
== svcSetMemoryAttribute ==
+
=== Result codes ===
 +
 
 +
'''0x0:''' Success. The memory region was reprotected.
 +
 
 +
'''0xCC01:''' Unaligned address specified.
   −
<div style="display: inline-block;">
+
'''0xCA01:''' Unaligned or zero size specified.
{| class="wikitable" border="1"
+
 
 +
'''0xD401:''' The provided memory region does not fall within the userland address space.
 +
 
 +
'''0xD801:''' Invalid permission specified. Valid permissions are ---, r-- and rw-.
 +
 
 +
'''0xD401:''' The provided memory region was in an invalid state. The region must have the PermissionChangeAllowed bit set in its [[#MemoryState]], and must not have the IsBorrowed or IsUncached [[#MemoryAttribute]].
 +
 
 +
'''0xCE01:''' Kernel resource exhausted.
 +
 
 +
== svcSetMemoryAttribute ==
 +
 
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
 
! Argument || Type || Name
 
! Argument || Type || Name
Line 625: Line 712:  
Cpu-id is an integer in the range 0-3.
 
Cpu-id is an integer in the range 0-3.
   −
== svcMapSharedMemory ==
+
== svcSignalEvent ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 632: Line 719:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || Handle<SharedMemory> || MemHandle
+
| (In) W0 || Handle<WritableEvent> || Event
 
|-
 
|-
| (In) X1 || void* || Addr
+
| (Out) X0 || [[#Result]] || Result
|-
  −
| (In) X2 || u64 || Size
  −
|-
  −
| (In) W3 || [[#Permission]] || Permissions
  −
|-
  −
| (Out) W0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
Maps the block supplied by the handle. The required permissions are different for the process that created the handle and all other processes.
+
'''Description:''' Puts the given event in the signaled state.
 +
 
 +
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.
 +
 
 +
=== Result codes ===
 +
 
 +
'''0x0:''' Success. Event is now in signaled state.
   −
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.
+
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a WritableEvent.
   −
== svcCreateTransferMemory ==
+
== svcClearEvent ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 655: Line 744:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || void* || Addr
+
| (In) W0 || Handle<WritableEvent or ReadableEvent> || Event
 
|-
 
|-
| (In) X2 || u64 || Size
+
| (Out) X0 || [[#Result]] || Result
|-
+
|}
| (In) W3 || [[#Permission]] || Permissions
  −
|-
  −
| (Out) W0 || [[#Result]] || Ret
  −
|-
  −
| (Out) W1 || Handle<TransferMemory> || Handle
  −
|}
   
</div>
 
</div>
   −
This one reprotects the src block with perms you give it. It also sets bit0 into [[#MemoryAttribute]].
+
'''Description:''' Takes the given event out of the signaled state.
 +
 
 +
=== Result codes ===
 +
 
 +
'''0x0:''' Success, the event is now in the not-signaled state.
   −
Executable bit perm not allowed.
+
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a ReadableEvent nor a WritableEvent.
   −
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
+
'''0xFA01:''' The handle was not in a signaled state.
   −
== svcWaitSynchronization ==
+
== svcMapSharedMemory ==
    
<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 || R1 || Handle* || HandlesPtr
+
| (In) W0 || Handle<SharedMemory> || MemHandle
 
|-
 
|-
| (In) W2 || R2 || u64 || HandlesNum
+
| (In) X1 || void* || Addr
 
|-
 
|-
| (In) X3 || R0, R3 || u64 || Timeout
+
| (In) X2 || u64 || Size
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (In) W3 || [[#Permission]] || Permissions
 
|-
 
|-
| (Out) W1 || R1 || u64 || HandleIndex
+
| (Out) W0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Works with num_handles <= 0x40.
     −
When zero handles are passed, this will wait forever until either timeout or cancellation occurs.
+
Maps the block supplied by the handle. The required permissions are different for the process that created the handle and all other processes.
   −
Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.
+
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.
   −
=== Object types ===
+
== svcCreateTransferMemory ==
   −
'''KDebug:''' signals when there is a new [[#DebugEventInfo|DebugEvent]] (retrievable via [[#svcGetDebugEvent]]).
+
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) X1 || void* || Addr
 +
|-
 +
| (In) X2 || u64 || Size
 +
|-
 +
| (In) W3 || [[#Permission]] || Permissions
 +
|-
 +
| (Out) W0 || [[#Result]] || Ret
 +
|-
 +
| (Out) W1 || Handle<TransferMemory> || Handle
 +
|}
 +
</div>
   −
'''KClientPort:''' signals when the number of sessions is less than the maximum allowed.
+
This one reprotects the src block with perms you give it. It also sets bit0 into [[#MemoryAttribute]].
   −
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#svcGetProcessInfo]]).
+
Executable bit perm not allowed.
   −
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via svcSignalEvent.
+
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
   −
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#svcAcceptSession|accepted]].
+
== svcResetSignal ==
 
  −
'''KServerSession:''' signals when there is an incoming message waiting to be [[#svcReplyAndReceive|received]] or the pipe is closed.
  −
 
  −
'''KThread:''' signals when the thread has exited.
  −
 
  −
=== Result codes ===
  −
 
  −
'''0x0:''' Success. One of the objects was signaled before the timeout expired, or one of the objects is a Session with a closed remote. Handle index is updated to indicate which object signaled.
  −
 
  −
'''0x7601:''' Thread termination requested. Handle index is not updated.
  −
 
  −
'''0xe401:''' Invalid handle. Returned when one of the handles passed is invalid. Handle index is not updated.
  −
 
  −
'''0xe601:''' Invalid address. Returned when the handles pointer is not a readable address. 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.
  −
 
  −
'''0xee01:''' Too many handles. Returned when the number of handles passed is > 0x40.
  −
 
  −
== svcCancelSynchronization ==
      
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 736: Line 815:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || Handle<Thread> || Handle
+
| (In) W0 || Handle<ReadableEvent> or Handle<Process> || Handle
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
Line 742: Line 821:  
</div>
 
</div>
   −
If the referenced thread is currently in a synchronization call ([[#svcWaitSynchronization]], [[#svcReplyAndReceive]] or [[#svcReplyAndReceiveLight]]), that call will be interrupted and return 0xec01.
+
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.
If that thread is not currently executing such a synchronization call, the next call to a synchronization call will return 0xec01.
     −
This doesn't take force-pause (activity/debug pause) into account.
+
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.
    
=== Result codes ===
 
=== Result codes ===
   −
'''0x0:''' Success. The thread was either interrupted or has had its flag set.
+
'''0x0:''' Success. The signal was reset.
   −
'''0xe401:''' Invalid handle. The handle given was either invalid or not a thread handle.
+
'''0xE401:''' The handle is invalid or of the wrong type.
   −
== svcGetSystemTick ==
+
'''0xFA01:''' The handle was not signaled, or the process is in exited state, causing it to be permanently signaled.
 +
 
 +
== svcWaitSynchronization ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 760: Line 840:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (Out) X0 || R0, R1 || u64 || Ticks
+
| (In) X1 || R1 || Handle* || HandlesPtr
 +
|-
 +
| (In) W2 || R2 || u64 || HandlesNum
 +
|-
 +
| (In) X3 || R0, R3 || u64 || Timeout
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Ret
 +
|-
 +
| (Out) W1 || R1 || u64 || HandleIndex
 
|}
 
|}
 
</div>
 
</div>
 +
Works with num_handles <= 0x40.
   −
Returns the value of cntpct_el0.
+
When zero handles are passed, this will wait forever until either timeout or cancellation occurs.
 +
 
 +
Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.
   −
The frequency is 19200000 Hz (constant from official sw).
+
=== Object types ===
   −
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.
+
'''KDebug:''' signals when there is a new [[#DebugEventInfo|DebugEvent]] (retrievable via [[#svcGetDebugEvent]]).
   −
== svcSendSyncRequestWithUserBuffer ==
+
'''KClientPort:''' signals when the number of sessions is less than the maximum allowed.
   −
<div style="display: inline-block;">
+
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#svcGetProcessInfo]]).
{| class="wikitable" border="1"
+
 
|-
+
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via svcSignalEvent.
! Argument || Type || Name
+
 
|-
+
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#svcAcceptSession|accepted]].
| (In) X0 || void* || CmdPtr
+
 
|-
+
'''KServerSession:''' signals when there is an incoming message waiting to be [[#svcReplyAndReceive|received]] or the pipe is closed.
| (In) X1 || u64 || Size
  −
|-
  −
| (In) W2 || Handle<Session> || Handle
  −
|-
  −
| (Out) W0 || [[#Result]] || Ret
  −
|}
  −
</div>
     −
Size and CmdPtr must be 0x1000-aligned.
+
'''KThread:''' signals when the thread has exited.
    
=== Result codes ===
 
=== Result codes ===
   −
'''0x0:''' Success.
+
'''0x0:''' Success. One of the objects was signaled before the timeout expired, or one of the objects is a Session with a closed remote. Handle index is updated to indicate which object signaled.
   −
'''0xcc01:''' CmdPtr is not 0x1000-aligned.
+
'''0x7601:''' Thread termination requested. Handle index is not updated.
   −
'''0xca01:''' Size is not 0x1000-aligned.
+
'''0xe401:''' Invalid handle. Returned when one of the handles passed is invalid. Handle index is not updated.
   −
'''0xce01:''' KSessionRequest allocation failed (unlikely) or pointer buffer size exceeded.
+
'''0xe601:''' Invalid address. Returned when the handles pointer is not a readable address. Handle index is not updated.
   −
'''0xe401:''' Handles does not exist, or handle is not an instance of KClientSession.
+
'''0xea01:''' Timeout. Returned when no objects have been signaled within the timeout. Handle index is not updated.
   −
== svcBreak ==
+
'''0xec01:''' Interrupted. Returned when another thread uses [[#svcCancelSynchronization]] to cancel this thread. Handle index is not updated.
 +
 
 +
'''0xee01:''' Too many handles. Returned when the number of handles passed is > 0x40.
 +
 
 +
== svcCancelSynchronization ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 808: Line 896:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || u64 || Break Reason
+
| (In) W0 || Handle<Thread> || Handle
 
|-
 
|-
| (In) X1 || u64 ||
+
| (Out) W0 || [[#Result]] || Ret
|-
  −
| (In) X2 || u64 || Info
  −
|-
  −
| (Out) W0 || Result || 0 (Success)
   
|}
 
|}
 
</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).
+
If the referenced thread is currently in a synchronization call ([[#svcWaitSynchronization]], [[#svcReplyAndReceive]] or [[#svcReplyAndReceiveLight]]), 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.
 +
 
 +
This doesn't take force-pause (activity/debug pause) into account.
 +
 
 +
=== Result codes ===
   −
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.
+
'''0x0:''' Success. The thread was either interrupted or has had its flag set.
   −
Otherwise just return 0.
+
'''0xe401:''' Invalid handle. The handle given was either invalid or not a thread handle.
   −
== svcGetInfo ==
+
== svcGetSystemTick ==
    
<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) W1 || u32 || InfoId
+
| (Out) X0 || R0, R1 || u64 || Ticks
|-
  −
| (In) W2 || Handle || Handle
  −
|-
  −
| (In) X3 || u64 || InfoSubId
  −
|-
  −
| (Out) W0 || [[#Result]] || Ret
  −
|-
  −
| (Out) X1 || u64 || Out
   
|}
 
|}
 
</div>
 
</div>
<div style="display: inline-block; vertical-align:top;">
+
 
 +
Returns the value of cntpct_el0.
 +
 
 +
The frequency is 19200000 Hz (constant from official sw).
 +
 
 +
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.
 +
 
 +
== svcSendSyncRequestWithUserBuffer ==
 +
 
 +
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
 
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) R0 || u32 || InfoSubIdLower32
+
| (In) X0 || void* || CmdPtr
 
|-
 
|-
| (In) R1 || u32 || InfoId
+
| (In) X1 || u64 || Size
 
|-
 
|-
| (In) R2 || Handle || Handle
+
| (In) W2 || Handle<Session> || Handle
 
|-
 
|-
| (In) R3 || u32 || InfoSubIdUpper32
+
| (Out) W0 || [[#Result]] || Ret
|-
+
|}
| (Out) R0 || [[#Result]] || Ret
  −
|-
  −
| (Out) R1 || u32 || OutLower32
  −
|-
  −
| (Out) R2 || u32 || OutUpper32
  −
|}
   
</div>
 
</div>
    +
Size and CmdPtr must be 0x1000-aligned.
   −
{| class=wikitable
+
=== Result codes ===
! Handle type || Id0 || Id1 || Description
+
 
 +
'''0x0:''' Success.
 +
 
 +
'''0xcc01:''' CmdPtr is not 0x1000-aligned.
 +
 
 +
'''0xca01:''' Size is not 0x1000-aligned.
 +
 
 +
'''0xce01:''' KSessionRequest allocation failed (unlikely) or pointer buffer size exceeded.
 +
 
 +
'''0xe401:''' Handles does not exist, or handle is not an instance of KClientSession.
 +
 
 +
== svcBreak ==
 +
 
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 0 || 0 || AllowedCpuIdBitmask
+
! Argument || Type || Name
 
|-
 
|-
| Process || 1 || 0 || AllowedThreadPrioBitmask
+
| (In) X0 || u64 || Break Reason
 
|-
 
|-
| Process || 2 || 0 || AliasRegionBaseAddr
+
| (In) X1 || u64 ||
 
|-
 
|-
| Process || 3 || 0 || AliasRegionSize
+
| (In) X2 || u64 || Info
 
|-
 
|-
| Process || 4 || 0 || HeapRegionBaseAddr
+
| (Out) W0 || Result || 0 (Success)
 +
|}
 +
</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).
 +
 
 +
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.
 +
 
 +
== svcGetInfo ==
 +
 
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 5 || 0 || HeapRegionSize
+
! Argument || Type || Name
 
|-
 
|-
| Process || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
+
| (In) W1 || u32 || InfoId
 
|-
 
|-
| Process || 7 || 0 || TotalMemoryUsage. Total used size of codebin memory + main-thread stack + allocated heap.
+
| (In) W2 || Handle || Handle
 
|-
 
|-
| Zero    || 8 || 0 || IsCurrentProcessBeingDebugged
+
| (In) X3 || u64 || InfoSubId
 
|-
 
|-
| Zero    || 9 || 0 || Returns ResourceLimit handle for current process. Used by [[Process_Manager_services|PM]].
+
| (Out) W0 || [[#Result]] || Ret
 
|-
 
|-
| Zero    || 10 || -1, {current coreid} || IdleTickCount
+
| (Out) X1 || u64 || Out
 +
|}
 +
</div>
 +
<div style="display: inline-block; vertical-align:top;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Zero    || 11 || 0-3 || RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
+
! Argument || Type || Name
 
|-
 
|-
| Process || 12 || 0 || [2.0.0+] AddressSpaceBaseAddr
+
| (In) R0 || u32 || InfoSubIdLower32
 
|-
 
|-
| Process || 13 || 0 || [2.0.0+] AddressSpaceSize
+
| (In) R1 || u32 || InfoId
 
|-
 
|-
| Process || 14 || 0 || [2.0.0+] StackRegionBaseAddr
+
| (In) R2 || Handle || Handle
 
|-
 
|-
| Process || 15 || 0 || [2.0.0+] StackRegionSize
+
| (In) R3 || u32 || InfoSubIdUpper32
 
|-
 
|-
| Process || 16 || 0 || [3.0.0+] PersonalMmHeapSize
+
| (Out) R0 || [[#Result]] || Ret
 
|-
 
|-
| Process || 17 || 0 || [3.0.0+] PersonalMmHeapUsage
+
| (Out) R1 || u32 || OutLower32
 
|-
 
|-
| Process || 18 || 0 || [3.0.0+] TitleId
+
| (Out) R2 || u32 || OutUpper32
 +
|}
 +
</div>
 +
 
 +
 
 +
{| class=wikitable
 +
! Handle type || Id0 || Id1 || Description
 
|-
 
|-
| Zero    || 19 || 0 || [4.0.0-4.1.0] PrivilegedProcessId_LowerBound
+
| Process || 0 || 0 || AllowedCpuIdBitmask
 +
|-
 +
| Process || 1 || 0 || AllowedThreadPrioBitmask
 
|-
 
|-
| Zero    || 19 || 1 || [4.0.0-4.1.0] PrivilegedProcessId_UpperBound
+
| Process || 2 || 0 || AliasRegionBaseAddr
 
|-
 
|-
| Process || 20 || 0 || [5.0.0+] UserExceptionContextAddr
+
| Process || 3 || 0 || AliasRegionSize
 
|-
 
|-
| Process || 21 || 0 || [6.0.0+] TotalMemoryAvailableWithoutMmHeap
+
| Process || 4 || 0 || HeapRegionBaseAddr
 
|-
 
|-
| Process || 22 || 0 || [6.0.0+] TotalMemoryUsedWithoutMmHeap
+
| Process || 5 || 0 || HeapRegionSize
 
|-
 
|-
| 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 || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
|}
  −
 
  −
== svcMapPhysicalMemory ==
  −
This is like svcSetHeapSize except you can allocate heap at any address you'd like.
  −
 
  −
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>
  −
 
  −
=== Result codes ===
  −
 
  −
'''0xf201:''' No session waiting to be accepted
  −
 
  −
== svcReplyAndReceive ==
  −
 
  −
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Argument64 || Argument32 || Type || Name
+
| Process || 14 || 0 || [2.0.0+] StackRegionBaseAddr
 +
|-
 +
| Process || 15 || 0 || [2.0.0+] StackRegionSize
 +
|-
 +
| Process || 16 || 0 || [3.0.0+] PersonalMmHeapSize
 +
|-
 +
| Process || 17 || 0 || [3.0.0+] PersonalMmHeapUsage
 +
|-
 +
| Process || 18 || 0 || [3.0.0+] TitleId
 +
|-
 +
| 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+]
 
|-
 
|-
| (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.
+
== svcMapPhysicalMemory ==
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.
+
This is like svcSetHeapSize except you can allocate heap at any address you'd like.
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.
+
Uses current process pool partition.
   −
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.
+
== svcDumpInfo ==
   −
=== Result codes ===
+
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) None || ||
 +
|-
 +
| (Out) None || ||
 +
|}
 +
</div>
   −
'''0x0:''' Success. Either a session has an incoming message or a port has an incoming connection. HandleIndex is set appropriately.
+
Does nothing, just returns with registers set to all-zero.
   −
'''0xea01:''' Timeout. No handles were signalled before the timeout expired. HandleIndex is not updated.
+
== svcAcceptSession ==
   −
'''0xf601:''' Port remote dead. One of the sessions has been closed. HandleIndex is set appropriately.
+
<div style="display: inline-block;">
 
+
{| class="wikitable" border="1"
== svcMapPhysicalMemoryUnsafe ==
+
|-
Same as [[#svcMapPhysicalMemory]] except it always uses pool partition 0.
+
! Argument || Type || Name
 
+
|-
== svcCreateCodeMemory ==
+
| (In) W1 || Handle<Port> || Port
Takes an address range with backing memory to create the code memory object.
+
|-
 +
| (Out) W0 || [[#Result]] || Result
 +
|-
 +
| (Out) W1 || Handle<ServerSession> || Session
 +
|}
 +
</div>
   −
The memory is initially memset to 0xFF after being locked.
+
=== Result codes ===
   −
== svcControlCodeMemory ==
+
'''0xf201:''' No session waiting to be accepted
Maps the backing memory for a Code memory object into the current process.
     −
For [[#CodeMemoryOperation|CodeMemoryOperation_MapOwner]], memory permission must be RW-.
+
== svcReplyAndReceive ==
 
  −
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;">
Line 1,022: Line 1,126:  
! Argument64 || Argument32 || Type || Name
 
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X1 || R2, R3 || u64 || RegAddr
+
| (In) W1 || R1 || *Handle<Port or ServerSession> || Handles
 
|-
 
|-
| (In) W2 || R0 || u64 || RwMask
+
| (In) W2 || R2 || u32 || NumHandles
 +
|-
 +
| (In) W3 || R3 || Handle<ServerSession> || ReplyTarget
 
|-
 
|-
| (In) W3 || R1 || u64 || InValue
+
| (In) X4 || R0, R4 || u64 (nanoseconds) || Timeout
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Result
 
|-
 
|-
| (Out) W1 || R1 || u64 || OutValue
+
| (Out) W1 || R1 || u32 || HandleIndex
 
|}
 
|}
 
</div>
 
</div>
   −
Read/write IO registers with a hardcoded whitelist. Input address is physical-address and must be aligned to 4.
+
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.
   −
rw_mask is 0 for reading and 0xffffffff for writing. You can also write individual bits by using a mask value.
+
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.
   −
You can only write to registers inside physical pages 0x70019000 (MC), 0x7001C000 (MC0), 0x7001D000 (MC1), and they all share the same whitelist.
+
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.
   −
The whitelist is same for writing as for reading.
+
=== Result codes ===
   −
The whitelist is:
+
'''0x0:''' Success. Either a session has an incoming message or a port has an incoming connection. HandleIndex is set appropriately.
   −
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
+
'''0xea01:''' Timeout. No handles were signalled before the timeout expired. HandleIndex is not updated.
    +
'''0xf601:''' Port remote dead. One of the sessions has been closed. HandleIndex is set appropriately.
   −
[2.0.0+] Whitelist was extended with 0x4c4, 0x4c8, 0x4cc, 0x584, 0x588, 0x58c.
+
== svcMapPhysicalMemoryUnsafe ==
 +
Same as [[#svcMapPhysicalMemory]] except it always uses pool partition 0.
   −
[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).
+
== 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.
   −
[4.0.0+] Access to the Memory Controller (0x70019000) also uses smcReadWriteRegister.
+
For [[#CodeMemoryOperation|CodeMemoryOperation_MapOwner]], memory permission must be RW-.
   −
Here is the whitelist imposed by that SMC, relative to the start of the PMC registers:
+
For [[#CodeMemoryOperation|CodeMemoryOperation_MapSlave]], memory permission must be R-- or R-X.
   −
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
+
Operations [[#CodeMemoryOperation|CodeMemoryOperation_UnmapOwner/CodeMemoryOperation_UnmapSlave]] unmap memory that was previously mapped this way.
   −
Here is the whitelist imposed by smcReadWriteRegister (checked in addition to the whitelist in svcReadWriteRegister), relative to the start of the MC registers:
+
This allows one "secure JIT" process to map the code memory as RW-, and the other "slave" process to map it R-X.
   −
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
+
[5.0.0+] Error 0xE401 is now returned when the process owner of the Code memory object is the same as the current process.
   −
== svcCreateSharedMemory ==
+
== svcReadWriteRegister ==
    
<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) W1 || u64 || Size
+
| (In) X1 || R2, R3 || u64 || RegAddr
 
|-
 
|-
| (In) W2 || [[#Permission]] || LocalPerm
+
| (In) W2 || R0 || u64 || RwMask
 
|-
 
|-
| (In) W3 || [[#Permission]] || RemotePerm
+
| (In) W3 || R1 || u64 || InValue
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W1 || Handle<SharedMemory> || MemHandle
+
| (Out) W1 || R1 || u64 || OutValue
 
|}
 
|}
 
</div>
 
</div>
   −
Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.
+
Read/write IO registers with a hardcoded whitelist. Input address is physical-address and must be aligned to 4.
   −
Allocates memory from the current process' pool partition.
+
rw_mask is 0 for reading and 0xffffffff for writing. You can also write individual bits by using a mask value.
   −
== svcMapTransferMemory ==
+
You can only write to registers inside physical pages 0x70019000 (MC), 0x7001C000 (MC0), 0x7001D000 (MC1), and they all share the same whitelist.
   −
<div style="display: inline-block;">
+
The whitelist is same for writing as for reading.
{| class="wikitable" border="1"
  −
|-
  −
! Argument || Type || Name
  −
|-
  −
| (In) X0 || Handle<TransferMemory> || MemHandle
  −
|-
  −
| (In) X1 || void* || Addr
  −
|-
  −
| (In) X2 || u64 || Size
  −
|-
  −
| (In) W3 || [[#Permission]] || Permissions
  −
|-
  −
| (Out) W0 || [[#Result]] || Ret
  −
|}
  −
</div>
     −
The newly mapped pages will have [[#MemoryState]] type 0xE.
+
The whitelist is:
   −
You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error.
+
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
   −
== svcUnmapTransferMemory ==
+
 
 +
[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;">
Line 1,114: Line 1,230:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || Handle<TransferMemory> || MemHandle
+
| (In) W1 || u64 || Size
 
|-
 
|-
| (In) X1 || void* || Addr
+
| (In) W2 || [[#Permission]] || LocalPerm
 
|-
 
|-
| (In) X2 || u64 || Size
+
| (In) W3 || [[#Permission]] || RemotePerm
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
 +
|-
 +
| (Out) W1 || Handle<SharedMemory> || MemHandle
 
|}
 
|}
 
</div>
 
</div>
   −
Size must match size given in map syscall, otherwise there's an invalid-size error.
+
Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.
    +
Allocates memory from the current process' pool partition.
   −
== svcCreateInterruptEvent ==
+
== svcMapTransferMemory ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 1,134: Line 1,253:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || u64 || IrqNum
+
| (In) X0 || Handle<TransferMemory> || MemHandle
 +
|-
 +
| (In) X1 || void* || Addr
 +
|-
 +
| (In) X2 || u64 || Size
 
|-
 
|-
| (In) W2 || bool || Flags
+
| (In) W3 || [[#Permission]] || Permissions
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
|-
  −
| (Out) W1 || Handle<ReadableEvent> || ReadableEventHandle
   
|}
 
|}
 
</div>
 
</div>
   −
Create 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.
+
The newly mapped pages will have [[#MemoryState]] type 0xE.
   −
=== Result codes ===
+
You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error.
   −
'''0x0:''' Success.
+
== svcUnmapTransferMemory ==
 
  −
'''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;">
Line 1,168: Line 1,276:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || u64 || Addr
+
| (In) X0 || Handle<TransferMemory> || MemHandle
 
|-
 
|-
| (Out) W0 || [[#Result]]|| Ret
+
| (In) X1 || void* || Addr
|-
  −
| (Out) X1 || u64 || PhysAddr
  −
|-
  −
| (Out) X2 || u64 || KernelAddr
  −
|-
  −
| (Out) X3 || u64 || Size
  −
|}
  −
</div>
  −
 
  −
== svcQueryIoMapping ==
  −
 
  −
<div style="display: inline-block;">
  −
{| class="wikitable" border="1"
  −
|-
  −
! Argument || Type || Name
  −
|-
  −
| (In) X1 || u64 || PhysAddr
   
|-
 
|-
 
| (In) X2 || u64 || Size
 
| (In) X2 || u64 || Size
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
|-
  −
| (Out) X1 || void* || VirtAddr
   
|}
 
|}
 
</div>
 
</div>
   −
'''Description:''' Returns a virtual address mapped to a given IO range.
+
Size must match size given in map syscall, otherwise there's an invalid-size error.
 +
 
   −
== svcCreateDeviceAddressSpace ==
+
== svcCreateInterruptEvent ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 1,206: Line 1,296:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X1 || u64 || StartAddr
+
| (In) X1 || u64 || IrqNum
 
|-
 
|-
| (In) X2 || u64 || EndAddr
+
| (In) W2 || bool || Flags
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W1 || Handle<DeviceAddressSpace> || AddressSpaceHandle
+
| (Out) W1 || Handle<ReadableEvent> || ReadableEventHandle
 
|}
 
|}
 
</div>
 
</div>
   −
'''Description:''' Creates a virtual address space for binding device address spaces and returns a handle.
+
Create 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.
   −
dev_as_start_addr is normally set to 0 and dev_as_end_addr is normally set to 0xFFFFFFFF.
     −
== svcAttachDeviceAddressSpace ==
+
== svcQueryPhysicalAddress ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 1,227: Line 1,330:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || [[#DeviceName]] || DeviceId
+
| (In) X1 || u64 || Addr
 +
|-
 +
| (Out) W0 || [[#Result]]|| Ret
 +
|-
 +
| (Out) X1 || u64 || PhysAddr
 
|-
 
|-
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (Out) X2 || u64 || BaseAddr
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) X3 || u64 || Size
 
|}
 
|}
 
</div>
 
</div>
   −
'''Description:''' Attaches a device address space to a [[#DeviceName|device]].
+
'''Description:''' Query the physical address of a virtual address. Will always fetch the lowest page-aligned mapping that contains the provided physical address.
   −
== svcDetachDeviceAddressSpace ==
+
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"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) X1 || R2, R3 || u64 || PhysAddr
 
|-
 
|-
| (In) W0 || [[#DeviceName]] || DeviceId
+
| (In) X2 || R0 || u64 || Size
 
|-
 
|-
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) X1 || R1 || void* || VirtAddr
 
|}
 
|}
 
</div>
 
</div>
   −
'''Description:''' Detaches a device address space from a [[#DeviceName|device]].
+
'''Description:''' Returns a virtual address mapped to a given IO range.
   −
== svcMapDeviceAddressSpaceByForce ==
+
== svcCreateDeviceAddressSpace ==
    
<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) W0 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (In) X1 || R2, R3 || u64 || StartAddr
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| (In) X2 || R0, R1 || u64 || EndAddr
 
|-
 
|-
| (In) X2 || void* || SrcAddr
+
| (Out) W0 || R0 || [[#Result]] || Ret
|-
  −
| (In) X3 || u64 || DeviceAsSize
  −
|-
  −
| (In) X4 || u64 || DeviceAsAddr
   
|-
 
|-
| (In) W5 || [[#Permission]] || Permissions
+
| (Out) W1 || R1 || Handle<DeviceAddressSpace> || AddressSpaceHandle
|-
  −
| (Out) W0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
'''Description:''' Maps an attached device address space to an userspace address.
+
'''Description:''' Creates a virtual address space for binding device address spaces and returns a handle.
   −
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]]).
+
dev_as_start_addr is normally set to 0 and dev_as_end_addr is normally set to 0xFFFFFFFF.
   −
The userspace destination address must have the [[SVC#MemoryState|MapDeviceAllowed]] bit set. Bit [[SVC#MemoryAttribute|IsDeviceMapped]] will be set after mapping.
+
== svcAttachDeviceAddressSpace ==
 
  −
== svcMapDeviceAddressSpaceAligned ==
      
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 1,290: Line 1,393:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W0 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (In) W0 || [[#DeviceName]] || DeviceId
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
 
|-
 
|-
| (In) X2 || void* || SrcAddr
+
| (Out) W0 || [[#Result]] || Ret
 +
|}
 +
</div>
 +
 
 +
'''Description:''' Attaches a device address space to a [[#DeviceName|device]].
 +
 
 +
== svcDetachDeviceAddressSpace ==
 +
 
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| (In) X3 || u64 || DeviceAsSize
+
! Argument || Type || Name
 
|-
 
|-
| (In) X4 || u64 || DeviceAsAddr
+
| (In) W0 || [[#DeviceName]] || DeviceId
 
|-
 
|-
| (In) W5 || [[#Permission]] || Permissions
+
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
Line 1,306: Line 1,418:  
</div>
 
</div>
   −
'''Description:''' Maps an attached device address space to an userspace address.
+
'''Description:''' Detaches a device address space from a [[#DeviceName|device]].
   −
Same as [[#svcMapDeviceAddressSpaceByForce]], but the userspace destination address must have the [[SVC#MemoryState|MapDeviceAlignedAllowed]] bit set instead.
+
== svcMapDeviceAddressSpaceByForce ==
 
  −
== svcUnmapDeviceAddressSpace ==
      
<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) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
 
|-
 
|-
| (In) W0 || Handle<DeviceAddressSpace> || DeviceAsHandle
+
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| (In) X2 || R2, R3 || void* || SrcAddr
 
|-
 
|-
| (In) X2 || void* || SrcAddr
+
| (In) X3 || R4 || u64 || DeviceAsSize
 
|-
 
|-
| (In) X3 || u64 || DeviceAsSize
+
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
 
|-
 
|-
| (In) X4 || u64 || DeviceAsAddr
+
| (In) W5 || R7 || [[#Permission]] || Permissions
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
   −
'''Description:''' Unmaps an attached device address space from an userspace address.
+
'''Description:''' Maps an attached device address space to an userspace address.
   −
== svcContinueDebugEvent ==
+
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]]).
   −
=== Result codes ===
+
The userspace destination address must have the [[SVC#MemoryState|MapDeviceAllowed]] bit set. Bit [[SVC#MemoryAttribute|IsDeviceMapped]] will be set after mapping.
   −
'''0x0:''' Success. The process has been resumed.
+
== svcMapDeviceAddressSpaceAligned ==
 
  −
'''0xe401:''' Invalid debug handle.
  −
 
  −
'''0xf401:''' Process has debug events queued or is already running.
  −
 
  −
== svcGetSystemInfo ==
      
<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) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
 +
|-
 +
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X1 || u64 || InfoId
+
| (In) X2 || R2, R3 || void* || SrcAddr
 
|-
 
|-
| (In) W2 || Handle || Handle
+
| (In) X3 || R4 || u64 || DeviceAsSize
 
|-
 
|-
| (In) X3 || u64 || InfoSubId
+
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (In) W5 || R7 || [[#Permission]] || Permissions
 
|-
 
|-
| (Out) X1 || u64 || Out
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
   −
{| class=wikitable
+
'''Description:''' Maps an attached device address space to an userspace address.
! Handle type || Id0 || Id1 || Description
+
 
|-
+
Same as [[#svcMapDeviceAddressSpaceByForce]], but the userspace destination address must have the [[SVC#MemoryState|MapDeviceAlignedAllowed]] bit set instead.
| Zero    || 0 || 0 || TotalMemorySize_Application
+
 
|-
+
== svcUnmapDeviceAddressSpace ==
| 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
  −
|-
  −
|}
  −
 
  −
== svcSetProcessMemoryPermission ==
      
<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) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
 
|-
 
|-
| (In) W0 || Handle<Process> || ProcessHandle
+
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X1 || u64 || Addr
+
| (In) X2 || R2, R3 || void* || SrcAddr
 
|-
 
|-
| (In) X2 || u64 || Size
+
| (In) X3 || R4 || u64 || DeviceAsSize
 
|-
 
|-
| (In) W3 || void* || Perm
+
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
   −
This sets the memory permissions for the specified memory with the supplied process handle.
+
'''Description:''' Unmaps an attached device address space from an userspace address.
 +
 
 +
== svcContinueDebugEvent ==
 +
 
 +
=== Result codes ===
 +
 
 +
'''0x0:''' Success. The process has been resumed.
 +
 
 +
'''0xe401:''' Invalid debug handle.
   −
This throws an error(0xD801) when the input perm is >0x5, hence -WX and RWX are not allowed.
+
'''0xf401:''' Process has debug events queued or is already running.
   −
== svcMapProcessMemory ==
+
== svcGetSystemInfo ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 1,417: Line 1,516:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || u64 || DstAddr
+
| (In) X1 || u64 || InfoId
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| (In) W2 || Handle || Handle
 
|-
 
|-
| (In) X2 || void* || SrcAddr
+
| (In) X3 || u64 || InfoSubId
 
|-
 
|-
| (In) X3 || u64 || Size
+
| (Out) W0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) X1 || u64 || Out
 
|}
 
|}
 
</div>
 
</div>
   −
Maps the src address from the supplied process handle into the current process.
+
{| class=wikitable
 
+
! Handle type || Id0 || Id1 || Description
This allows mapping code and rodata with RW- permission.
+
|-
 
+
| Zero    || 0 || 0 || TotalMemorySize_Application
== svcUnmapProcessMemory ==
+
|-
 
+
| Zero    || 0 || 1 || TotalMemorySize_Applet
<div style="display: inline-block;">
+
|-
{| class="wikitable" border="1"
+
| Zero    || 0 || 2 || TotalMemorySize_System
 
|-
 
|-
! Argument || Type || Name
+
| Zero    || 0 || 3 || TotalMemorySize_SystemUnsafe
 
|-
 
|-
| (In) X0 || void* || DstAddr
+
| Zero    || 1 || 0 || CurrentMemorySize_Application
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| Zero    || 1 || 1 || CurrentMemorySize_Applet
 
|-
 
|-
| (In) X2 || u64 || SrcAddr
+
| Zero    || 1 || 2 || CurrentMemorySize_System
 
|-
 
|-
| (In) X3 || u64 || Size
+
| Zero    || 1 || 3 || CurrentMemorySize_SystemUnsafe
 +
|-
 +
| Zero    || 2 || 0 || PrivilegedProcessId_LowerBound
 +
|-
 +
| Zero    || 2 || 1 || PrivilegedProcessId_UpperBound
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
   
|}
 
|}
</div>
     −
Unmaps what was mapped by [[#svcMapProcessMemory]].
+
== svcSetProcessMemoryPermission ==
 
  −
== svcQueryProcessMemory ==
      
<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 || [[#MemoryInfo]]* || MemInfoPtr
+
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) W2 || Handle<Process> || ProcessHandle
+
| (In) X1 || R2, R3 || u64 || Addr
 
|-
 
|-
| (In) X3 || u64 || Addr
+
| (In) X2 || R1, R4 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (In) W3 || R5 || void* || Perm
 
|-
 
|-
| (Out) W1 || PageInfo || PageInfo
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
   −
Equivalent to [[#svcQueryMemory]] except takes a process handle.
+
This sets the memory permissions for the specified memory with the supplied process handle.
 
+
 
== svcMapProcessCodeMemory ==
+
This throws an error(0xD801) when the input perm is >0x5, hence -WX and RWX are not allowed.
 
+
 
<div style="display: inline-block;">
+
== svcMapProcessMemory ==
{| class="wikitable" border="1"
+
 
|-
+
<div style="display: inline-block;">
! Argument || Type || Name
+
{| class="wikitable" border="1"
|-
+
|-
| (In) W0 || Handle<Process> || ProcessHandle
+
! Argument64 || Argument32 || Type || Name
|-
+
|-
| (In) X1 || u64 || DstAddr
+
| (In) X0 || R0 || u64 || DstAddr
|-
+
|-
| (In) X2 || u64 || SrcAddr
+
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
+
|-
| (In) X3 || u64 || Size
+
| (In) X2 || R2, R3 || void* || SrcAddr
|-
+
|-
| (Out) W0 || [[#Result]] || Ret
+
| (In) X3 || R4 || u64 || Size
|}
+
|-
</div>
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
+
|}
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.
+
</div>
 
+
 
== svcUnmapProcessCodeMemory ==
+
Maps the src address from the supplied process handle into the current process.
 
+
 
<div style="display: inline-block;">
+
This allows mapping code and rodata with RW- permission.
{| class="wikitable" border="1"
+
 
|-
+
== svcUnmapProcessMemory ==
! Argument || Type || Name
+
 
|-
+
<div style="display: inline-block;">
| (In) W0 || Handle<Process> || ProcessHandle
+
{| class="wikitable" border="1"
|-
+
|-
| (In) X1 || u64 || DstAddr
+
! Argument64 || Argument32 || Type || Name
|-
+
|-
| (In) X2 || u64 || SrcAddr
+
| (In) X0 || R0 || void* || DstAddr
|-
+
|-
| (In) X3 || u64 || Size
+
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
+
|-
| (Out) W0 || [[#Result]] || Ret
+
| (In) X2 || R2, R3 || u64 || SrcAddr
 +
|-
 +
| (In) X3 || R4 || u64 || Size
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Ret
 +
|}
 +
</div>
 +
 
 +
Unmaps what was mapped by [[#svcMapProcessMemory]].
 +
 
 +
== svcQueryProcessMemory ==
 +
 
 +
<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]] || Ret
 +
|-
 +
| (Out) W1 || R1 || PageInfo || PageInfo
 +
|}
 +
</div>
 +
 
 +
Equivalent to [[#svcQueryMemory]] except takes a process handle.
 +
 
 +
== svcMapProcessCodeMemory ==
 +
 
 +
<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>
 +
 
 +
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.
 +
 
 +
== svcUnmapProcessCodeMemory ==
 +
 
 +
<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>
 
</div>
Line 1,561: Line 1,727:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 +
|-
 +
| (In) W0 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) W0 || Handle<Process> || ProcessHandle
+
| (In) W1 || R2 || [[#ProcessInfoType]] || InfoType
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W1 || [[#ProcessState]] || State
+
| (Out) X1 || R1, R2 || [[#ProcessState]] || State
 
|}
 
|}
 
</div>
 
</div>
Line 1,578: Line 1,746:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || u64 || [[SMC#ID_0|Function ID]]
+
| (In) X0 || R0 || u64 || [[SMC#ID_0|Function ID]]
 
|-
 
|-
| (In) X1-X7 || u64 || SMC sub-arguments
+
| (In) X1-X7 || R1-R3 || u64 || SMC sub-arguments
 
|-
 
|-
| (Out) X0 || [[SMC#Errors|SMC Result]] || Result of SMC
+
| (Out) X0 || R0 || [[SMC#Errors|SMC Result]] || Result of SMC
 
|-
 
|-
| (Out) X1-X7 || u64 || SMC sub-output
+
| (Out) X1-X7 || R1-R3 || u64 || SMC sub-output
 
|}
 
|}
 
</div>
 
</div>
Line 1,614: Line 1,782:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) W0 || u32 || hardware_breakpoint_id
+
| (In) W0 || R0 || u32 || hardware_breakpoint_id
 
|-
 
|-
| (In) W1 || u64 || flags
+
| (In) X1 || R2, R3 || u64 || flags
 
|-
 
|-
| (In) W2 || u64 || value
+
| (In) X2 || R1, R4 || u64 || value
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Line 1,922: Line 2,090:  
== MemoryState ==
 
== MemoryState ==
 
{| class=wikitable
 
{| class=wikitable
! Bits || Description
+
! Bits || Description || Meaning
 
|-
 
|-
| 7-0 || Type
+
| 7-0 || Type ||
 
|-
 
|-
| 8 || [[#svcSetMemoryPermission|PermissionChangeAllowed]]
+
| 8 || [[#svcSetMemoryPermission|PermissionChangeAllowed]] ||
 
|-
 
|-
| 9 || ForceReadWritableByDebugSyscalls
+
| 9 || ForceReadWritableByDebugSyscalls || Allows using [[#svcWriteDebugProcessMemory]] on segments mapped read-only.
 
|-
 
|-
| 10 || IpcSendAllowed
+
| 10 || IpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=0.
 
|-
 
|-
| 11 || NonDeviceIpcSendAllowed
+
| 11 || NonDeviceIpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=1.
 
|-
 
|-
| 12 || NonSecureIpcSendAllowed
+
| 12 || NonSecureIpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=3.
 
|-
 
|-
| 14 || [[#svcSetProcessMemoryPermission|ProcessPermissionChangeAllowed]]
+
| 14 || [[#svcSetProcessMemoryPermission|ProcessPermissionChangeAllowed]] ||
 
|-
 
|-
| 15 || [[#svcMapMemory|MapAllowed]]
+
| 15 || [[#svcMapMemory|MapAllowed]] ||
 
|-
 
|-
| 16 || [[#svcUnmapProcessCodeMemory|UnmapProcessCodeMemoryAllowed]]
+
| 16 || [[#svcUnmapProcessCodeMemory|UnmapProcessCodeMemoryAllowed]] ||
 
|-
 
|-
| 17 || [[#svcCreateTransferMemory|TransferMemoryAllowed]]
+
| 17 || [[#svcCreateTransferMemory|TransferMemoryAllowed]] ||
 
|-
 
|-
| 18 || [[#svcQueryPhysicalAddress|QueryPhysicalAddressAllowed]]
+
| 18 || [[#svcQueryPhysicalAddress|QueryPhysicalAddressAllowed]] ||
 
|-
 
|-
| 19 || MapDeviceAllowed ([[#svcMapDeviceAddressSpace]] and [[#svcMapDeviceAddressSpaceByForce]])
+
| 19 || MapDeviceAllowed ([[#svcMapDeviceAddressSpace]] and [[#svcMapDeviceAddressSpaceByForce]]) ||
 
|-
 
|-
| 20 || [[#svcMapDeviceAddressSpaceAligned|MapDeviceAlignedAllowed]]
+
| 20 || [[#svcMapDeviceAddressSpaceAligned|MapDeviceAlignedAllowed]] ||
 
|-
 
|-
| 21 || [[#svcSendSyncRequestWithUserBuffer|IpcBufferAllowed]]
+
| 21 || [[#svcSendSyncRequestWithUserBuffer|IpcBufferAllowed]] ||
 
|-
 
|-
| 22 || IsPoolAllocated/IsReferenceCounted
+
| 22 || IsPoolAllocated/IsReferenceCounted || The physical memory blocks backing this region are refcounted.
 
|-
 
|-
| 23 || [[#svcMapProcessMemory|MapProcessAllowed]]
+
| 23 || [[#svcMapProcessMemory|MapProcessAllowed]] ||
 
|-
 
|-
| 24 || [[#svcSetMemoryAttribute|AttributeChangeAllowed]]
+
| 24 || [[#svcSetMemoryAttribute|AttributeChangeAllowed]] ||
 
|-
 
|-
| 25 || [4.0.0+] CodeMemoryAllowed
+
| 25 || [4.0.0+] [[#svcCreateCodeMemory|CodeMemoryAllowed]] ||
 
|}
 
|}
  
151

edits

Navigation menu