trap_subr.S revision 1.1 1 1.1 simonb /* $NetBSD: trap_subr.S,v 1.1 2001/06/13 06:01:48 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.1 simonb trapexit:
337 1.1 simonb /* Disable interrupts: */
338 1.1 simonb wrteei 0
339 1.1 simonb /* Test AST pending: */
340 1.1 simonb lwz 5,FRAME_SRR1+8(1)
341 1.1 simonb mtcr 5
342 1.1 simonb bc 4,17,1f /* branch if PSL_PR is false */
343 1.1 simonb #if defined(MULTIPROCESSOR)
344 1.1 simonb GET_CPUINFO(3)
345 1.1 simonb lwz 4,CI_ASTPENDING(3)
346 1.1 simonb #else
347 1.1 simonb lis 3,_C_LABEL(astpending)@ha
348 1.1 simonb lwz 4,_C_LABEL(astpending)@l(3)
349 1.1 simonb #endif
350 1.1 simonb andi. 4,4,1
351 1.1 simonb beq 1f
352 1.1 simonb li 6,EXC_AST
353 1.1 simonb stw 6,FRAME_EXC+8(1)
354 1.1 simonb b trapagain
355 1.1 simonb 1:
356 1.1 simonb FRAME_LEAVE(exitsave)
357 1.1 simonb rfi
358 1.1 simonb ba . /* Protect against prefetch */
359 1.1 simonb /*
360 1.1 simonb * External interrupt second level handler
361 1.1 simonb */
362 1.1 simonb
363 1.1 simonb #define INTRENTER \
364 1.1 simonb /* Save non-volatile registers: */ \
365 1.1 simonb stwu 1,-92(1); /* temporarily */ \
366 1.1 simonb stw 0,84(1); \
367 1.1 simonb mfsprg 0,1; /* get original SP */ \
368 1.1 simonb stw 0,0(1); /* and store it */ \
369 1.1 simonb stw 3,80(1); \
370 1.1 simonb stw 4,76(1); \
371 1.1 simonb stw 5,72(1); \
372 1.1 simonb stw 6,68(1); \
373 1.1 simonb stw 7,64(1); \
374 1.1 simonb stw 8,60(1); \
375 1.1 simonb stw 9,56(1); \
376 1.1 simonb stw 10,52(1); \
377 1.1 simonb stw 11,48(1); \
378 1.1 simonb stw 12,44(1); \
379 1.1 simonb stw 28,40(1); /* saved LR */ \
380 1.1 simonb stw 29,36(1); /* saved CR */ \
381 1.1 simonb stw 30,32(1); /* saved XER */ \
382 1.1 simonb lmw 28,tempsave(0); /* restore r28-r31 */ \
383 1.1 simonb mfctr 6; \
384 1.1 simonb lis 5,_C_LABEL(intr_depth)@ha; \
385 1.1 simonb lwz 5,_C_LABEL(intr_depth)@l(5); \
386 1.1 simonb mfsrr0 4; \
387 1.1 simonb mfsrr1 3; \
388 1.1 simonb stw 6,28(1); \
389 1.1 simonb stw 5,20(1); \
390 1.1 simonb stw 4,12(1); \
391 1.1 simonb stw 3,8(1); \
392 1.1 simonb mfpid 0; /* get currect PID register */ \
393 1.1 simonb stw 0,88(1) ; \
394 1.1 simonb li 0, KERNEL_PID; \
395 1.1 simonb mtpid 0; \
396 1.1 simonb /* interrupts are recoverable here, and enable translation */ \
397 1.1 simonb mfmsr 5; \
398 1.1 simonb ori 5,5,(PSL_IR|PSL_DR); \
399 1.1 simonb mtmsr 5; \
400 1.1 simonb isync
401 1.1 simonb
402 1.1 simonb .globl _C_LABEL(extint_call)
403 1.1 simonb extintr:
404 1.1 simonb INTRENTER
405 1.1 simonb _C_LABEL(extint_call):
406 1.1 simonb bl _C_LABEL(extint_call) /* to be filled in later */
407 1.1 simonb
408 1.1 simonb intr_exit:
409 1.1 simonb /* Disable interrupts (should already be disabled) and MMU here: */
410 1.1 simonb wrteei 0
411 1.1 simonb isync
412 1.1 simonb lwz 3,88(1)
413 1.1 simonb lwz 4,8(1) /* Load srr1 */
414 1.1 simonb bl _C_LABEL(ctx_setup) /* Get proper ctx */
415 1.1 simonb mfmsr 5
416 1.1 simonb lis 4,(PSL_EE|PSL_DR|PSL_IR)@h
417 1.1 simonb ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l
418 1.1 simonb andc 5,5,4
419 1.1 simonb mtmsr 5
420 1.1 simonb isync
421 1.1 simonb mtpid 3 /* Load CTX */
422 1.1 simonb
423 1.1 simonb /* restore possibly overwritten registers: */
424 1.1 simonb lwz 12,44(1)
425 1.1 simonb lwz 11,48(1)
426 1.1 simonb lwz 10,52(1)
427 1.1 simonb lwz 9,56(1)
428 1.1 simonb lwz 8,60(1)
429 1.1 simonb lwz 7,64(1)
430 1.1 simonb lwz 6,8(1)
431 1.1 simonb lwz 5,12(1)
432 1.1 simonb lwz 4,28(1)
433 1.1 simonb lwz 3,32(1)
434 1.1 simonb mtsrr1 6
435 1.1 simonb mtsrr0 5
436 1.1 simonb mtctr 4
437 1.1 simonb mtxer 3
438 1.1 simonb /* Returning to user mode? */
439 1.1 simonb mtcr 6 /* saved SRR1 */
440 1.1 simonb bc 4,17,1f /* branch if PSL_PR is false */
441 1.1 simonb
442 1.1 simonb #if defined(MULTIPROCESSOR)
443 1.1 simonb lwz 4,CI_ASTPENDING(4) /* Test AST pending */
444 1.1 simonb #else
445 1.1 simonb lis 3,_C_LABEL(astpending)@ha /* Test AST pending */
446 1.1 simonb lwz 4,_C_LABEL(astpending)@l(3)
447 1.1 simonb #endif
448 1.1 simonb andi. 4,4,1
449 1.1 simonb beq 1f
450 1.1 simonb /* Setup for entry to realtrap: */
451 1.1 simonb lwz 3,0(1) /* get saved SP */
452 1.1 simonb mtsprg 1,3
453 1.1 simonb li 6,EXC_AST
454 1.1 simonb stmw 28,tempsave(0) /* establish tempsave again */
455 1.1 simonb mtlr 6
456 1.1 simonb lwz 28,40(1) /* saved LR */
457 1.1 simonb lwz 29,36(1) /* saved CR */
458 1.1 simonb lwz 6,68(1)
459 1.1 simonb lwz 5,72(1)
460 1.1 simonb lwz 4,76(1)
461 1.1 simonb lwz 3,80(1)
462 1.1 simonb lwz 0,84(1)
463 1.1 simonb lis 30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
464 1.1 simonb lwz 31,_C_LABEL(intr_depth)@l(30)
465 1.1 simonb addi 31,31,-1
466 1.1 simonb stw 31,_C_LABEL(intr_depth)@l(30)
467 1.1 simonb b realtrap
468 1.1 simonb 1:
469 1.1 simonb /* Here is the normal exit of extintr: */
470 1.1 simonb lwz 5,36(1)
471 1.1 simonb lwz 6,40(1)
472 1.1 simonb mtcr 5
473 1.1 simonb mtlr 6
474 1.1 simonb lwz 6,68(1)
475 1.1 simonb lwz 5,72(1)
476 1.1 simonb lis 3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
477 1.1 simonb lwz 4,_C_LABEL(intr_depth)@l(3)
478 1.1 simonb addi 4,4,-1
479 1.1 simonb stw 4,_C_LABEL(intr_depth)@l(3)
480 1.1 simonb lwz 4,76(1)
481 1.1 simonb lwz 3,80(1)
482 1.1 simonb lwz 0,84(1)
483 1.1 simonb lwz 1,0(1)
484 1.1 simonb rfi
485 1.1 simonb ba . /* Protect against prefetch */
486 1.1 simonb
487 1.1 simonb /*
488 1.1 simonb * PIT interrupt handler.
489 1.1 simonb */
490 1.1 simonb .align 5
491 1.1 simonb _C_LABEL(pitint):
492 1.1 simonb mtsprg 1,1 /* save SP */
493 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
494 1.1 simonb mflr 28 /* save LR */
495 1.1 simonb mfcr 29 /* save CR */
496 1.1 simonb mfxer 30 /* save XER */
497 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
498 1.1 simonb addi 1,1,intstk+INTSTK@l
499 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
500 1.1 simonb addic. 31,31,1
501 1.1 simonb stw 31,0(1)
502 1.1 simonb beq 1f
503 1.1 simonb mfsprg 1,1 /* yes, get old SP */
504 1.1 simonb 1:
505 1.1 simonb INTRENTER
506 1.1 simonb addi 3,1,8 /* intr frame */
507 1.1 simonb bl _C_LABEL(decr_intr)
508 1.1 simonb b intr_exit
509 1.1 simonb
510 1.1 simonb /*
511 1.1 simonb * FIT interrupt handler.
512 1.1 simonb */
513 1.1 simonb .align 5
514 1.1 simonb fitint:
515 1.1 simonb mtsprg 1,1 /* save SP */
516 1.1 simonb stmw 28,tempsave(0) /* free r28-r31 */
517 1.1 simonb mflr 28 /* save LR */
518 1.1 simonb mfcr 29 /* save CR */
519 1.1 simonb mfxer 30 /* save XER */
520 1.1 simonb lis 1,intstk+INTSTK@ha /* get interrupt stack */
521 1.1 simonb addi 1,1,intstk+INTSTK@l
522 1.1 simonb lwz 31,0(1) /* were we already running on intstk? */
523 1.1 simonb addic. 31,31,1
524 1.1 simonb stw 31,0(1)
525 1.1 simonb beq 1f
526 1.1 simonb mfsprg 1,1 /* yes, get old SP */
527 1.1 simonb 1:
528 1.1 simonb INTRENTER
529 1.1 simonb addi 3,1,8 /* intr frame */
530 1.1 simonb bl _C_LABEL(stat_intr)
531 1.1 simonb b intr_exit
532 1.1 simonb
533 1.1 simonb #ifdef DDB
534 1.1 simonb /*
535 1.1 simonb * Deliberate entry to ddbtrap
536 1.1 simonb */
537 1.1 simonb .globl _C_LABEL(ddb_trap)
538 1.1 simonb _C_LABEL(ddb_trap):
539 1.1 simonb mtsprg 1,1
540 1.1 simonb mfmsr 3
541 1.1 simonb mtsrr1 3
542 1.1 simonb wrteei 0 /* disable interrupts */
543 1.1 simonb isync
544 1.1 simonb stmw 28,ddbsave(0)
545 1.1 simonb mflr 28
546 1.1 simonb li 29,EXC_BPT
547 1.1 simonb mtlr 29
548 1.1 simonb mfcr 29
549 1.1 simonb mtsrr0 28
550 1.1 simonb
551 1.1 simonb /*
552 1.1 simonb * Now the ddb trap catching code.
553 1.1 simonb */
554 1.1 simonb ddbtrap:
555 1.1 simonb FRAME_SETUP(ddbsave)
556 1.1 simonb /* Call C trap code: */
557 1.1 simonb addi 3,1,8
558 1.1 simonb bl _C_LABEL(ddb_trap_glue)
559 1.1 simonb or. 3,3,3
560 1.1 simonb bne ddbleave
561 1.1 simonb /* This wasn't for DDB, so switch to real trap: */
562 1.1 simonb lwz 3,FRAME_EXC+8(1) /* save exception */
563 1.1 simonb stw 3,ddbsave+12(0)
564 1.1 simonb FRAME_LEAVE(ddbsave)
565 1.1 simonb mtsprg 1,1 /* prepare for entrance to realtrap */
566 1.1 simonb stmw 28,tempsave(0)
567 1.1 simonb mflr 28
568 1.1 simonb mfcr 29
569 1.1 simonb lwz 31,ddbsave+12(0)
570 1.1 simonb mtlr 31
571 1.1 simonb b realtrap
572 1.1 simonb ddbleave:
573 1.1 simonb FRAME_LEAVE(ddbsave)
574 1.1 simonb rfi
575 1.1 simonb ba . /* Protect against prefetch */
576 1.1 simonb #endif /* DDB */
577 1.1 simonb
578 1.1 simonb #ifdef IPKDB
579 1.1 simonb /*
580 1.1 simonb * Deliberate entry to ipkdbtrap
581 1.1 simonb */
582 1.1 simonb .globl _C_LABEL(ipkdb_trap)
583 1.1 simonb _C_LABEL(ipkdb_trap):
584 1.1 simonb mtsprg 1,1
585 1.1 simonb mfmsr 3
586 1.1 simonb mtsrr1 3
587 1.1 simonb wrteei 0 /* disable interrupts */
588 1.1 simonb isync
589 1.1 simonb stmw 28,ipkdbsave(0)
590 1.1 simonb mflr 28
591 1.1 simonb li 29,EXC_BPT
592 1.1 simonb mtlr 29
593 1.1 simonb mfcr 29
594 1.1 simonb mtsrr0 28
595 1.1 simonb
596 1.1 simonb /*
597 1.1 simonb * Now the ipkdb trap catching code.
598 1.1 simonb */
599 1.1 simonb ipkdbtrap:
600 1.1 simonb FRAME_SETUP(ipkdbsave)
601 1.1 simonb /* Call C trap code: */
602 1.1 simonb addi 3,1,8
603 1.1 simonb bl _C_LABEL(ipkdb_trap_glue)
604 1.1 simonb or. 3,3,3
605 1.1 simonb bne ipkdbleave
606 1.1 simonb /* This wasn't for IPKDB, so switch to real trap: */
607 1.1 simonb lwz 3,FRAME_EXC+8(1) /* save exception */
608 1.1 simonb stw 3,ipkdbsave+8(0)
609 1.1 simonb FRAME_LEAVE(ipkdbsave)
610 1.1 simonb mtsprg 1,1 /* prepare for entrance to realtrap */
611 1.1 simonb stmw 28,tempsave(0)
612 1.1 simonb mflr 28
613 1.1 simonb mfcr 29
614 1.1 simonb lwz 31,ipkdbsave+8(0)
615 1.1 simonb mtlr 31
616 1.1 simonb b realtrap
617 1.1 simonb ipkdbleave:
618 1.1 simonb FRAME_LEAVE(ipkdbsave)
619 1.1 simonb rfi
620 1.1 simonb ba . /* Protect against prefetch */
621 1.1 simonb
622 1.1 simonb ipkdbfault:
623 1.1 simonb ba _ipkdbfault
624 1.1 simonb _ipkdbfault:
625 1.1 simonb mfsrr0 3
626 1.1 simonb addi 3,3,4
627 1.1 simonb mtsrr0 3
628 1.1 simonb li 3,-1
629 1.1 simonb rfi
630 1.1 simonb ba . /* Protect against prefetch */
631 1.1 simonb
632 1.1 simonb /*
633 1.1 simonb * int ipkdbfbyte(unsigned char *p)
634 1.1 simonb */
635 1.1 simonb .globl _C_LABEL(ipkdbfbyte)
636 1.1 simonb _C_LABEL(ipkdbfbyte):
637 1.1 simonb li 9,EXC_DSI /* establish new fault routine */
638 1.1 simonb lwz 5,0(9)
639 1.1 simonb lis 6,ipkdbfault@ha
640 1.1 simonb lwz 6,ipkdbfault@l(6)
641 1.1 simonb stw 6,0(9)
642 1.1 simonb #ifdef IPKDBUSERHACK
643 1.1 simonb #ifndef PPC_IBM4XX
644 1.1 simonb lis 8,_C_LABEL(ipkdbsr)@ha
645 1.1 simonb lwz 8,_C_LABEL(ipkdbsr)@l(8)
646 1.1 simonb mtsr USER_SR,8
647 1.1 simonb isync
648 1.1 simonb #endif
649 1.1 simonb #endif
650 1.1 simonb dcbst 0,9 /* flush data... */
651 1.1 simonb sync
652 1.1 simonb icbi 0,9 /* and instruction caches */
653 1.1 simonb lbz 3,0(3) /* fetch data */
654 1.1 simonb stw 5,0(9) /* restore previous fault handler */
655 1.1 simonb dcbst 0,9 /* and flush data... */
656 1.1 simonb sync
657 1.1 simonb icbi 0,9 /* and instruction caches */
658 1.1 simonb blr
659 1.1 simonb
660 1.1 simonb /*
661 1.1 simonb * int ipkdbsbyte(unsigned char *p, int c)
662 1.1 simonb */
663 1.1 simonb .globl _C_LABEL(ipkdbsbyte)
664 1.1 simonb _C_LABEL(ipkdbsbyte):
665 1.1 simonb li 9,EXC_DSI /* establish new fault routine */
666 1.1 simonb lwz 5,0(9)
667 1.1 simonb lis 6,ipkdbfault@ha
668 1.1 simonb lwz 6,ipkdbfault@l(6)
669 1.1 simonb stw 6,0(9)
670 1.1 simonb #ifdef IPKDBUSERHACK
671 1.1 simonb #ifndef PPC_IBM4XX
672 1.1 simonb lis 8,_C_LABEL(ipkdbsr)@ha
673 1.1 simonb lwz 8,_C_LABEL(ipkdbsr)@l(8)
674 1.1 simonb mtsr USER_SR,8
675 1.1 simonb isync
676 1.1 simonb #endif
677 1.1 simonb #endif
678 1.1 simonb dcbst 0,9 /* flush data... */
679 1.1 simonb sync
680 1.1 simonb icbi 0,9 /* and instruction caches */
681 1.1 simonb mr 6,3
682 1.1 simonb xor 3,3,3
683 1.1 simonb stb 4,0(6)
684 1.1 simonb dcbst 0,6 /* Now do appropriate flushes
685 1.1 simonb to data... */
686 1.1 simonb sync
687 1.1 simonb icbi 0,6 /* and instruction caches */
688 1.1 simonb stw 5,0(9) /* restore previous fault handler */
689 1.1 simonb dcbst 0,9 /* and flush data... */
690 1.1 simonb sync
691 1.1 simonb icbi 0,9 /* and instruction caches */
692 1.1 simonb blr
693 1.1 simonb #endif /* IPKDB */
694