SVC: Difference between revisions

Ootulp (talk | contribs)
 
(32 intermediate revisions by 6 users not shown)
Line 3: Line 3:
= System calls =
= System calls =
{| class=wikitable
{| class=wikitable
! Id || Name || In || Out
! ID || Return Type || Name || Arguments
|-
|-
| 0x1 || [[#SetHeapSize]] || ||
| 0x01 || Result || [[#SetHeapSize|SetHeapSize]] || uintptr_t *out_address, size_t size
|-
|-
| 0x2 || [[#SetMemoryPermission]] || ||
| 0x02 || Result || [[#SetMemoryPermission|SetMemoryPermission]] || uintptr_t address, size_t size, MemoryPermission perm
|-
|-
| 0x3 || [[#SetMemoryAttribute]] || ||
| 0x03 || Result || [[#SetMemoryAttribute|SetMemoryAttribute]] || uintptr_t address, size_t size, uint32_t mask, uint32_t attr
|-
|-
| 0x4 || [[#MapMemory]] || ||
| 0x04 || Result || [[#MapMemory|MapMemory]] || uintptr_t dst_address, uintptr_t src_address, size_t size
|-
|-
| 0x5 || [[#UnmapMemory]] || ||
| 0x05 || Result || [[#UnmapMemory|UnmapMemory]] || uintptr_t dst_address, uintptr_t src_address, size_t size
|-
|-
| 0x6 || [[#QueryMemory]] || ||
| 0x06 || Result || [[#QueryMemory|QueryMemory]] || arch::MemoryInfo *out_memory_info, PageInfo *out_page_info, uintptr_t address
|-
|-
| 0x7 || [[#ExitProcess]] || ||
| 0x07 || void || [[#ExitProcess|ExitProcess]] ||  
|-
|-
| 0x8 || [[#CreateThread]] || ||
| 0x08 || Result || [[#CreateThread|CreateThread]] || Handle *out_handle, ThreadFunc func, uintptr_t arg, uintptr_t stack_bottom, int32_t priority, int32_t core_id
|-
|-
| 0x9 || [[#StartThread]] || ||
| 0x09 || Result || [[#StartThread|StartThread]] || Handle thread_handle
|-
|-
| 0xA || [[#ExitThread]] || ||
| 0x0A || void || [[#ExitThread|ExitThread]] ||  
|-
|-
| 0xB || [[#SleepThread]] || ||
| 0x0B || void || [[#SleepThread|SleepThread]] || int64_t ns
|-
|-
| 0xC || [[#GetThreadPriority]] || ||
| 0x0C || Result || [[#GetThreadPriority|GetThreadPriority]] || int32_t *out_priority, Handle thread_handle
|-
|-
| 0xD || [[#SetThreadPriority]] || ||
| 0x0D || Result || [[#SetThreadPriority|SetThreadPriority]] || Handle thread_handle, int32_t priority
|-
|-
| 0xE || [[#GetThreadCoreMask]] || ||
| 0x0E || Result || [[#GetThreadCoreMask|GetThreadCoreMask]] || int32_t *out_core_id, uint64_t *out_affinity_mask, Handle thread_handle
|-
|-
| 0xF || [[#SetThreadCoreMask]] || ||
| 0x0F || Result || [[#SetThreadCoreMask|SetThreadCoreMask]] || Handle thread_handle, int32_t core_id, uint64_t affinity_mask
|-
|-
| 0x10 || [[#GetCurrentProcessorNumber]] || ||
| 0x10 || int32_t || [[#GetCurrentProcessorNumber|GetCurrentProcessorNumber]] ||  
|-
|-
| 0x11 || [[#SignalEvent]] || ||
| 0x11 || Result || [[#SignalEvent|SignalEvent]] || Handle event_handle
|-
|-
| 0x12 || [[#ClearEvent]] || ||
| 0x12 || Result || [[#ClearEvent|ClearEvent]] || Handle event_handle
|-
|-
| 0x13 || [[#MapSharedMemory]] || ||
| 0x13 || Result || [[#MapSharedMemory|MapSharedMemory]] || Handle shmem_handle, uintptr_t address, size_t size, MemoryPermission map_perm
|-
|-
| 0x14 || [[#UnmapSharedMemory]] || ||
| 0x14 || Result || [[#UnmapSharedMemory|UnmapSharedMemory]] || Handle shmem_handle, uintptr_t address, size_t size
|-
|-
| 0x15 || [[#CreateTransferMemory]] || ||
| 0x15 || Result || [[#CreateTransferMemory|CreateTransferMemory]] || Handle *out_handle, uintptr_t address, size_t size, MemoryPermission map_perm
|-
|-
| 0x16 || [[#CloseHandle]] || ||
| 0x16 || Result || [[#CloseHandle|CloseHandle]] || Handle handle
|-
|-
| 0x17 || [[#ResetSignal]] || ||
| 0x17 || Result || [[#ResetSignal|ResetSignal]] || Handle handle
|-
|-
| 0x18 || [[#WaitSynchronization]] || ||
| 0x18 || Result || [[#WaitSynchronization|WaitSynchronization]] || int32_t *out_index, const Handle *handles, int32_t numHandles, int64_t timeout_ns
|-
|-
| 0x19 || [[#CancelSynchronization]] || ||
| 0x19 || Result || [[#CancelSynchronization|CancelSynchronization]] || Handle handle
|-
|-
| 0x1A || [[#ArbitrateLock]] || ||
| 0x1A || Result || [[#ArbitrateLock|ArbitrateLock]] || Handle thread_handle, uintptr_t address, uint32_t tag
|-
|-
| 0x1B || [[#ArbitrateUnlock]] || ||
| 0x1B || Result || [[#ArbitrateUnlock|ArbitrateUnlock]] || uintptr_t address
|-
|-
| 0x1C || [[#WaitProcessWideKeyAtomic]] || ||
| 0x1C || Result || [[#WaitProcessWideKeyAtomic|WaitProcessWideKeyAtomic]] || uintptr_t address, uintptr_t cv_key, uint32_t tag, int64_t timeout_ns
|-
|-
| 0x1D || [[#SignalProcessWideKey]] || ||
| 0x1D || void || [[#SignalProcessWideKey|SignalProcessWideKey]] || uintptr_t cv_key, int32_t count
|-
|-
| 0x1E || [[#GetSystemTick]] || ||
| 0x1E || int64_t || [[#GetSystemTick|GetSystemTick]] ||  
|-
|-
| 0x1F || [[#ConnectToNamedPort]] || ||
| 0x1F || Result || [[#ConnectToNamedPort|ConnectToNamedPort]] || Handle *out_handle, const char *name
|-
|-
| 0x20 || [[#SendSyncRequestLight]] || ||
| 0x20 || Result || [[#SendSyncRequestLight|SendSyncRequestLight]] || Handle session_handle
|-
|-
| 0x21 || [[#SendSyncRequest]] || ||
| 0x21 || Result || [[#SendSyncRequest|SendSyncRequest]] || Handle session_handle
|-
|-
| 0x22 || [[#SendSyncRequestWithUserBuffer]] || ||
| 0x22 || Result || [[#SendSyncRequestWithUserBuffer|SendSyncRequestWithUserBuffer]] || uintptr_t message_buffer, size_t message_buffer_size, Handle session_handle
|-
|-
| 0x23 || [[#SendAsyncRequestWithUserBuffer]] || ||
| 0x23 || Result || [[#SendAsyncRequestWithUserBuffer|SendAsyncRequestWithUserBuffer]] || Handle *out_event_handle, uintptr_t message_buffer, size_t message_buffer_size, Handle session_handle
|-
|-
| 0x24 || [[#GetProcessId]] || ||
| 0x24 || Result || [[#GetProcessId|GetProcessId]] || uint64_t *out_process_id, Handle process_handle
|-
|-
| 0x25 || [[#GetThreadId]] || ||
| 0x25 || Result || [[#GetThreadId|GetThreadId]] || uint64_t *out_thread_id, Handle thread_handle
|-
|-
| 0x26 || [[#Break]] || ||
| 0x26 || void || [[#Break|Break]] || BreakReason break_reason, uintptr_t arg, size_t size
|-
|-
| 0x27 || [[#OutputDebugString]] || ||
| 0x27 || Result || [[#OutputDebugString|OutputDebugString]] || const char *debug_str, size_t len
|-
|-
| 0x28 || [[#ReturnFromException]] || ||
| 0x28 || void || [[#ReturnFromException|ReturnFromException]] || Result result
|-
|-
| 0x29 || [[#GetInfo]] || ||
| 0x29 || Result || [[#GetInfo|GetInfo]] || uint64_t *out, InfoType info_type, Handle handle, uint64_t info_subtype
|-
|-
| 0x2A || [[#FlushEntireDataCache]] || ||  
| 0x2A || void || [[#FlushEntireDataCache|FlushEntireDataCache]] ||  
|-
|-
| 0x2B || [[#FlushDataCache]] || ||
| 0x2B || Result || [[#FlushDataCache|FlushDataCache]] || uintptr_t address, size_t size
|-
|-
| 0x2C || [3.0.0+] [[#MapPhysicalMemory]] || ||
| [3.0.0+] 0x2C  || Result || [[#MapPhysicalMemory|MapPhysicalMemory]] || uintptr_t address, size_t size
|-
|-
| 0x2D || [3.0.0+] [[#UnmapPhysicalMemory]] || ||
| [3.0.0+] 0x2D  || Result || [[#UnmapPhysicalMemory|UnmapPhysicalMemory]] || uintptr_t address, size_t size
|-
|-
| 0x2E || [5.0.0+] [[#GetFutureThreadInfo]] || ||
| [5.0.0-5.1.0] 0x2E  || Result || GetFutureThreadInfo || arch::LastThreadContext *out_context, uintptr_t *out_tls_address, uint32_t *out_flags, int64_t ns
|-
|-
| 0x2F || [[#GetLastThreadInfo]] || ||
| [6.0.0+] 0x2E  || Result || [[#GetDebugFutureThreadInfo|GetDebugFutureThreadInfo]] || arch::LastThreadContext *out_context, uint64_t *thread_id, Handle debug_handle, int64_t ns
|-
|-
| 0x30 || [[#GetResourceLimitLimitValue]] || ||
| 0x2F || Result || [[#GetLastThreadInfo|GetLastThreadInfo]] || arch::LastThreadContext *out_context, uintptr_t *out_tls_address, uint32_t *out_flags
|-
|-
| 0x31 || [[#GetResourceLimitCurrentValue]] || ||
| 0x30 || Result || [[#GetResourceLimitLimitValue|GetResourceLimitLimitValue]] || int64_t *out_limit_value, Handle resource_limit_handle, LimitableResource which
|-
|-
| 0x32 || [[#SetThreadActivity]] || ||
| 0x31 || Result || [[#GetResourceLimitCurrentValue|GetResourceLimitCurrentValue]] || int64_t *out_current_value, Handle resource_limit_handle, LimitableResource which
|-
|-
| 0x33 || [[#GetThreadContext3]] || ||
| 0x32 || Result || [[#SetThreadActivity|SetThreadActivity]] || Handle thread_handle, ThreadActivity thread_activity
|-
|-
| 0x34 || [4.0.0+] [[#WaitForAddress]] || ||
| 0x33  || Result || [[#GetThreadContext3|GetThreadContext3]] || ThreadContext *out_context, Handle thread_handle
|-
|-
| 0x35 || [4.0.0+] [[#SignalToAddress]] || ||
| [4.0.0+] 0x34 || Result || [[#WaitForAddress|WaitForAddress]] || uintptr_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns
|-
|-
| 0x36 || [8.0.0+] [[#SynchronizePreemptionState]] || ||
| [4.0.0+] 0x35 || Result || [[#SignalToAddress|SignalToAddress]] || uintptr_t address, SignalType signal_type, int32_t value, int32_t count
|-
| [8.0.0+] 0x36 || void || [[#SynchronizePreemptionState|SynchronizePreemptionState]] ||  
|-
| [11.0.0+] 0x37 || Result || [[#GetResourceLimitPeakValue|GetResourceLimitPeakValue]] || int64_t *out_peak_value, Handle resource_limit_handle, LimitableResource which
|- style="border-top: double"
|- style="border-top: double"
| 0x3C || [4.0.0+] [[#KernelDebug]] ([1.0.0-3.0.2] [[#DumpInfo]]) || ||
| [13.0.0+] 0x39 || Result || CreateIoPool || Handle *out_handle, IoPoolType which_pool
|-
|-
| 0x3D || [4.0.0+] [[#ChangeKernelTraceState]] || ||
| [13.0.0+] 0x3A || Result || CreateIoRegion || Handle *out_handle, Handle io_pool, PhysicalAddress physical_address, size_t size, MemoryMapping mapping, MemoryPermission perm
|- style="border-top: double"
|- style="border-top: double"
| 0x40 || [[#CreateSession]] || ||
| [1.0.0-3.0.2] 0x3C || void || [[#DumpInfo|DumpInfo]] || DumpInfoType dump_info_type, uint64_t arg
|-
|-
| 0x41 || [[#AcceptSession]] || ||
| [4.0.0+] 0x3C || void || [[#KernelDebug|KernelDebug]] || KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2
|-
|-
| 0x42 || [[#ReplyAndReceiveLight]] || ||
| [4.0.0+] 0x3D || void || [[#ChangeKernelTraceState|ChangeKernelTraceState]] || KernelTraceState kern_trace_state
|- style="border-top: double"
| 0x40 || Result || [[#CreateSession|CreateSession]] || Handle *out_server_session_handle, Handle *out_client_session_handle, bool is_light, uintptr_t name
|-
|-
| 0x43 || [[#ReplyAndReceive]] || ||
| 0x41 || Result || [[#AcceptSession|AcceptSession]] || Handle *out_handle, Handle port
|-
|-
| 0x44 || [[#ReplyAndReceiveWithUserBuffer]] || ||
| 0x42 || Result || [[#ReplyAndReceiveLight|ReplyAndReceiveLight]] || Handle handle
|-
|-
| 0x45 || [[#CreateEvent]] || ||
| 0x43 || Result || [[#ReplyAndReceive|ReplyAndReceive]] || int32_t *out_index, const Handle *handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns
|- style="border-top: double"
|-
| 0x48 || [5.0.0+] [[#MapPhysicalMemoryUnsafe]] || ||
| 0x44 || Result || [[#ReplyAndReceiveWithUserBuffer|ReplyAndReceiveWithUserBuffer]] || int32_t *out_index, uintptr_t message_buffer, size_t message_buffer_size, const Handle *handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns
|-
| 0x45 || Result || [[#CreateEvent|CreateEvent]] || Handle *out_write_handle, Handle *out_read_handle
|-
| [13.0.0+] 0x46 || Result || MapIoRegion || Handle io_region, uintptr_t address, size_t size, MemoryPermission perm
|-
| [13.0.0+] 0x47 || Result || UnmapIoRegion || Handle io_region, uintptr_t address, size_t size
|-
| [5.0.0+] 0x48 || Result || [[#MapPhysicalMemoryUnsafe|MapPhysicalMemoryUnsafe]] || uintptr_t address, size_t size
|-
| [5.0.0+] 0x49 || Result || [[#UnmapPhysicalMemoryUnsafe|UnmapPhysicalMemoryUnsafe]] || uintptr_t address, size_t size
|-
|-
| 0x49 || [5.0.0+] [[#UnmapPhysicalMemoryUnsafe]] || ||
| [5.0.0+] 0x4A || Result || [[#SetUnsafeLimit|SetUnsafeLimit]] || size_t limit
|-
|-
| 0x4A || [5.0.0+] [[#SetUnsafeLimit]] || ||
| [4.0.0+] 0x4B || Result || [[#CreateCodeMemory|CreateCodeMemory]] || Handle *out_handle, uintptr_t address, size_t size
|-
|-
| 0x4B || [4.0.0+] [[#CreateCodeMemory]] || ||
| [4.0.0+] 0x4C || Result || [[#ControlCodeMemory|ControlCodeMemory]] || Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm
|-
|-
| 0x4C || [4.0.0+] [[#ControlCodeMemory]] || ||
| 0x4D || void || [[#SleepSystem|SleepSystem]] ||  
|-
|-
| 0x4D || [[#SleepSystem]] || ||
| 0x4E || Result || [[#ReadWriteRegister|ReadWriteRegister]] || uint32_t *out_value, PhysicalAddress address, uint32_t mask, uint32_t value
|-
|-
| 0x4E || [[#ReadWriteRegister]] || ||
| 0x4F || Result || [[#SetProcessActivity|SetProcessActivity]] || Handle process_handle, ProcessActivity process_activity
|-
|-
| 0x4F || [[#SetProcessActivity]] || ||
| 0x50 || Result || [[#CreateSharedMemory|CreateSharedMemory]] || Handle *out_handle, size_t size, MemoryPermission owner_perm, MemoryPermission remote_perm
|-
|-
| 0x50 || [[#CreateSharedMemory]] || ||
| 0x51 || Result || [[#MapTransferMemory|MapTransferMemory]] || Handle trmem_handle, uintptr_t address, size_t size, MemoryPermission owner_perm
|-
|-
| 0x51 || [[#MapTransferMemory]] || ||
| 0x52 || Result || [[#UnmapTransferMemory|UnmapTransferMemory]] || Handle trmem_handle, uintptr_t address, size_t size
|-
|-
| 0x52 || [[#UnmapTransferMemory]] || ||
| 0x53 || Result || [[#CreateInterruptEvent|CreateInterruptEvent]] || Handle *out_read_handle, int32_t interrupt_id, InterruptType interrupt_type
|-
|-
| 0x53 || [[#CreateInterruptEvent]] || ||
| 0x54 || Result || [[#QueryPhysicalAddress|QueryPhysicalAddress]] || arch::PhysicalMemoryInfo *out_info, uintptr_t address
|-
|-
| 0x54 || [[#QueryPhysicalAddress]] || ||
| [1.0.0-9.2.0] 0x55 || Result || [[#QueryIoMapping|QueryIoMapping]] || uintptr_t *out_address, PhysicalAddress physical_address, size_t size
|-
|-
| 0x55 || [[#QueryIoMapping]] || ||
| [10.0.0+] 0x55 || Result || QueryMemoryMapping || uintptr_t *out_address, size_t *out_size, PhysicalAddress physical_address, size_t size
|-
|-
| 0x56 || [[#CreateDeviceAddressSpace]] || ||
| 0x56 || Result || [[#CreateDeviceAddressSpace|CreateDeviceAddressSpace]] || Handle *out_handle, uint64_t das_address, uint64_t das_size
|-
|-
| 0x57 || [[#AttachDeviceAddressSpace]] || ||
| 0x57 || Result || [[#AttachDeviceAddressSpace|AttachDeviceAddressSpace]] || DeviceName device_name, Handle das_handle
|-
|-
| 0x58 || [[#DetachDeviceAddressSpace]] || ||
| 0x58 || Result || [[#DetachDeviceAddressSpace|DetachDeviceAddressSpace]] || DeviceName device_name, Handle das_handle
|-
|-
| 0x59 || [[#MapDeviceAddressSpaceByForce]] || ||
| 0x59 || Result || [[#MapDeviceAddressSpaceByForce|MapDeviceAddressSpaceByForce]] || Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, uint32_t option
|-
|-
| 0x5A || [[#MapDeviceAddressSpaceAligned]] || ||
| 0x5A || Result || [[#MapDeviceAddressSpaceAligned|MapDeviceAddressSpaceAligned]] || Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, uint32_t option
|-
|-
| 0x5B || [[#MapDeviceAddressSpace]] || ||
| [1.0.0-12.1.0] 0x5B || Result || [[#MapDeviceAddressSpace|MapDeviceAddressSpace]] || size_t *out_mapped_size, Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, MemoryPermission device_perm
|-
|-
| 0x5C || [[#UnmapDeviceAddressSpace]] || ||
| 0x5C || Result || [[#UnmapDeviceAddressSpace|UnmapDeviceAddressSpace]] || Handle das_handle, Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address
|-
|-
| 0x5D || [[#InvalidateProcessDataCache]] || ||
| 0x5D || Result || [[#InvalidateProcessDataCache|InvalidateProcessDataCache]] || Handle process_handle, uint64_t address, uint64_t size
|-
|-
| 0x5E || [[#StoreProcessDataCache]] || ||
| 0x5E || Result || [[#StoreProcessDataCache|StoreProcessDataCache]] || Handle process_handle, uint64_t address, uint64_t size
|-
|-
| 0x5F || [[#FlushProcessDataCache]] || ||
| 0x5F || Result || [[#FlushProcessDataCache|FlushProcessDataCache]] || Handle process_handle, uint64_t address, uint64_t size
|-
|-
| 0x60 || [[#DebugActiveProcess]] || ||
| 0x60 || Result || [[#DebugActiveProcess|DebugActiveProcess]] || Handle *out_handle, uint64_t process_id
|-
|-
| 0x61 || [[#BreakDebugProcess]] || ||
| 0x61 || Result || [[#BreakDebugProcess|BreakDebugProcess]] || Handle debug_handle
|-
|-
| 0x62 || [[#TerminateDebugProcess]] || ||
| 0x62 || Result || [[#TerminateDebugProcess|TerminateDebugProcess]] || Handle debug_handle
|-
|-
| 0x63 || [[#GetDebugEvent]] || ||
| 0x63 || Result || [[#GetDebugEvent|GetDebugEvent]] || arch::DebugEventInfo *out_info, Handle debug_handle
|-
|-
| 0x64 || [[#ContinueDebugEvent]] || ||
| 0x64 || Result || [[#ContinueDebugEvent|ContinueDebugEvent]] || Handle debug_handle, uint32_t flags, const uint64_t *thread_ids, int32_t num_thread_ids
|-
|-
| 0x65 || [[#GetProcessList]] || ||
| 0x65 || Result || [[#GetProcessList|GetProcessList]] || int32_t *out_num_processes, uint64_t *out_process_ids, int32_t max_out_count
|-
|-
| 0x66 || [[#GetThreadList]] || ||
| 0x66 || Result || [[#GetThreadList|GetThreadList]] || int32_t *out_num_threads, uint64_t *out_thread_ids, int32_t max_out_count, Handle debug_handle
|-
|-
| 0x67 || [[#GetDebugThreadContext]] || ||
| 0x67 || Result || [[#GetDebugThreadContext|GetDebugThreadContext]] || ThreadContext *out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags
|-
|-
| 0x68 || [[#SetDebugThreadContext]] || ||
| 0x68 || Result || [[#SetDebugThreadContext|SetDebugThreadContext]] || Handle debug_handle, uint64_t thread_id, const ThreadContext *context, uint32_t context_flags
|-
|-
| 0x69 || [[#QueryDebugProcessMemory]] || ||
| 0x69 || Result || [[#QueryDebugProcessMemory|QueryDebugProcessMemory]] || arch::MemoryInfo *out_memory_info, PageInfo *out_page_info, Handle process_handle, uintptr_t address
|-
|-
| 0x6A || [[#ReadDebugProcessMemory]] || ||
| 0x6A || Result || [[#ReadDebugProcessMemory|ReadDebugProcessMemory]] || uintptr_t buffer, Handle debug_handle, uintptr_t address, size_t size
|-
|-
| 0x6B || [[#WriteDebugProcessMemory]] || ||
| 0x6B || Result || [[#WriteDebugProcessMemory|WriteDebugProcessMemory]] || Handle debug_handle, uintptr_t buffer, uintptr_t address, size_t size
|-
|-
| 0x6C || [[#SetHardwareBreakPoint]] || ||
| 0x6C || Result || [[#SetHardwareBreakPoint|SetHardwareBreakPoint]] || HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value
|-
|-
| 0x6D || [[#GetDebugThreadParam]] || ||
| 0x6D || Result || [[#GetDebugThreadParam|GetDebugThreadParam]] || uint64_t *out_64, uint32_t *out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param
|- style="border-top: double"
|- style="border-top: double"
| 0x6F || [5.0.0+] [[#GetSystemInfo]] || ||
| [5.0.0+] 0x6F || Result || [[#GetSystemInfo|GetSystemInfo]] || uint64_t *out, SystemInfoType info_type, Handle handle, uint64_t info_subtype
|-
| 0x70 || Result || [[#CreatePort|CreatePort]] || Handle *out_server_handle, Handle *out_client_handle, int32_t max_sessions, bool is_light, uintptr_t name
|-
| 0x71 || Result || [[#ManageNamedPort|ManageNamedPort]] || Handle *out_server_handle, const char *name, int32_t max_sessions
|-
| 0x72 || Result || [[#ConnectToPort|ConnectToPort]] || Handle *out_handle, Handle port
|-
|-
| 0x70 || CreatePort || W2=max_sessions, W3=is_light, X4=name_ptr
| 0x73 || Result || [[#SetProcessMemoryPermission|SetProcessMemoryPermission]] || Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm
R0=name_ptr, R2=max_sessions, R3=is_light
|| W0=result, W1=serverport_handle, W2=clientport_handle
|-
|-
| 0x71 || ManageNamedPort || X1=name_ptr, W2=max_sessions || W0=result, W1=serverport_handle
| 0x74 || Result || [[#MapProcessMemory|MapProcessMemory]] || uintptr_t dst_address, Handle process_handle, uint64_t src_address, size_t size
|-
|-
| 0x72 || ConnectToPort || W1=clientport_handle || W0=result, W1=session_handle
| 0x75 || Result || [[#UnmapProcessMemory|UnmapProcessMemory]] || uintptr_t dst_address, Handle process_handle, uint64_t src_address, size_t size
|-
|-
| 0x73 || [[#SetProcessMemoryPermission]] || W0=process_handle, X1=addr, X2=size, W3=perm
| 0x76 || Result || [[#QueryProcessMemory|QueryProcessMemory]] || arch::MemoryInfo *out_memory_info, PageInfo *out_page_info, Handle process_handle, uint64_t address
R0=process_handle, R1=size_lower32, R2=addr_lower32, R3=addr_upper32, R4=size_upper32, R5=perm
|| W0=result
|-
|-
| 0x74 || [[#MapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
| 0x77 || Result || [[#MapProcessCodeMemory|MapProcessCodeMemory]] || Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
|| W0=result
|-
|-
| 0x75 || [[#UnmapProcessMemory]] || X0=dstaddr, W1=process_handle, X2=srcaddr, X3=size
| 0x78 || Result || [[#UnmapProcessCodeMemory|UnmapProcessCodeMemory]] || Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size
R0=dstaddr, R1=process_handle, R2=srcaddr_lower32, R3=srcaddr_upper32, R4=size
|| W0=result
|-
|-
| 0x76 || [[#QueryProcessMemory]] || X0=meminfo_ptr, W2=process_handle, X3=addr
| 0x79 || Result || [[#CreateProcess|CreateProcess]] || Handle *out_handle, const arch::CreateProcessParameter *parameters, const uint32_t *caps, int32_t num_caps
R0=meminfo_ptr, R1=addr_lower32, R2=process_handle, R3=addr_upper32
|| W0=result, W1=pageinfo
|-
|-
| 0x77 || [[#MapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size
| 0x7A || Result || [[#StartProcess|StartProcess]] || Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_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 || [[#UnmapProcessCodeMemory]] || W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size
| 0x7B || Result || [[#TerminateProcess|TerminateProcess]] || Handle process_handle
R0=process_handle, R1=srcaddr_lower32, R2=dstaddr_lower32, R3=dstaddr_upper32, R4=srcaddr_lower32, R5=size_lower32, R6=size_upper32
|| W0=result
|-
|-
| 0x79 || [[#CreateProcess]] || X1=procinfo_ptr, X2=caps_ptr, W3=cap_num ||  W0=result, W1=process_handle
| 0x7C || Result || [[#GetProcessInfo|GetProcessInfo]] || int64_t *out_info, Handle process_handle, ProcessInfoType info_type
|-
|-
| 0x7A || StartProcess || W0=process_handle, W1=main_thread_prio, W2=default_cpuid, W3=main_thread_stacksz
| 0x7D || Result || [[#CreateResourceLimit|CreateResourceLimit]] || Handle *out_handle
R0=process_handle, R1=main_thread_prio, R2=default_cpuid, R3=main_thread_stacksz_lower32, R4=main_thread_stacksz_upper32
|| W0=result
|-
|-
| 0x7B || TerminateProcess || W0=process_handle || W0=result
| 0x7E || Result || [[#SetResourceLimitLimitValue|SetResourceLimitLimitValue]] || Handle resource_limit_handle, LimitableResource which, int64_t limit_value
|-
|-
| 0x7C || [[#GetProcessInfo]] || W0=process_handle, W1=[[#ProcessInfoType]]
| 0x7F || void || [[#CallSecureMonitor|CallSecureMonitor]] || SecureMonitorArguments *args
R1=process_handle, R2=[[#ProcessInfoType]]
|| W0=result, X1=[[#ProcessState]]
R0=result, R1=[[#ProcessState]]_lower32, R2=[[#ProcessState]]_upper32
|-
|-
| 0x7D || CreateResourceLimit || None || W0=result, W1=reslimit_handle
| [S2] 0x80 || Result || SetMemoryAttribute2? || uintptr_t address, size_t size, uint32_t mask, uint32_t attr
|- style="border-top: double"
| [15.0.0+] 0x90  || Result || MapInsecurePhysicalMemory || uintptr_t address, size_t size
|-
|-
| 0x7E || SetResourceLimitLimitValue || W0=reslimit_handle, W1=[[#LimitableResource]], X2=value
| [15.0.0+] 0x91  || Result || UnmapInsecurePhysicalMemory || uintptr_t address, size_t size
R0=reslimit_handle, R1=[[#LimitableResource]], R2=value_lower32, R3=value_upper32
|| W0=result
|-
|-
| 0x7F || [[#CallSecureMonitor]] || 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 270: Line 269:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W1 || u64 || Size
| (In) X1 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) X1 || u64 || OutAddr
| (Out) X1 || void* || HeapAddress
|}
|}
</div>
</div>
Line 282: Line 281:
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, and always in the Heap memory region) 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 HeapAddress.


Uses current process pool partition. The memory allocated counts towards the caller's process Memory ResourceLimit.
Uses current process pool partition. The memory allocated counts towards the caller's process Memory ResourceLimit.
Line 307: Line 306:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || Addr
| (In) X0 || void* || Address
|-
|-
| (In) X1 || u64 || Size
| (In) X1 || uint64_t || Size
|-
|-
| (In) W2 || [[#Permission]] || Prot
| (In) W2 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 334: Line 333:
'''0xD801:''' Invalid permission specified. Valid permissions are ---, r-- and rw-.
'''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]].
'''0xD401:''' The provided memory region was in an invalid state. The region must have the [[#MemoryState|FlagCanReprotect]] state, and must not have the [[#MemoryAttribute|Locked]] or [[#MemoryAttribute|Uncached]] attributes.


'''0xCE01:''' Kernel resource exhausted.
'''0xCE01:''' Kernel resource exhausted.
Line 344: Line 343:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || Addr
| (In) X0 || void* || Address
|-
|-
| (In) X1 || u64 || Size
| (In) X1 || uint64_t || Size
|-
|-
| (In) W2 || u32 || State0
| (In) W2 || uint32_t || Mask
|-
|-
| (In) W3 || u32 || State1
| (In) W3 || uint32_t || Value
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 356: Line 355:
</div>
</div>


Changes attribute of page-aligned memory region.  
Changes attribute of page-aligned memory region. The only allowed combination of Value and Mask is 0x8, which means only bit3 in [[#MemoryAttribute]] can be set or cleared.


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


What happens "under the hood" is the "Memory Attribute Indirection Register" index is changed from 2 to 3 in the MMU descriptor.
What happens "under the hood" is the "Memory Attribute Indirection Register" index is changed from 2 to 3 in the MMU descriptor.
{| class=wikitable
! State0 || State1 || Action
|-
| 0 || 0 || Clear bit3 in [[#MemoryAttribute]].
|-
| 8 || 0 || Clear bit3 in [[#MemoryAttribute]].
|-
| 8 || 8 || Set bit3 in [[#MemoryAttribute]].
|}


== MapMemory ==
== MapMemory ==
Line 378: Line 367:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || DstAddr
| (In) X0 || void* || DstAddress
|-
|-
| (In) X1 || void* || SrcAddr
| (In) X1 || void* || SrcAddress
|-
|-
| (In) X2 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 410: Line 399:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || DstAddr
| (In) X0 || void* || DstAddress
|-
|-
| (In) X1 || void* || SrcAddr
| (In) X1 || void* || SrcAddress
|-
|-
| (In) X2 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 432: Line 421:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || [[#MemoryInfo]]* || MemInfo
| (In) X0 || [[#MemoryInfo]]* || MemoryInfo
|-
|-
| (In) X2 || void* || Addr
| (In) X2 || void* || Address
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || PageInfo || PageInfo
| (Out) W1 || [[#PageInfo]] || PageInfo
|}
|}
</div>
</div>
Line 472: Line 461:
| (In) X3 || R3 || void* || StackTop
| (In) X3 || R3 || void* || StackTop
|-
|-
| (In) W4 || R0 || u32 || Priority
| (In) W4 || R0 || int32_t || Priority
|-
|-
| (In) W5 || R4 || u32 || ProcessorId
| (In) W5 || R4 || int32_t || ProcessorId
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || Handle<Thread> || Handle
| (Out) W1 || R1 || Handle<Thread> || ThreadHandle
|}
|}
</div>
</div>
Line 484: Line 473:
Creates a thread in the current process.
Creates a thread in the current process.


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


== StartThread ==
== StartThread ==
Line 492: Line 481:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Thread> || Handle
| (In) W0 || Handle<Thread> || ThreadHandle
|-
|-
| (Out) None ||  ||
| (Out) None ||  ||
Line 520: Line 509:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0, R1 || s64 || Nanoseconds
| (In) X0 || R0, R1 || uint64_t || Nanoseconds
|}
|}
</div>
</div>
Line 547: Line 536:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W1|| Handle<Thread> || Handle
| (In) W1|| Handle<Thread> || ThreadHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || u64 || Priority
| (Out) W1 || int32_t || Priority
|}
|}
</div>
</div>
Line 563: Line 552:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0|| Handle<Thread> || Handle
| (In) W0|| Handle<Thread> || ThreadHandle
|-
|-
| (In) W1|| u32 || Priority
| (In) W1|| int32_t || Priority
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 581: Line 570:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W2 || R2 || Handle<Thread> || Handle
| (In) W2 || R2 || Handle<Thread> || ThreadHandle
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || u32 || CoreMask0
| (Out) W1 || R1 || int32_t || CoreMask0
|-
|-
| (Out) X2 || R2, R3 || u64 || CoreMask1
| (Out) X2 || R2, R3 || uint64_t || CoreMask1
|}
|}
</div>
</div>
Line 599: Line 588:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R0 || Handle<Thread> || Handle
| (In) W0 || R0 || Handle<Thread> || ThreadHandle
|-
|-
| (In) W1 || R1 || u32 || CoreMask0
| (In) W1 || R1 || int32_t || CoreMask0
|-
|-
| (In) X2 || R2, R3 || u64 || CoreMask1
| (In) X2 || R2, R3 || uint64_t || CoreMask1
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 619: Line 608:
| (In) None || ||  
| (In) None || ||  
|-
|-
| (Out) W0/X0 || u64 || CpuId
| (Out) W0 || uint32_t || CpuId
|}
|}
</div>
</div>
Line 633: Line 622:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<WritableEvent> || Event
| (In) W0 || Handle<WritableEvent> || EventHandle
|-
|-
| (Out) X0 || [[#Result]] || Result
| (Out) X0 || [[#Result]] || Result
Line 656: Line 645:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<WritableEvent> or Handle<ReadableEvent> || Event
| (In) W0 || Handle<WritableEvent> or Handle<ReadableEvent> || EventHandle
|-
|-
| (Out) X0 || [[#Result]] || Result
| (Out) X0 || [[#Result]] || Result
Line 662: Line 651:
</div>
</div>


Takes the given event out of the signaled state.
Takes the given event out of the signaled state, if it is signaled.


=== Result codes ===
=== Result codes ===
Line 668: Line 657:


'''0xE401:''' Invalid handle. The handle either does not exist, or is not a ReadableEvent nor a WritableEvent.
'''0xE401:''' Invalid handle. The handle either does not exist, or is not a ReadableEvent nor a WritableEvent.
'''0xFA01:''' The handle was not in a signaled state.


== MapSharedMemory ==
== MapSharedMemory ==
Line 677: Line 664:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<SharedMemory> || MemHandle
| (In) W0 || Handle<SharedMemory> || SharedMemoryHandle
|-
|-
| (In) X1 || void* || Addr
| (In) X1 || void* || Address
|-
|-
| (In) X2 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (In) W3 || [[#Permission]] || Permissions
| (In) W3 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 699: Line 686:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<SharedMemory> || MemHandle
| (In) W0 || Handle<SharedMemory> || SharedMemoryHandle
|-
|-
| (In) X1 || void* || Addr
| (In) X1 || void* || Address
|-
|-
| (In) X2 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 715: Line 702:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || void* || Addr
| (In) X1 || void* || Address
|-
|-
| (In) X2 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (In) W3 || [[#Permission]] || Permissions
| (In) W3 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || Handle<TransferMemory> || Handle
| (Out) W1 || Handle<TransferMemory> || TransferMemoryHandle
|}
|}
</div>
</div>
Line 757: Line 744:
</div>
</div>


Resets the signal on the given handle, ensuring future calls to [[#WaitSynchronization]] on this handle will sleep until the handle is signaled again. If the handle is a ReadableEvent, this is equivalent to calling ClearEvent() on the handle.
Resets the signal on the given handle, ensuring future calls to [[#WaitSynchronization]] on this handle will sleep until the handle is signaled again. If the handle is a ReadableEvent, this returns ResultInvalidState if the event is not signaled.


If the handle is a Process, it will clear the signaled state (which is set when the process changes [[#ProcessState]]. Once the process enters the Exited state, calling ResetSignal on the process will no longer have an effect (the process is permanently signaled), and the syscall will return 0xFA01.
If the handle is a Process, it will clear the signaled state (which is set when the process changes [[#ProcessState]]. Once the process enters the Exited state, calling ResetSignal on the process will no longer have an effect (the process is permanently signaled), and the syscall will return 0xFA01.
Line 776: Line 763:
| (In) X1 || R1 || Handle* || HandlesPtr
| (In) X1 || R1 || Handle* || HandlesPtr
|-
|-
| (In) W2 || R2 || u64 || HandlesNum
| (In) W2 || R2 || int32_t || HandlesNum
|-
|-
| (In) X3 || R0, R3 || u64 || Timeout
| (In) X3 || R0, R3 || int64_t || Timeout
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || u64 || HandleIndex
| (Out) W1 || R1 || uint64_t || HandleIndex
|}
|}
</div>
</div>


Works with num_handles <= 0x40.
Works with HandlesNum <= 0x40.


When zero handles are passed, this will wait forever until either timeout or cancellation occurs.
When zero handles are passed, this will wait forever until either timeout or cancellation occurs.
Line 799: Line 786:
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#GetProcessInfo]]).
'''KProcess:''' signals when the process undergoes a state change (retrievable via [[#GetProcessInfo]]).


'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via SignalEvent.
'''KReadableEvent:''' signals when the event's corresponding KWritableEvent has been signaled via [[#SignalEvent]].


'''KServerPort:''' signals when there is an incoming connection waiting to be [[#AcceptSession|accepted]].
'''KServerPort:''' signals when there is an incoming connection waiting to be [[#AcceptSession|accepted]].
Line 828: Line 815:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Thread> || Handle
| (In) W0 || Handle<Thread> || ThreadHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 850: Line 837:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Thread> || Handle
| (In) W0 || Handle<Thread> || ThreadHandle
|-
|-
| (In) X1 || void* || Addr
| (In) X1 || void* || Address
|-
|-
| (In) W2 || u32 || Tag
| (In) W2 || uint32_t || Tag
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 866: Line 853:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || Addr
| (In) X0 || void* || Address
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 878: Line 865:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0 || void* || KeyAddr
| (In) X0 || R0 || void* || KeyAddress
|-
|-
| (In) X1 || R1 || void* || TagAddr
| (In) X1 || R1 || void* || TagAddress
|-
|-
| (In) W2 || R2 || u32 || Tag
| (In) W2 || R2 || uint32_t || Tag
|-
|-
| (In) X3 || R3, R4 || u64 || Timeout
| (In) X3 || R3, R4 || int64_t || Timeout
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 896: Line 883:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || Addr
| (In) X0 || void* || Address
|-
|-
| (In) W1 || u32 || Value
| (In) W1 || int32_t || Value
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 910: Line 897:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (Out) X0 || R0, R1 || u64 || Ticks
| (Out) X0 || R0, R1 || uint64_t || Ticks
|}
|}
</div>
</div>
Line 930: Line 917:
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || Handle<Session> || Handle
| (Out) W1 || Handle<Session> || SessionHandle
|}
|}
</div>
</div>
Line 940: Line 927:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Session> || Handle
| (In) W0 || Handle<Session> || SessionHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 952: Line 939:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Session> || Handle
| (In) W0 || Handle<Session> || SessionHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 964: Line 951:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || void* || CmdPtr
| (In) X0 || void* || Address
|-
|-
| (In) X1 || u64 || Size
| (In) X1 || uint64_t || Size
|-
|-
| (In) W2 || Handle<Session> || Handle
| (In) W2 || Handle<Session> || SessionHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 974: Line 961:
</div>
</div>


Size and CmdPtr must be 0x1000-aligned.
Size and Address must be 0x1000-aligned.


=== Result codes ===
=== Result codes ===
'''0x0:''' Success.
'''0x0:''' Success.


'''0xcc01:''' CmdPtr is not 0x1000-aligned.
'''0xcc01:''' Address is not 0x1000-aligned.


'''0xca01:''' Size is not 0x1000-aligned.
'''0xca01:''' Size is not 0x1000-aligned.
Line 993: Line 980:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || void* || CmdPtr
| (In) X1 || void* || Address
|-
|-
| (In) X2 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (In) W3 || Handle<Session> || Handle
| (In) W3 || Handle<Session> || SessionHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || Handle<ReadableEvent> || Event
| (Out) W1 || Handle<ReadableEvent> || EventHandle
|}
|}
</div>
</div>


Size and CmdPtr must be 0x1000-aligned.
Size and Address must be 0x1000-aligned.
 
|-
| 0x23 || || X1=cmdbufptr, X2=size, X3=handle || W0=result, W1=revent_handle
|-


== GetProcessId ==
== GetProcessId ==
Line 1,017: Line 1,000:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W1 || R1 || Handle<Process> || Handle
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1 || R1, R2 || u64 || ProcessId
| (Out) X1 || R1, R2 || uint64_t || ProcessId
|}
|}
</div>
</div>
Line 1,031: Line 1,014:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W1 || R1 || Handle<Thread> || Handle
| (In) W1 || R1 || Handle<Thread> || ThreadHandle
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1 || R1, R2 || u64 || ThreadId
| (Out) X1 || R1, R2 || uint64_t || ThreadId
|}
|}
</div>
</div>
Line 1,045: Line 1,028:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || u64 || Break Reason
| (In) X0 || [[#BreakReason]] || BreakReason
|-
|-
| (In) X1 || u64 ||
| (In) X1 || uint64_t ||
|-
|-
| (In) X2 || u64 || Info
| (In) X2 || uint64_t || Info
|-
|-
| (Out) W0 || [[#Result]] || 0 (Success)
| (Out) W0 || [[#Result]] || Result
|}
|}
</div>
</div>


If the process is attached, report the Break event. Then, if ContinueDebugEvent didn't apply IgnoreException on the thread: if TPIDR_EL0 is 0, adjust ELR_EL1 to retry to svc instruction (and set TPIDR_EL0 to 1).
If the process is attached, report the Break event. Then, if [[#ContinueDebugEvent]] didn't apply IgnoreException on the thread: if TPIDR_EL0 is 0, adjust ELR_EL1 to retry to svc instruction (and set TPIDR_EL0 to 1).


Otherwise, if bit31 in reason isn't set, perform crash reporting (see Exception Handling section below), if it doesn't terminate the process adjust ELR_EL1 as well.
Otherwise, 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.
Line 1,069: Line 1,052:
| (In) X0 || char* || String
| (In) X0 || char* || String
|-
|-
| (In) X1 || u64 || Size
| (In) X1 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 1,081: Line 1,064:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (Out) X0 || [[#Result]] || Result
| (In) W0 || [[#Result]] || Result
|}
|}
</div>
</div>
Line 1,091: Line 1,074:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W1 || R1 || u32 || InfoId0
| (In) W1 || R1 || [[#InfoType]] || InfoType
|-
|-
| (In) W2 || R2 || Handle || Handle
| (In) W2 || R2 || Handle || Handle
|-
|-
| (In) X3 || R0, R3 || u64 || InfoId1
| (In) X3 || R0, R3 || uint64_t || InfoSubType
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1 || R1, R2 || u64 || Out
| (Out) X1 || R1, R2 || uint64_t || Info
|}
|}
</div>
</div>


{| class=wikitable
== FlushEntireDataCache ==
! Handle type || InfoId0 || InfoId1 || Description
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| Process || 0 || 0 || AllowedCpuIdBitmask
! Argument || Type || Name
|-
|-
| Process || 1 || 0 || AllowedThreadPrioBitmask
| (In) None || ||
|-
|-
| Process || 2 || 0 || AliasRegionBaseAddr
| (Out) None || ||
|}
</div>
 
== FlushDataCache ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| Process || 3 || 0 || AliasRegionSize
! Argument || Type || Name
|-
|-
| Process || 4 || 0 || HeapRegionBaseAddr
| (In) X0 || void* || Address
|-
|-
| Process || 5 || 0 || HeapRegionSize
| (In) X1 || uint64_t || Size
|-
|-
| Process || 6 || 0 || TotalMemoryAvailable. Total memory available(free+used).
| (Out) W0 || [[#Result]] || Result
|}
</div>
 
== MapPhysicalMemory ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| Process || 7 || 0 || TotalMemoryUsage. Total used size of codebin memory + main-thread stack + allocated heap.
! Argument || Type || Name
|-
|-
| Zero    || 8 || 0 || IsCurrentProcessBeingDebugged
| (In) X0 || void* || Address
|-
|-
| Zero    || 9 || 0 || Returns ResourceLimit handle for current process. Used by [[Process_Manager_services|PM]].
| (In) X1 || uint64_t || Size
|-
|-
| Zero    || 10 || -1, {current coreid} || IdleTickCount
| (Out) W0 || [[#Result]] || Result
|-
|}
| Zero    || 11 || 0-3 || RandomEntropy from current process. TRNG. Used to seed usermode PRNGs.
</div>
|-
 
| Process || 12 || 0 || [2.0.0+] AddressSpaceBaseAddr
Acts like [[#SetHeapSize]] except you can allocate heap at any address you'd like.
|-
 
| Process || 13 || 0 || [2.0.0+] AddressSpaceSize
Uses current process pool partition.
|-
 
| Process || 14 || 0 || [2.0.0+] StackRegionBaseAddr
=== Result codes ===
|-
'''0x0:''' Success.
| Process || 15 || 0 || [2.0.0+] StackRegionSize
 
'''0xCA01:''' Invalid size passed. It's either zero or not 4k-aligned
 
'''0xCC01:''' Invalid address. (not 4k-aligned)
 
'''0xDC01:''' Invalid memory range. It's either causes overflow, or does not fall into "reserved" address range (aka Alias). See AliasRegionAddress at [[#InfoType]]
 
'''0xFA01:''' Invalid state. (not enough SystemResource (see [[NPDM#SystemResourceSize]]))
 
== UnmapPhysicalMemory ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| Process || 16 || 0 || [3.0.0+] PersonalMmHeapSize
! Argument || Type || Name
|-
|-
| Process || 17 || 0 || [3.0.0+] PersonalMmHeapUsage
| (In) X0 || void* || Address
|-
|-
| Process || 18 || 0 || [3.0.0+] TitleId
| (In) X1 || uint64_t || Size
|-
|-
| Zero    || 19 || 0 || [4.0.0-4.1.0] PrivilegedProcessId_LowerBound
| (Out) W0 || [[#Result]] || Result
|}
</div>
 
== GetDebugFutureThreadInfo ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| Zero    || 19 || 1 || [4.0.0-4.1.0] PrivilegedProcessId_UpperBound
! Argument64 || Argument32 || Type || Name
|-
|-
| Process || 20 || 0 || [5.0.0+] UserExceptionContextAddr
| (In) X3 || R0, R1 || uint64_t || Timeout
|-
|-
| Process || 21 || 0 || [6.0.0+] TotalMemoryAvailableWithoutMmHeap
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| Process || 22 || 0 || [6.0.0+] TotalMemoryUsedWithoutMmHeap
| (Out) X1 || uint64_t || LastThreadContextParam0
|-
|-
| Process || 23 || 0 || [9.0.0+] IsApplication
| (Out) X2 || uint64_t || LastThreadContextParam1
|-
|-
| 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.
| (Out) X3 || uint64_t || LastThreadContextParam2
|}
 
== FlushEntireDataCache ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
! Argument || Type || Name
| (Out) X4 || uint64_t || LastThreadContextParam3
|-
|-
| (In) None || ||
| (Out) X5 || uint64_t ||
|-
|-
| (Out) None || ||
| (Out) W6 || uint32_t ||
|}
|}
</div>
</div>


== FlushDataCache ==
== GetLastThreadInfo ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,177: Line 1,185:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || u64 || Address
| (In) None || ||  
|-
|-
| (In) X1 || u64 || Size
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) X1 || uint64_t || LastThreadContextParam0
|}
|-
</div>
| (Out) X2 || uint64_t || LastThreadContextParam1
 
== MapPhysicalMemory ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
! Argument || Type || Name
| (Out) X3 || uint64_t || LastThreadContextParam2
|-
|-
| (In) X0 || u64 || Address
| (Out) X4 || uint64_t || LastThreadContextParam3
|-
|-
| (In) X1 || u64 || Size
| (Out) X5 || uint64_t ||
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W6 || uint32_t ||
|}
|}
</div>
</div>


Acts like [[#SetHeapSize]] except you can allocate heap at any address you'd like.
== GetResourceLimitLimitValue ==
 
Uses current process pool partition.
 
== UnmapPhysicalMemory ==
<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 || R1 || Handle<ResourceLimit> || ResourceLimitHandle
|-
|-
| (In) X0 || u64 || Address
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
|-
|-
| (In) X1 || u64 || Size
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) X1 || R1, R2 || int64_t || LimitValue
|}
|}
</div>
</div>


== GetFutureThreadInfo ==
== GetResourceLimitCurrentValue ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,223: Line 1,225:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X3 || R0, R1 || u64 || Timeout
| (In) W1 || R1 || Handle<ResourceLimit> || ResourceLimitHandle
|-
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1 || u64 || LastThreadContextParam0
| (Out) X1 || R1, R2 || int64_t || CurrentValue
|-
| (Out) X2 || u64 || LastThreadContextParam1
|-
| (Out) X3 || u64 || LastThreadContextParam2
|-
| (Out) X4 || u64 || LastThreadContextParam3
|-
| (Out) X5 || u64 ||
|-
| (Out) W6 || u32 ||
|}
|}
</div>
</div>


== GetLastThreadInfo ==
== SetThreadActivity ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,247: Line 1,241:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) None || ||  
| (In) W0 || Handle<Thread> || ThreadHandle
|-
| (In) W1 || [[#ThreadActivity]] || ThreadActivity
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|}
</div>
== GetThreadContext3 ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| (Out) X1 || u64 || LastThreadContextParam0
! Argument || Type || Name
|-
|-
| (Out) X2 || u64 || LastThreadContextParam1
| (In) X0 || [[#ThreadContext]]* || ThreadContext
|-
|-
| (Out) X3 || u64 || LastThreadContextParam2
| (In) W1 || Handle<Thread> || ThreadHandle
|-
|-
| (Out) X4 || u64 || LastThreadContextParam3
| (Out) W0 || [[#Result]] || Result
|-
| (Out) X5 || u64 ||
|-
| (Out) W6 || u32 ||
|}
|}
</div>
</div>


== GetResourceLimitLimitValue ==
== WaitForAddress ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,271: Line 1,269:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W1 || R1 || Handle<ResourceLimit> || Handle
| (In) X0 || R0 || void* || Address
|-
| (In) W1 || R1 || [[#ArbitrationType]] || ArbitrationType
|-
| (In) W2 || R2 || uint32_t || Value
|-
|-
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
| (In) X3 || R3, R4 || uint64_t || Timeout
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) X1 || R1, R2 || u64 || LimitValue
|}
|}
</div>
</div>


== GetResourceLimitCurrentValue ==
== SignalToAddress ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,287: Line 1,287:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W1 || R1 || Handle<ResourceLimit> || Handle
| (In) X0 || R0 || void* || Address
|-
| (In) W1 || R1 || [[#SignalType]] || SignalType
|-
|-
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
| (In) W2 || R2 || uint32_t || Value
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (In) W3 || R3 || uint32_t || NumToSignal
|-
|-
| (Out) X1 || R1, R2 || u64 || CurrentValue
| (Out) W0 || R0  || [[#Result]] || Result
|}
|}
</div>
</div>


== SetThreadActivity ==
== SynchronizePreemptionState ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,303: Line 1,305:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Thread> || ThreadHandle
| (In) None || ||  
|-
|-
| (In) W1 || ThreadActivity || ThreadActivity
| (Out) None || ||  
|-
| (Out) W0 || [[#Result]] || Result
|}
|}
</div>
</div>


== GetThreadContext3 ==
== GetResourceLimitPeakValue ==
<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 || R1 || Handle<ResourceLimit> || ResourceLimitHandle
|-
|-
| (In) X0 || [[#ThreadContext]]* || ThreadContext
| (In) W2 || R2 || [[#LimitableResource]] || LimitableResource
|-
|-
| (In) W1 || Handle<Thread> || ThreadHandle
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) X1 || R1, R2 || int64_t || PeakValue
|}
|}
</div>
</div>


== WaitForAddress ==
== DumpInfo ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Argument64 || Argument32 || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || R0 || u64 || Address
| (In) X0 || [[#DumpInfoType]] || DumpInfoType
|-
|-
| (In) W1 || R1 || [[#ArbitrationType]] || ArbitrationType
| (In) X1 || uint64_t || DumpInfoSubType
|-
|-
| (In) W2 || R2 || u32 || Value
| (Out) W0 || [[#Result]] || Result
|-
| (In) X3 || R3, R4 || u64 || Timeout
|-
| (Out) None || || ||
|}
|}
</div>
</div>


== SignalToAddress ==
Stubbed in retail kernel.
 
[4.0.0+] This function was removed and replaced by [[#KernelDebug]].
 
== KernelDebug ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Argument64 || Argument32 || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || R0 || u64 || Address
| (In) W0 || [[#KernelDebugType]] || KernelDebugType
|-
|-
| (In) W1 || R1 || [[#SignalType]] || SignalType
| (In) X1 || uint64_t ||  
|-
|-
| (In) W2 || R2 || u32 || Value
| (In) X2 || uint64_t ||  
|-
|-
| (In) W3 || R3 || u32 || NumToSignal
| (In) X3 || uint64_t ||  
|-
|-
| (Out) None || || ||
| (Out) W0 || [[#Result]] || Result
|}
|}
</div>
</div>


== SynchronizePreemptionState ==
Stubbed in retail kernel.
 
== ChangeKernelTraceState ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,367: Line 1,371:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) None || ||  
| (In) W0 || [[#KernelTraceState]] || KernelTraceState
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 1,373: Line 1,377:
</div>
</div>


== DumpInfo ==
Stubbed in retail kernel.
 
== CreateSession ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,379: Line 1,385:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || DumpInfoType || DumpInfoType
| (In) W2 || bool || IsLight
|-
|-
| (In) X1 || u64 ||  
| (In) X3 || uint64_t || Name
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<ServerSession> || ServerSessionHandle
|-
| (Out) W2 || Handle<ClientSession> || ClientSessionHandle
|}
|}
</div>
</div>


Stubbed in retail kernel.
== AcceptSession ==
 
[4.0.0+] This function was removed and replaced by [[#KernelDebug]].
 
== KernelDebug ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,397: Line 1,403:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || KernelDebugType || KernelDebugType
| (In) W1 || Handle<Port> || PortHandle
|-
|-
| (In) X1 || u64 ||
| (Out) W0 || [[#Result]] || Result
|-
| (In) X2 || u64 ||  
|-
|-
| (In) X3 || u64 ||
| (Out) W1 || Handle<ServerSession> || ServerSessionHandle
|-
| (Out) W0 || [[#Result]] || Result
|}
|}
</div>
</div>


Stubbed in retail kernel.
=== Result codes ===
'''0xf201:''' No session waiting to be accepted


== ChangeKernelTraceState ==
== ReplyAndReceiveLight ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,417: Line 1,420:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || KernelTraceState || KernelTraceState
| (In) W0 || Handle<Port> or Handle<ServerSession> || Handle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 1,423: Line 1,426:
</div>
</div>


Stubbed in retail kernel.
== ReplyAndReceive ==
 
== CreateSession ==
<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) W2 || bool || IsLight
| (In) X1 || R1 || Handle<Port>* or Handle<ServerSession>* || Handles
|-
|-
| (In) X3 || u64 || Name
| (In) W2 || R2 || uint32_t || NumHandles
|-
|-
| (Out) W0 || [[#Result]] || Result
| (In) W3 || R3 || Handle<ServerSession> || ReplyTargetSessionHandle
|-
|-
| (Out) W1 || Handle<ServerSession> || ServerHandle
| (In) X4 || R0, R4 || uint64_t || Timeout
|-
|-
| (Out) W2 || Handle<ClientSession> || ClientHandle
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) W1 || R1 || uint32_t || HandleIndex
|}
|}
</div>
</div>


== AcceptSession ==
If ReplyTargetSessionHandle is not zero, a reply from the TLS will be sent to that session.
Then it will wait until either of the passed sessions has an incoming message, is closed, a passed port has an incoming connection, or the timeout expires.
If there is an incoming message, it is copied to the TLS.
 
If ReplyTargetSessionHandle 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 ReplyTargetSessionHandle is not zero.
 
After being validated, passed handles will be enumerated in order; even if a session has been closed, if one that appears earlier in the list has an incoming message, it will take priority and a result code of 0x0 will be returned.
 
=== Result codes ===
'''0x0:''' Success. Either a session has an incoming message or a port has an incoming connection. HandleIndex is set appropriately.
 
'''0xea01:''' Timeout. No handles were signalled before the timeout expired. HandleIndex is not updated.
 
'''0xf601:''' Port remote dead. One of the sessions has been closed. HandleIndex is set appropriately.
 
== ReplyAndReceiveWithUserBuffer ==
<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 || R1 || void* || Address
|-
| (In) X2 || R2 || uint64_t || Size
|-
| (In) X3 || R3 || Handle<Port>* or Handle<ServerSession>* || Handles
|-
| (In) W4 || R0 || uint32_t || NumHandles
|-
| (In) W5 || R4 || Handle<ServerSession> || ReplyTargetSessionHandle
|-
|-
| (In) W1 || Handle<Port> || Port
| (In) X6 || R5, R6 || uint64_t || Timeout
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || Handle<ServerSession> || Session
| (Out) W1 || R1 || uint32_t || HandleIndex
|}
|}
</div>
</div>


=== Result codes ===
== CreateEvent ==
'''0xf201:''' No session waiting to be accepted
 
== ReplyAndReceiveLight ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,466: Line 1,491:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Port> or Handle<ServerSession> || Handle
| (In) None || ||
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<WritableEvent> || WritableEventHandle
|-
| (Out) W2 || Handle<ReadableEvent> || ReadableEventHandle
|}
|}
</div>
</div>


== ReplyAndReceive ==
== MapPhysicalMemoryUnsafe ==
<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) W1 || R1 || Handle<Port>* or Handle<ServerSession>* || Handles
| (In) X0 || void* || Address
|-
|-
| (In) W2 || R2 || u32 || NumHandles
| (In) X1 || uint64_t || Size
|-
|-
| (In) W3 || R3 || Handle<ServerSession> || ReplyTarget
| (Out) W0 || [[#Result]] || Result
|-
| (In) X4 || R0, R4 || u64 || Timeout
|-
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) W1 || R1 || u32 || HandleIndex
|}
|}
</div>
</div>


If ReplyTarget is not zero, a reply from the TLS will be sent to that session.
Same as [[#MapPhysicalMemory]] except it always uses pool partition 0.
Then it will wait until either of the passed sessions has an incoming message, is closed, a passed port has an incoming connection, or the timeout expires.
If there is an incoming message, it is copied to the TLS.


If ReplyTarget is zero, the TLS should contain a blank message. If this message has a C descriptor, the buffer it points to will be used as the pointer buffer. See [[IPC_Marshalling#IPC_buffers]]. Note that a pointer buffer cannot be specified if ReplyTarget is not zero.
== UnmapPhysicalMemoryUnsafe ==
 
After being validated, passed handles will be enumerated in order; even if a session has been closed, if one that appears earlier in the list has an incoming message, it will take priority and a result code of 0x0 will be returned.
 
=== Result codes ===
'''0x0:''' Success. Either a session has an incoming message or a port has an incoming connection. HandleIndex is set appropriately.
 
'''0xea01:''' Timeout. No handles were signalled before the timeout expired. HandleIndex is not updated.
 
'''0xf601:''' Port remote dead. One of the sessions has been closed. HandleIndex is set appropriately.
 
== ReplyAndReceiveWithUserBuffer ==
<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 || u64 || Address
| (In) X0 || void* || Address
|-
|-
| (In) X2 || R2 || u64 || Size
| (In) X1 || uint64_t || Size
|-
|-
| (In) X3 || R3 || Handle<Port>* or Handle<ServerSession>* || Handles
| (Out) W0 || [[#Result]] || Result
|-
|}
| (In) W4 || R0 || u32 || NumHandles
</div>
|-
| (In) W5 || R4 || Handle<ServerSession> || ReplyTarget
|-
| (In) X6 || R5, R6 || u64 || Timeout
|-
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) W1 || R1 || u32 || HandleIndex
|}
</div>


== CreateEvent ==
== SetUnsafeLimit ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,537: Line 1,537:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) None || ||
| (In) X0 || uint64_t || Limit
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<WritableEvent> || WritableEvent
|-
| (Out) W2 || Handle<ReadableEvent> || ReadableEvent
|}
|}
</div>
</div>


== MapPhysicalMemoryUnsafe ==
== CreateCodeMemory ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,553: Line 1,549:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || u64 || Address
| (In) X1 || void* || Address
|-
|-
| (In) X1 || u64 || Size
| (In) X2 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<CodeMemory> || CodeMemoryHandle
|}
|}
</div>
</div>


Same as [[#MapPhysicalMemory]] except it always uses pool partition 0.
Takes an address range with backing memory to create the code memory object.
 
The memory is initially memset to 0xFF after being locked.


== UnmapPhysicalMemoryUnsafe ==
== ControlCodeMemory ==
<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<CodeMemory> || CodeMemoryHandle
|-
| (In) W1 || R1 || [[#CodeMemoryOperation]] || CodeMemoryOperation
|-
| (In) X2 || R2, R3 || void* || Address
|-
|-
| (In) X0 || u64 || Address
| (In) X3 || R4, R5 || uint64_t || Size
|-
|-
| (In) X1 || u64 || Size
| (In) W4 || R6 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|}
|}
</div>
</div>


== SetUnsafeLimit ==
Maps the backing memory for a CodeMemory object into the current process.
<div style="display: inline-block;">
 
{| class="wikitable" border="1"
For [[#CodeMemoryOperation|MapOwner]], memory permission must be RW-.
|-
 
! Argument || Type || Name
For [[#CodeMemoryOperation|MapSlave]], memory permission must be R-- or R-X.
|-
 
| (In) X0 || u64 || Limit
Operations [[#CodeMemoryOperation|UnmapOwner/UnmapSlave]] unmap memory that was previously mapped this way.
|-
 
| (Out) W0 || [[#Result]] || Result
This allows one "secure JIT" process to map the code memory as RW-, and the other "slave" process to map it R-X.
|}
 
</div>
[5.0.0+] Error 0xE401 is now returned when the process owner of the Code memory object is the same as the current process.


== CreateCodeMemory ==
== SleepSystem ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,595: Line 1,601:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || u64 || Address
| (In) None || ||  
|-
|-
| (In) X2 || u64 || Size
| (Out) None || ||  
|-
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<CodeMemory> || Handle
|}
|}
</div>
</div>


Takes an address range with backing memory to create the code memory object.
== ReadWriteRegister ==
 
The memory is initially memset to 0xFF after being locked.
 
== ControlCodeMemory ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,615: Line 1,613:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R0 || Handle<CodeMemory> || Handle
| (In) X1 || R2, R3 || uint64_t || RegisterAddress
|-
| (In) W1 || R1 || [[#CodeMemoryOperation]] || CodeMemoryOperation
|-
|-
| (In) X2 || R2, R3 || u64 || Address
| (In) W2 || R0 || uint32_t || RwMask
|-
|-
| (In) X3 || R4, R5 || u64 || Size
| (In) W3 || R1 || uint32_t || InValue
|-
|-
| (In) W4 || R6 || MemoryPermission || Permission
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W1 || R1 || uint32_t || OutValue
|}
|}
</div>
</div>


Maps the backing memory for a Code memory object into the current process.
Read/write IO registers with a hardcoded whitelist. Input address is physical-address and must be aligned to 4.


For [[#CodeMemoryOperation|CodeMemoryOperation_MapOwner]], memory permission must be RW-.
rw_mask is 0 for reading and 0xffffffff for writing. You can also write individual bits by using a mask value.


For [[#CodeMemoryOperation|CodeMemoryOperation_MapSlave]], memory permission must be R-- or R-X.
You can only write to registers inside physical pages 0x70019000 (MC), 0x7001C000 (MC0), 0x7001D000 (MC1), and they all share the same whitelist.


Operations [[#CodeMemoryOperation|CodeMemoryOperation_UnmapOwner/CodeMemoryOperation_UnmapSlave]] unmap memory that was previously mapped this way.
The whitelist is same for writing as for reading.


This allows one "secure JIT" process to map the code memory as RW-, and the other "slave" process to map it R-X.
The whitelist is:
 
0x054, 0x090, 0x094, 0x098, 0x09c, 0x0a0, 0x0a4, 0x0a8, 0x0ac, 0x0b0, 0x0b4, 0x0b8, 0x0bc, 0x0c0, 0x0c4, 0x0c8, 0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x0e0, 0x100, 0x108, 0x10c, 0x118, 0x11c, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, 0x158, 0x15c, 0x164, 0x168, 0x16c, 0x170, 0x174, 0x178, 0x17c, 0x200, 0x204, 0x2e4, 0x2e8, 0x2ec, 0x2f4, 0x2f8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37c, 0x380, 0x390, 0x394, 0x398, 0x3ac, 0x3b8, 0x3bc, 0x3c0, 0x3c4, 0x3d8, 0x3e8, 0x41c, 0x420, 0x424, 0x428, 0x42c, 0x430, 0x44c, 0x47c, 0x480, 0x484, 0x50c, 0x554, 0x558, 0x55c, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69c, 0x6a0, 0x6a4, 0x6c0, 0x6c4, 0x6f0, 0x6f4, 0x960, 0x970, 0x974, 0xa20, 0xa24, 0xb88, 0xb8c, 0xbc4, 0xbc8, 0xbcc, 0xbd0, 0xbd4, 0xbd8, 0xbdc, 0xbe0, 0xbe4, 0xbe8, 0xbec, 0xc00, 0xc5c, 0xcac
 
[2.0.0+] Whitelist was extended with 0x4c4, 0x4c8, 0x4cc, 0x584, 0x588, 0x58c.
 
[2.0.0+] The IO registers in range 0x7000E400 (PMC) size 0xC00 skip the whitelist, and do a TrustZone call using [[SMC#ReadWriteRegister|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 the SMC [[SMC#ReadWriteRegister|ReadWriteRegister]] (checked in addition to the whitelist in the ReadWriteRegister SVC), relative to the start of the MC registers:


[5.0.0+] Error 0xE401 is now returned when the process owner of the Code memory object is the same as the current process.
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


== SleepSystem ==
== SetProcessActivity ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,647: Line 1,657:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) None || ||  
| (In) W0 || Handle<Process> || ProcessHandle
|-
| (In) W1 || [[#ProcessActivity]] || ProcessActivity
|-
|-
| (Out) None || ||  
| (Out) W0 || [[#Result]] || Result
|}
|}
</div>
</div>


== ReadWriteRegister ==
== CreateSharedMemory ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Argument64 || Argument32 || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || R2, R3 || u64 || RegAddr
| (In) W1 || uint64_t || Size
|-
|-
| (In) W2 || R0 || u64 || RwMask
| (In) W2 || [[#MemoryPermission]] || LocalMemoryPermission
|-
|-
| (In) W3 || R1 || u64 || InValue
| (In) W3 || [[#MemoryPermission]] || RemoteMemoryPermission
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || u64 || OutValue
| (Out) W1 || Handle<SharedMemory> || SharedMemoryHandle
|}
|}
</div>
</div>


Read/write IO registers with a hardcoded whitelist. Input address is physical-address and must be aligned to 4.
Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.


rw_mask is 0 for reading and 0xffffffff for writing. You can also write individual bits by using a mask value.
Allocates memory from the current process' pool partition.


You can only write to registers inside physical pages 0x70019000 (MC), 0x7001C000 (MC0), 0x7001D000 (MC1), and they all share the same whitelist.
== MapTransferMemory ==
 
The whitelist is same for writing as for reading.
 
The whitelist is:
 
0x054, 0x090, 0x094, 0x098, 0x09c, 0x0a0, 0x0a4, 0x0a8, 0x0ac, 0x0b0, 0x0b4, 0x0b8, 0x0bc, 0x0c0, 0x0c4, 0x0c8, 0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x0e0, 0x100, 0x108, 0x10c, 0x118, 0x11c, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, 0x158, 0x15c, 0x164, 0x168, 0x16c, 0x170, 0x174, 0x178, 0x17c, 0x200, 0x204, 0x2e4, 0x2e8, 0x2ec, 0x2f4, 0x2f8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37c, 0x380, 0x390, 0x394, 0x398, 0x3ac, 0x3b8, 0x3bc, 0x3c0, 0x3c4, 0x3d8, 0x3e8, 0x41c, 0x420, 0x424, 0x428, 0x42c, 0x430, 0x44c, 0x47c, 0x480, 0x484, 0x50c, 0x554, 0x558, 0x55c, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69c, 0x6a0, 0x6a4, 0x6c0, 0x6c4, 0x6f0, 0x6f4, 0x960, 0x970, 0x974, 0xa20, 0xa24, 0xb88, 0xb8c, 0xbc4, 0xbc8, 0xbcc, 0xbd0, 0xbd4, 0xbd8, 0xbdc, 0xbe0, 0xbe4, 0xbe8, 0xbec, 0xc00, 0xc5c, 0xcac
 
[2.0.0+] Whitelist was extended with 0x4c4, 0x4c8, 0x4cc, 0x584, 0x588, 0x58c.
 
[2.0.0+] The IO registers in range 0x7000E400 (PMC) size 0xC00 skip the whitelist, and do a TrustZone call using [[SMC#ReadWriteRegister|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 the SMC [[SMC#ReadWriteRegister|ReadWriteRegister]] (checked in addition to the whitelist in the ReadWriteRegister SVC), relative to the start of the MC registers:
 
0x000, 0x004, 0x008, 0x00C, 0x010, 0x01C, 0x020, 0x030, 0x034, 0x050, 0x054, 0x090, 0x094, 0x098, 0x09C, 0x0A0, 0x0A4, 0x0A8, 0x0AC, 0x0B0, 0x0B4, 0x0B8, 0x0BC, 0x0C0, 0x0C4, 0x0C8, 0x0D0, 0x0D4, 0x0D8, 0x0DC, 0x0E0, 0x100, 0x108, 0x10C, 0x118, 0x11C, 0x124, 0x128, 0x12C, 0x130, 0x134, 0x138, 0x13C, 0x158, 0x15C, 0x164, 0x168, 0x16C, 0x170, 0x174, 0x178, 0x17C, 0x200, 0x204, 0x238, 0x240, 0x244, 0x250, 0x254, 0x258, 0x264, 0x268, 0x26C, 0x270, 0x274, 0x280, 0x284, 0x288, 0x28C, 0x294, 0x2E4, 0x2E8, 0x2EC, 0x2F4, 0x2F8, 0x310, 0x314, 0x320, 0x328, 0x344, 0x348, 0x370, 0x374, 0x37C, 0x380, 0x390, 0x394, 0x398, 0x3AC, 0x3B8, 0x3BC, 0x3C0, 0x3C4, 0x3D8, 0x3E8, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430, 0x44C, 0x47C, 0x480, 0x484, 0x4C4, 0x4C8, 0x4CC, 0x50C, 0x554, 0x558, 0x55C, 0x584, 0x588, 0x58C, 0x670, 0x674, 0x690, 0x694, 0x698, 0x69C, 0x6A0, 0x6A4, 0x6C0, 0x6C4, 0x6F0, 0x6F4, 0x960, 0x970, 0x974, 0x9B8, 0xA20, 0xA24, 0xA88, 0xA94, 0xA98, 0xA9C, 0xAA0, 0xAA4, 0xAA8, 0xAAC, 0xAB0, 0xAB4, 0xAB8, 0xABC, 0xAC0, 0xAC4, 0xAC8, 0xACC, 0xAD0, 0xAD4, 0xAD8, 0xADC, 0xAE0, 0xB88, 0xB8C, 0xBC4, 0xBC8, 0xBCC, 0xBD0, 0xBD4, 0xBD8, 0xBDC, 0xBE0, 0xBE4, 0xBE8, 0xBEC, 0xC00, 0xC5C, 0xCAC
 
== SetProcessActivity ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,703: Line 1,693:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || Handle<Process> ||  
| (In) X0 || Handle<TransferMemory> || TransferMemoryHandle
|-
| (In) X1 || void* || Address
|-
| (In) X2 || uint64_t || Size
|-
|-
| (In) W1 || ProcessActivity || ProcessActivity
| (In) W3 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 1,711: Line 1,705:
</div>
</div>


== CreateSharedMemory ==
You must pass same size and permissions as given in [[#CreateTransferMemory]], otherwise error.
 
== UnmapTransferMemory ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,717: Line 1,713:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W1 || u64 || Size
| (In) X0 || Handle<TransferMemory> || TransferMemoryHandle
|-
|-
| (In) W2 || MemoryPermission || LocalPerm
| (In) X1 || void* || Address
|-
|-
| (In) W3 || MemoryPermission || RemotePerm
| (In) X2 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<SharedMemory> || MemHandle
|}
|}
</div>
</div>


Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.
Size must match size given in map syscall, otherwise there's an invalid-size error.


Allocates memory from the current process' pool partition.
== CreateInterruptEvent ==
 
== MapTransferMemory ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,739: Line 1,731:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || Handle<TransferMemory> || MemHandle
| (In) X1 || [[#Interrupt]] || Interrupt
|-
|-
| (In) X1 || void* || Addr
| (In) W2 || [[#InterruptType]] || InterruptType
|-
|-
| (In) X2 || u64 || Size
| (Out) W0 || [[#Result]] || Result
|-
|-
| (In) W3 || MemoryPermission || Permission
| (Out) W1 || Handle<ReadableEvent> || ReadableEventHandle
|-
| (Out) W0 || [[#Result]] || Result
|}
|}
</div>
</div>


The newly mapped pages will have [[#MemoryState]] type 0xE.
Creates an event handle for the given IRQ number. Waiting on this handle will wait until the IRQ is triggered. The InterruptType argument configures the triggering. If it is 0, the IRQ is active HIGH level sensitive, if it is 1 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.


You must pass same size and permissions as given in [[#CreateTransferMemory]], otherwise error.
'''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.


== UnmapTransferMemory ==
== QueryPhysicalAddress ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 1,761: Line 1,762:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || Handle<TransferMemory> || MemHandle
| (In) X1 || void* || VirtualAddress
|-
| (Out) W0 || [[#Result]]|| Result
|-
|-
| (In) X1 || void* || Addr
| (Out) X1 || uint64_t || PhysicalMemoryInfoAddress
|-
|-
| (In) X2 || u64 || Size
| (Out) X2 || uint64_t || PhysicalMemoryInfoBaseAddress
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) X3 || uint64_t || PhysicalMemoryInfoSize
|}
|}
</div>
</div>


Size must match size given in map syscall, otherwise there's an invalid-size error.
Queries the physical address of a virtual address. Will always fetch the lowest page-aligned mapping that contains the provided physical address.
 
The returned PhysicalMemoryInfoBaseAddress is the virtual address of that page-aligned mapping, while PhysicalMemoryInfoAddress is the physical address of that page. PhysicalMemoryInfoSize is the amount of continuous physical memory in that mapping.


== CreateInterruptEvent ==
== QueryIoMapping ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Argument || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X1 || u64 || IrqNum
| (In) X1 || R2, R3 || uint64_t || IoAddress
|-
|-
| (In) W2 || bool || Flags
| (In) X2 || R0 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || Handle<ReadableEvent> || ReadableEventHandle
| (Out) X1 || R1 || void* || VirtualAddress
|}
|}
</div>
</div>


Creates an event handle for the given IRQ number. Waiting on this handle will wait until the IRQ is triggered. The flags argument configures the triggering. If it is false, the IRQ is active HIGH level sensitive, if it is true it is rising-edge sensitive.
Returns a virtual address mapped to a given IO range.


=== Result codes ===
== CreateDeviceAddressSpace ==
'''0x0:''' Success.
 
'''0xF001:''' Flags was > 1
 
'''0xF201:''' IRQ above 0x3FF or outside the [[NPDM#Kernel_Access_Control|IRQ access mask]] was given.
 
'''0xCE01:''' A SlabHeap was exhausted (too many interrupts created).
 
'''0xF401:''' IRQ already has an event registered.
 
'''0xD201:''' The handle table is full. Try closing some handles.
 
== QueryPhysicalAddress ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Argument || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X1 || u64 || Addr
| (In) X1 || R2, R3 || uint64_t || DeviceAddressSpaceStartAddress
|-
|-
| (Out) W0 || [[#Result]]|| Result
| (In) X2 || R0, R1 || uint64_t || DeviceAddressSpaceEndAddress
|-
|-
| (Out) X1 || u64 || PhysAddr
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) X2 || u64 || BaseAddr
|-
|-
| (Out) X3 || u64 || Size
| (Out) W1 || R1 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|}
|}
</div>
</div>


Queries the physical address of a virtual address. Will always fetch the lowest page-aligned mapping that contains the provided physical address.
Creates a virtual address space for binding device address spaces and returns a handle.


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.
StartAddr is normally set to 0 and EndAddr is normally set to 0xFFFFFFFF.


== QueryIoMapping ==
== AttachDeviceAddressSpace ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Argument64 || Argument32 || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || R2, R3 || u64 || PhysAddr
| (In) W0 || [[#DeviceName]] || DeviceName
|-
|-
| (In) X2 || R0 || u64 || Size
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|-
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) X1 || R1 || void* || VirtAddr
|}
</div>
 
Returns a virtual address mapped to a given IO range.
 
== CreateDeviceAddressSpace ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument64 || Argument32 || Type || Name
|-
| (In) X1 || R2, R3 || u64 || StartAddr
|-
| (In) X2 || R0, R1 || u64 || EndAddr
|-
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) W1 || R1 || Handle<DeviceAddressSpace> || AddressSpaceHandle
|}
</div>
 
Creates a virtual address space for binding device address spaces and returns a handle.
 
StartAddr is normally set to 0 and EndAddr is normally set to 0xFFFFFFFF.
 
== AttachDeviceAddressSpace ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument || Type || Name
|-
| (In) W0 || [[#DeviceName]] || DeviceId
|-
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 1,886: Line 1,838:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) W0 || [[#DeviceName]] || DeviceId
| (In) W0 || [[#DeviceName]] || DeviceName
|-
|-
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAsHandle
| (In) X1 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 1,902: Line 1,854:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|-
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (In) X2 || R2, R3 || void* || SrcAddr
| (In) X2 || R2, R3 || void* || Address
|-
|-
| (In) X3 || R4 || u64 || DeviceAsSize
| (In) X3 || R4 || uint64_t || DeviceAddressSpaceSize
|-
|-
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
| (In) X4 || R5, R6 || uint64_t || DeviceAddressSpaceAddress
|-
|-
| (In) W5 || R7 || MemoryPermission || Permissions
| (In) W5 || R7 || uint32_t || Option
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 1,920: Line 1,872:
Maps an attached device address space to an userspace address.
Maps an attached device address space to an userspace address.


dev_map_addr is the userspace destination address, while dev_as_addr is the source address between dev_as_start_addr and dev_as_end_addr (passed to [[#CreateDeviceAddressSpace]]).
Address is the userspace destination address, while DeviceAddressSpaceAddress is the source address between DeviceAddressSpaceStartAddress and DeviceAddressSpaceEndAddress (passed to [[#CreateDeviceAddressSpace]]).


The userspace destination address must have the [[SVC#MemoryState|MapDeviceAllowed]] bit set. Bit [[SVC#MemoryAttribute|IsDeviceMapped]] will be set after mapping.
The userspace destination address must have the [[SVC#MemoryState|FlagCanDeviceMap]] bit set. Bit [[SVC#MemoryAttribute|DeviceShared]] will be set after mapping.
 
The Option encodes a [[#MemoryPermission]] in the low 16 bits, and an indicator of IO mapping in the high bits.


== MapDeviceAddressSpaceAligned ==
== MapDeviceAddressSpaceAligned ==
Line 1,930: Line 1,884:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|-
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (In) X2 || R2, R3 || void* || SrcAddr
| (In) X2 || R2, R3 || void* || Address
|-
|-
| (In) X3 || R4 || u64 || DeviceAsSize
| (In) X3 || R4 || uint64_t || DeviceAddressSpaceSize
|-
|-
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
| (In) X4 || R5, R6 || uint64_t || DeviceAddressSpaceAddress
|-
|-
| (In) W5 || R7 || MemoryPermission || Permission
| (In) W5 || R7 || uint32_t  || Option
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 1,948: Line 1,902:
Maps an attached device address space to an userspace address.
Maps an attached device address space to an userspace address.


Same as [[#MapDeviceAddressSpaceByForce]], but the userspace destination address must have the [[SVC#MemoryState|MapDeviceAlignedAllowed]] bit set instead.
Same as [[#MapDeviceAddressSpaceByForce]], but the userspace destination address must have the [[SVC#MemoryState|FlagCanAlignedDeviceMap]] bit set instead.
 
The Option encodes a [[#MemoryPermission]] in the low 16 bits, and an indicator of IO mapping in the high bits.


== MapDeviceAddressSpace ==
== MapDeviceAddressSpace ==
Line 1,956: Line 1,912:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W1 || R1 || Handle<DeviceAddressSpace> || DeviceAsHandle
| (In) W1 || R1 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|-
|-
| (In) W2 || R2 || Handle<Process> || ProcessHandle
| (In) W2 || R2 || Handle<Process> || ProcessHandle
|-
|-
| (In) X3 || R0, R3 || u64 || SrcAddr
| (In) X3 || R0, R3 || void* || Address
|-
|-
| (In) X4 || R4 || u64 || DeviceAsSize
| (In) X4 || R4 || uint64_t || DeviceAddressSpaceSize
|-
|-
| (In) X5 || R5, R6 || u64 || DeviceAsAddr
| (In) X5 || R5, R6 || uint64_t || DeviceAddressSpaceAddress
|-
|-
| (In) W6 || R7 || MemoryPermission || Permission
| (In) W6 || R7 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1 || R1 || u64 || MappedSize
| (Out) X1 || R1 || uint64_t || Size
|}
|}
</div>
</div>
Line 1,980: Line 1,936:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAsHandle
| (In) W0 || R0 || Handle<DeviceAddressSpace> || DeviceAddressSpaceHandle
|-
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (In) X2 || R2, R3 || void* || SrcAddr
| (In) X2 || R2, R3 || void* || Address
|-
|-
| (In) X3 || R4 || u64 || DeviceAsSize
| (In) X3 || R4 || uint64_t || DeviceAddressSpaceSize
|-
|-
| (In) X4 || R5, R6 || u64 || DeviceAsAddr
| (In) X4 || R5, R6 || uint64_t || DeviceAddressSpaceAddress
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,004: Line 1,960:
| (In) W0 || R0 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1 || R2, R3 || u64 || Address
| (In) X1 || R2, R3 || void* || Address
|-
|-
| (In) X2 || R1, R4 || u64 || Size
| (In) X2 || R1, R4 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,020: Line 1,976:
| (In) W0 || R0 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1 || R2, R3 || u64 || Address
| (In) X1 || R2, R3 || void* || Address
|-
|-
| (In) X2 || R1, R4 || u64 || Size
| (In) X2 || R1, R4 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,036: Line 1,992:
| (In) W0 || R0 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1 || R2, R3 || u64 || Address
| (In) X1 || R2, R3 || void* || Address
|-
|-
| (In) X2 || R1, R4 || u64 || Size
| (In) X2 || R1, R4 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,050: Line 2,006:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X1 || R2, R3 || u64 || ProcessId
| (In) X1 || R2, R3 || uint64_t || ProcessId
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,088: Line 2,044:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || [[#DebugEventInfo]]* || DebugEvents
| (In) X0 || [[#DebugEventInfo]]* || DebugEventInfo
|-
|-
| (In) W1 || Handle<Debug> || DebugHandle
| (In) W1 || Handle<Debug> || DebugHandle
Line 2,104: Line 2,060:
| (In) W0 || R0 || Handle<Debug> || DebugHandle
| (In) W0 || R0 || Handle<Debug> || DebugHandle
|-
|-
| (In) W1 || R1 || [[#ContinueDebugFlags]] ([1.0.0-2.3.0] [[#ContinueDebugFlagsOld]]) || DebugFlags
| (In) W1 || R1 || uint32_t || [[#ContinueDebugFlags]] ([1.0.0-2.3.0] [[#ContinueDebugFlagsOld]])
|-
|-
| (In) X2 || R2 ([1.0.0-2.3.0] R2, R3) || u64* ([1.0.0-2.3.0] u64)|| ThreadIdList ([1.0.0-2.3.0] ThreadId)
| (In) X2 || R2 ([1.0.0-2.3.0] R2, R3) || uint64_t* ([1.0.0-2.3.0] uint64_t)|| ThreadIdList ([1.0.0-2.3.0] ThreadId)
|-
|-
| (In) X3 || R3 || size_t || [3.0.0+] NumTids
| (In) X3 || R3 || uint64_t || [3.0.0+] NumThreadIds
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,114: Line 2,070:
</div>
</div>


Maximum NumTids is 64. 0 means "all threads".
Maximum NumThreadIds is 64. 0 means "all threads".


=== Result codes ===
=== Result codes ===
Line 2,129: Line 2,085:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X1 || R1 || u64* || ProcessIdBuffer
| (In) X1 || R1 || uint64_t* || ProcessIdBuffer
|-
|-
| (In) W2 || R2 || size_t || ProcessIdBufferSize
| (In) W2 || R2 || uint32_t || ProcessIdBufferSize
|-
|-
| (Out) X0 || R0 || [[#Result]] || Result
| (Out) X0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || size_t || NumProcesses
| (Out) W1 || R1 || uint32_t || NumProcesses
|}
|}
</div>
</div>
Line 2,141: Line 2,097:
Fills the provided array with the pids of currently living processes. A process "lives" so long as it is currently running or a handle to it still exists.
Fills the provided array with the pids of currently living processes. A process "lives" so long as it is currently running or a handle to it still exists.


It returns the total number of processes currently alive. If this number is bigger than the size of PidBuffer, the user won't have all the pids.
It returns the total number of processes currently alive. If this number is bigger than the size of ProcessIdBuffer, the user won't have all the pids.


=== Result codes ===
=== Result codes ===
Line 2,158: Line 2,114:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X1 || R1 || u64* || ThreadIdBuffer
| (In) X1 || R1 || uint64_t* || ThreadIdBuffer
|-
|-
| (In) W2 || R2 || size_t || ThreadIdBufferSize
| (In) W2 || R2 || uint32_t || ThreadIdBufferSize
|-
|-
| (In) W3 || R3 || Handle<Debug> || DebugHandle
| (In) W3 || R3 || Handle<Debug> || DebugHandle
Line 2,166: Line 2,122:
| (Out) X0 || R0 || [[#Result]] || Result
| (Out) X0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || size_t || NumThreads
| (Out) W1 || R1 || uint32_t || NumThreads
|}
|}
</div>
</div>
Line 2,176: Line 2,132:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0 || ThreadContext* || ThreadContextBuffer
| (In) X0 || R0 || [[#ThreadContext]]* || ThreadContext
|-
|-
| (In) X1 || R1 || Handle<Debug> || DebugHandle
| (In) X1 || R1 || Handle<Debug> || DebugHandle
|-
|-
| (In) X2 || R2, R3 || u64 || ThreadId
| (In) X2 || R2, R3 || uint64_t || ThreadId
|-
|-
| (In) W3 || R4 || u32 || [[#ThreadContextFlags]]
| (In) W3 || R4 || uint32_t || [[#ThreadContextFlags]]
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,196: Line 2,152:
| (In) W0 || R0 || Handle<Debug> || DebugHandle
| (In) W0 || R0 || Handle<Debug> || DebugHandle
|-
|-
| (In) X1 || R2, R3 || u64 || ThreadId
| (In) X1 || R2, R3 || uint64_t || ThreadId
|-
|-
| (In) X2 || R1 || ThreadContext* || ThreadContextBuffer
| (In) X2 || R1 || [[#ThreadContext]]* || ThreadContext
|-
|-
| (In) W3 || R4 || u32 || [[#ThreadContextFlags]]
| (In) W3 || R4 || uint32_t || [[#ThreadContextFlags]]
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,212: Line 2,168:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || [[#MemoryInfo]]* || MemoryInfoBuffer
| (In) X0 || [[#MemoryInfo]]* || MemoryInfo
|-
|-
| (In) W2 || Handle<Debug> || DebugHandle
| (In) W2 || Handle<Debug> || DebugHandle
|-
|-
| (In) X3 || u64 || Address
| (In) X3 || void* || Address
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) W1 || PageInfo || PageInfo
| (Out) W1 || [[#PageInfo]] || PageInfo
|}
|}
</div>
</div>
Line 2,230: Line 2,186:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X0 || u64 || MemoryBuffer
| (In) X0 || void* || MemoryBufferAddress
|-
|-
| (In) W1 || Handle<Debug> || DebugHandle
| (In) W1 || Handle<Debug> || DebugHandle
|-
|-
| (In) X2 || u64 || SrcAddress
| (In) X2 || void* || SrcAddress
|-
|-
| (In) X3 || u64 || Size
| (In) X3 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 2,250: Line 2,206:
| (In) W0 || Handle<Debug> || DebugHandle
| (In) W0 || Handle<Debug> || DebugHandle
|-
|-
| (In) X1 || u64 || MemoryBuffer
| (In) X1 || void* || MemoryBufferAddress
|-
|-
| (In) X2 || u64 || DstAddress
| (In) X2 || void* || DstAddress
|-
|-
| (In) X3 || u64 || Size
| (In) X3 || uint64_t || Size
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 2,266: Line 2,222:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R0 || HardwareBreakPointRegisterName || Name
| (In) W0 || R0 || [[#HardwareBreakPointRegisterName]] || Name
|-
|-
| (In) X1 || R2, R3 || u64 || Flags
| (In) X1 || R2, R3 || uint64_t || Flags
|-
|-
| (In) X2 || R1, R4 || u64 || Value
| (In) X2 || R1, R4 || uint64_t || Value
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,294: Line 2,250:
| (In) X2 || R2 || Handle<Debug> || DebugHandle
| (In) X2 || R2 || Handle<Debug> || DebugHandle
|-
|-
| (In) X3 || R0, R1 || u64 || ThreadId
| (In) X3 || R0, R1 || uint64_t || ThreadId
|-
|-
| (In) W4 || R3 || [[#DebugThreadParam]] || Param
| (In) W4 || R3 || [[#DebugThreadParam]] || DebugThreadParam
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1 || R1, R2 || u64 || Out0
| (Out) X1 || R1, R2 || uint64_t || Out0
|-
|-
| (Out) W2 || R3 || u32 || Out1
| (Out) W2 || R3 || uint32_t || Out1
|}
|}
</div>
</div>
Line 2,312: Line 2,268:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || u64 || InfoId
| (In) X1 || [[#SystemInfoType]] || SystemInfoType
|-
|-
| (In) W2 || Handle || Handle
| (In) W2 || Handle || Handle
|-
|-
| (In) X3 || u64 || InfoSubId
| (In) X3 || uint64_t || SystemInfoSubType
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
|-
|-
| (Out) X1 || u64 || Out
| (Out) X1 || uint64_t || SystemInfo
|}
|}
</div>
</div>


{| class=wikitable
== CreatePort ==
! Handle type || Id0 || Id1 || Description
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
|-
| Zero    || 0 || 0 || TotalMemorySize_Application
! Argument64 || Argument32 || Type || Name
|-
|-
| Zero    || 0 || 1 || TotalMemorySize_Applet
| (In) W2 || R2 || int32_t || MaxSessions
|-
|-
| Zero    || 0 || 2 || TotalMemorySize_System
| (In) W3 || R3 || bool || IsLight
|-
|-
| Zero    || 0 || 3 || TotalMemorySize_SystemUnsafe
| (In) X4 || R0 || uint64_t || Name
|-
|-
| Zero    || 1 || 0 || CurrentMemorySize_Application
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| Zero    || 1 || 1 || CurrentMemorySize_Applet
| (Out) W1 || R1 || Handle<Port> || ServerPortHandle
|-
|-
| Zero    || 1 || 2 || CurrentMemorySize_System
| (Out) W2 || R2 || Handle<Port> || ClientPortHandle
|}
</div>
 
== ManageNamedPort ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument || Type || Name
|-
| (In) X1 || char* || Name
|-
|-
| Zero    || 1 || 3 || CurrentMemorySize_SystemUnsafe
| (In) W2 || int32_t || MaxSessions
|-
|-
| Zero    || 2 || 0 || PrivilegedProcessId_LowerBound
| (Out) W0 || [[#Result]] || Result
|-
|-
| Zero    || 2 || 1 || PrivilegedProcessId_UpperBound
| (Out) W1 || Handle<Port> || ServerPortHandle
|}
|}
</div>
== ConnectToPort ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument || Type || Name
|-
| (In) W1 || Handle<Port> || ClientPortHandle
|-
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<Session> || SessionHandle
|}
</div>


== SetProcessMemoryPermission ==
== SetProcessMemoryPermission ==
Line 2,356: Line 2,338:
| (In) W0 || R0 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1 || R2, R3 || u64 || Addr
| (In) X1 || R2, R3 || void* || Addr
|-
|-
| (In) X2 || R1, R4 || u64 || Size
| (In) X2 || R1, R4 || uint64_t || Size
|-
|-
| (In) W3 || R5 || void* || Perm
| (In) W3 || R5 || [[#MemoryPermission]] || MemoryPermission
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,376: Line 2,358:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0 || u64 || DstAddr
| (In) X0 || R0 || void* || DstAddress
|-
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (In) X2 || R2, R3 || void* || SrcAddr
| (In) X2 || R2, R3 || void* || SrcAddress
|-
|-
| (In) X3 || R4 || u64 || Size
| (In) X3 || R4 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,398: Line 2,380:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0 || void* || DstAddr
| (In) X0 || R0 || void* || DstAddress
|-
|-
| (In) W1 || R1 || Handle<Process> || ProcessHandle
| (In) W1 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (In) X2 || R2, R3 || u64 || SrcAddr
| (In) X2 || R2, R3 || void* || SrcAddress
|-
|-
| (In) X3 || R4 || u64 || Size
| (In) X3 || R4 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,418: Line 2,400:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0 || [[#MemoryInfo]]* || MemInfoPtr
| (In) X0 || R0 || [[#MemoryInfo]]* || MemoryInfo
|-
|-
| (In) W2 || R2 || Handle<Process> || ProcessHandle
| (In) W2 || R2 || Handle<Process> || ProcessHandle
|-
|-
| (In) X3 || R1, R3 || u64 || Addr
| (In) X3 || R1, R3 || void* || Address
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) W1 || R1 || PageInfo || PageInfo
| (Out) W1 || R1 || [[#PageInfo]] || PageInfo
|}
|}
</div>
</div>
Line 2,440: Line 2,422:
| (In) W0 || R0 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1 || R2, R3 || u64 || DstAddr
| (In) X1 || R2, R3 || void* || DstAddress
|-
|-
| (In) X2 || R1, R4 || u64 || SrcAddr
| (In) X2 || R1, R4 || void* || SrcAddress
|-
|-
| (In) X3 || R5, R6 || u64 || Size
| (In) X3 || R5, R6 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,460: Line 2,442:
| (In) W0 || R0 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1 || R2, R3 || u64 || DstAddr
| (In) X1 || R2, R3 || void* || DstAddress
|-
|-
| (In) X2 || R1, R4 || u64 || SrcAddr
| (In) X2 || R1, R4 || void* || SrcAddress
|-
|-
| (In) X3 || R5, R6 || u64 || Size
| (In) X3 || R5, R6 || uint64_t || Size
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
Line 2,478: Line 2,460:
! Argument || Type || Name
! Argument || Type || Name
|-
|-
| (In) X1 || [[#CreateProcessInfo]]* || InfoPtr
| (In) X1 || [[#CreateProcessParameter]]* || CreateProcessParameter
|-
|-
| (In) X2 || u32* || CapabilitiesPtr
| (In) X2 || uint32_t* || Capabilities
|-
|-
| (In) X3 || u64 || CapabilitiesNum
| (In) X3 || int32_t || CapabilitiesNum
|-
|-
| (Out) W0 || [[#Result]] || Result
| (Out) W0 || [[#Result]] || Result
Line 2,490: Line 2,472:
</div>
</div>


Takes a [[#CreateProcessInfo]] as input.
Takes a [[#CreateProcessParameter]] as input.
CapabilitiesPtr points to an array of [[NPDM#Kernel_Access_Control|kernel capabilities]].
Capabilities points to an array of [[NPDM#Kernel_Access_Control|kernel capabilities]].
CapabilitiesNum is a number of capabilities in the CapabilitiesPtr array (number of element, not number of bytes).
CapabilitiesNum is a number of capabilities in the Capabilities array (number of element, not number of bytes).


=== Result codes ===
=== Result codes ===
Line 2,509: Line 2,491:
'''0xF001:''' Unused bits are set in mmuflags. Unknown address space type used.
'''0xF001:''' Unused bits are set in mmuflags. Unknown address space type used.


== GetProcessInfo ==
== StartProcess ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 2,515: Line 2,497:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) W0 || R1 || Handle<Process> || ProcessHandle
| (In) W0 || R0 || Handle<Process> || ProcessHandle
|-
| (In) W1 || R1 || int32_t || MainThreadPriority
|-
| (In) W2 || R2 || int32_t || DefaultCpuId
|-
|-
| (In) W1 || R2 || [[#ProcessInfoType]] || InfoType
| (In) X3 || R3, R4 || uint64_t || MainThreadStackSize
|-
|-
| (Out) W0 || R0 || [[#Result]] || Result
| (Out) W0 || R0 || [[#Result]] || Result
|-
| (Out) X1 || R1, R2 || [[#ProcessState]] || State
|}
|}
</div>
</div>


Returns an enum with value 0-7.
== TerminateProcess ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument || Type || Name
|-
| (In) W0 || Handle<Process> || ProcessHandle
|-
| (Out) W0 || [[#Result]] || Result
|}
</div>


== CallSecureMonitor ==
== GetProcessInfo ==
<div style="display: inline-block;">
<div style="display: inline-block;">
{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 2,533: Line 2,527:
! Argument64 || Argument32 || Type || Name
! Argument64 || Argument32 || Type || Name
|-
|-
| (In) X0 || R0 || u64 || [[SMC#ID_0|Function ID]]
| (In) W0 || R1 || Handle<Process> || ProcessHandle
|-
|-
| (In) X1-X7 || R1-R7 || u64 || SMC sub-arguments
| (In) W1 || R2 || [[#ProcessInfoType]] || ProcessInfoType
|-
|-
| (Out) X0 || R0 || [[SMC#Errors|SMC Result]] || Result of SMC
| (Out) W0 || R0 || [[#Result]] || Result
|-
|-
| (Out) X1-X7 || R1-R7 || u64 || SMC sub-output
| (Out) X1 || R1, R2 || uint64_t || [[#ProcessState]]
|}
|}
</div>
</div>


Takes in a SMC function ID in X0, and arguments for that SMC function in X1-X7.
Returns an enum with value 0-7.


Passing an invalid SMC function ID or calling from a core other than core 3 will result in a secure monitor panic.
== CreateResourceLimit ==
 
<div style="display: inline-block;">
The kernel parses bits 9-15 in the passed SMC function ID (per the ARM SMC calling convention), and when set uses as an indicator to translate a pointer in the associated register (X1-X7) to a physical address. The kernel will translate any address mapped as R-W, other addresses (R--, R-X, or invalid pointers) will be translated as 0/NULL.
{| class="wikitable" border="1"
|-
! Argument || Type || Name
|-
| (In) None || ||
|-
| (Out) W0 || [[#Result]] || Result
|-
| (Out) W1 || Handle<ResourceLimit> || ResourceLimitHandle
|}
</div>
 
== SetResourceLimitLimitValue ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument64 || Argument32 || Type || Name
|-
| (In) W0 || R0 || Handle<ResourceLimit> || ResourceLimitHandle
|-
| (In) W1 || R1 || [[#LimitableResource]] || LimitableResource
|-
| (In) X2 || R2, R3 || int64_t || LimitValue
|-
| (Out) W0 || R0 || [[#Result]] || Result
|}
</div>
 
== CallSecureMonitor ==
<div style="display: inline-block;">
{| class="wikitable" border="1"
|-
! Argument64 || Argument32 || Type || Name
|-
| (In) X0 || R0 || uint64_t || [[SMC#Secure_Monitor_calls|FunctionId]]
|-
| (In) X1-X7 || R1-R7 || uint64_t || SMC arguments
|-
| (Out) X0 || R0 || [[SMC#Result|Result]] || SMC result
|-
| (Out) X1-X7 || R1-R7 || uint64_t || SMC output
|}
</div>
 
Takes in a SMC function ID in X0, and arguments for that SMC function in X1-X7.
 
Passing an invalid SMC function ID or calling from a core other than core 3 will result in a secure monitor panic.
 
The kernel parses bits 9-15 in the passed SMC function ID (per the ARM SMC calling convention), and when set uses as an indicator to translate a pointer in the associated register (X1-X7) to a physical address. The kernel will translate any address mapped as R-W, other addresses (R--, R-X, or invalid pointers) will be translated as 0/NULL.


Output is returned raw from the Secure Monitor; X0 will be the untranslated SMC result and X1-X7 will contain other SMC output (or be unchanged, depending on the SMC).
Output is returned raw from the Secure Monitor; X0 will be the untranslated SMC result and X1-X7 will contain other SMC output (or be unchanged, depending on the SMC).
Line 2,563: Line 2,605:


= Enum/Structures =
= Enum/Structures =
== ThreadContextFlags ==
== InfoType ==
Bitfield of one of more of these:
 
{| class=wikitable
{| class=wikitable
! Bit || Bitmask || Name || Description
! Handle type || InfoType || InfoSubType || Description
|-
|-
| 0 || 1 || General-purpose registers || If in 64-bit mode, GPRs 0–28 will be read/written. If in 32-bit mode, GPRs 0–12 will be read/written.
| Process || 0 || 0 || CoreMask
|-
|-
| 1 || 2 || Control registers || Reads/writes the FP, LR, PC, SP, PSTATE, and TPIDR registers.
| Process || 1 || 0 || PriorityMask
|-
|-
| 2 || 4 || Floating-point registers || Reads/writes the floating-point vector registers.
| Process || 2 || 0 || AliasRegionAddress
|-
|-
| 3 || 8 || Floating-point control registers || Reads/writes the FPCR and FPSR registers.
| Process || 3 || 0 || AliasRegionSize
|}
 
== DeviceName ==
{| class=wikitable
! Value || Name
|-
|-
| 0 || AFI
| Process || 4 || 0 || HeapRegionAddress
|-
|-
| 1 || AVPC
| Process || 5 || 0 || HeapRegionSize
|-
|-
| 2 || DC
| Process || 6 || 0 || TotalMemorySize. Total memory available(free+used).
|-
|-
| 3 || DCB
| Process || 7 || 0 || UsedMemorySize. Total used size of codebin memory + main-thread stack + allocated heap.
|-
|-
| 4 || HC
| Zero    || 8 || 0 || DebuggerAttached
|-
|-
| 5 || HDA
| Zero    || 9 || 0 || ResourceLimit
|-
|-
| 6 || ISP2
| Zero    || 10 || -1, {current coreid} || IdleTickCount
|-
|-
| 7 || MSENCNVENC
| Zero    || 11 || 0-3 || RandomEntropy. Used to seed usermode PRNGs.
|-
|-
| 8 || NV
| Process || 12 || 0 || [2.0.0+] AslrRegionAddress
|-
|-
| 9 || NV2
| Process || 13 || 0 || [2.0.0+] AslrRegionSize
|-
|-
| 10 || PPCS
| Process || 14 || 0 || [2.0.0+] StackRegionAddress
|-
|-
| 11 || SATA
| Process || 15 || 0 || [2.0.0+] StackRegionSize
|-
|-
| 12 || VI
| Process || 16 || 0 || [3.0.0+] SystemResourceSizeTotal
|-
|-
| 13 || VIC
| Process || 17 || 0 || [3.0.0+] SystemResourceSizeUsed
|-
|-
| 14 || XUSB_HOST
| Process || 18 || 0 || [3.0.0+] ProgramId
|-
|-
| 15 || XUSB_DEV
| Zero    || 19 || 0 || [4.0.0-4.1.0] InitialProcessIdRange_LowerBound
|-
|-
| 16 || TSEC
| Zero    || 19 || 1 || [4.0.0-4.1.0] InitialProcessIdRange_UpperBound
|-
|-
| 17 || PPCS1
| Process || 20 || 0 || [5.0.0+] UserExceptionContextAddress
|-
|-
| 18 || DC1
| Process || 21 || 0 || [6.0.0+] TotalNonSystemMemorySize
|-
|-
| 19 || SDMMC1A
| Process || 22 || 0 || [6.0.0+] UsedNonSystemMemorySize
|-
|-
| 20 || SDMMC2A
| Process || 23 || 0 || [9.0.0+] IsApplication
|-
|-
| 21 || SDMMC3A
| Process || 24 || 0 || [11.0.0+] FreeThreadCount
|-
| Thread  || 25 ([1.0.0-12.1.0] 0xF0000002) || 0-3, -1 || ThreadTickCount. 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 || 26 || 0 || [14.0.0+] IsSvcPermitted
|-
| Process || 27 || 0 || [16.0.0+] IoRegionHint
|-
| Process || 28 || 0 || [18.0.0+] AliasRegionExtraSize
|}
 
== SystemInfoType ==
{| class=wikitable
! Handle type || SystemInfoType || SystemInfoSubType || Description
|-
| Zero    || 0 || 0 || TotalPhysicalMemorySize_Application
|-
| Zero    || 0 || 1 || TotalPhysicalMemorySize_Applet
|-
| Zero    || 0 || 2 || TotalPhysicalMemorySize_System
|-
| Zero    || 0 || 3 || TotalPhysicalMemorySize_SystemUnsafe
|-
| Zero    || 1 || 0 || UsedPhysicalMemorySize_Application
|-
| Zero    || 1 || 1 || UsedPhysicalMemorySize_Applet
|-
| Zero    || 1 || 2 || UsedPhysicalMemorySize_System
|-
| Zero    || 1 || 3 || UsedPhysicalMemorySize_SystemUnsafe
|-
| Zero    || 2 || 0 || InitialProcessIdRange_LowerBound
|-
| Zero    || 2 || 1 || InitialProcessIdRange_UpperBound
|}
 
== ThreadContextFlags ==
Bitfield of one of more of these:
 
{| class=wikitable
! Bit || Bitmask || Name || Description
|-
| 0 || 1 || General-purpose registers || If in 64-bit mode, GPRs 0–28 will be read/written. If in 32-bit mode, GPRs 0–12 will be read/written.
|-
| 1 || 2 || Control registers || Reads/writes the FP, LR, PC, SP, PSTATE, and TPIDR registers.
|-
| 2 || 4 || Floating-point registers || Reads/writes the floating-point vector registers.
|-
| 3 || 8 || Floating-point control registers || Reads/writes the FPCR and FPSR registers.
|}
 
== DeviceName ==
{| class=wikitable
! Value || Name
|-
| 0 || AFI
|-
| 1 || AVPC
|-
| 2 || DC
|-
| 3 || DCB
|-
| 4 || HC
|-
| 5 || HDA
|-
| 6 || ISP2
|-
| 7 || MSENCNVENC
|-
| 8 || NV
|-
| 9 || NV2
|-
| 10 || PPCS
|-
| 11 || SATA
|-
| 12 || VI
|-
| 13 || VIC
|-
| 14 || XUSB_HOST
|-
| 15 || XUSB_DEV
|-
| 16 || TSEC
|-
| 17 || PPCS1
|-
| 18 || DC1
|-
| 19 || SDMMC1A
|-
| 20 || SDMMC2A
|-
| 21 || SDMMC3A
|-
| 22 || SDMMC4A
|-
| 23 || ISP2B
|-
| 24 || GPU
|-
| 25 || GPUB
|-
| 26 || PPCS2
|-
| 27 || NVDEC
|-
| 28 || APE
|-
| 29 || SE
|-
| 30 || NVJPG
|-
| 31 || HC1
|-
| 32 || SE1
|-
| 33 || AXIAP
|-
| 34 || ETR
|-
| 35 || TSECB
|-
| 36 || TSEC1
|-
| 37 || TSECB1
|-
| 38 || NVDEC1
|}
 
== CodeMemoryOperation ==
{| class=wikitable
! Value || Name
|-
| 0 || MapOwner
|-
| 1 || MapSlave
|-
| 2 || UnmapOwner
|-
| 3 || UnmapSlave
|}
 
== LimitableResource ==
{| class=wikitable
! Value || Name || Description
|-
| 0 || PhysicalMemoryMax || Bytes of memory a process may allocate.
|-
| 1 || ThreadCountMax || Amount of threads a process can create.
|-
| 2 || EventCountMax || Amount of events a process can create through [[#CreateEvent]] or [[#SendAsyncRequestWithUserBuffer]].
|-
| 3 || TransferMemoryCountMax || Amount of TransferMemory a process can create through [[#CreateTransferMemory]].
|-
| 4 || SessionCountMax || Amount of session a process can create through [[#CreateSession]], [[#ConnectToPort]] or [[#ConnectToNamedPort]].
|}
 
= ThreadActivity =
{| class=wikitable
! Value || Name
|-
|-
| 22 || SDMMC4A
| 0 || None
|-
|-
| 23 || ISP2B
| 1 || Runnable
|-
| 24 || GPU
|-
| 25 || GPUB
|-
| 26 || PPCS2
|-
| 27 || NVDEC
|-
| 28 || APE
|-
| 29 || SE
|-
| 30 || NVJPG
|-
| 31 || HC1
|-
| 32 || SE1
|-
| 33 || AXIAP
|-
| 34 || ETR
|-
| 35 || TSECB
|-
| 36 || TSEC1
|-
| 37 || TSECB1
|-
| 38 || NVDEC1
|}
|}


== CodeMemoryOperation ==
== ProcessActivity ==
{| class=wikitable
{| class=wikitable
! Value || Name
! Value || Name
|-
|-
| 0 || MapOwner
| 0 || None
|-
| 1 || MapSlave
|-
| 2 || UnmapOwner
|-
| 3 || UnmapSlave
|}
 
== LimitableResource ==
{| class=wikitable
! Value || Name || Note
|-
| 0 || Memory || Bytes of memory a process may allocate.
|-
| 1 || Threads || Amount of threads a process can create.
|-
| 2 || Events || Amount of events a process can create through [[#CreateEvent]] or [[#SendAsyncRequestWithUserBuffer]].
|-
| 3 || TransferMemories || Amount of TransferMemory a process can create through [[#CreateTransferMemory]].
|-
|-
| 4 || Sessions || Amount of session a process can create through [[#CreateSession]], [[#ConnectToPort]] or [[#ConnectToNamedPort]].
| 1 || Runnable
|}
|}


Line 2,706: Line 2,856:
| 2 || Started ||
| 2 || Started ||
|-
|-
| 3 || Crashed || Processes will not enter this state unless they were created with [[#CreateProcessInfo|EnableDebug]].
| 3 || Crashed || Processes will not enter this state unless they were created with [[#CreateProcessParameter|EnableDebug]].
|-
|-
| 4 || StartedAttached ||
| 4 || StartedAttached ||
Line 2,743: Line 2,893:
AffinityMask: output in out1
AffinityMask: output in out1


== CreateProcessInfo ==
== CreateProcessParameter ==
{| class=wikitable
{| class=wikitable
! Offset || Length || Bits || Description
! Offset || Length || Bits || Description
Line 2,759: Line 2,909:
| 0x24 || 4 || || Flags
| 0x24 || 4 || || Flags
|-
|-
| || || Bit0 || IsAarch64
| || || Bit0 || Is64BitInstruction
|-
|-
| || || Bit3-1 || [[#AddressSpaceType]]
| || || Bit3-1 || [[#AddressSpaceType]]
Line 2,771: Line 2,921:
| || || Bit7 || [4.0.0] UseSecureMemory
| || || Bit7 || [4.0.0] UseSecureMemory
|-
|-
| || || Bit10-7 || [5.0.0+] PoolPartition (0=Application, 1=Applet, 2=Sysmodule, 3=Nvservices)
| || || Bit10-7 || [5.0.0+] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem)
|-
|-
| || || Bit11 || [7.0.0+] OptimizeMemoryAllocation (Only allowed in combination with IsApplication).
| || || Bit11 || [7.0.0+] OptimizeMemoryAllocation (only allowed in combination with IsApplication)
|-
|-
| 0x28 || 4 || || ResourceLimitHandle or zero
| 0x28 || 4 || || ResourceLimitHandle (can be zero)
|-
|-
| 0x2C || 4 || || [3.0.0+] SystemResourceNumPages
| 0x2C || 4 || || [3.0.0+] SystemResourceNumPages
|}
|}


On [1.0.0] there's only one pool.
On [1.0.0] there's only one MemoryRegion.


On [2.0.0-4.0.0] PoolPartition is 1 for built-ins and 0 for rest.
On [2.0.0-4.0.0] MemoryRegion is 1 for built-ins and 0 for rest.


On [5.0.0] PoolPartition is specified in CreateProcessArgs. There are now 4 pool partitions.
On [5.0.0] MemoryRegion is specified in CreateProcessArgs. There are now 4 pool partitions.


On [5.0.0] (maybe lower?) a zero ResourceLimitHandle defaults to sysmodule limits and 0x12300000 bytes of memory.
On [5.0.0] (maybe lower?) a zero ResourceLimitHandle defaults to sysmodule limits and 0x12300000 bytes of memory.
Line 2,797: Line 2,947:
! Type || Name || Width || Description
! Type || Name || Width || Description
|-
|-
| 0 || Normal_32Bit || 32 ||
| 0 || AddressSpace32Bit || 32 ||
|-
|-
| 1 || Normal_36Bit || 36 ||
| 1 || AddressSpace64BitOld || 36 ||
|-
|-
| 2 || WithoutMap_32Bit || 32 || Appears to be missing map region [?]
| 2 || AddressSpace32BitNoReserved || 32 || Appears to be missing map region [?]
|-
|-
| 3 || [2.0.0+] Normal_39Bit || 39 ||
| 3 || [2.0.0+] AddressSpace64Bit || 39 ||
|}
|}


Line 2,814: Line 2,964:
| 8 || 8 || Size
| 8 || 8 || Size
|-
|-
| 0x10 || 4 || MemoryType: lower 8 bits of [[#MemoryState]]
| 0x10 || 4 || [[#MemoryType]]
|-
|-
| 0x14 || 4 || [[#MemoryAttribute]]
| 0x14 || 4 || [[#MemoryAttribute]]
|-
|-
| 0x18 || 4 || Permission (bit0: R, bit1: W, bit2: X)
| 0x18 || 4 || [[#MemoryPermission]]
|-
|-
| 0x1C || 4 || IpcRefCount
| 0x1C || 4 || IpcRefCount
Line 2,825: Line 2,975:
|-
|-
| 0x24 || 4 || Padding: always zero
| 0x24 || 4 || Padding: always zero
|}
== MemoryPermission ==
{| class=wikitable
! Bits || Name || Description
|-
| 0 || Read || Can be set by [[#SetMemoryPermission]].
|-
| 1 || Write || Can be set by [[#SetMemoryPermission]].
|-
| 2 || Execute || Can be set by [[#SetProcessMemoryPermission]] and [[#ControlCodeMemory]].
|-
| 28 || DontCare ||
|}
|}


Line 2,831: Line 2,994:
! Bits || Name || Description
! Bits || Name || Description
|-
|-
| 0 || IsBorrowed || Used by MapMemory, as an async IPC user buffer,
| 0 || Locked || Used by MapMemory, as an async IPC user buffer.
|-
| 1 || IpcLocked || True when IpcRefCount > 0.
|-
| 2 || DeviceShared || True when DeviceRefCount > 0.
|-
| 3 || Uncached ||
|-
|-
| 1 || IsIpcLocked || True when IpcRefCount > 0
| 4 || PermissionLocked ||  
|-
|-
| 2 || IsDeviceShared || True when DeviceRefCount > 0
| 5-6 || [S2] ? || GPU/IOMMU related?
|-
|-
| 3 || IsUncached ||
|}
|}


Line 2,846: Line 3,014:
| 7-0 || [[#MemoryType]] ||  
| 7-0 || [[#MemoryType]] ||  
|-
|-
| 8 || [[#SetMemoryPermission|PermissionChangeAllowed]] ||
| 8 || [[#SetMemoryPermission|FlagCanReprotect]] ||
|-
| 9 || FlagCanDebug || Allows using [[#WriteDebugProcessMemory]] on segments mapped read-only.
|-
| 10 || FlagCanUseIpc || Allows sending this region as an IPC A/B/W buffer with flags=0.
|-
|-
| 9 || ForceReadWritableByDebugSyscalls || Allows using [[#WriteDebugProcessMemory]] on segments mapped read-only.
| 11 || FlagCanUseNonDeviceIpc || Allows sending this region as an IPC A/B/W buffer with flags=1.
|-
|-
| 10 || IpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=0.
| 12 || FlagCanUseNonSecureIpc || Allows sending this region as an IPC A/B/W buffer with flags=3.
|-
|-
| 11 || NonDeviceIpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=1.
| 13 || FlagMapped ||
|-
|-
| 12 || NonSecureIpcSendAllowed || Allows sending this region as an IPC A/B/W buffer with flags=3.
| 14 || [[#SetProcessMemoryPermission|FlagCode]] ||
|-
|-
| 14 || [[#SetProcessMemoryPermission|ProcessPermissionChangeAllowed]] ||
| 15 || [[#MapMemory|FlagCanAlias]] ||
|-
|-
| 15 || [[#MapMemory|MapAllowed]] ||
| 16 || [[#MapProcessCodeMemory|FlagCanCodeAlias]] ||
|-
|-
| 16 || [[#UnmapProcessCodeMemory|UnmapProcessCodeMemoryAllowed]] ||
| 17 || [[#CreateTransferMemory|FlagCanTransfer]] ||
|-
|-
| 17 || [[#CreateTransferMemory|TransferMemoryAllowed]] ||
| 18 || [[#QueryPhysicalAddress|FlagCanQueryPhysical]] ||
|-
|-
| 18 || [[#QueryPhysicalAddress|QueryPhysicalAddressAllowed]] ||
| 19 || [[#MapDeviceAddressSpace|FlagCanDeviceMap]] ||
|-
|-
| 19 || MapDeviceAllowed ([[#MapDeviceAddressSpace]] and [[#MapDeviceAddressSpaceByForce]]) ||
| 20 || [[#MapDeviceAddressSpaceAligned|FlagCanAlignedDeviceMap]] ||
|-
|-
| 20 || [[#MapDeviceAddressSpaceAligned|MapDeviceAlignedAllowed]] ||
| 21 || [[#SendSyncRequestWithUserBuffer|FlagCanIpcUserBuffer]] ||
|-
|-
| 21 || [[#SendSyncRequestWithUserBuffer|IpcBufferAllowed]] ||
| 22 || FlagReferenceCounted || The physical memory blocks backing this region are refcounted.
|-
|-
| 22 || IsPoolAllocated/IsReferenceCounted || The physical memory blocks backing this region are refcounted.
| 23 || [[#MapProcessMemory|FlagCanMapProcess]] ||
|-
|-
| 23 || [[#MapProcessMemory|MapProcessAllowed]] ||
| 24 || [[#SetMemoryAttribute|FlagCanChangeAttribute]] ||
|-
|-
| 24 || [[#SetMemoryAttribute|AttributeChangeAllowed]] ||
| 25 || [4.0.0+] [[#CreateCodeMemory|FlagCanCodeMemory]] ||
|-
|-
| 25 || [4.0.0+] [[#CreateCodeMemory|CodeMemoryAllowed]] ||
| 26 || [15.0.0+] FlagLinearMapped ||
|}
|}


Line 2,885: Line 3,057:
! Value || Type || Meaning
! Value || Type || Meaning
|-
|-
| 0x00000000 || Unmapped ||
| 0x00000000 || Free ||
|-
|-
| 0x00002001 || Io || Mapped by kernel capability parsing in [[#CreateProcess]].  
| 0x00002001 || Io || Mapped by kernel capability parsing in [[#CreateProcess]].  
|-
|-
| 0x00042002 || Normal || Mapped by kernel capability parsing in [[#CreateProcess]].
| 0x00042002 || Static || Mapped by kernel capability parsing in [[#CreateProcess]].
|-
|-
| 0x00DC7E03 || CodeStatic || Mapped during [[#CreateProcess]].
| 0x00DC7E03 || Code || Mapped during [[#CreateProcess]].
|-
|-
| [1.0.0+]
| [1.0.0+]
Line 2,900: Line 3,072:


0x03FEBD04
0x03FEBD04
|| CodeMutable || Transition from 0xDC7E03 performed by [[#SetProcessMemoryPermission]].
|| CodeData || Transition from 0xDC7E03 performed by [[#SetProcessMemoryPermission]].
|-
|-
| [1.0.0+]
| [1.0.0+]
Line 2,908: Line 3,080:


0x037EBD05
0x037EBD05
|| Heap || Mapped using [[#SetHeapSize]].
|| Normal || Mapped using [[#SetHeapSize]].
|-
|-
| 0x00402006 || SharedMemory || Mapped using [[#MapSharedMemory]].
| 0x00402006 || Shared || Mapped using [[#MapSharedMemory]].
|-
|-
| 0x00482907 || [1.0.0] Alias || Mapped using [[#MapMemory]].
| 0x00482907 || [1.0.0] Alias || Mapped using [[#MapMemory]].
|-
|-
| 0x00DD7E08 || ModuleCodeStatic || Mapped using [[#MapProcessCodeMemory]].
| 0x00DD7E08 || AliasCode || Mapped using [[#MapProcessCodeMemory]].
|-
|-
| [1.0.0+]
| [1.0.0+]
Line 2,923: Line 3,095:


0x03FFBD09
0x03FFBD09
|| ModuleCodeMutable || Transition from 0xDD7E08 performed by [[#SetProcessMemoryPermission]].
|| AliasCodeData || Transition from 0xDD7E08 performed by [[#SetProcessMemoryPermission]].
|-
|-
| 0x005C3C0A || [[IPC_Marshalling|Ipc]] || IPC buffers with descriptor flags=0.
| 0x005C3C0A || [[IPC_Marshalling|Ipc]] || IPC buffers with descriptor flags=0.
Line 2,931: Line 3,103:
| 0x0040200C || [[Thread Local Storage|ThreadLocal]] || Mapped during [[#CreateThread]].
| 0x0040200C || [[Thread Local Storage|ThreadLocal]] || Mapped during [[#CreateThread]].
|-
|-
| 0x015C3C0D || TransferMemoryIsolated || Mapped using [[#MapTransferMemory]] when the owning process has perm=0.
| 0x015C3C0D || Transfered || Mapped using [[#MapTransferMemory]] when the owning process has perm=0.
|-
|-
| 0x005C380E || TransferMemory || Mapped using [[#MapTransferMemory]] when the owning process has perm!=0.
| 0x005C380E || SharedTransfered || Mapped using [[#MapTransferMemory]] when the owning process has perm!=0.
|-
|-
| 0x0040380F || ProcessMemory || Mapped using [[#MapProcessMemory]].
| 0x0040380F || SharedCode || Mapped using [[#MapProcessMemory]].
|-
|-
| 0x00000010 || Reserved ||
| 0x00000010 || Inaccessible ||
|-
|-
| 0x005C3811 || [[IPC_Marshalling|NonSecureIpc]] || IPC buffers with descriptor flags=1.
| 0x005C3811 || [[IPC_Marshalling|NonSecureIpc]] || IPC buffers with descriptor flags=1.
Line 2,943: Line 3,115:
| 0x004C2812 || [[IPC_Marshalling|NonDeviceIpc]] || IPC buffers with descriptor flags=3.
| 0x004C2812 || [[IPC_Marshalling|NonDeviceIpc]] || IPC buffers with descriptor flags=3.
|-
|-
| 0x00002013 || KernelStack || Mapped in kernel during [[#CreateThread]].
| 0x00002013 || Kernel || Mapped in kernel during [[#CreateThread]].
|-
| 0x00402214 || [4.0.0+] GeneratedCode || Mapped in kernel during [[#ControlCodeMemory]].
|-
| 0x00402015 || [4.0.0+] CodeOut || Mapped in kernel during [[#ControlCodeMemory]].
|-
|-
| 0x00402214 || [4.0.0+] CodeReadOnly || Mapped in kernel during [[#ControlCodeMemory]].
| 0x00002016 || [13.0.0+] Coverage ||  
|-
|-
| 0x00402015 || [4.0.0+] CodeWritable || Mapped in kernel during [[#ControlCodeMemory]].
| 0x05583817 || [15.0.0+] Insecure ||  
|}
|}


Line 2,989: Line 3,165:
! Bit || Bitmask || Description
! Bit || Bitmask || Description
|-
|-
| 0 || 1 || IgnoreException (note: doesn't need to be set in the same call than Resume)
| 0 || 1 || HandleException (note: doesn't need to be set in the same call than Resume)
|-
|-
| 1 || 2 || DontCatchExceptions
| 1 || 2 || EnableExceptionEvent
|-
|-
| 2 || 4 || Resume
| 2 || 4 || ContinueAll
|-
|-
| 3 || 8 || IgnoreOtherThreadsExceptions
| 3 || 8 || ContinueOthers
|}
|}


IgnoreExceptionsOfOthers is like IgnoreException but acts on all threads that aren't in the input list. The affected threads are resumed.
ContinueOthers is like ContinueAll but acts on all threads that aren't in the input list. The affected threads are resumed.


Only one of of Resume and IgnoreOtherThreadsExceptions can be set at a time.
Only one of of HandleException and EnableExceptionEvent can be set at a time.


If the input number of threads is 0, this means "all threads".
If the input number of threads is 0, this means "all threads".