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