diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-05 02:34:11 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-05 02:34:11 +0200 |
| commit | beb76e4dd362374b8f42cd971d394bba1074cd8d (patch) | |
| tree | 3ea4cc342737afb9225c01160c92647ba66c78bd /indev/psn00bdbg-mk2/monitor/stubinst.S | |
| parent | 5d9aa2d3dfc7d6e51c2eb942ab4cdbae5571a40a (diff) | |
| download | psn00bsdk-fix-include.tar.gz | |
Replace .include with #includefix-include
For some reason, both mipsel-unknown-elf-gcc 8.2.0 and mipsel-non-elf
15.1.0 were unable to resolve .include assembler directives.
As a workaround, it is still possible to use the preprocessor, and
therefore the usual #include preprocessor directive. However, this
requires the assembly files to use the uppercase .S file extension.
Diffstat (limited to 'indev/psn00bdbg-mk2/monitor/stubinst.S')
| -rw-r--r-- | indev/psn00bdbg-mk2/monitor/stubinst.S | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/indev/psn00bdbg-mk2/monitor/stubinst.S b/indev/psn00bdbg-mk2/monitor/stubinst.S new file mode 100644 index 0000000..54bc8b9 --- /dev/null +++ b/indev/psn00bdbg-mk2/monitor/stubinst.S @@ -0,0 +1,185 @@ +# +# C-callable and linkable version of 'patchinst' portion of monitor.asm +# +# Assemble with: +# mipsel-none-elf-gcc -march=r3000 -c stubinst.s -o stubinst.o +# +# Then call the function early in your program: +# +# void mk2_InstallMonitor(void); +# +# ... +# +# int main(int argc, const char *argv[]) +# { +# ResetGraph(0); +# +# EnterCriticalSection(); +# mk2_InstallMonitor(); +# ExitCriticalSection(); +# ... +# +.set noreorder + +# +# These constants must reflect those in monitor.asm +# +.set MONADDR, 0xC000 +.set MAX_BREAK, 32 + +.set SAVE_mode, 0x30 +.set SAVE_tmode, 0x31 +.set SAVE_k0, 0x34 +.set SAVE_k1, 0x38 +.set SAVE_dcic, 0x3C + +.set DB_BRK_FLAG, 0 +.set DB_BRK_ADDR, 4 +.set DB_BRK_INST, 8 +.set DB_BRK_LCNT, 12 +.set DB_BRK_HCNT, 14 +.set DB_BRK_LEN, 16 + +.set DCIC, $7 + +.section .text + +.global _mk2_InstallMonitor +.type _mk2_InstallMonitor, @function +_mk2_InstallMonitor: + + addiu $sp, -4 + sw $ra, 0($sp) + li $a0, .Lbreakhook # Install breakpoint vector hook + li $a1, (.Lbreakhook_end-.Lbreakhook)+4 + li $a2, 0xA0000040 + jal .Lcopymem + nop + li $v0, 0x200 # Hook monitor entrypoint to + li $v1, 0x40 # SysErrUnresolvedException() slot + sll $v1, 2 + addu $v0, $v1 + la $v1, .Lpayload # Get entrypoint address + lw $v1, 0($v1) + nop + sw $v1, 0($v0) + addiu $t2, $0, 0xB0 # GetB0Table() + jalr $t2 + addiu $t1, $0, 0x57 + li $a0, 0x17 # Get pointer of ReturnFromException() + sll $a0, 2 + addu $a0, $v0 + lw $v0, 0($a0) # Save original address for later + la $v1, .Lpayload + lw $v1, 0($v1) + nop + beq $v0, $v1, .Lnoinstall # Don't install if hooked already + nop + addiu $sp, -4 + sw $a0, 0($sp) + li $a0, .Lpayload # Load monitor code into target + li $a1, (.Lpayload_end-.Lpayload)+4 # address + lui $a2, 0xA000 # write via uncached segment + jal .Lcopymem + ori $a2, MONADDR + lw $a0, 0($sp) + addiu $sp, 4 + lw $v0, 0($a0) + la $v1, .Lpayload + lw $v1, 4($v1) + nop + sw $v0, 0($v1) + la $v0, .Lpayload # Set new address to table + lw $v0, 0($v0) + nop + sw $v0, 0($a0) + li $a0, 0x80 # Move existing exception vector + li $a2, 0x90 # jump to prepend patch + jal .Lcopymem + li $a1, 16 + la $a0, .Lexceptpatch # Patch the exception vector for + li $a2, 0x80 # trace to work properly + jal .Lcopymem + li $a1, 16 + addiu $t2, $0, 0xA0 # FlushCache() just to make sure + jalr $t2 + addiu $t1, $0, 0x44 + jal .Linit_breakpoints + nop + .Lnoinstall: + lw $ra, 0($sp) # Return to caller, debugger + addiu $sp, 4 # already installed + jr $ra + nop + + # patchinst + +# +# = installer's copy routine +# +.Lcopymem: + addiu $a1, -4 + lw $v0, 0($a0) + addiu $a0, 4 + sw $v0, 0($a2) + bgtz $a1, .Lcopymem + addiu $a2, 4 + jr $ra + nop + + # copymem + +# +# = Initializes breakpoint list +# +.Linit_breakpoints: + la $a2, .Lpayload # Get address of breakpoint table + lw $a2, 8($a2) + li $a3, MAX_BREAK + addiu $v0, $0, -1 + .Lclear_loop: + sw $v0, DB_BRK_INST($a2) + sw $v0, DB_BRK_ADDR($a2) + sw $0 , DB_BRK_FLAG($a2) + addiu $a3, -1 + bnez $a3, .Lclear_loop + addiu $a2, DB_BRK_LEN + jr $ra + nop + # init_breakpoints + +# +# = Break vector hook code +# +# This is copied to the breakpoint exception vector at address 40h +# +.Lbreakhook: + sw $k0, SAVE_k0($0) # Save K0 and K1 registers + mfc0 $k0, DCIC # Save DCIC + sw $k1, SAVE_k1($0) + mtc0 $0, DCIC # Clear DCIC in case trace is still + sw $k0, SAVE_dcic($0) # effective + la $k0, breakhandler # Jump to break vector handler + jr $k0 + nop +.Lbreakhook_end: + +# +# = Exception vector patch +# +# This is prepended to the exception vector jump at address 80h +# +.Lexceptpatch: + mfc0 $k0, DCIC # backup DCIC value + nop + mtc0 $0 , DCIC # clear DCIC + sw $k0, SAVE_dcic($0) + +# +# = Payload data +# +.section .data + +.Lpayload: + .incbin "patchcode.bin" +.Lpayload_end: |
