trap_subr.S revision 1.2 1 1.2 simonb /* $NetBSD: trap_subr.S,v 1.2 2001/06/17 13:38:33 simonb Exp $ */
2 1.1 simonb
3 1.1 simonb /*
4 1.1 simonb * Copyright 2001 Wasabi Systems, Inc.
5 1.1 simonb * All rights reserved.
6 1.1 simonb *
7 1.1 simonb * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc.
8 1.1 simonb *
9 1.1 simonb * Redistribution and use in source and binary forms, with or without
10 1.1 simonb * modification, are permitted provided that the following conditions
11 1.1 simonb * are met:
12 1.1 simonb * 1. Redistributions of source code must retain the above copyright
13 1.1 simonb * notice, this list of conditions and the following disclaimer.
14 1.1 simonb * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 simonb * notice, this list of conditions and the following disclaimer in the
16 1.1 simonb * documentation and/or other materials provided with the distribution.
17 1.1 simonb * 3. All advertising materials mentioning features or use of this software
18 1.1 simonb * must display the following acknowledgement:
19 1.1 simonb * This product includes software developed for the NetBSD Project by
20 1.1 simonb * Wasabi Systems, Inc.
21 1.1 simonb * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 1.1 simonb * or promote products derived from this software without specific prior
23 1.1 simonb * written permission.
24 1.1 simonb *
25 1.1 simonb * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 1.1 simonb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 1.1 simonb * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 1.1 simonb * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 1.1 simonb * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 1.1 simonb * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 1.1 simonb * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 1.1 simonb * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 1.1 simonb * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 1.1 simonb * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 1.1 simonb * POSSIBILITY OF SUCH DAMAGE.
36 1.1 simonb */
37 1.1 simonb
38 1.1 simonb /*
39 1.1 simonb * Copyright (C) 1995, 1996 Wolfgang Solfrank.
40 1.1 simonb * Copyright (C) 1995, 1996 TooLs GmbH.
41 1.1 simonb * All rights reserved.
42 1.1 simonb *
43 1.1 simonb * Redistribution and use in source and binary forms, with or without
44 1.1 simonb * modification, are permitted provided that the following conditions
45 1.1 simonb * are met:
46 1.1 simonb * 1. Redistributions of source code must retain the above copyright
47 1.1 simonb * notice, this list of conditions and the following disclaimer.
48 1.1 simonb * 2. Redistributions in binary form must reproduce the above copyright
49 1.1 simonb * notice, this list of conditions and the following disclaimer in the
50 1.1 simonb * documentation and/or other materials provided with the distribution.
51 1.1 simonb * 3. All advertising materials mentioning features or use of this software
52 1.1 simonb * must display the following acknowledgement:
53 1.1 simonb * This product includes software developed by TooLs GmbH.
54 1.1 simonb * 4. The name of TooLs GmbH may not be used to endorse or promote products
55 1.1 simonb * derived from this software without specific prior written permission.
56 1.1 simonb *
57 1.1 simonb * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
58 1.1 simonb * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
59 1.1 simonb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
60 1.1 simonb * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61 1.1 simonb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
62 1.1 simonb * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
63 1.1 simonb * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
64 1.1 simonb * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
65 1.1 simonb * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
66 1.1 simonb * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 1.1 simonb */
68 1.1 simonb
69 1.1 simonb /*
70 1.1 simonb * NOTICE: This is not a standalone file. to use it, #include it in
71 1.1 simonb * your port's locore.S, like so:
72 1.1 simonb *
73 1.1 simonb * #include <powerpc/powerpc/trap_subr.S>
74 1.1 simonb */
75 1.1 simonb
76 1.1 simonb /*
77 1.1 simonb * Data used during primary/secondary traps/interrupts
78 1.1 simonb */
79 1.1 simonb #define tempsave 0x2e0 /* primary save area for trap handling */
80 1.1 simonb #define disisave 0x3e0 /* primary save area for dsi/isi traps */
81 1.1 simonb #define exitsave 0x4e0 /* use this so trap return does not conflict */
82 1.1 simonb /*
83 1.1 simonb * XXX Interrupt and spill stacks need to be per-CPU.
84 1.1 simonb */
85 1.1 simonb .data
86 1.1 simonb .align 4
87 1.1 simonb intstk:
88 1.1 simonb .space INTSTK /* interrupt stack */
89 1.1 simonb
90 1.1 simonb GLOBAL(intr_depth)
91 1.1 simonb .long -1 /* in-use marker */
92 1.1 simonb
93 1.1 simonb .comm spillstk,SPILLSTK,8
94 1.1 simonb
95 1.1 simonb #if defined(MULTIPROCESSOR)
96 1.1 simonb #define GET_PCB(rX) \
97 1.1 simonb GET_CPUINFO(rX); \
98 1.1 simonb lwz rX,CI_CURPCB(rX)
99 1.1 simonb #else
100 1.1 simonb #define GET_PCB(x) \
101 1.1 simonb lis 1,_C_LABEL(curpcb)@ha; \
102 1.1 simonb lwz 1,_C_LABEL(curpcb)@l(1)
103 1.1 simonb #endif
104 1.1 simonb
105 1.1 simonb #define STANDARD_PROLOG(savearea) \
106 1.1 simonb mtsprg 1,1; /* save SP */ \
107 1.1 simonb stmw 28,savearea(0); /* free r28-r31 */ \
108 1.1 simonb mflr 28; /* save LR */ \
109 1.1 simonb mfcr 29; /* save CR */ \
110 1.1 simonb mfsrr1 31; /* Test whether we already had PR set */ \
111 1.1 simonb mtcr 31; \
112 1.1 simonb bc 4,17,1f; /* branch if PSL_PR is clear */ \
113 1.1 simonb GET_PCB(1); \
114 1.1 simonb addi 1,1,USPACE; /* stack is top of user struct */ \
115 1.1 simonb 1:
116 1.1 simonb
117 1.1 simonb #define CRITICAL_PROLOG(savearea) \
118 1.1 simonb mtsprg 1,1; /* save SP */ \
119 1.1 simonb stmw 28,savearea(0); /* free r28-r31 */ \
120 1.1 simonb mflr 28; /* save LR */ \
121 1.1 simonb mfcr 29; /* save CR */ \
122 1.1 simonb mfsrr2 30; /* Fake a standard trap */ \
123 1.1 simonb mtsrr0 30; \
124 1.1 simonb mfsrr3 31; /* Test whether we already had PR set */ \
125 1.1 simonb mtsrr1 31; \
126 1.1 simonb mtcr 31; \
127 1.1 simonb bc 4,17,1f; /* branch if PSL_PR is clear */ \
128 1.1 simonb GET_PCB(1); \
129 1.1 simonb addi 1,1,USPACE; /* stack is top of user struct */ \
130 1.1 simonb 1:
131 1.1 simonb
132 1.1 simonb
133 1.1 simonb /* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */
134 1.1 simonb #define STANDARD_EXC_HANDLER(name)\
135 1.1 simonb .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \
136 1.1 simonb _C_LABEL(name ## trap): \
137 1.1 simonb STANDARD_PROLOG(tempsave); \
138 1.1 simonb bla s_trap ; \
139 1.1 simonb _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
140 1.1 simonb
141 1.1 simonb /* Access exceptions also need DEAR and ESR saved */
142 1.1 simonb #define ACCESS_EXC_HANDLER(name)\
143 1.1 simonb .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \
144 1.1 simonb _C_LABEL(name ## trap): \
145 1.1 simonb STANDARD_PROLOG(tempsave); \
146 1.1 simonb mfdear 30; \
147 1.1 simonb mfesr 31; \
148 1.1 simonb stmw 30,16+tempsave(0); \
149 1.1 simonb bla s_trap ; \
150 1.1 simonb _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
151 1.1 simonb
152 1.1 simonb /* Maybe this should call ddb.... */
153 1.1 simonb #define CRITICAL_EXC_HANDLER(name)\
154 1.1 simonb .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \
155 1.1 simonb _C_LABEL(name ## trap): \
156 1.1 simonb CRITICAL_PROLOG(tempsave); \
157 1.1 simonb bla s_trap ; \
158 1.1 simonb _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
159 1.1 simonb
160 1.1 simonb /*
161 1.1 simonb * This code gets copied to all the trap vectors
162 1.1 simonb * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
163 1.1 simonb * traps when using IPKDB).
164 1.1 simonb */
165 1.1 simonb .text
166 1.1 simonb STANDARD_EXC_HANDLER(default)
167 1.1 simonb ACCESS_EXC_HANDLER(ali)
168 1.1 simonb ACCESS_EXC_HANDLER(dsi)
169 1.1 simonb ACCESS_EXC_HANDLER(isi)
170 1.1 simonb STANDARD_EXC_HANDLER(debug)
171 1.1 simonb
172 1.1 simonb /*
173 1.1 simonb * This one for the external interrupt handler.
174 1.1 simonb */
175 1.1 simonb .globl _C_LABEL(extint),_C_LABEL(extsize)
176 1.1 simonb _C_LABEL(extint):
177 1.1 simonb mtsprg 1,1 /* save SP */
178 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
179 1.1 simonb mflr 28 /* save LR */
180 1.1 simonb mfcr 29 /* save CR */
181 1.1 simonb mfxer 30 /* save XER */
182 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
183 1.1 simonb addi 1,1,intstk+INTSTK@l
184 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
185 1.1 simonb addic. 31,31,1
186 1.1 simonb stw 31,0(1)
187 1.1 simonb beq 1f
188 1.1 simonb mfsprg 1,1 /* yes, get old SP */
189 1.1 simonb 1:
190 1.1 simonb ba extintr
191 1.1 simonb _C_LABEL(extsize) = .-_C_LABEL(extint)
192 1.1 simonb
193 1.1 simonb
194 1.1 simonb #ifdef DDB
195 1.1 simonb #define ddbsave 0xde0 /* primary save area for DDB */
196 1.1 simonb /*
197 1.1 simonb * In case of DDB we want a separate trap catcher for it
198 1.1 simonb */
199 1.1 simonb .local ddbstk
200 1.1 simonb .comm ddbstk,INTSTK,8 /* ddb stack */
201 1.1 simonb
202 1.1 simonb .globl _C_LABEL(ddblow),_C_LABEL(ddbsize)
203 1.1 simonb _C_LABEL(ddblow):
204 1.1 simonb mtsprg 1,1 /* save SP */
205 1.1 simonb stmw 28,ddbsave(0) /* free r28-r31 */
206 1.1 simonb mflr 28 /* save LR */
207 1.1 simonb mfcr 29 /* save CR */
208 1.1 simonb lis 1,ddbstk+INTSTK@ha /* get new SP */
209 1.1 simonb addi 1,1,ddbstk+INTSTK@l
210 1.1 simonb bla ddbtrap
211 1.1 simonb _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
212 1.1 simonb #endif /* DDB */
213 1.1 simonb
214 1.1 simonb #ifdef IPKDB
215 1.1 simonb #define ipkdbsave 0xde0 /* primary save area for IPKDB */
216 1.1 simonb /*
217 1.1 simonb * In case of IPKDB we want a separate trap catcher for it
218 1.1 simonb */
219 1.1 simonb
220 1.1 simonb .local ipkdbstk
221 1.1 simonb .comm ipkdbstk,INTSTK,8 /* ipkdb stack */
222 1.1 simonb
223 1.1 simonb .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
224 1.1 simonb _C_LABEL(ipkdblow):
225 1.1 simonb mtsprg 1,1 /* save SP */
226 1.1 simonb stmw 28,ipkdbsave(0) /* free r28-r31 */
227 1.1 simonb mflr 28 /* save LR */
228 1.1 simonb mfcr 29 /* save CR */
229 1.1 simonb lis 1,ipkdbstk+INTSTK@ha /* get new SP */
230 1.1 simonb addi 1,1,ipkdbstk+INTSTK@l
231 1.1 simonb bla ipkdbtrap
232 1.1 simonb _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
233 1.1 simonb #endif /* IPKDB */
234 1.1 simonb
235 1.1 simonb #ifdef DEBUG
236 1.1 simonb #define TRAP_IF_ZERO(r) tweqi r,0
237 1.1 simonb #else
238 1.1 simonb #define TRAP_IF_ZERO(r)
239 1.1 simonb #endif
240 1.1 simonb
241 1.1 simonb /*
242 1.1 simonb * FRAME_SETUP assumes:
243 1.1 simonb * SPRG1 SP (1)
244 1.1 simonb * savearea r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps)
245 1.1 simonb * 28 LR
246 1.1 simonb * 29 CR
247 1.1 simonb * 1 kernel stack
248 1.1 simonb * LR trap type
249 1.1 simonb * SRR0/1 as at start of trap
250 1.1 simonb */
251 1.1 simonb #define FRAME_SETUP(savearea) \
252 1.1 simonb /* Have to enable translation to allow access of kernel stack: */ \
253 1.1 simonb mfsrr0 30; \
254 1.1 simonb mfsrr1 31; \
255 1.1 simonb stmw 30,savearea+24(0); \
256 1.1 simonb mfpid 30; \
257 1.1 simonb li 31,KERNEL_PID; \
258 1.1 simonb mtpid 31; \
259 1.1 simonb mfmsr 31; \
260 1.1 simonb ori 31,31,(PSL_DR|PSL_IR)@l; \
261 1.1 simonb mtmsr 31; \
262 1.1 simonb isync; \
263 1.1 simonb mfsprg 31,1; \
264 1.1 simonb stwu 31,-FRAMELEN(1); \
265 1.1 simonb stw 30,FRAME_PID+8(1); \
266 1.1 simonb stw 0,FRAME_0+8(1); \
267 1.1 simonb stw 31,FRAME_1+8(1); \
268 1.1 simonb stw 28,FRAME_LR+8(1); \
269 1.1 simonb stw 29,FRAME_CR+8(1); \
270 1.1 simonb lmw 28,savearea(0); \
271 1.1 simonb stmw 2,FRAME_2+8(1); \
272 1.1 simonb lmw 28,savearea+16(0); \
273 1.1 simonb mfxer 3; \
274 1.1 simonb mfctr 4; \
275 1.1 simonb mflr 5; \
276 1.1 simonb andi. 5,5,0xff00; \
277 1.1 simonb stw 3,FRAME_XER+8(1); \
278 1.1 simonb stw 4,FRAME_CTR+8(1); \
279 1.1 simonb stw 5,FRAME_EXC+8(1); \
280 1.1 simonb stw 28,FRAME_DEAR+8(1); \
281 1.1 simonb stw 29,FRAME_ESR+8(1); \
282 1.1 simonb stw 30,FRAME_SRR0+8(1); \
283 1.1 simonb stw 31,FRAME_SRR1+8(1)
284 1.1 simonb
285 1.1 simonb #define FRAME_LEAVE(savearea) \
286 1.1 simonb /* Now restore regs: */ \
287 1.1 simonb lwz 3,FRAME_PID+8(1); \
288 1.1 simonb lwz 4,FRAME_SRR1+8(1); \
289 1.1 simonb bl _C_LABEL(ctx_setup); \
290 1.1 simonb TRAP_IF_ZERO(r3); \
291 1.1 simonb stw 3,FRAME_PID+8(1); \
292 1.1 simonb lmw 26,FRAME_LR+8(1); \
293 1.1 simonb mtlr 26; \
294 1.1 simonb mtcr 27; \
295 1.1 simonb mtxer 28; \
296 1.1 simonb mtctr 29; \
297 1.1 simonb mtsrr0 30; \
298 1.1 simonb mtsrr1 31; \
299 1.1 simonb lmw 2,FRAME_2+8(1); \
300 1.1 simonb lwz 0,FRAME_0+8(1); \
301 1.1 simonb stmw 29,savearea(0); \
302 1.1 simonb lwz 30,FRAME_PID+8(1); \
303 1.1 simonb lwz 1,FRAME_1+8(1); \
304 1.1 simonb mfmsr 31; \
305 1.1 simonb li 29,(PSL_DR|PSL_IR)@l; \
306 1.1 simonb andc 31,31,29; \
307 1.1 simonb mfcr 29; \
308 1.1 simonb mtcr 29; \
309 1.1 simonb mtmsr 31; \
310 1.1 simonb isync; \
311 1.1 simonb TRAP_IF_ZERO(r30); \
312 1.1 simonb mtpid 30; \
313 1.1 simonb lmw 29,savearea(0)
314 1.1 simonb
315 1.1 simonb realtrap: /* entry point after IPKDB is done with exception */
316 1.1 simonb /* Test whether we already had PR set */
317 1.1 simonb mfsrr1 1
318 1.1 simonb mtcr 1
319 1.1 simonb mfsprg 1,1 /* restore SP (might have been
320 1.1 simonb overwritten) */
321 1.1 simonb bc 4,17,s_trap /* branch if PSL_PR is false */
322 1.1 simonb lis 1,_C_LABEL(curpcb)@ha
323 1.1 simonb lwz 1,_C_LABEL(curpcb)@l(1)
324 1.1 simonb addi 1,1,USPACE /* stack is top of user struct */
325 1.1 simonb /*
326 1.1 simonb * Now the common trap catching code.
327 1.1 simonb */
328 1.1 simonb s_trap:
329 1.1 simonb FRAME_SETUP(tempsave)
330 1.1 simonb /* Now we can recover interrupts again: */
331 1.1 simonb trapagain:
332 1.1 simonb wrteei 1 /* Enable interrupts */
333 1.1 simonb /* Call C trap code: */
334 1.1 simonb addi 3,1,8
335 1.1 simonb bl _C_LABEL(trap)
336 1.2 simonb .globl _C_LABEL(trapexit)
337 1.2 simonb _C_LABEL(trapexit):
338 1.1 simonb /* Disable interrupts: */
339 1.1 simonb wrteei 0
340 1.1 simonb /* Test AST pending: */
341 1.1 simonb lwz 5,FRAME_SRR1+8(1)
342 1.1 simonb mtcr 5
343 1.1 simonb bc 4,17,1f /* branch if PSL_PR is false */
344 1.1 simonb #if defined(MULTIPROCESSOR)
345 1.1 simonb GET_CPUINFO(3)
346 1.1 simonb lwz 4,CI_ASTPENDING(3)
347 1.1 simonb #else
348 1.1 simonb lis 3,_C_LABEL(astpending)@ha
349 1.1 simonb lwz 4,_C_LABEL(astpending)@l(3)
350 1.1 simonb #endif
351 1.1 simonb andi. 4,4,1
352 1.1 simonb beq 1f
353 1.1 simonb li 6,EXC_AST
354 1.1 simonb stw 6,FRAME_EXC+8(1)
355 1.1 simonb b trapagain
356 1.1 simonb 1:
357 1.1 simonb FRAME_LEAVE(exitsave)
358 1.1 simonb rfi
359 1.1 simonb ba . /* Protect against prefetch */
360 1.1 simonb /*
361 1.1 simonb * External interrupt second level handler
362 1.1 simonb */
363 1.1 simonb
364 1.1 simonb #define INTRENTER \
365 1.1 simonb /* Save non-volatile registers: */ \
366 1.1 simonb stwu 1,-92(1); /* temporarily */ \
367 1.1 simonb stw 0,84(1); \
368 1.1 simonb mfsprg 0,1; /* get original SP */ \
369 1.1 simonb stw 0,0(1); /* and store it */ \
370 1.1 simonb stw 3,80(1); \
371 1.1 simonb stw 4,76(1); \
372 1.1 simonb stw 5,72(1); \
373 1.1 simonb stw 6,68(1); \
374 1.1 simonb stw 7,64(1); \
375 1.1 simonb stw 8,60(1); \
376 1.1 simonb stw 9,56(1); \
377 1.1 simonb stw 10,52(1); \
378 1.1 simonb stw 11,48(1); \
379 1.1 simonb stw 12,44(1); \
380 1.1 simonb stw 28,40(1); /* saved LR */ \
381 1.1 simonb stw 29,36(1); /* saved CR */ \
382 1.1 simonb stw 30,32(1); /* saved XER */ \
383 1.1 simonb lmw 28,tempsave(0); /* restore r28-r31 */ \
384 1.1 simonb mfctr 6; \
385 1.1 simonb lis 5,_C_LABEL(intr_depth)@ha; \
386 1.1 simonb lwz 5,_C_LABEL(intr_depth)@l(5); \
387 1.1 simonb mfsrr0 4; \
388 1.1 simonb mfsrr1 3; \
389 1.1 simonb stw 6,28(1); \
390 1.1 simonb stw 5,20(1); \
391 1.1 simonb stw 4,12(1); \
392 1.1 simonb stw 3,8(1); \
393 1.1 simonb mfpid 0; /* get currect PID register */ \
394 1.1 simonb stw 0,88(1) ; \
395 1.1 simonb li 0, KERNEL_PID; \
396 1.1 simonb mtpid 0; \
397 1.1 simonb /* interrupts are recoverable here, and enable translation */ \
398 1.1 simonb mfmsr 5; \
399 1.1 simonb ori 5,5,(PSL_IR|PSL_DR); \
400 1.1 simonb mtmsr 5; \
401 1.1 simonb isync
402 1.1 simonb
403 1.1 simonb .globl _C_LABEL(extint_call)
404 1.1 simonb extintr:
405 1.1 simonb INTRENTER
406 1.1 simonb _C_LABEL(extint_call):
407 1.1 simonb bl _C_LABEL(extint_call) /* to be filled in later */
408 1.1 simonb
409 1.1 simonb intr_exit:
410 1.1 simonb /* Disable interrupts (should already be disabled) and MMU here: */
411 1.1 simonb wrteei 0
412 1.1 simonb isync
413 1.1 simonb lwz 3,88(1)
414 1.1 simonb lwz 4,8(1) /* Load srr1 */
415 1.1 simonb bl _C_LABEL(ctx_setup) /* Get proper ctx */
416 1.1 simonb mfmsr 5
417 1.1 simonb lis 4,(PSL_EE|PSL_DR|PSL_IR)@h
418 1.1 simonb ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l
419 1.1 simonb andc 5,5,4
420 1.1 simonb mtmsr 5
421 1.1 simonb isync
422 1.1 simonb mtpid 3 /* Load CTX */
423 1.1 simonb
424 1.1 simonb /* restore possibly overwritten registers: */
425 1.1 simonb lwz 12,44(1)
426 1.1 simonb lwz 11,48(1)
427 1.1 simonb lwz 10,52(1)
428 1.1 simonb lwz 9,56(1)
429 1.1 simonb lwz 8,60(1)
430 1.1 simonb lwz 7,64(1)
431 1.1 simonb lwz 6,8(1)
432 1.1 simonb lwz 5,12(1)
433 1.1 simonb lwz 4,28(1)
434 1.1 simonb lwz 3,32(1)
435 1.1 simonb mtsrr1 6
436 1.1 simonb mtsrr0 5
437 1.1 simonb mtctr 4
438 1.1 simonb mtxer 3
439 1.1 simonb /* Returning to user mode? */
440 1.1 simonb mtcr 6 /* saved SRR1 */
441 1.1 simonb bc 4,17,1f /* branch if PSL_PR is false */
442 1.1 simonb
443 1.1 simonb #if defined(MULTIPROCESSOR)
444 1.1 simonb lwz 4,CI_ASTPENDING(4) /* Test AST pending */
445 1.1 simonb #else
446 1.1 simonb lis 3,_C_LABEL(astpending)@ha /* Test AST pending */
447 1.1 simonb lwz 4,_C_LABEL(astpending)@l(3)
448 1.1 simonb #endif
449 1.1 simonb andi. 4,4,1
450 1.1 simonb beq 1f
451 1.1 simonb /* Setup for entry to realtrap: */
452 1.1 simonb lwz 3,0(1) /* get saved SP */
453 1.1 simonb mtsprg 1,3
454 1.1 simonb li 6,EXC_AST
455 1.1 simonb stmw 28,tempsave(0) /* establish tempsave again */
456 1.1 simonb mtlr 6
457 1.1 simonb lwz 28,40(1) /* saved LR */
458 1.1 simonb lwz 29,36(1) /* saved CR */
459 1.1 simonb lwz 6,68(1)
460 1.1 simonb lwz 5,72(1)
461 1.1 simonb lwz 4,76(1)
462 1.1 simonb lwz 3,80(1)
463 1.1 simonb lwz 0,84(1)
464 1.1 simonb lis 30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
465 1.1 simonb lwz 31,_C_LABEL(intr_depth)@l(30)
466 1.1 simonb addi 31,31,-1
467 1.1 simonb stw 31,_C_LABEL(intr_depth)@l(30)
468 1.1 simonb b realtrap
469 1.1 simonb 1:
470 1.1 simonb /* Here is the normal exit of extintr: */
471 1.1 simonb lwz 5,36(1)
472 1.1 simonb lwz 6,40(1)
473 1.1 simonb mtcr 5
474 1.1 simonb mtlr 6
475 1.1 simonb lwz 6,68(1)
476 1.1 simonb lwz 5,72(1)
477 1.1 simonb lis 3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
478 1.1 simonb lwz 4,_C_LABEL(intr_depth)@l(3)
479 1.1 simonb addi 4,4,-1
480 1.1 simonb stw 4,_C_LABEL(intr_depth)@l(3)
481 1.1 simonb lwz 4,76(1)
482 1.1 simonb lwz 3,80(1)
483 1.1 simonb lwz 0,84(1)
484 1.1 simonb lwz 1,0(1)
485 1.1 simonb rfi
486 1.1 simonb ba . /* Protect against prefetch */
487 1.1 simonb
488 1.1 simonb /*
489 1.1 simonb * PIT interrupt handler.
490 1.1 simonb */
491 1.1 simonb .align 5
492 1.1 simonb _C_LABEL(pitint):
493 1.1 simonb mtsprg 1,1 /* save SP */
494 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
495 1.1 simonb mflr 28 /* save LR */
496 1.1 simonb mfcr 29 /* save CR */
497 1.1 simonb mfxer 30 /* save XER */
498 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
499 1.1 simonb addi 1,1,intstk+INTSTK@l
500 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
501 1.1 simonb addic. 31,31,1
502 1.1 simonb stw 31,0(1)
503 1.1 simonb beq 1f
504 1.1 simonb mfsprg 1,1 /* yes, get old SP */
505 1.1 simonb 1:
506 1.1 simonb INTRENTER
507 1.1 simonb addi 3,1,8 /* intr frame */
508 1.1 simonb bl _C_LABEL(decr_intr)
509 1.1 simonb b intr_exit
510 1.1 simonb
511 1.1 simonb /*
512 1.1 simonb * FIT interrupt handler.
513 1.1 simonb */
514 1.1 simonb .align 5
515 1.1 simonb fitint:
516 1.1 simonb mtsprg 1,1 /* save SP */
517 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
518 1.1 simonb mflr 28 /* save LR */
519 1.1 simonb mfcr 29 /* save CR */
520 1.1 simonb mfxer 30 /* save XER */
521 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
522 1.1 simonb addi 1,1,intstk+INTSTK@l
523 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
524 1.1 simonb addic. 31,31,1
525 1.1 simonb stw 31,0(1)
526 1.1 simonb beq 1f
527 1.1 simonb mfsprg 1,1 /* yes, get old SP */
528 1.1 simonb 1:
529 1.1 simonb INTRENTER
530 1.1 simonb addi 3,1,8 /* intr frame */
531 1.1 simonb bl _C_LABEL(stat_intr)
532 1.1 simonb b intr_exit
533 1.1 simonb
534 1.1 simonb #ifdef DDB
535 1.1 simonb /*
536 1.1 simonb * Deliberate entry to ddbtrap
537 1.1 simonb */
538 1.1 simonb .globl _C_LABEL(ddb_trap)
539 1.1 simonb _C_LABEL(ddb_trap):
540 1.1 simonb mtsprg 1,1
541 1.1 simonb mfmsr 3
542 1.1 simonb mtsrr1 3
543 1.1 simonb wrteei 0 /* disable interrupts */
544 1.1 simonb isync
545 1.1 simonb stmw 28,ddbsave(0)
546 1.1 simonb mflr 28
547 1.1 simonb li 29,EXC_BPT
548 1.1 simonb mtlr 29
549 1.1 simonb mfcr 29
550 1.1 simonb mtsrr0 28
551 1.1 simonb
552 1.1 simonb /*
553 1.1 simonb * Now the ddb trap catching code.
554 1.1 simonb */
555 1.1 simonb ddbtrap:
556 1.1 simonb FRAME_SETUP(ddbsave)
557 1.1 simonb /* Call C trap code: */
558 1.1 simonb addi 3,1,8
559 1.1 simonb bl _C_LABEL(ddb_trap_glue)
560 1.1 simonb or. 3,3,3
561 1.1 simonb bne ddbleave
562 1.1 simonb /* This wasn't for DDB, so switch to real trap: */
563 1.1 simonb lwz 3,FRAME_EXC+8(1) /* save exception */
564 1.1 simonb stw 3,ddbsave+12(0)
565 1.1 simonb FRAME_LEAVE(ddbsave)
566 1.1 simonb mtsprg 1,1 /* prepare for entrance to realtrap */
567 1.1 simonb stmw 28,tempsave(0)
568 1.1 simonb mflr 28
569 1.1 simonb mfcr 29
570 1.1 simonb lwz 31,ddbsave+12(0)
571 1.1 simonb mtlr 31
572 1.1 simonb b realtrap
573 1.1 simonb ddbleave:
574 1.1 simonb FRAME_LEAVE(ddbsave)
575 1.1 simonb rfi
576 1.1 simonb ba . /* Protect against prefetch */
577 1.1 simonb #endif /* DDB */
578 1.1 simonb
579 1.1 simonb #ifdef IPKDB
580 1.1 simonb /*
581 1.1 simonb * Deliberate entry to ipkdbtrap
582 1.1 simonb */
583 1.1 simonb .globl _C_LABEL(ipkdb_trap)
584 1.1 simonb _C_LABEL(ipkdb_trap):
585 1.1 simonb mtsprg 1,1
586 1.1 simonb mfmsr 3
587 1.1 simonb mtsrr1 3
588 1.1 simonb wrteei 0 /* disable interrupts */
589 1.1 simonb isync
590 1.1 simonb stmw 28,ipkdbsave(0)
591 1.1 simonb mflr 28
592 1.1 simonb li 29,EXC_BPT
593 1.1 simonb mtlr 29
594 1.1 simonb mfcr 29
595 1.1 simonb mtsrr0 28
596 1.1 simonb
597 1.1 simonb /*
598 1.1 simonb * Now the ipkdb trap catching code.
599 1.1 simonb */
600 1.1 simonb ipkdbtrap:
601 1.1 simonb FRAME_SETUP(ipkdbsave)
602 1.1 simonb /* Call C trap code: */
603 1.1 simonb addi 3,1,8
604 1.1 simonb bl _C_LABEL(ipkdb_trap_glue)
605 1.1 simonb or. 3,3,3
606 1.1 simonb bne ipkdbleave
607 1.1 simonb /* This wasn't for IPKDB, so switch to real trap: */
608 1.1 simonb lwz 3,FRAME_EXC+8(1) /* save exception */
609 1.1 simonb stw 3,ipkdbsave+8(0)
610 1.1 simonb FRAME_LEAVE(ipkdbsave)
611 1.1 simonb mtsprg 1,1 /* prepare for entrance to realtrap */
612 1.1 simonb stmw 28,tempsave(0)
613 1.1 simonb mflr 28
614 1.1 simonb mfcr 29
615 1.1 simonb lwz 31,ipkdbsave+8(0)
616 1.1 simonb mtlr 31
617 1.1 simonb b realtrap
618 1.1 simonb ipkdbleave:
619 1.1 simonb FRAME_LEAVE(ipkdbsave)
620 1.1 simonb rfi
621 1.1 simonb ba . /* Protect against prefetch */
622 1.1 simonb
623 1.1 simonb ipkdbfault:
624 1.1 simonb ba _ipkdbfault
625 1.1 simonb _ipkdbfault:
626 1.1 simonb mfsrr0 3
627 1.1 simonb addi 3,3,4
628 1.1 simonb mtsrr0 3
629 1.1 simonb li 3,-1
630 1.1 simonb rfi
631 1.1 simonb ba . /* Protect against prefetch */
632 1.1 simonb
633 1.1 simonb /*
634 1.1 simonb * int ipkdbfbyte(unsigned char *p)
635 1.1 simonb */
636 1.1 simonb .globl _C_LABEL(ipkdbfbyte)
637 1.1 simonb _C_LABEL(ipkdbfbyte):
638 1.1 simonb li 9,EXC_DSI /* establish new fault routine */
639 1.1 simonb lwz 5,0(9)
640 1.1 simonb lis 6,ipkdbfault@ha
641 1.1 simonb lwz 6,ipkdbfault@l(6)
642 1.1 simonb stw 6,0(9)
643 1.1 simonb #ifdef IPKDBUSERHACK
644 1.1 simonb #ifndef PPC_IBM4XX
645 1.1 simonb lis 8,_C_LABEL(ipkdbsr)@ha
646 1.1 simonb lwz 8,_C_LABEL(ipkdbsr)@l(8)
647 1.1 simonb mtsr USER_SR,8
648 1.1 simonb isync
649 1.1 simonb #endif
650 1.1 simonb #endif
651 1.1 simonb dcbst 0,9 /* flush data... */
652 1.1 simonb sync
653 1.1 simonb icbi 0,9 /* and instruction caches */
654 1.1 simonb lbz 3,0(3) /* fetch data */
655 1.1 simonb stw 5,0(9) /* restore previous fault handler */
656 1.1 simonb dcbst 0,9 /* and flush data... */
657 1.1 simonb sync
658 1.1 simonb icbi 0,9 /* and instruction caches */
659 1.1 simonb blr
660 1.1 simonb
661 1.1 simonb /*
662 1.1 simonb * int ipkdbsbyte(unsigned char *p, int c)
663 1.1 simonb */
664 1.1 simonb .globl _C_LABEL(ipkdbsbyte)
665 1.1 simonb _C_LABEL(ipkdbsbyte):
666 1.1 simonb li 9,EXC_DSI /* establish new fault routine */
667 1.1 simonb lwz 5,0(9)
668 1.1 simonb lis 6,ipkdbfault@ha
669 1.1 simonb lwz 6,ipkdbfault@l(6)
670 1.1 simonb stw 6,0(9)
671 1.1 simonb #ifdef IPKDBUSERHACK
672 1.1 simonb #ifndef PPC_IBM4XX
673 1.1 simonb lis 8,_C_LABEL(ipkdbsr)@ha
674 1.1 simonb lwz 8,_C_LABEL(ipkdbsr)@l(8)
675 1.1 simonb mtsr USER_SR,8
676 1.1 simonb isync
677 1.1 simonb #endif
678 1.1 simonb #endif
679 1.1 simonb dcbst 0,9 /* flush data... */
680 1.1 simonb sync
681 1.1 simonb icbi 0,9 /* and instruction caches */
682 1.1 simonb mr 6,3
683 1.1 simonb xor 3,3,3
684 1.1 simonb stb 4,0(6)
685 1.1 simonb dcbst 0,6 /* Now do appropriate flushes
686 1.1 simonb to data... */
687 1.1 simonb sync
688 1.1 simonb icbi 0,6 /* and instruction caches */
689 1.1 simonb stw 5,0(9) /* restore previous fault handler */
690 1.1 simonb dcbst 0,9 /* and flush data... */
691 1.1 simonb sync
692 1.1 simonb icbi 0,9 /* and instruction caches */
693 1.1 simonb blr
694 1.1 simonb #endif /* IPKDB */
695