Annotation of cci/sys/tahoe/locore.s, revision 1.1.1.2

1.1       root        1: /*     locore.s        4.50    81/05/18        */
                      2:  # -------------------
                      3: 
                      4: #include "../machine/mtpr.h"
                      5: #include "../machine/trap.h"
                      6: #include "../machine/psl.h"
                      7: #include "../machine/pte.h"
                      8: #include "../machine/cp.h"
                      9: #include "../machine/mem.h"
                     10: #include "../machine/fp.h"
1.1.1.2 ! root       11: /*---------------- Alignment code -------------------*/
        !            12: #include "../machine/alignment.h"
        !            13: /*---------------- Alignment code -------------------*/
1.1       root       14: 
                     15: #include "../h/errno.h"
                     16: 
1.1.1.2 ! root       17: .data
        !            18: .align 2
        !            19: .text
1.1       root       20:        .set    HIGH,0x1f       # mask for total disable
                     21:        .set    BERVEC,0x80     # offset into scb of the bus error vector 
                     22:        .set    RESTVEC,0x8     # offset into scb of the restart vector 
                     23:        .set    MEMUNIT,64*1024 # minimum memory increment
                     24: 
                     25:        .set    NISP,3          # number of interrupt stack pages
                     26:        .set    SYSTEM,0xC0000000 # virtual address of system start
                     27:        .set    PPAGES,0x100000  # Number of possible pages in P0,P1, etc.
                     28: 
                     29: /* ACBL for non-negative '_add' */
                     30: #define ACBL(_limit,_add,_index,_displ) \
                     31:        addl2   _add,_index; \
                     32:        cmpl    _index,_limit; \
                     33:        bleq    _displ
                     34: 
                     35: /* _ACBL for negative '_add' */
                     36: #define _ACBL(_limit,_add,_index,_displ) \
                     37:        addl2   _add,_index; \
                     38:        cmpl    _index,_limit; \
                     39:        bgeq    _displ
                     40: 
                     41: #define        MOVC3(_len,_srcaddr,_dstaddr) \
                     42:        movl    _srcaddr,r0; \
                     43:        movl    _dstaddr,r1; \
                     44:        movl    _len,r2; \
                     45:        movblk
                     46: 
                     47: /* Keep address of psl if coming from user mode */
                     48: #define CHECK_SFE(_delta) \
                     49:        bitl    $PSL_CURMOD,_delta(sp); \
                     50:        jeql    1f; \
                     51:        moval   _delta(sp),_user_psl; \
                     52: 1:
                     53: 
                     54: /*
                     55:  * User structure is UPAGES at top of user space.
                     56:  */
                     57:        .globl  _u
                     58:        .set    _u,SYSTEM - UPAGES*NBPG
                     59: 
                     60: /*
                     61:  * Restart stack. Used on power recovery or panic.
                     62:  * Takes a core-dump and then halts.
                     63:  */ 
                     64:        .globl  _rsstk
                     65: 
                     66: _rsstk:        .space  1024-8
                     67:        .globl  pwfl_stk        
                     68: pwfl_stk:      .space  4
                     69: dumpflag:      .space  4
                     70: 
                     71:        .globl  _intstack
                     72: _intstack:
                     73:        .space  NISP*NBPG
                     74: eintstack:
                     75: 
                     76:        .data
                     77:        .globl  pwfl_r0
                     78: pwfl_r0:       .space  14*4            # Enough for r0 - r13
                     79:        .globl  pwfl_sp
                     80: pwfl_sp:       .long   0x12345678      # r14
                     81:        .globl  pwfl_SCBB
                     82: pwfl_SCBB:     .long   0x12345678
                     83:        .globl  pwfl_SBR
                     84: pwfl_SBR:      .long   0x12345678
                     85:        .globl  pwfl_SLR
                     86: pwfl_SLR:      .long   0x12345678
                     87:        .globl  pwfl_P0BR
                     88: pwfl_P0BR:     .long   0x12345678
                     89:        .globl  pwfl_P0LR
                     90: pwfl_P0LR:     .long   0x12345678
                     91:        .globl  pwfl_P1BR
                     92: pwfl_P1BR:     .long   0x12345678
                     93:        .globl  pwfl_P1LR
                     94: pwfl_P1LR:     .long   0x12345678
                     95:        .globl  pwfl_P2BR
                     96: pwfl_P2BR:     .long   0x12345678
                     97:        .globl  pwfl_P2LR
                     98: pwfl_P2LR:     .long   0x12345678
                     99:        .globl  pwfl_IPL
                    100: pwfl_IPL:      .long   0x12345678
                    101:        .globl  pwfl_DCK
                    102: pwfl_DCK:      .long   0x12345678
                    103:        .globl  pwfl_CCK
                    104: pwfl_CCK:      .long   0x12345678
                    105:        .globl  pwfl_PCBB
                    106: pwfl_PCBB:     .long   0x12345678
                    107:        .globl  pwfl_ISP
                    108: pwfl_ISP:      .long   0x12345678
                    109:        .globl  pwfl_KSP
                    110: pwfl_KSP:      .long   0x12345678
                    111:        .globl  pwfl_USP
                    112: pwfl_USP:      .long   0x12345678
                    113:        .globl  pwfl_MME
                    114: pwfl_MME:      .long   0x12345678
                    115:        .globl  pwfl_PSL
                    116: pwfl_PSL:      .long   0x12345678
                    117: 
                    118: /*
                    119:  * Do a dump.
                    120:  * Called by auto-restart.
                    121:  * May be called manually.
                    122:  */
                    123:        .align  2
                    124:        .text
                    125:        .globl  _Xdoadump
                    126:        .globl  _doadump
                    127: _Xdoadump:                     # CP brings Tahoe here on power recovery
                    128:        loadr   $0x3fff,pwfl_r0 # Restore r0 - r13
                    129:        movl    pwfl_sp,sp      # Restore sp ( = r14 )
                    130:        mtpr    pwfl_SCBB,$SCBB
                    131:        mtpr    pwfl_SBR,$SBR   # Restore all re_loadable registers
                    132:        mtpr    pwfl_SLR,$SLR
                    133:        mtpr    pwfl_P0BR,$P0BR
                    134:        mtpr    pwfl_P0LR,$P0LR
                    135:        mtpr    pwfl_P1BR,$P1BR
                    136:        mtpr    pwfl_P1LR,$P1LR
                    137:        mtpr    pwfl_P2BR,$P2BR
                    138:        mtpr    pwfl_P2LR,$P2LR
                    139:        mtpr    pwfl_IPL,$IPL
                    140:        mtpr    pwfl_DCK,$DCK
                    141:        mtpr    pwfl_CCK,$CCK
                    142:        mtpr    pwfl_PCBB,$PCBB
                    143:        mtpr    pwfl_ISP,$ISP
                    144:        mtpr    pwfl_KSP,$KSP
                    145:        mtpr    pwfl_USP,$USP
                    146: 
                    147:        bicpsw  $0xff           # Restore PSW.
                    148:        bispsw  pwfl_PSL+2      # Set original bits back (just in case..)
                    149: /* now go to mapped mode */
                    150: /* Have to change PC to system addresses */
                    151:        mtpr    $1,$PACC        # Thoroughly clean up caches.
                    152:        mtpr    $1,$PADC
                    153:        mtpr    $1,$TBIA
                    154:        mtpr    pwfl_MME,$MME   # Restore MME. Last thing to be done.
                    155:        jmp     *$0f
                    156: _doadump:
                    157:        .word 0
                    158: #define        _rsstkmap       _Sysmap+12                      
                    159:                        # Tahoe storage, scb, rsstk, interrupt stack
                    160: 0:
                    161:        mtpr    $HIGH,$IPL
                    162:        andl2   $0!PG_PROT,_rsstkmap
                    163:        orl2    $PG_KW,_rsstkmap                # Make dump stack r/w
                    164:        tstl    dumpflag                        # dump only once!
                    165:        bneq    1f
                    166:        movl    $1,dumpflag
                    167:        mtpr    $0,$TBIA
                    168:        movab   dumpflag,sp
                    169:        callf   $4,_dumpsys
                    170: 1:
                    171:        halt
                    172: 
                    173: /*
                    174:  * Interrupt vector routines
                    175:  */ 
                    176:        .globl  _waittime
                    177: 
                    178: #define        SCBVEC(name) \
                    179:        .align 2; \
                    180:        .globl _X/**/name; \
                    181: _X/**/name
                    182: #define        PANIC(msg)      clrl _waittime; pushab 1f; \
                    183:                        callf $8,_panic; 1: .asciz msg
                    184: #define        PRINTF(n,msg)   pushab 1f; callf $(n*4)+4,_printf; MSG(msg)
                    185: #define        MSG(msg)        .data; 1: .asciz msg; .text
                    186: 
                    187:                        # these registers are not restored by the C-compiler.
                    188: #define        PUSHR           pushl r0; pushl r1;
                    189: #define        POPR            movl (sp)+, r1; movl (sp)+, r0;
                    190:                        # mask for error code on stack.
                    191: 
                    192: #define SAVE_FPSTAT(_delta)    bitl    $PSL_DBL,_delta(sp); \
                    193:                                beql    1f; \
                    194:                                pushl   $1; \
                    195:                                pushd; \
                    196:                                jmp     2f; \
                    197:                        1:      pushl   $0; \
                    198:                                pushl   $0; \
                    199:                                stf     -(sp); \
                    200:                        2:      tstl    _u+PCB_SAVACC; \
                    201:                                bneq    3f; \
                    202:                                moval   0(sp),_u+PCB_SAVACC; \
                    203:                                orl2    $2,8(sp);\
                    204:                        3:      pushl   $0;
                    205: 
                    206: #define REST_FPSTAT            tstl    (sp)+; \
                    207:                                bitl    $2,8(sp);\
                    208:                                beql    1f;\
                    209:                                movl    $0,_u+PCB_SAVACC; \
                    210:                        1:      bitl    $1,8(sp); \
                    211:                                beql    2f; \
                    212:                                ldd     (sp); \
                    213:                                jmp     3f; \
                    214:                        2:      ldf     (sp); \
                    215:                        3:      moval   12(sp),sp;
                    216: 
                    217: #define REST_ACC               tstl    _u+PCB_SAVACC; \
                    218:                                beql    2f; \
                    219:                                movl    _u+PCB_SAVACC,r1; \
                    220:                                andl3   $(EXPMASK|SIGNBIT),(r1),-(sp); \
                    221:                                cmpl    $0x80000000,(sp)+; \
                    222:                                bneq    3f; \
                    223:                                clrl    (r1); \
                    224:                        3:      bitl    $1,8(r1); \
                    225:                                beql    1f; \
                    226:                                ldd     (r1); \
                    227:                                jmp     2f; \
                    228:                        1:      ldf     (r1); \
                    229:                        2:      ;
                    230: 
                    231: #define PUSHBPAR       pushab  6*4(sp) /* Push address of buserr paramters */
                    232: #define BPAR1          28              /* Offset to first hardware parameter */
                    233: 
                    234: SCBVEC(buserr):
                    235:        CHECK_SFE(12)
                    236:        SAVE_FPSTAT(12);
                    237:        PUSHR
                    238:        andl3   BPAR1(sp),$ERRCD,r0
                    239:        jeql    go_on
                    240:        cmpl    r0,$APE
                    241:        jneq    1f
                    242:        halt            # Address parity error !!!
                    243: 1:     cmpl    r0,$VBE
                    244:        jneq    go_on
                    245:        halt            # Versabus error !!!
                    246: go_on:
                    247:        PUSHBPAR        # Pointer to parameters
                    248:        callf   $8,_buserror
                    249:        POPR
                    250:        REST_FPSTAT;
                    251:        movab   8(sp),sp        # Remove hardware parameters
                    252:        rei
                    253: 
                    254: SCBVEC(powfail):               # We should be on interrupt stack now.
                    255:        movpsl  pwfl_PSL        # Keeps all flags, etc.
                    256:        storer  $0x3fff,pwfl_r0 # Saves r0 - r13
                    257:        moval   0(sp),pwfl_sp   # Saves sp ( = r14 )
                    258:        mfpr    $SBR,pwfl_SBR   # Save all re_loadable registers
                    259:        mfpr    $SLR,pwfl_SLR
                    260:        mfpr    $P0BR,pwfl_P0BR
                    261:        mfpr    $P0LR,pwfl_P0LR
                    262:        mfpr    $P1BR,pwfl_P1BR
                    263:        mfpr    $P1LR,pwfl_P1LR
                    264:        mfpr    $P2BR,pwfl_P2BR
                    265:        mfpr    $P2LR,pwfl_P2LR
                    266:        mfpr    $IPL,pwfl_IPL
                    267:        mfpr    $MME,pwfl_MME  
                    268:        mfpr    $DCK,pwfl_DCK
                    269:        mfpr    $CCK,pwfl_CCK
                    270:        mfpr    $PCBB,pwfl_PCBB
                    271:        mfpr    $ISP,pwfl_ISP
                    272:        mfpr    $SCBB,pwfl_SCBB
                    273:        mfpr    $KSP,pwfl_KSP
                    274:        mfpr    $USP,pwfl_USP
                    275:        moval   _Xdoadump-SYSTEM,_scb+RESTVEC
                    276:        halt
                    277: 
                    278: SCBVEC(stray):
                    279:        PUSHR;
                    280:        movpsl  r0
                    281:        shrl    $16, r0,-(sp) 
                    282:        andl2   $0x1f, (sp)
                    283:        PRINTF(2, "******* Undefined interrupt at ipl 0x%x *******\n");
                    284:        POPR;
                    285:        rei
                    286: 
                    287: #include "../net/netisr.h"
                    288:        .globl  _netisr
                    289: SCBVEC(netintr):
                    290:        CHECK_SFE(4)
                    291:        SAVE_FPSTAT(4)
                    292:        PUSHR
                    293: 
                    294:        bbc     $NETISR_RAW,_netisr,1f
                    295:        andl2   $(0!(1<<NETISR_RAW)),_netisr    
                    296:        callf   $4,_rawintr     
                    297: 1:
                    298: #ifdef INET
                    299: #include "../netinet/in_systm.h"
                    300:        bbc     $NETISR_IP,_netisr,1f   
                    301:        andl2   $(0!(1<<NETISR_IP)),_netisr
                    302:        callf   $4,_ipintr      
                    303: 1:
                    304: #endif
                    305: #ifdef NS
                    306:        bbc     $NETISR_NS,_netisr,1f   
                    307:        andl2   $(0!(1<<NETISR_NS)),_netisr
                    308:        callf   $4,_nsintr      
                    309: 1:
                    310: #endif
                    311:        POPR; 
                    312:        REST_FPSTAT
                    313:        rei
                    314: SCBVEC(soft15):
                    315: SCBVEC(soft14):
                    316: SCBVEC(soft13):
                    317: SCBVEC(soft11):
                    318: SCBVEC(soft10):
                    319: #ifndef SIMIO
                    320: SCBVEC(soft9):
                    321: #endif
                    322: SCBVEC(soft7):
                    323: SCBVEC(soft6):
                    324: SCBVEC(soft5):
                    325: SCBVEC(soft4):
                    326: #ifndef SIMIO
                    327: SCBVEC(soft3):
                    328: SCBVEC(soft2):
                    329: SCBVEC(soft1):
                    330: #endif
                    331:        PUSHR
                    332:        PRINTF(1, "******* Undefined software interrupt *******\n")
                    333:        POPR;
                    334:        rei
                    335: 
                    336: #ifdef SIMIO
                    337: SCBVEC(soft2):
                    338: #endif
                    339: SCBVEC(cnrint):
                    340:        CHECK_SFE(4)
                    341:        SAVE_FPSTAT(4);PUSHR; 
                    342:        pushl $CPCONS; callf $8,_cnrint; POPR; incl _cnt+V_INTR;
                    343:        REST_FPSTAT; rei
                    344: #ifdef SIMIO
                    345: SCBVEC(soft3):
                    346: #endif
                    347: SCBVEC(cnxint):
                    348:        CHECK_SFE(4)
                    349:        SAVE_FPSTAT(4);PUSHR; 
                    350:        pushl $CPCONS; callf $8,_cnxint; POPR; REST_FPSTAT;
                    351:        incl _cnt+V_INTR; rei
                    352: SCBVEC(rmtrint):
                    353:        CHECK_SFE(4)
                    354:        SAVE_FPSTAT(4); PUSHR; 
                    355:        pushl $CPREMOT; callf $8,_cnrint; POPR; REST_FPSTAT;
                    356:        incl _cnt+V_INTR; rei
                    357: SCBVEC(rmtxint):
                    358:        CHECK_SFE(4)
                    359:        SAVE_FPSTAT(4); PUSHR; 
                    360:        pushl $CPREMOT; callf $8,_cnxint; POPR; REST_FPSTAT;
                    361:        incl _cnt+V_INTR; rei
                    362: #ifdef SIMIO
                    363: SCBVEC(soft9):
                    364: #endif
                    365: 
                    366: #define PUSHPCPSL      pushl 5*4+2*4(sp); pushl 5*4+2*4(sp);
                    367: 
                    368: SCBVEC(hardclock):
                    369:        CHECK_SFE(4)
                    370:        SAVE_FPSTAT(4)
                    371:        PUSHR
                    372:        PUSHPCPSL                               # push pc and psl
                    373:        callf $12,_hardclock                    # hardclock(pc,psl)
                    374:        POPR;
                    375:        REST_FPSTAT
                    376:        incl    _cnt+V_INTR             ## temp so not to break vmstat -= HZ
                    377:        rei
                    378: SCBVEC(softclock):
                    379:        CHECK_SFE(4)
                    380:        SAVE_FPSTAT(4)
                    381:        PUSHR
                    382:        PUSHPCPSL                               # push pc and psl
                    383:        callf $12,_softclock                    # softclock(pc,psl)
                    384:        POPR; 
                    385:        REST_FPSTAT
                    386:        rei
                    387: 
                    388: /*
                    389:  * Trap and fault vector routines
                    390:  */ 
                    391: #define        TRAP(a) pushl $T_/**/a; jbr alltraps
                    392: 
                    393: /*
                    394:  * Ast delivery (profiling and/or reschedule)
                    395:  */
                    396: /*
                    397:  * When we want to reschedule we will force a memory fault by setting the m.s.b
                    398:  *  of P0LR. Then , on memory fault if m.s.b of P0LR is on we will clear it and
                    399:  *  TRAP(astflt).
                    400:  *
                    401:  */
                    402:  
                    403:                                        # if this bit is on it is an ast.
                    404: #define        ASTBIT  0x00100000      
                    405: #define                P0MASK  0xc0000000
                    406: 
                    407: SCBVEC(kspnotval):
                    408:        CHECK_SFE(4)
                    409:        pushl $0;
                    410:        SAVE_FPSTAT(8)
                    411:        TRAP(KSPNOTVAL)
                    412: SCBVEC(privinflt):
                    413:        CHECK_SFE(4)
                    414:        pushl $0;
                    415:        SAVE_FPSTAT(8)
                    416:        TRAP(PRIVINFLT)
                    417: SCBVEC(resopflt):
                    418:        CHECK_SFE(4)
                    419:        pushl $0;
                    420:        SAVE_FPSTAT(8)
                    421:        TRAP(RESOPFLT)
                    422: SCBVEC(resadflt):
                    423:        CHECK_SFE(4)
                    424:        pushl $0;
                    425:        SAVE_FPSTAT(8)
                    426:        TRAP(RESADFLT)
                    427: SCBVEC(bptflt):
                    428:        CHECK_SFE(4)
                    429:        pushl $0;
                    430:        SAVE_FPSTAT(8)
                    431:        TRAP(BPTFLT)
                    432: SCBVEC(tracep):
                    433:        CHECK_SFE(4)
                    434:        pushl $0;
                    435:        SAVE_FPSTAT(8)
                    436:        TRAP(TRCTRAP)
                    437: SCBVEC(alignflt):
