Annotation of 43BSDReno/sys/hp300/locore.s, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 University of Utah.
        !             3:  * Copyright (c) 1980, 1990 The Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * This code is derived from software contributed to Berkeley by
        !             7:  * the Systems Programming Group of the University of Utah Computer
        !             8:  * Science Department.
        !             9:  *
        !            10:  * Redistribution is only permitted until one year after the first shipment
        !            11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !            12:  * binary forms are permitted provided that: (1) source distributions retain
        !            13:  * this entire copyright notice and comment, and (2) distributions including
        !            14:  * binaries display the following acknowledgement:  This product includes
        !            15:  * software developed by the University of California, Berkeley and its
        !            16:  * contributors'' in the documentation or other materials provided with the
        !            17:  * distribution and in all advertising materials mentioning features or use
        !            18:  * of this software.  Neither the name of the University nor the names of
        !            19:  * its contributors may be used to endorse or promote products derived from
        !            20:  * this software without specific prior written permission.
        !            21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            24:  *
        !            25:  * from: Utah $Hdr: locore.s 1.47 89/10/08$
        !            26:  *
        !            27:  *     @(#)locore.s    7.3 (Berkeley) 6/22/90
        !            28:  */
        !            29: 
        !            30:        .text
        !            31: /*
        !            32:  * This is where we wind up if the kernel jumps to location 0.
        !            33:  * (i.e. a bogus PC)  This is known to immediately follow the vector
        !            34:  * table and is hence at 0x400 (see reset vector in vectors.s).
        !            35:  */
        !            36:        .globl  _panic
        !            37:        pea     Ljmp0panic
        !            38:        jbsr    _panic
        !            39:        /* NOTREACHED */
        !            40: Ljmp0panic:
        !            41:        .asciz  "kernel jump to zero"
        !            42:        .even
        !            43: 
        !            44: /*
        !            45:  * Do a dump.
        !            46:  * Called by auto-restart.
        !            47:  */
        !            48:        .globl  _dumpsys
        !            49:        .globl  _doadump
        !            50: _doadump:
        !            51:        jbsr    _dumpsys
        !            52:        jbsr    _doboot
        !            53:        /*NOTREACHED*/
        !            54: 
        !            55: /*
        !            56:  * Trap/interrupt vector routines
        !            57:  */ 
        !            58: 
        !            59:        .globl  _trap, _nofault, _longjmp
        !            60: _buserr:
        !            61:        tstl    _nofault                | device probe?
        !            62:        jeq     _addrerr                | no, handle as usual
        !            63:        movl    _nofault,sp@-           | yes,
        !            64:        jbsr    _longjmp                |  longjmp(nofault)
        !            65: _addrerr:
        !            66:        clrw    sp@-                    | pad SR to longword
        !            67:        moveml  #0xFFFF,sp@-            | save user registers
        !            68:        movl    usp,a0                  | save the user SP
        !            69:        movl    a0,sp@(60)              |   in the savearea
        !            70:        lea     sp@(64),a1              | grab base of HW berr frame
        !            71:        movw    a1@(12),d0              | grab SSW for fault processing
        !            72:        btst    #12,d0                  | RB set?
        !            73:        jeq     LbeX0                   | no, test RC
        !            74:        bset    #14,d0                  | yes, must set FB
        !            75:        movw    d0,a1@(12)              | for hardware too
        !            76: LbeX0:
        !            77:        btst    #13,d0                  | RC set?
        !            78:        jeq     LbeX1                   | no, skip
        !            79:        bset    #15,d0                  | yes, must set FC
        !            80:        movw    d0,a1@(12)              | for hardware too
        !            81: LbeX1:
        !            82:        btst    #8,d0                   | data fault?
        !            83:        jeq     Lbe0                    | no, check for hard cases
        !            84:        movl    a1@(18),d1              | fault address is as given in frame
        !            85:        jra     Lbe10                   | thats it
        !            86: Lbe0:
        !            87:        btst    #4,a1@(8)               | long (type B) stack frame?
        !            88:        jne     Lbe4                    | yes, go handle
        !            89:        movl    a1@(4),d1               | no, can use save PC
        !            90:        btst    #14,d0                  | FB set?
        !            91:        jeq     Lbe3                    | no, try FC
        !            92:        addql   #4,d1                   | yes, adjust address
        !            93:        jra     Lbe10                   | done
        !            94: Lbe3:
        !            95:        btst    #15,d0                  | FC set?
        !            96:        jeq     Lbe10                   | no, done
        !            97:        addql   #2,d1                   | yes, adjust address
        !            98:        jra     Lbe10                   | done
        !            99: Lbe4:
        !           100:        movl    a1@(38),d1              | long format, use stage B address
        !           101:        btst    #15,d0                  | FC set?
        !           102:        jeq     Lbe10                   | no, all done
        !           103:        subql   #2,d1                   | yes, adjust address
        !           104: Lbe10:
        !           105:        movl    d1,sp@-                 | push fault VA
        !           106:        movw    d0,sp@-                 | and SSW
        !           107:        clrw    sp@-                    |   padded to longword
        !           108:        movw    a1@(8),d0               | get frame format/vector offset
        !           109:        andw    #0x0FFF,d0              | clear out frame format
        !           110:        cmpw    #12,d0                  | address error vector?
        !           111:        jeq     Lisaerr                 | yes, go to it
        !           112: #if defined(HP330) || defined(HP360) || defined(HP370)
        !           113:        tstl    _mmutype                | HP MMU?
        !           114:        jeq     Lbehpmmu                | yes, skip
        !           115:        movl    d1,a0                   | fault address
        !           116:        .long   0xf0109e11              | ptestr #1,a0@,#7
        !           117:        .long   0xf0176200              | pmove psr,sp@
        !           118:        btst    #7,sp@                  | bus error bit set?
        !           119:        jeq     Lismerr                 | no, must be MMU fault
        !           120:        clrw    sp@                     | yes, re-clear pad word
        !           121:        jra     Lisberr                 | and process as normal bus error
        !           122: Lbehpmmu:
        !           123: #endif
        !           124: #if defined(HP320) || defined(HP350)
        !           125:        lea     _IObase+MMUSTAT,a0      | no, get addr of MMU status
        !           126:        movl    a0@,d0                  | read status
        !           127:        btst    #3,d0                   | MMU fault?
        !           128:        jeq     Lisberr                 | no, just a non-MMU bus error so skip
        !           129:        andl    #~MMU_FAULT,a0@         | yes, clear fault bits
        !           130:        movw    d0,sp@                  | pass MMU stat in upper half of code
        !           131: #endif
        !           132: Lismerr:
        !           133:        movl    #T_MMUFLT,sp@-          | show that we are an MMU fault
        !           134:        jra     Lbexit                  | and deal with it
        !           135: Lisaerr:
        !           136:        movl    #T_ADDRERR,sp@-         | mark address error
        !           137:        jra     Lbexit                  | and deal with it
        !           138: Lisberr:
        !           139:        movl    #T_BUSERR,sp@-          | mark bus error
        !           140: Lbexit:
        !           141:        jbsr    _trap                   | handle the error
        !           142:        lea     sp@(12),sp              | pop value args
        !           143:        movl    sp@(60),a0              | restore user SP
        !           144:        movl    a0,usp                  |   from save area
        !           145:        moveml  sp@+,#0x7FFF            | restore most user regs
        !           146:        addql   #4,sp                   | toss SSP
        !           147:        tstw    sp@+                    | do we need to clean up stack?
        !           148:        jeq     rei                     | no, just continue
        !           149:        btst    #7,sp@(6)               | type 9/10/11 frame?
        !           150:        jeq     rei                     | no, nothing to do
        !           151:        btst    #5,sp@(6)               | type 9?
        !           152:        jne     Lbex1                   | no, skip
        !           153:        movw    sp@,sp@(12)             | yes, push down SR
        !           154:        movl    sp@(2),sp@(14)          | and PC
        !           155:        clrw    sp@(18)                 | and mark as type 0 frame
        !           156:        lea     sp@(12),sp              | clean the excess
        !           157:        jra     rei                     | all done
        !           158: Lbex1:
        !           159:        btst    #4,sp@(6)               | type 10?
        !           160:        jne     Lbex2                   | no, skip
        !           161:        movw    sp@,sp@(24)             | yes, push down SR
        !           162:        movl    sp@(2),sp@(26)          | and PC
        !           163:        clrw    sp@(30)                 | and mark as type 0 frame
        !           164:        lea     sp@(24),sp              | clean the excess
        !           165:        jra     rei                     | all done
        !           166: Lbex2:
        !           167:        movw    sp@,sp@(84)             | type 11, push down SR
        !           168:        movl    sp@(2),sp@(86)          | and PC
        !           169:        clrw    sp@(90)                 | and mark as type 0 frame
        !           170:        lea     sp@(84),sp              | clean the excess
        !           171:        jra     rei                     | all done
        !           172: 
        !           173: _illinst:
        !           174:        clrw    sp@-
        !           175:        moveml  #0xFFFF,sp@-
        !           176:        moveq   #T_ILLINST,d0
        !           177:        jra     _fault
        !           178: 
        !           179: _zerodiv:
        !           180:        clrw    sp@-
        !           181:        moveml  #0xFFFF,sp@-
        !           182:        moveq   #T_ZERODIV,d0
        !           183:        jra     _fault
        !           184: 
        !           185: _chkinst:
        !           186:        clrw    sp@-
        !           187:        moveml  #0xFFFF,sp@-
        !           188:        moveq   #T_CHKINST,d0
        !           189:        jra     _fault
        !           190: 
        !           191: _trapvinst:
        !           192:        clrw    sp@-
        !           193:        moveml  #0xFFFF,sp@-
        !           194:        moveq   #T_TRAPVINST,d0
        !           195:        jra     _fault
        !           196: 
        !           197: _privinst:
        !           198:        clrw    sp@-
        !           199:        moveml  #0xFFFF,sp@-
        !           200:        moveq   #T_PRIVINST,d0
        !           201:        jra     _fault
        !           202: 
        !           203: _coperr:
        !           204:        clrw    sp@-
        !           205:        moveml  #0xFFFF,sp@-
        !           206:        moveq   #T_COPERR,d0
        !           207:        jra     _fault
        !           208: 
        !           209: _fmterr:
        !           210:        clrw    sp@-
        !           211:        moveml  #0xFFFF,sp@-
        !           212:        moveq   #T_FMTERR,d0
        !           213:        jra     _fault
        !           214: 
        !           215: _fptrap:
        !           216: #ifdef FPCOPROC
        !           217:        clrw    sp@-            | pad SR to longword
        !           218:        moveml  #0xFFFF,sp@-    | save user registers
        !           219:        movl    usp,a0          | and save
        !           220:        movl    a0,sp@(60)      |   the user stack pointer
        !           221:        clrl    sp@-            | no VA arg
        !           222:        lea     _u+PCB_FPCTX,a0 | address of FP savearea
        !           223:        .word   0xf310          | fsave a0@
        !           224:        tstb    a0@             | null state frame?
        !           225:        jeq     Lfptnull        | yes, safe
        !           226:        clrw    d0              | no, need to tweak BIU
        !           227:        movb    a0@(1),d0       | get frame size
        !           228:        bset    #3,a0@(0,d0:w)  | set exc_pend bit of BIU
        !           229: Lfptnull:
        !           230:        .word   0xf227,0xa800   | fmovem fpsr,sp@- (code arg)
        !           231:        .word   0xf350          | frestore a0@
        !           232:        movl    #T_FPERR,sp@-   | push type arg
        !           233:        jbsr    _trap           | call trap
        !           234:        lea     sp@(12),sp      | pop value args
        !           235:        movl    sp@(60),a0      | restore
        !           236:        movl    a0,usp          |   user SP
        !           237:        moveml  sp@+,#0x7FFF    | and remaining user registers
        !           238:        addql   #6,sp           | pop SSP and align word
        !           239:        jra     rei             | all done
        !           240: #else
        !           241:        jra     _badtrap        | treat as an unexpected trap
        !           242: #endif
        !           243: 
        !           244:        .globl  _fault
        !           245: _fault:
        !           246:        movl    usp,a0          | get and save
        !           247:        movl    a0,sp@(60)      |   the user stack pointer
        !           248:        clrl    sp@-            | no VA arg
        !           249:        clrl    sp@-            | or code arg
        !           250:        movl    d0,sp@-         | push trap type
        !           251:        jbsr    _trap           | handle trap
        !           252:        lea     sp@(12),sp      | pop value args
        !           253:        movl    sp@(60),a0      | restore
        !           254:        movl    a0,usp          |   user SP
        !           255:        moveml  sp@+,#0x7FFF    | restore most user regs
        !           256:        addql   #6,sp           | pop SP and pad word
        !           257:        jra     rei             | all done
        !           258: 
        !           259:        .globl  _straytrap
        !           260: _badtrap:
        !           261:        clrw    sp@-
        !           262:        moveml  #0xC0C0,sp@-
        !           263:        movw    sp@(24),sp@-
        !           264:        clrw    sp@-
        !           265:        jbsr    _straytrap
        !           266:        addql   #4,sp
        !           267:        moveml  sp@+,#0x0303
        !           268:        addql   #2,sp
        !           269:        jra     rei
        !           270: 
        !           271:        .globl  _syscall
        !           272: _trap0:
        !           273:        clrw    sp@-                    | pad SR to longword
        !           274:        moveml  #0xFFFF,sp@-            | save user registers
        !           275:        movl    usp,a0                  | save the user SP
        !           276:        movl    a0,sp@(60)              |   in the savearea
        !           277:        movl    d0,sp@-                 | push syscall number
        !           278:        jbsr    _syscall                | handle it
        !           279:        addql   #4,sp                   | pop syscall arg
        !           280:        movl    sp@(60),a0              | grab and restore
        !           281:        movl    a0,usp                  |   user SP
        !           282:        moveml  sp@+,#0x7FFF            | restore most registers
        !           283:        addql   #6,sp                   | pop SSP and align word
        !           284:        jra     rei                     | all done
        !           285: 
        !           286: /*
        !           287:  * Routines for traps 1 and 2.  The meaning of the two traps depends
        !           288:  * on whether we are an HPUX compatible process or a native 4.3 process.
        !           289:  * Our native 4.3 implementation uses trap 1 as sigreturn() and trap 2
        !           290:  * as a breakpoint trap.  HPUX uses trap 1 for a breakpoint, so we have
        !           291:  * to make adjustments so that trap 2 is used for sigreturn.
        !           292:  */
        !           293: _trap1:
        !           294:        btst    #PCB_TRCB,_u+PCB_FLAGS+1| being traced by an HPUX process?
        !           295:        jeq     sigreturn               | no, trap1 is sigreturn
        !           296:        jra     _trace                  | yes, trap1 is breakpoint
        !           297: 
        !           298: _trap2:
        !           299:        btst    #PCB_TRCB,_u+PCB_FLAGS+1| being traced by an HPUX process?
        !           300:        jeq     _trace                  | no, trap2 is breakpoint
        !           301:        jra     sigreturn               | yes, trap2 is sigreturn
        !           302: 
        !           303: /*
        !           304:  * Trap 15 is used for:
        !           305:  *     - KGDB traps
        !           306:  *     - trace traps for SUN binaries (not fully supported yet)
        !           307:  * We just pass it on and let trap() sort it all out
        !           308:  */
        !           309: _trap15:
        !           310:        clrw    sp@-
        !           311:        moveml  #0xFFFF,sp@-
        !           312:        moveq   #T_TRAP15,d0
        !           313:        jra     _fault
        !           314: 
        !           315: /*
        !           316:  * Hit a breakpoint (trap 1 or 2) instruction.
        !           317:  * Push the code and treat as a normal fault.
        !           318:  */
        !           319: _trace:
        !           320:        clrw    sp@-
        !           321:        moveml  #0xFFFF,sp@-
        !           322:        moveq   #T_TRACE,d0
        !           323:        jra     _fault
        !           324: 
        !           325: /*
        !           326:  * The sigreturn() syscall comes here.  It requires special handling
        !           327:  * because we must open a hole in the stack to fill in the (possibly much
        !           328:  * larger) original stack frame.
        !           329:  */
        !           330: sigreturn:
        !           331:        lea     sp@(-84),sp             | leave enough space for largest frame
        !           332:        movl    sp@(84),sp@             | move up current 8 byte frame
        !           333:        movl    sp@(88),sp@(4)
        !           334:        movw    #0xFFFF,sp@-            | default: must clean stack
        !           335:        moveml  #0xFFFF,sp@-            | save user registers
        !           336:        movl    usp,a0                  | save the user SP
        !           337:        movl    a0,sp@(60)              |   in the savearea
        !           338:        movl    #SYS_sigreturn,sp@-     | push syscall number
        !           339:        jbsr    _syscall                | handle it
        !           340:        addql   #4,sp                   | pop syscall#
        !           341:        movl    sp@(60),a0              | grab and restore
        !           342:        movl    a0,usp                  |   user SP
        !           343:        lea     sp@(64),a1              | pointer to HW frame
        !           344:        tstw    a1@+                    | do we need to clean up stack?
        !           345:        jeq     Lsigr1                  | no, just continue
        !           346:        movb    a1@(6),d0               | grab format byte
        !           347:        lsrb    #4,d0                   | get rid of excess
        !           348:        cmpb    #10,d0                  | type 10 frame?
        !           349:        jne     Lsigr2                  | no, continue
        !           350:        movw    #32,d1                  | yes, frame size is 32 bytes
        !           351:        jra     Lsigrcp                 | go to it
        !           352: Lsigr2:
        !           353:        cmpb    #9,d0                   | type 9?
        !           354:        jne     Lsigr3                  | no, continue
        !           355:        movw    #20,d1                  | yes, frame size is 20 bytes
        !           356:        jra     Lsigrcp                 | go to it
        !           357: Lsigr3:
        !           358:        cmpb    #2,d0                   | type 2?
        !           359:        jne     Lsigr4                  | no, continue
        !           360:        movw    #12,d1                  | yes, frame size is 12 bytes
        !           361:        jra     Lsigrcp                 | go to it
        !           362: Lsigr4:
        !           363:        movw    #8,d1                   | must be type 0/1, size is 8 bytes
        !           364: Lsigrcp:
        !           365:        lea     a1@(92),a0              | destination
        !           366:        addw    d1,a1                   | source
        !           367:        lsrw    #1,d1                   | convert to word count
        !           368:        subqw   #1,d1                   | minus 1 for dbf
        !           369: Lsigrlp:
        !           370:        movw    a1@-,a0@-               | copy a word
        !           371:        dbf     d1,Lsigrlp              | continue
        !           372:        movl    a0,a1                   | new HW frame base
        !           373: Lsigr1:
        !           374:        movl    a1,sp@(60)              | new SP value
        !           375:        moveml  sp@+,#0x7FFF            | restore user registers
        !           376:        movl    sp@,sp                  | and our SP
        !           377:        jra     rei                     | all done
        !           378: 
        !           379: /*
        !           380:  * Interrupt handlers.
        !           381:  * All DIO device interrupts are auto-vectored.  Most can be configured
        !           382:  * to interrupt in the range IPL3 to IPL5.  Here are our assignments:
        !           383:  *
        !           384:  *     Level 0:        Spurious: ignored.
        !           385:  *     Level 1:        HIL
        !           386:  *     Level 2:
        !           387:  *     Level 3:        Internal HP-IB
        !           388:  *     Level 4:        "Fast" HP-IBs, SCSI
        !           389:  *     Level 5:        DMA, Ethernet, Built-in RS232
        !           390:  *     Level 6:        Clock
        !           391:  *     Level 7:        Non-maskable: parity errors, RESET key
        !           392:  */
        !           393:        .globl  _hilint, _intrhand, _hardclock, _nmihand
        !           394: 
        !           395: _spurintr:
        !           396:        addql   #1,_intrcnt+0
        !           397:        addql   #1,_cnt+V_INTR
        !           398:        jra     rei
        !           399: 
        !           400: _lev1intr:
        !           401:        addql   #1,_intrcnt+4
        !           402:        clrw    sp@-
        !           403:        moveml  #0xC0C0,sp@-
        !           404:        jbsr    _hilint
        !           405:        moveml  sp@+,#0x0303
        !           406:        addql   #2,sp
        !           407:        addql   #1,_cnt+V_INTR
        !           408:        jra     rei
        !           409: 
        !           410: /* check for DMA first to reduce overhead */
        !           411: _lev5intr:
        !           412:        clrw    sp@-
        !           413:        moveml  #0xC0C0,sp@-
        !           414:        jbsr    _dmaintr
        !           415:        tstl    d0
        !           416:        jeq     Lnotdma
        !           417:        addql   #1,_intrcnt+24
        !           418:        moveml  sp@+,#0x0303
        !           419:        addql   #2,sp
        !           420:        addql   #1,_cnt+V_INTR
        !           421:        jra     rei
        !           422: 
        !           423: _lev2intr:
        !           424: _lev3intr:
        !           425: _lev4intr:
        !           426:        clrw    sp@-
        !           427:        moveml  #0xC0C0,sp@-
        !           428: Lnotdma:
        !           429:        lea     _intrcnt,a0
        !           430:        movw    sp@(24),d0              | use vector offset
        !           431:        andw    #0xfff,d0               |   sans frame type
        !           432:        addql   #1,a0@(-0x60,d0:w)      |     to increment apropos counter
        !           433:        movw    sr,sp@-                 | push current SR value
        !           434:        clrw    sp@-                    |    padded to longword
        !           435:        jbsr    _intrhand               | handle interrupt
        !           436:        addql   #4,sp                   | pop SR
        !           437:        moveml  sp@+,#0x0303
        !           438:        addql   #2,sp
        !           439:        addql   #1,_cnt+V_INTR
        !           440:        jra     rei
        !           441: 
        !           442: _lev6intr:
        !           443:        clrw    sp@-
        !           444:        moveml  #0xC0C0,sp@-
        !           445: #ifdef DEBUG
        !           446:        .globl  _panicstr, _regdump, _panic
        !           447:        tstl    timebomb                | set to go off?
        !           448:        jeq     Lnobomb                 | no, skip it
        !           449:        subql   #1,timebomb             | decrement
        !           450:        jne     Lnobomb                 | not ready to go off
        !           451:        moveml  sp@+,#0x0303            | temporarily restore regs
        !           452:        jra     Luseours                | go die
        !           453: Lnobomb:
        !           454:        cmpl    #_u+NBPG+NBPG,sp        | our we still in stack page?
        !           455:        jcc     Lstackok                | yes, continue normally
        !           456:        tstl    _panicstr               | have we paniced?
        !           457:        jne     Lstackok                | yes, do not re-panic
        !           458:        moveml  sp@+,#0x0303            | no, temporarily restore regs
        !           459:        cmpl    #_u+NBPG+0x400,sp       | our we safely in redzone?
        !           460:        jcc     Luseours                | yes, panic with this stack
        !           461:        lea     tmpstk,sp               | no, switch to tmpstk
        !           462: Luseours:
        !           463:        moveml  #0xFFFF,sp@-            | push all registers
        !           464:        movl    sp,a0                   | remember this spot
        !           465:        movl    #256,sp@-               | longword count
        !           466:        movl    a0,sp@-                 | and reg pointer
        !           467:        jbsr    _regdump                | dump core
        !           468:        addql   #8,sp                   | pop params
        !           469:        movl    #Lstkrip,sp@-           | push panic message
        !           470:        jbsr    _panic                  | ES and D
        !           471: Lstkrip:
        !           472:        .asciz  "k-stack overflow"
        !           473:        .even
        !           474: Lstackok:
        !           475: #endif
        !           476:        movb    _IObase+CLKSR,d0        | read clock status
        !           477: #ifdef PROFTIMER
        !           478:        .globl  _profon
        !           479:        tstb    _profon                 | profile clock on?
        !           480:        jeq     Ltimer1                 | no, then must be timer1 interrupt
        !           481:        btst    #2,d0                   | timer3 interrupt?
        !           482:        jeq     Ltimer1                 | no, must be timer1
        !           483:        movb    _IObase+CLKMSB3,d1      | clear timer3 interrupt
        !           484:        lea     sp@(16),a1              | get pointer to PS
        !           485: #ifdef GPROF
        !           486:        .globl  _profclock
        !           487:        movl    d0,sp@-                 | save status so jsr will not clobber
        !           488:        movl    a1@,sp@-                | push padded PS
        !           489:        movl    a1@(4),sp@-             | push PC
        !           490:        jbsr    _profclock              | profclock(pc, ps)
        !           491:        addql   #8,sp                   | pop params
        !           492: #else
        !           493:        btst    #5,a1@(2)               | saved PS in user mode?
        !           494:        jne     Lttimer1                | no, go check timer1
        !           495:        tstl    _u+U_PROFSCALE          | process being profiled?
        !           496:        jeq     Lttimer1                | no, go check timer1
        !           497:        movl    d0,sp@-                 | save status so jsr will not clobber
        !           498:        movl    #1,sp@-
        !           499:        movl    #_u+U_PROF,sp@-
        !           500:        movl    a1@(4),sp@-
        !           501:        jbsr    _addupc                 | addupc(pc, &u.u_prof, 1)
        !           502:        lea     sp@(12),sp              | pop params
        !           503: #endif
        !           504:        addql   #1,_intrcnt+32          | add another profile clock interrupt
        !           505:        movl    sp@+,d0                 | get saved clock status
        !           506: Lttimer1:
        !           507:        btst    #0,d0                   | timer1 interrupt?
        !           508:        jeq     Ltimend                 | no, check state of kernel profiling
        !           509: Ltimer1:
        !           510: #endif
        !           511:        movb    _IObase+CLKMSB1,d1      | clear timer1 interrupt
        !           512:        lea     sp@(16),a1              | get pointer to PS
        !           513:        movl    a1@,sp@-                | push padded PS
        !           514:        movl    a1@(4),sp@-             | push PC
        !           515:        jbsr    _hardclock              | call generic clock int routine
        !           516:        addql   #8,sp                   | pop params
        !           517:        addql   #1,_intrcnt+28          | add another system clock interrupt
        !           518: #ifdef PROFTIMER
        !           519: Ltimend:
        !           520: #ifdef GPROF
        !           521:        .globl  _profiling, _startprofclock
        !           522:        tstl    _profiling              | kernel profiling desired?
        !           523:        jne     Ltimdone                | no, all done
        !           524:        bset    #7,_profon              | mark continuous timing
        !           525:        jne     Ltimdone                | was already enabled, all done
        !           526:        jbsr    _startprofclock         | else turn it on
        !           527: Ltimdone:
        !           528: #endif
        !           529: #endif
        !           530:        moveml  sp@+,#0x0303            | restore scratch regs
        !           531:        addql   #2,sp                   | pop pad word
        !           532:        addql   #1,_cnt+V_INTR          | chalk up another interrupt
        !           533:        jra     rei                     | all done
        !           534: 
        !           535: _lev7intr:
        !           536: #ifdef PROFTIMER
        !           537:        addql   #1,_intrcnt+36
        !           538: #else
        !           539:        addql   #1,_intrcnt+32
        !           540: #endif
        !           541:        clrw    sp@-                    | pad SR to longword
        !           542:        moveml  #0xFFFF,sp@-            | save registers
        !           543:        movl    usp,a0                  | and save
        !           544:        movl    a0,sp@(60)              |   the user stack pointer
        !           545:        jbsr    _nmihand                | call handler
        !           546:        movl    sp@(60),a0              | restore
        !           547:        movl    a0,usp                  |   user SP
        !           548:        moveml  sp@+,#0x7FFF            | and remaining registers
        !           549:        addql   #6,sp                   | pop SSP and align word
        !           550:        jra     rei                     | all done
        !           551: 
        !           552: /*
        !           553:  * Emulation of VAX REI instruction.
        !           554:  *
        !           555:  * This code deals with checking for and servicing ASTs
        !           556:  * (profiling, scheduling) and software interrupts (network, softclock).
        !           557:  * We check for ASTs first, just like the VAX.  To avoid excess overhead
        !           558:  * the T_ASTFLT handling code will also check for software interrupts so we
        !           559:  * do not have to do it here.
        !           560:  *
        !           561:  * This code is complicated by the fact that sendsig may have been called
        !           562:  * necessitating a stack cleanup.  A cleanup should only be needed at this
        !           563:  * point for coprocessor mid-instruction frames (type 9), but we also test
        !           564:  * for bus error frames (type 10 and 11).
        !           565:  */
        !           566:        .comm   _ssir,1
        !           567: rei:
        !           568: #ifdef DEBUG
        !           569:        tstl    _panicstr               | have we paniced?
        !           570:        jne     Ldorte                  | yes, do not make matters worse
        !           571: #endif
        !           572:        btst    #PCB_ASTB,_u+PCB_FLAGS+1| AST pending?
        !           573:        jeq     Lchksir                 | no, go check for SIR
        !           574:        btst    #5,sp@                  | yes, are we returning to user mode?
        !           575:        jne     Lchksir                 | no, go check for SIR
        !           576:        clrw    sp@-                    | pad SR to longword
        !           577:        moveml  #0xFFFF,sp@-            | save all registers
        !           578:        movl    usp,a1                  | including
        !           579:        movl    a1,sp@(60)              |    the users SP
        !           580:        clrl    sp@-                    | VA == none
        !           581:        clrl    sp@-                    | code == none
        !           582:        movl    #T_ASTFLT,sp@-          | type == async system trap
        !           583:        jbsr    _trap                   | go handle it
        !           584:        lea     sp@(12),sp              | pop value args
        !           585:        movl    sp@(60),a0              | restore
        !           586:        movl    a0,usp                  |   user SP
        !           587:        moveml  sp@+,#0x7FFF            | and all remaining registers
        !           588:        addql   #4,sp                   | toss SSP
        !           589:        tstw    sp@+                    | do we need to clean up stack?
        !           590:        jeq     Ldorte                  | no, just continue
        !           591:        btst    #7,sp@(6)               | type 9/10/11 frame?
        !           592:        jeq     Ldorte                  | no, nothing to do
        !           593:        btst    #5,sp@(6)               | type 9?
        !           594:        jne     Last1                   | no, skip
        !           595:        movw    sp@,sp@(12)             | yes, push down SR
        !           596:        movl    sp@(2),sp@(14)          | and PC
        !           597:        clrw    sp@(18)                 | and mark as type 0 frame
        !           598:        lea     sp@(12),sp              | clean the excess
        !           599:        jra     Ldorte                  | all done
        !           600: Last1:
        !           601:        btst    #4,sp@(6)               | type 10?
        !           602:        jne     Last2                   | no, skip
        !           603:        movw    sp@,sp@(24)             | yes, push down SR
        !           604:        movl    sp@(2),sp@(26)          | and PC
        !           605:        clrw    sp@(30)                 | and mark as type 0 frame
        !           606:        lea     sp@(24),sp              | clean the excess
        !           607:        jra     Ldorte                  | all done
        !           608: Last2:
        !           609:        movw    sp@,sp@(84)             | type 11, push down SR
        !           610:        movl    sp@(2),sp@(86)          | and PC
        !           611:        clrw    sp@(90)                 | and mark as type 0 frame
        !           612:        lea     sp@(84),sp              | clean the excess
        !           613:        jra     Ldorte                  | all done
        !           614: Lchksir:
        !           615:        tstb    _ssir                   | SIR pending?
        !           616:        jeq     Ldorte                  | no, all done
        !           617:        movl    d0,sp@-                 | need a scratch register
        !           618:        movw    sp@(4),d0               | get SR
        !           619:        andw    #PSL_IPL7,d0            | mask all but IPL
        !           620:        jne     Lnosir                  | came from interrupt, no can do
        !           621:        movl    sp@+,d0                 | restore scratch register
        !           622: Lgotsir:
        !           623:        movw    #SPL1,sr                | prevent others from servicing int
        !           624:        tstb    _ssir                   | too late?
        !           625:        jeq     Ldorte                  | yes, oh well...
        !           626:        clrw    sp@-                    | pad SR to longword
        !           627:        moveml  #0xFFFF,sp@-            | save all registers
        !           628:        movl    usp,a1                  | including
        !           629:        movl    a1,sp@(60)              |    the users SP
        !           630:        clrl    sp@-                    | VA == none
        !           631:        clrl    sp@-                    | code == none
        !           632:        movl    #T_SSIR,sp@-            | type == software interrupt
        !           633:        jbsr    _trap                   | go handle it
        !           634:        lea     sp@(12),sp              | pop value args
        !           635:        movl    sp@(60),a0              | restore
        !           636:        movl    a0,usp                  |   user SP
        !           637:        moveml  sp@+,#0x7FFF            | and all remaining registers
        !           638:        addql   #6,sp                   | pop SSP and align word
        !           639:        rte
        !           640: Lnosir:
        !           641:        movl    sp@+,d0                 | restore scratch register
        !           642: Ldorte:
        !           643:        rte                             | real return
        !           644: 
        !           645: /*
        !           646:  * System page table
        !           647:  * Mbmap, Usrptmap, and Usriomap are enlarged by CLSIZE entries
        !           648:  * as they are managed by resource maps starting with index 1 or CLSIZE.
        !           649:  * Usrptmap is allocated last so that we can also use the pad space up
        !           650:  * to eSysmap. (no point in wasting it!)
        !           651:  */ 
        !           652: #define        vaddr(x)        x-_Sysmap/4*NBPG
        !           653: #define SYSMAP(mname,vname,size) \
        !           654:        .globl  _/**/mname,_/**/vname; \
        !           655: _/**/mname: \
        !           656:        .space  size*4; \
        !           657:        _/**/vname = vaddr(_/**/mname)
        !           658: #define        ADDMAP(npte)    .space  npte*4
        !           659: 
        !           660:        .data
        !           661:        SYSMAP(Sysmap   ,Sysbase        ,SYSPTSIZE      )
        !           662:        SYSMAP(Forkmap  ,forkutl        ,UPAGES         )
        !           663:        SYSMAP(Xswapmap ,xswaputl       ,UPAGES         )
        !           664:        SYSMAP(Xswap2map,xswap2utl      ,UPAGES         )
        !           665:        SYSMAP(Swapmap  ,swaputl        ,UPAGES         )
        !           666:        SYSMAP(Pushmap  ,pushutl        ,UPAGES         )
        !           667:        SYSMAP(Vfmap    ,vfutl          ,UPAGES         )
        !           668:        SYSMAP(CMAP1    ,CADDR1         ,1              )
        !           669:        SYSMAP(CMAP2    ,CADDR2         ,1              )
        !           670:        SYSMAP(mmap     ,vmmap          ,1              )
        !           671:        SYSMAP(msgbufmap,msgbuf         ,MSGBUFPTECNT   )
        !           672:        SYSMAP(Umap     ,u              ,UPAGES         )
        !           673:        SYSMAP(Mbmap    ,mbutl          ,NMBCLUSTERS*MCLBYTES/NBPG+CLSIZE )
        !           674:        /*
        !           675:         * This is the map used by the kernel memory allocator.
        !           676:         * It is expanded as necessary by the special features
        !           677:         * that use it.
        !           678:         *
        !           679:         * XXX: NEED way to compute kmem size from maxusers,
        !           680:         * device complement
        !           681:         */
        !           682:        SYSMAP(kmempt   ,kmembase       ,NKMEMCLUSTERS*CLSIZE )
        !           683: #ifdef SYSVSHM
        !           684:                                ADDMAP( SHMMAXPGS       )
        !           685: #endif
        !           686: #ifdef GPROF
        !           687:                                ADDMAP( 768*1024/NBPG   )
        !           688: #endif
        !           689:        SYSMAP(ekmempt  ,kmemlimit      ,0              )
        !           690:        SYSMAP(IOmap    ,IObase         ,IOMAPSIZE      )   /* map DIO space */
        !           691:        SYSMAP(eIOmap   ,IOlimit        ,0              )
        !           692: #if defined(HP360) || defined(HP370)
        !           693:        SYSMAP(Grfmap   ,grfregs        ,1024           )   /* 340 @ SC132 */
        !           694: #endif
        !           695:        SYSMAP(Usriomap ,usrio          ,USRIOSIZE+CLSIZE ) /* for PHYSIO */
        !           696:        SYSMAP(Usrptmap ,usrpt          ,USRPTSIZE+CLSIZE )
        !           697:        . = . + NBPG - 1 & -NBPG        /* align to page boundry */
        !           698: eSysmap:
        !           699: 
        !           700: /*
        !           701:  * System segment table.  1 page is sufficient to map the entire
        !           702:  * 4Gb address space. (funny how that works out...)
        !           703:  */
        !           704:        .globl  _Sysseg
        !           705: _Sysseg:
        !           706:        .space  NBPG
        !           707: eSysseg:
        !           708: 
        !           709:        .globl  _Syssize, _Usrptsize
        !           710: _Syssize       = eSysmap-_Sysmap/4
        !           711: _Usrptsize     = eSysmap-_Usrptmap/4
        !           712: 
        !           713: /*
        !           714:  * Initialization
        !           715:  *
        !           716:  * A5 contains physical load point from boot
        !           717:  * VBR contains zero from ROM.  Exceptions will continue to vector
        !           718:  * through ROM until MMU is turned on at which time they will vector
        !           719:  * through our table (vectors.s).
        !           720:  */
        !           721:        .comm   _lowram,4
        !           722: 
        !           723:        .text
        !           724:        .globl  _edata
        !           725:        .globl  _etext,_end
        !           726:        .globl  start
        !           727: start:
        !           728:        movw    #PSL_HIGHIPL,sr         | no interrupts
        !           729:        lea     _lowram,a0
        !           730:        addl    a5,a0
        !           731:        movl    a5,a0@                  | store start of physical memory
        !           732:        movl    #CACHE_OFF,d0
        !           733:        movc    d0,cacr                 | clear and disable on-chip cache(s)
        !           734: 
        !           735: /* determine our CPU/MMU combo - check for all regardless of kernel config */
        !           736:        movl    #0x200,d0               | data freeze bit
        !           737:        movc    d0,cacr                 |   only exists on 68030
        !           738:        movc    cacr,d0                 | read it back
        !           739:        tstl    d0                      | zero?
        !           740:        jeq     Lis68020                | yes, we have 68020
        !           741:        lea     _mmutype,a0             | no, we have 68030
        !           742:        addl    a5,a0
        !           743:        movl    #-1,a0@                 | set to reflect 68030 PMMU
        !           744:        lea     _machineid,a0
        !           745:        addl    a5,a0
        !           746:        movl    #0x80,IOBASE+MMUCMD     | set magic cookie
        !           747:        movl    IOBASE+MMUCMD,d0        | read it back
        !           748:        btst    #7,d0                   | cookie still on?
        !           749:        jeq     Lnot370                 | no, 360 or 375
        !           750:        movl    #0,IOBASE+MMUCMD        | clear magic cookie
        !           751:        movl    IOBASE+MMUCMD,d0        | read it back
        !           752:        btst    #7,d0                   | still on?
        !           753:        jeq     Lisa370                 | no, must be a 370
        !           754:        movl    #5,a0@                  | yes, must be a 340
        !           755:        jra     Lstart1
        !           756: Lnot370:
        !           757:        movl    #3,a0@                  | type is at least a 360
        !           758:        movl    #0,IOBASE+MMUCMD        | clear magic cookie2
        !           759:        movl    IOBASE+MMUCMD,d0        | read it back
        !           760:        btst    #16,d0                  | still on?
        !           761:        jeq     Lstart1                 | no, must be a 360
        !           762:        movl    #6,a0@                  | yes, must be a 345/375
        !           763:        jra     Lhaspac
        !           764: Lisa370:
        !           765:        movl    #4,a0@                  | set to 370
        !           766: Lhaspac:
        !           767:        lea     _ectype,a0
        !           768:        addl    a5,a0
        !           769:        movl    #-1,a0@                 | also has a physical address cache
        !           770:        jra     Lstart1
        !           771: Lis68020:
        !           772:        movl    #1,IOBASE+MMUCMD        | a 68020, write HP MMU location
        !           773:        movl    IOBASE+MMUCMD,d0        | read it back
        !           774:        btst    #0,d0                   | non-zero?
        !           775:        jne     Lishpmmu                | yes, we have HP MMU
        !           776:        lea     _mmutype,a0
        !           777:        addl    a5,a0
        !           778:        movl    #1,a0@                  | no, we have PMMU
        !           779:        lea     _machineid,a0
        !           780:        addl    a5,a0
        !           781:        movl    #1,a0@                  | and 330 CPU
        !           782:        jra     Lstart1
        !           783: Lishpmmu:
        !           784:        lea     _ectype,a0              | 320 or 350
        !           785:        addl    a5,a0
        !           786:        movl    #1,a0@                  | both have a virtual address cache
        !           787:        movl    #0x80,IOBASE+MMUCMD     | set magic cookie
        !           788:        movl    IOBASE+MMUCMD,d0        | read it back
        !           789:        btst    #7,d0                   | cookie still on?
        !           790:        jeq     Lstart1                 | no, just a 320
        !           791:        lea     _machineid,a0
        !           792:        addl    a5,a0
        !           793:        movl    #2,a0@                  | yes, a 350
        !           794: 
        !           795: Lstart1:
        !           796:        movl    #0,IOBASE+MMUCMD        | clear out MMU again
        !           797: /* initialize source/destination control registers for movs */
        !           798:        moveq   #FC_USERD,d0            | user space
        !           799:        movc    d0,sfc                  |   as source
        !           800:        movc    d0,dfc                  |   and destination of transfers
        !           801: /* initialize proc. 0 (system) page table */
        !           802:        movl    #_Sysmap,a0             | SYSPT map addr
        !           803:        addl    a5,a0                   | relocate
        !           804: /* text pages are read-only */
        !           805:        clrl    d0                      | assume load at VA 0
        !           806:        movl    a5,d1                   | get load PA
        !           807:        andl    #PG_FRAME,d1            | convert to a page frame
        !           808:        orl     #PG_RO+PG_V,d1          | mark as valid and RO
        !           809:        movl    #_etext,a1              | go til end of text
        !           810: Lispt1:
        !           811:        movl    d1,a0@+                 | load PTE
        !           812:        addl    #NBPG,d1                | increment page frame number
        !           813:        addl    #NBPG,d0                | and address counter
        !           814:        cmpl    a1,d0                   | done yet?
        !           815:        jcs     Lispt1                  | no, keep going
        !           816: /* data and bss are read/write */
        !           817:        andl    #PG_FRAME,d1            | mask out old prot bits
        !           818:        orl     #PG_RW+PG_V,d1          | mark as valid and RW
        !           819:        movl    #_end,a1                | go til end of data/bss
        !           820: Lispt2:
        !           821:        movl    d1,a0@+                 | load PTE
        !           822:        addl    #NBPG,d1                | increment page frame number
        !           823:        addl    #NBPG,d0                | and address counter
        !           824:        cmpl    a1,d0                   | done yet?
        !           825:        jcs     Lispt2                  | no, keep going
        !           826: /* invalidate remainder of system page table */
        !           827:        movl    #eSysmap,a1             | end of map
        !           828:        addl    a5,a1                   | relocate
        !           829: Lispt3:
        !           830:        movl    #PG_NV,a0@+             | invalidate PTE
        !           831:        cmpl    a1,a0                   | done yet?
        !           832:        jcs     Lispt3                  | no, keep going
        !           833: /* go back and initialize IOmap */
        !           834:        movl    #_IOmap,a0              | IO map addr
        !           835:        addl    a5,a0                   | relocate
        !           836:        movl    #_eIOmap,a1             | end of map
        !           837:        addl    a5,a1                   | relocate
        !           838:        movl    #IOBASE,d1              | physical IO base
        !           839:        andl    #PG_FRAME,d1            | mask to frame number
        !           840:        orl     #PG_RW+PG_CI+PG_V,d1    | mark valid, RW and CI
        !           841: Lispt4:
        !           842:        movl    d1,a0@+                 | load PTE
        !           843:        addl    #NBPG,d1                | increment page frame number
        !           844:        cmpl    a1,a0                   | done yet?
        !           845:        jcs     Lispt4                  | no, keep going
        !           846: /* initialize proc. 0 (system) segment table */
        !           847:        movl    #_Sysseg,a0             | segment table
        !           848:        addl    a5,a0                   | relocate
        !           849:        movl    #eSysmap-_Sysmap/NBPG*4,a1 | bytes of PTEs for Sysmap
        !           850:        addl    a0,a1                   | make an end count
        !           851:        movl    #_Sysmap,d1             | system PT addr
        !           852:        addl    a5,d1                   | relocate
        !           853:        andl    #SG_FRAME,d1            | mask to frame number
        !           854:        orl     #SG_RW+SG_V,d1          | mark as RW and valid
        !           855: Lispt5:
        !           856:        movl    d1,a0@+                 | load STE
        !           857:        addl    #NBPG,d1                | increment page frame number
        !           858:        cmpl    a1,a0                   | done yet?
        !           859:        jcs     Lispt5                  | no, keep going
        !           860: /* invalidate the unused part */
        !           861:        movl    #eSysseg,a1             | end of segment table
        !           862:        addl    a5,a1                   | relocate
        !           863: Lispt6:
        !           864:        movl    #SG_NV,a0@+             | invalidate STE
        !           865:        cmpl    a1,a0                   | done yet?
        !           866:        jcs     Lispt6                  | no, keep going
        !           867: 
        !           868: /*
        !           869:  * Setup page table for process 0.
        !           870:  *
        !           871:  * We set up page table access for the kernel via Usrptmap (usrpt)
        !           872:  * and access to the u-area itself via Umap (u).  First page beyond
        !           873:  * kernel BSS (d0) is used for proc0 page table.  Next UPAGES pages
        !           874:  * following are for u-area.
        !           875:  */
        !           876:        addl    a5,d0                   | relocate PT address
        !           877:        movl    d0,d1
        !           878:        andl    #PG_FRAME,d1            | mask to page frame number
        !           879:        orl     #PG_RW+PG_V,d1          | RW and valid
        !           880:        movl    #_Usrptmap,a1           | get PT map address
        !           881:        addl    a5,a1                   | relocate
        !           882:        movl    d1,a1@                  | validate PTE for proc0 PT
        !           883:        movl    d0,a0                   | base of proc0 PT
        !           884:        addl    #NBPG,d0                | plus one page yields
        !           885:        movl    d0,a2                   | base of u-area
        !           886: /* invalidate entire page table */
        !           887: Liudot1:
        !           888:        movl    #PG_NV,a0@+             | invalidate PTE
        !           889:        cmpl    a2,a0                   | done yet?
        !           890:        jcs     Liudot1                 | no, keep going
        !           891: /* now go back and validate u-area PTEs */
        !           892:        subl    #HIGHPAGES*4,a0         | base of PTEs for u-area (p_addr)
        !           893:        movl    a0,a1
        !           894:        addl    #UPAGES*4,a1            | end of PTEs for u-area
        !           895:        movl    d0,d1                   | get base of u-area
        !           896:        andl    #PG_FRAME,d1            | mask to page frame number
        !           897:        orl     #PG_RW+PG_V,d1          | add valid and writable
        !           898:        movl    #_Umap,a3               | address of u
        !           899:        addl    a5,a3                   | relocate
        !           900: Liudot2:
        !           901:        movl    d1,a0@+                 | validate p_addr PTE
        !           902:        movl    d1,a3@+                 | validate u PTE
        !           903:        addl    #NBPG,d1                | to next page
        !           904:        cmpl    a1,a0                   | done yet?
        !           905:        jcs     Liudot2                 | no, keep going
        !           906: /* clear process 0 u-area */
        !           907:        addl    #NBPG*UPAGES,d0         | end of u-area
        !           908: Lclru1:
        !           909:        clrl    a2@+                    | clear
        !           910:        cmpl    d0,a2                   | done yet?
        !           911:        jcs     Lclru1                  | no, keep going
        !           912:        movl    a2,a4                   | save addr of first avail page
        !           913: 
        !           914: /*
        !           915:  * Prepare to enable MMU.
        !           916:  * Since the kernel is not mapped logical == physical we must insure
        !           917:  * that when the MMU is turned on, all prefetched addresses (including
        !           918:  * the PC) are valid.  In order guarentee that, we map the last page of
        !           919:  * memory logical == physical and load up that page with enough code to
        !           920:  * defeat the prefetch, then we execute the jump back to here.
        !           921:  *
        !           922:  * Is this all really necessary, or am I paranoid??
        !           923:  */
        !           924:        movl    #_Sysseg,d1             | system segment table addr
        !           925:        addl    a5,d1                   | relocate
        !           926:        lea     _mmutype,a0
        !           927:        addl    a5,a0
        !           928:        tstl    a0@                     | HP MMU?
        !           929:        jeq     Lhpmmu2                 | yes, skip
        !           930:        lea     _protorp,a0
        !           931:        addl    a5,a0
        !           932:        movl    #0x80000202,a0@         | nolimit + share global + 4 byte PTEs
        !           933:        movl    d1,a0@(4)               | + segtable address
        !           934:        .long   0xf0104800              | pmove a0@,srp
        !           935:        movl    #0x80000002,a0@         | reinit upper half for CRP loads
        !           936:        jra     Lstploaddone            | done
        !           937: Lhpmmu2:
        !           938:        moveq   #PGSHIFT,d2
        !           939:        lsrl    d2,d1                   | convert to page frame
        !           940:        movl    d1,IOBASE+MMUSSTP       | load in sysseg table register
        !           941: Lstploaddone:
        !           942:        movl    #eSysseg-4,a1           | last entry in sysseg table
        !           943:        addl    a5,a1                   | relocate
        !           944:        movl    d0,d1                   | use page after proc0 u for tmp PT
        !           945:        andl    #SG_FRAME,d1            | mask to page frame
        !           946:        orl     #SG_RW+SG_V,d1          | mark valid and writable
        !           947:        movl    d1,a1@                  | load in segment table
        !           948:        movl    d0,a1                   | page table address
        !           949:        addl    #NBPG-4,a1              | move to last entry
        !           950:        movl    #MAXADDR,d1             | address of last page of memory
        !           951:        movl    d1,a2
        !           952:        andl    #PG_FRAME,d1            | mask to page frame
        !           953:        orl     #PG_RW+PG_V,d1          | mark valid and writable
        !           954:        movl    d1,a1@                  | store PTE in table
        !           955:        movl    #Lhighcode,a1           | addr of high code
        !           956:        addl    a5,a1                   | relocate
        !           957:        movl    #Lehighcode,a3          | end addr
        !           958:        addl    a5,a3                   | relocate
        !           959: Lcodecopy:
        !           960:        movw    a1@+,a2@+               | copy a word
        !           961:        cmpl    a3,a1                   | done yet?
        !           962:        jcs     Lcodecopy               | no, keep going
        !           963:        jmp     MAXADDR                 | go for it!
        !           964: 
        !           965: Lhighcode:
        !           966:        lea     _mmutype,a0
        !           967:        addl    a5,a0
        !           968:        tstl    a0@                             | HP MMU?
        !           969:        jeq     Lhpmmu3                         | yes, skip
        !           970:        movl    #MMU_IEN+MMU_FPE,IOBASE+MMUCMD  | enable 68881 and i-cache
        !           971:        movl    #0x82c0aa00,a2@                 | value to load TC with
        !           972:        .long   0xf0124000                      | pmove a2@,tc
        !           973:        jmp     Lenab1
        !           974: Lhpmmu3:
        !           975:        movl    #0,IOBASE+MMUCMD                | clear external cache
        !           976:        movl    #MMU_ENAB,IOBASE+MMUCMD         | turn on MMU
        !           977:        jmp     Lenab1                          | jmp to mapped code
        !           978: Lehighcode:
        !           979: 
        !           980: /*
        !           981:  * Should be running mapped from this point on
        !           982:  */
        !           983: Lenab1:
        !           984: /* while the ROM scratch page is mapped, check for internal HP-IB in SYSFLAG */
        !           985:        btst    #5,0xfffffed2           | internal HP-IB?
        !           986:        jeq     Linitmem                | yes, have HP-IB continue normally
        !           987:        clrl    _internalhpib           | no, clear associated address
        !           988: /* init mem sizes */
        !           989: Linitmem:
        !           990:        movl    #MAXADDR,d1             | last page
        !           991:        moveq   #PGSHIFT,d2
        !           992:        lsrl    d2,d1                   | convert to page (click) number
        !           993:        movl    d1,_maxmem              | save as maxmem
        !           994:        movl    _lowram,d0              | lowram value from ROM via boot
        !           995:        lsrl    d2,d0                   | convert to page number
        !           996:        subl    d0,d1                   | compute amount of RAM present
        !           997:        movl    d1,_freemem             | save as freemem
        !           998:        movl    d1,_physmem             | and physmem
        !           999: /* initialize (slightly) the pcb */
        !          1000:        movl    #_u,a1                  | proc0 u-area
        !          1001:        movl    a1,sp
        !          1002:        addl    #UPAGES*NBPG-4,sp       | set kernel stack to end of u-area
        !          1003:        movl    #USRSTACK-4,a2
        !          1004:        movl    a2,usp                  | init user SP
        !          1005:        movl    #_usrpt,a1@(PCB_P0BR)   | p0br: SVA of text/data user PT
        !          1006:        clrl    a1@(PCB_P0LR)           | p0lr: 0 (does not really exist)
        !          1007:        movl    #_usrpt+NBPG,d0         | addr of end of PT
        !          1008:        subl    #P1PAGES*4,d0           | backup size of P1 region
        !          1009:        movl    d0,a1@(PCB_P1BR)        | p1br: P1PAGES from end of PT
        !          1010:        movl    #P1PAGES-HIGHPAGES,a1@(PCB_P1LR)        | p1lr: vax style
        !          1011:        movl    #CLSIZE,a1@(PCB_SZPT)   | page table size
        !          1012:        clrw    a1@(PCB_FLAGS)          | clear flags
        !          1013: #ifdef FPCOPROC
        !          1014:        clrl    a1@(PCB_FPCTX)          | ensure null FP context
        !          1015:        movl    a1,sp@-
        !          1016:        jbsr    _m68881_restore         | restore it (does not kill a1)
        !          1017:        addql   #4,sp
        !          1018: #endif
        !          1019:        addl    #PCB_SIGC,a1            | address of proc0 sig trampoline code
        !          1020:        movl    #Lsigcode,a2            | address of sig trampoline proto
        !          1021: Lsigc:
        !          1022:        movw    a2@+,a1@+               | copy
        !          1023:        cmpl    #Lesigcode,a2           | done yet?
        !          1024:        jcs     Lsigc                   | no, keep going
        !          1025: /* flush TLB and turn on caches */
        !          1026:        movl    #PG_NV,eSysseg-4        | invalidate last page
        !          1027:        jbsr    _TBIA                   | invalidate TLB
        !          1028:        movl    #CACHE_ON,d0
        !          1029:        movc    d0,cacr                 | clear cache(s)
        !          1030:        tstl    _ectype
        !          1031:        jeq     Lnocache0
        !          1032:        orl     #MMU_CEN,_IObase+MMUCMD | turn on external cache
        !          1033: Lnocache0:
        !          1034: /* final setup for C code */
        !          1035:        movw    #PSL_LOWIPL,sr          | lower SPL
        !          1036:        movl    d7,_boothowto           | save reboot flags
        !          1037:        movl    d6,_bootdev             |   and boot device
        !          1038:        movl    a4,d1                   | addr of first available RAM
        !          1039:        moveq   #PGSHIFT,d2
        !          1040:        lsrl    d2,d1                   | convert to click
        !          1041:        movl    d1,sp@-                 | param to main
        !          1042:        jbsr    _main                   | main(firstaddr)
        !          1043:        addql   #4,sp
        !          1044: /* proc[1] == init now running here;
        !          1045:  * create a null exception frame and return to user mode in icode
        !          1046:  */
        !          1047:        clrw    sp@-                    | vector offset/frame type
        !          1048:        clrl    sp@-                    | return to icode location 0
        !          1049:        movw    #PSL_USER,sp@-          | in user mode
        !          1050:        rte
        !          1051: 
        !          1052: /*
        !          1053:  * Signal "trampoline" code (18 bytes).  Invoked from RTE setup by sendsig().
        !          1054:  * 
        !          1055:  * Stack looks like:
        !          1056:  *
        !          1057:  *     sp+0 -> signal number
        !          1058:  *     sp+4    signal specific code
        !          1059:  *     sp+8    pointer to signal context frame (scp)
        !          1060:  *     sp+12   address of handler
        !          1061:  *     sp+16   saved hardware state
        !          1062:  *                     .
        !          1063:  *                     .
        !          1064:  *     scp+0-> beginning of signal context frame
        !          1065:  */
        !          1066: Lsigcode:
        !          1067:        movl    sp@(12),a0              | signal handler addr   (4 bytes)
        !          1068:        jsr     a0@                     | call signal handler   (2 bytes)
        !          1069:        addql   #4,sp                   | pop signo             (2 bytes)
        !          1070:        trap    #1                      | special syscall entry (2 bytes)
        !          1071:        movl    d0,sp@(4)               | save errno            (4 bytes)
        !          1072:        moveq   #1,d0                   | syscall == exit       (2 bytes)
        !          1073:        trap    #0                      | exit(errno)           (2 bytes)
        !          1074: Lesigcode:
        !          1075: 
        !          1076: /*
        !          1077:  * Icode is copied out to process 1 to exec init.
        !          1078:  * If the exec fails, process 1 exits.
        !          1079:  */
        !          1080:        argv1 = argv-_icode
        !          1081:        init1 = init-_icode
        !          1082:        .globl  _icode,_initflags,_szicode
        !          1083: _icode:
        !          1084:        movl    #argv1,sp@-
        !          1085:        movl    #init1,sp@-
        !          1086:        clrl    sp@-
        !          1087:        moveq   #SYS_execv,d0
        !          1088:        trap    #0
        !          1089:        moveq   #SYS_exit,d0
        !          1090:        trap    #0
        !          1091: 
        !          1092: init:
        !          1093:        .asciz  "/sbin/init"
        !          1094:        .even
        !          1095: _initflags:
        !          1096:        .long   0
        !          1097: argv:
        !          1098:        .long   init+6-_icode
        !          1099:        .long   _initflags-_icode
        !          1100:        .long   0
        !          1101: _szicode:
        !          1102:        .long   _szicode-_icode
        !          1103: 
        !          1104: /*
        !          1105:  * Primitives
        !          1106:  */ 
        !          1107: 
        !          1108: #ifdef GPROF
        !          1109: #ifdef __GNUC__
        !          1110: #define        ENTRY(name) \
        !          1111:        .globl _/**/name; _/**/name: link a6,#0; jbsr mcount; unlk a6
        !          1112: #define ALTENTRY(name, rname) \
        !          1113:        ENTRY(name); jra rname+12
        !          1114: #else
        !          1115: #define        ENTRY(name) \
        !          1116:        .globl _/**/name; _/**/name: jbsr mcount
        !          1117: #define ALTENTRY(name, rname) \
        !          1118:        ENTRY(name); jra rname+6
        !          1119: #endif
        !          1120: #else
        !          1121: #define        ENTRY(name) \
        !          1122:        .globl _/**/name; _/**/name:
        !          1123: #define ALTENTRY(name, rname) \
        !          1124:        .globl _/**/name; _/**/name:
        !          1125: #endif
        !          1126: 
        !          1127: /*
        !          1128:  * update profiling information for the user
        !          1129:  * addupc(pc, &u.u_prof, ticks)
        !          1130:  */
        !          1131: ENTRY(addupc)
        !          1132:        movl    a2,sp@-                 | scratch register
        !          1133:        movl    sp@(12),a2              | get &u.u_prof
        !          1134:        movl    sp@(8),d0               | get user pc
        !          1135:        subl    a2@(8),d0               | pc -= pr->pr_off
        !          1136:        jlt     Lauexit                 | less than 0, skip it
        !          1137:        movl    a2@(12),d1              | get pr->pr_scale
        !          1138:        lsrl    #1,d0                   | pc /= 2
        !          1139:        lsrl    #1,d1                   | scale /= 2
        !          1140:        mulul   d1,d0                   | pc /= scale
        !          1141:        moveq   #14,d1
        !          1142:        lsrl    d1,d0                   | pc >>= 14
        !          1143:        bclr    #0,d0                   | pc &= ~1
        !          1144:        cmpl    a2@(4),d0               | too big for buffer?
        !          1145:        jge     Lauexit                 | yes, screw it
        !          1146:        addl    a2@,d0                  | no, add base
        !          1147:        movl    d0,sp@-                 | push address
        !          1148:        jbsr    _fusword                | grab old value
        !          1149:        movl    sp@+,a0                 | grab address back
        !          1150:        cmpl    #-1,d0                  | access ok
        !          1151:        jeq     Lauerror                | no, skip out
        !          1152:        addw    sp@(18),d0              | add tick to current value
        !          1153:        movl    d0,sp@-                 | push value
        !          1154:        movl    a0,sp@-                 | push address
        !          1155:        jbsr    _susword                | write back new value
        !          1156:        addql   #8,sp                   | pop params
        !          1157:        tstl    d0                      | fault?
        !          1158:        jeq     Lauexit                 | no, all done
        !          1159: Lauerror:
        !          1160:        clrl    a2@(12)                 | clear scale (turn off prof)
        !          1161: Lauexit:
        !          1162:        movl    sp@+,a2                 | restore scratch reg
        !          1163:        rts
        !          1164: 
        !          1165: /*
        !          1166:  * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
        !          1167:  *
        !          1168:  * Copy a null terminated string from the user address space into
        !          1169:  * the kernel address space.
        !          1170:  * NOTE: maxlength must be < 64K
        !          1171:  */
        !          1172: ENTRY(copyinstr)
        !          1173:        movl    sp@(4),a0               | a0 = fromaddr
        !          1174:        movl    sp@(8),a1               | a1 = toaddr
        !          1175:        moveq   #0,d0
        !          1176:        movw    sp@(14),d0              | d0 = maxlength
        !          1177:        jlt     Lcisflt1                | negative count, error
        !          1178:        jeq     Lcisdone                | zero count, all done
        !          1179:        movl    #Lcisflt1,_u+PCB_ONFAULT | set up to catch faults
        !          1180:        subql   #1,d0                   | set up for dbeq
        !          1181: Lcisloop:
        !          1182:        movsb   a0@+,d1                 | grab a byte
        !          1183:        movb    d1,a1@+                 | copy it
        !          1184:        dbeq    d0,Lcisloop             | if !null and more, continue
        !          1185:        jne     Lcisflt2                | ran out of room, error
        !          1186:        moveq   #0,d0                   | got a null, all done
        !          1187: Lcisdone:
        !          1188:        tstl    sp@(16)                 | return length desired?
        !          1189:        jeq     Lcisret                 | no, just return
        !          1190:        subl    sp@(4),a0               | determine how much was copied
        !          1191:        movl    sp@(16),a1              | return location
        !          1192:        movl    a0,a1@                  | stash it
        !          1193: Lcisret:
        !          1194:        clrl    _u+PCB_ONFAULT          | clear fault addr
        !          1195:        rts
        !          1196: Lcisflt1:
        !          1197:        moveq   #EFAULT,d0              | copy fault
        !          1198:        jra     Lcisdone
        !          1199: Lcisflt2:
        !          1200:        moveq   #ENOENT,d0              | ran out of space
        !          1201:        jra     Lcisdone        
        !          1202: 
        !          1203: /*
        !          1204:  * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
        !          1205:  *
        !          1206:  * Copy a null terminated string from the kernel
        !          1207:  * address space to the user address space.
        !          1208:  * NOTE: maxlength must be < 64K
        !          1209:  */
        !          1210: ENTRY(copyoutstr)
        !          1211:        movl    sp@(4),a0               | a0 = fromaddr
        !          1212:        movl    sp@(8),a1               | a1 = toaddr
        !          1213:        moveq   #0,d0
        !          1214:        movw    sp@(14),d0              | d0 = maxlength
        !          1215:        jlt     Lcosflt1                | negative count, error
        !          1216:        jeq     Lcosdone                | zero count, all done
        !          1217:        movl    #Lcosflt1,_u+PCB_ONFAULT| set up to catch faults
        !          1218:        subql   #1,d0                   | set up for dbeq
        !          1219: Lcosloop:
        !          1220:        movb    a0@+,d1                 | grab a byte
        !          1221:        movsb   d1,a1@+                 | copy it
        !          1222:        dbeq    d0,Lcosloop             | if !null and more, continue
        !          1223:        jne     Lcosflt2                | ran out of room, error
        !          1224:        moveq   #0,d0                   | got a null, all done
        !          1225: Lcosdone:
        !          1226:        tstl    sp@(16)                 | return length desired?
        !          1227:        jeq     Lcosret                 | no, just return
        !          1228:        subl    sp@(4),a0               | determine how much was copied
        !          1229:        movl    sp@(16),a1              | return location
        !          1230:        movl    a0,a1@                  | stash it
        !          1231: Lcosret:
        !          1232:        clrl    _u+PCB_ONFAULT          | clear fault addr
        !          1233:        rts
        !          1234: Lcosflt1:
        !          1235:        moveq   #EFAULT,d0              | copy fault
        !          1236:        jra     Lcosdone
        !          1237: Lcosflt2:
        !          1238:        moveq   #ENOENT,d0              | ran out of space
        !          1239:        jra     Lcosdone        
        !          1240: 
        !          1241: /*
        !          1242:  * copystr(fromaddr, toaddr, maxlength, &lencopied)
        !          1243:  *
        !          1244:  * Copy a null terminated string from one point to another in
        !          1245:  * the kernel address space.
        !          1246:  * NOTE: maxlength must be < 64K
        !          1247:  */
        !          1248: ENTRY(copystr)
        !          1249:        movl    sp@(4),a0               | a0 = fromaddr
        !          1250:        movl    sp@(8),a1               | a1 = toaddr
        !          1251:        moveq   #0,d0
        !          1252:        movw    sp@(14),d0              | d0 = maxlength
        !          1253:        jlt     Lcsflt1                 | negative count, error
        !          1254:        jeq     Lcsdone                 | zero count, all done
        !          1255:        movl    #Lcsflt1,_u+PCB_ONFAULT | set up to catch faults
        !          1256:        subql   #1,d0                   | set up for dbeq
        !          1257: Lcsloop:
        !          1258:        movb    a0@+,a1@+               | copy a byte
        !          1259:        dbeq    d0,Lcsloop              | if !null and more, continue
        !          1260:        jne     Lcsflt2                 | ran out of room, error
        !          1261:        moveq   #0,d0                   | got a null, all done
        !          1262: Lcsdone:
        !          1263:        tstl    sp@(16)                 | return length desired?
        !          1264:        jeq     Lcsret                  | no, just return
        !          1265:        subl    sp@(4),a0               | determine how much was copied
        !          1266:        movl    sp@(16),a1              | return location
        !          1267:        movl    a0,a1@                  | stash it
        !          1268: Lcsret:
        !          1269:        clrl    _u+PCB_ONFAULT          | clear fault addr
        !          1270:        rts
        !          1271: Lcsflt1:
        !          1272:        moveq   #EFAULT,d0              | copy fault
        !          1273:        jra     Lcsdone
        !          1274: Lcsflt2:
        !          1275:        moveq   #ENOENT,d0              | ran out of space
        !          1276:        jra     Lcsdone 
        !          1277: 
        !          1278: /* 
        !          1279:  * Copyin(from, to, len)
        !          1280:  *
        !          1281:  * Copy specified amount of data from user space into the kernel.
        !          1282:  * NOTE: len must be < 64K
        !          1283:  */
        !          1284: ENTRY(copyin)
        !          1285:        movl    d2,sp@-                 | scratch register
        !          1286:        movl    #Lciflt,_u+PCB_ONFAULT  | catch faults
        !          1287:        movl    sp@(16),d2              | check count
        !          1288:        jlt     Lciflt                  | negative, error
        !          1289:        jeq     Lcidone                 | zero, done
        !          1290:        movl    sp@(8),a0               | src address
        !          1291:        movl    sp@(12),a1              | dest address
        !          1292:        movl    a0,d0
        !          1293:        btst    #0,d0                   | src address odd?
        !          1294:        jeq     Lcieven                 | no, go check dest
        !          1295:        movsb   a0@+,d1                 | yes, get a byte
        !          1296:        movb    d1,a1@+                 | put a byte
        !          1297:        subql   #1,d2                   | adjust count
        !          1298:        jeq     Lcidone                 | exit if done
        !          1299: Lcieven:
        !          1300:        movl    a1,d0
        !          1301:        btst    #0,d0                   | dest address odd?
        !          1302:        jne     Lcibyte                 | yes, must copy by bytes
        !          1303:        movl    d2,d0                   | no, get count
        !          1304:        lsrl    #2,d0                   | convert to longwords
        !          1305:        jeq     Lcibyte                 | no longwords, copy bytes
        !          1306:        subql   #1,d0                   | set up for dbf
        !          1307: Lcilloop:
        !          1308:        movsl   a0@+,d1                 | get a long
        !          1309:        movl    d1,a1@+                 | put a long
        !          1310:        dbf     d0,Lcilloop             | til done
        !          1311:        andl    #3,d2                   | what remains
        !          1312:        jeq     Lcidone                 | all done
        !          1313: Lcibyte:
        !          1314:        subql   #1,d2                   | set up for dbf
        !          1315: Lcibloop:
        !          1316:        movsb   a0@+,d1                 | get a byte
        !          1317:        movb    d1,a1@+                 | put a byte
        !          1318:        dbf     d2,Lcibloop             | til done
        !          1319: Lcidone:
        !          1320:        moveq   #0,d0                   | success
        !          1321: Lciexit:
        !          1322:        clrl    _u+PCB_ONFAULT          | reset fault catcher
        !          1323:        movl    sp@+,d2                 | restore scratch reg
        !          1324:        rts
        !          1325: Lciflt:
        !          1326:        moveq   #EFAULT,d0              | got a fault
        !          1327:        jra     Lciexit
        !          1328: 
        !          1329: /* 
        !          1330:  * Copyout(from, to, len)
        !          1331:  *
        !          1332:  * Copy specified amount of data from kernel to the user space
        !          1333:  * NOTE: len must be < 64K
        !          1334:  */
        !          1335: ENTRY(copyout)
        !          1336:        movl    d2,sp@-                 | scratch register
        !          1337:        movl    #Lcoflt,_u+PCB_ONFAULT  | catch faults
        !          1338:        movl    sp@(16),d2              | check count
        !          1339:        jlt     Lcoflt                  | negative, error
        !          1340:        jeq     Lcodone                 | zero, done
        !          1341:        movl    sp@(8),a0               | src address
        !          1342:        movl    sp@(12),a1              | dest address
        !          1343:        movl    a0,d0
        !          1344:        btst    #0,d0                   | src address odd?
        !          1345:        jeq     Lcoeven                 | no, go check dest
        !          1346:        movb    a0@+,d1                 | yes, get a byte
        !          1347:        movsb   d1,a1@+                 | put a byte
        !          1348:        subql   #1,d2                   | adjust count
        !          1349:        jeq     Lcodone                 | exit if done
        !          1350: Lcoeven:
        !          1351:        movl    a1,d0
        !          1352:        btst    #0,d0                   | dest address odd?
        !          1353:        jne     Lcobyte                 | yes, must copy by bytes
        !          1354:        movl    d2,d0                   | no, get count
        !          1355:        lsrl    #2,d0                   | convert to longwords
        !          1356:        jeq     Lcobyte                 | no longwords, copy bytes
        !          1357:        subql   #1,d0                   | set up for dbf
        !          1358: Lcolloop:
        !          1359:        movl    a0@+,d1                 | get a long
        !          1360:        movsl   d1,a1@+                 | put a long
        !          1361:        dbf     d0,Lcolloop             | til done
        !          1362:        andl    #3,d2                   | what remains
        !          1363:        jeq     Lcodone                 | all done
        !          1364: Lcobyte:
        !          1365:        subql   #1,d2                   | set up for dbf
        !          1366: Lcobloop:
        !          1367:        movb    a0@+,d1                 | get a byte
        !          1368:        movsb   d1,a1@+                 | put a byte
        !          1369:        dbf     d2,Lcobloop             | til done
        !          1370: Lcodone:
        !          1371:        moveq   #0,d0                   | success
        !          1372: Lcoexit:
        !          1373:        clrl    _u+PCB_ONFAULT          | reset fault catcher
        !          1374:        movl    sp@+,d2                 | restore scratch reg
        !          1375:        rts
        !          1376: Lcoflt:
        !          1377:        moveq   #EFAULT,d0              | got a fault
        !          1378:        jra     Lcoexit
        !          1379: 
        !          1380: /*
        !          1381:  * non-local gotos
        !          1382:  */
        !          1383: ALTENTRY(savectx, _setjmp)
        !          1384: ENTRY(setjmp)
        !          1385:        movl    sp@(4),a0       | savearea pointer
        !          1386:        moveml  #0xFCFC,a0@     | save d2-d7/a2-a7
        !          1387:        movl    sp@,a0@(48)     | and return address
        !          1388:        moveq   #0,d0           | return 0
        !          1389:        rts
        !          1390: 
        !          1391: ENTRY(qsetjmp)
        !          1392:        movl    sp@(4),a0       | savearea pointer
        !          1393:        lea     a0@(40),a0      | skip regs we do not save
        !          1394:        movl    a6,a0@+         | save FP
        !          1395:        movl    sp,a0@+         | save SP
        !          1396:        movl    sp@,a0@         | and return address
        !          1397:        moveq   #0,d0           | return 0
        !          1398:        rts
        !          1399: 
        !          1400: ENTRY(longjmp)
        !          1401:        movl    sp@(4),a0
        !          1402:        moveml  a0@+,#0xFCFC
        !          1403:        movl    a0@,sp@
        !          1404:        moveq   #1,d0
        !          1405:        rts
        !          1406: 
        !          1407: /*
        !          1408:  * The following primitives manipulate the run queues.
        !          1409:  * _whichqs tells which of the 32 queues _qs
        !          1410:  * have processes in them.  Setrq puts processes into queues, Remrq
        !          1411:  * removes them from queues.  The running process is on no queue,
        !          1412:  * other processes are on a queue related to p->p_pri, divided by 4
        !          1413:  * actually to shrink the 0-127 range of priorities into the 32 available
        !          1414:  * queues.
        !          1415:  */
        !          1416: 
        !          1417:        .globl  _whichqs,_qs,_cnt,_panic
        !          1418:        .comm   _noproc,4
        !          1419:        .comm   _runrun,4
        !          1420: 
        !          1421: /*
        !          1422:  * Setrq(p)
        !          1423:  *
        !          1424:  * Call should be made at spl6(), and p->p_stat should be SRUN
        !          1425:  */
        !          1426: ENTRY(setrq)
        !          1427:        movl    sp@(4),a0
        !          1428:        tstl    a0@(P_RLINK)
        !          1429:        jeq     Lset1
        !          1430:        movl    #Lset2,sp@-
        !          1431:        jbsr    _panic
        !          1432: Lset1:
        !          1433:        clrl    d0
        !          1434:        movb    a0@(P_PRI),d0
        !          1435:        lsrb    #2,d0
        !          1436:        movl    _whichqs,d1
        !          1437:        bset    d0,d1
        !          1438:        movl    d1,_whichqs
        !          1439:        lslb    #3,d0
        !          1440:        addl    #_qs,d0
        !          1441:        movl    d0,a0@(P_LINK)
        !          1442:        movl    d0,a1
        !          1443:        movl    a1@(P_RLINK),a0@(P_RLINK)
        !          1444:        movl    a0,a1@(P_RLINK)
        !          1445:        movl    a0@(P_RLINK),a1
        !          1446:        movl    a0,a1@(P_LINK)
        !          1447:        rts
        !          1448: 
        !          1449: Lset2:
        !          1450:        .asciz  "setrq"
        !          1451:        .even
        !          1452: 
        !          1453: /*
        !          1454:  * Remrq(p)
        !          1455:  *
        !          1456:  * Call should be made at spl6().
        !          1457:  */
        !          1458: ENTRY(remrq)
        !          1459:        movl    sp@(4),a0
        !          1460:        clrl    d0
        !          1461:        movb    a0@(P_PRI),d0
        !          1462:        lsrb    #2,d0
        !          1463:        movl    _whichqs,d1
        !          1464:        bclr    d0,d1
        !          1465:        jne     Lrem1
        !          1466:        movl    #Lrem3,sp@-
        !          1467:        jbsr    _panic
        !          1468: Lrem1:
        !          1469:        movl    d1,_whichqs
        !          1470:        movl    a0@(P_LINK),a1
        !          1471:        movl    a0@(P_RLINK),a1@(P_RLINK)
        !          1472:        movl    a0@(P_RLINK),a1
        !          1473:        movl    a0@(P_LINK),a1@(P_LINK)
        !          1474:        movl    #_qs,a1
        !          1475:        movl    d0,d1
        !          1476:        lslb    #3,d1
        !          1477:        addl    d1,a1
        !          1478:        cmpl    a1@(P_LINK),a1
        !          1479:        jeq     Lrem2
        !          1480:        movl    _whichqs,d1
        !          1481:        bset    d0,d1
        !          1482:        movl    d1,_whichqs
        !          1483: Lrem2:
        !          1484:        clrl    a0@(P_RLINK)
        !          1485:        rts
        !          1486: 
        !          1487: Lrem3:
        !          1488:        .asciz  "remrq"
        !          1489: Lsw0:
        !          1490:        .asciz  "swtch"
        !          1491:        .even
        !          1492: 
        !          1493: /*
        !          1494:  * When no processes are on the runq, Swtch branches to idle
        !          1495:  * to wait for something to come ready.
        !          1496:  */
        !          1497:        .globl  Idle
        !          1498: Idle:
        !          1499: idle:
        !          1500:        movw    #PSL_LOWIPL,sr
        !          1501:        tstl    _whichqs
        !          1502:        jne     Lsw1
        !          1503:        stop    #PSL_LOWIPL
        !          1504:        jra     idle
        !          1505: 
        !          1506: Lbadsw:
        !          1507:        movl    #Lsw0,sp@-
        !          1508:        jbsr    _panic
        !          1509:        /*NOTREACHED*/
        !          1510: 
        !          1511: /*
        !          1512:  * Swtch()
        !          1513:  */
        !          1514: ENTRY(swtch)
        !          1515:        movw    sr,_u+PCB_PS
        !          1516:        movl    #1,_noproc
        !          1517:        addql   #1,_cnt+V_SWTCH
        !          1518: Lsw1:
        !          1519:        clrl    d0
        !          1520:        movl    _whichqs,d1
        !          1521: Lswchk:
        !          1522:        btst    d0,d1
        !          1523:        jne     Lswfnd
        !          1524:        addqb   #1,d0
        !          1525:        cmpb    #32,d0
        !          1526:        jne     Lswchk
        !          1527:        jra     idle
        !          1528: Lswfnd:
        !          1529:        movw    #PSL_HIGHIPL,sr
        !          1530:        movl    _whichqs,d1
        !          1531:        bclr    d0,d1
        !          1532:        jeq     Lsw1
        !          1533:        movl    d1,_whichqs
        !          1534:        movl    d0,d1
        !          1535:        lslb    #3,d1
        !          1536:        addl    #_qs,d1
        !          1537:        movl    d1,a1
        !          1538:        cmpl    a1@(P_LINK),a1
        !          1539:        jeq     Lbadsw
        !          1540:        movl    a1@(P_LINK),a0
        !          1541:        movl    a0@(P_LINK),a1@(P_LINK)
        !          1542:        movl    a0@(P_LINK),a1
        !          1543:        movl    a0@(P_RLINK),a1@(P_RLINK)
        !          1544:        cmpl    a0@(P_LINK),d1
        !          1545:        jeq     Lsw2
        !          1546:        movl    _whichqs,d1
        !          1547:        bset    d0,d1
        !          1548:        movl    d1,_whichqs
        !          1549: Lsw2:
        !          1550:        clrl    _noproc
        !          1551:        clrl    _runrun
        !          1552:        tstl    a0@(P_WCHAN)
        !          1553:        jne     Lbadsw
        !          1554:        cmpb    #SRUN,a0@(P_STAT)
        !          1555:        jne     Lbadsw
        !          1556:        clrl    a0@(P_RLINK)
        !          1557:        movl    a0@(P_ADDR),d0
        !          1558:        jra     Lres0
        !          1559: 
        !          1560: /*
        !          1561:  * Resume(p_addr)
        !          1562:  *
        !          1563:  * NOTE: on the PMMU we attempt to avoid flushing the entire TAC.
        !          1564:  * The effort involved in selective flushing may not be worth it,
        !          1565:  * maybe we should just flush the whole thing?
        !          1566:  */
        !          1567: ENTRY(resume)
        !          1568:        movw    sr,_u+PCB_PS
        !          1569:        movl    sp@(4),d0
        !          1570: Lres0:
        !          1571:        lea     _u,a1                   | &u
        !          1572:        movl    usp,a0                  | grab USP
        !          1573:        movl    a0,a1@(PCB_USP)         | and save it
        !          1574:        moveml  #0xFCFC,a1@(PCB_REGS)   | save non-scratch registers
        !          1575: #ifdef FPCOPROC
        !          1576:        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
        !          1577:        .word   0xf310                  | fsave a0@
        !          1578:        tstb    a0@                     | null state frame?
        !          1579:        jeq     Lresnofpsave            | yes, all done
        !          1580:        .word   0xf228,0xf0ff,0x00d8    | fmovem fp0-fp7,a0@(216)
        !          1581:        .word   0xf228,0xbc00,0x0138    | fmovem fpcr/fpsr/fpiar,a0@(312)
        !          1582: Lresnofpsave:
        !          1583: #endif
        !          1584: #ifdef PROFTIMER
        !          1585:        movw    #SPL6,sr                | protect against clock interrupts
        !          1586:        bclr    #0,_profon              | clear user profiling bit, was set?
        !          1587:        jeq     Lskipoff                | no, clock off or doing kernel only
        !          1588: #ifdef GPROF
        !          1589:        tstb    _profon                 | kernel profiling also enabled?
        !          1590:        jlt     Lskipoff                | yes, nothing more to do
        !          1591: #endif
        !          1592:        movb    #0,_IObase+CLKCR2       | no, just user, select CR3
        !          1593:        movb    #0,_IObase+CLKCR3       | and turn it off
        !          1594: Lskipoff:
        !          1595: #endif
        !          1596:        movl    _CMAP2,a1@(PCB_CMAP2)   | save temporary map PTE
        !          1597:        movw    #PSL_HIGHIPL,sr         | go crit while changing PTEs
        !          1598:        lea     tmpstk,sp               | now goto a tmp stack for NMI
        !          1599:        movl    d0,a0                   | address of new context
        !          1600:        lea     _Umap,a1                | address of PTEs for u
        !          1601:        moveq   #UPAGES-1,d0            | sizeof u
        !          1602: Lres1:
        !          1603:        movl    a0@+,d1                 | get PTE
        !          1604:        andl    #~PG_PROT,d1            | mask out old protection
        !          1605:        orl     #PG_RW+PG_V,d1          | ensure valid and writable
        !          1606:        movl    d1,a1@+                 | load it up
        !          1607:        dbf     d0,Lres1                | til done
        !          1608:        lea     _u,a1                   | reload &u
        !          1609:        movl    #CACHE_CLR,d0
        !          1610:        movc    d0,cacr                 | invalidate cache(s)
        !          1611: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          1612:        tstl    _mmutype                | HP MMU?
        !          1613:        jeq     Lhpmmu4                 | yes, skip
        !          1614:        jmi     Lnot68851a              | must flush all on 68030 MMU
        !          1615: #ifdef DEBUG
        !          1616:        tstl    fullflush               | 68851, conservative?
        !          1617:        jne     Lnot68851a              | yes, go flush all
        !          1618: #endif
        !          1619:        .long   0xf0003494              | no, pflushs #4,#4 (flush super side)
        !          1620:        jra     Lres2
        !          1621: Lnot68851a:
        !          1622:        .long   0xf0002400              | pflusha
        !          1623: Lres2:
        !          1624:        movl    a1@(PCB_USTP),d0        | get USTP
        !          1625:        moveq   #PGSHIFT,d1
        !          1626:        lsll    d1,d0                   | convert to addr
        !          1627:        lea     _protorp,a0             | CRP prototype
        !          1628:        movl    d0,a0@(4)               | stash USTP
        !          1629:        .long   0xf0104C00              | pmove a0@,crp
        !          1630:        jra     Lcxswdone               | thats it
        !          1631: Lhpmmu4:       
        !          1632: #endif
        !          1633: #if defined(HP320) || defined(HP350)
        !          1634:        movl    _IObase+MMUTBINVAL,d1   | invalidate TLB
        !          1635:        tstl    _ectype                 | got external VAC?
        !          1636:        jle     Lnocache1               | no, skip
        !          1637:        movl    #_IObase+MMUCMD,a0      | addr of MMU command register
        !          1638:        andl    #~MMU_CEN,a0@           | toggle cache enable
        !          1639:        orl     #MMU_CEN,a0@            | to clear data cache
        !          1640: Lnocache1:
        !          1641:        movl    a1@(PCB_USTP),_IObase+MMUUSTP   | context switch
        !          1642: #endif
        !          1643: Lcxswdone:
        !          1644:        movl    a1@(U_PROCP),a0         | u.u_procp
        !          1645:        bclr    #SPTECHGB-24,a0@(P_FLAG)| clear SPTECHG bit
        !          1646: #if defined(HP330)
        !          1647:        jeq     Lnot68851b              | if set need to flush user TLB
        !          1648:        tstl    _mmutype                | 68851 PMMU?
        !          1649:        jle     Lnot68851b              | no, skip
        !          1650:        .long   0xf0003490              | pflushs #0,#4
        !          1651: Lnot68851b:
        !          1652: #endif
        !          1653:        movl    a1@(PCB_CMAP2),_CMAP2   | reload tmp map
        !          1654:        moveml  a1@(PCB_REGS),#0xFCFC   | and registers
        !          1655:        movl    a1@(PCB_USP),a0
        !          1656:        movl    a0,usp                  | and USP
        !          1657: #ifdef PROFTIMER
        !          1658:        tstl    a1@(U_PROFSCALE)        | process being profiled?
        !          1659:        jeq     Lskipon                 | no, do nothing
        !          1660:        orb     #1,_profon              | turn on user profiling bit
        !          1661: #ifdef GPROF
        !          1662:        jlt     Lskipon                 | already profiling kernel, all done
        !          1663: #endif
        !          1664:        lea     _IObase+CLKMSB3,a0      | address timer 3 counter
        !          1665:        movl    _profint,d1             | profiling interval
        !          1666:        subql   #1,d1                   |   adjusted
        !          1667:        movepw  d1,a0@(0)               | set interval
        !          1668:        movb    #0,_IObase+CLKCR2       | select CR3
        !          1669:        movb    #64,_IObase+CLKCR3      | turn it on
        !          1670: Lskipon:
        !          1671: #endif
        !          1672: #ifdef FPCOPROC
        !          1673:        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
        !          1674:        tstb    a0@                     | null state frame?
        !          1675:        jeq     Lresfprest              | yes, easy
        !          1676:        .word   0xf228,0x9c00,0x0138    | fmovem a0@(312),fpcr/fpsr/fpiar
        !          1677:        .word   0xf228,0xd0ff,0x00d8    | fmovem a0@(216),fp0-fp7
        !          1678: Lresfprest:
        !          1679:        .word   0xf350                  | frestore a0@
        !          1680: #endif
        !          1681:        tstl    a1@(PCB_SSWAP)          | do an alternate return?
        !          1682:        jne     Lres3                   | yes, go reload regs
        !          1683:        movw    a1@(PCB_PS),sr          | no, restore PS
        !          1684:        rts
        !          1685: Lres3:
        !          1686:        movl    a1@(PCB_SSWAP),a0       | addr of saved context
        !          1687:        clrl    a1@(PCB_SSWAP)          | clear flag
        !          1688:        moveml  a0@+,#0x7CFC            | restore registers
        !          1689:        movl    a0@+,a1                 | and SP
        !          1690:        cmpl    sp,a1                   | paranoia...
        !          1691:        jge     Lres4                   | ...must be popping, yes?
        !          1692:        lea     tmpstk,sp               | no! set up a legit stack
        !          1693:        movl    #Lres5,sp@-             | push a panic message
        !          1694:        jbsr    _panic                  | and panic
        !          1695:        /* NOTREACHED */
        !          1696: Lres4:
        !          1697:        movl    a1,sp                   | restore SP
        !          1698:        movl    a0@,sp@                 | and PC
        !          1699:        moveq   #1,d0                   | arrange for non-zero return
        !          1700:        movw    #PSL_LOWIPL,sr          | lower SPL
        !          1701:        rts
        !          1702: 
        !          1703: Lres5:
        !          1704:        .asciz  "ldctx"
        !          1705:        .even
        !          1706: 
        !          1707: /*
        !          1708:  * {fu,su},{byte,sword,word}
        !          1709:  */
        !          1710: ALTENTRY(fuiword, _fuword)
        !          1711: ENTRY(fuword)
        !          1712:        movl    sp@(4),d0               | address to read
        !          1713:        btst    #0,d0                   | is it odd?
        !          1714:        jne     Lfserr                  | yes, a fault
        !          1715:        movl    #Lfserr,_u+PCB_ONFAULT  | where to return to on a fault
        !          1716:        movl    d0,a0
        !          1717:        movsl   a0@,d0                  | do read from user space
        !          1718:        jra     Lfsdone
        !          1719: 
        !          1720: ENTRY(fusword)
        !          1721:        movl    sp@(4),d0
        !          1722:        btst    #0,d0                   | is address odd?
        !          1723:        jne     Lfserr                  | yes, a fault
        !          1724:        movl    #Lfserr,_u+PCB_ONFAULT  | where to return to on a fault
        !          1725:        movl    d0,a0                   | address to read
        !          1726:        moveq   #0,d0
        !          1727:        movsw   a0@,d0                  | do read from user space
        !          1728:        jra     Lfsdone
        !          1729: 
        !          1730: ALTENTRY(fuibyte, _fubyte)
        !          1731: ENTRY(fubyte)
        !          1732:        movl    #Lfserr,_u+PCB_ONFAULT  | where to return to on a fault
        !          1733:        movl    sp@(4),a0               | address to read
        !          1734:        moveq   #0,d0
        !          1735:        movsb   a0@,d0                  | do read from user space
        !          1736:        jra     Lfsdone
        !          1737: 
        !          1738: Lfserr:
        !          1739:        moveq   #-1,d0                  | error indicator
        !          1740: Lfsdone:
        !          1741:        clrl    _u+PCB_ONFAULT          | clear fault address
        !          1742:        rts
        !          1743: 
        !          1744: ALTENTRY(suiword, _suword)
        !          1745: ENTRY(suword)
        !          1746:        movl    sp@(4),d0               | address to write
        !          1747:        btst    #0,d0                   | is it odd?
        !          1748:        jne     Lfserr                  | yes, a fault
        !          1749:        movl    #Lfserr,_u+PCB_ONFAULT  | where to return to on a fault
        !          1750:        movl    d0,a0                   | address to write
        !          1751:        movl    sp@(8),d0               | value to put there
        !          1752:        movsl   d0,a0@                  | do write to user space
        !          1753:        moveq   #0,d0                   | indicate no fault
        !          1754:        jra     Lfsdone
        !          1755: 
        !          1756: ENTRY(susword)
        !          1757:        movl    sp@(4),d0               | address to write
        !          1758:        btst    #0,d0                   | is it odd?
        !          1759:        jne     Lfserr                  | yes, a fault
        !          1760:        movl    #Lfserr,_u+PCB_ONFAULT  | where to return to on a fault
        !          1761:        movl    d0,a0                   | address to write
        !          1762:        movw    sp@(10),d0              | value to put there
        !          1763:        movsw   d0,a0@                  | do write to user space
        !          1764:        moveq   #0,d0                   | indicate no fault
        !          1765:        jra     Lfsdone
        !          1766: 
        !          1767: ALTENTRY(suibyte, _subyte)
        !          1768: ENTRY(subyte)
        !          1769:        movl    #Lfserr,_u+PCB_ONFAULT  | where to return to on a fault
        !          1770:        movl    sp@(4),a0               | address to write
        !          1771:        movb    sp@(11),d0              | value to put there
        !          1772:        movsb   d0,a0@                  | do write to user space
        !          1773:        moveq   #0,d0                   | indicate no fault
        !          1774:        jra     Lfsdone
        !          1775: 
        !          1776: /*
        !          1777:  * Copy 1 relocation unit (NBPG bytes)
        !          1778:  * from user virtual address to physical address
        !          1779:  */
        !          1780: ENTRY(copyseg)
        !          1781:        movl    sp@(8),d0                       | destination page number
        !          1782:        moveq   #PGSHIFT,d1
        !          1783:        lsll    d1,d0                           | convert to address
        !          1784:        orl     #PG_CI+PG_RW+PG_V,d0            | make sure valid and writable
        !          1785:        movl    d0,_CMAP2                       | load in page table
        !          1786:        movl    #_CADDR2,sp@-                   | destination kernel VA
        !          1787:        jbsr    _TBIS                           | invalidate any old mapping
        !          1788:        addql   #4,sp
        !          1789:        movl    #_CADDR2,a1                     | destination addr
        !          1790:        movl    sp@(4),a0                       | source addr
        !          1791:        movl    #NBPG/4-1,d0                    | count
        !          1792:        movl    #Lcpydone,_u+PCB_ONFAULT        | where to go on a fault
        !          1793: Lcpyloop:
        !          1794:        movsl   a0@+,d1                         | read longword
        !          1795:        movl    d1,a1@+                         | write longword
        !          1796:        dbf     d0,Lcpyloop                     | continue until done
        !          1797: Lcpydone:
        !          1798:        clrl    _u+PCB_ONFAULT                  | clear error catch
        !          1799:        rts
        !          1800: 
        !          1801: /*
        !          1802:  * zero out physical memory
        !          1803:  * specified in relocation units (NBPG bytes)
        !          1804:  */
        !          1805: ENTRY(clearseg)
        !          1806:        movl    sp@(4),d0                       | destination page number
        !          1807:        moveq   #PGSHIFT,d1
        !          1808:        lsll    d1,d0                           | convert to address
        !          1809:        orl     #PG_CI+PG_RW+PG_V,d0            | make sure valid and writable
        !          1810:        movl    d0,_CMAP1                       | load in page map
        !          1811:        movl    #_CADDR1,sp@-                   | destination kernel VA
        !          1812:        jbsr    _TBIS                           | invalidate any old mapping
        !          1813:        addql   #4,sp
        !          1814:        movl    #_CADDR1,a1                     | destination addr
        !          1815:        movl    #NBPG/4-1,d0                    | count
        !          1816: /* simple clear loop is fastest on 68020 */
        !          1817: Lclrloop:
        !          1818:        clrl    a1@+                            | clear a longword
        !          1819:        dbf     d0,Lclrloop                     | continue til done
        !          1820:        rts
        !          1821: 
        !          1822: /*
        !          1823:  * Invalidate entire TLB.
        !          1824:  */
        !          1825: ENTRY(TBIA)
        !          1826: __TBIA:
        !          1827: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          1828:        tstl    _mmutype                | HP MMU?
        !          1829:        jeq     Lhpmmu6                 | yes, skip
        !          1830:        .long   0xf0002400              | no, pflusha
        !          1831: #if defined(HP360) || defined(HP370)
        !          1832:        jpl     Lmc68851a               | 68851 implies no d-cache
        !          1833:        movl    #DC_CLEAR,d0
        !          1834:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          1835: Lmc68851a:
        !          1836: #endif
        !          1837:        rts
        !          1838: Lhpmmu6:
        !          1839: #endif
        !          1840: #if defined(HP320) || defined(HP350)
        !          1841:        movl    _IObase+MMUTBINVAL,sp@- | do not ask me, this
        !          1842:        addql   #4,sp                   |   is how hpux does it
        !          1843:        jra     __DCIA                  | XXX: invalidate entire cache
        !          1844: #endif
        !          1845:        rts
        !          1846: 
        !          1847: /*
        !          1848:  * Invalidate any TLB entry for given VA (TB Invalidate Single)
        !          1849:  */
        !          1850: ENTRY(TBIS)
        !          1851: #ifdef DEBUG
        !          1852:        tstl    fullflush               | being conservative?
        !          1853:        jne     __TBIA                  | yes, flush entire TLB
        !          1854: #endif
        !          1855: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          1856:        tstl    _mmutype                | HP MMU?
        !          1857:        jeq     Lhpmmu5                 | yes, skip
        !          1858:        movl    sp@(4),a0               | get addr to flush
        !          1859: #if defined(HP360) || defined(HP370)
        !          1860:        jpl     Lmc68851b               | is 68851?
        !          1861:        .long   0xf0103810              | pflush #0,#0,a0@
        !          1862:        movl    #DC_CLEAR,d0
        !          1863:        movc    d0,cacr                 | invalidate on-chip data cache
        !          1864:        rts
        !          1865: Lmc68851b:
        !          1866: #endif
        !          1867:        .long   0xf0103c10              | pflushs #0,#0,a0@
        !          1868:        rts
        !          1869: Lhpmmu5:
        !          1870: #endif
        !          1871: #if defined(HP320) || defined(HP350)
        !          1872:        movl    sp@(4),d0               | VA to invalidate
        !          1873:        bclr    #0,d0                   | ensure even
        !          1874:        movl    d0,a0
        !          1875:        movw    sr,d1                   | go critical
        !          1876:        movw    #PSL_HIGHIPL,sr         |   while in purge space
        !          1877:        moveq   #FC_PURGE,d0            | change address space
        !          1878:        movc    d0,dfc                  |   for destination
        !          1879:        moveq   #0,d0                   | zero to invalidate?
        !          1880:        movsl   d0,a0@                  | hit it
        !          1881:        moveq   #FC_USERD,d0            | back to old
        !          1882:        movc    d0,dfc                  |   address space
        !          1883:        movw    d1,sr                   | restore IPL
        !          1884: #endif
        !          1885:        rts
        !          1886: 
        !          1887: /*
        !          1888:  * Invalidate supervisor side of TLB
        !          1889:  */
        !          1890: ENTRY(TBIAS)
        !          1891: #ifdef DEBUG
        !          1892:        tstl    fullflush               | being conservative?
        !          1893:        jne     __TBIA                  | yes, flush everything
        !          1894: #endif
        !          1895: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          1896:        tstl    _mmutype                | HP MMU?
        !          1897:        jeq     Lhpmmu7                 | yes, skip
        !          1898: #if defined(HP360) || defined(HP370)
        !          1899:        jpl     Lmc68851c               | 68851?
        !          1900:        .long   0xf0003094              | pflush #4,#4
        !          1901:        movl    #DC_CLEAR,d0
        !          1902:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          1903:        rts
        !          1904: Lmc68851c:
        !          1905: #endif
        !          1906:        .long   0xf0003494              | pflushs #4,#4
        !          1907:        rts
        !          1908: Lhpmmu7:
        !          1909: #endif
        !          1910: #if defined(HP320) || defined(HP350)
        !          1911:        movl    #0x8000,d0              | more
        !          1912:        movl    d0,_IObase+MMUTBINVAL   |   HP magic
        !          1913:        jra     __DCIS                  | XXX: invalidate entire sup. cache
        !          1914: #endif
        !          1915:        rts
        !          1916: 
        !          1917: /*
        !          1918:  * Invalidate user side of TLB
        !          1919:  */
        !          1920: ENTRY(TBIAU)
        !          1921: #ifdef DEBUG
        !          1922:        tstl    fullflush               | being conservative?
        !          1923:        jne     __TBIA                  | yes, flush everything
        !          1924: #endif
        !          1925: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          1926:        tstl    _mmutype                | HP MMU?
        !          1927:        jeq     Lhpmmu8                 | yes, skip
        !          1928: #if defined(HP360) || defined(HP370)
        !          1929:        jpl     Lmc68851d               | 68851?
        !          1930:        .long   0xf0003090              | pflush #0,#4
        !          1931:        movl    #DC_CLEAR,d0
        !          1932:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          1933:        rts
        !          1934: Lmc68851d:
        !          1935: #endif
        !          1936:        .long   0xf0003490              | pflushs #0,#4
        !          1937:        rts
        !          1938: Lhpmmu8:
        !          1939: #endif
        !          1940: #if defined(HP320) || defined(HP350)
        !          1941:        moveq   #0,d0                   | more
        !          1942:        movl    d0,_IObase+MMUTBINVAL   |   HP magic
        !          1943:        jra     __DCIU                  | XXX: invalidate entire user cache
        !          1944: #endif
        !          1945:        rts
        !          1946: 
        !          1947: /*
        !          1948:  * Invalidate instruction cache
        !          1949:  */
        !          1950: ENTRY(ICIA)
        !          1951:        movl    #IC_CLEAR,d0
        !          1952:        movc    d0,cacr                 | invalidate i-cache
        !          1953:        rts
        !          1954: 
        !          1955: /*
        !          1956:  * Invalidate data cache.
        !          1957:  * HP external cache allows for invalidation of user/supervisor portions.
        !          1958:  */
        !          1959: ENTRY(DCIA)
        !          1960: __DCIA:
        !          1961: #if defined(HP360) || defined(HP370)
        !          1962:        movl    #DC_CLEAR,d0
        !          1963:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          1964: #endif
        !          1965: #if defined(HP320) || defined(HP350)
        !          1966:        tstl    _ectype                 | got external VAC?
        !          1967:        jle     Lnocache2               | no, all done
        !          1968:        movl    #_IObase+MMUCMD,a0      | MMU control reg
        !          1969:        andl    #~MMU_CEN,a0@           | disable cache
        !          1970:        orl     #MMU_CEN,a0@            | reenable cache
        !          1971: Lnocache2:
        !          1972: #endif
        !          1973:        rts
        !          1974: 
        !          1975: ENTRY(DCIS)
        !          1976: __DCIS:
        !          1977: #if defined(HP360) || defined(HP370)
        !          1978:        movl    #DC_CLEAR,d0
        !          1979:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          1980: #endif
        !          1981: #if defined(HP320) || defined(HP350)
        !          1982:        tstl    _ectype                 | got external VAC?
        !          1983:        jle     Lnocache3               | no, all done
        !          1984:        movl    _IObase+MMUSSTP,d0      | read the supervisor STP
        !          1985:        movl    d0,_IObase+MMUSSTP      | write it back
        !          1986: Lnocache3:
        !          1987: #endif
        !          1988:        rts
        !          1989: 
        !          1990: ENTRY(DCIU)
        !          1991: __DCIU:
        !          1992: #if defined(HP360) || defined(HP370)
        !          1993:        movl    #DC_CLEAR,d0
        !          1994:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          1995: #endif
        !          1996: #if defined(HP320) || defined(HP350)
        !          1997:        tstl    _ectype                 | got external VAC?
        !          1998:        jle     Lnocache4               | no, all done
        !          1999:        movl    _IObase+MMUUSTP,d0      | read the user STP
        !          2000:        movl    d0,_IObase+MMUUSTP      | write it back
        !          2001: Lnocache4:
        !          2002: #endif
        !          2003:        rts
        !          2004: 
        !          2005: #if defined(HP370)
        !          2006: ENTRY(PCIA)
        !          2007:        tstl    _ectype                 | got external PAC?
        !          2008:        jge     Lnocache6               | no, all done
        !          2009:        movl    #_IObase+MMUCMD,a0      | MMU control reg
        !          2010:        andl    #~MMU_CEN,a0@           | disable cache
        !          2011:        orl     #MMU_CEN,a0@            | reenable cache
        !          2012: Lnocache6:
        !          2013:        rts
        !          2014: #endif
        !          2015: 
        !          2016: ENTRY(ecacheon)
        !          2017:        tstl    _ectype
        !          2018:        jeq     Lnocache7
        !          2019:        movl    #_IObase+MMUCMD,a0
        !          2020:        orl     #MMU_CEN,a0@
        !          2021: Lnocache7:
        !          2022:        rts
        !          2023: 
        !          2024: ENTRY(ecacheoff)
        !          2025:        tstl    _ectype
        !          2026:        jeq     Lnocache8
        !          2027:        movl    #_IObase+MMUCMD,a0
        !          2028:        andl    #~MMU_CEN,a0@
        !          2029: Lnocache8:
        !          2030:        rts
        !          2031: 
        !          2032:        .globl  _getsfc, _getdfc
        !          2033: _getsfc:
        !          2034:        movc    sfc,d0
        !          2035:        rts
        !          2036: _getdfc:
        !          2037:        movc    dfc,d0
        !          2038:        rts
        !          2039: 
        !          2040: /*
        !          2041:  * Load a new user segment table pointer.
        !          2042:  */
        !          2043: ENTRY(loadustp)
        !          2044: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          2045:        tstl    _mmutype                | HP MMU?
        !          2046:        jeq     Lhpmmu9                 | yes, skip
        !          2047:        movl    sp@(4),d0               | new USTP
        !          2048:        moveq   #PGSHIFT,d1
        !          2049:        lsll    d1,d0                   | convert to addr
        !          2050:        lea     _protorp,a0             | CRP prototype
        !          2051:        movl    d0,a0@(4)               | stash USTP
        !          2052:        .long   0xf0104C00              | pmove a0@,crp
        !          2053:        movl    #DC_CLEAR,d0
        !          2054:        movc    d0,cacr                 | invalidate on-chip d-cache
        !          2055:        rts                             |   since pmove flushes TLB
        !          2056: Lhpmmu9:
        !          2057: #endif
        !          2058: #if defined(HP320) || defined(HP350)
        !          2059:        movl    sp@(4),_IObase+MMUUSTP  | load a new USTP
        !          2060: #endif
        !          2061:        rts
        !          2062: 
        !          2063: /*
        !          2064:  * Flush any hardware context associated with given USTP.
        !          2065:  * Only does something for HP330 where we must flush RPT
        !          2066:  * and ATC entries in PMMU.
        !          2067:  */
        !          2068: ENTRY(flushustp)
        !          2069: #if defined(HP330)
        !          2070:        tstl    _mmutype                | 68851 PMMU?
        !          2071:        jle     Lnot68851               | no, nothing to do
        !          2072:        movl    sp@(4),d0               | get USTP to flush
        !          2073:        moveq   #PGSHIFT,d1
        !          2074:        lsll    d1,d0                   | convert to address
        !          2075:        movl    d0,_protorp+4           | stash USTP
        !          2076:        .long   0xf039a000,_protorp     | pflushr _protorp
        !          2077: Lnot68851:
        !          2078: #endif
        !          2079:        rts
        !          2080: 
        !          2081: ENTRY(ploadw)
        !          2082: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          2083:        movl    sp@(4),a0               | address to load
        !          2084:        .long   0xf0102011              | pload #1,a0@
        !          2085: #endif
        !          2086:        rts
        !          2087: 
        !          2088: /*
        !          2089:  * Set processor priority level calls.  Most could (should) be replaced
        !          2090:  * by inline asm expansions.  However, SPL0 and SPLX require special
        !          2091:  * handling.  If we are returning to the base processor priority (SPL0)
        !          2092:  * we need to check for our emulated software interrupts.
        !          2093:  */
        !          2094: 
        !          2095: ENTRY(spl0)
        !          2096:        moveq   #0,d0
        !          2097:        movw    sr,d0                   | get old SR for return
        !          2098:        movw    #PSL_LOWIPL,sr          | restore new SR
        !          2099:        jra     Lsplsir
        !          2100: 
        !          2101: ENTRY(splx)
        !          2102:        moveq   #0,d0
        !          2103:        movw    sr,d0                   | get current SR for return
        !          2104:        movw    sp@(6),d1               | get new value
        !          2105:        movw    d1,sr                   | restore new SR
        !          2106:        andw    #PSL_IPL7,d1            | mask all but PSL_IPL
        !          2107:        jne     Lspldone                | non-zero, all done
        !          2108: Lsplsir:
        !          2109:        tstb    _ssir                   | software interrupt pending?
        !          2110:        jeq     Lspldone                | no, all done
        !          2111:        subql   #4,sp                   | make room for RTE frame
        !          2112:        movl    sp@(4),sp@(2)           | position return address
        !          2113:        clrw    sp@(6)                  | set frame type 0
        !          2114:        movw    #PSL_LOWIPL,sp@         | and new SR
        !          2115:        jra     Lgotsir                 | go handle it
        !          2116: Lspldone:
        !          2117:        rts
        !          2118: 
        !          2119: ALTENTRY(splsoftclock, _spl1)
        !          2120: ALTENTRY(splnet, _spl1)
        !          2121: ENTRY(spl1)
        !          2122:        moveq   #0,d0
        !          2123:        movw    sr,d0
        !          2124:        movw    #SPL1,sr
        !          2125:        rts
        !          2126: 
        !          2127: ENTRY(spl2)
        !          2128:        moveq   #0,d0
        !          2129:        movw    sr,d0
        !          2130:        movw    #SPL2,sr
        !          2131:        rts
        !          2132: 
        !          2133: ENTRY(spl3)
        !          2134:        moveq   #0,d0
        !          2135:        movw    sr,d0
        !          2136:        movw    #SPL3,sr
        !          2137:        rts
        !          2138: 
        !          2139: ENTRY(spl4)
        !          2140:        moveq   #0,d0
        !          2141:        movw    sr,d0
        !          2142:        movw    #SPL4,sr
        !          2143:        rts
        !          2144: 
        !          2145: ALTENTRY(splimp, _spl5)
        !          2146: ALTENTRY(splbio, _spl5)
        !          2147: ALTENTRY(spltty, _spl5)
        !          2148: ENTRY(spl5)
        !          2149:        moveq   #0,d0
        !          2150:        movw    sr,d0
        !          2151:        movw    #SPL5,sr
        !          2152:        rts
        !          2153: 
        !          2154: ALTENTRY(splclock, _spl6)
        !          2155: ENTRY(spl6)
        !          2156:        moveq   #0,d0
        !          2157:        movw    sr,d0
        !          2158:        movw    #SPL6,sr
        !          2159:        rts
        !          2160: 
        !          2161: ALTENTRY(splhigh, _spl7)
        !          2162: ENTRY(spl7)
        !          2163:        moveq   #0,d0
        !          2164:        movw    sr,d0
        !          2165:        movw    #PSL_HIGHIPL,sr
        !          2166:        rts
        !          2167: 
        !          2168: #ifdef GPROF
        !          2169: /*
        !          2170:  * Special versions of splhigh and splx called by mcount().
        !          2171:  * Note that __splx does not check for software interrupts.
        !          2172:  */
        !          2173:        .globl  __splhigh, __splx
        !          2174: __splhigh:
        !          2175:        moveq   #0,d0
        !          2176:        movw    sr,d0
        !          2177:        movw    #PSL_HIGHIPL,sr
        !          2178:        rts
        !          2179: 
        !          2180: __splx:
        !          2181:        moveq   #0,d0
        !          2182:        movw    sr,d0                   | get current SR for return
        !          2183:        movw    sp@(6),d1               | get new value
        !          2184:        movw    d1,sr                   | restore new SR
        !          2185:        rts
        !          2186: #endif
        !          2187: 
        !          2188: ENTRY(_insque)
        !          2189:        movw    sr,d0
        !          2190:        movw    #PSL_HIGHIPL,sr         | atomic
        !          2191:        movl    sp@(8),a0               | where to insert (after)
        !          2192:        movl    sp@(4),a1               | element to insert (e)
        !          2193:        movl    a0@,a1@                 | e->next = after->next
        !          2194:        movl    a0,a1@(4)               | e->prev = after
        !          2195:        movl    a1,a0@                  | after->next = e
        !          2196:        movl    a1@,a0
        !          2197:        movl    a1,a0@(4)               | e->next->prev = e
        !          2198:        movw    d0,sr
        !          2199:        rts
        !          2200: 
        !          2201: ENTRY(_remque)
        !          2202:        movw    sr,d0
        !          2203:        movw    #PSL_HIGHIPL,sr         | atomic
        !          2204:        movl    sp@(4),a0               | element to remove (e)
        !          2205:        movl    a0@,a1
        !          2206:        movl    a0@(4),a0
        !          2207:        movl    a0,a1@(4)               | e->next->prev = e->prev
        !          2208:        movl    a1,a0@                  | e->prev->next = e->next
        !          2209:        movw    d0,sr
        !          2210:        rts
        !          2211: 
        !          2212: ALTENTRY(blkclr, _bzero)
        !          2213: ENTRY(bzero)
        !          2214:        movl    sp@(4),a0
        !          2215:        movl    sp@(8),d0
        !          2216:        jeq     1$
        !          2217:        movl    a0,d1
        !          2218:        btst    #0,d1
        !          2219:        jeq     2$
        !          2220:        clrb    a0@+
        !          2221:        subql   #1,d0
        !          2222:        jeq     1$
        !          2223: 2$:
        !          2224:        movl    d0,d1
        !          2225:        andl    #31,d0
        !          2226:        lsrl    #5,d1
        !          2227:        jeq     3$
        !          2228: 4$:
        !          2229:        clrl    a0@+; clrl      a0@+; clrl      a0@+; clrl      a0@+;
        !          2230:        clrl    a0@+; clrl      a0@+; clrl      a0@+; clrl      a0@+;
        !          2231:        subql   #1,d1
        !          2232:        jne     4$
        !          2233:        tstl    d0
        !          2234:        jeq     1$
        !          2235: 3$:
        !          2236:        clrb    a0@+
        !          2237:        subql   #1,d0
        !          2238:        jne     3$
        !          2239: 1$:
        !          2240:        rts
        !          2241: 
        !          2242: /*
        !          2243:  * strlen(str)
        !          2244:  */
        !          2245: ENTRY(strlen)
        !          2246:        moveq   #-1,d0
        !          2247:        movl    sp@(4),a0       | string
        !          2248: Lslloop:
        !          2249:        addql   #1,d0           | increment count
        !          2250:        tstb    a0@+            | null?
        !          2251:        jne     Lslloop         | no, keep going
        !          2252:        rts
        !          2253: 
        !          2254: /*
        !          2255:  * bcmp(s1, s2, len)
        !          2256:  *
        !          2257:  * WARNING!  This guy only works with counts up to 64K
        !          2258:  */
        !          2259: ENTRY(bcmp)
        !          2260:        movl    sp@(4),a0               | string 1
        !          2261:        movl    sp@(8),a1               | string 2
        !          2262:        moveq   #0,d0
        !          2263:        movw    sp@(14),d0              | length
        !          2264:        jeq     Lcmpdone                | if zero, nothing to do
        !          2265:        subqw   #1,d0                   | set up for DBcc loop
        !          2266: Lcmploop:
        !          2267:        cmpmb   a0@+,a1@+               | equal?
        !          2268:        dbne    d0,Lcmploop             | yes, keep going
        !          2269:        addqw   #1,d0                   | +1 gives zero on match
        !          2270: Lcmpdone:
        !          2271:        rts
        !          2272:        
        !          2273: /*
        !          2274:  * {ov}bcopy(from, to, len)
        !          2275:  *
        !          2276:  * Works for counts up to 128K.
        !          2277:  */
        !          2278: ALTENTRY(ovbcopy, _bcopy)
        !          2279: ENTRY(bcopy)
        !          2280:        movl    sp@(12),d0              | get count
        !          2281:        jeq     Lcpyexit                | if zero, return
        !          2282:        movl    sp@(4),a0               | src address
        !          2283:        movl    sp@(8),a1               | dest address
        !          2284:        cmpl    a1,a0                   | src before dest?
        !          2285:        jlt     Lcpyback                | yes, copy backwards (avoids overlap)
        !          2286:        movl    a0,d1
        !          2287:        btst    #0,d1                   | src address odd?
        !          2288:        jeq     Lcfeven                 | no, go check dest
        !          2289:        movb    a0@+,a1@+               | yes, copy a byte
        !          2290:        subql   #1,d0                   | update count
        !          2291:        jeq     Lcpyexit                | exit if done
        !          2292: Lcfeven:
        !          2293:        movl    a1,d1
        !          2294:        btst    #0,d1                   | dest address odd?
        !          2295:        jne     Lcfbyte                 | yes, must copy by bytes
        !          2296:        movl    d0,d1                   | no, get count
        !          2297:        lsrl    #2,d1                   | convert to longwords
        !          2298:        jeq     Lcfbyte                 | no longwords, copy bytes
        !          2299:        subql   #1,d1                   | set up for dbf
        !          2300: Lcflloop:
        !          2301:        movl    a0@+,a1@+               | copy longwords
        !          2302:        dbf     d1,Lcflloop             | til done
        !          2303:        andl    #3,d0                   | get remaining count
        !          2304:        jeq     Lcpyexit                | done if none
        !          2305: Lcfbyte:
        !          2306:        subql   #1,d0                   | set up for dbf
        !          2307: Lcfbloop:
        !          2308:        movb    a0@+,a1@+               | copy bytes
        !          2309:        dbf     d0,Lcfbloop             | til done
        !          2310: Lcpyexit:
        !          2311:        rts
        !          2312: Lcpyback:
        !          2313:        addl    d0,a0                   | add count to src
        !          2314:        addl    d0,a1                   | add count to dest
        !          2315:        movl    a0,d1
        !          2316:        btst    #0,d1                   | src address odd?
        !          2317:        jeq     Lcbeven                 | no, go check dest
        !          2318:        movb    a0@-,a1@-               | yes, copy a byte
        !          2319:        subql   #1,d0                   | update count
        !          2320:        jeq     Lcpyexit                | exit if done
        !          2321: Lcbeven:
        !          2322:        movl    a1,d1
        !          2323:        btst    #0,d1                   | dest address odd?
        !          2324:        jne     Lcbbyte                 | yes, must copy by bytes
        !          2325:        movl    d0,d1                   | no, get count
        !          2326:        lsrl    #2,d1                   | convert to longwords
        !          2327:        jeq     Lcbbyte                 | no longwords, copy bytes
        !          2328:        subql   #1,d1                   | set up for dbf
        !          2329: Lcblloop:
        !          2330:        movl    a0@-,a1@-               | copy longwords
        !          2331:        dbf     d1,Lcblloop             | til done
        !          2332:        andl    #3,d0                   | get remaining count
        !          2333:        jeq     Lcpyexit                | done if none
        !          2334: Lcbbyte:
        !          2335:        subql   #1,d0                   | set up for dbf
        !          2336: Lcbbloop:
        !          2337:        movb    a0@-,a1@-               | copy bytes
        !          2338:        dbf     d0,Lcbbloop             | til done
        !          2339:        rts
        !          2340: 
        !          2341: /*
        !          2342:  * Emulate fancy VAX string operations:
        !          2343:  *     scanc(count, startc, table, mask)
        !          2344:  *     skpc(mask, count, startc)
        !          2345:  *     locc(mask, count, startc)
        !          2346:  */
        !          2347: ENTRY(scanc)
        !          2348:        movl    sp@(4),d0       | get length
        !          2349:        jeq     Lscdone         | nothing to do, return
        !          2350:        movl    sp@(8),a0       | start of scan
        !          2351:        movl    sp@(12),a1      | table to compare with
        !          2352:        movb    sp@(19),d1      | and mask to use
        !          2353:        movw    d2,sp@-         | need a scratch register
        !          2354:        clrw    d2              | clear it out
        !          2355:        subqw   #1,d0           | adjust for dbra
        !          2356: Lscloop:
        !          2357:        movb    a0@+,d2         | get character
        !          2358:        movb    a1@(0,d2:w),d2  | get table entry
        !          2359:        andb    d1,d2           | mask it
        !          2360:        dbne    d0,Lscloop      | keep going til no more or non-zero
        !          2361:        addqw   #1,d0           | overshot by one
        !          2362:        movw    sp@+,d2         | restore scratch
        !          2363: Lscdone:
        !          2364:        rts
        !          2365: 
        !          2366: ENTRY(skpc)
        !          2367:        movl    sp@(8),d0       | get length
        !          2368:        jeq     Lskdone         | nothing to do, return
        !          2369:        movb    sp@(7),d1       | mask to use
        !          2370:        movl    sp@(12),a0      | where to start
        !          2371:        subqw   #1,d0           | adjust for dbcc
        !          2372: Lskloop:
        !          2373:        cmpb    a0@+,d1         | compate with mask
        !          2374:        dbne    d0,Lskloop      | keep going til no more or zero
        !          2375:        addqw   #1,d0           | overshot by one
        !          2376: Lskdone:
        !          2377:        rts
        !          2378: 
        !          2379: ENTRY(locc)
        !          2380:        movl    sp@(8),d0       | get length
        !          2381:        jeq     Llcdone         | nothing to do, return
        !          2382:        movb    sp@(7),d1       | mask to use
        !          2383:        movl    sp@(12),a0      | where to start
        !          2384:        subqw   #1,d0           | adjust for dbcc
        !          2385: Llcloop:
        !          2386:        cmpb    a0@+,d1         | compate with mask
        !          2387:        dbeq    d0,Llcloop      | keep going til no more or non-zero
        !          2388:        addqw   #1,d0           | overshot by one
        !          2389: Llcdone:
        !          2390:        rts
        !          2391: 
        !          2392: /*
        !          2393:  * Emulate VAX FFS (find first set) instruction.
        !          2394:  */
        !          2395: ENTRY(ffs)
        !          2396:        moveq   #-1,d0
        !          2397:        movl    sp@(4),d1
        !          2398:        beq     Lffsdone
        !          2399: Lffsloop:
        !          2400:        addql   #1,d0
        !          2401:        btst    d0,d1
        !          2402:        beq     Lffsloop
        !          2403: Lffsdone:
        !          2404:        addql   #1,d0
        !          2405:        rts
        !          2406: 
        !          2407: #ifdef FPCOPROC
        !          2408: /*
        !          2409:  * Save and restore 68881 state.
        !          2410:  * Pretty awful looking since our assembler does not
        !          2411:  * recognize FP mnemonics.
        !          2412:  */
        !          2413: ENTRY(m68881_save)
        !          2414:        movl    sp@(4),a0               | save area pointer
        !          2415:        .word   0xf310                  | fsave a0@
        !          2416:        tstb    a0@                     | null state frame?
        !          2417:        jeq     Lm68881sdone            | yes, all done
        !          2418:        .word   0xf228,0xf0ff,0x00d8    | fmovem fp0-fp7,a0@(216)
        !          2419:        .word   0xf228,0xbc00,0x0138    | fmovem fpcr/fpsr/fpiar,a0@(312)
        !          2420: Lm68881sdone:
        !          2421:        rts
        !          2422: 
        !          2423: ENTRY(m68881_restore)
        !          2424:        movl    sp@(4),a0               | save area pointer
        !          2425:        tstb    a0@                     | null state frame?
        !          2426:        jeq     Lm68881rdone            | yes, easy
        !          2427:        .word   0xf228,0x9c00,0x0138    | fmovem a0@(312),fpcr/fpsr/fpiar
        !          2428:        .word   0xf228,0xd0ff,0x00d8    | fmovem a0@(216),fp0-fp7
        !          2429: Lm68881rdone:
        !          2430:        .word   0xf350                  | frestore a0@
        !          2431:        rts
        !          2432: #endif
        !          2433: 
        !          2434: /*
        !          2435:  * Handle the nitty-gritty of rebooting the machine.
        !          2436:  * Basically we just turn off the MMU and jump to the appropriate ROM routine.
        !          2437:  * Note that we must be running in an address range that is mapped one-to-one
        !          2438:  * logical to physical so that the PC is still valid immediately after the MMU
        !          2439:  * is turned off.
        !          2440:  */
        !          2441:        .globl  _doboot
        !          2442: _doboot:
        !          2443:        movl    #CACHE_OFF,d0
        !          2444:        movc    d0,cacr                 | disable on-chip cache(s)
        !          2445: #if defined(HP320) || defined(HP350) || defined(HP370)
        !          2446:        tstl    _ectype
        !          2447:        jeq     Lnocache5
        !          2448:        andl    #~MMU_CEN,_IObase+MMUCMD| disable external cache
        !          2449: Lnocache5:
        !          2450: #endif
        !          2451: /* one-to-one map the last page of memory */
        !          2452:        movl    #MAXADDR,d0             | last page of RAM used to pass params
        !          2453:        orl     #PG_RW+PG_V,d0          | create a PTE
        !          2454:        movl    d0,_mmap                |   to access that page
        !          2455:        jbsr    _TBIA                   | invalidate TLB
        !          2456:        movl    #MAXADDR,d0             | last page of RAM is also used
        !          2457:        orl     #SG_RW+SG_V,d0          |   as the page table for itself
        !          2458:        movl    d0,eSysseg-4            |   (ok since it needs only last word)
        !          2459:        movl    _vmmap+NBPG-4,d2        | save old contents
        !          2460:        movl    _mmap,_vmmap+NBPG-4     | store PTE in new page table
        !          2461:        jbsr    _TBIA                   | invalidate again
        !          2462:        lea     MAXADDR,a0              | can now access last page
        !          2463:        movl    _boothowto,a0@+         | store howto
        !          2464:        movl    _bootdev,a0@+           | and devtype
        !          2465:        lea     Lbootcode,a1            | start of boot code
        !          2466:        lea     Lebootcode,a3           | end of boot code
        !          2467: Lbootcopy:
        !          2468:        movw    a1@+,a0@+               | copy a word
        !          2469:        cmpl    a3,a1                   | done yet?
        !          2470:        jcs     Lbootcopy               | no, keep going
        !          2471:        jmp     MAXADDR+8               | jump to last page
        !          2472: 
        !          2473: Lbootcode:
        !          2474:        lea     MAXADDR+0x800,sp        | physical SP in case of NMI
        !          2475: #if defined(HP330) || defined(HP360) || defined(HP370)
        !          2476:        tstl    _mmutype                | HP MMU?
        !          2477:        jeq     LhpmmuB                 | yes, skip
        !          2478:        movl    #0,a0@                  | value for pmove to TC (turn off MMU)
        !          2479:        .long   0xf0104000              | pmove a0@,tc
        !          2480:        movl    d2,MAXADDR+NBPG-4       | restore old high page contents
        !          2481:        jmp     0x1A4                   | goto REQ_REBOOT
        !          2482: LhpmmuB:
        !          2483: #endif
        !          2484: #if defined(HP320) || defined(HP350)
        !          2485:        movl    #0xFFFF0000,_IObase+MMUCMD      | totally disable MMU
        !          2486:        movl    d2,MAXADDR+NBPG-4       | restore old high page contents
        !          2487:        jmp     0x1A4                   | goto REQ_REBOOT
        !          2488: #endif
        !          2489: Lebootcode:
        !          2490: 
        !          2491:        .data
        !          2492:        .space  NBPG
        !          2493: tmpstk:
        !          2494:        .globl  _machineid
        !          2495: _machineid:
        !          2496:        .long   0               | default to 320
        !          2497:        .globl  _mmutype,_protorp
        !          2498: _mmutype:
        !          2499:        .long   0               | default to HP MMU
        !          2500: _protorp:
        !          2501:        .long   0,0             | prototype root pointer
        !          2502:        .globl  _ectype
        !          2503: _ectype:
        !          2504:        .long   0               | external cache type, default to none
        !          2505:        .globl  _cold
        !          2506: _cold:
        !          2507:        .long   1               | cold start flag
        !          2508: #ifdef DEBUG
        !          2509:        .globl  fullflush
        !          2510: fullflush:
        !          2511:        .long   0
        !          2512:        .globl  timebomb
        !          2513: timebomb:
        !          2514:        .long   0
        !          2515: #endif
        !          2516: /* interrupt counters */
        !          2517:        .globl  _intrcnt,_eintrcnt,_intrnames,_eintrnames
        !          2518: _intrnames:
        !          2519:        .asciz  "spur"
        !          2520:        .asciz  "hil"
        !          2521:        .asciz  "lev2"
        !          2522:        .asciz  "lev3"
        !          2523:        .asciz  "lev4"
        !          2524:        .asciz  "lev5"
        !          2525:        .asciz  "dma"
        !          2526:        .asciz  "clock"
        !          2527: #ifdef PROFTIMER
        !          2528:        .asciz  "pclock"
        !          2529: #endif
        !          2530:        .asciz  "nmi"
        !          2531: _eintrnames:
        !          2532:        .even
        !          2533: _intrcnt:
        !          2534: #ifdef PROFTIMER
        !          2535:        .long   0,0,0,0,0,0,0,0,0,0
        !          2536: #else
        !          2537:        .long   0,0,0,0,0,0,0,0,0
        !          2538: #endif
        !          2539: _eintrcnt:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.