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 
 13 /* format: style4,insnl,delnl */
 14 init_sst:
 15      procedure;
 16 
 17 /* This procedure is called early in initialization to set up the sst:
 18    the page table words, the ast entries, and the core map are initialized.
 19    It is assumed that bootload_loader has loaded all supervisor segments in a block
 20    of contiguous core beginning with the end of the physical record buffer, and has loaded
 21    all initialization segments in a contiguous block of core at the top of core.
 22    The sst is allocated as high as possible on the bootload scu, but below
 23    initialization segments.
 24 
 25    Last Modified: (Date and Reason)
 26    85-03-08 Keith Loepere for the real covert event limits.
 27    85-02-12 Keith Loepere for another try at setting controller abs_wired.
 28    85-01-08 Keith Loepere to add covert channel variables.
 29    84-05-04 Keith Loepere for fix to setting abs_wired for memory controllers.
 30    84-01-05 BIM to finish below.
 31    831220 by E. N. Kittlitz for pc$segmove variables
 32    November 1983 by Keith Loepere for bce_sst_sizes.
 33    September 1983 by Keith Loepere for paged sst and core_map; also to
 34           write_limit correctly for early initialization.
 35    07/20/82 BIM to redo WOS's early initialization entrypoint
 36    and memory clearing tricks for Bootload Multics.
 37    06/21/82 by E. N. Kittlitz to move core map.
 38    12/18/81 by J. Bongiovanni to remove pdmap, add ast hash table
 39    11/21/80 by J. Bongiovanni to allocate sst high on bootload scu
 40    2/19/79 by D. Spector to set sst.write_limit
 41    8/16/77 by B. Greenberg to obey mem card limits.
 42    2/9/76 by S. Webber for get_main and new reconfiguration stuff
 43    04/16/75 by BSG for SST name table on top of New Storage System
 44    10/03/71 by RHG to add PAGE card to config deck
 45    09/22/71 by RHG to set cmep->cme.contr earlier
 46    08/27/71 by Richard H. Gumpertz for page multi-level
 47 */
 48 
 49 /* Automatic */
 50 
 51 dcl  base fixed bin (18);                                   /* base page number (1024 word block) of system controller */
 52 dcl  cm_size fixed bin (18);                                /* size of core map (words) */
 53 dcl  cmp ptr;
 54 dcl  coresize fixed bin (18);                               /* number of pages (max) in core */
 55 dcl  early_call bit (1) aligned;
 56 dcl  i fixed bin;
 57 dcl  initbase fixed bin (18);                               /* base page no for init segments */
 58 dcl  memory_address fixed bin (26);
 59 dcl  n_astes fixed bin;                                     /* total number of ASTEs */
 60 dcl  n_buckets fixed bin;                                   /* number of AST hast table buckets */
 61 dcl  next_available ptr;
 62 dcl  page_no fixed bin (18);
 63 dcl  pool_idx fixed bin;
 64 dcl  scu_top fixed bin (18);                                /* page number of high page on bootload scu */
 65 dcl  size_mod_1024 fixed bin (18, -10);
 66 dcl  sizes (0:3) fixed bin (18);                            /* array for AST pool sizes */
 67 dcl  sst_size fixed bin (18);
 68 dcl  sst_absadr fixed bin (26);
 69 dcl  total_base fixed bin (18);                             /* page number of begin of sst/cm segments */
 70 dcl  total_pages fixed bin (18);                            /* number of pages in sst & cmp */
 71 dcl  total_size fixed bin (21);                             /* number of words in sst & cmp */
 72 dcl  total_top fixed bin (18);                              /* page number of end of cmp */
 73 dcl  suptop fixed bin (18);                                 /* top page number for supervisor segments */
 74 dcl  top fixed bin (18);                                    /* top page number of memory module */
 75 dcl  uid_mask bit (36) aligned;                             /* mask to strip out low-order bits of uid */
 76 
 77 dcl  (cm_sdw, sst_sdw) fixed bin (71);
 78 dcl  1 local_sst_card aligned like sst_card;
 79 
 80 /* Static */
 81 
 82 /* dcl  debug bit (1) aligned init ("1"b) static options (constant); /* build unpaged sst, core_map */
 83 dcl  AVG_HT_DEPTH fixed bin int static options (constant) init (5);
 84                                                             /* desired avg AST hash table depth */
 85 dcl  HT_SIZES (6) fixed bin int static options (constant)   /* allowable AST hash table sizes */
 86           init (64, 128, 256, 512, 1024, 2048);
 87 dcl  HT_UID_MASKS (6) bit (36) aligned int static options (constant)
 88                                                             /* corresponding masks to strip out low-order uid bits */
 89           init ("000000000077"b3, "000000000177"b3, "000000000377"b3, "000000000777"b3, "000000001777"b3,
 90           "000000003777"b3);
 91 dcl  PTS (0:3) fixed bin static init (4, 16, 64, 256) options (constant);
 92                                                             /* Global constants */
 93 
 94 dcl  WHOAMI char (8) init ("init_sst") int static options (constant);
 95 
 96 /* Builtins */
 97 
 98 dcl  (addr, addrel, baseno, divide, hbound, lbound, max, min, bit, bin, null, size, sum, unspec) builtin;
 99 
