1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/stage2/handlers.S Tue Jun 23 23:08:19 2015 +0200
1.3 @@ -0,0 +1,168 @@
1.4 +/*
1.5 + * Handler routines.
1.6 + *
1.7 + * Copyright (C) 2008 by Maurus Cuelenaere
1.8 + * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.9 + *
1.10 + * This program is free software: you can redistribute it and/or modify
1.11 + * it under the terms of the GNU General Public License as published by
1.12 + * the Free Software Foundation, either version 3 of the License, or
1.13 + * (at your option) any later version.
1.14 + *
1.15 + * This program is distributed in the hope that it will be useful,
1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.18 + * GNU General Public License for more details.
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License
1.21 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
1.22 + */
1.23 +
1.24 +.text
1.25 +.extern irq_handle
1.26 +.globl real_exception_handler
1.27 +.set noreorder
1.28 +.set noat
1.29 +
1.30 +#define C0_STATUS $12
1.31 +#define C0_CAUSE $13
1.32 +#define C0_EPC $14
1.33 +#define C0_CONFIG $16
1.34 +#define S_CauseExcCode 2
1.35 +#define M_CauseExcCode (0x1f << S_CauseExcCode)
1.36 +
1.37 +real_exception_handler:
1.38 + addiu $sp, -0x80
1.39 + sw $ra, 0($sp)
1.40 + sw $fp, 4($sp)
1.41 + sw $gp, 8($sp)
1.42 + sw $t9, 0xC($sp)
1.43 + sw $t8, 0x10($sp)
1.44 + sw $s7, 0x14($sp)
1.45 + sw $s6, 0x18($sp)
1.46 + sw $s5, 0x1C($sp)
1.47 + sw $s4, 0x20($sp)
1.48 + sw $s3, 0x24($sp)
1.49 + sw $s2, 0x28($sp)
1.50 + sw $s1, 0x2C($sp)
1.51 + sw $s0, 0x30($sp)
1.52 + sw $t7, 0x34($sp)
1.53 + sw $t6, 0x38($sp)
1.54 + sw $t5, 0x3C($sp)
1.55 + sw $t4, 0x40($sp)
1.56 + sw $t3, 0x44($sp)
1.57 + sw $t2, 0x48($sp)
1.58 + sw $t1, 0x4C($sp)
1.59 + sw $t0, 0x50($sp)
1.60 + sw $a3, 0x54($sp)
1.61 + sw $a2, 0x58($sp)
1.62 + sw $a1, 0x5C($sp)
1.63 + sw $a0, 0x60($sp)
1.64 + sw $v1, 0x64($sp)
1.65 + sw $v0, 0x68($sp)
1.66 + sw $1, 0x6C($sp)
1.67 + mflo $k0
1.68 + nop
1.69 + sw $k0, 0x70($sp)
1.70 + mfhi $k0
1.71 + nop
1.72 + sw $k0, 0x74($sp)
1.73 + mfc0 $k0, C0_STATUS
1.74 + sll $zero, 1
1.75 + sll $zero, 1
1.76 + sll $zero, 1
1.77 + sll $zero, 1
1.78 + sw $k0, 0x78($sp)
1.79 + mfc0 $k0, C0_EPC
1.80 + sll $zero, 1
1.81 + sll $zero, 1
1.82 + sll $zero, 1
1.83 + sll $zero, 1
1.84 + sw $k0, 0x7C($sp)
1.85 +
1.86 + li $k1, M_CauseExcCode
1.87 + mfc0 $k0, C0_CAUSE
1.88 + and $k0, $k1
1.89 + beq $zero, $k0, _int
1.90 + nop
1.91 + j _exception
1.92 + nop
1.93 +
1.94 +_int:
1.95 + /* Invoke the handler. */
1.96 +
1.97 + jal irq_handle
1.98 + nop
1.99 + j _exception_return
1.100 +
1.101 +_exception:
1.102 + move $a0, $sp
1.103 + mfc0 $a1, C0_CAUSE
1.104 + sll $zero, 1
1.105 + sll $zero, 1
1.106 + sll $zero, 1
1.107 + sll $zero, 1
1.108 + mfc0 $a2, C0_EPC
1.109 + sll $zero, 1
1.110 + sll $zero, 1
1.111 + sll $zero, 1
1.112 + sll $zero, 1
1.113 + /* jal exception_handler */
1.114 + j _exception_return
1.115 + nop
1.116 +
1.117 +_exception_return:
1.118 + lw $ra, 0($sp)
1.119 + lw $fp, 4($sp)
1.120 + lw $gp, 8($sp)
1.121 + lw $t9, 0xC($sp)
1.122 + lw $t8, 0x10($sp)
1.123 + lw $s7, 0x14($sp)
1.124 + lw $s6, 0x18($sp)
1.125 + lw $s5, 0x1C($sp)
1.126 + lw $s4, 0x20($sp)
1.127 + lw $s3, 0x24($sp)
1.128 + lw $s2, 0x28($sp)
1.129 + lw $s1, 0x2C($sp)
1.130 + lw $s0, 0x30($sp)
1.131 + lw $t7, 0x34($sp)
1.132 + lw $t6, 0x38($sp)
1.133 + lw $t5, 0x3C($sp)
1.134 + lw $t4, 0x40($sp)
1.135 + lw $t3, 0x44($sp)
1.136 + lw $t2, 0x48($sp)
1.137 + lw $t1, 0x4C($sp)
1.138 + lw $t0, 0x50($sp)
1.139 + lw $a3, 0x54($sp)
1.140 + lw $a2, 0x58($sp)
1.141 + lw $a1, 0x5C($sp)
1.142 + lw $a0, 0x60($sp)
1.143 + lw $v1, 0x64($sp)
1.144 + lw $v0, 0x68($sp)
1.145 + lw $1, 0x6C($sp)
1.146 + lw $k0, 0x70($sp)
1.147 + mtlo $k0
1.148 + nop
1.149 + lw $k0, 0x74($sp)
1.150 + mthi $k0
1.151 + nop
1.152 + lw $k0, 0x78($sp)
1.153 + mtc0 $k0, C0_STATUS
1.154 + nop
1.155 + sll $zero, 1
1.156 + sll $zero, 1
1.157 + sll $zero, 1
1.158 + sll $zero, 1
1.159 + lw $k0, 0x7C($sp)
1.160 + mtc0 $k0, C0_EPC
1.161 + nop
1.162 + sll $zero, 1
1.163 + sll $zero, 1
1.164 + sll $zero, 1
1.165 + sll $zero, 1
1.166 + addiu $sp, 0x80
1.167 + eret
1.168 + nop
1.169 +
1.170 +.set reorder
1.171 +.set at