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 " HISTORY COMMENTS:
 13 "  1) change(87-09-03,GDixon), approve(87-09-10,MECR0006),
 14 "     audit(87-09-30,Farley), install(87-09-10,MR12.1-1104):
 15 "      A) Change $reset_ips_mask to only reset the mask if the control bit
 16 "         is on in the incoming mask.  Otherwise, it will only return the
 17 "         current mask value.
 18 "  2) change(87-10-07,GDixon), approve(87-10-07,MCR7770),
 19 "     audit(87-11-02,Farley), install(87-11-30,MR12.2-1004):
 20 "      A) Formally install changes covered by MECR0006 (change 1 above).
 21 "                                                      END HISTORY COMMENTS
 22 
 23 " Name:  ips_
 24 "
 25 "      The procedure "ips_" controls the enabling and disabling of
 26 " interprocess signal (IPS) interrupts.  Each ring of each process
 27 " has an IPS mask and an automatic IPS mask stored in the "pds".
 28 " Individual bits of the mask words correspond to specific IPS
 29 " interrupts.  The correspondence is defined by the procedure
 30 " "create_ips_mask_".  The following "ips_" entries inspect or
 31 " modify the IPS mask or the automatic IPS mask of the calling
 32 " process's current validation level.  Entries that change a mask
 33 " return the former value of the mask.  The entries are all
 34 " accessible via the hardcore gate "hcs_".
 35 "
 36 "      The last (thirty-sixth) bit of an IPS mask does not
 37 " correspond to an interrupt, but is instead a control bit.  The
 38 " control bit of each IPS mask and each automatic IPS mask stored
 39 " in the "pds" is always zero.  On mask values input to procedure
 40 " "ips_", the control bit is ignored.  On masks returned from
 41 " "ips_", the control bit is set to either "0"b or "1"b, as
 42 " specified in the individual entry descriptions below, to notify
 43 " the user that the requested action has been performed.  No
 44 " process interrupts can occur in the time interval between the
 45 " requested mask modification and the return of the old mask and
 46 " control bit.  Hence, each call on an "ips_" entry behaves as an
 47 " atomic operation.
 48 "
 49 "
 50 "
 51 " Entry:  ips_$get_ips_mask
 52 "
 53 "      This entry returns the value of the current IPS mask without
 54 " modifying it.  The control bit is returned as "0"b.
 55 "
 56 " Usage:
 57 "
 58 " dcl ips_$get_ips_mask entry(bit(36)aligned);
 59 "
 60 " call ips_$get_ips_mask(oldmask);
 61 "
 62 " 1) oldmask          is the current value of the IPS mask, with a
 63 "                     control bit of "0"b (output).
 64 "
 65 "
 66 "
 67 " Entry:  ips_$set_ips_mask
 68 "
 69 "      This entry replaces the entire IPS mask with a supplied
 70 " value and returns the previous value of the mask with a control
 71 " bit of "1"b.
 72 "
 73 " Usage:
 74 "
 75 " dcl ips_$set_ips_mask entry(bit(36)aligned,bit(36)aligned);
 76 "
 77 " call ips_$set_ips_mask(mask,oldmask);
 78 "
 79 " 1) mask             is the new value to replace the IPS mask
 80 "                     (input).
 81 "
 82 " 2) oldmask          is the former value of the IPS mask, with a
 83 "                     control bit of "1"b (output).
 84 "
 85 "
 86 "
 87 " Entry:  ips_$reset_ips_mask
 88 "
 89 "      This entry is exactly the same as "ips_$set_ips_mask" except
 90 " that the control bit in the returned former mask is "0"b.  These
 91 " two entries can be used to bracket sections of critical code
 92 " during which interrupts must be masked.  The control bit then
 93 " serves as rigorous identification of whether control is in a
 94 " critical section.
 95 "
 96 " Usage:
 97 "
 98 " dcl ips_$reset_ips_mask entry(bit(36)aligned,bit(36)aligned);
 99 "
