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