[BACK]Return to locore.S CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / macppc / macppc

Annotation of src/sys/arch/macppc/macppc/locore.S, Revision 1.27

1.27    ! tsubai      1: /*     $NetBSD: locore.S,v 1.26 2000/07/06 22:56:24 tsubai Exp $       */
1.1       tsubai      2:
                      3: /*
                      4:  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
                      5:  * Copyright (C) 1995, 1996 TooLs GmbH.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by TooLs GmbH.
                     19:  * 4. The name of TooLs GmbH may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     26:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     27:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     28:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     29:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     30:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     31:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
1.4       jonathan   34: #include "opt_ddb.h"
1.21      ws         35: #include "opt_ipkdb.h"
1.27    ! tsubai     36: #include "opt_lockdebug.h"
1.24      thorpej    37: #include "opt_multiprocessor.h"
1.1       tsubai     38: #include "assym.h"
                     39:
                     40: #include <sys/syscall.h>
                     41:
                     42: #include <machine/param.h>
                     43: #include <machine/pmap.h>
                     44: #include <machine/psl.h>
                     45: #include <machine/trap.h>
                     46: #include <machine/asm.h>
                     47:
                     48: /*
                     49:  * Some instructions gas doesn't understand (yet?)
                     50:  */
                     51: #define        bdneq   bdnzf 2,
                     52:
1.26      tsubai     53: #if defined(MULTIPROCESSOR)
                     54: /*
                     55:  * Get varios per-cpu values.
                     56:  */
                     57: #define        GET_CPUINFO(r)                                          \
                     58:        mfspr   r,1023;                 /* r = cpu_number() */  \
                     59:        mulli   r,r,CI_SIZE;                                    \
                     60:        addis   r,r,_C_LABEL(cpu_info)@ha;                      \
                     61:        addi    r,r,_C_LABEL(cpu_info)@l;
                     62: #endif
                     63:
1.1       tsubai     64: /*
                     65:  * Globals
                     66:  */
                     67:        .data
                     68: GLOBAL(esym)
                     69:        .long   0                       /* end of symbol table */
                     70: GLOBAL(proc0paddr)
                     71:        .long   0                       /* proc0 p_addr */
                     72:
                     73: GLOBAL(intrnames)
                     74:        .asciz  "irq0", "irq1", "irq2", "irq3"
                     75:        .asciz  "irq4", "irq5", "irq6", "irq7"
                     76:        .asciz  "irq8", "irq9", "irq10", "irq11"
                     77:        .asciz  "irq12", "irq13", "irq14", "irq15"
                     78:        .asciz  "irq16", "irq17", "irq18", "irq19"
                     79:        .asciz  "irq20", "irq21", "irq22", "irq23"
                     80:        .asciz  "irq24", "irq25", "irq26", "irq27"
                     81:        .asciz  "irq28", "irq29", "irq30", "irq31"
1.9       tsubai     82:        .asciz  "irq32", "irq33", "irq34", "irq35"
                     83:        .asciz  "irq36", "irq37", "irq38", "irq39"
                     84:        .asciz  "irq40", "irq41", "irq42", "irq43"
                     85:        .asciz  "irq44", "irq45", "irq46", "irq47"
                     86:        .asciz  "irq48", "irq49", "irq50", "irq51"
                     87:        .asciz  "irq52", "irq53", "irq54", "irq55"
                     88:        .asciz  "irq56", "irq57", "irq58", "irq59"
                     89:        .asciz  "irq60", "irq61", "irq62", "irq63"
                     90:        .asciz  "clock", "softclock", "softnet", "softserial"
1.1       tsubai     91: GLOBAL(eintrnames)
                     92:        .align  4
                     93: GLOBAL(intrcnt)
                     94:        .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                     95:        .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1.9       tsubai     96:        .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                     97:        .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                     98:        .long   0,0,0,0
1.1       tsubai     99: GLOBAL(eintrcnt)
                    100:
1.10      tsubai    101: GLOBAL(ofmsr)
                    102:        .long   0                       /* msr used in Open Firmware */
1.8       tsubai    103:
1.20      tsubai    104: GLOBAL(powersave)
                    105:        .long   0
                    106:
1.1       tsubai    107: /*
                    108:  * File-scope for locore.S
                    109:  */
1.26      tsubai    110: #if !defined(MULTIPROCESSOR)
1.1       tsubai    111: idle_u:
                    112:        .long   0                       /* fake uarea during idle after exit */
1.26      tsubai    113: #endif
1.1       tsubai    114: openfirmware_entry:
                    115:        .long   0                       /* openfirmware entry point */
1.11      tsubai    116: srsave:
                    117:        .long   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1.1       tsubai    118:
                    119: /*
                    120:  * This symbol is here for the benefit of kvm_mkdb, and is supposed to
                    121:  * mark the start of kernel text.
                    122:  */
                    123:        .text
                    124:        .globl  _C_LABEL(kernel_text)
                    125: _C_LABEL(kernel_text):
                    126:
                    127: /*
                    128:  * Startup entry.  Note, this must be the first thing in the text
                    129:  * segment!
                    130:  */
                    131:        .text
                    132:        .globl  __start
                    133: __start:
                    134: #ifdef FIRMWORKSBUGS
                    135:        mfmsr   0
                    136:        andi.   0,0,PSL_IR|PSL_DR
                    137:        beq     1f
                    138:
                    139:        bl      _C_LABEL(ofwr_init)
                    140: 1:
                    141: #endif
1.5       tsubai    142:        mfmsr   0
1.8       tsubai    143:        lis     9,ofmsr@ha
                    144:        stw     0,ofmsr@l(9)
1.5       tsubai    145:
1.1       tsubai    146:        li      0,0
                    147:        mtmsr   0                       /* Disable FPU/MMU/exceptions */
                    148:        isync
                    149:
                    150: /* compute end of kernel memory */
                    151:        lis     8,_C_LABEL(end)@ha
                    152:        addi    8,8,_C_LABEL(end)@l
                    153: #ifdef DDB
1.14      tsubai    154:        /* skip symbol table */
1.15      tsubai    155:        cmpwi   6,0
                    156:        beq     1f
1.14      tsubai    157:        add     9,6,7                   /* r9 = args + l */
                    158:        lwz     9,-8(9)                 /* esym */
                    159:        cmpwi   9,0
                    160:        beq     1f
                    161:        mr      8,9
                    162: 1:
1.1       tsubai    163: #endif
                    164:        li      9,PGOFSET
                    165:        add     8,8,9
                    166:        andc    8,8,9
                    167:        lis     9,_C_LABEL(OF_buf)@ha
                    168:        stw     8,_C_LABEL(OF_buf)@l(9)
                    169:        addi    8,8,NBPG
1.26      tsubai    170: #if defined(MULTIPROCESSOR)
                    171:        lis     9,_C_LABEL(cpu_info)@ha
                    172:        addi    9,9,_C_LABEL(cpu_info)@l
                    173:        stw     8,CI_IDLE_PCB(9)
                    174: #else
1.1       tsubai    175:        lis     9,idle_u@ha
                    176:        stw     8,idle_u@l(9)
1.26      tsubai    177: #endif
1.1       tsubai    178:        addi    8,8,USPACE              /* space for idle_u */
                    179:        lis     9,_C_LABEL(proc0paddr)@ha
                    180:        stw     8,_C_LABEL(proc0paddr)@l(9)
                    181:        addi    1,8,USPACE-FRAMELEN     /* stackpointer for proc0 */
                    182:        mr      4,1                     /* end of mem reserved for kernel */
                    183:        xor     0,0,0
                    184:        stwu    0,-16(1)                /* end of stack chain */
                    185:
                    186:        lis     8,openfirmware_entry@ha
                    187:        stw     5,openfirmware_entry@l(8) /* save client interface handler */
                    188:        lis     3,__start@ha
                    189:        addi    3,3,__start@l
                    190:        mr      5,6                     /* args string */
                    191:        bl      _C_LABEL(initppc)
                    192:        bl      _C_LABEL(main)
                    193:        b       _C_LABEL(OF_exit)
                    194:
                    195: /*
                    196:  * OpenFirmware entry point
                    197:  */
                    198: ENTRY(openfirmware)
                    199:        mflr    0                       /* save return address */
                    200:        stw     0,4(1)
                    201:        stwu    1,-16(1)                /* setup stack frame */
                    202:
                    203:        mfmsr   4                       /* save msr */
                    204:        stw     4,8(1)
                    205:
                    206:        lis     4,openfirmware_entry@ha /* get firmware entry point */
                    207:        lwz     4,openfirmware_entry@l(4)
                    208:        mtlr    4
1.16      tsubai    209:
                    210:        li      0,0                     /* clear battable translations */
                    211:        mtdbatu 2,0
                    212:        mtdbatu 3,0
                    213:        mtibatu 2,0
                    214:        mtibatu 3,0
1.1       tsubai    215:
1.8       tsubai    216:        lis     4,ofmsr@ha              /* Open Firmware msr */
                    217:        lwz     4,ofmsr@l(4)
1.5       tsubai    218:        mtmsr   4
1.1       tsubai    219:        isync
                    220:
