1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1984 *
  6 " *                                                         *
  7 " * Copyright (c) 1972 by Massachusetts Institute of        *
  8 " * Technology and Honeywell Information Systems, Inc.      *
  9 " *                                                         *
 10 " ***********************************************************
 11 
 12 " HISTORY COMMENTS:
 13 "  1) change(1985-09-09,Farley), approve(1985-09-09,MCR6979),
 14 "     audit(1986-01-31,GDixon), install(1986-03-21,MR12.0-1033):
 15 "     select the proper bootload tape device, when the info in the IDCW &
 16 "     status word may be different.
 17 "  2) change(1987-04-02,Farley), approve(1987-07-06,MCR7717),
 18 "     audit(1987-07-15,Fawcett), install(1987-07-17,MR12.1-1043):
 19 "     Added chk_mpc_state routine to test the tape controller's intelligence
 20 "     level, which will allow proper setting of the "cold mpc flag".
 21 "  3) change(1987-07-23,Farley), approve(1987-07-23,PBF7717),
 22 "     audit(1987-07-24,Fawcett), install(1987-07-28,MR12.1-1047):
 23 "     Added POF retry to rd_tape routine, because unwedging of the tape
 24 "     controller on an IMU takes a long time (> 4sec) to complete (sigh!).
 25 "  4) change(1987-10-02,Farley), approve(1988-02-26,MCR7794),
 26 "     audit(1988-03-04,Fawcett), install(1988-03-15,MR12.2-1035):
 27 "     Added code to copy the IMU bit from the system_fault_vector into the
 28 "     bootload info area.  It will later be copied into
 29 "     bootload_info$imu_type_iom.
 30 "  5) change(2021-11-06,Swenson), approve(2021-11-06,MCR10100),
 31 "     audit(2021-11-07,GDixon), install(2021-11-07,MR12.8-1007):
 32 "     Fix values in comments about IOM mailbox.
 33 "                                                      END HISTORY COMMENTS
 34 
 35 
 36           name      bootload_tape_label
 37 
 38 " Written by J. A. Bush 12/80
 39 " Modified for bootload Multics and macros BIM 2/82
 40 " Modified to read in whole first segment by C. Hornig, October 1982.
 41 " Modified for DPS88 support by K. Loepere, September 1983.
 42 " Modified to run on any IOM by Keith Loepere, March 1984.
 43 " Modified 1095-05-16, BIM: don't bomb on padded records.
 44 " Modified to run on IMU by Paul Farley, June 1984.
 45 " Modified 08/31/84 by Paul Farley to select the proper bootload tape
 46 "  device, when the info in the IDCW & status word may be different.
 47 " ^L
 48 " This program is copied by the tape_mult_ "boot_program" control order and
 49 " written onto a bootable MST when tape_mult_ is subsequently opened for
 50 " writing.  This program is put into execution by a bootload sequence as
 51 " follows: The system operator depresses initialize and bootload (or
 52 " equivalent) on the system console.  Assuming an MST with this program written
 53 " on its label is mounted and ready on the selected tape drive, the IOM (or
 54 " equivalant) hardwired bootload program will read in the first record on the
 55 " tape (the label record), starting at location 30 (8) absolute.  When the
 56 " record has been completely read in, a terminate interrupt is executed.  The
 57 " interrupt cell used for a terminate interrupt is a function of the IOM
 58 " number.  For IOM #0, interrupt cell 12 is used, for IOM #1, 2, and 3,
 59 " interrupt cells 13, 14, and 15 respectively are used.  The interrupt cell is
 60 " used to form the interrupt vector address.  Since interrupt vectors are two
 61 " locations long, the interrupt cell is multiplied by 2.  Therefore for IOM #0,
 62 " the interrupt vector address would be 24 (10) or 30 (8).  IOM #s 1, 2, and 3
 63 " interrupt vector addresses would be 32, 34, and 36 (8) respectively.  For the
 64 " IOX, only vector address 30 is used.  When the processor senses the
 65 " terminate interrupt (via an execute interrupt present (xip) signal), a
 66 " hardware XED instruction is forced to be executed to the interrupt vector
 67 " address formed in the SCU.  Since this program is read in so that location 0
 68 " is overlayed at location 30 (8) absolute, by the IOM bootload program, the
 69 " XED is forced to execute the transfer vector instructions (2) at the
 70 " beginning of the record supplied by tape_mult_ for the appropriate IOM #
 71 " and control is transferred to the label "my_zero" from the transfer vector.
 72 "
 73 " The function of this program is to read the next segment off the boot tape
 74 " and to transfer control to it.
 75 "
 76 " The fault vectors (locations 100 to 177 (8)) are overlayed by an SCU 200/DIS
 77 " pair.  Therefore if this program dies in a DIS instruction, one can look at
 78 " absolute location 200 - 207 for the SCU data stored as the result of the
 79 " fault.
 80 " ^L
 81 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 82 "
 83 " The IOM Bootload Program:
 84 "
 85 " The IOM Bootload program looks like this (locations are absolute memory):
 86 "
 87 " Location     Contents                           Purpose
 88 "
 89 "   000000     18/0, 18/720201                    Bootload channel PCW, word 1
 90 "   000001     3/0, 12/Chan#, 24/0, 3/Port#       Bootload channel PCW, word 2
 91 "
 92 "   000002     12/Base, 6/0, 15/PIbase, 3/IOM#    Info used by bootloaded pgm
 93 "   000003     6/Command, 6/Device#, 6/0, 18/700000
 94 "                                                 Bootload IDCW - Command is 05
 95 "                                                 for tape, 01 for cards.
 96 "   000004     18/000030, 18/0                    Second IDCW: IOTD to loc 30
 97 "
 98 " System fault vector, at 000010 + 2*IOM#
 99 "              1/0, 1/IMU, 16/0, 18/616200        DIS 0 instruction
