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