1.1.1.2 ! root      438: /*---------------- Alignment code -------------------*/
        !           439: /*     CHECK_SFE(4)                                 */
        !           440:        bitl    $PSL_CURMOD,4(sp)
        !           441:        jeql    align_excp              # Can't emulate for kernel mode !
        !           442:        jmp     non_aligned             # Only emulated for user mode.
        !           443: align_excp:
        !           444: /*---------------- Alignment code -------------------*/
1.1       root      445:        pushl $0;
                    446:        SAVE_FPSTAT(8)
                    447:        TRAP(ALIGNFLT)
                    448: SCBVEC(arithtrap):
                    449:        CHECK_SFE(8)
                    450:        SAVE_FPSTAT(8)
                    451:        TRAP(ARITHTRAP)
                    452: 
                    453: SCBVEC(protflt):
                    454:        CHECK_SFE(12)
                    455:        bitl    $1,(sp)+
                    456:        jneq    segflt
                    457:        SAVE_FPSTAT(8)
                    458:        TRAP(PROTFLT)
                    459: segflt:
                    460:        SAVE_FPSTAT(8)
                    461:        TRAP(SEGFLT)
                    462: 
                    463: SCBVEC(fpm):                   # Floating Point eMulation
                    464:        .globl  _fpemulate
                    465:        CHECK_SFE(16)
                    466:        SAVE_FPSTAT(16)
                    467:        callf   $4,_fpemulate
                    468:        REST_FPSTAT
                    469:        moval   8(sp),sp        # Pop operand
                    470:        tstl    (sp)            # Stack= PSL, PC, return_code
                    471:        jneq    _Xarithtrap     # If not OK, emulate F.P. exception
                    472:        movab   4(sp),sp        # Else remove return_code and
                    473:        rei
                    474: 
                    475: SCBVEC(sfexcep):
                    476:        CHECK_SFE(4)
                    477:        pushl $0
                    478:        SAVE_FPSTAT(8)
                    479:        TRAP(ASTFLT)
                    480: 
                    481: SCBVEC(transflt):
                    482:        CHECK_SFE(12)
                    483:        bitl    $1,(sp)+
                    484:        bneq    tableflt
                    485: pageflt:
                    486:        SAVE_FPSTAT(8)
                    487:        TRAP(PAGEFLT)
                    488: tableflt:
                    489:        SAVE_FPSTAT(8)
                    490:        TRAP(TABLEFLT)
                    491: 
                    492: #define REST_STACK     movab 4(sp), sp; REST_FPSTAT; movab 4(sp), sp
                    493: 
                    494: alltraps:
                    495:        mfpr    $USP,-(sp); 
                    496:        callf $4,_trap; mtpr (sp)+,$USP
                    497:        incl    _cnt+V_TRAP
                    498:        REST_STACK                      # pop type, code, an fp stuff
                    499:        mtpr    $HIGH,$IPL              ## dont go to a higher IPL (GROT)
                    500:        rei
                    501: 
                    502: SCBVEC(syscall):
                    503:        CHECK_SFE(8)
                    504:        SAVE_FPSTAT(8)
                    505:        pushl   $T_SYSCALL
                    506:        mfpr    $USP,-(sp); callf $4,_syscall; mtpr (sp)+,$USP
                    507:        incl    _cnt+V_SYSCALL
                    508:        REST_STACK                      # pop type, code, an fp stuff
                    509:        mtpr    $HIGH,$IPL              ## dont go to a higher IPL (GROT)
                    510:        rei
                    511: 
                    512: /*
                    513:  * System page table
                    514:  */ 
                    515: #define        vaddr(x)        ((((x)-_Sysmap)/4)*NBPG+SYSTEM)
                    516: #define        SYSMAP(mname, vname, npte)                      \
                    517: _/**/mname:    .globl  _/**/mname;             \
                    518:        .space  npte*4;                         \
                    519:        .globl  _/**/vname;                     \
                    520:        .set    _/**/vname,vaddr(_/**/mname)
                    521: 
                    522:        .data
                    523:        .align  2
                    524:        SYSMAP(Sysmap   ,Sysbase        ,SYSPTSIZE      )
                    525:        SYSMAP(VMEMbeg  ,vmembeg        ,0              )
                    526:        SYSMAP(VMEMmap  ,vmem           ,IOSIZE         )
                    527:        SYSMAP(ACE0map  ,ace0utl        ,(ACEBPTE+1)    )
                    528:        SYSMAP(ACE1map  ,ace1utl        ,(ACEBPTE+1)    )
