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 /* This procedure is called three times by the Multics initializer.
 14    It initializes the fault and interrupt mechanism by setting pointers
 15    in the fim, the wired_fim, the iom_interrupt, the pds, the prds, and the fault vector.
 16    The procedures restart_fault, and emergency_shutdown
 17    are also initialized.
 18 
 19    Last Modified: (Date and reason)
 20 
 21    01/06/84 by Keith Loepere for drl special drls in bce (breakpoints) and for pmut$cam_both.
 22    10/21/83 by Keith Loepere for hardcore_sct_seg$hardcore_sct_seg (in bound seg).
 23    05/17/83 by E. N. Kittlitz for drl_entry.
 24    09/22/82 by BIM to reorganize to signal in collection 1.
 25    08/10/82 by BIM to eliminate the zero out entirely.
 26    07/14/82 by BIM to change bootstrap1 to bound_bootload_1.
 27    06/25/82 by E. N. Kittlitz to move core map.
 28    03/19/81 by J. A. Bush during DPS8/70M debug to 0 out bootstrap1's SDW
 29    02/23/81 by J. Bongiovanni for fast connect code
 30    12/01/80 by C. Hornig for new interrupt mechanism.
 31    08/27/80 by J. A. Bush for  DPS8/70M
 32    08/13/79 by J. A. Bush for new signal_entry & parity_entry of fim
 33    05/10/79 by BSG for shared stack_0's.
 34    08/09/77 by Bernard Greenberg to reinstate derail fault  vector
 35    06/10/77 by Melanie Weaver to set up signaller and sct handler
 36    2/08/76 by Noel I. Morris for new reconfig
 37    01/06/75 at 21:07:50 by R F Mabee.  Removed crock setting signal_ptr in stack.
 38    4/25/74 by B. Greenberg for cache system
 39    2/74 by S. Webber for privileged-mode page control
 40    8/10/73 by R.Snyder to read switches to get bootload memory rather than believe MEM card.
 41    5/18/73 by R.Snyder to cause initialize interrupts to be ignored in general.
 42    7/26/71 by rhg to divert sys_trouble interrupts to special ii entry
 43    7/26/71 by RHG to make cell number reading off config deck be mod 64
 44    rather than pds$page_fault_data+32
 45    7/24/71 by RHG to use ii$paging_interrupt_entry, ii$pageable_interrupt_entry, scs$interrupt_state
 46    7/16/71 by Richard H. Gumpertz to fix initialization of pointers in prds, pds
 47    coded May 1970 by Roger R. Schell
 48 */
 49 
 50 
 51 /* format: style2,^indattr */
 52 initialize_faults:
 53      procedure;
 54 
 55 /* Declaration of external references we want to get pointers to */
 56 
 57           dcl     sctptr ptr;
 58           dcl     sctp (0:1023) ptr unal based;
 59 
 60           dcl     core_map$ ext bit (36);
 61           dcl     copy_on_write_handler_$copy_on_write_handler_ ext entry;
 62           dcl     dseg$ (0:4095) fixed bin (71) ext;
 63           dcl     emergency_shutdown$ ext bit (36);
 64           dcl     fault_vector$ ext bit (36);
 65           dcl     fim$drl_entry entry ext;
 66           dcl     fim$onc_start_shut_entry entry ext;
 67           dcl     fim$parity_entry entry ext;
 68           dcl     fim$signal_entry entry ext;
 69           dcl     fim$access_violation_entry entry ext;
 70           dcl     fim$primary_fault_entry entry ext;
 71           dcl     hardcore_sct_seg$hardcore_sct_seg ext fixed bin;
 72           dcl     iom_interrupt$interrupt_entry entry ext;
 73           dcl     isot_fault_handler_$isot_fault_handler_ ext entry;
 74           dcl     lot_fault_handler_$lot_fault_handler_ ext entry;
 75           dcl     pds$stack_0_ptr ptr ext;
 76           dcl     1 pds$fim_data aligned like mc external;
 77           dcl     1 pds$page_fault_data aligned like mc external;
 78           dcl     1 pds$signal_data aligned like mc external;
 79           dcl     1 prds$fim_data aligned like mc external;
 80           dcl     prds$fast_connect_code entry external;
 81           dcl     1 prds$ignore_data aligned like scu external;
 82           dcl     prds$ignore_pl (8) bit (36) aligned external;
 83           dcl     1 prds$interrupt_data aligned like mc external;
 84           dcl     1 prds$sys_trouble_data aligned like mc external;
 85           dcl     return_to_ring_0_$restart_fault_ptr ptr ext;
 86           dcl     signal_$signal_ entry external;
 87           dcl     tc_data$ bit (36) aligned external;
 88           dcl     wired_fim$xec_fault entry external;
 89           dcl     wired_fim$unexp_fault entry external;
 90           dcl     wired_fim$ignore entry external;
 91           dcl     page_fault$fault entry external;
 92           dcl     wired_fim$timer_runout entry external;
 93 
 94           dcl     (
 95                   emergency_shutdown$lp,
 96                   emergency_shutdown$pp,
 97                   fim$prs,
 98                   fim$scu,
 99                   fim$sig_prs,
100                   fim$sig_scu,
101                   fim$lp,
102                   iom_interrupt$iilink,
103                   iom_interrupt$prds_prs,
104                   iom_interrupt$prds_scu,
105                   page_fault$my_lp,
106                   pds$apt_ptr,
107                   restart_fault$,
108                   restart_fault$lp,
109                   restart_fault$scu,
110                   wired_fim$prs,
111                   wired_fim$scuinfo,
112                   wired_fim$trouble_prs,
113                   wired_fim$trouble_scuinfo,
114                   wired_fim$int_scuinfo,
115                   wired_fim$ignore_pl,
116                   wired_fim$ignore_scuinfo,
117                   wired_fim$my_linkage_ptr,
118                   page_fault$cme_offsets,
119                   page_fault$pf_prs,
120                   page_fault$pf_scuinfo
121                   ) pointer external;
122 
123 
124           dcl     cme_offsets (0:size (cme) - 1) ptr based (addr (page_fault$cme_offsets));
125 
126           dcl     lot$ (0:1023) pointer unaligned external static;
127 
128           dcl     privileged_mode_ut$cam_both ext entry,    /* to clear our associative memory */
129                   privileged_mode_ut$set_mask entry (bit (72) aligned, fixed bin (71)),
130                                                             /* to set memory controller masks */
131                   privileged_mode_ut$ldt ext entry (fixed bin);
132                                                             /* to load timer register */
133           dcl     sdw_util_$get_access entry (ptr, bit (4) unaligned);
134           dcl     sdw_util_$set_access entry (ptr, bit (4) unaligned);
135 
136 
137           dcl     (
138                   ignore_ptr,                               /* pointer to FIM entry to ignore */
139                   ignore_d_ptr,                             /* pointer to place in PRDS for ignored SCU data */
140                   primary_trap,
141                   primary_scup,
142                   signal_trap,
143                   signal_scup,
144                   onc_trap,
145                   onc_scup,
146                   unexp_trap,
147                   unexp_scup,
148                   p
149                   ) ptr;
150 
151           dcl     i fixed bin (5);                          /* loop index */
152           dcl     access bit (4);                           /* saved access of procedure segment */
153 
154           dcl     (addr, baseno, baseptr, codeptr, fixed, null, ptr, size) builtin;
155 
156           declare (
157                   initialize_faults_data$primary_one,
158                   initialize_faults_data$primary_two,
159                   initialize_faults_data$signal_one,
160                   initialize_faults_data$signal_two,
161                   initialize_faults_data$onc_one,
162                   initialize_faults_data$onc_two
163                   ) (0:31) bit (1) unaligned ext static;
164 ^L
165 
166 
167 /* FAULT_INIT_ONE - Initialize Fault and Interrupt Mechanism
168    and Set Up Fault Vector for Remainder of Initialization */
169 
170 fault_init_one:
171      entry;
172 
173 /* initialize pointers that we will need */
174 
175           call GET_STANDARD_POINTERS;
176 
177 
178           do i = 0 to 31;                                   /* first set up all faults and interrupts the same */
179 
180                if initialize_faults_data$primary_one (i)
181                then do;
182                          fv.f_tra_ptr (i) = primary_trap;
183                          fv.f_scu_ptr (i) = primary_scup;
184                     end;
185                else if initialize_faults_data$signal_one (i)
186                then do;
187                          fv.f_tra_ptr (i) = signal_trap;
188                          fv.f_scu_ptr (i) = signal_scup;
189                     end;
190                else if initialize_faults_data$onc_one (i)
191                then do;
192                          fv.f_tra_ptr (i) = onc_trap;
193                          fv.f_scu_ptr (i) = onc_scup;
194                     end;
195                else do;                                     /* otherwise unaccounted for */
196                          fv.f_tra_ptr (i) = unexp_trap;
197                          fv.f_scu_ptr (i) = unexp_scup;
198                     end;
199 
200 
201                fv.i_tra_ptr (i) = ignore_ptr;               /* ignore all interrupts */
202                fv.i_scu_ptr (i) = ignore_d_ptr;             /* put SCU data where we can find it */
203 
204           end;
205 
206           fv.f_tra_ptr (FAULT_NO_LUF) = ignore_ptr;         /* ignore lockup faults */
207           fv.f_scu_ptr (FAULT_NO_LUF) = ignore_d_ptr;       /* put SCU data where we can find it */
208 
209           fv.f_tra_ptr (FAULT_NO_TRO) = ignore_ptr;
210           fv.f_scu_ptr (FAULT_NO_TRO) = ignore_d_ptr;
211 
212 /* Execute faults have special meaning. */
213           fv.f_tra_ptr (FAULT_NO_EXF) = codeptr (wired_fim$xec_fault);
214           fv.f_scu_ptr (FAULT_NO_EXF) = addr (prds$sys_trouble_data.scu);
215 
216 /* set up for page faults */
217           fv.f_tra_ptr (FAULT_NO_DF1) = codeptr (page_fault$fault);
218           fv.f_scu_ptr (FAULT_NO_DF1) = addr (pds$page_fault_data.scu);
219 
220 /* set up for df0 (seg faults) */
221           fv.f_tra_ptr (FAULT_NO_DF0) = codeptr (fim$primary_fault_entry);
222           fv.f_scu_ptr (FAULT_NO_DF0) = addr (addr (pds$fim_data) -> mc.scu (0));
223 
224 /* entry for connect faults */
225           fv.f_tra_ptr (FAULT_NO_CON) = codeptr (prds$fast_connect_code);
226           fv.f_scu_ptr (FAULT_NO_CON) = addr (prds$fim_data.scu);
227 
228 /* direct derail faults to a special entry */
229 
230           fv.f_tra_ptr (FAULT_NO_DRL) = addr (fim$drl_entry);
231 
232 /* initialize the FIM */
233 
234           call set_access (fim$prs);
235           fim$prs = addr (pds$fim_data);                    /* Set pointer to place for pointer regs. */
236           fim$scu = addr (pds$fim_data.scu);                /* Set pointer to place for SCU data. */
237           fim$sig_prs = addr (pds$signal_data);             /* Set ptr for signal_data ptr regs. */
238           fim$sig_scu = addr (pds$signal_data.scu);         /* Set ptr for signal_data SCU data. */
239           call set_lp (fim$lp);                             /* Store linkage pointer and set access. */
240 
241 /* initialize the Interrupt Interceptor */
242 
243           call set_access (iom_interrupt$prds_prs);
244 
245           iom_interrupt$prds_prs = addr (prds$interrupt_data);
246                                                             /* Set pointer for SPRI in the PRDS */
247           iom_interrupt$prds_scu = addr (prds$interrupt_data.scu);
248                                                             /* Set pointer for SCU in the PRDS */
249           call set_lp (iom_interrupt$iilink);               /* Store linkage ptr. */
250 
251 /* initialize wired_fim */
252 
253           call set_access (wired_fim$prs);
254 
255           wired_fim$prs = addr (prds$fim_data);             /* Set pointer to place for pointer registers. */
256           wired_fim$scuinfo = addr (prds$fim_data.scu);     /* Set pointer to place for SCU data. */
257 
258 /* Set machine condition pointer for wired_sys_trouble. */
259           wired_fim$trouble_prs = addr (prds$sys_trouble_data);
260                                                             /* Set pointer to place for pointer registers. */
261           wired_fim$trouble_scuinfo = addr (prds$sys_trouble_data.scu);
262                                                             /* Set pointer to place for SCU data. */
263 
264           wired_fim$int_scuinfo = addr (pds$page_fault_data.scu);
265                                                             /* Set pointer in wired_fim. */
266 
267           wired_fim$ignore_pl = addr (prds$ignore_pl);
268           wired_fim$ignore_scuinfo = ignore_d_ptr;          /* Set pointer for ignoring faults. */
269 
270           call set_lp (wired_fim$my_linkage_ptr);           /* store linkage pointer */
271 
272 /* initialize Page Fault Handler */
273 
274           call set_access (page_fault$my_lp);
275 
276           page_fault$pf_prs = addr (pds$page_fault_data);   /* save pointer to place for pointer registers */
277           page_fault$pf_scuinfo = addr (pds$page_fault_data.scu);
278                                                             /* save pointer to place for SCU data */
279           cmep = null;
280           do i = 0 to size (cme) - 1;                       /* set up C.M. ITS pointers */
281                cme_offsets (i) = ptr (addr (core_map$), i);
282           end;
283           call set_lp (page_fault$my_lp);                   /* store linkage pointer for page */
284 
285 /* initialize restart_fault */
286 
287           call set_access (restart_fault$scu);
288           restart_fault$scu = addr (pds$signal_data.scu);   /* Set RCU pointer for restart_fault. */
289           call set_lp (restart_fault$lp);                   /* store linkage pointer */
290 
291 /* initialize emergency_shutdown */
292 
293           call set_access (emergency_shutdown$lp);
294           emergency_shutdown$pp = addr (emergency_shutdown$);
295                                                             /* save pointer to itself */
296           call set_lp (emergency_shutdown$lp);              /* store linkage pointer */
297 
298           pds$apt_ptr = addr (tc_data$);                    /* set pointer so that pxss can work */
299 
300 
301 /* Initialize return_to_ring_0_$restart_fault_ptr for returns to ring zero */
302 
303           call set_access (return_to_ring_0_$restart_fault_ptr);
304                                                             /* allow stores to rr0_ */
305           return_to_ring_0_$restart_fault_ptr = addr (restart_fault$);
306                                                             /* store pointer to restart_fault */
307           call restore_access;                              /* restore old rr0_ access */
308 
309 /* What follows used to be signal_init */
310 
311 /* Fill in inzr_stk0 stack base. init_stack_0 will fill in others */
312 
313           pds$stack_0_ptr = stackbaseptr ();                /* Allow fim to work, interim. */
314           stackbaseptr () -> stack_header.signal_ptr = codeptr (signal_$signal_);
315           stackbaseptr () -> stack_header.unwinder_ptr = null;
316                                                             /* take a fault */
317           stackbaseptr () -> stack_header.sct_ptr = addr (hardcore_sct_seg$hardcore_sct_seg);
318 
319 /* Put a standard for scu/tra pair in the vector for derail. Bootstrap1 has been leaving it lying around
320    as an immediate RTB up till now for clean crashes. */
321 
322           fv.fpair (FAULT_NO_DRL).scu = rel (addr (fv.f_scu_ptr (FAULT_NO_DRL))) || "657220"b3;
323                                                             /* fv seg is at 0 abs. */
324           fv.fpair (FAULT_NO_DRL).tra = rel (addr (fv.f_tra_ptr (FAULT_NO_DRL))) || "710220"b3;
325 
326           scs$faults_initialized = "1"b;                    /* Mark faults as initialized. */
327           return;
328 ^L
329 
330 /* INTERRUPT_INIT - Set Up Interrupt Vector for Multics Operation. */
331 
332 interrupt_init:
333      entry;
334 
335 /* initialize pointers */
336 
337           fvp = addr (fault_vector$);                       /* Get pointer to fault vector. */
338 
339 /* turn off all interrupts */
340 
341           call privileged_mode_ut$set_mask (scs$sys_level, 0);
342                                                             /* Make sure no interrupts come in. */
343                                                             /* set up SCU pointer for the PRDS */
344           fv.i_tra_ptr (*) = codeptr (iom_interrupt$interrupt_entry);
345           fv.i_scu_ptr (*) = addr (prds$interrupt_data.scu);
346 
347 /* Open the memory controller mask */
348 
349           call privileged_mode_ut$set_mask (scs$open_level, 0);
350                                                             /* Open mask for all interrupts. */
351 
352           return;                                           /* Interrupts are under weigh. */
353 ^L
354 
355 /* FAULT_INIT_TWO -- reset some fault vector assignments for file system */
356 /*                   operations */
357 
358 fault_init_two:
359      entry;
360 
361 
362           call GET_STANDARD_POINTERS;
363 
364 /* set the timer to give us time to change fault vector */
365 
366           call privileged_mode_ut$ldt (-1);                 /* Load the timer register. */
367 
368 /* Direct most faults to the FIM. */
369 
370           do i = 0 to 31;                                   /* Loop. */
371 
372                if initialize_faults_data$primary_two (i)
373                then do;
374                          fv.f_tra_ptr (i) = primary_trap;
375                          fv.f_scu_ptr (i) = primary_scup;
376                     end;
377                else if initialize_faults_data$signal_two (i)
378                then do;
379                          fv.f_tra_ptr (i) = signal_trap;
380                          fv.f_scu_ptr (i) = signal_scup;
381                     end;
382                else if initialize_faults_data$onc_two (i)
383                then do;
384                          fv.f_tra_ptr (i) = onc_trap;
385                          fv.f_scu_ptr (i) = onc_scup;
386                     end;
387                     else if i > 25 & i < 31
388                     then do;
389                               fv.f_tra_ptr (i) = unexp_trap;
390                               fv.f_scu_ptr (i) = unexp_scup;
391                          end;
392           end;
393 
394 /* direct access violations to a special entry */
395 
396           fv.f_tra_ptr (FAULT_NO_ACV) = codeptr (fim$access_violation_entry);
397           fv.f_scu_ptr (FAULT_NO_ACV) = primary_scup;
398 
399 /* direct derail faults to a special entry */
400 
401           fv.f_tra_ptr (FAULT_NO_DRL) = addr (fim$drl_entry);
402 
403 /* Direct timer runouts to special handler. */
404 
405           fv.f_tra_ptr (FAULT_NO_TRO) = codeptr (wired_fim$timer_runout);
406           fv.f_scu_ptr (FAULT_NO_TRO) = addr (prds$fim_data.scu);
407 
408 /* direct parity errors to a special entry */
409 
410           fv.f_tra_ptr (FAULT_NO_PAR) = codeptr (fim$parity_entry);
411           fv.f_scu_ptr (FAULT_NO_PAR) = primary_scup;
412 
413 /* Fill in the ring zero static handlers. This can only be called after */
414 /* collection 2 is loaded */
415 
416           sctptr = addr (hardcore_sct_seg$hardcore_sct_seg);
417 
418           sctptr -> sctp (no_write_permission_sct_index) = codeptr (copy_on_write_handler_$copy_on_write_handler_);
419           sctptr -> sctp (isot_fault_sct_index) = codeptr (isot_fault_handler_$isot_fault_handler_);
420           sctptr -> sctp (lot_fault_sct_index) = codeptr (lot_fault_handler_$lot_fault_handler_);
421 
422           return;
423 %page;
424 /* SET_LP - Store Linkage Pointer and Set Proper Access. */
425 
426 set_lp:
427      proc (link_ptr);                                       /* Entry to set text-embedded linkage pointers */
428 
429           dcl     link_ptr ptr;                             /* cell to contain linkage pointer */
430 
431           dcl     segno fixed bin (15);                     /* segment number of segment */
432           dcl     target_ptr ptr;                           /* pointer to segment whose linkage we want */
433 
434           target_ptr = addr (link_ptr);                     /* for set_lp we want our own linkage */
435 
436           segno = fixed (baseno (target_ptr), 18);          /* compute segment number */
437           link_ptr = lot$ (segno);                          /* Generate pointer to linkage section. */
438 
439 
440           call restore_access;                              /* restore proper seg access */
441 
442           return;
443 
444      end set_lp;
445 
446 
447 
448 /* SET_ACCESS/RESTORE_ACCESS - Set Write Access to Procedure and Reset Later. */
449 
450 set_access:
451      procedure (textp);                                     /* proc to set write access */
452 
453           dcl     segno fixed bin (15);
454           dcl     textp ptr;                                /* any pointer residing in text segment */
455 
456           segno = fixed (baseno (addr (textp)), 18);        /* get segment number */
457           call sdw_util_$get_access (addr (dseg$ (segno)), access);
458                                                             /* save old access */
459           call sdw_util_$set_access (addr (dseg$ (segno)), access | RW_ACCESS);
460                                                             /* allow writing */
461           call privileged_mode_ut$cam_both;                 /* make sure it takes */
462 
463           return;
464 
465 
466 restore_access:
467      entry;                                                 /* to be called after set_access has been called */
468 
469           call sdw_util_$set_access (addr (dseg$ (segno)), access);
470                                                             /* restore old access */
471           call privileged_mode_ut$cam_both;                 /* make sure that takes */
472 
473           return;
474 
475 
476      end set_access;
477 
478 
479 GET_STANDARD_POINTERS:
480      procedure;
481 
482           fvp = addr (fault_vector$);
483           ignore_ptr = codeptr (wired_fim$ignore);
484           ignore_d_ptr = addr (prds$ignore_data);
485 
486 /* initialize SCU and TRA pointers for faults and interrupts */
487 
488           primary_trap = codeptr (fim$primary_fault_entry);
489           primary_scup = addr (pds$fim_data.scu);
490           signal_trap = codeptr (fim$signal_entry);
491           signal_scup = addr (pds$signal_data.scu);
492           onc_trap = codeptr (fim$onc_start_shut_entry);
493           onc_scup = primary_scup;
494           unexp_trap = codeptr (wired_fim$unexp_fault);
495           unexp_scup = addr (prds$sys_trouble_data.scu);
496      end;
497 
498 %page;
499 %include cmp;
500 %include fault_vector;
501 %include mc;
502 %include scs;
503 %include static_handlers;
504 %include stack_header;
505 %include access_mode_values;
506      end initialize_faults;