Home | History | Annotate | Line # | Download | only in ibm4xx
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