1 /****^ ***********************************************************
2 * *
3 * Copyright, C Honeywell Bull Inc., 1987 *
4 * *
5 * Copyright, C Honeywell Information Systems Inc., 1982 *
6 * *
7 *********************************************************** */
8 /* format: style4,delnl,insnl,indattr,ifthen,dclind10 */
9 /* use: pl1_macro pc_abs.pl1.pmac -target l68 */
10 pc_abs:
11 procedure;
12
13 /* This procedure is responsible for adding and removing blocks of memory
14 and for abs-wiring memory for I/O segments.
15
16 The original pc_abs was written by Roger R. Schell in September 1970.
17 Rewritten 6/3/74 by Bernard S. Greenberg for evict_page and page$pwait.
18 Abs-wire functions removed 6/3/74 by B. Greenberg for I/O Buffer manager.
19 Totally rewritten for new cme protocols, no remove list, and 75% code reduction, 03/12/75, BSG.
20 Modified to allow evict_page to delete, for automatic parity deletion, BSG, 05/11/78.
21 Modified to handle case when pages to be deleted are already gone, Chris Jones, 8/84
22 Modified 1984-10-26 BIM to pay attention to the first argument to
23 wire/unwire.
24 Modified 1984-12-07, Keith Loepere, to not avoid abs wiring in low 256K.
25 */
26
27
28 /****^ HISTORY COMMENTS:
29 1) change86-10-07Farley, approve86-11-20MECR0002,
30 audit86-11-19Fawcett, install86-11-20MR12.0-1222:
31 Added three checks to the unwire_abs entry. First verify that the Astep
32 parameter is non-null. Second verify that the page table word does really
33 define a wired/in-core page. Third verify that the CME is really abs wired.
34 Crash if any of these are incorrect.
35 2) change86-12-19Farley, approve86-12-19MCR7587,
36 audit86-12-19Fawcett, install87-01-05MR12.0-1253:
37 Formal installation to close out above MECR0002.
38 END HISTORY COMMENTS */
39
40
41 dcl Code fixed bin 35 parameter;
42 dcl Absaddr fixed bin 26 parameter;
43 dcl Fpage fixed bin 9 parameter; /* zero based */
44 dcl Npages fixed bin 9 parameter;
45 dcl Fframe fixed bin 16 parameter;
46 dcl Nframes fixed bin 16 parameter;
47 dcl Modulus fixed bin 16 parameter;
48 dcl Astep pointer parameter;
49
50 dcl astep ptr;
51 dcl ind aind fixed bin 35;
52 dcl fframe nframes frame modulus
53 fixed bin 16;
54 dcl fp np page fixed bin 9;
55 dcl frames 0:255 fixed bin 16;
56
57 dcl oldmask fixed bin 71 aligned;
58 dcl sptp ptr;
59
60 dcl based_word fixed bin 35 aligned based;
61
62 dcl page$evict entry ptr fixed bin 35;
63 dcl page$pwait entry fixed bin 35;
64 dcl page$wire_abs entry ptr fixed bin 35 ptr fixed bin 9;
65 dcl pmut$lock_ptl entry fixed bin 71 aligned ptr;
66 dcl pmut$unlock_ptl entry fixed bin 71 aligned ptr;
67 dcl syserr entry options variable;
68
69 dcl ALL_ONES fixed bin 35 static options constant init -1;
70 dcl CORE bit 4 static options constant init "8"b4;
71
72 dcl error_table_$out_of_main_memory
73 fixed bin 35 external static;
74 dcl sst$abs_wired_count fixed bin 35 external;
75 dcl sst$astsize fixed bin 17 external;
76 dcl sst$cmp ptr external;
77 dcl sst$first_core_block fixed bin 16 external;
78 dcl sst$last_core_block fixed bin 16 external;
79 dcl sst$nused fixed bin 35 external;
80 dcl sst$usedp bit 18 aligned external;
81 dcl sst$wusedp bit 18 aligned external;
82 dcl sst$wired fixed bin 35 external;
83 dcl sys_info$page_size fixed bin 17 external static;
84
85 dcl addr addrel binary max mod null ptr rel wordno
86 builtin;
87 ^L
88 remove_core:
89 entry Fframe Nframes Code;
90
91 Code = 0;
92 fframe = Fframe;
93 nframes = Nframes;
94
95 call lock; /* wire and lock */
96
97 do frame = 1 to nframes; /* make sure it is not in use */
98 if sst$cmp -> cma fframe + frame - 1.abs_w then do;
99 call unlock;
100 Code = 2; /* return error code */
101 return;
102 end;
103 end;
104
105 call remove_frames; /* get rid of them */
106
107 call unlock;
108 return;
109 %skip 3;
110 remove_core_mod:
111 entry Nframes Modulus Absaddr Code;
112
113 nframes = Nframes;
114 modulus = Modulus;
115 Absaddr = -1;
116 Code = 0;
117
118 call lock;
119 call find_frames;
120 call remove_frames;
121 call unlock;
122
123 Absaddr = fframe * sys_info$page_size;
124 return;
125 ^L
126 wire_abs_contig:
127 entry Astep Fpage Npages Code;
128
129 astep = Astep; /* Copy args before locking page table lock */
130 fp = Fpage;
131 np, nframes = Npages;
132 Code = 0;
133
134 call lock;
135
136 modulus = 1;
137 retry_contig:
138 call find_frames;
139
140 if fframe >= 256 then
141 goto noalloc; /* must keep I/O buffers low */
142 /* see iom_connect.alm for details. */
143
144 do frame = 0 to nframes - 1;
145 frames frame = fframe + frame;
146 end;
147
148 if ^abs_wire_frames then
149 goto retry_contig;
150
151 call unlock;
152
153 return;
154 ^L
155 wire_abs:
156 entry Astep Fpage Npages Code;
157
158 astep = Astep;
159 fp = Fpage;
160 np, nframes = Npages;
161 Code = 0;
162
163 call lock;
164
165 retry:
166 page = 0;
167 do fframe = max sst$first_core_block 256 to sst$last_core_block while page < np;
168 /* save low 256K for wire_abs_contig */
169 cmep = addr sst$cmp -> cma fframe;
170 if cmep -> based_word ^= ALL_ONES & ^cme.abs_w & ^cme.removing & cme.abs_usable
171 & cme.fp ^= ""b | cme.ptwp ^= ""b then do;
172 frames page = fframe;
173 page = page + 1;
174 end;
175 end;
176 if page < np then do;
177 noalloc:
178 call unlock;
179 Code = error_table_$out_of_main_memory;
180 return;
181 end;
182
183 if ^abs_wire_frames then
184 goto retry;
185
186 call unlock;
187 return;
188 ^L
189 unwire_abs:
190 entry Astep Fpage Npages;
191
192 astep = Astep;
193 fp = Fpage;
194 np = Npages;
195
196 if astep = null then do;
197 call syserr CRASH "pc_abs$unwire_abs: Called with NULL astep.";
198 return;
199 end;
200
201 do page = fp to fp + np - 1; /* unwire the pages */
202 ptp = addrel astep sst$astsize + page;
203 if ptw.add_type = CORE & ptw.wired then do;/* valid PTW */
204 frame = core_ptw.frame; /* find the core frame */
205
206 cmep = addr sst$cmp -> cma frame;
207 if ^cme.abs_w
208 then call syserr CRASH "pc_abs$unwire_abs: Attempt to unwire inconsistent CME at ^p." cmep;
209
210 /* reset wired & abs_w here */
211
212 ptw.phm = "1"b; /* in case the IOM modified it */
213 ptw.wired = "0"b; /* not wired any more */
214
215 cme.abs_w = "0"b;
216
217 sst$wired = sst$wired - 1;
218 sst$abs_wired_count = sst$abs_wired_count - 1;
219 end;
220 else call syserr CRASH "pc_abs$unwire_abs: Attempt to unwire inconsistent PTW at ^p." ptp;
221 end;
222
223 return;
224 ^L
225 find_frames:
226 procedure;
227
228 dcl j fixed bin 16;
229
230 do fframe = sst$first_core_block + mod -sst$first_core_block modulus by modulus to sst$last_core_block;
231 /* find a possible first page */
232 j = 0;
233 if mod fframe + nframes - 1 256 < nframes - 1 then
234 goto will_not_do; /* and we won't cross 256K boundary */
235 do j = 0 to nframes - 1; /* check each page */
236 cmep = addr sst$cmp -> cma fframe + j;
237 /* get ptr to cme */
238 if cmep -> based_word = ALL_ONES | cme.abs_w | cme.removing | ^cme.abs_usable
239 | cme.fp = ""b & cme.ptwp = ""b then
240 go to will_not_do; /* OS are just fine, as long as... */
241 end;
242
243 return;
244
245 will_not_do:
246 fframe = fframe + j - mod j modulus;
247 end;
248
249 goto noalloc;
250
251 end find_frames;
252 ^L
253 remove_frames:
254 procedure;
255
256 do frame = 1 to nframes; /* mark all frames */
257 sst$cmp -> cma fframe + frame - 1.removing = "1"b;
258 end;
259
260 ind = -1; /* do at least one pass */
261 do while ind ^= 0; /* loop until it's done */
262 ind = 0;
263 do frame = 1 to nframes; /* for each frame to be evicted */
264 cmep = addr sst$cmp -> cma fframe + frame - 1;
265 /* find CME */
266 if cmep -> based_word ^= ALL_ONES then do;
267 /* it has not yet been deleted */
268 call page$evict cmep aind; /* start it out */
269 if cmep -> based_word ^= ALL_ONES & aind = 0 then do;
270 ptr cmep cme.fp -> cme.bp = cme.bp;
271 /* unthread it */
272 ptr cmep cme.bp -> cme.fp = cme.fp;
273 if sst$usedp = rel cmep then
274 sst$usedp = cme.fp;
275 if sst$wusedp = rel cmep then
276 sst$wusedp = cme.fp;
277 cmep -> based_word = ALL_ONES;/* mark it gone */
278 cme.abs_usable, cme.removing = "0"b;
279 sst$nused = sst$nused - 1;
280 end;
281 else if ind = 0 then
282 ind = aind; /* multiplex waits */
283 end;
284 end;
285 if ind ^= 0 then
286 call page$pwait ind;
287 end;
288
289 if fframe + nframes > sst$last_core_block then
290 sst$last_core_block = fframe - 1;
291
292 return;
293
294 end remove_frames;
295 ^L
296 abs_wire_frames:
297 procedure returns bit 1 aligned;
298
299 /**** In this procedure, "page" is the index from zero
300 into the array of abs_usuable pages found in the core map,
301 and fp + page is the index into the segment's page table. */
302
303 do frame = 1 to nframes; /* mark them used */
304 sst$cmp -> cma frames frame - 1.abs_w = "1"b;
305 end;
306
307 ind = -1;
308 do while ind ^= 0;
309 ind, aind = 0;
310 do page = 0 to np - 1;
311 cmep = addr sst$cmp -> cma frames page;
312 if wordno astep + sst$astsize + fp + page ^= binary cme.ptwp 18 then
313 call page$evict cmep aind;
314
315 if cmep -> based_word = ALL_ONES then do;
316 call syserr CRASH "pc_abs: Parity error in I/O buffer.";
317 return "0"b;
318 end;
319
320 if aind = 0 then
321 call page$wire_abs cmep aind astep fp + page;
322
323 if ind = 0 then
324 ind = aind;
325 end;
326
327 if ind ^= 0 then
328 call page$pwait ind;
329 end;
330
331 sst$abs_wired_count = sst$abs_wired_count + nframes;
332 return "1"b;
333
334 end abs_wire_frames;
335 ^L
336 lock:
337 procedure;
338
339 call pmut$lock_ptl oldmask sptp; /* lock the ptl */
340 return;
341
342 end lock;
343
344
345 unlock:
346 procedure;
347
348 call pmut$unlock_ptl oldmask sptp; /* almost done */
349 return;
350
351 end unlock;
352 ^L
353 %include syserr_constants;
354 %page;
355 %include cmp;
356 %INCLUDE "ptw.macro";
357 ^L
358 /* BEGIN MESSAGE DOCUMENTATION
359
360 Message:
361 pc_abs: Parity error in I/O buffer.
362
363 S: $crash
364
365 T: $run
366
367 M: $err
368
369 A: $recover
370
371 Message:
372 pc_abs$unwire_abs: Called with NULL astep.
373
374 S: $crash
375
376 T: $run
377
378 M: $err
379
380 A: $inform
381 $recover
382
383 Message:
384 pc_abs$unwire_abs: Attempt to unwire inconsistent CME at CMEP.
385
386 S: $crash
387
388 T: $run
389
390 M: The core map entry for the page being abs unwired did not
391 have the abs_w flag on, which indicates that it was properly abs wired.
392 $err
393
394 A: $inform
395 $recover
396
397 Message:
398 pc_abs$unwire_abs: Attempt to unwire inconsistent PTW at PTP.
399
400 S: $crash
401
402 T: $run
403
404 M: A page at PTP, within the range of pages being unwired for,
405 was found to either not be wired or no longer in memory.
406 $err
407
408 A: $inform
409 $recover
410
411 END MESSAGE DOCUMENTATION */
412
413 end pc_abs;