Difference between revisions of "IOS/Syscalls"

From WiiBrew
< IOS
Jump to: navigation, search
(corrected syscall 47)
(Updated starlet_syscall_handler code to IOS70)
Line 25: Line 25:
 
  kernel:FFFF0004              LDR    PC, =starlet_syscall_handler
 
  kernel:FFFF0004              LDR    PC, =starlet_syscall_handler
 
   
 
   
  kernel:FFFF1894             starlet_syscall_handler                ; CODE XREF: start�j
+
  kernel:FFFF1F24             starlet_syscall_handler                ; CODE XREF: start�j
  kernel:FFFF1894 E9 CD 7F FF                STMFA  SP, {R0-LR}^
+
  kernel:FFFF1F24 E9 CD 7F FF                STMFA  SP, {R0-LR}^
  kernel:FFFF1898 E1 4F 80 00                MRS    R8, SPSR
+
  kernel:FFFF1F28 E1 4F 80 00                MRS    R8, SPSR
  kernel:FFFF189C E5 8D 80 00                STR    R8, [SP,#arg_0]
+
  kernel:FFFF1F2C E5 8D 80 00                STR    R8, [SP,#spsr_register_save]
  kernel:FFFF18A0 E5 8D E0 40                STR    LR, [SP,#arg_40]
+
  kernel:FFFF1F30 E5 8D E0 40                STR    LR, [SP,#lr_register_save]
  kernel:FFFF18A4 E5 1E A0 04                LDR    R10, [LR,#-4]
+
  kernel:FFFF1F34 E5 1E A0 04                LDR    R10, [LR,#-4]   ; R10 = E600XXXX  (the invalid instruction)
  kernel:FFFF18A8 E3 CA 9D 7F                BIC    R9, R10, #0x1FC0
+
  kernel:FFFF1F38 E3 CA 9D 7F                BIC    R9, R10, #NOT 0xFFFFE03F
  kernel:FFFF18AC E5 9F 84 9C                 LDR    R8, =0xE6000010
+
  kernel:FFFF1F3C E5 9F 84 CC                 LDR    R8, =0xE6000010 ; syscall base
  kernel:FFFF18B0 E3 C9 90 20                BIC    R9, R9, #0x20
+
  kernel:FFFF1F40 E3 C9 90 20                BIC    R9, R9, #NOT 0xFFFFFFDF
  kernel:FFFF18B4 E1 59 00 08                CMP    R9, R8
+
  kernel:FFFF1F44 E1 59 00 08                CMP    R9, R8         ; ???
  kernel:FFFF18B8 1A 00 00 1F                BNE    loc_FFFF193C
+
  kernel:FFFF1F48 1A 00 00 1F                BNE    loc_FFFF1FCC
  kernel:FFFF18BC E1 A0 A2 CA                MOV    R10, R10,ASR#5
+
  kernel:FFFF1F4C E1 A0 A2 CA                MOV    R10, R10,ASR#5  ; R10 = R10 >> 5
  kernel:FFFF18C0 E2 0A A0 FF                AND    R10, R10, #0xFF
+
  kernel:FFFF1F50 E2 0A A0 FF                AND    R10, R10, #0xFF ; R10 = R10 & 0xFF
  kernel:FFFF18C4 E3 5A 00 75                 CMP    R10, #0x75 ; 'u'
+
  kernel:FFFF1F54 E3 5A 00 7A                 CMP    R10, #0x7A      ; max index of syscall ?
  kernel:FFFF18C8 CA 00 00 11                BGT    loc_FFFF1914
+
  kernel:FFFF1F58 CA 00 00 11                BGT    return_to_caller
  kernel:FFFF18CC E1 A0 80 0D                MOV    R8, SP
+
  kernel:FFFF1F5C E1 A0 80 0D                MOV    R8, SP
  kernel:FFFF18D0 E3 A0 B0 1F                MOV    R11, #0x1F
+
  kernel:FFFF1F60 E3 A0 B0 1F                MOV    R11, #0b11111
  kernel:FFFF18D4 E1 21 F0 0B                MSR    CPSR_c, R11
+
  kernel:FFFF1F64 E1 21 F0 0B                MSR    CPSR_c, R11     ; switch to system mode, disable irq & fiq
  kernel:FFFF18D8 E5 98 80 44                LDR    R8, [R8,#arg_44]
+
  kernel:FFFF1F68 E5 98 80 44                LDR    R8, [R8,#sp_register_save]
  kernel:FFFF18DC E5 9F B4 70                 LDR    R11, =syscall_flags_maybe
+
  kernel:FFFF1F6C E5 9F B4 A0                 LDR    R11, =literal_2
  kernel:FFFF18E0 E7 9B B1 0A                LDR    R11, [R11,R10,LSL#2]
+
  kernel:FFFF1F70 E7 9B B1 0A                LDR    R11, [R11,R10,LSL#2]
  kernel:FFFF18E4 E0 8D D1 0B                ADD    SP, SP, R11,LSL#2
+
  kernel:FFFF1F74 E0 8D D1 0B                ADD    SP, SP, R11,LSL#2
  kernel:FFFF18E8
+
  kernel:FFFF1F78             unknown_loop                           ; CODE XREF: start+1F8C�j
kernel:FFFF18E8             loc_FFFF18E8                           ; CODE XREF: starlet_syscall_handler+68�j
+
  kernel:FFFF1F78 E3 5B 00 00                CMP    R11, #0
  kernel:FFFF18E8 E3 5B 00 00                CMP    R11, #0
+
  kernel:FFFF1F7C 0A 00 00 03                BEQ    find_syscall_and_jump
  kernel:FFFF18EC 0A 00 00 03                BEQ    loc_FFFF1900
+
  kernel:FFFF1F80 E5 3D 90 04                LDR    R9, [SP,#var_4]!
  kernel:FFFF18F0 E5 3D 90 04                LDR    R9, [SP,#var_4]!
+
  kernel:FFFF1F84 E5 28 90 04                STR    R9, [R8,#-4]!
  kernel:FFFF18F4 E5 28 90 04                STR    R9, [R8,#-4]!
+
  kernel:FFFF1F88 E2 4B B0 01                SUB    R11, R11, #1
  kernel:FFFF18F8 E2 4B B0 01                SUB    R11, R11, #1
+
  kernel:FFFF1F8C EA FF FF F9                B      unknown_loop
  kernel:FFFF18FC EA FF FF F9                B      loc_FFFF18E8
+
  kernel:FFFF1F90             find_syscall_and_jump                  ; CODE XREF: start+1F7C�j
  kernel:FFFF1900             loc_FFFF1900                            ; CODE XREF: starlet_syscall_handler+58�j
+
  kernel:FFFF1F90 E1 A0 D0 08                MOV    SP, R8
  kernel:FFFF1900 E1 A0 D0 08                MOV    SP, R8
+
  kernel:FFFF1F94 E5 9F B4 7C                 LDR    R11, =syscall_table
  kernel:FFFF1904 E5 9F B4 4C                 LDR    R11, =syscall_base
+
  kernel:FFFF1F98 E7 9B B1 0A                LDR    R11, [R11,R10,LSL#2] ; syscall number * sizeof(dword) + syscall table offset
  kernel:FFFF1908 E7 9B B1 0A                LDR    R11, [R11,R10,LSL#2]
+
  kernel:FFFF1F9C E1 A0 E0 0F                MOV    LR, PC         ; save returning position
  kernel:FFFF190C E1 A0 E0 0F                MOV    LR, PC
+
  kernel:FFFF1FA0 E1 2F FF 1B                BX      R11             ; jump to syscall implementation
  kernel:FFFF1910 E1 2F FF 1B                BX      R11
+
  kernel:FFFF1FA0                                                    ;
  kernel:FFFF1914             loc_FFFF1914                            ; CODE XREF: starlet_syscall_handler+34�j
+
kernel:FFFF1FA0                                                    ; NOTE: every syscall function
  kernel:FFFF1914 E3 A0 B0 DB                MOV    R11, #0xDB ; '¦'
+
kernel:FFFF1FA0                                                    ; ends with something like "bx lr"
  kernel:FFFF1918 E1 21 F0 0B                MSR    CPSR_c, R11
+
kernel:FFFF1FA4
  kernel:FFFF191C E5 9D B0 00                LDR    R11, [SP,#arg_0]
+
kernel:FFFF1FA4             return_to_caller                        ; CODE XREF: start+1F58�j
  kernel:FFFF1920 E1 6F F0 0B                MSR    SPSR_cxsf, R11
+
  kernel:FFFF1FA4 E3 A0 B0 DB                MOV    R11, #0xDB     ; switch to undefined mode + re-enable FIQ/IRQ
  kernel:FFFF1924 E1 A0 E0 00                MOV    LR, R0
+
  kernel:FFFF1FA8 E1 21 F0 0B                MSR    CPSR_c, R11
  kernel:FFFF1928 E9 DD 7F FF                LDMED  SP, {R0-LR}^
+
  kernel:FFFF1FAC E5 9D B0 00                LDR    R11, [SP,#spsr_register_save]
  kernel:FFFF192C E1 A0 00 00                NOP
+
  kernel:FFFF1FB0 E1 6F F0 0B                MSR    SPSR_cxsf, R11 ; restore spsr
  kernel:FFFF1930 E1 A0 00 0E                MOV    R0, LR
+
  kernel:FFFF1FB4 E1 A0 E0 00                MOV    LR, R0
  kernel:FFFF1934 E5 9D E0 40                LDR    LR, [SP,#arg_40]
+
  kernel:FFFF1FB8 E9 DD 7F FF                LDMED  SP, {R0-LR}^
  kernel:FFFF1938 E1 B0 F0 0E                MOVS    PC, LR
+
  kernel:FFFF1FBC E1 A0 00 00                NOP
  kernel:FFFF193C             loc_FFFF193C                           ; CODE XREF: starlet_syscall_handler+24�j
+
  kernel:FFFF1FC0 E1 A0 00 0E                MOV    R0, LR
  kernel:FFFF193C E5 9F D4 18                 LDR    SP, =current_thread_context
+
  kernel:FFFF1FC4 E5 9D E0 40                LDR    LR, [SP,#lr_register_save]
  kernel:FFFF1940 E5 9D D0 00                LDR    SP, [SP,#arg_0]
+
  kernel:FFFF1FC8 E1 B0 F0 0E                MOVS    PC, LR         ; return to caller
  kernel:FFFF1944 E5 8D E0 40                STR    LR, [SP,#arg_40]
+
kernel:FFFF1FCC
  kernel:FFFF1948 E3 A0 E0 06                MOV    LR, #6
+
  kernel:FFFF1FCC             loc_FFFF1FCC                           ; CODE XREF: start+1F48�j
  kernel:FFFF194C E5 8D E0 50                STR    LR, [SP,#arg_50]
+
  kernel:FFFF1FCC E5 9F D4 48                 LDR    SP, =current_thread_context_addr
  kernel:FFFF1950 E2 8D D0 04                ADD    SP, SP, #4
+
  kernel:FFFF1FD0 E5 9D D0 00                LDR    SP, [SP,#spsr_register_save]
  kernel:FFFF1954 E9 4D 7F FF                STMFD  SP, {R0-LR}^
+
  kernel:FFFF1FD4 E5 8D E0 40                STR    LR, [SP,#lr_register_save]
  kernel:FFFF1958 E1 4F B0 00                MRS    R11, SPSR
+
  kernel:FFFF1FD8 E3 A0 E0 06                MOV    LR, #6
  kernel:FFFF195C E5 0D B0 04                STR    R11, [SP,#-4+arg_0]
+
  kernel:FFFF1FDC E5 8D E0 50                STR    LR, [SP,#arg_50]
  kernel:FFFF1960 EA 00 00 C9                 B      schedule
+
  kernel:FFFF1FE0 E2 8D D0 04                ADD    SP, SP, #4
  kernel:FFFF1960             ; End of function starlet_syscall_handler
+
  kernel:FFFF1FE4 E9 4D 7F FF                STMFD  SP, {R0-LR}^
 +
  kernel:FFFF1FE8 E1 4F B0 00                MRS    R11, SPSR
 +
  kernel:FFFF1FEC E5 0D B0 04                STR    R11, [SP,#-4+spsr_register_save]
 +
  kernel:FFFF1FF0 EA 00 00 D2                 B      schedule
 +
  kernel:FFFF1FF0             ; End of function starlet_syscall_handler
 
   
 
   
Syscalls are invoked by way of the invalid instruction handler; syscalls take the form 0xE6000010 | (syscall_num << 5). (E.g. E6000010 is syscall 0, E60006D0 is syscall 0x36, etc.)
+
Syscalls are invoked by way of the invalid instruction handler; syscalls take the form 0xE6000010 | (syscall_num << 5). (E.g. E6000010 is syscall 0, E60006D0 is syscall 0x36, etc.). IOS70 has 0x7A available syscalls.
  
 
tmbinc has written an IDAPython script which can take a database that has "syscall_base" defined, and transform the references to it into more meaningful things -- it is available here: [[IOS/Syscall IDAPython]]
 
tmbinc has written an IDAPython script which can take a database that has "syscall_base" defined, and transform the references to it into more meaningful things -- it is available here: [[IOS/Syscall IDAPython]]

Revision as of 21:15, 10 December 2009

There are 2 types of syscalls:

1. Syscalls using undefined ARM instruction.

2. Syscalls using ARM syscall instruction.

Syscalls (via undefined instructions)

Internally, IOS uses a syscall table that is stored toward the end of the binary. The exact address varies with version of IOS, but there are two methods to locate it:

ELF header:

The second-to-last program header is the syscall table. For example:

$ arm-eabi-readelf -l ~/wii/system_updates/boot2.elf  | tail -2
 LOAD           0x0230d5 0xffff7f60 0xffff7f60 0x00a88 0x00a88 RW  0x10
 LOAD           0x023b5d 0xffff8a00 0xffff8a00 0x00000 0x071e8 RW  0x20

or

elf_header:134C01A0 elf32_phdr < 1, 0x230D5, syscall_base, syscall_base, 0xA88, 0xA88,  6, 0x10>
elf_header:134C01C0 elf32_phdr < 1, 0x23B5D, current_thread_context, current_thread_context, 0, 0x71E8,  6, 0x20>

Syscall Handler: The second vector is the invalid instruction handler, which is used to implement syscalls:

kernel:FFFF0000               LDR     PC, =_reset
kernel:FFFF0004               LDR     PC, =starlet_syscall_handler

kernel:FFFF1F24             starlet_syscall_handler                 ; CODE XREF: start�j
kernel:FFFF1F24 E9 CD 7F FF                 STMFA   SP, {R0-LR}^
kernel:FFFF1F28 E1 4F 80 00                 MRS     R8, SPSR
kernel:FFFF1F2C E5 8D 80 00                 STR     R8, [SP,#spsr_register_save]
kernel:FFFF1F30 E5 8D E0 40                 STR     LR, [SP,#lr_register_save]
kernel:FFFF1F34 E5 1E A0 04                 LDR     R10, [LR,#-4]   ; R10 = E600XXXX  (the invalid instruction)
kernel:FFFF1F38 E3 CA 9D 7F                 BIC     R9, R10, #NOT 0xFFFFE03F
kernel:FFFF1F3C E5 9F 84 CC                 LDR     R8, =0xE6000010 ; syscall base
kernel:FFFF1F40 E3 C9 90 20                 BIC     R9, R9, #NOT 0xFFFFFFDF
kernel:FFFF1F44 E1 59 00 08                 CMP     R9, R8          ; ???
kernel:FFFF1F48 1A 00 00 1F                 BNE     loc_FFFF1FCC
kernel:FFFF1F4C E1 A0 A2 CA                 MOV     R10, R10,ASR#5  ; R10 = R10 >> 5
kernel:FFFF1F50 E2 0A A0 FF                 AND     R10, R10, #0xFF ; R10 = R10 & 0xFF
kernel:FFFF1F54 E3 5A 00 7A                 CMP     R10, #0x7A      ; max index of syscall ?
kernel:FFFF1F58 CA 00 00 11                 BGT     return_to_caller
kernel:FFFF1F5C E1 A0 80 0D                 MOV     R8, SP
kernel:FFFF1F60 E3 A0 B0 1F                 MOV     R11, #0b11111
kernel:FFFF1F64 E1 21 F0 0B                 MSR     CPSR_c, R11     ; switch to system mode, disable irq & fiq
kernel:FFFF1F68 E5 98 80 44                 LDR     R8, [R8,#sp_register_save]
kernel:FFFF1F6C E5 9F B4 A0                 LDR     R11, =literal_2
kernel:FFFF1F70 E7 9B B1 0A                 LDR     R11, [R11,R10,LSL#2]
kernel:FFFF1F74 E0 8D D1 0B                 ADD     SP, SP, R11,LSL#2
kernel:FFFF1F78             unknown_loop                            ; CODE XREF: start+1F8C�j
kernel:FFFF1F78 E3 5B 00 00                 CMP     R11, #0
kernel:FFFF1F7C 0A 00 00 03                 BEQ     find_syscall_and_jump
kernel:FFFF1F80 E5 3D 90 04                 LDR     R9, [SP,#var_4]!
kernel:FFFF1F84 E5 28 90 04                 STR     R9, [R8,#-4]!
kernel:FFFF1F88 E2 4B B0 01                 SUB     R11, R11, #1
kernel:FFFF1F8C EA FF FF F9                 B       unknown_loop
kernel:FFFF1F90             find_syscall_and_jump                   ; CODE XREF: start+1F7C�j
kernel:FFFF1F90 E1 A0 D0 08                 MOV     SP, R8
kernel:FFFF1F94 E5 9F B4 7C                 LDR     R11, =syscall_table
kernel:FFFF1F98 E7 9B B1 0A                 LDR     R11, [R11,R10,LSL#2] ; syscall number * sizeof(dword) + syscall table offset
kernel:FFFF1F9C E1 A0 E0 0F                 MOV     LR, PC          ; save returning position
kernel:FFFF1FA0 E1 2F FF 1B                 BX      R11             ; jump to syscall implementation
kernel:FFFF1FA0                                                     ;
kernel:FFFF1FA0                                                     ; NOTE: every syscall function
kernel:FFFF1FA0                                                     ; ends with something like "bx lr"
kernel:FFFF1FA4
kernel:FFFF1FA4             return_to_caller                        ; CODE XREF: start+1F58�j
kernel:FFFF1FA4 E3 A0 B0 DB                 MOV     R11, #0xDB      ; switch to undefined mode + re-enable FIQ/IRQ
kernel:FFFF1FA8 E1 21 F0 0B                 MSR     CPSR_c, R11
kernel:FFFF1FAC E5 9D B0 00                 LDR     R11, [SP,#spsr_register_save]
kernel:FFFF1FB0 E1 6F F0 0B                 MSR     SPSR_cxsf, R11  ; restore spsr
kernel:FFFF1FB4 E1 A0 E0 00                 MOV     LR, R0
kernel:FFFF1FB8 E9 DD 7F FF                 LDMED   SP, {R0-LR}^
kernel:FFFF1FBC E1 A0 00 00                 NOP
kernel:FFFF1FC0 E1 A0 00 0E                 MOV     R0, LR
kernel:FFFF1FC4 E5 9D E0 40                 LDR     LR, [SP,#lr_register_save]
kernel:FFFF1FC8 E1 B0 F0 0E                 MOVS    PC, LR          ; return to caller
kernel:FFFF1FCC
kernel:FFFF1FCC             loc_FFFF1FCC                            ; CODE XREF: start+1F48�j
kernel:FFFF1FCC E5 9F D4 48                 LDR     SP, =current_thread_context_addr
kernel:FFFF1FD0 E5 9D D0 00                 LDR     SP, [SP,#spsr_register_save]
kernel:FFFF1FD4 E5 8D E0 40                 STR     LR, [SP,#lr_register_save]
kernel:FFFF1FD8 E3 A0 E0 06                 MOV     LR, #6
kernel:FFFF1FDC E5 8D E0 50                 STR     LR, [SP,#arg_50]
kernel:FFFF1FE0 E2 8D D0 04                 ADD     SP, SP, #4
kernel:FFFF1FE4 E9 4D 7F FF                 STMFD   SP, {R0-LR}^
kernel:FFFF1FE8 E1 4F B0 00                 MRS     R11, SPSR
kernel:FFFF1FEC E5 0D B0 04                 STR     R11, [SP,#-4+spsr_register_save]
kernel:FFFF1FF0 EA 00 00 D2                 B       schedule
kernel:FFFF1FF0             ; End of function starlet_syscall_handler

Syscalls are invoked by way of the invalid instruction handler; syscalls take the form 0xE6000010 | (syscall_num << 5). (E.g. E6000010 is syscall 0, E60006D0 is syscall 0x36, etc.). IOS70 has 0x7A available syscalls.

tmbinc has written an IDAPython script which can take a database that has "syscall_base" defined, and transform the references to it into more meaningful things -- it is available here: IOS/Syscall IDAPython

(please feel free to contribute your own findings!)

ID # Internal name Description Return value
0 u32 thread_create( u32 (*proc)(void* arg), u8 priority, u32* stack, u32 stacksize, void* arg, BOOL autostart) Creates a thread Returns threadid
1 thread_join
2 thread_cancel( u32 threadid, u32 ? )
3 get_tid
4 get_pid
5 thread_continue
6 thread_stop( u32 threadid )
7 thread_yield
8 thread_get_priority
9 thread_set_priority
a message_queue_create(void *ptr, int n_msgs)
b message_queue_destroy(int queue)
c message_queue_send
d message_queue_send_now
e message_queue_receive(int queue, void *message, int flags)
f RegisterEventHandler(int device, int queue, int message)
10 UnregisterEventHandler
11 IOS_CreateTimer(int time, int wtf, int message_queue, int message)
12 IOS_RestartTimer
13 IOS_StopTimer
14 IOS_DestroyTimer
15 timer_now
16 heap_create(void *ptr, int size)
17 heap_destroy(int heap)
18 heap_alloc(int heap, int size)
19 heap_alloc_aligned(int heap, int size, int align)
1a heap_free(void *ptr)
1b BOOL device_register(char* device, u32 messagequeue) Registers device to the device tree, so it can be opened (from Starlet and PPC) Returns 0 on success, else error
1c s32 device_open(char* device, int mode) Similar to IOS_Open on PPC, except now internal to the IOS system Returns an fd
1d s32 device_close(s32 fd)
1e s32 device_read(s32 fd, void *buf, s32 len)
1f s32 device_write(s32 fd, void *buf, s32 len)
20 s32 device_seek(s32 fd, s32 where, s32 whence)
21 s32 device_ioctl(s32 fd, u32 request, void *input_buffer, u32 input_buffer_len, void *output_buffer, u32 output_buffer_len)
22 s32 device_ioctlv(s32 fd, u32 request, u32 bytes_in, u32 bytes_out, struct iovec *vector)
23 s32 device_open_async(char* device, int mode, void *callback)
24 s32 device_close_async(s32 fd, void *callback)
25 s32 device_read_async(s32 fd, void *buf, s32 len, void *callback)
26 s32 device_write_async(s32 fd, void *buf, s32 len, void *callback)
27 s32 device_seek_async(s32 fd, s32 where, s32 whence, void *callback)
28 s32 device_ioctl_async(s32 fd, u32 request, void *input_buffer, u32 input_buffer_len, void *output_buffer, u32 output_buffer_len, void *callback
29 s32 device_ioctlv_async(s32 fd, u32 request, u32 bytes_in, u32 bytes_out, struct iovec *vector, void *callback)
2a int IOS_ResourceReply( struct ios_ressource_request *request, int retval) return from a cmd on a ressource
2b SetUID
2c get_hmac_queue_for_pid
2d SetGID
2e lookup_GID_maybe
2f cc_ahbMemFlush
30 syscall_ahbMemFlush_wrapper
31 software_IRQ_31 seems to enable hardware interrupts for device nr 31
32 software_irq_18 seems to enable hardware interrupts for device nr 18
33 software_IRQ_7_or_8(id) seems to enable hardware interrupts for device nr 7 if id==0, else device nr 8 (sdhc)
34 software_IRQ(id) enables hardware interrupts for device nr. id; check caller PID
35 access_iobuf_pool(arg1) no-op in IOS-35, arg1=0 returns always 0
36 struct iobuf *alloc_iobuf(arg1, sbuf) allocate an iobuf, arg1=0 (unknown), sbuf = buffer size return NULL on error
37 int free_iobuf(struct iobuf *buf) free an allocated iobuf
38 iobuf_log_header_info
39 iobuf_log_buffer_info
3a void *extend_iobuf(struct iobuf *iob, unsigned short num) extend the data in the buffer by num bytes returns pointer to extended area
3b void *IOS_PushIob(struct iobuf *iob, unsigned short num) move head pointer in io buffer num bytes towards the buffer end returns old head pointer
3c void *IOS_PullIob(struct iobuf *iob, unsigned short num) move head pointer in io buffer num bytes towards the buffer start
3d int verify_iobuf(struct iobuf *iob) verify if the argument points to an io buffer
3e syscall_3e
3f void sync_before_read(u32 address, u32 size) Invalidates dcache, and something (probably related to flushing memory)
40 sync_after_write(u32 address, u32 size) Flushes dcache and does magic bullshit (aka magic AHB operations)
41 ppc_boot
42 ios_boot
43 syscall_43
44 int syscall_assert_di_reset Clears bit 10 of 0xD800194 Returns 0 on success, -1 on error
45 int syscall_deassert_di_reset Enables bit 10 of 0xD800194 Returns 0 on success, -1 on error
46 BOOL syscall_check_di_reset Checks bit 10 of 0xD800194 Returns 1 on reset asserted, 0 on (deasserted or error)
47 GetSomeFlags Depending on what is currently running (boot2/IOS) it returns different values IOS: *(u32*)r0=0 *(u16*)r1=0

Boot2: *(u32*)r0=3 *(u16*)r1=0

48 set_r0_1_r1_0
49 get_boot_vector
4a GetHollywoodRevision
4b kernel_debug_print
4c kernel_set_version
4d kernel_get_version
4e poke_E0_1
4f virt_to_phys(void *ptr)
50 syscall_50
51 syscall_51
52 syscall_52
53 syscall_53 allows Broadway to access otherwise protected hardware (e.g. SD, NAND,...) directly. can only be called from kernel context
54 syscall_54
55 get_bc_flag
56 poke_gpios
57 syscall_57
58 call_poke_debug_port
59 create_key
5a destroy_key
5b do_something_with_tmd
5c IOSC_DeleteObject
5d set_public_key (7 arguments)
5e crypto_syscall_5e (7 arguments)
5f crypto_syscall_5f
60 crypto_syscall_60
61 get_keyid
62 crypto_syscall_62
63 get_key Used to get entries from the keyring. R0 is key index:
0 ECC Private Key
1 Console ID
2 NAND AES Key
3 NAND HMAC
4 Common Key
5 PRNG Seed (unused?)
6 SD Key
7 Boot2 version
8 ?
9 ?
10 Filesystem metadata (SFFS) generation
11 "Korean Common Key"
64 sha_async
65 sha
66 aes_async (7 args)
67 aes (5 args)
68 crypto_syscall_68 (7 args)
69 crypto_syscall_69 (5 args)
6a crypto_syscall_6a (7 args)
6b aes_decrypt(int keyid, void *iv, void *in, int len, void *out)
6c hmac_async
6d crypto_syscall_6d (8 args)
6e get_ng_cert (10 args)
6f key_set_permission_mask
70 crypto_syscall_70
71 crypto_syscall_71
72 crypto_syscall_72
73 crypto_syscall_73
74 crypto_syscall_74
75 crypto_syscall_75
76 crypto_syscall_76

Syscalls (via ARM syscall instruction)

These types of syscalls are created with the ARM syscall instruction. The exception handler is empty and just do nothing and returns. These syscalls are RealView semihosting operations that allow communication with a debugger. Currently only the following syscalls are still used in distributed IOS versions:

MOVS r0, #syscall_number
SVC 0xAB

Register r0 takes the syscall number. Register r1 takes the first parameter.

ID # Internal name Description Return value
4 write(const char *string) Prints a null-terminated debug message. unknown.