Changes

Jump to navigation Jump to search
5,100 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
 
| 0x55 || [[#svcQueryIoMapping]] || X1=physaddr, X2=size
Line 297: Line 297:  
|| W0=result, W1=pageinfo
 
|| 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 334: 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 362: 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 668: 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 675: 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
+
</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"
 +
|-
 +
! 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 697: Line 766:  
|-
 
|-
 
! Argument || Type || Name
 
! Argument || Type || Name
 +
|-
 +
| (In) W0 || Handle<SharedMemory> || MemHandle
 
|-
 
|-
 
| (In) X1 || void* || Addr
 
| (In) X1 || void* || Addr
Line 705: 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.
 +
 
 +
Increases reference count for the KSharedMemory object. Thus in order to release the memory associated with the object, all handles to it must be closed and all mappings must be unmapped.
 +
 
 +
== svcCreateTransferMemory ==
 +
 
 +
<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>
 +
 
 +
This one reprotects the src block with perms you give it. It also sets bit0 into [[#MemoryAttribute]].
    
Executable bit perm not allowed.
 
Executable bit perm not allowed.
    
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
 
Closing all handles automatically causes the bit0 in [[#MemoryAttribute]] to clear, and the permission to reset.
 +
 +
== svcResetSignal ==
 +
 +
<div style="display: inline-block;">
 +
{| class="wikitable" border="1"
 +
|-
 +
! Argument || Type || Name
 +
|-
 +
| (In) W0 || Handle<ReadableEvent> or Handle<Process> || Handle
 +
|-
 +
| (Out) W0 || [[#Result]] || Ret
 +
|}
 +
</div>
 +
 +
Resets the signal on the given handle, ensuring future calls to [[#svcWaitSynchronization]] on this handle will sleep until the handle is signaled again. If the handle is a ReadableEvent, this is equivalent to calling svcClearEvent() on the handle.
 +
 +
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 ===
 +
 +
'''0x0:''' Success. The signal was reset.
 +
 +
'''0xE401:''' The handle is invalid or of the wrong type.
 +
 +
'''0xFA01:''' The handle was not signaled, or the process is in exited state, causing it to be permanently signaled.
    
== svcWaitSynchronization ==
 
== svcWaitSynchronization ==
Line 957: 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,217: Line 1,336:  
| (Out) X1 || u64 || PhysAddr
 
| (Out) X1 || u64 || PhysAddr
 
|-
 
|-
| (Out) X2 || u64 || KernelAddr
+
| (Out) X2 || u64 || BaseAddr
 
|-
 
|-
 
| (Out) X3 || u64 || Size
 
| (Out) X3 || u64 || Size
 
|}
 
|}
 
</div>
 
</div>
 +
 +
'''Description:''' Query the physical address of a virtual address. Will always fetch the lowest page-aligned mapping that contains the provided physical address.
 +
 +
The returned BaseAddr is the virtual address of that page-aligned mapping, while PhysAddr is the physical address of that page. Size is the amount of continuous physical memory in that mapping.
    
== svcQueryIoMapping ==
 
== svcQueryIoMapping ==
Line 1,523: Line 1,646:  
{| 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,544: Line 1,667:  
{| 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,604: 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,621: 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,965: 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