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 "         restart_fault
 13 "
 14 "         Original coding (extract of code from signaller) 10/73 SHW.
 15 "         Last Modified: (date and reason):
 16 "
 17 " 3/85    by E.D. Schroth (UNCA) to clear all overflow fault related indicators
 18 " 3/82    by J. Bongiovanni to allow user-ring restart if SCU data unchanged, ^IPR
 19 " 11/81   by E. N. Kittlitz for cleanup null mc_ptr check.
 20 " 5/79    by M. Grady for stack 0 sharing.
 21 " 11/76   by B. Greenberg for EIS IPR restarts.
 22 " 10/75   by R. Bratt to unconditionally allow restarts from ring zero
 23 " 8/75    by B. Greenberg to fix bugs restarting ill_rtn mc's
 24 " 3/75    by S. Webber to implement more secure restarts
 25 " 8/1/74  by S. Webber to fix security bug that didn't check TRR against signalling ring.
 26 " 2/74    by Steve Webber to trace restarts of faults in pds trace data
 27 "
 28 "
 29 "         This program is the one called by "return_to_ring_0_" when
 30 "         the latter is returned to in the user ring to restart
 31 "         a signalled fault (or quit, etc). It can only be transferred
 32 "         to at location 0 as the entry bound is set to 1 by
 33 "         init_hardcore_gates.
 34 "
 35 "         The program must validate the machine conditions and if they appear to
 36 "         be valid, it will restart them.
 37 
 38 
 39           name      restart_fault
 40 
 41           inhibit   on                  <+><+><+><+><+><+><+><+><+><+><+><+>
 42 
 43 
 44           segdef    lp,scu
 45           segdef    .my_lp,.tv_end
 46 
 47 "^L
 48           include   signaller_stack
 49           include   mc
 50           include   apte
 51           include   stack_header
 52           include   stack_frame
 53           include   fault_vector
 54 
 55           equ       if_rfi_bits,scu.cu.if+scu.cu.rfi
 56           equ       allowed_cu_stat_changes,-1-if_rfi_bits
 57 " ^L
 58 "         There are two entries to this program. The first (location 0) is
 59 "         called to restart a fault. The stack pointer points to the
 60 "         signaller frame containing the machine conditions to try to
 61 "         restart.
 62 "
 63 "         The second entry (location 1) is used by the signaller cleanup handler
 64 "         to discard the ring 0 copy of the set of machine conditions being
 65 "         "released" or "nonlocal goto'd" around.
 66 "
 67           tra       restart_entry
 68           tra       cleanup_entry
 69 
 70 restart_entry:
 71           epplp     lp,*                get our own linkage pointer
 72           tsplb     page_fault$trace_restart_fault
 73           epplp     lp,*
 74 
 75           epbpsb    sp|0                get a valid sb as well
 76           epaq      sp|0
 77           cana      -1,dl
 78           tze       restart_from_ring_zero
 79 
 80 
 81 " The three instructions at the end of signaller that return to the
 82 " point of the fault must be executed without taking a page fault. Since they
 83 " reload the machine condiditons we must place the machine conditions in
 84 " a safe wired-down place  -  the PDS.
 85 
 86           eppbp     pds$signal_data     bp -> wired-down m.c.
 87           eppap     mach_cond           ap -> m.c. in stack
 88           mlr       (pr),(pr)
 89           desc9a    ap|0,48*4           Copy whole shebang, including
 90           desc9a    bp|0,48*4           regs, fim_temp.
 91 "
 92 "         Now copy the prs, we must use epp-type instructions in order
 93 "         to preserve the validation...
 94 
 95           eax1      8*2
 96           epplb     ap|-2,1*            copy prs with epplb instructions
 97           sprilb    bp|-2,1
 98           eax1      -2,1
 99           tpnz      *-3