1.11      tsubai    221:        lis     4,srsave@ha             /* save old SR */
                    222:        addi    4,4,srsave@l
                    223:        li      5,0
                    224: 1:     mfsrin  0,5
                    225:        stw     0,0(4)
                    226:        addi    4,4,4
                    227:        addis   5,5,0x10000000@h
                    228:        cmpwi   5,0
                    229:        bne     1b
                    230:
                    231:        lis     4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
                    232:        addi    4,4,_C_LABEL(ofw_pmap)@l
                    233:        lwz     0,PM_KERNELSR(4)
                    234:        cmpwi   0,0                     /* pm_sr[KERNEL_SR] == 0? */
                    235:        beq     2f                      /* then skip (not initialized yet) */
                    236:        li      5,0
                    237: 1:     lwz     0,0(4)
                    238:        mtsrin  0,5
                    239:        addi    4,4,4
                    240:        addis   5,5,0x10000000@h
                    241:        cmpwi   5,0
                    242:        bne     1b
                    243: 2:
1.8       tsubai    244:        blrl                            /* call Open Firmware */
1.11      tsubai    245:
                    246:        lis     4,srsave@ha             /* restore saved SR */
                    247:        addi    4,4,srsave@l
                    248:        li      5,0
1.12      tsubai    249: 1:     lwz     0,0(4)
                    250:        mtsrin  0,5
1.11      tsubai    251:        addi    4,4,4
                    252:        addis   5,5,0x10000000@h
                    253:        cmpwi   5,0
                    254:        bne     1b
1.1       tsubai    255:
                    256:        lwz     4,8(1)                  /* restore msr */
                    257:        mtmsr   4
                    258:        isync
                    259:
                    260:        lwz     1,0(1)                  /* and return */
                    261:        lwz     0,4(1)
                    262:        mtlr    0
                    263:        blr
                    264:
                    265: /*
                    266:  * Switch to/from OpenFirmware real mode stack
                    267:  *
                    268:  * Note: has to be called as the very first thing in OpenFirmware interface
                    269:  * routines.
                    270:  * E.g.:
                    271:  * int
                    272:  * OF_xxx(arg1, arg2)
                    273:  * type arg1, arg2;
                    274:  * {
                    275:  *     static struct {
                    276:  *             char *name;
                    277:  *             int nargs;
                    278:  *             int nreturns;
                    279:  *             char *method;
                    280:  *             int arg1;
                    281:  *             int arg2;
                    282:  *             int ret;
                    283:  *     } args = {
                    284:  *             "xxx",
                    285:  *             2,
                    286:  *             1,
                    287:  *     };
                    288:  *
                    289:  *     ofw_stack();
                    290:  *     args.arg1 = arg1;
                    291:  *     args.arg2 = arg2;
                    292:  *     if (openfirmware(&args) < 0)
                    293:  *             return -1;
                    294:  *     return args.ret;
                    295:  * }
                    296:  */
                    297:
                    298:        .local  firmstk
                    299:        .comm   firmstk,NBPG,8
                    300:
                    301: ENTRY(ofw_stack)
                    302:        mfmsr   8                       /* turn off interrupts */
                    303:        andi.   0,8,~(PSL_EE|PSL_RI)@l
                    304:        mtmsr   0
                    305:        stw     8,4(1)                  /* abuse return address slot */
                    306:
                    307:        lwz     5,0(1)                  /* get length of stack frame */
                    308:        subf    5,1,5
                    309:
                    310:        lis     7,firmstk+NBPG-8@ha
                    311:        addi    7,7,firmstk+NBPG-8@l
                    312:        lis     6,ofw_back@ha
                    313:        addi    6,6,ofw_back@l
                    314:        subf    4,5,7                   /* make room for stack frame on
                    315:                                           new stack */
                    316:        stw     6,-4(7)                 /* setup return pointer */
                    317:        stwu    1,-8(7)
                    318:
                    319:        stw     7,-8(4)
                    320:
                    321:        addi    3,1,8
                    322:        addi    1,4,-8
                    323:        subi    5,5,8
                    324:
                    325:        b       _C_LABEL(ofbcopy)       /* and copy it */
                    326:
                    327: ofw_back:
                    328:        lwz     1,0(1)                  /* get callers original stack pointer */
                    329:
                    330:        lwz     0,4(1)                  /* get saved msr from abused slot */
                    331:        mtmsr   0
                    332:
                    333:        lwz     1,0(1)                  /* return */
                    334:        lwz     0,4(1)
                    335:        mtlr    0
                    336:        blr
                    337:
                    338: 
                    339: /*
                    340:  * No processes are runnable, so loop waiting for one.
                    341:  * Separate label here for accounting purposes.
1.27    ! tsubai    342:  * When we get here, interrupts are off (MSR[EE]=0) and sched_lock is held.
1.1       tsubai    343:  */
                    344: ASENTRY(Idle)
1.23      thorpej   345:        lis     8,_C_LABEL(sched_whichqs)@ha
                    346:        lwz     9,_C_LABEL(sched_whichqs)@l(8)
1.1       tsubai    347:
                    348:        or.     9,9,9
                    349:        bne-    .Lsw1                   /* at least one queue non-empty */
                    350:
1.27    ! tsubai    351: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
        !           352:        bl      _C_LABEL(sched_unlock_idle)
        !           353: #endif
        !           354:
        !           355:        mfmsr   3
1.1       tsubai    356:        ori     3,3,PSL_EE@l            /* reenable ints again */
                    357:        mtmsr   3
                    358:        isync
                    359:
1.20      tsubai    360: /* Check if we can use power saving mode */
                    361:        lis     8,_C_LABEL(powersave)@ha
                    362:        lwz     9,_C_LABEL(powersave)@l(8)
                    363:
                    364:        or.     9,9,9
                    365:        beq     1f
                    366:
                    367:        sync
                    368:        oris    3,3,PSL_POW@h           /* enter power saving mode */
                    369:        mtmsr   3
                    370:        isync
                    371: 1:
1.27    ! tsubai    372:        andi.   3,3,~PSL_EE@l           /* disable interrupts while
        !           373:                                           manipulating runque */
        !           374:        mtmsr   3
        !           375:
        !           376: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
        !           377:        bl      _C_LABEL(sched_lock_idle)
        !           378: #endif
1.1       tsubai    379:        b       _ASM_LABEL(Idle)
                    380:
                    381: /*
1.6       thorpej   382:  * switchexit gets called from cpu_exit to complete the exit procedure.
1.1       tsubai    383:  */
                    384: ENTRY(switchexit)
                    385: /* First switch to the idle pcb/kernel stack */
1.26      tsubai    386: #if defined(MULTIPROCESSOR)
                    387:        GET_CPUINFO(7)
                    388:        lwz     6,CI_IDLE_PCB(7)
                    389:        stw     6,CI_CURPCB(7)
                    390: #else
1.1       tsubai    391:        lis     6,idle_u@ha
                    392:        lwz     6,idle_u@l(6)
                    393:        lis     7,_C_LABEL(curpcb)@ha
                    394:        stw     6,_C_LABEL(curpcb)@l(7)
1.26      tsubai    395: #endif
1.1       tsubai    396:        addi    1,6,USPACE-16           /* 16 bytes are reserved at stack top */
1.6       thorpej   397:        /*
                    398:         * Schedule the vmspace and stack to be freed (the proc arg is
                    399:         * already in r3).
                    400:         */
                    401:        bl      _C_LABEL(exit2)
                    402:
1.27    ! tsubai    403: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
        !           404:        bl      _C_LABEL(sched_lock_idle)
        !           405: #endif
        !           406:
1.1       tsubai    407: /* Fall through to cpu_switch to actually select another proc */
                    408:        li      3,0                     /* indicate exited process */
                    409:
                    410: /*
                    411:  * void cpu_switch(struct proc *p)
                    412:  * Find a runnable process and switch to it.
                    413:  */
                    414: /* XXX noprofile?  --thorpej@netbsd.org */
                    415: ENTRY(cpu_switch)
                    416:        mflr    0                       /* save lr */
                    417:        stw     0,4(1)
                    418:        stwu    1,-16(1)
                    419:        stw     31,12(1)
                    420:        stw     30,8(1)
                    421:
                    422:        mr      30,3
1.26      tsubai    423: #if defined(MULTIPROCESSOR)
                    424:        GET_CPUINFO(3)
                    425:        xor     31,31,31
                    426:        stw     31,CI_CURPROC(3)        /* Zero to not accumulate cpu time */
                    427:        lwz     31,CI_CURPCB(3)
                    428: #else
1.1       tsubai    429:        lis     3,_C_LABEL(curproc)@ha
                    430:        xor     31,31,31
                    431:        stw     31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */
                    432:        lis     3,_C_LABEL(curpcb)@ha
                    433:        lwz     31,_C_LABEL(curpcb)@l(3)
1.26      tsubai    434: #endif
1.1       tsubai    435:
1.27    ! tsubai    436: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
        !           437: /* Release the sched_lock before processing interrupts. */
        !           438:        bl      _C_LABEL(sched_unlock_idle)
        !           439: #endif
        !           440:
1.1       tsubai    441:        xor     3,3,3
                    442:        bl      _C_LABEL(lcsplx)
                    443:        stw     3,PCB_SPL(31)           /* save spl */
                    444:
1.27    ! tsubai    445: /* Lock the scheduler. */
1.1       tsubai    446:        mfmsr   3
                    447:        andi.   3,3,~PSL_EE@l           /* disable interrupts while
                    448:                                           manipulating runque */
                    449:        mtmsr   3
                    450:        isync
