1: /* 2: * Primary tape boot program to load and execute secondary boot. 3: * 4: * 1995/05/31 - unit number changed to be in bits 3-5 of 'bootdev' 5: * 6: * This is a universal tape boot which can handle HT, TM, TS and TMSCP 7: * tapes. This boot is FULL. Some of the more extended error 8: * checking had to be left out to get all the drivers to fit. 9: * 10: * Two copies of the primary boot are stored in the first and second records 11: * of the first tape file (some boot proms execute the second one when 12: * booting a tape). The secondary boot is also stored in the first tape 13: * file, starting at record #3. 14: * 15: * Also note that the struct exec header must be removed from this bootstrap. 16: * This needs to be done so taking the address of the tape read and rewind 17: * functions will work. 18: * 19: * Due to size constraints and the rather destructive way in which 20: * all the registers are used, this boot does not support the 21: * "jsr pc,0; br restart" convention. 22: */ 23: NEWLOC = [48.*1024.] / we relocate ourselves to this address 24: OURSIZE = 512. / assume we are up to this size 25: 26: HT_MAJOR = 0 / major device number from bdevsw[] 27: TM_MAJOR = 1 28: TS_MAJOR = 2 29: TMS_MAJOR = 12. 30: 31: a_text = 02 / a_text (struct exec) field offset 32: a_data = 04 / a_data (struct exec) field offset 33: 34: csr = r5 / saved csr of boot device 35: tread = r4 / pointer at tread routine 36: blkcnt = r3 / number of blocks to read 37: memaddr = r2 / memory location to read into 38: / r1 & r0 are junk registers 39: 40: .. = NEWLOC / so absolute address work ... 41: start: 42: nop / DEC boot block standard 43: br 1f / " " " " 44: 1: 45: mov $NEWLOC,sp / give ourselves a stack to work with 46: clr r4 47: mov sp,r5 48: mov $OURSIZE\/2,r3 / primary boot size in words 49: 2: 50: clr OURSIZE(r5) / clear work area (major & TS/MSCP area) 51: mov (r4)+,(r5)+ / move primary boot to just above 52: sob r3,2b / the stack 53: jmp *$3f / bypass the relocation code 54: 3: 55: mov r0,unit / save unit number 56: mov r1,csr / save the csr 57: cmp r1,$172440 / HT is always at this address 58: beq common / r3 is table index 59: inc r3 / index for TMSCP 60: cmp r1,$172522 / is this a TS? 61: blo common / no - br, likely TMSCP 62: cmp r1,$172522+[7*4] / is CSR in the TS range? 63: bhi common / no, is a TMSCP - br 64: inc r3 / adjust index to TS 65: mov (r1),r4 / save contents of csr in case of a TM 66: clr (r1) / poke the controller 67: / clr r2 / now we delay 68: /1: 69: / sob r2,1b / time for TS to run diagnostics 70: 2: 71: tstb (r1) / is controller ready? 72: bpl 2b / no - br 73: bit $2000,(r1) / TS "address required" bit 74: bne common / if a TS - br 75: mov r4,(r1) / is a TM, restore unit/density select 76: inc r3 / make TM index 77: common: 78: movb table1(r3),major+1 / save major device number to high byte 79: asl r3 / make a word index 80: mov table2(r3),tread / fetch read routine address 81: jsr pc,*table3(r3) / call rewind routine (must preserve r4) 82: readit: 83: clr memaddr / load starting at 0 84: jsr pc,*tread / skip the two copies of this 85: jsr pc,*tread / program on the tape 86: clr memaddr / reset memory address 87: jsr pc,*tread / read first block of boot 88: 89: mov *$a_text,blkcnt / compute remaining amount to read: 90: add *$a_data,blkcnt / (a_text + a_data 91: add $15.,blkcnt / + sizeof(struct exec) + 511 92: ash $-9.,blkcnt / - 512) [already read one block] 93: bic $177600,blkcnt / / 512 [[unsigned]] 94: beq done / already done if == 0 [not likely] 95: 2: 96: jsr pc,*tread 97: sob blkcnt,2b 98: done: 99: 1: / down by sizeof(struct exec) 100: mov 20(blkcnt),(blkcnt)+ / r3 cleared by loop above 101: cmp blkcnt,sp 102: blo 1b 103: mov csr,r1 / put things where 'boot' 104: mov unit,r3 / expects them 105: ash $3,r3 / unit # in bits 3-5 106: bis major,r3 / the major device to high byte 107: clr pc / go to location 0 ... no return 108: 109: /* 110: * HT tape driver 111: */ 112: htcs1 = 0 / offset from base csr 113: htwc = 2 114: htba = 4 115: htfc = 6 116: htcs2 = 10 117: htds = 12 118: hter = 14 119: httc = 32 120: 121: RESET = 040 122: READ = 071 123: REW = 07 124: 125: hrrec: 126: mov memaddr,htba(csr) 127: mov $-256.,htwc(csr) 128: mov $READ,(csr) / htcs1 129: htcmd: 130: tstb (csr) / controller ready? 131: bpl htcmd 132: tst htds(csr) / drive ready? 133: bpl htcmd 134: tstb htcs2+1(csr) / any controller errors? 135: bne ctlerr 136: bit $!1000,hter(csr) / any drive errors except HTER_FCE? 137: beq bumpaddr / no, go bump address 138: ctlerr: 139: halt 140: 141: /* 142: * Rewind tape. This routine is only done once and must preceed any reads. 143: */ 144: htrew: 145: tstb (csr) / controller ready? 146: bpl htrew / no - go try again 147: mov htcs2(csr),r1 / boot unit(formatter) number 148: bic $!7,r1 / only the low bits 149: mov httc(csr),r0 / save format,slave,density 150: bic $!3767,r0 / only the bits we're interested in 151: mov $RESET,htcs2(csr) / reset controller 152: movb r1,htcs2(csr) / reselect boot unit(formatter) 153: mov r0,httc(csr) / reselect density/format/slave(drive) 154: mov $REW,(csr) 155: br htcmd / join common code 156: 157: /* 158: * TM tape driver 159: */ 160: tmer = -2 / offset from base csr 161: tmcs = 0 162: tmbc = 2 163: tmba = 4 164: tmdb = 6 165: tmrd = 10 166: tmmr = 12 167: 168: tmrrec: 169: mov $-512.,tmbc(csr) / bytecount 170: mov memaddr,tmba(csr) / bus address 171: mov $3,r1 / 'read' 172: tmcmd: 173: mov (csr),r0 174: bic $!63400,r0 / save the density and unit 175: bis r1,r0 / merge in the function code 176: mov r0,(csr) / tmcs - give command 177: /1: 178: / bit $100,tmer(csr) / unit still selected? (TMER_SELR) 179: / beq ctlerr / nope, go halt 180: / bit $1,tmer(csr) / unit ready? (TMER_TUR) 181: / beq 1b / no, keep waiting 182: tmtscom: 183: bit $100200,(csr) / error or ready? 184: beq tmtscom / neither, keep looking 185: bmi ctlerr / error - go halt 186: 187: bumpaddr: 188: add $512.,memaddr 189: rts pc 190: 191: /* 192: * Rewind tape. 193: * Side effects: 194: * just what the first line says ... 195: */ 196: tmrew: 197: mov $17,r1 / 'rewind' 198: br tmcmd / join common code 199: 200: /* 201: * TS tape driver 202: */ 203: tsdb = -2 / offset from ROM supplied address 204: tssr = 0 205: 206: TSCHAR = 140004 207: TSREW = 102010 208: TSREAD = 100001 209: 210: tsrrec: 211: mov $tsdbuf+6,r0 212: mov $512.,(r0) 213: clr -(r0) 214: mov memaddr,-(r0) 215: mov $TSREAD,-(r0) 216: mov r0,tsdb(csr) 217: br tmtscom 218: 219: /* 220: * Rewind and initialize tape - only done once. 221: * Side effects: 222: * just what the first line says ... 223: */ 224: tsrew: 225: mov $tsdbuf,tsdb(csr) 226: br tmtscom / go join common code 227: 228: .if [.-start]&2 229: .blkb 2 / tsdbuf must be on a mod 4 boundary 230: .endif 231: tsdbuf: 232: TSCHAR / command 233: tsdbuf+10 / buffer address (lo) 234: 0 / buffer address (hi - always 0) 235: 10 / length of command buffer 236: 237: / from here on is used only at initialization/rewind time. The Set 238: / Charactistics command only looks at the word following the buffer length, 239: / part of the TMSCP code is used as the remainder of the characteristics packet. 240: 241: tsdbuf+10 / buffer address (lo) 242: 0 / buffer address (hi - always 0) 243: 16 / minimum length packet 244: 0 / characteristics to set (lo byte) 245: 246: /* 247: * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. 248: * All Rights Reserved. 249: * Reference "/usr/src/COPYRIGHT" for applicable restrictions. 250: * 251: * ULTRIX-11 Block Zero Bootstrap for TMSCP Magtape 252: * 253: * SCCSID: @(#)tkboot.s 3.0 4/21/86 254: * 255: * Chung_wu Lee 2/8/85 256: * 257: * sms 4/27/91 - merged into universal tape boot 258: * sms 4/12/91 - saved some more space. the major device number and unit 259: * number are now passed to the secondary boot along with the csr of 260: * the booting controller. 261: * 262: * Steven M. Schultz (sms@wlv.imsd.contel.com) Aug 20 1990. Port to 2.11BSD 263: */ 264: 265: s1 = 4000 266: go = 1 267: 268: / TK initialization (and rewind) - only done once 269: tkrew: 270: clr (csr)+ / start tk init sequence 271: / move pointer to tksa register 272: mov $s1,r0 / set tk state test bit to step 1 273: mov $cmdtbl,r1 / address of init seq table 274: 2: 275: tst (csr) / error ? 276: bmi . / yes, hang - can't restart !!! 277: bit r0,(csr) / current step done ? 278: beq 2b / no 279: mov (r1)+,(csr) / yes, load next step info from table 280: asl r0 / change state test bit to next step 281: bpl 2b / if all steps not done, go back 282: / r0 now = 100000, TK_OWN bit 283: mov $400,cmdhdr+2 / tape VCID = 1 284: mov $36.,cmdhdr / command packet length 285: / don't set response packet length, 286: / little shakey but it works. 287: / unit is already loaded at tkcmd+4 288: mov $11,tkcmd+8. / on-line command opcode 289: mov $20000,tkcmd+10. / set clear serious exception 290: mov $ring,r2 / initialize cmd/rsp ring 291: mov $tkrsp,(r2)+ / address of response packet 292: mov r0,(r2)+ / set TK owner 293: mov $tkcmd,(r2)+ / address of command packet 294: mov r0,(r2)+ / set TK owner 295: mov -(csr),r0 / start TK polling 296: 3: 297: jsr pc,tkready 298: mov $tkcmd+8.,r0 299: mov $45,(r0)+ / reposition opcode 300: mov $20002,(r0)+ / set rewind & clear serious exception 301: clr (r0)+ / clear record/object count 302: clr (r0)+ / zzz2 303: clr (r0)+ / clear tape mark count 304: tkpoll: 305: mov $100000,ring+2 / set TK owner of response 306: mov $100000,ring+6 / set TK owner of command 307: mov (csr),r0 / start TK polling 308: tkready: 309: tst ring+2 / wait for response 310: bmi tkready 311: tstb tkrsp+10. / does returned status = SUCCESS ? 312: bne . / no, hang 313: rts pc 314: tkread: 315: mov $tkcmd+8.,r0 316: mov $41,(r0)+ / read opcode 317: mov $20000,(r0)+ / set clear serious exception 318: mov $512.,(r0)+ / byte count 319: clr (r0)+ / zzz2 320: mov memaddr,(r0)+ / buffer address 321: jsr pc,bumpaddr / bump address 322: br tkpoll / wait for response 323: 324: cmdtbl: 325: 100000 / TK_ERR, init step 1 326: ring / address of ringbase 327: 0 / hi ringbase address 328: go / TK go bit 329: 330: table1: 331: .byte HT_MAJOR 332: .byte TMS_MAJOR 333: .byte TS_MAJOR 334: .byte TM_MAJOR 335: table2: 336: hrrec 337: tkread 338: tsrrec 339: tmrrec 340: table3: 341: htrew 342: tkrew 343: tsrew 344: tmrew 345: end: 346: 347: major = NEWLOC+OURSIZE 348: cmdint = major+2 / TMSCP stuff 349: rspint = cmdint+2. 350: ring = rspint+2. 351: rsphdr = ring+8. 352: tkrsp = rsphdr+4. 353: cmdhdr = tkrsp+48. 354: tkcmd = cmdhdr+4. 355: unit = tkcmd+4