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