1.27    ! tsubai    451: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
        !           452:        bl      _C_LABEL(sched_lock_idle)
        !           453: #endif
1.1       tsubai    454:
1.27    ! tsubai    455: /* Find a new process */
1.23      thorpej   456:        lis     8,_C_LABEL(sched_whichqs)@ha
                    457:        lwz     9,_C_LABEL(sched_whichqs)@l(8)
1.1       tsubai    458:
                    459:        or.     9,9,9
                    460:        beq-    _ASM_LABEL(Idle)        /* all queues empty */
                    461: .Lsw1:
                    462:        cntlzw  10,9
1.23      thorpej   463:        lis     4,_C_LABEL(sched_qs)@ha
                    464:        addi    4,4,_C_LABEL(sched_qs)@l
1.1       tsubai    465:        slwi    3,10,3
                    466:        add     3,3,4                   /* select queue */
                    467:
                    468:        lwz     31,P_FORW(3)            /* unlink first proc from queue */
                    469:        lwz     4,P_FORW(31)
                    470:        stw     4,P_FORW(3)
                    471:        stw     3,P_BACK(4)
                    472:
                    473:        cmpl    0,3,4                   /* queue empty? */
                    474:        bne     1f
                    475:
                    476:        lis     3,0x80000000@h
                    477:        srw     3,3,10
                    478:        andc    9,9,3
1.23      thorpej   479:        stw     9,_C_LABEL(sched_whichqs)@l(8) /* mark it empty */
1.1       tsubai    480:
                    481: 1:
                    482:        /* just did this resched thing */
                    483:        xor     3,3,3
                    484:        lis     4,_C_LABEL(want_resched)@ha
                    485:        stw     3,_C_LABEL(want_resched)@l(4)
                    486:
                    487:        stw     3,P_BACK(31)            /* probably superfluous */
1.27    ! tsubai    488:
        !           489: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
        !           490:        /* Unlock the sched_lock, but leave interrupts off, for now. */
        !           491:        bl      _C_LABEL(sched_unlock_idle)
        !           492: #endif
1.24      thorpej   493:
                    494: #if defined(MULTIPROCESSOR)
1.26      tsubai    495:        GET_CPUINFO(4)
                    496:        stw     4,P_CPU(31)             /* p->p_cpu = curcpu() */
1.24      thorpej   497: #endif
1.22      thorpej   498:
                    499:        /* Process now running on a processor. */
                    500:        li      3,SONPROC               /* p->p_stat = SONPROC */
                    501:        stb     3,P_STAT(31)
1.1       tsubai    502:
                    503:        /* record new process */
1.26      tsubai    504: #if defined(MULTIPROCESSOR)
                    505:        stw     31,CI_CURPROC(4)
                    506: #else
1.1       tsubai    507:        lis     4,_C_LABEL(curproc)@ha
                    508:        stw     31,_C_LABEL(curproc)@l(4)
1.26      tsubai    509: #endif
1.1       tsubai    510:
                    511:        mfmsr   3
                    512:        ori     3,3,PSL_EE@l            /* Now we can interrupt again */
                    513:        mtmsr   3
                    514:
                    515:        cmpl    0,31,30                 /* is it the same process? */
                    516:        beq     switch_return
                    517:
                    518:        or.     30,30,30                /* old process was exiting? */
                    519:        beq     switch_exited
                    520:
                    521:        mfsr    10,USER_SR              /* save USER_SR for copyin/copyout */
                    522:        mfcr    11                      /* save cr */
                    523:        mr      12,2                    /* save r2 */
                    524:        stwu    1,-SFRAMELEN(1)         /* still running on old stack */
                    525:        stmw    10,8(1)
                    526:        lwz     3,P_ADDR(30)
                    527:        stw     1,PCB_SP(3)             /* save SP */
                    528:
                    529: switch_exited:
                    530:        mfmsr   3
                    531:        andi.   3,3,~PSL_EE@l           /* disable interrupts while
                    532:                                           actually switching */
                    533:        mtmsr   3
                    534:
                    535:        /* indicate new pcb */
                    536:        lwz     4,P_ADDR(31)
1.26      tsubai    537: #if defined(MULTIPROCESSOR)
                    538:        GET_CPUINFO(6)
                    539:        stw     4,CI_CURPCB(6)
                    540: #else
1.1       tsubai    541:        lis     5,_C_LABEL(curpcb)@ha
                    542:        stw     4,_C_LABEL(curpcb)@l(5)
1.26      tsubai    543: #endif
1.1       tsubai    544:
                    545:        /* save real pmap pointer for spill fill */
                    546:        lwz     5,PCB_PMR(4)
1.26      tsubai    547: #if defined(MULTIPROCESSOR)
                    548:        stwu    5,CI_CURPM(6)
                    549: #else
1.1       tsubai    550:        lis     6,_C_LABEL(curpm)@ha
                    551:        stwu    5,_C_LABEL(curpm)@l(6)
1.26      tsubai    552: #endif
1.1       tsubai    553:        stwcx.  5,0,6                   /* clear possible reservation */
                    554:
                    555:        addic.  5,5,64
                    556:        li      6,0
                    557:        mfsr    8,KERNEL_SR             /* save kernel SR */
                    558: 1:
                    559:        addis   6,6,-0x10000000@ha      /* set new procs segment registers */
                    560:        or.     6,6,6                   /* This is done from the real
                    561:                                           address pmap */
                    562:        lwzu    7,-4(5)                 /* so we don't have to worry */
                    563:        mtsrin  7,6                     /* about accessibility */
                    564:        bne     1b
                    565:        mtsr    KERNEL_SR,8             /* restore kernel SR */
                    566:        isync
                    567:
                    568:        lwz     1,PCB_SP(4)             /* get new procs SP */
                    569:
                    570:        ori     3,3,PSL_EE@l            /* interrupts are okay again */
                    571:        mtmsr   3
                    572:
                    573:        lmw     10,8(1)                 /* get other regs */
                    574:        lwz     1,0(1)                  /* get saved SP */
                    575:        mr      2,12                    /* get saved r2 */
                    576:        mtcr    11                      /* get saved cr */
                    577:        isync
                    578:        mtsr    USER_SR,10              /* get saved USER_SR */
                    579:        isync
                    580:
                    581: switch_return:
                    582:        mr      30,7                    /* save proc pointer */
                    583:        lwz     3,PCB_SPL(4)
                    584:        bl      _C_LABEL(lcsplx)
                    585:
                    586:        mr      3,30                    /* get curproc for special fork
                    587:                                           returns */
                    588:
                    589:        lwz     31,12(1)
                    590:        lwz     30,8(1)
                    591:        addi    1,1,16
                    592:        lwz     0,4(1)
                    593:        mtlr    0
                    594:        blr
                    595:
                    596: 
                    597: /*
                    598:  * Data used during primary/secondary traps/interrupts
                    599:  */
                    600: #define        tempsave        0x2e0   /* primary save area for trap handling */
                    601: #define        disisave        0x3e0   /* primary save area for dsi/isi traps */
                    602:
                    603: #define        INTSTK  (8*1024)        /* 8K interrupt stack */
                    604:        .data
                    605:        .align  4
                    606: intstk:
                    607:        .space  INTSTK          /* interrupt stack */
                    608:
                    609: GLOBAL(intr_depth)
                    610:        .long   -1              /* in-use marker */
                    611:
                    612: #define        SPILLSTK 1024           /* 1K spill stack */
                    613:
                    614:        .comm   spillstk,SPILLSTK,8
                    615:
                    616: /*
                    617:  * This code gets copied to all the trap vectors
1.19      danw      618:  * (except ISI/DSI, ALI, the interrupts, and possibly the debugging
                    619:  * traps when using IPKDB).
1.1       tsubai    620:  */
                    621:        .text
                    622:        .globl  _C_LABEL(trapcode),_C_LABEL(trapsize)
                    623: _C_LABEL(trapcode):
                    624:        mtsprg  1,1                     /* save SP */
                    625:        stmw    28,tempsave(0)          /* free r28-r31 */
                    626:        mflr    28                      /* save LR */
                    627:        mfcr    29                      /* save CR */
                    628: /* Test whether we already had PR set */
                    629:        mfsrr1  31
                    630:        mtcr    31
                    631:        bc      4,17,1f                 /* branch if PSL_PR is clear */
1.26      tsubai    632: #if defined(MULTIPROCESSOR)
                    633:        GET_CPUINFO(1)
                    634:        lwz     1,CI_CURPCB(1)
                    635: #else
1.1       tsubai    636:        lis     1,_C_LABEL(curpcb)@ha
                    637:        lwz     1,_C_LABEL(curpcb)@l(1)
1.26      tsubai    638: #endif
1.1       tsubai    639:        addi    1,1,USPACE              /* stack is top of user struct */
                    640: 1:
                    641:        bla     s_trap
                    642: _C_LABEL(trapsize) = .-_C_LABEL(trapcode)
