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) change87-02-18Lippard, approve87-03-16MCR7640,
12 " audit87-06-17Farley, install87-07-17MR12.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