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