1.19      danw      643:
                    644: /*
                    645:  * For ALI: has to save DSISR and DAR
                    646:  */
                    647:        .globl  _C_LABEL(alitrap),_C_LABEL(alisize)
                    648: _C_LABEL(alitrap):
                    649:        mtsprg  1,1                     /* save SP */
                    650:        stmw    28,tempsave(0)          /* free r28-r31 */
                    651:        mfdar   30
                    652:        mfdsisr 31
                    653:        stmw    30,tempsave+16(0)
                    654:        mflr    28                      /* save LR */
                    655:        mfcr    29                      /* save CR */
                    656: /* Test whether we already had PR set */
                    657:        mfsrr1  31
                    658:        mtcr    31
                    659:        bc      4,17,1f                 /* branch if PSL_PR is clear */
1.26      tsubai    660: #if defined(MULTIPROCESSOR)
                    661:        GET_CPUINFO(1)
                    662:        lwz     1,CI_CURPCB(1)
                    663: #else
1.19      danw      664:        lis     1,_C_LABEL(curpcb)@ha
                    665:        lwz     1,_C_LABEL(curpcb)@l(1)
1.26      tsubai    666: #endif
1.19      danw      667:        addi    1,1,USPACE              /* stack is top of user struct */
                    668: 1:
                    669:        bla     s_trap
                    670: _C_LABEL(alisize) = .-_C_LABEL(alitrap)
1.1       tsubai    671:
                    672: /*
                    673:  * Similar to the above for DSI
                    674:  * Has to handle BAT spills
                    675:  * and standard pagetable spills
                    676:  */
                    677:        .globl  _C_LABEL(dsitrap),_C_LABEL(dsisize)
                    678: _C_LABEL(dsitrap):
                    679:        stmw    28,disisave(0)          /* free r28-r31 */
                    680:        mfcr    29                      /* save CR */
                    681:        mfxer   30                      /* save XER */
                    682:        mtsprg  2,30                    /* in SPRG2 */
                    683:        mfsrr1  31                      /* test kernel mode */
                    684:        mtcr    31
                    685:        bc      12,17,1f                /* branch if PSL_PR is set */
                    686:        mfdar   31                      /* get fault address */
                    687:        rlwinm  31,31,7,25,28           /* get segment * 8 */
                    688:
                    689:        /* get batu */
                    690:        addis   31,31,_C_LABEL(battable)@ha
                    691:        lwz     30,_C_LABEL(battable)@l(31)
                    692:        mtcr    30
                    693:        bc      4,30,1f                 /* branch if supervisor valid is
                    694:                                           false */
                    695:        /* get batl */
                    696:        lwz     31,_C_LABEL(battable)+4@l(31)
                    697: /* We randomly use the highest two bat registers here */
                    698:        mftb    28
                    699:        andi.   28,28,1
                    700:        bne     2f
                    701:        mtdbatu 2,30
                    702:        mtdbatl 2,31
                    703:        b       3f
                    704: 2:
                    705:        mtdbatu 3,30
                    706:        mtdbatl 3,31
                    707: 3:
                    708:        mfsprg  30,2                    /* restore XER */
                    709:        mtxer   30
                    710:        mtcr    29                      /* restore CR */
                    711:        lmw     28,disisave(0)          /* restore r28-r31 */
                    712:        rfi                             /* return to trapped code */
                    713: 1:
                    714:        mflr    28                      /* save LR */
                    715:        bla     s_dsitrap
                    716: _C_LABEL(dsisize) = .-_C_LABEL(dsitrap)
                    717:
                    718: /*
                    719:  * Similar to the above for ISI
                    720:  */
                    721:        .globl  _C_LABEL(isitrap),_C_LABEL(isisize)
                    722: _C_LABEL(isitrap):
                    723:        stmw    28,disisave(0)          /* free r28-r31 */
                    724:        mflr    28                      /* save LR */
                    725:        mfcr    29                      /* save CR */
                    726:        mfsrr1  31                      /* test kernel mode */
                    727:        mtcr    31
                    728:        bc      12,17,1f                /* branch if PSL_PR is set */
                    729:        mfsrr0  31                      /* get fault address */
                    730:        rlwinm  31,31,7,25,28           /* get segment * 8 */
                    731:
                    732:        /* get batu */
                    733:        addis   31,31,_C_LABEL(battable)@ha
                    734:        lwz     30,_C_LABEL(battable)@l(31)
                    735:        mtcr    30
                    736:        bc      4,30,1f                 /* branch if supervisor valid is
                    737:                                           false */
                    738:        mtibatu 3,30
                    739:
                    740:        /* get batl */
                    741:        lwz     30,_C_LABEL(battable)+4@l(31)
                    742:        mtibatl 3,30
                    743:
                    744:        mtcr    29                      /* restore CR */
                    745:        lmw     28,disisave(0)          /* restore r28-r31 */
                    746:        rfi                             /* return to trapped code */
                    747: 1:
                    748:        bla     s_isitrap
                    749: _C_LABEL(isisize)= .-_C_LABEL(isitrap)
                    750:
                    751: /*
                    752:  * This one for the external interrupt handler.
                    753:  */
                    754:        .globl  _C_LABEL(extint),_C_LABEL(extsize)
                    755: _C_LABEL(extint):
                    756:        mtsprg  1,1                     /* save SP */
                    757:        stmw    28,tempsave(0)          /* free r28-r31 */
                    758:        mflr    28                      /* save LR */
                    759:        mfcr    29                      /* save CR */
                    760:        mfxer   30                      /* save XER */
                    761:        lis     1,intstk+INTSTK@ha      /* get interrupt stack */
                    762:        addi    1,1,intstk+INTSTK@l
                    763:        lwz     31,0(1)                 /* were we already running on intstk? */
                    764:        addic.  31,31,1
                    765:        stw     31,0(1)
                    766:        beq     1f
                    767:        mfsprg  1,1                     /* yes, get old SP */
                    768: 1:
                    769:        ba      extintr
                    770: _C_LABEL(extsize) = .-_C_LABEL(extint)
                    771:
                    772: /*
                    773:  * And this one for the decrementer interrupt handler.
                    774:  */
                    775:        .globl  _C_LABEL(decrint),_C_LABEL(decrsize)
                    776: _C_LABEL(decrint):
                    777:        mtsprg  1,1                     /* save SP */
                    778:        stmw    28,tempsave(0)          /* free r28-r31 */
                    779:        mflr    28                      /* save LR */
                    780:        mfcr    29                      /* save CR */
                    781:        mfxer   30                      /* save XER */
                    782:        lis     1,intstk+INTSTK@ha      /* get interrupt stack */
                    783:        addi    1,1,intstk+INTSTK@l
                    784:        lwz     31,0(1)                 /* were we already running on intstk? */
                    785:        addic.  31,31,1
                    786:        stw     31,0(1)
                    787:        beq     1f
                    788:        mfsprg  1,1                     /* yes, get old SP */
                    789: 1:
                    790:        ba      decrintr
                    791: _C_LABEL(decrsize) = .-_C_LABEL(decrint)
                    792:
                    793: /*
                    794:  * Now the tlb software load for 603 processors:
                    795:  * (Code essentially from the 603e User Manual, Chapter 5, but
                    796:  * corrected a lot.)
                    797:  */
                    798: #define        DMISS   976
                    799: #define        DCMP    977
                    800: #define        HASH1   978
                    801: #define        HASH2   979
                    802: #define        IMISS   980
                    803: #define        ICMP    981
                    804: #define        RPA     982
                    805:
                    806:        .globl  _C_LABEL(tlbimiss),_C_LABEL(tlbimsize)
                    807: _C_LABEL(tlbimiss):
                    808:        mfspr   2,HASH1                 /* get first pointer */
                    809:        li      1,8
                    810:        mfctr   0                       /* save counter */
                    811:        mfspr   3,ICMP                  /* get first compare value */
                    812:        addi    2,2,-8                  /* predec pointer */
                    813: 1:
                    814:        mtctr   1                       /* load counter */
                    815: 2:
                    816:        lwzu    1,8(2)                  /* get next pte */
                    817:        cmpl    0,1,3                   /* see if found pte */
                    818:        bdneq   2b                      /* loop if not eq */
                    819:        bne     3f                      /* not found */
                    820:        lwz     1,4(2)                  /* load tlb entry lower word */
                    821:        andi.   3,1,8                   /* check G-bit */
                    822:        bne     4f                      /* if guarded, take ISI */
                    823:        mtctr   0                       /* restore counter */
                    824:        mfspr   0,IMISS                 /* get the miss address for the tlbli */
                    825:        mfsrr1  3                       /* get the saved cr0 bits */
                    826:        mtcrf   0x80,3                  /* and restore */
                    827:        ori     1,1,0x100               /* set the reference bit */
                    828:        mtspr   RPA,1                   /* set the pte */
                    829:        srwi    1,1,8                   /* get byte 7 of pte */
                    830:        tlbli   0                       /* load the itlb */
                    831:        stb     1,6(2)                  /* update page table */
                    832:        rfi
                    833:
                    834: 3:     /* not found in pteg */
                    835:        andi.   1,3,0x40                /* have we already done second hash? */
                    836:        bne     5f
                    837:        mfspr   2,HASH2                 /* get the second pointer */
                    838:        ori     3,3,0x40                /* change the compare value */
                    839:        li      1,8
                    840:        addi    2,2,-8                  /* predec pointer */
                    841:        b       1b
                    842: 4:     /* guarded */
                    843:        mfsrr1  3
                    844:        andi.   2,3,0xffff              /* clean upper srr1 */
                    845:        oris    2,2,0x8000000@h         /* set srr<4> to flag prot violation */
                    846:        b       6f
                    847: 5:     /* not found anywhere */
                    848:        mfsrr1  3
                    849:        andi.   2,3,0xffff              /* clean upper srr1 */
                    850:        oris    2,2,0x40000000@h        /* set srr1<1> to flag pte not found */
                    851: 6:
                    852:        mtctr   0                       /* restore counter */
                    853:        mtsrr1  2
                    854:        mfmsr   0
                    855:        xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
                    856:        mtcrf   0x80,3                  /* restore cr0 */
                    857:        mtmsr   0                       /* now with native gprs */
                    858:        isync
                    859:        ba      EXC_ISI
                    860: _C_LABEL(tlbimsize) = .-_C_LABEL(tlbimiss)
                    861:
                    862:        .globl  _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize)
                    863: _C_LABEL(tlbdlmiss):
                    864:        mfspr   2,HASH1                 /* get first pointer */
                    865:        li      1,8
                    866:        mfctr   0                       /* save counter */
                    867:        mfspr   3,DCMP                  /* get first compare value */
                    868:        addi    2,2,-8                  /* predec pointer */
                    869: 1:
                    870:        mtctr   1                       /* load counter */
                    871: 2:
                    872:        lwzu    1,8(2)                  /* get next pte */
                    873:        cmpl    0,1,3                   /* see if found pte */
                    874:        bdneq   2b                      /* loop if not eq */
                    875:        bne     3f                      /* not found */
                    876:        lwz     1,4(2)                  /* load tlb entry lower word */
                    877:        mtctr   0                       /* restore counter */
                    878:        mfspr   0,DMISS                 /* get the miss address for the tlbld */
                    879:        mfsrr1  3                       /* get the saved cr0 bits */
                    880:        mtcrf   0x80,3                  /* and restore */
                    881:        ori     1,1,0x100               /* set the reference bit */
                    882:        mtspr   RPA,1                   /* set the pte */
                    883:        srwi    1,1,8                   /* get byte 7 of pte */
                    884:        tlbld   0                       /* load the dtlb */
                    885:        stb     1,6(2)                  /* update page table */
                    886:        rfi
                    887:
                    888: 3:     /* not found in pteg */
                    889:        andi.   1,3,0x40                /* have we already done second hash? */
                    890:        bne     5f
                    891:        mfspr   2,HASH2                 /* get the second pointer */
                    892:        ori     3,3,0x40                /* change the compare value */
                    893:        li      1,8
                    894:        addi    2,2,-8                  /* predec pointer */
                    895:        b       1b
                    896: 5:     /* not found anywhere */
                    897:        mfsrr1  3
                    898:        lis     1,0x40000000@h          /* set dsisr<1> to flag pte not found */
                    899:        mtctr   0                       /* restore counter */
                    900:        andi.   2,3,0xffff              /* clean upper srr1 */
                    901:        mtsrr1  2
                    902:        mtdsisr 1                       /* load the dsisr */
                    903:        mfspr   1,DMISS                 /* get the miss address */
                    904:        mtdar   1                       /* put in dar */
                    905:        mfmsr   0
                    906:        xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
                    907:        mtcrf   0x80,3                  /* restore cr0 */
                    908:        mtmsr   0                       /* now with native gprs */
                    909:        isync
                    910:        ba      EXC_DSI
                    911: _C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss)
                    912:
                    913:        .globl  _C_LABEL(tlbdsmiss),_C_LABEL(tlbdsmsize)
                    914: _C_LABEL(tlbdsmiss):
                    915:        mfspr   2,HASH1                 /* get first pointer */
                    916:        li      1,8
                    917:        mfctr   0                       /* save counter */
                    918:        mfspr   3,DCMP                  /* get first compare value */
                    919:        addi    2,2,-8                  /* predec pointer */
                    920: 1:
                    921:        mtctr   1                       /* load counter */
                    922: 2:
                    923:        lwzu    1,8(2)                  /* get next pte */
                    924:        cmpl    0,1,3                   /* see if found pte */
                    925:        bdneq   2b                      /* loop if not eq */
                    926:        bne     3f                      /* not found */
                    927:        lwz     1,4(2)                  /* load tlb entry lower word */
                    928:        andi.   3,1,0x80                /* check the C-bit */
                    929:        beq     4f
                    930: 5:
                    931:        mtctr   0                       /* restore counter */
                    932:        mfspr   0,DMISS                 /* get the miss address for the tlbld */
                    933:        mfsrr1  3                       /* get the saved cr0 bits */
                    934:        mtcrf   0x80,3                  /* and restore */
                    935:        mtspr   RPA,1                   /* set the pte */
                    936:        tlbld   0                       /* load the dtlb */
                    937:        rfi
                    938:
                    939: 3:     /* not found in pteg */
                    940:        andi.   1,3,0x40                /* have we already done second hash? */
                    941:        bne     5f
                    942:        mfspr   2,HASH2                 /* get the second pointer */
                    943:        ori     3,3,0x40                /* change the compare value */
                    944:        li      1,8
                    945:        addi    2,2,-8                  /* predec pointer */
                    946:        b       1b
                    947: 4:     /* found, but C-bit = 0 */
                    948:        rlwinm. 3,1,30,0,1              /* test PP */
                    949:        bge-    7f
                    950:        andi.   3,1,1
                    951:        beq+    8f
                    952: 9:     /* found, but protection violation (PP==00)*/
                    953:        mfsrr1  3
                    954:        lis     1,0xa000000@h           /* indicate protection violation
                    955:                                           on store */
                    956:        b       1f
                    957: 7:     /* found, PP=1x */
                    958:        mfspr   3,DMISS                 /* get the miss address */
                    959:        mfsrin  1,3                     /* get the segment register */
                    960:        mfsrr1  3
                    961:        rlwinm  3,3,18,31,31            /* get PR-bit */
                    962:        rlwnm.  2,2,3,1,1               /* get the key */
                    963:        bne-    9b                      /* protection violation */
                    964: 8:     /* found, set reference/change bits */
                    965:        lwz     1,4(2)                  /* reload tlb entry */
                    966:        ori     1,1,0x180
                    967:        sth     1,6(2)
                    968:        b       5b
                    969: 5:     /* not found anywhere */
                    970:        mfsrr1  3
                    971:        lis     1,0x42000000@h          /* set dsisr<1> to flag pte not found */
                    972:                                        /* dsisr<6> to flag store */
                    973: 1:
                    974:        mtctr   0                       /* restore counter */
                    975:        andi.   2,3,0xffff              /* clean upper srr1 */
                    976:        mtsrr1  2
                    977:        mtdsisr 1                       /* load the dsisr */
                    978:        mfspr   1,DMISS                 /* get the miss address */
                    979:        mtdar   1                       /* put in dar */
                    980:        mfmsr   0
                    981:        xoris   0,0,0x20000@h           /* flip the msr<tgpr> bit */
                    982:        mtcrf   0x80,3                  /* restore cr0 */
                    983:        mtmsr   0                       /* now with native gprs */
                    984:        isync
                    985:        ba      EXC_DSI
                    986: _C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss)
                    987:
                    988: #ifdef DDB
                    989: #define        ddbsave 0xde0           /* primary save area for DDB */
                    990: /*
                    991:  * In case of DDB we want a separate trap catcher for it
                    992:  */
                    993:        .local  ddbstk
                    994:        .comm   ddbstk,INTSTK,8         /* ddb stack */
                    995:
                    996:        .globl  _C_LABEL(ddblow),_C_LABEL(ddbsize)
                    997: _C_LABEL(ddblow):
                    998:        mtsprg  1,1                     /* save SP */
                    999:        stmw    28,ddbsave(0)           /* free r28-r31 */
                   1000:        mflr    28                      /* save LR */
                   1001:        mfcr    29                      /* save CR */
                   1002:        lis     1,ddbstk+INTSTK@ha      /* get new SP */
                   1003:        addi    1,1,ddbstk+INTSTK@l
                   1004:        bla     ddbtrap
                   1005: _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
                   1006: #endif /* DDB */
                   1007:
