1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6 " *                                                         *
  7 " ***********************************************************
  8 
  9 
 10 " HISTORY COMMENTS:
 11 "  1) change(87-02-18,Lippard), approve(87-03-16,MCR7640),
 12 "     audit(87-06-17,Farley), install(87-07-17,MR12.1-1043):
 13 "     Added volmap word validity check (fix by Swenson).
 14 "                                                      END HISTORY COMMENTS
 15 
 16 
 17 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 18 "
 19 "         volmap
 20 "
 21 "         Routines for manipulating the volume map, migrating record addresses
 22 "         between the volume map and the stock.
 23 "
 24 "         Entries:
 25 "                   withdraw_from_volmap - volmap into stock
 26 "                   deposit_to_volmap    - stock into volmap
 27 "                   drain_stock          - empty stock into volmap
 28 "                   reset_pvte           - reset lock, state for ESD
 29 "
 30 "         These routines are controlled by threshold values in the stock.
 31 "
 32 "         This version has some quick kludges for the old volmap format.
 33 "         It will be changed for the new format.
 34 "
 35 "         Written February 1982 by J. Bongiovanni
 36 "         Modified December 1982 by J. Bongiovanni to reset ovfl before fno
 37 "
 38 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 39 
 40           name      volmap
 41 
 42           segdef    withdraw_from_volmap
 43           segdef    deposit_to_volmap
 44           segdef    drain_stock
 45           segdef    reset_pvte
 46 
 47           equ       word_to_record.ls,5
 48           equ       volmap_page_high,1024
 49           equ       volmap_first_page,64
 50           bool      high_record_address,377777
 51           bool      os_address,400000
 52           bool      volmap_word_mask,400000000007
 53 
 54           link      volmap_abs_seg_link,volmap_abs_seg$
 55 
 56 "^L
 57           include   page_info
 58 "^L
 59           include   pvte
 60 "^L
 61           include   pxss_page_stack
 62 "^L
 63           include   stock_seg
 64 "^L
 65 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 66 "
 67 "         withdraw_from_volmap
 68 "
 69 "         tsx7      volmap$withdraw_from_volmap
 70 "
 71 "         On entry,
 72 "             bp -> pvte
 73 "             ab -> stock_seg$meters
 74 "             bb -> record_stock
 75 "             Areg contains page number in volmap_seg
 76 "
 77 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 78 
 79 withdraw_from_volmap:
 80           increment ab|rsmeters.n_v_withdraw_attempts
 81 
 82           ldx0      bb|record_stock.volmap_page,al " Number free records this page
 83           tze       0,x7                          " None to be had
 84 
 85           ldx0      bb|record_stock.target        " Is volume shut down
 86           tze       0,x7                          " Yes
 87 
 88           tsx6      page_fault$savex
 89           sta       volmap_temp
 90           tsx6      setup_abs_seg                 " To read volmap_seg
 91 
 92           lda       volmap_temp                   " Page number in volmap_seg
 93           als       page_power                    " Offset within segment
 94           eppap     volmap_abs_seg$               " ap -> base of volmap_seg
 95           eppap     ap|0,al                       " ap -> page of volmap
 96           spriap    volmap_save_ptr
 97 
 98 withdraw_loop:
 99           lca       1,dl                          " Bail-out counter
