14static int lock_sema = -1;
15static int lock_sema2 = -1;
16static u16 hooked_version = 0;
18intrman_internals_t *mmce_sio2_intrman_internals_ptr = NULL;
21typedef void (*psio2_transfer_init)(void);
22typedef int (*psio2_transfer)(sio2_transfer_data_t *td);
23typedef void (*psio2_transfer_reset)(void);
26psio2_transfer_init _23_psio2_pad_transfer_init;
27psio2_transfer_init _24_psio2_mc_transfer_init;
28psio2_transfer_init _46_psio2_pad_transfer_init;
29psio2_transfer_init _47_psio2_mc_transfer_init;
30psio2_transfer_init _48_psio2_mtap_transfer_init;
31psio2_transfer_init _49_psio2_rm_transfer_init;
32psio2_transfer_init _50_psio2_unk_transfer_init;
33psio2_transfer _25_psio2_transfer;
34psio2_transfer _51_psio2_transfer;
35psio2_transfer_reset _26_psio2_transfer_reset;
36psio2_transfer_reset _52_psio2_transfer_reset;
39static void _sio2_transfer_init(psio2_transfer_init init_func)
47static int _sio2_transfer(psio2_transfer transfer_func, sio2_transfer_data_t *td)
54 rv = transfer_func(td);
55 SignalSema(lock_sema2);
61static void _sio2_transfer_reset(psio2_transfer_reset reset_func)
66 SignalSema(lock_sema);
70static void _23_sio2_pad_transfer_init() { _sio2_transfer_init(_23_psio2_pad_transfer_init); }
71static void _24_sio2_mc_transfer_init() { _sio2_transfer_init(_24_psio2_mc_transfer_init); }
72static void _46_sio2_pad_transfer_init() { _sio2_transfer_init(_46_psio2_pad_transfer_init); }
73static void _47_sio2_mc_transfer_init() { _sio2_transfer_init(_47_psio2_mc_transfer_init); }
74static void _48_sio2_mtap_transfer_init() { _sio2_transfer_init(_48_psio2_mtap_transfer_init); }
75static void _49_sio2_rm_transfer_init() { _sio2_transfer_init(_49_psio2_rm_transfer_init); }
76static void _50_sio2_unk_transfer_init() { _sio2_transfer_init(_50_psio2_unk_transfer_init); }
77static void _26_sio2_transfer_reset() { _sio2_transfer_reset(_26_psio2_transfer_reset); }
78static void _52_sio2_transfer_reset() { _sio2_transfer_reset(_52_psio2_transfer_reset); }
79static int _25_sio2_transfer(sio2_transfer_data_t *td) {
return _sio2_transfer(_25_psio2_transfer, td); }
80static int _51_sio2_transfer(sio2_transfer_data_t *td) {
return _sio2_transfer(_51_psio2_transfer, td); }
82static void _sio2man_unhook(iop_library_t *lib)
84 if (hooked_version == 0) {
85 DPRINTF(
"Warning: trying to unhook sio2man while not hooked\n");
97 if ((hooked_version >= IRX_VER(1, 2)) && (hooked_version < IRX_VER(2, 0))) {
114static void _sio2man_hook(iop_library_t *lib)
116 if (hooked_version != 0) {
117 DPRINTF(
"Warning: trying to hook sio2man version 0x%x\n", lib->version);
118 DPRINTF(
" while version 0x%x already hooked\n", hooked_version);
123 if (lib->version > IRX_VER(1, 1)) {
124 DPRINTF(
"Installing sio2man hooks for version 0x%x\n", lib->version);
128 _23_psio2_pad_transfer_init();
137 if ((lib->version >= IRX_VER(1, 2)) && (lib->version < IRX_VER(2, 0))) {
152 _26_psio2_transfer_reset();
154 hooked_version = lib->version;
156 DPRINTF(
"ERROR: sio2man version 0x%x not supported\n", lib->version);
161static int hooked = 0;
162int (*pRegisterIntrHandler)(
int irq,
int mode, int (*handler)(
void *),
void *arg);
163static int hookRegisterIntrHandler(
int irq,
int mode,
int (*handler)(
void *),
void *arg)
165 DPRINTF(
"RegisterIntrHandler irq: %i, handler @ 0x%p\n", irq, handler);
168 if (irq == 17 && hooked == 0) {
170 if (handler != mmce_sio2_intr_handler_ptr) {
171 sio2man_intr_handler_ptr = handler;
172 sio2man_intr_arg_ptr = arg;
175 DPRINTF(
"Got SIO2MAN intr handler @ 0x%p, arg @ 0x%p\n", handler, arg);
179 return pRegisterIntrHandler(irq, mode, handler, arg);
183int (*pRegisterLibraryEntries)(iop_library_t *lib);
184static int hookRegisterLibraryEntries(iop_library_t *lib)
188 if (!strcmp(lib->name,
"sio2man")) {
192 return pRegisterLibraryEntries(lib);
195int sio2man_hook_init()
203 mmce_sio2_intrman_internals_ptr = GetIntrmanInternalData();
204 if (mmce_sio2_intrman_internals_ptr == NULL) {
205 DPRINTF(
"Failed to get intrman internals ptr\n");
214 lock_sema = CreateSema(&sema);
215 lock_sema2 = CreateSema(&sema);
221 sio2man_intr_handler_ptr = mmce_sio2_intrman_internals_ptr->interrupt_handler_table[17].handler;
222 sio2man_intr_arg_ptr = mmce_sio2_intrman_internals_ptr->interrupt_handler_table[17].userdata;
223 DPRINTF(
"Got SIO2MAN intr handler @ 0x%p, arg @ 0x%p\n", sio2man_intr_handler_ptr, sio2man_intr_arg_ptr);
227 ioplib_relinkExports(lib);
234 DeleteSema(lock_sema);
235 DeleteSema(lock_sema2);
243 DeleteSema(lock_sema);
244 DeleteSema(lock_sema2);
253void sio2man_hook_deinit()
262 _sio2man_unhook(lib);
263 ioplib_relinkExports(lib);
279 DeleteSema(lock_sema);
280 DeleteSema(lock_sema2);
283void sio2man_hook_sio2_lock()
287 WaitSema(lock_sema2);
290void sio2man_hook_sio2_unlock()
293 SignalSema(lock_sema2);
294 SignalSema(lock_sema);
iop_library_t * ioplib_getByName(const char *name)
get library object of any IRX Module
void * ioplib_hookExportEntry(iop_library_t *lib, unsigned int entry, void *func)
hook an IRX Module exported function