1.1.1.2 ! root      529:        SYSMAP(ENP0map  ,enp0utl        ,128            )
        !           530:        SYSMAP(ENP1map  ,enp1utl        ,128            )
1.1       root      531:        SYSMAP(VMEMend  ,vmemend        ,0              )
                    532:        SYSMAP(Usrptmap ,usrpt          ,USRPTSIZE      )
                    533:        SYSMAP(Forkmap  ,forkutl        ,UPAGES         )
                    534:        SYSMAP(Xswapmap ,xswaputl       ,UPAGES         )
                    535:        SYSMAP(Xswap2map,xswap2utl      ,UPAGES         )
                    536:        SYSMAP(Swapmap  ,swaputl        ,UPAGES         )
                    537:        SYSMAP(Pushmap  ,pushutl        ,UPAGES         )
                    538:        SYSMAP(Vfmap    ,vfutl          ,UPAGES         )
                    539:        SYSMAP(VD0map   ,vd0utl         ,(MAXBPTE+1)    )
                    540:        SYSMAP(VD1map   ,vd1utl         ,(MAXBPTE+1)    )
                    541:        SYSMAP(VD2map   ,vd2utl         ,(MAXBPTE+1)    )
                    542:        SYSMAP(VD3map   ,vd3utl         ,(MAXBPTE+1)    )
1.1.1.2 ! root      543:        SYSMAP(VD4map   ,vd4utl         ,(MAXBPTE+1)    )
        !           544:        SYSMAP(VD5map   ,vd5utl         ,(MAXBPTE+1)    )
        !           545:        SYSMAP(VD6map   ,vd6utl         ,(MAXBPTE+1)    )
        !           546:        SYSMAP(VD7map   ,vd7utl         ,(MAXBPTE+1)    )
