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