The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/powerpc/trap_subr.S

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $FreeBSD: releng/5.2/sys/powerpc/powerpc/trap_subr.S 111551 2003-02-26 14:41:39Z grehan $ */
    2 /* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $ */
    3 
    4 /*
    5  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
    6  * Copyright (C) 1995, 1996 TooLs GmbH.
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by TooLs GmbH.
   20  * 4. The name of TooLs GmbH may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   29  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   31  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   32  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 /*
   36  * NOTICE: This is not a standalone file.  to use it, #include it in
   37  * your port's locore.S, like so:
   38  *
   39  *      #include <powerpc/powerpc/trap_subr.S>
   40  */
   41 
   42 /*
   43  * XXX Fake AST trap vector.  This is here until we work out how to safely
   44  * remove the AST code.
   45  */
   46 #define EXC_AST 0x3000
   47         .data
   48         .align  4
   49 cpassert:
   50         .asciz  "attempting to return from kernel with no current pmap"
   51 
   52 /*
   53  * Data used during primary/secondary traps/interrupts
   54  */
   55 #define tempsave        EXC_MCHK+0xe0 /* primary save area for trap handling */
   56 #define disisave        EXC_DSI+0xe0  /* primary save area for dsi/isi traps */
   57 
   58 /*
   59  * XXX Interrupt and spill stacks need to be per-CPU.
   60  */
   61         .data
   62         .align  4
   63 intstk:
   64         .space  INTSTK          /* interrupt stack */
   65 
   66 GLOBAL(intr_depth)
   67         .long   -1              /* in-use marker */
   68 
   69         .comm   spillstk,SPILLSTK,8
   70 
   71 /*
   72  * This code gets copied to all the trap vectors
   73  * (except ISI/DSI, ALI, the interrupts, and possibly the debugging 
   74  * traps when using IPKDB).
   75  */
   76         .text
   77         .globl  CNAME(trapcode),CNAME(trapsize)
   78 CNAME(trapcode):
   79         mtsprg  1,1                     /* save SP */
   80         stmw    28,tempsave(0)          /* free r28-r31 */
   81         mflr    28                      /* save LR */
   82         mfcr    29                      /* save CR */
   83 /* Test whether we already had PR set */
   84         mfsrr1  31
   85         mtcr    31
   86         bc      4,17,1f                 /* branch if PSL_PR is clear */
   87         mfsprg  31,0
   88         lwz     1,PC_CURPCB(31)
   89 1:
   90         bla     s_trap
   91 CNAME(trapsize) = .-CNAME(trapcode)
   92 
   93 /*
   94  * For ALI: has to save DSISR and DAR
   95  */
   96         .globl  CNAME(alitrap),CNAME(alisize)
   97 CNAME(alitrap):
   98         mtsprg  1,1                     /* save SP */
   99         stmw    28,tempsave(0)          /* free r28-r31 */
  100         mfdar   30
  101         mfdsisr 31
  102         stmw    30,tempsave+16(0)
  103         mflr    28                      /* save LR */
  104         mfcr    29                      /* save CR */
  105 /* Test whether we already had PR set */
  106         mfsrr1  31
  107         mtcr    31
  108         bc      4,17,1f                 /* branch if PSL_PR is clear */
  109         mfsprg  31,0
  110         lwz     1,PC_CURPCB(31)
  111 1:
  112         bla     s_trap
  113 CNAME(alisize) = .-CNAME(alitrap)
  114 
  115 /*
  116  * Similar to the above for DSI
  117  * Has to handle BAT spills
  118  * and standard pagetable spills
  119  */
  120         .globl  CNAME(dsitrap),CNAME(dsisize)
  121 CNAME(dsitrap):
  122         stmw    28,disisave(0)          /* free r28-r31 */
  123         mfcr    29                      /* save CR */
  124         mfxer   30                      /* save XER */
  125         mtsprg  2,30                    /* in SPRG2 */
  126         mfsrr1  31                      /* test kernel mode */
  127         mtcr    31
  128         bc      12,17,1f                /* branch if PSL_PR is set */
  129         mfdar   31                      /* get fault address */
  130         rlwinm  31,31,7,25,28           /* get segment * 8 */
  131 
  132         /* get batu */
  133         addis   31,31,CNAME(battable)@ha
  134         lwz     30,CNAME(battable)@l(31)
  135         mtcr    30
  136         bc      4,30,1f                 /* branch if supervisor valid is
  137                                            false */
  138         /* get batl */
  139         lwz     31,CNAME(battable)+4@l(31)
  140 /* We randomly use the highest two bat registers here */
  141         mftb    28
  142         andi.   28,28,1
  143         bne     2f
  144         mtdbatu 2,30
  145         mtdbatl 2,31
  146         b       3f
  147 2:
  148         mtdbatu 3,30
  149         mtdbatl 3,31
  150 3:
  151         mfsprg  30,2                    /* restore XER */
  152         mtxer   30
  153         mtcr    29                      /* restore CR */
  154         lmw     28,disisave(0)          /* restore r28-r31 */
  155         rfi                             /* return to trapped code */
  156 1:
  157         mflr    28                      /* save LR */
  158         bla     s_dsitrap
  159 CNAME(dsisize) = .-CNAME(dsitrap)
  160 
  161 /*
  162  * Dedicated MPC601 version of the above.
  163  * Considers different BAT format and combined implementation
  164  * (being addressed as I-BAT).
  165  */
  166         .globl  CNAME(dsitrap601),CNAME(dsi601size)
  167 CNAME(dsitrap601):
  168         stmw    28,disisave(0)          /* free r28-r31 */
  169         mfcr    29                      /* save CR */
  170         mfxer   30                      /* save XER */
  171         mtsprg  2,30                    /* in SPRG2 */
  172         mfsrr1  31                      /* test kernel mode */
  173         mtcr    31
  174         bc      12,17,1f                /* branch if PSL_PR is set */
  175         mfdar   31                      /* get fault address */
  176         rlwinm  31,31,12,20,28          /* get "segment" battable offset */
  177 
  178         /* get batl */
  179         addis   31,31,CNAME(battable)@ha
  180         lwz     30,CNAME(battable)+4@l(31)
  181         mtcr    30
  182         bc      4,25,1f                 /* branch if Valid is is false,
  183                                            presently assumes supervisor only */
  184 
  185         /* get batu */
  186         lwz     31,CNAME(battable)@l(31)
  187 /* We randomly use the highest two bat registers here */
  188         mfspr   28,SPR_RTCL_R
  189         andi.   28,28,128
  190         bne     2f
  191         mtibatu 2,31
  192         mtibatl 2,30
  193         b       3f
  194 2:
  195         mtibatu 3,31
  196         mtibatl 3,30
  197 3:
  198         mfsprg  30,2                    /* restore XER */
  199         mtxer   30
  200         mtcr    29                      /* restore CR */
  201         lmw     28,disisave(0)          /* restore r28-r31 */
  202         rfi                             /* return to trapped code */
  203 1:
  204         mflr    28                      /* save LR */
  205         bla     s_dsitrap
  206 CNAME(dsi601size) = .-CNAME(dsitrap601)
  207 
  208 /*
  209  * Similar to the above for ISI
  210  */
  211         .globl  CNAME(isitrap),CNAME(isisize)
  212 CNAME(isitrap):
  213         stmw    28,disisave(0)          /* free r28-r31 */
  214         mflr    28                      /* save LR */
  215         mfcr    29                      /* save CR */
  216         mfsrr1  31                      /* test kernel mode */
  217         mtcr    31
  218         bc      12,17,1f                /* branch if PSL_PR is set */
  219         mfsrr0  31                      /* get fault address */
  220         rlwinm  31,31,7,25,28           /* get segment * 8 */
  221 
  222         /* get batu */
  223         addis   31,31,CNAME(battable)@ha
  224         lwz     30,CNAME(battable)@l(31)
  225         mtcr    30
  226         bc      4,30,1f                 /* branch if supervisor valid is
  227                                            false */
  228         mtibatu 3,30
  229 
  230         /* get batl */
  231         lwz     30,CNAME(battable)+4@l(31)
  232         mtibatl 3,30
  233 
  234         mtcr    29                      /* restore CR */
  235         lmw     28,disisave(0)          /* restore r28-r31 */
  236         rfi                             /* return to trapped code */
  237 1:
  238         bla     s_isitrap
  239 CNAME(isisize)= .-CNAME(isitrap)
  240 
  241 /*
  242  * Dedicated MPC601 version of the above.
  243  * Considers different BAT format.
  244  */
  245         .globl  CNAME(isitrap601),CNAME(isi601size)
  246 CNAME(isitrap601):
  247         stmw    28,disisave(0)          /* free r28-r31 */
  248         mflr    28                      /* save LR */
  249         mfcr    29                      /* save CR */
  250         mfsrr1  31                      /* test kernel mode */
  251         mtcr    31
  252         bc      12,17,1f                /* branch if PSL_PR is set */
  253         mfsrr0  31                      /* get fault address */
  254         rlwinm  31,31,12,20,28          /* get "segment" battable offset */
  255 
  256         /* get batl */
  257         addis   31,31,CNAME(battable)@ha
  258         lwz     30,CNAME(battable)+4@l(31)
  259         mtcr    30
  260         bc      4,25,1f                 /* branch if Valid is is false,
  261                                            presently assumes supervisor only */
  262         /* get batu */
  263         lwz     31,CNAME(battable)@l(31)
  264 
  265         mtibatu 3,31
  266         mtibatl 3,30
  267 
  268         mtcr    29                      /* restore CR */
  269         lmw     28,disisave(0)          /* restore r28-r31 */
  270         rfi                             /* return to trapped code */
  271 1:
  272         bla     s_isitrap
  273 CNAME(isi601size)= .-CNAME(isitrap601)
  274 
  275 /*
  276  * Now the tlb software load for 603 processors:
  277  * (Code essentially from the 603e User Manual, Chapter 5, but
  278  * corrected a lot.)
  279  */
  280 
  281         .globl  CNAME(tlbimiss),CNAME(tlbimsize)
  282 CNAME(tlbimiss):
  283 #ifdef PMAPDEBUG
  284         mfspr   2,SPR_IMISS             /* exception address */
  285         li      1,24                    /* get rid of the lower */
  286         srw     2,2,1                   /*   24 bits */
  287         li      1,1                     /* Load 1 */
  288         cmpl    2,1,1                   /* is it > 16MB */
  289         blt     99f                     /* nope, skip saving these SPRs */
  290         li      1,0xc0                  /* arbitrary */
  291         mfspr   2,SPR_HASH1
  292         stw     2,0(1)
  293         mfspr   2,SPR_HASH2
  294         stw     2,4(1)
  295         mfspr   2,SPR_IMISS
  296         stw     2,8(1)
  297         mfspr   2,SPR_ICMP
  298         stw     2,12(1)
  299 99:
  300 #endif /* PMAPDEBUG */
  301         mfspr   2,SPR_HASH1             /* get first pointer */
  302         li      1,8
  303         mfctr   0                       /* save counter */
  304         mfspr   3,SPR_ICMP              /* get first compare value */
  305         addi    2,2,-8                  /* predec pointer */
  306 1:
  307         mtctr   1                       /* load counter */
  308 2:
  309         lwzu    1,8(2)                  /* get next pte */
  310         cmpl    0,1,3                   /* see if found pte */
  311         bdneq   2b                      /* loop if not eq */
  312         bne     3f                      /* not found */
  313         lwz     1,4(2)                  /* load tlb entry lower word */
  314         andi.   3,1,8                   /* check G-bit */
  315         bne     4f                      /* if guarded, take ISI */
  316         mtctr   0                       /* restore counter */
  317         mfspr   0,SPR_IMISS             /* get the miss address for the tlbli */
  318         mfsrr1  3                       /* get the saved cr0 bits */
  319         mtcrf   0x80,3                  /* and restore */
  320         ori     1,1,0x100               /* set the reference bit */
  321         mtspr   SPR_RPA,1               /* set the pte */
  322         srwi    1,1,8                   /* get byte 7 of pte */
  323         tlbli   0                       /* load the itlb */
  324         stb     1,6(2)                  /* update page table */
  325         rfi
  326 
  327 3:      /* not found in pteg */
  328         andi.   1,3,0x40                /* have we already done second hash? */
  329         bne     5f
  330         mfspr   2,SPR_HASH2             /* get the second pointer */
  331         ori     3,3,0x40                /* change the compare value */
  332         li      1,8
  333         addi    2,2,-8                  /* predec pointer */
  334         b       1b
  335 4:      /* guarded */
  336         mfsrr1  3
  337         andi.   2,3,0xffff              /* clean upper srr1 */
  338         oris    2,2,0x8000000@h         /* set srr<4> to flag prot violation */
  339         b       6f
  340 5:      /* not found anywhere */
  341         mfsrr1  3
  342         andi.   2,3,0xffff              /* clean upper srr1 */
  343         oris    2,2,0x40000000@h        /* set srr1<1> to flag pte not found */
  344 6:
  345         mtctr   0                       /* restore counter */
  346         mtsrr1  2
  347         mfmsr   0
  348         xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
  349         mtcrf   0x80,3                  /* restore cr0 */
  350         mtmsr   0                       /* now with native gprs */
  351         isync
  352         ba      EXC_ISI
  353 CNAME(tlbimsize) = .-CNAME(tlbimiss)
  354 
  355         .globl  CNAME(tlbdlmiss),CNAME(tlbdlmsize)
  356 CNAME(tlbdlmiss):
  357         mfspr   2,SPR_HASH1             /* get first pointer */
  358         li      1,8
  359         mfctr   0                       /* save counter */
  360         mfspr   3,SPR_DCMP              /* get first compare value */
  361         addi    2,2,-8                  /* predec pointer */
  362 1:
  363         mtctr   1                       /* load counter */
  364 2:
  365         lwzu    1,8(2)                  /* get next pte */
  366         cmpl    0,1,3                   /* see if found pte */
  367         bdneq   2b                      /* loop if not eq */
  368         bne     3f                      /* not found */
  369         lwz     1,4(2)                  /* load tlb entry lower word */
  370         mtctr   0                       /* restore counter */
  371         mfspr   0,SPR_DMISS             /* get the miss address for the tlbld */
  372         mfsrr1  3                       /* get the saved cr0 bits */
  373         mtcrf   0x80,3                  /* and restore */
  374         ori     1,1,0x100               /* set the reference bit */
  375         mtspr   SPR_RPA,1                       /* set the pte */
  376         srwi    1,1,8                   /* get byte 7 of pte */
  377         tlbld   0                       /* load the dtlb */
  378         stb     1,6(2)                  /* update page table */
  379         rfi
  380 
  381 3:      /* not found in pteg */
  382         andi.   1,3,0x40                /* have we already done second hash? */
  383         bne     5f
  384         mfspr   2,SPR_HASH2             /* get the second pointer */
  385         ori     3,3,0x40                /* change the compare value */
  386         li      1,8
  387         addi    2,2,-8                  /* predec pointer */
  388         b       1b
  389 5:      /* not found anywhere */
  390         mfsrr1  3
  391         lis     1,0x40000000@h          /* set dsisr<1> to flag pte not found */
  392         mtctr   0                       /* restore counter */
  393         andi.   2,3,0xffff              /* clean upper srr1 */
  394         mtsrr1  2
  395         mtdsisr 1                       /* load the dsisr */
  396         mfspr   1,SPR_DMISS             /* get the miss address */
  397         mtdar   1                       /* put in dar */
  398         mfmsr   0
  399         xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
  400         mtcrf   0x80,3                  /* restore cr0 */
  401         mtmsr   0                       /* now with native gprs */
  402         isync
  403         ba      EXC_DSI
  404 CNAME(tlbdlmsize) = .-CNAME(tlbdlmiss)
  405 
  406         .globl  CNAME(tlbdsmiss),CNAME(tlbdsmsize)
  407 CNAME(tlbdsmiss):
  408         mfspr   2,SPR_HASH1             /* get first pointer */
  409         li      1,8
  410         mfctr   0                       /* save counter */
  411         mfspr   3,SPR_DCMP              /* get first compare value */
  412         addi    2,2,-8                  /* predec pointer */
  413 1:
  414         mtctr   1                       /* load counter */
  415 2:
  416         lwzu    1,8(2)                  /* get next pte */
  417         cmpl    0,1,3                   /* see if found pte */
  418         bdneq   2b                      /* loop if not eq */
  419         bne     3f                      /* not found */
  420         lwz     1,4(2)                  /* load tlb entry lower word */
  421         andi.   3,1,0x80                /* check the C-bit */
  422         beq     4f
  423 5:
  424         mtctr   0                       /* restore counter */
  425         mfspr   0,SPR_DMISS             /* get the miss address for the tlbld */
  426         mfsrr1  3                       /* get the saved cr0 bits */
  427         mtcrf   0x80,3                  /* and restore */
  428         mtspr   SPR_RPA,1               /* set the pte */
  429         tlbld   0                       /* load the dtlb */
  430         rfi
  431 
  432 3:      /* not found in pteg */
  433         andi.   1,3,0x40                /* have we already done second hash? */
  434         bne     5f
  435         mfspr   2,SPR_HASH2             /* get the second pointer */
  436         ori     3,3,0x40                /* change the compare value */
  437         li      1,8
  438         addi    2,2,-8                  /* predec pointer */
  439         b       1b
  440 4:      /* found, but C-bit = 0 */
  441         rlwinm. 3,1,30,0,1              /* test PP */
  442         bge-    7f
  443         andi.   3,1,1
  444         beq+    8f
  445 9:      /* found, but protection violation (PP==00)*/
  446         mfsrr1  3
  447         lis     1,0xa000000@h           /* indicate protection violation
  448                                            on store */
  449         b       1f
  450 7:      /* found, PP=1x */
  451         mfspr   3,SPR_DMISS             /* get the miss address */
  452         mfsrin  1,3                     /* get the segment register */
  453         mfsrr1  3
  454         rlwinm  3,3,18,31,31            /* get PR-bit */
  455         rlwnm.  2,2,3,1,1               /* get the key */
  456         bne-    9b                      /* protection violation */
  457 8:      /* found, set reference/change bits */
  458         lwz     1,4(2)                  /* reload tlb entry */
  459         ori     1,1,0x180
  460         sth     1,6(2)
  461         b       5b
  462 5:      /* not found anywhere */
  463         mfsrr1  3
  464         lis     1,0x42000000@h          /* set dsisr<1> to flag pte not found */
  465                                         /* dsisr<6> to flag store */
  466 1:
  467         mtctr   0                       /* restore counter */
  468         andi.   2,3,0xffff              /* clean upper srr1 */
  469         mtsrr1  2
  470         mtdsisr 1                       /* load the dsisr */
  471         mfspr   1,SPR_DMISS             /* get the miss address */
  472         mtdar   1                       /* put in dar */
  473         mfmsr   0
  474         xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
  475         mtcrf   0x80,3                  /* restore cr0 */
  476         mtmsr   0                       /* now with native gprs */
  477         isync
  478         ba      EXC_DSI
  479 CNAME(tlbdsmsize) = .-CNAME(tlbdsmiss)
  480 
  481 #if defined(DDB) || defined(KGDB)
  482 #define ddbsave 0xde0           /* primary save area for DDB */
  483 /*
  484  * In case of DDB we want a separate trap catcher for it
  485  */
  486         .local  ddbstk
  487         .comm   ddbstk,INTSTK,8         /* ddb stack */
  488 
  489         .globl  CNAME(ddblow),CNAME(ddbsize)
  490 CNAME(ddblow):
  491         mtsprg  1,1                     /* save SP */
  492         stmw    28,ddbsave(0)           /* free r28-r31 */
  493         mflr    28                      /* save LR */
  494         mfcr    29                      /* save CR */
  495         lis     1,ddbstk+INTSTK@ha      /* get new SP */
  496         addi    1,1,ddbstk+INTSTK@l
  497         bla     ddbtrap
  498 CNAME(ddbsize) = .-CNAME(ddblow)
  499 #endif  /* DDB | KGDB */
  500 
  501 #ifdef IPKDB
  502 #define ipkdbsave       0xde0           /* primary save area for IPKDB */
  503 /*
  504  * In case of IPKDB we want a separate trap catcher for it
  505  */
  506 
  507         .local  ipkdbstk
  508         .comm   ipkdbstk,INTSTK,8               /* ipkdb stack */
  509 
  510         .globl  CNAME(ipkdblow),CNAME(ipkdbsize)
  511 CNAME(ipkdblow):
  512         mtsprg  1,1                     /* save SP */
  513         stmw    28,ipkdbsave(0)         /* free r28-r31 */
  514         mflr    28                      /* save LR */
  515         mfcr    29                      /* save CR */
  516         lis     1,ipkdbstk+INTSTK@ha    /* get new SP */
  517         addi    1,1,ipkdbstk+INTSTK@l
  518         bla     ipkdbtrap
  519 CNAME(ipkdbsize) = .-CNAME(ipkdblow)
  520 #endif  /* IPKDB */
  521 
  522 /*
  523  * FRAME_SETUP assumes:
  524  *      SPRG1           SP (1)
  525  *      savearea        r28-r31,DAR,DSISR       (DAR & DSISR only for DSI traps)
  526  *      28              LR
  527  *      29              CR
  528  *      1               kernel stack
  529  *      LR              trap type
  530  *      SRR0/1          as at start of trap
  531  */
  532 #define FRAME_SETUP(savearea)                                           \
  533 /* Have to enable translation to allow access of kernel stack: */       \
  534         mfsrr0  30;                                                     \
  535         mfsrr1  31;                                                     \
  536         stmw    30,savearea+24(0);                                      \
  537         mfmsr   30;                                                     \
  538         ori     30,30,(PSL_DR|PSL_IR|PSL_RI)@l;                         \
  539         mtmsr   30;                                                     \
  540         isync;                                                          \
  541         mfsprg  31,1;                                                   \
  542         stwu    31,-FRAMELEN(1);                                        \
  543         stw     0,FRAME_0+8(1);                                         \
  544         stw     31,FRAME_1+8(1);                                        \
  545         stw     28,FRAME_LR+8(1);                                       \
  546         stw     29,FRAME_CR+8(1);                                       \
  547         lmw     28,savearea(0);                                         \
  548         stmw    2,FRAME_2+8(1);                                         \
  549         lmw     28,savearea+16(0);                                      \
  550         mfxer   3;                                                      \
  551         mfctr   4;                                                      \
  552         mflr    5;                                                      \
  553         andi.   5,5,0xff00;                                             \
  554         stw     3,FRAME_XER+8(1);                                       \
  555         stw     4,FRAME_CTR+8(1);                                       \
  556         stw     5,FRAME_EXC+8(1);                                       \
  557         stw     28,FRAME_DAR+8(1);                                      \
  558         stw     29,FRAME_DSISR+8(1);                                    \
  559         stw     30,FRAME_SRR0+8(1);                                     \
  560         stw     31,FRAME_SRR1+8(1)
  561 
  562 #define FRAME_LEAVE(savearea)                                           \
  563 /* Now restore regs: */                                                 \
  564         lwz     2,FRAME_SRR0+8(1);                                      \
  565         lwz     3,FRAME_SRR1+8(1);                                      \
  566         lwz     4,FRAME_CTR+8(1);                                       \
  567         lwz     5,FRAME_XER+8(1);                                       \
  568         lwz     6,FRAME_LR+8(1);                                        \
  569         lwz     7,FRAME_CR+8(1);                                        \
  570         stw     2,savearea(0);                                          \
  571         stw     3,savearea+4(0);                                        \
  572         mtctr   4;                                                      \
  573         mtxer   5;                                                      \
  574         mtlr    6;                                                      \
  575         mtsprg  1,7;                    /* save cr */                   \
  576         lmw     2,FRAME_2+8(1);                                         \
  577         lwz     0,FRAME_0+8(1);                                         \
  578         lwz     1,FRAME_1+8(1);                                         \
  579         mtsprg  2,2;                    /* save r2 & r3 */              \
  580         mtsprg  3,3;                                                    \
  581 /* Disable translation, machine check and recoverability: */            \
  582         mfmsr   2;                                                      \
  583         andi.   2,2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l;            \
  584         mtmsr   2;                                                      \
  585         isync;                                                          \
  586 /* Decide whether we return to user mode: */                            \
  587         lwz     3,savearea+4(0);                                        \
  588         mtcr    3;                                                      \
  589         bc      4,17,1f;                /* branch if PSL_PR is false */ \
  590 /* Restore user & kernel access SR: */                                  \
  591         mfsprg  2,0;                                                    \
  592         lwz     2,PC_CURPMAP(2);                                        \
  593         cmpwi   cr4,2,0;                /* is curpmap NULL? */          \
  594         bne     cr4,2f;                                                 \
  595         lis     3,cpassert@ha;          /* if it is, panic */           \
  596         addi    3,3,cpassert@l;                                         \
  597         b       panic;                                                  \
  598 2:      lwz     3,PM_SR+0(2);                                           \
  599         mtsr    0,3;                    /* restore SR0 */               \
  600         lwz     3,PM_SR+4(2);                                           \
  601         mtsr    1,3;                    /* restore SR1 */               \
  602         lwz     3,PM_SR+8(2);                                           \
  603         mtsr    2,3;                    /* restore SR2 */               \
  604         lwz     3,PM_SR+12(2);                                          \
  605         mtsr    3,3;                    /* restore SR3 */               \
  606         lwz     3,PM_SR+16(2);                                          \
  607         mtsr    4,3;                    /* restore SR4 */               \
  608         lwz     3,PM_SR+20(2);                                          \
  609         mtsr    5,3;                    /* restore SR5 */               \
  610         lwz     3,PM_SR+24(2);                                          \
  611         mtsr    6,3;                    /* restore SR6 */               \
  612         lwz     3,PM_SR+28(2);                                          \
  613         mtsr    7,3;                    /* restore SR7 */               \
  614         lwz     3,PM_USRSR(2);                                          \
  615         mtsr    USER_SR,3;                                              \
  616         lwz     3,PM_KERNELSR(2);                                       \
  617         mtsr    KERNEL_SR,3;                                            \
  618 1:      mfsprg  2,1;                    /* restore cr */                \
  619         mtcr    2;                                                      \
  620         lwz     2,savearea(0);                                          \
  621         lwz     3,savearea+4(0);                                        \
  622         mtsrr0  2;                                                      \
  623         mtsrr1  3;                                                      \
  624         mfsprg  2,2;                    /* restore r2 & r3 */           \
  625         mfsprg  3,3
  626 
  627 /*
  628  * Preamble code for DSI/ISI traps
  629  */
  630 disitrap:
  631         lmw     30,disisave(0)
  632         stmw    30,tempsave(0)
  633         lmw     30,disisave+8(0)
  634         stmw    30,tempsave+8(0)
  635         mfdar   30
  636         mfdsisr 31
  637         stmw    30,tempsave+16(0)
  638 realtrap:
  639 /* Test whether we already had PR set */
  640         mfsrr1  1
  641         mtcr    1
  642         mfsprg  1,1                     /* restore SP (might have been
  643                                            overwritten) */
  644         bc      4,17,s_trap             /* branch if PSL_PR is false */
  645         mfsprg  31,0
  646         lwz     1,PC_CURPCB(31)
  647 
  648 /*
  649  * Now the common trap catching code.
  650  */
  651 s_trap:
  652 /* First have to enable KERNEL mapping */
  653         lis     31,KERNEL_SEGMENT@h
  654         ori     31,31,KERNEL_SEGMENT@l
  655         mtsr    KERNEL_SR,31
  656 /* Obliterate SRs so BAT spills work correctly */
  657         lis     31,EMPTY_SEGMENT@h
  658         ori     31,31,EMPTY_SEGMENT@l
  659         mtsr    0,31
  660         mtsr    1,31
  661         mtsr    2,31
  662         mtsr    3,31
  663         mtsr    4,31
  664         mtsr    5,31
  665         mtsr    6,31
  666         mtsr    7,31
  667         FRAME_SETUP(tempsave)
  668 /* Now we can recover interrupts again: */
  669 #if 0
  670         mfmsr   7
  671         ori     7,7,(PSL_EE|PSL_ME|PSL_RI)@l
  672         mtmsr   7
  673         isync
  674 #endif
  675 /* Call C interrupt dispatcher: */
  676 trapagain:
  677         addi    3,1,8
  678         bl      CNAME(powerpc_interrupt)
  679         .globl  CNAME(trapexit)
  680 CNAME(trapexit):
  681 
  682 /* Disable interrupts: */
  683         mfmsr   3
  684         andi.   3,3,~PSL_EE@l
  685         mtmsr   3
  686 /* Test AST pending: */
  687         lwz     5,FRAME_SRR1+8(1)
  688         mtcr    5
  689         bc      4,17,1f                 /* branch if PSL_PR is false */
  690 
  691         mfsprg  3, 0                    /* get per-CPU pointer */
  692         lwz     4, PC_CURTHREAD(3)      /* deref to get curthread */
  693         lwz     4, TD_FLAGS(4)          /* get thread flags value */
  694         lis     5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
  695         ori     5,5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l 
  696         and.    4,4,5
  697         beq     1f
  698         mfmsr   3                       /* re-enable interrupts */
  699         ori     3,3,PSL_EE@l
  700         mtmsr   3
  701         isync
  702         addi    3,1,8
  703         bl      CNAME(ast)
  704         b       trapexit                /* test ast ret value ? */
  705 1:
  706         FRAME_LEAVE(tempsave)
  707         rfi
  708 
  709 /*
  710  * DSI second stage fault handler
  711  */
  712 s_dsitrap:
  713         mfdsisr 31                      /* test whether this may be a
  714                                            spill fault */
  715         mtcr    31
  716         mtsprg  1,1                     /* save SP */
  717         bc      4,1,disitrap            /* branch if table miss is false */
  718         lis     1,spillstk+SPILLSTK@ha
  719         addi    1,1,spillstk+SPILLSTK@l /* get spill stack */
  720         stwu    1,-SPFRAMELEN(1)
  721         stw     0,SPFRAME_R0(1)         /* save non-volatile registers */
  722         stw     3,SPFRAME_R3(1)
  723         stw     4,SPFRAME_R4(1)
  724         stw     5,SPFRAME_R5(1)
  725         stw     6,SPFRAME_R6(1)
  726         stw     7,SPFRAME_R7(1)
  727         stw     8,SPFRAME_R8(1)
  728         stw     9,SPFRAME_R9(1)
  729         stw     10,SPFRAME_R10(1)
  730         stw     11,SPFRAME_R11(1)
  731         stw     12,SPFRAME_R12(1)
  732         mflr    30                      /* save trap type */
  733         mfctr   31                      /* & CTR */
  734         mfdar   3
  735 s_pte_spill:
  736         bl      CNAME(pmap_pte_spill)   /* try a spill */
  737         or.     3,3,3
  738         mtctr   31                      /* restore CTR */
  739         mtlr    30                      /* and trap type */
  740         mfsprg  31,2                    /* get saved XER */
  741         mtxer   31                      /* restore XER */
  742         lwz     12,SPFRAME_R12(1)       /* restore non-volatile registers */
  743         lwz     11,SPFRAME_R11(1)
  744         lwz     10,SPFRAME_R10(1)
  745         lwz     9,SPFRAME_R9(1)
  746         lwz     8,SPFRAME_R8(1)
  747         lwz     7,SPFRAME_R7(1)
  748         lwz     6,SPFRAME_R6(1)
  749         lwz     5,SPFRAME_R5(1)
  750         lwz     4,SPFRAME_R4(1)
  751         lwz     3,SPFRAME_R3(1)
  752         lwz     0,SPFRAME_R0(1)
  753         beq     disitrap
  754         mfsprg  1,1                     /* restore SP */
  755         mtcr    29                      /* restore CR */
  756         mtlr    28                      /* restore LR */
  757         lmw     28,disisave(0)          /* restore r28-r31 */
  758         rfi                             /* return to trapped code */
  759 
  760 /*
  761  * ISI second stage fault handler
  762  */
  763 s_isitrap:
  764         mfsrr1  31                      /* test whether this may be a
  765                                            spill fault */
  766         mtcr    31
  767         mtsprg  1,1                     /* save SP */
  768         bc      4,1,disitrap            /* branch if table miss is false */
  769         lis     1,spillstk+SPILLSTK@ha
  770         addi    1,1,spillstk+SPILLSTK@l /* get spill stack */
  771         stwu    1,-SPFRAMELEN(1)
  772         stw     0,SPFRAME_R0(1)         /* save non-volatile registers */
  773         stw     3,SPFRAME_R3(1)
  774         stw     4,SPFRAME_R4(1)
  775         stw     5,SPFRAME_R5(1)
  776         stw     6,SPFRAME_R6(1)
  777         stw     7,SPFRAME_R7(1)
  778         stw     8,SPFRAME_R8(1)
  779         stw     9,SPFRAME_R9(1)
  780         stw     10,SPFRAME_R10(1)
  781         stw     11,SPFRAME_R11(1)
  782         stw     12,SPFRAME_R12(1)
  783         mfxer   30                      /* save XER */
  784         mtsprg  2,30
  785         mflr    30                      /* save trap type */
  786         mfctr   31                      /* & ctr */
  787         mfsrr0  3
  788         b       s_pte_spill             /* above */
  789 
  790 
  791 #if defined(DDB)
  792 /*
  793  * Deliberate entry to ddbtrap
  794  */
  795         .globl  CNAME(ddb_trap)
  796 CNAME(ddb_trap):
  797         mtsprg  1,1
  798         mfmsr   3
  799         mtsrr1  3
  800         andi.   3,3,~(PSL_EE|PSL_ME)@l
  801         mtmsr   3                       /* disable interrupts */
  802         isync
  803         stmw    28,ddbsave(0)
  804         mflr    28
  805         li      29,EXC_BPT
  806         mtlr    29
  807         mfcr    29
  808         mtsrr0  28
  809 #endif /* DDB */
  810 
  811 #if defined(DDB) || defined(KGDB)
  812 /*
  813  * Now the ddb trap catching code.
  814  */
  815 ddbtrap:
  816         FRAME_SETUP(ddbsave)
  817 /* Call C trap code: */
  818         addi    3,1,8
  819         bl      CNAME(ddb_trap_glue)
  820         or.     3,3,3
  821         bne     ddbleave
  822 /* This wasn't for DDB, so switch to real trap: */
  823         lwz     3,FRAME_EXC+8(1)        /* save exception */
  824         stw     3,ddbsave+8(0)
  825         FRAME_LEAVE(ddbsave)
  826         mtsprg  1,1                     /* prepare for entrance to realtrap */
  827         stmw    28,tempsave(0)
  828         mflr    28
  829         mfcr    29
  830         lwz     31,ddbsave+8(0)
  831         mtlr    31
  832         b       realtrap
  833 ddbleave:
  834         FRAME_LEAVE(ddbsave)
  835         rfi
  836 #endif /* DDB || KGDB */
  837 
  838 #ifdef IPKDB
  839 /*
  840  * Deliberate entry to ipkdbtrap
  841  */
  842         .globl  CNAME(ipkdb_trap)
  843 CNAME(ipkdb_trap):
  844         mtsprg  1,1
  845         mfmsr   3
  846         mtsrr1  3
  847         andi.   3,3,~(PSL_EE|PSL_ME)@l
  848         mtmsr   3                       /* disable interrupts */
  849         isync
  850         stmw    28,ipkdbsave(0)
  851         mflr    28
  852         li      29,EXC_BPT
  853         mtlr    29
  854         mfcr    29
  855         mtsrr0  28
  856 
  857 /*
  858  * Now the ipkdb trap catching code.
  859  */
  860 ipkdbtrap:
  861         FRAME_SETUP(ipkdbsave)
  862 /* Call C trap code: */
  863         addi    3,1,8
  864         bl      CNAME(ipkdb_trap_glue)
  865         or.     3,3,3
  866         bne     ipkdbleave
  867 /* This wasn't for IPKDB, so switch to real trap: */
  868         lwz     3,FRAME_EXC+8(1)        /* save exception */
  869         stw     3,ipkdbsave+8(0)
  870         FRAME_LEAVE(ipkdbsave)
  871         mtsprg  1,1                     /* prepare for entrance to realtrap */
  872         stmw    28,tempsave(0)
  873         mflr    28
  874         mfcr    29
  875         lwz     31,ipkdbsave+8(0)
  876         mtlr    31
  877         b       realtrap
  878 ipkdbleave:
  879         FRAME_LEAVE(ipkdbsave)
  880         rfi
  881 
  882 ipkdbfault:
  883         ba      _ipkdbfault
  884 _ipkdbfault:
  885         mfsrr0  3
  886         addi    3,3,4
  887         mtsrr0  3
  888         li      3,-1
  889         rfi
  890 
  891 /*
  892  * int ipkdbfbyte(unsigned char *p)
  893  */
  894         .globl  CNAME(ipkdbfbyte)
  895 CNAME(ipkdbfbyte):
  896         li      9,EXC_DSI               /* establish new fault routine */
  897         lwz     5,0(9)
  898         lis     6,ipkdbfault@ha
  899         lwz     6,ipkdbfault@l(6)
  900         stw     6,0(9)
  901 #ifdef  IPKDBUSERHACK
  902         lis     8,CNAME(ipkdbsr)@ha
  903         lwz     8,CNAME(ipkdbsr)@l(8)
  904         mtsr    USER_SR,8
  905         isync
  906 #endif
  907         dcbst   0,9                     /* flush data... */
  908         sync
  909         icbi    0,9                     /* and instruction caches */
  910         lbz     3,0(3)                  /* fetch data */
  911         stw     5,0(9)                  /* restore previous fault handler */
  912         dcbst   0,9                     /* and flush data... */
  913         sync
  914         icbi    0,9                     /* and instruction caches */
  915         blr
  916 
  917 /*
  918  * int ipkdbsbyte(unsigned char *p, int c)
  919  */
  920         .globl  CNAME(ipkdbsbyte)
  921 CNAME(ipkdbsbyte):
  922         li      9,EXC_DSI               /* establish new fault routine */
  923         lwz     5,0(9)
  924         lis     6,ipkdbfault@ha
  925         lwz     6,ipkdbfault@l(6)
  926         stw     6,0(9)
  927 #ifdef  IPKDBUSERHACK
  928         lis     8,CNAME(ipkdbsr)@ha
  929         lwz     8,CNAME(ipkdbsr)@l(8)
  930         mtsr    USER_SR,8
  931         isync
  932 #endif
  933         dcbst   0,9                     /* flush data... */
  934         sync
  935         icbi    0,9                     /* and instruction caches */
  936         mr      6,3
  937         xor     3,3,3
  938         stb     4,0(6)
  939         dcbst   0,6                     /* Now do appropriate flushes
  940                                            to data... */
  941         sync
  942         icbi    0,6                     /* and instruction caches */
  943         stw     5,0(9)                  /* restore previous fault handler */
  944         dcbst   0,9                     /* and flush data... */
  945         sync
  946         icbi    0,9                     /* and instruction caches */    
  947         blr
  948 #endif  /* IPKDB */

Cache object: 137230fa44136bb35fb043da1bec84be


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.