1.1       root      547:        SYSMAP(CY0map   ,cy0utl         ,(TBUFSIZ+1)    )
                    548:        SYSMAP(CY1map   ,cy1utl         ,(TBUFSIZ+1)    )
                    549:        SYSMAP(CMAP1    ,CADDR1         ,1              )
                    550:        SYSMAP(CMAP2    ,CADDR2         ,1              )
                    551:        SYSMAP(mmap     ,vmmap          ,1              )
                    552:        SYSMAP(msgbufmap,msgbuf         ,MSGBUFPTECNT   )
                    553:        SYSMAP(camap    ,cabase         ,16*CLSIZE      )
                    554:        SYSMAP(ecamap   ,calimit        ,0              )
                    555:        SYSMAP(Mbmap    ,mbutl          ,NMBCLUSTERS*CLSIZE)
                    556:        SYSMAP(Msgmap   ,msgutl         ,MSGMAPPTE)
                    557: eSysmap:
                    558:        .globl  _Syssize
                    559:        .set    _Syssize,(eSysmap-_Sysmap)/4
                    560: 
                    561:        .text
                    562: /*
                    563:  * Initialization
                    564:  *
                    565:  * IPL 0x1f; MME 0; scbb, pcbb, sbr, slr, isp, ksp not set
                    566:  *
                    567:  */
                    568: 
                    569:        .align  2
                    570:        .globl  start
                    571: start:
                    572:        .word   0
                    573: 
                    574: /* set system control block base and system page table params */
                    575: 
                    576:        mtpr    $_scb-SYSTEM,$SCBB
                    577:        mtpr    $_Sysmap-SYSTEM,$SBR
                    578:        mtpr    $_Syssize,$SLR
                    579: 
                    580: /* double map the kernel into the virtual user addresses of phys mem */
                    581: /* (to be on the safe side.This is supposed to run in system sace. )  */
                    582:        mtpr    $_Sysmap,$P0BR
                    583:        mtpr    $_Syssize,$P0LR
                    584: 
                    585:        mtpr    $_Sysmap,$P1BR          # Against Murphy
                    586:        mtpr    $_Syssize,$P1LR
                    587: 
                    588: /* set ISP */
                    589:        movl    $_intstack-SYSTEM+NISP*NBPG,sp  # Still physical !
                    590:        mtpr    $_intstack+NISP*NBPG,$ISP
                    591: 
                    592: /* count up memory */
                    593: 
                    594:        clrl    r7
                    595: 1:     pushl   $1; pushl r7; callf $12,_badaddr; tstl r0; bneq 9f
                    596:        addl2   $MEMUNIT,r7
                    597:        brb     1b
                    598: 9:
                    599: /* clear memory from kernel bss and pages for proc 0 u. and page table */
                    600:        movab   _edata,r6
                    601:        movab   _end,r5
                    602:        andl2   $0!SYSTEM,r6
                    603:        andl2   $0!SYSTEM,r5
                    604:        addl2   $(UPAGES*NBPG)+NBPG+NBPG,r5
                    605: 1:     clrl    (r6); ACBL( r5,$4,r6,1b)
                    606: 
                    607: /* trap() and syscall() save r0-r13 in the entry mask (per ../h/reg.h) */
                    608: /* For floating point emulation, we do same for 'fpemulate' */
1.1.1.2 ! root      609: /* force panic() to save r0-r12 for easier debugging */
1.1       root      610:        orw2    $0x01fff,_trap
                    611:        orw2    $0x01fff,_syscall
                    612:        orw2    $0x01fff,_fpemulate
1.1.1.2 ! root      613:        orw2    $0x01fff,_panic
        !           614: 
        !           615: /*---------------- Alignment code -------------------*/
        !           616:        orw2    $0x01fff,_alignment
        !           617: /*---------------- Alignment code -------------------*/
