2 Copyright 2010, jimmikaelkael <jimmikaelkael@wanadoo.fr>
3 Licenced under Academic Free License version 3.0
4 Review Open PS2 Loader README & LICENSE files for further details.
6 The goal of the code in this file is to force syscall hooks to use
7 an alternate stack when they need to use stack.
10 #include <ee_cop0_defs.h>
11 #include <syscallnr.h>
14 #define ARGBUF_SIZE 580
16 #define COMPAT_MODE_3 0x04
18 #define PADOPEN_HOOK 0
26 /**************************************************************************
30 **************************************************************************/
45 .extern iop_reboot_count
49 .extern padOpen_hooked
51 .extern Old_CreateThread
58 .extern Install_PadOpen_Hook
61 .globl Hook_LoadExecPS2
65 .globl Hook_CreateThread
69 * _LoadExecPS2: this function preserves args and change stack pointer
70 * before to execute t_loadElf
75 /* save args, not needed to preserve sX/ra registers values as we won't return */
76 daddu $s0, $a0, $zero /* ELF path */
77 daddu $s1, $a1, $zero /* argc */
78 daddu $s2, $a2, $zero /* argv */
80 /* dark blue BG color */
87 mfc0 $v1, EE_COP0_Status
90 daddu $a0, $zero, $zero
96 mfc0 $v1, EE_COP0_Status
103 /* entering Kernel mode */
104 mfc0 $v0, EE_COP0_Status
108 mtc0 $v0, EE_COP0_Status
111 /* set g_argc to arg count , or MAX_ARGS if greater */
112 slti $v0, $s1, MAX_ARGS+1
113 addiu $v1, $zero, MAX_ARGS
118 /* pointer to g_argbuf */
122 daddu $a0, $s3, $zero
123 daddu $a1, $zero, $zero
125 addiu $a2, $zero, ARGBUF_SIZE
127 /* copy elfname to argv[0] */
128 daddu $a0, $s3, $zero
129 daddu $a1, $s0, $zero
131 addiu $a2, $zero, ARGBUF_SIZE
133 /* set g_argv[0] to g_argbuf */
137 /* increment arg buffer pointer */
139 daddu $a0, $s0, $zero
143 /* increment g_argc */
146 daddu $s4, $v0, $zero /* g_argc(-1) */
150 /* copy args from main ELF to args buffer */
152 daddu $s5, $zero, $zero /* counter */
154 /* get arg len and increment it */
155 daddu $a0, $s2, $zero
160 addiu $s6, $v0, 1 /* arg len */
162 /* copy arg to main args buffer */
163 daddu $a0, $s3, $zero
164 daddu $a1, $s2, $zero
169 daddu $a2, $s6, $zero
171 /* store arg pointer to g_argv[counter+1] */
177 /* increment arg buffer pointer with arg len + 1 */
180 /* loop on every args */
186 /* exiting Kernel mode */
187 mfc0 $v0, EE_COP0_Status
189 mtc0 $v0, EE_COP0_Status
196 daddu $a0, $zero, $zero
197 addiu $v1, $zero, __NR_FlushCache
200 addiu $v1, $zero, __NR_FlushCache
203 /* change stack pointer to top of user memory */
205 daddu $sp, $v0, $zero
208 * ExecPS2() does the following for us:
209 * - do a soft EE peripheral reset
210 * - terminate all threads and delete all semaphores
211 * - set up ELF loader thread and run it
214 daddu $a1, $zero, $zero
215 daddu $a2, $zero, $zero
216 daddu $a3, $zero, $zero
217 addiu $v1, $zero, __NR_ExecPS2
224 * Hook_LoadExecPS2: exit syscall to _LoadExecPS2
226 .ent Hook_LoadExecPS2
229 /* exit syscall to _LoadExecPS2 */
235 .end Hook_LoadExecPS2
238 * _SifSetDma: function designed to use our own stack during IOP reboot trap
243 /* save original stack pointer */
244 daddu $a2, $sp, $zero
246 #ifdef LOAD_EECORE_DOWN
248 /* ori $v0, $v0, 0x0000 */
253 /* change the stack pointer */
254 daddu $sp, $v0, $zero
256 /* call New_SifSetDma, preserving ra and a2 registers values */
257 addiu $sp, $sp, -0x10
262 /* restore a2 and ra registers */
266 /* restore the original stack pointer */
267 daddu $sp, $a2, $zero
269 #ifdef LOAD_EECORE_DOWN
279 sq $zero, 0x0000($v0)
280 sq $zero, 0x0010($v0)
281 sq $zero, 0x0020($v0)
282 sq $zero, 0x0030($v0)
283 addiu $v0, $v0, 0x0040
288 daddu $a0, $zero, $zero
289 addiu $v1, $zero, __NR_FlushCache
292 addiu $v1, $zero, __NR_FlushCache
301 * Hook_SifSetDma: exit syscall to _SifSetDma when IOP reboot trapped
306 /* check ((SifDmaTransfer_t *)$a0)->attr == 0x44 */
308 addiu $v0, $zero, 0x44
311 /* check ((SifDmaTransfer_t *)$a0)->size == 0x68 */
313 addiu $v0, $zero, 0x68
316 /* check ((SifDmaTransfer_t *)$a0)->size == 0x70 */
317 addiu $v0, $zero, 0x70
320 /* check (SifCmdResetData *)((SifDmaTransfer_t *)$a0->src)->chdr.psize == ((SifDmaTransfer_t *)$a0)->size */
325 /* check (SifCmdResetData *)((SifDmaTransfer_t *)$a0->src)->chdr.fcode == 0x80000003 */
332 /* exit syscall to _SifSetDma */
337 /* call & return with original SifSetDma */
338 lw $v0, Old_SifSetDma
345 * _Apply_Mode3: unhook SifSetDma/SifSetReg
350 /* save original stack pointer */
351 daddu $a0, $sp, $zero
353 #ifdef LOAD_EECORE_DOWN
355 /* ori $v0, $v0, 0x0000 */
360 /* change the stack pointer */
361 daddu $sp, $v0, $zero
363 /* preserving ra and a0 registers values */
364 addiu $sp, $sp, -0x10
368 /* unhook SifSetDma */
369 addiu $a0, $zero, __NR_SifSetDma
370 lw $a1, Old_SifSetDma
371 addiu $v1, $zero, __NR_SetSyscall
374 /* unhook SifSetReg */
375 addiu $a0, $zero, __NR_SifSetReg
376 lw $a1, Old_SifSetReg
377 addiu $v1, $zero, __NR_SetSyscall
381 daddu $a0, $zero, $zero
382 addiu $v1, $zero, __NR_FlushCache
385 addiu $v1, $zero, __NR_FlushCache
388 /* restore a0 and ra registers */
392 /* restore the original stack pointer */
393 daddu $sp, $a0, $zero
401 * Hook_SifSetReg: disable SifSetReg and unhook SifSetDma/SifSetReg when needed
406 /* load set_reg_hook counter to a2 */
410 /* check set_reg_hook is != 0, otherwise execute normal SifSetReg */
413 lw $v0, Old_SifSetReg
417 /* decrement set_reg_hook counter by 1 */
428 sd $zero, 0x0000($v0)
430 /* check compat mode 3 is enabled */
431 lw $v0, g_compat_mask
432 andi $v0, $v0, COMPAT_MODE_3
435 /* check iop_reboot_count is == 2 */
437 lw $v0, iop_reboot_count
441 /* exit syscall to _Apply_Mode3 */
456 /* not needed to preserve sX/ra registers values as ExecPS2 won't return */
457 daddu $s0, $a0, $zero
458 daddu $s1, $a1, $zero
459 daddu $s2, $a2, $zero
460 daddu $s3, $a3, $zero
462 /* check entry point is >= 0x00100000 */
467 /* save original stack pointer */
468 daddu $s4, $sp, $zero
470 #ifdef LOAD_EECORE_DOWN
472 /* ori $v0, $v0, 0x0000 */
478 /* change stack pointer */
479 daddu $sp, $v0, $zero
481 /* call Install_PadOpen_Hook */
484 jal Install_PadOpen_Hook
485 addiu $a2, $zero, PADOPEN_HOOK
486 la $v1, padOpen_hooked
489 /* restore stack pointer */
490 daddu $sp, $s4, $zero
493 daddu $a0, $s0, $zero
494 daddu $a1, $s1, $zero
495 daddu $a2, $s2, $zero
498 daddu $a3, $s3, $zero
505 .ent Hook_CreateThread
508 /* check padOpen_hooked == 0 */
509 lw $v0, padOpen_hooked
512 /* check thread_param->initial_priority == 0 */
516 /* check thread_param->initial_priority < 5 */
520 /* check thread_param->current_priority == 0 */
524 /* save original stack pointer */
525 daddu $a1, $sp, $zero
527 #ifdef LOAD_EECORE_DOWN
529 /* ori $v0, $v0, 0x0000 */
534 /* change the stack pointer */
535 daddu $sp, $v0, $zero
537 /* preserves ra, a1 and a0 registers values */
538 addiu $sp, $sp, -0x20
543 /* call Install_PadOpen_Hook */
546 jal Install_PadOpen_Hook
547 addiu $a2, $zero, PADOPEN_HOOK
548 la $v1, padOpen_hooked
551 /* restore a0, a1 and ra registers */
556 /* restore the original stack pointer */
557 daddu $sp, $a1, $zero
559 /* call CreateThread */
560 lw $v0, Old_CreateThread
564 .end Hook_CreateThread
567 /**************************************************************************
571 **************************************************************************/