ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / kernel / genex.S
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8  * Copyright (C) 2001 MIPS Technologies, Inc.
9  * Copyright (C) 2002 Maciej W. Rozycki
10  */
11 #include <linux/config.h>
12 #include <linux/init.h>
13
14 #include <asm/asm.h>
15 #include <asm/cacheops.h>
16 #include <asm/regdef.h>
17 #include <asm/fpregdef.h>
18 #include <asm/mipsregs.h>
19 #include <asm/stackframe.h>
20 #include <asm/war.h>
21
22         __INIT
23
24 NESTED(except_vec0_generic, 0, sp)
25         PANIC("Exception vector 0 called")
26         END(except_vec0_generic)
27
28 NESTED(except_vec1_generic, 0, sp)
29         PANIC("Exception vector 1 called")
30         END(except_vec1_generic)
31
32 /*
33  * General exception vector for all other CPUs.
34  *
35  * Be careful when changing this, it has to be at most 128 bytes
36  * to fit into space reserved for the exception handler.
37  */
38 NESTED(except_vec3_generic, 0, sp)
39         .set    push
40         .set    noat
41 #if R5432_CP0_INTERRUPT_WAR
42         mfc0    k0, CP0_INDEX
43 #endif
44         mfc0    k1, CP0_CAUSE
45         andi    k1, k1, 0x7c
46 #ifdef CONFIG_MIPS64
47         dsll    k1, k1, 1
48 #endif
49         PTR_L   k0, exception_handlers(k1)
50         jr      k0
51         .set    pop
52         END(except_vec3_generic)
53
54 /*
55  * General exception handler for CPUs with virtual coherency exception.
56  *
57  * Be careful when changing this, it has to be at most 256 (as a special
58  * exception) bytes to fit into space reserved for the exception handler.
59  */
60 NESTED(except_vec3_r4000, 0, sp)
61         .set    push
62         .set    mips3
63         .set    noat
64         mfc0    k1, CP0_CAUSE
65         li      k0, 31<<2
66         andi    k1, k1, 0x7c
67         .set    push
68         .set    noreorder
69         .set    nomacro
70         beq     k1, k0, handle_vced
71          li     k0, 14<<2
72         beq     k1, k0, handle_vcei
73 #ifdef CONFIG_MIPS64
74         dsll    k1, k1, 1
75 #endif
76         .set    pop
77         PTR_L   k0, exception_handlers(k1)
78         jr      k0
79
80         /*
81          * Big shit, we now may have two dirty primary cache lines for the same
82          * physical address.  We can savely invalidate the line pointed to by
83          * c0_badvaddr because after return from this exception handler the
84          * load / store will be re-executed.
85          */
86 handle_vced:
87         DMFC0   k0, CP0_BADVADDR
88         li      k1, -4                                  # Is this ...
89         and     k0, k1                                  # ... really needed?
90         mtc0    zero, CP0_TAGLO
91         cache   Index_Store_Tag_D,(k0)
92         cache   Hit_Writeback_Inv_SD,(k0)
93 #ifdef CONFIG_PROC_FS
94         PTR_LA  k0, vced_count
95         lw      k1, (k0)
96         addiu   k1, 1
97         sw      k1, (k0)
98 #endif
99         eret
100
101 handle_vcei:
102         MFC0    k0, CP0_BADVADDR
103         cache   Hit_Writeback_Inv_SD, (k0)              # also cleans pi
104 #ifdef CONFIG_PROC_FS
105         PTR_LA  k0, vcei_count
106         lw      k1, (k0)
107         addiu   k1, 1
108         sw      k1, (k0)
109 #endif
110         eret
111         .set    pop
112         END(except_vec3_r4000)
113
114 /*
115  * Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
116  * This is a dedicated interrupt exception vector which reduces the
117  * interrupt processing overhead.  The jump instruction will be replaced
118  * at the initialization time.
119  *
120  * Be careful when changing this, it has to be at most 128 bytes
121  * to fit into space reserved for the exception handler.
122  */
123 NESTED(except_vec4, 0, sp)
124 1:      j       1b                      /* Dummy, will be replaced */
125         END(except_vec4)
126
127 /*
128  * EJTAG debug exception handler.
129  * The EJTAG debug exception entry point is 0xbfc00480, which
130  * normally is in the boot PROM, so the boot PROM must do a
131  * unconditional jump to this vector.
132  */
133 NESTED(except_vec_ejtag_debug, 0, sp)
134         j       ejtag_debug_handler
135         END(except_vec_ejtag_debug)
136
137         __FINIT
138
139 /*
140  * EJTAG debug exception handler.
141  */
142 NESTED(ejtag_debug_handler, PT_SIZE, sp)
143         .set    push
144         .set    noat
145         .set    noreorder
146         MTC0    k0, CP0_DESAVE
147         mfc0    k0, CP0_DEBUG
148
149         sll     k0, k0, 30      # Check for SDBBP.
150         bgez    k0, ejtag_return
151         nop
152
153         PTR_LA  k0, ejtag_debug_buffer
154         LONG_S  k1, 0(k0)
155         SAVE_ALL
156         jal     ejtag_exception_handler
157          move   a0, sp
158         RESTORE_ALL
159         PTR_LA  k0, ejtag_debug_buffer
160         LONG_L  k1, 0(k0)
161
162 ejtag_return:
163         MFC0    k0, CP0_DESAVE
164         .set    mips32
165         deret
166          nop
167         .set pop
168         END(ejtag_debug_handler)
169
170 /*
171  * This buffer is reserved for the use of the EJTAG debug
172  * handler.
173  */
174         .data
175 EXPORT(ejtag_debug_buffer)
176         .fill   LONGSIZE
177         .previous
178
179         __INIT
180
181 /*
182  * NMI debug exception handler for MIPS reference boards.
183  * The NMI debug exception entry point is 0xbfc00000, which
184  * normally is in the boot PROM, so the boot PROM must do a
185  * unconditional jump to this vector.
186  */
187 NESTED(except_vec_nmi, 0, sp)
188         j       nmi_handler
189         END(except_vec_nmi)
190
191         __FINIT
192
193 NESTED(nmi_handler, PT_SIZE, sp)
194         .set    push
195         .set    noat
196         .set    mips3
197         SAVE_ALL
198         move    a0, sp
199         jal     nmi_exception_handler
200         RESTORE_ALL
201         eret
202         .set    pop
203         END(nmi_handler)
204
205         .macro  __build_clear_none
206         .endm
207
208         .macro  __build_clear_sti
209         STI
210         .endm
211
212         .macro  __build_clear_cli
213         CLI
214         .endm
215
216         .macro  __build_clear_fpe
217         cfc1    a1, fcr31
218         li      a2, ~(0x3f << 12)
219         and     a2, a1
220         ctc1    a2, fcr31
221         STI
222         .endm
223
224         .macro  __build_clear_ade
225         MFC0    t0, CP0_BADVADDR
226         PTR_S   t0, PT_BVADDR(sp)
227         KMODE
228         .endm
229
230         .macro  __BUILD_silent exception
231         .endm
232
233         /* Gas tries to parse the PRINT argument as a string containing
234            string escapes and emits bogus warnings if it believes to
235            recognize an unknown escape code.  So make the arguments
236            start with an n and gas will believe \n is ok ...  */
237         .macro  __BUILD_verbose nexception
238         LONG_L  a1, PT_EPC(sp)
239 #if CONFIG_MIPS32
240         PRINT("Got \nexception at %08lx\012")
241 #endif  
242 #if CONFIG_MIPS64
243         PRINT("Got \nexception at %016lx\012")
244 #endif  
245         .endm
246
247         .macro  __BUILD_count exception
248         LONG_L  t0,exception_count_\exception
249         LONG_ADDIU t0, 1
250         LONG_S  t0,exception_count_\exception
251         .comm   exception_count\exception, 8, 8
252         .endm
253
254         .macro  __BUILD_HANDLER exception handler clear verbose ext
255         .align  5
256         NESTED(handle_\exception, PT_SIZE, sp)
257         .set    noat
258         SAVE_ALL
259         FEXPORT(handle_\exception\ext)
260         __BUILD_clear_\clear
261         .set    at
262         __BUILD_\verbose \exception
263         move    a0, sp
264         jal     do_\handler
265         j       ret_from_exception
266         END(handle_\exception)
267         .endm
268
269         .macro  BUILD_HANDLER exception handler clear verbose
270         __BUILD_HANDLER \exception \handler \clear \verbose _int
271         .endm
272
273         BUILD_HANDLER adel ade ade silent               /* #4  */
274         BUILD_HANDLER ades ade ade silent               /* #5  */
275         BUILD_HANDLER ibe be cli silent                 /* #6  */
276         BUILD_HANDLER dbe be cli silent                 /* #7  */
277         BUILD_HANDLER bp bp sti silent                  /* #9  */
278         BUILD_HANDLER ri ri sti silent                  /* #10 */
279         BUILD_HANDLER cpu cpu sti silent                /* #11 */
280         BUILD_HANDLER ov ov sti silent                  /* #12 */
281         BUILD_HANDLER tr tr sti silent                  /* #13 */
282         BUILD_HANDLER fpe fpe fpe silent                /* #15 */
283         BUILD_HANDLER mdmx mdmx sti silent              /* #22 */
284         BUILD_HANDLER watch watch sti verbose           /* #23 */
285         BUILD_HANDLER mcheck mcheck cli verbose         /* #24 */
286         BUILD_HANDLER reserved reserved sti verbose     /* others */
287
288 #ifdef CONFIG_MIPS64
289 /* A temporary overflow handler used by check_daddi(). */
290
291         __INIT
292
293         BUILD_HANDLER  daddi_ov daddi_ov none silent    /* #12 */
294 #endif