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;