trap_subr.S revision 1.2 1 /* $NetBSD: trap_subr.S,v 1.2 2001/06/17 13:38:33 simonb 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
172 /*
173 * This one for the external interrupt handler.
174 */
175 .globl _C_LABEL(extint),_C_LABEL(extsize)
176 _C_LABEL(extint):
177 mtsprg 1,1 /* save SP */
178 stmw 28,tempsave(0) /* free r28-r31 */
179 mflr 28 /* save LR */
180 mfcr 29 /* save CR */
181 mfxer 30 /* save XER */
182 lis 1,intstk+INTSTK@ha /* get interrupt stack */
183 addi 1,1,intstk+INTSTK@l
184 lwz 31,0(1) /* were we already running on intstk? */
185 addic. 31,31,1
186 stw 31,0(1)
187 beq 1f
188 mfsprg 1,1 /* yes, get old SP */
189 1:
190 ba extintr
191 _C_LABEL(extsize) = .-_C_LABEL(extint)
192
193
194 #ifdef DDB
195 #define ddbsave 0xde0 /* primary save area for DDB */
196 /*
197 * In case of DDB we want a separate trap catcher for it
198 */
199 .local ddbstk
200 .comm ddbstk,INTSTK,8 /* ddb stack */
201
202 .globl _C_LABEL(ddblow),_C_LABEL(ddbsize)
203 _C_LABEL(ddblow):
204 mtsprg 1,1 /* save SP */
205 stmw 28,ddbsave(0) /* free r28-r31 */
206 mflr 28 /* save LR */
207 mfcr 29 /* save CR */
208 lis 1,ddbstk+INTSTK@ha /* get new SP */
209 addi 1,1,ddbstk+INTSTK@l
210 bla ddbtrap
211 _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
212 #endif /* DDB */
213
214 #ifdef IPKDB
215 #define ipkdbsave 0xde0 /* primary save area for IPKDB */
216 /*
217 * In case of IPKDB we want a separate trap catcher for it
218 */
219
220 .local ipkdbstk
221 .comm ipkdbstk,INTSTK,8 /* ipkdb stack */
222
223 .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
224 _C_LABEL(ipkdblow):
225 mtsprg 1,1 /* save SP */
226 stmw 28,ipkdbsave(0) /* free r28-r31 */
227 mflr 28 /* save LR */
228 mfcr 29 /* save CR */
229 lis 1,ipkdbstk+INTSTK@ha /* get new SP */
230 addi 1,1,ipkdbstk+INTSTK@l
231 bla ipkdbtrap
232 _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
233 #endif /* IPKDB */
234
235 #ifdef DEBUG
236 #define TRAP_IF_ZERO(r) tweqi r,0
237 #else
238 #define TRAP_IF_ZERO(r)
239 #endif
240
241 /*
242 * FRAME_SETUP assumes:
243 * SPRG1 SP (1)
244 * savearea r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps)
245 * 28 LR
246 * 29 CR
247 * 1 kernel stack
248 * LR trap type
249 * SRR0/1 as at start of trap
250 */
251 #define FRAME_SETUP(savearea) \
252 /* Have to enable translation to allow access of kernel stack: */ \
253 mfsrr0 30; \
254 mfsrr1 31; \
255 stmw 30,savearea+24(0); \
256 mfpid 30; \
257 li 31,KERNEL_PID; \
258 mtpid 31; \
259 mfmsr 31; \
260 ori 31,31,(PSL_DR|PSL_IR)@l; \
261 mtmsr 31; \
262 isync; \
263 mfsprg 31,1; \
264 stwu 31,-FRAMELEN(1); \
265 stw 30,FRAME_PID+8(1); \
266 stw 0,FRAME_0+8(1); \
267 stw 31,FRAME_1+8(1); \
268 stw 28,FRAME_LR+8(1); \
269 stw 29,FRAME_CR+8(1); \
270 lmw 28,savearea(0); \
271 stmw 2,FRAME_2+8(1); \
272 lmw 28,savearea+16(0); \
273 mfxer 3; \
274 mfctr 4; \
275 mflr 5; \
276 andi. 5,5,0xff00; \
277 stw 3,FRAME_XER+8(1); \
278 stw 4,FRAME_CTR+8(1); \
279 stw 5,FRAME_EXC+8(1); \
280 stw 28,FRAME_DEAR+8(1); \
281 stw 29,FRAME_ESR+8(1); \
282 stw 30,FRAME_SRR0+8(1); \
283 stw 31,FRAME_SRR1+8(1)
284
285 #define FRAME_LEAVE(savearea) \
286 /* Now restore regs: */ \
287 lwz 3,FRAME_PID+8(1); \
288 lwz 4,FRAME_SRR1+8(1); \
289 bl _C_LABEL(ctx_setup); \
290 TRAP_IF_ZERO(r3); \
291 stw 3,FRAME_PID+8(1); \
292 lmw 26,FRAME_LR+8(1); \
293 mtlr 26; \
294 mtcr 27; \
295 mtxer 28; \
296 mtctr 29; \
297 mtsrr0 30; \
298 mtsrr1 31; \
299 lmw 2,FRAME_2+8(1); \
300 lwz 0,FRAME_0+8(1); \
301 stmw 29,savearea(0); \
302 lwz 30,FRAME_PID+8(1); \
303 lwz 1,FRAME_1+8(1); \
304 mfmsr 31; \
305 li 29,(PSL_DR|PSL_IR)@l; \
306 andc 31,31,29; \
307 mfcr 29; \
308 mtcr 29; \
309 mtmsr 31; \
310 isync; \
311 TRAP_IF_ZERO(r30); \
312 mtpid 30; \
313 lmw 29,savearea(0)
314
315 realtrap: /* entry point after IPKDB is done with exception */
316 /* Test whether we already had PR set */
317 mfsrr1 1
318 mtcr 1
319 mfsprg 1,1 /* restore SP (might have been
320 overwritten) */
321 bc 4,17,s_trap /* branch if PSL_PR is false */
322 lis 1,_C_LABEL(curpcb)@ha
323 lwz 1,_C_LABEL(curpcb)@l(1)
324 addi 1,1,USPACE /* stack is top of user struct */
325 /*
326 * Now the common trap catching code.
327 */
328 s_trap:
329 FRAME_SETUP(tempsave)
330 /* Now we can recover interrupts again: */
331 trapagain:
332 wrteei 1 /* Enable interrupts */
333 /* Call C trap code: */
334 addi 3,1,8
335 bl _C_LABEL(trap)
336 .globl _C_LABEL(trapexit)
337 _C_LABEL(trapexit):
338 /* Disable interrupts: */
339 wrteei 0
340 /* Test AST pending: */
341 lwz 5,FRAME_SRR1+8(1)
342 mtcr 5
343 bc 4,17,1f /* branch if PSL_PR is false */
344 #if defined(MULTIPROCESSOR)
345 GET_CPUINFO(3)
346 lwz 4,CI_ASTPENDING(3)
347 #else
348 lis 3,_C_LABEL(astpending)@ha
349 lwz 4,_C_LABEL(astpending)@l(3)
350 #endif
351 andi. 4,4,1
352 beq 1f
353 li 6,EXC_AST
354 stw 6,FRAME_EXC+8(1)
355 b trapagain
356 1:
357 FRAME_LEAVE(exitsave)
358 rfi
359 ba . /* Protect against prefetch */
360 /*
361 * External interrupt second level handler
362 */
363
364 #define INTRENTER \
365 /* Save non-volatile registers: */ \
366 stwu 1,-92(1); /* temporarily */ \
367 stw 0,84(1); \
368 mfsprg 0,1; /* get original SP */ \
369 stw 0,0(1); /* and store it */ \
370 stw 3,80(1); \
371 stw 4,76(1); \
372 stw 5,72(1); \
373 stw 6,68(1); \
374 stw 7,64(1); \
375 stw 8,60(1); \
376 stw 9,56(1); \
377 stw 10,52(1); \
378 stw 11,48(1); \
379 stw 12,44(1); \
380 stw 28,40(1); /* saved LR */ \
381 stw 29,36(1); /* saved CR */ \
382 stw 30,32(1); /* saved XER */ \
383 lmw 28,tempsave(0); /* restore r28-r31 */ \
384 mfctr 6; \
385 lis 5,_C_LABEL(intr_depth)@ha; \
386 lwz 5,_C_LABEL(intr_depth)@l(5); \
387 mfsrr0 4; \
388 mfsrr1 3; \
389 stw 6,28(1); \
390 stw 5,20(1); \
391 stw 4,12(1); \
392 stw 3,8(1); \
393 mfpid 0; /* get currect PID register */ \
394 stw 0,88(1) ; \
395 li 0, KERNEL_PID; \
396 mtpid 0; \
397 /* interrupts are recoverable here, and enable translation */ \
398 mfmsr 5; \
399 ori 5,5,(PSL_IR|PSL_DR); \
400 mtmsr 5; \
401 isync
402
403 .globl _C_LABEL(extint_call)
404 extintr:
405 INTRENTER
406 _C_LABEL(extint_call):
407 bl _C_LABEL(extint_call) /* to be filled in later */
408
409 intr_exit:
410 /* Disable interrupts (should already be disabled) and MMU here: */
411 wrteei 0
412 isync
413 lwz 3,88(1)
414 lwz 4,8(1) /* Load srr1 */
415 bl _C_LABEL(ctx_setup) /* Get proper ctx */
416 mfmsr 5
417 lis 4,(PSL_EE|PSL_DR|PSL_IR)@h
418 ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l
419 andc 5,5,4
420 mtmsr 5
421 isync
422 mtpid 3 /* Load CTX */
423
424 /* restore possibly overwritten registers: */
425 lwz 12,44(1)
426 lwz 11,48(1)
427 lwz 10,52(1)
428 lwz 9,56(1)
429 lwz 8,60(1)
430 lwz 7,64(1)
431 lwz 6,8(1)
432 lwz 5,12(1)
433 lwz 4,28(1)
434 lwz 3,32(1)
435 mtsrr1 6
436 mtsrr0 5
437 mtctr 4
438 mtxer 3
439 /* Returning to user mode? */
440 mtcr 6 /* saved SRR1 */
441 bc 4,17,1f /* branch if PSL_PR is false */
442
443 #if defined(MULTIPROCESSOR)
444 lwz 4,CI_ASTPENDING(4) /* Test AST pending */
445 #else
446 lis 3,_C_LABEL(astpending)@ha /* Test AST pending */
447 lwz 4,_C_LABEL(astpending)@l(3)
448 #endif
449 andi. 4,4,1
450 beq 1f
451 /* Setup for entry to realtrap: */
452 lwz 3,0(1) /* get saved SP */
453 mtsprg 1,3
454 li 6,EXC_AST
455 stmw 28,tempsave(0) /* establish tempsave again */
456 mtlr 6
457 lwz 28,40(1) /* saved LR */
458 lwz 29,36(1) /* saved CR */
459 lwz 6,68(1)
460 lwz 5,72(1)
461 lwz 4,76(1)
462 lwz 3,80(1)
463 lwz 0,84(1)
464 lis 30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
465 lwz 31,_C_LABEL(intr_depth)@l(30)
466 addi 31,31,-1
467 stw 31,_C_LABEL(intr_depth)@l(30)
468 b realtrap
469 1:
470 /* Here is the normal exit of extintr: */
471 lwz 5,36(1)
472 lwz 6,40(1)
473 mtcr 5
474 mtlr 6
475 lwz 6,68(1)
476 lwz 5,72(1)
477 lis 3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
478 lwz 4,_C_LABEL(intr_depth)@l(3)
479 addi 4,4,-1
480 stw 4,_C_LABEL(intr_depth)@l(3)
481 lwz 4,76(1)
482 lwz 3,80(1)
483 lwz 0,84(1)
484 lwz 1,0(1)
485 rfi
486 ba . /* Protect against prefetch */
487
488 /*
489 * PIT interrupt handler.
490 */
491 .align 5
492 _C_LABEL(pitint):
493 mtsprg 1,1 /* save SP */
494 stmw 28,tempsave(0) /* free r28-r31 */
495 mflr 28 /* save LR */
496 mfcr 29 /* save CR */
497 mfxer 30 /* save XER */
498 lis 1,intstk+INTSTK@ha /* get interrupt stack */
499 addi 1,1,intstk+INTSTK@l
500 lwz 31,0(1) /* were we already running on intstk? */
501 addic. 31,31,1
502 stw 31,0(1)
503 beq 1f
504 mfsprg 1,1 /* yes, get old SP */
505 1:
506 INTRENTER
507 addi 3,1,8 /* intr frame */
508 bl _C_LABEL(decr_intr)
509 b intr_exit
510
511 /*
512 * FIT interrupt handler.
513 */
514 .align 5
515 fitint:
516 mtsprg 1,1 /* save SP */
517 stmw 28,tempsave(0) /* free r28-r31 */
518 mflr 28 /* save LR */
519 mfcr 29 /* save CR */
520 mfxer 30 /* save XER */
521 lis 1,intstk+INTSTK@ha /* get interrupt stack */
522 addi 1,1,intstk+INTSTK@l
523 lwz 31,0(1) /* were we already running on intstk? */
524 addic. 31,31,1
525 stw 31,0(1)
526 beq 1f
527 mfsprg 1,1 /* yes, get old SP */
528 1:
529 INTRENTER
530 addi 3,1,8 /* intr frame */
531 bl _C_LABEL(stat_intr)
532 b intr_exit
533
534 #ifdef DDB
535 /*
536 * Deliberate entry to ddbtrap
537 */
538 .globl _C_LABEL(ddb_trap)
539 _C_LABEL(ddb_trap):
540 mtsprg 1,1
541 mfmsr 3
542 mtsrr1 3
543 wrteei 0 /* disable interrupts */
544 isync
545 stmw 28,ddbsave(0)
546 mflr 28
547 li 29,EXC_BPT
548 mtlr 29
549 mfcr 29
550 mtsrr0 28
551
552 /*
553 * Now the ddb trap catching code.
554 */
555 ddbtrap:
556 FRAME_SETUP(ddbsave)
557 /* Call C trap code: */
558 addi 3,1,8
559 bl _C_LABEL(ddb_trap_glue)
560 or. 3,3,3
561 bne ddbleave
562 /* This wasn't for DDB, so switch to real trap: */
563 lwz 3,FRAME_EXC+8(1) /* save exception */
564 stw 3,ddbsave+12(0)
565 FRAME_LEAVE(ddbsave)
566 mtsprg 1,1 /* prepare for entrance to realtrap */
567 stmw 28,tempsave(0)
568 mflr 28
569 mfcr 29
570 lwz 31,ddbsave+12(0)
571 mtlr 31
572 b realtrap
573 ddbleave:
574 FRAME_LEAVE(ddbsave)
575 rfi
576 ba . /* Protect against prefetch */
577 #endif /* DDB */
578
579 #ifdef IPKDB
580 /*
581 * Deliberate entry to ipkdbtrap
582 */
583 .globl _C_LABEL(ipkdb_trap)
584 _C_LABEL(ipkdb_trap):
585 mtsprg 1,1
586 mfmsr 3
587 mtsrr1 3
588 wrteei 0 /* disable interrupts */
589 isync
590 stmw 28,ipkdbsave(0)
591 mflr 28
592 li 29,EXC_BPT
593 mtlr 29
594 mfcr 29
595 mtsrr0 28
596
597 /*
598 * Now the ipkdb trap catching code.
599 */
600 ipkdbtrap:
601 FRAME_SETUP(ipkdbsave)
602 /* Call C trap code: */
603 addi 3,1,8
604 bl _C_LABEL(ipkdb_trap_glue)
605 or. 3,3,3
606 bne ipkdbleave
607 /* This wasn't for IPKDB, so switch to real trap: */
608 lwz 3,FRAME_EXC+8(1) /* save exception */
609 stw 3,ipkdbsave+8(0)
610 FRAME_LEAVE(ipkdbsave)
611 mtsprg 1,1 /* prepare for entrance to realtrap */
612 stmw 28,tempsave(0)
613 mflr 28
614 mfcr 29
615 lwz 31,ipkdbsave+8(0)
616 mtlr 31
617 b realtrap
618 ipkdbleave:
619 FRAME_LEAVE(ipkdbsave)
620 rfi
621 ba . /* Protect against prefetch */
622
623 ipkdbfault:
624 ba _ipkdbfault
625 _ipkdbfault:
626 mfsrr0 3
627 addi 3,3,4
628 mtsrr0 3
629 li 3,-1
630 rfi
631 ba . /* Protect against prefetch */
632
633 /*
634 * int ipkdbfbyte(unsigned char *p)
635 */
636 .globl _C_LABEL(ipkdbfbyte)
637 _C_LABEL(ipkdbfbyte):
638 li 9,EXC_DSI /* establish new fault routine */
639 lwz 5,0(9)
640 lis 6,ipkdbfault@ha
641 lwz 6,ipkdbfault@l(6)
642 stw 6,0(9)
643 #ifdef IPKDBUSERHACK
644 #ifndef PPC_IBM4XX
645 lis 8,_C_LABEL(ipkdbsr)@ha
646 lwz 8,_C_LABEL(ipkdbsr)@l(8)
647 mtsr USER_SR,8
648 isync
649 #endif
650 #endif
651 dcbst 0,9 /* flush data... */
652 sync
653 icbi 0,9 /* and instruction caches */
654 lbz 3,0(3) /* fetch data */
655 stw 5,0(9) /* restore previous fault handler */
656 dcbst 0,9 /* and flush data... */
657 sync
658 icbi 0,9 /* and instruction caches */
659 blr
660
661 /*
662 * int ipkdbsbyte(unsigned char *p, int c)
663 */
664 .globl _C_LABEL(ipkdbsbyte)
665 _C_LABEL(ipkdbsbyte):
666 li 9,EXC_DSI /* establish new fault routine */
667 lwz 5,0(9)
668 lis 6,ipkdbfault@ha
669 lwz 6,ipkdbfault@l(6)
670 stw 6,0(9)
671 #ifdef IPKDBUSERHACK
672 #ifndef PPC_IBM4XX
673 lis 8,_C_LABEL(ipkdbsr)@ha
674 lwz 8,_C_LABEL(ipkdbsr)@l(8)
675 mtsr USER_SR,8
676 isync
677 #endif
678 #endif
679 dcbst 0,9 /* flush data... */
680 sync
681 icbi 0,9 /* and instruction caches */
682 mr 6,3
683 xor 3,3,3
684 stb 4,0(6)
685 dcbst 0,6 /* Now do appropriate flushes
686 to data... */
687 sync
688 icbi 0,6 /* and instruction caches */
689 stw 5,0(9) /* restore previous fault handler */
690 dcbst 0,9 /* and flush data... */
691 sync
692 icbi 0,9 /* and instruction caches */
693 blr
694 #endif /* IPKDB */
695