Home | History | Annotate | Line # | Download | only in ibm4xx
trap_subr.S revision 1.5
      1 /*	$NetBSD: trap_subr.S,v 1.5 2002/08/02 03:46:42 chs Exp $	*/
      2 
      3 /*
      4  * Copyright 2001 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 /*
     39  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
     40  * Copyright (C) 1995, 1996 TooLs GmbH.
     41  * All rights reserved.
     42  *
     43  * Redistribution and use in source and binary forms, with or without
     44  * modification, are permitted provided that the following conditions
     45  * are met:
     46  * 1. Redistributions of source code must retain the above copyright
     47  *    notice, this list of conditions and the following disclaimer.
     48  * 2. Redistributions in binary form must reproduce the above copyright
     49  *    notice, this list of conditions and the following disclaimer in the
     50  *    documentation and/or other materials provided with the distribution.
     51  * 3. All advertising materials mentioning features or use of this software
     52  *    must display the following acknowledgement:
     53  *	This product includes software developed by TooLs GmbH.
     54  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     55  *    derived from this software without specific prior written permission.
     56  *
     57  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     58  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     59  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     60  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     61  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     62  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     63  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     64  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     65  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     66  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     67  */
     68 
     69 /*
     70  * NOTICE: This is not a standalone file.  to use it, #include it in
     71  * your port's locore.S, like so:
     72  *
     73  *	#include <powerpc/ibm4xx/trap_subr.S>
     74  */
     75 
     76 /*
     77  * Data used during primary/secondary traps/interrupts
     78  */
     79 #define	tempsave	0x2e0	/* primary save area for trap handling */
     80 #define	disisave	0x3e0	/* primary save area for dsi/isi traps */
     81 #define	exitsave	0x4e0	/* use this so trap return does not conflict */
     82 /*
     83  * XXX Interrupt and spill stacks need to be per-CPU.
     84  */
     85 	.data
     86 	.align	4
     87 intstk:
     88 	.space	INTSTK		/* interrupt stack */
     89 
     90 GLOBAL(intr_depth)
     91 	.long	-1		/* in-use marker */
     92 
     93 	.comm	spillstk,SPILLSTK,8
     94 
     95 #if defined(MULTIPROCESSOR)
     96 #define	GET_PCB(rX)	\
     97 	GET_CPUINFO(rX);	\
     98 	lwz	rX,CI_CURPCB(rX)
     99 #else
    100 #define GET_PCB(x)	\
    101 	lis	1,_C_LABEL(curpcb)@ha; \
    102 	lwz	1,_C_LABEL(curpcb)@l(1)
    103 #endif
    104 
    105 #define	STANDARD_PROLOG(savearea)	\
    106 	mtsprg	1,1;			/* save SP */ 		\
    107 	stmw	28,savearea(0);		/* free r28-r31 */	\
    108 	mflr	28;			/* save LR */		\
    109 	mfcr	29;			/* save CR */		\
    110 	mfsrr1	31; /* Test whether we already had PR set */	\
    111 	mtcr	31;						\
    112 	bc	4,17,1f;	/* branch if PSL_PR is clear */	\
    113 	GET_PCB(1);						\
    114 	addi	1,1,USPACE;	/* stack is top of user struct */ \
    115 1:
    116 
    117 #define	CRITICAL_PROLOG(savearea)	\
    118 	mtsprg	1,1;			/* save SP */ 		\
    119 	stmw	28,savearea(0);		/* free r28-r31 */	\
    120 	mflr	28;			/* save LR */		\
    121 	mfcr	29;			/* save CR */		\
    122 	mfsrr2	30; /* Fake a standard trap */			\
    123 	mtsrr0	30;						\
    124 	mfsrr3	31; /* Test whether we already had PR set */	\
    125 	mtsrr1	31;						\
    126 	mtcr	31;						\
    127 	bc	4,17,1f;	/* branch if PSL_PR is clear */	\
    128 	GET_PCB(1);						\
    129 	addi	1,1,USPACE;	/* stack is top of user struct */ \
    130 1:
    131 
    132 
    133 /* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */
    134 #define STANDARD_EXC_HANDLER(name)\
    135 	.globl	_C_LABEL(name ## trap),_C_LABEL(name ## size) ;	\
    136 _C_LABEL(name ## trap):						\
    137 	STANDARD_PROLOG(tempsave);				\
    138 	bla	s_trap  ;					\
    139 _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
    140 
    141 /* Access exceptions also need DEAR and ESR saved */
    142 #define ACCESS_EXC_HANDLER(name)\
    143 	.globl	_C_LABEL(name ## trap),_C_LABEL(name ## size) ;	\
    144 _C_LABEL(name ## trap):						\
    145 	STANDARD_PROLOG(tempsave);				\
    146 	mfdear	30;						\
    147 	mfesr	31;						\
    148 	stmw	30,16+tempsave(0);				\
    149 	bla	s_trap  ;					\
    150 _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
    151 
    152 /* Maybe this should call ddb.... */
    153 #define CRITICAL_EXC_HANDLER(name)\
    154 	.globl	_C_LABEL(name ## trap),_C_LABEL(name ## size) ;	\
    155 _C_LABEL(name ## trap):						\
    156 	CRITICAL_PROLOG(tempsave);				\
    157 	bla	s_trap  ;					\
    158 _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
    159 
    160 /*
    161  * This code gets copied to all the trap vectors
    162  * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
    163  * traps when using IPKDB).
    164  */
    165 	.text
    166 	STANDARD_EXC_HANDLER(default)
    167 	ACCESS_EXC_HANDLER(ali)
    168 	ACCESS_EXC_HANDLER(dsi)
    169 	ACCESS_EXC_HANDLER(isi)
    170 	STANDARD_EXC_HANDLER(debug)
    171 	CRITICAL_EXC_HANDLER(mchk)
    172 
    173 /*
    174  * This one for the external interrupt handler.
    175  */
    176 	.globl	_C_LABEL(extint),_C_LABEL(extsize)
    177 _C_LABEL(extint):
    178 	mtsprg	1,1			/* save SP */
    179 	stmw	28,tempsave(0)		/* free r28-r31 */
    180 	mflr	28			/* save LR */
    181 	mfcr	29			/* save CR */
    182 	mfxer	30			/* save XER */
    183 	lis	1,intstk+INTSTK@ha	/* get interrupt stack */
    184 	addi	1,1,intstk+INTSTK@l
    185 	lwz	31,0(1)			/* were we already running on intstk? */
    186 	addic.	31,31,1
    187 	stw	31,0(1)
    188 	beq	1f
    189 	mfsprg	1,1			/* yes, get old SP */
    190 1:
    191 	ba	extintr
    192 _C_LABEL(extsize) = .-_C_LABEL(extint)
    193 
    194 
    195 #ifdef DDB
    196 #define	ddbsave	0xde0		/* primary save area for DDB */
    197 /*
    198  * In case of DDB we want a separate trap catcher for it
    199  */
    200 	.local	ddbstk
    201 	.comm	ddbstk,INTSTK,8		/* ddb stack */
    202 
    203 	.globl	_C_LABEL(ddblow),_C_LABEL(ddbsize)
    204 _C_LABEL(ddblow):
    205 	mtsprg	1,1			/* save SP */
    206 	stmw	28,ddbsave(0)		/* free r28-r31 */
    207 	mflr	28			/* save LR */
    208 	mfcr	29			/* save CR */
    209 	lis	1,ddbstk+INTSTK@ha	/* get new SP */
    210 	addi	1,1,ddbstk+INTSTK@l
    211 	bla	ddbtrap
    212 _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
    213 #endif	/* DDB */
    214 
    215 #ifdef IPKDB
    216 #define	ipkdbsave	0xde0		/* primary save area for IPKDB */
    217 /*
    218  * In case of IPKDB we want a separate trap catcher for it
    219  */
    220 
    221 	.local	ipkdbstk
    222 	.comm	ipkdbstk,INTSTK,8		/* ipkdb stack */
    223 
    224 	.globl	_C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
    225 _C_LABEL(ipkdblow):
    226 	mtsprg	1,1			/* save SP */
    227 	stmw	28,ipkdbsave(0)		/* free r28-r31 */
    228 	mflr	28			/* save LR */
    229 	mfcr	29			/* save CR */
    230 	lis	1,ipkdbstk+INTSTK@ha	/* get new SP */
    231 	addi	1,1,ipkdbstk+INTSTK@l
    232 	bla	ipkdbtrap
    233 _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
    234 #endif	/* IPKDB */
    235 
    236 #ifdef DEBUG
    237 #define TRAP_IF_ZERO(r)	tweqi	r,0
    238 #else
    239 #define TRAP_IF_ZERO(r)
    240 #endif
    241 
    242 /*
    243  * FRAME_SETUP assumes:
    244  *	SPRG1		SP (1)
    245  *	savearea	r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps)
    246  *	28		LR
    247  *	29		CR
    248  *	1		kernel stack
    249  *	LR		trap type
    250  *	SRR0/1		as at start of trap
    251  */
    252 #define	FRAME_SETUP(savearea)						\
    253 /* Have to enable translation to allow access of kernel stack: */	\
    254 	mfsrr0	30;							\
    255 	mfsrr1	31;							\
    256 	stmw	30,savearea+24(0);					\
    257 	mfpid	30;							\
    258 	li	31,KERNEL_PID;						\
    259 	mtpid	31;							\
    260 	mfmsr	31;							\
    261 	ori	31,31,(PSL_DR|PSL_IR)@l;				\
    262 	mtmsr	31;							\
    263 	isync;								\
    264 	mfsprg	31,1;							\
    265 	stwu	31,-FRAMELEN(1);					\
    266 	stw	30,FRAME_PID+8(1);					\
    267 	stw	0,FRAME_0+8(1);						\
    268 	stw	31,FRAME_1+8(1);					\
    269 	stw	28,FRAME_LR+8(1);					\
    270 	stw	29,FRAME_CR+8(1);					\
    271 	lmw	28,savearea(0);						\
    272 	stmw	2,FRAME_2+8(1);						\
    273 	lmw	28,savearea+16(0);					\
    274 	mfxer	3;							\
    275 	mfctr	4;							\
    276 	mflr	5;							\
    277 	andi.	5,5,0xff00;						\
    278 	stw	3,FRAME_XER+8(1);					\
    279 	stw	4,FRAME_CTR+8(1);					\
    280 	stw	5,FRAME_EXC+8(1);					\
    281 	stw	28,FRAME_DEAR+8(1);					\
    282 	stw	29,FRAME_ESR+8(1);					\
    283 	stw	30,FRAME_SRR0+8(1);					\
    284 	stw	31,FRAME_SRR1+8(1)
    285 
    286 #define	FRAME_LEAVE(savearea)						\
    287 /* Now restore regs: */							\
    288 	lwz	3,FRAME_PID+8(1);					\
    289 	lwz	4,FRAME_SRR1+8(1);					\
    290 	bl	_C_LABEL(ctx_setup);					\
    291 	TRAP_IF_ZERO(r3);						\
    292 	stw	3,FRAME_PID+8(1);					\
    293 	lmw	26,FRAME_LR+8(1);					\
    294 	mtlr	26;							\
    295 	mtcr	27;							\
    296 	mtxer	28;							\
    297 	mtctr	29;							\
    298 	mtsrr0	30;							\
    299 	mtsrr1	31;							\
    300 	lmw	2,FRAME_2+8(1);						\
    301 	lwz	0,FRAME_0+8(1);						\
    302 	stmw	29,savearea(0);						\
    303 	lwz	30,FRAME_PID+8(1);					\
    304 	lwz	1,FRAME_1+8(1);						\
    305 	mfmsr	31;							\
    306 	li	29,(PSL_DR|PSL_IR)@l;					\
    307 	andc	31,31,29;						\
    308 	mfcr	29;							\
    309 	mtcr	29;							\
    310 	mtmsr	31;							\
    311 	isync;								\
    312 	TRAP_IF_ZERO(r30);						\
    313 	mtpid	30;							\
    314 	lmw	29,savearea(0)
    315 
    316 realtrap:	/* entry point after IPKDB is done with exception */
    317 	/* Test whether we already had PR set */
    318 	mfsrr1	1
    319 	mtcr	1
    320 	mfsprg	1,1			/* restore SP (might have been
    321 					   overwritten) */
    322 	bc	4,17,s_trap		/* branch if PSL_PR is false */
    323 	lis	1,_C_LABEL(curpcb)@ha
    324 	lwz	1,_C_LABEL(curpcb)@l(1)
    325 	addi	1,1,USPACE		/* stack is top of user struct */
    326 /*
    327  * Now the common trap catching code.
    328  */
    329 s_trap:
    330 	FRAME_SETUP(tempsave)
    331 /* Now we can recover interrupts again: */
    332 trapagain:
    333 	wrteei	1			/* Enable interrupts */
    334 /* Call C trap code: */
    335 	addi	3,1,8
    336 	bl	_C_LABEL(trap)
    337 	.globl	_C_LABEL(trapexit)
    338 _C_LABEL(trapexit):
    339 	/* Disable interrupts: */
    340 	wrteei	0
    341 	/* Test AST pending: */
    342 	lwz	5,FRAME_SRR1+8(1)
    343 	mtcr	5
    344 	bc	4,17,1f			/* branch if PSL_PR is false */
    345 #if defined(MULTIPROCESSOR)
    346 	GET_CPUINFO(3)
    347 	lwz	4,CI_ASTPENDING(3)
    348 #else
    349 	lis	3,_C_LABEL(astpending)@ha
    350 	lwz	4,_C_LABEL(astpending)@l(3)
    351 #endif
    352 	andi.	4,4,1
    353 	beq	1f
    354 	li	6,EXC_AST
    355 	stw	6,FRAME_EXC+8(1)
    356 	b	trapagain
    357 1:
    358 	FRAME_LEAVE(exitsave)
    359 	rfi
    360 	ba	.	/* Protect against prefetch */
    361 
    362 
    363 
    364 	.globl	_C_LABEL(sctrap),_C_LABEL(scsize)
    365 _C_LABEL(sctrap):
    366 	STANDARD_PROLOG(tempsave);
    367 	bla	s_sctrap
    368 _C_LABEL(scsize) = .-_C_LABEL(sctrap)
    369 
    370 s_sctrap:
    371 	FRAME_SETUP(tempsave)
    372 /* Now we can recover interrupts again: */
    373 	wrteei	1			/* Enable interrupts */
    374 /* Call the appropriate syscall handler: */
    375 	addi	3,1,8
    376 	lis	4,_C_LABEL(curproc)@ha
    377 	lwz	4,_C_LABEL(curproc)@l(4)
    378 	lwz	4,P_MD_SYSCALL@l(4)
    379 	mtctr	4
    380 	bctrl
    381 /* Disable interrupts: */
    382 	wrteei	0
    383 /* Test AST pending: */
    384 	lwz	5,FRAME_SRR1+8(1)
    385 	mtcr	5
    386 	bc	4,17,1f			/* branch if PSL_PR is false */
    387 #if defined(MULTIPROCESSOR)
    388 	GET_CPUINFO(3)
    389 	lwz	4,CI_ASTPENDING(3)
    390 #else
    391 	lis	3,_C_LABEL(astpending)@ha
    392 	lwz	4,_C_LABEL(astpending)@l(3)
    393 #endif
    394 	andi.	4,4,1
    395 	beq	1f
    396 	li	6,EXC_AST
    397 	stw	6,FRAME_EXC+8(1)
    398 	b	trapagain
    399 1:
    400 	FRAME_LEAVE(exitsave)
    401 	rfi
    402 	ba	.	/* Protect against prefetch */
    403 
    404 
    405 /*
    406  * External interrupt second level handler
    407  */
    408 
    409 #define	INTRENTER							\
    410 /* Save non-volatile registers: */					\
    411 	stwu	1,-92(1);		/* temporarily */		\
    412 	stw	0,84(1);						\
    413 	mfsprg	0,1;			/* get original SP */		\
    414 	stw	0,0(1);			/* and store it */		\
    415 	stw	3,80(1);						\
    416 	stw	4,76(1);						\
    417 	stw	5,72(1);						\
    418 	stw	6,68(1);						\
    419 	stw	7,64(1);						\
    420 	stw	8,60(1);						\
    421 	stw	9,56(1);						\
    422 	stw	10,52(1);						\
    423 	stw	11,48(1);						\
    424 	stw	12,44(1);						\
    425 	stw	28,40(1);		/* saved LR */			\
    426 	stw	29,36(1);		/* saved CR */			\
    427 	stw	30,32(1);		/* saved XER */			\
    428 	lmw	28,tempsave(0);		/* restore r28-r31 */		\
    429 	mfctr	6;							\
    430 	lis	5,_C_LABEL(intr_depth)@ha;				\
    431 	lwz	5,_C_LABEL(intr_depth)@l(5);				\
    432 	mfsrr0	4;							\
    433 	mfsrr1	3;							\
    434 	stw	6,28(1);						\
    435 	stw	5,20(1);						\
    436 	stw	4,12(1);						\
    437 	stw	3,8(1);							\
    438 	mfpid	0;			/* get currect PID register */  \
    439 	stw	0,88(1)	;						\
    440 	li	0, KERNEL_PID;						\
    441 	mtpid	0;							\
    442 /* interrupts are recoverable here, and enable translation */		\
    443 	mfmsr	5;							\
    444 	ori	5,5,(PSL_IR|PSL_DR);					\
    445 	mtmsr	5;							\
    446 	isync
    447 
    448 	.globl	_C_LABEL(extint_call)
    449 extintr:
    450 	INTRENTER
    451 _C_LABEL(extint_call):
    452 	bl	_C_LABEL(extint_call)	/* to be filled in later */
    453 
    454 intr_exit:
    455 /* Disable interrupts (should already be disabled) and MMU here: */
    456 	wrteei	0
    457 	isync
    458 	lwz	3,88(1)
    459 	lwz	4,8(1)			/* Load srr1 */
    460 	bl	_C_LABEL(ctx_setup)	/* Get proper ctx */
    461 	mfmsr	5
    462 	lis	4,(PSL_EE|PSL_DR|PSL_IR)@h
    463 	ori	4,4,(PSL_EE|PSL_DR|PSL_IR)@l
    464 	andc	5,5,4
    465 	mtmsr	5
    466 	isync
    467 	mtpid	3			/* Load CTX */
    468 
    469 /* restore possibly overwritten registers: */
    470 	lwz	12,44(1)
    471 	lwz	11,48(1)
    472 	lwz	10,52(1)
    473 	lwz	9,56(1)
    474 	lwz	8,60(1)
    475 	lwz	7,64(1)
    476 	lwz	6,8(1)
    477 	lwz	5,12(1)
    478 	lwz	4,28(1)
    479 	lwz	3,32(1)
    480 	mtsrr1	6
    481 	mtsrr0	5
    482 	mtctr	4
    483 	mtxer	3
    484 /* Returning to user mode? */
    485 	mtcr	6			/* saved SRR1 */
    486 	bc	4,17,1f			/* branch if PSL_PR is false */
    487 
    488 #if defined(MULTIPROCESSOR)
    489 	lwz	4,CI_ASTPENDING(4)	 /* Test AST pending */
    490 #else
    491 	lis	3,_C_LABEL(astpending)@ha /* Test AST pending */
    492 	lwz	4,_C_LABEL(astpending)@l(3)
    493 #endif
    494 	andi.	4,4,1
    495 	beq	1f
    496 /* Setup for entry to realtrap: */
    497 	lwz	3,0(1)			/* get saved SP */
    498 	mtsprg	1,3
    499 	li	6,EXC_AST
    500 	stmw	28,tempsave(0)		/* establish tempsave again */
    501 	mtlr	6
    502 	lwz	28,40(1)		/* saved LR */
    503 	lwz	29,36(1)		/* saved CR */
    504 	lwz	6,68(1)
    505 	lwz	5,72(1)
    506 	lwz	4,76(1)
    507 	lwz	3,80(1)
    508 	lwz	0,84(1)
    509 	lis	30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
    510 	lwz	31,_C_LABEL(intr_depth)@l(30)
    511 	addi	31,31,-1
    512 	stw	31,_C_LABEL(intr_depth)@l(30)
    513 	b	realtrap
    514 1:
    515 /* Here is the normal exit of extintr: */
    516 	lwz	5,36(1)
    517 	lwz	6,40(1)
    518 	mtcr	5
    519 	mtlr	6
    520 	lwz	6,68(1)
    521 	lwz	5,72(1)
    522 	lis	3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
    523 	lwz	4,_C_LABEL(intr_depth)@l(3)
    524 	addi	4,4,-1
    525 	stw	4,_C_LABEL(intr_depth)@l(3)
    526 	lwz	4,76(1)
    527 	lwz	3,80(1)
    528 	lwz	0,84(1)
    529 	lwz	1,0(1)
    530 	rfi
    531 	ba	.	/* Protect against prefetch */
    532 
    533 /*
    534  * PIT interrupt handler.
    535  */
    536 	.align	5
    537 _C_LABEL(pitint):
    538 	mtsprg	1,1			/* save SP */
    539 	stmw	28,tempsave(0)		/* free r28-r31 */
    540 	mflr	28			/* save LR */
    541 	mfcr	29			/* save CR */
    542 	mfxer	30			/* save XER */
    543 	lis	1,intstk+INTSTK@ha	/* get interrupt stack */
    544 	addi	1,1,intstk+INTSTK@l
    545 	lwz	31,0(1)			/* were we already running on intstk? */
    546 	addic.	31,31,1
    547 	stw	31,0(1)
    548 	beq	1f
    549 	mfsprg	1,1			/* yes, get old SP */
    550 1:
    551 	INTRENTER
    552 	addi	3,1,8			/* intr frame */
    553 	bl	_C_LABEL(decr_intr)
    554 	b	intr_exit
    555 
    556 /*
    557  * FIT interrupt handler.
    558  */
    559 	.align	5
    560 fitint:
    561 	mtsprg	1,1			/* save SP */
    562 	stmw	28,tempsave(0)		/* free r28-r31 */
    563 	mflr	28			/* save LR */
    564 	mfcr	29			/* save CR */
    565 	mfxer	30			/* save XER */
    566 	lis	1,intstk+INTSTK@ha	/* get interrupt stack */
    567 	addi	1,1,intstk+INTSTK@l
    568 	lwz	31,0(1)			/* were we already running on intstk? */
    569 	addic.	31,31,1
    570 	stw	31,0(1)
    571 	beq	1f
    572 	mfsprg	1,1			/* yes, get old SP */
    573 1:
    574 	INTRENTER
    575 	addi	3,1,8			/* intr frame */
    576 	bl	_C_LABEL(stat_intr)
    577 	b	intr_exit
    578 
    579 #ifdef DDB
    580 /*
    581  * Deliberate entry to ddbtrap
    582  */
    583 	.globl	_C_LABEL(ddb_trap)
    584 _C_LABEL(ddb_trap):
    585 	mtsprg	1,1
    586 	mfmsr	3
    587 	mtsrr1	3
    588 	wrteei	0			/* disable interrupts */
    589 	isync
    590 	stmw	28,ddbsave(0)
    591 	mflr	28
    592 	li	29,EXC_BPT
    593 	mtlr	29
    594 	mfcr	29
    595 	mtsrr0	28
    596 
    597 /*
    598  * Now the ddb trap catching code.
    599  */
    600 ddbtrap:
    601 	FRAME_SETUP(ddbsave)
    602 /* Call C trap code: */
    603 	addi	3,1,8
    604 	bl	_C_LABEL(ddb_trap_glue)
    605 	or.	3,3,3
    606 	bne	ddbleave
    607 /* This wasn't for DDB, so switch to real trap: */
    608 	lwz	3,FRAME_EXC+8(1)	/* save exception */
    609 	stw	3,ddbsave+12(0)
    610 	FRAME_LEAVE(ddbsave)
    611 	mtsprg	1,1			/* prepare for entrance to realtrap */
    612 	stmw	28,tempsave(0)
    613 	mflr	28
    614 	mfcr	29
    615 	lwz	31,ddbsave+12(0)
    616 	mtlr	31
    617 	b	realtrap
    618 ddbleave:
    619 	FRAME_LEAVE(ddbsave)
    620 	rfi
    621 	ba	.	/* Protect against prefetch */
    622 #endif /* DDB */
    623 
    624 #ifdef IPKDB
    625 /*
    626  * Deliberate entry to ipkdbtrap
    627  */
    628 	.globl	_C_LABEL(ipkdb_trap)
    629 _C_LABEL(ipkdb_trap):
    630 	mtsprg	1,1
    631 	mfmsr	3
    632 	mtsrr1	3
    633 	wrteei	0			/* disable interrupts */
    634 	isync
    635 	stmw	28,ipkdbsave(0)
    636 	mflr	28
    637 	li	29,EXC_BPT
    638 	mtlr	29
    639 	mfcr	29
    640 	mtsrr0	28
    641 
    642 /*
    643  * Now the ipkdb trap catching code.
    644  */
    645 ipkdbtrap:
    646 	FRAME_SETUP(ipkdbsave)
    647 /* Call C trap code: */
    648 	addi	3,1,8
    649 	bl	_C_LABEL(ipkdb_trap_glue)
    650 	or.	3,3,3
    651 	bne	ipkdbleave
    652 /* This wasn't for IPKDB, so switch to real trap: */
    653 	lwz	3,FRAME_EXC+8(1)	/* save exception */
    654 	stw	3,ipkdbsave+8(0)
    655 	FRAME_LEAVE(ipkdbsave)
    656 	mtsprg	1,1			/* prepare for entrance to realtrap */
    657 	stmw	28,tempsave(0)
    658 	mflr	28
    659 	mfcr	29
    660 	lwz	31,ipkdbsave+8(0)
    661 	mtlr	31
    662 	b	realtrap
    663 ipkdbleave:
    664 	FRAME_LEAVE(ipkdbsave)
    665 	rfi
    666 	ba	.	/* Protect against prefetch */
    667 
    668 ipkdbfault:
    669 	ba	_ipkdbfault
    670 _ipkdbfault:
    671 	mfsrr0	3
    672 	addi	3,3,4
    673 	mtsrr0	3
    674 	li	3,-1
    675 	rfi
    676 	ba	.	/* Protect against prefetch */
    677 
    678 /*
    679  * int ipkdbfbyte(unsigned char *p)
    680  */
    681 	.globl	_C_LABEL(ipkdbfbyte)
    682 _C_LABEL(ipkdbfbyte):
    683 	li	9,EXC_DSI		/* establish new fault routine */
    684 	lwz	5,0(9)
    685 	lis	6,ipkdbfault@ha
    686 	lwz	6,ipkdbfault@l(6)
    687 	stw	6,0(9)
    688 #ifdef	IPKDBUSERHACK
    689 #ifndef PPC_IBM4XX
    690 	lis	8,_C_LABEL(ipkdbsr)@ha
    691 	lwz	8,_C_LABEL(ipkdbsr)@l(8)
    692 	mtsr	USER_SR,8
    693 	isync
    694 #endif
    695 #endif
    696 	dcbst	0,9			/* flush data... */
    697 	sync
    698 	icbi	0,9			/* and instruction caches */
    699 	lbz	3,0(3)			/* fetch data */
    700 	stw	5,0(9)			/* restore previous fault handler */
    701 	dcbst	0,9			/* and flush data... */
    702 	sync
    703 	icbi	0,9			/* and instruction caches */
    704 	blr
    705 
    706 /*
    707  * int ipkdbsbyte(unsigned char *p, int c)
    708  */
    709 	.globl	_C_LABEL(ipkdbsbyte)
    710 _C_LABEL(ipkdbsbyte):
    711 	li	9,EXC_DSI		/* establish new fault routine */
    712 	lwz	5,0(9)
    713 	lis	6,ipkdbfault@ha
    714 	lwz	6,ipkdbfault@l(6)
    715 	stw	6,0(9)
    716 #ifdef	IPKDBUSERHACK
    717 #ifndef PPC_IBM4XX
    718 	lis	8,_C_LABEL(ipkdbsr)@ha
    719 	lwz	8,_C_LABEL(ipkdbsr)@l(8)
    720 	mtsr	USER_SR,8
    721 	isync
    722 #endif
    723 #endif
    724 	dcbst	0,9			/* flush data... */
    725 	sync
    726 	icbi	0,9			/* and instruction caches */
    727 	mr	6,3
    728 	xor	3,3,3
    729 	stb	4,0(6)
    730 	dcbst	0,6			/* Now do appropriate flushes
    731 					   to data... */
    732 	sync
    733 	icbi	0,6			/* and instruction caches */
    734 	stw	5,0(9)			/* restore previous fault handler */
    735 	dcbst	0,9			/* and flush data... */
    736 	sync
    737 	icbi	0,9			/* and instruction caches */
    738 	blr
    739 #endif	/* IPKDB */
    740