1.21      ws       1008: #ifdef IPKDB
1.1       tsubai   1009: #define        ipkdbsave       0xde0           /* primary save area for IPKDB */
                   1010: /*
                   1011:  * In case of IPKDB we want a separate trap catcher for it
                   1012:  */
                   1013:
                   1014:        .local  ipkdbstk
                   1015:        .comm   ipkdbstk,INTSTK,8               /* ipkdb stack */
                   1016:
                   1017:        .globl  _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize)
                   1018: _C_LABEL(ipkdblow):
                   1019:        mtsprg  1,1                     /* save SP */
                   1020:        stmw    28,ipkdbsave(0)         /* free r28-r31 */
                   1021:        mflr    28                      /* save LR */
                   1022:        mfcr    29                      /* save CR */
                   1023:        lis     1,ipkdbstk+INTSTK@ha    /* get new SP */
                   1024:        addi    1,1,ipkdbstk+INTSTK@l
                   1025:        bla     ipkdbtrap
                   1026: _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
1.21      ws       1027: #endif /* IPKDB */
1.1       tsubai   1028:
                   1029: /*
                   1030:  * FRAME_SETUP assumes:
                   1031:  *     SPRG1           SP (1)
                   1032:  *     savearea        r28-r31,DAR,DSISR       (DAR & DSISR only for DSI traps)
                   1033:  *     28              LR
                   1034:  *     29              CR
                   1035:  *     1               kernel stack
                   1036:  *     LR              trap type
                   1037:  *     SRR0/1          as at start of trap
                   1038:  */
                   1039: #define        FRAME_SETUP(savearea)                                           \
                   1040: /* Have to enable translation to allow access of kernel stack: */      \
                   1041:        mfsrr0  30;                                                     \
                   1042:        mfsrr1  31;                                                     \
                   1043:        stmw    30,savearea+24(0);                                      \
                   1044:        mfmsr   30;                                                     \
                   1045:        ori     30,30,(PSL_DR|PSL_IR);                                  \
                   1046:        mtmsr   30;                                                     \
                   1047:        isync;                                                          \
                   1048:        mfsprg  31,1;                                                   \
                   1049:        stwu    31,-FRAMELEN(1);                                        \
                   1050:        stw     0,FRAME_0+8(1);                                         \
                   1051:        stw     31,FRAME_1+8(1);                                        \
                   1052:        stw     28,FRAME_LR+8(1);                                       \
                   1053:        stw     29,FRAME_CR+8(1);                                       \
                   1054:        lmw     28,savearea(0);                                         \
                   1055:        stmw    2,FRAME_2+8(1);                                         \
                   1056:        lmw     28,savearea+16(0);                                      \
                   1057:        mfxer   3;                                                      \
                   1058:        mfctr   4;                                                      \
                   1059:        mflr    5;                                                      \
                   1060:        andi.   5,5,0xff00;                                             \
                   1061:        stw     3,FRAME_XER+8(1);                                       \
                   1062:        stw     4,FRAME_CTR+8(1);                                       \
                   1063:        stw     5,FRAME_EXC+8(1);                                       \
                   1064:        stw     28,FRAME_DAR+8(1);                                      \
                   1065:        stw     29,FRAME_DSISR+8(1);                                    \
                   1066:        stw     30,FRAME_SRR0+8(1);                                     \
                   1067:        stw     31,FRAME_SRR1+8(1)
                   1068:
                   1069: #define        FRAME_LEAVE(savearea)                                           \
                   1070: /* Now restore regs: */                                                        \
                   1071:        lwz     2,FRAME_SRR0+8(1);                                      \
                   1072:        lwz     3,FRAME_SRR1+8(1);                                      \
                   1073:        lwz     4,FRAME_CTR+8(1);                                       \
                   1074:        lwz     5,FRAME_XER+8(1);                                       \
                   1075:        lwz     6,FRAME_LR+8(1);                                        \
                   1076:        lwz     7,FRAME_CR+8(1);                                        \
                   1077:        stw     2,savearea(0);                                          \
                   1078:        stw     3,savearea+4(0);                                        \
                   1079:        mtctr   4;                                                      \
                   1080:        mtxer   5;                                                      \
                   1081:        mtlr    6;                                                      \
                   1082:        mtsprg  1,7;                    /* save cr */                   \
                   1083:        lmw     2,FRAME_2+8(1);                                         \
                   1084:        lwz     0,FRAME_0+8(1);                                         \
                   1085:        lwz     1,FRAME_1+8(1);                                         \
                   1086:        mtsprg  2,2;                    /* save r2 & r3 */              \
                   1087:        mtsprg  3,3;                                                    \
                   1088: /* Disable translation, machine check and recoverability: */           \
                   1089:        mfmsr   2;                                                      \
                   1090:        andi.   2,2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l;                   \
                   1091:        mtmsr   2;                                                      \
                   1092:        isync;                                                          \
                   1093: /* Decide whether we return to user mode: */                           \
                   1094:        lwz     3,savearea+4(0);                                        \
                   1095:        mtcr    3;                                                      \
                   1096:        bc      4,17,1f;                /* branch if PSL_PR is false */ \
                   1097: /* Restore user & kernel access SR: */                                 \
