Annotation of 43BSDReno/sys/tahoe/locore.s, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  *
                      6:  *     @(#)locore.s    7.14 (Berkeley) 5/10/90
                      7:  */
                      8: 
                      9: #include "../tahoe/mtpr.h"
                     10: #include "../tahoe/trap.h"
                     11: #include "../tahoe/psl.h"
                     12: #include "../tahoe/pte.h"
                     13: #include "../tahoe/cp.h"
                     14: #include "../tahoe/mem.h"
                     15: #include "../tahoe/SYS.h"
                     16: 
                     17: #include "../tahoemath/fp.h"
                     18: 
                     19: #include "errno.h"
                     20: #include "syscall.h"
                     21: #include "cmap.h"
                     22: 
                     23:        .set    HIGH,0x1f               # mask for total disable
                     24:        .set    NISP,3                  # number of interrupt stack pages
                     25:        .set    SYSTEM,0xC0000000       # virtual address of system start
                     26:        .set    PPAGES,0x100000         # possible pages in P0,P1, etc.
                     27: 
                     28: /* ACBL for non-negative '_add' */
                     29: #define ACBL(_limit,_add,_index,_displ) \
                     30:        addl2   _add,_index; \
                     31:        cmpl    _index,_limit; \
                     32:        bleq    _displ
                     33: 
                     34: /* _ACBL for negative '_add' */
                     35: #define _ACBL(_limit,_add,_index,_displ) \
                     36:        addl2   _add,_index; \
                     37:        cmpl    _index,_limit; \
                     38:        bgeq    _displ
                     39: 
                     40: #define        MOVC3(_srcaddr,_dstaddr,_len) \
                     41:        movl    _srcaddr,r0; \
                     42:        movl    _dstaddr,r1; \
                     43:        movl    _len,r2; \
                     44:        movblk
                     45: 
                     46: /* keep address of psl if coming from user mode */
                     47: #define CHECK_SFE(_delta) \
                     48:        bitl    $PSL_CURMOD,_delta(sp); \
                     49:        jeql    1f; \
                     50:        moval   _delta(sp),_user_psl; \
                     51: 1:
                     52: 
                     53: /*
                     54:  * User structure is UPAGES at top of user space.
                     55:  */
                     56:        .globl  _u
                     57:        .set    _u,SYSTEM - UPAGES*NBPG
                     58: 
                     59: /*
                     60:  * Restart stack. Used on power recovery or panic.
                     61:  * Takes a core-dump and then halts.
                     62:  */ 
                     63:        .globl  _rsstk
                     64:        .globl  pwfl_stk        
                     65: _rsstk:
                     66:        .space  1024-8
                     67: pwfl_stk:
                     68:        .space  4
                     69: dumpflag:
                     70:        .space  4
                     71: 
                     72:        .globl  _intstack
                     73: _intstack:
                     74:        .space  NISP*NBPG
                     75: eintstack:
                     76: 
                     77: /*
                     78:  * Power failure storage block and
                     79:  * macros for saving and restoring.
                     80:  */
                     81: #define        POWERFAIL(id,longs) \
                     82:        .globl  pwfl_/**/id \
                     83: pwfl_/**/id: .space longs*4
                     84:        .data
                     85:        POWERFAIL(r0,   14)             # r0-r13
                     86:        POWERFAIL(sp,   1)              # r14
                     87:        POWERFAIL(SCBB, 1)              # system control block base
                     88:        POWERFAIL(SBR,  1)              # system pte base
                     89:        POWERFAIL(SLR,  1)              # system pte length
                     90:        POWERFAIL(P0BR, 1)              # p0 pte base
                     91:        POWERFAIL(P0LR, 1)              # p0 pte length
                     92:        POWERFAIL(P1BR, 1)              # p1 pte base
                     93:        POWERFAIL(P1LR, 1)              # p1 pte length
                     94:        POWERFAIL(P2BR, 1)              # p2 pte base
                     95:        POWERFAIL(P2LR, 1)              # p2 pte length
                     96:        POWERFAIL(IPL,  1)              # interrupt priority level
                     97:        POWERFAIL(DCK,  1)              # data cache key
                     98:        POWERFAIL(CCK,  1)              # code cache key
                     99:        POWERFAIL(PCBB, 1)              # process control block base
                    100:        POWERFAIL(ISP,  1)              # interrupt stack pointer
                    101:        POWERFAIL(KSP,  1)              # kernel mode stack pointer
                    102:        POWERFAIL(USP,  1)              # user mode stack pointer
                    103:        POWERFAIL(MME,  1)              # memory management enable
                    104:        POWERFAIL(PSL,  1)              # processor status longword
                    105: 
                    106: /*
                    107:  * Save current state in power fail storage block.
                    108:  */
                    109: #define        SAVEpwfl() \
                    110:        movpsl  pwfl_PSL        # Keeps all flags, etc. \
                    111:        storer  $0x3fff,pwfl_r0 # Saves r0-r13 \
                    112:        moval   0(sp),pwfl_sp   # Saves sp (=r14) \
                    113:        mfpr    $SBR,pwfl_SBR   # Save all re_loadable registers \
                    114:        mfpr    $SLR,pwfl_SLR \
                    115:        mfpr    $P0BR,pwfl_P0BR \
                    116:        mfpr    $P0LR,pwfl_P0LR \
                    117:        mfpr    $P1BR,pwfl_P1BR \
                    118:        mfpr    $P1LR,pwfl_P1LR \
                    119:        mfpr    $P2BR,pwfl_P2BR \
                    120:        mfpr    $P2LR,pwfl_P2LR \
                    121:        mfpr    $IPL,pwfl_IPL \
                    122:        mfpr    $MME,pwfl_MME \
                    123:        mfpr    $DCK,pwfl_DCK \
                    124:        mfpr    $CCK,pwfl_CCK \
                    125:        mfpr    $PCBB,pwfl_PCBB \
                    126:        mfpr    $ISP,pwfl_ISP \
                    127:        mfpr    $SCBB,pwfl_SCBB \
                    128:        mfpr    $KSP,pwfl_KSP \
                    129:        mfpr    $USP,pwfl_USP
                    130: 
                    131: /*
                    132:  * Restore state saved in power fail block and
                    133:  * jmp to location specified after (possibly)
                    134:  * enabling memory management.
                    135:  */
                    136: #define        RESTOREpwfl(loc) \
                    137:        loadr   $0x3fff,pwfl_r0 # Restore r0-r13 \
                    138:        movl    pwfl_sp,sp      # Restore sp (=r14) \
                    139:        mtpr    pwfl_SCBB,$SCBB \
                    140:        mtpr    pwfl_SBR,$SBR   # Restore all re_loadable registers \
                    141:        mtpr    pwfl_SLR,$SLR \
                    142:        mtpr    pwfl_P0BR,$P0BR \
                    143:        mtpr    pwfl_P0LR,$P0LR \
                    144:        mtpr    pwfl_P1BR,$P1BR \
                    145:        mtpr    pwfl_P1LR,$P1LR \
                    146:        mtpr    pwfl_P2BR,$P2BR \
                    147:        mtpr    pwfl_P2LR,$P2LR \
                    148:        mtpr    pwfl_IPL,$IPL \
                    149:        mtpr    pwfl_DCK,$DCK \
                    150:        mtpr    pwfl_CCK,$CCK \
                    151:        mtpr    pwfl_PCBB,$PCBB \
                    152:        mtpr    pwfl_ISP,$ISP \
                    153:        mtpr    pwfl_KSP,$KSP \
                    154:        mtpr    pwfl_USP,$USP \
                    155: \
                    156:        bicpsw  $0xff           # Restore PSW. \
                    157:        bispsw  pwfl_PSL+2      # Set original bits back (just in case..) \
                    158: # now go to mapped mode \
                    159: # Have to change PC to system addresses \
                    160:        mtpr    $1,$PACC        # Thoroughly clean up caches. \
                    161:        mtpr    $1,$PADC \
                    162:        mtpr    $1,$TBIA \
                    163:        mtpr    pwfl_MME,$MME   # Restore MME. Last thing to be done. \
                    164:        jmp     loc
                    165: 
                    166: /*
                    167:  * Do a dump.
                    168:  * Called by auto-restart.
                    169:  * May be called manually.
                    170:  */
                    171:        .align  2
                    172:        .text
                    173:        .globl  _Xdoadump
                    174:        .globl  _doadump
                    175: _Xdoadump:                                     # CP comes here after power fail
                    176:        RESTOREpwfl(*0f)                        # restore state
                    177: _doadump:
                    178:        .word 0
                    179: 0:     mtpr    $HIGH,$IPL
                    180: #define        _rsstkmap _Sysmap+12    # powerfail storage, scb, rsstk, int stack
                    181:        tstl    dumpflag                        # dump only once!
                    182:        bneq    1f
                    183:        andl2   $~PG_PROT,_rsstkmap
                    184:        orl2    $PG_KW,_rsstkmap                # Make dump stack r/w
                    185:        mtpr    $0,$TBIA
                    186:        movl    $1,dumpflag
                    187:        movab   dumpflag,sp
                    188:        callf   $4,_dumpsys
                    189: 1:
                    190:        halt
                    191: 
                    192: /*
                    193:  * Interrupt vector routines
                    194:  */ 
                    195:        .globl  _waittime
                    196: #define        SCBVEC(name) \
                    197:        .align 2; \
                    198:        .globl _X/**/name; \
                    199: _X/**/name
                    200: #define        PANIC(msg) \
                    201:        clrl _waittime; pushab 1f; callf $8,_panic; 1: .asciz msg
                    202: #define        PRINTF(n,msg) \
                    203:        pushab 1f; callf $(n+2)*4,_printf; MSG(msg)
                    204: #define        MSG(msg) .data; 1: .asciz msg; .text
                    205: /*
                    206:  * r0-r5 are saved across all faults and interrupts.
                    207:  * Routines below and those hidden in vbglue.s (device
                    208:  * interrupts) invoke the PUSHR/POPR macros to execute
                    209:  * this.  Also, certain stack frame offset calculations
                    210:  * use this, using the REGSPC definition (and FPSPC defined below).
                    211:  */
                    212: #define        REGSPC  6*4
                    213: #define        PUSHR   movab -REGSPC(sp),sp; storer $0x3f,(sp)
                    214: #define        POPR    loadr $0x3f,(sp); movab REGSPC(sp),sp
                    215: 
                    216: /*
                    217:  * Floating point state is saved across faults and
                    218:  * interrupts.  The state occupies 4 longwords on
                    219:  * the stack:
                    220:  *     precision indicator (single = 0/double = 1)
                    221:  *     double representation of accumulator
                    222:  *     save accumulator status flag (pcb_savacc)
                    223:  */
                    224: #define        FPSPC   (4*4)
                    225: 
                    226: #define SAVE_FPSTAT(_delta) \
                    227:        bitl    $PSL_DBL,_delta(sp); \
                    228:        beql    1f; \
                    229:        pushl   $1; \
                    230:        pushd; \
                    231:        jmp     2f; \
                    232: 1:     pushl   $0; \
                    233:        pushl   $0; \
                    234:        stf     -(sp); \
                    235: 2:     tstl    _u+PCB_SAVACC; \
                    236:        bneq    3f; \
                    237:        moval   0(sp),_u+PCB_SAVACC; \
                    238:        orl2    $2,8(sp);\
                    239: 3:     pushl   $0;
                    240: 
                    241: #define REST_FPSTAT \
                    242:        tstl    (sp)+; \
                    243:        bitl    $2,8(sp);\
                    244:        beql    1f;\
                    245:        movl    $0,_u+PCB_SAVACC; \
                    246: 1:     bitl    $1,8(sp); \
                    247:        beql    2f; \
                    248:        ldd     (sp); \
                    249:        jmp     3f; \
                    250: 2:     ldf     (sp); \
                    251: 3:     moval   12(sp),sp;
                    252: 
                    253: #define REST_ACC \
                    254:        tstl    _u+PCB_SAVACC; \
                    255:        beql    2f; \
                    256:        movl    _u+PCB_SAVACC,r1; \
                    257:        andl3   $(EXPMASK|SIGNBIT),(r1),-(sp); \
                    258:        cmpl    $0x80000000,(sp)+; \
                    259:        bneq    3f; \
                    260:        clrl    (r1); \
                    261: 3:     bitl    $1,8(r1); \
                    262:        beql    1f; \
                    263:        ldd     (r1); \
                    264:        jmp     2f; \
                    265: 1:     ldf     (r1); \
                    266: 2:     ;
                    267: 
                    268:        .data
                    269: nofault: .space        4                       # bus error non-local goto label
                    270: 
                    271:        .text
                    272: SCBVEC(buserr):
                    273:        CHECK_SFE(12)
                    274:        SAVE_FPSTAT(12)
                    275:        incl    _intrcnt+I_BUSERR       # keep stats...
                    276:        pushl   r0                      # must save
                    277:        andl3   24(sp),$ERRCD,r0        # grab pushed MER value
                    278:        cmpl    r0,$APE                 # address parity error?
                    279:        jneq    1f
                    280:        halt    
                    281: 1:     cmpl    r0,$VBE                 # versabus error?
                    282:        jneq    2f
                    283:        halt
                    284: 2:
                    285:        movl    (sp)+,r0                # restore r0 and...
                    286:        bitl    $PSL_CURMOD,4*4+3*4(sp) # check if happened in user mode?
                    287:        jeql    3f                      # yes, then shift stack up for trap...
                    288:        movl    12(sp),16(sp)           # sorry, no space for which-buss...
                    289:        movl    8(sp),12(sp)
                    290:        movl    4(sp),8(sp)
                    291:        movl    0(sp),4(sp)
                    292:        movl    $T_BUSERR,0(sp)         # push trap type code and...
                    293:        jbr     alltraps                # ...merge with all other traps
                    294: 3:                                     # kernel mode, check to see if...
                    295:        tstl    nofault                 # ...doing peek/poke?
                    296:        jeql    4f                      # nofault set? if so, jump to it...
                    297:        movl    nofault,4*4+2*4(sp)     # ...setup for non-local goto
                    298:        clrl    nofault
                    299:        jbr     5f
                    300: 4:
                    301:        PUSHR
                    302:        pushab  4*4+REGSPC(sp)          # address of bus error parameters
                    303:        callf   $8,_buserror
                    304:        POPR
                    305: 5:
                    306:        REST_FPSTAT
                    307:        movab   8(sp),sp                # remove bus error parameters
                    308:        rei
                    309: 
                    310: SCBVEC(powfail):                       # We should be on interrupt stack now.
                    311:        SAVEpwfl()                      # save machine state
                    312:        moval   _Xdoadump-SYSTEM,_scb+SCB_DOADUMP
                    313:        halt
                    314: 
                    315: SCBVEC(stray):
                    316:        incl    _cnt+V_INTR             # add to statistics
                    317:        rei
                    318: 
                    319: #include "../net/netisr.h"
                    320:        .globl  _netisr
                    321: SCBVEC(netintr):
                    322:        CHECK_SFE(4)
                    323:        SAVE_FPSTAT(4); PUSHR
                    324: #include "imp.h"
                    325: #if NIMP > 0
                    326:        bbc     $NETISR_IMP,_netisr,1f;
                    327:        andl2   $~(1<<NETISR_IMP),_netisr
                    328:        callf   $4,_impintr;
                    329: 1:
                    330: #endif
                    331: #ifdef INET
                    332:        bbc     $NETISR_IP,_netisr,1f   
                    333:        andl2   $~(1<<NETISR_IP),_netisr
                    334:        callf   $4,_ipintr      
                    335: 1:
                    336: #endif
                    337: #ifdef NS
                    338:        bbc     $NETISR_NS,_netisr,1f   
                    339:        andl2   $~(1<<NETISR_NS),_netisr
                    340:        callf   $4,_nsintr      
                    341: 1:
                    342: #endif
                    343: #ifdef ISO
                    344:        bbc     $NETISR_ISO,_netisr,1f  
                    345:        andl2   $~(1<<NETISR_ISO),_netisr
                    346:        callf   $4,_clnlintr    
                    347: 1:
                    348: #endif
                    349:        incl    _cnt+V_SOFT
                    350:        POPR; REST_FPSTAT
                    351:        rei
                    352: 
                    353: SCBVEC(cnrint):
                    354:        CHECK_SFE(4)
                    355:        SAVE_FPSTAT(4); PUSHR; 
                    356:        pushl $CPCONS; callf $8,_cnrint;
                    357:        incl    _intrcnt+I_CNR
                    358:        incl    _cnt+V_INTR
                    359:        POPR; REST_FPSTAT;
                    360:        rei
                    361: SCBVEC(cnxint):
                    362:        CHECK_SFE(4)
                    363:        SAVE_FPSTAT(4); PUSHR; 
                    364:        pushl $CPCONS; callf $8,_cnxint;
                    365:        incl    _intrcnt+I_CNX
                    366:        incl    _cnt+V_INTR
                    367:        POPR; REST_FPSTAT;
                    368:        rei
                    369: SCBVEC(rmtrint):
                    370:        CHECK_SFE(4)
                    371:        SAVE_FPSTAT(4); PUSHR; 
                    372:        pushl $CPREMOT; callf $8,_cnrint;
                    373:        incl    _intrcnt+I_RMTR
                    374:        incl    _cnt+V_INTR
                    375:        POPR; REST_FPSTAT;
                    376:        rei
                    377: SCBVEC(rmtxint):
                    378:        CHECK_SFE(4)
                    379:        SAVE_FPSTAT(4); PUSHR; 
                    380:        pushl $CPREMOT; callf $8,_cnxint;
                    381:        incl    _intrcnt+I_RMTX
                    382:        incl    _cnt+V_INTR
                    383:        POPR; REST_FPSTAT;
                    384:        rei
                    385: 
                    386: #define PUSHPCPSL      pushl 4+FPSPC+REGSPC(sp); pushl 4+FPSPC+REGSPC(sp);
                    387: 
                    388: SCBVEC(hardclock):
                    389:        tstl    _clk_enable
                    390:        bneq    1f
                    391:        rei
                    392: 1:
                    393:        CHECK_SFE(4)
                    394:        SAVE_FPSTAT(4); PUSHR
                    395:        PUSHPCPSL                       # push pc and psl
                    396:        callf   $12,_hardclock          # hardclock(pc,psl)
                    397:        incl    _intrcnt+I_CLOCK
                    398:        incl    _cnt+V_INTR             ## temp so not to break vmstat -= HZ
                    399:        POPR; REST_FPSTAT
                    400:        rei
                    401: SCBVEC(softclock):
                    402:        CHECK_SFE(4)
                    403:        SAVE_FPSTAT(4); PUSHR;
                    404:        PUSHPCPSL                               # push pc and psl
                    405:        callf   $12,_softclock                  # softclock(pc,psl)
                    406:        incl    _cnt+V_SOFT
                    407:        POPR; REST_FPSTAT
                    408:        rei
                    409: 
                    410: /*
                    411:  * Stray VERSAbus interrupt catch routines
                    412:  */
                    413:        .data
                    414: #define        PJ      .align 2; callf $4,_Xvstray
                    415:        .globl  _catcher
                    416: _catcher:
                    417:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    418:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    419:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    420:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    421:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    422:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    423:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    424:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    425:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    426:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    427:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    428:        PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
                    429: 
                    430:        .align  2
                    431:        .globl  _cold
                    432: _cold: .long   0x3
                    433: 
                    434:        .text
                    435: SCBVEC(vstray):
                    436:        .word   0
                    437:        bbc     $0,_cold,2f             # system running?
                    438:        bbc     $1,_cold,1f             # doing autoconfig?
                    439:        jbr     3f                      # random interrupt, ignore
                    440: 1:
                    441:        mfpr    $IPL,r12                # ...setup br and cvec
                    442:        subl3   $_catcher+7,-8(fp),r11; shar $3,r11,r11
                    443:        addl2   $SCB_DEVBASE,r11
                    444:        jbr     3f
                    445: 2:
                    446:        PUSHR
                    447:        subl3   $_catcher+7,-8(fp),r0; shar $3,r0,r0
                    448:        addl3   $SCB_DEVBASE,r0,-(sp);
                    449:        mfpr    $IPL,-(sp)
                    450:        PRINTF(2, "stray intr ipl %x vec %x\n")
                    451:        POPR
                    452: 3:     moval   0f,-8(fp); ret          # pop callf frame...
                    453: 0:     rei                             # ...and return
                    454: 
                    455: /*
                    456:  * Trap and fault vector routines
                    457:  */ 
                    458: #define        TRAP(a) pushl $T_/**/a; jbr alltraps
                    459: 
                    460: /*
                    461:  * Ast delivery (profiling and/or reschedule)
                    462:  */
                    463: 
                    464: SCBVEC(kspnotval):
                    465:        CHECK_SFE(4)
                    466:        pushl $0;
                    467:        SAVE_FPSTAT(8)
                    468:        TRAP(KSPNOTVAL)
                    469: SCBVEC(privinflt):
                    470:        CHECK_SFE(4)
                    471:        pushl $0;
                    472:        SAVE_FPSTAT(8)
                    473:        TRAP(PRIVINFLT)
                    474: SCBVEC(resopflt):
                    475:        CHECK_SFE(4)
                    476:        pushl $0;
                    477:        SAVE_FPSTAT(8)
                    478:        TRAP(RESOPFLT)
                    479: SCBVEC(resadflt):
                    480:        CHECK_SFE(4)
                    481:        pushl $0;
                    482:        SAVE_FPSTAT(8)
                    483:        TRAP(RESADFLT)
                    484: SCBVEC(bptflt):
                    485:        CHECK_SFE(4)
                    486:        pushl $0;
                    487:        SAVE_FPSTAT(8)
                    488:        TRAP(BPTFLT)
                    489: SCBVEC(kdbintr):
                    490:        CHECK_SFE(4);
                    491:        pushl $0;
                    492:        SAVE_FPSTAT(8);
                    493:        TRAP(KDBTRAP);
                    494: SCBVEC(tracep):
                    495:        CHECK_SFE(4)
                    496:        pushl $0;
                    497:        SAVE_FPSTAT(8)
                    498:        TRAP(TRCTRAP)
                    499: SCBVEC(alignflt):
                    500: #ifdef ALIGN
                    501:        bitl    $PSL_CURMOD,4(sp)
                    502:        jeql    align_excp              # Can't emulate for kernel mode !
                    503:        jbr     non_aligned             # Only emulated for user mode.
                    504: align_excp:
                    505: #else
                    506:        CHECK_SFE(4)
                    507: #endif
                    508:        pushl $0;
                    509:        SAVE_FPSTAT(8)
                    510:        TRAP(ALIGNFLT)
                    511: SCBVEC(arithtrap):
                    512:        CHECK_SFE(8)
                    513:        SAVE_FPSTAT(8)
                    514:        TRAP(ARITHTRAP)
                    515: 
                    516: SCBVEC(protflt):
                    517:        CHECK_SFE(12)
                    518:        bitl    $1,(sp)+
                    519:        jneq    segflt
                    520:        SAVE_FPSTAT(8)
                    521:        TRAP(PROTFLT)
                    522: segflt:
                    523:        SAVE_FPSTAT(8)
                    524:        TRAP(SEGFLT)
                    525: 
                    526: SCBVEC(fpm):                   # Floating Point Emulation
                    527: #ifdef FPE
                    528:        CHECK_SFE(16)
                    529:        SAVE_FPSTAT(16)
                    530:        incl    _cnt+V_FPE      # count emulation traps
                    531:        callf   $4,_fpemulate
                    532:        REST_FPSTAT
                    533: #endif
                    534:        moval   8(sp),sp        # Pop operand
                    535:        tstl    (sp)            # Stack= PSL, PC, return_code
                    536:        jneq    _Xarithtrap     # If not OK, emulate F.P. exception
                    537:        movab   4(sp),sp        # Else remove return_code and
                    538:        rei
                    539: 
                    540: SCBVEC(sfexcep):
                    541:        CHECK_SFE(4)
                    542:        pushl $0
                    543:        SAVE_FPSTAT(8)
                    544:        TRAP(ASTFLT)
                    545: 
                    546: SCBVEC(transflt):
                    547:        CHECK_SFE(12)
                    548:        bitl    $2,(sp)+
                    549:        bneq    tableflt
                    550: pageflt:
                    551:        SAVE_FPSTAT(8)
                    552:        TRAP(PAGEFLT)
                    553: tableflt:
                    554:        SAVE_FPSTAT(8)
                    555:        TRAP(TABLEFLT)
                    556: 
                    557: #define REST_STACK     movab 4(sp), sp; REST_FPSTAT; movab 4(sp), sp
                    558: 
                    559: alltraps:
                    560:        mfpr    $USP,-(sp); 
                    561:        callf   $4,_trap;
                    562:        mtpr    (sp)+,$USP
                    563:        incl    _cnt+V_TRAP
                    564:        REST_STACK                      # pop type, code, and fp stuff
                    565:        mtpr    $HIGH,$IPL              ## dont go to a higher IPL (GROT)
                    566:        rei
                    567: 
                    568: SCBVEC(syscall):
                    569:        CHECK_SFE(8)
                    570:        SAVE_FPSTAT(8)
                    571:        pushl   $T_SYSCALL
                    572:        mfpr    $USP,-(sp);
                    573:        callf   $4,_syscall;
                    574:        mtpr    (sp)+,$USP
                    575:        incl    _cnt+V_SYSCALL
                    576:        REST_STACK                      # pop type, code, and fp stuff
                    577:        mtpr    $HIGH,$IPL              ## dont go to a higher IPL (GROT)
                    578:        rei
                    579: 
                    580: /*
                    581:  * System page table.
                    582:  *
                    583:  * Mbmap and Usrptmap are enlarged by CLSIZE entries
                    584:  * as they are managed by resource maps starting with index 1 or CLSIZE.
                    585:  */ 
                    586: #define        vaddr(x)        ((((x)-_Sysmap)/4)*NBPG+SYSTEM)
                    587: #define        SYSMAP(mname, vname, npte)                      \
                    588: _/**/mname:    .globl  _/**/mname;             \
                    589:        .space  (npte)*4;                       \
                    590:        .globl  _/**/vname;                     \
                    591:        .set    _/**/vname,vaddr(_/**/mname)
                    592: #define        ADDMAP(npte)    .space  (npte)*4
                    593: 
                    594:        .data
                    595:        .align  2
                    596:        SYSMAP(Sysmap   ,Sysbase        ,SYSPTSIZE      )
                    597:        SYSMAP(Forkmap  ,forkutl        ,UPAGES         )
                    598:        SYSMAP(Xswapmap ,xswaputl       ,UPAGES         )
                    599:        SYSMAP(Xswap2map,xswap2utl      ,UPAGES         )
                    600:        SYSMAP(Swapmap  ,swaputl        ,UPAGES         )
                    601:        SYSMAP(Pushmap  ,pushutl        ,UPAGES         )
                    602:        SYSMAP(Vfmap    ,vfutl          ,UPAGES         )
                    603:        SYSMAP(CMAP1    ,CADDR1         ,1              )
                    604:        SYSMAP(CMAP2    ,CADDR2         ,1              )
                    605:        SYSMAP(mmap     ,vmmap          ,1              )
                    606:        SYSMAP(alignmap ,alignutl       ,1              )       /* XXX */
                    607:        SYSMAP(msgbufmap,msgbuf         ,MSGBUFPTECNT   )
                    608:        SYSMAP(Mbmap    ,mbutl          ,NMBCLUSTERS*MCLBYTES/NBPG+CLSIZE )
                    609: #ifdef MFS
                    610: #include "../ufs/mfsiom.h"
                    611:        /*
                    612:         * Used by the mfs_doio() routine for physical I/O
                    613:         */
                    614:        SYSMAP(Mfsiomap ,mfsiobuf       ,MFS_MAPREG )
                    615: #endif /* MFS */
                    616: #ifdef NFS
                    617: #include "../nfs/nfsiom.h"
                    618:        /*
                    619:         * Used by the nfs_doio() routine for physical I/O
                    620:         */
                    621:        SYSMAP(Nfsiomap ,nfsiobuf       ,NFS_MAPREG )
                    622: #endif /* NFS */
                    623:        /*
                    624:         * This is the map used by the kernel memory allocator.
                    625:         * It is expanded as necessary by the special features
                    626:         * that use it.
                    627:         */
                    628:        SYSMAP(kmempt   ,kmembase       ,NKMEMCLUSTERS*CLSIZE   )
                    629: #ifdef SYSVSHM
                    630:                                ADDMAP( SHMMAXPGS       )
                    631: #endif
                    632: #ifdef GPROF
                    633:                                ADDMAP( 600*CLSIZE      )
                    634: #endif
                    635:        /*
                    636:         * Enlarge kmempt as needed for bounce buffers allocated
                    637:         * by tahoe controllers.
                    638:         */
                    639: #include "hd.h"
                    640: #if NHD > 0
                    641:                                ADDMAP( NHDC*(MAXPHYS/NBPG+CLSIZE) )
                    642: #endif
                    643: #include "dk.h"
                    644: #if NDK > 0
                    645:                                ADDMAP( NVD*(MAXPHYS/NBPG+CLSIZE) )
                    646: #endif
                    647: #include "yc.h"
                    648: #if NYC > 0
                    649:                                ADDMAP( NCY*(MAXPHYS/NBPG+CLSIZE) )
                    650: #endif
                    651: #include "mp.h"
                    652:                                ADDMAP( NMP*14          )
                    653:        SYSMAP(ekmempt  ,kmemlimit      ,0              )
                    654: 
                    655:        SYSMAP(VMEMbeg  ,vmembeg        ,0              )
                    656:        SYSMAP(VMEMmap  ,vmem           ,VBIOSIZE       )
                    657:        SYSMAP(VMEMmap1 ,vmem1          ,0              )
                    658: #include "ace.h"
                    659: #if NACE > 0
                    660:                                ADDMAP( NACE*32 )
                    661: #endif
                    662: #if NHD > 0
                    663:                                ADDMAP( NHDC )
                    664: #endif
                    665: #include "vx.h"
                    666: #if NVX > 0
                    667:                                ADDMAP( NVX * 16384/NBPG )
                    668: #endif
                    669:        SYSMAP(VMEMend  ,vmemend        ,0              )
                    670: 
                    671:        SYSMAP(VBmap    ,vbbase         ,CLSIZE         )
                    672: #if NHD > 0
                    673:                                ADDMAP( NHDC*(MAXPHYS/NBPG+CLSIZE) )
                    674: #endif
                    675: #if NDK > 0
                    676:                                ADDMAP( NVD*(MAXPHYS/NBPG+CLSIZE) )
                    677: #endif
                    678: #if NYC > 0
                    679:                                ADDMAP( NCY*(MAXPHYS/NBPG+CLSIZE) )
                    680: #endif
                    681:                                ADDMAP( NMP*14          )
                    682:        SYSMAP(eVBmap   ,vbend          ,0              )
                    683: 
                    684:        SYSMAP(Usrptmap ,usrpt          ,USRPTSIZE+CLSIZE )
                    685: eSysmap:
                    686:        .globl  _Syssize
                    687:        .set    _Syssize,(eSysmap-_Sysmap)/4
                    688: 
                    689:        .text
                    690: /*
                    691:  * Initialization
                    692:  *
                    693:  * IPL 0x1f; MME 0; scbb, pcbb, sbr, slr, isp, ksp not set
                    694:  */
                    695:        .align  2
                    696:        .globl  start
                    697: start:
                    698:        .word   0
                    699: /* set system control block base and system page table params */
                    700:        mtpr    $_scb-SYSTEM,$SCBB
                    701:        mtpr    $_Sysmap-SYSTEM,$SBR
                    702:        mtpr    $_Syssize,$SLR
                    703: /* double map the kernel into the virtual user addresses of phys mem */
                    704:        mtpr    $_Sysmap,$P0BR
                    705:        mtpr    $_Syssize,$P0LR
                    706:        mtpr    $_Sysmap,$P1BR                  # against Murphy
                    707:        mtpr    $_Syssize,$P1LR
                    708: /* set ISP */
                    709:        movl    $_intstack-SYSTEM+NISP*NBPG,sp  # still physical
                    710:        mtpr    $_intstack+NISP*NBPG,$ISP
                    711: /* count up memory; _physmem contains limit */
                    712:        clrl    r7
                    713:        shll    $PGSHIFT,_physmem,r8
                    714:        decl    r8
                    715: 1:     pushl   $1; pushl r7; callf $12,_badaddr; tstl r0; bneq 9f
                    716:        ACBL(r8,$64*1024,r7,1b)
                    717: 9:
                    718: /* clear memory from kernel bss and pages for proc 0 u. and page table */
                    719:        movab   _edata,r6; andl2 $~SYSTEM,r6
                    720:        movab   _end,r5; andl2 $~SYSTEM,r5
                    721: #ifdef KADB
                    722:        subl2   $4,r5
                    723: 1:     clrl    (r6); ACBL(r5,$4,r6,1b)         # clear just bss
                    724:        addl2   $4,r5
                    725:        bbc     $6,r11,0f                       # check RB_KDB
                    726:        andl3   $~SYSTEM,r9,r5                  # skip symbol & string tables
                    727:        andl3   $~SYSTEM,r9,r6
                    728: #endif
                    729: 0:     orl3    $SYSTEM,r5,r9                   # convert to virtual address
                    730:        addl2   $NBPG-1,r9                      # roundup to next page
                    731:        addl2   $(UPAGES*NBPG)+NBPG+NBPG,r5
                    732: 1:     clrl    (r6); ACBL(r5,$4,r6,1b)
                    733: /* trap(), syscall(), and fpemulate() save r0-r12 in the entry mask */
                    734:        orw2    $0x01fff,_trap
                    735:        orw2    $0x01fff,_syscall
                    736: #ifdef FPE
                    737:        orw2    $0x01fff,_fpemulate
                    738: #endif
                    739:        orw2    $0x01ffc,_panic                 # for debugging (no r0|r1)
                    740:        callf   $4,_fixctlrmask                 # setup for autoconfig
                    741: /* initialize system page table: scb and int stack writeable */
                    742:        clrl    r2
                    743:        movab   eintstack,r1 
                    744:        andl2   $~SYSTEM,r1
                    745:        shrl    $PGSHIFT,r1,r1                  # r1-page number of eintstack
                    746: /* make 1st page processor storage read/only, 2nd read/write */
                    747:        orl3    $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2;
                    748:        orl3    $PG_V|PG_KW,r2,_Sysmap[r2]; incl r2;
                    749: /* other parts of the system are read/write for kernel */
                    750: 1:     orl3    $PG_V|PG_KW,r2,_Sysmap[r2];     # data:kernel write+phys=virtual
                    751:        aoblss r1,r2,1b
                    752: /* make rsstk read-only as red zone for interrupt stack */
                    753:        andl2   $~PG_PROT,_rsstkmap
                    754:        orl2    $PG_V|PG_KR,_rsstkmap
                    755: /* make kernel text space read-only */
                    756:        movab   _etext+NBPG-1,r1
                    757:        andl2   $~SYSTEM,r1
                    758:        shrl    $PGSHIFT,r1,r1
                    759: 1:     orl3    $PG_V|PG_KR,r2,_Sysmap[r2]
                    760:        aoblss r1,r2,1b
                    761: /* make kernel data, bss, read-write */
                    762:        andl3   $~SYSTEM,r9,r1
                    763:        shrl    $PGSHIFT,r1,r1
                    764: 1:     orl3    $PG_V|PG_KW,r2,_Sysmap[r2]
                    765:        aoblss r1,r2,1b
                    766: /* go to mapped mode, have to change both pc and sp to system addresses */
                    767:        mtpr    $1,$TBIA
                    768:        mtpr    $1,$PADC                        # needed by HW parity&ECC logic
                    769:        mtpr    $1,$PACC                        # just in case
                    770:        mtpr    $1,$MME
                    771:        movab   SYSTEM(sp),sp
                    772:        jmp     *$0f
                    773: 0:
                    774: /* disable any interrupts */
                    775:        movl    $0,_intenable
                    776: /* init mem sizes */
                    777:        shrl    $PGSHIFT,r7,_physmem
                    778: /* setup context for proc[0] == scheduler */
                    779:        andl3   $~SYSTEM,r9,r6                  # convert to physical
                    780:        andl2   $~(NBPG-1),r6                   # make page boundary
                    781: /* setup page table for proc[0] */
                    782:        shrl    $PGSHIFT,r6,r3                  # r3 = btoc(r6)
                    783:        orl3    $PG_V|PG_KW,r3,_Usrptmap        # init first upt entry
                    784:        incl    r3                              # r3 - next page
                    785:        movab   _usrpt,r0                       # r0 - first user page
                    786:        mtpr    r0,$TBIS
                    787: /* init p0br, p0lr */
                    788:        mtpr    r0,$P0BR                        # no p0 for proc[0]
                    789:        mtpr    $0,$P0LR
                    790:        mtpr    r0,$P1BR                        # no p1 either
                    791:        mtpr    $0,$P1LR
                    792: /* init p2br, p2lr */
                    793:        movab   NBPG(r0),r0
                    794:        movl    $PPAGES-UPAGES,r1
                    795:        mtpr    r1,$P2LR
                    796:        moval   -4*PPAGES(r0),r2
                    797:        mtpr    r2,$P2BR
                    798: /* setup mapping for UPAGES of _u */
                    799:        clrl    r2
                    800:        movl    $SYSTEM,r1
                    801:        addl2   $UPAGES,r3
                    802:        jbr 2f
                    803: 1:     decl    r3
                    804:        moval   -NBPG(r1),r1    # r1 = virtual add of next (downward) _u page
                    805:        subl2   $4,r0           # r0 = pte address
                    806:        orl3    $PG_V|PG_URKW,r3,(r0)
                    807:        mtpr    r1,$TBIS
                    808: 2:     aobleq  $UPAGES,r2,1b
                    809: /* initialize (slightly) the pcb */
                    810:        movab   UPAGES*NBPG(r1),PCB_KSP(r1)     # KSP starts at end of _u
                    811:        movl    r1,PCB_USP(r1)                  # USP starts just below _u
                    812:        mfpr    $P0BR,PCB_P0BR(r1)
                    813:        mfpr    $P0LR,PCB_P0LR(r1)
                    814:        mfpr    $P1BR,PCB_P1BR(r1)
                    815:        mfpr    $P1LR,PCB_P1LR(r1)
                    816:        mfpr    $P2BR,PCB_P2BR(r1)
                    817:        mfpr    $P2LR,PCB_P2LR(r1)
                    818:        movl    $CLSIZE,PCB_SZPT(r1)            # init u.u_pcb.pcb_szpt
                    819:        movl    r9,PCB_R9(r1)                   # r9 obtained from boot
                    820:        movl    r10,PCB_R10(r1)                 # r10 obtained from boot
                    821:        movl    r11,PCB_R11(r1)                 # r11 obtained from CP on boot
                    822:        movab   1f,PCB_PC(r1)                   # initial pc
                    823:        clrl    PCB_PSL(r1)                     # kernel mode, ipl=0
                    824:        shll    $PGSHIFT,r3,r3
                    825:        mtpr    r3,$PCBB                        # first pcbb (physical)
                    826: /* go to kernel mode */
                    827:        ldpctx
                    828:        rei                                     # Actually next instruction:
                    829: /* put signal trampoline code in u. area */
                    830: 1:     movab   sigcode,r0
                    831:        movab   _u+PCB_SIGC,r1
                    832:        movl    $19,r2
                    833:        movblk
                    834: /* save boot device in global _bootdev */
                    835:        movl    r10,_bootdev
                    836: /* save reboot flags in global _boothowto */
                    837:        movl    r11,_boothowto
                    838: #ifdef KADB
                    839: /* save end of symbol & string table in global _bootesym */
                    840:        subl3   $NBPG-1,r9,_bootesym
                    841: #endif
                    842: /* calculate firstaddr, and call main() */
                    843:        andl3   $~SYSTEM,r9,r0
                    844:        shrl    $PGSHIFT,r0,-(sp)
                    845:        addl2   $UPAGES+1,(sp)                  # first physical unused page
                    846:        callf   $8,_main
                    847: /* proc[1] == /etc/init now running here in kernel mode; run icode */
                    848:        pushl   $PSL_CURMOD                     # User mode PSL
                    849:        pushl $0                                # PC = 0 (virtual now)
                    850:        rei
                    851: 
                    852: /*
                    853:  * Mask for saving/restoring registers on entry to
                    854:  * a user signal handler.  Space for the registers
                    855:  * is reserved in sendsig, so beware if you want
                    856:  * to change the mask.
                    857:  */
                    858: #define        SIGREGS (R0|R1|R2|R3|R4|R5)
                    859:        .align  2
                    860:        .globl  sigcode
                    861: sigcode:
                    862:        storer  $SIGREGS,16(sp) # save volatile registers
                    863:        calls   $4*3+4,*12(sp)  # params pushed by sendsig for handler
                    864:        loadr   $SIGREGS,4(sp)  # restore volatile registers
                    865:        movab   24(sp),fp       # use parameter list set up in sendsig
                    866:        kcall   $SYS_sigreturn  # cleanup mask and onsigstack
                    867:        halt                    # sigreturn does not return!
                    868: 
                    869:        .globl  _icode
                    870:        .globl  _initflags
                    871:        .globl  _szicode
                    872: /*
                    873:  * Icode is copied out to process 1 to exec /etc/init.
                    874:  * If the exec fails, process 1 exits.
                    875:  */
                    876:        .align  2
                    877: _icode:
                    878:        /* try /sbin/init */
                    879:        pushab  b`argv1-l0(pc)
                    880: l0:    pushab  b`init1-l1(pc)
                    881: l1:    pushl   $2
                    882:        movab   (sp),fp
                    883:        kcall   $SYS_execv
                    884:        /* try /etc/init */
                    885:        pushab  b`argv2-l2(pc)
                    886: l2:    pushab  b`init2-l3(pc)
                    887: l3:    pushl   $2
                    888:        movab   (sp),fp
                    889:        kcall   $SYS_execv
                    890:        /* give up */
                    891:        pushl   r0
                    892:        pushl   $1
                    893:        movab   (sp),fp
                    894:        kcall   $SYS_exit
                    895: 
                    896: init1: .asciz  "/sbin/init"
                    897: init2: .asciz  "/etc/init"
                    898:        .align  2
                    899: _initflags:
                    900:        .long   0
                    901: argv1: .long   init1+6-_icode
                    902:        .long   _initflags-_icode
                    903:        .long   0
                    904: argv2: .long   init2+5-_icode
                    905:        .long   _initflags-_icode
                    906:        .long   0
                    907: _szicode:
                    908:        .long   _szicode-_icode
                    909: 
                    910: /*
                    911:  * Primitives
                    912:  */ 
                    913: 
                    914: /*
                    915:  * badaddr(addr, len)
                    916:  *     see if access addr with a len type instruction causes a machine check
                    917:  *     len is length of access (1=byte, 2=short, 4=long)
                    918:  *     r0 = 0 means good(exists); r0 =1 means does not exist.
                    919:  */
                    920: ENTRY(badaddr, R3|R4)
                    921:        mfpr    $IPL,r1
                    922:        mtpr    $HIGH,$IPL
                    923:        movl    _scb+SCB_BUSERR,r2
                    924:        movl    4(fp),r3
                    925:        movl    8(fp),r4
                    926:        movab   9f,_scb+SCB_BUSERR
                    927:        bbc     $0,r4,1f; tstb  (r3)
                    928: 1:     bbc     $1,r4,1f; tstw  (r3)
                    929: 1:     bbc     $2,r4,1f; tstl  (r3)
                    930: 1:     clrl    r0
                    931: 2:     movl    r2,_scb+SCB_BUSERR
                    932:        mtpr    r1,$IPL
                    933:        ret
                    934: 
                    935: /*
                    936:  * wbadaddr(addr, len, value)
                    937:  *     see if write of value to addr with a len type instruction causes
                    938:  *     a machine check
                    939:  *     len is length of access (1=byte, 2=short, 4=long)
                    940:  *     r0 = 0 means good(exists); r0 =1 means does not exist.
                    941:  */
                    942: ENTRY(wbadaddr, R3|R4)
                    943:        mfpr    $IPL,r1
                    944:        mtpr    $HIGH,$IPL
                    945:        movl    _scb+SCB_BUSERR,r2
                    946:        movl    4(fp),r3
                    947:        movl    8(fp),r4
                    948:        movab   9f,_scb+SCB_BUSERR
                    949:        bbc     $0,r4,1f; movb  15(fp), (r3)
                    950: 1:     bbc     $1,r4,1f; movw  14(fp), (r3)
                    951: 1:     bbc     $2,r4,1f; movl  12(fp), (r3)
                    952: 1:     movl    $30000,r0               # delay for error interrupt
                    953: 1:     decl    r0
                    954:        jneq    1b
                    955: 2:     movl    r2,_scb+SCB_BUSERR      # made it w/o machine checks; r0 is 0
                    956:        mtpr    r1,$IPL
                    957:        ret
                    958: 
                    959:        .align  2
                    960: 9:                             # catch buss error (if it comes)
                    961:        andl3   4(sp),$ERRCD,r0
                    962:        cmpl    r0,$APE
                    963:        jneq    1f
                    964:        halt                    # address parity error
                    965: 1:     cmpl    r0,$VBE
                    966:        jneq    1f
                    967:        halt                    # Versabus error
                    968: 1:
                    969:        movl    $1,r0           # Anything else = bad address
                    970:        movab   8(sp),sp        # discard buss error trash
                    971:        movab   2b,(sp)         # new program counter on stack.
                    972:        rei
                    973: 
                    974: /*
                    975:  * badcyaddr(addr)
                    976:  *     see if access tape master controller addr causes a bus error
                    977:  *     r0 = 0: no error; r0 = 1: timeout error.
                    978:  */
                    979: ENTRY(badcyaddr, 0)
                    980:        mfpr    $IPL,r1
                    981:        mtpr    $HIGH,$IPL
                    982:        clrl    r2
                    983:        movab   2f,nofault
                    984:        movob   $-1, *4(fp)
                    985: 1:     aobleq  $1000, r2, 1b
                    986:        clrl    nofault                 # made it w/o bus error
                    987:        clrl    r0
                    988:        jbr     3f
                    989: 2:     movl    $1,r0
                    990: 3:     mtpr    r1,$IPL
                    991:        ret
                    992: 
                    993: /*
                    994:  * peek(addr)
                    995:  *     fetch word and catch any bus error
                    996:  */
                    997: ENTRY(peek, 0)
                    998:        mfpr    $IPL,r1
                    999:        mtpr    $0x18,$IPL      # not reentrant
                   1000:        movl    4(fp),r2
                   1001:        movab   1f,nofault
                   1002:        movw    (r2),r0
                   1003:        clrl    nofault
                   1004:        andl2   $0xffff,r0
                   1005:        jbr     2f
                   1006: 1:     movl    $-1,r0          # bus error
                   1007: 2:     mtpr    r1,$IPL
                   1008:        ret
                   1009: 
                   1010: /*
                   1011:  * poke(addr, val)
                   1012:  *     write word and catch any bus error
                   1013:  */
                   1014: ENTRY(poke, R3)
                   1015:        mfpr    $IPL,r1
                   1016:        mtpr    $0x18,$IPL      # not reentrant
                   1017:        movl    4(fp),r2
                   1018:        movl    8(fp),r3
                   1019:        clrl    r0
                   1020:        movab   1f,nofault
                   1021:        movw    r3,(r2)
                   1022:        clrl    nofault
                   1023:        jbr     2f
                   1024: 1:     movl    $-1,r0          # bus error
                   1025: 2:     mtpr    r1,$IPL
                   1026:        ret
                   1027: 
                   1028: /*
                   1029:  * Copy a potentially overlapping block of memory.
                   1030:  *
                   1031:  * ovbcopy(src, dst, count)
                   1032:  *     caddr_t src, dst; unsigned count;
                   1033:  */
                   1034: ENTRY(ovbcopy, R3|R4)
                   1035:        movl    4(fp),r0
                   1036:        movl    8(fp),r1
                   1037:        movl    12(fp),r2
                   1038:        cmpl    r0,r1
                   1039:        bgtru   1f                      # normal forward case
                   1040:        beql    2f                      # equal, nothing to do
                   1041:        addl2   r2,r0                   # may be overlapping
                   1042:        cmpl    r0,r1
                   1043:        bgtru   3f
                   1044:        subl2   r2,r0                   # normal forward case
                   1045: 1:
                   1046:        movblk
                   1047: 2:
                   1048:        ret
                   1049: 3:
                   1050:        addl2   r2,r1                   # overlapping, must do backwards
                   1051:        subl3   r0,r1,r3
                   1052:        movl    r2,r4
                   1053:        jbr     5f
                   1054: 4:
                   1055:        subl2   r3,r0
                   1056:        subl2   r3,r1
                   1057:        movl    r3,r2
                   1058:        movblk
                   1059:        subl2   r3,r0
                   1060:        subl2   r3,r1
                   1061:        subl2   r3,r4
                   1062: 5:
                   1063:        cmpl    r4,r3
                   1064:        jgtr    4b
                   1065:        movl    r4,r2
                   1066:        subl2   r2,r0
                   1067:        subl2   r2,r1
                   1068:        movblk
                   1069:        ret
                   1070: 
                   1071: /*
                   1072:  * Copy a null terminated string from the user address space into
                   1073:  * the kernel address space.
                   1074:  *
                   1075:  * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
                   1076:  */
                   1077: ENTRY(copyinstr, 0)
                   1078:        movl    12(fp),r5               # r5 = max length
                   1079:        jlss    5f
                   1080:        movl    8(fp),r4                # r4 = kernel address
                   1081:        movl    4(fp),r0                # r0 = user address
                   1082:        andl3   $(NBPG*CLSIZE-1),r0,r2  # r2 = bytes on first page
                   1083:        subl3   r2,$(NBPG*CLSIZE),r2
                   1084: 1:
                   1085:        cmpl    r5,r2                   # r2 = min(bytes on page, length left);
                   1086:        jgeq    2f
                   1087:        movl    r5,r2
                   1088: 2:
                   1089:        prober  $1,(r0),r2              # bytes accessible?
                   1090:        jeql    5f
                   1091:        subl2   r2,r5                   # update bytes left count
                   1092:        movl    r2,r3                   # r3 = saved count
                   1093:        movl    r0,r1
                   1094:        cmps3                           # check for null
                   1095:        tstl    r2
                   1096:        jneq    3f
                   1097:        subl2   r3,r0                   # back up r0
                   1098:        movl    r4,r1
                   1099:        movl    r3,r2
                   1100:        movblk                          # copy in next piece
                   1101:        movl    r1,r4
                   1102:        movl    $(NBPG*CLSIZE),r2       # check next page
                   1103:        tstl    r5                      # run out of space?
                   1104:        jneq    1b
                   1105:        movl    $ENOENT,r0              # set error code and return
                   1106:        jbr     6f
                   1107: 3:
                   1108:        tstl    16(fp)                  # return length?
                   1109:        beql    4f
                   1110:        subl3   r5,12(fp),r5            # actual len = maxlen - unused pages
                   1111:        subl2   r2,r5                   #       - unused on this page
                   1112:        addl3   $1,r5,*16(fp)           #       + the null byte
                   1113: 4:
                   1114:        movl    r4,r1
                   1115:        subl3   r2,r3,r2                # calc char cnt
                   1116:        subl2   r2,r0                   # back up r0
                   1117:        incl    r2                      # add on null byte
                   1118:        movblk                          # copy last piece
                   1119:        clrl    r0
                   1120:        ret
                   1121: 5:
                   1122:        movl    $EFAULT,r0
                   1123: 6:
                   1124:        tstl    16(fp)
                   1125:        beql    7f
                   1126:        subl3   r5,12(fp),*16(fp)
                   1127: 7:
                   1128:        ret
                   1129: 
                   1130: /*
                   1131:  * Copy a null terminated string from the kernel
                   1132:  * address space to the user address space.
                   1133:  *
                   1134:  * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
                   1135:  */
                   1136: ENTRY(copyoutstr, 0)
                   1137:        movl    12(fp),r5               # r5 = max length
                   1138:        jlss    5f
                   1139:        movl    4(fp),r0                # r0 = kernel address
                   1140:        movl    8(fp),r4                # r4 = user address
                   1141:        andl3   $(NBPG*CLSIZE-1),r4,r2  # r2 = bytes on first page
                   1142:        subl3   r2,$(NBPG*CLSIZE),r2
                   1143: 1:
                   1144:        cmpl    r5,r2                   # r2 = min(bytes on page, length left);
                   1145:        jgeq    2f
                   1146:        movl    r5,r2
                   1147: 2:
                   1148:        probew  $1,(r4),r2              # bytes accessible?
                   1149:        jeql    5f
                   1150:        subl2   r2,r5                   # update bytes left count
                   1151:        movl    r2,r3                   # r3 = saved count
                   1152:        movl    r0,r1
                   1153: /*
                   1154:  * This is a workaround for a microcode bug that causes
                   1155:  * a trap type 9 when cmps3/movs3 touches the last byte
                   1156:  * on a valid page immediately followed by an invalid page.
                   1157:  */
                   1158: #ifdef good_cmps3
                   1159:        cmps3                           # check for null
                   1160:        tstl    r2
                   1161:        jneq    3b
                   1162: #else
                   1163:        decl    r2
                   1164:        beql    9f                      # cannot handle case of r2 == 0!
                   1165:        cmps3                           # check for null up to last byte
                   1166: 9:
                   1167:        incl    r2
                   1168:        cmpl    $1,r2                   # get to last byte on page?
                   1169:        bneq    3b
                   1170:        tstb    (r0)                    # last byte on page null?
                   1171:        beql    3b
                   1172:        incl    r0                      # not null, so bump pointer
                   1173: #endif not good_cmps3
                   1174:        subl2   r3,r0                   # back up r0
                   1175:        movl    r4,r1
                   1176:        movl    r3,r2
                   1177:        movblk                          # copy out next piece
                   1178:        movl    r1,r4
                   1179:        movl    $(NBPG*CLSIZE),r2       # check next page
                   1180:        tstl    r5                      # run out of space?
                   1181:        jneq    1b
                   1182:        movl    $ENOENT,r0              # set error code and return
                   1183:        jbr     6b
                   1184: 5:
                   1185:        clrl    *$0             # this should never execute, if it does
                   1186:        movl    $EFAULT,r0      #  save me a core dump (mkm - 9/87)
                   1187: 6:
                   1188:        tstl    16(fp)
                   1189:        beql    7f
                   1190:        subl3   r5,12(fp),*16(fp)
                   1191: 7:
                   1192:        ret
                   1193: 
                   1194: 
                   1195: /*
                   1196:  * Copy a null terminated string from one point to another in
                   1197:  * the kernel address space.
                   1198:  *
                   1199:  * copystr(fromaddr, toaddr, maxlength, &lencopied)
                   1200:  */
                   1201: ENTRY(copystr, 0)
                   1202:        movl    12(fp),r3               # r3 = max length
                   1203:        jlss    5b
                   1204:        movl    4(fp),r0                # r0 = src address
                   1205:        movl    8(fp),r4                # r4 = dest address
                   1206:        clrl    r5                      # r5 = bytes left
                   1207:        movl    r3,r2                   # r2 = max bytes to copy
                   1208:        movl    r0,r1
                   1209:        cmps3                           # check for null
                   1210:        tstl    r2
                   1211:        jneq    3b
                   1212:        subl2   r3,r0                   # back up r0
                   1213:        movl    r4,r1
                   1214:        movl    r3,r2
                   1215:        movblk                          # copy next piece
                   1216:        movl    $ENOENT,r0              # set error code and return
                   1217:        jbr     6b
                   1218: 
                   1219: /*
                   1220:  * Copy a block of data from the user address space into
                   1221:  * the kernel address space.
                   1222:  *
                   1223:  * copyin(fromaddr, toaddr, count)
                   1224:  */
                   1225: ENTRY(copyin, 0)
                   1226:        movl    12(fp),r0               # copy length
                   1227:        blss    9f
                   1228:        movl    4(fp),r1                # copy user address
                   1229:        cmpl    $(CLSIZE*NBPG),r0       # probing one page or less ?
                   1230:        bgeq    2f                      # yes
                   1231: 1:
                   1232:        prober  $1,(r1),$(CLSIZE*NBPG)  # bytes accessible ?
                   1233:        beql    9f                      # no
                   1234:        addl2   $(CLSIZE*NBPG),r1       # incr user address ptr
                   1235:        _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r0,1b)   # reduce count and loop
                   1236: 2:
                   1237:        prober  $1,(r1),r0              # bytes accessible ?
                   1238:        beql    9f                      # no
                   1239:        MOVC3(4(fp),8(fp),12(fp))
                   1240:        clrl    r0
                   1241:        ret
                   1242: 9:
                   1243:        movl    $EFAULT,r0
                   1244:        ret
                   1245: 
                   1246: /*
                   1247:  * Copy a block of data from the kernel 
                   1248:  * address space to the user address space.
                   1249:  *
                   1250:  * copyout(fromaddr, toaddr, count)
                   1251:  */
                   1252: ENTRY(copyout, 0)
                   1253:        movl    12(fp),r0               # get count
                   1254:        blss    9b
                   1255:        movl    8(fp),r1                # get user address
                   1256:        cmpl    $(CLSIZE*NBPG),r0       # can do in one probew?
                   1257:        bgeq    2f                      # yes
                   1258: 1:
                   1259:        probew  $1,(r1),$(CLSIZE*NBPG)  # bytes accessible?
                   1260:        beql    9b                      # no 
                   1261:        addl2   $(CLSIZE*NBPG),r1       # increment user address
                   1262:        _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r0,1b)   # reduce count and loop
                   1263: 2:
                   1264:        probew  $1,(r1),r0              # bytes accessible?
                   1265:        beql    9b                      # no
                   1266:        MOVC3(4(fp),8(fp),12(fp))
                   1267:        clrl    r0
                   1268:        ret
                   1269: 
                   1270: /*
                   1271:  * savectx is like setjmp but saves all registers.
                   1272:  * Called before swapping out the u. area, restored by resume()
                   1273:  * below.
                   1274:  */
                   1275: ENTRY(savectx, 0)
                   1276:        movl    4(fp),r2
                   1277:        storer  $0x1ff8,(r2); addl2 $40,r2      # r3-r12
                   1278:        movl    (fp),(r2); addl2 $4,r2          # fp
                   1279:        movab   8(fp),(r2); addl2 $4,r2         # sp
                   1280:        movl    -8(fp),(r2)                     # pc
                   1281:        clrl    r0
                   1282:        ret
                   1283: 
                   1284: #ifdef KADB
                   1285: /*
                   1286:  * C library -- reset, setexit -- XXX
                   1287:  *
                   1288:  *     reset(x)
                   1289:  * will generate a "return" from
                   1290:  * the last call to
                   1291:  *     setexit()
                   1292:  * by restoring r2 - r12, fp
                   1293:  * and doing a return.
                   1294:  * The returned value is x; on the original
                   1295:  * call the returned value is 0.
                   1296:  */
                   1297: ENTRY(setexit, 0)
                   1298:        movab   setsav,r0
                   1299:        storer  $0x1ffc, (r0)
                   1300:        movl    (fp),44(r0)             # fp
                   1301:        moval   4(fp),48(r0)            # sp
                   1302:        movl    -8(fp),52(r0)           # pc
                   1303:        clrl    r0
                   1304:        ret
                   1305: 
                   1306: ENTRY(reset, 0)
                   1307:        movl    4(fp),r0        # returned value
                   1308:        movab   setsav,r1
                   1309:        loadr   $0x1ffc,(r1)
                   1310:        movl    44(r1),fp
                   1311:        movl    48(r1),sp
                   1312:        jmp     *52(r1)
                   1313: 
                   1314:        .data
                   1315:        .align  2
                   1316: setsav:        .space  14*4
                   1317:        .text
                   1318: #endif
                   1319: 
                   1320:        .globl  _whichqs
                   1321:        .globl  _qs
                   1322:        .globl  _cnt
                   1323: 
                   1324:        .globl  _noproc
                   1325:        .comm   _noproc,4
                   1326:        .globl  _runrun
                   1327:        .comm   _runrun,4
                   1328: /*
                   1329:  * The following primitives use the fancy TAHOE instructions.
                   1330:  * _whichqs tells which of the 32 queues _qs
                   1331:  * have processes in them.  setrq puts processes into queues, remrq
                   1332:  * removes them from queues.  The running process is on no queue,
                   1333:  * other processes are on a queue related to p->p_pri, divided by 4
                   1334:  * actually to shrink the 0-127 range of priorities into the 32 available
                   1335:  * queues.
                   1336:  */
                   1337: 
                   1338: /*
                   1339:  * setrq(p), using fancy TAHOE instructions.
                   1340:  *
                   1341:  * Call should be made at spl8(), and p->p_stat should be SRUN
                   1342:  */
                   1343: ENTRY(setrq, 0)
                   1344:        movl    4(fp),r0
                   1345:        tstl    P_RLINK(r0)             ## firewall: p->p_rlink must be 0
                   1346:        beql    set1                    ##
                   1347:        pushab  set3                    ##
                   1348:        callf   $8,_panic               ##
                   1349: set1:
                   1350:        movzbl  P_PRI(r0),r1            # put on queue which is p->p_pri / 4
                   1351:        shar    $2,r1,r1
                   1352:        shal    $1,r1,r2
                   1353:        moval   _qs[r2],r2
                   1354:        insque  (r0),*4(r2)             # at end of queue
                   1355:        shal    r1,$1,r1
                   1356:        orl2    r1,_whichqs             # mark queue non-empty
                   1357:        ret
                   1358: 
                   1359: set3:  .asciz  "setrq"
                   1360: 
                   1361: /*
                   1362:  * remrq(p), using fancy TAHOE instructions
                   1363:  *
                   1364:  * Call should be made at spl8().
                   1365:  */
                   1366: ENTRY(remrq, 0)
                   1367:        movl    4(fp),r0
                   1368:        movzbl  P_PRI(r0),r1
                   1369:        shar    $2,r1,r1
                   1370:        bbs     r1,_whichqs,rem1
                   1371:        pushab  rem3                    # it wasn't recorded to be on its q
                   1372:        callf   $8,_panic
                   1373: rem1:
                   1374:        remque  (r0)
                   1375:        bneq    rem2                    # q not empty yet
                   1376:        shal    r1,$1,r1
                   1377:        mcoml   r1,r1
                   1378:        andl2   r1,_whichqs             # mark queue empty
                   1379: rem2:
                   1380:        clrl    P_RLINK(r0)             ## for firewall checking
                   1381:        ret
                   1382: 
                   1383: rem3:  .asciz  "remrq"
                   1384: 
                   1385: /*
                   1386:  * Masterpaddr is the p->p_addr of the running process on the master
                   1387:  * processor.  When a multiprocessor system, the slave processors will have
                   1388:  * an array of slavepaddr's.
                   1389:  */
                   1390:        .globl  _masterpaddr
                   1391:        .data
                   1392:        .align  2
                   1393: _masterpaddr: .long    0
                   1394: 
                   1395:        .text
                   1396: sw0:   .asciz  "swtch"
                   1397: 
                   1398: /*
                   1399:  * When no processes are on the runq, swtch branches to idle
                   1400:  * to wait for something to come ready.
                   1401:  */
                   1402:        .globl  Idle
                   1403: Idle: idle:
                   1404:        movl    $1,_noproc
                   1405:        mtpr    $0,$IPL                 # must allow interrupts here
                   1406: 1:
                   1407:        tstl    _whichqs                # look for non-empty queue
                   1408:        bneq    sw1
                   1409:        brb     1b
                   1410: 
                   1411: badsw: pushab  sw0
                   1412:        callf   $8,_panic
                   1413:        /* NOTREACHED */
                   1414: 
                   1415:        .align  2
                   1416: /*
                   1417:  * swtch(), using fancy tahoe instructions
                   1418:  */
                   1419: ENTRY(swtch, 0)
                   1420:        movl    (fp),fp                 # prepare for rei
                   1421:        movl    (sp),4(sp)              # saved pc
                   1422:        tstl    (sp)+
                   1423:        movpsl  4(sp)
                   1424:        incl    _cnt+V_SWTCH
                   1425: sw1:   ffs     _whichqs,r0             # look for non-empty queue
                   1426:        blss    idle                    # if none, idle
                   1427:        mtpr    $0x18,$IPL              # lock out all so _whichqs==_qs
                   1428:        bbc     r0,_whichqs,sw1         # proc moved via interrupt
                   1429:        shal    $1,r0,r1
                   1430:        moval   _qs[r1],r1
                   1431:        movl    (r1),r2                 # r2 = p = highest pri process
                   1432:        remque  *(r1)
                   1433:        bvs     badsw                   # make sure something was there
                   1434:        bneq    sw2
                   1435:        shal    r0,$1,r1
                   1436:        mcoml   r1,r1
                   1437:        andl2   r1,_whichqs             # no more procs in this queue
                   1438: sw2:
                   1439:        clrl    _noproc
                   1440:        clrl    _runrun
                   1441: #ifdef notdef
                   1442:        tstl    P_WCHAN(r2)             ## firewalls
                   1443:        bneq    badsw                   ##
                   1444:        cmpb    P_STAT(r2),$SRUN        ##
                   1445:        bneq    badsw                   ##
                   1446: #endif
                   1447:        clrl    P_RLINK(r2)             ##
                   1448:        movl    *P_ADDR(r2),r0
                   1449: #ifdef notdef
                   1450:        cmpl    r0,_masterpaddr         # resume of current proc is easy
                   1451:        beql    res0
                   1452: #endif
                   1453:        movl    r0,_masterpaddr
                   1454:        shal    $PGSHIFT,r0,r0          # r0 = pcbb(p)
                   1455:        brb     swresume
                   1456: 
                   1457: /*
                   1458:  * resume(pf)
                   1459:  */
                   1460: ENTRY(resume, 0)
                   1461:        shal    $PGSHIFT,4(fp),r0       # r0 = pcbb(pf)
                   1462:        movl    (fp),fp                 # prepare for rei
                   1463:        movl    (sp)+,4(sp)             # saved pc
                   1464:        tstl    (sp)+
                   1465:        movpsl  4(sp)
                   1466: swresume:
                   1467:        mtpr    $0x18,$IPL              # no interrupts, please
                   1468:        movl    _CMAP2,_u+PCB_CMAP2     # yech
                   1469:        REST_ACC                        # restore original accumulator
                   1470:        svpctx
                   1471:        mtpr    r0,$PCBB
                   1472:        ldpctx
                   1473:        movl    _u+PCB_CMAP2,_CMAP2     # yech
                   1474:        mtpr    $_CADDR2,$TBIS
                   1475: res0:
                   1476:        movl    _u+U_PROCP,r2           # r2 = u.u_procp
                   1477:        tstl    P_CKEY(r2)              # does proc have code key?
                   1478:        bneq    1f
                   1479:        callf   $4,_getcodekey          # no, give him one
                   1480:        movl    _u+U_PROCP,r2           # r2 = u.u_procp
                   1481:        movl    r0,P_CKEY(r2)
                   1482: 1:
                   1483:        tstl    P_DKEY(r2)              # does proc have data key?
                   1484:        bneq    1f
                   1485:        callf   $4,_getdatakey          # no, give him one
                   1486:        movl    _u+U_PROCP,r2           # r2 = u.u_procp
                   1487:        movl    r0,P_DKEY(r2)
                   1488: 1:
                   1489:        mtpr    P_CKEY(r2),$CCK         # set code cache key
                   1490:        mtpr    P_DKEY(r2),$DCK         # set data cache key
                   1491:        tstl    _u+PCB_SSWAP
                   1492:        bneq    res1
                   1493:        rei
                   1494: res1:                                  # restore alternate saved context
                   1495:        movl    _u+PCB_SSWAP,r2
                   1496:        clrl    _u+PCB_SSWAP
                   1497:        loadr   $0x3ff8,(r2); addl2 $44,r2      # restore r3-r13 (r13=fp)
                   1498:        movl    (r2),r1; addl2 $4,r2    # fetch previous sp ...
                   1499:        movab   (sp),r0                 # ... and current sp and
                   1500:        cmpl    r1,r0                   # check for credibility,
                   1501:        bgequ   1f                      # if further up stack ...
                   1502:        pushab 2f; callf $8,_panic      # ... panic
                   1503:        /*NOTREACHED*/
                   1504: 1:                                     # sp ok, complete return
                   1505:        movl    r1,sp                   # restore sp
                   1506:        pushl   $PSL_PRVMOD             # kernel mode, ipl 0
                   1507:        pushl   (r2)                    # return address
                   1508:        rei
                   1509: 2:     .asciz  "ldctx"
                   1510: 
                   1511: /*
                   1512:  * {fu,su},{byte,word}
                   1513:  */
                   1514: ENTRY(fuword, 0)
                   1515:        movl    4(fp), r1
                   1516:        prober  $1,(r1),$4              # check access
                   1517:        beql    fserr                   # page unreadable
                   1518:        bitl    $1,r1                   # check byte alignment
                   1519:        bneq    2f                      # odd, do byte-word-byte
                   1520:        bitl    $2,r1                   # check word alignment
                   1521:        bneq    1f                      # odd, do in 2 words
                   1522:        movl    (r1),r0                 # move longword
                   1523:        ret
                   1524: 1:
                   1525:        movw    (r1),r0                 # move two words
                   1526:        shal    $16,r0,r0
                   1527:        movzwl  2(r1),r1                # orw2 sign extends
                   1528:        orl2    r1,r0
                   1529:        ret
                   1530: 2:
                   1531:        movb    (r1),r0                 # move byte-word-byte
                   1532:        shal    $24,r0,r0
                   1533:        movzwl  1(r1),r2                # orw2 sign extends
                   1534:        shal    $8,r2,r2
                   1535:        movzbl  3(r1),r1                # orb2 sign extends
                   1536:        orl2    r2,r1
                   1537:        orl2    r1,r0
                   1538:        ret
                   1539: fserr:
                   1540:        mnegl   $1,r0
                   1541:        ret
                   1542: 
                   1543: ENTRY(fubyte, 0)
                   1544:        prober  $1,*4(fp),$1
                   1545:        beql    fserr
                   1546:        movzbl  *4(fp),r0
                   1547:        ret
                   1548: 
                   1549: ENTRY(suword, 0)
                   1550:        movl    4(fp), r0
                   1551:        probew  $1,(r0),$4              # check access
                   1552:        beql    fserr                   # page unwritable
                   1553:        bitl    $1,r0                   # check byte alignment
                   1554:        bneq    1f                      # odd byte boundary
                   1555:        bitl    $2,r0                   # check word alignment
                   1556:        beql    2f                      # longword aligned
                   1557:        movw    8(fp),(r0)              # move two words
                   1558:        movw    10(fp),2(r0)
                   1559:        jbr     3f
                   1560: 1:
                   1561:        movb    8(fp),(r0)
                   1562:        movb    9(fp),1(r0)
                   1563:        movb    10(fp),2(r0)
                   1564:        movb    11(fp),3(r0)
                   1565:        jbr     3f
                   1566: 2:
                   1567:        movl    8(fp),(r0)
                   1568: 3:
                   1569:        clrl    r0
                   1570:        ret
                   1571: 
                   1572: ENTRY(subyte, 0)
                   1573:        probew  $1,*4(fp),$1
                   1574:        beql    fserr
                   1575:        movb    11(fp),*4(fp)
                   1576:        clrl    r0
                   1577:        ret
                   1578: 
                   1579: /*
                   1580:  * Copy 1 relocation unit (NBPG bytes)
                   1581:  * from user virtual address to physical address
                   1582:  */
                   1583: ENTRY(copyseg, 0)
                   1584:        orl3    $PG_V|PG_KW,8(fp),_CMAP2
                   1585:        mtpr    $_CADDR2,$TBIS  # invalidate entry for copy 
                   1586:        MOVC3(4(fp),$_CADDR2,$NBPG)
                   1587:        ret
                   1588: 
                   1589: /*
                   1590:  * Clear a page of memory.  The page frame is specified.
                   1591:  *
                   1592:  * clearseg(pf);
                   1593:  */
                   1594: ENTRY(clearseg, 0)
                   1595:        orl3    $PG_V|PG_KW,4(fp),_CMAP1        # Maps to virtual addr CADDR1
                   1596:        mtpr    $_CADDR1,$TBIS
                   1597:        movl    $255,r0                         # r0 = limit
                   1598:        clrl    r1                              # r1 = index of cleared long
                   1599: 1:
                   1600:        clrl    _CADDR1[r1]
                   1601:        aobleq  r0,r1,1b
                   1602:        ret
                   1603: 
                   1604: /*
                   1605:  * Check user mode read/write access.
                   1606:  *
                   1607:  * useracc(addr, count, mode)
                   1608:  *     caddr_t addr; int count, mode;
                   1609:  * mode = 0    write access
                   1610:  * mode = 1    read access
                   1611:  */
                   1612: ENTRY(useracc, 0)
                   1613:        movl    $1,r2                   # r2 = 'user mode' for probew/probew
                   1614: probes:
                   1615:        movl    4(fp),r0                # get va
                   1616:        movl    8(fp),r1                # count
                   1617:        tstl    12(fp)                  # test for read access ?
                   1618:        bneq    userar                  # yes
                   1619:        cmpl    $(CLSIZE*NBPG),r1       # can we do it in one probe ?
                   1620:        bgeq    uaw2                    # yes
                   1621: uaw1:
                   1622:        probew  r2,(r0),$(CLSIZE*NBPG)
                   1623:        beql    uaerr                   # no access
                   1624:        addl2   $(CLSIZE*NBPG),r0
                   1625:        _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r1,uaw1)
                   1626: uaw2:
                   1627:        probew  r2,(r0),r1
                   1628:        beql    uaerr
                   1629:        movl    $1,r0
                   1630:        ret
                   1631: userar:
                   1632:        cmpl    $(CLSIZE*NBPG),r1
                   1633:        bgeq    uar2
                   1634: uar1:
                   1635:        prober  r2,(r0),$(CLSIZE*NBPG)
                   1636:        beql    uaerr
                   1637:        addl2   $(CLSIZE*NBPG),r0
                   1638:        _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r1,uar1)
                   1639: uar2:
                   1640:        prober  r2,(r0),r1
                   1641:        beql    uaerr
                   1642:        movl    $1,r0
                   1643:        ret
                   1644: uaerr:
                   1645:        clrl    r0
                   1646:        ret
                   1647: 
                   1648: /*
                   1649:  * Check kernel mode read/write access.
                   1650:  *
                   1651:  * kernacc(addr, count, mode)
                   1652:  *     caddr_t addr; int count, mode;
                   1653:  * mode = 0    write access
                   1654:  * mode = 1    read access
                   1655:  */
                   1656: ENTRY(kernacc, 0)
                   1657:        clrl    r2              # r2 = 0 means kernel mode probe.
                   1658:        jbr     probes          # Dijkstra would get gastric distress here.
                   1659: 
                   1660: /*
                   1661:  * addupc - increment some histogram counter
                   1662:  *     in the profiling buffer
                   1663:  *
                   1664:  * addupc(pc, prof, delta)
                   1665:  *     long pc; short delta; struct uprof *prof;
                   1666:  * 
                   1667:  * struct uprof {              # profile arguments 
                   1668:  *     short   *r_base;        # buffer base 
                   1669:  *     unsigned pr_size;       # buffer size 
                   1670:  *     unsigned pr_off;        # pc offset 
                   1671:  *     unsigned pr_scale;      # pc scaling 
                   1672:  * }
                   1673:  */
                   1674: ENTRY(addupc, 0)
                   1675:        movl    8(fp),r2                # r2 points to structure
                   1676:        subl3   8(r2),4(fp),r0          # r0 = PC - lowpc
                   1677:        jlss    9f                      # PC < lowpc , out of range !
                   1678:        shrl    $1,r0,r0                # the unit is words
                   1679:        shrl    $1,12(r2),r1            # ditto for scale
                   1680:        emul    r1,r0,$0,r0
                   1681:        shrq    $14,r0,r0
                   1682:        tstl    r0                      # too big
                   1683:        jneq    9f
                   1684:        cmpl    r1,4(r2)                # Check buffer overflow
                   1685:        jgequ   9f
                   1686:        probew  $1,*0(r2)[r1],$2        # counter accessible?
                   1687:        jeql    9f
                   1688:        shrl    $1,r1,r1                # make r1 word index
                   1689:        addw2   14(fp),*0(r2)[r1]
                   1690: 9:     ret
                   1691: 
                   1692: /*
                   1693:  * scanc(size, cp, table, mask)
                   1694:  */
                   1695: ENTRY(scanc, R3|R4)
                   1696:        movl    8(fp),r0                # r0 = cp
                   1697:        addl3   4(fp),r0,r2             # end = &cp[size]
                   1698:        movl    12(fp),r1               # r1 = table
                   1699:        movb    19(fp),r4               # r4 = mask
                   1700:        decl    r0                      # --cp
                   1701:        jbr     0f                      # just like Fortran...
                   1702: 1:                                     # do {
                   1703:        movzbl  (r0),r3 
                   1704:        bitb    r4,(r1)[r3]             #       if (table[*cp] & mask)
                   1705:        jneq    2f                      #               break;
                   1706: 0:     aoblss  r2,r0,1b                # } while (++cp < end);
                   1707: 2:
                   1708:        subl3   r0,r2,r0; ret           # return (end - cp);
                   1709: 
                   1710: /*
                   1711:  * skpc(mask, size, cp)
                   1712:  */
                   1713: ENTRY(skpc, 0)
                   1714:        movl    12(fp),r0               # r0 = cp
                   1715:        addl3   8(fp),r0,r1             # r1 = end = &cp[size];
                   1716:        movb    7(fp),r2                # r2 = mask
                   1717:        decl    r0                      # --cp;
                   1718:        jbr     0f
                   1719: 1:                                     # do
                   1720:        cmpb    (r0),r2                 #       if (*cp != mask)
                   1721:        jneq    2f                      #               break;
                   1722: 0:     aoblss  r1,r0,1b                # while (++cp < end);
                   1723: 2:
                   1724:        subl3   r0,r1,r0; ret           # return (end - cp);
                   1725: 
                   1726: /*
                   1727:  * locc(mask, size, cp)
                   1728:  */
                   1729: ENTRY(locc, 0)
                   1730:        movl    12(fp),r0               # r0 = cp
                   1731:        addl3   8(fp),r0,r1             # r1 = end = &cp[size]
                   1732:        movb    7(fp),r2                # r2 = mask
                   1733:        decl    r0                      # --cp;
                   1734:        jbr     0f
                   1735: 1:                                     # do
                   1736:        cmpb    (r0),r2                 #       if (*cp == mask)
                   1737:        jeql    2f                      #               break;
                   1738: 0:     aoblss  r1,r0,1b                # while (++cp < end);
                   1739: 2:
                   1740:        subl3   r0,r1,r0; ret           # return (end - cp);
                   1741: 
                   1742: #ifdef ALIGN
                   1743: #include "../tahoealign/align.h"
                   1744: 
                   1745:        .globl  _alignment
                   1746: /*
                   1747:  * There's an intimate relationship between this piece of code
                   1748:  * and the alignment emulation code (especially the layout
                   1749:  * of local variables in alignment.c! Don't change unless
                   1750:  * you update both this, alignment.h and alignment.c !!
                   1751:  */
                   1752: non_aligned:
                   1753:        orb2    $EMULATEALIGN,_u+U_EOSYS
                   1754:        incl    _cnt+V_TRAP
                   1755:        incl    _cnt+V_ALIGN            # count emulated alignment traps
                   1756:        moval   4(sp),_user_psl
                   1757:        SAVE_FPSTAT(4)                  # Also zeroes out ret_exception !
                   1758:        pushl   $0                      # ret_addr
                   1759:        pushl   $0                      # ret_code
                   1760:        mfpr    $USP,-(sp)              # user sp
                   1761:        callf   $4,_alignment           # call w/o parms so regs may be modified
                   1762:        /*
                   1763:         * We return here after a successful emulation or an exception.
                   1764:         * The registers have been restored and we must not alter them
                   1765:         * before returning to the user.
                   1766:         */
                   1767: 2:     mtpr    (sp)+,$USP              # restore user sp
                   1768:        tstl    8(sp)                   # Any exception ?
                   1769:        bneq    got_excp                # Yes, reflect it back to user.
                   1770:        moval   8(sp),sp                # pop 2 zeroes pushed above
                   1771:        REST_FPSTAT
                   1772:        xorb2   $EMULATEALIGN,_u+U_EOSYS
                   1773: 
                   1774:        bitl    $PSL_T,4(sp)            # check for trace bit set
                   1775:        beql    9f
                   1776:        CHECK_SFE(4)
                   1777:        pushl $0
                   1778:        SAVE_FPSTAT(8)
                   1779:        TRAP(TRCTRAP)
                   1780: 9:     rei
                   1781: 
                   1782: got_excp:                              # decode exception
                   1783:        casel   8(sp),$ILL_ADDRMOD,$ALIGNMENT
                   1784:        .align  1
                   1785: L1:
                   1786:        .word   ill_addrmod-L1
                   1787:        .word   ill_access-L1
                   1788:        .word   ill_oprnd-L1
                   1789:        .word   arithmetic-L1
                   1790:        .word   alignment-L1
                   1791:        brw     alignment               # default - shouldn't come here at all !
                   1792: 
                   1793: ill_addrmod:                           # No other parameters. Set up stack as
                   1794:        moval   8(sp),sp                # the HW would do it in a real case.
                   1795:        REST_FPSTAT
                   1796:        jbr     _Xresadflt
                   1797: ill_oprnd:
                   1798:        moval   8(sp),sp
                   1799:        REST_FPSTAT
                   1800:        jbr     _Xresopflt
                   1801: alignment:
                   1802:        moval   8(sp),sp
                   1803:        REST_FPSTAT
                   1804:        jbr     align_excp      # NB: going to _Xalignflt would cause loop
                   1805: ill_access:
                   1806:        /*
                   1807:         * Must restore accumulator w/o modifying sp and w/o using
                   1808:         * registers.  Solution: copy things needed by REST_FPSTAT.
                   1809:         */
                   1810:        pushl   20(sp)                  # The flags longword
                   1811:        pushl   20(sp)                  # acc_low
                   1812:        pushl   20(sp)                  # acc_high
                   1813:        pushl   20(sp)                  # ret_exception ignored by REST_FPSTAT 
                   1814:        REST_FPSTAT                     # Back where we were with the sp !
                   1815:        movl    (sp),16(sp)             # code for illegal access
                   1816:        movl    4(sp),20(sp)            # original virtual address
                   1817:        moval   16(sp),sp               # Just like the HW would set it up
                   1818:        jbr     _Xprotflt
                   1819: arithmetic:                            # same trickery as above
                   1820:        pushl   20(sp)                  # The flags longword
                   1821:        pushl   20(sp)                  # acc_low
                   1822:        pushl   20(sp)                  # acc_high
                   1823:        pushl   20(sp)                  # ret_exception ignored by REST_FPSTAT 
                   1824:        REST_FPSTAT                     # Back where we were with the sp !
                   1825:        movl    (sp),20(sp)             # code for arithmetic exception
                   1826:        moval   20(sp),sp               # Just like the HW would set it up
                   1827:        jbr     _Xarithtrap
                   1828: #endif

unix.superglobalmegacorp.com

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