[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

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