1.26      tsubai   1098:        GET_CURPM(2);                   /* get real address of pmap */  \
1.1       tsubai   1099:        lwz     3,PM_USRSR(2);                                          \
                   1100:        mtsr    USER_SR,3;                                              \
                   1101:        lwz     3,PM_KERNELSR(2);                                       \
                   1102:        mtsr    KERNEL_SR,3;                                            \
                   1103: 1:     mfsprg  2,1;                    /* restore cr */                \
                   1104:        mtcr    2;                                                      \
                   1105:        lwz     2,savearea(0);                                          \
                   1106:        lwz     3,savearea+4(0);                                        \
                   1107:        mtsrr0  2;                                                      \
                   1108:        mtsrr1  3;                                                      \
                   1109:        mfsprg  2,2;                    /* restore r2 & r3 */           \
                   1110:        mfsprg  3,3
                   1111:
1.26      tsubai   1112: #if defined(MULTIPROCESSOR)
                   1113: #define        GET_CURPM(r)                                                    \
                   1114:        GET_CPUINFO(r);                                                 \
                   1115:        lwz     r,CI_CURPM(r);
                   1116: #else
                   1117: #define        GET_CURPM(r)                                                    \
                   1118:        lis     r,_C_LABEL(curpm)@ha;                                   \
                   1119:        lwz     r,_C_LABEL(curpm)@l(r);
                   1120: #endif
                   1121:
1.1       tsubai   1122: /*
                   1123:  * Preamble code for DSI/ISI traps
                   1124:  */
                   1125: disitrap:
                   1126:        lmw     30,disisave(0)
                   1127:        stmw    30,tempsave(0)
                   1128:        lmw     30,disisave+8(0)
                   1129:        stmw    30,tempsave+8(0)
                   1130:        mfdar   30
                   1131:        mfdsisr 31
                   1132:        stmw    30,tempsave+16(0)
                   1133: realtrap:
                   1134: /* Test whether we already had PR set */
                   1135:        mfsrr1  1
                   1136:        mtcr    1
                   1137:        mfsprg  1,1                     /* restore SP (might have been
                   1138:                                           overwritten) */
                   1139:        bc      4,17,s_trap             /* branch if PSL_PR is false */
1.26      tsubai   1140: #if defined(MULTIPROCESSOR)
                   1141:        GET_CPUINFO(1)
                   1142:        lwz     1,CI_CURPCB(1)
                   1143: #else
1.1       tsubai   1144:        lis     1,_C_LABEL(curpcb)@ha
                   1145:        lwz     1,_C_LABEL(curpcb)@l(1)
