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