1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6 " *                                                         *
  7 " * Copyright (c) 1972 by Massachusetts Institute of        *
  8 " * Technology and Honeywell Information Systems, Inc.      *
  9 " *                                                         *
 10 " ***********************************************************
 11 
 12 """"""""""""""""""""""""""""""""""""""""""""""""""
 13 "
 14 "         call page$evict (cmep, event);
 15 "
 16 "         forces current occupant out of core pointed to by cmep
 17 "         Event returned non-zero if waiting necessary.
 18 "
 19 "         May take 2 calls for wired os page.
 20 "
 21 "         Bernard Greenberg, May 16, 1974
 22 "         Adjusted for pc_recover_sst, BSG, 9/3/77
 23 "         Modified for cam_cache by J. Bongiovanni 2/23/81
 24 "         Modified 03/14/81, W. Olin Sibert, for ADP conversion
 25 "         Modified for read_page_abs calling sequence by J. Bongiovanni 2/26/82
 26 "         Modified to move core map, E. N. Kittlitz, 6/21/82.
 27 "         Modified to call page_synch$move, Chris Jones, 05/09/84.
 28 "
 29 """"""""""""""""""""""""""""""""""""""""""""""""""
 30 
 31 
 32           include   ptw
 33           include   sdw
 34           include   aste
 35           include   stack_frame
 36           include   mc
 37           include   null_addresses
 38           include   add_type
 39           include   page_info
 40           include   sst
 41           include   cmp
 42           include   pxss_page_stack
 43 
 44 " ^L
 45 
 46           name      evict_page
 47 
 48 
 49           segdef    evict,wire_abs
 50 
 51 
 52           link      abs_seg_link,abs_seg$
 53 
 54 "^L
 55 evict:    push      "                   set up stack frame
 56           lda       evict_entry,dl      set up entry flag
 57           sta       entry_sw
 58           eppbp     ap|2,*              point to first arg
 59           eppbp     bp|0,*              point to cme of interest
 60           stz       ap|4,*              zero wait event
 61           eax4      bp|0                get cmep into x4
 62           epbpbb    sst$                bb -> SST through out page
 63           tsx6      page_fault$init_savex         set up for internal calls
 64           stx4      pre_temp            save cmep
 65 
 66           tsx6      make_ptw            compute coreadd
 67           stq       pre_temp+1          save coreadd
 68           stq       core_add
 69 
 70           ldx2      page_fault$cme_ptwp,*4 see if in use
 71           tze       .ret                no, can return
 72           lxl3      page_fault$cme_astep,*4 pick up astep
 73           stx2      ptp_astep           save page pointer
 74           sxl3      ptp_astep           and astep
 75           eppbp     sst|0,2             point to ptw with bp
 76           lda       ptw|0               now inspect ptw
 77           cana      ptw.os,dl           read or write going on?
 78           tnz       await_ptw           yes, must wait for ptw event
 79           cana      ptw.wired,dl        wired page, not out of service
 80           tnz       move_wired
 81 
 82           lca       ptw.valid+1,dl      set to turn off access
 83           ansa      ptw|0               turn off access
 84           tsx7      cam_cache$cam_cache tell world, blast out of caches
 85                                         "core_add set by make_ptw call above
 86           lda       ptw|0               look at ptw now
 87           cana      ptw.phm+ptw.phm1,dl see if modified at _^Ha_^Hn_^Hy time previous
 88           tze       not_mod_ptw         no, very easy case
 89 
 90           tsx7      page_fault$find_core_         get a page to move into
 91           tsx7      set_up_abs_seg_2    get destination abs seg on ab
 92           tsx6      make_from_abs_seg   get ap abs seg together
 93           tsx7      move_page           move page into new location
 94           tsx7      swap_cme            fix core map
 95           lda       page_fault$cme_flags,*x5
 96           cana      cme.synch_held,dl
 97           tze       2,ic
 98           tsx7      page_synch$move     " update dm_journal_seg_
 99           tsx7      swap_ptw            change ptw and open it
