1 /* 2 * Handler routines. 3 * 4 * Copyright (C) 2008 by Maurus Cuelenaere 5 * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk> 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 .text 22 .extern irq_handle 23 .extern irq_counter 24 .globl real_exception_handler 25 .set noreorder 26 .set noat 27 28 #define C0_STATUS $12 29 #define C0_CAUSE $13 30 #define C0_EPC $14 31 #define C0_CONFIG $16 32 #define C0_ERROREPC $30 33 #define S_CauseExcCode 2 34 #define M_CauseExcCode (0x1f << S_CauseExcCode) 35 36 real_exception_handler: 37 addiu $sp, -0x88 /* multiple of 8 */ 38 sw $ra, 0($sp) 39 sw $fp, 4($sp) 40 sw $gp, 8($sp) 41 sw $t9, 0xC($sp) 42 sw $t8, 0x10($sp) 43 sw $s7, 0x14($sp) 44 sw $s6, 0x18($sp) 45 sw $s5, 0x1C($sp) 46 sw $s4, 0x20($sp) 47 sw $s3, 0x24($sp) 48 sw $s2, 0x28($sp) 49 sw $s1, 0x2C($sp) 50 sw $s0, 0x30($sp) 51 sw $t7, 0x34($sp) 52 sw $t6, 0x38($sp) 53 sw $t5, 0x3C($sp) 54 sw $t4, 0x40($sp) 55 sw $t3, 0x44($sp) 56 sw $t2, 0x48($sp) 57 sw $t1, 0x4C($sp) 58 sw $t0, 0x50($sp) 59 sw $a3, 0x54($sp) 60 sw $a2, 0x58($sp) 61 sw $a1, 0x5C($sp) 62 sw $a0, 0x60($sp) 63 sw $v1, 0x64($sp) 64 sw $v0, 0x68($sp) 65 sw $1, 0x6C($sp) 66 mflo $k0 67 nop 68 sw $k0, 0x70($sp) 69 mfhi $k0 70 nop 71 sw $k0, 0x74($sp) 72 mfc0 $k0, C0_STATUS 73 sll $zero, 1 74 sll $zero, 1 75 sll $zero, 1 76 sll $zero, 1 77 sw $k0, 0x78($sp) 78 mfc0 $k0, C0_EPC 79 sll $zero, 1 80 sll $zero, 1 81 sll $zero, 1 82 sll $zero, 1 83 sw $k0, 0x7C($sp) 84 mfc0 $k0, C0_ERROREPC 85 sll $zero, 1 86 sll $zero, 1 87 sll $zero, 1 88 sll $zero, 1 89 sw $k0, 0x80($sp) 90 91 li $k1, M_CauseExcCode 92 mfc0 $k0, C0_CAUSE 93 and $k0, $k1 94 beq $zero, $k0, _int 95 nop 96 j _exception 97 nop 98 99 _int: 100 /* Initialise the globals pointer. */ 101 102 lui $gp, %hi(_GLOBAL_OFFSET_TABLE_) 103 ori $gp, $gp, %lo(_GLOBAL_OFFSET_TABLE_) 104 105 /* Test with counter. */ 106 107 la $t0, irq_counter 108 lw $t1, 0($t0) 109 addiu $t1, $t1, 1 110 sw $t1, 0($t0) 111 112 /* Invoke the handler. */ 113 114 jal irq_handle 115 nop 116 j _exception_return 117 nop 118 119 _exception: 120 j _exception_return 121 nop 122 123 _exception_return: 124 lw $ra, 0($sp) 125 lw $fp, 4($sp) 126 lw $gp, 8($sp) 127 lw $t9, 0xC($sp) 128 lw $t8, 0x10($sp) 129 lw $s7, 0x14($sp) 130 lw $s6, 0x18($sp) 131 lw $s5, 0x1C($sp) 132 lw $s4, 0x20($sp) 133 lw $s3, 0x24($sp) 134 lw $s2, 0x28($sp) 135 lw $s1, 0x2C($sp) 136 lw $s0, 0x30($sp) 137 lw $t7, 0x34($sp) 138 lw $t6, 0x38($sp) 139 lw $t5, 0x3C($sp) 140 lw $t4, 0x40($sp) 141 lw $t3, 0x44($sp) 142 lw $t2, 0x48($sp) 143 lw $t1, 0x4C($sp) 144 lw $t0, 0x50($sp) 145 lw $a3, 0x54($sp) 146 lw $a2, 0x58($sp) 147 lw $a1, 0x5C($sp) 148 lw $a0, 0x60($sp) 149 lw $v1, 0x64($sp) 150 lw $v0, 0x68($sp) 151 lw $1, 0x6C($sp) 152 lw $k0, 0x70($sp) 153 mtlo $k0 154 nop 155 lw $k0, 0x74($sp) 156 mthi $k0 157 nop 158 lw $k0, 0x78($sp) 159 mtc0 $k0, C0_STATUS 160 nop 161 sll $zero, 1 162 sll $zero, 1 163 sll $zero, 1 164 sll $zero, 1 165 lw $k0, 0x7C($sp) 166 mtc0 $k0, C0_EPC 167 nop 168 sll $zero, 1 169 sll $zero, 1 170 sll $zero, 1 171 sll $zero, 1 172 lw $k0, 0x80($sp) 173 mtc0 $k0, C0_ERROREPC 174 nop 175 sll $zero, 1 176 sll $zero, 1 177 sll $zero, 1 178 sll $zero, 1 179 addiu $sp, 0x88 /* multiple of 8 */ 180 eret 181 nop 182 183 .set reorder 184 .set at