Annotation of researchv9/sys/sun3/vax.s, revision 1.1.1.1

1.1       root        1:        .data
                      2:        .asciz  "@(#)vax.s 1.1 86/02/03 Copyr 1986 Sun Micro"
                      3:        .even
                      4:        .text
                      5: /*
                      6:  * Copyright (c) 1986 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: /*
                     10:  * Emulate VAX instructions on the 68020.
                     11:  */
                     12: 
                     13: #include "../h/param.h"
                     14: #include "../machine/asm_linkage.h"
                     15: #include "../machine/mmu.h"
                     16: #include "../machine/psl.h"
                     17: #include "assym.s"
                     18: 
                     19: /*
                     20:  * Macro to raise prio level,
                     21:  * avoid dropping prio if already at high level.
                     22:  * NOTE - Assumes that we are never in "master" mode.
                     23:  */
                     24: #define        RAISE(level)    \
                     25:        movw    sr,d0;  \
                     26:        andw    #(SR_SMODE+SR_INTPRI),d0;       \
                     27:        cmpw    #(SR_SMODE+(/**/level*0x100)),d0;       \
                     28:        jge     0f;     \
                     29:        movw    #(SR_SMODE+(/**/level*0x100)),sr;       \
                     30: 0:     rts
                     31: 
                     32: #define        SETPRI(level)   \
                     33:        movw    sr,d0;  \
                     34:        movw    #(SR_SMODE+(/**/level*0x100)),sr;       \
                     35:        rts
                     36: 
                     37:        ENTRY(splimp)
                     38:        RAISE(3)
                     39: 
                     40:        ENTRY(splnet)
                     41:        RAISE(1)
                     42: 
                     43:        ENTRY(splie)
                     44:        RAISE(3)
                     45: 
                     46:        ENTRY(splclock)
                     47:        RAISE(5)
                     48: 
                     49:        ENTRY(splzs)
                     50:        SETPRI(6)
                     51: 
                     52:        ENTRY(spl7)
                     53:        SETPRI(7)
                     54: 
                     55:        ENTRY2(spl6,spl5)
                     56:        SETPRI(5)
                     57: 
                     58:        ENTRY(spl4)
                     59:        SETPRI(4)
                     60: 
                     61:        ENTRY(spl3)
                     62:        SETPRI(3)
                     63: 
                     64:        ENTRY(spl2)
                     65:        SETPRI(2)
                     66: 
                     67:        ENTRY(spl1)
                     68:        SETPRI(1)
                     69: 
                     70:        ENTRY(spl0)
                     71:        SETPRI(0)
                     72: 
                     73:        ENTRY(splx)
                     74:        movw    sr,d0
                     75:        movw    sp@(6),sr
                     76:        rts
                     77: 
                     78:        ENTRY(insque)
                     79:        movl    sp@(4),a0
                     80:        movl    sp@(8),a1
                     81:        movl    a1@,a0@
                     82:        movl    a1,a0@(4)
                     83:        movl    a0,a1@
                     84:        movl    a0@,a1
                     85:        movl    a0,a1@(4)
                     86:        rts
                     87: 
                     88:        ENTRY(remque)
                     89:        movl    sp@(4),a0
                     90:        movl    a0@,a1
                     91:        movl    a0@(4),a0
                     92:        movl    a1,a0@
                     93:        movl    a0,a1@(4)
                     94:        rts
                     95: 
                     96:        ENTRY(scanc)
                     97:        movl    sp@(8),a0       | string
                     98:        movl    sp@(12),a1      | table
                     99:        movl    sp@(16),d1      | mask
                    100:        movl    d2,sp@-
                    101:        clrw    d2
                    102:        movl    sp@(8),d0       | len
                    103:        subqw   #1,d0           | subtract one for dbxx
                    104:        jmi     1f
                    105: 2:
                    106:        movb    a0@+,d2         | get the byte from the string
                    107:        movb    a1@(0,d2:w),d2  | get the corresponding table entry
                    108:        andb    d1,d2           | apply the mask
                    109:        dbne    d0,2b           | check for loop termination
                    110: 1:
                    111:        addqw   #1,d0           | dbxx off by one
                    112:        movl    sp@+,d2
                    113:        rts
                    114: 
                    115: /*
                    116:  * _whichqs tells which of the 32 queues _qs have processes in them
                    117:  * setrq puts processes into queues, remrq removes them from queues
                    118:  * The running process is on no queue, other processes are on a
                    119:  * queue related to p->p_pri, divided by 4 actually to shrink the
                    120:  * 0-127 range of priorities into the 32 available queues.
                    121:  */
                    122: 
                    123: /*
                    124:  * setrq(p), using semi-fancy 68020 instructions.
                    125:  *
                    126:  * Call should be made at spl6(), and p->p_stat should be SRUN
                    127:  */
                    128:        ENTRY(setrq)
                    129:        movl    sp@(4),a0       | get proc pointer
                    130:        tstl    a0@(P_RLINK)    | firewall: p->p_rlink must be 0
                    131:        jne     1f
                    132:        moveq   #31,d1
                    133:        clrl    d0
                    134:        movb    a0@(P_PRI),d0   | get the priority
                    135:        lsrl    #2,d0           | divide by 4
                    136:        subl    d0,d1
                    137:        lea     _qs,a1
                    138:        movl    a1@(4,d1:l:8),a1| qs[d1].ph_rlink, 8 == sizeof (qs[0])
                    139:        movl    a1@,a0@         | insque(p, blah)
                    140:        movl    a1,a0@(4)
                    141:        movl    a0,a1@
                    142:        movl    a0@,a1
                    143:        movl    a0,a1@(4)
                    144:        bfset   _whichqs{d0:#1} | set appropriate bit in whichqs
                    145:        rts
                    146: 1:
                    147:        pea     2f
                    148:        jsr     _panic
                    149: 
                    150: 2:     .asciz  "setrq"
                    151:        .even
                    152: 
                    153: /*
                    154:  * remrq(p), using semi-fancy 68020 instructions
                    155:  *
                    156:  * Call should be made at spl6().
                    157:  */
                    158:        ENTRY(remrq)
                    159:        movl    sp@(4),a0
                    160:        clrl    d0
                    161:        movb    a0@(P_PRI),d0
                    162:        lsrl    #2,d0           | divide by 4
                    163:        bftst   _whichqs{d0:#1}
                    164:        jeq     1f
                    165:        movl    a0@,a1          | remque(p);
                    166:        movl    a0@(4),a0
                    167:        movl    a1,a0@
                    168:        movl    a0,a1@(4)
                    169:        cmpl    a0,a1
                    170:        jne     2f              | queue not empty
                    171:        bfclr   _whichqs{d0:#1} | queue empty, clear the bit
                    172: 2:
                    173:        movl    sp@(4),a0
                    174:        clrl    a0@(P_RLINK)
                    175:        rts
                    176: 1:
                    177:        pea     3f
                    178:        jsr     _panic
                    179: 
                    180: 3:     .asciz  "remrq"
                    181:        .even
                    182: 
                    183: /*
                    184:  * swtch(), using semi-fancy 68020 instructions
                    185:  */
                    186:        ENTRY(swtch)
                    187:        movw    sr,sp@-         | save processor priority
                    188:        movl    #1,_noproc
                    189:        clrl    _runrun
                    190:        bclr    #AST_SCHED_BIT-24,_u+PCB_P0LR
                    191: 2:
                    192:        bfffo   _whichqs{#0:#32},d0 | test if any bit on
                    193:        cmpl    #32,d0
                    194:        jne     3f              | found one
                    195:        stop    #SR_LOW         | must allow interrupts here
                    196: 
                    197:        .globl  idle
                    198: idle:                          | wait here for interrupts
                    199:        jra     2b              | try again
                    200: 
                    201: 3:
                    202:        movw    #SR_HIGH,sr     | lock out all so _whichqs == _qs
                    203:        moveq   #31,d1
                    204:        subl    d0,d1
                    205:        bfclr   _whichqs{d0:#1}
                    206:        jeq     2b              | proc moved via lbolt interrupt
                    207:        lea     _qs,a0
                    208:        movl    a0@(0,d1:l:8),a0| get qs[d1].ph_link = p = highest pri process
                    209:        movl    a0,d1           | save it
                    210:        movl    a0@,a1          | remque(p);
                    211:        cmpl    a0,a1           | is queue empty?
                    212:        jne     4f
                    213: 8:
                    214:        pea     9f
                    215:        jsr     _panic
                    216: 9:
                    217:        .asciz  "swtch"
                    218:        .even
                    219: 4:
                    220:        movl    a0@(4),a0
                    221:        movl    a1,a0@
                    222:        movl    a0,a1@(4)
                    223:        cmpl    a0,a1
                    224:        jeq     5f              | queue empty
                    225:        bfset   _whichqs{d0:#1} | queue not empty, set appropriate bit
                    226: 5:
                    227:        movl    d1,a0           | restore p
                    228:        clrl    _noproc
                    229:        tstl    a0@(P_WCHAN)    || firewalls
                    230:        jne     8b              ||
                    231:        cmpb    #SRUN,a0@(P_STAT) ||
                    232:        jne     8b              ||
                    233:        clrl    a0@(P_RLINK)    ||
                    234:        addql   #1,_cnt+V_SWTCH
                    235:        movl    a0,sp@-
                    236:        jsr     _resume
                    237:        addqw   #4,sp
                    238:        movw    sp@+,sr         | restore processor priority
                    239:        rts
                    240: 
                    241: 
                    242: /*
                    243:  * fpprocp is the pointer to the proc structure whose external
                    244:  * state (i.e. registers) was last loaded into the 68881.
                    245:  */
                    246:        .data
                    247:        .globl  _fpprocp
                    248: _fpprocp:      .long 0                 | struct proc *fpprocp;
                    249:        .text
                    250: 
                    251: /*
                    252:  * masterprocp is the pointer to the proc structure for the currently
                    253:  * mapped u area.  It is used to set up the mapping for the u area
                    254:  * by the debugger since the u area is not in the Sysmap.
                    255:  */
                    256:        .data
                    257:        .globl  _masterprocp
                    258: _masterprocp:  .long   0               | struct proc *masterprocp;
                    259:        .text
                    260: 
                    261: /*
                    262:  * resume(p)
                    263:  *
                    264:  * Assumes that there is only one real page to worry about (UPAGES = 1),
                    265:  * that the kernel stack starts below the u area in the middle of
                    266:  * a page, that the redzone is below that and is always marked
                    267:  * for no access across all contexts, the default sfc and dfs are
                    268:  * set to FC_MAP, and that we are running on the u area kernel stack
                    269:  * when we are called.
                    270:  */
                    271: SAVREGS = 0xFCFC
                    272:        ENTRY(resume)
                    273:        tstw    _fppstate               | is fpp present and enabled?
                    274:        jle     1f                      | branch if not
                    275:        fsave   _u+U_FP_ISTATE          | save internal state
                    276:        tstw    _u+U_FP_ISTATE          | test for null state
                    277:        jeq     1f                      | branch if so
                    278:        fmovem  fpc/fps/fpi,_u+U_FPS_CTRL | save control registers
                    279:        fmovem  fp0-fp7,_u+U_FPS_REGS   | save fp data registers
                    280:        movl    _masterprocp,_fpprocp   | remember whose regs are still loaded
                    281: 1:
                    282:        movl    sp@,_u+PCB_REGS         | save return pc in pcb
                    283:        movl    sp@(4),a0               | a0 contains proc pointer
                    284:        movw    sr,_u+PCB_SR+2          | save the current psw in u area
                    285:        orw     #SR_INTPRI,sr           | mask interrupts
                    286:        moveml  #SAVREGS,_u+PCB_REGS+4  | save data/address regs
                    287:        movl    a0,_masterprocp         | set proc pointer for new process
                    288:        lea     eintstack,sp            | use the interrupt stack
                    289:        moveq   #KCONTEXT,d0
                    290:        movsb   d0,CONTEXTBASE          | invalidate context
                    291:        lea     U_MAPVAL,a1     | a1 has address used to access pme for u area
                    292:        movl    a0@(P_ADDR),a2  | get p_addr (address of pte's), a2 is scratch
                    293:        movl    a2@,d0                  | get u pte
                    294:        movsl   d0,a1@                  |   and set pme
                    295: /*
                    296:  * Check to see if we already have context.  If so and
                    297:  * SPTECHG bit is not on then set up the next context.
                    298:  */
                    299:        tstl    a0@(P_CTX)              | check p->p_ctx
                    300:        jeq     1f                      | if zero, skip ahead
                    301:        btst    #SPTECHG_BIT-24,a0@(P_FLAG)     | check (p->p_flag & SPTECHG)
                    302:        jne     1f                      | if SPTECHG bit is on, skip ahead
                    303:        movl    a0@(P_CTX),a1
                    304:        movw    a1@(CTX_CONTEXT),d0     | get context number in d0
                    305:        movsb   d0,CONTEXTBASE          | set up the context
                    306: 1:
                    307:        tstw    _fppstate               | is fpp present and enabled?
                    308:        jle     1f                      | branch if not
                    309:        tstw    _u+U_FP_ISTATE          | test for null state
                    310:        jeq     0f                      | branch if so
                    311:        cmpl    _fpprocp,a0             | check if we were last proc using fpp
                    312:        beq     0f                      | if so, jump and skip loading ext regs
                    313:        fmovem  _u+U_FPS_REGS:w,fp0-fp7 | restore fp data registers
                    314:        fmovem  _u+U_FPS_CTRL,fpc/fps/fpi | restore control registers
                    315: 0:
                    316:        frestore _u+U_FP_ISTATE         | restore internal state
                    317: 1:
                    318:        moveml  _u+PCB_REGS+4,#SAVREGS  | restore data/address regs
                    319: | Note: we just changed stacks
                    320:        movw    _u+PCB_SR+2,sr
                    321:        tstl    _u+PCB_SSWAP
                    322:        jeq     1f
                    323:        movl    _u+PCB_SSWAP,sp@(4)     | blech...
                    324:        clrl    _u+PCB_SSWAP
                    325:        movw    #SR_LOW,sr
                    326:        jmp     _longjmp
                    327: 1:
                    328:        rts

unix.superglobalmegacorp.com

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