pcsx2/pcsx2hostfs/ee/exceptions.S

226 lines
6.3 KiB
ArmAsm

/*********************************************************************
* Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
* This file is subject to the terms and conditions of the PS2Link License.
* See the file LICENSE in the main directory of this distribution for more
* details.
*/
# ASM exception handlers
#include "r5900_regs.h"
.set noat
.set noreorder
.text
.p2align 4
.global _savedRegs
.global pkoStepBP
.ent pkoStepBP
pkoStepBP:
# Should check for cause in cop0 Cause reg
# If Bp, increase EPC (DO NOT PUT 'break' in a branch delay slot!!!)
mfc0 k0, EPC # cop0 EPC
addiu k0, k0, 4 # Step over breakpoint
mtc0 k0, EPC
sync.p
eret
.end pkoStepBP
# Save all user regs
# Save HI/LO, SR, BadVAddr, Cause, EPC, ErrorEPC,
# ShiftAmount, cop0: $24, $25
# Save float regs??
# Set EPC to debugger
# Set stack to 'exception stack'
# eret
.global pkoExceptionHandler
.ent pkoExceptionHandler
pkoExceptionHandler:
la k0, _savedRegs
sq $0, 0x00(k0)
sq at, 0x10(k0)
sq v0, 0x20(k0)
sq v1, 0x30(k0)
sq a0, 0x40(k0)
sq a1, 0x50(k0)
sq a2, 0x60(k0)
sq a3, 0x70(k0)
sq t0, 0x80(k0)
sq t1, 0x90(k0)
sq t2, 0xa0(k0)
sq t3, 0xb0(k0)
sq t4, 0xc0(k0)
sq t5, 0xd0(k0)
sq t6, 0xe0(k0)
sq t7, 0xf0(k0)
sq t8, 0x100(k0)
sq t9, 0x110(k0)
sq s0, 0x120(k0)
sq s1, 0x130(k0)
sq s2, 0x140(k0)
sq s3, 0x150(k0)
sq s4, 0x160(k0)
sq s5, 0x170(k0)
sq s6, 0x180(k0)
sq s7, 0x190(k0)
# sq k0, 0x1a0(k0) # $k0
sq zero, 0x1a0(k0) # zero instead
sq k1, 0x1b0(k0) # $k1
sq gp, 0x1c0(k0)
sq sp, 0x1d0(k0) # sp
sq fp, 0x1e0(k0)
sq ra, 0x1f0(k0) # $ra
pmfhi t0 # HI
pmflo t1 # LO
sq t0, 0x200(k0)
sq t1, 0x210(k0)
mfc0 t0, BadVAddr # Cop0 state regs
mfc0 t1, Status
sw t0, 0x220(k0)
sw t1, 0x224(k0)
mfc0 t0, Cause
mfc0 t1, EPC
sw t0, 0x228(k0)
sw t1, 0x22c(k0)
# Kernel saves these two also..
mfc0 t0, DEPC
mfc0 t1, PerfCnt
sw t0, 0x230(k0)
sw t1, 0x234(k0)
mfsa t0
sw t0, 0x238(k0)
# Use our own stack..
la sp, _exceptionStack+0x2000-16
la gp, _gp # Use exception handlers _gp
# Return from exception and start 'debugger'
mfc0 a0, Cause # arg0
mfc0 a1, BadVAddr
mfc0 a2, Status
mfc0 a3, EPC
addu t0, zero, k0 # arg4 = registers
move t1, sp
la k0, pkoDebug
mtc0 k0, EPC # eret return address
sync.p
mfc0 k0, Status # check this out..
li v0, 0xfffffffe
and k0, v0
mtc0 k0, Status
sync.p
nop
nop
nop
nop
eret
nop
.end pkoExceptionHandler
# Put EE in kernel mode
# Restore all user regs etc
# Restore PC? & Stack ptr
# Restore interrupt sources
# Jump to EPC
.ent pkoReturnFromDebug
.global pkoReturnFromDebug
pkoReturnFromDebug:
lui t1, 0x1
_disable:
di
sync
mfc0 t0, Status
and t0, t1
beqz t0, _disable
nop
la k0, _savedRegs
lq t0, 0x200(k0)
lq t1, 0x210(k0)
pmthi t0 # HI
pmtlo t1 # LO
lw t0, 0x220(k0)
lw t1, 0x224(k0)
mtc0 t0, BadVAddr
mtc0 t1, Status
lw t0, 0x228(k0)
lw t1, 0x22c(k0)
mtc0 t0, Cause
mtc0 t1, EPC
# Kernel saves these two also..
lw t0, 0x230(k0)
lw t1, 0x234(k0)
mtc0 t0, DEPC
mtc0 t1, PerfCnt
# Shift Amount reg
lw t0, 0x238(k0)
mtsa t0
# ori t2, 0xff
# sw t2, 0(k1)
# lq $0, 0x00(k0)
lq $1, 0x10(k0)
lq $2, 0x20(k0)
lq $3, 0x30(k0)
lq $4, 0x40(k0)
lq $5, 0x50(k0)
lq $6, 0x60(k0)
lq $7, 0x70(k0)
lq $8, 0x80(k0)
lq $9, 0x90(k0)
lq $10, 0xa0(k0)
lq $11, 0xb0(k0)
lq $12, 0xc0(k0)
lq $13, 0xd0(k0)
lq $14, 0xe0(k0)
lq $15, 0xf0(k0)
lq $16, 0x100(k0)
lq $17, 0x110(k0)
lq $18, 0x120(k0)
lq $19, 0x130(k0)
lq $10, 0x140(k0)
lq $21, 0x150(k0)
lq $22, 0x160(k0)
lq $23, 0x170(k0)
lq $24, 0x180(k0)
lq $25, 0x190(k0)
# lq $26, 0x1a0(k0) # $k0
lq $27, 0x1b0(k0) # $k1
lq $28, 0x1c0(k0)
lq $29, 0x1d0(k0) # $sp
lq $30, 0x1e0(k0)
# lq $31, 0x1f0(k0) # $ra
lw ra, 0x22c(k0)
# Guess one should have some check here, and only advance PC if
# we are going to step over a Breakpoint or something
# (i.e. do stuff depending on Cause)
addiu ra, 4
sync.p
ei
sync.p
jr ra
nop
.end pkoReturnFromDebug