trap_subr.S revision 1.4 1 1.4 simonb /* $NetBSD: trap_subr.S,v 1.4 2002/07/11 01:38:49 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.4 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.4 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.4 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.4 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.4 simonb
160 1.1 simonb /*
161 1.1 simonb * This code gets copied to all the trap vectors
162 1.4 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.3 eeh CRITICAL_EXC_HANDLER(mchk)
172 1.1 simonb
173 1.1 simonb /*
174 1.1 simonb * This one for the external interrupt handler.
175 1.1 simonb */
176 1.1 simonb .globl _C_LABEL(extint),_C_LABEL(extsize)
177 1.1 simonb _C_LABEL(extint):
178 1.1 simonb mtsprg 1,1 /* save SP */
179 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
180 1.1 simonb mflr 28 /* save LR */
181 1.1 simonb mfcr 29 /* save CR */
182 1.1 simonb mfxer 30 /* save XER */
183 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
184 1.1 simonb addi 1,1,intstk+INTSTK@l
185 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
186 1.1 simonb addic. 31,31,1
187 1.1 simonb stw 31,0(1)
188 1.1 simonb beq 1f
189 1.1 simonb mfsprg 1,1 /* yes, get old SP */
190 1.1 simonb 1:
191 1.1 simonb ba extintr
192 1.1 simonb _C_LABEL(extsize) = .-_C_LABEL(extint)
193 1.1 simonb
194 1.4 simonb
195 1.1 simonb #ifdef DDB
196 1.1 simonb #define ddbsave 0xde0 /* primary save area for DDB */
197 1.1 simonb /*
198 1.1 simonb * In case of DDB we want a separate trap catcher for it
199 1.1 simonb */
200 1.1 simonb .local ddbstk
201 1.1 simonb .comm ddbstk,INTSTK,8 /* ddb stack */
202 1.1 simonb
203 1.1 simonb .globl _C_LABEL(ddblow),_C_LABEL(ddbsize)
204 1.1 simonb _C_LABEL(ddblow):
205 1.1 simonb mtsprg 1,1 /* save SP */
206 1.1 simonb stmw 28,ddbsave(0) /* free r28-r31 */
207 1.1 simonb mflr 28 /* save LR */
208 1.1 simonb mfcr 29 /* save CR */
209 1.1 simonb lis 1,ddbstk+INTSTK@ha /* get new SP */
210 1.1 simonb addi 1,1,ddbstk+INTSTK@l
211 1.1 simonb bla ddbtrap
212 1.1 simonb _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
213 1.1 simonb #endif /* DDB */
214 1.1 simonb
215 1.1 simonb #ifdef IPKDB
216 1.1 simonb #define ipkdbsave 0xde0 /* primary save area for IPKDB */
217 1.1 simonb /*
218 1.1 simonb * In case of IPKDB we want a separate trap catcher for it
219 1.1 simonb */
220 1.1 simonb
221 1.1 simonb .local ipkdbstk
222 1.1 simonb .comm ipkdbstk,INTSTK,8 /* ipkdb stack */
223 1.1 simonb
224 1.1 simonb .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
225 1.1 simonb _C_LABEL(ipkdblow):
226 1.1 simonb mtsprg 1,1 /* save SP */
227 1.1 simonb stmw 28,ipkdbsave(0) /* free r28-r31 */
228 1.1 simonb mflr 28 /* save LR */
229 1.1 simonb mfcr 29 /* save CR */
230 1.1 simonb lis 1,ipkdbstk+INTSTK@ha /* get new SP */
231 1.1 simonb addi 1,1,ipkdbstk+INTSTK@l
232 1.1 simonb bla ipkdbtrap
233 1.1 simonb _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
234 1.1 simonb #endif /* IPKDB */
235 1.1 simonb
236 1.1 simonb #ifdef DEBUG
237 1.1 simonb #define TRAP_IF_ZERO(r) tweqi r,0
238 1.1 simonb #else
239 1.1 simonb #define TRAP_IF_ZERO(r)
240 1.1 simonb #endif
241 1.4 simonb
242 1.1 simonb /*
243 1.1 simonb * FRAME_SETUP assumes:
244 1.1 simonb * SPRG1 SP (1)
245 1.1 simonb * savearea r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps)
246 1.1 simonb * 28 LR
247 1.1 simonb * 29 CR
248 1.1 simonb * 1 kernel stack
249 1.1 simonb * LR trap type
250 1.1 simonb * SRR0/1 as at start of trap
251 1.1 simonb */
252 1.1 simonb #define FRAME_SETUP(savearea) \
253 1.1 simonb /* Have to enable translation to allow access of kernel stack: */ \
254 1.1 simonb mfsrr0 30; \
255 1.1 simonb mfsrr1 31; \
256 1.1 simonb stmw 30,savearea+24(0); \
257 1.1 simonb mfpid 30; \
258 1.1 simonb li 31,KERNEL_PID; \
259 1.1 simonb mtpid 31; \
260 1.1 simonb mfmsr 31; \
261 1.1 simonb ori 31,31,(PSL_DR|PSL_IR)@l; \
262 1.1 simonb mtmsr 31; \
263 1.1 simonb isync; \
264 1.1 simonb mfsprg 31,1; \
265 1.1 simonb stwu 31,-FRAMELEN(1); \
266 1.1 simonb stw 30,FRAME_PID+8(1); \
267 1.1 simonb stw 0,FRAME_0+8(1); \
268 1.1 simonb stw 31,FRAME_1+8(1); \
269 1.1 simonb stw 28,FRAME_LR+8(1); \
270 1.1 simonb stw 29,FRAME_CR+8(1); \
271 1.1 simonb lmw 28,savearea(0); \
272 1.1 simonb stmw 2,FRAME_2+8(1); \
273 1.1 simonb lmw 28,savearea+16(0); \
274 1.1 simonb mfxer 3; \
275 1.1 simonb mfctr 4; \
276 1.1 simonb mflr 5; \
277 1.1 simonb andi. 5,5,0xff00; \
278 1.1 simonb stw 3,FRAME_XER+8(1); \
279 1.1 simonb stw 4,FRAME_CTR+8(1); \
280 1.1 simonb stw 5,FRAME_EXC+8(1); \
281 1.1 simonb stw 28,FRAME_DEAR+8(1); \
282 1.1 simonb stw 29,FRAME_ESR+8(1); \
283 1.1 simonb stw 30,FRAME_SRR0+8(1); \
284 1.1 simonb stw 31,FRAME_SRR1+8(1)
285 1.1 simonb
286 1.1 simonb #define FRAME_LEAVE(savearea) \
287 1.1 simonb /* Now restore regs: */ \
288 1.1 simonb lwz 3,FRAME_PID+8(1); \
289 1.1 simonb lwz 4,FRAME_SRR1+8(1); \
290 1.1 simonb bl _C_LABEL(ctx_setup); \
291 1.1 simonb TRAP_IF_ZERO(r3); \
292 1.1 simonb stw 3,FRAME_PID+8(1); \
293 1.1 simonb lmw 26,FRAME_LR+8(1); \
294 1.1 simonb mtlr 26; \
295 1.1 simonb mtcr 27; \
296 1.1 simonb mtxer 28; \
297 1.1 simonb mtctr 29; \
298 1.1 simonb mtsrr0 30; \
299 1.1 simonb mtsrr1 31; \
300 1.1 simonb lmw 2,FRAME_2+8(1); \
301 1.1 simonb lwz 0,FRAME_0+8(1); \
302 1.1 simonb stmw 29,savearea(0); \
303 1.1 simonb lwz 30,FRAME_PID+8(1); \
304 1.1 simonb lwz 1,FRAME_1+8(1); \
305 1.1 simonb mfmsr 31; \
306 1.1 simonb li 29,(PSL_DR|PSL_IR)@l; \
307 1.1 simonb andc 31,31,29; \
308 1.1 simonb mfcr 29; \
309 1.1 simonb mtcr 29; \
310 1.1 simonb mtmsr 31; \
311 1.1 simonb isync; \
312 1.1 simonb TRAP_IF_ZERO(r30); \
313 1.1 simonb mtpid 30; \
314 1.1 simonb lmw 29,savearea(0)
315 1.1 simonb
316 1.1 simonb realtrap: /* entry point after IPKDB is done with exception */
317 1.1 simonb /* Test whether we already had PR set */
318 1.4 simonb mfsrr1 1
319 1.4 simonb mtcr 1
320 1.4 simonb mfsprg 1,1 /* restore SP (might have been
321 1.4 simonb overwritten) */
322 1.4 simonb bc 4,17,s_trap /* branch if PSL_PR is false */
323 1.4 simonb lis 1,_C_LABEL(curpcb)@ha
324 1.4 simonb lwz 1,_C_LABEL(curpcb)@l(1)
325 1.4 simonb addi 1,1,USPACE /* stack is top of user struct */
326 1.1 simonb /*
327 1.1 simonb * Now the common trap catching code.
328 1.1 simonb */
329 1.1 simonb s_trap:
330 1.1 simonb FRAME_SETUP(tempsave)
331 1.1 simonb /* Now we can recover interrupts again: */
332 1.1 simonb trapagain:
333 1.1 simonb wrteei 1 /* Enable interrupts */
334 1.1 simonb /* Call C trap code: */
335 1.1 simonb addi 3,1,8
336 1.1 simonb bl _C_LABEL(trap)
337 1.2 simonb .globl _C_LABEL(trapexit)
338 1.2 simonb _C_LABEL(trapexit):
339 1.1 simonb /* Disable interrupts: */
340 1.1 simonb wrteei 0
341 1.1 simonb /* Test AST pending: */
342 1.1 simonb lwz 5,FRAME_SRR1+8(1)
343 1.1 simonb mtcr 5
344 1.1 simonb bc 4,17,1f /* branch if PSL_PR is false */
345 1.1 simonb #if defined(MULTIPROCESSOR)
346 1.1 simonb GET_CPUINFO(3)
347 1.1 simonb lwz 4,CI_ASTPENDING(3)
348 1.1 simonb #else
349 1.1 simonb lis 3,_C_LABEL(astpending)@ha
350 1.1 simonb lwz 4,_C_LABEL(astpending)@l(3)
351 1.1 simonb #endif
352 1.1 simonb andi. 4,4,1
353 1.1 simonb beq 1f
354 1.1 simonb li 6,EXC_AST
355 1.1 simonb stw 6,FRAME_EXC+8(1)
356 1.1 simonb b trapagain
357 1.1 simonb 1:
358 1.1 simonb FRAME_LEAVE(exitsave)
359 1.1 simonb rfi
360 1.1 simonb ba . /* Protect against prefetch */
361 1.1 simonb /*
362 1.1 simonb * External interrupt second level handler
363 1.1 simonb */
364 1.4 simonb
365 1.1 simonb #define INTRENTER \
366 1.1 simonb /* Save non-volatile registers: */ \
367 1.1 simonb stwu 1,-92(1); /* temporarily */ \
368 1.1 simonb stw 0,84(1); \
369 1.1 simonb mfsprg 0,1; /* get original SP */ \
370 1.1 simonb stw 0,0(1); /* and store it */ \
371 1.1 simonb stw 3,80(1); \
372 1.1 simonb stw 4,76(1); \
373 1.1 simonb stw 5,72(1); \
374 1.1 simonb stw 6,68(1); \
375 1.1 simonb stw 7,64(1); \
376 1.1 simonb stw 8,60(1); \
377 1.1 simonb stw 9,56(1); \
378 1.1 simonb stw 10,52(1); \
379 1.1 simonb stw 11,48(1); \
380 1.1 simonb stw 12,44(1); \
381 1.1 simonb stw 28,40(1); /* saved LR */ \
382 1.1 simonb stw 29,36(1); /* saved CR */ \
383 1.1 simonb stw 30,32(1); /* saved XER */ \
384 1.1 simonb lmw 28,tempsave(0); /* restore r28-r31 */ \
385 1.1 simonb mfctr 6; \
386 1.1 simonb lis 5,_C_LABEL(intr_depth)@ha; \
387 1.1 simonb lwz 5,_C_LABEL(intr_depth)@l(5); \
388 1.1 simonb mfsrr0 4; \
389 1.1 simonb mfsrr1 3; \
390 1.1 simonb stw 6,28(1); \
391 1.1 simonb stw 5,20(1); \
392 1.1 simonb stw 4,12(1); \
393 1.1 simonb stw 3,8(1); \
394 1.1 simonb mfpid 0; /* get currect PID register */ \
395 1.1 simonb stw 0,88(1) ; \
396 1.1 simonb li 0, KERNEL_PID; \
397 1.1 simonb mtpid 0; \
398 1.1 simonb /* interrupts are recoverable here, and enable translation */ \
399 1.1 simonb mfmsr 5; \
400 1.1 simonb ori 5,5,(PSL_IR|PSL_DR); \
401 1.1 simonb mtmsr 5; \
402 1.1 simonb isync
403 1.1 simonb
404 1.1 simonb .globl _C_LABEL(extint_call)
405 1.1 simonb extintr:
406 1.1 simonb INTRENTER
407 1.1 simonb _C_LABEL(extint_call):
408 1.1 simonb bl _C_LABEL(extint_call) /* to be filled in later */
409 1.1 simonb
410 1.1 simonb intr_exit:
411 1.1 simonb /* Disable interrupts (should already be disabled) and MMU here: */
412 1.1 simonb wrteei 0
413 1.1 simonb isync
414 1.1 simonb lwz 3,88(1)
415 1.1 simonb lwz 4,8(1) /* Load srr1 */
416 1.1 simonb bl _C_LABEL(ctx_setup) /* Get proper ctx */
417 1.1 simonb mfmsr 5
418 1.1 simonb lis 4,(PSL_EE|PSL_DR|PSL_IR)@h
419 1.1 simonb ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l
420 1.1 simonb andc 5,5,4
421 1.1 simonb mtmsr 5
422 1.1 simonb isync
423 1.1 simonb mtpid 3 /* Load CTX */
424 1.4 simonb
425 1.1 simonb /* restore possibly overwritten registers: */
426 1.1 simonb lwz 12,44(1)
427 1.1 simonb lwz 11,48(1)
428 1.1 simonb lwz 10,52(1)
429 1.1 simonb lwz 9,56(1)
430 1.1 simonb lwz 8,60(1)
431 1.1 simonb lwz 7,64(1)
432 1.1 simonb lwz 6,8(1)
433 1.1 simonb lwz 5,12(1)
434 1.1 simonb lwz 4,28(1)
435 1.1 simonb lwz 3,32(1)
436 1.1 simonb mtsrr1 6
437 1.1 simonb mtsrr0 5
438 1.1 simonb mtctr 4
439 1.1 simonb mtxer 3
440 1.1 simonb /* Returning to user mode? */
441 1.1 simonb mtcr 6 /* saved SRR1 */
442 1.1 simonb bc 4,17,1f /* branch if PSL_PR is false */
443 1.1 simonb
444 1.1 simonb #if defined(MULTIPROCESSOR)
445 1.1 simonb lwz 4,CI_ASTPENDING(4) /* Test AST pending */
446 1.1 simonb #else
447 1.1 simonb lis 3,_C_LABEL(astpending)@ha /* Test AST pending */
448 1.1 simonb lwz 4,_C_LABEL(astpending)@l(3)
449 1.1 simonb #endif
450 1.1 simonb andi. 4,4,1
451 1.1 simonb beq 1f
452 1.1 simonb /* Setup for entry to realtrap: */
453 1.1 simonb lwz 3,0(1) /* get saved SP */
454 1.1 simonb mtsprg 1,3
455 1.1 simonb li 6,EXC_AST
456 1.1 simonb stmw 28,tempsave(0) /* establish tempsave again */
457 1.1 simonb mtlr 6
458 1.1 simonb lwz 28,40(1) /* saved LR */
459 1.1 simonb lwz 29,36(1) /* saved CR */
460 1.1 simonb lwz 6,68(1)
461 1.1 simonb lwz 5,72(1)
462 1.1 simonb lwz 4,76(1)
463 1.1 simonb lwz 3,80(1)
464 1.1 simonb lwz 0,84(1)
465 1.1 simonb lis 30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
466 1.1 simonb lwz 31,_C_LABEL(intr_depth)@l(30)
467 1.1 simonb addi 31,31,-1
468 1.1 simonb stw 31,_C_LABEL(intr_depth)@l(30)
469 1.1 simonb b realtrap
470 1.1 simonb 1:
471 1.1 simonb /* Here is the normal exit of extintr: */
472 1.1 simonb lwz 5,36(1)
473 1.1 simonb lwz 6,40(1)
474 1.1 simonb mtcr 5
475 1.1 simonb mtlr 6
476 1.1 simonb lwz 6,68(1)
477 1.1 simonb lwz 5,72(1)
478 1.1 simonb lis 3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
479 1.1 simonb lwz 4,_C_LABEL(intr_depth)@l(3)
480 1.1 simonb addi 4,4,-1
481 1.1 simonb stw 4,_C_LABEL(intr_depth)@l(3)
482 1.1 simonb lwz 4,76(1)
483 1.1 simonb lwz 3,80(1)
484 1.1 simonb lwz 0,84(1)
485 1.1 simonb lwz 1,0(1)
486 1.1 simonb rfi
487 1.1 simonb ba . /* Protect against prefetch */
488 1.4 simonb
489 1.1 simonb /*
490 1.1 simonb * PIT interrupt handler.
491 1.1 simonb */
492 1.1 simonb .align 5
493 1.1 simonb _C_LABEL(pitint):
494 1.1 simonb mtsprg 1,1 /* save SP */
495 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
496 1.1 simonb mflr 28 /* save LR */
497 1.1 simonb mfcr 29 /* save CR */
498 1.1 simonb mfxer 30 /* save XER */
499 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
500 1.1 simonb addi 1,1,intstk+INTSTK@l
501 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
502 1.1 simonb addic. 31,31,1
503 1.1 simonb stw 31,0(1)
504 1.1 simonb beq 1f
505 1.1 simonb mfsprg 1,1 /* yes, get old SP */
506 1.1 simonb 1:
507 1.1 simonb INTRENTER
508 1.1 simonb addi 3,1,8 /* intr frame */
509 1.1 simonb bl _C_LABEL(decr_intr)
510 1.1 simonb b intr_exit
511 1.1 simonb
512 1.1 simonb /*
513 1.1 simonb * FIT interrupt handler.
514 1.1 simonb */
515 1.1 simonb .align 5
516 1.1 simonb fitint:
517 1.1 simonb mtsprg 1,1 /* save SP */
518 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
519 1.1 simonb mflr 28 /* save LR */
520 1.1 simonb mfcr 29 /* save CR */
521 1.1 simonb mfxer 30 /* save XER */
522 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
523 1.1 simonb addi 1,1,intstk+INTSTK@l
524 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
525 1.1 simonb addic. 31,31,1
526 1.1 simonb stw 31,0(1)
527 1.1 simonb beq 1f
528 1.1 simonb mfsprg 1,1 /* yes, get old SP */
529 1.1 simonb 1:
530 1.1 simonb INTRENTER
531 1.1 simonb addi 3,1,8 /* intr frame */
532 1.1 simonb bl _C_LABEL(stat_intr)
533 1.1 simonb b intr_exit
534 1.1 simonb
535 1.1 simonb #ifdef DDB
536 1.1 simonb /*
537 1.1 simonb * Deliberate entry to ddbtrap
538 1.1 simonb */
539 1.1 simonb .globl _C_LABEL(ddb_trap)
540 1.1 simonb _C_LABEL(ddb_trap):
541 1.1 simonb mtsprg 1,1
542 1.1 simonb mfmsr 3
543 1.1 simonb mtsrr1 3
544 1.1 simonb wrteei 0 /* disable interrupts */
545 1.1 simonb isync
546 1.1 simonb stmw 28,ddbsave(0)
547 1.1 simonb mflr 28
548 1.1 simonb li 29,EXC_BPT
549 1.1 simonb mtlr 29
550 1.1 simonb mfcr 29
551 1.1 simonb mtsrr0 28
552 1.1 simonb
553 1.1 simonb /*
554 1.1 simonb * Now the ddb trap catching code.
555 1.1 simonb */
556 1.1 simonb ddbtrap:
557 1.1 simonb FRAME_SETUP(ddbsave)
558 1.1 simonb /* Call C trap code: */
559 1.1 simonb addi 3,1,8
560 1.1 simonb bl _C_LABEL(ddb_trap_glue)
561 1.1 simonb or. 3,3,3
562 1.1 simonb bne ddbleave
563 1.1 simonb /* This wasn't for DDB, so switch to real trap: */
564 1.1 simonb lwz 3,FRAME_EXC+8(1) /* save exception */
565 1.1 simonb stw 3,ddbsave+12(0)
566 1.1 simonb FRAME_LEAVE(ddbsave)
567 1.1 simonb mtsprg 1,1 /* prepare for entrance to realtrap */
568 1.1 simonb stmw 28,tempsave(0)
569 1.1 simonb mflr 28
570 1.1 simonb mfcr 29
571 1.1 simonb lwz 31,ddbsave+12(0)
572 1.1 simonb mtlr 31
573 1.1 simonb b realtrap
574 1.1 simonb ddbleave:
575 1.1 simonb FRAME_LEAVE(ddbsave)
576 1.1 simonb rfi
577 1.1 simonb ba . /* Protect against prefetch */
578 1.1 simonb #endif /* DDB */
579 1.1 simonb
580 1.1 simonb #ifdef IPKDB
581 1.1 simonb /*
582 1.1 simonb * Deliberate entry to ipkdbtrap
583 1.1 simonb */
584 1.1 simonb .globl _C_LABEL(ipkdb_trap)
585 1.1 simonb _C_LABEL(ipkdb_trap):
586 1.1 simonb mtsprg 1,1
587 1.1 simonb mfmsr 3
588 1.1 simonb mtsrr1 3
589 1.1 simonb wrteei 0 /* disable interrupts */
590 1.1 simonb isync
591 1.1 simonb stmw 28,ipkdbsave(0)
592 1.1 simonb mflr 28
593 1.1 simonb li 29,EXC_BPT
594 1.1 simonb mtlr 29
595 1.1 simonb mfcr 29
596 1.1 simonb mtsrr0 28
597 1.1 simonb
598 1.1 simonb /*
599 1.1 simonb * Now the ipkdb trap catching code.
600 1.1 simonb */
601 1.1 simonb ipkdbtrap:
602 1.1 simonb FRAME_SETUP(ipkdbsave)
603 1.1 simonb /* Call C trap code: */
604 1.1 simonb addi 3,1,8
605 1.1 simonb bl _C_LABEL(ipkdb_trap_glue)
606 1.1 simonb or. 3,3,3
607 1.1 simonb bne ipkdbleave
608 1.1 simonb /* This wasn't for IPKDB, so switch to real trap: */
609 1.1 simonb lwz 3,FRAME_EXC+8(1) /* save exception */
610 1.1 simonb stw 3,ipkdbsave+8(0)
611 1.1 simonb FRAME_LEAVE(ipkdbsave)
612 1.1 simonb mtsprg 1,1 /* prepare for entrance to realtrap */
613 1.1 simonb stmw 28,tempsave(0)
614 1.1 simonb mflr 28
615 1.1 simonb mfcr 29
616 1.1 simonb lwz 31,ipkdbsave+8(0)
617 1.1 simonb mtlr 31
618 1.1 simonb b realtrap
619 1.1 simonb ipkdbleave:
620 1.1 simonb FRAME_LEAVE(ipkdbsave)
621 1.1 simonb rfi
622 1.1 simonb ba . /* Protect against prefetch */
623 1.1 simonb
624 1.1 simonb ipkdbfault:
625 1.1 simonb ba _ipkdbfault
626 1.1 simonb _ipkdbfault:
627 1.1 simonb mfsrr0 3
628 1.1 simonb addi 3,3,4
629 1.1 simonb mtsrr0 3
630 1.1 simonb li 3,-1
631 1.1 simonb rfi
632 1.1 simonb ba . /* Protect against prefetch */
633 1.1 simonb
634 1.1 simonb /*
635 1.1 simonb * int ipkdbfbyte(unsigned char *p)
636 1.1 simonb */
637 1.1 simonb .globl _C_LABEL(ipkdbfbyte)
638 1.1 simonb _C_LABEL(ipkdbfbyte):
639 1.1 simonb li 9,EXC_DSI /* establish new fault routine */
640 1.1 simonb lwz 5,0(9)
641 1.1 simonb lis 6,ipkdbfault@ha
642 1.1 simonb lwz 6,ipkdbfault@l(6)
643 1.1 simonb stw 6,0(9)
644 1.1 simonb #ifdef IPKDBUSERHACK
645 1.1 simonb #ifndef PPC_IBM4XX
646 1.1 simonb lis 8,_C_LABEL(ipkdbsr)@ha
647 1.1 simonb lwz 8,_C_LABEL(ipkdbsr)@l(8)
648 1.1 simonb mtsr USER_SR,8
649 1.1 simonb isync
650 1.4 simonb #endif
651 1.1 simonb #endif
652 1.1 simonb dcbst 0,9 /* flush data... */
653 1.1 simonb sync
654 1.1 simonb icbi 0,9 /* and instruction caches */
655 1.1 simonb lbz 3,0(3) /* fetch data */
656 1.1 simonb stw 5,0(9) /* restore previous fault handler */
657 1.1 simonb dcbst 0,9 /* and flush data... */
658 1.1 simonb sync
659 1.1 simonb icbi 0,9 /* and instruction caches */
660 1.1 simonb blr
661 1.1 simonb
662 1.1 simonb /*
663 1.1 simonb * int ipkdbsbyte(unsigned char *p, int c)
664 1.1 simonb */
665 1.1 simonb .globl _C_LABEL(ipkdbsbyte)
666 1.1 simonb _C_LABEL(ipkdbsbyte):
667 1.1 simonb li 9,EXC_DSI /* establish new fault routine */
668 1.1 simonb lwz 5,0(9)
669 1.1 simonb lis 6,ipkdbfault@ha
670 1.1 simonb lwz 6,ipkdbfault@l(6)
671 1.1 simonb stw 6,0(9)
672 1.1 simonb #ifdef IPKDBUSERHACK
673 1.1 simonb #ifndef PPC_IBM4XX
674 1.1 simonb lis 8,_C_LABEL(ipkdbsr)@ha
675 1.1 simonb lwz 8,_C_LABEL(ipkdbsr)@l(8)
676 1.1 simonb mtsr USER_SR,8
677 1.1 simonb isync
678 1.4 simonb #endif
679 1.1 simonb #endif
680 1.1 simonb dcbst 0,9 /* flush data... */
681 1.1 simonb sync
682 1.1 simonb icbi 0,9 /* and instruction caches */
683 1.1 simonb mr 6,3
684 1.1 simonb xor 3,3,3
685 1.1 simonb stb 4,0(6)
686 1.1 simonb dcbst 0,6 /* Now do appropriate flushes
687 1.1 simonb to data... */
688 1.1 simonb sync
689 1.1 simonb icbi 0,6 /* and instruction caches */
690 1.1 simonb stw 5,0(9) /* restore previous fault handler */
691 1.1 simonb dcbst 0,9 /* and flush data... */
692 1.1 simonb sync
693 1.4 simonb icbi 0,9 /* and instruction caches */
694 1.1 simonb blr
695 1.1 simonb #endif /* IPKDB */
696