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