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