100 " call ips_$reset_ips_mask(mask,oldmask);
101 "
102 " 1) mask             is the new value to replace the IPS mask
103 "                     (input).
104 "
105 " 2) oldmask          is the former value of the IPS mask, with a
106 "                     control bit of "0"b (output).
107 "
108 "
109 "
110 " Entry:  ips_$unmask_ips
111 "
112 "      This entry disables specified IPS interrupts.  Bits in the
113 " supplied mask value cause corresponding bits of the IPS mask to
114 " be reset.  The former value of the IPS mask is returned with a
115 " control bit of "1"b.  Warning: for historical reasons, this entry
116 " is misnamed (it masks rather than unmasks).
117 "
118 " Usage:
119 "
120 " dcl ips_$unmask_ips entry(bit(36)aligned,bit(36)aligned);
121 "
122 " call ips_$unmask_ips(mask,oldmask);
123 "
124 " 1) mask             for each bit on in this word, the
125 "                     corresponding bit in the IPS mask is turned
126 "                     off--i.e., the corresponding IPS interrupt is
127 "                     disabled (input).
128 "
129 " 2) oldmask          is the former value of the IPS mask, with a
130 "                     control bit of "1"b (output).
131 "
132 "
133 "
134 " Entry:  ips_$mask_ips
135 "
136 "      This entry enables specified IPS interrupts.  Bits in the
137 " supplied mask value cause corresponding bits of the IPS mask to
138 " be set.  The former value of the IPS mask is returned with a
139 " control bit of "0"b.  Entry "ips_$unmask_ips" and this entry can
140 " be used to bracket sections of critical code during with certain
141 " interrupts must be masked.  The control bit then serves as
142 " rigorous identification of whether control is in a critical
143 " section.  Warning: for historical reasons, this entry is misnamed
144 " (it unmasks rather than masks).
145 "
146 " Usage:
147 "
148 " dcl ips_$mask_ips entry(bit(36)aligned,bit(36)aligned);
149 "
150 " call ips_$mask_ips(mask,oldmask);
151 "
152 " 1) mask             for each bit on in this word, the
153 "                     corresponding bit in the IPS mask is turned
154 "                     on--i.e., the corresponding IPS interrupt is
155 "                     enabled (input).
156 "
157 " 2) oldmask          is the former value of the IPS mask, with a
158 "                     control bit of "0"b (output).
159 "
160 "
161 "
162 " Entry:  ips_$set_automatic_ips_mask
163 "
164 "      This entry replaces the entire automatic IPS mask with a
165 " supplied value and returns the previous value of the mask with a
166 " control bit of "1"b.
167 "
168 " Usage:
169 "
170 " dcl ips_$set_automatic_ips_mask
171 " entry(bit(36)aligned,bit(36)aligned);
172 "
173 " call ips_$set_automatic_ips_mask(mask,oldmask);
174 "
175 " 1) mask             is the new value to replace the automatic IPS
176 "                     mask (input).
177 "
178 " 2) oldmask          is the former value of the automatic IPS
179 "                     mask, with a control bit of "1"b (output).
180 "
181 "
182 "
183 "
184 "         Modified August 1981 by J. Bongiovanni for IPS signals to take
185 "                   immediately when unmasked (or shortly thereafter)
186 "^L
187 
188           entry     get_ips_mask                  Inspect IPS mask without changing it.
189           entry     set_ips_mask                  Replace entire IPS mask.
190           entry     reset_ips_mask                Replace entire IPS mask.
191           entry     unmask_ips                    Disable specific IPS interrupts.
192           entry     mask_ips                      Enable specific IPS interrupts.
193           entry     set_automatic_ips_mask        Replace entire auto IPS mask.
194 "
195 "
196 "
197 " Entry:  ips_$get_ips_mask(oldmask)
198 "
199 get_ips_mask:
200           lxl7      pds$validation_level          Validation level to X7.
201           ldq       pds$ips_mask,7                Save old IPS mask in the Q.
202           anq       =o777777777776                Make sure control bit is 0.
203           stq       ap|2,*                        Pass it back to caller.
204           short_return                            Return to caller.
205 "
206 "
207 "
208 " Entry:  ips_$set_ips_mask(mask,oldmask)
209 "
210 set_ips_mask:
211           lxl7      pds$validation_level          Validation level to X7.
212           ldq       pds$ips_mask,7                Save old IPS mask in the Q.
213           lda       ap|2,*                        Caller's desired new mask.
214           ana       =o777777777776                Control bit must be off.
215           sta       pds$ips_mask,7                Set new IPS mask.
216 ret1:     orq       =o1,dl                        Set control bit 1 in old mask.
217           stq       ap|4,*                        Pass it back to caller.
218           tra       check_ips_pending             Make pending, unmasked IPS take
219 "                                                 And return to caller.
220 "
221 "
222 "
223 " Entry:  ips_$reset_ips_mask(mask,oldmask)
224 "
225 reset_ips_mask:
226           lxl7      pds$validation_level          Validation level to X7.
227           ldq       pds$ips_mask,7                Save old IPS mask in the Q.
228           lda       ap|2,*                        Caller's desired new mask.
229           cana      1,dl                          Check if control bit is on.
230           tze       ret0                          No, don't reset mask.
231           ana       =o777777777776                Control bit must be off.
232           sta       pds$ips_mask,7                Set new IPS mask.
233 ret0:     anq       =o777777777776                Set control bit 0 in old mask.
234           stq       ap|4,*                        Pass it back to caller.
235           tra       check_ips_pending             Make pending, unmasked IPS take
236 "                                                 And return to caller.
237 "
238 "
239 "
240 " Entry:  ips_$unmask_ips(mask,oldmask)
241 "
242 unmask_ips:
243           lxl7      pds$validation_level          Validation level to X7.
244           ldq       pds$ips_mask,7                Save old IPS mask in the Q.
245           lda       ap|2,*                        Get bits to be cleared.
246           era       =o777777777776                Change bits to zeros for logical AND.
247           ansa      pds$ips_mask,7                Clear selected bits of IPS mask.
248           tra       ret1                          Return old mask with control bit 1.
249 "
250 "
251 "
252 " Entry:  ips_$mask_ips(mask,oldmask)
253 "
254 mask_ips:
255           lxl7      pds$validation_level          Validation level to X7.
256           ldq       pds$ips_mask,7                Save old IPS mask in the Q.
257           lda       ap|2,*                        Get bits to be set.
258           ana       =o777777777776                Control bit must remain off.
259           orsa      pds$ips_mask,7                Set selected bits of IPS mask.
260           tra       ret0                          Return old mask with control bit 0.
261 "
262 "
263 "
264 " Entry:  ips_$set_automatic_ips_mask(mask,oldmask)
265 "
266 set_automatic_ips_mask:
267           lxl7      pds$validation_level          Validation level to X7.
268           ldq       pds$auto_mask,7               Save old auto IPS mask in the Q.
269           lda       ap|2,*                        Caller's desired new mask.
270           ana       =o777777777776                Control bit must be off.
271           sta       pds$auto_mask,7               Set new auto IPS mask.
272           tra       ret1                          Return old auto mask with control bit 1.
273 "
274 "
275 "^L
276 "
277 "         Internal procedure to check for pending IPS signals which are unmasked
278 "         as a result of this call.  If any are found, ring_alarm is called
279 "         to determine and set an appropriate value of the ring_alarm register
280 "         so that the recently unmasked IPS signal will take within a short
281 "         amount of time.
282 "
283 "         On entry, x7 = current validation level
284 "
285 "         This routine will exit to the caller of ips_
286 "
287 
288 check_ips_pending:
289           eppbp     pds$apt_ptr,*                 bp -> APTE for this process
290           lda       bp|apte.ips_message           Get pending IPS signals
291           ana       pds$ips_mask,7                Check for unmasked in ring of validation
292           tnz       set_ring_alarm                Pending IPS found
293           short_return                            None found -- return to caller
294 set_ring_alarm:
295           push                                  " For call out
296           call      ring_alarm$reset
297           return                                  Return to caller
298 "^L
299           include   apte
300 
301           end