[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     ! 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