Difference between revisions of "SVC"
Line 248: | Line 248: | ||
== svcMapMemory == | == svcMapMemory == | ||
− | Maps a memory range into a different range | + | '''Description:''' Maps a memory range into a different range. |
− | Source range gets reprotected to ---, and | + | Useful for adding guard pages around stack. |
+ | |||
+ | Source range gets reprotected to --- (it can no longer be accessed), and bit0 is set in [[#MemoryAttribute]]. | ||
Destination range is enforced to be within a special region. Code can get the range of this region from [[#svcGetInfo]] id0=2,3. | Destination range is enforced to be within a special region. Code can get the range of this region from [[#svcGetInfo]] id0=2,3. |
Revision as of 05:41, 17 August 2017
System calls
Id | Name | In | Out |
---|---|---|---|
0x1 | #svcSetHeapSize | W1=size | W0=result, X1=outaddr |
0x2 | #svcSetMemoryPermission | X0=addr, X1=size, W2=prot | W0=result |
0x3 | #svcSetMemoryAttribute | X0=addr, X1=size, W2=state0, W3=state1 | W0=result |
0x4 | #svcMapMemory | X0=dstaddr, X1=srcaddr, X2=size | W0=result |
0x5 | svcUnmapMemory | X0=dstaddr, X1=srcaddr, X2=size | W0=result |
0x6 | svcQueryMemory | X0=meminfo_ptr, X2=addr | W0=result, W1=pageinfo |
0x7 | svcExitProcess | None | |
0x8 | #svcCreateThread | X1=entry, X2=arg, X3=stacktop, W4=prio, W5=processor_id | W0=result, W1=handle |
0x9 | svcStartThread | W0=thread_handle | W0=result |
0xA | svcExitThread | None | |
0xB | #svcSleepThread | X0=nano | W0=result |
0xC | svcGetThreadPriority | W1=thread_handle | W0=result, W1=prio |
0xD | svcSetThreadPriority | W0=thread_handle, W1=prio | W0=result |
0xE | svcGetThreadCoreMask | W2=thread_handle | W0=result, W1=out, X2=out |
0xF | svcSetThreadCoreMask | W0=thread_handle, W1=in, X2=in2 | W0=result |
0x10 | svcGetCurrentProcessorNumber | None | W0/X0=cpuid |
0x11 | svcSignalEvent | W0=wevent_handle | W0=result |
0x12 | svcClearEvent | W0=wevent_or_revent_handle | W0=result |
0x13 | #svcMapSharedMemory | W0=memblk_handle, X1=addr, X2=size, W3=perm | W0=result |
0x14 | svcUnmapSharedMemory | W0=memblk_handle, X1=addr, X2=size | W0=result |
0x15 | #svcCreateTransferMemory | X1=addr, X2=size, W3=perm | W0=result, W1=handle |
0x16 | svcCloseHandle | W0=handle | W0=result |
0x17 | svcResetSignal | W0=handle | W0=result |
0x18 | #svcWaitSynchronization | X1=handles_ptr, W2=num_handles. X3=timeout | W0=result, W1=handle_idx |
0x19 | svcCancelSynchronization | W0=handle | W0=result |
0x1A | svcArbitrateLock | W0=cur_thread_handle, X1=ptr, W2=req_thread_handle | |
0x1B | svcArbitrateUnlock | X0=ptr | |
0x1C | svcWaitProcessWideKeyAtomic | X0=ptr0, X1=ptr, W2=thread_handle, X3=timeout | W0=result |
0x1D | svcSignalProcessWideKey | X0=ptr, W1=value | W0=result |
0x1E | svcGetSystemTick | ||
0x1F | svcConnectToNamedPort | X1=port_name_str | W0=result, W1=handle |
0x20 | svcSendSyncRequestLight | ||
0x21 | svcSendSyncRequest | X0=handle | W0=result |
0x22 | #svcSendSyncRequestWithUserBuffer | X0=cmdbufptr, X1=size, X2=handle | W0=result |
0x23 | svcSendAsyncRequestWithUserBuffer | ||
0x24 | svcGetProcessId | ||
0x25 | svcGetThreadId | W0=thread_handle | W0=result, X1=out |
0x26 | svcBreak | X0,X1,X2=info | ? |
0x27 | svcOutputDebugString | X0=str, X1=size | |
0x28 | svcReturnFromException | X0=result | |
0x29 | #svcGetInfo | X1=info_id, X2=handle, X3=info_sub_id | W0=result, X1=out |
0x2A | svcFlushEntireDataCache | ||
0x2B | svcFlushDataCache | ||
0x2C | [ 3.0.0+ ] svcMapPhysicalMemory | ||
0x2D | [ 3.0.0+ ] svcUnmapPhysicalMemory | ||
.... | ? | ? | ? |
0x2F | svcGetLastThreadInfo | ||
0x30 | svcGetResourceLimitLimitValue | ||
0x31 | svcGetResourceLimitCurrentValue | ||
0x32 | svcSetThreadActivity | ||
0x33 | svcGetThreadContext3 | ||
0x3C | svcDumpInfo | ||
0x40 | svcCreateSession | W2=?, X3=? | W0=result, W1=client_handle, W2=server_handle |
0x41 | svcAcceptSession | W1=port_handle | W0=result, W1=session_handle |
0x42 | svcReplyAndReceiveLight | ||
0x43 | svcReplyAndReceive | X1=ptr_handles, W2=num_handles, X3=?, X4=timeout | W0=result, W1=handle_idx |
0x44 | svcReplyAndReceiveWithUserBuffer | X1=buf, X2=sz, X3=ptr_handles, W4=num_handles, X5=?, X6=timeout | W0=result, W1=handle_idx |
0x45 | svcCreateEvent | None | W0=result, W1=client_handle ?, W2=server_handle ? |
0x4D | svcSleepSystem | ||
0x4E | #svcReadWriteRegister | X1=reg_addr, W2=rw_mask, W3=in_val | W0=result, W1=out_val |
0x4F | svcSetProcessActivity | ||
0x50 | #svcCreateSharedMemory | W1=size?, W2=myperm, W3=otherperm | W0=result, W1=handle |
0x51 | #svcMapTransferMemory | X0=mirror_handle, X1=addr, X2=size, W3=perm | W0=result |
0x52 | #svcUnmapTransferMemory | W0=mirror_handle, X1=addr, X2=size | W0=result |
0x53 | svcCreateInterruptEvent | X1=irq_id, W2=flag | W0=result, W1=handle |
0x54 | #svcQueryPhysicalAddress | ||
0x55 | #svcQueryIoMapping | X0=physaddr, X1=size | X0=virtaddr |
0x56 | svcCreateDeviceAddressSpace | X1=dev_addr, X2=dev_size | W0=result, W1=handle |
0x57 | #svcAttachDeviceAddressSpace | W0=device, X1=handle | W0=result |
0x58 | #svcDetachDeviceAddressSpace | W0=device, X1=handle | W0=result |
0x59 | svcMapDeviceAddressSpaceByForce | W0=handle, W1=proc_handle, X2=dev_addr, X3=dev_size, X4=map_addr, W5=perm | W0=result |
0x5A | svcMapDeviceAddressSpaceAligned | W0=handle, W1=proc_handle, X2=dev_addr, X3=dev_size, X4=map_addr, W5=perm | W0=result |
0x5B | svcMapDeviceAddressSpace | ||
0x5C | svcUnmapDeviceAddressSpace | W0=handle, W1=proc_handle, X2=map_addr, X3=map_size, W4=perm | W0=result |
0x5D | svcInvalidateProcessDataCache | ||
0x5E | svcStoreProcessDataCache | ||
0x5F | svcFlushProcessDataCache | ||
0x60 | svcDebugActiveProcess | ||
0x61 | svcBreakDebugProcess | ||
0x62 | svcTerminateDebugProcess | ||
0x63 | svcGetDebugEvent | ||
0x64 | svcContinueDebugEvent | ||
0x65 | svcGetProcessList | ||
0x66 | svcGetThreadList | ||
0x67 | svcGetDebugThreadContext | ||
0x68 | svcSetDebugThreadContext | ||
0x69 | svcQueryDebugProcessMemory | ||
0x6A | svcReadDebugProcessMemory | ||
0x6B | svcWriteDebugProcessMemory | ||
0x6C | svcSetHardwareBreakPoint | ||
0x6D | svcGetDebugThreadParam | ||
0x70 | svcCreatePort | ||
0x71 | svcManageNamedPort | ||
0x72 | svcConnectToPort | ||
0x73 | svcSetProcessMemoryPermission | ||
0x74 | svcMapProcessMemory | X0=srcaddr, W1=process_handle, X2=dstaddr, X3=size | W0=result |
0x75 | svcUnmapProcessMemory | W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size | W0=result |
0x76 | svcQueryProcessMemory | ||
0x77 | svcMapProcessCodeMemory | W0=process_handle, X2=dstaddr, X2=srcaddr, X3=size | W0=result |
0x78 | svcUnmapProcessCodeMemory | W0=process_handle, X1=dstaddr, X2=srcaddr, X3=size | W0=result |
0x79 | #svcCreateProcess | X1=procinfo_ptr, X2=caps_ptr, W3=cap_num | W0=result, W1=process_handle |
0x7A | svcStartProcess | W0=proc_handle, W1=main_thread_prio, W2=default_cpuid, W3=main_thread_stacksz | W0=result |
0x7B | svcTerminateProcess | ||
0x7C | svcGetProcessInfo | ||
0x7D | svcCreateResourceLimit | ||
0x7E | svcSetResourceLimitLimitValue | ||
0x7F | svcCallSecureMonitor |
svcSetHeapSize
Description: Set the process heap to a given size. It can both extend and shrink the heap.
Size must be a multiple of 0x2000000.
On success, the heap base-address (which is fixed by kernel, aslr'd) is written to outaddr.
svcSetMemoryPermission
Description: Change permission of page-aligned memory region.
Bit2 of permission (exec) is not allowed. Setting write-only is not allowed either (bit1).
This can be used to move back and forth between ---, r-- and rw-.
svcSetMemoryAttribute
Description: Change attribute of page-aligned memory region.
This is used to turn on/off caching for a given memory area. Useful when talking to devices such as the GPU.
State0 | State1 | Action |
---|---|---|
0 | 0 | Clear bit3 in #MemoryAttribute. |
8 | 0 | Clear bit3 in #MemoryAttribute. |
8 | 8 | Set bit3 in #MemoryAttribute. |
svcMapMemory
Description: Maps a memory range into a different range.
Useful for adding guard pages around stack.
Source range gets reprotected to --- (it can no longer be accessed), and bit0 is set in #MemoryAttribute.
Destination range is enforced to be within a special region. Code can get the range of this region from #svcGetInfo id0=2,3.
svcCreateThread
Processor_id must be 0,1,2,3 or -2, where -2 uses the default cpuid for process.
svcSleepThread
Setting nano=0 means "yield thread".
Maps the block supplied by the handle. The required permissions are different for the process that created the handle and all other processes.
Increases reference count for the KSharedMemory object. Thus in order to release the memory associated with the object, all handles to it must be closed and all mappings must be unmapped.
svcCreateTransferMemory
This one reprotects the src block with perms you give it. It also sets bit0 into #MemoryAttribute.
Executable bit perm not allowed.
Closing all handles automatically causes the bit0 in #MemoryAttribute to clear, and the permission to reset.
svcWaitSynchronization
Works with num_handles <= 0x40, error on num_handles == 0.
Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.
svcSendSyncRequestWithUserBuffer
Size must be 0x1000-aligned.
svcBreak
When used on retail where inx0 bit31 is clear, the system will throw a fatal-error. Otherwise when bit31 is set, it will return 0.
svcGetInfo
Handle type | Id0 | Id1 | Description |
---|---|---|---|
Process | 0 | 0 | AllowedCpuIdBitmask |
Process | 1 | 0 | AllowedThreadPrioBitmask |
Process | 2 | 0 | MapRegionBaseAddress |
Process | 3 | 0 | MapRegionSize |
Process | 4 | 0 | HeapRegionBaseAddress |
Process | 5 | 0 | HeapRegionSize |
Process | 6 | 0 | TotalMemoryUsage |
Process | 7 | 0 | TotalHeapUsage |
Zero | 8 | 0 | ExceptionInfo for current process. |
Zero | 9 | 0 | Returns ResourceLimit handle for current process. Used by PM. |
Zero | 10 | -1, {current coreid} | Unknown. Output data changes each time this SVC is used. Global and core-specific tick-count? |
Zero | 11 | 0-3 | RandomEntropy from current process. TRNG. Used to seed usermode PRNGs. |
Process | 12 | 0 | [ 2.0.0 +] AddressSpaceStart. |
Process | 13 | 0 | [ 2.0.0 +] AddressSpaceSize. |
Process | 14 | 0 | [ 2.0.0 +] MapRegionBased. Randomized. |
Process | 15 | 0 | [ 2.0.0 +] MapRegionSize. |
Process | 18 | 0 | [ 3.0.0 +] Title-id. |
Thread | 0xF0000002 | 0 | Performance counter related. |
svcReadWriteRegister
Read/write Tegra hardware registers with a hardcoded whitelist. Input address is physical-address.
rw_mask is 0 for reading and -1 for writing.
The whitelist is same for writing as for reading.
Registers
Address | Register Name | Description |
---|---|---|
0x700192E8 | MC_LATENCY_ALLOWANCE_DC_0_0 | Latency allowance settings for DC clients |
0x700192EC | MC_LATENCY_ALLOWANCE_DC_1_0 | Latency allowance settings for DC clients |
0x700192F0 | MC_LATENCY_ALLOWANCE_DC_2_0 | Latency allowance settings for DC clients |
0x700192F4 | MC_LATENCY_ALLOWANCE_DCB_0_0 | Latency allowance settings for DCB clients |
0x700192F8 | MC_LATENCY_ALLOWANCE_DCB_1_0 | Latency allowance settings for DCB clients |
0x7001941C | MC_DIS_PTSA_RATE_0 | DDA rate for dis PTSA |
0x70019420 | MC_DIS_PTSA_MIN_0 | DDA minimum value for direct client dis PTSA. |
0x70019424 | MC_DIS_PTSA_MAX_0 | DDA maximum value for direct client dis PTSA. |
0x70019428 | MC_DISB_PTSA_RATE_0 | DDA rate for disb PTSA |
0x7001942C | MC_DISB_PTSA_MIN_0 | DDA minimum value for direct client disb PTSA |
0x70019430 | MC_DISB_PTSA_MAX_0 | DDA maximum value for direct client disb PTSA |
0x7001944C | MC_MLL_MPCORER_PTSA_RATE_0 | DDA rate for mll_mpcorer PTSA |
0x7001947C | MC_RING1_PTSA_RATE_0 | DDA rate for ring1 PTSA |
0x70019480 | MC_RING1_PTSA_MIN_0 | DDA minimum value for direct client ring1 PTSA |
0x70019484 | MC_RING1_PTSA_MAX_0 | DDA maximum value for direct client ring1 PTSA |
0x7001950C | MC_FTOP_PTSA_RATE_0 | DDA rate for ftop PTSA |
0x70019670 | MC_SEC_CARVEOUT_BOM_0 | Baseaddress for the SEC carveout address space. |
0x70019674 | MC_SEC_CARVEOUT_SIZE_MB_0 | Size in MB for the SEC carveout region |
0x70019690 | MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A_0 | Scaled Latency Allowance settings for DISPLAY0A |
0x70019694 | MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB_0 | Scaled Latency Allowance settings for DISPLAY0AB |
0x70019698 | MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B_0 | Scaled Latency Allowance settings for DISPLAY0B |
0x7001969C | MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB_0 | Scaled Latency Allowance settings for DISPLAY0BB |
0x700196A0 | MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C_0 | Scaled Latency Allowance settings for DISPLAY0C |
0x700196A4 | MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB_0 | Scaled Latency Allowance settings for DISPLAY0CB |
0x70019C5C |
Other perm can be used to enforce permission 1, 3, or 0x10000000 if don't care.
svcMapTransferMemory
The newly mapped pages will have #MemoryState type 0xE.
You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error.
svcUnmapTransferMemory
Size must match size given in map syscall, otherwise there's an invalid-size error.
svcQueryPhysicalAddress
The inverse operation of #svcQueryIoMapping.
svcQueryIoMapping
svcCreateProcess
Takes a #CreateProcessInfo as input.
svcAttachDeviceAddressSpace / svcDetachDeviceAddressSpace
These take a #DeviceName and a device address space handle.
Structures
DeviceName
Value | Name |
---|---|
0 | AFI |
1 | AVPC |
2 | DC |
3 | DCB |
4 | HC |
5 | HDA |
6 | ISP2 |
7 | MSENC NVENC |
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 |
CreateProcessInfo
Offset | Length | Description |
---|---|---|
0 | 8 | |
8 | 2 | |
0xA | 2 | |
0xC | 4 | |
0x10 | 8 | TitleId |
0x18 | 8 | CodeAddr |
0x20 | 4 | CodeNumPages |
0x24 | 4 | Flags. Bit0: Is64bit (maybe?), bit3-1: MmuTableType (0=32-bit, 1=64-bit 0x800000000, 2=64-bit 0x400000000), bit4: DebugAllowed, bit5, bit6 |
0x28 | 4 | ResourceLimitHandle |
0x2C | 4 |
MemoryAttribute
Bits | Description |
---|---|
0 | IsBorrowed |
1 | IsIpcMapped [?] |
2 | IsDeviceMapped |
3 | IsUncached [?] |
MemoryState
Bits | Description |
---|---|
7-0 | Type |
8 | PermissionChangeAllowed |
14 | ProcessPermissionChangeAllowed |
15 | MapAllowed |
16 | UnmapProcessCodeMemoryAllowed |
17 | TransferMemoryAllowed |
19 | MapDeviceAllowed (#svcMapDeviceAddressSpace and #svcMapDeviceAddressSpaceByForce) |
20 | MapDeviceAlignedAllowed |
21 | IpcBufferAllowed |
22 | IsCached [?] |
23 | MapProcessAllowed |
24 | AttributeChangeAllowed |
Value | Type | Meaning |
---|---|---|
0x00000000 |
Unmapped | |
0x00002001 |
IO | Mapped by kernel capability parsing in #svcCreateProcess. |
0x00042002 |
IO | Mapped by kernel capability parsing in #svcCreateProcess. |
0x00DC7E03 |
Code static | Mapped during #svcCreateProcess. |
0x01FEBD04 |
Code | Transition from 0xDC7E03 performed by #svcSetProcessMemoryPermission. |
0x017EBD05 |
Heap | Mapped using #svcSetHeapSize. |
0x00402006 |
Shared memory block | Mapped using #svcMapSharedMemory. |
0x00482907 |
Weird mapped memory | Mapped using #svcMapMemory. |
0x00DD7E08 |
Module code static | Mapped using #svcMapProcessCodeMemory. |
0x01FFBD09 |
Module code mutable | Transition from 0xDD7E08 performed by #svcSetProcessMemoryPermission. |
0x005C3C0B |
Mapped memory | Mapped using #svcMapMemory. |
0x0040200C |
Thread local storage | Mapped during #svcCreateThread. |
0x015C3C0D |
Isolated transfer memory | Mapped using #svcMapTransferMemory when the owning process has perm=0. |
0x005C380E |
Transfer memory | Mapped using #svcMapTransferMemory when the owning process has perm!=0. |
0x0040380F |
Process memory | Mapped using #svcMapProcessMemory. |
0x00000010 |
Reserved |
Exception Handling
There appears to be userland code for handling exceptions, however this doesn't seem to be executed on retail.
On usermode exception, it jumps to main code binary entrypoint (main_binary_address+0) with X0=exception_info_ptr and X1=exception_info2_ptr. On boot, X0 is set to 0 triggering normal crt0 setup.