Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc/powerpc MP version of trap routines.



details:   https://anonhg.NetBSD.org/src/rev/50be5a5073b3
branches:  trunk
changeset: 506881:50be5a5073b3
user:      tsubai <tsubai%NetBSD.org@localhost>
date:      Wed Mar 07 08:05:07 2001 +0000

description:
MP version of trap routines.

diffstat:

 sys/arch/powerpc/powerpc/trap_subr_mp.S |  983 ++++++++++++++++++++++++++++++++
 1 files changed, 983 insertions(+), 0 deletions(-)

diffs (truncated from 987 to 300 lines):

diff -r d333edad1570 -r 50be5a5073b3 sys/arch/powerpc/powerpc/trap_subr_mp.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/powerpc/powerpc/trap_subr_mp.S   Wed Mar 07 08:05:07 2001 +0000
@@ -0,0 +1,983 @@
+/*     $NetBSD: trap_subr_mp.S,v 1.1 2001/03/07 08:05:07 tsubai Exp $  */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * NOTICE: This is not a standalone file.  to use it, #include it in
+ * your port's locore.S, like so:
+ *
+ *     #include <powerpc/powerpc/trap_subr.S>
+ */
+
+/*
+ * This code gets copied to all the trap vectors
+ * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
+ * traps when using IPKDB).
+ */
+       .text
+       .globl  _C_LABEL(trapcode),_C_LABEL(trapsize)
+_C_LABEL(trapcode):
+       mtsprg  1,1                     /* save SP */
+       GET_CPUINFO(1)
+       stmw    28,CI_TEMPSAVE(1)       /* free r28-r31 */
+       mfsprg  1,1                     /* restore SP */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+/* Test whether we already had PR set */
+       mfsrr1  31
+       mtcr    31
+       bc      4,17,1f                 /* branch if PSL_PR is clear */
+       GET_CPUINFO(1)
+       lwz     1,CI_CURPCB(1)
+       addi    1,1,USPACE              /* stack is top of user struct */
+1:
+       bla     s_trap
+_C_LABEL(trapsize) = .-_C_LABEL(trapcode)
+
+/*
+ * For ALI: has to save DSISR and DAR
+ */
+       .globl  _C_LABEL(alitrap),_C_LABEL(alisize)
+_C_LABEL(alitrap):
+       mtsprg  1,1                     /* save SP */
+       GET_CPUINFO(1)
+       stmw    28,CI_TEMPSAVE(1)       /* free r28-r31 */
+       mfdar   30
+       mfdsisr 31
+       stmw    30,CI_TEMPSAVE+16(1)
+       mfsprg  1,1                     /* restore SP */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+/* Test whether we already had PR set */
+       mfsrr1  31
+       mtcr    31
+       bc      4,17,1f                 /* branch if PSL_PR is clear */
+       GET_CPUINFO(1)
+       lwz     1,CI_CURPCB(1)
+       addi    1,1,USPACE              /* stack is top of user struct */
+1:
+       bla     s_trap
+_C_LABEL(alisize) = .-_C_LABEL(alitrap)
+
+/*
+ * Similar to the above for DSI
+ * Has to handle BAT spills
+ * and standard pagetable spills
+ */
+       .globl  _C_LABEL(dsitrap),_C_LABEL(dsisize)
+_C_LABEL(dsitrap):
+       mtsprg  1,1
+       GET_CPUINFO(1)
+       stmw    28,CI_DISISAVE(1)       /* free r28-r31 */
+       mfsprg  1,1
+       mfcr    29                      /* save CR */
+       mfxer   30                      /* save XER */
+       mtsprg  2,30                    /* in SPRG2 */
+       mfsrr1  31                      /* test kernel mode */
+       mtcr    31
+       bc      12,17,1f                /* branch if PSL_PR is set */
+       mfdar   31                      /* get fault address */
+       rlwinm  31,31,7,25,28           /* get segment * 8 */
+
+       /* get batu */
+       addis   31,31,_C_LABEL(battable)@ha
+       lwz     30,_C_LABEL(battable)@l(31)
+       mtcr    30
+       bc      4,30,1f                 /* branch if supervisor valid is
+                                          false */
+       /* get batl */
+       lwz     31,_C_LABEL(battable)+4@l(31)
+/* We randomly use the highest two bat registers here */
+       mftb    28
+       andi.   28,28,1
+       bne     2f
+       mtdbatu 2,30
+       mtdbatl 2,31
+       b       3f
+2:
+       mtdbatu 3,30
+       mtdbatl 3,31
+3:
+       mfsprg  30,2                    /* restore XER */
+       mtxer   30
+       mtcr    29                      /* restore CR */
+       mtsprg  1,1
+       GET_CPUINFO(1)
+       lmw     28,CI_DISISAVE(1)       /* restore r28-r31 */
+       mfsprg  1,1
+       rfi                             /* return to trapped code */
+1:
+       mflr    28                      /* save LR */
+       bla     s_dsitrap
+_C_LABEL(dsisize) = .-_C_LABEL(dsitrap)
+
+/*
+ * Similar to the above for ISI
+ */
+       .globl  _C_LABEL(isitrap),_C_LABEL(isisize)
+_C_LABEL(isitrap):
+       mtsprg  1,1
+       GET_CPUINFO(1)
+       stmw    28,CI_DISISAVE(1)       /* free r28-r31 */
+       mfsprg  1,1
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+       mfsrr1  31                      /* test kernel mode */
+       mtcr    31
+       bc      12,17,1f                /* branch if PSL_PR is set */
+       mfsrr0  31                      /* get fault address */
+       rlwinm  31,31,7,25,28           /* get segment * 8 */
+
+       /* get batu */
+       addis   31,31,_C_LABEL(battable)@ha
+       lwz     30,_C_LABEL(battable)@l(31)
+       mtcr    30
+       bc      4,30,1f                 /* branch if supervisor valid is
+                                          false */
+       mtibatu 3,30
+
+       /* get batl */
+       lwz     30,_C_LABEL(battable)+4@l(31)
+       mtibatl 3,30
+
+       mtcr    29                      /* restore CR */
+       mtsprg  1,1
+       GET_CPUINFO(1)
+       lmw     28,CI_DISISAVE(1)       /* restore r28-r31 */
+       mfsprg  1,1
+       rfi                             /* return to trapped code */
+1:
+       bla     s_isitrap
+_C_LABEL(isisize)= .-_C_LABEL(isitrap)
+
+/*
+ * This one for the external interrupt handler.
+ */
+       .globl  _C_LABEL(extint),_C_LABEL(extsize)
+_C_LABEL(extint):
+       mtsprg  1,1                     /* save SP */
+       GET_CPUINFO(1)
+       stmw    28,CI_TEMPSAVE(1)       /* free r28-r31 */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+       mfxer   30                      /* save XER */
+       lwz     31,CI_INTRDEPTH(1)      /* were we already running on intstk? */
+       addic.  31,31,1
+       stw     31,CI_INTRDEPTH(1)
+       lwz     1,CI_INTSTK(1)          /* get interrupt stack */
+       beq     1f
+       mfsprg  1,1                     /* yes, get old SP */
+1:
+       ba      extintr
+_C_LABEL(extsize) = .-_C_LABEL(extint)
+
+/*
+ * And this one for the decrementer interrupt handler.
+ */
+       .globl  _C_LABEL(decrint),_C_LABEL(decrsize)
+_C_LABEL(decrint):
+       mtsprg  1,1                     /* save SP */
+       GET_CPUINFO(1)
+       stmw    28,CI_TEMPSAVE(1)       /* free r28-r31 */
+       mflr    28                      /* save LR */
+       mfcr    29                      /* save CR */
+       mfxer   30                      /* save XER */
+       lwz     31,CI_INTRDEPTH(1)      /* were we already running on intstk? */
+       addic.  31,31,1
+       stw     31,CI_INTRDEPTH(1)
+       lwz     1,CI_INTSTK(1)          /* get interrupt stack */
+       beq     1f
+       mfsprg  1,1                     /* yes, get old SP */
+1:
+       ba      decrintr
+_C_LABEL(decrsize) = .-_C_LABEL(decrint)
+
+/*
+ * Now the tlb software load for 603 processors:
+ * (Code essentially from the 603e User Manual, Chapter 5, but
+ * corrected a lot.)
+ */
+#define        DMISS   976
+#define        DCMP    977
+#define        HASH1   978
+#define        HASH2   979
+#define        IMISS   980
+#define        ICMP    981
+#define        RPA     982
+
+       .globl  _C_LABEL(tlbimiss),_C_LABEL(tlbimsize)
+_C_LABEL(tlbimiss):
+       mfspr   2,HASH1                 /* get first pointer */
+       li      1,8
+       mfctr   0                       /* save counter */
+       mfspr   3,ICMP                  /* get first compare value */
+       addi    2,2,-8                  /* predec pointer */
+1:
+       mtctr   1                       /* load counter */
+2:
+       lwzu    1,8(2)                  /* get next pte */
+       cmpl    0,1,3                   /* see if found pte */
+       bdneq   2b                      /* loop if not eq */
+       bne     3f                      /* not found */
+       lwz     1,4(2)                  /* load tlb entry lower word */
+       andi.   3,1,8                   /* check G-bit */
+       bne     4f                      /* if guarded, take ISI */
+       mtctr   0                       /* restore counter */
+       mfspr   0,IMISS                 /* get the miss address for the tlbli */
+       mfsrr1  3                       /* get the saved cr0 bits */
+       mtcrf   0x80,3                  /* and restore */
+       ori     1,1,0x100               /* set the reference bit */
+       mtspr   RPA,1                   /* set the pte */
+       srwi    1,1,8                   /* get byte 7 of pte */
+       tlbli   0                       /* load the itlb */
+       stb     1,6(2)                  /* update page table */
+       rfi
+
+3:     /* not found in pteg */
+       andi.   1,3,0x40                /* have we already done second hash? */
+       bne     5f
+       mfspr   2,HASH2                 /* get the second pointer */
+       ori     3,3,0x40                /* change the compare value */
+       li      1,8
+       addi    2,2,-8                  /* predec pointer */
+       b       1b
+4:     /* guarded */
+       mfsrr1  3
+       andi.   2,3,0xffff              /* clean upper srr1 */
+       oris    2,2,0x8000000@h         /* set srr<4> to flag prot violation */
+       b       6f
+5:     /* not found anywhere */
+       mfsrr1  3
+       andi.   2,3,0xffff              /* clean upper srr1 */
+       oris    2,2,0x40000000@h        /* set srr1<1> to flag pte not found */
+6:
+       mtctr   0                       /* restore counter */
+       mtsrr1  2
+       mfmsr   0
+       xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
+       mtcrf   0x80,3                  /* restore cr0 */
+       mtmsr   0                       /* now with native gprs */
+       isync
+       ba      EXC_ISI
+_C_LABEL(tlbimsize) = .-_C_LABEL(tlbimiss)
+
+       .globl  _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize)
+_C_LABEL(tlbdlmiss):
+       mfspr   2,HASH1                 /* get first pointer */
+       li      1,8



Home | Main Index | Thread Index | Old Index