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