100           szn       dev_signal          did parity wipe page out?
101           tnz       parity_destroys_page tough _.
102 .ret:     return    "                   done
103 "
104 
105 not_mod_ptw:        "                   page was not modified - make find_core_ look guilty
106           tsx7      page_fault$cleanup_page       do find-core wrap-up
107           return
108 
109 
110 await_ptw:          "                   come here to wait for out of service
111           eppap     sp|stack_frame.arg_ptr,*      get ptr to arglist
112           sxl2      ap|4,*              set wait event
113           return
114 
115 
116 move_wired:         "                   very hard case- move wired page
117           tsx7      page_fault$find_core_         get new place for page
118           tsx7      set_up_abs_seg_2    get ab-based abs-seg
119           tsx6      make_from_abs_seg   set up 'from' abs seg
120           ldx2      ptp_astep           restore original ptw ptr
121           eppbp     sst|0,2
122 
123 move_merge:
124           lda       ptw|0               get ptw
125           ana       ptw.phm,dl          isolate mod bit
126           sta       sst|sst.evict_phmbit          save for pcrsst
127           stx2      sst|sst.evict_ptp   now recoverable till stz, then ok.
128           ersa      ptw|0               possibly turn off, in an RAR way
129           eax5      0,al                save state of modified bit
130 
131           tsx7      cam_cache$cam_ptws            drive page out of cache and ptwams
132           tsx7      move_page
133           tsx7      cam_cache$cam_with_wait       stop the world
134           lda       ptw|0               look at ptw once more now
135           cana      ptw.phm,dl          see if moved any time in between
136           tze       not_mod_during_move
137 
138           tsx7      move_page           move with world stopped
139           increment sst|sst.recopies    meter
140 
141 not_mod_during_move:
142           eaa       0,5                 restore old mod bit
143           arl       18
144           orsa      ptw|0
145           stz       sst|sst.evict_ptp   tell pcrsst its safe.
146           tsx7      swap_cme            move core map data around.
147           lda       page_fault$cme_flags,*x5
148           cana      cme.synch_held,dl
149           tze       2,ic
150           tsx7      page_synch$move     " update dm_journal_seg_
151           tsx7      swap_ptw            fix the ptw
152           stz       scs$cam_wait        release everybody
153           camp
154           cams      4                   CLEAR CACHE
155           szn       dev_signal          did parity galumph the page?
156           tnz       parity_destroys_page
157           return    "                   and we are done
158 " ^L "
159 "
160 "         Damage segment due to parity error.
161 "         Continue to use page.
162 "
163 parity_destroys_page:
164 
165           lda       aste.fmchanged,du
166           orsa      ast|aste.fmchanged_word,3     "damage seg
167           lda       aste.damaged,dl
168           orsa      ast|aste.damaged_word,3
169 
170           lda       pre_temp+1          set up params for report call
171           sta       core_add
172           ldx4      pre_temp            old frame of interest
173 
174           lda       ptw|0               wired case?
175           cana      ptw.wired,dl
176           tnz       page_error$wired_parity_error crash
177 
178           tsx7      page_error$page_move_parity
179           tsx7      page_fault$delete_mm_frame    take mem out of use
180           tra       .ret
181 "^L
182 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
183 "                                                                     "
184 "                                                                     "
185 "         call page$wire_abs (cmep, event, astep, i);                 "
186 "                                                                     "
187 "         wires page (astep, i) into core pointed to by cmep          "
188 "         may take up to 3 calls, as per convention.                  "
189 "                                                                     "
190 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
191 
192 wire_abs: push                          "get stack together
193           lda       abs_wire_entry,dl   set entry indr
194           sta       entry_sw
195           tsx6      page_fault$init_savex         set up call stack
196           eppbp     ap|6,*              bp -> astep
197           eppbp     bp|0,*              bp -> aste
198           eax3      bp|0                set x3 to aste
199           epbpbb    bp|0                bb                  -> sst$+0
200           lxl0      ap|8,*              x0 contains i
201           eppbp     bp|aste_size,0      bp -> ptw
202           eax2      bp|0                x2 -> ptw
203 
204           stz       ap|4,*              init wait event
205           epplb     ap|2,*              lb -> cmep
206           eax4      lb|0,*              x4 -> cme
207           stx2      ptp_astep           save x2 similarly
208           sxl3      ptp_astep           and astep
209 
210           lda       ptw.wired,dl        attempt to wire page wherever it is -
211                                         "This deterministically  suppresses further writes,
212                                         " causes page to stay in if os on read.
213 
214           cana      ptw|0               see if already wired
215           tnz       already_wired       dont wire it, already wired
216           orsa      ptw|0
217           increment sst|sst.wired       maintain meter
218 
219 already_wired:
220           lda       ptw|0               inspect the ptw
221           cana      ptw.os,dl           see if reading or writing
222           tnz       await_ptw           wait for ptw event
223           cana      ptw.valid,dl        see if in core now
224           tnz       in_core_now         already in - move if not already in place
225           cana      ptw.er,dl           previous error?
226           tze       absread.not_prev_error
227 
228           tsx7      page_fault$disk_offlinep
229            tra      absread.await_any
230 absread.not_prev_error:
231           tsx7      page_fault$read_page_abs      attempt to read page in
232            tra      await_a             wait for event
233            tra      absread.no_wait
234            tra      absread.await_any   volmap event
235 
236 "
237 "         If read_page_abs said no event, then page is in.
238 "
239 absread.no_wait:
240           return
241 
242 await_a:
243           eax2      0,au                wait for event in a
244           tra       await_ptw
245 
246 absread.await_any:
247           eppap     sp|stack_frame.arg_ptr,*
248           sta       ap|4,*
249           return
250 
251 
252 
253 in_core_now:                            "page already in core, might be in right place,
254                                         "then again, might not
255           tsx6      make_ptw            get current ptw for cme
256           era       ptw|0               compare with real ptw
257           ana       ptw_add_mask,du     look at only address
258           tze       .ret                in core, right place, access on, abs wired. GREAT!
259 
260           tsx7      set_up_abs_seg_2    set up 'to' abs_seg
261           lda       ptw|0               get current home of page
262           ana       ptw_add_mask,du     get only address bits
263           arl       ptw_to_coreadd.rl   align to coreadd (ADP/L68 OK)
264           sta       core_add            set up for set_up_abs_seg
265           als       coreadd_to_cmep.ls  get in cmep units (ADP/L68 OK)
266           eaa       sst|sst.cmp,*au     get cmep
267           sta       pre_temp
268           tsx6      page_fault$set_up_abs_seg     set up 'from' abs seg
269           tra       move_merge          move the page
270 "^L "
271 "
272 "
273 "         subroutines
274 "
275 move_page:          "                   move a page from the ap abs seg to the ab abs seg
276           stz       dev_signal          init parity check
277           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
278           ldi       scu.ir.bm+scu.ir.parm,dl      clear out inds, set parmask
279           lda       1024*4,dl
280           mlr       (pr,rl),(pr,rl)
281           desc9a    ap|0,al
282           desc9a    ab|0,al
283           nop       0
284           nop       0                   allow cp and cx boards to synchronize
285           sti       temp
286           ldi       scu.ir.bm,dl
287           nop       0
288           inhibit   off       <-><-><-><-><-><-><-><-><-><-><-><->
289           lda       temp                get ir
290           ana       scu.ir.par,dl
291           orsa      dev_signal          store it
292           tra       0,7
293 
294 
295 set_up_abs_seg_2:                       " set up abs seg on ab - assumes x4 -> cme
296           ldx0      lp|abs_seg_link
297           adlx0     lp|abs_seg_link     " get 2*segno in x0
298           eaa       0,x4                " Get CMEP in A, and
299           sbla      sst|sst.cmp+1       " convert to CME offset
300           als       cmep_to_sdw.ls      " Convert to SDW address (ADP/L68 OK)
301 
302           eaq       0                   " zero the q
303           oraq      sdw_bits
304           staq      dseg$+0,x0          " store in dseg
305 
306           iftarget  l68                 " CAM is different on ADP/L68
307             cams    0                   " clear am of segs
308             camp    0                   " and poss abs-seg pages
309           ifend
310           iftarget  adp
311             cams    0                   " clear am of segs
312             camp    0                   " and poss abs-seg pages
313           ifend
314 
315           eppab     lp|abs_seg_link,*   " Point PR1 at the abs_seg
316           tra       0,x7                " and return
317 
318 " ^L
319 
320 swap_ptw:
321                                         "makes ptw point at cme of x4
322           tsx6      make_ptw
323           ora       add_type.core,dl
324           staddra   ptw|0               store in ptw
325           lda       ptw.valid,dl        get access bit
326           orsa      ptw|0               turn on access if not there already
327           tra       0,7
328 
329 swap_cme: "                             cleans up cme's for swap_ptw
330           ldx2      ptp_astep           restore ptw if clobbered
331           lxl3      ptp_astep           restore astep
332           eppbp     sst|0,2
333           ldx5      pre_temp            "old" cme
334 
335           lda       page_fault$cme_devadd,*5 get "old" (only) devadd
336           staddra   page_fault$cme_devadd,*4 move to "new" cme, which is still free.
337           sxl3      page_fault$cme_astep,*4 still unofficial
338           eax0      0                   get a zero ready.
339 
340 "
341 "         The interval between the next two instructions is unsafe
342 "         with respect to pc_recover_sst. If somehow (only possibility is
343 "         operand cpu error on this cpu) we lose control between them, pcrsst
344 "         will clobber this page. This is not bad.
345 "
346           even
347           inhibit   on <+><+><+><+><+><+><+><+><+><+><+><+>
348           stx0      page_fault$cme_ptwp,*5 It's not in old one,
349           stx2      page_fault$cme_ptwp,*4 It's now in new one.
350           inhibit   off <-><-><-><-><-><-><-><-><-><-><-><->
351 
352           sxl0      page_fault$cme_astep,*5 for cleanliness only.
353           tra       0,7
354 
355 make_ptw:                               " subr to make ptw (and addr in QL) from x4
356           eaa       0,x4                get cmep
357           sbla      sst|sst.cmp+1       get offset
358 
359           iftarget  l68                 " L68 & ADP shift differently here
360             als     cmep_to_ptw.ls      " make PTW addr from cmep offset
361           ifend
362           iftarget  adp
363             arl     cmep_to_ptw.rl      " make PTW addr from cmep offset
364           ifend
365 
366           eaq       0,au                make lower in q
367           qrl       ptw_to_coreadd.rl (ADP/L68 OK)
368           tra       0,x6
369 
370 make_from_abs_seg:  " Common, TSX6 subroutine, relys on page_fault to TRA back
371           ldq       pre_temp+1          get 'from' core_add
372           stq       core_add            set for page_fault routine
373           tra       page_fault$set_up_abs_seg     finish same
374 
375 
376 " ^L "
377 "
378 "         constants
379 "
380           even
381 sdw_bits:                     " Bits for abs-seg SDW -- it is
382                               " Address 0, read/write, one unpaged page
383 
384           iftarget  L68       " SDW is different format for each
385             vfd     18/0,18/sdw.valid
386             vfd     1/0,14/(1024/16)-1,3/sdw.read+sdw.write,18/sdw.unpaged
387           ifend
388 
389           iftarget  ADP
390             vfd     18/0,18/sdw.valid
391             vfd     14/(1024/16)-1,4/0,18/sdw.read+sdw.write+sdw.unpaged
392           ifend
393 
394           end