1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         *********************************************************** */
  8 volmap_util$free_address_for_scavenge:
  9      proc (Pvtx, Record_Address);
 10 
 11 /*  Volume Map Utilities
 12 
 13     free_address_for_scavenge   - ensures that a record address is not free
 14                                   by removing from stock and volume map
 15 
 16     Written July 1982 by J. Bongiovanni
 17     Modified November 1982, J. Bongiovanni, to check stock under volmap lock
 18 */
 19 
 20 /*  Parameter  */
 21 
 22           dcl     Pvtx                   fixed bin;         /* PVTE index */
 23           dcl     Record_Address         fixed bin (18);
 24 
 25 /*  Automatic  */
 26 
 27           dcl     bit_no                 fixed bin;
 28           dcl     page_no                fixed bin;
 29           dcl     p99                    pic "99";
 30           dcl     record_address         fixed bin (18);
 31           dcl     volmap_locked          bit (1) aligned;
 32           dcl     vpage_ptr              ptr;
 33           dcl     word_no                fixed bin;
 34 
 35 /*  Static  */
 36 
 37           dcl     NULL_SDW               fixed bin (71) int static options (constant) init (0);
 38           dcl     RECORDS_PER_WORD       fixed bin int static options (constant) init (32);
 39 
 40 /*  Based  */
 41 
 42           dcl     1 vpage                aligned based (vpage_ptr),
 43                     2 word               (0:1023) aligned,
 44                       3 pad1             bit (1) unaligned,
 45                       3 bits             (0:31) bit (1) unaligned,
 46                       3 pad2             bit (3) unaligned;
 47 
 48 /*  External  */
 49 
 50           dcl     volmap_abs_seg$        external;
 51 
 52 /*  Entry  */
 53 
 54           dcl     condition_             entry (char (*), entry);
 55           dcl     page$grab_volmap_page_unwired entry (ptr, fixed bin, ptr);
 56           dcl     page$lock_volmap       entry (ptr);
 57           dcl     page$unlock_volmap     entry (ptr);
 58           dcl     page$withdraw_range    entry (ptr, fixed bin (18), fixed bin (18), fixed bin (18));
 59           dcl     page$write_volmap_page_unwired entry (ptr, fixed bin);
 60           dcl     pmut$swap_sdw          entry (ptr, ptr);
 61           dcl     syserr                 entry options (variable);
 62 %page;
 63           record_address = Record_Address;
 64 
 65           page_no = -1;
 66           volmap_locked = "0"b;
 67 
 68           call SETUP_LOCK;
 69 
 70           call condition_ ("page_fault_error", PAGE_FAULT_ERROR);
 71 
 72           call FIND_VOLMAP_PAGE (record_address, page_no);
 73 
 74           call page$grab_volmap_page_unwired (pvtep, page_no - 1, vpage_ptr);
 75 
 76           call page$withdraw_range (pvtep, record_address, record_address + 1, (0));
 77 
 78           word_no = divide (record_address - record_stock.volmap_page (page_no).baseadd, RECORDS_PER_WORD, 17);
 79           bit_no = mod (record_address - record_stock.volmap_page (page_no).baseadd, RECORDS_PER_WORD);
 80           vpage.word (word_no).bits (bit_no) = "0"b;
 81 
 82           call page$write_volmap_page_unwired (pvtep, page_no);
 83           page_no = -1;
 84 
 85           call UNLOCK_RESET;
 86 
 87           return;
 88 %page;
 89 /*  Internal Procedure to setup pointers and lock the volume map  */
 90 
 91 SETUP_LOCK:
 92      proc;
 93 
 94           pvtep = addr (addr (pvt$array) -> pvt_array (Pvtx));
 95           record_stockp = pvte.volmap_stock_ptr;
 96 
 97           call page$lock_volmap (pvtep);
 98           volmap_locked = "1"b;
 99 
100           call pmut$swap_sdw (addr (volmap_abs_seg$), addr (pvte.volmap_seg_sdw));
101 
102      end SETUP_LOCK;
103 
104 
105 
106 /*  Internal Procedure to reset and unlock  */
107 
108 UNLOCK_RESET:
109      proc;
110 
111 
112           if page_no > 0
113           then call page$write_volmap_page_unwired (pvtep, page_no - 1);
114           page_no = -1;
115 
116           if volmap_locked
117           then call page$unlock_volmap (pvtep);
118           volmap_locked = "0"b;
119 
120           call pmut$swap_sdw (addr (volmap_abs_seg$), addr (NULL_SDW));
121 
122      end UNLOCK_RESET;
123 %page;
124 /* Internal Procedure to find the Volume Map page associated with a given
125    address */
126 
127 FIND_VOLMAP_PAGE:
128      proc (Devadd, Page_no);
129 
130           dcl     Devadd                 fixed bin (18) parameter;
131           dcl     Page_no                fixed bin parameter;
132 
133           dcl     vpagex                 fixed bin;
134           dcl     vpage_found            bit (1);
135           dcl     address                fixed bin;
136 
137 
138           vpage_found = "0"b;
139           address = Devadd;
140 
141           if address < pvte.baseadd | address >= pvte.baseadd + pvte.totrec
142           then call syserr (CRASH, "volmap_util: Address ^o out of paging region on ^a_^a.", address, pvte.devname,
143                     convert (p99, pvte.logical_area_number));
144 
145           do vpagex = record_stock.n_volmap_pages to 1 by -1 while (^vpage_found);
146                if address >= record_stock.volmap_page (vpagex).baseadd
147                then do;
148                          vpage_found = "1"b;
149                          Page_no = vpagex;
150                     end;
151           end;
152 
153           if ^vpage_found
154           then call syserr (CRASH, "volmap_util: Invalid address ^o on ^a_^a.", address, pvte.devname,
155                     convert (p99, pvte.logical_area_number));
156           return;
157 
158      end FIND_VOLMAP_PAGE;
159 %page;
160 /*  Internal Procedure to clean up and continue signalling of
161     page_fault_error
162 */
163 
164 PAGE_FAULT_ERROR:
165      proc (Mcptr, Condition, Coptr, Infoptr, Continue) options (non_quick);
166 
167           dcl     Mcptr                  ptr;
168           dcl     Condition              char (*);
169           dcl     Coptr                  ptr;
170           dcl     Infoptr                ptr;
171           dcl     Continue               bit (1) aligned;
172 
173           call UNLOCK_RESET;
174           Continue = "1"b;
175 
176      end PAGE_FAULT_ERROR;
177 %page;
178 %include pvte;
179 %page;
180 %include stock_seg;
181 %page;
182 %include syserr_constants;
183 %page;
184 /* BEGIN MESSAGE DOCUMENTATION
185 
186    Message:
187    volmap_util: Address XXXXXX out of paging region on dskX_NN.
188 
189    S:     $crash
190 
191    T:     During a physical volume scavenge
192 
193    M:     The scavenger attempted to remove an invalid address from the
194    volume map.
195 
196    A:     $recover
197 
198    Message:
199    volmap_util: Invalid address XXXXXX on dskX_NN.
200 
201    S:     $crash
202 
203    T:     During a physical volume scavenge
204 
205    M:     In attempting to deposit address XXXXXX on device dskX_NN, an invalid
206    volume map offset was computed.
207 
208    A:     $recover
209 
210 
211    END MESSAGE DOCUMENTATION */
212 
213      end volmap_util$free_address_for_scavenge;