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