1 /****^ ***********************************************************
2 * *
3 * Copyright, C Honeywell Bull Inc., 1987 *
4 * *
5 * Copyright, C Honeywell Information Systems Inc., 1982 *
6 * *
7 *********************************************************** */
8
9 /* use: pl1_macro pc.pl1.pmac -target l68 */
10 pc_wired: proc;
11
12 /* RE Mullen, v2pl1, oct 1973 */
13 /* Modified for unified page wait primitive, B. Greenberg 6/6/74 */
14 /* write_wait_uid for new lock, 11/3/75 by BSG */
15 /* Modified for ADP conversion, 03/03/81, W. Olin Sibert */
16 /* Modified for unwire_write_wait, February 1982, J. Bongiovanni */
17 /* Modified for write_wait_uid_list, November 1982, J. Bongiovanni */
18
19 dcl a_astep pointer parameter; /* pointer to AST entry */
20 dcl first_page fixed bin parameter; /* first page affected */
21 dcl no_pages fixed bin parameter; /* number of pages, or -1 if all remaining */
22 dcl a_uid bit 36 aligned parameter; /* arg uid of segment */
23 dcl a_listp ptr parameter; /* pointer to list of pages */
24 dcl a_list 0:255 fixed bin based a_listp; /* list of pages */
25
26 dcl fp fixed bin; /* first page */
27 dcl waitev fixed bin 35; /* wait event from pread */
28 dcl i fixed bin; /* loop index */
29 dcl j k fixed bin 35; /* temporary wait indices */
30 dcl rptp fixed bin 18; /* offset of page table */
31 dcl lp fixed bin; /* last page */
32 dcl np fixed bin; /* number of pages */
33 dcl max_page fixed bin; /* highest page number allowed */
34 dcl increment fixed bin; /* do loop increment */
35 dcl uid bit 36 aligned; /* uid of segment */
36 dcl oldmask fixed bin 71; /* saved interrupt mask */
37 dcl ptwp ptr; /* saved pointer to ptw for wired stack pages */
38
39 dcl do_io bit 1 aligned; /* flag on if I/O is to be done */
40 dcl io bit 1 aligned; /* ="1"b for read, "0"b for write */
41 dcl must_wait bit 1 aligned; /* on if must wait for I/O to complete */
42 dcl set_wired bit 1 aligned; /* on if wired bit is to be set */
43 dcl wired bit 1 aligned; /* value of wired bit, if to be set */
44 dcl uent bit 1 aligned; /* on if must check uid before looking around */
45 dcl have_list bit 1 aligned; /* on if we were passed a list of pages */
46
47 dcl page_no fixed bin; /* current page number */
48 dcl wptwp ptr; /* pointer to current PTW */
49
50 dcl list 0:255 fixed bin; /* copy of list of pages */
51
52 dcl 1 wptw aligned like ptw based wptwp; /* working PTW */
53
54 dcl pmut$lock_ptl entry fixed bin 71 ptr;
55 dcl pmut$unlock_ptl entry fixed bin 71 ptr;
56 dcl page$pread entry ptr fixed bin fixed bin 35;
57 dcl page$pwrite entry ptr fixed bin;
58 dcl page$pwait entry fixed bin 35;
59
60 dcl sst$astsize fixed bin external static;
61 dcl sst$pts 0 : 3 fixed bin external static;
62 dcl sst$wired fixed bin external static;
63
64 dcl addrel binary min rel builtin;
65
66 /* ^L */
67
68 pc_wired$wire_wait: entry a_astep first_page no_pages; /* entry to get pages into core and wire down */
69
70 io = "1"b;
71 do_io = "1"b;
72 must_wait = "1"b;
73 set_wired = "1"b;
74 wired = "1"b;
75 uent = "0"b;
76 have_list = "0"b;
77 go to join;
78
79 pc_wired$wire: entry a_astep first_page no_pages; /* entry to wire pages */
80
81 do_io = "0"b;
82 must_wait = "0"b;
83 set_wired = "1"b;
84 wired = "1"b;
85 uent = "0"b;
86 have_list = "0"b;
87 go to join;
88
89
90 pc_wired$read: entry a_astep first_page no_pages; /* entry to read pages */
91
92 io = "1"b;
93 do_io = "1"b;
94 must_wait = "0"b;
95 set_wired = "0"b;
96 uent = "0"b;
97 have_list = "0"b;
98 go to join;
99
100
101 pc_wired$unwire: entry a_astep first_page no_pages; /* entry to turn off wired bit */
102
103 io = "0"b;
104 must_wait = "0"b;
105 set_wired = "1"b;
106 wired = "0"b;
107 uent = "0"b;
108 have_list = "0"b;
109 go to join;
110
111
112 pc_wired$write_wait: entry a_astep first_page no_pages; /* entry to issue write and wait for I/O */
113
114 io = "0"b;
115 do_io = "1"b;
116 must_wait = "1"b;
117 set_wired = "0"b;
118 uent = "0"b;
119 have_list = "0"b;
120 go to join;
121
122
123 pc_wired$write: entry a_astep first_page no_pages; /* entry to issue a write */
124
125 io = "0"b;
126 do_io = "1"b;
127 must_wait = "0"b;
128 set_wired = "0"b;
129 uent = "0"b;
130 have_list = "0"b;
131 go to join;
132
133
134 pc_wired$write_wait_uid: entry a_astep first_page no_pages a_uid; /* For cleanup */
135
136 io = "0"b;
137 do_io = "1"b;
138 must_wait = "1"b;
139 set_wired = "0"b;
140 uent = "1"b;
141 uid = a_uid;
142 have_list = "0"b;
143 go to join;
144
145 pc_wired$write_wait_uid_list: entry a_astep a_listp first_page no_pages a_uid;
146
147 io = "0"b;
148 do_io = "1"b;
149 must_wait = "1"b;
150 set_wired = "0"b;
151 uent = "1"b;
152 uid = a_uid;
153 have_list = "1"b;
154 goto join;
155
156 pc_wired$unwire_write_wait: entry a_astep first_page no_pages;
157
158 io = "0"b;
159 do_io = "1"b;
160 must_wait = "1"b;
161 set_wired = "1"b;
162 wired = "0"b;
163 uent = "0"b;
164 have_list = "0"b;
165
166
167
168 join: astep = a_astep; /* Copy args. */
169 np = no_pages;
170 max_page = sst$pts binary astep -> aste.ptsi 3 - 1; /* Highest valid page number */
171 fp = first_page;
172
173 if have_list then do;
174 list = a_list;
175 lp = fp + np - 1;
176 end;
177 else do;
178 if np = -1 then lp = binary astep -> aste.csl 9 - 1;
179 else lp = fp + np - 1;
180 end;
181
182 call pmut$lock_ptl oldmask ptwp; /* lock and mask */
183
184 ptp = addrel astep sst$astsize; /* get a pointer to the page table */
185 rptp = binary rel ptp 18; /* get offset for pwait calls */
186
187
188 if set_wired then do i = fp to lp; /* Unwire/wire all needed pages. */
189 if have_list then page_no = list i;
190 else page_no = i;
191 if page_no <= max_page then do;
192 wptwp = addr ptp -> ptwa page_no;
193 if wired ^= wptw.wired /* if changing wired bit */
194 then if wired
195 then sst$wired = sst$wired + 1; /* change total */
196 else sst$wired = sst$wired - 1;
197 wptw.wired = wired; /* Wire/unwire as needed. */
198 end;
199 end;
200
201 loop: k, j, waitev = -1; /* Set out of service indicator. */
202 if uent then /* Racing with cleanup, but we are in same racket */
203 if uid ^= astep -> aste.uid then go to nomore;
204
205 do i = lp to fp by -1; /* Loop backwards to optimize disk spiral */
206 if have_list then page_no = list i;
207 else page_no = i;
208 if page_no <= max_page then do;
209 wptwp = addr ptp -> ptwa page_no;
210 if wptw.os then k = page_no + rptp; /* If out of service remember to wait. */
211 else if do_io then do;
212 if ^wptw.valid then do; /* Try to read in a page. */
213 if io then call page$pread astep page_no waitev; /* try to read the page */
214 if waitev > 0 then j = waitev;/* use new wait event */
215 end;
216 else do; /* page is in core, probably want to write */
217 if ^io then if wptw.phm | wptw.phm1 then
218 call page$pwrite astep page_no; /* issue the write request */
219 if wptw.os then j = page_no + rptp;
220 end;
221 end;
222 end;
223 end;
224
225 if k ^= -1 then do;
226 j = k;
227 go to wait1;
228 end;
229
230 if must_wait & j ^= -1 then do; /* See if we must wait */
231 wait1: call page$pwait j; /* wait for event */
232 go to loop;
233 end;
234
235 nomore: call pmut$unlock_ptl oldmask ptwp; /* unlock and unmask */
236 return;
237
238 %page; %include aste;
239 %page;
240 %INCLUDE "ptw.macro";
241
242 end pc_wired;