Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / powerpc / ibm4xx / trap_subr.S
blob142c875c1281e51aa43e34c8ca136091b5c5dbbd
1 /*      $NetBSD: trap_subr.S,v 1.10.38.1 2007/05/28 20:01:43 freza Exp $        */
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  */
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  */
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  */
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 */
83  * XXX Interrupt and spill stacks need to be per-CPU.
84  */
86 #define GET_PCB(rX)     \
87         GET_CPUINFO(rX);        \
88         lwz     rX,CI_CURPCB(rX)
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 */ \
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 */ \
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)
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)
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)
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)
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 */
176         ba      extintr
177 _C_LABEL(extsize) = .-_C_LABEL(extint)
180 #if defined(DDB) || defined(KGDB)
181 #define ddbsave 0xde0           /* primary save area for DDB */
183  * In case of DDB we want a separate trap catcher for it
184  */
185         .local  ddbstk
186         .comm   ddbstk,INTSTK,8         /* ddb stack */
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 */
200 #ifdef IPKDB
201 #define ipkdbsave       0xde0           /* primary save area for IPKDB */
203  * In case of IPKDB we want a separate trap catcher for it
204  */
206         .local  ipkdbstk
207         .comm   ipkdbstk,INTSTK,8               /* ipkdb stack */
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 */
221 #ifdef DEBUG
222 #define TRAP_IF_ZERO(r) tweqi   r,0
223 #else
224 #define TRAP_IF_ZERO(r)
225 #endif
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)
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)
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 */
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
337         FRAME_LEAVE(exitsave)
338         rfi
339         ba      .       /* Protect against prefetch */
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)
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
376         FRAME_LEAVE(exitsave)
377         rfi
378         ba      .       /* Protect against prefetch */
382  * External interrupt second level handler
383  */
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
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 */
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 */
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 */
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
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 */
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 */
518         INTRENTER
519         addi    3,1,8                   /* intr frame */
520         bl      _C_LABEL(decr_intr)
521         b       intr_exit
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 */
541         INTRENTER
542         addi    3,1,8                   /* intr frame */
543         bl      _C_LABEL(stat_intr)
544         b       intr_exit
546 #if defined(DDB) || defined(KGDB)
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
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 */
591 #ifdef IPKDB
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
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 */
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 */
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
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 */