1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 ring_alarm:
39 procedure;
40
41
42 dcl a_mcp ptr;
43
44 dcl target_ring fixed bin (3);
45 dcl i fixed bin;
46 dcl mask fixed bin (71);
47 dcl setting fixed bin (4);
48
49 dcl pds$admin_privileges bit (36) aligned ext;
50 dcl pds$alarm_ring fixed bin (3) ext;
51 dcl pds$apt_ptr ptr ext;
52 dcl pds$connect_pending bit (1) aligned ext;
53
54 dcl pds$ips_mask (0:7) bit (36) aligned ext;
55
56 dcl pds$ring_alarm_val (0:7) fixed bin (3) ext;
57
58 dcl pds$process_group_id char (32) ext static;
59 dcl pds$validation_level fixed bin (3) ext;
60
61 dcl scs$sys_level fixed bin (71) ext;
62
63 dcl wired_hardcore_data$trap_invalid_masked
64 bit (1) aligned ext;
65 dcl severity fixed bin;
66 dcl (stop_flag, pre_empt_flag, ips_flag, check_ips, validation_flag, privileges_flag)
67 bit (1) aligned init ("0"b);
68
69
70 dcl fs_get$path_name entry (ptr, char (*), fixed bin (21), char (*), fixed bin (35));
71 dcl pmut$lrar entry (fixed bin (3));
72 dcl pmut$read_mask entry (fixed bin (71));
73 dcl pxss$force_stop entry;
74 dcl set_privileges$admin_ring_alarm
75 entry;
76 dcl syserr entry options (variable);
77 dcl syserr$binary entry options (variable);
78 dcl (addr, codeptr, fixed, max, min, mod)
79 builtin;
80
81 declare active_hardcore_data$validation_fix_severity
82 fixed bin external;
83 dcl any_other condition;
84 ^L
85
86
87
88 fault:
89 entry (a_mcp);
90 mcp = a_mcp;
91
92 scup = addr (mcp -> mc.scu (0));
93
94
95
96 target_ring = fixed (scup -> scu.tpr.trr, 3);
97
98 call ANALYZE_RING_ALARM$$fault (target_ring);
99
100
101 pds$connect_pending = pds$connect_pending | stop_flag | pre_empt_flag | ips_flag;
102
103
104
105
106
107 ^L
108
109
110
111 reset:
112 entry;
113
114 Reset_common:
115 pds$alarm_ring = 0;
116 setting = 8;
117
118 aptep = pds$apt_ptr;
119 check_ips = ^ips_flag & (apte.ips_message ^= ""b);
120
121
122 do i = 0 to 7 while (setting = 8);
123
124 if check_ips & ((apte.ips_message & pds$ips_mask (i)) ^= ""b)
125
126 then setting = i;
127 else if pds$ring_alarm_val (i) ^= 0
128 & (i < 7)
129 then setting = i + 1;
130 end;
131
132 if (pds$admin_privileges ^= ""b)
133 then setting = min (2, setting);
134
135
136
137 if (apte.pre_empt_pending & ^pre_empt_flag)
138 then setting = 1;
139 else if (apte.stop_pending & ^stop_flag)
140 then setting = 1;
141
142 debug
143
144 if wired_hardcore_data$trap_invalid_masked
145 then do;
146 call pmut$read_mask (mask);
147 if mask = scs$sys_level
148 then setting = 1;
149 end;
150
151
152
153
154 setting = mod (setting, 8);
155 call set (fixed (setting, 3));
156
157 return;
158
159 reset_no_pre_empt:
160 entry;
161
162 pre_empt_flag = "1"b;
163 go to Reset_common;
164 ^L
165
166
167
168 set:
169 entry (ringno);
170
171 dcl ringno fixed bin (3);
172
173
174 setting = pds$alarm_ring;
175 if setting = 0
176 then setting = 8;
177 setting = min (setting, ringno);
178 pds$alarm_ring = mod (setting, 8);
179 call pmut$lrar (pds$alarm_ring);
180
181 return;
182 ^L
183
184
185
186
187 poll:
188 entry returns (bit (1) aligned);
189
190 declare callerframe pointer;
191 declare outer_ring_ptr pointer;
192 declare its_ptr pointer;
193
194 if wired_hardcore_data$trap_invalid_masked
195 then do;
196 call pmut$read_mask (mask);
197 if mask = scs$sys_level
198 then call syserr (CRASH, "ring_alarm$poll: processor is masked at exit from ring 0.");
199 end;
200
201
202 callerframe = stackframeptr () -> stack_frame.prev_sp -> stack_frame.prev_sp;
203
204
205 outer_ring_ptr = callerframe -> stack_frame.return_ptr;
206
207
208 its_ptr = addr (outer_ring_ptr);
209 target_ring = its_ptr -> its_unsigned.ringno;
210
211 call ANALYZE_RING_ALARM (target_ring);
212
213 if ^pre_empt_flag & ^stop_flag
214 then do;
215
216
217
218 call reset;
219 return ("0"b);
220 end;
221
222
223 if stop_flag
224 then call pxss$force_stop;
225
226
227
228 if pre_empt_flag
229 then do;
230 call reset_no_pre_empt;
231 return ("1"b);
232 end;
233
234 call syserr (CRASH, "ring_alarm$poll: Mysterious ring alarm.");
235 ^L
236
237
238
239
240
241 ANALYZE_RING_ALARM:
242 procedure (Target_ring);
243
244 declare Target_ring fixed bin (3);
245 declare fault bit (1);
246 declare old_validation_level fixed bin (3);
247
248 fault = "0"b;
249 go to Join;
250
251 ANALYZE_RING_ALARM$$fault:
252 entry (Target_ring);
253
254 fault = "1"b;
255
256 Join:
257 old_validation_level = pds$validation_level;
258
259 do i = 0 to Target_ring - 1;
260 if pds$ring_alarm_val (i) ^= 0
261 then do;
262 pds$validation_level = pds$ring_alarm_val (i);
263 pds$ring_alarm_val (i) = 0;
264 end;
265 end;
266
267 pds$validation_level = max (Target_ring, pds$validation_level);
268
269
270
271 if old_validation_level ^= pds$validation_level & active_hardcore_data$validation_fix_severity >= 0
272 then do;
273 call syserr (active_hardcore_data$validation_fix_severity,
274 "ring_alarm: Fixed validation level^[ on fault^] from ^d to ^d.", fault, old_validation_level,
275 pds$validation_level);
276 validation_flag = "1"b;
277 end;
278
279 if pds$admin_privileges ^= ""b & Target_ring > 1
280 then do;
281 if active_hardcore_data$validation_fix_severity = -1
282 then severity = JUST_LOG;
283 else severity = active_hardcore_data$validation_fix_severity;
284 call syserr (severity, "ring_alarm: Reset admin privileges^[ on fault^].", fault);
285 call set_privileges$admin_ring_alarm;
286 privileges_flag = "1"b;
287 end;
288
289
290
291 aptep = pds$apt_ptr;
292 if apte.stop_pending
293 then stop_flag = "1"b;
294
295
296
297 else if apte.pre_empt_pending
298 then pre_empt_flag = "1"b;
299
300
301
302 else if apte.ips_message & pds$ips_mask (Target_ring)
303 then ips_flag = "1"b;
304
305 return;
306
307 end ANALYZE_RING_ALARM;
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371 %page; %include mc;
372 %page; %include apte;
373 %page; %include syserr_constants;
374 %page; %include its;
375 %page; %include signaller_stack;
376 %page; %include stack_frame;
377 %page; %include stack_header;
378 %page; %include syserr_binary_def;
379 end ring_alarm;