100 
101 "         Now copy the SCU data and pointers and lengths from the
102 "         safe store area in the pds (after validating SCU).
103 
104           ldx0      mach_cond+mc.fim_temp get unique code for search
105           tsx7      find_scu_data
106           tra       illegal_return      error, not found
107 
108 "         AP -> good stuff
109 "         BP -> stuff handed in.
110 
111 
112           stx0      bp|mc.scu.tsr_stat_word save so CMPC will work
113 
114 "         Check for SCU Data Unmodified. This is allowable unless the
115 "         MIF is ON and the fault is an IPR
116 
117           cmpc      (pr),(pr)
118           desc9a    ap|0,8*4
119           desc9a    bp|mc.scu,8*4
120 
121           tnz       check_mif           SCU Data Changed
122 
123           lda       ap|scu.indicators_word
124           cana      scu.ir.mif,dl       Is MIF ON
125           tze       mc_ok               No
126           lda       ap|scu.fault_data_word
127           ana       scu.fi_num_mask,dl
128           cmpa      2*FAULT_NO_IPR,dl   IPR
129           tnz       mc_ok               No
130           tra       illegal_return      Yes - don't allow
131 
132 check_mif:
133           lda       ap|scu.indicators_word
134           cana      scu.ir.mif,dl
135           tze       allow_more          SCU Data Changed, ^MIF in safe data
136 
137           ldq       if_rfi_bits,dl      SCU Data Changed, MIF in safe data
138           cnaq      bp|mc.scu.cu_stat_word
139           tze       allow_more          Only allow if both IF and RFI set
140           tra       illegal_return      Otherwise invalid
141 
142 "         make sure certain indicators not changed
143 
144 allow_more:
145           era       bp|mc.scu.indicators_word
146           cana      scu.ir.parm+scu.ir.abs,dl
147           tnz       illegal_return
148 
149 "         Those indicators are OK. Check the first 4 words. No change allowed.
150 
151           cmpc      (pr),(pr)
152           desc9a    ap|0,4*4
153           desc9a    bp|mc.scu,4*4
154           tnz       illegal_return
155 
156 "         Check CU stat word.
157 
158           lda       ap|scu.cu_stat_word
159           era       bp|mc.scu.cu_stat_word
160           ana       allowed_cu_stat_changes,dl
161           tnz       illegal_return
162 
163 "         Now check legal changes to MIF bit.
164 
165           lda       if_rfi_bits,dl
166           cnaa      bp|mc.scu.cu_stat_word
167           tze       has_set_rfi_off_mif
168 
169 "         Guy hasn't set RFI/IF, better not have changed
170 "         MIF.
171 
172           lda       ap|scu.indicators_word
173           era       bp|mc.scu.indicators_word
174           cana      scu.ir.mif,dl
175           tnz       illegal_return
176           tra       mc_ok
177 
178 "         He did RFI/IF. Force MIF off.
179 
180 has_set_rfi_off_mif:
181           lda       scu.ir.mif,dl
182           orsa      bp|mc.scu.indicators_word
183           ersa      bp|mc.scu.indicators_word
184 
185 "         Machine conditions have been validated.  If original fault was an
186 "         overflow fault, then clear the indicators for fixedoverflow,
187 "         exponent overflow and underflow and truncation.
188 "         This is to ensure that the next overflow fault starts clean and is
189 "         not improperly dissected.
190 
191 mc_ok:
192           lda       ap|scu.fault_data_word        determine fault type
193           ana       scu.fi_num_mask,dl
194           cmpa      FAULT_NO_OFL*2,dl             was it overflow
195           tnz       copy_eis                      NO, do not clear indicators
196           lca       scu.ir.ovfl+scu.ir.eovf+scu.ir.eufl+scu.ir.tru+1,dl indicators affected
197           ansa      bp|mc.scu.indicators_word     turn them OFF
198 "
199 "         Now that the machine conditions have been "validated" we can copy
200 "         the EIS stuff into signal_data for restarting
201 
202 copy_eis:
203           mlr       (pr),(pr)
204           desc9a    ap|8,8*4
205           desc9a    bp|mc.eis_info,8*4
206 
207           tsx7      pop_scu_data        discard SCU data
208 
209 
210 " Now abandon the current stack frame in the signalling ring.  This is like a
211 " special "pop" of our stack. We don't need our stack frame any more.
212 "
213 restart:  lda       sp|stack_frame.prev_sp+1 pick up word offset of prev frame
214           eppap     sb|0,au             generate pointer to prev frame
215           lda       ap|stack_frame.flag_word update the next frame pointer with flag
216           cana      fim_frame_flag,dl   see if flag is indeed ON
217           tze       term7,*             no, terminate the process
218           era       fim_frame_flag,dl   turn OFF fim frame flag
219           sta       ap|stack_frame.flag_word and save value in stack frame
220           lda       ap|stack_frame.next_sp+1 update next_sp for min_length more words
221           sbla      stack_frame.min_length,du ..
222           era       fim_frame_flag,dl   turn off old fim frame flag
223           sta       ap|stack_frame.next_sp+1
224           sta       sb|stack_header.stack_end_ptr+1
225           eppsp     ap|0                set stack pointer to frame being returned to
226 
227 
228 
229 "         Reset the ips mask if called for.
230 
231           ldq       bp|mc.scu.ppr.prr_word get ring number for index into pds$ips_mask
232           qrl       scu.ppr.prr_shift
233           lda       bp|mc.ips_temp      see if mask should be restored
234           cana      =o1,dl              by looking at the low order bit
235           tze       *+3                 no, just restore and RCU
236           era       =o1,dl              yes, turn off restore-mask bit
237           sta       pds$ips_mask,ql     and store it in the PDS
238 
239           eppap     pds$apt_ptr,*       see if any IPS interrupts are ready to go OFF
240           ana       ap|apte.ips_message ..
241           tze       no_ips
242           lda       1,dl                make sure users gets message
243           sta       pds$alarm_ring
244           lra       pds$alarm_ring
245 no_ips:
246 
247 " Restore machine conditions and exit.
248 
249           lda       bp|mc.scu.indicators_word
250           cana      scu.ir.mif,dl
251           tze       *+2                 Leave EIS alone if no MIF
252           lpl       bp|mc.eis_info      Restore pointers and length
253           lreg      bp|mc.regs          Restore registers
254           lpri      bp|mc.prs           and pointer registers.
255           rcu       scu,*               back to faulting location
256 
257 restart_from_ring_zero:
258           eppbp     mach_cond
259           tra       restart
260 " ^L
261 
262 " Arrive here if return to signaller was illegal.
263 
264 illegal_return:
265 "
266 "         Leave the bad SCU data in signal_data, for signaller to signal with.
267 "         User's problem to figure out why it's bad and fix it. Leave scux in
268 "         there, to cleanup if unwound, and restart when good.
269 
270 
271           "
272           " Do not pop scu data. Leave good copy for possible restart.
273           " signaller$no_save will not save bad copy.
274 
275 
276           eppsp     pds$stack_0_ptr,*
277           epbpsb    sp|0                so the entry operator of the signaller will
278 "                                       use the correct stack header.
279           eppap     pds$condition_name  ap -> PDS place for signal name
280           lda       ilrtn_name          get length of name
281           arl       27
282           adla      1,dl                for "acc" count character
283           mlr       (rl),(pr),fill(0)
284           desc9a    ilrtn_name,al
285           desc9a    ap|0,32
286           tra       signaller$no_save
287 " ^L
288 "         Subroutines for managing copies of SCU data
289 "
290 "         find_scu_data is called with x0 containing the unique index
291 "         to be searched for. x1 is left pointing to the entry found.
292 "
293 find_scu_data:
294           eppap     pds$mc_save_area,*  set ap to start of save region
295           ldx1      pds$mc_save_ptr     start looking at end of list
296           sbx1      pds$mc_save_area    get number of words currently allocated
297           tmoz      0,7                 none, error return
298 loop:     eax1      -16,1               go back to previous set
299           tmi       0,7                 no more, error return
300           cmpx0     ap|scu.tsr_stat_word,1 check this set of SCU data
301           tnz       loop
302           eppap     ap|0,1              set ap to info of interest
303           tra       1,7                 take success exit
304 
305 "         pop_scu_data is called with ap pointing to the set of machine
306 "         conditions to be discarded.
307 "
308 pop_scu_data:
309           eppab     pds$mc_save_ptr,*
310           eppab     ab|-16              get pointer to last set of conditions
311           eax1      ap|16               see if this is top of stack
312           cmpx1     pds$mc_save_ptr     see if we are restarting the last set
313           tze       last_set            yes, pop stack
314           mlr       (pr),(pr)           else move last set to area just restarted from
315           desc9a    ab|0,16*4           to condense stack
316           desc9a    ap|0,16*4
317 last_set:
318           eax1      ab|0                set x1 to location just vacated
319           stx1      pds$mc_save_ptr     save next mc here
320           tra       0,7
321 "^L
322 "
323 "         This entry discards the machine conditions associated with a signaller frame
324 "         being released around.
325 
326 cleanup_entry:
327 
328 "         This entry is called by the signal_ procedure as a result of
329 "         finding a cleanup condition. The first argument is the name
330 "         "cleanup". This entry must fetch the display pointer from the
331 "         argument list in order to find the signaller stack frame.
332 "         It must then go to the next stack frame and examine the argument
333 "         list pointer found there. The second argument in _^Ht_^Hh_^Hi_^Hs
334 "         argument list is a pointer to the machine conditions of interest.
335 "
336           epplp     lp,*                get own linkage pointer
337           lda       ap|0                check for special bit
338           cana      =8,dl               indicating display pointer present
339           tze       short               if not there, we're out of luck
340           eppap     ap|2,au*            get display pointer (return_to_ring_0_ frame)
341           eppap     ap|stack_frame.next_sp,* get next frame pointer
342           eppap     ap|stack_frame.arg_ptr,* get argument list pointer
343           eppap     ap|4,*              mc_ptr is second argument
344           eppap     ap|0,*              it is a pointer...
345           epaq      ap|0                now look at the segment number
346           ana       =o077777,du         just the segno
347           cmpa      =o077777,du         is it null?
348           tze       short               yes - nothing can be done
349 
350           ldx0      ap|mc.fim_temp      fetch unique index from machine conditions
351           tsx7      find_scu_data
352           tra       short               IC+1 -> didn't find scu data
353           tsx7      pop_scu_data        IC+2 -> ah, found them. now eliminate themx
354 short:    short_return
355 "^L
356 " The following items must be filled in at
357 " system initialization time.
358 
359 
360           even
361 .my_lp:
362 lp:       its       -1,1                lp value for restart_fault
363 scu:      its       -1,1                pointer to pds$signal_data+16
364 
365 " The following item is used by init_hardcore gates to set
366 " the call limiter field for this procedure's SDW.
367 
368 .tv_end:  vfd       14/2
369 term7:
370           its       -2,-7
371 ilrtn_name:
372           acc       "illegal_return"
373 
374 
375 
376 
377 
378 
379           end