-
Notifications
You must be signed in to change notification settings - Fork 6
The input output processor (IOP)
The input/output processor (IOP) is a MIPS R3000A, or in later PlayStation 2 models a PowerPC 405GP emulating a MIPS R3000A. It provides a number of services, particularly for peripheral devices, such as USB devices, controllers, and so on. Device drivers for these are implemented as IOP modules that the Linux kernel loads as firmware.
Loaded IOP modules are accessible via the iop-module-sysfs.ko
sysfs kernel module. It gives information on IOP module file names, sizes, and addresses, and so on. The modules are numbered in directories, from 1:
# ls /sys/firmware/iop
1 4 7 10 13 16 19 22 25
2 5 8 11 14 17 20 23 26
3 6 9 12 15 18 21 24 27
Directories have module properties:
# ls /sys/firmware/iop/1
bss_size entry gp name text_size version
data_size flags id newflags text_start
List of all module names:
# cat /sys/firmware/iop/*/name | sort -f | column
cdvd_driver IOP_SIF_rpc_interface ROM_file_driver
cdvd_ee_driver irq secrman_for_cex
dmacman irqrelay ssbus_service
Exception_Manager LoadModuleByEE Stdio
FILEIO_service Module_Manager SyncEE
Heap_lib Moldule_File_loader System_C_lib
Interrupt_Manager Multi_Thread_Manager System_Memory_Manager
IO/File_Manager printk Timer_Manager
IOP_SIF_manager RebootByEE Vblank_service
The memory of loaded modules can be examined using /dev/mem
. First, one needs to obtain the IOP RAM base address:
# grep IOP /proc/iomem
1c000000-1c1fffff : IOP RAM
Now let’s look at the text segment of the first module, which happens to be System_Memory_Manager
:
# cd /sys/firmware/iop/1
# cat name
System_Memory_Manager
# dd if=/dev/mem bs=$(cat text_size) iflag=skip_bytes \
skip=$(( 0x1c000000 + $(cat text_start) )) count=1 status=none | xxd | head
00000000: 0000 0000 400d 0400 0101 0000 7379 736d ....@.......sysm
00000010: 656d 0000 9008 0000 0809 0000 8808 0000 em..............
00000020: 900c 0000 1c0b 0000 6c0b 0000 340a 0000 ........l...4...
00000030: 600a 0000 c40a 0000 d40b 0000 3c0c 0000 `...........<...
00000040: 8808 0000 8808 0000 8808 0000 c013 0000 ................
00000050: 0c14 0000 0000 0000 0800 e003 0000 0000 ................
00000060: e8ff bd27 7f00 023c 00ff 4234 2a10 4400 ...'...<..B4*.D.
00000070: 0300 4010 1000 bfaf 7f00 043c 00ff 8434 ..@........<...4
00000080: 0000 023c c315 4224 00ff 0324 2410 4300 ...<..B$...$$.C.
00000090: 0000 053c b414 a524 2418 8300 0000 a2ac ...<...$$.......
IOP modules are IRX objects based on the executable and linkable format (ELF), having the suffix .irx
. All valid IOP modules have a special .iopmod
section containing the module name, version, etc. IOP module link requests are only permitted if the major versions match and the module version is at least of the same minor as the requested version.
When the IOP is reset, a set of modules are automatically linked from read-only memory (ROM). Non-ROM modules are handled as firmware by the IOP module linker.
IOP modules may import and export any number of library functions, including non at all. Imported libraries must be resolved and prelinked before the given module is allowed to link itself. Other modules can link with its exported libraries.
IOP modules begin to execute their entry function immediately after linking. The modules can either stay resident in the IOP, and provide services, or unlink themselves when exiting the entry function. Many modules provide remote procedure call (RPC) services via the sub-system interface (SIF).
As a simplification the IOP module linker assumes that modules with exported libraries are resident. The primary effect is that it refuses to link modules exporting libraries with the same names more than once, even if the they may have been unlinked in the IOP. This is because the IOP module linker maintains its own list of exported libraries, rather than asking the IOP about them, which remains to be implemented.
The IOP module linker also assumes that if a module exports a library it has the same name as the module. The simplifies resolving dependencies. In general, and with most ROM modules, the module name is not the same as the exported library names. A single module may export multiple libraries, but that is currently not not fully supported with IOP modules for Linux, due to dependency resolving limitations.
The iopmod-info
tool from the iopmod repo can be used to examine IRX objects, particularly properties that other tools such as objdump doesn’t recognise:
# iopmod-info SIFMAN.irx
iopmod id addr 0xf70
iopmod id name IOP_SIF_manager
iopmod id version 0x0101
iopmod entry addr 0x0
iopmod unknown addr 0x8f70
iopmod text size 3792
iopmod data size 176
iopmod bss size 1072
iopmod version 0x0101
iopmod name IOP_SIF_manager
import library 0x0101 loadcore
import 0 6
import library 0x0102 intrman
import 0 4 intrman_request_irq
import 1 5 intrman_release_irq
import 2 6 intrman_enable_irq
import 3 7 intrman_disable_irq
import 4 9 intrman_cpu_enable_irqs
import 5 17 intrman_cpu_suspend_irq
import 6 18 intrman_cpu_resume_irq
export library 0x0101 sifman
export 0 0x0000 _init_module
export 1 0x0e48
export 2 0x0268
export 3 0x0e48
export 4 0x00f4 sifman_dma2_init
export 5 0x0148 sifman_init
export 6 0x02e8 sifman_set_dchain
export 7 0x0598 sifman_set_dma
export 8 0x0740 sifman_dma_stat
export 9 0x0798 sifman_set_one_dma
export 10 0x0894
export 11 0x08d4
export 12 0x08ec sifman_dma0_transfer
export 13 0x09a8 sifman_dma0_sync
export 14 0x09e8 sifman_dma0_sending
export 15 0x0a00 sifman_dma1_transfer
export 16 0x0ad8 sifman_dma1_sync
export 17 0x0b18 sifman_dma1_sending
export 18 0x0b30 sifman_dma2_transfer
export 19 0x0c34 sifman_dma2_sync
export 20 0x0c74 sifman_dma2_sending
export 21 0x0c8c sifman_get_ms_flag
export 22 0x0cac sifman_set_ms_flag
export 23 0x0cd8 sifman_get_sm_flag
export 24 0x0cf8 sifman_set_sm_flag
export 25 0x0d24 sifman_get_main_addr
export 26 0x0d34 sifman_get_sub_addr
export 27 0x0d48 sifman_set_sub_addr
export 28 0x0d60 sifman_intr_main
export 29 0x02d8 sifman_check_init
export 30 0x033c sifman_set_dma_intr_handler
export 31 0x0350 sifman_reset_dma_intr_handler
export 32 0x0e48 sifman_set_dma_intr
export 33 0x0e48
export 34 0x0e48
export 35 0x0e48
See #11.