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,fill0
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