28#define M_DEBUG DPRINTF
32typedef void (*psio2_transfer_init)(void);
34typedef void (*psio2_transfer_reset)(void);
40 psio2_transfer_init m_23_psio2_pad_transfer_init;
42 psio2_transfer m_25_psio2_transfer;
44 psio2_transfer_reset m_26_psio2_transfer_reset;
48static iop_library_t *g_loadcore_lib;
49#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
50static iop_library_t *g_intrman_lib;
51static int (*g_sio2man_intr_handler_ptr)(
void *arg);
52static void *g_sio2man_intr_arg_ptr;
65 for (i = 0; i < (
sizeof(td->regdata)/
sizeof(td->regdata[0])); i++) {
67 if (td->regdata[i] == 0)
72 if ((td->regdata[i] & 3) == PORT_NR)
73 return transfer_func(&g_null_td);
76 return transfer_func(td);
80static int _1_25_sio2_transfer(
sio2_transfer_data_t *td) {
return _sio2_transfer(g_hook_data[0].m_25_psio2_transfer, td); }
81static int _2_25_sio2_transfer(
sio2_transfer_data_t *td) {
return _sio2_transfer(g_hook_data[1].m_25_psio2_transfer, td); }
84static void unhook_loadcore(
void);
85#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
86static void unhook_intrman(
void);
89static void _sio2man_hook(iop_library_t *
lib)
103 M_DEBUG(
"Installing sio2man hooks for version 0x%x\n",
lib->version);
105 major_version = ((
lib->version >> 8) & 0xFF);
106 if (g_hook_data[major_version - 1].m_lib) {
107 M_DEBUG(
"Warning: trying to hook sio2man version 0x%x\n",
lib->version);
108 M_DEBUG(
" while version 0x%x already hooked\n", g_hook_data[major_version - 1].m_lib->version);
110 g_hook_data[major_version - 1].m_lib =
lib;
111 g_hook_data[major_version - 1].m_23_psio2_pad_transfer_init =
lib->exports[23];
113 g_hook_data[major_version - 1].m_25_psio2_transfer = ioplib_hookSameExportEntries(
lib, 25, (major_version == 1) ? &_1_25_sio2_transfer : &_2_25_sio2_transfer);
115 g_hook_data[major_version - 1].m_26_psio2_transfer_reset =
lib->exports[26];
117 ioplib_relinkExports(
lib);
123 M_DEBUG(
"ERROR: sio2man version 0x%x not supported\n",
lib->version);
127 if (g_hook_data[0].m_lib && g_hook_data[1].m_lib)
132#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
134static int (*pRegisterIntrHandler)(
int irq,
int mode, int (*handler)(
void *),
void *arg);
135static int hookRegisterIntrHandler(
int irq,
int mode,
int (*handler)(
void *),
void *arg)
138 M_DEBUG(
"RegisterIntrHandler irq: %i, handler @ 0x%p\n", irq, handler);
140 ret = pRegisterIntrHandler(irq, mode, handler, arg);
145 if (irq == IOP_IRQ_SIO2 && !g_sio2man_intr_handler_ptr) {
146 g_sio2man_intr_handler_ptr = handler;
147 g_sio2man_intr_arg_ptr = arg;
148 M_DEBUG(
"Got SIO2MAN intr handler @ 0x%p, arg @ 0x%p\n", handler, arg);
156static int (*pRegisterLibraryEntries)(iop_library_t *
lib);
157static int hookRegisterLibraryEntries(iop_library_t *
lib)
160 M_DEBUG(
"RegisterLibraryEntries: %s 0x%x\n",
lib->name,
lib->version);
162 ret = pRegisterLibraryEntries(
lib);
166 if (!strcmp(
lib->name,
"sio2man"))
171static void unhook_loadcore(
void)
176 if (g_loadcore_lib) {
177 if (pRegisterLibraryEntries)
178 ioplib_hookSameExportEntries(g_loadcore_lib, 6, pRegisterLibraryEntries);
179 g_loadcore_lib = NULL;
184#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
185static void unhook_intrman(
void)
191 if (pRegisterIntrHandler)
192 ioplib_hookSameExportEntries(g_intrman_lib, 4, pRegisterIntrHandler);
193 g_intrman_lib = NULL;
199static int generic_hook_iterate_cb(iop_library_t *
lib,
void *userdata)
202 if (userdata && !*(iop_library_t **)userdata)
203 *(iop_library_t **)userdata =
lib;
207static int sio2man_hook_iterate_cb(iop_library_t *
lib,
void *userdata)
210 switch ((
lib->version >> 8) & 0xFF)
216 return (g_hook_data[0].m_lib && g_hook_data[1].m_lib) ? 1 : 0;
223int sio2man_hook_init()
225 M_DEBUG(
"%s\n", __FUNCTION__);
227#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
229 intrman_internals_t *intrman_internals;
231 intrman_internals = GetIntrmanInternalData();
233 g_sio2man_intr_handler_ptr = intrman_internals->interrupt_handler_table[IOP_IRQ_SIO2].handler;
234 g_sio2man_intr_arg_ptr = intrman_internals->interrupt_handler_table[IOP_IRQ_SIO2].userdata;
239 if (!ioplib_iterateByName(
"sio2man", &sio2man_hook_iterate_cb, NULL)) {
241 ioplib_iterateByName(
"loadcore", &generic_hook_iterate_cb, &g_loadcore_lib);
242#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
244 ioplib_iterateByName(
"intrman", &generic_hook_iterate_cb, &g_intrman_lib);
248#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
252 pRegisterLibraryEntries = ioplib_hookSameExportEntries(g_loadcore_lib, 6, hookRegisterLibraryEntries);
253 ioplib_relinkExports(g_loadcore_lib);
254#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
255 pRegisterIntrHandler = ioplib_hookSameExportEntries(g_intrman_lib, 4, hookRegisterIntrHandler);
256 ioplib_relinkExports(g_intrman_lib);
263void sio2man_hook_deinit()
267 M_DEBUG(
"%s\n", __FUNCTION__);
270 for (i = 0; i < (
sizeof(g_hook_data)/
sizeof(g_hook_data[0])); i += 1) {
271 if (g_hook_data[i].m_lib) {
273 if (g_hook_data[i].m_25_psio2_transfer) {
274 ioplib_hookSameExportEntries(g_hook_data[i].m_lib, 25, g_hook_data[i].m_25_psio2_transfer);
275 g_hook_data[i].m_25_psio2_transfer = NULL;
277 ioplib_relinkExports(g_hook_data[i].m_lib);
279 g_hook_data[i].m_lib = NULL;
284#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
289void sio2man_hook_sio2_lock()
292 if (g_hook_data[1].m_23_psio2_pad_transfer_init)
293 g_hook_data[1].m_23_psio2_pad_transfer_init();
296void sio2man_hook_sio2_unlock()
299 if (g_hook_data[1].m_26_psio2_transfer_reset)
300 g_hook_data[1].m_26_psio2_transfer_reset();
303#if SIO2MAN_HOOK_SUPPORT_SET_INTR_HANDLER
304void sio2man_hook_sio2_set_intr_handler(
int (*handler)(
void *userdata),
void *userdata)
306 intrman_internals_t *intrman_internals;
309 intrman_internals = GetIntrmanInternalData();
311 intrman_internals->interrupt_handler_table[IOP_IRQ_SIO2].handler = handler ? handler : g_sio2man_intr_handler_ptr;
312 intrman_internals->interrupt_handler_table[IOP_IRQ_SIO2].userdata = handler ? userdata : g_sio2man_intr_arg_ptr;
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)