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

Annotation of sys/arch/mvme68k/mvme68k/locore.s, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: locore.s,v 1.54 2007/05/15 13:46:22 martin Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 1995 Theo de Raadt
                      5:  * Copyright (c) 1999 Steve Murphree, Jr. (68060 support)
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     17:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     19:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
                     20:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     26:  * SUCH DAMAGE.
                     27:  *
                     28:  * Copyright (c) 1988 University of Utah.
                     29:  * Copyright (c) 1980, 1990, 1993
                     30:  *     The Regents of the University of California.  All rights reserved.
                     31:  *
                     32:  * This code is derived from software contributed to Berkeley by
                     33:  * the Systems Programming Group of the University of Utah Computer
                     34:  * Science Department.
                     35:  *
                     36:  * Redistribution and use in source and binary forms, with or without
                     37:  * modification, are permitted provided that the following conditions
                     38:  * are met:
                     39:  * 1. Redistributions of source code must retain the above copyright
                     40:  *    notice, this list of conditions and the following disclaimer.
                     41:  * 2. Redistributions in binary form must reproduce the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer in the
                     43:  *    documentation and/or other materials provided with the distribution.
                     44:  * 3. Neither the name of the University nor the names of its contributors
                     45:  *    may be used to endorse or promote products derived from this software
                     46:  *    without specific prior written permission.
                     47:  *
                     48:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     49:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     50:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     51:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     52:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     53:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     54:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     55:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     56:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     57:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     58:  * SUCH DAMAGE.
                     59:  *
                     60:  * from: Utah $Hdr: locore.s 1.66 92/12/22$
                     61:  *
                     62:  *     @(#)locore.s    8.6 (Berkeley) 5/27/94
                     63:  */
                     64:
                     65: #include "assym.h"
                     66: #include "ksyms.h"
                     67: #include <machine/asm.h>
                     68: #include <machine/prom.h>
                     69: #include <machine/trap.h>
                     70:
                     71: /*
                     72:  * Relocate a symbol, used before MMU is enabled.
                     73:  */
                     74: #define        _RELOC(var, ar) \
                     75:        lea     var,ar
                     76:
                     77: #define        RELOC(var, ar)          _RELOC(_C_LABEL(var), ar)
                     78: #define        ASRELOC(var, ar)        _RELOC(_ASM_LABEL(var), ar)
                     79:
                     80: /*
                     81:  * Invoke a BUG routine.
                     82:  */
                     83: #define BUGCALL(id) \
                     84:        trap    #15;    \
                     85:        .short  id
                     86:
                     87: /*
                     88:  * Temporary stack for a variety of purposes.
                     89:  * Try and make this the first thing is the data segment so it
                     90:  * is page aligned.  Note that if we overflow here, we run into
                     91:  * our text segment.
                     92:  */
                     93:        .data
                     94:        .space  NBPG
                     95: ASLOCAL(tmpstk)
                     96:
                     97: /*
                     98:  * Initialization
                     99:  *
                    100:  * The bootstrap loader loads us in starting at 0, and VBR is non-zero.
                    101:  * On entry, args on stack are boot device, boot filename, console unit,
                    102:  * boot flags (howto), boot device name, filesystem type name.
                    103:  */
                    104: BSS(esym, 4)
                    105: BSS(emini, 4)
                    106: BSS(smini, 4)
                    107: BSS(promvbr, 4)
                    108: BSS(promcall, 4)
                    109:
                    110:        .text
                    111: /*
                    112: GLOBAL(edata)
                    113: GLOBAL(etext)
                    114: GLOBAL(end)
                    115: */
                    116: GLOBAL(kernel_text)
                    117:
                    118: ASENTRY_NOPROFILE(start)
                    119:        movw    #PSL_HIGHIPL,sr         | no interrupts
                    120:        movl    sp@(4), d7              | get boothowto
                    121:        movl    sp@(8), d6              | get bootaddr
                    122:        movl    sp@(12),d5              | get bootctrllun
                    123:        movl    sp@(16),d4              | get bootdevlun
                    124:        movl    sp@(20),d3              | get bootpart
                    125:        movl    sp@(24),d2              | get esyms
                    126:        /* note: d2-d7 in use */
                    127:
                    128:        ASRELOC(tmpstk, a0)
                    129:        movl    a0,sp                   | give ourselves a temporary stack
                    130:
                    131:        RELOC(edata, a0)                | clear out BSS
                    132:        movl    #_C_LABEL(end)-4,d0     | (must be <= 256 kB)
                    133:        subl    #_C_LABEL(edata),d0
                    134:        lsrl    #2,d0
                    135: 1:     clrl    a0@+
                    136:        dbra    d0,1b
                    137:
                    138:        movc    vbr,d0                  | save prom's trap #15 vector
                    139:        RELOC(promvbr, a0)
                    140:        movl    d0, a0@
                    141:        RELOC(esym, a0)
                    142:        movl    d2,a0@                  | store end of symbol table
                    143:        /* note: d2 now free, d3-d7 still in use */
                    144:
                    145:        clrl    sp@-
                    146:        BUGCALL(MVMEPROM_GETBRDID)
                    147:        movl    sp@+, a1
                    148:
                    149:        movl    #SIZEOF_MVMEPROM_BRDID, d0      | copy to local variables
                    150:        RELOC(brdid, a0)
                    151: 1:     movb    a1@+, a0@+
                    152:        subql   #1, d0
                    153:        bne     1b
                    154:
                    155:        clrl    d0
                    156:        RELOC(brdid, a1)
                    157:        movw    a1@(MVMEPROM_BRDID_MODEL), d0
                    158:        RELOC(cputyp, a0)
                    159:        movl    d0, a0@                 | init _cputyp
                    160:
                    161: #ifdef MVME147
                    162:        cmpw    #CPU_147, d0
                    163:        beq     is147
                    164: #endif
                    165:
                    166: #ifdef MVME162
                    167:        cmpw    #CPU_162, d0
                    168:        beq     is162
                    169: #endif
                    170:
                    171: #ifdef MVME167
                    172:        cmpw    #CPU_166, d0
                    173:        beq     is167
                    174:        cmpw    #CPU_167, d0
                    175:        beq     is167
                    176: #endif
                    177:
                    178: #ifdef MVME177
                    179: #ifdef notyet
                    180:         cmpw   #CPU_176, d0
                    181:        beq     is177
                    182: #endif
                    183:         cmpw   #CPU_177, d0
                    184:        beq     is177
                    185: #endif
                    186:
                    187: #ifdef MVME172
                    188:        cmpw    #CPU_172, d0
                    189:        beq     is172
                    190: #endif
                    191:
                    192:        .data
                    193: notsup:        .asciz  "kernel does not support this model."
                    194: notsupend:
                    195:        .even
                    196:        .text
                    197:
                    198:        | first we bitch, then we die.
                    199:        movl    #notsupend, sp@-
                    200:        movl    #notsup, sp@-
                    201:        BUGCALL(MVMEPROM_OUTSTRCRLF)
                    202:        addql   #8,sp
                    203:
                    204:        BUGCALL(MVMEPROM_EXIT)          | return to m68kbug
                    205:        /*NOTREACHED*/
                    206:
                    207: #ifdef MVME147
                    208: is147:
                    209:        RELOC(mmutype, a0)              | no, we have 68030
                    210:        movl    #MMU_68030,a0@          | set to reflect 68030 PMMU
                    211:
                    212:        RELOC(cputype, a0)              | no, we have 68030
                    213:        movl    #CPU_68030,a0@          | set to reflect 68030 CPU
                    214:
                    215:        movl    #CACHE_OFF,d0
                    216:        movc    d0,cacr                 | clear and disable on-chip cache(s)
                    217:
                    218:        movb    #0, 0xfffe1026          | XXX serial interrupt off
                    219:        movb    #0, 0xfffe1018          | XXX timer 1 off
                    220:        movb    #0, 0xfffe1028          | XXX ethernet off
                    221:
                    222:        movl    #0xfffe0000, a0         | mvme147 nvram base
                    223:        | move nvram component of etheraddr (only last 3 bytes)
                    224:        RELOC(myea, a1)
                    225:        movw    a0@(NVRAM_147_ETHER+0), a1@(3+0)
                    226:        movb    a0@(NVRAM_147_ETHER+2), a1@(3+2)
                    227:        movl    a0@(NVRAM_147_EMEM), d1 | pass memory size
                    228:
                    229:        RELOC(iiomapsize, a1)
                    230:        movl    #INTIOSIZE_147, a1@
                    231:        RELOC(iiomapbase, a1)
                    232:        movl    #INTIOBASE_147, a1@
                    233:        bra     Lstart1
                    234: #endif
                    235:
                    236: #ifdef MVME162
                    237: is162:
                    238: #if 0
                    239:        | the following 3 things are "just in case". they won't make
                    240:        | the kernel work properly, but they will at least let it get
                    241:        | far enough that you can figure out that something had an
                    242:        | interrupt pending. which the bootrom shouldn't allow, i don't
                    243:        | think..
                    244:        clrb    0xfff42002              | XXX MCchip irq off
                    245:        clrl    0xfff42018              | XXX MCchip timers irq off
                    246:        clrb    0xfff4201d              | XXX MCchip scc irq off
                    247: #endif
                    248:        RELOC(memsize162, a1)           | how much memory?
                    249:        jbsr    a1@
                    250:        movl    d0, d2
                    251:
                    252:        RELOC(mmutype, a0)
                    253:        movl    #MMU_68040,a0@          | with a 68040 MMU
                    254:
                    255:        RELOC(cputype, a0)              | no, we have 68040
                    256:        movl    #CPU_68040,a0@          | set to reflect 68040 CPU
                    257:
                    258:        RELOC(fputype, a0)
                    259:        movl    #FPU_68040,a0@          | and a 68040 FPU
                    260:
                    261:        RELOC(vectab, a1)
                    262:        movl    #_C_LABEL(buserr40),a1@(8)
                    263:        movl    #_C_LABEL(addrerr4060),a1@(12)
                    264:
                    265:        bra     is16x
                    266: #endif
                    267:
                    268: #ifdef MVME167
                    269: is167:
                    270:        RELOC(memsize1x7, a1)           | how much memory?
                    271:        jbsr    a1@
                    272:
                    273:        RELOC(mmutype, a0)
                    274:        movl    #MMU_68040,a0@          | with a 68040 MMU
                    275:
                    276:        RELOC(cputype, a0)              | no, we have 68040
                    277:        movl    #CPU_68040,a0@          | set to reflect 68040 CPU
                    278:
                    279:        RELOC(fputype, a0)
                    280:        movl    #FPU_68040,a0@          | and a 68040 FPU
                    281:
                    282:        RELOC(vectab, a1)
                    283:        movl    #_C_LABEL(buserr40),a1@(8)
                    284:        movl    #_C_LABEL(addrerr4060),a1@(12)
                    285:
                    286:        bra     is16x
                    287: #endif
                    288:
                    289: #ifdef MVME172
                    290: is172:
                    291:
                    292:        RELOC(memsize162, a1)           | how much memory?
                    293:        jbsr    a1@
                    294:        movl    d0, d2
                    295:
                    296:         /* enable Super Scalar Dispatch */
                    297:        .word   0x4e7a,0x0808           | movc  pcr,d0
                    298:        bset   #0,d0                    | turn on bit 0.
                    299:        .word   0x4e7b,0x0808           | movc  d0,pcr  Bang!
                    300:
                    301:        RELOC(mmutype, a0)
                    302:        movl    #MMU_68060,a0@          | with a 68060 MMU
                    303:
                    304:        RELOC(cputype, a0)              | no, we have 68060
                    305:        movl    #CPU_68060,a0@          | set to reflect 68060 CPU
                    306:
                    307:        RELOC(fputype, a0)
                    308:        movl    #FPU_68060,a0@          | and a 68060 FPU
                    309:
                    310:        RELOC(vectab, a1)
                    311:        movl    #_C_LABEL(buserr60),a1@(8)
                    312:        movl    #_C_LABEL(addrerr4060),a1@(12)
                    313:
                    314:        bra     is16x
                    315: #endif
                    316:
                    317: #ifdef MVME177
                    318: is177:
                    319:        RELOC(memsize1x7, a1)           | how much memory?
                    320:        jbsr    a1@
                    321:
                    322:         /* enable Super Scalar Dispatch */
                    323:        .word   0x4e7a,0x0808           | movc  pcr,d0
                    324:        bset   #0,d0                    | turn on bit 0.
                    325:        .word   0x4e7b,0x0808           | movc  d0,pcr  Bang!  We are smokin' !
                    326:
                    327:        RELOC(mmutype, a0)
                    328:        movl    #MMU_68060,a0@          | with a 68060 MMU
                    329:
                    330:        RELOC(cputype, a0)              | no, we have 68060
                    331:        movl    #CPU_68060,a0@          | set to reflect 68060 CPU
                    332:
                    333:        RELOC(fputype, a0)
                    334:        movl    #FPU_68060,a0@          | and a 68060 FPU
                    335:
                    336:        RELOC(vectab, a1)
                    337:        movl    #_C_LABEL(buserr60),a1@(8)
                    338:        movl    #_C_LABEL(addrerr4060),a1@(12)
                    339:
                    340:        bra     is16x
                    341: #endif
                    342:
                    343: #if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined(MVME172)
                    344: #define        ROMPKT_LEN      200
                    345: BSS(rompkt, ROMPKT_LEN)
                    346:        .even
                    347:        .text
                    348: is16x:
                    349:        RELOC(iiomapsize, a1)
                    350:        movl    #INTIOSIZE_162, a1@
                    351:        RELOC(iiomapbase, a1)
                    352:        movl    #INTIOBASE_162, a1@
                    353:
                    354:        /* get ethernet address */
                    355:        RELOC(rompkt, a0)               | build a .NETCTRL packet
                    356:        movb    #0, a0@(NETCTRL_DEV)    | onboard ethernet
                    357:        movb    #0, a0@(NETCTRL_CTRL)   | onboard ethernet
                    358:        movl    #NETCTRLCMD_GETETHER, a0@(NETCTRL_CMD)
                    359:        RELOC(myea, a1)
                    360:        movl    a1, a0@(NETCTRL_ADDR)   | where to put it
                    361:        movl    #6, a0@(NETCTRL_LEN)    | it is 6 bytes long
                    362:
                    363:        movl    a0, sp@-
                    364:        BUGCALL(MVMEPROM_NETCTRL)       | ask the rom
                    365:        addl    #4, sp
                    366:
                    367:        | if memory size is unknown, print a diagnostic and make an
                    368:        | assumption
                    369:        movl    d2, d1
                    370:        cmpl    #0, d1
                    371:        bne     Lstart1
                    372:
                    373:        movl    #unkmemend, sp@-
                    374:        movl    #unkmem, sp@-
                    375:        BUGCALL(MVMEPROM_OUTSTRCRLF)
                    376:        addql   #8,sp
                    377:
                    378:        movl    #4*1024*1024, d1        | XXX assume 4M of ram
                    379:        bra     Lstart1
                    380:
                    381:        .data
                    382: unkmem:        .asciz  "could not figure out how much memory; assuming 4M."
                    383: unkmemend:
                    384:        .even
                    385:        .text
                    386:
                    387: #endif
                    388:
                    389: Lstart1:
                    390: /* initialize source/destination control registers for movs */
                    391:        moveq   #FC_USERD,d0            | user space
                    392:        movc    d0,sfc                  |   as source
                    393:        movc    d0,dfc                  |   and destination of transfers
                    394:         moveq  #PGSHIFT,d2
                    395:        lsrl    d2,d1                   | convert to pages
                    396:        RELOC(physmem, a0)
                    397:        movl    d1,a0@                  | save as physmem
                    398:
                    399: /* configure kernel and proc0 VA space so we can get going */
                    400: #if defined(DDB) || NKSYMS > 0
                    401:        RELOC(esym,a0)                  | end of static kernel text/data/syms
                    402:        movl    a0@,d2
                    403:        jne     Lstart2
                    404: #endif
                    405:        movl    #_C_LABEL(end),d2       | end of static kernel text/data
                    406: Lstart2:
                    407:        addl    #NBPG-1,d2
                    408:        andl    #PG_FRAME,d2            | round to a page
                    409:        movl    d2,a4
                    410: #if 0
                    411:        | XXX clear from end-of-kernel to 1M, as a workaround for an
                    412:        | insane pmap_bootstrap bug I cannot find (68040-specific)
                    413:        movl    a4,a0
                    414:        movl    #1024*1024,d0
                    415:        cmpl    a0,d0                   | end of kernel is beyond 1M?
                    416:        jlt     2f
                    417:        subl    a0,d0
                    418: 1:     clrb    a0@+
                    419:        subql   #1,d0
                    420:        bne     1b
                    421: 2:
                    422: #endif
                    423:
                    424: /* do pmap_bootstrap stuff */
                    425:        clrl    sp@-                    | firstpa
                    426:        pea     a4@                     | nextpa
                    427:        RELOC(pmap_bootstrap,a0)
                    428:        jbsr    a0@                     | pmap_bootstrap(firstpa, nextpa)
                    429:        addql   #8,sp
                    430:
                    431: /*
                    432:  * While still running physical, override copypage() with the 68040
                    433:  * optimized version, copypage040(), if possible.
                    434:  * This relies upon the fact that copypage() immediately follows
                    435:  * copypage040() in memory.
                    436:  */
                    437:        RELOC(mmutype, a0)
                    438:        cmpl    #MMU_68040,a0@
                    439:        jgt     Lmmu_enable
                    440:        RELOC(copypage040, a0)
                    441:        RELOC(copypage, a1)
                    442:        movl    a1, a2
                    443: 1:
                    444:        movw    a0@+, a2@+
                    445:        cmpl    a0, a1
                    446:        jgt     1b
                    447:
                    448: /*
                    449:  * Enable the MMU.
                    450:  * Since the kernel is mapped logical == physical, we just turn it on.
                    451:  */
                    452: Lmmu_enable:
                    453:        RELOC(Sysseg, a0)               | system segment table addr
                    454:        movl    a0@,d1                  | read value (a KVA)
                    455:        RELOC(mmutype, a0)
                    456:        cmpl    #MMU_68040,a0@          | 68040 or 68060?
                    457:        jgt     Lmotommu1               | no, skip
                    458:        .long   0x4e7b1807              | movc d1,srp
                    459:        .long   0x4e7b1806              | movc d1,urp
                    460:        jra     Lstploaddone
                    461: Lmotommu1:
                    462:        RELOC(protorp, a0)
                    463:        movl    #0x80000202,a0@         | nolimit + share global + 4 byte PTEs
                    464:        movl    d1,a0@(4)               | + segtable address
                    465:        pmove   a0@,srp                 | load the supervisor root pointer
                    466:        movl    #0x80000002,a0@         | reinit upper half for CRP loads
                    467: Lstploaddone:
                    468:        RELOC(mmutype, a0)
                    469:        cmpl    #MMU_68040,a0@          | 68040 or 68060?
                    470:        jgt     Lmotommu2               | no, skip
                    471:
                    472:        moveq   #0,d0                   | ensure TT regs are disabled
                    473:        .long   0x4e7b0004              | movc d0,itt0
                    474:        .long   0x4e7b0005              | movc d0,itt1
                    475:        .long   0x4e7b0006              | movc d0,dtt0
                    476:        .long   0x4e7b0007              | movc d0,dtt1
                    477:
                    478:        .word   0xf4d8                  | cinva bc
                    479:        .word   0xf518                  | pflusha
                    480:         movl   #0x8000,d0
                    481:        .long   0x4e7b0003              | movc d0,tc
                    482:        /* Enable 68060 extensions here */
                    483:        RELOC(mmutype, a0)
                    484:        cmpl    #MMU_68060,a0@          | 68060?
                    485:         jne     Lchache040
                    486:         movl   #CACHE60_ON,d0          | branch cache, etc...
                    487:        movc    d0,cacr                 | turn on both caches
                    488:        jmp     Lenab1
                    489: Lchache040:
                    490:         movl   #CACHE40_ON,d0
                    491:        movc    d0,cacr                 | turn on both caches
                    492:        jmp     Lenab1
                    493: Lmotommu2:
                    494:        movl    #0x82c0aa00,a2@         | value to load TC with
                    495:        pmove   a2@,tc                  | load it
                    496: Lenab1:
                    497:
                    498: /*
                    499:  * Should be running mapped from this point on
                    500:  */
                    501: /* select the software page size now */
                    502:        lea     _ASM_LABEL(tmpstk),sp   | temporary stack
                    503:        jbsr    _C_LABEL(uvm_setpagesize) | select software page size
                    504: /* set kernel stack, user SP, and initial pcb */
                    505:        movl    _C_LABEL(proc0paddr),a1 | get proc0 pcb addr
                    506:        lea     a1@(USPACE-4),sp        | set kernel stack to end of area
                    507:        lea     _C_LABEL(proc0), a2     | initialize proc0.p_addr so that
                    508:        movl    a1,a2@(P_ADDR)          |  we don't deref NULL in trap()
                    509:        movl    #USRSTACK-4,a2
                    510:        movl    a2,usp                  | init user SP
                    511:        movl    a1,_C_LABEL(curpcb)     | proc0 is running
                    512:
                    513:        tstl    _C_LABEL(fputype)       | Have an FPU?
                    514:        jeq     Lenab2                  | No, skip.
                    515:        clrl    a1@(PCB_FPCTX)          | ensure null FP context
                    516:        movl    a1,sp@-
                    517:        jbsr    _C_LABEL(m68881_restore) | restore it (does not kill a1)
                    518:        addql   #4,sp
                    519: Lenab2:
                    520: /* flush TLB and turn on caches */
                    521:        jbsr    _ASM_LABEL(TBIA)        | invalidate TLB
                    522:        cmpl    #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
                    523:        jle     Lnocache0               | yes, cache already on
                    524:        movl    #CACHE_ON,d0
                    525:        movc    d0,cacr                 | clear cache(s)
                    526: Lnocache0:
                    527: /* final setup for C code */
                    528: #if 1
                    529:        movl    #_vectab,d2             | set VBR
                    530:        movc    d2,vbr
                    531: #endif
                    532:        movw    #PSL_LOWIPL,sr          | lower SPL
                    533:        movl    d3, _C_LABEL(bootpart)  | save bootpart
                    534:        movl    d4, _C_LABEL(bootdevlun) | save bootdevlun
                    535:        movl    d5, _C_LABEL(bootctrllun) | save bootctrllun
                    536:        movl    d6, _C_LABEL(bootaddr)  | save bootaddr
                    537:        movl    d7, _C_LABEL(boothowto) | save boothowto
                    538:        /* d3-d7 now free */
                    539:
                    540: /* Final setup for call to main(). */
                    541:        jbsr    _C_LABEL(mvme68k_init)
                    542:
                    543: /*
                    544:  * Create a fake exception frame so that cpu_fork() can copy it.
                    545:  * main() never returns; we exit to user mode from a forked process
                    546:  * later on.
                    547:  */
                    548:        clrw    sp@-                    | vector offset/frame type
                    549:        clrl    sp@-                    | PC - filled in by "execve"
                    550:        movw    #PSL_USER,sp@-          | in user mode
                    551:        clrl    sp@-                    | stack adjust count and padding
                    552:        lea     sp@(-64),sp             | construct space for D0-D7/A0-A7
                    553:        lea     _C_LABEL(proc0),a0      | save pointer to frame
                    554:        movl    sp,a0@(P_MD_REGS)       |   in proc0.p_md.md_regs
                    555:
                    556:        jra     _C_LABEL(main)          | main()
                    557:        PANIC("main() returned")
                    558:        /* NOTREACHED */
                    559:
                    560: #if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined(MVME172)
                    561: /*
                    562:  * Figure out the size of onboard DRAM by querying the memory controller(s).
                    563:  * This has to be done in locore as badaddr() can not yet be used at this
                    564:  * point.
                    565:  */
                    566: GLOBAL(memsize1x7)
                    567:        movl    #0xfff43008,a0          | MEMC040/MEMECC Controller #1
                    568:        jbsr    memc040read
                    569:        movl    d0,d2
                    570:
                    571:        movl    #0xfff43108,a0          | MEMC040/MEMECC Controller #2
                    572:        jbsr    memc040read
                    573:        addl    d0,d2
                    574:
                    575:        rts
                    576:
                    577: /*
                    578:  * Probe for a memory controller ASIC (MEMC040 or MEMECC) at the
                    579:  * address in a0. If found, return the size in bytes of any RAM
                    580:  * controller by the ASIC in d0. Otherwise return zero.
                    581:  */
                    582: ASLOCAL(memc040read)
                    583:        moveml  d1-d2/a1-a2,sp@-        | save scratch regs
                    584:        movc    vbr,d2                  | Save vbr
                    585:        RELOC(vectab,a2)                | Install our own vectab, temporarily
                    586:        movc    a2,vbr
                    587:        ASRELOC(Lmemc040berr,a1)        | get address of bus error handler
                    588:        movl    a2@(8),sp@-             | Save current bus error handler addr
                    589:        movl    a1,a2@(8)               | Install our own handler
                    590:        movl    sp,d0                   | Save current stack pointer value
                    591:        movql   #0x07,d1
                    592:        andb    a0@,d1                  | Access MEMC040/MEMECC
                    593:        movl    #0x400000,d0
                    594:        lsll    d1,d0                   | Convert to memory size, in bytes
                    595: Lmemc040ret:
                    596:        movc    d2,vbr                  | Restore original vbr
                    597:        movl    sp@+,a2@(8)             | Restore original bus error handler
                    598:        moveml  sp@+,d1-d2/a1-a2
                    599:        rts
                    600: /*
                    601:  * If the memory controller doesn't exist, we get a bus error trying
                    602:  * to access a0@ above. Control passes here, where we flag 'no bytes',
                    603:  * ditch the exception frame and return as normal.
                    604:  */
                    605: Lmemc040berr:
                    606:        movl    d0,sp                   | Get rid of the exception frame
                    607:        clrl    d0                      | No ASIC at this location, then!
                    608:        jbra    Lmemc040ret             | Done
                    609: #endif
                    610:
                    611: /*
                    612:  * proc_trampoline: call function in register a2 with a3 as an arg
                    613:  * and then rei.
                    614:  */
                    615: GLOBAL(proc_trampoline)
                    616:        movl    a3,sp@-                 | push function arg
                    617:        jbsr    a2@                     | call function
                    618:        addql   #4,sp                   | pop arg
                    619:        movl    sp@(FR_SP),a0           | grab and load
                    620:        movl    a0,usp                  |   user SP
                    621:        moveml  sp@+,#0x7FFF            | restore most user regs
                    622:        addql   #8,sp                   | toss SP and stack adjust
                    623:        jra     _ASM_LABEL(rei)         | and return
                    624:
                    625:
                    626: /*
                    627:  * Trap/interrupt vector routines - new for 060
                    628:  */
                    629: #include <m68k/m68k/trap_subr.s>
                    630:
                    631: #if defined(M68040) || defined(M68060)
                    632: ENTRY_NOPROFILE(addrerr4060)
                    633:        clrl    sp@-                    | stack adjust count
                    634:        moveml  #0xFFFF,sp@-            | save user registers
                    635:        movl    usp,a0                  | save the user SP
                    636:        movl    a0,sp@(FR_SP)           |   in the savearea
                    637:        movl    sp@(FR_HW+8),sp@-
                    638:        clrl    sp@-                    | dummy code
                    639:        movl    #T_ADDRERR,sp@-         | mark address error
                    640:        jra     _ASM_LABEL(faultstkadj) | and deal with it
                    641: #endif
                    642:
                    643: #if defined(M68060)
                    644: ENTRY_NOPROFILE(buserr60)
                    645:        clrl    sp@-                    | stack adjust count
                    646:        moveml  #0xFFFF,sp@-            | save user registers
                    647:        movl    usp,a0                  | save the user SP
                    648:        movl    a0,sp@(FR_SP)           |   in the savearea
                    649:        movel   sp@(FR_HW+12),d0        | FSLW
                    650:        btst    #2,d0                   | branch prediction error?
                    651:        jeq     Lnobpe
                    652:        movc    cacr,d2
                    653:        orl     #IC60_CABC,d2           | clear all branch cache entries
                    654:        movc    d2,cacr
                    655:        movl    d0,d1
                    656:        andl    #0x7ffd,d1
                    657:        jeq     _ASM_LABEL(faultstkadjnotrap2)
                    658: Lnobpe:
                    659: | we need to adjust for misaligned addresses
                    660:        movl    sp@(FR_HW+8),d1         | grab VA
                    661:        btst    #27,d0                  | check for mis-aligned access
                    662:        jeq     Lberr3                  | no, skip
                    663:        addl    #28,d1                  | yes, get into next page
                    664:                                        | operand case: 3,
                    665:                                         | instruction case: 4+12+12
                    666:        andl    #PG_FRAME,d1            | and truncate
                    667: Lberr3:
                    668:        movl    d1,sp@-
                    669:        movl    d0,sp@-                 | code is FSLW now.
                    670:        andw    #0x1f80,d0
                    671:        jeq     Lbuserr60               | no, handle as usual
                    672:        movl    #T_MMUFLT,sp@-          | show that we are an MMU fault
                    673:        jra     _ASM_LABEL(faultstkadj) | and deal with it
                    674: Lbuserr60:
                    675:        tstl    _C_LABEL(nofault)       | device probe?
                    676:        jeq     Lisberr                 | Bus Error?
                    677:        movl    _C_LABEL(nofault),sp@-  | yes,
                    678:        jbsr    _C_LABEL(longjmp)       |  longjmp(nofault)
                    679: #endif
                    680: #if defined(M68040)
                    681: ENTRY_NOPROFILE(buserr40)
                    682:         clrl   sp@-                    | stack adjust count
                    683:        moveml  #0xFFFF,sp@-            | save user registers
                    684:        movl    usp,a0                  | save the user SP
                    685:        movl    a0,sp@(FR_SP)           |   in the savearea
                    686:        movl    sp@(FR_HW+20),d1        | get fault address
                    687:        moveq   #0,d0
                    688:        movw    sp@(FR_HW+12),d0        | get SSW
                    689:        btst    #11,d0                  | check for mis-aligned
                    690:        jeq     Lbe1stpg                | no skip
                    691:        addl    #3,d1                   | get into next page
                    692:        andl    #PG_FRAME,d1            | and truncate
                    693: Lbe1stpg:
                    694:        movl    d1,sp@-                 | pass fault address.
                    695:        movl    d0,sp@-                 | pass SSW as code
                    696:        btst    #10,d0                  | test ATC
                    697:        jeq     Lbuserr40               | no, handle as usual
                    698:        movl    #T_MMUFLT,sp@-          | show that we are an MMU fault
                    699:        jra     _ASM_LABEL(faultstkadj) | and deal with it
                    700: Lbuserr40:
                    701:        tstl    _C_LABEL(nofault)       | device probe?
                    702:        jeq     Lisberr                 | it is a bus error
                    703:        movl    _C_LABEL(nofault),sp@-  | yes,
                    704:        jbsr    _C_LABEL(longjmp)       |  longjmp(nofault)
                    705:        /* NOTREACHED */
                    706: #endif
                    707:
                    708: ENTRY_NOPROFILE(busaddrerr2030)
                    709:        clrl    sp@-                    | stack adjust count
                    710:        moveml  #0xFFFF,sp@-            | save user registers
                    711:        movl    usp,a0                  | save the user SP
                    712:        movl    a0,sp@(FR_SP)           |   in the savearea
                    713:        lea     sp@(FR_HW),a1           | grab base of HW berr frame
                    714:        moveq   #0,d0
                    715:        movw    a1@(10),d0              | grab SSW for fault processing
                    716:        btst    #12,d0                  | RB set?
                    717:        jeq     LbeX0                   | no, test RC
                    718:        bset    #14,d0                  | yes, must set FB
                    719:        movw    d0,a1@(10)              | for hardware too
                    720: LbeX0:
                    721:        btst    #13,d0                  | RC set?
                    722:        jeq     LbeX1                   | no, skip
                    723:        bset    #15,d0                  | yes, must set FC
                    724:        movw    d0,a1@(10)              | for hardware too
                    725: LbeX1:
                    726:        btst    #8,d0                   | data fault?
                    727:        jeq     Lbe0                    | no, check for hard cases
                    728:        movl    a1@(16),d1              | fault address is as given in frame
                    729:        jra     Lbe10                   | thats it
                    730: Lbe0:
                    731:        btst    #4,a1@(6)               | long (type B) stack frame?
                    732:        jne     Lbe4                    | yes, go handle
                    733:        movl    a1@(2),d1               | no, can use save PC
                    734:        btst    #14,d0                  | FB set?
                    735:        jeq     Lbe3                    | no, try FC
                    736:        addql   #4,d1                   | yes, adjust address
                    737:        jra     Lbe10                   | done
                    738: Lbe3:
                    739:        btst    #15,d0                  | FC set?
                    740:        jeq     Lbe10                   | no, done
                    741:        addql   #2,d1                   | yes, adjust address
                    742:        jra     Lbe10                   | done
                    743: Lbe4:
                    744:        movl    a1@(36),d1              | long format, use stage B address
                    745:        btst    #15,d0                  | FC set?
                    746:        jeq     Lbe10                   | no, all done
                    747:        subql   #2,d1                   | yes, adjust address
                    748: Lbe10:
                    749:        movl    d1,sp@-                 | push fault VA
                    750:        movl    d0,sp@-                 | and padded SSW
                    751:        movw    a1@(6),d0               | get frame format/vector offset
                    752:        andw    #0x0FFF,d0              | clear out frame format
                    753:        cmpw    #12,d0                  | address error vector?
                    754:        jeq     Lisaerr                 | yes, go to it
                    755:        movl    d1,a0                   | fault address
                    756:        movl    sp@,d0                  | function code from ssw
                    757:        btst    #8,d0                   | data fault?
                    758:        jne     Lbe10a
                    759:        movql   #1,d0                   | user program access FC
                    760:                                        | (we dont separate data/program)
                    761:        btst    #5,a1@                  | supervisor mode?
                    762:        jeq     Lbe10a                  | if no, done
                    763:        movql   #5,d0                   | else supervisor program access
                    764: Lbe10a:
                    765:        ptestr  d0,a0@,#7               | do a table search
                    766:        pmove   psr,sp@                 | save result
                    767:        movb    sp@,d1
                    768:        btst    #2,d1                   | invalid (incl. limit viol. and berr)?
                    769:        jeq     Lmightnotbemerr         | no -> wp check
                    770:        btst    #7,d1                   | is it MMU table berr?
                    771:        jeq     Lismerr                 | no, must be fast
                    772:        jra     Lisberr1                | real bus err needs not be fast.
                    773: Lmightnotbemerr:
                    774:        btst    #3,d1                   | write protect bit set?
                    775:        jeq     Lisberr1                | no: must be bus error
                    776:        movl    sp@,d0                  | ssw into low word of d0
                    777:        andw    #0xc0,d0                | Write protect is set on page:
                    778:        cmpw    #0x40,d0                | was it read cycle?
                    779:        jeq     Lisberr1                | yes, was not WPE, must be bus err
                    780: Lismerr:
                    781:        movl    #T_MMUFLT,sp@-          | show that we are an MMU fault
                    782:        jra     _ASM_LABEL(faultstkadj) | and deal with it
                    783: Lisaerr:
                    784:        movl    #T_ADDRERR,sp@-         | mark address error
                    785:        jra     _ASM_LABEL(faultstkadj) | and deal with it
                    786: Lisberr1:
                    787:        clrw    sp@                     | re-clear pad word
                    788: Lisberr:
                    789:        movl    #T_BUSERR,sp@-          | mark bus error
                    790:        jra     _ASM_LABEL(faultstkadj) | and deal with it
                    791:
                    792: /*
                    793:  * FP exceptions.
                    794:  */
                    795: ENTRY_NOPROFILE(fpfline)
                    796: #if defined(M68040) || defined(M68060)
                    797:        cmpl    #FPU_68040,_C_LABEL(fputype) | 68040 or 68060 FPU?
                    798:        jlt     Lfp_unimp               | no, skip FPSP
                    799:        cmpw    #0x202c,sp@(6)          | format type 2?
                    800:        jne     _C_LABEL(illinst)       | no, not an FP emulation
                    801: Ldofp_unimp:
                    802: #ifdef FPSP
                    803:        jmp     _ASM_LABEL(fpsp_unimp)  | yes, go handle it
                    804: #endif
                    805: Lfp_unimp:
                    806: #endif/* M68040 || M68060 */
                    807: #ifdef FPU_EMULATE
                    808:        clrl    sp@-                    | stack adjust count
                    809:        moveml  #0xFFFF,sp@-            | save registers
                    810:        moveq   #T_FPEMULI,d0           | denote as FP emulation trap
                    811:        jra     _ASM_LABEL(fault)       | do it
                    812: #else
                    813:        jra     _C_LABEL(illinst)
                    814: #endif
                    815:
                    816: ENTRY_NOPROFILE(fpunsupp)
                    817: #if defined(M68040) || defined(M68060)
                    818:        cmpl    #FPU_68040,_C_LABEL(fputype) | 68040 or 68060 FPU?
                    819:        jlt     _C_LABEL(illinst)       | no, treat as illinst
                    820: #ifdef FPSP
                    821:        jmp     _ASM_LABEL(fpsp_unsupp) | yes, go handle it
                    822: #endif
                    823: Lfp_unsupp:
                    824: #endif /* M68040 */
                    825: #ifdef FPU_EMULATE
                    826:        clrl    sp@-                    | stack adjust count
                    827:        moveml  #0xFFFF,sp@-            | save registers
                    828:        moveq   #T_FPEMULD,d0           | denote as FP emulation trap
                    829:        jra     _ASM_LABEL(fault)               | do it
                    830: #else
                    831:        jra     _C_LABEL(illinst)
                    832: #endif
                    833:
                    834: /*
                    835:  * Handles all other FP coprocessor exceptions.
                    836:  * Note that since some FP exceptions generate mid-instruction frames
                    837:  * and may cause signal delivery, we need to test for stack adjustment
                    838:  * after the trap call.
                    839:  */
                    840: ENTRY_NOPROFILE(fpfault)
                    841:        clrl    sp@-            | stack adjust count
                    842:        moveml  #0xFFFF,sp@-    | save user registers
                    843:        movl    usp,a0          | and save
                    844:        movl    a0,sp@(FR_SP)   |   the user stack pointer
                    845:        clrl    sp@-            | no VA arg
                    846:        movl    _C_LABEL(curpcb),a0 | current pcb
                    847:        lea     a0@(PCB_FPCTX),a0 | address of FP savearea
                    848:        fsave   a0@             | save state
                    849: #if defined(M68040) || defined(M68060)
                    850:        /* always null state frame on 68040, 68060 */
                    851:        cmpl    #CPU_68040,_C_LABEL(cputype)
                    852:        jge     Lfptnull
                    853: #endif
                    854:        tstb    a0@             | null state frame?
                    855:        jeq     Lfptnull        | yes, safe
                    856:        clrw    d0              | no, need to tweak BIU
                    857:        movb    a0@(1),d0       | get frame size
                    858:        bset    #3,a0@(0,d0:w)  | set exc_pend bit of BIU
                    859: Lfptnull:
                    860:        fmovem  fpsr,sp@-       | push fpsr as code argument
                    861:        frestore a0@            | restore state
                    862:        movl    #T_FPERR,sp@-   | push type arg
                    863:        jra     _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
                    864:
                    865: /*
                    866:  * Other exceptions only cause four and six word stack frame and require
                    867:  * no post-trap stack adjustment.
                    868:  */
                    869: ENTRY_NOPROFILE(hardtrap)
                    870:        moveml  #0xC0C0,sp@-            | save scratch regs
                    871:        lea     sp@(16),a1              | get pointer to frame
                    872:        movl    a1,sp@-
                    873:        movw    sp@(26),d0
                    874:        movl    d0,sp@-                 | push exception vector info
                    875:        movl    sp@(26),sp@-            | and PC
                    876:        jbsr    _C_LABEL(hardintr)      | doit
                    877:        lea     sp@(12),sp              | pop args
                    878:        moveml  sp@+,#0x0303            | restore regs
                    879:        jra     _ASM_LABEL(rei)         | all done
                    880:
                    881: ENTRY_NOPROFILE(badtrap)
                    882:        moveml  #0xC0C0,sp@-            | save scratch regs
                    883:        movw    sp@(22),sp@-            | push exception vector info
                    884:        clrw    sp@-
                    885:        movl    sp@(22),sp@-            | and PC
                    886:        jbsr    _C_LABEL(straytrap)     | report
                    887:        addql   #8,sp                   | pop args
                    888:        moveml  sp@+,#0x0303            | restore regs
                    889:        jra     _ASM_LABEL(rei)         | all done
                    890:
                    891: ENTRY_NOPROFILE(trap0)
                    892:        clrl    sp@-                    | stack adjust count
                    893:        moveml  #0xFFFF,sp@-            | save user registers
                    894:        movl    usp,a0                  | save the user SP
                    895:        movl    a0,sp@(FR_SP)           |   in the savearea
                    896:        movl    d0,sp@-                 | push syscall number
                    897:        jbsr    _C_LABEL(syscall)       | handle it
                    898:        addql   #4,sp                   | pop syscall arg
                    899:        tstl    _C_LABEL(astpending)
                    900:        jne     Lrei2
                    901:        tstb    _C_LABEL(ssir)
                    902:        jeq     Ltrap1
                    903:        movw    #SPL1,sr
                    904:        tstb    _C_LABEL(ssir)
                    905:        jne     Lsir1
                    906: Ltrap1:
                    907:        movl    sp@(FR_SP),a0           | grab and restore
                    908:        movl    a0,usp                  |   user SP
                    909:        moveml  sp@+,#0x7FFF            | restore most registers
                    910:        addql   #8,sp                   | pop SP and stack adjust
                    911:        rte
                    912:
                    913: /*
                    914:  * Trap 1 - sigreturn
                    915:  */
                    916: ENTRY_NOPROFILE(trap1)
                    917:        jra     _ASM_LABEL(sigreturn)
                    918:
                    919: /*
                    920:  * Trap 2 - trace trap
                    921:  */
                    922: ENTRY_NOPROFILE(trap2)
                    923:        jra     _C_LABEL(trace)
                    924:
                    925: /*
                    926:  * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
                    927:  *     cachectl(command, addr, length)
                    928:  * command in d0, addr in a1, length in d1
                    929:  */
                    930: ENTRY_NOPROFILE(trap12)
                    931:        movl    d1,sp@-                 | push length
                    932:        movl    a1,sp@-                 | push addr
                    933:        movl    d0,sp@-                 | push command
                    934:        movl    CURPROC,sp@-            | push proc pointer
                    935:        jbsr    _C_LABEL(cachectl)      | do it
                    936:        lea     sp@(16),sp              | pop args
                    937:        jra     _ASM_LABEL(rei)         | all done
                    938:
                    939: /*
                    940:  * Trace (single-step) trap (trap 1 or 2) instruction. Kernel-mode is
                    941:  * special. User mode traps are simply passed on to trap().
                    942:  */
                    943: ENTRY_NOPROFILE(trace)
                    944:        clrl    sp@-
                    945:        moveml  #0xFFFF,sp@-
                    946:        moveq   #T_TRACE,d0
                    947:
                    948:        | Check PSW and see what happened.
                    949:        |   T=0 S=0     (should not happen)
                    950:        |   T=1 S=0     trace trap from user mode
                    951:        |   T=0 S=1     trace trap on a trap instruction
                    952:        |   T=0 S=0     trace trap from system mode (kernel breakpoint)
                    953:
                    954:        movw    sp@(FR_HW),d1           | get SSW
                    955:        notw    d1                      | XXX no support for T0 on 680[234]0
                    956:        andw    #PSL_S,d1               | from system mode (T=1, S=1)?
                    957:        jeq     Lkbrkpt                 | yes, kernel breakpoint
                    958:        jra     _ASM_LABEL(fault)       | no, user-mode fault
                    959:
                    960: /*
                    961:  * Trap 15 is used for:
                    962:  *     - GDB breakpoints (in user programs)
                    963:  *     - KGDB breakpoints (in the kernel)
                    964:  *     - trace traps for SUN binaries (not fully supported yet)
                    965:  *     - calling the prom, but only from the kernel
                    966:  * We just pass it on and let trap() sort it all out
                    967:  */
                    968: ENTRY_NOPROFILE(trap15)
                    969:        clrl    sp@-                    | stack adjust count
                    970:        moveml  #0xFFFF,sp@-
                    971:
                    972:        tstl    _C_LABEL(promcall)
                    973:        jeq     L_notpromcall
                    974:        moveml  sp@+,#0xFFFF
                    975:        addql   #4, sp
                    976:        | unwind stack to put to known value
                    977:        | this routine is from the 147 BUG manual
                    978:        | currently save and restore are excessive.
                    979:        subql   #4,sp
                    980:        link    a6,#0
                    981:        moveml  #0xFFFE,sp@-
                    982:        movl    _C_LABEL(promvbr),a0
                    983:        movw    a6@(14),d0
                    984:        andl    #0xfff,d0
                    985:        movl    a0@(d0:w),a6@(4)
                    986:        moveml  sp@+,#0x7FFF
                    987:        unlk    a6
                    988:        rts
                    989:        | really jumps to the bug trap handler
                    990: L_notpromcall:
                    991:        moveq   #T_TRAP15,d0
                    992:        movw    sp@(FR_HW),d1           | get PSW
                    993:        andw    #PSL_S,d1               | from system mode?
                    994:        jne     Lkbrkpt                 | yes, kernel breakpoint
                    995:        jra     _ASM_LABEL(fault)       | no, user-mode fault
                    996:
                    997: Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type)
                    998:        | Save the system sp rather than the user sp.
                    999:        movw    #PSL_HIGHIPL,sr         | lock out interrupts
                   1000:        lea     sp@(FR_SIZE),a6         | Save stack pointer
                   1001:        movl    a6,sp@(FR_SP)           |   from before trap
                   1002:
                   1003:        | If we are not on tmpstk switch to it.
                   1004:        | (so debugger can change the stack pointer)
                   1005:        movl    a6,d1
                   1006:        cmpl    #_ASM_LABEL(tmpstk),d1
                   1007:        jls     Lbrkpt2                 | already on tmpstk
                   1008:        | Copy frame to the temporary stack
                   1009:        movl    sp,a0                   | a0=src
                   1010:        lea     _ASM_LABEL(tmpstk)-96,a1 | a1=dst
                   1011:        movl    a1,sp                   | sp=new frame
                   1012:        moveq   #FR_SIZE,d1
                   1013: Lbrkpt1:
                   1014:        movl    a0@+,a1@+
                   1015:        subql   #4,d1
                   1016:        bgt     Lbrkpt1
                   1017:
                   1018: Lbrkpt2:
                   1019:        | Call the trap handler for the kernel debugger.
                   1020:        | Do not call trap() to do it, so that we can
                   1021:        | set breakpoints in trap() if we want.  We know
                   1022:        | the trap type is either T_TRACE or T_BREAKPOINT.
                   1023:        | If we have both DDB and KGDB, let KGDB see it first,
                   1024:        | because KGDB will just return 0 if not connected.
                   1025:        | Save args in d2, a2
                   1026:        movl    d0,d2                   | trap type
                   1027:        movl    sp,a2                   | frame ptr
                   1028: #ifdef KGDB
                   1029:        | Let KGDB handle it (if connected)
                   1030:        movl    a2,sp@-                 | push frame ptr
                   1031:        movl    d2,sp@-                 | push trap type
                   1032:        jbsr    _C_LABEL(kgdb_trap)     | handle the trap
                   1033:        addql   #8,sp                   | pop args
                   1034:        cmpl    #0,d0                   | did kgdb handle it?
                   1035:        jne     Lbrkpt3                 | yes, done
                   1036: #endif
                   1037: #ifdef DDB
                   1038:        | Let DDB handle it
                   1039:        movl    a2,sp@-                 | push frame ptr
                   1040:        movl    d2,sp@-                 | push trap type
                   1041:        jbsr    _C_LABEL(kdb_trap)      | handle the trap
                   1042:        addql   #8,sp                   | pop args
                   1043:        cmpl    #0,d0                   | did ddb handle it?
                   1044:        jne     Lbrkpt3                 | yes, done
                   1045: #endif
                   1046:        | Drop into the prom
                   1047:        BUGCALL(MVMEPROM_EXIT)
                   1048: Lbrkpt3:
                   1049:        | The stack pointer may have been modified, or
                   1050:        | data below it modified (by kgdb push call),
                   1051:        | so push the hardware frame at the current sp
                   1052:        | before restoring registers and returning.
                   1053:
                   1054:        movl    sp@(FR_SP),a0           | modified sp
                   1055:        lea     sp@(FR_SIZE),a1         | end of our frame
                   1056:        movl    a1@-,a0@-               | copy 2 longs with
                   1057:        movl    a1@-,a0@-               | ... predecrement
                   1058:        movl    a0,sp@(FR_SP)           | sp = h/w frame
                   1059:        moveml  sp@+,#0x7FFF            | restore all but sp
                   1060:        movl    sp@,sp                  | ... and sp
                   1061:        rte                             | all done
                   1062:
                   1063: /* Use common m68k sigreturn */
                   1064: #include <m68k/m68k/sigreturn.s>
                   1065:
                   1066: /*
                   1067:  * Interrupt handlers.
                   1068:  * No device interrupts are auto-vectored.
                   1069:  */
                   1070:
                   1071: ENTRY_NOPROFILE(spurintr)
                   1072:        addql   #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
                   1073:        jra     _ASM_LABEL(rei)         | all done
                   1074:
                   1075: /*
                   1076:  * Emulation of VAX REI instruction.
                   1077:  *
                   1078:  * This code deals with checking for and servicing ASTs
                   1079:  * (profiling, scheduling) and software interrupts (network, softclock).
                   1080:  * We check for ASTs first, just like the VAX.  To avoid excess overhead
                   1081:  * the T_ASTFLT handling code will also check for software interrupts so we
                   1082:  * do not have to do it here.  After identifing that we need an AST we
                   1083:  * drop the IPL to allow device interrupts.
                   1084:  *
                   1085:  * This code is complicated by the fact that sendsig may have been called
                   1086:  * necessitating a stack cleanup.
                   1087:  */
                   1088:
                   1089: BSS(ssir,1)
                   1090:
                   1091: ASENTRY_NOPROFILE(rei)
                   1092:        tstl    _C_LABEL(astpending)    | AST pending?
                   1093:        jeq     Lchksir                 | no, go check for SIR
                   1094: Lrei1:
                   1095:        btst    #5,sp@                  | yes, are we returning to user mode?
                   1096:        jne     Lchksir                 | no, go check for SIR
                   1097:        movw    #PSL_LOWIPL,sr          | lower SPL
                   1098:        clrl    sp@-                    | stack adjust
                   1099:        moveml  #0xFFFF,sp@-            | save all registers
                   1100:        movl    usp,a1                  | including
                   1101:        movl    a1,sp@(FR_SP)           |    the users SP
                   1102: Lrei2:
                   1103:        clrl    sp@-                    | VA == none
                   1104:        clrl    sp@-                    | code == none
                   1105:        movl    #T_ASTFLT,sp@-          | type == async system trap
                   1106:        jbsr    _C_LABEL(trap)          | go handle it
                   1107:        lea     sp@(12),sp              | pop value args
                   1108:        movl    sp@(FR_SP),a0           | restore user SP
                   1109:        movl    a0,usp                  |   from save area
                   1110:        movw    sp@(FR_ADJ),d0          | need to adjust stack?
                   1111:        jne     Laststkadj              | yes, go to it
                   1112:        moveml  sp@+,#0x7FFF            | no, restore most user regs
                   1113:        addql   #8,sp                   | toss SP and stack adjust
                   1114:        rte                             | and do real RTE
                   1115: Laststkadj:
                   1116:        lea     sp@(FR_HW),a1           | pointer to HW frame
                   1117:        addql   #8,a1                   | source pointer
                   1118:        movl    a1,a0                   | source
                   1119:        addw    d0,a0                   |  + hole size = dest pointer
                   1120:        movl    a1@-,a0@-               | copy
                   1121:        movl    a1@-,a0@-               |  8 bytes
                   1122:        movl    a0,sp@(FR_SP)           | new SSP
                   1123:        moveml  sp@+,#0x7FFF            | restore user registers
                   1124:        movl    sp@,sp                  | and our SP
                   1125:        rte                             | and do real RTE
                   1126: Lchksir:
                   1127:        tstb    _C_LABEL(ssir)          | SIR pending?
                   1128:        jeq     Ldorte                  | no, all done
                   1129:        movl    d0,sp@-                 | need a scratch register
                   1130:        movw    sp@(4),d0               | get SR
                   1131:        andw    #PSL_IPL7,d0            | mask all but IPL
                   1132:        jne     Lnosir                  | came from interrupt, no can do
                   1133:        movl    sp@+,d0                 | restore scratch register
                   1134: Lgotsir:
                   1135:        movw    #SPL1,sr                | prevent others from servicing int
                   1136:        tstb    _C_LABEL(ssir)          | too late?
                   1137:        jeq     Ldorte                  | yes, oh well...
                   1138:        clrl    sp@-                    | stack adjust
                   1139:        moveml  #0xFFFF,sp@-            | save all registers
                   1140:        movl    usp,a1                  | including
                   1141:        movl    a1,sp@(FR_SP)           |    the users SP
                   1142: Lsir1:
                   1143:        clrl    sp@-                    | VA == none
                   1144:        clrl    sp@-                    | code == none
                   1145:        movl    #T_SSIR,sp@-            | type == software interrupt
                   1146:        jbsr    _C_LABEL(trap)          | go handle it
                   1147:        lea     sp@(12),sp              | pop value args
                   1148:        movl    sp@(FR_SP),a0           | restore
                   1149:        movl    a0,usp                  |   user SP
                   1150:        moveml  sp@+,#0x7FFF            | and all remaining registers
                   1151:        addql   #8,sp                   | pop SP and stack adjust
                   1152:        rte
                   1153: Lnosir:
                   1154:        movl    sp@+,d0                 | restore scratch register
                   1155: Ldorte:
                   1156:        rte                             | real return
                   1157:
                   1158: /*
                   1159:  * Use common m68k signal trampoline.
                   1160:  */
                   1161: #include <m68k/m68k/sigcode.s>
                   1162:
                   1163: /*
                   1164:  * Use common m68k support routines.
                   1165:  */
                   1166: #include <m68k/m68k/support.s>
                   1167:
                   1168: /*
                   1169:  * Use common m68k process manipulation routines.
                   1170:  */
                   1171: #include <m68k/m68k/proc_subr.s>
                   1172:
                   1173:        .data
                   1174: GLOBAL(curpcb)
                   1175:        .long   0
                   1176:
                   1177: ASBSS(nullpcb,SIZEOF_PCB)
                   1178:
                   1179: /*
                   1180:  * At exit of a process, do a switch for the last time.
                   1181:  * Switch to a safe stack and PCB, and deallocate the process's resources.
                   1182:  */
                   1183: ENTRY(switch_exit)
                   1184:        movl    sp@(4),a0
                   1185:        | save state into garbage pcb
                   1186:        movl    #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
                   1187:        lea     _ASM_LABEL(tmpstk),sp   | goto a tmp stack
                   1188:
                   1189:         /* Schedule the vmspace and stack to be freed. */
                   1190:        movl    a0,sp@-                 | exit2(p)
                   1191:        jbsr    _C_LABEL(exit2)
                   1192:        lea     sp@(4),sp               | pop args
                   1193:
                   1194:        jra     _C_LABEL(cpu_switch)
                   1195:
                   1196: /*
                   1197:  * When no processes are on the runq, Swtch branches to Idle
                   1198:  * to wait for something to come ready.
                   1199:  */
                   1200: ASENTRY_NOPROFILE(Idle)
                   1201:        stop    #PSL_LOWIPL
                   1202:        movw    #PSL_HIGHIPL,sr
                   1203:        movl    _C_LABEL(whichqs),d0
                   1204:        jeq     _ASM_LABEL(Idle)
                   1205:        jra     Lsw1
                   1206:
                   1207: Lbadsw:
                   1208:        PANIC("switch")
                   1209:        /*NOTREACHED*/
                   1210:
                   1211: /*
                   1212:  * cpu_switch()
                   1213:  *
                   1214:  * NOTE: On the mc68851 we attempt to avoid flushing the
                   1215:  * entire ATC.  The effort involved in selective flushing may not be
                   1216:  * worth it, maybe we should just flush the whole thing?
                   1217:  *
                   1218:  * NOTE 2: With the new VM layout we now no longer know if an inactive
                   1219:  * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
                   1220:  * bit).  For now, we just always flush the full ATC.
                   1221:  */
                   1222: ENTRY(cpu_switch)
                   1223:        movl    _C_LABEL(curpcb),a0     | current pcb
                   1224:        movw    sr,a0@(PCB_PS)          | save sr before changing ipl
                   1225: #ifdef notyet
                   1226:        movl    CURPROC,sp@-            | remember last proc running
                   1227: #endif
                   1228:        clrl    CURPROC
                   1229:
                   1230:        /*
                   1231:         * Find the highest-priority queue that isn't empty,
                   1232:         * then take the first proc from that queue.
                   1233:         */
                   1234:        movw    #PSL_HIGHIPL,sr         | lock out interrupts
                   1235:        movl    _C_LABEL(whichqs),d0
                   1236:        jeq     _ASM_LABEL(Idle)
                   1237: Lsw1:
                   1238:        movl    d0,d1
                   1239:        negl    d0
                   1240:        andl    d1,d0
                   1241:        bfffo   d0{#0:#32},d1
                   1242:        eorib   #31,d1
                   1243:
                   1244:        movl    d1,d0
                   1245:        lslb    #3,d1                   | convert queue number to index
                   1246:        addl    #_C_LABEL(qs),d1        | locate queue (q)
                   1247:        movl    d1,a1
                   1248:        movl    a1@(P_FORW),a0          | p = q->p_forw
                   1249:        cmpal   d1,a0                   | anyone on queue?
                   1250:        jeq     Lbadsw                  | no, panic
                   1251:        movl    a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
                   1252:        movl    a0@(P_FORW),a1          | n = p->p_forw
                   1253:        movl    d1,a1@(P_BACK)          | n->p_back = q
                   1254:        cmpal   d1,a1                   | anyone left on queue?
                   1255:        jne     Lsw2                    | yes, skip
                   1256:        movl    _C_LABEL(whichqs),d1
                   1257:        bclr    d0,d1                   | no, clear bit
                   1258:        movl    d1,_C_LABEL(whichqs)
                   1259: Lsw2:
                   1260:        movl    a0,CURPROC
                   1261:        clrl    _C_LABEL(want_resched)
                   1262: #ifdef notyet
                   1263:        movl    sp@+,a1
                   1264:        cmpl    a0,a1                   | switching to same proc?
                   1265:        jeq     Lswdone                 | yes, skip save and restore
                   1266: #endif
                   1267:        /*
                   1268:         * Save state of previous process in its pcb.
                   1269:         */
                   1270:         movl   _C_LABEL(curpcb),a1
                   1271:        moveml  #0xFCFC,a1@(PCB_REGS)   | save non-scratch registers
                   1272:        movl    usp,a2                  | grab USP (a2 has been saved)
                   1273:        movl    a2,a1@(PCB_USP)         | and save it
                   1274: #ifdef FPU_EMULATE
                   1275:        tstl    _C_LABEL(fputype)       | do we have any FPU?
                   1276:        jeq     Lswnofpsave             | no, dont save
                   1277: #endif
                   1278:        lea     a1@(PCB_FPCTX),a2       | pointer to FP save area
                   1279:        fsave   a2@                     | save FP state
                   1280: #ifdef M68060
                   1281:        cmpl    #FPU_68060,_C_LABEL(fputype) | is 68060?
                   1282:        jeq     Lsavfp60                | yes, goto Lsavfp60
                   1283: #endif  /* M68060 */
                   1284:        tstb    a2@                     | null state frame?
                   1285:        jeq     Lswnofpsave             | yes, all done
                   1286:        fmovem  fp0-fp7,a2@(FPF_REGS)   | save FP general registers
                   1287:        fmovem  fpcr/fpsr/fpi,a2@(FPF_FPCR)     | save FP control registers
                   1288: #ifdef M68060
                   1289:        jra     Lswnofpsave
                   1290: Lsavfp60:
                   1291:        tstb    a2@(2)                  | null state frame?
                   1292:        jeq     Lswnofpsave             | yes, all done
                   1293:        fmovem  fp0-fp7,a2@(FPF_REGS)   | save FP general registers
                   1294:        fmovem  fpcr,a2@(FPF_FPCR)      | save FP control registers
                   1295:        fmovem  fpsr,a2@(FPF_FPSR)
                   1296:        fmovem  fpi,a2@(FPF_FPI)
                   1297: #endif /* M68060 */
                   1298: Lswnofpsave:
                   1299: #ifdef DIAGNOSTIC
                   1300:        tstl    a0@(P_WCHAN)
                   1301:        jne     Lbadsw
                   1302:        cmpb    #SRUN,a0@(P_STAT)
                   1303:        jne     Lbadsw
                   1304: #endif
                   1305:        movb    #SONPROC,a0@(P_STAT)
                   1306:        clrl    a0@(P_BACK)             | clear back link
                   1307:        movl    a0@(P_ADDR),a1          | get p_addr
                   1308:        movl    a1,_C_LABEL(curpcb)
                   1309:
                   1310:        /*
                   1311:         * Activate process's address space.
                   1312:         * XXX Should remember the last USTP value loaded, and call this
                   1313:         * XXX only of it has changed.
                   1314:         */
                   1315:        pea     a0@                     | push proc
                   1316:        jbsr    _C_LABEL(pmap_activate) | pmap_activate(p)
                   1317:        addql   #4,sp
                   1318:        movl    _C_LABEL(curpcb),a1     | restore p_addr
                   1319:
                   1320:        lea     _ASM_LABEL(tmpstk),sp   | now goto a tmp stack for NMI
                   1321:
                   1322:        moveml  a1@(PCB_REGS),#0xFCFC   | and registers
                   1323:        movl    a1@(PCB_USP),a0
                   1324:        movl    a0,usp                  | and USP
                   1325:
                   1326: #ifdef FPU_EMULATE
                   1327:        tstl    _C_LABEL(fputype)       | do we _have_ any fpu?
                   1328:        jne     Lresnonofpatall
                   1329:        movw    a1@(PCB_PS),sr          | no, restore PS
                   1330:        moveq   #1,d0                   | return 1 (for alternate returns)
                   1331:        rts
                   1332: Lresnonofpatall:
                   1333: #endif
                   1334:        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
                   1335: #ifdef M68060
                   1336:        cmpl    #FPU_68060,_C_LABEL(fputype) | is 68060?
                   1337:        jeq     Lresfp60rest1           | yes, goto Lresfp60rest1
                   1338: #endif /* M68060 */
                   1339:        tstb    a0@                     | null state frame?
                   1340:        jeq     Lresfprest2             | yes, easy
                   1341:        fmovem  a0@(FPF_FPCR),fpcr/fpsr/fpi     | restore FP control registers
                   1342:        fmovem  a0@(FPF_REGS),fp0-fp7   | restore FP general registers
                   1343: Lresfprest2:
                   1344:        frestore a0@                    | restore state
                   1345:        movw    a1@(PCB_PS),sr          | no, restore PS
                   1346:        moveq   #1,d0                   | return 1 (for alternate returns)
                   1347:        rts
                   1348:
                   1349: #ifdef M68060
                   1350: Lresfp60rest1:
                   1351:        tstb    a0@(2)                  | null state frame?
                   1352:        jeq     Lresfp60rest2           | yes, easy
                   1353:        fmovem  a0@(FPF_FPCR),fpcr      | restore FP control registers
                   1354:        fmovem  a0@(FPF_FPSR),fpsr
                   1355:        fmovem  a0@(FPF_FPI),fpi
                   1356:        fmovem  a0@(FPF_REGS),fp0-fp7   | restore FP general registers
                   1357: Lresfp60rest2:
                   1358:        frestore a0@                    | restore state
                   1359:        movw    a1@(PCB_PS),sr          | no, restore PS
                   1360:        moveq   #1,d0                   | return 1 (for alternate returns)
                   1361:        rts
                   1362: #endif /* M68060 */
                   1363:
                   1364:
                   1365: /*
                   1366:  * savectx(pcb)
                   1367:  * Update pcb, saving current processor state.
                   1368:  */
                   1369: ENTRY(savectx)
                   1370:        movl    sp@(4),a1
                   1371:        movw    sr,a1@(PCB_PS)
                   1372:        movl    usp,a0                  | grab USP
                   1373:        movl    a0,a1@(PCB_USP)         | and save it
                   1374:        moveml  #0xFCFC,a1@(PCB_REGS)   | save non-scratch registers
                   1375: #ifdef FPU_EMULATE
                   1376:        tstl    _C_LABEL(fputype)
                   1377:        jeq     Lsavedone
                   1378: #endif
                   1379:        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
                   1380:        fsave   a0@                     | save FP state
                   1381: #ifdef M68060
                   1382:        cmpl    #FPU_68060,_C_LABEL(fputype) | is 68060?
                   1383:        jeq     Lsavctx60               | yes, goto Lsavctx60
                   1384: #endif
                   1385:        tstb    a0@                     | null state frame?
                   1386:        jeq     Lsavedone               | yes, all done
                   1387:        fmovem  fp0-fp7,a0@(FPF_REGS)   | save FP general registers
                   1388:        fmovem  fpcr/fpsr/fpi,a0@(FPF_FPCR)     | save FP control registers
                   1389:        moveq   #0,d0
                   1390:        rts
                   1391: #ifdef M68060
                   1392: Lsavctx60:
                   1393:        tstb    a0@(2)
                   1394:        jeq     Lsavedone
                   1395:        fmovem  fp0-fp7,a0@(FPF_REGS)   | save FP general registers
                   1396:        fmovem  fpcr,a0@(FPF_FPCR)      | save FP control registers
                   1397:        fmovem  fpsr,a0@(FPF_FPSR)
                   1398:        fmovem  fpi,a0@(FPF_FPI)
                   1399: #endif
                   1400: Lsavedone:
                   1401:        moveq   #0,d0                   | return 0
                   1402:        rts
                   1403:
                   1404: #if defined(M68040) || defined(M68060)
                   1405: ENTRY(suline)
                   1406:        movl    sp@(4),a0               | address to write
                   1407:        movl    _C_LABEL(curpcb),a1     | current pcb
                   1408:        movl    #Lslerr,a1@(PCB_ONFAULT) | where to return to on a fault
                   1409:        movl    sp@(8),a1               | address of line
                   1410:        movl    a1@+,d0                 | get lword
                   1411:        movsl   d0,a0@+                 | put lword
                   1412:        nop                             | sync
                   1413:        movl    a1@+,d0                 | get lword
                   1414:        movsl   d0,a0@+                 | put lword
                   1415:        nop                             | sync
                   1416:        movl    a1@+,d0                 | get lword
                   1417:        movsl   d0,a0@+                 | put lword
                   1418:        nop                             | sync
                   1419:        movl    a1@+,d0                 | get lword
                   1420:        movsl   d0,a0@+                 | put lword
                   1421:        nop                             | sync
                   1422:        moveq   #0,d0                   | indicate no fault
                   1423:        jra     Lsldone
                   1424: Lslerr:
                   1425:        moveq   #-1,d0
                   1426: Lsldone:
                   1427:        movl    _C_LABEL(curpcb),a1     | current pcb
                   1428:        clrl    a1@(PCB_ONFAULT)        | clear fault address
                   1429:        rts
                   1430: #endif
                   1431:
                   1432: /*
                   1433:  * Invalidate entire TLB.
                   1434:  */
                   1435: ASENTRY_NOPROFILE(TBIA)
                   1436:        cmpl    #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
                   1437:        jle     Ltbia040                | yes, goto Ltbia040
                   1438:        pflusha                         | flush entire TLB
                   1439:        tstl    _C_LABEL(mmutype)
                   1440:        jpl     Lmc68851a               | 68851 implies no d-cache
                   1441:        movl    #DC_CLEAR,d0
                   1442:        movc    d0,cacr                 | invalidate on-chip d-cache
                   1443: Lmc68851a:
                   1444:        rts
                   1445: Ltbia040:
                   1446:        .word   0xf518                  | pflusha
                   1447: #ifdef M68060
                   1448:        cmpl    #MMU_68060,_C_LABEL(mmutype) | is 68060?
                   1449:        jne     Ltbiano60               | no, skip
                   1450:        movc    cacr,d0
                   1451:        orl     #IC60_CABC,d0           | and clear all branch cache entries
                   1452:        movc    d0,cacr
                   1453: #endif
                   1454: Ltbiano60:
                   1455:        rts
                   1456:
                   1457:
                   1458: /*
                   1459:  * Invalidate any TLB entry for given VA (TB Invalidate Single)
                   1460:  */
                   1461: ENTRY(TBIS)
                   1462:        movl    sp@(4),a0               | get addr to flush
                   1463:        cmpl    #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060 ?
                   1464:        jle     Ltbis040                | yes, goto Ltbis040
                   1465:        tstl    _C_LABEL(mmutype)
                   1466:        jpl     Lmc68851b               | is 68851?
                   1467:        pflush  #0,#0,a0@               | flush address from both sides
                   1468:        movl    #DC_CLEAR,d0
                   1469:        movc    d0,cacr                 | invalidate on-chip data cache
                   1470:        rts
                   1471: Lmc68851b:
                   1472:        pflushs #0,#0,a0@               | flush address from both sides
                   1473:        rts
                   1474: Ltbis040:
                   1475:        moveq   #FC_SUPERD,d0           | select supervisor
                   1476:        movc    d0,dfc
                   1477:        .word   0xf508                  | pflush a0@
                   1478:        moveq   #FC_USERD,d0            | select user
                   1479:        movc    d0,dfc
                   1480:        .word   0xf508                  | pflush a0@
                   1481: #ifdef M68060
                   1482:        cmpl    #MMU_68060,_C_LABEL(mmutype) | is 68060?
                   1483:        jne     Ltbisno60               | no, skip
                   1484:        movc    cacr,d0
                   1485:        orl     #IC60_CABC,d0           | and clear all branch cache entries
                   1486:        movc    d0,cacr
                   1487: Ltbisno60:
                   1488: #endif
                   1489:        rts
                   1490:
                   1491: /*
                   1492:  * Invalidate supervisor side of TLB
                   1493:  */
                   1494: #if defined(M68060)
                   1495: ENTRY(TBIAS)
                   1496:        | 68060 cannot specify supervisor/user on pflusha, so we flush all
                   1497:        .word   0xf518                  | pflusha
                   1498:        movc    cacr,d0
                   1499:        orl     #IC60_CABC,d0           | and clear all branch cache entries
                   1500:        movc    d0,cacr
                   1501:        rts
                   1502: #endif
                   1503:
                   1504: #if defined(COMPAT_HPUX) || defined(M68060)
                   1505: /*
                   1506:  * Invalidate user side of TLB
                   1507:  */
                   1508: ENTRY(TBIAU)
                   1509:        cmpl    #MMU_68040,_C_LABEL(mmutype)
                   1510:        jle     Ltbiau040
                   1511:        tstl    _C_LABEL(mmutype)
                   1512:        jpl     Lmc68851d               | 68851?
                   1513:        pflush  #0,#4                   | flush user TLB entries
                   1514:        movl    #DC_CLEAR,d0
                   1515:        movc    d0,cacr                 | invalidate on-chip d-cache
                   1516:        rts
                   1517: Lmc68851d:
                   1518:        pflushs #0,#4                   | flush user TLB entries
                   1519:        rts
                   1520: Ltbiau040:
                   1521: | 68040 cannot specify supervisor/user on pflusha, so we flush all
                   1522:        .word   0xf518                  | pflusha
                   1523: #ifdef M68060
                   1524:        cmpl    #MMU_68060,_C_LABEL(mmutype)
                   1525:        jne     Ltbiauno60
                   1526:        movc    cacr,d0
                   1527:        orl     #IC60_CUBC,d0           | but only user branch cache entries
                   1528:        movc    d0,cacr
                   1529: Ltbiauno60:
                   1530: #endif
                   1531:        rts
                   1532: #endif /* defined(COMPAT_HPUX) || defined(M68060) */
                   1533:
                   1534: /*
                   1535:  * Invalidate instruction cache
                   1536:  */
                   1537: ENTRY(ICIA)
                   1538: #if defined(M68040) || defined(M68060)
                   1539:        cmpl    #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
                   1540:        jgt     1f                      | no, skip
                   1541:        .word   0xf498                  | cinva ic
                   1542:        rts
                   1543: 1:
                   1544: #endif
                   1545:        movl    #IC_CLEAR,d0
                   1546:        movc    d0,cacr                 | invalidate i-cache
                   1547:        rts
                   1548:
                   1549: /*
                   1550:  * Invalidate data cache.
                   1551:  *
                   1552:  * NOTE: we do not flush 68030 on-chip cache as there are no aliasing
                   1553:  * problems with DC_WA.  The only cases we have to worry about are context
                   1554:  * switch and TLB changes, both of which are handled "in-line" in resume
                   1555:  * and TBI*.
                   1556:  * Because of this, since there is no way on 68040 and 68060 to flush
                   1557:  * user and supervisor modes specfically, DCIS and DCIU are the same entry
                   1558:  * point as DCIA.
                   1559:  */
                   1560: ENTRY(DCIA)
                   1561: ENTRY(DCIS)
                   1562: ENTRY(DCIU)
                   1563: #if defined(M68040) || defined(M68060)
                   1564:        cmpl    #MMU_68040,_C_LABEL(mmutype) | 68040 or 68060?
                   1565:        jgt     1f                      | no, skip
                   1566:        .word   0xf478                  | cpusha dc
                   1567: #endif
                   1568:        rts
                   1569:
                   1570: #if defined(M68040) || defined(M68060)
                   1571: ENTRY(ICPA)
                   1572:        .word   0xf498                  | cinva ic
                   1573:        rts
                   1574: ENTRY(DCFA)
                   1575:        .word   0xf478                  | cpusha dc
                   1576:        rts
                   1577: ENTRY(ICPL)
                   1578:        movl    sp@(4),a0               | address
                   1579:        .word   0xf488                  | cinvl ic,a0@
                   1580:        rts
                   1581: ENTRY(ICPP)
                   1582:        movl    sp@(4),a0               | address
                   1583:        .word   0xf490                  | cinvp ic,a0@
                   1584:        rts
                   1585: ENTRY(DCPL)
                   1586:        movl    sp@(4),a0               | address
                   1587:        .word   0xf448                  | cinvl dc,a0@
                   1588:        rts
                   1589: ENTRY(DCPP)
                   1590:        movl    sp@(4),a0               | address
                   1591:        .word   0xf450                  | cinvp dc,a0@
                   1592:        rts
                   1593: ENTRY(DCFL)
                   1594:        movl    sp@(4),a0               | address
                   1595:        .word   0xf468                  | cpushl dc,a0@
                   1596:        rts
                   1597: ENTRY(DCFP)
                   1598:        movl    sp@(4),a0               | address
                   1599:        .word   0xf470                  | cpushp dc,a0@
                   1600:        rts
                   1601: #endif
                   1602:
                   1603: ENTRY(getsfc)
                   1604:        movc    sfc,d0
                   1605:        rts
                   1606:
                   1607: ENTRY(getdfc)
                   1608:        movc    dfc,d0
                   1609:        rts
                   1610:
                   1611: /*
                   1612:  * Load a new user segment table pointer.
                   1613:  */
                   1614: ENTRY(loadustp)
                   1615:        movl    sp@(4),d0               | new USTP
                   1616:        moveq   #PGSHIFT,d1
                   1617:        lsll    d1,d0                   | convert to addr
                   1618: #if defined(M68040) || defined(M68060)
                   1619:        cmpl    #MMU_68040,_C_LABEL(mmutype)
                   1620: #ifdef M68060
                   1621:        jlt     Lldustp060
                   1622: #endif
                   1623: #ifdef M68040
                   1624:        jeq     Lldustp040
                   1625: #endif
                   1626: #endif
                   1627:        pflusha                         | flush entire TLB
                   1628:        lea     _C_LABEL(protorp),a0    | CRP prototype
                   1629:        movl    d0,a0@(4)               | stash USTP
                   1630:        pmove   a0@,crp                 | load root pointer
                   1631:        movl    #CACHE_CLR,d0
                   1632:        movc    d0,cacr                 | invalidate cache(s)
                   1633:        rts
                   1634:
                   1635: #ifdef M68060
                   1636: Lldustp060:
                   1637:        movc    cacr,d1
                   1638:        orl     #IC60_CUBC,d1           | clear user branch cache entries
                   1639:        movc    d1,cacr
                   1640:        /* FALLTHROUGH */
                   1641: #endif
                   1642: Lldustp040:
                   1643:        .word   0xf518                  | pflusha
                   1644:        .long   0x4e7b0806              | movec d0,URP
                   1645:        rts
                   1646:
                   1647: /*
                   1648:  * Set processor priority level calls.  Most are implemented with
                   1649:  * inline asm expansions.  However, spl0 requires special handling
                   1650:  * as we need to check for our emulated software interrupts.
                   1651:  */
                   1652:
                   1653: ENTRY(spl0)
                   1654:        moveq   #0,d0
                   1655:        movw    sr,d0                   | get old SR for return
                   1656:        movw    #PSL_LOWIPL,sr          | restore new SR
                   1657:        tstb    _C_LABEL(ssir)          | software interrupt pending?
                   1658:        jeq     Lspldone                | no, all done
                   1659:        subql   #4,sp                   | make room for RTE frame
                   1660:        movl    sp@(4),sp@(2)           | position return address
                   1661:        clrw    sp@(6)                  | set frame type 0
                   1662:        movw    #PSL_LOWIPL,sp@         | and new SR
                   1663:        jra     Lgotsir                 | go handle it
                   1664: Lspldone:
                   1665:        rts
                   1666:
                   1667: /*
                   1668:  * Save and restore 68881 state.
                   1669:  * Pretty awful looking since our assembler does not
                   1670:  * recognize FP mnemonics.
                   1671:  */
                   1672: ENTRY(m68881_save)
                   1673:        movl    sp@(4),a0               | save area pointer
                   1674:        fsave   a0@                     | save state
                   1675: #ifdef M68060
                   1676:        cmpl    #FPU_68060,_C_LABEL(fputype) | is 68060?
                   1677:        jeq     Lm68060fpsave           | yes, goto Lm68060fpsave
                   1678: #endif
                   1679:        tstb    a0@                     | null state frame?
                   1680:        jeq     Lm68881sdone            | yes, all done
                   1681:        fmovem  fp0-fp7,a0@(FPF_REGS)   | save FP general registers
                   1682:        fmovem  fpcr/fpsr/fpi,a0@(FPF_FPCR)     | save FP control registers
                   1683: Lm68881sdone:
                   1684:        rts
                   1685:
                   1686: #ifdef M68060
                   1687: Lm68060fpsave:
                   1688:        tstb    a0@(2)                  | null state frame?
                   1689:        jeq     Lm68060sdone            | yes, all done
                   1690:        fmovem  fp0-fp7,a0@(FPF_REGS)   | save FP general registers
                   1691:        fmovem  fpcr,a0@(FPF_FPCR)      | save FP control registers
                   1692:        fmovem  fpsr,a0@(FPF_FPSR)
                   1693:        fmovem  fpi,a0@(FPF_FPI)
                   1694: Lm68060sdone:
                   1695:        rts
                   1696: #endif
                   1697:
                   1698: ENTRY(m68881_restore)
                   1699:        movl    sp@(4),a0               | save area pointer
                   1700: #ifdef M68060
                   1701:        cmpl    #FPU_68060,_C_LABEL(fputype) | is 68060?
                   1702:        jeq     Lm68060fprestore        | yes, goto Lm68060fprestore
                   1703: #endif
                   1704:        tstb    a0@                     | null state frame?
                   1705:        jeq     Lm68881rdone            | yes, easy
                   1706:        fmovem  a0@(FPF_FPCR),fpcr/fpsr/fpi     | restore FP control registers
                   1707:        fmovem  a0@(FPF_REGS),fp0-fp7   | restore FP general registers
                   1708: Lm68881rdone:
                   1709:        frestore a0@                    | restore state
                   1710:        rts
                   1711:
                   1712: #ifdef M68060
                   1713: Lm68060fprestore:
                   1714:        tstb    a0@(2)                  | null state frame?
                   1715:        jeq     Lm68060fprdone          | yes, easy
                   1716:        fmovem  a0@(FPF_FPCR),fpcr      | restore FP control registers
                   1717:        fmovem  a0@(FPF_FPSR),fpsr
                   1718:        fmovem  a0@(FPF_FPI),fpi
                   1719:        fmovem  a0@(FPF_REGS),fp0-fp7   | restore FP general registers
                   1720: Lm68060fprdone:
                   1721:        frestore a0@                    | restore state
                   1722:        rts
                   1723: #endif
                   1724:
                   1725: /*
                   1726:  * Handle the nitty-gritty of rebooting the machine.
                   1727:  * Basically we just turn off the MMU and jump to the appropriate ROM routine.
                   1728:  * XXX add support for rebooting -- that means looking at boothowto and doing
                   1729:  * the right thing
                   1730:  */
                   1731: ENTRY_NOPROFILE(doboot)
                   1732:        lea     _ASM_LABEL(tmpstk),sp   | physical SP in case of NMI
                   1733: #if defined(M68040) || defined(M68060)
                   1734:        cmpl    #MMU_68040,_C_LABEL(mmutype) | 68040?
                   1735:        jgt     Lbootnot040             | no, skip
                   1736:        movl    #0,d0
                   1737:        movc    d0,cacr                 | caches off
                   1738:        .long   0x4e7b0003              | movc d0,tc (turn off MMU)
                   1739:        bra     1f
                   1740: Lbootnot040:
                   1741: #endif
                   1742:        movl    #CACHE_OFF,d0
                   1743:        movc    d0,cacr                 | disable on-chip cache(s)
                   1744:        movl    #0,a7@                  | value for pmove to TC (turn off MMU)
                   1745:        pmove   a7@,tc                  | disable MMU
                   1746:
                   1747: 1:     movl    #0,d0
                   1748:        movc    d0,vbr                  | ROM VBR
                   1749:
                   1750:        /*
                   1751:         * We're going down. Make various sick attempts to reset the board.
                   1752:         */
                   1753:        RELOC(cputyp, a0)
                   1754:        movl    a0@,d0
                   1755:        cmpw    #CPU_147,d0
                   1756:        bne     not147
                   1757:        movl    #0xfffe2000,a0          | MVME147: "struct vme1reg *"
                   1758:        movw    a0@,d0
                   1759:        movl    d0,d1
                   1760:        andw    #0x0001,d1              | is VME1_SCON_SWITCH set?
                   1761:        beq     1f                      | not SCON. may not use SRESET.
                   1762:        orw     #0x0002,d0              | ok, assert VME1_SCON_SRESET
                   1763:        movw    d0,a0@
                   1764: 1:
                   1765:        movl    #0xff800000,a0          | if we get here, SRESET did not work.
                   1766:        movl    a0@(4),a0               | try jumping directly to the ROM.
                   1767:        jsr     a0@
                   1768:        | still alive! just return to the prom..
                   1769:        bra     3f
                   1770:
                   1771: not147:
                   1772:        movl    #0xfff40000,a0          | MVME16x: "struct vme2reg *"
                   1773:        movl    a0@(0x60),d0
                   1774:        movl    d0,d1
                   1775:        andl    #0x40000000,d1          | is VME2_TCTL_SCON set?
                   1776:        beq     1f                      | not SCON. may not use SRESET.
                   1777:        orl     #0x00800000,d0          | ok, assert VME2_TCTL_SRST
                   1778:        movl    d0,a0@(0x60)
                   1779: 1:
                   1780:        | lets try the local bus reset
                   1781:        movl    #0xfff40000,a0          | MVME16x: "struct vme2reg *"
                   1782:        movl    a0@(0x104),d0
                   1783:        orw     #0x00000080,d0
                   1784:        movl    d0,a0@(0x104)
                   1785:        | lets try jumping off to rom.
                   1786:        movl    #0xff800000,a0          | if we get here, SRESET did not work.
                   1787:        movl    a0@(4),a0               | try jumping directly to the ROM.
                   1788:        jsr     a0@
                   1789:        | still alive! just return to the prom..
                   1790:
                   1791: 3:     BUGCALL(MVMEPROM_EXIT)          | return to m68kbug
                   1792:        /*NOTREACHED*/
                   1793:
                   1794: #if defined(M68060) && defined(M060SP)
                   1795: GLOBAL(intemu60)
                   1796:        jra     _I_CALL_TOP+128+0x00
                   1797: GLOBAL(fpiemu60)
                   1798:        jra     _FP_CALL_TOP+128+0x30
                   1799: GLOBAL(fpdemu60)
                   1800:        jra     _FP_CALL_TOP+128+0x38
                   1801: GLOBAL(fpeaemu60)
                   1802:        jra     _FP_CALL_TOP+128+0x40
                   1803: #endif
                   1804:
                   1805:        .data
                   1806: GLOBAL(mmutype)
                   1807:        .long   MMU_68030       | default to MMU_68030
                   1808: GLOBAL(cputype)
                   1809:        .long   CPU_68030       | default to CPU_68030
                   1810: GLOBAL(fputype)
                   1811:        .long   FPU_68881       | default to 68881 FPU
                   1812: GLOBAL(protorp)
                   1813:        .long   0,0             | prototype root pointer
                   1814: GLOBAL(cold)
                   1815:        .long   1               | cold start flag
                   1816: GLOBAL(want_resched)
                   1817:        .long   0
                   1818: GLOBAL(proc0paddr)
                   1819:        .long   0               | KVA of proc0 u-area
                   1820: GLOBAL(intiobase)
                   1821:        .long   0               | KVA of base of internal IO space
                   1822: GLOBAL(intiolimit)
                   1823:        .long   0               | KVA of end of internal IO space
                   1824: GLOBAL(extiobase)
                   1825:        .long   0               | KVA of base of external IO space
                   1826:
                   1827: #include <mvme68k/mvme68k/vectors.s>

CVSweb