1.1       root      618: 
                    619: /* initialize system page table: scb and int stack writeable */
                    620:        clrl    r2
                    621:        movab   eintstack,r1 
                    622:        andl2   $0!SYSTEM,r1
                    623:        shrl    $PGSHIFT,r1,r1          # r1-page number of eintstack.
                    624: 
                    625: /* Start by making the processor storage read/only */
                    626: 
                    627:        orl3    $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2;
                    628:        orl3    $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2;
                    629: 
                    630: /* Other parts of the system are read/write for kernel */
                    631: 
                    632: 1:     orl3    $PG_V|PG_KW,r2,_Sysmap[r2]; # data:kernel write + phys=virtual
                    633:        aoblss r1,r2,1b
                    634: 
                    635: /* make rsstk read-only as red zone for interrupt stack */
                    636:        andl2   $0!PG_PROT,_rsstkmap
                    637:        orl2    $PG_V|PG_KR,_rsstkmap           # Make dump stack r/w
                    638: 
                    639: /* make kernel text space read-only */
                    640: /*
                    641:  * HAVE TO CHECK ALL THE MAGIC CONSTANTS USED HERE : $xxxxxx */
                    642: 
                    643:        movab   _etext+NBPG-1,r1
                    644:        andl2   $0!SYSTEM,r1
                    645:        shrl    $PGSHIFT,r1,r1
                    646: 1:     orl3    $PG_V|PG_KR,r2,_Sysmap[r2]
                    647:        aoblss r1,r2,1b
                    648: 
                    649: /* make kernel data, bss, read-write */
                    650:        movab   _end+NBPG-1,r1
                    651:        andl2   $0!SYSTEM,r1
                    652:        shrl    $PGSHIFT,r1,r1
                    653: 1:     orl3    $PG_V|PG_KW,r2,_Sysmap[r2]
                    654:        aoblss r1,r2,1b
                    655: 
                    656: /* now go to mapped mode */
                    657: /* Have to change both PC and SP to system addresses */
                    658:        mtpr    $1,$TBIA
                    659:        mtpr    $1,$PADC        /* needed by HW parity & ECC logic */
                    660:        mtpr    $1,$PACC        /* just in case */
                    661:        mtpr    $1,$MME
                    662:        movab   SYSTEM(sp),sp
                    663:        .globl  go_virt
                    664: go_virt:       
                    665:        jmp     *$0f
                    666: 0:
                    667: 
                    668: /* disable any interrupts */
                    669:        movl    $0,_intenable
                    670: /* init mem sizes */
                    671:        shrl    $PGSHIFT,r7,_maxmem
                    672:        movl    _maxmem,_physmem
                    673:        movl    _maxmem,_freemem
                    674: 
                    675: /* setup context for proc[0] == Scheduler */
                    676:        movab   _end-SYSTEM+NBPG-1,r6
                    677:        andl2   $0!(NBPG-1),r6          # make page boundary
                    678: 
                    679: /* setup page table for proc[0] */
                    680:        shrl    $PGSHIFT,r6,r3                  # r3 = btoc(r6)
                    681:        orl3    $PG_V|PG_KW,r3,_Usrptmap        # init first upt entry
                    682:        incl    r3                              # r3 - next page
                    683:        movab   _usrpt,r0                       # r0 - first user page
                    684:        mtpr    r0,$TBIS
                    685: 
                    686: /* init p0br, p0lr */
                    687:        mtpr    r0,$P0BR        # No P0 for proc[0]
                    688:        mtpr    $0,$P0LR
                    689: 
                    690:        mtpr    r0,$P1BR        # No P1 either
                    691:        mtpr    $0,$P1LR
                    692: 
                    693: 
                    694: /* init p2br, p2lr */
                    695:        movab   NBPG(r0),r0
                    696:        movl    $PPAGES-UPAGES,r1
                    697:        mtpr    r1,$P2LR
                    698:        moval   -4*PPAGES(r0),r2
                    699:        mtpr    r2,$P2BR
                    700: 
                    701: /* setup mapping for UPAGES of _u */
                    702:        clrl    r2; 
                    703:        movl    $SYSTEM,r1
                    704:        addl2   $UPAGES,r3
                    705:        jbr 2f
                    706: 1:     decl    r3
                    707:        moval   -NBPG(r1),r1;   # r1 = virtual add of next (downward) _u page
                    708:        subl2   $4,r0           # r0 = pte address
                    709:        orl3    $PG_V|PG_URKW,r3,(r0)
                    710:        mtpr    r1,$TBIS
                    711: 2:     aobleq  $UPAGES,r2,1b
                    712: 
                    713: /* initialize (slightly) the pcb */
                    714:        movab   UPAGES*NBPG(r1),PCB_KSP(r1)     # KSP starts at end of _u
                    715:        movl    r1,PCB_USP(r1)                  # USP starts just below _u
                    716:        mfpr    $P0BR,PCB_P0BR(r1)
                    717:        mfpr    $P0LR,PCB_P0LR(r1)
                    718:        mfpr    $P1BR,PCB_P1BR(r1)
                    719:        mfpr    $P1LR,PCB_P1LR(r1)
                    720:        mfpr    $P2BR,PCB_P2BR(r1)
                    721:        mfpr    $P2LR,PCB_P2LR(r1)
                    722:        movl    $CLSIZE,PCB_SZPT(r1)            # init u.u_pcb.pcb_szpt
                    723:        movl    r11,PCB_R11(r1)                 # r11 obtained from CP on boot
                    724:        movab   1f,PCB_PC(r1)                   # initial pc
                    725:        clrl    PCB_PSL(r1)                     # kernel mode, ipl=0
                    726:        shll    $PGSHIFT,r3,r3
                    727:        mtpr    r3,$PCBB                        # first pcbb (physical ! )
                    728: 
                    729: /* Go to a 'normal' process mode (kernel) */
                    730: 
                    731:        ldpctx
                    732:        rei             # Actually 'returns' to the next instruction:
                    733: 
                    734: /* put signal trampoline code in u. area */
                    735: 1:     movab   _u,r0
                    736:        movl    sigcode+0,PCB_SIGC+0(r0)
                    737:        movl    sigcode+4,PCB_SIGC+4(r0)
                    738:        movl    sigcode+8,PCB_SIGC+8(r0)
                    739:        movl    sigcode+12,PCB_SIGC+12(r0)
                    740: 
                    741: /* save reboot flags in global _boothowto */
                    742:        movl    r11,_boothowto
                    743: 
                    744: /* calculate firstaddr, and call main() */
                    745:        movab   _end-SYSTEM+NBPG-1,r0
                    746:        shrl    $PGSHIFT,r0,-(sp)
                    747:        addl2   $UPAGES+1,(sp)          # First physical unused page number
                    748:        callf   $8,_main
                    749: 
                    750: /* proc[1] == /etc/init now running here in kernel mode; run icode */
                    751:        pushl   $PSL_CURMOD             # User mode PSL
                    752:        pushl $0                        # PC = 0 (virtual now)
                    753:        rei
                    754: 
                    755: /* signal trampoline code: it is known that this code takes up to 16    */
                    756: /* bytes in pcb.h and in the code above                                */
                    757: /*  The following user stack layout was set up by machdep.c/sendsig    */
                    758: /*     routine:                                                        */
                    759: /*                                                                     */
                    760: /*     +---------------+                                               */
                    761: /*     |  Last PSL     |\                                              */
                    762: /*     +---------------+ > for rei                                     */
                    763: /*  :-->|  Last PC     |/                                              */
                    764: /*  |  +---------------+                                               */
                    765: /*  :___|__*   SP      |\                                              */
                    766: /*     +---------------+ |                                             */
                    767: /*     |  sigmask      | |                                             */
                    768: /*     +---------------+  > cleaned by kcall $139 (sigcleanup)         */
                    769: /*  :-->|  u.u_onstack | |                                             */
                    770: /*  |  +---------------+ |                                             */
                    771: /*  :___|_* copy of SCP        |/                                              */
                    772: /*  |  +---------------+                                               */
                    773: /*  |  |  Process' r0  |                                               */
                    774: /*  |  +---------------+                                               */
                    775: /*  |  |  Process' r1  |                                               */
                    776: /*  |  +---------------+                                               */
                    777: /*  |  | Handler addr. |\                                              */
                    778: /*  |  +---------------+ |                                             */
                    779: /*  :___|_*   SCP      | |                                             */
                    780: /*     +---------------+  > cleaned by ret from calls                  */
                    781: /*     |  u.u_code     | |                                             */
                    782: /*     +---------------+ |                                             */
                    783: /*     |  signal number|/                                              */
                    784: /*     +---------------+                                               */
                    785: /*                                                                     */
                    786: /*   * Stack when entering sigcode; setup by sendsig();                        */
                    787: /*                                                                     */
                    788:        .align  2
                    789: sigcode:                       # When the process executes this code
                    790:                                #  (located in its u. structure), it
                    791:                                #  is in user mode !
                    792:        calls   $4*4+4,*12(sp)  # 4 words popped from stack when this call returns
                    793:        movl    (sp)+,r1
                    794:        movl    (sp)+,r0
                    795:        kcall   $139            # Signal cleanup
                    796:        rei                     # From user mode to user mode !
                    797: 
                    798: /*
                    799:  * Primitives
                    800:  */ 
                    801: 
                    802: /*
                    803:  * badaddr(addr, len)
                    804:  *     see if access addr with a len type instruction causes a machine check
                    805:  *     len is length of access (1=byte, 2=short, 4=long)
                    806:  *     r0 = 0 means good(exists); r0 =1 means does not exist.
                    807:  */
                    808:        .globl  _badaddr
                    809: _badaddr:
                    810:        .word   0x1c    # Keep r4,r3,r2
                    811:        mfpr    $IPL,r1
                    812:        mtpr    $HIGH,$IPL
                    813:        movl    _scb+BERVEC,r2
                    814:        movl    4(fp),r3
                    815:        movl    8(fp),r4
                    816:        movab   9f,_scb+BERVEC
                    817:        bbc     $0,r4,1f; tstb  (r3)
                    818: 1:     bbc     $1,r4,1f; tstw  (r3)
                    819: 1:     bbc     $2,r4,1f; tstl  (r3)
                    820: 1:     clrl    r0                      # made it w/o machine checks
                    821: 2:     movl    r2,_scb+BERVEC
                    822:        mtpr    r1,$IPL
                    823:        ret
                    824: 
                    825:        .align  2
                    826: 9:                     # Here we catch buss error (if it comes)
                    827:        andl3   4(sp),$ERRCD,r0
                    828:        cmpl    r0,$APE
                    829:        jneq    1f
                    830:        halt                    # Address parity error !!!
                    831: 1:     cmpl    r0,$VBE
                    832:        jneq    1f
                    833:        halt                    # Versabus error
                    834: 1:
                    835:        movl    $1,r0           # Anything else = bad address
                    836:        movab   8(sp),sp        # discard buss error trash
                    837:        movab   2b,(sp)         # new program counter on stack.
                    838:        rei
                    839: 
                    840: 
                    841: /*
                    842:  * badcyaddr(addr)
                    843:  *     see if access tape master controller addr causes a bus error
                    844:  *     r0 = 0: no error; r0 = 1: timeout error.
                    845:  */
                    846:        .globl  _badcyaddr
                    847: _badcyaddr:
                    848:        .word   0x0c    # Keep r3,r2
                    849:        mfpr    $IPL,r1
                    850:        mtpr    $HIGH,$IPL
                    851:        movl    _scb+BERVEC,r2
                    852:        clrl    r3
                    853:        movab   9f,_scb+BERVEC
                    854:        movob   $-1, *4(fp)
                    855: 1:     aobleq  $1000, r3, 1b
                    856:        clrl    r0                      # made it w/o machine checks
                    857: 2:     movl    r2,_scb+BERVEC
                    858:        mtpr    r1,$IPL
                    859:        ret
                    860: 
                    861:        .align  2
                    862: 9:                     # Here we catch buss error (if it comes)
                    863:        andl3   4(sp),$ERRCD,r0
                    864:        cmpl    r0,$APE
                    865:        jneq    1f
                    866:        halt                    # Address parity error !!!
                    867: 1:     cmpl    r0,$VBE
                    868:        jneq    1f
                    869:        halt                    # Versabus error
                    870: 1:
                    871:        movl    $1,r0           # Anything else = timeout
                    872:        movab   8(sp),sp        # discard buss error trash
                    873:        movab   2b,(sp)         # new program counter on stack.
                    874:        rei
                    875: 
                    876: _bcopy:        .globl  _bcopy
                    877:        .word   0x4             # save r2
                    878:                                # Called by ovbcopy(from,dst,len)
                    879:        movl    4(fp),r0
                    880:        movl    8(fp),r1
                    881:        movl    12(fp),r2
                    882:        movblk
                    883:        ret
                    884: 
                    885: _ovbcopy:      .globl  _ovbcopy
                    886:        .word   0x001c
                    887:        movl    4(fp),r0
                    888:        movl    8(fp),r1
                    889:        movl    12(fp),r2
                    890:        cmpl    r0,r1
                    891:        bgtru   1f              # normal forward case
                    892:        beql    2f              # equal, nothing to do
                    893:        addl2   r2,r0           # may be overlapping
                    894:        cmpl    r0,r1
                    895:        bgtru   3f
                    896:        subl2   r2,r0           # normal forward case
                    897: 1:
                    898:        movblk
                    899: 2:
                    900:        ret
                    901: 3:
                    902:        addl2   r2,r1           # overlapping, must do backwards
                    903:        subl3   r0,r1,r3
                    904:        movl    r2,r4
                    905:        jbr     5f
                    906: 4:
                    907:        subl2   r3,r0
                    908:        subl2   r3,r1
                    909:        movl    r3,r2
                    910:        movblk
                    911:        subl2   r3,r0
                    912:        subl2   r3,r1
                    913:        subl2   r3,r4
                    914: 5:
                    915:        cmpl    r4,r3
                    916:        jgtr    4b
                    917:        movl    r4,r2
                    918:        subl2   r2,r0
                    919:        subl2   r2,r1
                    920:        movblk
                    921:        ret
                    922: 
                    923: /*
                    924:  * bzero (base, count)
                    925:  * zero out a block starting at 'base', size 'count'.
                    926:  */
                    927: _bzero:        
                    928:        .globl  _bzero
                    929:        .word   0x4
                    930:        movl    $1f,r0                          # r0 = null source string
                    931:        movl    4(fp),r1                        # r1 = destination address
                    932:        movl    8(fp),r2                        # r2 = count
                    933:        movs3
                    934:        ret
                    935: 1:
                    936:        .byte 0
                    937: 
                    938: 
                    939: _copyin:       .globl  _copyin         # the _Copyin subroutine in VAX
                    940:                                        # became _copyin procedure for TAHOE
                    941:        .word   0x0004
                    942:        movl    12(fp),r0               # copy length
                    943:        blss    ersb
                    944:        movl    4(fp),r1                # copy user address
                    945:        cmpl    $NBPG,r0                # probing one page or less ?
                    946:        bgeq    cishort                 # yes
                    947: ciloop:
                    948:        prober  $1,(r1),$NBPG           # bytes accessible ?
                    949:        beql    ersb                    # no
                    950:        addl2   $NBPG,r1                # incr user address ptr
                    951:        _ACBL   ($NBPG+1,$-NBPG,r0,ciloop)      # reduce count and loop
                    952: cishort:
1.1.1.2 ! root      953:        prober  $1,(r1),$1              # first byte accessible ?
        !           954:        beql    ersb                    # no
        !           955:        addl2   r0,r1                   # get last byte's address
        !           956:        decl    r1
        !           957:        prober  $1,(r1),$1              # last byte accessible ?