1.26      tsubai   1146: #endif
1.1       tsubai   1147:        addi    1,1,USPACE              /* stack is top of user struct */
                   1148:
                   1149: /*
                   1150:  * Now the common trap catching code.
                   1151:  */
                   1152: s_trap:
                   1153: /* First have to enable KERNEL mapping */
                   1154:        lis     31,KERNEL_SEGMENT@h
                   1155:        ori     31,31,KERNEL_SEGMENT@l
                   1156:        mtsr    KERNEL_SR,31
                   1157:        FRAME_SETUP(tempsave)
                   1158: /* Now we can recover interrupts again: */
                   1159:        mfmsr   7
                   1160:        ori     7,7,(PSL_EE|PSL_ME|PSL_RI)@l
                   1161:        mtmsr   7
                   1162:        isync
                   1163: /* Call C trap code: */
                   1164: trapagain:
                   1165:        addi    3,1,8
                   1166:        bl      _C_LABEL(trap)
                   1167: trapexit:
                   1168: /* Disable interrupts: */
                   1169:        mfmsr   3
                   1170:        andi.   3,3,~PSL_EE@l
                   1171:        mtmsr   3
                   1172: /* Test AST pending: */
                   1173:        lwz     5,FRAME_SRR1+8(1)
                   1174:        mtcr    5
                   1175:        bc      4,17,1f                 /* branch if PSL_PR is false */
                   1176:        lis     3,_C_LABEL(astpending)@ha
                   1177:        lwz     4,_C_LABEL(astpending)@l(3)
                   1178:        andi.   4,4,1
                   1179:        beq     1f
                   1180:        li      6,EXC_AST
                   1181:        stw     6,FRAME_EXC+8(1)
                   1182:        b       trapagain
                   1183: 1:
                   1184:        FRAME_LEAVE(tempsave)
                   1185:        rfi
                   1186:
                   1187: /*
                   1188:  * Child comes here at the end of a fork.
                   1189:  * Mostly similar to the above.
                   1190:  */
                   1191:        .globl  _C_LABEL(fork_trampoline)
                   1192: _C_LABEL(fork_trampoline):
                   1193:        xor     3,3,3
                   1194:        bl      _C_LABEL(lcsplx)
                   1195:        mtlr    31
                   1196:        mr      3,30
                   1197:        blrl                            /* jump indirect to r31 */
                   1198:        b       trapexit
                   1199:
                   1200: /*
                   1201:  * DSI second stage fault handler
                   1202:  */
                   1203: s_dsitrap:
                   1204:        mfdsisr 31                      /* test whether this may be a
                   1205:                                           spill fault */
                   1206:        mtcr    31
                   1207:        mtsprg  1,1                     /* save SP */
                   1208:        bc      4,1,disitrap            /* branch if table miss is false */
                   1209:        lis     1,spillstk+SPILLSTK@ha
                   1210:        addi    1,1,spillstk+SPILLSTK@l /* get spill stack */
                   1211:        stwu    1,-52(1)
                   1212:        stw     0,48(1)                 /* save non-volatile registers */
                   1213:        stw     3,44(1)
                   1214:        stw     4,40(1)
                   1215:        stw     5,36(1)
                   1216:        stw     6,32(1)
                   1217:        stw     7,28(1)
                   1218:        stw     8,24(1)
                   1219:        stw     9,20(1)
                   1220:        stw     10,16(1)
                   1221:        stw     11,12(1)
                   1222:        stw     12,8(1)
                   1223:        mflr    30                      /* save trap type */
                   1224:        mfctr   31                      /* & CTR */
                   1225:        mfdar   3
                   1226: s_pte_spill:
                   1227:        bl      _C_LABEL(pte_spill)     /* try a spill */
                   1228:        or.     3,3,3
                   1229:        mtctr   31                      /* restore CTR */
                   1230:        mtlr    30                      /* and trap type */
                   1231:        mfsprg  31,2                    /* get saved XER */
                   1232:        mtxer   31                      /* restore XER */
                   1233:        lwz     12,8(1)                 /* restore non-volatile registers */
                   1234:        lwz     11,12(1)
                   1235:        lwz     10,16(1)
                   1236:        lwz     9,20(1)
                   1237:        lwz     8,24(1)
                   1238:        lwz     7,28(1)
                   1239:        lwz     6,32(1)
                   1240:        lwz     5,36(1)
                   1241:        lwz     4,40(1)
                   1242:        lwz     3,44(1)
                   1243:        lwz     0,48(1)
                   1244:        beq     disitrap
                   1245:        mfsprg  1,1                     /* restore SP */
                   1246:        mtcr    29                      /* restore CR */
                   1247:        mtlr    28                      /* restore LR */
                   1248:        lmw     28,disisave(0)          /* restore r28-r31 */
                   1249:        rfi                             /* return to trapped code */
                   1250:
                   1251: /*
                   1252:  * ISI second stage fault handler
                   1253:  */
                   1254: s_isitrap:
                   1255:        mfsrr1  31                      /* test whether this may be a
                   1256:                                           spill fault */
                   1257:        mtcr    31
                   1258:        mtsprg  1,1                     /* save SP */
                   1259:        bc      4,1,disitrap            /* branch if table miss is false */
                   1260:        lis     1,spillstk+SPILLSTK@ha
                   1261:        addi    1,1,spillstk+SPILLSTK@l /* get spill stack */
                   1262:        stwu    1,-52(1)
                   1263:        stw     0,48(1)                 /* save non-volatile registers */
                   1264:        stw     3,44(1)
                   1265:        stw     4,40(1)
                   1266:        stw     5,36(1)
                   1267:        stw     6,32(1)
                   1268:        stw     7,28(1)
                   1269:        stw     8,24(1)
                   1270:        stw     9,20(1)
                   1271:        stw     10,16(1)
                   1272:        stw     11,12(1)
                   1273:        stw     12,8(1)
                   1274:        mfxer   30                      /* save XER */
                   1275:        mtsprg  2,30
                   1276:        mflr    30                      /* save trap type */
                   1277:        mfctr   31                      /* & ctr */
                   1278:        mfsrr0  3
                   1279:        b       s_pte_spill             /* above */
                   1280:
                   1281: /*
                   1282:  * External interrupt second level handler
                   1283:  */
                   1284: #define        INTRENTER                                                       \
                   1285: /* Save non-volatile registers: */                                     \
                   1286:        stwu    1,-88(1);               /* temporarily */               \
                   1287:        stw     0,84(1);                                                \
                   1288:        mfsprg  0,1;                    /* get original SP */           \
                   1289:        stw     0,0(1);                 /* and store it */              \
                   1290:        stw     3,80(1);                                                \
                   1291:        stw     4,76(1);                                                \
                   1292:        stw     5,72(1);                                                \
                   1293:        stw     6,68(1);                                                \
                   1294:        stw     7,64(1);                                                \
                   1295:        stw     8,60(1);                                                \
                   1296:        stw     9,56(1);                                                \
                   1297:        stw     10,52(1);                                               \
                   1298:        stw     11,48(1);                                               \
                   1299:        stw     12,44(1);                                               \
                   1300:        stw     28,40(1);               /* saved LR */                  \
                   1301:        stw     29,36(1);               /* saved CR */                  \
                   1302:        stw     30,32(1);               /* saved XER */                 \
                   1303:        lmw     28,tempsave(0);         /* restore r28-r31 */           \
                   1304:        mfctr   6;                                                      \
                   1305:        lis     5,_C_LABEL(intr_depth)@ha;                              \
                   1306:        lwz     5,_C_LABEL(intr_depth)@l(5);                            \
                   1307:        mfsrr0  4;                                                      \
                   1308:        mfsrr1  3;                                                      \
                   1309:        stw     6,28(1);                                                \
                   1310:        stw     5,20(1);                                                \
                   1311:        stw     4,12(1);                                                \
                   1312:        stw     3,8(1);                                                 \
                   1313: /* interrupts are recoverable here, and enable translation */          \
                   1314:        lis     3,(KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@h;                 \
                   1315:        ori     3,3,(KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@l;               \
                   1316:        mtsr    KERNEL_SR,3;                                            \
                   1317:        mfmsr   5;                                                      \
                   1318:        ori     5,5,(PSL_IR|PSL_DR|PSL_RI);                             \
                   1319:        mtmsr   5;                                                      \
                   1320:        isync
                   1321:
                   1322:        .globl  _C_LABEL(extint_call)
                   1323: extintr:
                   1324:        INTRENTER
                   1325: _C_LABEL(extint_call):
                   1326:        bl      _C_LABEL(extint_call)   /* to be filled in later */
                   1327:
                   1328: intr_exit:
                   1329: /* Disable interrupts (should already be disabled) and MMU here: */
                   1330:        mfmsr   3
                   1331:        andi.   3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l
                   1332:        mtmsr   3
                   1333:        isync
                   1334: /* restore possibly overwritten registers: */
                   1335:        lwz     12,44(1)
                   1336:        lwz     11,48(1)
                   1337:        lwz     10,52(1)
                   1338:        lwz     9,56(1)
                   1339:        lwz     8,60(1)
                   1340:        lwz     7,64(1)
                   1341:        lwz     6,8(1)
                   1342:        lwz     5,12(1)
                   1343:        lwz     4,28(1)
                   1344:        lwz     3,32(1)
                   1345:        mtsrr1  6
                   1346:        mtsrr0  5
                   1347:        mtctr   4
                   1348:        mtxer   3
                   1349: /* Returning to user mode? */
                   1350:        mtcr    6                       /* saved SRR1 */
                   1351:        bc      4,17,1f                 /* branch if PSL_PR is false */
1.26      tsubai   1352: #if defined(MULTIPROCESSOR)
                   1353:        GET_CPUINFO(3)
                   1354:        lwz     3,CI_CURPM(3)
                   1355: #else
1.18      danw     1356:        lis     3,_C_LABEL(curpm)@ha    /* get current pmap real address */
1.1       tsubai   1357:        lwz     3,_C_LABEL(curpm)@l(3)
1.26      tsubai   1358: #endif
1.1       tsubai   1359:        lwz     3,PM_KERNELSR(3)
                   1360:        mtsr    KERNEL_SR,3             /* Restore kernel SR */
                   1361:        lis     3,_C_LABEL(astpending)@ha /* Test AST pending */
                   1362:        lwz     4,_C_LABEL(astpending)@l(3)
                   1363:        andi.   4,4,1
                   1364:        beq     1f
                   1365: /* Setup for entry to realtrap: */
                   1366:        lwz     3,0(1)                  /* get saved SP */
                   1367:        mtsprg  1,3
                   1368:        li      6,EXC_AST
                   1369:        stmw    28,tempsave(0)          /* establish tempsave again */
                   1370:        mtlr    6
                   1371:        lwz     28,40(1)                /* saved LR */
                   1372:        lwz     29,36(1)                /* saved CR */
                   1373:        lwz     6,68(1)
                   1374:        lwz     5,72(1)
                   1375:        lwz     4,76(1)
                   1376:        lwz     3,80(1)
                   1377:        lwz     0,84(1)
                   1378:        lis     30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
                   1379:        lwz     31,_C_LABEL(intr_depth)@l(30)
                   1380:        addi    31,31,-1
                   1381:        stw     31,_C_LABEL(intr_depth)@l(30)
                   1382:        b       realtrap
                   1383: 1:
                   1384: /* Here is the normal exit of extintr: */
                   1385:        lwz     5,36(1)
                   1386:        lwz     6,40(1)
                   1387:        mtcr    5
                   1388:        mtlr    6
                   1389:        lwz     6,68(1)
                   1390:        lwz     5,72(1)
                   1391:        lis     3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
                   1392:        lwz     4,_C_LABEL(intr_depth)@l(3)
                   1393:        addi    4,4,-1
                   1394:        stw     4,_C_LABEL(intr_depth)@l(3)
                   1395:        lwz     4,76(1)
                   1396:        lwz     3,80(1)
                   1397:        lwz     0,84(1)
                   1398:        lwz     1,0(1)
                   1399:        rfi
                   1400:
                   1401: /*
                   1402:  * Decrementer interrupt second level handler
                   1403:  */
                   1404: decrintr:
                   1405:        INTRENTER
                   1406:        addi    3,1,8                   /* intr frame */
                   1407:        bl      _C_LABEL(decr_intr)
                   1408:        b       intr_exit
                   1409:
                   1410: #ifdef DDB
                   1411: /*
                   1412:  * Deliberate entry to ddbtrap
                   1413:  */
                   1414:        .globl  _C_LABEL(ddb_trap)
                   1415: _C_LABEL(ddb_trap):
                   1416:        mtsprg  1,1
                   1417:        mfmsr   3
                   1418:        mtsrr1  3
                   1419:        andi.   3,3,~(PSL_EE|PSL_ME)@l
                   1420:        mtmsr   3                       /* disable interrupts */
                   1421:        isync
                   1422:        stmw    28,ddbsave(0)
                   1423:        mflr    28
                   1424:        li      29,EXC_BPT
                   1425:        mtlr    29
                   1426:        mfcr    29
                   1427:        mtsrr0  28
                   1428:
                   1429: /*
                   1430:  * Now the ddb trap catching code.
                   1431:  */
                   1432: ddbtrap:
                   1433:        FRAME_SETUP(ddbsave)
                   1434: /* Call C trap code: */
                   1435:        addi    3,1,8
                   1436:        bl      _C_LABEL(ddb_trap_glue)
                   1437:        or.     3,3,3
                   1438:        bne     ddbleave
                   1439: /* This wasn't for DDB, so switch to real trap: */
                   1440:        lwz     3,FRAME_EXC+8(1)        /* save exception */
                   1441:        stw     3,ddbsave+8(0)
                   1442:        FRAME_LEAVE(ddbsave)
                   1443:        mtsprg  1,1                     /* prepare for entrance to realtrap */
                   1444:        stmw    28,tempsave(0)
                   1445:        mflr    28
                   1446:        mfcr    29
                   1447:        lwz     31,ddbsave+8(0)
                   1448:        mtlr    31
                   1449:        b       realtrap
                   1450: ddbleave:
                   1451:        FRAME_LEAVE(ddbsave)
                   1452:        rfi
                   1453: #endif /* DDB */
                   1454:
1.21      ws       1455: #ifdef IPKDB
1.1       tsubai   1456: /*
                   1457:  * Deliberate entry to ipkdbtrap
                   1458:  */
                   1459:        .globl  _C_LABEL(ipkdb_trap)
                   1460: _C_LABEL(ipkdb_trap):
                   1461:        mtsprg  1,1
                   1462:        mfmsr   3
                   1463:        mtsrr1  3
                   1464:        andi.   3,3,~(PSL_EE|PSL_ME)@l
                   1465:        mtmsr   3                       /* disable interrupts */
                   1466:        isync
                   1467:        stmw    28,ipkdbsave(0)
                   1468:        mflr    28
                   1469:        li      29,EXC_BPT
                   1470:        mtlr    29
                   1471:        mfcr    29
                   1472:        mtsrr0  28
                   1473:
                   1474: /*
                   1475:  * Now the ipkdb trap catching code.
                   1476:  */
                   1477: ipkdbtrap:
                   1478:        FRAME_SETUP(ipkdbsave)
                   1479: /* Call C trap code: */
                   1480:        addi    3,1,8
                   1481:        bl      _C_LABEL(ipkdb_trap_glue)
                   1482:        or.     3,3,3
                   1483:        bne     ipkdbleave
                   1484: /* This wasn't for IPKDB, so switch to real trap: */
                   1485:        lwz     3,FRAME_EXC+8(1)        /* save exception */
                   1486:        stw     3,ipkdbsave+8(0)
                   1487:        FRAME_LEAVE(ipkdbsave)
                   1488:        mtsprg  1,1                     /* prepare for entrance to realtrap */
                   1489:        stmw    28,tempsave(0)
                   1490:        mflr    28
                   1491:        mfcr    29
                   1492:        lwz     31,ipkdbsave+8(0)
                   1493:        mtlr    31
                   1494:        b       realtrap
                   1495: ipkdbleave:
                   1496:        FRAME_LEAVE(ipkdbsave)
                   1497:        rfi
                   1498:
                   1499: ipkdbfault:
                   1500:        ba      _ipkdbfault
                   1501: _ipkdbfault:
                   1502:        mfsrr0  3
                   1503:        addi    3,3,4
                   1504:        mtsrr0  3
                   1505:        li      3,-1
                   1506:        rfi
                   1507:
                   1508: /*
                   1509:  * int ipkdbfbyte(unsigned char *p)
                   1510:  */
                   1511:        .globl  _C_LABEL(ipkdbfbyte)
                   1512: _C_LABEL(ipkdbfbyte):
                   1513:        li      9,EXC_DSI               /* establish new fault routine */
                   1514:        lwz     5,0(9)
                   1515:        lis     6,ipkdbfault@ha
                   1516:        lwz     6,ipkdbfault@l(6)
                   1517:        stw     6,0(9)
                   1518: #ifdef IPKDBUSERHACK
                   1519:        lis     8,_C_LABEL(ipkdbsr)@ha
                   1520:        lwz     8,_C_LABEL(ipkdbsr)@l(8)
                   1521:        mtsr    USER_SR,8
                   1522:        isync
                   1523: #endif
                   1524:        dcbst   0,9                     /* flush data... */
                   1525:        sync
                   1526:        icbi    0,9                     /* and instruction caches */
                   1527:        lbz     3,0(3)                  /* fetch data */
                   1528:        stw     5,0(9)                  /* restore previous fault handler */
                   1529:        dcbst   0,9                     /* and flush data... */
                   1530:        sync
                   1531:        icbi    0,9                     /* and instruction caches */
                   1532:        blr
                   1533:
                   1534: /*
                   1535:  * int ipkdbsbyte(unsigned char *p, int c)
                   1536:  */
                   1537:        .globl  _C_LABEL(ipkdbsbyte)
                   1538: _C_LABEL(ipkdbsbyte):
                   1539:        li      9,EXC_DSI               /* establish new fault routine */
                   1540:        lwz     5,0(9)
                   1541:        lis     6,ipkdbfault@ha
                   1542:        lwz     6,ipkdbfault@l(6)
                   1543:        stw     6,0(9)
                   1544: #ifdef IPKDBUSERHACK
                   1545:        lis     8,_C_LABEL(ipkdbsr)@ha
                   1546:        lwz     8,_C_LABEL(ipkdbsr)@l(8)
                   1547:        mtsr    USER_SR,8
                   1548:        isync
                   1549: #endif
                   1550:        dcbst   0,9                     /* flush data... */
                   1551:        sync
                   1552:        icbi    0,9                     /* and instruction caches */
                   1553:        mr      6,3
                   1554:        xor     3,3,3
                   1555:        stb     4,0(6)
                   1556:        dcbst   0,6                     /* Now do appropriate flushes
                   1557:                                           to data... */
                   1558:        sync
                   1559:        icbi    0,6                     /* and instruction caches */
                   1560:        stw     5,0(9)                  /* restore previous fault handler */
                   1561:        dcbst   0,9                     /* and flush data... */
                   1562:        sync
                   1563:        icbi    0,9                     /* and instruction caches */
                   1564:        blr
1.21      ws       1565: #endif /* IPKDB */
1.1       tsubai   1566:
                   1567: /*
                   1568:  * int setfault()
                   1569:  *
                   1570:  * Similar to setjmp to setup for handling faults on accesses to user memory.
                   1571:  * Any routine using this may only call bcopy, either the form below,
                   1572:  * or the (currently used) C code optimized, so it doesn't use any non-volatile
                   1573:  * registers.
                   1574:  */
                   1575:        .globl  _C_LABEL(setfault)
                   1576: _C_LABEL(setfault):
                   1577:        mflr    0
                   1578:        mfcr    12
1.26      tsubai   1579: #if defined(MULTIPROCESSOR)
                   1580:        GET_CPUINFO(4)
                   1581:        lwz     4,CI_CURPCB(4)
                   1582: #else
1.1       tsubai   1583:        lis     4,_C_LABEL(curpcb)@ha
                   1584:        lwz     4,_C_LABEL(curpcb)@l(4)
1.26      tsubai   1585: #endif
1.1       tsubai   1586:        stw     3,PCB_FAULT(4)
                   1587:        stw     0,0(3)
                   1588:        stw     1,4(3)
                   1589:        stw     2,8(3)
                   1590:        stmw    12,12(3)
                   1591:        xor     3,3,3
                   1592:        blr
1.25      tsubai   1593:
1.26      tsubai   1594: #if defined(MULTIPROCESSOR)
1.25      tsubai   1595:        .globl  _C_LABEL(cpu_spinup_trampoline)
                   1596: _C_LABEL(cpu_spinup_trampoline):
                   1597:        li      0,0
                   1598:        mtmsr   0
                   1599:        isync
                   1600:
                   1601:        lis     3,cpu_hatchstack@ha
                   1602:        lwz     1,cpu_hatchstack@l(3)
                   1603:
                   1604:        bl      _C_LABEL(cpu_hatch)
                   1605:
1.26      tsubai   1606: /* Loop forever. */
1.25      tsubai   1607: 1:
                   1608:        sync
                   1609:        mfmsr   3
                   1610:        oris    3,3,PSL_POW@h
                   1611:        mtmsr   3
                   1612:        isync
                   1613:        b       1b
                   1614:
1.26      tsubai   1615: #endif

CVSweb <webmaster@jp.NetBSD.org>