100 /* External */
101 
102 dcl  core_map$ ext bit (36) aligned;
103 dcl  slt$ ext bit (36) aligned;
104 dcl  sys_boot_info$bce_sst_sizes (0:3) fixed bin ext static;
105 dcl  sys_boot_info$bootload_mem_size fixed bin (26) ext static;
106 dcl  unpaged_page_tables$ ext static;
107 
108 /* Entries */
109 
110 dcl  absadr entry (ptr, fixed bin (35)) returns (fixed bin (26));
111 dcl  config_$init_card entry (char (4) aligned, ptr);
112 dcl  config_$add entry (ptr, ptr);
113 dcl  config_$find_parm entry (char (4) aligned, ptr);
114 dcl  freecore entry (fixed bin (18));
115 dcl  get_main entry (ptr, fixed bin (18), fixed bin (71));
116 dcl  get_main$given_address entry (ptr, fixed bin (26), fixed bin (18), fixed bin (71));
117 dcl  init_aste_pools entry;
118 dcl  pmut$swap_sdw entry (ptr, ptr);
119 dcl  syserr entry options (variable);
120 dcl  config_$find entry (char (4) aligned, ptr);
121 ^L
122 
123 early:
124      entry;
125 
126 /* This entrypoint is called to set up an SST for the early environment, */
127 /* where there is only sys_boot_info$bootload_mem_size available. */
128 /* This may or may not turn out to be the right SST setup for the */
129 /* returnable to system */
130 
131           call init_ptrs;                                   /* get seg ptrs to sst, core map, slt, etc. */
132 
133           early_call = "1"b;                                /* Remember why we're here */
134 
135           sizes (*) = sys_boot_info$bce_sst_sizes (*);
136 
137           coresize = divide (sys_boot_info$bootload_mem_size, 1024, 26, 0);
138 
139           suptop = divide (slt.free_core_start + 1023, 1024, 18, 0);
140                                                             /* First page boundary after the wired supervisor */
141           initbase = divide (slt.free_core_start + slt.free_core_size, 1024, 18, 0) - 1;
142                                                             /* first page boundary below the init segs */
143           goto ALLOCATE_SST;
144 ^L
145 
146 normal:
147      entry;
148 
149 /* This entrypoint is used for service boots. It pays attention to */
150 /* the config deck, rather than hoking the situation up */
151 
152           call init_ptrs;                                   /* get pointers to interesting places */
153 
154           early_call = "0"b;
155 
156 /* Get storage for SST as function of SST card. */
157 
158           sst_cardp = null;
159           call config_$find ("sst ", sst_cardp);            /* get SST card */
160           if sst_cardp = null then do;
161                sst_cardp = addr (local_sst_card);           /* prepare to construct */
162                call config_$init_card (SST_CARD_WORD, sst_cardp);
163 
164                sst_card.no_aste (0) = 400;
165                sst_card.no_aste (1) = 150;
166                sst_card.no_aste (2) = 50;                   /* These add up to nice size */
167                sst_card.no_aste (3) = 20;                   /* and Olin thought this needed to be this big */
168 
169                do pool_idx = 1 to 4;
170                     sst_card.field_type (pool_idx) = CONFIG_DECIMAL_TYPE;
171                end;
172 
173                call config_$add (sst_cardp, null);          /* add it in */
174 
175 
176                call syserr (BEEP, "^a: No SST card in config deck. One has been added: SST^2x^4(^d.^2x^)", WHOAMI,
177                     sst_card.no_aste);
178 
179           end;
180 
181           sizes (*) = sst_card.no_aste (*);                 /* Copy them locally */
182 ^L
183 
184 /* Now see how much storage has to be described in the core map */
185 /* Note that this code will work even if the supervisor segs */
186 /* overflow into a second controller. */
187 
188 
189           suptop = divide (slt.free_core_start + 1023, 1024, 18, 0);
190                                                             /* First page boundary after the wired supervisor */
191           initbase = divide (slt.free_core_start + slt.free_core_size, 1024, 18, 0) - 1;
192                                                             /* first page boundary below the init segs */
193 
194           scu_top = 0;
195           coresize = 0;
196           do i = 0 to 7;
197                if scs$controller_data (i).online | scs$controller_data (i).offline
198                                                             /* make sure controller is being used */
199                then do;
200                     coresize = max (coresize, scs$controller_data (i).size + scs$controller_data (i).base);
201                     if scs$controller_data (i).online then do;
202                          base = scs$controller_data (i).base;
203                                                             /* starts at zero */
204                          top = base + scs$controller_config_size (i) - 1;
205                                                             /* make zero based page number */
206                          if base < suptop
207                          then                               /* controller abs-wired */
208                               if top > scu_top
209                               then scu_top = top;
210                     end;
211                end;
212           end;
213 ^L
214 
215 ALLOCATE_SST:                                               /* early and normal entrypoints join here, with coresize and other */
216                                                             /* handy variables set */
217                                                             /* Now see how big the Hash Table gets */
218 
219           n_astes = sum (sizes);                            /* builtins are good things */
220 
221           n_buckets = divide (n_astes, AVG_HT_DEPTH, 17);
222           do i = 1 to hbound (HT_SIZES, 1) while (n_buckets > HT_SIZES (i));
223           end;
224           if i > hbound (HT_SIZES, 1)
225           then i = hbound (HT_SIZES, 1);
226           n_buckets = HT_SIZES (i);
227           uid_mask = HT_UID_MASKS (i);
228 
229 /* Now we know enough to get size of sst segment */
230 
231           sst_size = size (sst) + n_buckets;
232           do i = 0 to 3;                                    /* now include AST/PT storage */
233                sst_size = sst_size + (size (aste) + PTS (i)) * sizes (i);
234           end;
235 
236           cm_size = coresize * size (cme) + 8;              /* The 8 is for a backstop to detect invalid zero threads ! */
237 
238           size_mod_1024 = sst_size + 1023;
239           sst_size = size_mod_1024;                         /* compiler bug stops obvious builtin form */
240                                                             /* i.e., fixed (fixed (foo, 18, -10), 18, 0) makes bad code */
241           size_mod_1024 = cm_size + 1023;
242           cm_size = size_mod_1024;
243 
244 
245           if early_call                                     /* dont know from controllers, just shtup it someplace */
246           then do;
247                call get_main (sstp, sst_size, sst_sdw);
248                call get_main (cmp, cm_size, cm_sdw);
249                call pmut$swap_sdw (sstp, addr (sst_sdw));
250                call pmut$swap_sdw (cmp, addr (cm_sdw));
251 /*             if debug then call make_unpaged; */
252           end;
253           else do;
254                total_size = sst_size + cm_size;
255                size_mod_1024 = total_size + 1023;
256                total_pages = divide (size_mod_1024, 1024, 18, 0);
257                                                             /* and shift down */
258                                                             /* size of sst & cm in pages */
259 
260                total_top = min (scu_top, initbase);         /* allocate as high as possible on bootload scu */
261                                                             /* but below init segs */
262                total_base = total_top - total_pages + 1;    /* base of sst; we want to use pages total_top, total_top -1, ... total_top - (total_pages + 1) */
263                                                             /* which is total_pages pages */
264 
265                if total_base < suptop
266                then call syserr (CRASH, "init_sst: insufficient main storage for sst_seg and core map.");
267                                                             /* crash the system */
268 
269                memory_address = total_base * 1024;
270                call get_main$given_address (sstp, memory_address, sst_size, sst_sdw);
271                call pmut$swap_sdw (sstp, addr (sst_sdw));   /* and make it addressable */
272 
273                memory_address = (total_base * 1024) + sst_size;
274                call get_main$given_address (cmp, memory_address, cm_size, cm_sdw);
275                call pmut$swap_sdw (cmp, addr (cm_sdw));     /* and make it addressable */
276 /*             if debug then call make_unpaged; */
277           end;                                              /* non-early case */
278 
279 declare  1 CME (0:coresize - 1) aligned like cme based (cmp);
280 
281           addr (flagbox$) -> fgbx.sst_sdw = unspec (sst_sdw);         /* tell BOS about sst area */
282 
283 /* Now we have the SST -- we can fill it in */
284 
285           sst.astsize = size (aste);                        /* Set the size of an AST entry */
286           sst.cmesize = size (cme);                         /* And a CM entry */
287           sst_absadr = absadr (addr (sst_seg$), (0));
288           addr (unpaged_page_tables$) -> upt.sst_absloc, sst.ptwbase = sst_absadr;
289           addr (unpaged_page_tables$) -> upt.sst_last_loc = sst_absadr + sst_size - 1;
290 
291           do i = 0 to 3;
292                sst.pts (i) = PTS (i);
293                sst.no_aste (i) = bit (sizes (i), 18);
294           end;
295 
296 /* Now set up the core map. All core map entries to an initial "deconfigured" state */
297 
298           begin;
299 declare  BACK_STOP (8) bit (36) aligned based (cmp);
300                BACK_STOP = (36)"1"b;
301           end;
302           cmp = addrel (cmp, 8);                            /* Skip 8 words of -1's that force faults */
303                                                             /* when the tnreads are invalid */
304 
305           sst.cmp = cmp;                                    /* sst pointer */
306 
307           begin;
308 declare  1 TEMPLATE_CME aligned like cme;
309                unspec (TEMPLATE_CME) = ""b;
310                TEMPLATE_CME.fp, TEMPLATE_CME.bp = "777777"b3;
311                CME (*) = TEMPLATE_CME;                      /* compiler is clever with these */
312           end;
313 
314 /* Now set up pointers, etc., to the AST hash table */
315 
316           next_available = addrel (sstp, size (sst));
317           sst.ast_ht_ptr = next_available;
318           sst.ast_ht_n_buckets = n_buckets;
319           sst.ast_ht_uid_mask = uid_mask;
320           next_available = addrel (next_available, n_buckets);
321 
322           sst.astap, astep = next_available;
323 
324 /* Set up wait events */
325 
326           sst.astl_event = "400000000000"b3;
327           sst.temp_w_event = "200000000000"b3;              /* Set up temp wire lock event */
328 
329           call init_aste_pools;                             /* init all the ASTE's */
330 
331 
332 /* Now initialize core map entries for all the memory we know about */
333 /* Put completely unused pages into the free pool, leave the rest */
334 /* untouched, and also not threaded in */
335 /* Collect_free_core will set the perm_wired pages to have -1 threads, */
336 /* and worry about the rest. */
337 
338           if ^early_call
339           then do i = 0 to 7;                               /* go through all memory controllers */
340                base = scs$controller_data (i).base;
341                top = base + scs$controller_config_size (i) - 1;
342                if scs$controller_data (i).online | scs$controller_data (i).offline
343                then begin;                                  /* update core map and core usage map */
344 declare  1 THIS_CTRL_CME (0:top - base) aligned like cme defined (CME (base));
345 
346                     scs$controller_data (i).abs_wired = (base < suptop);
347                                                             /* remember if controller is absolute wired */
348 
349                     THIS_CTRL_CME.contr = bit (bin (i, 3));
350                end;
351           end;
352           else do i = lbound (scs$controller_data, 1) to hbound (scs$controller_data, 1); /* go through all memory controllers */
353                base = scs$controller_data (i).base;
354                top = base + 511;                            /* only 512k used */
355                if (scs$controller_data (i).online | scs$controller_data (i).offline) & base = 0
356                then begin;                                  /* we found our bootload controller */
357 declare  1 THIS_CTRL_CME (0:top - base) aligned like cme defined (CME (base));
358 
359                     scs$controller_data (i).abs_wired = "1"b;
360                                                             /* remember if controller is absolute wired */
361                                                             /* So that freecore calls will reflect into abs_usuable */
362                     THIS_CTRL_CME.contr = bit (bin (i, 3));
363                end;
364           end;
365 
366           if early_call
367           then do page_no = divide (slt.free_core_start + 1023, 1024, 24, 0)
368                     to divide (slt.free_core_start + slt.free_core_size - 1, 1024, 24, 0) - 1;
369                                                             /* dont free first page of PVT */
370                call freecore (page_no);
371           end;
372           else do page_no = suptop to total_base - 1, total_top + 1 to initbase - 1;
373                                                             /* Skip the SST, low memory, and initsegs */
374                call freecore (page_no);
375           end;
376 
377           sst.space (*) = -1;                               /* BACKSTOP */
378 
379 /* Set write_limit to reasonable value.  Final setting will be done at end of init_pvt. */
380           sst.write_limit = slt.free_core_size / 8192;      /* 1/8th memory */
381 
382 /* setup for pc$segmove */
383 
384           sst.segmove_lock.pid = ""b;
385 declare  SEGM char (4) init ("segm") int static options (constant);
386           sst.segmove_lock.event = unspec (SEGM);
387           sst.segmove_lock.notify = "0"b;
388           sst.segmove_io_limit = 20;
389           sst.segmove_found_synch = 0;
390           sst.segmove_synch_disappeared = 0;
391           sst.segmove_max_tries = 0;
392           sst.segmove_astep, sst.segmove_old_addr_astep, sst.segmove_new_addr_astep = null;
393                                                             /* no pc segmove in progress */
394           sst.segmove_pvtx, sst.segmove_vtocx = 0;
395 
396           sst.seg_state_change_limit = 256;                 /* covert channel limits */
397           sst.max_seg_state_change_bw = 50;
398           sst.audit_seg_state_change_bw = 5;
399           return;
400 ^L
401 
402 /* Procedure to get things both entrypoints want */
403 
404 init_ptrs:
405      procedure;
406           sstp = addr (sst_seg$);
407           sstnp = addr (sst_names_$);
408           sltp = addr (slt$);
409           cmp = addr (core_map$);
410      end init_ptrs;
411 
412 /* routine to make sst and core_map unapged for BOS' sake */
413 /* make_unpaged:
414      procedure;
415           call sdw_util_$dissect (addr (sst_sdw), addr (sdwi));
416           sdwi.paged = "0"b;
417           sdwi.address = absadr (sstp, (0));
418           call sdw_util_$construct (addr (sst_sdw), addr (sdwi));
419           call pmut$swap_sdw (sstp, addr (sst_sdw));
420 
421           call sdw_util_$dissect (addr (cm_sdw), addr (sdwi));
422           sdwi.paged = "0"b;
423           sdwi.address = absadr (cmp, (0));
424           call sdw_util_$construct (addr (cm_sdw), addr (sdwi));
425           call pmut$swap_sdw (cmp, addr (cm_sdw));
426           return;
427      end; */
428 ^L
429 /* format: off */
430 
431 %page; %include flagbox;
432 %page; %include null_addresses;
433 %page; %include scs;
434 %page; %include config_sst_card;
435 %include config_parm_card;
436 %include config_deck;
437 %page; %include sst;
438 %page; %include aste;
439 %page; %include slt;
440 %page; %include slte;
441 %page; %include cmp;
442 %page; %include sdw_info;
443 %page; %include sstnt;
444 %page; %include syserr_constants;
445 %page; %include unpaged_page_tables;
446 ^L
447 /* BEGIN MESSAGE DOCUMENTATION
448 
449    Message:
450    init_sst: No SST card in config deck. One has been added: SST N N N N
451 
452    S:   $beep
453 
454    T:   $init
455 
456    M:   No SST card was found in the config deck. ASTE pool sizes
457    of N N N N have been set as defaults.
458 
459    Message:
460    init_sst: insufficient storage available for sst_seg and core map.
461 
462    S:     $crash
463 
464    T:     $init
465 
466    M:     Not enough main storage was available to create the sst_seg during
467    initialization.  The system tape may be bad, or the configuration
468    may be too small, or the system parameters specified in the
469    configuration deck may be incorrect or inconsistent with the amount
470    of main storage available.
471 
472    A:     $recover
473    Check the configuration and the CONFIG deck
474    $boot_tape
475 
476    END MESSAGE DOCUMENTATION */
477 
478      end init_sst;