[BACK]Return to locore.S CVS log [TXT][DIR] Up to [local] / sys / arch / mvmeppc / mvmeppc

Annotation of sys/arch/mvmeppc/mvmeppc/locore.S, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: locore.S,v 1.12 2005/11/24 12:08:16 pedro Exp $       */
        !             2: /*     $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws 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: #include "assym.h"
        !            36:
        !            37: #include <sys/syscall.h>
        !            38:
        !            39: #include <machine/asm.h>
        !            40: #include <machine/param.h>
        !            41: #include <machine/pmap.h>
        !            42: #include <machine/psl.h>
        !            43: #include <machine/trap.h>
        !            44:
        !            45: /*
        !            46:  * Globals
        !            47:  */
        !            48:        .globl  _C_LABEL(esym),_C_LABEL(proc0paddr)
        !            49:        .type   _C_LABEL(esym),@object
        !            50:        .type   _C_LABEL(proc0paddr),@object
        !            51:        .data
        !            52: _C_LABEL(esym):                .long   0       /* end of symbol table */
        !            53: _C_LABEL(proc0paddr):  .long   0       /* proc0 p_addr */
        !            54: idle_u:                        .long   0       /* fake uarea during idle after exit */
        !            55:
        !            56: /*
        !            57:  * Startup entry
        !            58:  */
        !            59: _ENTRY(_C_LABEL(kernel_text))
        !            60: _ENTRY(_ASM_LABEL(start))
        !            61: /*
        !            62:  * Arguments to start for mvmeppc
        !            63:  * r1 - stack provided by firmware/bootloader
        !            64:  * r3 - boot flags
        !            65:  * r4 - boot device
        !            66:  * r5 - firmware pointer (NULL for PPC1bug)
        !            67:  * r6 - arg list (NULL)
        !            68:  * r7 - length (0)
        !            69:  * r8 - end of symbol table
        !            70:  */
        !            71:        .globl  start
        !            72:        .type start,@function
        !            73: start:
        !            74:        li      %r0,0
        !            75:        mtmsr   %r0                     /* Disable FPU/MMU/exceptions */
        !            76:        isync
        !            77:
        !            78:        /* save boot device and flags */
        !            79:        lis     %r9, _C_LABEL(boothowto)@ha
        !            80:        stw     %r3, _C_LABEL(boothowto)@l(%r9)
        !            81:        lis     %r9, _C_LABEL(bootdev)@ha
        !            82:        stw     %r4, _C_LABEL(bootdev)@l(%r9)
        !            83:
        !            84: /* compute end of kernel memory */
        !            85: #if defined(DDB)
        !            86:        lis     %r9,_C_LABEL(esym)@ha
        !            87:        stw     %r8,_C_LABEL(esym)@l(%r9)       /* save for symbol handling */
        !            88: #else
        !            89:        lis     %r8,_end@ha
        !            90:        addi    %r8,%r8,_end@l
        !            91: #endif
        !            92:        li      %r9,PGOFSET
        !            93:        add     %r8,%r8,%r9
        !            94:        andc    %r8,%r8,%r9
        !            95:        lis     %r9,idle_u@ha
        !            96:        stw     %r8,idle_u@l(%r9)
        !            97:        addi    %r8,%r8,USPACE          /* space for idle_u */
        !            98:        lis     %r9,_C_LABEL(proc0paddr)@ha
        !            99:        stw     %r8,_C_LABEL(proc0paddr)@l(%r9)
        !           100:        addi    %r1,%r8,USPACE-FRAMELEN /* stackpointer for proc0 */
        !           101:        mr      %r4,%r1                 /* end of mem reserved for kernel */
        !           102:        li      %r0,0
        !           103:        stwu    %r0,-16(%r1)            /* end of stack chain */
        !           104:
        !           105:        lis     %r3,start@ha
        !           106:        addi    %r3,%r3,start@l
        !           107:        mr      %r5,%r6                 /* args string */
        !           108:        bl      _C_LABEL(initppc)
        !           109:        bl      _C_LABEL(main)
        !           110:        b       _C_LABEL(PPC1_exit)
        !           111: 
        !           112: /*
        !           113:  * No processes are runnable, so loop waiting for one.
        !           114:  * Separate label here for accounting purposes.
        !           115:  */
        !           116: _C_LABEL(idle):
        !           117:        mfmsr   %r3
        !           118:        /* disable interrupts while manipulating runque */
        !           119:        andi.   %r3,%r3,~PSL_EE@l
        !           120:        mtmsr   %r3
        !           121:
        !           122:        lis     %r8,_C_LABEL(whichqs)@ha
        !           123:        lwz     %r9,_C_LABEL(whichqs)@l(%r8)
        !           124:
        !           125:        or.     %r9,%r9,%r9
        !           126:        bne-    _C_LABEL(sw1)                   /* at least one queue non-empty */
        !           127:
        !           128:        ori     %r3,%r3,PSL_EE          /* reenable ints again */
        !           129:        mtmsr   %r3
        !           130:        isync
        !           131:        sync
        !           132:        /* low power mode */
        !           133:        mfmsr   %r3
        !           134:        oris    %r3, %r3, PSL_POW@h
        !           135:        mtmsr   %r3
        !           136:        isync
        !           137:
        !           138: /* May do some power saving here? */
        !           139:
        !           140:        b       _C_LABEL(idle)
        !           141:
        !           142: /*
        !           143:  * switchexit gets called from cpu_exit to free the user structure
        !           144:  * and kernel stack of the current process.
        !           145:  */
        !           146: _ENTRY(_C_LABEL(switchexit))
        !           147: /* First switch to the idle pcb/kernel stack */
        !           148:        lis     %r6,idle_u@ha
        !           149:        lwz     %r6,idle_u@l(%r6)
        !           150:        lis     %r7,_C_LABEL(curpcb)@ha
        !           151:        stw     %r6,_C_LABEL(curpcb)@l(%r7)
        !           152:        addi    %r1,%r6,USPACE-16       /* 16 bytes are reserved at stack top */
        !           153:        /*
        !           154:         * Schedule the vmspace and stack to be freed (the proc arg is
        !           155:         * already in r3).
        !           156:         */
        !           157:        bl      _C_LABEL(exit2)
        !           158:
        !           159:        /* Fall through to cpu_switch to actually select another proc */
        !           160:        li      %r3,0                   /* indicate exited process */
        !           161:
        !           162: /* Fall through to cpu_switch to actually select another proc */
        !           163:
        !           164: /*
        !           165:  * void cpu_switch(struct proc *p)
        !           166:  * Find a runnable process and switch to it.
        !           167:  */
        !           168: _ENTRY(_C_LABEL(cpu_switch))
        !           169:        mflr    %r0                     /* save lr */
        !           170:        stw     %r0,4(%r1)
        !           171:        stwu    %r1,-16(%r1)
        !           172:        stw     %r31,12(%r1)
        !           173:        stw     %r30,8(%r1)
        !           174:
        !           175:        mr      %r30,%r3
        !           176:        lis     %r3,_C_LABEL(curproc)@ha
        !           177:        li      %r31,0
        !           178:        /* Zero to not accumulate cpu time */
        !           179:        stw     %r31,_C_LABEL(curproc)@l(%r3)
        !           180:        lis     %r3,_C_LABEL(curpcb)@ha
        !           181:        lwz     %r31,_C_LABEL(curpcb)@l(%r3)
        !           182:
        !           183:        li      %r3,0
        !           184:        bl      _C_LABEL(lcsplx)
        !           185:        stw     %r3,PCB_SPL(%r31)       /* save spl */
        !           186:
        !           187: /* Find a new process */
        !           188:        mfmsr   %r3
        !           189:        andi.   %r3,%r3,~PSL_EE@l       /* disable interrupts while
        !           190:                                           manipulating runque */
        !           191:        mtmsr   %r3
        !           192:        isync
        !           193:
        !           194:        lis     %r8,_C_LABEL(whichqs)@ha
        !           195:        lwz     %r9,_C_LABEL(whichqs)@l(%r8)
        !           196:
        !           197:        or.     %r9,%r9,%r9
        !           198:        beq-    _C_LABEL(idle)          /* all queues empty */
        !           199: _C_LABEL(sw1):
        !           200:        cntlzw  %r10,%r9
        !           201:        lis     %r4,_C_LABEL(qs)@ha
        !           202:        addi    %r4,%r4,_C_LABEL(qs)@l
        !           203:        slwi    %r3,%r10,3
        !           204:        add     %r3,%r3,%r4             /* select queue */
        !           205:
        !           206:        lwz     %r31,P_FORW(%r3)        /* unlink first proc from queue */
        !           207:        lwz     %r4,P_FORW(%r31)
        !           208:        stw     %r4,P_FORW(%r3)
        !           209:        stw     %r3,P_BACK(%r4)
        !           210:
        !           211:        cmpl    0,%r3,%r4                       /* queue empty? */
        !           212:        bne     1f
        !           213:
        !           214:        lis     %r3,0x80000000@ha
        !           215:        srw     %r3,%r3,%r10
        !           216:        andc    %r9,%r9,%r3
        !           217:        stw     %r9,_C_LABEL(whichqs)@l(%r8)    /* mark it empty */
        !           218:
        !           219: 1:
        !           220:        /* just did this resched thing, clear resched */
        !           221:        li      %r3,0
        !           222:        lis     %r4,_C_LABEL(want_resched)@ha
        !           223:        stw     %r3,_C_LABEL(want_resched)@l(%r4)
        !           224:
        !           225:        stw     %r3,P_BACK(%r31)                /* probably superfluous */
        !           226:
        !           227:        lis     %r4,_C_LABEL(curproc)@ha
        !           228:        stw     %r31,_C_LABEL(curproc)@l(%r4)   /* record new process */
        !           229:
        !           230:        li      %r3,SONPROC
        !           231:        stb     %r3,P_STAT(%r31)
        !           232:
        !           233:        mfmsr   %r3
        !           234:        ori     %r3,%r3,PSL_EE          /* Now we can interrupt again */
        !           235:        mtmsr   %r3
        !           236:
        !           237:        cmpl    0,%r31,%r30             /* is it the same process? */
        !           238:        beq     switch_return
        !           239:
        !           240:        or.     %r30,%r30,%r30          /* old process was exiting? */
        !           241:        beq     switch_exited
        !           242:
        !           243:        mfsr    %r10,PPC_USER_SR        /* save PPC_USER_SR for copyin/copyout*/
        !           244:        mfcr    %r11                    /* save cr */
        !           245:        mr      %r12,%r2                /* save r2 */
        !           246:        stwu    %r1,-SFRAMELEN(%r1)     /* still running on old stack */
        !           247:        stmw    %r10,8(%r1)
        !           248:        lwz     %r3,P_ADDR(%r30)
        !           249:        stw     %r1,PCB_SP(%r3)         /* save SP */
        !           250:
        !           251: switch_exited:
        !           252:        /* disable interrupts while actually switching */
        !           253:        mfmsr   %r3
        !           254:        andi.   %r3,%r3,~PSL_EE@l
        !           255:        mtmsr   %r3
        !           256:
        !           257:        lwz     %r4,P_ADDR(%r31)
        !           258:        lis     %r5,_C_LABEL(curpcb)@ha
        !           259:        stw     %r4,_C_LABEL(curpcb)@l(%r5)     /* indicate new pcb */
        !           260:
        !           261:        lwz     %r5,PCB_PMR(%r4)
        !           262:
        !           263:        /* save real pmap pointer for spill fill */
        !           264:        lis     %r6,_C_LABEL(curpm)@ha
        !           265:        stwu    %r5,_C_LABEL(curpm)@l(%r6)
        !           266:        stwcx.  %r5,%r0,%r6             /* clear possible reservation */
        !           267:
        !           268:        addic.  %r5,%r5,64
        !           269:        li      %r6,0
        !           270:        mfsr    %r8,PPC_KERNEL_SR       /* save kernel SR */
        !           271: 1:
        !           272:        addis   %r6,%r6,-0x10000000@ha  /* set new procs segment registers */
        !           273:        or.     %r6,%r6,%r6             /* This is done from the real address pmap */
        !           274:        lwzu    %r7,-4(%r5)             /* so we don't have to worry */
        !           275:        mtsrin  %r7,%r6                 /* about accessibility */
        !           276:        bne     1b
        !           277:        mtsr    PPC_KERNEL_SR,%r8       /* restore kernel SR */
        !           278:        isync
        !           279:
        !           280:        lwz     %r1,PCB_SP(%r4)         /* get new procs SP */
        !           281:
        !           282:        ori     %r3,%r3,PSL_EE          /* interrupts are okay again */
        !           283:        mtmsr   %r3
        !           284:
        !           285:        lmw     %r10,8(%r1)             /* get other regs */
        !           286:        lwz     %r1,0(%r1)              /* get saved SP */
        !           287:        mr      %r2,%r12                /* get saved r2 */
        !           288:        mtcr    %r11                    /* get saved cr */
        !           289:        isync
        !           290:        mtsr    PPC_USER_SR,%r10        /* get saved PPC_USER_SR */
        !           291:        isync
        !           292:
        !           293: switch_return:
        !           294:        mr      %r30,%r7                /* save proc pointer */
        !           295:        lwz     %r3,PCB_SPL(%r4)
        !           296:        bl      _C_LABEL(lcsplx)
        !           297:
        !           298:        mr      %r3,%r30                /* curproc for special fork returns */
        !           299:
        !           300:        lwz     %r31,12(%r1)
        !           301:        lwz     %r30,8(%r1)
        !           302:        addi    %r1,%r1,16
        !           303:        lwz     %r0,4(%r1)
        !           304:        mtlr    %r0
        !           305:        blr
        !           306:
        !           307: 
        !           308: /*
        !           309:  * Data used during primary/secondary traps/interrupts
        !           310:  */
        !           311: #define        tempsave        0x2e0           /* primary save area for trap handling */
        !           312: #define        disisave        0x3e0           /* primary save area for dsi/isi traps */
        !           313: #define        INTSTK  (8*1024)                /* 8K interrupt stack */
        !           314:        .data
        !           315: intstk:        .space  INTSTK                  /* interrupt stack */
        !           316:        .global _C_LABEL(intr_depth)
        !           317:        .type  _C_LABEL(intr_depth),@object
        !           318: _C_LABEL(intr_depth):
        !           319:        .long   -1                      /* in-use marker */
        !           320: #define        SPILLSTK 1024                   /* 1K spill stack */
        !           321: .lcomm spillstk,SPILLSTK,8
        !           322:
        !           323: /*
        !           324:  * This code gets copied to all the trap vectors
        !           325:  * except ISI/DSI, ALI, and the interrupts
        !           326:  */
        !           327:        .text
        !           328:        .globl  _C_LABEL(trapcode),_C_LABEL(trapsize)
        !           329:        .type   _C_LABEL(trapcode),@function
        !           330:        .type   _C_LABEL(trapsize),@object
        !           331: _C_LABEL(trapcode):
        !           332:        mtsprg  1,%r1                   /* save SP */
        !           333:        stmw    %r28,tempsave(%r0)      /* free r28-r31 */
        !           334:        mflr    %r28                    /* save LR */
        !           335:        mfcr    %r29                    /* save CR */
        !           336:
        !           337:        /* Test whether we already had PR set */
        !           338:        mfsrr1  %r31
        !           339:        mtcr    %r31
        !           340:        bc      4,17,1f                 /* branch if PSL_PR is clear */
        !           341:        lis     %r1,_C_LABEL(curpcb)@ha
        !           342:        lwz     %r1,_C_LABEL(curpcb)@l(%r1)
        !           343:        addi    %r1,%r1,USPACE          /* stack is top of user struct */
        !           344: 1:
        !           345:        bla     s_trap
        !           346: _C_LABEL(trapsize) =   .-_C_LABEL(trapcode)
        !           347:
        !           348: /*
        !           349:  * For ALI: has to save DSISR and DAR
        !           350:  */
        !           351:        .globl  _C_LABEL(alitrap),_C_LABEL(alisize)
        !           352: _C_LABEL(alitrap):
        !           353:        mtsprg  1,%r1                   /* save SP */
        !           354:        stmw    %r28,tempsave(0)        /* free r28-r31 */
        !           355:        mfdar   %r30
        !           356:        mfdsisr %r31
        !           357:        stmw    %r30,tempsave+16(0)
        !           358:        mflr    %r28                    /* save LR */
        !           359:        mfcr    %r29                    /* save CR */
        !           360:
        !           361:        /* Test whether we already had PR set */
        !           362:        mfsrr1  %r31
        !           363:        mtcr    %r31
        !           364:        bc      4,17,1f                 /* branch if PSL_PR is clear */
        !           365:        lis     %r1,_C_LABEL(curpcb)@ha
        !           366:        lwz     %r1,_C_LABEL(curpcb)@l(%r1)
        !           367:        addi    %r1,%r1,USPACE          /* stack is top of user struct */
        !           368: 1:
        !           369:        bla     s_trap
        !           370: _C_LABEL(alisize) =    .-_C_LABEL(alitrap)
        !           371:
        !           372: /*
        !           373:  * Similar to the above for DSI
        !           374:  * Has to handle BAT spills
        !           375:  * and standard pagetable spills
        !           376:  */
        !           377:        .globl  _C_LABEL(dsitrap),_C_LABEL(dsisize)
        !           378:        .type   _C_LABEL(dsitrap),@function
        !           379:        .type   _C_LABEL(dsisize),@object
        !           380: _C_LABEL(dsitrap):
        !           381:        stmw    %r28,disisave(0)        /* free r28-r31 */
        !           382:        mfcr    %r29                    /* save CR */
        !           383:        mfxer   %r30                    /* save XER */
        !           384:        mtsprg  2,%r30                  /* in SPRG2 */
        !           385:        mfsrr1  %r31                    /* test kernel mode */
        !           386: #if 0
        !           387:        mtcr    %r31
        !           388:        bc      12,17,1f                /* branch if PSL_PR is set */
        !           389:        mfdar   %r31                    /* get fault address */
        !           390:        rlwinm  %r31,%r31,7,25,28       /* get segment * 8 */
        !           391:        addis   %r31,%r31,_C_LABEL(battable)@ha
        !           392:        lwz     %r30,_C_LABEL(battable)@l(%r31) /* get batu */
        !           393:        mtcr    %r30
        !           394:        bc      4,30,1f                 /* branch if supervisor valid is false */
        !           395:        lwz     %r31,_C_LABEL(battable)+4@l(%r31)       /* get batl */
        !           396: /* We randomly use the highest two bat registers here */
        !           397:        mftb    %r28
        !           398:        andi.   %r28,%r28,1
        !           399:        bne     2f
        !           400:        mtdbatu 2,%r30
        !           401:        mtdbatl 2,%r31
        !           402:        b       3f
        !           403: 2:
        !           404:        mtdbatu 3,%r30
        !           405:        mtdbatl 3,%r31
        !           406: 3:
        !           407:        mfsprg  %r30,2                  /* restore XER */
        !           408:        mtxer   %r30
        !           409:        mtcr    %r29                    /* restore CR */
        !           410:        lmw     %r28,disisave(0)        /* restore r28-r31 */
        !           411:        rfi                             /* return to trapped code */
        !           412: 1:
        !           413: #endif
        !           414:        mflr    %r28                    /* save LR */
        !           415:        bla     s_dsitrap
        !           416: _C_LABEL(dsisize) =    .-_C_LABEL(dsitrap)
        !           417:
        !           418: /*
        !           419:  * Similar to the above for ISI
        !           420:  */
        !           421:        .globl  _C_LABEL(isitrap),_C_LABEL(isisize)
        !           422:        .type   _C_LABEL(isitrap),@function
        !           423:        .type   _C_LABEL(isisize),@object
        !           424: _C_LABEL(isitrap):
        !           425:        stmw    %r28,disisave(0)        /* free r28-r31 */
        !           426:        mflr    %r28                    /* save LR */
        !           427:        mfcr    %r29                    /* save CR */
        !           428:        mfsrr1  %r31                    /* test kernel mode */
        !           429: #if 0
        !           430:        mtcr    %r31
        !           431:        bc      12,17,1f                /* branch if PSL_PR is set */
        !           432:        mfsrr0  %r31                    /* get fault address */
        !           433:        rlwinm  %r31,%r31,7,25,28               /* get segment * 8 */
        !           434:        addis   %r31,%r31,_C_LABEL(battable)@ha
        !           435:        lwz     %r30,_C_LABEL(battable)@l(%r31) /* get batu */
        !           436:        mtcr    %r30
        !           437:        bc      4,30,1f                 /* branch if supervisor valid is false */
        !           438:        mtibatu 3,%r30
        !           439:        lwz     %r30,_C_LABEL(battable)+4@l(%r31)       /* get batl */
        !           440:        mtibatl 3,%r30
        !           441:        mtcr    %r29                    /* restore CR */
        !           442:        lmw     %r28,disisave(0)        /* restore r28-r31 */
        !           443:        rfi                             /* return to trapped code */
        !           444: 1:
        !           445: #endif
        !           446:        bla     s_isitrap
        !           447: _C_LABEL(isisize) =    .-_C_LABEL(isitrap)
        !           448:
        !           449: /*
        !           450:  * This one for the external interrupt handler.
        !           451:  */
        !           452:        .globl  _C_LABEL(extint),_C_LABEL(extsize)
        !           453:        .type   _C_LABEL(extint),@function
        !           454:        .type   _C_LABEL(extsize),@object
        !           455: _C_LABEL(extint):
        !           456:        mtsprg  1,%r1                   /* save SP */
        !           457:        stmw    %r28,tempsave(0)        /* free r28-r31 */
        !           458:        mflr    %r28                    /* save LR */
        !           459:        mfcr    %r29                    /* save CR */
        !           460:        mfxer   %r30                    /* save XER */
        !           461:        lis     %r1,intstk+INTSTK@ha    /* get interrupt stack */
        !           462:        addi    %r1,%r1,intstk+INTSTK@l
        !           463:        lwz     %r31,0(%r1)             /* were we already running on intstk? */
        !           464:        addic.  %r31,%r31,%r1
        !           465:        stw     %r31,0(%r1)
        !           466:        beq     1f
        !           467:        mfsprg  %r1,1                   /* yes, get old SP */
        !           468: 1:
        !           469:        ba      extintr
        !           470: _C_LABEL(extsize) =    .-_C_LABEL(extint)
        !           471:
        !           472: /*
        !           473:  * And this one for the decrementer interrupt handler.
        !           474:  */
        !           475:        .globl  _C_LABEL(decrint),_C_LABEL(decrsize)
        !           476:        .type   _C_LABEL(decrint),@function
        !           477:        .type   _C_LABEL(decrsize),@object
        !           478: _C_LABEL(decrint):
        !           479:        mtsprg  1,%r1                   /* save SP */
        !           480:        stmw    %r28,tempsave(0)        /* free r28-r31 */
        !           481:        mflr    %r28                    /* save LR */
        !           482:        mfcr    %r29                    /* save CR */
        !           483:        mfxer   %r30                    /* save XER */
        !           484:        lis     %r1,intstk+INTSTK@ha    /* get interrupt stack */
        !           485:        addi    %r1,%r1,intstk+INTSTK@l
        !           486:        lwz     %r31,0(%r1)             /* were we already running on intstk? */
        !           487:        addic.  %r31,%r31,%r1
        !           488:        stw     %r31,0(%r1)
        !           489:        beq     1f
        !           490:        mfsprg  %r1,1                   /* yes, get old SP */
        !           491: 1:
        !           492:        ba      decrintr
        !           493: _C_LABEL(decrsize) =   .-_C_LABEL(decrint)
        !           494:
        !           495: /*
        !           496:  * Now the tlb software load for 603 processors:
        !           497:  * (Code essentially from the 603e User Manual, Chapter 5)
        !           498:  */
        !           499: #define        DMISS   976
        !           500: #define        DCMP    977
        !           501: #define        HASH1   978
        !           502: #define        HASH2   979
        !           503: #define        IMISS   980
        !           504: #define        ICMP    981
        !           505: #define        RPA     982
        !           506:
        !           507: #define        bdneq   bdnzf 2,
        !           508: #define        tlbli   .long   0x7c0007e4+0x800*
        !           509: #define        tlbld   .long   0x7c0007a4+0x800*
        !           510:
        !           511:        .globl  _C_LABEL(tlbimiss),_C_LABEL(tlbimsize)
        !           512:        .type   _C_LABEL(tlbimiss),@function
        !           513:        .type   _C_LABEL(tlbimsize),@object
        !           514: _C_LABEL(tlbimiss):
        !           515:        mfspr   %r2,HASH1               /* get first pointer */
        !           516:        li      %r1,8
        !           517:        mfctr   %r0                     /* save counter */
        !           518:        mfspr   %r3,ICMP                /* get first compare value */
        !           519:        addi    %r2,%r2,-8              /* predec pointer */
        !           520: 1:
        !           521:        mtctr   %r1                     /* load counter */
        !           522: 2:
        !           523:        lwzu    %r1,8(%r2)              /* get next pte */
        !           524:        cmpl    0,%r1,%r3               /* see if found pte */
        !           525:        bdneq   2b                      /* loop if not eq */
        !           526:        bne     3f                      /* not found */
        !           527:        lwz     %r1,4(%r2)              /* load tlb entry lower word */
        !           528:        andi.   %r3,%r1,8               /* check G-bit */
        !           529:        bne     4f                      /* if guarded, take ISI */
        !           530:        mtctr   %r0                     /* restore counter */
        !           531:        mfspr   %r0,IMISS               /* get the miss address for the tlbli */
        !           532:        mfsrr1  %r3                     /* get the saved cr0 bits */
        !           533:        mtcrf   0x80,%r3                /* and restore */
        !           534:        ori     %r1,%r1,0x100           /* set the reference bit */
        !           535:        mtspr   RPA,%r1                 /* set the pte */
        !           536:        srwi    %r1,%r1,8               /* get byte 7 of pte */
        !           537:        tlbli   0                       /* load the itlb */
        !           538:        stb     %r1,6(%r2)              /* update page table */
        !           539:        rfi
        !           540:
        !           541: 3:     /* not found in pteg */
        !           542:        andi.   %r1,%r3,0x40            /* have we already done second hash? */
        !           543:        bne     5f
        !           544:        mfspr   %r2,HASH2               /* get the second pointer */
        !           545:        ori     %r3,%r3,0x40            /* change the compare value */
        !           546:        li      %r1,8
        !           547:        addi    %r2,%r2,-8              /* predec pointer */
        !           548:        b       1b
        !           549: 4:     /* guarded */
        !           550:        mfsrr1  %r3
        !           551:        andi.   %r2,%r3,0xffff          /* clean upper srr1 */
        !           552:        addis   %r2,%r2,0x800           /* set srr<4> to flag prot violation */
        !           553:        b       6f
        !           554: 5:     /* not found anywhere */
        !           555:        mfsrr1  %r3
        !           556:        andi.   %r2,%r3,0xffff          /* clean upper srr1 */
        !           557:        addis   %r2,%r2,0x4000          /* set srr1<1> to flag pte not found */
        !           558: 6:
        !           559:        mtctr   %r0                     /* restore counter */
        !           560:        mtsrr1  %r2
        !           561:        mfmsr   %r0
        !           562:        xoris   %r0,%r0,2               /* flip the msr<tgpr> bit */
        !           563:        mtcrf   0x80,%r3                /* restore cr0 */
        !           564:        mtmsr   %r0                     /* now with native gprs */
        !           565:        isync
        !           566:        ba      EXC_ISI
        !           567: _C_LABEL(tlbimsize) =  .-_C_LABEL(tlbimiss)
        !           568:
        !           569:        .globl  _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize)
        !           570:        .type   _C_LABEL(tlbdlmiss),@function
        !           571:        .type   _C_LABEL(tlbdlmsize),@object
        !           572: _C_LABEL(tlbdlmiss):
        !           573:        mfspr   %r2,HASH1               /* get first pointer */
        !           574:        li      %r1,8
        !           575:        mfctr   %r0                     /* save counter */
        !           576:        mfspr   %r3,DCMP                /* get first compare value */
        !           577:        addi    %r2,%r2,-8              /* predec pointer */
        !           578: 1:
        !           579:        mtctr   %r1                     /* load counter */
        !           580: 2:
        !           581:        lwzu    %r1,8(%r2)              /* get next pte */
        !           582:        cmpl    0,%r1,%r3               /* see if found pte */
        !           583:        bdneq   2b                      /* loop if not eq */
        !           584:        bne     3f                      /* not found */
        !           585:        lwz     %r1,4(%r2)              /* load tlb entry lower word */
        !           586:        mtctr   %r0                     /* restore counter */
        !           587:        mfspr   %r0,DMISS               /* get the miss address for the tlbld */
        !           588:        mfsrr1  %r3                     /* get the saved cr0 bits */
        !           589:        mtcrf   0x80,%r3                /* and restore */
        !           590:        ori     %r1,%r1,0x100           /* set the reference bit */
        !           591:        mtspr   RPA,%r1                 /* set the pte */
        !           592:        srwi    %r1,%r1,8               /* get byte 7 of pte */
        !           593:        tlbld   0                       /* load the dtlb */
        !           594:        stb     %r1,6(%r2)              /* update page table */
        !           595:        rfi
        !           596:
        !           597: 3:     /* not found in pteg */
        !           598:        andi.   %r1,%r3,0x40            /* have we already done second hash? */
        !           599:        bne     5f
        !           600:        mfspr   %r2,HASH2               /* get the second pointer */
        !           601:        ori     %r3,%r3,0x40            /* change the compare value */
        !           602:        li      %r1,8
        !           603:        addi    %r2,%r2,-8              /* predec pointer */
        !           604:        b       1b
        !           605: 5:     /* not found anywhere */
        !           606:        mfsrr1  %r3
        !           607:        lis     %r1,0x4000              /* set dsisr<1> to flag pte not found */
        !           608:        mtctr   %r0                     /* restore counter */
        !           609:        andi.   %r2,%r3,0xffff          /* clean upper srr1 */
        !           610:        mtsrr1  %r2
        !           611:        mtdsisr %r1                     /* load the dsisr */
        !           612:        mfspr   %r1,DMISS               /* get the miss address */
        !           613:        mtdar   %r1                     /* put in dar */
        !           614:        mfmsr   %r0
        !           615:        xoris   %r0,%r0,2               /* flip the msr<tgpr> bit */
        !           616:        mtcrf   0x80,%r3                /* restore cr0 */
        !           617:        mtmsr   %r0                     /* now with native gprs */
        !           618:        isync
        !           619:        ba      EXC_DSI
        !           620: _C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss)
        !           621:
        !           622:        .globl  _C_LABEL(tlbdsmiss),_C_LABEL(tlbdsmsize)
        !           623:        .type   _C_LABEL(tlbdsmiss),@function
        !           624:        .type   _C_LABEL(tlbdsmsize),@object
        !           625: _C_LABEL(tlbdsmiss):
        !           626:        mfspr   %r2,HASH1               /* get first pointer */
        !           627:        li      %r1,8
        !           628:        mfctr   %r0                     /* save counter */
        !           629:        mfspr   %r3,DCMP                /* get first compare value */
        !           630:        addi    %r2,%r2,-8              /* predec pointer */
        !           631: 1:
        !           632:        mtctr   %r1                     /* load counter */
        !           633: 2:
        !           634:        lwzu    %r1,8(%r2)              /* get next pte */
        !           635:        cmpl    0,%r1,%r3               /* see if found pte */
        !           636:        bdneq   2b                      /* loop if not eq */
        !           637:        bne     3f                      /* not found */
        !           638:        lwz     %r1,4(%r2)              /* load tlb entry lower word */
        !           639:        andi.   %r3,%r1,0x80            /* check the C-bit */
        !           640:        beq     4f
        !           641: 5:
        !           642:        mtctr   %r0                     /* restore counter */
        !           643:        mfspr   %r0,DMISS               /* get the miss address for the tlbld */
        !           644:        mfsrr1  %r3                     /* get the saved cr0 bits */
        !           645:        mtcrf   0x80,%r3                /* and restore */
        !           646:        mtspr   RPA,%r1                 /* set the pte */
        !           647:        tlbld   0                       /* load the dtlb */
        !           648:        rfi
        !           649:
        !           650: 3:     /* not found in pteg */
        !           651:        andi.   %r1,%r3,0x40            /* have we already done second hash? */
        !           652:        bne     5f
        !           653:        mfspr   %r2,HASH2               /* get the second pointer */
        !           654:        ori     %r3,%r3,0x40            /* change the compare value */
        !           655:        li      %r1,8
        !           656:        addi    %r2,%r2,-8              /* predec pointer */
        !           657:        b       1b
        !           658: 4:     /* found, but C-bit = 0 */
        !           659:        rlwinm. %r3,%r1,30,0,1          /* test PP */
        !           660:        bge-    7f
        !           661:        andi.   %r3,%r1,1
        !           662:        beq+    8f
        !           663: 9:     /* found, but protection violation (PP==00)*/
        !           664:        mfsrr1  %r3
        !           665:        lis     %r1,0xa00       /* indicate protection violation on store */
        !           666:        b       1f
        !           667: 7:     /* found, PP=1x */
        !           668:        mfspr   %r3,DMISS               /* get the miss address */
        !           669:        mfsrin  %r1,%r3                 /* get the segment register */
        !           670:        mfsrr1  %r3
        !           671:        rlwinm  %r3,%r3,18,31,31        /* get PR-bit */
        !           672:        rlwnm.  %r2,%r2,3,1,1           /* get the key */
        !           673:        bne-    9b                      /* protection violation */
        !           674: 8:     /* found, set reference/change bits */
        !           675:        lwz     %r1,4(%r2)              /* reload tlb entry */
        !           676:        ori     %r1,%r1,0x180
        !           677:        sth     %r1,6(%r2)
        !           678:        b       5b
        !           679: 5:     /* not found anywhere */
        !           680:        mfsrr1  %r3
        !           681:        lis     %r1,0x4200              /* set dsisr<1> to flag pte not found */
        !           682:                                        /* dsisr<6> to flag store */
        !           683: 1:
        !           684:        mtctr   %r0                     /* restore counter */
        !           685:        andi.   %r2,%r3,0xffff          /* clean upper srr1 */
        !           686:        mtsrr1  %r2
        !           687:        mtdsisr %r1                     /* load the dsisr */
        !           688:        mfspr   %r1,DMISS               /* get the miss address */
        !           689:        mtdar   %r1                     /* put in dar */
        !           690:        mfmsr   %r0
        !           691:        xoris   %r0,%r0,2               /* flip the msr<tgpr> bit */
        !           692:        mtcrf   0x80,%r3                /* restore cr0 */
        !           693:        mtmsr   %r0                     /* now with native gprs */
        !           694:        isync
        !           695:        ba      EXC_DSI
        !           696: _C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss)
        !           697:
        !           698: #ifdef DDB
        !           699: #define ddbsave        0xde0           /* primary save area for DDB */
        !           700: /*
        !           701:  * In case of DDB we want a separate trap catcher for it
        !           702:  */
        !           703:        .local  ddbstk
        !           704:        .comm   ddbstk,INTSTK,8 /* ddb stack */
        !           705:
        !           706:        .globl  _C_LABEL(ddblow),_C_LABEL(ddbsize)
        !           707: _C_LABEL(ddblow):
        !           708:        mtsprg  1,%r1                   /* save SP */
        !           709:        stmw    %r28,ddbsave(0)         /* free r28-r31 */
        !           710:        mflr    %r28                    /* save LR */
        !           711:        mfcr    %r29                    /* save CR */
        !           712:        lis     %r1,ddbstk+INTSTK@ha    /* get new SP */
        !           713:        addi    %r1,%r1,ddbstk+INTSTK@l
        !           714:        bla     ddbtrap
        !           715: _C_LABEL(ddbsize) =    .-_C_LABEL(ddblow)
        !           716: #endif  /* DDB */
        !           717:
        !           718:
        !           719: /*
        !           720:  * FRAME_SETUP assumes:
        !           721:  *     SPRG1           SP (1)
        !           722:  *     savearea        r28-r31,DAR,DSISR       (DAR & DSISR only for DSI traps)
        !           723:  *     28              LR
        !           724:  *     29              CR
        !           725:  *     1               kernel stack
        !           726:  *     LR              trap type
        !           727:  *     SRR0/1          as at start of trap
        !           728:  */
        !           729: #define        FRAME_SETUP(savearea)                                           \
        !           730: /* Have to enable translation to allow access of kernel stack: */      \
        !           731:        mfsrr0  %r30;                                                   \
        !           732:        mfsrr1  %r31;                                                   \
        !           733:        stmw    %r30,savearea+24(0);                                    \
        !           734:        mfmsr   %r30;                                                   \
        !           735:        ori     %r30,%r30,(PSL_DR|PSL_IR);                              \
        !           736:        mtmsr   %r30;                                                   \
        !           737:        isync;                                                          \
        !           738:        mfsprg  %r31,1;                                                 \
        !           739:        stwu    %r31,-FRAMELEN(%r1);                                    \
        !           740:        stw     %r0,FRAME_0+8(%r1);                                     \
        !           741:        stw     %r31,FRAME_1+8(%r1);                                    \
        !           742:        stw     %r28,FRAME_LR+8(%r1);                                   \
        !           743:        stw     %r29,FRAME_CR+8(%r1);                                   \
        !           744:        lmw     %r28,savearea(0);                                       \
        !           745:        stmw    %r2,FRAME_2+8(%r1);                                     \
        !           746:        lmw     %r28,savearea+16(0);                                    \
        !           747:        mfxer   %r3;                                                    \
        !           748:        mfctr   %r4;                                                    \
        !           749:        mflr    %r5;                                                    \
        !           750:        andi.   %r5,%r5,0xff00;                                         \
        !           751:        stw     %r3,FRAME_XER+8(%r1);                                   \
        !           752:        stw     %r4,FRAME_CTR+8(%r1);                                   \
        !           753:        stw     %r5,FRAME_EXC+8(%r1);                                   \
        !           754:        stw     %r28,FRAME_DAR+8(%r1);                                  \
        !           755:        stw     %r29,FRAME_DSISR+8(%r1);                                \
        !           756:        stw     %r30,FRAME_SRR0+8(%r1);                                 \
        !           757:        stw     %r31,FRAME_SRR1+8(%r1)
        !           758:
        !           759: #define        FRAME_LEAVE(savearea)                                           \
        !           760: /* Now restore regs: */                                                        \
        !           761:        lwz     %r2,FRAME_SRR0+8(%r1);                                  \
        !           762:        lwz     %r3,FRAME_SRR1+8(%r1);                                  \
        !           763:        lwz     %r4,FRAME_CTR+8(%r1);                                   \
        !           764:        lwz     %r5,FRAME_XER+8(%r1);                                   \
        !           765:        lwz     %r6,FRAME_LR+8(%r1);                                    \
        !           766:        lwz     %r7,FRAME_CR+8(%r1);                                    \
        !           767:        stw     %r2,savearea(0);                                        \
        !           768:        stw     %r3,savearea+4(0);                                      \
        !           769:        mtctr   %r4;                                                    \
        !           770:        mtxer   %r5;                                                    \
        !           771:        mtlr    %r6;                                                    \
        !           772:        mtsprg  1,%r7;                  /* save cr */                   \
        !           773:        lmw     %r2,FRAME_2+8(%r1);                                     \
        !           774:        lwz     %r0,FRAME_0+8(%r1);                                     \
        !           775:        lwz     %r1,FRAME_1+8(%r1);                                     \
        !           776:        mtsprg  2,%r2;                  /* save r2 & r3 */              \
        !           777:        mtsprg  3,%r3;                                                  \
        !           778: /* Disable translation, machine check and recoverability: */           \
        !           779:        mfmsr   %r2;                                                    \
        !           780:        lis     %r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@ha;                   \
        !           781:        addi    %r3,%r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l;                \
        !           782:        andc    %r2,%r2,%r3;                                            \
        !           783:        mtmsr   %r2;                                                    \
        !           784:        isync;                                                          \
        !           785: /* Decide whether we return to user mode: */                           \
        !           786:        lwz     %r3,savearea+4(0);                                      \
        !           787:        mtcr    %r3;                                                    \
        !           788:        bc      4,17,1f;                /* branch if PSL_PR is false */ \
        !           789: /* Restore user & kernel access SR: */                                 \
        !           790:        lis     %r2,_C_LABEL(curpm)@ha; /* get real address of pmap */  \
        !           791:        lwz     %r2,_C_LABEL(curpm)@l(%r2);                             \
        !           792:        lwz     %r3,PM_USRSR(%r2);                                      \
        !           793:        mtsr    PPC_USER_SR,%r3;                                        \
        !           794:        lwz     %r3,PM_KERNELSR(%r2);                                   \
        !           795:        mtsr    PPC_KERNEL_SR,%r3;                                      \
        !           796: 1:     mfsprg  %r2,1;                  /* restore cr */                \
        !           797:        mtcr    %r2;                                                    \
        !           798:        lwz     %r2,savearea(0);                                        \
        !           799:        lwz     %r3,savearea+4(0);                                      \
        !           800:        mtsrr0  %r2;                                                    \
        !           801:        mtsrr1  %r3;                                                    \
        !           802:        mfsprg  %r2,2;                  /* restore r2 & r3 */           \
        !           803:        mfsprg  %r3,3
        !           804:
        !           805: /*
        !           806:  * Preamble code for DSI/ISI traps
        !           807:  */
        !           808: disitrap:
        !           809:        lmw     %r30,disisave(0)
        !           810:        stmw    %r30,tempsave(0)
        !           811:        lmw     %r30,disisave+8(0)
        !           812:        stmw    %r30,tempsave+8(0)
        !           813:        mfdar   %r30
        !           814:        mfdsisr %r31
        !           815:        stmw    %r30,tempsave+16(0)
        !           816: realtrap:
        !           817:        /* Test whether we already had PR set */
        !           818:        mfsrr1  %r1
        !           819:        mtcr    %r1
        !           820:        /* restore SP (might have been overwritten) */
        !           821:        mfsprg  %r1,1
        !           822:        bc      4,17,s_trap             /* branch if PSL_PR is false */
        !           823:        lis     %r1,_C_LABEL(curpcb)@ha
        !           824:        lwz     %r1,_C_LABEL(curpcb)@l(%r1)
        !           825:        addi    %r1,%r1,USPACE          /* stack is top of user struct */
        !           826: /*
        !           827:  * Now the common trap catching code.
        !           828:  */
        !           829: s_trap:
        !           830: /* First have to enable KERNEL mapping */
        !           831:        lis     %r31,PPC_KERNEL_SEGMENT@ha
        !           832:        addi    %r31,%r31,PPC_KERNEL_SEGMENT@l
        !           833:        mtsr    PPC_KERNEL_SR,%r31
        !           834:        FRAME_SETUP(tempsave)
        !           835: /* Now we can recover interrupts again: */
        !           836:        mfmsr   %r7
        !           837:        mfsrr1  %r31
        !           838:        andi.   %r31,%r31,PSL_EE        /* restore EE from previous context */
        !           839:        or      %r7,%r7,%r31
        !           840:        ori     %r7,%r7,(PSL_ME|PSL_RI)
        !           841:        mtmsr   %r7
        !           842:        isync
        !           843: /* Call C trap code: */
        !           844: trapagain:
        !           845:        addi    %r3,%r1,8
        !           846:        bl      _C_LABEL(trap)
        !           847: trapexit:
        !           848: /* Disable interrupts: */
        !           849:        mfmsr   %r3
        !           850:        andi.   %r3,%r3,~PSL_EE@l
        !           851:        mtmsr   %r3
        !           852: /* Test AST pending: */
        !           853:        lwz     %r5,FRAME_SRR1+8(%r1)
        !           854:        mtcr    %r5
        !           855:        bc      4,17,1f                 /* branch if PSL_PR is false */
        !           856:        lis     %r3,_C_LABEL(astpending)@ha
        !           857:        lwz     %r4,_C_LABEL(astpending)@l(%r3)
        !           858:        andi.   %r4,%r4,1
        !           859:        beq     1f
        !           860:        li      %r6,EXC_AST
        !           861:        stw     %r6,FRAME_EXC+8(%r1)
        !           862:        b       trapagain
        !           863: 1:
        !           864:        FRAME_LEAVE(tempsave)
        !           865:        rfi
        !           866:
        !           867: /*
        !           868:  * Child comes here at the end of a fork.
        !           869:  * Mostly similar to the above.
        !           870:  */
        !           871:        .globl  _C_LABEL(fork_trampoline)
        !           872:        .type   _C_LABEL(fork_trampoline),@function
        !           873: _C_LABEL(fork_trampoline):
        !           874:        li      %r3,0
        !           875:        bl      _C_LABEL(lcsplx)
        !           876:        mtlr    %r31
        !           877:        mr      %r3,%r30
        !           878:        blrl                            /* jump indirect to r31 */
        !           879:        b       trapexit
        !           880:
        !           881: /*
        !           882:  * DSI second stage fault handler
        !           883:  */
        !           884: s_dsitrap:
        !           885:        mfdsisr %r31                    /* test if this is spill fault */
        !           886:        mtcr    %r31
        !           887:        mtsprg  1,%r1                   /* save SP */
        !           888:        bc      4,1,disitrap            /* branch if table miss is false */
        !           889:        lis     %r1,spillstk+SPILLSTK@ha
        !           890:        addi    %r1,%r1,spillstk+SPILLSTK@l     /* get spill stack */
        !           891:        stwu    %r1,-52(%r1)
        !           892:        stw     %r0,48(%r1)             /* save non-volatile registers */
        !           893:        stw     %r3,44(%r1)
        !           894:        stw     %r4,40(%r1)
        !           895:        stw     %r5,36(%r1)
        !           896:        stw     %r6,32(%r1)
        !           897:        stw     %r7,28(%r1)
        !           898:        stw     %r8,24(%r1)
        !           899:        stw     %r9,20(%r1)
        !           900:        stw     %r10,16(%r1)
        !           901:        stw     %r11,12(%r1)
        !           902:        stw     %r12,8(%r1)
        !           903:        mfxer   %r30                    /* save XER */
        !           904:        mtsprg  2,%r30
        !           905:        mflr    %r30                    /* save trap type */
        !           906:        mfctr   %r31                    /* & CTR */
        !           907:        mfdar   %r3
        !           908:        mfsrr1  %r4
        !           909:        mfdsisr %r5
        !           910:        li      %r6, 0
        !           911: s_pte_spill:
        !           912:        bl      _C_LABEL(pte_spill_r)   /* try a spill */
        !           913:        cmpwi   0,%r3,0
        !           914:        mtctr   %r31                    /* restore CTR */
        !           915:        mtlr    %r30                    /* and trap type */
        !           916:        mfsprg  %r31,2                  /* get saved XER */
        !           917:        mtxer   %r31                    /* restore XER */
        !           918:        lwz     %r12,8(%r1)             /* restore non-volatile registers */
        !           919:        lwz     %r11,12(%r1)
        !           920:        lwz     %r10,16(%r1)
        !           921:        lwz     %r9,20(%r1)
        !           922:        lwz     %r8,24(%r1)
        !           923:        lwz     %r7,28(%r1)
        !           924:        lwz     %r6,32(%r1)
        !           925:        lwz     %r5,36(%r1)
        !           926:        lwz     %r4,40(%r1)
        !           927:        lwz     %r3,44(%r1)
        !           928:        lwz     %r0,48(%r1)
        !           929:        beq     disitrap
        !           930:        mfsprg  %r1,1                   /* restore SP */
        !           931:        mtcr    %r29                    /* restore CR */
        !           932:        mtlr    %r28                    /* restore LR */
        !           933:        lmw     %r28,disisave(0)        /* restore r28-r31 */
        !           934:        rfi                             /* return to trapped code */
        !           935:
        !           936: /*
        !           937:  * ISI second stage fault handler
        !           938:  */
        !           939: s_isitrap:
        !           940:        mfsrr1  %r31                    /* test if this may be a spill fault */
        !           941:        mtcr    %r31
        !           942:        mtsprg  1,%r1                   /* save SP */
        !           943:        bc      4,%r1,disitrap          /* branch if table miss is false */
        !           944:        lis     %r1,spillstk+SPILLSTK@ha
        !           945:        addi    %r1,%r1,spillstk+SPILLSTK@l     /* get spill stack */
        !           946:        stwu    %r1,-52(%r1)
        !           947:        stw     %r0,48(%r1)             /* save non-volatile registers */
        !           948:        stw     %r3,44(%r1)
        !           949:        stw     %r4,40(%r1)
        !           950:        stw     %r5,36(%r1)
        !           951:        stw     %r6,32(%r1)
        !           952:        stw     %r7,28(%r1)
        !           953:        stw     %r8,24(%r1)
        !           954:        stw     %r9,20(%r1)
        !           955:        stw     %r10,16(%r1)
        !           956:        stw     %r11,12(%r1)
        !           957:        stw     %r12,8(%r1)
        !           958:        mfxer   %r30                    /* save XER */
        !           959:        mtsprg  2,%r30
        !           960:        mflr    %r30                    /* save trap type */
        !           961:        mfctr   %r31                    /* & ctr */
        !           962:        mfsrr0  %r3
        !           963:        mfsrr1  %r4
        !           964:        li      %r5, 0
        !           965:        li      %r6, 1
        !           966:        b       s_pte_spill             /* above */
        !           967:
        !           968: /*
        !           969:  * External interrupt second level handler
        !           970:  */
        !           971: #define        INTRENTER                                                       \
        !           972: /* Save non-volatile registers: */                                     \
        !           973:        stwu    %r1,-88(%r1);           /* temporarily */               \
        !           974:        stw     %r0,84(%r1);                                            \
        !           975:        mfsprg  %r0,1;                  /* get original SP */           \
        !           976:        stw     %r0,0(%r1);             /* and store it */              \
        !           977:        stw     %r3,80(%r1);                                            \
        !           978:        stw     %r4,76(%r1);                                            \
        !           979:        stw     %r5,72(%r1);                                            \
        !           980:        stw     %r6,68(%r1);                                            \
        !           981:        stw     %r7,64(%r1);                                            \
        !           982:        stw     %r8,60(%r1);                                            \
        !           983:        stw     %r9,56(%r1);                                            \
        !           984:        stw     %r10,52(%r1);                                           \
        !           985:        stw     %r11,48(%r1);                                           \
        !           986:        stw     %r12,44(%r1);                                           \
        !           987:        stw     %r28,40(%r1);           /* saved LR */                  \
        !           988:        stw     %r29,36(%r1);           /* saved CR */                  \
        !           989:        stw     %r30,32(%r1);           /* saved XER */                 \
        !           990:        lmw     %r28,tempsave(0);       /* restore r28-r31 */           \
        !           991:        mfctr   %r6;                                                    \
        !           992:        lis     %r5,_C_LABEL(intr_depth)@ha;                            \
        !           993:        lwz     %r5,_C_LABEL(intr_depth)@l(%r5);                        \
        !           994:        mfsrr0  %r4;                                                    \
        !           995:        mfsrr1  %r3;                                                    \
        !           996:        stw     %r6,28(%r1);                                            \
        !           997:        stw     %r5,20(%r1);                                            \
        !           998:        stw     %r4,12(%r1);                                            \
        !           999:        stw     %r3,8(%r1);                                             \
        !          1000: /* interrupts are recoverable here, and enable translation */          \
        !          1001:        lis     %r3,(PPC_KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@ha;          \
        !          1002:        addi    %r3,%r3,(PPC_KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@l;       \
        !          1003:        mtsr    PPC_KERNEL_SR,%r3;                                      \
        !          1004:        mfmsr   %r5;                                                    \
        !          1005:        ori     %r5,%r5,(PSL_IR|PSL_DR|PSL_RI);                         \
        !          1006:        mtmsr   %r5;                                                    \
        !          1007:        isync
        !          1008:
        !          1009:        .globl  _C_LABEL(extint_call)
        !          1010:        .type   _C_LABEL(extint_call),@function
        !          1011: extintr:
        !          1012:        INTRENTER
        !          1013: _C_LABEL(extint_call):
        !          1014:        bl      _C_LABEL(extint_call)           /* to be filled in later */
        !          1015: intr_exit:
        !          1016: /* Disable interrupts (should already be disabled) and MMU here: */
        !          1017:        mfmsr   %r3
        !          1018:        andi.   %r3,%r3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l
        !          1019:        mtmsr   %r3
        !          1020:        isync
        !          1021: /* restore possibly overwritten registers: */
        !          1022:        lwz     %r12,44(%r1)
        !          1023:        lwz     %r11,48(%r1)
        !          1024:        lwz     %r10,52(%r1)
        !          1025:        lwz     %r9,56(%r1)
        !          1026:        lwz     %r8,60(%r1)
        !          1027:        lwz     %r7,64(%r1)
        !          1028:        lwz     %r6,8(%r1)
        !          1029:        lwz     %r5,12(%r1)
        !          1030:        lwz     %r4,28(%r1)
        !          1031:        lwz     %r3,32(%r1)
        !          1032:        mtsrr1  %r6
        !          1033:        mtsrr0  %r5
        !          1034:        mtctr   %r4
        !          1035:        mtxer   %r3
        !          1036: /* Returning to user mode? */
        !          1037:        mtcr    %r6                     /* saved SRR1 */
        !          1038:        bc      4,17,1f                 /* branch if PSL_PR is false */
        !          1039:        lis     %r3,_C_LABEL(curpm)@ha  /* get current pmap real address */
        !          1040:        lwz     %r3,_C_LABEL(curpm)@l(%r3)
        !          1041:        lwz     %r3,PM_KERNELSR(%r3)
        !          1042:        mtsr    PPC_KERNEL_SR,%r3               /* Restore kernel SR */
        !          1043:        lis     %r3,_C_LABEL(astpending)@ha     /* Test AST pending */
        !          1044:        lwz     %r4,_C_LABEL(astpending)@l(%r3)
        !          1045:        andi.   %r4,%r4,1
        !          1046:        beq     1f
        !          1047: /* Setup for entry to realtrap: */
        !          1048:        lwz     %r3,0(%r1)              /* get saved SP */
        !          1049:        mtsprg  %r1,3
        !          1050:        li      %r6,EXC_AST
        !          1051:        stmw    %r28,tempsave(0)        /* establish tempsave again */
        !          1052:        mtlr    %r6
        !          1053:        lwz     %r28,40(%r1)            /* saved LR */
        !          1054:        lwz     %r29,36(%r1)            /* saved CR */
        !          1055:        lwz     %r6,68(%r1)
        !          1056:        lwz     %r5,72(%r1)
        !          1057:        lwz     %r4,76(%r1)
        !          1058:        lwz     %r3,80(%r1)
        !          1059:        lwz     %r0,84(%r1)
        !          1060:        lis     %r30,_C_LABEL(intr_depth)@ha    /* adjust reentrancy count */
        !          1061:        lwz     %r31,_C_LABEL(intr_depth)@l(%r30)
        !          1062:        addi    %r31,%r31,-1
        !          1063:        stw     %r31,_C_LABEL(intr_depth)@l(%r30)
        !          1064:        b       realtrap
        !          1065: 1:
        !          1066: /* Here is the normal exit of extintr: */
        !          1067:        lwz     %r5,36(%r1)
        !          1068:        lwz     %r6,40(%r1)
        !          1069:        mtcr    %r5
        !          1070:        mtlr    %r6
        !          1071:        lwz     %r6,68(%r1)
        !          1072:        lwz     %r5,72(%r1)
        !          1073:        lis     %r3,_C_LABEL(intr_depth)@ha     /* adjust reentrancy count */
        !          1074:        lwz     %r4,_C_LABEL(intr_depth)@l(%r3)
        !          1075:        addi    %r4,%r4,-1
        !          1076:        stw     %r4,_C_LABEL(intr_depth)@l(%r3)
        !          1077:        lwz     %r4,76(%r1)
        !          1078:        lwz     %r3,80(%r1)
        !          1079:        lwz     %r0,84(%r1)
        !          1080:        lwz     %r1,0(%r1)
        !          1081:        rfi
        !          1082:
        !          1083: /*
        !          1084:  * Decrementer interrupt second level handler
        !          1085:  */
        !          1086: decrintr:
        !          1087:        INTRENTER
        !          1088:        addi    %r3,%r1,8                       /* intr frame */
        !          1089:        bl      _C_LABEL(decr_intr)
        !          1090:        b       intr_exit
        !          1091:
        !          1092:
        !          1093: /*
        !          1094:  * int setfault()
        !          1095:  *
        !          1096:  * Similar to setjmp to setup for handling faults on accesses to user memory.
        !          1097:  * Any routine using this may only call bcopy, either the form below,
        !          1098:  * or the (currently used) C code optimized, so it doesn't use any non-volatile
        !          1099:  * registers.
        !          1100:  */
        !          1101:        .globl  _C_LABEL(setfault)
        !          1102:        .type   _C_LABEL(setfault),@function
        !          1103: _C_LABEL(setfault):
        !          1104:        mflr    %r0
        !          1105:        mfcr    %r12
        !          1106:        mfmsr   %r2
        !          1107:        lis     %r4,_C_LABEL(curpcb)@ha
        !          1108:        lwz     %r4,_C_LABEL(curpcb)@l(%r4)
        !          1109:        stw     %r3,PCB_FAULT(%r4)
        !          1110:        stw     %r0,0(%r3)
        !          1111:        stw     %r2,4(%r3)
        !          1112:        stw     %r1,8(%r3)
        !          1113:        stmw    %r12,12(%r3)
        !          1114:        li      %r3,0
        !          1115:        blr
        !          1116:
        !          1117: /*
        !          1118:  * The following code gets copied to the top of the user stack on process
        !          1119:  * execution.  It does signal trampolining on signal delivery.
        !          1120:  *
        !          1121:  * On entry r1 points to a struct sigframe at bottom of current stack.
        !          1122:  * All other registers are unchanged.
        !          1123:  */
        !          1124:        .globl  _C_LABEL(sigcode),_C_LABEL(esigcode)
        !          1125:        .type   _C_LABEL(sigcode),@function
        !          1126:        .type   _C_LABEL(esigcode),@function
        !          1127: _C_LABEL(sigcode):
        !          1128:        addi    %r1,%r1,-((16+FPSIG_SIZEOF+15)& ~0xf)           /* reserved space for callee */
        !          1129:        addi    %r6,%r1,8
        !          1130:        stfd    %f0,0(%r6)
        !          1131:        stfd    %f1,8(%r6)
        !          1132:        stfd    %f2,16(%r6)
        !          1133:        stfd    %f3,24(%r6)
        !          1134:        stfd    %f4,32(%r6)
        !          1135:        stfd    %f5,40(%r6)
        !          1136:        stfd    %f6,48(%r6)
        !          1137:        stfd    %f7,56(%r6)
        !          1138:        stfd    %f8,64(%r6)
        !          1139:        stfd    %f9,72(%r6)
        !          1140:        stfd    %f10,80(%r6)
        !          1141:        stfd    %f11,88(%r6)
        !          1142:        stfd    %f12,96(%r6)
        !          1143:        stfd    %f13,104(%r6)
        !          1144:        mffs    %f0
        !          1145:        stfd    %f0,112(%r6)
        !          1146:        lfd     %f0,0(%r6)      /* restore the clobbered register */
        !          1147:
        !          1148:        blrl
        !          1149:        addi    %r6,%r1,8
        !          1150:        lfd     %f0,112(%r6)
        !          1151:        mtfsf   0xff,%f0
        !          1152:        lfd     %f0,0(%r6)
        !          1153:        lfd     %f1,8(%r6)
        !          1154:        lfd     %f2,16(%r6)
        !          1155:        lfd     %f3,24(%r6)
        !          1156:        lfd     %f4,32(%r6)
        !          1157:        lfd     %f5,40(%r6)
        !          1158:        lfd     %f6,48(%r6)
        !          1159:        lfd     %f7,56(%r6)
        !          1160:        lfd     %f8,64(%r6)
        !          1161:        lfd     %f9,72(%r6)
        !          1162:        lfd     %f10,80(%r6)
        !          1163:        lfd     %f11,88(%r6)
        !          1164:        lfd     %f12,96(%r6)
        !          1165:        lfd     %f13,104(%r6)
        !          1166:        addi    %r3,%r1,((16+FPSIG_SIZEOF+15)&~0xf)+SF_SC       /* compute &sf_sc */
        !          1167:        li      %r0,SYS_sigreturn
        !          1168:        sc                              /* sigreturn(scp) */
        !          1169:        li      %r0,SYS_exit
        !          1170:        sc                              /* exit(errno) */
        !          1171: _C_LABEL(esigcode):
        !          1172:
        !          1173:
        !          1174: #ifdef DDB
        !          1175: /*
        !          1176:  * Deliberate entry to ddbtrap
        !          1177:  */
        !          1178:        .globl  _C_LABEL(ddb_trap)
        !          1179: _C_LABEL(ddb_trap):
        !          1180:        mtsprg  %r1,1
        !          1181:        mfmsr   %r3
        !          1182:        mtsrr1  %r3
        !          1183:        andi.   %r3,%r3,~(PSL_EE|PSL_ME)@l
        !          1184:        mtmsr   %r3                             /* disable interrupts */
        !          1185:        isync
        !          1186:        stmw    %r28,ddbsave(0)
        !          1187:        mflr    %r28
        !          1188:        li      %r29,EXC_BPT
        !          1189:        mtlr    %r29
        !          1190:        mfcr    %r29
        !          1191:        mtsrr0  %r28
        !          1192:
        !          1193: /*
        !          1194:  * Now the ddb trap catching code.
        !          1195:  */
        !          1196: ddbtrap:
        !          1197:        FRAME_SETUP(ddbsave)
        !          1198: /* Call C trap code: */
        !          1199:        addi    %r3,%r1,8
        !          1200:        bl      _C_LABEL(ddb_trap_glue)
        !          1201:        or.     %r3,%r3,%r3
        !          1202:        bne     ddbleave
        !          1203: /* This wasn't for DDB, so switch to real trap: */
        !          1204:        lwz     %r3,FRAME_EXC+8(%r1)    /* save exception */
        !          1205:        stw     %r3,ddbsave+8(0)
        !          1206:        FRAME_LEAVE(ddbsave)
        !          1207:        mtsprg  %r1,1                   /* prepare for entrance to realtrap */
        !          1208:        stmw    %r28,tempsave(0)
        !          1209:        mflr    %r28
        !          1210:        mfcr    %r29
        !          1211:        lwz     %r31,ddbsave+8(0)
        !          1212:        mtlr    %r31
        !          1213:        b       realtrap
        !          1214: ddbleave:
        !          1215:        FRAME_LEAVE(ddbsave)
        !          1216:        rfi
        !          1217: #endif /* DDB */
        !          1218:

CVSweb