[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.16.2.2

1.16.2.2! bouyer      1: /*     $NetBSD$        */
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.16.2.1  bouyer     35: #include "opt_ipkdb.h"
                     36: #include "opt_lockdebug.h"
                     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.16.2.1  bouyer     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.16.2.1  bouyer    104: GLOBAL(powersave)
                    105:        .long   0
                    106:
1.1       tsubai    107: /*
                    108:  * File-scope for locore.S
                    109:  */
1.16.2.1  bouyer    110: #if !defined(MULTIPROCESSOR)
1.1       tsubai    111: idle_u:
                    112:        .long   0                       /* fake uarea during idle after exit */
1.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    342:  * When we get here, interrupts are off (MSR[EE]=0) and sched_lock is held.
1.1       tsubai    343:  */
                    344: ASENTRY(Idle)
1.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    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:
                    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.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    434: #endif
                    435:
                    436: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
                    437: /* Release the sched_lock before processing interrupts. */
                    438:        bl      _C_LABEL(sched_unlock_idle)
                    439: #endif
1.1       tsubai    440:
                    441:        xor     3,3,3
                    442:        bl      _C_LABEL(lcsplx)
                    443:        stw     3,PCB_SPL(31)           /* save spl */
                    444:
1.16.2.1  bouyer    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.16.2.1  bouyer    451: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
                    452:        bl      _C_LABEL(sched_lock_idle)
                    453: #endif
1.1       tsubai    454:
1.16.2.1  bouyer    455: /* Find a new process */
                    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.16.2.1  bouyer    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.16.2.1  bouyer    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 */
                    488:
1.16.2.1  bouyer    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
                    493:
                    494: #if defined(MULTIPROCESSOR)
                    495:        GET_CPUINFO(4)
                    496:        stw     4,P_CPU(31)             /* p->p_cpu = curcpu() */
                    497: #endif
                    498:
                    499:        /* Process now running on a processor. */
                    500:        li      3,SONPROC               /* p->p_stat = SONPROC */
                    501:        stb     3,P_STAT(31)
                    502:
1.1       tsubai    503:        /* record new process */
1.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    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.16.2.1  bouyer    543: #endif
1.1       tsubai    544:
                    545:        /* save real pmap pointer for spill fill */
                    546:        lwz     5,PCB_PMR(4)
1.16.2.1  bouyer    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.16.2.1  bouyer    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:  * Child comes here at the end of a fork.
1.16.2.2! bouyer    598:  * Return to userspace via the trap return path.
1.1       tsubai    599:  */
                    600:        .globl  _C_LABEL(fork_trampoline)
                    601: _C_LABEL(fork_trampoline):
                    602:        xor     3,3,3
                    603:        bl      _C_LABEL(lcsplx)
                    604:        mtlr    31
                    605:        mr      3,30
                    606:        blrl                            /* jump indirect to r31 */
                    607:        b       trapexit
                    608:
                    609: /*
1.16.2.2! bouyer    610:  * Pull in common trap vector code.
1.1       tsubai    611:  */
1.16.2.2! bouyer    612: #include <powerpc/powerpc/trap_subr.S>
1.1       tsubai    613:
                    614: /*
                    615:  * int ipkdbsbyte(unsigned char *p, int c)
                    616:  */
                    617:        .globl  _C_LABEL(ipkdbsbyte)
                    618: _C_LABEL(ipkdbsbyte):
                    619:        li      9,EXC_DSI               /* establish new fault routine */
                    620:        lwz     5,0(9)
                    621:        lis     6,ipkdbfault@ha
                    622:        lwz     6,ipkdbfault@l(6)
                    623:        stw     6,0(9)
                    624: #ifdef IPKDBUSERHACK
                    625:        lis     8,_C_LABEL(ipkdbsr)@ha
                    626:        lwz     8,_C_LABEL(ipkdbsr)@l(8)
                    627:        mtsr    USER_SR,8
                    628:        isync
                    629: #endif
                    630:        dcbst   0,9                     /* flush data... */
                    631:        sync
                    632:        icbi    0,9                     /* and instruction caches */
                    633:        mr      6,3
                    634:        xor     3,3,3
                    635:        stb     4,0(6)
                    636:        dcbst   0,6                     /* Now do appropriate flushes
                    637:                                           to data... */
                    638:        sync
                    639:        icbi    0,6                     /* and instruction caches */
                    640:        stw     5,0(9)                  /* restore previous fault handler */
                    641:        dcbst   0,9                     /* and flush data... */
                    642:        sync
                    643:        icbi    0,9                     /* and instruction caches */
                    644:        blr
1.16.2.1  bouyer    645: #endif /* IPKDB */
1.1       tsubai    646:
                    647: /*
                    648:  * int setfault()
                    649:  *
                    650:  * Similar to setjmp to setup for handling faults on accesses to user memory.
                    651:  * Any routine using this may only call bcopy, either the form below,
                    652:  * or the (currently used) C code optimized, so it doesn't use any non-volatile
                    653:  * registers.
                    654:  */
                    655:        .globl  _C_LABEL(setfault)
                    656: _C_LABEL(setfault):
                    657:        mflr    0
                    658:        mfcr    12
1.16.2.1  bouyer    659: #if defined(MULTIPROCESSOR)
                    660:        GET_CPUINFO(4)
                    661:        lwz     4,CI_CURPCB(4)
                    662: #else
1.1       tsubai    663:        lis     4,_C_LABEL(curpcb)@ha
                    664:        lwz     4,_C_LABEL(curpcb)@l(4)
1.16.2.1  bouyer    665: #endif
1.1       tsubai    666:        stw     3,PCB_FAULT(4)
                    667:        stw     0,0(3)
                    668:        stw     1,4(3)
                    669:        stw     2,8(3)
                    670:        stmw    12,12(3)
                    671:        xor     3,3,3
                    672:        blr
                    673:
1.16.2.1  bouyer    674: #if defined(MULTIPROCESSOR)
                    675:        .globl  _C_LABEL(cpu_spinup_trampoline)
                    676: _C_LABEL(cpu_spinup_trampoline):
                    677:        li      0,0
                    678:        mtmsr   0
                    679:        isync
                    680:
                    681:        lis     3,cpu_hatchstack@ha
                    682:        lwz     1,cpu_hatchstack@l(3)
                    683:
                    684:        bl      _C_LABEL(cpu_hatch)
                    685:
                    686: /* Loop forever. */
                    687: 1:
                    688:        sync
                    689:        mfmsr   3
                    690:        oris    3,3,PSL_POW@h
                    691:        mtmsr   3
                    692:        isync
                    693:        b       1b
                    694:
                    695: #endif

CVSweb <webmaster@jp.NetBSD.org>