100           sta       volmap_temp+1
101 
102           lxl0      volmap_temp                   " Page number
103           ldx1      bb|record_stock.volmap_page,x0 " Records left this page
104           tmoz      withdraw_returns              " None
105           ldx1      bb|record_stock.old_volmap_page,x0 " Roving pointer
106           eppap     volmap_save_ptr,*
107 
108           eax0      0,x0                          " Page number
109           tnz       withdraw_inner_loop           " Not first page
110           cmpx1     volmap_first_page,du          " Kludge for old volmap
111           tpl       withdraw_inner_loop           " Above bound
112           ldx1      volmap_first_page,du          " Set to minimum value
113 
114 withdraw_inner_loop:
115           increment ab|rsmeters.withdraw_volmap_steps
116           lda       ap|0,x1                       " Any free this word
117           tnz       withdraw_got                  " Yes
118           eax1      1,x1                          " Bump to next word
119           cmpx1     volmap_page_high,du           " End of page
120           tmi       withdraw_inner_loop           " No
121           aos       volmap_temp+1                 " Bump bail-out counter
122           tpnz      page_error$volmap_inconsistent
123           ldx1      0,du                          " Start at the beginning
124           eax0      0,x0                          " Unless its page 0
125           tnz       withdraw_inner_loop
126           ldx1      volmap_first_page,du
127           tra       withdraw_inner_loop
128 
129 withdraw_got:
130           cana      =v36/volmap_word_mask         " Check validity of word
131           tnz       page_error$invalid_volmap_word " mbz bits are not
132           ldi       0,dl                          " Let fno work as expected, not as advertised
133           lde       0,du                          " Find first bit on
134           fno
135           stz       volmap_temp_1
136           ste       volmap_temp_1
137           lda       volmap_temp_1
138           neg
139           arl       17-7                          " Record within word
140           sta       volmap_temp_1
141 
142           arl       18                            " AL = Record within word
143           eaq       0,x1                          " QU = Word offset within volmap page
144           lrl       18                            " QU = Record within word
145                                                   " QL = Word offset within  volmap page
146 
147           eaa       0,x1                          " Word offset within volmap page
148           als       word_to_record.ls             " Record offset of begin of word
149           asa       volmap_temp_1                 " Record offset within volmap page
150           lxl2      bb|record_stock.volmap_page,x0 " Base address of page
151           adlx2     volmap_temp_1                 " True address
152           eaa       0,x2
153           arl       18
154           ora       os_address,dl                 " Out-of-service until write completes
155           stx1      bb|record_stock.old_volmap_page,x0 " Roving pointer
156           stq       volmap_temp_1                 " QU = Record within word
157                                                   " QL = Word offset within volmap page
158           tsx7      stock$deposit
159           tra       withdraw_returns              " Stock is full
160 
161           eppap     volmap_save_ptr,*             " ap -> page of volmap
162           lda       volmap_temp_1                 " AU = Record within word
163                                                   " AL = Word offset within volmap page
164           ldq       =o200000,du                   " Reset bit in volmap
165           qrl       0,au
166           ersq      ap|0,al
167 
168           increment ab|rsmeters.n_pages_withdraw_async
169           ldx0      bp|pvte.nleft
170           sblx0     1,du
171           tmi       page_error$volmap_inconsistent
172           stx0      bp|pvte.nleft
173           lxl1      volmap_temp
174           ldx0      bb|record_stock.volmap_page,x1
175           sblx0     1,du
176           tmi       page_error$volmap_inconsistent
177           stx0      bb|record_stock.volmap_page,x1
178           lxl0      bb|record_stock.n_os_in_stock
179           adlx0     bb|record_stock.n_free_in_stock
180           cmpx0     bb|record_stock.target        " Are we there yet
181           tmi       withdraw_loop                 " No
182 
183 withdraw_returns:
184           tsx6      restore_abs_seg
185           tsx6      page_fault$unsavex
186 "^L
187 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
188 "
189 "         deposit_to_volmap
190 "
191 "         tsx7      volmap$deposit_to_volmap
192 "
193 "         On entry,
194 "             bp -> pvte
195 "             ab -> stock_seg$meters
196 "             bb -> record_stock
197 "             Areg contains page number in volmap_seg
198 "
199 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
200 
201 deposit_to_volmap:
202           increment ab|rsmeters.n_v_deposit_attempts
203 
204           tsx6      page_fault$savex
205 
206           eax0      0,al                          " Page number
207           stx0      volmap_temp
208           tsx6      setup_abs_seg
209 
210           lda       volmap_temp                   " Page number
211           ana       -1,du                         "   in AU
212           arl       18-page_power                 " Offset in AL
213           eppap     volmap_abs_seg$
214           eppap     ap|0,al                       " ap -> base of page
215 
216           ldx0      volmap_temp                   " Page number
217           lda       bb|record_stock.volmap_page,x0
218           ana       -1,dl                         " AL = base address
219           sta       volmap_temp+1
220 
221           ldx1      high_record_address,du        " Set for last page
222           lxl2      bb|record_stock.n_volmap_pages " Number of pages in volmap
223           sblx2     1,du                          " Index of last page
224           cmpx2     volmap_temp                   " Is this page the last
225           tze       deposit_last                  " Yes
226           lxl1      bb|record_stock.volmap_page+1,x0 " Pick up base address of next
227 deposit_last:
228           stx1      volmap_temp+1                 " Low address in lower/high address is upper
229           spriap    volmap_save_ptr
230 
231 deposit_loop:
232           lxl0      bb|record_stock.n_os_in_stock
233           adlx0     bb|record_stock.n_free_in_stock
234           cmpx0     bb|record_stock.target        " Are we done
235           tmoz      deposit_returns               " Yes
236 
237           lda       volmap_temp+1                 " Range of addresses this page
238           tsx7      stock$withdraw_range          " Get an address within the rage
239           tra       deposit_returns               " None left
240 
241           eppap     volmap_save_ptr,*
242           ldx0      volmap_temp                   " Page number
243           lxl1      bb|record_stock.volmap_page,x0 " Base address of page
244           stz       volmap_temp_1
245           stx1      volmap_temp_1
246           sta       devadd                        " Save address for page_error
247           als       18                            " Address in AU
248           sbla      volmap_temp_1                 " Relative address within page
249           tmi       page_error$bad_volmap_address " Bogus
250           arl       18                            " Address in AL
251           ldq       0,dl
252           lrl       word_to_record.ls             " Word offset in AL
253           qrl       18-word_to_record.ls          " Bit within word in QU
254           eax1      0,qu                          " Bit within word in x1
255           ldq       =o200000,du                   " Mask to set bit
256           qrl       0,x1                          " Shift to the right bit
257           cmpa      1024,dl                       " Within a page
258           tpl       page_error$bad_volmap_address " No
259           canq      ap|0,al                       " Already marked as free
260           tze       deposit_valid                 " No
261           szn       pvt$shutdown_state            " In ESD?
262           tnz       deposit_loop                  " Yes, this can happen normally
263           ldx1      1,du
264           asx1      bp|pvte.vol_trouble_count     " Add to inconsistency count
265           tsx7      page_error$deposit_inuse_address " And tell the world
266           tra       deposit_loop
267 
268 deposit_valid:
269           orsq      ap|0,al                       " Mark address as free
270           increment ab|rsmeters.n_pages_deposit_volmap
271           ldx0      1,du
272           asx0      bp|pvte.nleft
273           ldx1      volmap_temp
274           asx0      bb|record_stock.volmap_page,x1
275           tra       deposit_loop
276 
277 deposit_returns:
278           tsx6      restore_abs_seg
279           tsx6      page_fault$unsavex
280 "^L
281 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
282 "
283 "         drain_stock
284 "
285 "         call page$drain_record_stock (pvtep)
286 "
287 "         Where
288 "             pvtep -> PVTE
289 "
290 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
291 
292 drain_stock:
293           push
294           tsx6      page_fault$init_savex
295 
296           eppbp     ap|2,*                        " bp -> ptr -> PVTE
297           eppbp     bp|0,*                        " bp -> PVTE
298           lprpbb    bp|pvte.volmap_stock_ptr      " bb -> record stock
299           epbpab    bb|0                          " ab -> base of stock_seg
300           eppab     ab|stock_seg.meters           " ab -> meters
301 
302 drain_retry:
303           tsx7      lock_volmap$lock_wired_wait   " Get lock, async idle
304           tra       drain_waits                   " Failed, wait event in APTE
305 
306           ldx0      0,du                          " Succeeded
307           stx0      bb|record_stock.low_threshold " Clear thresholds
308           sxl0      bb|record_stock.high_threshold " And deposit will do the rest
309           stx0      bb|record_stock.target
310           lda       bb|record_stock.n_volmap_pages
311           ana       -1,dl                         " Areg = number of pages in volmap
312           sta       volmap_temp_2
313 
314 drain_loop:
315           lda       volmap_temp_2
316           sba       1,dl                          " Next page to drain
317           sta       volmap_temp_2
318           tmi       drain_returns                 " Done
319           tsx7      deposit_to_volmap             " Clear this page
320           tra       drain_loop
321 
322 drain_returns:
323           tsx7      lock_volmap$unlock_wired      " Unlock
324           return
325 
326 drain_waits:
327           call      pxss$wait                     " APTE already has event
328           tra       drain_retry
329 
330 "^L
331 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
332 "
333 "         reset_pvte
334 "
335 "         call page$reset_pvte (pvtep)
336 "
337 "         Where
338 "              pvtep -> PVTE
339 "
340 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
341 
342 reset_pvte:
343           push
344 
345           eppbp     ap|2,*                        " bp -> ptr -> PVTE
346           eppbp     bp|0,*                        " bp -> PVTE
347 
348           stz       bp|pvte.volmap_lock           " Clear lock
349           stz       bp|pvte.volmap_async_state    " Set state to Idle, page to 0
350           stz       bp|pvte.vtoc_map_lock         " Clear lock
351 
352           lda       bp|pvte.volmap_stock_ptr      " See whether stock exists
353           tze       reset_pvte_returns            " No
354           ana       =o007777,du                   " Check for null pointer
355           cmpa      =o007777,du
356           tze       reset_pvte_returns            " Is null - no stock
357 
358           lprpbb    bp|pvte.volmap_stock_ptr      " bb -> record stock
359           epbpab    bb|0                          " ab -> base of stock seg
360           eppap     ap|stock_seg.meters           " ab -> meter area
361 
362           tsx7      stock$recover                 " Attempt to fix any damage
363           tsx7      stock$reset_os                " Reset any out-of-service
364                                                   " Safe since ESD doesn't withdraw
365 
366 reset_pvte_returns:
367           return
368 
369 "^L
370 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
371 "
372 "         Internal procedure to set up and restore the volmap_abs_seg
373 "
374 "         tsx6      setup_abs_seg
375 "                   bp -> PVTE
376 "
377 "         tsx6      restore_abs_seg
378 "
379 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
380 
381 setup_abs_seg:
382 
383           ldx0      lp|volmap_abs_seg_link        " Segment number in x0
384           adlx0     lp|volmap_abs_seg_link        " Offset in dseg
385           ldaq      dseg$0,x0                     " Previous SDW
386           staq      volmap_save_sdw               " Save into stack
387           ldaq      bp|pvte.volmap_seg_sdw        " Volmap seg of interest
388           staq      dseg$0,x0                     " Set the SDW
389           cams                                    " And the SDWAM
390           camp                                    " And the PTWAM
391           tra       0,x6
392 
393 restore_abs_seg:
394 
395           ldx0      lp|volmap_abs_seg_link        " Segment number in x0
396           adlx0     lp|volmap_abs_seg_link        " Offset in dseg
397           ldaq      volmap_save_sdw               " Previous value
398           staq      dseg$0,x0                     " Set the SDW
399           cams                                    " And the SDWAM
400           tra       0,x6
401 
402           end