1.1       root      958:        beql    ersb                    # no
                    959:        MOVC3   (12(fp),4(fp),8(fp))
                    960:        clrl    r0
                    961:        ret
                    962: 
                    963: ersb:
                    964:        movl    $EFAULT,r0
                    965:        ret
                    966: 
                    967: _copyout:      .globl  _copyout        # the _Copyout subroutine in VAX
                    968:                                        # became _copyout procedure for TAHOE
                    969:        .word   0x04
                    970:        movl    12(fp),r0               # get count
                    971:        blss    ersb
                    972:        movl    8(fp),r1                # get user address
                    973:        cmpl    $NBPG,r0                # can do in one probew?
                    974:        bgeq    coshort                 # yes
                    975: coloop:
                    976:        probew  $1,(r1),$NBPG           # bytes accessible?
                    977:        beql    ersb                    # no 
                    978:        addl2   $NBPG,r1                # increment user address
                    979:        _ACBL   ($NBPG+1,$-NBPG,r0,coloop)      # reduce count and loop
                    980: coshort:
1.1.1.2 ! root      981:        probew  $1,(r1),$1              # first byte accessible?
        !           982:        beql    ersb                    # no
        !           983:        addl2   r0,r1                   # get last byte's address
        !           984:        decl    r1
        !           985:        probew  $1,(r1),$1              # last byte accessible?
1.1       root      986:        beql    ersb                    # no
                    987:        MOVC3   (12(fp),4(fp),8(fp))
                    988:        clrl    r0
                    989:        ret
                    990: 
                    991: /*
                    992:  * non-local goto's
                    993:  */
                    994:        .globl  _setjmp                 # the _Setjmp subroutine in VAX
                    995:                                        # became _setjmp procedure for TAHOE
                    996: _setjmp:
                    997:        .word   0x0
                    998:        movl    4(fp),r2
                    999:        storer  $0x1ff8,(r2)
                   1000:        addl2   $40,r2
                   1001:        movl    (fp),(r2)
                   1002:        addl2   $4,r2
                   1003:        movab   8(fp),(r2)
                   1004:        addl2   $4,r2
                   1005:        movl    -8(fp),(r2)
                   1006:        clrl    r0
                   1007:        ret
                   1008: 
                   1009:        .globl  _longjmp                # the _Longjmp subroutine in VAX
                   1010:                                        # became _longjmp procedure for TAHOE
                   1011: _longjmp:
                   1012:        .word   0x0000
                   1013:        movl    4(fp),r2
                   1014: _Longjmp:                      # called from swtch
                   1015:        loadr   $0x3ff8,(r2)
                   1016:        addl2   $44,r2
                   1017:        movl    (r2),r1
                   1018:        addl2   $4,r2
                   1019:        movab   (sp),r0
                   1020:        cmpl    r1,r0                           # must be a pop
                   1021:        bgequ   lj2
                   1022:        pushab  lj1
                   1023:        callf   $8,_panic
                   1024: lj2:
                   1025:        movl    r1,sp
                   1026:        jmp     *(r2)
                   1027: 
                   1028: lj1:   .asciz  "longjmp"
                   1029: 
                   1030: 
                   1031:        .globl  _whichqs
                   1032:        .globl  _qs
                   1033:        .globl  _cnt
                   1034: 
                   1035:        .globl  _noproc
                   1036:        .comm   _noproc,4
                   1037:        .globl  _runrun
                   1038:        .comm   _runrun,4
                   1039: 
                   1040: /*
                   1041:  * The following primitives use the fancy TAHOE instructions.
                   1042:  * _whichqs tells which of the 32 queues _qs
                   1043:  * have processes in them.  setrq puts processes into queues, remrq
                   1044:  * removes them from queues.  The running process is on no queue,
                   1045:  * other processes are on a queue related to p->p_pri, divided by 4
                   1046:  * actually to shrink the 0-127 range of priorities into the 32 available
                   1047:  * queues.
                   1048:  */
                   1049: 
                   1050: /*
                   1051:  * setrq(p), using fancy TAHOE instructions.
                   1052:  *
                   1053:  * Call should be made at spl8(), and p->p_stat should be SRUN
                   1054:  */
                   1055:        .globl  _setrq
                   1056: _setrq:
                   1057:        .word   0x4
                   1058:        movl    4(fp),r0
                   1059:        tstl    P_RLINK(r0)             ## firewall: p->p_rlink must be 0
                   1060:        beql    set1                    ##
                   1061:        pushab  set3                    ##
                   1062:        callf   $8,_panic               ##
                   1063: set1:
                   1064:        movzbl  P_PRI(r0),r1            # put on queue which is p->p_pri / 4
                   1065:        shar    $2,r1,r1
                   1066:        shal    $1,r1,r2
                   1067:        moval   _qs[r2],r2
                   1068:        insque  (r0),*4(r2)             # at end of queue
                   1069:        shal    r1,$1,r1
                   1070:        orl2    r1,_whichqs             # mark queue non-empty
                   1071:        ret
                   1072: 
                   1073: set3:  .asciz  "setrq"
                   1074: 
                   1075: /*
                   1076:  * remrq(p), using fancy TAHOE instructions
                   1077:  *
                   1078:  * Call should be made at spl8().
                   1079:  */
                   1080:        .globl  _remrq
                   1081: _remrq:
                   1082:        .word   0x0
                   1083:        movl    4(fp),r0
                   1084:        movzbl  P_PRI(r0),r1
                   1085:        shar    $2,r1,r1
                   1086:        bbs     r1,_whichqs,rem1
                   1087:        pushab  rem3                    # it wasn't recorded to be on its q
                   1088:        callf   $8,_panic
                   1089: rem1:
                   1090:        remque  (r0)
                   1091:        bneq    rem2                    # q not empty yet
                   1092:        shal    r1,$1,r1
                   1093:        mcoml   r1,r1
                   1094:        andl2   r1,_whichqs             # mark queue empty
                   1095: rem2:
                   1096:        clrl    P_RLINK(r0)             ## for firewall checking
                   1097:        ret
                   1098: 
                   1099: rem3:  .asciz  "remrq"
                   1100: 
                   1101:        .globl __insque
                   1102: __insque:
                   1103:        .word 0
                   1104:        insque  *4(fp), *8(fp)
                   1105:        ret
                   1106: 
                   1107: 
                   1108:        .globl __remque
                   1109: __remque:
                   1110:        .word 0
                   1111:        remque  *4(fp)
                   1112:        ret
                   1113: 
                   1114: /*
                   1115:  * Masterpaddr is the p->p_addr of the running process on the master
                   1116:  * processor.  When a multiprocessor system, the slave processors will have
                   1117:  * an array of slavepaddr's.
                   1118:  */
                   1119:        .globl  _masterpaddr
                   1120:        .data
                   1121: _masterpaddr:
                   1122:        .long   0
                   1123: 
                   1124:        .text
                   1125: sw0:   .asciz  "swtch"
                   1126: /*
                   1127:  * swtch(), using fancy TAHOE instructions
                   1128:  */
                   1129:        .globl  _swtch
                   1130: _swtch:
                   1131:        .word   0x0
                   1132:        movl    (fp),fp                 # prepare for rei
                   1133:        movl    (sp),4(sp)              # saved pc
                   1134:        tstl    (sp)+
                   1135:        movpsl  4(sp)
                   1136:        movl    $1,_noproc
                   1137:        clrl    _runrun
                   1138: mtpr0: mtpr    $0,$IPL                 # must allow interrupts here
                   1139: sw1:   ffs     _whichqs,r0             # look for non-empty queue
                   1140:        bgeq    sw1a
                   1141:        brb     sw1                     # this is an idle loop!
                   1142: sw1a:  mtpr    $0x18,$IPL              # lock out all so _whichqs==_qs
                   1143:        bbc     r0,_whichqs,mtpr0       # proc moved via lbolt interrupt
                   1144:        shal    $1,r0,r1
                   1145:        moval   _qs[r1],r1
                   1146:        movl    (r1),r2                 # r2 = p = highest pri process
                   1147:        remque  *(r1)
                   1148:        bvc     sw2                     # make sure something was there
                   1149: sw1b:  pushab  sw0
                   1150:        callf   $8,_panic
                   1151: sw2:   bneq    sw3
                   1152:        shal    r0,$1,r1
                   1153:        mcoml   r1,r1
                   1154:        andl2   r1,_whichqs             # no more procs in this queue
                   1155: sw3:
                   1156:        clrl    _noproc
                   1157:        tstl    P_WCHAN(r2)             ## firewalls
                   1158:        bneq    sw1b                    ##
                   1159:        movzbl  P_STAT(r2),r3           ##
                   1160:        cmpl    $SRUN,r3                ##
                   1161:        bneq    sw1b                    ##
                   1162:        clrl    P_RLINK(r2)             ##
                   1163:        movl    *P_ADDR(r2),r0
                   1164:        movl    r0,_masterpaddr
                   1165:        shal    $PGSHIFT,r0,r0          # r0 = pcbb(p)
                   1166: /*     mfpr    $PCBB,r1                # resume of current proc is easy
                   1167:  *     cmpl    r0,r1
                   1168:  */    beql    res0
                   1169:        incl    _cnt+V_SWTCH
                   1170:        brb     swresume
                   1171: /* fall into... */
                   1172: 
                   1173:        .data
                   1174:        .globl  _prevpcb
                   1175: _prevpcb:
                   1176:        .long   0
                   1177:        .text
                   1178: /*
                   1179:  * resume(pf)
                   1180:  */
                   1181:        .globl  _resume
                   1182: _resume:
                   1183:        .word   0x0
                   1184:        shal    $PGSHIFT,4(fp),r0       # r0 = pcbb(p)
                   1185:        movl    (fp),fp                 # prepare for rei
                   1186:        movl    (sp)+,4(sp)             # saved pc
                   1187:        tstl    (sp)+
                   1188:        movpsl  4(sp)
                   1189: swresume:
                   1190:        mtpr    $0x18,$IPL                      # no interrupts, please
                   1191:        movl    _CMAP2,_u+PCB_CMAP2     # yech
                   1192:        REST_ACC                        # restore original accumulator
                   1193:        svpctx
                   1194:        mtpr    r0,$PCBB
                   1195:        ldpctx
                   1196:        movl    _u+PCB_CMAP2,_CMAP2     # yech
                   1197:        mtpr    $_CADDR2,$TBIS
                   1198: res0:
                   1199:        tstl    _u+PCB_SSWAP
                   1200:        beql    res1
                   1201:        movl    _u+PCB_SSWAP,r2
                   1202:        clrl    _u+PCB_SSWAP
                   1203:        movab   _Longjmp,(sp)
                   1204:        clrl    4(sp)                   # PSL = kernel mode, IPL=0
                   1205: res1:
                   1206: /*
                   1207:  * Now we have to care about code and data keys.
                   1208:  * 2 functions may be called, so r0 and r1 must be
                   1209:  * saved across the 'callf'. Also, r2 is used as index
                   1210:  * since r1 may be changed by the functions (just a
                   1211:  * precaution).
                   1212:  */
                   1213:        PUSHR                           # ro and r1
                   1214:        pushl   r2
                   1215:        movl    _u+U_PROCP,r2           # r2 = & proc[?]
                   1216:        tstl    P_CKEY(r2)              # does he have a code key ?
                   1217:        bneq    ckey_ok
                   1218:        callf   $4,_getcodekey          # no, we have to give him one.
                   1219:        movl    r0,P_CKEY(r2)
                   1220: ckey_ok:
                   1221:        tstl    P_DKEY(r2)              # same stuff for data key
                   1222:        bneq    dkey_ok
                   1223:        callf   $4,_getdatakey
                   1224:        movl    r0,P_DKEY(r2)
                   1225: dkey_ok:
                   1226:        mtpr    P_CKEY(r2),$CCK
                   1227:        mtpr    P_DKEY(r2),$DCK
                   1228:        movl    (sp)+,r2                # restore his registers
                   1229:        POPR
                   1230:        rei
                   1231: 
                   1232: /*
                   1233:  * {fu,su},{byte,word}
                   1234:  */
                   1235:        .globl  _fuiword
                   1236:        .globl  _fuword
                   1237: _fuiword:
                   1238: _fuword:
1.1.1.2 ! root     1239:        .word   0x4                     # save r2
        !          1240:        movl    4(fp),r1
        !          1241:        prober  $1,(r1),$1              # check access of first byte
        !          1242:        beql    fserr                   # page unreadable
        !          1243:        prober  $1,3(r1),$1             # check access of last byte
        !          1244:        beql    fserr                   # page unreadable
        !          1245:        bitl    $1,r1                   # check byte alignment
        !          1246:        bneq    2f                      # odd, do byte-word-byte
        !          1247:        bitl    $2,r1                   # check word alignment
        !          1248:        bneq    1f                      # even, do in 2 words
        !          1249:        movl    (r1),r0                 # move longword
        !          1250:        ret
        !          1251: 1:
        !          1252:        movw    (r1),r0                 # move two words
        !          1253:        shal    $16,r0,r0
        !          1254:        movzwl  2(r1),r1                # orw2 sign extends
        !          1255:        orl2    r1,r0
        !          1256:        ret
        !          1257: 2:
        !          1258:        movb    (r1),r0                 # move byte-word-byte
        !          1259:        shal    $24,r0,r0
        !          1260:        movzwl  1(r1),r2                # orw2 sign extends
        !          1261:        shal    $8,r2,r2
        !          1262:        movzbl  3(r1),r1                # orb2 sign extends
        !          1263:        orl2    r2,r1
        !          1264:        orl2    r1,r0
1.1       root     1265:        ret
                   1266: fserr:
                   1267:        mnegl   $1,r0
                   1268:        ret
                   1269: 
                   1270:        .globl  _fuibyte
                   1271:        .globl  _fubyte
                   1272: _fuibyte:
                   1273: _fubyte:
                   1274:        .word   0x0
                   1275:        prober  $1,*4(fp),$1
                   1276:        beql    fserr
                   1277:        movzbl  *4(fp),r0
                   1278:        ret
                   1279: 
                   1280:        .globl  _suiword
                   1281:        .globl  _suword
                   1282: _suiword:
                   1283: _suword:
                   1284:        .word   0x0
1.1.1.2 ! root     1285:        movl    4(fp),r0
        !          1286:        probew  $1,(r0),$1              # check access of first byte
        !          1287:        beql    fserr                   # page unwritable
        !          1288:        probew  $1,3(r0),$1             # check access of last byte
        !          1289:        beql    fserr                   # page unwritable
        !          1290:        bitl    $1,r0                   # check byte alignment
        !          1291:        bneq    1f                      # odd byte boundary
        !          1292:        bitl    $2,r0                   # check word alignment
        !          1293:        beql    2f                      # longword boundary
        !          1294:        movw    8(fp),(r0)              # move two words
        !          1295:        movw    10(fp),2(r0)
        !          1296:        jbr     3f
        !          1297: 1:
        !          1298:        movb    8(fp),(r0)
        !          1299:        movb    9(fp),1(r0)
        !          1300:        movb    10(fp),2(r0)
        !          1301:        movb    11(fp),3(r0)
        !          1302:        jbr     3f
        !          1303: 2:
        !          1304:        movl    8(fp),(r0)
        !          1305: 3:
1.1       root     1306:        clrl    r0
                   1307:        ret
                   1308: 
                   1309:        .globl  _suibyte
                   1310:        .globl  _subyte
                   1311: _suibyte:
                   1312: _subyte:
                   1313:        .word   0x0
                   1314:        probew  $1,*4(fp),$1
                   1315:        beql    fserr
                   1316:        movb    11(fp),*4(fp)
                   1317:        clrl    r0
                   1318:        ret
                   1319: 
                   1320: /*
                   1321:  * Copy 1 relocation unit (NBPG bytes)
                   1322:  * from user virtual address to physical address
                   1323:  */
                   1324: _copyseg:      .globl  _copyseg
                   1325:        .word   0x4
                   1326:        orl3    $PG_V|PG_KW,8(fp),_CMAP2
                   1327:        mtpr    $_CADDR2,$TBIS  # invalidate entry for copy 
                   1328:        MOVC3   ($NBPG,4(fp),$_CADDR2)
                   1329:        ret
                   1330: 
                   1331: /*
                   1332:  * clearseg(physical_page_number);
                   1333:  *
                   1334:  * zero out physical memory
                   1335:  * specified in relocation units (NBPG bytes)
                   1336:  * This routine was optimized for speed on Tahoe.
                   1337:  */
                   1338: _clearseg:     .globl  _clearseg
                   1339:        .word   0
                   1340:        orl3    $PG_V|PG_KW,4(fp),_CMAP1        # Maps to virtual addr CADDR1
                   1341:        mtpr    $_CADDR1,$TBIS
                   1342:        movl    $255,r0                         # r0 = limit
                   1343:        clrl    r1                              # r1 = index of cleared long
                   1344: 1:
                   1345:        clrl    _CADDR1[r1]
                   1346:        aobleq  r0,r1,1b
                   1347:        ret
                   1348: 
                   1349: /*
                   1350:  * if ( useracc(address, count, mode) ) ....
                   1351:  * Check address.
                   1352:  * Given virtual address, byte count, and rw flag
                   1353:  * returns 0 on no access.
                   1354:  * Note : it is assumed that on all calls to this routine,
                   1355:  *  mode=0 means write access, mode=1 means read access.
                   1356:  */
                   1357: _useracc:      .globl  _useracc
                   1358:        .word   0x4
                   1359:        movl    $1,r2                   # r2 = 'user mode' for probew/probew
                   1360: probes:
                   1361:        movl    4(fp),r0                # get va
                   1362:        movl    8(fp),r1                # count
                   1363:        tstl    12(fp)                  # test for read access ?
                   1364:        bneq    userar                  # yes
1.1.1.2 ! root     1365:        cmpl    $NBPG,r1                # can we do it in one probe ?
1.1       root     1366:        bgeq    uaw2                    # yes
                   1367: uaw1:
                   1368:        probew  r2,(r0),$NBPG
                   1369:        beql    uaerr                   # no access
                   1370:        addl2   $NBPG,r0
                   1371:        _ACBL($NBPG+1,$-NBPG,r1,uaw1)
                   1372: uaw2:
1.1.1.2 ! root     1373:        probew  r2,(r0),$1              # check first byte
        !          1374:        beql    uaerr
        !          1375:        addl2   r1,r0                   # get the address of the last byte
        !          1376:        decl    r0
        !          1377:        probew  r2,(r0),$1              # check last byte
1.1       root     1378:        beql    uaerr
                   1379:        movl    $1,r0
                   1380:        ret
                   1381: 
                   1382: userar:
                   1383:        cmpl    $NBPG,r1
                   1384:        bgeq    uar2
                   1385: uar1:
                   1386:        prober  r2,(r0),$NBPG
                   1387:        beql    uaerr
                   1388:        addl2   $NBPG,r0
                   1389:        _ACBL($NBPG+1,$-NBPG,r1,uar1)
                   1390: uar2:
1.1.1.2 ! root     1391:        prober  r2,(r0),$1              # check first byte
        !          1392:        beql    uaerr
        !          1393:        addl2   r1,r0                   # get the address of the last byte
        !          1394:        decl    r0
        !          1395:        prober  r2,(r0),$1              # check last byte
1.1       root     1396:        beql    uaerr
                   1397:        movl    $1,r0
                   1398:        ret
                   1399: uaerr:
                   1400:        clrl    r0
                   1401:        ret
                   1402: 
                   1403: /*
                   1404:  * if ( kernacc(address, count, mode) ) ....
                   1405:  * Check address.
                   1406:  * Given virtual address, byte count, and rw flag
                   1407:  * returns 0 on no access.
                   1408:  * Same as useracc routine but checks for kernel access rights.
                   1409:  */
                   1410: 
                   1411: _kernacc:      .globl  _kernacc
                   1412:        .word   0x4
                   1413:        clrl    r2              # r2 = 0 means kernel mode probe.
                   1414:        jbr     probes          # Dijkstra would get gastric distress here.
                   1415: 
                   1416: /*
                   1417:  * addupc - increment some histogram counter
                   1418:  *     in the profiling buffer
                   1419:  *
                   1420:  * addupc(pc, prof, counts)
                   1421:  * long        pc , counts;    Only least significant word of 'counts' is added.
                   1422:  * struct      uprof *prof;
                   1423:  * 
                   1424:  * struct uprof {              # profile arguments 
                   1425:  *     short   *r_base;        # buffer base 
                   1426:  *     unsigned pr_size;       # buffer size 
                   1427:  *     unsigned pr_off;        # pc offset 
                   1428:  *     unsigned pr_scale;      # pc scaling 
                   1429:  * }
                   1430:  */
                   1431:        .globl  _addupc
                   1432: _addupc:
                   1433:        .word   4
                   1434:        movl    8(fp),r2        # r2 points to structure
                   1435:        subl3   8(r2),4(fp),r0  # r0 = PC - lowpc
                   1436:        jlss    9f              # PC < lowpc , out of range !
                   1437:        shrl    $1,r0,r0        # the unit is words
                   1438:        shrl    $1,12(r2),r1    # ditto for scale
                   1439:        emul    r1,r0,$0,r0
                   1440:        shrq    $14,r0,r0
                   1441:        tstl    r0              # too big
                   1442:        jneq    9f
                   1443:        cmpl    r1,4(r2)        # Check buffer overflow
                   1444:        jgequ   9f
1.1.1.2 ! root     1445:        probew  $1,*0(r2)[r1],$1        # first byte of counter accessible?
        !          1446:        jeql    9f
        !          1447:        addl3   $1,r1,r0        # get address of the last byte
        !          1448:        probew  $1,*0(r2)[r0],$1        # last byte of counter accessible?
1.1       root     1449:        jeql    9f
                   1450:        shrl    $1,r1,r1        # make r1 word index
                   1451:        addw2   14(fp),*0(r2)[r1]
                   1452: 9:     ret
                   1453: SCBVEC(udintr0):
                   1454: SCBVEC(xpintr0):
                   1455:        jbr     _Xstray
1.1.1.2 ! root     1456: 
        !          1457: /*---------------- Alignment code -------------------*/
        !          1458: /*
        !          1459:  * There's an intimate relationship between this piece of code
        !          1460:  *     and the alignment emulation code (especially the layout
        !          1461:  *     of local variables in alignment.c! Don't change unless
        !          1462:  *     you update both this, alignment.h and alignment.c !!
        !          1463:  */
        !          1464: 
        !          1465:        .globl  _alignment
        !          1466: non_aligned:
        !          1467:        orb2    $EMULATEALIGN,_u+U_EOSYS
        !          1468:        incl    _cnt+V_TRAP
        !          1469:        moval   4(sp),_user_psl
        !          1470:        SAVE_FPSTAT(4)          # Also zeroes out ret_exception !
        !          1471:        pushl   $0              # ret_addr
        !          1472:        pushl   $0              # ret_code
        !          1473:        mfpr    $USP,-(sp)      # user sp
        !          1474:        callf   $4,_alignment   # 0 parameters == don't remove user sp
        !          1475:                                #  on return, it may be changed by emulation
        !          1476:                                #  so we have to reload it by hand !
        !          1477: 
        !          1478: /*
        !          1479: # We're back either after correct emulation or after an exception.
        !          1480: # The registers now are the user's original registers, so take care
        !          1481: #      not to ruin them before the 'rei' or whatever !
        !          1482: */
        !          1483: 2:     mtpr    (sp)+,$USP      # restore user sp. HW sp points to ret_code
        !          1484:        tstl    8(sp)           # Any exception ?
        !          1485:        bneq    got_excp        # Yes, reflect it back to user.
        !          1486:        moval   8(sp),sp        # pop the 2 zeroes we pushed
        !          1487:        REST_FPSTAT
        !          1488:        xorb2   $EMULATEALIGN,_u+U_EOSYS
        !          1489: /*
        !          1490:  * Check for trace bit set.
        !          1491:  */
        !          1492:        bitl    $PSL_T,4(sp)
        !          1493:        beql    9f
        !          1494:        CHECK_SFE(4)
        !          1495:        pushl $0
        !          1496:        SAVE_FPSTAT(8)
        !          1497:        TRAP(TRCTRAP)
        !          1498: 9:     rei
        !          1499: 
        !          1500: got_excp:                      # Have to see what exception it was
        !          1501:        casel   8(sp),$ILL_ADDRMOD,$ALIGNMENT
        !          1502:        .align  1
        !          1503: L1:
        !          1504:        .word   ill_addrmod-L1
        !          1505:        .word   ill_access -L1
        !          1506:        .word   ill_oprnd  -L1
        !          1507:        .word   arithmetic -L1
        !          1508:        .word   alignment  -L1
        !          1509:        brw     alignment       # default - shouldn't come here at all !
        !          1510: 
        !          1511: ill_addrmod:                   # No other parameters. Set up stack as
        !          1512:        moval   8(sp),sp        # the HW would do it in a real case.
        !          1513:        REST_FPSTAT
        !          1514:        jbr     _Xresadflt
        !          1515: ill_oprnd:
        !          1516:        moval   8(sp),sp
        !          1517:        REST_FPSTAT
        !          1518:        jbr     _Xresopflt
        !          1519: alignment:
        !          1520:        moval   8(sp),sp
        !          1521:        REST_FPSTAT
        !          1522:        jbr     align_excp      # Note : don't go to _Xalignflt, this
        !          1523:                                #       would cause endless loop !
        !          1524: ill_access:
        !          1525:  /*
        !          1526:  #
        !          1527:  # Now it's tricky. I want to restore the accumulator, but leave the
        !          1528:  #     sp where it is, to keep the ret_code and ret_address!
        !          1529:  #     And I can't use registers! Solution: make a copy of the things
        !          1530:  #     needed by REST_FPSTAT ! Not speedy, but who cares, the process
        !          1531:  #     is just about to go into hyperspace...
        !          1532:  #
        !          1533:  */
        !          1534:        pushl   20(sp)                  # The flags longword
        !          1535:        pushl   20(sp)                  # acc_low
        !          1536:        pushl   20(sp)                  # acc_high
        !          1537:        pushl   20(sp)                  # ret_exception ignored by REST_FPSTAT 
        !          1538:        REST_FPSTAT                     # Back where we were with the sp !
        !          1539:        movl    (sp),16(sp)             # code for illegal access
        !          1540:        movl    4(sp),20(sp)            # original virtual address
        !          1541:        moval   16(sp),sp               # Just like the HW would set it up
        !          1542:        jbr     _Xprotflt
        !          1543: 
        !          1544: arithmetic:
        !          1545: /*
        !          1546:  #
        !          1547:  # Same trickery as for illegal access.
        !          1548:  #
        !          1549:  */
        !          1550:        pushl   20(sp)                  # The flags longword
        !          1551:        pushl   20(sp)                  # acc_low
        !          1552:        pushl   20(sp)                  # acc_high
        !          1553:        pushl   20(sp)                  # ret_exception ignored by REST_FPSTAT 
        !          1554:        REST_FPSTAT                     # Back where we were with the sp !
        !          1555:        movl    (sp),20(sp)             # code for arithmetic exception
        !          1556:        moval   20(sp),sp               # Just like the HW would set it up
        !          1557:        jbr     _Xarithtrap
        !          1558: 
        !          1559: /*---------------- Alignment code -------------------*/

unix.superglobalmegacorp.com

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