Changes

Jump to navigation Jump to search
5,312 bytes added ,  09:58, 20 September 2019
Link resetsignal to doc.
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 273: Line 273:  
R0=result, R1=out_lower32, R2=out_upper32
 
R0=result, R1=out_lower32, R2=out_upper32
 
|-
 
|-
| 0x70 || svcCreatePort || W2=max_sessions, W3=is_light, X4=name_ptr || 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 279: 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 324: 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 352: Line 390:     
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-.
 +
 +
=== Result codes ===
 +
 +
'''0x0:''' Success. The memory region was reprotected.
 +
 +
'''0xCC01:''' Unaligned address specified.
 +
 +
'''0xCA01:''' Unaligned or zero size specified.
 +
 +
'''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 ==
 
== svcSetMemoryAttribute ==
Line 658: 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 665: 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
 +
|}
 +
</div>
 +
 
 +
'''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.
 +
 
 +
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a WritableEvent.
 +
 
 +
== svcClearEvent ==
 +
 
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| (In) X2 || u64 || Size
+
! Argument || Type || Name
 
|-
 
|-
| (In) W3 || [[#Permission]] || Permissions
+
| (In) W0 || Handle<WritableEvent or ReadableEvent> || Event
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) X0 || [[#Result]] || Result
 
|}
 
|}
 
</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:''' Takes the given event out of the signaled state.
 +
 
 +
=== Result codes ===
 +
 
 +
'''0x0:''' Success, the event is now in the not-signaled state.
 +
 
 +
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a ReadableEvent nor a WritableEvent.
   −
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.
+
'''0xFA01:''' The handle was not in a signaled state.
   −
== svcCreateTransferMemory ==
+
== svcMapSharedMemory ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 687: Line 766:  
|-
 
|-
 
! Argument || Type || Name
 
! Argument || Type || Name
 +
|-
 +
| (In) W0 || Handle<SharedMemory> || MemHandle
 
|-
 
|-
 
| (In) X1 || void* || Addr
 
| (In) X1 || void* || Addr
Line 695: Line 776:  
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (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]].
+
Maps the block supplied by the handle. The required permissions are different for the process that created the handle and all other processes.
   −
Executable bit perm not allowed.
+
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.
   −
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
+
== svcCreateTransferMemory ==
 
  −
== svcWaitSynchronization ==
      
<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) X1 || void* || Addr
 
|-
 
|-
| (In) W2 || R2 || u64 || HandlesNum
+
| (In) X2 || u64 || Size
 
|-
 
|-
| (In) X3 || R0, R3 || u64 || Timeout
+
| (In) W3 || [[#Permission]] || Permissions
 
|-
 
|-
| (Out) W0 || R0 || [[#Result]] || Ret
+
| (Out) W0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W1 || R1 || u64 || HandleIndex
+
| (Out) W1 || Handle<TransferMemory> || Handle
 
|}
 
|}
 
</div>
 
</div>
Works with num_handles <= 0x40.
     −
When zero handles are passed, this will wait forever until either timeout or cancellation occurs.
+
This one reprotects the src block with perms you give it. It also sets bit0 into [[#MemoryAttribute]].
   −
Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.
+
Executable bit perm not allowed.
   −
=== Object types ===
+
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
   −
'''KDebug:''' signals when there is a new [[#DebugEventInfo|DebugEvent]] (retrievable via [[#svcGetDebugEvent]]).
+
== svcResetSignal ==
   −
'''KClientPort:''' signals when the number of sessions is less than the maximum allowed.
+
<div style="display: inline-block;">
 
+
{| class="wikitable" border="1"
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#svcGetProcessInfo]]).
+
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || Handle<ReadableEvent> or Handle<Process> || Handle
 +
|-
 +
| (Out) W0 || [[#Result]] || Ret
 +
|}
 +
</div>
   −
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via svcSignalEvent.
+
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.
 
  −
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#svcAcceptSession|accepted]].
     −
'''KServerSession:''' signals when there is an incoming message waiting to be [[#svcReplyAndReceive|received]] or the pipe is closed.
+
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.
 
  −
'''KThread:''' signals when the thread has exited.
      
=== Result codes ===
 
=== 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.
+
'''0x0:''' Success. The signal was reset.
 
  −
'''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.
+
'''0xE401:''' The handle is invalid or of the wrong type.
   −
'''0xea01:''' Timeout. Returned when no objects have been signaled within the timeout. Handle index is not updated.
+
'''0xFA01:''' The handle was not signaled, or the process is in exited state, causing it to be permanently signaled.
   −
'''0xec01:''' Interrupted. Returned when another thread uses [[#svcCancelSynchronization]] to cancel this thread. Handle index is not updated.
+
== svcWaitSynchronization ==
 
  −
'''0xee01:''' Too many handles. Returned when the number of handles passed is > 0x40.
  −
 
  −
== svcCancelSynchronization ==
      
<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<Thread> || Handle
+
| (In) X1 || R1 || Handle* || HandlesPtr
 +
|-
 +
| (In) W2 || R2 || u64 || HandlesNum
 +
|-
 +
| (In) X3 || R0, R3 || u64 || Timeout
 +
|-
 +
| (Out) W0 || R0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W1 || R1 || u64 || HandleIndex
 
|}
 
|}
 
</div>
 
</div>
 +
Works with num_handles <= 0x40.
 +
 +
When zero handles are passed, this will wait forever until either timeout or cancellation occurs.
   −
If the referenced thread is currently in a synchronization call ([[#svcWaitSynchronization]], [[#svcReplyAndReceive]] or [[#svcReplyAndReceiveLight]]), that call will be interrupted and return 0xec01.
+
Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.
If that thread is not currently executing such a synchronization call, the next call to a synchronization call will return 0xec01.
+
 
 +
=== Object types ===
   −
This doesn't take force-pause (activity/debug pause) into account.
+
'''KDebug:''' signals when there is a new [[#DebugEventInfo|DebugEvent]] (retrievable via [[#svcGetDebugEvent]]).
   −
=== Result codes ===
+
'''KClientPort:''' signals when the number of sessions is less than the maximum allowed.
   −
'''0x0:''' Success. The thread was either interrupted or has had its flag set.
+
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#svcGetProcessInfo]]).
   −
'''0xe401:''' Invalid handle. The handle given was either invalid or not a thread handle.
+
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via svcSignalEvent.
   −
== svcGetSystemTick ==
+
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#svcAcceptSession|accepted]].
   −
<div style="display: inline-block;">
+
'''KServerSession:''' signals when there is an incoming message waiting to be [[#svcReplyAndReceive|received]] or the pipe is closed.
{| class="wikitable" border="1"
+
 
|-
+
'''KThread:''' signals when the thread has exited.
! Argument64 || Argument32 || Type || Name
+
 
|-
+
=== Result codes ===
| (Out) X0 || R0, R1 || u64 || Ticks
+
 
|}
+
'''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.
</div>
+
 
 +
'''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.
   −
Returns the value of cntpct_el0.
+
'''0xea01:''' Timeout. Returned when no objects have been signaled within the timeout. Handle index is not updated.
   −
The frequency is 19200000 Hz (constant from official sw).
+
'''0xec01:''' Interrupted. Returned when another thread uses [[#svcCancelSynchronization]] to cancel this thread. Handle index is not updated.
   −
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.
+
'''0xee01:''' Too many handles. Returned when the number of handles passed is > 0x40.
   −
== svcSendSyncRequestWithUserBuffer ==
+
== svcCancelSynchronization ==
    
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 810: Line 896:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) X0 || void* || CmdPtr
+
| (In) W0 || Handle<Thread> || Handle
 
|-
 
|-
| (In) X1 || u64 || Size
+
| (Out) W0 || [[#Result]] || Ret
|-
  −
| (In) W2 || Handle<Session> || Handle
  −
|-
  −
| (Out) W0 || [[#Result]] || Ret
   
|}
 
|}
 
</div>
 
</div>
   −
Size and CmdPtr must be 0x1000-aligned.
+
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 ===
 
=== Result codes ===
   −
'''0x0:''' Success.
+
'''0x0:''' Success. The thread was either interrupted or has had its flag set.
   −
'''0xcc01:''' CmdPtr is not 0x1000-aligned.
+
'''0xe401:''' Invalid handle. The handle given was either invalid or not a thread handle.
   −
'''0xca01:''' Size is not 0x1000-aligned.
+
== svcGetSystemTick ==
 
  −
'''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;">
 
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || u64 || Break Reason
+
| (Out) X0 || R0, R1 || u64 || Ticks
|-
+
|}
| (In) X1 || u64 ||
+
</div>
|-
+
 
| (In) X2 || u64 || Info
+
Returns the value of cntpct_el0.
|-
  −
| (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).
+
The frequency is 19200000 Hz (constant from official sw).
   −
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.
+
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.
   −
Otherwise just return 0.
+
== svcSendSyncRequestWithUserBuffer ==
 
  −
== svcGetInfo ==
      
<div style="display: inline-block;">
 
<div style="display: inline-block;">
Line 864: Line 937:  
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) W1 || u32 || InfoId
+
| (In) X0 || void* || CmdPtr
 
|-
 
|-
| (In) W2 || Handle || Handle
+
| (In) X1 || u64 || Size
 
|-
 
|-
| (In) X3 || u64 || InfoSubId
+
| (In) W2 || Handle<Session> || Handle
 
|-
 
|-
 
| (Out) W0 || [[#Result]] || Ret
 
| (Out) W0 || [[#Result]] || Ret
|-
  −
| (Out) X1 || u64 || Out
   
|}
 
|}
 
</div>
 
</div>
<div style="display: inline-block; vertical-align:top;">
+
 
{| class="wikitable" border="1"
+
Size and CmdPtr must be 0x1000-aligned.
|-
+
 
 +
=== Result codes ===
 +
 
 +
'''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"
 +
|-
 
! Argument || Type || Name
 
! Argument || Type || Name
 
|-
 
|-
| (In) R0 || u32 || InfoSubIdLower32
+
| (In) X0 || u64 || Break Reason
 
|-
 
|-
| (In) R1 || u32 || InfoId
+
| (In) X1 || u64 ||
 
|-
 
|-
| (In) R2 || Handle || Handle
+
| (In) X2 || u64 || Info
 
|-
 
|-
| (In) R3 || u32 || InfoSubIdUpper32
+
| (Out) W0 || Result || 0 (Success)
|-
  −
| (Out) R0 || [[#Result]] || Ret
  −
|-
  −
| (Out) R1 || u32 || OutLower32
  −
|-
  −
| (Out) R2 || u32 || OutUpper32
   
|}
 
|}
 
</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).
 +
 +
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 ==
   −
{| class=wikitable
+
<div style="display: inline-block;">
! Handle type || Id0 || Id1 || Description
+
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 0 || 0 || AllowedCpuIdBitmask
+
! Argument || Type || Name
 
|-
 
|-
| Process || 1 || 0 || AllowedThreadPrioBitmask
+
| (In) W1 || u32 || InfoId
 
|-
 
|-
| Process || 2 || 0 || AliasRegionBaseAddr
+
| (In) W2 || Handle || Handle
 
|-
 
|-
| Process || 3 || 0 || AliasRegionSize
+
| (In) X3 || u64 || InfoSubId
 
|-
 
|-
| Process || 4 || 0 || HeapRegionBaseAddr
+
| (Out) W0 || [[#Result]] || Ret
 
|-
 
|-
| Process || 5 || 0 || HeapRegionSize
+
| (Out) X1 || u64 || Out
 +
|}
 +
</div>
 +
<div style="display: inline-block; vertical-align:top;">
 +
{| class="wikitable" border="1"
 
|-
 
|-
| Process || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
+
! Argument || Type || Name
 
|-
 
|-
| Process || 7 || 0 || TotalMemoryUsage. Total used size of codebin memory + main-thread stack + allocated heap.
+
| (In) R0 || u32 || InfoSubIdLower32
 
|-
 
|-
| Zero    || 8 || 0 || IsCurrentProcessBeingDebugged
+
| (In) R1 || u32 || InfoId
 
|-
 
|-
| Zero    || 9 || 0 || Returns ResourceLimit handle for current process. Used by [[Process_Manager_services|PM]].
+
| (In) R2 || Handle || Handle
 
|-
 
|-
| Zero    || 10 || -1, {current coreid} || IdleTickCount
+
| (In) R3 || u32 || InfoSubIdUpper32
 
|-
 
|-
| Zero    || 11 || 0-3 || RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
+
| (Out) R0 || [[#Result]] || Ret
 
|-
 
|-
| Process || 12 || 0 || [2.0.0+] AddressSpaceBaseAddr
+
| (Out) R1 || u32 || OutLower32
 
|-
 
|-
| Process || 13 || 0 || [2.0.0+] AddressSpaceSize
+
| (Out) R2 || u32 || OutUpper32
 +
|}
 +
</div>
 +
 
 +
 
 +
{| class=wikitable
 +
! Handle type || Id0 || Id1 || Description
 
|-
 
|-
| Process || 14 || 0 || [2.0.0+] StackRegionBaseAddr
+
| Process || 0 || 0 || AllowedCpuIdBitmask
 
|-
 
|-
| Process || 15 || 0 || [2.0.0+] StackRegionSize
+
| Process || 1 || 0 || AllowedThreadPrioBitmask
 
|-
 
|-
| Process || 16 || 0 || [3.0.0+] PersonalMmHeapSize
+
| Process || 2 || 0 || AliasRegionBaseAddr
 
|-
 
|-
| Process || 17 || 0 || [3.0.0+] PersonalMmHeapUsage
+
| Process || 3 || 0 || AliasRegionSize
 
|-
 
|-
| Process || 18 || 0 || [3.0.0+] TitleId
+
| Process || 4 || 0 || HeapRegionBaseAddr
 +
|-
 +
| Process || 5 || 0 || HeapRegionSize
 +
|-
 +
| Process || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
 +
|-
 +
| Process || 7 || 0 || TotalMemoryUsage. Total used size of codebin memory + main-thread stack + allocated heap.
 +
|-
 +
| Zero    || 8 || 0 || IsCurrentProcessBeingDebugged
 +
|-
 +
| Zero    || 9 || 0 || Returns ResourceLimit handle for current process. Used by [[Process_Manager_services|PM]].
 +
|-
 +
| Zero    || 10 || -1, {current coreid} || IdleTickCount
 +
|-
 +
| Zero    || 11 || 0-3 || RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
 +
|-
 +
| Process || 12 || 0 || [2.0.0+] AddressSpaceBaseAddr
 +
|-
 +
| Process || 13 || 0 || [2.0.0+] AddressSpaceSize
 +
|-
 +
| 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
 
| Zero    || 19 || 0 || [4.0.0-4.1.0] PrivilegedProcessId_LowerBound
Line 947: Line 1,074:  
|-
 
|-
 
| Process || 22 || 0 || [6.0.0+] TotalMemoryUsedWithoutMmHeap
 
| Process || 22 || 0 || [6.0.0+] TotalMemoryUsedWithoutMmHeap
 +
|-
 +
| Process || 23 || 0 || [9.0.0+]
 
|-
 
|-
 
| 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.
 
| 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.
Line 1,425: Line 1,554:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) W0 || Handle<Process> || ProcessHandle
+
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X1 || u64 || Addr
+
| (In) X1 || R2, R3 || u64 || Addr
 
|-
 
|-
| (In) X2 || u64 || Size
+
| (In) X2 || R1, R4 || u64 || Size
 
|-
 
|-
| (In) W3 || void* || Perm
+
| (In) W3 || R5 || void* || Perm
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Line 1,448: Line 1,577:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || u64 || DstAddr
+
| (In) X0 || R0 || u64 || DstAddr
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X2 || void* || SrcAddr
+
| (In) X2 || R2, R3 || void* || SrcAddr
 
|-
 
|-
| (In) X3 || u64 || Size
+
| (In) X3 || R4 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Line 1,471: Line 1,600:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || void* || DstAddr
+
| (In) X0 || R0 || void* || DstAddr
 
|-
 
|-
| (In) W1 || Handle<Process> || ProcessHandle
+
| (In) W1 || R1 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X2 || u64 || SrcAddr
+
| (In) X2 || R2, R3 || u64 || SrcAddr
 
|-
 
|-
| (In) X3 || u64 || Size
+
| (In) X3 || R4 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Line 1,492: Line 1,621:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) X0 || [[#MemoryInfo]]* || MemInfoPtr
+
| (In) X0 || R0 || [[#MemoryInfo]]* || MemInfoPtr
 
|-
 
|-
| (In) W2 || Handle<Process> || ProcessHandle
+
| (In) W2 || R2 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X3 || u64 || Addr
+
| (In) X3 || R1, R3 || u64 || Addr
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|-
 
|-
| (Out) W1 || PageInfo || PageInfo
+
| (Out) W1 || R1 || PageInfo || PageInfo
 
|}
 
|}
 
</div>
 
</div>
Line 1,513: Line 1,642:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) W0 || Handle<Process> || ProcessHandle
+
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X1 || u64 || DstAddr
+
| (In) X1 || R2, R3 || u64 || DstAddr
 
|-
 
|-
| (In) X2 || u64 || SrcAddr
+
| (In) X2 || R1, R4 || u64 || SrcAddr
 
|-
 
|-
| (In) X3 || u64 || Size
+
| (In) X3 || R5, R6 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Line 1,534: Line 1,663:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Argument || Type || Name
+
! Argument64 || Argument32 || Type || Name
 
|-
 
|-
| (In) W0 || Handle<Process> || ProcessHandle
+
| (In) W0 || R0 || Handle<Process> || ProcessHandle
 
|-
 
|-
| (In) X1 || u64 || DstAddr
+
| (In) X1 || R2, R3 || u64 || DstAddr
 
|-
 
|-
| (In) X2 || u64 || SrcAddr
+
| (In) X2 || R1, R4 || u64 || SrcAddr
 
|-
 
|-
| (In) X3 || u64 || Size
+
| (In) X3 || R5, R6 || u64 || Size
 
|-
 
|-
| (Out) W0 || [[#Result]] || Ret
+
| (Out) W0 || R0 || [[#Result]] || Ret
 
|}
 
|}
 
</div>
 
</div>
Line 1,594: Line 1,723:  
{| 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,611: Line 1,742:  
{| 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,955: Line 2,086:  
== 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