Difference between revisions of "SVC"
Line 246: | Line 246: | ||
|- | |- | ||
| 0x60 | | 0x60 | ||
− | | DebugActiveProcess(Handle * | + | | Result DebugActiveProcess(Handle* debug, u32 processID) |
|- | |- | ||
| 0x61 | | 0x61 | ||
− | | BreakDebugProcess(Handle) | + | | Result BreakDebugProcess(Handle debug) |
|- | |- | ||
| 0x62 | | 0x62 | ||
− | | TerminateDebugProcess(Handle) | + | | Result TerminateDebugProcess(Handle debug) |
|- | |- | ||
| 0x63 | | 0x63 | ||
− | | GetProcessDebugEvent(DebugEventInfo*, Handle) | + | | Result GetProcessDebugEvent(DebugEventInfo* info, Handle debug) |
|- | |- | ||
| 0x64 | | 0x64 | ||
− | | ContinueDebugEvent(Handle, | + | | Result ContinueDebugEvent(Handle debug, u32 flags) |
|- | |- | ||
| 0x65 | | 0x65 | ||
− | | GetProcessList( | + | | Result GetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount) |
|- | |- | ||
| 0x66 | | 0x66 | ||
− | | GetThreadList( | + | | Result GetThreadList(s32* threadCount, u32* threadIds, s32 threadIdMaxCount, Handle domain) |
|- | |- | ||
| 0x67 | | 0x67 | ||
− | | GetDebugThreadContext(ThreadContext*, Handle, | + | | Result GetDebugThreadContext(ThreadContext* context, Handle debug, u32 threadId, u32 controlFlags) |
|- | |- | ||
| 0x68 | | 0x68 | ||
− | | SetDebugThreadContext(Handle, | + | | Result SetDebugThreadContext(Handle debug, u32 threadId, ThreadContext* context, u32 controlFlags) |
|- | |- | ||
| 0x69 | | 0x69 | ||
− | | QueryDebugProcessMemory(MemoryInfo*, PageInfo*, Handle, | + | | Result QueryDebugProcessMemory(MemoryInfo* blockInfo, PageInfo* pageInfo, Handle process, u32 addr) |
|- | |- | ||
| 0x6A | | 0x6A | ||
− | | ReadProcessMemory(void* | + | | Result ReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size) |
|- | |- | ||
| 0x6B | | 0x6B | ||
− | | WriteProcessMemory(Handle | + | | Result WriteProcessMemory(Handle debug, void const* buffer, u32 addr, u32 size) |
|- | |- | ||
| 0x6C | | 0x6C | ||
− | | SetHardwareBreakPoint( | + | | Result SetHardwareBreakPoint(s32 registerId, u32 control, u32 value) |
|- | |- | ||
| 0x6D | | 0x6D |
Revision as of 04:32, 22 February 2013
System calls
Id | Description |
---|---|
0x1 | Result ControlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions) (outaddr is usually the same as the input addr0) |
0x2 | Result QueryMemory(MemoryInfo* info, PageInfo* out, u32 Addr) |
0x3 | void ExitProcess(void) |
0x4 | Result GetProcessAffinityMask(u8* affinitymask, Handle process, s32 processorcount) |
0x5 | Result SetProcessAffinityMask(Handle process, u8* affinitymask, s32 processorcount) |
0x6 | Result GetProcessIdealProcessor(s32 *idealprocessor, Handle process) |
0x7 | Result SetProcessIdealProcessor(Handle process, s32 idealprocessor) |
0x8 | Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid) |
0x9 | void ExitThread(void) |
0xA | void SleepThread(s64 nanoseconds) |
0xB | Result GetThreadPriority(s32* priority, Handle thread) |
0xC | Result SetThreadPriority(Handle thread, s32 priority) |
0xD | Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount) |
0xE | Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount) |
0xF | Result GetThreadIdealProcessor(s32* processorid, Handle thread) |
0x10 | Result SetThreadIdealProcessor(Handle thread, s32 processorid) |
0x11 | s32 GetCurrentProcessorNumber(void) |
0x12 | Result Run(Handle process, StartupInfo* info) (This starts the main() thread. Buf+0 is main-thread priority, Buf+4 is main-thread stack-size.) |
0x13 | Result CreateMutex(Handle* mutex, bool initialLocked) |
0x14 | Result ReleaseMutex(Handle mutex) |
0x15 | Result CreateSemaphore(Handle* semaphore, s32 initialCount, s32 maxCount) |
0x16 | Result ReleaseSemaphore(s32* count, Handle semaphore, s32 releaseCount) |
0x17 | Result CreateEvent(Handle* event, ResetType resettype) |
0x18 | Result SignalEvent(Handle event) |
0x19 | Result ClearEvent(Handle event) |
0x1A | Result CreateTimer(Handle* timer, ResetType resettype) |
0x1B | Result SetTimer(Handle timer, s64 initial, s64 interval) |
0x1C | Result CancelTimer(Handle timer) |
0x1D | Result ClearTimer(Handle timer) |
0x1E | Result CreateMemoryBlock(Handle* memblock, u32 memory, u32 size, u32 mypermission, u32 otherpermission) |
0x1F | Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) |
0x20 | Result UnmapMemoryBlock(Handle memblock, u32 addr) |
0x21 | Result CreateAddressArbiter(Handle* arbiter) |
0x22 | Result ArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value) |
0x23 | Result CloseHandle(Handle handle) |
0x24 | Result WaitSynchronization1(Handle handle, s64 nanoseconds) |
0x25 | Result WaitSynchronizationN(s32* out, Handle* handles, s32 handlecount, bool waitAll, s64 nanoseconds) |
0x26 | Result SignalAndWait(s32* out, Handle signal, Handle* handles, s32 handleCount, bool waitAll, s64 nanoseconds) |
0x27 | Result DuplicateHandle(Handle* out, Handle original) |
0x28 | s64 GetSystemTick(void) |
0x29 | Result GetHandleInfo(s64* out, Handle handle, HandleInfoType type) |
0x2A | Result GetSystemInfo(s64* out, SystemInfoType type, s32 param) |
0x2B | Result GetProcessInfo(s64* out, Handle process, ProcessInfoType type) |
0x2C | Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type) |
0x2D | Result ConnectToPort(Handle* out, const char* portName) |
0x2E | Result SendSyncRequest1(Handle session) (Stubbed) |
0x2F | Result SendSyncRequest2(Handle session) (Stubbed) |
0x30 | Result SendSyncRequest3(Handle session) (Stubbed) |
0x31 | Result SendSyncRequest4(Handle session) (Stubbed) |
0x32 | Result SendSyncRequest(Handle session) |
0x33 | Result OpenProcess(Handle* process, u32 processId) |
0x34 | Result OpenThread(Handle* thread, Handle process, u32 threadId) |
0x35 | Result GetProcessId(u32* processId, Handle process) |
0x36 | Result GetProcessIdOfThread(u32* processId, Handle thread) |
0x37 | Result GetThreadId(u32* threadId, Handle thread) |
0x38 | Result GetResourceLimit(Handle* resourceLimit, Handle process) |
0x39 | Result GetResourceLimitLimitValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount) |
0x3A | Result GetResourceLimitCurrentValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount) |
0x3B | Result GetThreadContext(ThreadContext* context, Handle thread) (Stubbed) |
0x3C | Break(BreakReason) |
0x3D | OutputDebugString(void const, int) (Does nothing on non-debug units) |
0x3E | ControlPerformanceCounter(unsigned long long, int, unsigned int, unsigned long long) |
0x47 | Result CreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions) |
0x48 | Result CreateSessionToPort(Handle* session, Handle port) |
0x49 | Result CreateSession(Handle* sessionServer, Handle* sessionClient) |
0x4A | Result AcceptSession(Handle* session, Handle port) |
0x4B | Result ReplyAndReceive1(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4C | Result ReplyAndReceive2(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4D | Result ReplyAndReceive3(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4E | Result ReplyAndReceive4(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4F | Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) |
0x50 | Result BindInterrupt(Interrupt name, Handle syncObject, s32 priority, bool isManualClear) |
0x51 | Result UnbindInterrupt(Interrupt name, Handle syncObject) |
0x52 | Result InvalidateProcessDataCache(Handle process, void* addr, u32 size) |
0x53 | Result StoreProcessDataCache(Handle process, void const* addr, u32 size) |
0x54 | Result FlushProcessDataCache(Handle process, void const* addr, u32 size) |
0x55 | Result StartInterProcessDma(Handle* dma, Handle dstProcess, void* dst, Handle srcProcess, const void* src, u32 size, const DmaConfig& config ) |
0x56 | Result StopDma(Handle dma) |
0x57 | Result GetDmaState(DmaState* state, Handle dma) |
0x58 | RestartDma(nn::Handle, void *, void const*, unsigned int, signed char) |
0x60 | Result DebugActiveProcess(Handle* debug, u32 processID) |
0x61 | Result BreakDebugProcess(Handle debug) |
0x62 | Result TerminateDebugProcess(Handle debug) |
0x63 | Result GetProcessDebugEvent(DebugEventInfo* info, Handle debug) |
0x64 | Result ContinueDebugEvent(Handle debug, u32 flags) |
0x65 | Result GetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount) |
0x66 | Result GetThreadList(s32* threadCount, u32* threadIds, s32 threadIdMaxCount, Handle domain) |
0x67 | Result GetDebugThreadContext(ThreadContext* context, Handle debug, u32 threadId, u32 controlFlags) |
0x68 | Result SetDebugThreadContext(Handle debug, u32 threadId, ThreadContext* context, u32 controlFlags) |
0x69 | Result QueryDebugProcessMemory(MemoryInfo* blockInfo, PageInfo* pageInfo, Handle process, u32 addr) |
0x6A | Result ReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size) |
0x6B | Result WriteProcessMemory(Handle debug, void const* buffer, u32 addr, u32 size) |
0x6C | Result SetHardwareBreakPoint(s32 registerId, u32 control, u32 value) |
0x6D | GetDebugThreadParam(long long *, int *, nn::Handle, unsigned int, nn::dmnt::DebugThreadParam) (Disabled on regular kernel) |
0x70 | ControlProcessMemory(Handle KProcess, unsigned int Addr0, unsigned int Addr1, unsigned int Size, unsigned int Type, unsigned int Permissions) |
0x71 | MapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr) |
0x72 | UnmapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr) |
0x73 | ? |
0x74 | Stubbed on regular kernel |
0x75 | ? |
0x76 | TerminateProcess(Handle) |
0x77 | (Handle KProcess, Handle KResourceLimit) |
0x78 | CreateResourceLimit(Handle *KResourceLimit) |
0x79 | ? |
0x7A | DisableExecuteNever(unsigned int Addr, unsigned int Size) (Stubbed for regular kernel beginning with 2.0.0-2) |
0x7C | KernelSetState(unsigned int Type, unsigned int Param0, unsigned int Param1, unsigned int Param2) (The Type determines the usage of each param) |
0x7D | QueryProcessMemory(MemInfo *Info, unsigned int *Out, Handle KProcess, unsigned int Addr) |
0xFF | Debug related (The Syscall access control mask doesn't apply for this SVC) |
Types and structures
enum MemoryState
Memory state flags | Bit |
---|---|
FREE | 0 |
RESERVED | 1 |
IO | 2 |
STATIC | 3 |
CODE | 4 |
PRIVATE | 5 |
SHARED | 6 |
CONTINUOUS | 7 |
ALIASED | 8 |
ALIAS | 9 |
ALIAS CODE | 10 |
LOCKED | 11 |
enum PageFlags
Page flags | Bit |
---|---|
LOCKED | 0 |
CHANGED | 1 |
enum MemoryOperation
Memory operation | Id |
---|---|
FREE | 1 |
RESERVE | 2 |
COMMIT | 3 |
MAP | 4 |
UNMAP | 5 |
PROTECT | 6 |
REGION APP | 0x100 |
REGION SYSTEM | 0x200 |
REGION BASE | 0x300 |
LINEAR | 0x1000 |
enum MemoryPermission
Memory permission | Id |
---|---|
NONE | 0 |
READ | 1 |
WRITE | 2 |
READWRITE | 3 |
DONTCARE | 0x10000000 |
enum ResetType
Reset type | Id |
---|---|
ONESHOT | 0 |
STICKY | 1 |
PULSE | 2 |
struct MemoryInfo
Type | Field |
---|---|
u32 | Base address |
u32 | Size |
u32 | Permission |
enum MemoryState | State |
struct PageInfo
Type | Field |
---|---|
u32 | Flags |
struct StartupInfo
Type | Field |
---|---|
s32 | Priority |
u32 | Stack size |
s32 | argc |
s16* | argv |
s16* | envp |
Processes
Each process can only use SVCs which are enabled in the exheader for this process. The ARM11 kernel SVC handler checks whether the SVC is enabled in the syscall access control mask stored on the SVC-mode stack, when the SVC isn't enabled a kernelpanic() is triggered. Each process has a separate SVC-mode stack, this stack and the syscall access mask stored here is initialized when the process is started. Applications normally only have access to SVCs <=0x3D, however not all SVCs <=0x3D are accessible to the application. The majority of the SVCs accessible to applications are unused by the application.
Each process has a separate handle-table, the size of this table is stored in the exheader. The handles in a handle-table can't be used in the context of other processes, since those handles don't exist in other handle-tables.
0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for the current KThread.
Calling svcBreak on retail will only terminate the process which called this SVC.
Threads
For svcCreateThread the input address used for Entrypoint_Param and StackTop are normally the same, however these can be arbitrary. For the main thread the Entrypoint_Param is value 0.
Using CloseHandle() with a KThread handle will terminate the specified thread.
Memory Mapping
ControlMemory and MapMemoryBlock can be used to map memory pages, these two SVCs only support mapping execute-never R/W pages. The input permissions parameter for these SVCs must be <=3, where value zero is used when un-mapping memory. Bitmask 0xf00 for ControlMemory parameter MemoryType is the memory-type, when this is zero the memory-type is loaded from the kernel flags stored in the exheader ARM11 kernel descriptors, for the process using the SVC. ControlMemory parameter MemoryType with value 0x10003 is used for mapping the GSP heap. The low 8-bits are the type: 1 is for un-mapping memory, 3 for mapping memory. Type4 is used to mirror the RW memory at Addr1, to Addr0. Type4 will return an error if Addr1 is located in read-only memory. Addr1 is not used for type1 and type3.
ControlProcessMemory maps memory in the specified process, this is the only SVC which allows mapping executable memory. Format of the permissions field for memory mapping SVCs: bit0=R, bit1=W, bit2=X. Type6 sets the Addr0 memory permissions to the input permissions, for already mapped memory.
MapProcessMemory maps RW memory starting at address 0x00100000 in the specified KProcess, at the specified StartAddr in the current process. MapProcessMemory then maps 0x08000000 in the specified process, to StartAddr+0x7f00000 in the current process. UnmapProcessMemory unmaps the memory which was mapped by MapProcessMemory.
Debugging
DebugActiveProcess is used to attach to a process for debugging. This SVC can only be used when the target process' ARM11 descriptors stored in the exheader have the kernel flag for "Enable debug" set. Otherwise when that flag is clear, the kernel flags for the process using this SVC must have the "Force debug" flag set.
KernelSetState
Type0 initializes the programID for launching FIRM, then triggers launching FIRM. Param0 and Param2 are unused. Param1 is the programID-low, and the programID-high is 0x00040138.
Type3 is used for initializing the 0x1000-byte buffer used by the launched FIRM. Param2 is unused. When Param0 is value 1, this buffer is copied to the beginning of FCRAM at 0xF0000000, and Param1 is unused. When Param0 is value 0, this kernel buffer is mapped to process address Param1.
GetSystemInfo
Type0 value 26(Type1 is unused) writes the total number of processes which were directly launched by the kernel, to Output. For the NATIVE_FIRM/SAFE_MODE_FIRM ARM11 kernel, this is normally 5, for processes sm, fs, pm, loader, and pxi.