In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Difference between revisions of "IOSU syscalls"

From WiiUBrew
Jump to navigation Jump to search
(Redirected page to IOS)
Tag: New redirect
 
(34 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{stub}}
+
#REDIRECT [[IOS]]
There are 2 types of syscalls:
 
 
 
1. Syscalls using undefined ARM instruction.
 
 
 
2. Syscalls using ARM syscall instruction.
 
 
 
== Syscalls (via undefined instructions) ==
 
Similarly to the Wii's IOS, the IOSU uses a syscall table that is stored toward the end of the kernel area inside the main ARM binary (fw.img).
 
 
 
The second vector is the invalid instruction handler, which is used to implement syscalls:
 
fw:FFFF0000              LDR    PC, =_reset
 
fw:FFFF0004              LDR    PC, =starbuck_syscall_handler
 
 
 
The Starbuck syscall handler:
 
starbuck_syscall_handler
 
    STMFA          SP, {R0-LR}^
 
    MRS            R8, SPSR
 
    STR            R8, [SP]
 
    STR            LR, [SP,#0x40]
 
    LDR            R10, [LR,#-4]  ; R10 = E7F0XXXX  (the invalid instruction)
 
    BIC            R9, R10, #0xFF00
 
    LDR            R8, =0xE7F000F0  ; Syscall base
 
    CMP            R9, R8            ; Were any bits set other than the syscall number
 
    BNE            invalid_syscall
 
    MOV            R10, R10,ASR#8
 
    AND            R10, R10, #0xFF
 
    CMP            R10, #0x94        ; Max index of syscall (can possibly vary)
 
    BGT            return_to_caller
 
    MOV            R8, SP
 
    MOV            R11, #0x1F
 
    MSR            CPSR_c, R11      ; Switch to system mode and disable FIQ/IRQ
 
    LDR            R8, [R8,#0x44]
 
    LDR            R11, =syscall_stack_arg_counts
 
    LDR            R11, [R11,R10,LSL#2]  ; Number of args on stack for this syscall
 
    ADD            SP, SP, R11,LSL#2
 
get_stack_arg                           
 
    CMP            R11, #0
 
    BEQ            find_syscall_and_jump
 
    LDR            R9, [SP,#-4]! ; Copy argument value
 
    STR            R9, [R8,#-4]!
 
    SUB            R11, R11, #1
 
    B              get_stack_arg
 
find_syscall_and_jump
 
    MOV            SP, R8
 
    LDR            R11, =syscall_table
 
    LDR            R11, [R11,R10,LSL#2]
 
    MOV            LR, PC
 
    BX              R11
 
return_to_caller
 
    MOV            R11, #0xDB  ; Switch to undefined mode and re-enable FIQ/IRQ
 
    MSR            CPSR_c, R11
 
    LDR            R11, [SP]
 
    MSR            SPSR_cxsf, R11
 
    MOV            LR, R0
 
    LDMED          SP, {R0-LR}^
 
    NOP
 
    MOV            R0, LR
 
    LDR            LR, [SP,#0x40]
 
    MOVS            PC, LR       ; Return
 
invalid_syscall
 
    LDR            SP, =current_thread_ctx_addr
 
    LDR            SP, [SP]
 
    STR            LR, [SP,#0x40]
 
    ADD            SP, SP, #0x40
 
    STMFD          SP, {R0-LR}^
 
    SUB            R0, SP, #0x40
 
    MOV            LR, #6 ; STATE_FAULTED
 
    STR            LR, [R0,#0x50]
 
    LDR            SP, =debug_args_addr
 
    BL              debug_print  ; Illegal Instruction:tid=%d,pid=%d,pc=0x%08x,sp=0x%08x
 
    B              schedule_yield
 
 
 
Syscalls are invoked by way of the invalid instruction handler; syscalls take the form 0xE7F000F0 | (syscall_num << 8). (E.g. E7F000F0 is syscall 0, E7F036F0 is syscall 0x36, etc.).<br>
 
The IOSU currently has 0x94 available syscalls (the number of installed syscalls can vary between system versions).<br><br>
 
NOTE: Official syscall names begin with "IOS_", the rest are merely educated guesses.
 
 
 
{|border=1
 
|-
 
! ID # !! Internal name !! Description !! Return value
 
|-
 
| 0x00 || int IOS_CreateThread(u32 (*proc)(void* arg), void* arg, u32* stack_top, u32 stacksize, int priority, BOOL detached)  || Creates a thread (in paused state) || New threadid or error (negative value)
 
|-
 
| 0x01 || int thread_join(int threadid, u32 *returned_value) || Waits for a thread to finish executing || 0 on success
 
|-
 
| 0x02 || int thread_cancel(int threadid, u32 unk)  || Cancels an active thread || 0 on success
 
|-
 
| 0x03 || int get_tid() || Get the current thread's ID || Current threadid
 
|-
 
| 0x04 || || ||
 
|-
 
| 0x05 || int get_pid() || Get the current process' ID || Current processid
 
|-
 
| 0x06 || int get_process_name(int pid, char *out_buffer, u32 out_size) || Get the specified process' name string || 0 on success
 
|-
 
| 0x07 || int thread_resume(int threadid) || Resume the specified thread || 0 on success
 
|-
 
| 0x08 || int thread_suspend(int threadid) || Suspend the specified thread || 0 on success
 
|-
 
| 0x09 || int thread_yield() || Yield execution to any higher priority threads || 0 on success
 
|-
 
| 0x0A || int IOS_GetThreadPriority(int threadid) || Get the priority of the specified thread || The thread's priority or error (negative value)
 
|-
 
| 0x0B || int IOS_SetThreadPriority(int threadid, int priority) || Set the priority of the specified thread || 0 on success
 
|-
 
| 0x0C || int IOS_CreateMessageQueue(u32 *ptr, u32 n_msgs) || Create a queue at ptr, for n_msgs messages || The queue ID
 
|-
 
| 0x0D || int IOS_DestroyMessageQueue(int queueid) || Destroy a message queue || 0 on success
 
|-
 
| 0x0E || int IOS_SendMessage(int queueid, u32 message, u32 flags) || Add a message to the end queue || 0 on success
 
|-
 
| 0x0F || int IOS_JamMessage(int queueid, u32 message, u32 flags) || Add a message to the front of a queue || 0 on success
 
|-
 
| 0x10 || int IOS_ReceiveMessage(int queueid, u32 *message, u32 flags) || Fetch a message from the front of a queue || 0 on success
 
|-
 
| 0x11 || int IOS_HandleEvent(int device, int queueid, int message) || Register queueid as a handler for interrupts generated by device (sends message to queueid when device's interrupt is triggered) || 0 on success
 
|-
 
| 0x12 || int unregister_event_handler(int device) || Unregister handler for device || 0 on success
 
|-
 
| 0x13 || int IOS_CreateTimer(int time_us, int repeat_time_us, int queueid, u32 message) || Create a timer that sends a message to a queue after the elapsed period(s) || Timerid or error (negative value)
 
|-
 
| 0x14 || int IOS_RestartTimer(int timerid, int time_us, int repeat_time_us) || Restart a timer using the specified period(s) || 0 on success
 
|-
 
| 0x15 || int IOS_StopTimer(int timerid) || Pauses the specified timer || 0 on success
 
|-
 
| 0x16 || int IOS_DestroyTimer(int timerid) || Destroys the specified timer || 0 on success
 
|-
 
| 0x17 || || ||
 
|-
 
| 0x18 || || ||
 
|-
 
| 0x19 || IOS_GetUpTimeStruct(???) || ||
 
|-
 
| 0x1A || IOS_GetUpTime64(???) || ||
 
|-
 
| 0x1B || || ||
 
|-
 
| 0x1C || IOS_GetAbsTimeCalendar(???) || ||
 
|-
 
| 0x1D || IOS_GetAbsTime64(???) || ||
 
|-
 
| 0x1E || IOS_GetAbsTimeStruct(???) || ||
 
|-
 
| 0x1F || || ||
 
|-
 
| 0x20 || || ||
 
|-
 
| 0x21 || int check_jtag() || Get the current status of the JTAG || 0 if JTAG is enabled or -4 if disabled
 
|-
 
| 0x22 || || ||
 
|-
 
| 0x23 || int heap_create(void *ptr, int size) || Create a new heap at ptr of size bytes || The heapid or error (negative value)
 
|-
 
| 0x24 || int IOS_CreateLocalProcessHeap(void *ptr, int size) || Create a new local process heap of size bytes || The heap ID or error (negative value)
 
|-
 
| 0x25 || int IOS_CreateCrossProcessHeap(int size) || Create a new cross process heap of size bytes || The heap ID or error (negative value)
 
|-
 
| 0x26 || int heap_destroy(int heapid) || Destroy the specified heap || 0 on success
 
|-
 
| 0x27 || void* IOS_Alloc(int heapid, u32 size) || Allocate size bytes from the specified heap || Pointer to memory
 
|-
 
| 0x28 || void* heap_alloc_aligned(int heapid, u32 size, u32 align) || Allocate size bytes from the specified heap with the requested alignment || Pointer to aligned memory
 
|-
 
| 0x29 || void IOS_Free(int heapid, void *ptr)  || Release allocated memory back to the heap || 0 on success
 
|-
 
| 0x2A || || ||
 
|-
 
| 0x2B || || ||
 
|-
 
| 0x2C || || ||
 
|-
 
| 0x2D || BOOL device_register(const char* device, int queueid) || Registers device to the device tree, so it can be opened (from Starbuck and PPC) || 0 on success
 
|-
 
| 0x2E || || ||
 
|-
 
| 0x2F || || ||
 
|-
 
| 0x30 || || ||
 
|-
 
| 0x31 || || ||
 
|-
 
| 0x32 || int query_featureid(int featureid, int out_size, void *out_buffer) || ||
 
|-
 
| 0x33 || int IOS_Open(const char* device, int mode) || Similar to IOS_Open on PPC, except now internal to the IOSU system || Returns an fd or error (negative)
 
|-
 
| 0x34 || int IOS_Close(int fd) || Close a previously opened fd || 0 on success
 
|-
 
| 0x35 || int IOS_Read(int fd, void *buf, u32 len) || Read len bytes from fd into buf || The number of bytes read or error
 
|-
 
| 0x36 || int IOS_Write(int fd, const void *buf, u32 len) || Write len bytes to fd from buf || The number of bytes written or error
 
|-
 
| 0x37 || int IOS_Seek(int fd, int offset, int origin) || Seek to offset relative to origin || The new absolute offset or error
 
|-
 
| 0x38 || int IOS_Ioctl(int fd, u32 request, void *input_buffer, u32 input_buffer_len, void *output_buffer, u32 output_buffer_len) || Perform the requested IOCTL || Return value from IOCTL
 
|-
 
| 0x39 || int IOS_Ioctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, struct iovec *vector) || Perform the requested IOCTL || Return value from IOCTL
 
|-
 
| 0x3A || int IOS_OpenAsync(const char* device, int mode, int queueid, ipcmessage *message) || Async implementation of IOS_Open || 0 on success, ipcmessage is sent to the queue with the command's return value
 
|-
 
| 0x3B || int IOS_CloseAsync(int fd, int queueid, ipcmessage *message) || Async implementation of IOS_Close || 0 on success
 
|-
 
| 0x3C || int IOS_ReadAsync(int fd, void *buf, u32 len, int queueid, ipcmessage *message) || Async implementation of IOS_Read || 0 on success
 
|-
 
| 0x3D || int IOS_WriteAsync(int fd, const void *buf, u32 len, int queueid, ipcmessage *message) || Async implementation of IOS_Write || 0 on success
 
|-
 
| 0x3E || int IOS_SeekAsync(int fd, int offset int origin, int queueid, ipcmessage *message) || Async implementation of IOS_Seek || 0 on success
 
|-
 
| 0x3F || int IOS_IoctlAsync(int fd, u32 request, void *input_buffer, u32 input_buffer_len, void *output_buffer, u32 output_buffer_len, int queueid, ipcmessage *message) || Async implementation of IOS_Ioctl || 0 on success
 
|-
 
| 0x40 || int IOS_IoctlvAsync(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, struct iovec *vector, int queueid, ipcmessage *message) || Async implementation of IOS_Ioctlv || 0 on success
 
|-
 
| 0x41 || || ||
 
|-
 
| 0x42 || || ||
 
|-
 
| 0x43 || || ||
 
|-
 
| 0x44 || || ||
 
|-
 
| 0x45 || || ||
 
|-
 
| 0x46 || || ||
 
|-
 
| 0x47 || || ||
 
|-
 
| 0x48 || || ||
 
|-
 
| 0x49 || IOS_ResourceReply(???) || ||
 
|-
 
| 0x4A || || ||
 
|-
 
| 0x4B || || ||
 
|-
 
| 0x4C || || ||
 
|-
 
| 0x4D || || ||
 
|-
 
| 0x4E || || ||
 
|-
 
| 0x4F || || ||
 
|-
 
| 0x50 || IOS_ClearandEnable(???) || ||
 
|-
 
| 0x51 || access_iobuf_pool(???) || ||
 
|-
 
| 0x52 || || ||
 
|-
 
| 0x53 || || ||
 
|-
 
| 0x54 || || ||
 
|-
 
| 0x55 || || ||
 
|-
 
| 0x56 || || ||
 
|-
 
| 0x57 || || ||
 
|-
 
| 0x58 || || ||
 
|-
 
| 0x59 || || ||
 
|-
 
| 0x5A || || ||
 
|-
 
| 0x5B || || ||
 
|-
 
| 0x5C || || ||
 
|-
 
| 0x5D || || ||
 
|-
 
| 0x5E || || ||
 
|-
 
| 0x5F || || ||
 
|-
 
| 0x60 || || ||
 
|-
 
| 0x61 || IOS_CreateSemaphore(???) || ||
 
|-
 
| 0x62 || IOS_WaitSemaphore(???) || ||
 
|-
 
| 0x63 || IOS_SignalSemaphore(???) || ||
 
|-
 
| 0x64 || IOS_DestroySemaphore(???) || ||
 
|-
 
| 0x65 || || ||
 
|-
 
| 0x66 || || ||
 
|-
 
| 0x67 || || ||
 
|-
 
| 0x68 || || ||
 
|-
 
| 0x69 || || ||
 
|-
 
| 0x6A || get_iop_cpu_utilization(???) || ||
 
|-
 
| 0x6B || || ||
 
|-
 
| 0x6C || IOS_ThreadProfileCommand(???) || ||
 
|-
 
| 0x6D || get_thread_utilization(???) || ||
 
|-
 
| 0x6E || || ||
 
|-
 
| 0x6F || || ||
 
|-
 
| 0x70 || || ||
 
|-
 
| 0x71 || get_iobuf_utilization(???) || ||
 
|-
 
| 0x72 || get_message_utilization(???) || ||
 
|-
 
| 0x73 || get_active_resources(???) || ||
 
|-
 
| 0x74 || || ||
 
|-
 
| 0x75 || get_timer_utilization(???) || ||
 
|-
 
| 0x76 || get_semaphore_utilization(???) || ||
 
|-
 
| 0x77 || || ||
 
|-
 
| 0x78 || || ||
 
|-
 
| 0x79 || || ||
 
|-
 
| 0x7A || || ||
 
|-
 
| 0x7B || || ||
 
|-
 
| 0x7C || || ||
 
|-
 
| 0x7D || || ||
 
|-
 
| 0x7E || || ||
 
|-
 
| 0x7F || panic(???) || ||
 
|-
 
| 0x80 || crash(???) || ||
 
|-
 
| 0x81 || || ||
 
|-
 
| 0x82 || || ||
 
|-
 
| 0x83 || || ||
 
|-
 
| 0x84 || || ||
 
|-
 
| 0x85 || || ||
 
|-
 
| 0x86 || || ||
 
|-
 
| 0x87 || || ||
 
|-
 
| 0x88 || || ||
 
|-
 
| 0x89 || || ||
 
|-
 
| 0x8A || || ||
 
|-
 
| 0x8B || || ||
 
|-
 
| 0x8C || || ||
 
|-
 
| 0x8D || || ||
 
|-
 
| 0x8E || get_resource_violations(???) || ||
 
|-
 
| 0x8F || || ||
 
|-
 
| 0x90 || || ||
 
|-
 
| 0x91 || || ||
 
|-
 
| 0x92 || || ||
 
|-
 
| 0x93 || || ||
 
|}
 

Latest revision as of 03:07, 11 February 2024

Redirect to: