Annotation of 43BSDReno/sys/mdec/tmscpboot.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     @(#)tmscpboot.c 7.2 (Berkeley) 1/22/88
                      3:  *
                      4:  * TK50 tape boot block for distribution tapes
                      5:  * works on Q-bus tk50 drive on uVaxen
                      6:  *
                      7:  * Rick Lindsley
                      8:  * [email protected]
                      9:  *
                     10:  * reads a program from a tp directory on a tape and executes it
                     11:  * program must be stripped of the header and is loaded ``bits as is''
                     12:  * you can return to this loader via ``ret'' as you are called ``calls $0,ent''
                     13:  */
                     14:        .set    RELOC,0x70000
                     15: /* tp directory definitions */
                     16:        .set    FILSIZ,38       # tp direc offset for file size
                     17:        .set    BNUM,44         # tp dir offset for start block no.
                     18:        .set    ENTSIZ,64       # size of 1 TP dir entry, bytes
                     19:        .set    PTHSIZ,32       # size of TP path name, bytes
                     20:        .set    BLKSIZ,512      # tape block size, bytes
                     21:        .set    NUMDIR,24       # no. of dir blocks on tape
                     22:        .set    ENTBLK,8        # no. of dir entries per tape block
                     23: /* processor registers and bits */
                     24:        .set    RXCS,32
                     25:        .set    RXDB,33
                     26:        .set    TXCS,34
                     27:        .set    TXDB,35
                     28:        .set    RXCS_DONE,0x80
                     29:        .set    TXCS_RDY,0x80
                     30:        .set    TXCS_pr,7       /* bit position of TXCS ready bit */
                     31:        .set    RXCS_pd,7       /* bit position of RXCS done bit */
                     32: /* UBA registers */
                     33:        .set    MAPSTART,0x20088000     # for a uVax, anyway
                     34:        .set    UBAMEM,0x1ffc2000       # again, for a uVax
                     35:        .set    MRV,0x80000000          # map register valid bit
                     36: /* TMSCP UBA registers */
                     37:        .set    TMSCP_CSR, 0774500      # CSR of tk50
                     38:        .set    TMSCPip,0               # initialization and polling
                     39:        .set    TMSCPsa,2               # status and address
                     40: /* handy values for tmscp communication area */
                     41:        .set    TMSCP_OWN,0x80000000
                     42:        .set    TMSCP_ERR,0x8000
                     43:        .set    TMSCP_STEP4,0x4000
                     44:        .set    TMSCP_STEP3,0x2000
                     45:        .set    TMSCP_STEP2,0x1000
                     46:        .set    TMSCP_STEP1,0x800
                     47:        .set    TMSCP_IE,0x80
                     48:        .set    TMSCP_GO,1
                     49: /* handy offsets into tmscp communication area (from tmscpca) */
                     50:        .set    cmdint,4
                     51:        .set    rspint,6
                     52:        .set    rspdsc,8
                     53:        .set    cmddsc,12
                     54: /* handy offsets into mscp packets (from %rCMD or %rRSP) */
                     55:        .set    msglen,0
                     56:        .set    vcid,3
                     57:        .set    unit,8
                     58:        .set    op,12
                     59:        .set    status,14
                     60:        .set    modifier,14
                     61:        .set    bytecnt,16
                     62:        .set    cntflgs,18
                     63:        .set    buffer,20
                     64:        .set    tmkcnt,20
                     65:        .set    lbn,32
                     66:        .set    dscptr,40
                     67: /* TMSCP commands and modifiers */
                     68:        .set    M_OP_STCON,4
                     69:        .set    M_OP_ONLIN,9
                     70:        .set    M_OP_READ,33
                     71:        .set    M_OP_REPOS,37
                     72:        .set    M_MD_REWND,2
                     73:        .set    M_MD_IMMED,0x80
                     74:        .set    M_MD_CLSEX,0x200
                     75:        .set    M_ST_MASK,0x1f
                     76:        .set    M_ST_TAPEM,14
                     77: /* miscellaneous */
                     78:        .set    IUR, 0x37
                     79:        .set    SID, 0x3e
                     80:        .set    VAX_630,8
                     81: /* local stack variables */
                     82:        .set    tmscpca,-240-PTHSIZ-26  # struct tmscpca (see tmscpreg.h)
                     83:        .set    rsp,-240-PTHSIZ-10      # tmscp response area
                     84:        .set    cmd,-120-PTHSIZ-10      # tmscp command area
                     85:        .set    name,-PTHSIZ-10         # operator-typed file name
                     86:        .set    dirread,-10             # is the tape directory incore already?
                     87:        .set    mtapa,-8                # cur tape addr (last blk we read)
                     88:        .set    tapa,-4                 # desired tape addr (inclusive)
                     89: /* register usage */
                     90:        .set    rCMD,r7
                     91:        .set    rRSP,r8
                     92:        .set    rUBADDR,r9
                     93:        .set    rMAPREGS,r10
                     94:        .set    rCSR,r11
                     95: /* ===== */
                     96: 
                     97: /* initialization */
                     98: init:
                     99:        #
                    100:        # if on a uVax, we were loaded by VMB from tape. We also have
                    101:        # only one unibus, at 0x1fffc2000 (see above). Elstwise, this
                    102:        # boot program will almost certainly need help.
                    103:        #
                    104:        mfpr    $SID,r0
                    105:        cmpzv   $24,$8,r0,$VAX_630
                    106:        beql    1f
                    107:        halt
                    108:        #
                    109:        # We must have been loaded by VMB, and thus we are at a non-zero
                    110:        # location.  sp will contain the base address of the area at which
                    111:        # we were loaded. So we add sp to $end to get the true end-of-program
                    112:        # address.
                    113:        #
                    114: 1:     movl    sp,r6           # r6 - beginning of program
                    115:        movl    $RELOC,fp       # core loc to which to move this program
                    116:        addl3   $-512,fp,sp     # set stack pointer; leave room for locals
                    117:        addl3   $-512,fp,r0     # zero our destination mem .. we start here
                    118:        addl3   $end,fp,r1      # and end here
                    119: clr:   clrl    (r0)+
                    120:        cmpl    r0,r1
                    121:        jlss    clr
                    122: 
                    123:        movc3   $end,(r6),(fp)  # copy to relocated position
                    124:        addl3   $reginit,$RELOC,r0
                    125:        jmp     (r0)            # and go there
                    126: reginit:
                    127:        /* initialize our registers. Should need to do this only once */
                    128:        addl3   $UBAMEM, $TMSCP_CSR, %rCSR      # set up CSR register
                    129:        movl    $MAPSTART, %rMAPREGS    # locate map registers
                    130: 
                    131:        moval   tmscpca(fp), %rUBADDR   # set unibus address for comm area
                    132:        extzv   $0,$9,%rUBADDR,%rUBADDR # format: (MR# << 9) | (&comm & 0x1ff)
                    133:        ashl    $-9,$RELOC-512,r0       # setting up map register for our stack
                    134:        bisl3   $MRV,r0,(%rMAPREGS)     # mark our stack valid (MR #0)
                    135: 
                    136:        moval   cmd(fp),%rCMD           # location of cmd mscp packet
                    137:        moval   rsp(fp),%rRSP           # location of rsp mscp packet
                    138:        bsbw    inittmscp               # init the unit
                    139:        bsbw    onlin                   # set tape online
                    140:        bsbw    rew                     # rewind tape
                    141: 
                    142: start:
                    143: #ifdef DEBUG
                    144:        movzbl  $11,r0                  # newline
                    145:        bsbw    putc
                    146:        movzbl  $13,r0                  # return
                    147:        bsbw    putc
                    148: #endif
                    149:        movzbl  $'=,r0                  # prompt
                    150:        bsbw    putc
                    151:        bsbw    getname
                    152: 
                    153:        # desired TP filename is in name(fp).  Now read in entire tp directory
                    154:        # contents into low core, starting at loc 0. Because tk50's are slow,
                    155:        # and because we are going to go over 512 bytes anyway, and because
                    156:        # it requires so little effort, we'll keep track of whether the data
                    157:        # at location 0 is the tape directory.
                    158: 
                    159:        tstw    dirread(fp)     # if directory needs to be read in, do so
                    160:        bneq    1f
                    161:        bsbw    readdir
                    162: 1:
                    163:        #
                    164:        # all of directory is now in locore, @ 0.
                    165:        # search for filename; return to start if it isn't there.
                    166:        #
                    167:        clrl    r0                      # start at location 0
                    168: nxtdir:        moval   name(fp),r2
                    169:        movl    r0,r1
                    170: 1:     cmpb    (r1),(r2)
                    171:        bneq    2f
                    172:        tstb    (r1)
                    173:        beql    found
                    174:        incl    r1
                    175:        incl    r2
                    176:        brb     1b
                    177: 2:     acbl    $NUMDIR*BLKSIZ-1,$ENTSIZ,r0,nxtdir
                    178:        brw     start                   # entry not in directory; start over
                    179: 
                    180:        # entry IS here; read it in from tape
                    181: 
                    182: found: movzwl  BNUM(r0),tapa(fp)       # start block no., 2 bytes
                    183:        addl2   $2-1,tapa(fp)           # skip over this program (2 blocks)
                    184:                                        # minus 1 because we will read THROUGH
                    185:                                        # this block; so we want to stop just
                    186:                                        # before it
                    187:        movzwl  FILSIZ(r0),r4           # low 2 bytes file size
                    188:        insv    FILSIZ-1(r0),$16,$8,r4  # file size, high byte
                    189:        cmpl    r4,$RELOC-512           # check if file fits below stack
                    190:        bgeq    start                   # file too large
                    191: 
                    192:        # Now advance to proper place on tape. tapa has our
                    193:        # desired address
                    194: 
                    195:        clrw    dirread(fp)     # we are about to obliterate our incore copy
                    196:                                # of the directory
                    197: 2:     clrl    r3      # rrec expects r3 to point to a buffer. 0 will do ...
                    198:        bsbw    rrec
                    199:        cmpl    mtapa(fp),tapa(fp)
                    200:        blss    2b
                    201: 
                    202:        # tape now positioned correctly. Read in program. Number of bytes
                    203:        # to read is in r4. We must round up to an even BLKSIZ boundary.
                    204:        # Clear the area we are putting it at; unix expects zeroes in its
                    205:        # data and bss section.
                    206: 
                    207:        addl2   $BLKSIZ-1,r4            # round up
                    208:        bicl2   $BLKSIZ-1,r4            # mask out
                    209:        movl    r4,r5                   # use r5; need to save r4 for later
                    210: 1:     clrl    (r5)
                    211:        sobgtr  r5,1b
                    212: 
                    213:        # now read in file.
                    214: 
                    215:        clrl    r3                      # read into page 0 (incremented by rrec)
                    216:        ashl    $-9,r4,r5               # r5 now holds # blks to read
                    217:        addl2   r5,tapa(fp)             # compute desired tape blk #
                    218: 1:     bsbw    rrec
                    219:        cmpl    mtapa(fp),tapa(fp)      # got it yet?
                    220:        blss    1b
                    221: 
                    222:        # begin execution. Call as a function.
                    223:        clrl    r5
                    224:        calls   $0,(r5)
                    225: 
                    226:        # now, since the called function has reset the tape drive for
                    227:        # us (!) we must reinit it again ourselves.
                    228: 
                    229:        ashl    $-9,$RELOC-512,r0       # set up map register for our stack
                    230:        bisl3   $MRV,r0,(%rMAPREGS)     # mark our stack valid (MR #0)
                    231:        bsbw    inittmscp               # re-init drive
                    232:        bsbw    onlin                   # re-online it
                    233:        brw     start
                    234: 
                    235:        # getname will set name(fp) and leave len(name(fp)) in r6
                    236: getname:moval  name(fp),r1             # mov to register for ease of access
                    237: nxtc:  bsbw    getc
                    238:        cmpb    r0,$012                 # end of line?
                    239:        beql    nullc
                    240:        movb    r0,(r1)+
                    241:        brb     nxtc
                    242: nullc: moval   name(fp),r0
                    243:        subl3   r0,r1,r6                # length of path name
                    244:        jeql    start                   # just hit return; nothing useful here
                    245:        clrb    (r1)+                   # add null at end
                    246:        incl    r6                      # add null to length
                    247:        rsb
                    248: 
                    249: getc:  mfpr    $RXCS,r0
                    250:        bbc     $RXCS_pd,r0,getc        /* receiver ready ? */
                    251:        mfpr    $RXDB,r0
                    252:        extzv   $0,$7,r0,r0
                    253:        cmpb    r0,$015
                    254:        bneq    putc
                    255:        bsbw    putc
                    256:        movb    $0,r0
                    257:        bsbw    putc
                    258:        movb    $012,r0
                    259: 
                    260: putc:  mfpr    $TXCS,r2
                    261:        bbc     $TXCS_pr,r2,putc        /* transmitter ready ? */
                    262:        extzv   $0,$7,r0,r0
                    263:        mtpr    r0,$TXDB
                    264:        rsb
                    265: 
                    266: inittmscp:
                    267:        movw    $0,TMSCPip(%rCSR)               # start step 1
                    268: 1:     bitw    $TMSCP_STEP1,TMSCPsa(%rCSR)
                    269:        beql    1b
                    270: #ifdef DEBUG
                    271:        movzbl  $'1,r0
                    272:        bsbw    putc
                    273: #endif
                    274: init2: movw    $TMSCP_ERR,TMSCPsa(%rCSR)       # start step 2
                    275: 2:     bitw    $TMSCP_STEP2,TMSCPsa(%rCSR)
                    276:        beql    2b
                    277: #ifdef DEBUG
                    278:        movzbl  $'2,r0
                    279:        bsbw    putc
                    280: #endif
                    281: init3: addl3   $8,%rUBADDR,r0                  # start step 3
                    282:        cvtlw   r0,TMSCPsa(%rCSR)
                    283: 3:     bitw    $TMSCP_STEP3,TMSCPsa(%rCSR)
                    284:        beql    3b
                    285: #ifdef DEBUG
                    286:        movzbl  $'3,r0
                    287:        bsbw    putc
                    288: #endif
                    289: init4: addl3   $8,%rUBADDR,r0                  # start step 4
                    290:        ashl    $-16,r0,r0
                    291:        cvtlw   r0,TMSCPsa(%rCSR)
                    292: 4:     bitw    $TMSCP_STEP4,TMSCPsa(%rCSR)
                    293:        beql    4b
                    294: #ifdef DEBUG
                    295:        movzbl  $'4,r0
                    296:        bsbw    putc
                    297: #endif
                    298: setchar:
                    299:        movw    $TMSCP_GO,TMSCPsa(%rCSR)
                    300:        moval   140(%rUBADDR),tmscpca+cmddsc(fp)
                    301:        moval   tmscpca+cmddsc(fp),dscptr(%rCMD)
                    302:        movb    $1,vcid(%rCMD)
                    303:        moval   20(%rUBADDR),tmscpca+rspdsc(fp)
                    304:        moval   tmscpca+rspdsc(fp),dscptr(%rRSP)
                    305:        clrw    cntflgs(%rCMD)
                    306: 
                    307:        movb    $M_OP_STCON,op(%rCMD)
                    308:        clrw    modifier(%rCMD)
                    309:        clrl    buffer(%rCMD)
                    310:        clrl    bytecnt(%rCMD)
                    311:        bsbw    tmscpcmd
                    312: #ifdef DEBUG
                    313:        movzbl  $'S,r0
                    314:        bsbw    putc
                    315: #endif
                    316:        rsb
                    317: 
                    318: tmscpcmd:
                    319:        movw    $116,msglen(%rCMD)              # 116 -- size of an mscp packet
                    320:        bisl2   $TMSCP_OWN,tmscpca+cmddsc(fp)
                    321:        movw    $116,msglen(%rRSP)
                    322:        bisl2   $TMSCP_OWN,tmscpca+rspdsc(fp)
                    323:        movw    TMSCPip(%rCSR),r0               # start polling
                    324: wait:  cvtwl   TMSCPsa(%rCSR),r0
                    325:        bitl    $TMSCP_ERR,r0
                    326:        beql    1f
                    327:        movw    modifier(%rRSP),r1      # so we can read status easily
                    328:        halt                            # some error or other
                    329: 1:     tstl    tmscpca+4(fp)
                    330:        beql    2f
                    331:        clrw    tmscpca+4(fp)
                    332: 2:     bitl    $TMSCP_OWN,tmscpca+rspdsc(fp)
                    333:        bneq    wait
                    334: 
                    335:        # cmd done
                    336: 
                    337:        clrw    tmscpca+rspint(fp)
                    338:        extzv   $0,$5,status(%rRSP),r0
                    339:        tstl    r0
                    340:        beql    ok                      # no errors
                    341:        cmpl    $M_ST_TAPEM, r0
                    342:        beql    ok                      # not an error, just a tape mark
                    343:        halt                            # some unknown error
                    344: ok:    rsb
                    345: 
                    346: rew:   movb    $M_OP_REPOS,op(%rCMD)
                    347:        movw    $M_MD_REWND|M_MD_IMMED,modifier(%rCMD)
                    348:        clrl    buffer(%rCMD)
                    349:        clrl    bytecnt(%rCMD)
                    350:        bsbw    tmscpcmd
                    351: #ifdef DEBUG
                    352:        movzbl  $'r,r0                  # to indicate r)ewind
                    353:        bsbw    putc
                    354: #endif
                    355:        movl    $-1,mtapa(fp)           # no blocks read yet
                    356:        rsb
                    357: 
                    358: onlin: movb    $M_OP_ONLIN,op(%rCMD)
                    359:        clrw    modifier(%rCMD)
                    360:        clrl    buffer(%rCMD)
                    361:        clrl    bytecnt(%rCMD)
                    362:        bsbw    tmscpcmd
                    363: #ifdef DEBUG
                    364:        movzbl  $'O,r0                  # to indicate O)nline
                    365:        bsbw    putc
                    366: #endif
                    367:        rsb
                    368: 
                    369:        # Read the tp directory. Number of blocks to read is in tapa(fp),
                    370:        # and will be read into memory starting at location 0.
                    371: readdir:bsbw   rew                     # beginning of tape
                    372:        addl3   $2,$NUMDIR,tapa(fp)     # blocks to read (skip this 1k program)
                    373:        clrl    r3                      # using mem starting at 0 as free space
                    374:        bsbw    rrec; bsbw rrec         # read and discard first two blocks --
                    375:                                        # those are this program
                    376:        bsbw    rrec                    # read and discard first tp block
                    377:        clrl    r3                      # reset starting place
                    378:        incw    dirread(fp)             # show that directory is incore
                    379: 1:     bsbw    rrec
                    380:        cmpl    mtapa(fp),tapa(fp)      # done yet?
                    381:        blss    1b
                    382:        rsb
                    383: 
                    384:        # read 1 block from mag tape into page indicated by r3, which will
                    385:        # automatically be incremented here. mtapa is also advanced.
                    386: 
                    387: rrec:  bisl3   $MRV,r3,4(%rMAPREGS)    # using map register #1
                    388:        movl    $BLKSIZ,bytecnt(%rCMD)  # how much to read
                    389:        ashl    $9,$1,buffer(%rCMD)     # indicating mr #1. We just happen to
                    390:                                        # be on a page boundary, so filling in
                    391:                                        # the low 9 bits is not necessary.
                    392:        movb    $M_OP_READ,op(%rCMD)
                    393:        clrw    modifier(%rCMD)
                    394:        bsbw    tmscpcmd
                    395: #ifdef DEBUG
                    396:        movzbl  $'R,r0                  # to indicate R)ead a record
                    397:        bsbw    putc
                    398: #endif
                    399:        incl    mtapa(fp)
                    400:        incl    r3
                    401:        rsb
                    402: end:

unix.superglobalmegacorp.com

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