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 " SIGNALLER - Ring 0 Module to Perform Signalling Operation.
13 " Modification record: Date and Reason
14 " 83-12-12 by BIM to unmask before -2 terminates
15 " 7/81 by J. Bongiovanni for prev stack frame bug
16 " 8/80 by J. A. Bush for DPS8/70M
17 " 5/79 by M. Grady to implement stack 0 sharing.
18 " 10/78 by B. Greenberg to set support bit in frame.
19 " 10/75 by R. Bratt to signal on primary stack if prr ^= sp.ring_no
20 " 7/75 by B. Greenberg, to limit MC saving
21 " 3/75 by S. Webber to use new safe RCU conventions
22 " 2/74 by Steve Webber to trace signallings in pds trace data
23 " 10/73 by Steve Webber to separate out restart_fault code into different segment
24 " 9/73 by M. Weaver to move fim_frame_flag and fill in entry ptr
25 " 29 Aug 72 by R F Mabee to remove numerous followon conversion bugs.
26 " 8/8/72 by Steve Webber to fix the 4 signaller bugs.
27 " 6/26/72 by Bill Silver for 645F.
28
29
30 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
31 "
32 " SIGNALLER -- This program must by called transferred to in ring
33 " 0 when a fault or condition is to be signalled. It
34 " expects the machine conditions to be in pds$signal_data
35 " and the condition name to be in pds$condition_name.
36 "
37 " A dummy signaller stack frame is created on the stack
38 " being signalled on and the machine conditions and name
39 " are copied into this frame. The signal_ procedure defined
40 " by the signal_ptr in the stack header of the stack being
41 " signalled on is then called.
42 "
43 " The procedure shares the stack frame with "restart_fault"
44 " and hence any changes to stack variables in either program
45 " must be reflected in the other.
46 "
47 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
48
49
50 name signaller
51
52 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+>
53
54
55
56
57
58 link signaller_link,<*text>|0
59 link restart_fault_link,restart_fault$
60 link pds_link,pds$
61
62
63
64 include signaller_stack
65 include mc
66 include apte
67 include stack_header
68 include stack_frame
69 " ^L
70 entry signaller
71 entry no_save
72
73 no_save: "entry to signal illegal_return data
74 tsplb page_fault$trace_signaller
75 eax7 2 no save, but leave scux in fim_temp.
76 tra merge
77
78 signaller:
79 tsplb page_fault$trace_signaller
80 eax7 0 set to save mc
81 merge: epaq *
82 lprplp sb|stack_header.lot_ptr,*au
83 eppbp pds$signal_data bp -> m.c. data in PDS.
84
85 " Now we must unmask to open level. All interrupts are
86 " allowed after we signal. We unmask here so that the
87 " following termination happens in an unmasked environment.
88
89 ldaq scs$open_level open up mask
90 lxl1 prds$processor_tag CPU tag in X1
91 lprpab scs$mask_ptr,1 get pointer for masking
92 xec scs$set_mask,1
93
94 " Terminate process if fault occurred during signalling.
95
96 ldx0 bp|mc.scu.ppr.psr_word Pick up PPR.PRR and PPR.PSR
97 anx0 scu.ppr.psr_mask,du from m.c. and zero PPR.PRR.
98 cmpx0 lp|signaller_link were we in signaller?
99 tze term4,*
100 cmpx0 lp|restart_fault_link what about restart_fault?
101 tze term4,* if so, bye-bye!
102
103
104 " Now we must save the stack pointer we are currently using. This
105 " will be used to reset the stack end pointer if we are signalling
106 " on a different stack.
107
108 sprisp bp|mc.mask
109 eppsp bp|mc.prs+6*2,* set sp to stack to signal on
110 eppap sp|0 save for prev frame pointer
111 lda bp|mc.scu.indicators_word see if we were in bar mode
112 cana scu.ir.bm,dl ..
113 tze bar_mode
114 lda bp|mc.prs+6*2 get ring of sp
115 als 18
116 era bp|mc.scu.ppr.psr_word compare to prr
117 cana =o700000,du
118 tze set_sb equal - signal on sp
119 lda bp|mc.scu.ppr.psr_word
120 arl 36-3
121 als 1
122 epbpsp pds$stacks,al*
123 eppsp sp|stack_header.stack_end_ptr,*
124 tra set_sb not equal - signal on pds$stacks prr
125 bar_mode: epbpsb sp|0 make sb point to base of stack
126 lda sb|stack_header.bar_mode_sp+1 get word offset of saved sp
127 " saved before entering BAR mode
128 eawpsp 0,au use this value since BAR mode pgm could clobber ADR6
129 eppap sp|0 and save as prev pointer
130 " which is also word offset of sp
131 ldaq sp|stack_frame.next_sp get next sp from current frame
132 cmpaq sb|stack_header.stack_end_ptr better be equal to stack end ptr
133 tnz term8,* it isn't...we can't trust sp so wipe the guy out
134 set_sb:
135
136 epbpsb sp|0 Make sb point to base of validated stack segment.
137 " Get offset of next frame.
138 ldq fim_frame_flag,dl turn ON fim frame flag
139 orsq sp|stack_frame.flag_word
140 ldq sb|stack_header.stack_end_ptr+1
141
142 " Add default frame size to frame offset in case fault occurred when adding a new frame
143 " but before all pointers were set - for example, in the middle of a "push".
144
145 adlq stack_frame.min_length,du
146 orq fim_frame_flag,dl OR in old fim frame flag bit.
147 " Update the pointer in the old frame.
148 stq sp|stack_frame.next_sp+1
149
150
151 " Setup "sp" to point to the new frame. We can't trust the segment number in
152 " the stack_header.stack_end_ptr nor in the next_sp pointer in the previous
153 " frame. We will use the validated "sb" as the segment number. The offset
154 " we trust.
155
156 eppsp sb|0,qu Offset still in QU.
157 " Now "sp" points to the new frame.
158
159 spriap sp|stack_frame.prev_sp Store ptr to old frame.
160 ldx0 push get size of signaller frame
161 eppap sp|0,0 get pointer to end of frame
162 spriap sp|stack_frame.next_sp Store ptr to next frame.
163 spriap sb|stack_header.stack_end_ptr Update header.
164 sprilp sp|stack_frame.lp_ptr
165 lda 4,du fill in translator ID
166 sta sp|stack_frame.translator_id
167 lda stack_frame.support_bit,dl
168 orsa sp|stack_frame.prev_sp turn on support bit.
169
170 eppap return_to_ring_0_$return_to_ring_0_
171 spriap sp|stack_frame.entry_ptr
172 epaq sp|0 now check to see if we're abandoning a stack
173 eax0 0,au segno of new stack in x0
174 cmpx0 bp|mc.mask same as old stack ?
175 tze old_stack we're still using this stack, don't reset
176 epbplb bp|mc.mask,* get pointer to base of old stack
177 ldaq lb|stack_header.stack_begin_ptr reset end pointer to begin pointer
178 staq lb|stack_header.stack_end_ptr
179 old_stack:
180 "
181 " Save the machine conditions in the pds. We will only save the SCU data
182 " and the pointers and lengths.
183 "
184 tsx1 copy_and_save_mc save mc in pds and copy into stack frame
185
186 eppap mach_cond get pointer to machine conditions
187 spriap mc_ptr save mc pointer in stack
188
189 ldq 0,dl set up for no hregs zero length
190 szn pds$hregs_saved do history regs exist?
191 tze *+2 xfer if no, pad hreg blk with 0's
192 ldq 128*4,dl yes, set length
193 mlr prrl,pr,fill0
194 desc9a bp|48,ql
195 desc9a history_registers,128*4
196
197 " Copy the condition name into stack frame.
198
199 eppbp pds$condition_name bp -> condition name in wired storage
200 eppap signal_string ap -> condition name in stack
201 mlr pr,pr
202 desc9a bp|0,32
203 desc9a ap|0,32
204 " ^L
205 " Make descriptors for call to signal.
206
207 lda signal_string pick up first word of string
208 arl 27 right-justify character count
209 ora char_desc_mask,du Insert bits for desc_mask
210 sta string_descriptor save the descriptor
211
212 lda ptr_desc_mask,du Make a descriptor for pointer.
213 sta ptr_descriptor save the descriptor
214
215 " Now set up the cleanup handler to discard the MC if necessary
216 "
217 tsx1 set_up_cleanup set up cleanup condition handler
218
219 " Create argument list for call to signal.
220
221 ldaq arg_list_header Setup argument list header.
222 staq arglist
223
224 eppap null,* ap contains null pointer
225 spriap null_ptr set up null pointer for call
226
227 eppap signal_string set up argument list
228 spriap arglist+2
229 lda 9*512,dl don't forget the bit offset
230 orsa arglist+3 for character string
231
232 eppap mc_ptr call signal_ condition_name mc_ptr mc mc
233 eppbp null_ptr ap -> m.c. pointer, bp -> null pointer.
234 spriap arglist+4 set arguments
235
236 eppap null_ptr
237 spriap arglist+6
238
239 spribp arglist+8
240
241 eppap string_descriptor set pointers to descriptors
242 spriap arglist+10
243
244 eppap ptr_descriptor
245 spriap arglist+12
246 spriap arglist+14
247 spriap arglist+16
248
249 eppbb sb|stack_header.signal_ptr,* we want to call signal_
250 eppap arglist set up ap for call
251 join:
252 eppbp return_to_ring_0_$return_to_ring_0_ get pointer which gets us to ring 0
253 spribp sp|stack_frame.return_ptr save in normal return loc
254 spribp sp|stack_frame.entry_ptr for debuggers
255
256 "
257 " Before calling signal_, we return to system code in return_to_ring_0_ which
258 " will execute in the user ring so that any pending ring alarm faults can be handled.
259 " This is done by first returning to return_to_ring_0_ which really returns to ring N
260 " which will then call signal_.
261 "
262 eppab pds$signal_data+mc.mask return from this place
263 sprisb ab|0 save this for ring number only
264 epaq return_to_ring_0_$return_to_ring_n
265 stca ab|0,70
266 stcq ab|1,70
267 rtcd ab|0 return to return_to_ring_n
268 "^L
269 " for_linker
270 "
271 " This entry is used by the linker to complete the work of calling the trap_caller
272 " for a trap-before-link or trap-at-first-reference.
273 "
274 " Call is: call signaller$for_linker stack_ptr entry_ptr
275 "
276 entry for_linker
277 for_linker:
278 epbplb sp|0 save pointer to stack we're on
279 eppbp lb|stack_header.stack_begin_ptr,* reset stack
280 spribp lb|stack_header.stack_end_ptr ..
281
282 eppbb ap|2,* get target stack pointer
283 eppsp bb|0,* into sp register
284 epbpsb sp|0 generate pointer to stack base
285
286 eppbb ap|4,* get entry to call
287 eppbb bb|0,* ,,
288
289 eax7 0 hopefully save machine conditions
290 eppbp pds$signal_data get ptr to place to stash data
291 tsx1 copy_and_save_mc do the work
292 tsx1 set_up_cleanup and set up a cleanup handler in outer ring
293
294 eppap sp|stack_frame.operator_ptr,* left here by trap_caller_caller_
295 tra join
296
297 "^L
298 " Subroutines
299 "
300
301 copy_and_save_mc:
302 ldx0 bp|mc.scu.ppr.psr_word what is ring?
303 canx0 =o700000,du pds ?
304 tnz *+2 if not, don't inhibit saving.
305 eax7 1 Was the PDS, can't restart, so don't save.
306
307 eax0 0 set for 0 SCU index if not saved.
308 eax7 0,7 Is state of mc rotten already?
309 tnz dont_save yes, don't save MC.
310
311 eppap pds$mc_save_ptr,* get place to put data
312 eax0 ap|16 where will that put us?
313 cmpx0 pds$mc_save_limit too many?
314 tpl too_many signal new problem if too many
315
316 stx0 pds$mc_save_ptr save new next ptr
317
318 mlr pr,pr
319 desc9a bp|mc.scu,8*4
320 desc9a ap|0,8*4
321 mlr pr,pr
322 desc9a bp|mc.eis_info,8*4
323 desc9a ap|8,8*4
324 aos pds$unique_scu_index
325 lxl0 pds$unique_scu_index
326 stx0 ap|scu.tsr_stat_word save unique index in ring 0 copy
327
328 " Copy the machine conditions into stack frame.
329
330 dont_save:
331 mlr pr,pr
332 desc9a bp|0,48*4
333 desc9a mach_cond,48*4
334 cmpx7 2,du is this illegal return signal?
335 tze *+2 if so, leave original scux
336 stx0 mach_cond+mc.fim_temp save the unique index
337 tra 0,1
338
339 set_up_cleanup:
340
341 " Generate condition unit for cleanup
342
343 lda =o100,dl set condition flag
344 orsa sp|stack_frame.prev_sp
345 equ on_unit_offset,on_unit
346 eax0 on_unit_offset get offset of on-unit structure in new stack frame
347 stx0 sp|stack_frame.on_unit_rel_ptrs
348
349 eppbp on_unit+8 get pointer to place to store string
350 spribp on_unit save it in the real on unit
351 lda 7,dl set length of the name
352 sta on_unit+4
353 stz on_unit+5 clear flags word
354 eppbp <restart_fault>|1
355 spribp on_unit+2
356
357 mlr ,pr,fill040 move the string into the stack
358 desc9a cname,7
359 desc9a on_unit+8,32
360
361 tra 0,1
362
363 "
364 " User has willingly prevented mc cleanup. Flag the mc identifiably,
365 " and don't save them.
366 "
367 too_many:
368 eax0 -1 make identifiable flag in mc
369 tra dont_save merge
370 "^L
371 " storage and constants
372
373 even
374 term4: its -2,-4
375 term8: its -2,-8
376 null: its -1,1
377
378 arg_list_header:
379 vfd 18/8,18/4
380 vfd 18/8,18/0
381
382 bool ptr_desc_mask,464000
383 bool char_desc_mask,524000
384
385 push: push
386 cname: aci "cleanup"
387
388 end