100 "
101 " Terminate interrupt vector, at 000030 + 2*IOM#  Overwritten by bootloaded
102 "              18/0, 18/616200                    program: a DIS 0 instruction
103 "
104 " IOM Mailbox, at Base*64
105 "   mbx + 07   12/Base, 6/02, 18/000002           Fault channel DCW
106 "   mbx + 10   18/0, 18/040000                    Connect channel LPW -> PCW
107 "                                                 at 000000
108 "
109 " Channel mailbox, at Base*64 + 4*Chan#
110 "   mbx + 0    18/000003, 6/02, 12/0003           Boot dev LPW -> IDCW @ 000003
111 "   mbx + 2    12/Base, 6/0, 18/0                 Boot dev SCW -> IOM mailbox
112 "
113 "
114 " For Multics, the IOM Base ("Base") must be 0012, locating the IOM mailbox at
115 " location 001200.
116 "
117 " Multics can only be booted from tape -- booting from cards is not very
118 " useful, since the card reader firmware must be loaded in order to do so.
119 " Unfortunately, we have no genuine boot-from-disk mechanism available to us,
120 " because there is nothing to support the bootload connect in a cold disk MPC.
121 "
122 " The channel number ("Chan#") is set by the switches on the IOM to be the
123 " channel for the tape subsystem holding the bootload tape. The drive number
124 " for the bootload tape is set by switches on the tape MPC itself.
125 "
126 " The IOM number (IOM#) is set by IOM switches.
127 "^L
128 " The IOX Bootload Program:
129 "
130 " The IOX Bootload program looks like this (locations are absolute memory):
131 "
132 " Location     Contents                           Purpose
133 "
134 "   000000     6/Command, 6/Device#, 6/0, 18/700000
135 "                                                 Bootload IDCW - Command is 05
136 "                                                 for tape
137 "   000001     18/000030, 18/0                    Second IDCW: IOTD to loc 30
138 "
139 "   000004     24/7000000,12/IOXoffset            A register value for connect
140 "
141 " System fault vector, at 000010
142 "              18/1, 18/612000                    HALT instruction
143 "
144 " Terminate interrupt vector, at 000030           Overwritten by bootloaded
145 "              18/10, 18/612000                   program: a HALT instruction
146 "
147 " IOX mailbox
148 "
149 "   001400     36/0                               base addr 0
150 "   001401     36/0                               base addr 1
151 "   001402     36/0                               base addr 2
152 "   001403     36/0                               base addr 3
153 "   001404     18/777777,18/0                     bound 0, bound 1
154 "   001405     18/0,18/0                          bound 2, bound 3
155 "   001406     24/0,12/3034                       channel link word
156 "   001407     18/0,9/400,9/400                   lpw
157 "
158 " We compromise between the IOM and IOX version of memory from 1400 onward
159 " with the IOX values except for the lpw which was fetched before the tape
160 " overwrote it.  The code will fix it up.  The presence of a 0 in the top six
161 " bits of word 0 denote an IOM boot from an IOX boot.
162 "
163 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
164 " ^L
165           include             bootload_equs
166           include_nolist      make_data_macros
167           include_nolist      iom_word_macros
168           include             mstr
169           include_nolist      tape_io_commands
170           include             toe_hold
171 "^L
172           equ       bootload_info,0     " address of IOM bootload program
173           equ_o     load_offset,30      " offset of IOM load
174           equ       my_offset,load_offset+mst_label.boot_pgm
175 
176           bool      cold_tape_mpc,400000 " DU
177           bool      imu,200000          " DU
178           equ       imu_bit_shift,1
179           equ_o     iom_fault_vector,10
180           bool      iom_num_mask,000007 " DL
181 
182 " Layout of the physical_record_buffer
183 " The first part is common to all phases of the loader.
184 
185           equ       prb.prb_it,prb_absloc
186           equ       prb.mstrh,prb.prb_it+1
187           equ       prb.data,prb.mstrh+mstr_header_size
188           equ       prb.mstrt,prb.data+1024
189 
190           inhibit   on                  <-><-><-><-><-><-><-><-><-><-><-><->
191 my_zero:
192           lda       bootload_info
193           ana       =o770000,du
194           sta       system_type-*,ic    non-zero for IOX
195 
196           tnz       iox_setup-*,ic
197 
198           decor     dps8                <<<>>>
199 
200           eax1      7*64                set all controller masks
201           fld       0,dl                mask all interrupts
202           sscr      2*8,x1              ..
203           eax1      -64,x1              SSCR will do nothing for unassigned masks
204           tpl       -2,ic               ..
205 
206           ldt       -1,du               Prevent timer runout
207           inhibit   off                 <-><-><-><-><-><-><-><-><-><-><-><->
208 
209           lcpr      mr-my_zero+my_offset,04
210                                         " clear the mode register
211           lcpr      cmr-my_zero+my_offset,02
212                                         " disable the cache
213           camp      2                   " enable and clear the PTWAM
214           cams      6                   " enable and clear the SDWAM
215                                         " clear the cache
216 
217           stz       bootload_info+7     " clear software region
218 
219           ldq       bootload_info+2     Get mailbox and int. base word
220           anq       iom_num_mask,dl     and extract the IOM number
221           qls       1                   iom# * 2
222           lda       iom_fault_vector,ql Get fault vector word
223           als       imu_bit_shift       shift IMU bit to sign position
224           tpl       +3,ic               If not IMU, skip setting of IMU bit
225           ldq       imu,du
226           orsq      bootload_info+7     save IMU flag in software region
227 
228           ldq       bootload_info+1     Last PCW
229           qrl       9-2
230           eax6      0,qu                Tape channel number * 4 in X6.
231           adlx6     bootload_info+2     Add in base of mailbox
232 
233           ldx5      bootload_info+2     Mailbox loc in X5
234           ldaq      0,x5                check status from first read
235           cana      status_mask-*,ic
236           tnz       boot_die-*,ic       bad status
237 
238           ldq       bootload_info+3     " get the IDCW
239           anq       =o007700,du         " device number
240           orsq      data_idcw-*,ic      " save it
241           canq      =o007700,du         " boot from IOM or FIPS device zero?
242           tze       get_device-*,ic     " yes
243 
244           stq       device_hold-*,ic    " save device# from IDCW
245           llr       24+36               " get device# from status word
246           anq       =o007700,du         " only device# please
247           tze       got_device-*,ic     " = 00 in both places...
248           cmpq      device_hold-*,ic    " are the two the same?
249           tze       got_device-*,ic     " yes, everything ok
250           lda       device_mask-*,ic    " no, get ready to zero device field
251           ansa      bootload_info+3     " first the bootload IDCW
252           ansa      data_idcw-*,ic      " then the data IDCW
253           orsq      bootload_info+3     " now put in the right number
254           orsq      data_idcw-*,ic      " ditto the data IDCW
255           tra       got_device-*,ic     " now its ready
256 
257 get_device:
258           llr       24+36               " get it from status word
259           anq       =o007700,du         " device only
260           tze       got_device-*,ic     " already zero, proceed
261           orsq      bootload_info+3     " save in IDCW (for bootload_io)
262           tra       got_device-*,ic
263 
264 iox_setup:
265           decor     adp                 <<<>>>
266 
267           inhibit   on                  <-><-><-><-><-><-><-><-><-><-><-><->
268 
269           lda       =0,dl               Mask interrupts
270           limr
271 
272           ldt       -1,du               Prevent timer runout
273           inhibit   off                 <-><-><-><-><-><-><-><-><-><-><-><->
274 
275           ldo       or-*,ic             " set option register
276 
277           camp2                         " enable and clear the PTWAM
278 
279           stz       bootload_info+7     " clear software region
280 
281           lda       iox_lpw-*,ic
282           sta       iox_mailbox+7
283           eax6      iox_mailbox+7
284 
285           eax5      iox_mailbox+8       " Mailbox loc in X5
286           ldaq      0,x5                " check status from first read
287           cana      status_mask-*,ic
288           tnz       boot_die-*,ic       " bad status
289 
290           ldq       bootload_info       " get the IDCW
291           anq       =o007700,du         " device number
292           orsq      data_idcw-*,ic      " save it
293 
294           decor     dps8                <<<>>> or whatever
295 
296 got_device:
297           tsx2      chk_mpc_state-*,ic  " is tape controller cold or warm?
298           orsq      bootload_info+7     " save cold boot flag in software region
299           tsx2      rd_tape-*,ic        " read eof record, and ignore status
300           nop                           " ignore errors
301 " ^L
302           tsx2      rd_tape-*,ic        read in  first real record
303           tra       boot_die-*,ic       " error
304 
305           lda       prb.data            " less SLTE size
306           ada       1,dl                " and control word
307           als       18
308           asa       prb.prb_it          " adjust address
309           arl       12
310           neg       0
311           asa       prb.prb_it          " and tally
312 
313           lxl4      prb.prb_it,id       " bound_bootload_0 control word
314 
315 next_record:
316           lda       prb.prb_it,id       " get the next data word
317           ttn       read_more_data-*,ic
318           sta       data_it-my_zero+my_offset,id  " store it
319           eax4      -1,x4               " tally it off
320           tpnz      next_record-*,ic
321 
322 " we are done reading in bound_bootload_0
323 
324           tra       bbl0_absloc+2*TOE_HOLD_BOOT_ENTRY       " tra through
325                                         " toehold to bootload_abs_mode
326 
327 read_more_data:
328           tsx2      rd_tape-*,ic        " read another record
329           tra       boot_die-*,ic
330           tra       next_record-*,ic    " keep copying
331 " ^L
332 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
333 "         chk_mpc_state - subroutine to issue special connect to
334 "         tape channel to determine if intelligence is present.
335 
336 chk_mpc_state:
337           szn       system_type-*,ic
338           tze       3,ic
339 
340           decor     adp                 <<<>>>
341           ldq       0,dl                " indicate intelligence
342           tra       0,x2
343 
344           decor     dps8                <<<>>>
345           rscr      32
346           staq      chk_io_time-*,ic    " save start time
347           eaa       chk_idcw-*,ic       " absolute address of DCW list.
348           sta       0,x6                " set tape LPW.
349           stz       0,x5                " clear status word.
350 
351           cioc      bootload_info+1     " port # stuck in PCW
352 
353           lda       0,x5                " check for status
354           tmi       got_status-*,ic     " status has arrived
355           rscr      32                  " nop, need to wait
356           sbaq      chk_io_time-*,ic
357           cmpaq     pause_time-*,ic
358           tmi       -5,ic               " continue waiting
359 
360 " Timeout, tape controller must be wedged..
361 
362 unwedge:
363           lda       =o070000,dl         " reset and mask PCW bits
364           orsa      bootload_info       " set bits in PCW
365           eaa       ignore_idcw-*,ic    " absolute address of DCW list.
366           sta       0,x6                " set tape LPW.
367           stz       0,x5                " clear status word.
368 
369           cioc      bootload_info+1     " port # stuck in PCW
370 
371           rscr      32                  " small pause for reset/mask
372           staq      chk_io_time-*,ic
373           rscr      32
374           sbaq      chk_io_time-*,ic
375           cmpaq     pause_time-*,ic
376           tmi       -3,ic
377           lda       =o050000,dl         " get mask and marker PCW bits
378           ersa      bootload_info       " turn them off in the PCW
379           ldq       cold_tape_mpc,du    " indicate no intelligence
380           tra       0,x2
381 
382 got_status:
383           rscr      32                  " small pause for IO interrupt cycle
384           staq      chk_io_time-*,ic
385           rscr      32
386           sbaq      chk_io_time-*,ic
387           cmpaq     pause_time-*,ic
388           tmi       -3,ic
389           lda       0,x5                " get status word
390           cana      pof_mask-*,ic       " check for power-off
391           tnz       unwedge-*,ic        " yes, will need to unwedge
392           ldq       0,dl                " indicate intelligence
393           tra       0,x2
394 
395           make_idcw chk_idcw,TAPE.reset_device_status,0,nondata,terminate
396 
397           make_idcw ignore_idcw,TAPE.request_status,0,nondata,terminate
398 
399 pof_mask: oct       200000000000
400           even
401 chk_io_time:
402           bss       ,2
403 pause_time:
404           dec       0,1000000           " one second
405 " ^L
406 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
407 "         rd_tape - subroutine to issue connect to tape channel
408 "         and wait for status word to be stored
409 
410 rd_tape:  rscr      32                  " get the time
411           staq      io_start_time-*,ic  " and save it
412 try_rd_again:
413           eaa       data_idcw-*,ic      Absolute address of DCW list.
414           sta       0,x6                Set tape LPW.
415           stz       0,x5                Clear status word.
416 
417           lda       bootload_info+4     iox a data
418 
419           szn       system_type-*,ic
420           tnz       3,ic
421 
422           decor     dps8                <<<>>>
423           cioc      bootload_info+1     read next record (port # stuck in pcw)
424           tra       2,ic
425 
426           decor     adp                 <<<>>>
427           cioc      iox_mailbox
428 
429           decor     dps8                <<<>>>
430           odd
431 
432           lda       0,x5
433           tpl       -1,ic               Wait for it to happen.
434 
435 " IMU only does single presision stores, so after status word
436 " arrives we need to wait for the second word to be stored...
437 
438           ldq       =o1000,dl
439           sblq      1,dl
440           tnz       -1,ic
441           ldaq      0,x5                " should be there now!!
442 
443           cana      status_mask-*,ic    " error?
444           tnz       tape_error-*,ic     " yes
445           canq      =o7777,dl           " tally residue?
446           tnz       0,x2                " yes, noise on the tape
447 
448 " check for valid record
449 
450           lda       prb.mstrh+mstr_header.flags_word
451           cana      mstr_header.repeat,du   " the only fatal flag.
452           tnz       boot_die-*,ic       " yes
453 
454 " compute prb pointer
455 
456           ldq       prb.mstrh+mstr_header.data_bits_used
457           div       36,du               " number of words in QL
458           adq       1,dl                " plus one
459           qls       18-12               " in Q(18:29)
460           adq       prb.data,du         " whole pointer
461           stq       prb.prb_it
462 
463           tra       1,x2                return to caller
464 
465 tape_error:
466           ana       =o770000,du         " get just major/minor status
467           cmpa      =o600000,du         " POF?
468           tze       retry_pof-*,ic      " yes, try again
469           tra       0,x2                " no, give up
470 
471 retry_pof:
472           rscr      32                  " get the time
473           sbaq      io_start_time-*,ic  " rel-a-tize
474           cmpaq     ten_sec_limit-*,ic  " is ten seconds up?
475           tmi       try_rd_again-*,ic   " no, try one mo time
476           tra       0,x2                " yes, give up
477 "^L
478           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
479 boot_die: dis       0                   stop the machine
480           tra       -1,ic               I said stop!
481 
482           inhibit   off       <-><-><-><-><-><-><-><-><-><-><-><->
483 
484           make_idcw data_idcw,TAPE.read_binary_record,0,record,terminate
485 
486           make_ddcw data_dcw,prb.mstrh,mstr_header_size+1024+mstr_trailer_size,
487                               iotd
488 
489 data_it:  vfd       18/bbl0_absloc,12/0,6/0 " indirect word for storing code
490 
491 mr:       oct       000000000061        " enable history registers
492 cmr:      oct       000000000003        " disable cache, LUF in 16 ms.
493 or:       oct       300000000000        " LUF in 16 ms.
494 
495 status_mask:
496           oct       370000770000
497 
498 device_mask:
499           oct       770077777777
500 
501 iox_lpw:  vfd       24/0,12o/3034
502 
503 system_type:
504           oct       0                   " non zero is DPS88 (IOX)
505 device_hold:
506           oct       0                   " temp holding area for # from IDCW
507           even
508 io_start_time:
509           bss       ,2
510 ten_sec_limit:
511           dec       0,10000000          " ten seconds (in micros)
512 "^L
513 " If this program is bootloaded from tape by the IOM/IOX bootload program,
514 " the IOM/IOX mailbox will get overwritten with the contents of this
515 " tape record.  It is imperative that the previous contents be restored.
516 " It is the purpose of the following code to perform this restoration.
517 
518           equ_o     iom_mbx_absloc,1200
519           equ_o     iox_mailbox,1400
520 
521 " IMW area
522 
523           org       iom_mbx_absloc-my_offset
524           bss       ,128
525 
526           macro     status_mailboxes
527           oct       0,0                 for status storage or base addr 0, 1
528           oct       0,0                 for system fault storage or base addr 2, 3
529 
530           vfd       18o/777777,18/0     bound 0, 1
531           vfd       18/0,18/0           bound 2, 3
532           vfd       24/0,12o/3034       channel link word
533           vfd       18o/&1+2,6/0,12/2   system fault DCW or iox lpw
534 
535           vfd       18/0,6o/04,12/0     connect LPW or iox status
536           bss       ,3
537 
538           bss       ,20
539           &end
540 
541 " status mbx's for IOM 0
542 
543           status_mailboxes    1400
544 
545 " channel mbx's for IOM 0
546 
547           maclist   off,save
548           dup       56                  payload channel mailboxes
549           vfd       18/3,o6/02,12/3     LPW
550           bss       ,1                  LPWX
551           vfd       18o/1400,6/,12/0    SCW
552           bss       ,1                  DCW
553           dupend
554           maclist   restore
555 
556 " status mbx's for IOM 1
557 
558           status_mailboxes    2000
559 
560 " the channel mbx's for channels 8 and 9 get overwritten by the tape trailer
561 "^L
562 "
563 " BEGIN MESSAGE DOCUMENTATION
564 "
565 " Message:
566 " HALT with only the first MST tape record read.
567 "
568 " S: $crash
569 "
570 " T: $init
571 "
572 " M: If the high-order bit of the AQ register is on, the pattern in the AQ
573 "    register is the (bad) status returned by the IOM while reading a tape
574 "    record.  If the high order bit is not on, the A register contains the
575 "    flags word from a MST header record indicating that this record is bad.
576 "
577 " A: Try booting on a different drive or with a different tape.
578 "
579 " END MESSAGE DOCUMENTATION
580 
581           end