1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 /* format: style2 */
 13 segment_loader:
 14      proc;
 15 
 16 /* format: off */
 17 
 18 /* SEGMENT_LOADER - Loader for Multics Initialization.
 19 
 20    The segment loader will be called to load a collection from
 21    the Multics System Tape (MST).
 22    All segments contained in the MST collection
 23    will be loaded. When a collection mark is found on MST,
 24    the segment loader will return to its caller.
 25 
 26    Written 06/05/67, Noel I. Morris
 27    Modified 03/29/76, Noel I. Morris for loading separate defs.
 28    Modified 08/02/77, Bernard S. Greenberg for aste.gtpd and flush.
 29    Modified 04/06/81, W. Olin Sibert, to update for ADP SDWs and sdw_util_
 30    Modified 6/82 BIM boot_tape_io, hc_linkage_seg, hc_definitions_seg.
 31    Modified '82 CAH to have pre linking done externally, also slt_manager change.
 32    Modified 10/83 by Keith Loepere for warm boot from disk.
 33    */
 34 
 35 /* format: on */
 36           dcl     header_area            (1000) fixed bin (35);
 37                                                             /* area into which segment header is read */
 38           dcl     header_ptr             ptr;               /* pointer to header area */
 39           dcl     type                   fixed bin (17);    /* type of record on MST */
 40           dcl     count                  fixed bin (17);    /* length of record on MST */
 41           dcl     seg_ptr                ptr;               /* pointer to segment being loaded */
 42           dcl     text_ptr               ptr;               /* pointer to text segment */
 43           dcl     text_no                fixed bin (18);    /* text segment number */
 44           dcl     link_ptr               ptr;               /* pointer to linkage section */
 45           dcl     seg_number             fixed bin (18);    /* segment number of segment being loaded */
 46           dcl     expect_link            bit (1) aligned;   /* linkage section expected switch */
 47           dcl     expect_defs            bit (1) aligned;   /* definitions expected switch */
 48           dcl     control_ptr            ptr;               /* pointer to control word */
 49           dcl     last_sltep             ptr;               /* pointer to previous slt entry */
 50           dcl     tsdw                   fixed bin (71);
 51           dcl     reading_sdw            fixed bin (71);
 52           dcl     ptp                    ptr;
 53 
 54           dcl     1 control_word         aligned,           /* MST control word */
 55                   ( 2 type               fixed bin (17),    /* control word type */
 56                     2 count              fixed bin (17)
 57                     )                    unaligned;         /* count of words following */
 58 
 59 
 60           dcl     as_linkage$            external static;   /* combined linkage segments */
 61           dcl     ws_linkage$            external static;
 62           dcl     ai_linkage$            external static;
 63           dcl     wi_linkage$            external static;
 64 
 65           dcl     slt$                   external static;
 66 
 67           dcl     1 lot$                 ext like lot;      /* linkage offset table */
 68 
 69           dcl     definitions_$          ext;               /* definitions segment */
 70 
 71           dcl     make_sdw               entry (fixed bin (18), fixed bin (71), ptr, ptr);
 72           dcl     pc_wired$write         entry (ptr, fixed bin, fixed bin);
 73           dcl     pmut$swap_sdw          entry (ptr, ptr);
 74           dcl     sdw_util_$set_access   entry (pointer, bit (4) unaligned);
 75           dcl     slt_manager$build_entry
 76                                          entry (ptr) returns (ptr);
 77           dcl     syserr                 entry options (variable);
 78           dcl     disk_reader            entry (ptr, fixed bin (17));
 79 
 80           dcl     (addr, addrel, baseno, bin, mod, null, rel, size)
 81                                          builtin;
 82 ^L
 83 
 84           expect_defs = "0"b;                               /* Initialize the control switches */
 85           expect_link = "0"b;
 86 
 87           sltp = addr (slt$);                               /* Get a pointer to SLT structure. */
 88           lotp = addr (lot$);                               /* Get a pointer to the LOT. */
 89           definitions_ptr = addr (definitions_$);
 90 
 91           header_ptr = addr (header_area);                  /* Generate pointer to header area. */
 92 
 93           control_ptr = addr (control_word);                /* Generate pointer to control word. */
 94 
 95 /* Read control word and dispatch on it. */
 96 
 97 loop:
 98           call read_control_word (type, count);             /* Read a control word. */
 99           if type = 2
