1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1983 *
  6 " *                                                         *
  7 " ***********************************************************
  8 
  9 
 10 " FIM_UTIL - Utility subroutines for the fim, wired_fim, and ii.
 11 "         consolidated 10/18/76 by Noel I. Morris
 12 "         Modified 1 Feb 79 by D. Spector for new scs format for 8-cpu cioc
 13 "         Modified 8/27/79 by J. A. Bush to reorganize the check_fault subroutine
 14 "         Modified 8/25/80 by J. A. Bush for the DPS8/70M CPU
 15 "         Modified 2/23/81 by J. Bongiovanni for fast connect code
 16 "         Modified 3/5/81 by J. Bongiovanni for OOSB on prds
 17 "         Modified 3/23/81 by J. A. Bush to dump extended APU history reg. for DPS8/70M.
 18 "         Modified 9/23/81 by J. A. Bush to not use QU mode when saving AMs
 19 "         Modified 10/28/81 by J. Bongiovanni for bug in check_fault
 20 "         Modified 2/8/82 by J. Bongiovanni to trap on masked in user ring (conditionally)
 21 "         Modified 02/16/82 by J. A. Bush to not trash mc.fault_reg for sys_trouble crash
 22 "         Modified 07/30/82 by J. Bongiovanni for scs$trouble_processid
 23 "         Modified 10/13/82 by E. N. Kittlitz to clear indicators in v_time_init.
 24 "         Modified sometime by B. I. Margulies for bootload multics.
 25 "         Modified 4/7/83 by E. N. Kittlitz for drl_fault_trouble.
 26 "         Modified 10/8/83 by J. A. Bush to dump extended fault register
 27 "         Modified 10/18/83 by R. Coppola to meter per-processor cache errors
 28 "         Modified 11/27/83 by E. N. Kittlitz for ext vcpu entries
 29 "         Modified 83-12-05 by BIM for checking fault-masked always.
 30 
 31 
 32 " HISTORY COMMENTS:
 33 "  1) change(88-05-24,Farley), approve(88-06-30,MCR7927),
 34 "     audit(88-07-12,Fawcett), install(88-08-02,MR12.2-1076):
 35 "     Added checking in force_hist_regs for the new prds$hregs_last_saved time
 36 "     and in save_fault_reg for prds$fault_reg_last_saved.  This is to prevent
 37 "     multiple attempts to save the data, resulting in the data becoming zero.
 38 "                                                      END HISTORY COMMENTS
 39 
 40 
 41           name      fim_util
 42 
 43 
 44           segdef    check_fault         validate a fault
 45           segdef    check_interrupt     validate an interrupt
 46           segdef    fault_trouble       illegal fault condition
 47           segdef    drl_fault_trouble   illegal fault, you say what it is
 48           segdef    copy_mc             copy machine conditions
 49           segdef    push_stack          push stack frame
 50           segdef    push_stack_32       push stack frame with grace area
 51           segdef    set_mask            set controller mask to sys level
 52           segdef    restore_mask        restore previous controller mask
 53           segdef    hist_regs           save history regs and AMs
 54           segdef    force_hist_regs     force save history regs and AMs
 55           segdef    check_mct           check and trace machine conditions and hregs
 56           segdef    reset_mode_reg      turn on hist reg and cache
 57           segdef    v_time_init         start virtual time meter
 58           segdef    fim_v_time_init     save virtual time for FIM
 59           segdef    v_time_calc         stop virtual time meter
 60           segdef    fim_v_time_calc     compute virtual time for FIM
 61 
 62           entry     fim_v_time_calc_ext externally callable fim_v_time_calc
 63           entry     fim_v_time_init_ext externally callable fim_v_time_init
 64 
 65           link      prds_link,prds$+0
 66 
 67 
 68           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
 69 
 70 " ^L
 71 
 72 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 73 "
 74 "         Procedure to check validity of faults and interrupts
 75 "
 76 "
 77 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 78 
 79 check_fault:
 80           ldaq      pds$apt_ptr         get pointer to our APT entry
 81           cmpaq     prds$idle_ptr       are we in idle process?
 82           tze       idle_trouble        if so, stop the entire system at once
 83 
 84           lxl1      prds$processor_tag
 85           lprpab    scs$mask_ptr,1
 86           xec       scs$read_mask,1
 87           cmpaq     scs$sys_level       masked to system level
 88           tze       fault_masked_trouble
 89 
 90 check_interrupt:
 91           lda       bp|mc.scu.ppr.prr_word  check whether running in ring-0
 92           cana      scu.ppr.prr_mask,du ring number in ppr
 93           tnz       not_invalid         not ring-0
 94 
 95           eax7      0                   nothing invalid yet
 96           lda       bp|mc.prs+6*2       1st word of stack pointer
 97           ldq       =o77777,dl          mask to check seg-no and val. ring
 98           cmk       lp|prds_link        is stack=prds and ring-0
 99           tnz       not_on_prds         no
