Annotation of 43BSDReno/sys/mdec/tmscpboot.c, revision 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.