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