100           ldx7      -trbl_prds_fi,du    fault on prds
101 
102           lda       bp|mc.scu.tpr.tsr_word        now check for stack overflow
103           ldq       =o777777,dl         ring number, segment number in TSR
104           cmk       lp|prds_link        was target prds
105           tnz       not_on_prds         no
106           lda       bp|mc.scu.fault_data_word  stack overflow is OOSB
107           cana      scu.fd.oosb,du      is it possibly OOSB (must also be acv)
108           tze       not_on_prds         not at all
109           ana       scu.fi_num_mask+scu.fi_flag_mask,dl  check fault type
110           cmpa      2*FAULT_NO_ACV+1,dl fault/access violation
111           tze       oosb_prds_trouble   on the prds!
112 
113 not_on_prds:
114           lda       pds$processid       do we have ptr locked
115           cmpa      sst$ptl
116           tnz       not_ptl_locked      no
117           ldx7      -trbl_ptl_fi,du     f/i with ptl locked
118 
119 not_ptl_locked:
120           eaa       0,7                 any invalid condition found
121           tze       not_invalid         no
122           ars       18                  set up sys_trouble_pending
123           tra       check_fault_trouble ..
124 
125 not_invalid:
126           lca       scu.ir.parm+1,dl    turn OFF parity mask
127           ansa      bp|mc.scu.indicators_word
128 
129           tra       0,0                 return to caller
130 
131 idle_trouble:
132           lca       trbl_idle_flt,dl    fault while in idle process
133           tra       check_fault_trouble ..
134 
135 fault_masked_trouble:
136           lca       trbl_fault_masked,dl fault while masked to system level
137           tra       check_fault_trouble
138 
139 oosb_prds_trouble:
140           lca       trbl_oosb_prds,dl   yes--oosb on prds (stack overflow)
141           tra       check_fault_trouble ..
142 
143 fault_trouble:
144           lca       trbl_illeg_flt,dl   unrecognized fault
145           tra       check_fault_trouble
146 
147 drl_fault_trouble:
148           lca       trbl_r0_drl_flt,dl  ring 0 derail
149           tra       check_fault_trouble
150 
151 check_fault_trouble:
152           sta       scs$sys_trouble_pending  set trouble flags
153 
154           lda       pds$processid                 save our process ID
155           stac      scs$trouble_processid         if we're the first
156 
157           tsx1      save_fault_reg                save fault reg and cpu type
158 
159           lda       sys_info$initialization_state Too early for connect?
160           cmpa      =2,dl                         Multiprocessing?
161           tmoz      sys_trouble$sys_trouble       Go directly to jail ...
162 
163           lxl1      prds$processor_tag  prepare to send connect
164           cioc      scs$cow_ptrs,1*     ZAP
165 
166           dis       *                   cannot inhibit connects at a DIS
167           tra       -1,ic               STOP
168 " ^L
169 
170 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
171 "
172 "         COPY_MC - Procedure to copy machine conditions
173 "
174 "
175 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
176 
177 copy_mc:
178           mlr       (pr),(pr)           copy machine conditions
179           desc9a    bp|0,48*4
180           desc9a    ap|0,48*4
181           eppbp     ap|0                make bp -> copied conditions
182 
183           tra       0,0                 return to caller
184 
185 
186 
187 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
188 "
189 "         PUSH_STACK - Procedure to create a stack frame
190 "
191 "
192 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
193 
194 push_stack:
195           eppap     sb|stack_header.stack_end_ptr,*  ap -> place for frame
196 push_join:
197           sprisp    ap|stack_frame.prev_sp        save current sp
198           eppsp     ap|0                          set sp to new frame
199           eppap     sp|0,7                        ap -> end of frame
200           spriap    sp|stack_frame.next_sp        save next sp
201           spriap    sb|stack_header.stack_end_ptr save end pointer
202           sprilp    sp|stack_frame.lp_ptr         save our linkage ptr
203 
204           tra       0,0                           return to caller
205 
206 
207 push_stack_32:
208           eppap     sb|stack_header.stack_end_ptr,*  ap -> place for frame
209           eppap     ap|32               leave room for push in progress
210           tra       push_join           join common code
211 
212 " ^L
213 
214 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
215 "
216 "         Procedures to save and restore controller masks
217 "
218 "
219 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
220 
221 set_mask:
222           lxl1      prds$processor_tag  processor tag in X1
223           lprpab    scs$mask_ptr,1      get pointer for masking
224           xec       scs$read_mask,1     read mask, if assigned
225           staq      bp|mc.mask          save it
226 
227           lxl1      prds$processor_tag  CPU tag in X1
228           lprpab    scs$mask_ptr,1      get pointer for masking
229           ldaq      scs$sys_level       going to mask all interrupts
230           xec       scs$set_mask,1      only if mask is assigned
231 
232           tra       0,0
233 
234 
235 
236 restore_mask:
237           lxl1      prds$processor_tag  CPU tag in X1
238           lprpab    scs$mask_ptr,1      get pointer for masking
239           ldaq      bp|mc.mask          get original mask
240           oraq      channel_mask_set    make sure channel mask is correct
241           anaq      scs$open_level      ..
242           xec       scs$set_mask,1      restore the mask
243 
244           tra       0,0                 return to caller
245 
246 
247           even
248 channel_mask_set:
249           oct       17,17
250 
251 " ^L
252 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
253 "
254 "         Procedures to save history regs. Enter with bb -> place to store history regs.
255 "         hist_regs -         save history regs only if per-system
256 "                             (wired_hardcore_data$global_hregs) or per-process
257 "                             (pds$save_history_regs) flags are set.
258 "         force_hist_regs -   save history regs unconditionaly
259 "
260 "         X4 is set  with the cpu type (0 = L68/DPS, 1 = DPS8) by the
261 "         save_fault_reg subroutine  which is called by the check_mct subroutine
262 "         which is called by all callers of this subroutine.
263 "
264 "
265 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
266 
267 hist_regs:
268           szn       wired_hardcore_data$global_hregs is global history reg save flag on?
269           tmi       force_hist_regs               xfer if yes
270           szn       pds$save_history_regs         no, is per_process hregs switch on?
271           tmi       force_hist_regs               xfer if yes
272           stz       pds$hregs_saved               no, zero switch for signaller
273           tra       0,0                           and return to caller
274 
275 force_hist_regs:
276           ldaq      bp|mc.fault_time              check fault time
277           ana       =o777777,dl                   only lower 54 bits
278           cmpaq     prds$hregs_last_saved         against last time saved
279           tmoz      0,0                           return if already saved
280           staq      prds$hregs_last_saved         set to fault time if not
281           lda       =o400000,du                   set hreg saved switch
282           sta       pds$hregs_saved               for signaller
283           tsx1      save_am                       go save associative memory
284           ldq       2,du                          get a 2 for stepping address
285           eax6      4                             4 blocks of
286 scpr1:    eax7      16                            16 history registers
287           eax3      0                             set up for L68 CPU type initally
288           cmpx4     1,du                          is this a DPS8/70M CPU?
289           tnz       scpr2                         xfer if no, it is L68
290           eax3      48                            yes, set up to skip first 48 hregs
291 scpr2:    lda       scpr-1,6                      get correct instruction
292           sta       bp|mc.fim_temp                save in stack
293 scpr3:    xec       bp|mc.fim_temp                execute the instruction
294           cmpx3     0,du                          are we through skipping hregs?
295           tze       scpr4                         yes, go increment address
296           eax3      -1,3                          no, skip another
297           tra       scpr3                         and go execute scpr again
298 
299 scpr4:    asq       bp|mc.fim_temp                increment address of instruction
300           eax7      -1,7                          count down
301           tnz       scpr3                         more of this 16 double word block
302           eax6      -1,6                          count down
303           tnz       scpr1                         another kind of hreg
304 
305           eax7      64                            initially set clear count to 64
306           cmpx4     1,du                          is this a DPS8/70M CPU?
307           tze       *+2                           yes, clear all 64 hregs
308           eax7      16                            no, clear only 16 hregs
309           lcpr      0,03                          set all history regs to zero
310           eax7      -1,7                          count down
311           tpnz      *-2                           xfer if more to do
312           tra       0,0                           return to caller
313 
314 scpr:     scpr      bb|0,40                       OU History Regs for L68, OU/DU for DPS8
315           scpr      bb|32,20                      CU History Regs
316           scpr      bb|64,10                      DU History Regs for L68, extended APU for DPS8
317           scpr      bb|96,00                      APU History Regs
318 
319 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
320 "
321 "         Internal subroutine for saving fault register, extended fault
322 "         register and CPU type (from RSW (2)), int the machine condition area.
323 "         entry via tsx1 save_fault_reg. Exit with x4 containing the CPU type
324 "
325 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
326 
327 save_fault_reg:
328           ldaq      bp|mc.fault_time              check fault time
329           ana       =o777777,dl                   only lower 54 bits
330           cmpaq     prds$fault_reg_last_saved     against last time saved
331           tmoz      0,1                           return if already saved
332           staq      prds$fault_reg_last_saved     set to fault time if not
333           scpr      bp|mc.fim_temp,01             store the fault register
334           ldaq      bp|mc.fim_temp
335           sta       bp|mc.fault_reg               save M.S. 36 bits
336           rsw       2                             get cpu type in a
337           arl       30                            position in al
338           ana       3,dl
339           eax4      0,al                          save cpu type in x4
340           lrl       mc.cpu_type_shift             merge with ext. fault reg
341           stcq      bp|mc.cpu_type_word,70        and save in M.C.
342           lda       prds$processor_tag            get cpu num
343           xec       cache_ctr_tab,al              lb=> per-cpu cache err ctrs
344           lda       bp|mc.fault_reg               reload PFR
345           ana       =o10,dl                       cache dir parity (bit 32)?
346           tze       check_efr                     no, go check EFR
347           aos       lb|1                          yes, increment the per-cpu ctr
348 check_efr:
349           anq       mc.ext_fault_reg_mask,du      mask unwanted bits OFF
350           tze       0,1                           no bits on, return
351           qls       2                             get EFR bits in Q 1-17
352           eaa       0                             set up A as incrementer
353 efr_loop:
354           ada       1,dl                          increment EFR slot number
355           qls       1                             is this bit on?
356           tpnz      efr_loop                      no, but some other bit on
357           tze       0,1                           no more EFR bits, return
358           aos       lb|1,al                       increment EFR counter
359           tra       efr_loop                      look for nxt EFR bit
360 
361 cache_ctr_tab:
362           epplb     wired_hardcore_data$cpu_a_cache_err_ctr_array
363           epplb     wired_hardcore_data$cpu_b_cache_err_ctr_array
364           epplb     wired_hardcore_data$cpu_c_cache_err_ctr_array
365           epplb     wired_hardcore_data$cpu_d_cache_err_ctr_array
366           epplb     wired_hardcore_data$cpu_e_cache_err_ctr_array
367           epplb     wired_hardcore_data$cpu_f_cache_err_ctr_array
368           epplb     wired_hardcore_data$cpu_g_cache_err_ctr_array
369           epplb     wired_hardcore_data$cpu_h_cache_err_ctr_array
370 " ^L
371 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
372 "
373 "         Internal subroutine for saving associative memory in the prds
374 "
375 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
376 
377 save_am:
378           eax3      4                             4 instructions to execute
379           eax6      3                             initialy set for DPS8 (4 sets of 16)
380           cmpx4     1,du                          is it a DPS8 CPU?
381           tze       sam1                          yes, go execute code
382           eax6      0                             no, only 1 set for each type on L68
383 
384 sam1:     xec       samt1-1,3                     load LB with proper AM type
385           lda       samt2-1,3                     load instruction to execute in A
386           sta       bp|mc.fim_temp                and save
387           eax7      0,6                           initialize counter
388 sam2:     eaq       0,7                           copy to qu
389           qls       4                             multiply by 16
390           cmpx3     2,du                          is it for sdw_am_regs?
391           tnz       *+2                           xfwr if no
392           qls       1                             yes, make it times 32
393           stcq      bp|mc.fim_temp,30             set quad offset
394           xec       bp|mc.fim_temp                execute instruction
395           eax7      -1,7                          count down
396           tpl       sam2                          do next set
397           eax3      -1,3                          count down instructions to exucute
398           tnz       sam1                          go do next instuction set
399           tra       0,1                           return to caller
400 
401 samt1:    epplb     prds$sdw_am_ptrs
402           epplb     prds$sdw_am_regs
403           epplb     prds$ptw_am_ptrs
404           epplb     prds$ptw_am_regs
405 
406 samt2:    ssdp      lb|0
407           ssdr      lb|0
408           sptp      lb|0
409           sptr      lb|0
410 
411 "^L
412 
413 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
414 "
415 "         Procedure to check if conditions are met for machine condition tracing
416 "         if conditions are not true for machine condition tracing, return is ic +1 (tra  0,0)
417 "         if conditions are met for machine condition tracing, then
418 "         return is ic +2 (tra   1,0), bb -> place to pick up history regs and
419 "         lb -> place to pick up machine conditions directly from machine condition trace buffer
420 "
421 "
422 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
423 
424 check_mct:
425           tsx1      save_fault_reg                save fault reg and get CPU type in x4
426           szn       pds$mc_trace_sw               is this process tracing machine conditions?
427           tpl       0,0                           return to caller if no
428           szn       pds$mc_trace_seg              Does user want to trace all M. Cs?
429           tze       cp_hregs                      xfer if seg number zero
430           lda       bp|mc.scu.ppr.psr_word        look at the psr
431           ana       scu.ppr.psr_mask,du           and out  everything except psr
432           cmpa      pds$mc_trace_seg              compare psr to object we are tracing
433           tze       cp_hregs                      xfer if psr = object we are tracing
434           lda       bp|mc.scu.tpr.tsr_word        look at tsr
435           ana       scu.tpr.tsr_mask,du           and out everthing except tsr
436           cmpa      pds$mc_trace_seg              compare tsr to object we are tracing
437           tnz       0,0                           return to caller if psr or tsr don't have seg
438 cp_hregs:
439           lprplb    pds$mc_trace_buf              get packed ptr to wired trace buffer
440           stx0      lb|mctseg.x0save              safe store return address
441           lxl5      lb|mctseg.hr_nxtad            x5 = rel ptr to next H. R. storage location
442           cmpx5     lb|mctseg.hr_lim              do we have to roll over the trace?
443           tmi       hr_roll                       xfer if no
444           ldx5      lb|mctseg.hr_strt             yes, pick up initial storage location
445           sxl5      lb|mctseg.hr_nxtad            store new location
446 hr_roll:
447           eax5      mctseg.hr_size,5              increment storage location
448           sxl5      lb|mctseg.hr_nxtad            set rel ptr to next H. R. storage location
449           eppbb     lb|-mctseg.hr_size,5          bb -> current HR storage location
450           tsx0      force_hist_regs               go save history regs in mc_trace buf
451           lprplb    pds$mc_trace_buf              get packed ptr to wired trace buffer
452           ldx0      lb|mctseg.x0save              restore return address
453           lxl5      lb|mctseg.mc_nxtad            x5 = rel ptr to next M. C. storage location
454           cmpx5     lb|mctseg.mc_lim              do we have to roll over the trace?
455           tmi       mc_roll                       xfer if no
456           ldx5      lb|mctseg.mc_strt             yes, pick up initial storage location
457           sxl5      lb|mctseg.mc_nxtad            store new location
458 mc_roll:
459           eax5      mctseg.mc_size,5              increment storage location
460           sxl5      lb|mctseg.mc_nxtad            set rel ptr to next M. C. storage location
461           epplb     lb|-mctseg.mc_size,5          lp -> current MC storage location
462           mlr       (pr),(pr)                     move the data to wired buffer
463           desc9a    bp|0,mctseg.mc_size*4
464           desc9a    lb|0,mctseg.mc_size*4
465           tra       1,0                           return to caller at ic +2
466 
467 
468 " ^L
469 
470 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
471 "
472 "         Procedure to reset mode registers to continue strobing
473 "         data into the history registers.
474 "
475 "
476 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
477 
478 reset_mode_reg:
479           epplb     prds$cache_luf_reg  point to cache/luf reg setting
480           lcpr      lb|0,02             set cache enable and full luf time
481 
482           lda       prds$mode_reg       retrieve template mode reg
483           ora       mr.enable_mr+mr.enable_hist,dl  enable mode reg and enable hist regs
484           sta       prds$mode_reg_enabled         save this mode reg value
485           epplb     prds$mode_reg_enabled         get pointer to temp mode reg value
486           lcpr      lb|0,04             reload the mode register
487           tra       0,0                           return to caller
488 
489 " ^L
490 
491 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
492 "
493 "         Procedures to suspend virtual time metering
494 "
495 "
496 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
497 
498           even                          anyone know why we do this?
499 v_time_init:
500           tsx7      get_times           get fault time and virtual time
501 
502           ldi       0,dl                clear indicators as a service to our caller
503           aos       pds$vtime_count     step virtual time count
504           tpnz      0,0                 if already set, don't meter
505 
506           staq      pds$time_v_temp     save for later
507           tra       0,0
508 
509 
510 
511           odd                           or this? actually, just why are they different?
512 fim_v_time_init:
513           tsx7      get_times           get times
514 
515           ldi       0,dl                clear indicators as a service to our caller
516           szn       pds$vtime_count     metering already?
517           tpl       0,0                 if so, return
518 
519           staq      pds$fim_v_temp      save current virtual time
520           ldaq      pds$virtual_delta   save current delta
521           staq      pds$fim_v_delta     ..
522           tra       0,0                 and return to caller
523 
524 
525 fim_v_time_init_ext:
526           eppbp     ap|2,*              let get_times clobber first arg
527           eppbp     bp|-mc.fault_time   ...
528           tsx0      fim_v_time_init
529           ldaq      pds$fim_v_temp      now, just like pds copies pds cells to stack...
530           staq      ap|2,*              we drop them as output arguments
531           ldaq      pds$fim_v_delta
532           staq      ap|4,*
533           short_return
534 
535 
536           even
537 get_times:
538           rccl      sys_info$clock_,*   read the clock
539           staq      bp|mc.fault_time    save time of fault/interrupt
540           sbaq      pds$cpu_time        compute virtual time
541           tra       0,7                 return to caller
542 
543 " ^L
544 
545 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
546 "
547 "         Procedures to reinstate virtual time metering
548 "
549 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
550 
551           even
552 v_time_calc:
553           lca       1,dl                decrement virtual time count
554           asa       pds$vtime_count     ..
555           tpl       0,0                 if others, don't meter
556 
557 v_calc_join:
558           rccl      sys_info$clock_,*   read the clock
559           adl       96,dl               add in correction delta
560           sbaq      pds$cpu_time        get current value of CPU time
561           sbaq      pds$time_v_temp     get time we used
562           staq      pds$time_v_temp     save temporarily
563 
564           adaq      pds$virtual_delta   compute virtual time increment
565           staq      pds$virtual_delta   and save
566 
567           ldaq      pds$time_v_temp     time used in AQ again
568           adaq      tc_data$delta_vcpu  compute total vcpu time
569           staq      tc_data$delta_vcpu  ..
570 
571           tra       0,0
572 
573 
574 
575           even
576 fim_v_time_calc:
577           szn       pds$vtime_count     metering virtual time?
578           tpl       0,0                 if not, just return
579 
580           ldaq      pds$virtual_delta   get current virtual delta
581           sbaq      pds$fim_v_delta     subtract original delta
582           adaq      pds$fim_v_temp      correct FIM time
583           staq      pds$time_v_temp     store corrected time
584           tra       v_calc_join         join common code
585 
586 
587 fim_v_time_calc_ext:
588           ldaq      ap|2,*              copy automatic values back to pds just like fim
589           staq      pds$fim_v_temp
590           ldaq      ap|4,*
591           staq      pds$fim_v_delta
592           tsx0      fim_v_time_calc
593           short_return
594 " ^L
595 
596           include   stack_frame
597 
598 " ^L
599 
600           include   stack_header
601           include   mctseg
602 
603 " ^L
604 
605           include   sys_trouble_codes
606 
607           include   mode_reg
608 
609           include   mc
610 
611 " ^L
612 
613           include   fault_vector
614 
615 
616 
617           end