1 /* 2 * Handler routines. 3 * 4 * Copyright (C) 2015 Nicholas FitzRoy-Dale <wzdd.code@lardcave.net> 5 * Copyright (C) 2015, 2016 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 tlb_handle 23 .extern irq_handle 24 .extern current_stack_pointer 25 .extern current_task 26 .globl tlb_handler 27 .globl interrupt_handler 28 .set noreorder 29 .set noat 30 31 tlb_handler: 32 /* gp should have been set in the entrypoint. */ 33 34 jal save_state 35 nop 36 37 /* Invoke the handler. */ 38 39 jal tlb_handle 40 nop 41 42 j load_and_return 43 nop 44 45 interrupt_handler: 46 /* gp should have been set in the entrypoint. */ 47 48 jal save_state 49 nop 50 51 /* Record the stack pointer. */ 52 53 la $k0, current_stack_pointer 54 sw $sp, 0($k0) 55 56 /* Invoke the handler. */ 57 58 jal irq_handle 59 nop 60 61 /* Switch the stack pointer. */ 62 63 la $k0, current_stack_pointer 64 lw $sp, 0($k0) 65 66 /* Set the current task ASID. */ 67 68 la $k0, current_task 69 lw $k1, 0($k0) 70 mtc0 $k1, $10 /* CP0_ENTRYHI */ 71 nop 72 73 j load_and_return 74 nop 75 76 save_state: 77 sw $at, -4($sp) 78 sw $v0, -8($sp) 79 sw $v1, -12($sp) 80 sw $a0, -16($sp) 81 sw $a1, -20($sp) 82 sw $a2, -24($sp) 83 sw $a3, -28($sp) 84 sw $t0, -32($sp) 85 sw $t1, -36($sp) 86 sw $t2, -40($sp) 87 sw $t3, -44($sp) 88 sw $t4, -48($sp) 89 sw $t5, -52($sp) 90 sw $t6, -56($sp) 91 sw $t7, -60($sp) 92 sw $s0, -64($sp) 93 sw $s1, -68($sp) 94 sw $s2, -72($sp) 95 sw $s3, -76($sp) 96 sw $s4, -80($sp) 97 sw $s5, -84($sp) 98 sw $s6, -88($sp) 99 sw $s7, -92($sp) 100 sw $t8, -96($sp) 101 /* sw $t9, -100($sp) */ 102 /* sw $gp, -104($sp) */ 103 sw $fp, -108($sp) 104 /* sw $ra, -112($sp) */ 105 106 mfc0 $k0, $14 /* CP0_EPC */ 107 nop 108 sw $k0, -116($sp) 109 110 addi $sp, $sp, -120 111 j $ra 112 nop 113 114 load_and_return: 115 116 addi $sp, $sp, 120 117 118 lw $at, -4($sp) 119 lw $v0, -8($sp) 120 lw $v1, -12($sp) 121 lw $a0, -16($sp) 122 lw $a1, -20($sp) 123 lw $a2, -24($sp) 124 lw $a3, -28($sp) 125 lw $t0, -32($sp) 126 lw $t1, -36($sp) 127 lw $t2, -40($sp) 128 lw $t3, -44($sp) 129 lw $t4, -48($sp) 130 lw $t5, -52($sp) 131 lw $t6, -56($sp) 132 lw $t7, -60($sp) 133 lw $s0, -64($sp) 134 lw $s1, -68($sp) 135 lw $s2, -72($sp) 136 lw $s3, -76($sp) 137 lw $s4, -80($sp) 138 lw $s5, -84($sp) 139 lw $s6, -88($sp) 140 lw $s7, -92($sp) 141 lw $t8, -96($sp) 142 lw $t9, -100($sp) 143 lw $gp, -104($sp) 144 lw $fp, -108($sp) 145 lw $ra, -112($sp) 146 147 lw $k0, -116($sp) 148 mtc0 $k0, $14 /* CP0_EPC */ 149 nop 150 151 lw $k0, -120($sp) 152 mtc0 $k0, $12 /* CP0_STATUS */ 153 nop 154 155 eret 156 nop 157 158 .set reorder 159 .set at