Difference between revisions of "SVC"
Line 5: | Line 5: | ||
| 0x1 || svcSetupHeap || X1=size || W0=result, X1=outaddr | | 0x1 || svcSetupHeap || X1=size || W0=result, X1=outaddr | ||
|- | |- | ||
− | | 0x2 || svcProtectMemory || X0=addr, X1=size, W2=prot || W0=result | + | | 0x2 || [[#svcProtectMemory]] || X0=addr, X1=size, W2=prot || W0=result |
|- | |- | ||
− | | 0x3 || svcSetMemoryState || X0=addr, X1=size, W2=state0, W3=state1 || W0=result | + | | 0x3 || [[#svcSetMemoryState]] || X0=addr, X1=size, W2=state0, W3=state1 || W0=result |
|- | |- | ||
− | | 0x4 || svcMirrorStack || X0=dstaddr, X1=srcaddr, X2=size || W0=result | + | | 0x4 || [[#svcMirrorStack]] || X0=dstaddr, X1=srcaddr, X2=size || W0=result |
|- | |- | ||
| 0x5 || svcUnmirrorStack || X0=dstaddr, X1=srcaddr, X2=size || W0=result | | 0x5 || svcUnmirrorStack || X0=dstaddr, X1=srcaddr, X2=size || W0=result | ||
Line 23: | Line 23: | ||
| 0xA || svcExitThread || None || | | 0xA || svcExitThread || None || | ||
|- | |- | ||
− | | 0xB || svcSleepThread || X0=nano || | + | | 0xB || [[#svcSleepThread]] || X0=nano || |
|- | |- | ||
| 0xC || svcGetThreadPriority || W1=thread_handle || W0=result, W1=prio | | 0xC || svcGetThreadPriority || W1=thread_handle || W0=result, W1=prio | ||
Line 43: | Line 43: | ||
| 0x14 || svcUnmapMemoryBlock || W0=memblk_handle, X1=addr, X2=size || W0=result | | 0x14 || svcUnmapMemoryBlock || W0=memblk_handle, X1=addr, X2=size || W0=result | ||
|- | |- | ||
− | | 0x15 || svcCreateMemoryMirror || X1=addr, X2=size, W3=perm || W0=result, W1=handle | + | | 0x15 || [[#svcCreateMemoryMirror]] || X1=addr, X2=size, W3=perm || W0=result, W1=handle |
|- | |- | ||
| 0x16 || svcCloseHandle || W0=handle || W0=result | | 0x16 || svcCloseHandle || W0=handle || W0=result | ||
Line 49: | Line 49: | ||
| 0x17 || ? || ? || ? | | 0x17 || ? || ? || ? | ||
|- | |- | ||
− | | 0x18 || svcWaitSynchronizationN || X1=handles_ptr, X2=num_handles. X3=timeout || W1=out | + | | 0x18 || [[#svcWaitSynchronizationN]] || X1=handles_ptr, X2=num_handles. X3=timeout || W1=out |
|- | |- | ||
| 0x19 || ? || W0=handle? || ? | | 0x19 || ? || W0=handle? || ? | ||
Line 99: | Line 99: | ||
| 0x50 || svcCreateMemoryBlock || W1=size?, W2=perm0, W3=perm1 || W0=result, W1=handle | | 0x50 || svcCreateMemoryBlock || W1=size?, W2=perm0, W3=perm1 || W0=result, W1=handle | ||
|- | |- | ||
− | | 0x51 || svcMapMemoryMirror || X0=mirror_handle, X1=addr, X2=size, W3=perm || W0=result | + | | 0x51 || [[#svcMapMemoryMirror]] || X0=mirror_handle, X1=addr, X2=size, W3=perm || W0=result |
|- | |- | ||
− | | 0x52 || svcUnmapMemoryMirror || W0=mirror_handle, X1=addr, X2=size || W0=result | + | | 0x52 || [[#svcUnmapMemoryMirror]] || W0=mirror_handle, X1=addr, X2=size || W0=result |
|} | |} | ||
+ | |||
+ | == svcProtectMemory == | ||
+ | Bit2 of permission (exec) is not allowed. | ||
+ | |||
+ | Setting write-only is not allowed either (bit1). | ||
+ | |||
+ | == svcSetMemoryState == | ||
+ | {| class=wikitable | ||
+ | ! State0 || State1 || Action | ||
+ | |- | ||
+ | | 0 || 0 || Clear bit35 in [[#MemoryState]]. | ||
+ | |- | ||
+ | | 8 || 0 || Clear bit35 in [[#MemoryState]]. | ||
+ | |- | ||
+ | | 8 || 8 || Set bit35 in [[#MemoryState]]. | ||
+ | |} | ||
+ | |||
+ | This might used for switching between cached and non-cached mappings. | ||
+ | |||
+ | == svcMirrorStack == | ||
+ | Memory is only allowed to be mapped into a special region. | ||
+ | |||
+ | Code can get the range of this region from [[#svcGetHandleInfo]]. | ||
+ | |||
+ | The source region gets reprotected to ---, and sets bit32 is set in [[#MemoryState]]. | ||
+ | |||
+ | == svcSleepThread == | ||
+ | Setting nano=0 means "yield thread". | ||
+ | |||
+ | == svcCreateMemoryMirror == | ||
+ | This one reprotects the src block with perms you give it. It also sets bit32 into [[#MemoryState]]. | ||
+ | |||
+ | Executable bit perm not allowed. | ||
+ | |||
+ | Closing the returned handle automatically causes the bit32 in [[#MemoryState]] to clear. | ||
+ | |||
+ | == svcWaitSynchronizationN == | ||
+ | Works with num_handles <= 0x40, error on num_handles == 0. | ||
+ | |||
+ | Does not accept 0xFFFF8001 or 0xFFFF8000 as handles. | ||
+ | |||
+ | == svcMapMemoryMirror == | ||
+ | The newly mapped pages will have [[#MemoryState]] type 0xE. | ||
+ | |||
+ | You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error. | ||
+ | |||
+ | == svcUnmapMemoryMirror == | ||
+ | Size must match size given in map syscall, otherwise there's an invalid-size error. | ||
+ | |||
+ | == MemoryState == | ||
+ | {| class=wikitable | ||
+ | ! Lower 8 bits || Type || Meaning | ||
+ | |- | ||
+ | | 0x3 || Code static || .text and .rodata | ||
+ | |- | ||
+ | | 0x4 || Code || .data | ||
+ | |- | ||
+ | | 0x5 || Heap || | ||
+ | |- | ||
+ | | 0x6 || Shared memory block || | ||
+ | |- | ||
+ | | 0x8 || Module code static || .text and .rodata | ||
+ | |- | ||
+ | | 0x9 || Module code || .data | ||
+ | |- | ||
+ | | 0xB || Stack mirror || | ||
+ | |- | ||
+ | | 0xC || Thread local storage || | ||
+ | |- | ||
+ | | 0xE || Memory mirror || | ||
+ | |- | ||
+ | | 0x10 || Reserved || | ||
+ | |} | ||
+ | |||
+ | Bit32: is_mirrored | ||
+ | |||
+ | Bit35: is_uncached? |
Revision as of 20:24, 5 April 2017
System calls
Id | Name | In | Out |
---|---|---|---|
0x1 | svcSetupHeap | X1=size | W0=result, X1=outaddr |
0x2 | #svcProtectMemory | X0=addr, X1=size, W2=prot | W0=result |
0x3 | #svcSetMemoryState | X0=addr, X1=size, W2=state0, W3=state1 | W0=result |
0x4 | #svcMirrorStack | X0=dstaddr, X1=srcaddr, X2=size | W0=result |
0x5 | svcUnmirrorStack | X0=dstaddr, X1=srcaddr, X2=size | W0=result |
0x6 | svcQueryMemory | X0=meminfo_ptr, X2=addr | W0=result, W1=pageinfo |
0x7 | svcExitProcess | None | |
0x8 | svcCreateThread | ||
0x9 | svcStartThread | W0=thread_handle | |
0xA | svcExitThread | None | |
0xB | #svcSleepThread | X0=nano | |
0xC | svcGetThreadPriority | W1=thread_handle | W0=result, W1=prio |
0xD | svcSetThreadPriority | W0=thread_handle, W1=prio | W0=result |
0xE | svcGetThreadAffinityMask | W2=thread_handle | W0=result, W1=out, X2=out |
0xF | svcSetThreadAffinityMask | W0=thread_handle, W1=in, X2=in2 | W0=result |
0x10 | svcGetCurrentProcessorNumber | None | W0/X0=cpuid |
0x11 | svcGetMemoryBlockSomethingA? | W0=handle | ? |
0x12 | svcGetMemoryBlockSomethingB? | W0=handle | ? |
0x13 | svcMapMemoryBlock | W0=memblk_handle, X1=addr, X2=size, W3=perm | W0=result |
0x14 | svcUnmapMemoryBlock | W0=memblk_handle, X1=addr, X2=size | W0=result |
0x15 | #svcCreateMemoryMirror | X1=addr, X2=size, W3=perm | W0=result, W1=handle |
0x16 | svcCloseHandle | W0=handle | W0=result |
0x17 | ? | ? | ? |
0x18 | #svcWaitSynchronizationN | X1=handles_ptr, X2=num_handles. X3=timeout | W1=out |
0x19 | ? | W0=handle? | ? |
0x1A | svcLockMutex | W0=old_val, X1=ptr, W2=new_val | ? |
0x1B | svcUnlockMutex | X0=ptr | ? |
0x1C | ? | X0=ptr0, X1=ptr, W2=tag, X3=timeout | W0=result |
0x1D | svcArbitrateAddress? | X0=ptr, W1=value | W0=result |
0x1F | svcConnectToPort | X1=port_name_str | W0=result, W1=handle |
.... | ? | ? | ? |
0x21 | svcSendSyncRequest | X0=handle | W0=result |
0x22 | svcSendSyncRequestByBuf | X0=cmdbufptr, X1=size, X2=handle | W0=result |
.... | ? | ? | ? |
0x25 | svcGetThreadId | W0=thread_handle | W0=result, X1=out |
0x26 | ??? | ? | ? |
0x27 | svcOutputDebugString | ||
0x28 | svcPanic | X0=error? | |
0x29 | svcGetHandleInfo | X1=info_id, X2=handle, X3=info_sub_id | W0=result, X1=out |
.... | ? | ? | ? |
0x40 | ??? | W2=?, X3=? | W0=result, W1=?, W2=? |
0x41 | ??? | X1=u32? | W0=result, W1=? |
.... | ? | ? | ? |
0x43 | svcReplyAndReceive | X1=ptr_handles, W2=num_handles, X3=?, X4=timeout | W0=result, W1=handle_idx |
0x44 | svcReplyAndReceiveByBuf | X1=buf, X2=sz, X3=ptr_handles, W4=num_handles, X5=?, X6=timeout | W0=result, W1=handle_idx |
0x45 | ??? | None | W0=result, W1=?, W2=? |
.... | ? | ? | ? |
0x50 | svcCreateMemoryBlock | W1=size?, W2=perm0, W3=perm1 | W0=result, W1=handle |
0x51 | #svcMapMemoryMirror | X0=mirror_handle, X1=addr, X2=size, W3=perm | W0=result |
0x52 | #svcUnmapMemoryMirror | W0=mirror_handle, X1=addr, X2=size | W0=result |
svcProtectMemory
Bit2 of permission (exec) is not allowed.
Setting write-only is not allowed either (bit1).
svcSetMemoryState
State0 | State1 | Action |
---|---|---|
0 | 0 | Clear bit35 in #MemoryState. |
8 | 0 | Clear bit35 in #MemoryState. |
8 | 8 | Set bit35 in #MemoryState. |
This might used for switching between cached and non-cached mappings.
svcMirrorStack
Memory is only allowed to be mapped into a special region.
Code can get the range of this region from #svcGetHandleInfo.
The source region gets reprotected to ---, and sets bit32 is set in #MemoryState.
svcSleepThread
Setting nano=0 means "yield thread".
svcCreateMemoryMirror
This one reprotects the src block with perms you give it. It also sets bit32 into #MemoryState.
Executable bit perm not allowed.
Closing the returned handle automatically causes the bit32 in #MemoryState to clear.
svcWaitSynchronizationN
Works with num_handles <= 0x40, error on num_handles == 0.
Does not accept 0xFFFF8001 or 0xFFFF8000 as handles.
svcMapMemoryMirror
The newly mapped pages will have #MemoryState type 0xE.
You must pass same size and permissions as given in svcCreateMemoryMirror, otherwise error.
svcUnmapMemoryMirror
Size must match size given in map syscall, otherwise there's an invalid-size error.
MemoryState
Lower 8 bits | Type | Meaning |
---|---|---|
0x3 | Code static | .text and .rodata |
0x4 | Code | .data |
0x5 | Heap | |
0x6 | Shared memory block | |
0x8 | Module code static | .text and .rodata |
0x9 | Module code | .data |
0xB | Stack mirror | |
0xC | Thread local storage | |
0xE | Memory mirror | |
0x10 | Reserved |
Bit32: is_mirrored
Bit35: is_uncached?