Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1994 - 1999 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics * * Low level exception handling */ #define __ASSEMBLY__ #include <linux/init.h> #include <asm/asm.h> #include <asm/regdef.h> #include <asm/fpregdef.h> #include <asm/mipsregs.h> #include <asm/stackframe.h> #include <asm/r4kcacheops.h> .macro __build_clear_none .endm .macro __build_clear_sti STI .endm .macro __build_clear_cli CLI .endm .macro __build_clear_fpe cfc1 a1, fcr31 li a2, ~(0x3f << 13) and a2, a1 ctc1 a2, fcr31 STI .endm .macro __build_clear_ade dmfc0 t0, CP0_BADVADDR sd t0, PT_BVADDR(sp) KMODE .endm .macro __BUILD_silent exception .endm /* Gas tries to parse the PRINT argument as a string containing string escapes and emits bogus warnings if it believes to recognize an unknown escape code. So make the arguments start with an n and gas will believe \n is ok ... */ .macro __BUILD_verbose nexception ld a1, PT_EPC(sp) PRINT("Got \nexception at %016lx\012") .endm .macro __BUILD_count exception .set reorder ld t0,exception_count_\exception daddiu t0, 1 sd t0,exception_count_\exception .set noreorder .comm exception_count\exception, 8, 8 .endm .macro BUILD_HANDLER exception handler clear verbose .align 5 NESTED(handle_\exception, PT_SIZE, sp) .set noat SAVE_ALL #if DEBUG_MIPS64 jal dodebug2 ld $4, PT_R4(sp) ld $5, PT_R5(sp) ld $6, PT_R6(sp) ld $7, PT_R7(sp) ld $2, PT_R2(sp) #endif __BUILD_clear_\clear .set at __BUILD_\verbose \exception move a0, sp jal do_\handler j ret_from_sys_call nop END(handle_\exception) .endm BUILD_HANDLER adel ade ade silent /* #4 */ BUILD_HANDLER ades ade ade silent /* #5 */ BUILD_HANDLER ibe ibe cli silent /* #6 */ BUILD_HANDLER dbe dbe cli silent /* #7 */ BUILD_HANDLER bp bp sti silent /* #9 */ BUILD_HANDLER ri ri sti silent /* #10 */ BUILD_HANDLER cpu cpu sti silent /* #11 */ BUILD_HANDLER ov ov sti silent /* #12 */ BUILD_HANDLER tr tr sti silent /* #13 */ BUILD_HANDLER fpe fpe fpe silent /* #15 */ BUILD_HANDLER watch watch sti verbose /* #23 */ BUILD_HANDLER reserved reserved sti verbose /* others */ __INIT /* General exception handler for CPUs with virtual coherency exception. * * Be careful when changing this, it has to be at most 128 bytes to fit * into space reserved for the exception handler. */ NESTED(except_vec3_r4000, 0, sp) .set noat mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c li k0, 31<<2 beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei dsll k1, k1, 1 ld k0, exception_handlers(k1) jr k0 /* * Big shit, we now may have two dirty primary cache lines for the same * physical address. We can savely invalidate the line pointed to by * c0_badvaddr because after return from this exception handler the load / * store will be re-executed. */ handle_vced: mfc0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO cache Index_Store_Tag_D,(k0) cache Hit_Writeback_Inv_SD,(k0) lui k0, %hi(vced_count) lw k1, %lo(vced_count)(k0) addiu k1, 1 sw k1, %lo(vced_count)(k0) eret handle_vcei: mfc0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD,(k0) # also cleans pi lui k0, %hi(vcei_count) lw k1, %lo(vcei_count)(k0) addiu k1, 1 sw k1, %lo(vcei_count)(k0) eret END(except_vec3_r4000) .set at /* General exception vector for all other CPUs. */ NESTED(except_vec3_generic, 0, sp) .set noat mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c dsll k1, k1, 1 ld k0, exception_handlers(k1) jr k0 nop END(except_vec3_generic) .set at /* * Special interrupt vector for embedded MIPS. This is a dedicated interrupt * vector which reduces interrupt processing overhead. The jump instruction * will be inserted here at initialization time. This handler may only be 8 * bytes in size! */ NESTED(except_vec4, 0, sp) 1: j 1b /* Dummy, will be replaced */ nop END(except_vec4) __FINIT |