daedalus/Source/SysPSP/PRX/ExceptionHandler/exception_asm.S
2019-02-27 17:04:51 +11:00

214 lines
6.6 KiB
ArmAsm

#include "as_reg_compat.h"
.set noreorder
.set noat
#define BadVAddr $8 // Address for the most recent address-related exception
#define Status $12 // Processor status and control
#define Cause $13 // Cause of last general exception
#define EPC $14 // Program counter at last exception
#define PRId $15 // Processor identification and revision
#define FSR $31
#define FIR $0
#define REG_GPR_0 (6*4)
#define REG_GPR_1 (REG_GPR_0 + 4)
#define REG_GPR_2 (REG_GPR_1 + 4)
#define REG_GPR_3 (REG_GPR_2 + 4)
#define REG_GPR_4 (REG_GPR_3 + 4)
#define REG_GPR_5 (REG_GPR_4 + 4)
#define REG_GPR_6 (REG_GPR_5 + 4)
#define REG_GPR_7 (REG_GPR_6 + 4)
#define REG_GPR_8 (REG_GPR_7 + 4)
#define REG_GPR_9 (REG_GPR_8 + 4)
#define REG_GPR_10 (REG_GPR_9 + 4)
#define REG_GPR_11 (REG_GPR_10 + 4)
#define REG_GPR_12 (REG_GPR_11 + 4)
#define REG_GPR_13 (REG_GPR_12 + 4)
#define REG_GPR_14 (REG_GPR_13 + 4)
#define REG_GPR_15 (REG_GPR_14 + 4)
#define REG_GPR_16 (REG_GPR_15 + 4)
#define REG_GPR_17 (REG_GPR_16 + 4)
#define REG_GPR_18 (REG_GPR_17 + 4)
#define REG_GPR_19 (REG_GPR_18 + 4)
#define REG_GPR_20 (REG_GPR_19 + 4)
#define REG_GPR_21 (REG_GPR_20 + 4)
#define REG_GPR_22 (REG_GPR_21 + 4)
#define REG_GPR_23 (REG_GPR_22 + 4)
#define REG_GPR_24 (REG_GPR_23 + 4)
#define REG_GPR_25 (REG_GPR_24 + 4)
#define REG_GPR_26 (REG_GPR_25 + 4)
#define REG_GPR_27 (REG_GPR_26 + 4)
#define REG_GPR_28 (REG_GPR_27 + 4)
#define REG_GPR_29 (REG_GPR_28 + 4)
#define REG_GPR_30 (REG_GPR_29 + 4)
#define REG_GPR_31 (REG_GPR_30 + 4)
#define REG_STATUS (REG_GPR_31 + 4)
#define REG_LO (REG_STATUS + 4)
#define REG_HI (REG_LO + 4)
#define REG_BADVADDR (REG_HI + 4)
#define REG_CAUSE (REG_BADVADDR + 4)
#define REG_EPC (REG_CAUSE + 4)
#define REG_FPR_0 (REG_EPC + 4)
#define REG_FPR_1 (REG_FPR_0 + 4)
#define REG_FPR_2 (REG_FPR_1 + 4)
#define REG_FPR_3 (REG_FPR_2 + 4)
#define REG_FPR_4 (REG_FPR_3 + 4)
#define REG_FPR_5 (REG_FPR_4 + 4)
#define REG_FPR_6 (REG_FPR_5 + 4)
#define REG_FPR_7 (REG_FPR_6 + 4)
#define REG_FPR_8 (REG_FPR_7 + 4)
#define REG_FPR_9 (REG_FPR_8 + 4)
#define REG_FPR_10 (REG_FPR_9 + 4)
#define REG_FPR_11 (REG_FPR_10 + 4)
#define REG_FPR_12 (REG_FPR_11 + 4)
#define REG_FPR_13 (REG_FPR_12 + 4)
#define REG_FPR_14 (REG_FPR_13 + 4)
#define REG_FPR_15 (REG_FPR_14 + 4)
#define REG_FPR_16 (REG_FPR_15 + 4)
#define REG_FPR_17 (REG_FPR_16 + 4)
#define REG_FPR_18 (REG_FPR_17 + 4)
#define REG_FPR_19 (REG_FPR_18 + 4)
#define REG_FPR_20 (REG_FPR_19 + 4)
#define REG_FPR_21 (REG_FPR_20 + 4)
#define REG_FPR_22 (REG_FPR_21 + 4)
#define REG_FPR_23 (REG_FPR_22 + 4)
#define REG_FPR_24 (REG_FPR_23 + 4)
#define REG_FPR_25 (REG_FPR_24 + 4)
#define REG_FPR_26 (REG_FPR_25 + 4)
#define REG_FPR_27 (REG_FPR_26 + 4)
#define REG_FPR_28 (REG_FPR_27 + 4)
#define REG_FPR_29 (REG_FPR_28 + 4)
#define REG_FPR_30 (REG_FPR_29 + 4)
#define REG_FPR_31 (REG_FPR_30 + 4)
#define REG_FSR (REG_FPR_31 + 4)
#define REG_FIR (REG_FSR + 4)
#define REG_FP (REG_FIR + 4)
.extern exception_regs
.extern curr_handler
.global _pspDebugExceptionHandler
.ent _pspDebugExceptionHandler
_pspDebugExceptionHandler:
nop
nop
lw $v0, exception_regs
sw $0, REG_GPR_0($v0)
sw $1, REG_GPR_1($v0)
cfc0 $1, $4 # Get original v0
sw $1, REG_GPR_2($v0)
cfc0 $1, $5 # Get original v1
sw $1, REG_GPR_3($v0)
sw $4, REG_GPR_4($v0)
sw $5, REG_GPR_5($v0)
sw $6, REG_GPR_6($v0)
sw $7, REG_GPR_7($v0)
sw $8, REG_GPR_8($v0)
sw $9, REG_GPR_9($v0)
sw $10, REG_GPR_10($v0)
sw $11, REG_GPR_11($v0)
sw $12, REG_GPR_12($v0)
sw $13, REG_GPR_13($v0)
sw $14, REG_GPR_14($v0)
sw $15, REG_GPR_15($v0)
sw $16, REG_GPR_16($v0)
sw $17, REG_GPR_17($v0)
sw $18, REG_GPR_18($v0)
sw $19, REG_GPR_19($v0)
sw $20, REG_GPR_20($v0)
sw $21, REG_GPR_21($v0)
sw $22, REG_GPR_22($v0)
sw $23, REG_GPR_23($v0)
sw $24, REG_GPR_24($v0)
sw $25, REG_GPR_25($v0)
sw $26, REG_GPR_26($v0)
sw $27, REG_GPR_27($v0)
sw $28, REG_GPR_28($v0)
sw $29, REG_GPR_29($v0)
sw $30, REG_GPR_30($v0)
sw $31, REG_GPR_31($v0)
mflo $v1
sw $v1, REG_LO($v0)
mfhi $v1
sw $v1, REG_HI($v0)
mfc0 $v1, BadVAddr
sw $v1, REG_BADVADDR($v0)
mfc0 $v1, Cause
sw $v1, REG_CAUSE($v0)
mfc0 $v1, EPC
sw $v1, REG_EPC($v0)
mfc0 $v1, Status
sw $v1, REG_STATUS($v0)
# Check if cop1 is enable and skip if not
lui $a0, 0x2000
and $a0, $a0, $v1
beq $a0, $0, 1f
nop
swc1 $0, REG_FPR_0($v0)
swc1 $1, REG_FPR_1($v0)
swc1 $2, REG_FPR_2($v0)
swc1 $3, REG_FPR_3($v0)
swc1 $4, REG_FPR_4($v0)
swc1 $5, REG_FPR_5($v0)
swc1 $6, REG_FPR_6($v0)
swc1 $7, REG_FPR_7($v0)
swc1 $8, REG_FPR_8($v0)
swc1 $9, REG_FPR_9($v0)
swc1 $10, REG_FPR_10($v0)
swc1 $11, REG_FPR_11($v0)
swc1 $12, REG_FPR_12($v0)
swc1 $13, REG_FPR_13($v0)
swc1 $14, REG_FPR_14($v0)
swc1 $15, REG_FPR_15($v0)
swc1 $16, REG_FPR_16($v0)
swc1 $17, REG_FPR_17($v0)
swc1 $18, REG_FPR_18($v0)
swc1 $19, REG_FPR_19($v0)
swc1 $20, REG_FPR_20($v0)
swc1 $21, REG_FPR_21($v0)
swc1 $22, REG_FPR_22($v0)
swc1 $23, REG_FPR_23($v0)
swc1 $24, REG_FPR_24($v0)
swc1 $25, REG_FPR_25($v0)
swc1 $26, REG_FPR_26($v0)
swc1 $27, REG_FPR_27($v0)
swc1 $28, REG_FPR_28($v0)
swc1 $29, REG_FPR_29($v0)
swc1 $30, REG_FPR_30($v0)
swc1 $31, REG_FPR_31($v0)
cfc1 $t0, FSR
sw $t0, REG_FSR($v0)
cfc1 $t0, FIR
sw $t0, REG_FIR($v0)
ctc1 $0, FSR # Clear any cause flags
# Jump target for ignore cop1
1:
sw $sp, REG_FP($v0)
move $a0, $v0
lw $2, curr_handler
mtc0 $2, $14
nop
nop
eret
nop
nop
.end _pspDebugExceptionHandler
#include "pspimport.s"
IMPORT_START "ExceptionManagerForKernel",0x00010011
IMPORT_FUNC "ExceptionManagerForKernel",0x565C0B0E,sceKernelRegisterDefaultExceptionHandler371