Home | History | Annotate | Line # | Download | only in ibm4xx
trap_subr.S revision 1.7
      1 /*	$NetBSD: trap_subr.S,v 1.7 2003/02/02 20:43:23 matt 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 
     86 #define	GET_PCB(rX)	\
     87 	GET_CPUINFO(rX);	\
     88 	lwz	rX,CI_CURPCB(rX)
     89 
     90 #define	STANDARD_PROLOG(savearea)	\
     91 	mtsprg	1,1;			/* save SP */ 		\
     92 	stmw	28,savearea(0);		/* free r28-r31 */	\
     93 	mflr	28;			/* save LR */		\
     94 	mfcr	29;			/* save CR */		\
     95 	mfsrr1	31; /* Test whether we already had PR set */	\
     96 	mtcr	31;						\
     97 	bc	4,17,1f;	/* branch if PSL_PR is clear */	\
     98 	GET_PCB(1);						\
     99 	addi	1,1,USPACE;	/* stack is top of user struct */ \
    100 1:
    101 
    102 #define	CRITICAL_PROLOG(savearea)	\
    103 	mtsprg	1,1;			/* save SP */ 		\
    104 	stmw	28,savearea(0);		/* free r28-r31 */	\
    105 	mflr	28;			/* save LR */		\
    106 	mfcr	29;			/* save CR */		\
    107 	mfsrr2	30; /* Fake a standard trap */			\
    108 	mtsrr0	30;						\
    109 	mfsrr3	31; /* Test whether we already had PR set */	\
    110 	mtsrr1	31;						\
    111 	mtcr	31;						\
    112 	bc	4,17,1f;	/* branch if PSL_PR is clear */	\
    113 	GET_PCB(1);						\
    114 	addi	1,1,USPACE;	/* stack is top of user struct */ \
    115 1:
    116 
    117 
    118 /* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */
    119 #define STANDARD_EXC_HANDLER(name)\
    120 	.globl	_C_LABEL(name ## trap),_C_LABEL(name ## size) ;	\
    121 _C_LABEL(name ## trap):						\
    122 	STANDARD_PROLOG(tempsave);				\
    123 	bla	s_trap  ;					\
    124 _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
    125 
    126 /* Access exceptions also need DEAR and ESR saved */
    127 #define ACCESS_EXC_HANDLER(name)\
    128 	.globl	_C_LABEL(name ## trap),_C_LABEL(name ## size) ;	\
    129 _C_LABEL(name ## trap):						\
    130 	STANDARD_PROLOG(tempsave);				\
    131 	mfdear	30;						\
    132 	mfesr	31;						\
    133 	stmw	30,16+tempsave(0);				\
    134 	bla	s_trap  ;					\
    135 _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
    136 
    137 /* Maybe this should call ddb.... */
    138 #define CRITICAL_EXC_HANDLER(name)\
    139 	.globl	_C_LABEL(name ## trap),_C_LABEL(name ## size) ;	\
    140 _C_LABEL(name ## trap):						\
    141 	CRITICAL_PROLOG(tempsave);				\
    142 	bla	s_trap  ;					\
    143 _C_LABEL(name ## size) = .-_C_LABEL(name ## trap)
    144 
    145 /*
    146  * This code gets copied to all the trap vectors
    147  * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
    148  * traps when using IPKDB).
    149  */
    150 	.text
    151 	STANDARD_EXC_HANDLER(default)
    152 	ACCESS_EXC_HANDLER(ali)
    153 	ACCESS_EXC_HANDLER(dsi)
    154 	ACCESS_EXC_HANDLER(isi)
    155 	STANDARD_EXC_HANDLER(debug)
    156 	CRITICAL_EXC_HANDLER(mchk)
    157 
    158 /*
    159  * This one for the external interrupt handler.
    160  */
    161 	.globl	_C_LABEL(extint),_C_LABEL(extsize)
    162 _C_LABEL(extint):
    163 	mtsprg	1,1			/* save SP */
    164 	stmw	28,tempsave(0)		/* free r28-r31 */
    165 	mflr	28			/* save LR */
    166 	mfcr	29			/* save CR */
    167 	mfxer	30			/* save XER */
    168 	GET_CPUINFO(1)
    169 	lwz	31,CI_INTRDEPTH(1)	/* were we already running on intstk? */
    170 	addic.	31,31,1
    171 	stw	31,CI_INTRDEPTH(1)
    172 	lwz	1,CI_INTSTK(1)		/* get intstk */
    173 	beq	1f
    174 	mfsprg	1,1			/* yes, get old SP */
    175 1:
    176 	ba	extintr
    177 _C_LABEL(extsize) = .-_C_LABEL(extint)
    178 
    179 
    180 #ifdef DDB
    181 #define	ddbsave	0xde0		/* primary save area for DDB */
    182 /*
    183  * In case of DDB we want a separate trap catcher for it
    184  */
    185 	.local	ddbstk
    186 	.comm	ddbstk,INTSTK,8		/* ddb stack */
    187 
    188 	.globl	_C_LABEL(ddblow),_C_LABEL(ddbsize)
    189 _C_LABEL(ddblow):
    190 	mtsprg	1,1			/* save SP */
    191 	stmw	28,ddbsave(0)		/* free r28-r31 */
    192 	mflr	28			/* save LR */
    193 	mfcr	29			/* save CR */
    194 	lis	1,ddbstk+INTSTK@ha	/* get new SP */
    195 	addi	1,1,ddbstk+INTSTK@l
    196 	bla	ddbtrap
    197 _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
    198 #endif	/* DDB */
    199 
    200 #ifdef IPKDB
    201 #define	ipkdbsave	0xde0		/* primary save area for IPKDB */
    202 /*
    203  * In case of IPKDB we want a separate trap catcher for it
    204  */
    205 
    206 	.local	ipkdbstk
    207 	.comm	ipkdbstk,INTSTK,8		/* ipkdb stack */
    208 
    209 	.globl	_C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
    210 _C_LABEL(ipkdblow):
    211 	mtsprg	1,1			/* save SP */
    212 	stmw	28,ipkdbsave(0)		/* free r28-r31 */
    213 	mflr	28			/* save LR */
    214 	mfcr	29			/* save CR */
    215 	lis	1,ipkdbstk+INTSTK@ha	/* get new SP */
    216 	addi	1,1,ipkdbstk+INTSTK@l
    217 	bla	ipkdbtrap
    218 _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
    219 #endif	/* IPKDB */
    220 
    221 #ifdef DEBUG
    222 #define TRAP_IF_ZERO(r)	tweqi	r,0
    223 #else
    224 #define TRAP_IF_ZERO(r)
    225 #endif
    226 
    227 /*
    228  * FRAME_SETUP assumes:
    229  *	SPRG1		SP (1)
    230  *	savearea	r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps)
    231  *	28		LR
    232  *	29		CR
    233  *	1		kernel stack
    234  *	LR		trap type
    235  *	SRR0/1		as at start of trap
    236  */
    237 #define	FRAME_SETUP(savearea)						\
    238 /* Have to enable translation to allow access of kernel stack: */	\
    239 	mfsrr0	30;							\
    240 	mfsrr1	31;							\
    241 	stmw	30,savearea+24(0);					\
    242 	mfpid	30;							\
    243 	li	31,KERNEL_PID;						\
    244 	mtpid	31;							\
    245 	mfmsr	31;							\
    246 	ori	31,31,(PSL_DR|PSL_IR)@l;				\
    247 	mtmsr	31;							\
    248 	isync;								\
    249 	mfsprg	31,1;							\
    250 	stwu	31,-FRAMELEN(1);					\
    251 	stw	30,FRAME_PID+8(1);					\
    252 	stw	0,FRAME_0+8(1);						\
    253 	stw	31,FRAME_1+8(1);					\
    254 	stw	28,FRAME_LR+8(1);					\
    255 	stw	29,FRAME_CR+8(1);					\
    256 	lmw	28,savearea(0);						\
    257 	stmw	2,FRAME_2+8(1);						\
    258 	lmw	28,savearea+16(0);					\
    259 	mfxer	3;							\
    260 	mfctr	4;							\
    261 	mflr	5;							\
    262 	andi.	5,5,0xff00;						\
    263 	stw	3,FRAME_XER+8(1);					\
    264 	stw	4,FRAME_CTR+8(1);					\
    265 	stw	5,FRAME_EXC+8(1);					\
    266 	stw	28,FRAME_DEAR+8(1);					\
    267 	stw	29,FRAME_ESR+8(1);					\
    268 	stw	30,FRAME_SRR0+8(1);					\
    269 	stw	31,FRAME_SRR1+8(1)
    270 
    271 #define	FRAME_LEAVE(savearea)						\
    272 /* Now restore regs: */							\
    273 	lwz	3,FRAME_PID+8(1);					\
    274 	lwz	4,FRAME_SRR1+8(1);					\
    275 	bl	_C_LABEL(ctx_setup);					\
    276 	TRAP_IF_ZERO(r3);						\
    277 	stw	3,FRAME_PID+8(1);					\
    278 	lmw	26,FRAME_LR+8(1);					\
    279 	mtlr	26;							\
    280 	mtcr	27;							\
    281 	mtxer	28;							\
    282 	mtctr	29;							\
    283 	mtsrr0	30;							\
    284 	mtsrr1	31;							\
    285 	lmw	2,FRAME_2+8(1);						\
    286 	lwz	0,FRAME_0+8(1);						\
    287 	stmw	29,savearea(0);						\
    288 	lwz	30,FRAME_PID+8(1);					\
    289 	lwz	1,FRAME_1+8(1);						\
    290 	mfmsr	31;							\
    291 	li	29,(PSL_DR|PSL_IR)@l;					\
    292 	andc	31,31,29;						\
    293 	mfcr	29;							\
    294 	mtcr	29;							\
    295 	mtmsr	31;							\
    296 	isync;								\
    297 	TRAP_IF_ZERO(r30);						\
    298 	mtpid	30;							\
    299 	lmw	29,savearea(0)
    300 
    301 realtrap:	/* entry point after IPKDB is done with exception */
    302 	/* Test whether we already had PR set */
    303 	mfsrr1	1
    304 	mtcr	1
    305 	mfsprg	1,1			/* restore SP (might have been
    306 					   overwritten) */
    307 	bc	4,17,s_trap		/* branch if PSL_PR is false */
    308 	GET_PCB(1)
    309 	addi	1,1,USPACE		/* stack is top of user struct */
    310 /*
    311  * Now the common trap catching code.
    312  */
    313 s_trap:
    314 	FRAME_SETUP(tempsave)
    315 /* Now we can recover interrupts again: */
    316 trapagain:
    317 	wrteei	1			/* Enable interrupts */
    318 /* Call C trap code: */
    319 	addi	3,1,8
    320 	bl	_C_LABEL(trap)
    321 	.globl	_C_LABEL(trapexit)
    322 _C_LABEL(trapexit):
    323 	/* Disable interrupts: */
    324 	wrteei	0
    325 	/* Test AST pending: */
    326 	lwz	5,FRAME_SRR1+8(1)
    327 	mtcr	5
    328 	bc	4,17,1f			/* branch if PSL_PR is false */
    329 	GET_CPUINFO(3)
    330 	lwz	4,CI_ASTPENDING(3)
    331 	andi.	4,4,1
    332 	beq	1f
    333 	li	6,EXC_AST
    334 	stw	6,FRAME_EXC+8(1)
    335 	b	trapagain
    336 1:
    337 	FRAME_LEAVE(exitsave)
    338 	rfi
    339 	ba	.	/* Protect against prefetch */
    340 
    341 
    342 
    343 	.globl	_C_LABEL(sctrap),_C_LABEL(scsize)
    344 _C_LABEL(sctrap):
    345 	STANDARD_PROLOG(tempsave);
    346 	bla	s_sctrap
    347 _C_LABEL(scsize) = .-_C_LABEL(sctrap)
    348 
    349 s_sctrap:
    350 	FRAME_SETUP(tempsave)
    351 /* Now we can recover interrupts again: */
    352 	wrteei	1			/* Enable interrupts */
    353 /* Call the appropriate syscall handler: */
    354 	addi	3,1,8
    355 	GET_CPUINFO(4)
    356 	lwz	4,CI_CURLWP(4)
    357 	lwz	4,L_PROC(4)
    358 	lwz	4,P_MD_SYSCALL(4)
    359 	mtctr	4
    360 	bctrl
    361 /* Disable interrupts: */
    362 	wrteei	0
    363 /* Test AST pending: */
    364 	lwz	5,FRAME_SRR1+8(1)
    365 	mtcr	5
    366 	bc	4,17,1f			/* branch if PSL_PR is false */
    367 	GET_CPUINFO(3)
    368 	lwz	4,CI_ASTPENDING(3)
    369 	andi.	4,4,1
    370 	beq	1f
    371 	li	6,EXC_AST
    372 	stw	6,FRAME_EXC+8(1)
    373 	b	trapagain
    374 1:
    375 	FRAME_LEAVE(exitsave)
    376 	rfi
    377 	ba	.	/* Protect against prefetch */
    378 
    379 
    380 /*
    381  * External interrupt second level handler
    382  */
    383 
    384 #define	INTRENTER							\
    385 /* Save non-volatile registers: */					\
    386 	stwu	1,-IFRAMELEN(1);	/* temporarily */		\
    387 	stw	0,IFRAME_R0(1);						\
    388 	mfsprg	0,1;			/* get original SP */		\
    389 	stw	0,IFRAME_R1(1);		/* and store it */		\
    390 	stw	3,IFRAME_R3(1);						\
    391 	stw	4,IFRAME_R4(1);						\
    392 	stw	5,IFRAME_R5(1);						\
    393 	stw	6,IFRAME_R6(1);						\
    394 	stw	7,IFRAME_R7(1);						\
    395 	stw	8,IFRAME_R8(1);						\
    396 	stw	9,IFRAME_R9(1);						\
    397 	stw	10,IFRAME_R10(1);					\
    398 	stw	11,IFRAME_R11(1);					\
    399 	stw	12,IFRAME_R12(1);					\
    400 	stw	28,IFRAME_LR(1);	/* saved LR */			\
    401 	stw	29,IFRAME_CR(1);	/* saved CR */			\
    402 	stw	30,IFRAME_XER(1);	/* saved XER */			\
    403 	lmw	28,tempsave(0);		/* restore r28-r31 */		\
    404 	mfctr	6;							\
    405 	GET_CPUINFO(5);							\
    406 	lwz	5,CI_INTRDEPTH(5);					\
    407 	mfsrr0	4;							\
    408 	mfsrr1	3;							\
    409 	stw	6,IFRAME_CTR(1);					\
    410 	stw	5,IFRAME_INTR_DEPTH(1);					\
    411 	stw	4,IFRAME_SRR0(1);					\
    412 	stw	3,IFRAME_SRR1(1);					\
    413 	mfpid	0;			/* get currect PID register */  \
    414 	stw	0,IFRAME_PID(1);					\
    415 	li	0,KERNEL_PID;						\
    416 	mtpid	0;							\
    417 /* interrupts are recoverable here, and enable translation */		\
    418 	mfmsr	5;							\
    419 	ori	5,5,(PSL_IR|PSL_DR);					\
    420 	mtmsr	5;							\
    421 	isync
    422 
    423 	.globl	_C_LABEL(extint_call)
    424 extintr:
    425 	INTRENTER
    426 _C_LABEL(extint_call):
    427 	bl	_C_LABEL(extint_call)	/* to be filled in later */
    428 
    429 intr_exit:
    430 /* Disable interrupts (should already be disabled) and MMU here: */
    431 	wrteei	0
    432 	isync
    433 	lwz	3,IFRAME_PID(1)
    434 	lwz	4,IFRAME_SRR1(1)	/* Load srr1 */
    435 	bl	_C_LABEL(ctx_setup)	/* Get proper ctx */
    436 	mfmsr	5
    437 	lis	4,(PSL_EE|PSL_DR|PSL_IR)@h
    438 	ori	4,4,(PSL_EE|PSL_DR|PSL_IR)@l
    439 	andc	5,5,4
    440 	mtmsr	5
    441 	isync
    442 	mtpid	3			/* Load CTX */
    443 
    444 /* restore possibly overwritten registers: */
    445 	lwz	12,IFRAME_R12(1)
    446 	lwz	11,IFRAME_R11(1)
    447 	lwz	10,IFRAME_R10(1)
    448 	lwz	9,IFRAME_R9(1)
    449 	lwz	8,IFRAME_R8(1)
    450 	lwz	7,IFRAME_R7(1)
    451 	lwz	6,IFRAME_SRR1(1)
    452 	lwz	5,IFRAME_SRR0(1)
    453 	lwz	4,IFRAME_CTR(1)
    454 	lwz	3,IFRAME_XER(1)
    455 	mtsrr1	6
    456 	mtsrr0	5
    457 	mtctr	4
    458 	mtxer	3
    459 /* Returning to user mode? */
    460 	GET_CPUINFO(5)
    461 	lwz	4,CI_INTRDEPTH(5)
    462 	addi	4,4,-1			/* adjust reentrancy count */
    463 	stw	4,CI_INTRDEPTH(5)
    464 	mtcr	6			/* saved SRR1 */
    465 	bc	4,17,1f			/* branch if PSL_PR is false */
    466 
    467 	lwz	4,CI_ASTPENDING(5)	 /* Test AST pending */
    468 	andi.	4,4,1
    469 	beq	1f
    470 /* Setup for entry to realtrap: */
    471 	lwz	3,0(1)			/* get saved SP */
    472 	mtsprg	1,3
    473 	li	6,EXC_AST
    474 	stmw	28,tempsave(0)		/* establish tempsave again */
    475 	mtlr	6
    476 	lwz	28,IFRAME_LR(1)		/* saved LR */
    477 	lwz	29,IFRAME_CR(1)		/* saved CR */
    478 	lwz	6,IFRAME_R6(1)
    479 	lwz	5,IFRAME_R5(1)
    480 	lwz	4,IFRAME_R4(1)
    481 	lwz	3,IFRAME_R3(1)
    482 	lwz	0,IFRAME_R0(1)
    483 	b	realtrap
    484 1:
    485 /* Here is the normal exit of extintr: */
    486 	lwz	5,IFRAME_CR(1)
    487 	lwz	6,IFRAME_LR(1)
    488 	mtcr	5
    489 	mtlr	6
    490 	lwz	6,IFRAME_R6(1)
    491 	lwz	5,IFRAME_R5(1)
    492 	lwz	4,IFRAME_R4(1)
    493 	lwz	3,IFRAME_R3(1)
    494 	lwz	0,IFRAME_R0(1)
    495 	lwz	1,IFRAME_R1(1)
    496 	rfi
    497 	ba	.	/* Protect against prefetch */
    498 
    499 /*
    500  * PIT interrupt handler.
    501  */
    502 	.align	5
    503 _C_LABEL(pitint):
    504 	mtsprg	1,1			/* save SP */
    505 	stmw	28,tempsave(0)		/* free r28-r31 */
    506 	mflr	28			/* save LR */
    507 	mfcr	29			/* save CR */
    508 	mfxer	30			/* save XER */
    509 	GET_CPUINFO(1)
    510 	lwz	31,CI_INTRDEPTH(1)	/* were we already running on intstk? */
    511 	addic.	31,31,1
    512 	stw	31,CI_INTRDEPTH(1)
    513 	lwz	1,CI_INTSTK(1)		/* get intstk */
    514 	beq	1f
    515 	mfsprg	1,1			/* yes, get old SP */
    516 1:
    517 	INTRENTER
    518 	addi	3,1,8			/* intr frame */
    519 	bl	_C_LABEL(decr_intr)
    520 	b	intr_exit
    521 
    522 /*
    523  * FIT interrupt handler.
    524  */
    525 	.align	5
    526 fitint:
    527 	mtsprg	1,1			/* save SP */
    528 	stmw	28,tempsave(0)		/* free r28-r31 */
    529 	mflr	28			/* save LR */
    530 	mfcr	29			/* save CR */
    531 	mfxer	30			/* save XER */
    532 	GET_CPUINFO(1)
    533 	lwz	31,CI_INTRDEPTH(1)	/* were we already running on intstk? */
    534 	addic.	31,31,1
    535 	stw	31,CI_INTRDEPTH(1)
    536 	lwz	1,CI_INTSTK(1)		/* get intstk */
    537 	beq	1f
    538 	mfsprg	1,1			/* yes, get old SP */
    539 1:
    540 	INTRENTER
    541 	addi	3,1,8			/* intr frame */
    542 	bl	_C_LABEL(stat_intr)
    543 	b	intr_exit
    544 
    545 #ifdef DDB
    546 /*
    547  * Deliberate entry to ddbtrap
    548  */
    549 	.globl	_C_LABEL(ddb_trap)
    550 _C_LABEL(ddb_trap):
    551 	mtsprg	1,1
    552 	mfmsr	3
    553 	mtsrr1	3
    554 	wrteei	0			/* disable interrupts */
    555 	isync
    556 	stmw	28,ddbsave(0)
    557 	mflr	28
    558 	li	29,EXC_BPT
    559 	mtlr	29
    560 	mfcr	29
    561 	mtsrr0	28
    562 
    563 /*
    564  * Now the ddb trap catching code.
    565  */
    566 ddbtrap:
    567 	FRAME_SETUP(ddbsave)
    568 /* Call C trap code: */
    569 	addi	3,1,8
    570 	bl	_C_LABEL(ddb_trap_glue)
    571 	or.	3,3,3
    572 	bne	ddbleave
    573 /* This wasn't for DDB, so switch to real trap: */
    574 	lwz	3,FRAME_EXC+8(1)	/* save exception */
    575 	stw	3,ddbsave+12(0)
    576 	FRAME_LEAVE(ddbsave)
    577 	mtsprg	1,1			/* prepare for entrance to realtrap */
    578 	stmw	28,tempsave(0)
    579 	mflr	28
    580 	mfcr	29
    581 	lwz	31,ddbsave+12(0)
    582 	mtlr	31
    583 	b	realtrap
    584 ddbleave:
    585 	FRAME_LEAVE(ddbsave)
    586 	rfi
    587 	ba	.	/* Protect against prefetch */
    588 #endif /* DDB */
    589 
    590 #ifdef IPKDB
    591 /*
    592  * Deliberate entry to ipkdbtrap
    593  */
    594 	.globl	_C_LABEL(ipkdb_trap)
    595 _C_LABEL(ipkdb_trap):
    596 	mtsprg	1,1
    597 	mfmsr	3
    598 	mtsrr1	3
    599 	wrteei	0			/* disable interrupts */
    600 	isync
    601 	stmw	28,ipkdbsave(0)
    602 	mflr	28
    603 	li	29,EXC_BPT
    604 	mtlr	29
    605 	mfcr	29
    606 	mtsrr0	28
    607 
    608 /*
    609  * Now the ipkdb trap catching code.
    610  */
    611 ipkdbtrap:
    612 	FRAME_SETUP(ipkdbsave)
    613 /* Call C trap code: */
    614 	addi	3,1,8
    615 	bl	_C_LABEL(ipkdb_trap_glue)
    616 	or.	3,3,3
    617 	bne	ipkdbleave
    618 /* This wasn't for IPKDB, so switch to real trap: */
    619 	lwz	3,FRAME_EXC+8(1)	/* save exception */
    620 	stw	3,ipkdbsave+8(0)
    621 	FRAME_LEAVE(ipkdbsave)
    622 	mtsprg	1,1			/* prepare for entrance to realtrap */
    623 	stmw	28,tempsave(0)
    624 	mflr	28
    625 	mfcr	29
    626 	lwz	31,ipkdbsave+8(0)
    627 	mtlr	31
    628 	b	realtrap
    629 ipkdbleave:
    630 	FRAME_LEAVE(ipkdbsave)
    631 	rfi
    632 	ba	.	/* Protect against prefetch */
    633 
    634 ipkdbfault:
    635 	ba	_ipkdbfault
    636 _ipkdbfault:
    637 	mfsrr0	3
    638 	addi	3,3,4
    639 	mtsrr0	3
    640 	li	3,-1
    641 	rfi
    642 	ba	.	/* Protect against prefetch */
    643 
    644 /*
    645  * int ipkdbfbyte(unsigned char *p)
    646  */
    647 	.globl	_C_LABEL(ipkdbfbyte)
    648 _C_LABEL(ipkdbfbyte):
    649 	li	9,EXC_DSI		/* establish new fault routine */
    650 	lwz	5,0(9)
    651 	lis	6,ipkdbfault@ha
    652 	lwz	6,ipkdbfault@l(6)
    653 	stw	6,0(9)
    654 #ifdef	IPKDBUSERHACK
    655 #ifndef PPC_IBM4XX
    656 	lis	8,_C_LABEL(ipkdbsr)@ha
    657 	lwz	8,_C_LABEL(ipkdbsr)@l(8)
    658 	mtsr	USER_SR,8
    659 	isync
    660 #endif
    661 #endif
    662 	dcbst	0,9			/* flush data... */
    663 	sync
    664 	icbi	0,9			/* and instruction caches */
    665 	lbz	3,0(3)			/* fetch data */
    666 	stw	5,0(9)			/* restore previous fault handler */
    667 	dcbst	0,9			/* and flush data... */
    668 	sync
    669 	icbi	0,9			/* and instruction caches */
    670 	blr
    671 
    672 /*
    673  * int ipkdbsbyte(unsigned char *p, int c)
    674  */
    675 	.globl	_C_LABEL(ipkdbsbyte)
    676 _C_LABEL(ipkdbsbyte):
    677 	li	9,EXC_DSI		/* establish new fault routine */
    678 	lwz	5,0(9)
    679 	lis	6,ipkdbfault@ha
    680 	lwz	6,ipkdbfault@l(6)
    681 	stw	6,0(9)
    682 #ifdef	IPKDBUSERHACK
    683 #ifndef PPC_IBM4XX
    684 	lis	8,_C_LABEL(ipkdbsr)@ha
    685 	lwz	8,_C_LABEL(ipkdbsr)@l(8)
    686 	mtsr	USER_SR,8
    687 	isync
    688 #endif
    689 #endif
    690 	dcbst	0,9			/* flush data... */
    691 	sync
    692 	icbi	0,9			/* and instruction caches */
    693 	mr	6,3
    694 	xor	3,3,3
    695 	stb	4,0(6)
    696 	dcbst	0,6			/* Now do appropriate flushes
    697 					   to data... */
    698 	sync
    699 	icbi	0,6			/* and instruction caches */
    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 #endif	/* IPKDB */
    706