100           then go to collection;
101           else if type ^= 0
102           then call syserr (CRASH, "segment_loader: unknown control type ^d", type);
103 
104 /* Process header record. */
105 
106           if count > size (header_area)
107           then /* Error if header is too large ... */
108                call syserr (CRASH, "segment_loader: bad header size ^d", count);
109                                                             /* ... or too small. */
110 
111           call disk_reader (header_ptr, count);             /* Read in the header. */
112 
113           call read_control_word (type, count);             /* Read in next control word. */
114           if type ^= 1
115           then /* It must be a segment control word. */
116                call syserr (CRASH, "segment_loader: unexpected control type ^d", type);
117 
118           if header_ptr -> slte.link_sect
119           then do;                                          /* If this is a linkage segment... */
120                     if ^expect_link
121                     then /* If unexpected ... */
122                          call syserr (CRASH, "segment_loader: Unexpected linkage.");
123                     expect_link = "0"b;                     /* Turn off switch. */
124                     expect_defs = "1"b;                     /* Defs should come next. */
125 
126                     if last_sltep -> slte.combine_link
127                     then do;                                /* If linkage may be combined ... */
128                               if last_sltep -> slte.link_sect_wired
129                               then /* If linkage is wired ... */
130                                    if last_sltep -> slte.init_seg
131                                    then /* If text is init seg ... */
132                                         hclsp = addr (wi_linkage$);
133                                                             /* Use wired_init_linkage. */
134                                    else /* If text is sup seg ... */
135                                         hclsp = addr (ws_linkage$);
136                                                             /* Use wired_sup_linkage. */
137                               else /* If linkage is not wired ... */
138                                    if last_sltep -> slte.init_seg
139                               then /* If text is init seg ... */
140                                    hclsp = addr (ai_linkage$);
141                                                             /* Use active_init_linkage. */
142                               else /* If text is sup seg ... */
143                                    hclsp = addr (as_linkage$);
144                                                             /* Use active_sup_linkage. */
145 
146                               seg_ptr = hclsp -> hc_linkage_seg.next_free_ptr;
147                                                             /* Get pointer to end of combined linkage. */
148                               hclsp -> hc_linkage_seg.next_free_ptr = addrel (seg_ptr, count + mod (count, 2));
149                                                             /* Update pointer to next free even loc. */
150 
151                               call disk_reader (seg_ptr, count);
152                                                             /* Read in the linkage section into place. */
153                          end;
154 
155                     else /* If linkage not to be combined ... */
156                          call load_segment;                 /* Load in the segment. */
157 
158                     link_ptr = seg_ptr;                     /* Save pointer to linkage. */
159                     lot.lp (text_no) = link_ptr;            /* Set LOT entry. */
160                     link_ptr -> linkage_header.segment_number = text_no;
161                                                             /* Save text segment number in linkage header. */
162                end;
163 
164           else if header_ptr -> slte.defs
165           then do;                                          /* If this is a definitions segment ... */
166                     if ^expect_defs
167                     then /* If unexpected ... */
168                          call syserr (CRASH, "segment_loader: Unexpected defs.");
169                     expect_defs = "0"b;
170 
171                     seg_ptr = definitions.next_free_ptr;    /* Get pointer to end of definitions. */
172                     definitions.next_free_ptr = addrel (seg_ptr, count);
173                                                             /* Update pointer to next free. */
174 
175                     call disk_reader (seg_ptr, count);      /* Read definitions into place. */
176 
177                     definitions.dot (text_no).offset = bin (rel (seg_ptr), 18);
178                     definitions.dot (text_no).length = count;
179                                                             /* Fill in offset table entry. */
180 
181                     link_ptr -> linkage_header.def_ptr = seg_ptr;
182                                                             /* Set correct defs pointer. */
183                end;
184 
185           else do;                                          /* Must be text, or something. */
186                     if expect_link | expect_defs
187                     then /* Must not expect anything else. */
188                          call syserr (CRASH, "segment_loader: Missing linkage or defs.");
189                     expect_link = header_ptr -> slte.link_provided;
190                                                             /* Set switch. */
191 
192                     call load_segment;                      /* Load in the segment. */
193                     text_ptr = seg_ptr;                     /* Save pointer to the text. */
194                     text_no = bin (baseno (text_ptr), 18);  /* Also, get text segment number. */
195                end;
196 
197           last_sltep = sltep;                               /* Save pointer to last SLT entry. */
198 
199           go to loop;                                       /* Continue. */
200 
201 /* Process collection record. */
202 
203 collection:
204           call read_control_word (type, count);             /* Read the collection mark. */
205 
206           return;                                           /* Return to caller. */
207 %page;
208 /* LOAD_SEGMENT - Build a segment and read it in from disk. */
209 
210 load_segment:
211      proc;
212 
213           seg_ptr = slt_manager$build_entry (header_ptr);   /* Build new entry in SLT. */
214           if seg_ptr = null ()
215           then call syserr (CRASH, "segment_loader: error from slt_manager$build_entry");
216 
217           seg_number = bin (baseno (seg_ptr), 15);          /* Get segment number of new segment. */
218 
219           sltep = addr (slt.seg (seg_number));
220 
221           call make_sdw (seg_number, tsdw, astep, ptp);     /* Get an AST entry */
222           if astep = null ()
223           then return;                                      /* abs-seg */
224 
225           reading_sdw = tsdw;                               /* get copy of SDW for disk reader */
226           call sdw_util_$set_access (addr (reading_sdw), "1010"b);
227                                                             /* Force RW access while we're reading */
228           call pmut$swap_sdw (seg_ptr, addr (reading_sdw)); /* place SDW in DSEG */
229 
230           aste.gtpd = "1"b;                                 /* Keep off PD until flushed */
231 
232           call disk_reader (seg_ptr, count);                /* Slurp in the new segment. */
233 
234           call pmut$swap_sdw (seg_ptr, addr (tsdw));        /* store real SDW in DSEG */
235 
236           call pc_wired$write (astep, 0, -1);               /* Flush to disk */
237 
238           aste.gtpd = "0"b;                                 /* PD migration ok now */
239 
240           return;
241 
242 
243      end load_segment;
244 ^L
245 
246 /* READ_CONTROL_WORD - Read a control word from MST. */
247 
248 read_control_word:
249      proc (type, count);
250 
251           dcl     type                   fixed bin (17),    /* control word type */
252                   count                  fixed bin (17);    /* count of following record */
253 
254 
255           call disk_reader (control_ptr, 1);                /* Read in the control word. */
256 
257           type = control_word.type;                         /* Return the type. */
258           count = control_word.count;                       /* Return the count. */
259 
260           return;
261 
262 
263      end read_control_word;                                 /* format: off */
264 
265 %page; %include hc_linkage_seg; %include hc_definitions_seg;
266 %page; %include aste;
267 %page; %include slt;
268 %page; %include slte;
269 %page; %include object_link_dcls;
270 %page; %include lot;
271 %page; %include syserr_constants;
272 
273  ^L
274 
275 /* BEGIN MESSAGE DOCUMENTATION
276 
277    Message:
278    segment_loader: unknown control type TTT
279 
280    S: $crash
281 
282    T: $init
283 
284    M: A bad segment control word was found in the mst source.
285 
286    A: $recover
287    $boot_tape
288 
289    Message:
290    segment_loader: bad header size: SSS
291 
292    S: $crash
293 
294    T: $init
295 
296    M: A bad segment header was found in the mst source.
297 
298    A: $recover
299    $boot_tape
300 
301    Message:
302    segment_loader: unexpected control type: TTT
303 
304    S: $crash
305 
306    T: $init
307 
308    M: A segment control word was found out of sequence in the mst source.
309 
310    A: $recover
311    $boot_tape
312 
313    Message:
314    segment_loader: Unexpected DEFS/LINKAGE
315 
316    S: $crash
317 
318    T: $init
319 
320    M: A linkage or definitions section was found out of sequence in the mst source.
321 
322    A: $recover
323    $boot_tape
324 
325    Message:
326    segment_loader: Missing linkage or defs.
327 
328    S: $crash
329 
330    T: $init
331 
332    M: A linkage or definitions section which should be in the
333    mst source appears to be missing.
334 
335    A: $recover
336    $boot_tape
337 
338    Message:
339    segment_loader: error from slt_manager$build_entry
340 
341    S: $crash
342 
343    T: $init
344 
345    M: $err
346 
347    A: $recover
348    $boot_tape
349 
350    END MESSAGE DOCUMENTATION */
351 
352 
353      end segment_loader;