trap_subr64.S revision 103608
195719Sbenno/* $FreeBSD: head/sys/powerpc/aim/trap_subr.S 103608 2002-09-19 04:39:04Z grehan $ */
295719Sbenno/* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $	*/
395719Sbenno
495719Sbenno/*
595719Sbenno * Copyright (C) 1995, 1996 Wolfgang Solfrank.
695719Sbenno * Copyright (C) 1995, 1996 TooLs GmbH.
795719Sbenno * All rights reserved.
895719Sbenno *
995719Sbenno * Redistribution and use in source and binary forms, with or without
1095719Sbenno * modification, are permitted provided that the following conditions
1195719Sbenno * are met:
1295719Sbenno * 1. Redistributions of source code must retain the above copyright
1395719Sbenno *    notice, this list of conditions and the following disclaimer.
1495719Sbenno * 2. Redistributions in binary form must reproduce the above copyright
1595719Sbenno *    notice, this list of conditions and the following disclaimer in the
1695719Sbenno *    documentation and/or other materials provided with the distribution.
1795719Sbenno * 3. All advertising materials mentioning features or use of this software
1895719Sbenno *    must display the following acknowledgement:
1995719Sbenno *	This product includes software developed by TooLs GmbH.
2095719Sbenno * 4. The name of TooLs GmbH may not be used to endorse or promote products
2195719Sbenno *    derived from this software without specific prior written permission.
2295719Sbenno *
2395719Sbenno * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
2495719Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2595719Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2695719Sbenno * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2795719Sbenno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2895719Sbenno * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2995719Sbenno * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3095719Sbenno * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
3195719Sbenno * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
3295719Sbenno * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3395719Sbenno */
3495719Sbenno
3595719Sbenno/*
3695719Sbenno * NOTICE: This is not a standalone file.  to use it, #include it in
3795719Sbenno * your port's locore.S, like so:
3895719Sbenno *
3995719Sbenno *	#include <powerpc/powerpc/trap_subr.S>
4095719Sbenno */
4195719Sbenno
4295719Sbenno/*
4395719Sbenno * XXX Fake AST trap vector.  This is here until we work out how to safely
4495719Sbenno * remove the AST code.
4595719Sbenno */
4695719Sbenno#define	EXC_AST	0x3000
4795719Sbenno	.data
4895719Sbenno	.align	4
4996253Sbennocpassert:
5096253Sbenno	.asciz	"attempting to return from kernel with no current pmap"
5195719Sbenno
5295719Sbenno/*
5395719Sbenno * Data used during primary/secondary traps/interrupts
5495719Sbenno */
5595719Sbenno#define	tempsave	EXC_MCHK+0xe0 /* primary save area for trap handling */
5695719Sbenno#define	disisave	EXC_DSI+0xe0  /* primary save area for dsi/isi traps */
5795719Sbenno
5895719Sbenno/*
5995719Sbenno * XXX Interrupt and spill stacks need to be per-CPU.
6095719Sbenno */
6195719Sbenno	.data
6295719Sbenno	.align	4
6395719Sbennointstk:
6495719Sbenno	.space	INTSTK		/* interrupt stack */
6595719Sbenno
6695719SbennoGLOBAL(intr_depth)
6795719Sbenno	.long	-1		/* in-use marker */
6895719Sbenno
6995719Sbenno	.comm	spillstk,SPILLSTK,8
7095719Sbenno
7195719Sbenno/*
7295719Sbenno * This code gets copied to all the trap vectors
7395719Sbenno * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
7495719Sbenno * traps when using IPKDB).
7595719Sbenno */
7695719Sbenno	.text
7796773Sbenno	.globl	CNAME(trapcode),CNAME(trapsize)
7896773SbennoCNAME(trapcode):
7995719Sbenno	mtsprg	1,1			/* save SP */
8095719Sbenno	stmw	28,tempsave(0)		/* free r28-r31 */
8195719Sbenno	mflr	28			/* save LR */
8295719Sbenno	mfcr	29			/* save CR */
8395719Sbenno/* Test whether we already had PR set */
8495719Sbenno	mfsrr1	31
8595719Sbenno	mtcr	31
8695719Sbenno	bc	4,17,1f			/* branch if PSL_PR is clear */
8795719Sbenno	mfsprg	31,0
8895719Sbenno	lwz	1,PC_CURPCB(31)
8995719Sbenno1:
9095719Sbenno	bla	s_trap
9196773SbennoCNAME(trapsize) = .-CNAME(trapcode)
9295719Sbenno
9395719Sbenno/*
9495719Sbenno * For ALI: has to save DSISR and DAR
9595719Sbenno */
9696773Sbenno	.globl	CNAME(alitrap),CNAME(alisize)
9796773SbennoCNAME(alitrap):
9895719Sbenno	mtsprg	1,1			/* save SP */
9995719Sbenno	stmw	28,tempsave(0)		/* free r28-r31 */
10095719Sbenno	mfdar	30
10195719Sbenno	mfdsisr	31
10295719Sbenno	stmw	30,tempsave+16(0)
10395719Sbenno	mflr	28			/* save LR */
10495719Sbenno	mfcr	29			/* save CR */
10595719Sbenno/* Test whether we already had PR set */
10695719Sbenno	mfsrr1	31
10795719Sbenno	mtcr	31
10895719Sbenno	bc	4,17,1f			/* branch if PSL_PR is clear */
10995719Sbenno	mfsprg	31,0
11095719Sbenno	lwz	1,PC_CURPCB(31)
11195719Sbenno1:
11295719Sbenno	bla	s_trap
11396773SbennoCNAME(alisize) = .-CNAME(alitrap)
11495719Sbenno
11595719Sbenno/*
11695719Sbenno * Similar to the above for DSI
11795719Sbenno * Has to handle BAT spills
11895719Sbenno * and standard pagetable spills
11995719Sbenno */
12096773Sbenno	.globl	CNAME(dsitrap),CNAME(dsisize)
12196773SbennoCNAME(dsitrap):
12295719Sbenno	stmw	28,disisave(0)		/* free r28-r31 */
12395719Sbenno	mfcr	29			/* save CR */
12495719Sbenno	mfxer	30			/* save XER */
12595719Sbenno	mtsprg	2,30			/* in SPRG2 */
12695719Sbenno	mfsrr1	31			/* test kernel mode */
12795719Sbenno	mtcr	31
12895719Sbenno	bc	12,17,1f		/* branch if PSL_PR is set */
12995719Sbenno	mfdar	31			/* get fault address */
13095719Sbenno	rlwinm	31,31,7,25,28		/* get segment * 8 */
13195719Sbenno
13295719Sbenno	/* get batu */
13396773Sbenno	addis	31,31,CNAME(battable)@ha
13496773Sbenno	lwz	30,CNAME(battable)@l(31)
13595719Sbenno	mtcr	30
13695719Sbenno	bc	4,30,1f			/* branch if supervisor valid is
13795719Sbenno					   false */
13895719Sbenno	/* get batl */
13996773Sbenno	lwz	31,CNAME(battable)+4@l(31)
14095719Sbenno/* We randomly use the highest two bat registers here */
14195719Sbenno	mftb	28
14295719Sbenno	andi.	28,28,1
14395719Sbenno	bne	2f
14495719Sbenno	mtdbatu	2,30
14595719Sbenno	mtdbatl	2,31
14695719Sbenno	b	3f
14795719Sbenno2:
14895719Sbenno	mtdbatu	3,30
14995719Sbenno	mtdbatl	3,31
15095719Sbenno3:
15195719Sbenno	mfsprg	30,2			/* restore XER */
15295719Sbenno	mtxer	30
15395719Sbenno	mtcr	29			/* restore CR */
15495719Sbenno	lmw	28,disisave(0)		/* restore r28-r31 */
15595719Sbenno	rfi				/* return to trapped code */
15695719Sbenno1:
15795719Sbenno	mflr	28			/* save LR */
15895719Sbenno	bla	s_dsitrap
15996773SbennoCNAME(dsisize) = .-CNAME(dsitrap)
16095719Sbenno
16195719Sbenno/*
16295719Sbenno * Dedicated MPC601 version of the above.
16395719Sbenno * Considers different BAT format and combined implementation
16495719Sbenno * (being addressed as I-BAT).
16595719Sbenno */
16696773Sbenno	.globl	CNAME(dsitrap601),CNAME(dsi601size)
16796773SbennoCNAME(dsitrap601):
16895719Sbenno	stmw	28,disisave(0)		/* free r28-r31 */
16995719Sbenno	mfcr	29			/* save CR */
17095719Sbenno	mfxer	30			/* save XER */
17195719Sbenno	mtsprg	2,30			/* in SPRG2 */
17295719Sbenno	mfsrr1	31			/* test kernel mode */
17395719Sbenno	mtcr	31
17495719Sbenno	bc	12,17,1f		/* branch if PSL_PR is set */
17595719Sbenno	mfdar	31			/* get fault address */
17695719Sbenno	rlwinm	31,31,12,20,28		/* get "segment" battable offset */
17795719Sbenno
17895719Sbenno	/* get batl */
17996773Sbenno	addis	31,31,CNAME(battable)@ha
18096773Sbenno	lwz	30,CNAME(battable)+4@l(31)
18195719Sbenno	mtcr	30
18295719Sbenno	bc	4,25,1f			/* branch if Valid is is false,
18395719Sbenno					   presently assumes supervisor only */
18495719Sbenno
18595719Sbenno	/* get batu */
18696773Sbenno	lwz	31,CNAME(battable)@l(31)
18795719Sbenno/* We randomly use the highest two bat registers here */
18895719Sbenno	mfspr	28,SPR_RTCL_R
18995719Sbenno	andi.	28,28,128
19095719Sbenno	bne	2f
19195719Sbenno	mtibatu	2,31
19295719Sbenno	mtibatl	2,30
19395719Sbenno	b	3f
19495719Sbenno2:
19595719Sbenno	mtibatu	3,31
19695719Sbenno	mtibatl	3,30
19795719Sbenno3:
19895719Sbenno	mfsprg	30,2			/* restore XER */
19995719Sbenno	mtxer	30
20095719Sbenno	mtcr	29			/* restore CR */
20195719Sbenno	lmw	28,disisave(0)		/* restore r28-r31 */
20295719Sbenno	rfi				/* return to trapped code */
20395719Sbenno1:
20495719Sbenno	mflr	28			/* save LR */
20595719Sbenno	bla	s_dsitrap
20696773SbennoCNAME(dsi601size) = .-CNAME(dsitrap601)
20795719Sbenno
20895719Sbenno/*
20995719Sbenno * Similar to the above for ISI
21095719Sbenno */
21196773Sbenno	.globl	CNAME(isitrap),CNAME(isisize)
21296773SbennoCNAME(isitrap):
21395719Sbenno	stmw	28,disisave(0)		/* free r28-r31 */
21495719Sbenno	mflr	28			/* save LR */
21595719Sbenno	mfcr	29			/* save CR */
21695719Sbenno	mfsrr1	31			/* test kernel mode */
21795719Sbenno	mtcr	31
21895719Sbenno	bc	12,17,1f		/* branch if PSL_PR is set */
21995719Sbenno	mfsrr0	31			/* get fault address */
22095719Sbenno	rlwinm	31,31,7,25,28		/* get segment * 8 */
22195719Sbenno
22295719Sbenno	/* get batu */
22396773Sbenno	addis	31,31,CNAME(battable)@ha
22496773Sbenno	lwz	30,CNAME(battable)@l(31)
22595719Sbenno	mtcr	30
22695719Sbenno	bc	4,30,1f			/* branch if supervisor valid is
22795719Sbenno					   false */
22895719Sbenno	mtibatu	3,30
22995719Sbenno
23095719Sbenno	/* get batl */
23196773Sbenno	lwz	30,CNAME(battable)+4@l(31)
23295719Sbenno	mtibatl	3,30
23395719Sbenno
23495719Sbenno	mtcr	29			/* restore CR */
23595719Sbenno	lmw	28,disisave(0)		/* restore r28-r31 */
23695719Sbenno	rfi				/* return to trapped code */
23795719Sbenno1:
23895719Sbenno	bla	s_isitrap
23996773SbennoCNAME(isisize)= .-CNAME(isitrap)
24095719Sbenno
24195719Sbenno/*
24295719Sbenno * Dedicated MPC601 version of the above.
24395719Sbenno * Considers different BAT format.
24495719Sbenno */
24596773Sbenno	.globl	CNAME(isitrap601),CNAME(isi601size)
24696773SbennoCNAME(isitrap601):
24795719Sbenno	stmw	28,disisave(0)		/* free r28-r31 */
24895719Sbenno	mflr	28			/* save LR */
24995719Sbenno	mfcr	29			/* save CR */
25095719Sbenno	mfsrr1	31			/* test kernel mode */
25195719Sbenno	mtcr	31
25295719Sbenno	bc	12,17,1f		/* branch if PSL_PR is set */
25395719Sbenno	mfsrr0	31			/* get fault address */
25495719Sbenno	rlwinm	31,31,12,20,28		/* get "segment" battable offset */
25595719Sbenno
25695719Sbenno	/* get batl */
25796773Sbenno	addis	31,31,CNAME(battable)@ha
25896773Sbenno	lwz	30,CNAME(battable)+4@l(31)
25995719Sbenno	mtcr	30
26095719Sbenno	bc	4,25,1f			/* branch if Valid is is false,
26195719Sbenno					   presently assumes supervisor only */
26295719Sbenno	/* get batu */
26396773Sbenno	lwz	31,CNAME(battable)@l(31)
26495719Sbenno
26595719Sbenno	mtibatu	3,31
26695719Sbenno	mtibatl	3,30
26795719Sbenno
26895719Sbenno	mtcr	29			/* restore CR */
26995719Sbenno	lmw	28,disisave(0)		/* restore r28-r31 */
27095719Sbenno	rfi				/* return to trapped code */
27195719Sbenno1:
27295719Sbenno	bla	s_isitrap
27396773SbennoCNAME(isi601size)= .-CNAME(isitrap601)
27495719Sbenno
27595719Sbenno/*
27695719Sbenno * Now the tlb software load for 603 processors:
27795719Sbenno * (Code essentially from the 603e User Manual, Chapter 5, but
27895719Sbenno * corrected a lot.)
27995719Sbenno */
28095719Sbenno
28196773Sbenno	.globl	CNAME(tlbimiss),CNAME(tlbimsize)
28296773SbennoCNAME(tlbimiss):
28395719Sbenno#ifdef PMAPDEBUG
28495719Sbenno	mfspr	2,SPR_IMISS		/* exception address */
28595719Sbenno	li	1,24			/* get rid of the lower */
28695719Sbenno	srw	2,2,1			/*   24 bits */
28795719Sbenno	li	1,1			/* Load 1 */
28895719Sbenno	cmpl	2,1,1			/* is it > 16MB */
28995719Sbenno	blt	99f			/* nope, skip saving these SPRs */
29095719Sbenno	li	1,0xc0			/* arbitrary */
29195719Sbenno	mfspr	2,SPR_HASH1
29295719Sbenno	stw	2,0(1)
29395719Sbenno	mfspr	2,SPR_HASH2
29495719Sbenno	stw	2,4(1)
29595719Sbenno	mfspr	2,SPR_IMISS
29695719Sbenno	stw	2,8(1)
29795719Sbenno	mfspr	2,SPR_ICMP
29895719Sbenno	stw	2,12(1)
29995719Sbenno99:
30095719Sbenno#endif /* PMAPDEBUG */
30195719Sbenno	mfspr	2,SPR_HASH1		/* get first pointer */
30295719Sbenno	li	1,8
30395719Sbenno	mfctr	0			/* save counter */
30495719Sbenno	mfspr	3,SPR_ICMP		/* get first compare value */
30595719Sbenno	addi	2,2,-8			/* predec pointer */
30695719Sbenno1:
30795719Sbenno	mtctr	1			/* load counter */
30895719Sbenno2:
30995719Sbenno	lwzu	1,8(2)			/* get next pte */
31095719Sbenno	cmpl	0,1,3			/* see if found pte */
31195719Sbenno	bdneq	2b			/* loop if not eq */
31295719Sbenno	bne	3f			/* not found */
31395719Sbenno	lwz	1,4(2)			/* load tlb entry lower word */
31495719Sbenno	andi.	3,1,8			/* check G-bit */
31595719Sbenno	bne	4f			/* if guarded, take ISI */
31695719Sbenno	mtctr	0			/* restore counter */
31795719Sbenno	mfspr	0,SPR_IMISS		/* get the miss address for the tlbli */
31895719Sbenno	mfsrr1	3			/* get the saved cr0 bits */
31995719Sbenno	mtcrf	0x80,3			/* and restore */
32095719Sbenno	ori	1,1,0x100		/* set the reference bit */
32195719Sbenno	mtspr	SPR_RPA,1		/* set the pte */
32295719Sbenno	srwi	1,1,8			/* get byte 7 of pte */
32395719Sbenno	tlbli	0			/* load the itlb */
32495719Sbenno	stb	1,6(2)			/* update page table */
32595719Sbenno	rfi
32695719Sbenno
32795719Sbenno3:	/* not found in pteg */
32895719Sbenno	andi.	1,3,0x40		/* have we already done second hash? */
32995719Sbenno	bne	5f
33095719Sbenno	mfspr	2,SPR_HASH2		/* get the second pointer */
33195719Sbenno	ori	3,3,0x40		/* change the compare value */
33295719Sbenno	li	1,8
33395719Sbenno	addi	2,2,-8			/* predec pointer */
33495719Sbenno	b	1b
33595719Sbenno4:	/* guarded */
33695719Sbenno	mfsrr1	3
33795719Sbenno	andi.	2,3,0xffff		/* clean upper srr1 */
33895719Sbenno	oris	2,2,0x8000000@h		/* set srr<4> to flag prot violation */
33995719Sbenno	b	6f
34095719Sbenno5:	/* not found anywhere */
34195719Sbenno	mfsrr1	3
34295719Sbenno	andi.	2,3,0xffff		/* clean upper srr1 */
34395719Sbenno	oris	2,2,0x40000000@h	/* set srr1<1> to flag pte not found */
34495719Sbenno6:
34595719Sbenno	mtctr	0			/* restore counter */
34695719Sbenno	mtsrr1	2
34795719Sbenno	mfmsr	0
34895719Sbenno	xoris	0,0,0x20000@h		/* flip the msr<tgpr> bit */
34995719Sbenno	mtcrf	0x80,3			/* restore cr0 */
35095719Sbenno	mtmsr	0			/* now with native gprs */
35195719Sbenno	isync
35295719Sbenno	ba	EXC_ISI
35396773SbennoCNAME(tlbimsize) = .-CNAME(tlbimiss)
35495719Sbenno
35596773Sbenno	.globl	CNAME(tlbdlmiss),CNAME(tlbdlmsize)
35696773SbennoCNAME(tlbdlmiss):
35795719Sbenno	mfspr	2,SPR_HASH1		/* get first pointer */
35895719Sbenno	li	1,8
35995719Sbenno	mfctr	0			/* save counter */
36095719Sbenno	mfspr	3,SPR_DCMP		/* get first compare value */
36195719Sbenno	addi	2,2,-8			/* predec pointer */
36295719Sbenno1:
36395719Sbenno	mtctr	1			/* load counter */
36495719Sbenno2:
36595719Sbenno	lwzu	1,8(2)			/* get next pte */
36695719Sbenno	cmpl	0,1,3			/* see if found pte */
36795719Sbenno	bdneq	2b			/* loop if not eq */
36895719Sbenno	bne	3f			/* not found */
36995719Sbenno	lwz	1,4(2)			/* load tlb entry lower word */
37095719Sbenno	mtctr	0			/* restore counter */
37195719Sbenno	mfspr	0,SPR_DMISS		/* get the miss address for the tlbld */
37295719Sbenno	mfsrr1	3			/* get the saved cr0 bits */
37395719Sbenno	mtcrf	0x80,3			/* and restore */
37495719Sbenno	ori	1,1,0x100		/* set the reference bit */
37595719Sbenno	mtspr	SPR_RPA,1			/* set the pte */
37695719Sbenno	srwi	1,1,8			/* get byte 7 of pte */
37795719Sbenno	tlbld	0			/* load the dtlb */
37895719Sbenno	stb	1,6(2)			/* update page table */
37995719Sbenno	rfi
38095719Sbenno
38195719Sbenno3:	/* not found in pteg */
38295719Sbenno	andi.	1,3,0x40		/* have we already done second hash? */
38395719Sbenno	bne	5f
38495719Sbenno	mfspr	2,SPR_HASH2		/* get the second pointer */
38595719Sbenno	ori	3,3,0x40		/* change the compare value */
38695719Sbenno	li	1,8
38795719Sbenno	addi	2,2,-8			/* predec pointer */
38895719Sbenno	b	1b
38995719Sbenno5:	/* not found anywhere */
39095719Sbenno	mfsrr1	3
39195719Sbenno	lis	1,0x40000000@h		/* set dsisr<1> to flag pte not found */
39295719Sbenno	mtctr	0			/* restore counter */
39395719Sbenno	andi.	2,3,0xffff		/* clean upper srr1 */
39495719Sbenno	mtsrr1	2
39595719Sbenno	mtdsisr	1			/* load the dsisr */
39695719Sbenno	mfspr	1,SPR_DMISS		/* get the miss address */
39795719Sbenno	mtdar	1			/* put in dar */
39895719Sbenno	mfmsr	0
39995719Sbenno	xoris	0,0,0x20000@h		/* flip the msr<tgpr> bit */
40095719Sbenno	mtcrf	0x80,3			/* restore cr0 */
40195719Sbenno	mtmsr	0			/* now with native gprs */
40295719Sbenno	isync
40395719Sbenno	ba	EXC_DSI
40496773SbennoCNAME(tlbdlmsize) = .-CNAME(tlbdlmiss)
40595719Sbenno
40696773Sbenno	.globl	CNAME(tlbdsmiss),CNAME(tlbdsmsize)
40796773SbennoCNAME(tlbdsmiss):
40895719Sbenno	mfspr	2,SPR_HASH1		/* get first pointer */
40995719Sbenno	li	1,8
41095719Sbenno	mfctr	0			/* save counter */
41195719Sbenno	mfspr	3,SPR_DCMP		/* get first compare value */
41295719Sbenno	addi	2,2,-8			/* predec pointer */
41395719Sbenno1:
41495719Sbenno	mtctr	1			/* load counter */
41595719Sbenno2:
41695719Sbenno	lwzu	1,8(2)			/* get next pte */
41795719Sbenno	cmpl	0,1,3			/* see if found pte */
41895719Sbenno	bdneq	2b			/* loop if not eq */
41995719Sbenno	bne	3f			/* not found */
42095719Sbenno	lwz	1,4(2)			/* load tlb entry lower word */
42195719Sbenno	andi.	3,1,0x80		/* check the C-bit */
42295719Sbenno	beq	4f
42395719Sbenno5:
42495719Sbenno	mtctr	0			/* restore counter */
42595719Sbenno	mfspr	0,SPR_DMISS		/* get the miss address for the tlbld */
42695719Sbenno	mfsrr1	3			/* get the saved cr0 bits */
42795719Sbenno	mtcrf	0x80,3			/* and restore */
42895719Sbenno	mtspr	SPR_RPA,1		/* set the pte */
42995719Sbenno	tlbld	0			/* load the dtlb */
43095719Sbenno	rfi
43195719Sbenno
43295719Sbenno3:	/* not found in pteg */
43395719Sbenno	andi.	1,3,0x40		/* have we already done second hash? */
43495719Sbenno	bne	5f
43595719Sbenno	mfspr	2,SPR_HASH2		/* get the second pointer */
43695719Sbenno	ori	3,3,0x40		/* change the compare value */
43795719Sbenno	li	1,8
43895719Sbenno	addi	2,2,-8			/* predec pointer */
43995719Sbenno	b	1b
44095719Sbenno4:	/* found, but C-bit = 0 */
44195719Sbenno	rlwinm.	3,1,30,0,1		/* test PP */
44295719Sbenno	bge-	7f
44395719Sbenno	andi.	3,1,1
44495719Sbenno	beq+	8f
44595719Sbenno9:	/* found, but protection violation (PP==00)*/
44695719Sbenno	mfsrr1	3
44795719Sbenno	lis	1,0xa000000@h		/* indicate protection violation
44895719Sbenno					   on store */
44995719Sbenno	b	1f
45095719Sbenno7:	/* found, PP=1x */
45195719Sbenno	mfspr	3,SPR_DMISS		/* get the miss address */
45295719Sbenno	mfsrin	1,3			/* get the segment register */
45395719Sbenno	mfsrr1	3
45495719Sbenno	rlwinm	3,3,18,31,31		/* get PR-bit */
45595719Sbenno	rlwnm.	2,2,3,1,1		/* get the key */
45695719Sbenno	bne-	9b			/* protection violation */
45795719Sbenno8:	/* found, set reference/change bits */
45895719Sbenno	lwz	1,4(2)			/* reload tlb entry */
45995719Sbenno	ori	1,1,0x180
46095719Sbenno	sth	1,6(2)
46195719Sbenno	b	5b
46295719Sbenno5:	/* not found anywhere */
46395719Sbenno	mfsrr1	3
46495719Sbenno	lis	1,0x42000000@h		/* set dsisr<1> to flag pte not found */
46595719Sbenno					/* dsisr<6> to flag store */
46695719Sbenno1:
46795719Sbenno	mtctr	0			/* restore counter */
46895719Sbenno	andi.	2,3,0xffff		/* clean upper srr1 */
46995719Sbenno	mtsrr1	2
47095719Sbenno	mtdsisr	1			/* load the dsisr */
47195719Sbenno	mfspr	1,SPR_DMISS		/* get the miss address */
47295719Sbenno	mtdar	1			/* put in dar */
47395719Sbenno	mfmsr	0
47495719Sbenno	xoris	0,0,0x20000@h		/* flip the msr<tgpr> bit */
47595719Sbenno	mtcrf	0x80,3			/* restore cr0 */
47695719Sbenno	mtmsr	0			/* now with native gprs */
47795719Sbenno	isync
47895719Sbenno	ba	EXC_DSI
47996773SbennoCNAME(tlbdsmsize) = .-CNAME(tlbdsmiss)
48095719Sbenno
48195719Sbenno#if defined(DDB) || defined(KGDB)
48295719Sbenno#define	ddbsave	0xde0		/* primary save area for DDB */
48395719Sbenno/*
48495719Sbenno * In case of DDB we want a separate trap catcher for it
48595719Sbenno */
48695719Sbenno	.local	ddbstk
48795719Sbenno	.comm	ddbstk,INTSTK,8		/* ddb stack */
48895719Sbenno
48996773Sbenno	.globl	CNAME(ddblow),CNAME(ddbsize)
49096773SbennoCNAME(ddblow):
49195719Sbenno	mtsprg	1,1			/* save SP */
49295719Sbenno	stmw	28,ddbsave(0)		/* free r28-r31 */
49395719Sbenno	mflr	28			/* save LR */
49495719Sbenno	mfcr	29			/* save CR */
49595719Sbenno	lis	1,ddbstk+INTSTK@ha	/* get new SP */
49695719Sbenno	addi	1,1,ddbstk+INTSTK@l
49795719Sbenno	bla	ddbtrap
49896773SbennoCNAME(ddbsize) = .-CNAME(ddblow)
49995719Sbenno#endif	/* DDB | KGDB */
50095719Sbenno
50195719Sbenno#ifdef IPKDB
50295719Sbenno#define	ipkdbsave	0xde0		/* primary save area for IPKDB */
50395719Sbenno/*
50495719Sbenno * In case of IPKDB we want a separate trap catcher for it
50595719Sbenno */
50695719Sbenno
50795719Sbenno	.local	ipkdbstk
50895719Sbenno	.comm	ipkdbstk,INTSTK,8		/* ipkdb stack */
50995719Sbenno
51096773Sbenno	.globl	CNAME(ipkdblow),CNAME(ipkdbsize)
51196773SbennoCNAME(ipkdblow):
51295719Sbenno	mtsprg	1,1			/* save SP */
51395719Sbenno	stmw	28,ipkdbsave(0)		/* free r28-r31 */
51495719Sbenno	mflr	28			/* save LR */
51595719Sbenno	mfcr	29			/* save CR */
51695719Sbenno	lis	1,ipkdbstk+INTSTK@ha	/* get new SP */
51795719Sbenno	addi	1,1,ipkdbstk+INTSTK@l
51895719Sbenno	bla	ipkdbtrap
51996773SbennoCNAME(ipkdbsize) = .-CNAME(ipkdblow)
52095719Sbenno#endif	/* IPKDB */
52195719Sbenno
52295719Sbenno/*
52395719Sbenno * FRAME_SETUP assumes:
52495719Sbenno *	SPRG1		SP (1)
52595719Sbenno *	savearea	r28-r31,DAR,DSISR	(DAR & DSISR only for DSI traps)
52695719Sbenno *	28		LR
52795719Sbenno *	29		CR
52895719Sbenno *	1		kernel stack
52995719Sbenno *	LR		trap type
53095719Sbenno *	SRR0/1		as at start of trap
53195719Sbenno */
53295719Sbenno#define	FRAME_SETUP(savearea)						\
53395719Sbenno/* Have to enable translation to allow access of kernel stack: */	\
53495719Sbenno	mfsrr0	30;							\
53595719Sbenno	mfsrr1	31;							\
53695719Sbenno	stmw	30,savearea+24(0);					\
53795719Sbenno	mfmsr	30;							\
538103608Sgrehan	ori	30,30,(PSL_DR|PSL_IR|PSL_RI)@l;				\
53995719Sbenno	mtmsr	30;							\
54095719Sbenno	isync;								\
54195719Sbenno	mfsprg	31,1;							\
54295719Sbenno	stwu	31,-FRAMELEN(1);					\
54395719Sbenno	stw	0,FRAME_0+8(1);						\
54495719Sbenno	stw	31,FRAME_1+8(1);					\
54595719Sbenno	stw	28,FRAME_LR+8(1);					\
54695719Sbenno	stw	29,FRAME_CR+8(1);					\
54795719Sbenno	lmw	28,savearea(0);						\
54895719Sbenno	stmw	2,FRAME_2+8(1);						\
54995719Sbenno	lmw	28,savearea+16(0);					\
55095719Sbenno	mfxer	3;							\
55195719Sbenno	mfctr	4;							\
55295719Sbenno	mflr	5;							\
55395719Sbenno	andi.	5,5,0xff00;						\
55495719Sbenno	stw	3,FRAME_XER+8(1);					\
55595719Sbenno	stw	4,FRAME_CTR+8(1);					\
55695719Sbenno	stw	5,FRAME_EXC+8(1);					\
55795719Sbenno	stw	28,FRAME_DAR+8(1);					\
55895719Sbenno	stw	29,FRAME_DSISR+8(1);					\
55995719Sbenno	stw	30,FRAME_SRR0+8(1);					\
56095719Sbenno	stw	31,FRAME_SRR1+8(1)
56195719Sbenno
56295719Sbenno#define	FRAME_LEAVE(savearea)						\
56395719Sbenno/* Now restore regs: */							\
56495719Sbenno	lwz	2,FRAME_SRR0+8(1);					\
56595719Sbenno	lwz	3,FRAME_SRR1+8(1);					\
56695719Sbenno	lwz	4,FRAME_CTR+8(1);					\
56795719Sbenno	lwz	5,FRAME_XER+8(1);					\
56895719Sbenno	lwz	6,FRAME_LR+8(1);					\
56995719Sbenno	lwz	7,FRAME_CR+8(1);					\
57095719Sbenno	stw	2,savearea(0);						\
57195719Sbenno	stw	3,savearea+4(0);					\
57295719Sbenno	mtctr	4;							\
57395719Sbenno	mtxer	5;							\
57495719Sbenno	mtlr	6;							\
57595719Sbenno	mtsprg	1,7;			/* save cr */			\
57695719Sbenno	lmw	2,FRAME_2+8(1);						\
57795719Sbenno	lwz	0,FRAME_0+8(1);						\
57895719Sbenno	lwz	1,FRAME_1+8(1);						\
57995719Sbenno	mtsprg	2,2;			/* save r2 & r3 */		\
58095719Sbenno	mtsprg	3,3;							\
58195719Sbenno/* Disable translation, machine check and recoverability: */		\
58295719Sbenno	mfmsr	2;							\
583103608Sgrehan	andi.	2,2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l;		\
58495719Sbenno	mtmsr	2;							\
58595719Sbenno	isync;								\
58695719Sbenno/* Decide whether we return to user mode: */				\
58795719Sbenno	lwz	3,savearea+4(0);					\
58895719Sbenno	mtcr	3;							\
58995719Sbenno	bc	4,17,1f;		/* branch if PSL_PR is false */	\
59095719Sbenno/* Restore user & kernel access SR: */					\
59195719Sbenno	mfsprg	2,0;							\
59295719Sbenno	lwz	2,PC_CURPMAP(2);					\
59396253Sbenno	cmpwi	cr4,2,0;		/* is curpmap NULL? */		\
59496253Sbenno	bne	cr4,2f;							\
59596253Sbenno	lis	3,cpassert@ha;		/* if it is, panic */		\
59696253Sbenno	addi	3,3,cpassert@l;						\
59796253Sbenno	b	panic;							\
59896253Sbenno2:	lwz	3,PM_SR+0(2);						\
59995719Sbenno	mtsr	0,3;			/* restore SR0 */		\
60095719Sbenno	lwz	3,PM_SR+4(2);						\
60195719Sbenno	mtsr	1,3;			/* restore SR1 */		\
60295719Sbenno	lwz	3,PM_SR+8(2);						\
60395719Sbenno	mtsr	2,3;			/* restore SR2 */		\
60495719Sbenno	lwz	3,PM_SR+12(2);						\
60595719Sbenno	mtsr	3,3;			/* restore SR3 */		\
60695719Sbenno	lwz	3,PM_SR+16(2);						\
60795719Sbenno	mtsr	4,3;			/* restore SR4 */		\
60895719Sbenno	lwz	3,PM_SR+20(2);						\
60995719Sbenno	mtsr	5,3;			/* restore SR5 */		\
61095719Sbenno	lwz	3,PM_SR+24(2);						\
61195719Sbenno	mtsr	6,3;			/* restore SR6 */		\
61295719Sbenno	lwz	3,PM_SR+28(2);						\
61395719Sbenno	mtsr	7,3;			/* restore SR7 */		\
61495719Sbenno	lwz	3,PM_USRSR(2);						\
61595719Sbenno	mtsr	USER_SR,3;						\
61695719Sbenno	lwz	3,PM_KERNELSR(2);					\
61795719Sbenno	mtsr	KERNEL_SR,3;						\
61895719Sbenno1:	mfsprg	2,1;			/* restore cr */		\
61995719Sbenno	mtcr	2;							\
62095719Sbenno	lwz	2,savearea(0);						\
62195719Sbenno	lwz	3,savearea+4(0);					\
62295719Sbenno	mtsrr0	2;							\
62395719Sbenno	mtsrr1	3;							\
62495719Sbenno	mfsprg	2,2;			/* restore r2 & r3 */		\
62595719Sbenno	mfsprg	3,3
62695719Sbenno
62795719Sbenno/*
62895719Sbenno * Preamble code for DSI/ISI traps
62995719Sbenno */
63095719Sbennodisitrap:
63195719Sbenno	lmw	30,disisave(0)
63295719Sbenno	stmw	30,tempsave(0)
63395719Sbenno	lmw	30,disisave+8(0)
63495719Sbenno	stmw	30,tempsave+8(0)
63595719Sbenno	mfdar	30
63695719Sbenno	mfdsisr	31
63795719Sbenno	stmw	30,tempsave+16(0)
63895719Sbennorealtrap:
63995719Sbenno/* Test whether we already had PR set */
64095719Sbenno	mfsrr1	1
64195719Sbenno	mtcr	1
64295719Sbenno	mfsprg	1,1			/* restore SP (might have been
64395719Sbenno					   overwritten) */
64495719Sbenno	bc	4,17,s_trap		/* branch if PSL_PR is false */
64595719Sbenno	mfsprg	31,0
64695719Sbenno	lwz	1,PC_CURPCB(31)
64795719Sbenno
64895719Sbenno/*
64995719Sbenno * Now the common trap catching code.
65095719Sbenno */
65195719Sbennos_trap:
65295719Sbenno/* First have to enable KERNEL mapping */
65395719Sbenno	lis	31,KERNEL_SEGMENT@h
65495719Sbenno	ori	31,31,KERNEL_SEGMENT@l
65595719Sbenno	mtsr	KERNEL_SR,31
65695719Sbenno/* Obliterate SRs so BAT spills work correctly */
65795719Sbenno	lis	31,EMPTY_SEGMENT@h
65895719Sbenno	ori	31,31,EMPTY_SEGMENT@l
65995719Sbenno	mtsr	0,31
66095719Sbenno	mtsr	1,31
66195719Sbenno	mtsr	2,31
66295719Sbenno	mtsr	3,31
66395719Sbenno	mtsr	4,31
66495719Sbenno	mtsr	5,31
66595719Sbenno	mtsr	6,31
66695719Sbenno	mtsr	7,31
66795719Sbenno	FRAME_SETUP(tempsave)
66895719Sbenno/* Now we can recover interrupts again: */
66999032Sbenno#if 0
67095719Sbenno	mfmsr	7
67195719Sbenno	ori	7,7,(PSL_EE|PSL_ME|PSL_RI)@l
67295719Sbenno	mtmsr	7
67395719Sbenno	isync
67499032Sbenno#endif
67599032Sbenno/* Call C interrupt dispatcher: */
67695719Sbennotrapagain:
67795719Sbenno	addi	3,1,8
67899032Sbenno	bl	CNAME(powerpc_interrupt)
67996773Sbenno	.globl	CNAME(trapexit)
68096773SbennoCNAME(trapexit):
68199032Sbenno
68295719Sbenno/* Disable interrupts: */
68395719Sbenno	mfmsr	3
68495719Sbenno	andi.	3,3,~PSL_EE@l
68595719Sbenno	mtmsr	3
68695719Sbenno/* Test AST pending: */
68795719Sbenno	lwz	5,FRAME_SRR1+8(1)
68895719Sbenno	mtcr	5
68995719Sbenno	bc	4,17,1f			/* branch if PSL_PR is false */
69099032Sbenno
69199032Sbenno	mfsprg	3, 0			/* get per-CPU pointer */
69299032Sbenno	lwz	4, PC_CURTHREAD(3)	/* deref to get curthread */
69399032Sbenno	lwz	3, TD_KSE(4)		/* deref to get current KSE */
69499032Sbenno	lwz	4, KE_FLAGS(3)		/* get KSE flags value */
69599032Sbenno	andi.	4,4,KEF_ASTPENDING|KEF_NEEDRESCHED
69695719Sbenno	beq	1f
69799032Sbenno	mfmsr	3			/* re-enable interrupts */
69899032Sbenno	ori	3,3,PSL_EE@l
69999032Sbenno	mtmsr	3
70099032Sbenno	isync
70199032Sbenno	addi	3,1,8
702103608Sgrehan	bl	CNAME(ast)
70399032Sbenno	b	trapexit		/* test ast ret value ? */
70495719Sbenno1:
70595719Sbenno	FRAME_LEAVE(tempsave)
70695719Sbenno	rfi
70795719Sbenno
70895719Sbenno/*
70995719Sbenno * DSI second stage fault handler
71095719Sbenno */
71195719Sbennos_dsitrap:
71295719Sbenno	mfdsisr	31			/* test whether this may be a
71395719Sbenno					   spill fault */
71495719Sbenno	mtcr	31
71595719Sbenno	mtsprg	1,1			/* save SP */
71695719Sbenno	bc	4,1,disitrap		/* branch if table miss is false */
71795719Sbenno	lis	1,spillstk+SPILLSTK@ha
71895719Sbenno	addi	1,1,spillstk+SPILLSTK@l	/* get spill stack */
71995719Sbenno	stwu	1,-SPFRAMELEN(1)
72095719Sbenno	stw	0,SPFRAME_R0(1)		/* save non-volatile registers */
72195719Sbenno	stw	3,SPFRAME_R3(1)
72295719Sbenno	stw	4,SPFRAME_R4(1)
72395719Sbenno	stw	5,SPFRAME_R5(1)
72495719Sbenno	stw	6,SPFRAME_R6(1)
72595719Sbenno	stw	7,SPFRAME_R7(1)
72695719Sbenno	stw	8,SPFRAME_R8(1)
72795719Sbenno	stw	9,SPFRAME_R9(1)
72895719Sbenno	stw	10,SPFRAME_R10(1)
72995719Sbenno	stw	11,SPFRAME_R11(1)
73095719Sbenno	stw	12,SPFRAME_R12(1)
73195719Sbenno	mflr	30			/* save trap type */
73295719Sbenno	mfctr	31			/* & CTR */
73395719Sbenno	mfdar	3
73495719Sbennos_pte_spill:
73596773Sbenno	bl	CNAME(pmap_pte_spill)	/* try a spill */
73695719Sbenno	or.	3,3,3
73795719Sbenno	mtctr	31			/* restore CTR */
73895719Sbenno	mtlr	30			/* and trap type */
73995719Sbenno	mfsprg	31,2			/* get saved XER */
74095719Sbenno	mtxer	31			/* restore XER */
74195719Sbenno	lwz	12,SPFRAME_R12(1)	/* restore non-volatile registers */
74295719Sbenno	lwz	11,SPFRAME_R11(1)
74395719Sbenno	lwz	10,SPFRAME_R10(1)
74495719Sbenno	lwz	9,SPFRAME_R9(1)
74595719Sbenno	lwz	8,SPFRAME_R8(1)
74695719Sbenno	lwz	7,SPFRAME_R7(1)
74795719Sbenno	lwz	6,SPFRAME_R6(1)
74895719Sbenno	lwz	5,SPFRAME_R5(1)
74995719Sbenno	lwz	4,SPFRAME_R4(1)
75095719Sbenno	lwz	3,SPFRAME_R3(1)
75195719Sbenno	lwz	0,SPFRAME_R0(1)
75295719Sbenno	beq	disitrap
75395719Sbenno	mfsprg	1,1			/* restore SP */
75495719Sbenno	mtcr	29			/* restore CR */
75595719Sbenno	mtlr	28			/* restore LR */
75695719Sbenno	lmw	28,disisave(0)		/* restore r28-r31 */
75795719Sbenno	rfi				/* return to trapped code */
75895719Sbenno
75995719Sbenno/*
76095719Sbenno * ISI second stage fault handler
76195719Sbenno */
76295719Sbennos_isitrap:
76395719Sbenno	mfsrr1	31			/* test whether this may be a
76495719Sbenno					   spill fault */
76595719Sbenno	mtcr	31
76695719Sbenno	mtsprg	1,1			/* save SP */
76795719Sbenno	bc	4,1,disitrap		/* branch if table miss is false */
76895719Sbenno	lis	1,spillstk+SPILLSTK@ha
76995719Sbenno	addi	1,1,spillstk+SPILLSTK@l	/* get spill stack */
77095719Sbenno	stwu	1,-SPFRAMELEN(1)
77195719Sbenno	stw	0,SPFRAME_R0(1)		/* save non-volatile registers */
77295719Sbenno	stw	3,SPFRAME_R3(1)
77395719Sbenno	stw	4,SPFRAME_R4(1)
77495719Sbenno	stw	5,SPFRAME_R5(1)
77595719Sbenno	stw	6,SPFRAME_R6(1)
77695719Sbenno	stw	7,SPFRAME_R7(1)
77795719Sbenno	stw	8,SPFRAME_R8(1)
77895719Sbenno	stw	9,SPFRAME_R9(1)
77995719Sbenno	stw	10,SPFRAME_R10(1)
78095719Sbenno	stw	11,SPFRAME_R11(1)
78195719Sbenno	stw	12,SPFRAME_R12(1)
78295719Sbenno	mfxer	30			/* save XER */
78395719Sbenno	mtsprg	2,30
78495719Sbenno	mflr	30			/* save trap type */
78595719Sbenno	mfctr	31			/* & ctr */
78695719Sbenno	mfsrr0	3
78795719Sbenno	b	s_pte_spill		/* above */
78895719Sbenno
78995719Sbenno
79095719Sbenno#if defined(DDB)
79195719Sbenno/*
79295719Sbenno * Deliberate entry to ddbtrap
79395719Sbenno */
79496773Sbenno	.globl	CNAME(ddb_trap)
79596773SbennoCNAME(ddb_trap):
79695719Sbenno	mtsprg	1,1
79795719Sbenno	mfmsr	3
79895719Sbenno	mtsrr1	3
79995719Sbenno	andi.	3,3,~(PSL_EE|PSL_ME)@l
80095719Sbenno	mtmsr	3			/* disable interrupts */
80195719Sbenno	isync
80295719Sbenno	stmw	28,ddbsave(0)
80395719Sbenno	mflr	28
80495719Sbenno	li	29,EXC_BPT
80595719Sbenno	mtlr	29
80695719Sbenno	mfcr	29
80795719Sbenno	mtsrr0	28
80895719Sbenno#endif /* DDB */
80995719Sbenno
81095719Sbenno#if defined(DDB) || defined(KGDB)
81195719Sbenno/*
81295719Sbenno * Now the ddb trap catching code.
81395719Sbenno */
81495719Sbennoddbtrap:
81595719Sbenno	FRAME_SETUP(ddbsave)
81695719Sbenno/* Call C trap code: */
81795719Sbenno	addi	3,1,8
81896773Sbenno	bl	CNAME(ddb_trap_glue)
81995719Sbenno	or.	3,3,3
82095719Sbenno	bne	ddbleave
82195719Sbenno/* This wasn't for DDB, so switch to real trap: */
82295719Sbenno	lwz	3,FRAME_EXC+8(1)	/* save exception */
82395719Sbenno	stw	3,ddbsave+8(0)
82495719Sbenno	FRAME_LEAVE(ddbsave)
82595719Sbenno	mtsprg	1,1			/* prepare for entrance to realtrap */
82695719Sbenno	stmw	28,tempsave(0)
82795719Sbenno	mflr	28
82895719Sbenno	mfcr	29
82995719Sbenno	lwz	31,ddbsave+8(0)
83095719Sbenno	mtlr	31
83195719Sbenno	b	realtrap
83295719Sbennoddbleave:
83395719Sbenno	FRAME_LEAVE(ddbsave)
83495719Sbenno	rfi
83595719Sbenno#endif /* DDB || KGDB */
83695719Sbenno
83795719Sbenno#ifdef IPKDB
83895719Sbenno/*
83995719Sbenno * Deliberate entry to ipkdbtrap
84095719Sbenno */
84196773Sbenno	.globl	CNAME(ipkdb_trap)
84296773SbennoCNAME(ipkdb_trap):
84395719Sbenno	mtsprg	1,1
84495719Sbenno	mfmsr	3
84595719Sbenno	mtsrr1	3
84695719Sbenno	andi.	3,3,~(PSL_EE|PSL_ME)@l
84795719Sbenno	mtmsr	3			/* disable interrupts */
84895719Sbenno	isync
84995719Sbenno	stmw	28,ipkdbsave(0)
85095719Sbenno	mflr	28
85195719Sbenno	li	29,EXC_BPT
85295719Sbenno	mtlr	29
85395719Sbenno	mfcr	29
85495719Sbenno	mtsrr0	28
85595719Sbenno
85695719Sbenno/*
85795719Sbenno * Now the ipkdb trap catching code.
85895719Sbenno */
85995719Sbennoipkdbtrap:
86095719Sbenno	FRAME_SETUP(ipkdbsave)
86195719Sbenno/* Call C trap code: */
86295719Sbenno	addi	3,1,8
86396773Sbenno	bl	CNAME(ipkdb_trap_glue)
86495719Sbenno	or.	3,3,3
86595719Sbenno	bne	ipkdbleave
86695719Sbenno/* This wasn't for IPKDB, so switch to real trap: */
86795719Sbenno	lwz	3,FRAME_EXC+8(1)	/* save exception */
86895719Sbenno	stw	3,ipkdbsave+8(0)
86995719Sbenno	FRAME_LEAVE(ipkdbsave)
87095719Sbenno	mtsprg	1,1			/* prepare for entrance to realtrap */
87195719Sbenno	stmw	28,tempsave(0)
87295719Sbenno	mflr	28
87395719Sbenno	mfcr	29
87495719Sbenno	lwz	31,ipkdbsave+8(0)
87595719Sbenno	mtlr	31
87695719Sbenno	b	realtrap
87795719Sbennoipkdbleave:
87895719Sbenno	FRAME_LEAVE(ipkdbsave)
87995719Sbenno	rfi
88095719Sbenno
88195719Sbennoipkdbfault:
88295719Sbenno	ba	_ipkdbfault
88395719Sbenno_ipkdbfault:
88495719Sbenno	mfsrr0	3
88595719Sbenno	addi	3,3,4
88695719Sbenno	mtsrr0	3
88795719Sbenno	li	3,-1
88895719Sbenno	rfi
88995719Sbenno
89095719Sbenno/*
89195719Sbenno * int ipkdbfbyte(unsigned char *p)
89295719Sbenno */
89396773Sbenno	.globl	CNAME(ipkdbfbyte)
89496773SbennoCNAME(ipkdbfbyte):
89595719Sbenno	li	9,EXC_DSI		/* establish new fault routine */
89695719Sbenno	lwz	5,0(9)
89795719Sbenno	lis	6,ipkdbfault@ha
89895719Sbenno	lwz	6,ipkdbfault@l(6)
89995719Sbenno	stw	6,0(9)
90095719Sbenno#ifdef	IPKDBUSERHACK
90196773Sbenno	lis	8,CNAME(ipkdbsr)@ha
90296773Sbenno	lwz	8,CNAME(ipkdbsr)@l(8)
90395719Sbenno	mtsr	USER_SR,8
90495719Sbenno	isync
90595719Sbenno#endif
90695719Sbenno	dcbst	0,9			/* flush data... */
90795719Sbenno	sync
90895719Sbenno	icbi	0,9			/* and instruction caches */
90995719Sbenno	lbz	3,0(3)			/* fetch data */
91095719Sbenno	stw	5,0(9)			/* restore previous fault handler */
91195719Sbenno	dcbst	0,9			/* and flush data... */
91295719Sbenno	sync
91395719Sbenno	icbi	0,9			/* and instruction caches */
91495719Sbenno	blr
91595719Sbenno
91695719Sbenno/*
91795719Sbenno * int ipkdbsbyte(unsigned char *p, int c)
91895719Sbenno */
91996773Sbenno	.globl	CNAME(ipkdbsbyte)
92096773SbennoCNAME(ipkdbsbyte):
92195719Sbenno	li	9,EXC_DSI		/* establish new fault routine */
92295719Sbenno	lwz	5,0(9)
92395719Sbenno	lis	6,ipkdbfault@ha
92495719Sbenno	lwz	6,ipkdbfault@l(6)
92595719Sbenno	stw	6,0(9)
92695719Sbenno#ifdef	IPKDBUSERHACK
92796773Sbenno	lis	8,CNAME(ipkdbsr)@ha
92896773Sbenno	lwz	8,CNAME(ipkdbsr)@l(8)
92995719Sbenno	mtsr	USER_SR,8
93095719Sbenno	isync
93195719Sbenno#endif
93295719Sbenno	dcbst	0,9			/* flush data... */
93395719Sbenno	sync
93495719Sbenno	icbi	0,9			/* and instruction caches */
93595719Sbenno	mr	6,3
93695719Sbenno	xor	3,3,3
93795719Sbenno	stb	4,0(6)
93895719Sbenno	dcbst	0,6			/* Now do appropriate flushes
93995719Sbenno					   to data... */
94095719Sbenno	sync
94195719Sbenno	icbi	0,6			/* and instruction caches */
94295719Sbenno	stw	5,0(9)			/* restore previous fault handler */
94395719Sbenno	dcbst	0,9			/* and flush data... */
94495719Sbenno	sync
94595719Sbenno	icbi	0,9			/* and instruction caches */
94695719Sbenno	blr
94795719Sbenno#endif	/* IPKDB */
948