1 " ***********************************************************
   2 " *                                                         *
   3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
   4 " *                                                         *
   5 " * Copyright, (C) Honeywell Information Systems Inc., 1984 *
   6 " *                                                         *
   7 " * Copyright (c) 1972 by Massachusetts Institute of        *
   8 " * Technology and Honeywell Information Systems, Inc.      *
   9 " *                                                         *
  10 " ***********************************************************
  11 
  12 " HISTORY COMMENTS:
  13 "  1) change(1985-11-27,Herbst), approve(1987-07-20,MCR7697),
  14 "     audit(1987-07-20,GDixon), install(1987-08-04,MR12.1-1055):
  15 "     Added system_message_ IPS signal.
  16 "  2) change(2021-11-06,Swenson), approve(2021-11-06,MCR10100),
  17 "     audit(2021-11-07,GDixon), install(2021-11-07,MR12.8-1007):
  18 "     Fix typo in comment regarding load of fault data word.
  19 "                                                      END HISTORY COMMENTS
  20 
  21 
  22 "
  23 " FIM - Multics Fault Intercept Module.
  24 "
  25 "         Modification record: (Date and Reason)
  26 "         85-03-20 by E.D. Schroth (UNCA) to clear exp under/overflow
  27 "                   indicators when restarting
  28 "         84-12-03 by EJ Sharpe for new security auditing
  29 "         08/22/84 by R. Michael Tague: Removed dm_shutdown_warning_ and
  30 "             dm_user_shutdown_ from table of signals.  Added
  31 "             system_shutdown_scheduled_ and dm_shutdown_scheduled_.
  32 "         07/16/84 by R. Michael Tague: Added dm_shutdown_warning_ and
  33 "                     dm_user_shutdown_ signals to the table of signals.
  34 "         December 1983 by Keith Loepere for hardcore breakpoint support
  35 "         831206 by E. N. Kittlitz for hex overflow support
  36 "         10 October 1983 by R. Coppola to meter faults and cache errors
  37 "         on a per-cpu basis.
  38 "         19 September 1983 by E. N. Kittlitz to set rfi+if for all overflows
  39 "         August 1983 by Keith Loepere for minor fix to null pointer fault
  40 "         13 October 1982 (Wednesday, this month) by E. N. Kittlitz for instruction size
  41 "         06 October 1982 by BIM to check for signal_entry fault
  42 "         in fim, running fim in collection 1.
  43 "         24 March 1983 by J. A. Bush for 16/32K cache parity data capture
  44 "         6 April 1983 by E. N. Kittlitz DRL in ring 0 causes crash.
  45 "         sometime by BIM for bootload multics.
  46 "         17 July 1981 by M. Weaver for undefined_pointer
  47 "         04 June 81 by J. A. Bush to fix some unreported bugs
  48 "         3 April 81 by Benson I. Margulies for null_pointer
  49 "         17 Jan 81 by J. Bongiovanni for fault_counters
  50 "         27 August 80 by J. A. Bush for the DPS8/70M
  51 "         25 march 80 by J. A. Bush to fix negative exp. overflow bug
  52 "         15 Jan 80 by J. A. Bush for cache parity error data capture
  53 "         24 July 79 by J. A. Bush for new signal_entry and to merge fim_table  back in.
  54 "         1 Feb 79 by D. Spector for new scs format for 8-cpu cioc
  55 "         2/8/76 by Noel I. Morris for new reconfig
  56 "         10/14/75 by R. Bratt for prelinking
  57 "         6/20/75 by S.Webber for static handlers
  58 "         3/75 by S. Webber for new restarting conventions and returning
  59 "                   history registers to users.
  60 "         5/29/74 by M. Weaver to special case out of bounds on stack
  61 "         11/1/73 by Steve Webber to allow truncation (stringsize) faults to be restarted
  62 "         10/15/73 by Steve Webber to correct some illegal procedure "fanout" mapping problems.
  63 "         07/21/71 by Richard H. Gumpertz to use prds_link to get prds segment number
  64 "         5/30/70             - Noel I. Morris
  65 
  66 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
  67 "
  68 " FIM is transferred to as the result of a fault. The control
  69 " unit data has been stored either in pds$fim_data or pds$signal_data.
  70 "
  71 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
  72 
  73 
  74           name      fim
  75           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
  76 
  77 
  78 " ^L
  79 
  80           link      prds_link,prds$+0
  81 
  82 
  83 
  84           bool      lprp_insts,760000
  85           bool      minus_128,400000
  86           bool      dp_opcode,2000
  87           bool      inst_bit27_on,400
  88           bool      op_code_mask,777400
  89           bool      fstr_inst,470000
  90           bool      dfstr_inst,472000
  91           bool      cu_hreg,40
  92           bool      apu_hreg,140
  93           bool      access_audit_flag,400000      " indicates in fault_table that fault is auditable
  94 
  95           tempd     v_temp              temporary for virtual time computation
  96           tempd     v_delta             temporary to remember virtual_delta
  97           tempd     pad(2)
  98           temp8     mach_cond(6)        machine conditions
  99           temp8     history_registers(16)
 100           tempd     mc_ptr              pointer to machine conditions
 101           tempd     call_ptr            pointer to fault handling routine
 102           tempd     arglist(4)          argument list
 103           temp      fcode               fault code
 104           temp      temp(3)             temporary cells
 105 
 106 " ^L
 107 
 108 " ACCESS_VIOLATION_ENTRY - Handle Access Violation Faults.
 109 
 110           segdef    access_violation_entry
 111 
 112           even
 113 access_violation_entry:
 114           spri      prs,*                         save prs
 115           eppbp     prs,*                         bp -> machine conditions
 116           sreg      bp|mc.regs                    save registers
 117           epplp     lp,*                          set lp value
 118           spl       bp|mc.eis_info                save eis ptrs and lengths
 119           tsx0      fim_util$fim_v_time_init      remember accrued virtual time
 120           tsx0      fim_util$check_fault  is it OK to take this fault?
 121 
 122           epaq      *                   get our segment number
 123           era       bp|mc.scu.ppr.psr_word  compare against procedure segment register
 124           ana       scu.ppr.psr_mask,du were we in the fim?
 125           tze       die_die_die_        suicide
 126 
 127           tra       fault_join
 128 " ^L
 129 " ONC_START_SHUT_ENTRY - entry to handle op-not-complete, startup and shutdown faults
 130 
 131           segdef    onc_start_shut_entry
 132 
 133           even
 134 onc_start_shut_entry:
 135           spri      prs,*                         save prs
 136           eppbp     prs,*                         bp -> machine conditions
 137           sreg      bp|mc.regs                    save registers
 138           epplp     lp,*                          set lp value
 139           spl       bp|mc.eis_info                save eis ptrs and lengths
 140           lpl       eight_angry_zeros             try to condition EIS box
 141           tsx0      fim_util$fim_v_time_init      remember accrued virtual time
 142 
 143           tsx0      fim_util$check_fault          kill Multics if not legal fault
 144           eppbb     pds$history_reg_data          bb -> place to store history regs
 145           tsx0      fim_util$check_mct            go save M.C.'s an hregs if required
 146           tsx0      fim_util$force_hist_regs      (ret ic +1) force save hregs in pds
 147           tra       onc_par_join                  go join common code
 148 "^L
 149 " drl_entry - entry to handle derail faults, special case of signal_entry.
 150 
 151           segdef    drl_entry
 152 
 153           even
 154 drl_entry:
 155           spri      sig_prs,*           save prs
 156           eppbp     sig_prs,*           bp -> machine conditions
 157           sreg      bp|mc.regs          save registers
 158           epplp     lp,*                set lp value
 159           spl       bp|mc.eis_info      what the hell...
 160           ldq       bp|mc.scu.ppr.prr_word check whether running in ring-0
 161           canq      scu.ppr.prr_mask,du ring number in ppr
 162           tnz       drl_join            not ring 0
 163 
 164           stz       scs$drl_message_pointer assume the worst
 165           lda       bp|mc.scu.ilc_word
 166           eppbb     0,au                offset of DRL
 167           lda       bp|mc.scu.ppr.psr_word
 168           ana       scu.ppr.psr_mask,du
 169           easpbb    0,au                segno of DRL
 170           lda       bb|0                get the DRL instruction
 171           ana       =o777777,du
 172           tze       drl_die             no operand
 173           cmpa      =o777777,du
 174           tze       breakpoint          drl -1 => breakpoint
 175 
 176           eawpbb    0,au                operand of DRL instruction
 177           sprpbb    scs$drl_message_pointer
 178 drl_die:  tra       fim_util$drl_fault_trouble punt ye system
 179 "^L
 180 " Handle a hardcore breakpoint - call bce
 181 
 182 breakpoint:
 183           eppap     flagbox$
 184           lda       fgbx.breakpoint,du
 185           orsa      ap|fgbx.rtb
 186 
 187           eppap     breakpoint_page$              place so bce can find
 188           tsx0      fim_util$copy_mc
 189           scpr      bp|bkpt_page.mode_reg,06
 190           sdbr      bp|bkpt_page.dbr
 191           sbar      bp|bkpt_page.bar
 192 
 193           tsx0      fim_util$reset_mode_reg
 194 
 195           lda       1,du                          make so simple bce go works
 196           adla      bp|mc.scu.ilc_word
 197           sta       bp|mc.scu.ilc_word
 198           lda       scu.cu.rfi,dl                 refetch instruction
 199           sta       bp|mc.scu.cu_stat_word
 200 
 201           eppsb     pds$stack_0_ptr,*
 202           ldx7      push
 203           tsx0      fim_util$push_stack           prepare for pmut call
 204 
 205           call      pmut$bce_and_return
 206 
 207           eppap     flagbox$
 208           lca       fgbx.breakpoint,du
 209           sba       1,dl                make sure bit off
 210           ansa      ap|fgbx.rtb
 211 
 212           eppap     prs,*               ap -> wired-down m.c.
 213           mlr       (pr),(pr)
 214           desc9a    bp|mc.scu,8*4
 215           desc9a    ap|mc.scu,8*4
 216 
 217           sprisp    sb|stack_header.stack_end_ptr pop frame
 218 
 219           eppbp     breakpoint_page$              return to break
 220           lpl       bp|mc.eis_info
 221           lreg      bp|mc.regs
 222           lpri      bp|mc.prs
 223           rcu       scu,*               return to breakpoint
 224 "^L
 225 " parity_entry - entry to handle parity faults
 226 
 227           segdef    parity_entry
 228           even
 229 parity_entry:
 230           lcpr      cache_off,02                  turn cache off in case this is cache parity
 231           spri      prs,*                         save prs
 232           eppbp     prs,*                         bp -> machine conditions
 233           sreg      bp|mc.regs                    save registers
 234           epplp     lp,*                          set lp value
 235           spl       bp|mc.eis_info                save eis ptrs and lengths
 236           tsx0      fim_util$fim_v_time_init      remember accrued virtual time
 237           eppbb     pds$history_reg_data          bb -> place to store history regs
 238           tsx0      fim_util$check_mct            go save M. C.'s and hregs if required
 239           tsx0      fim_util$force_hist_regs      (ret ic +1) force save hregs in pds
 240           lda       bp|mc.fault_reg               load fault reg
 241           cana      12,dl                         is it cache store or cache dir parity?
 242           tnz       csd_par                       xfer if yes
 243           tsx0      fim_util$check_fault          no, kill Multics if parity in hardcore etc.
 244           tra       onc_par_join                  and join common code
 245 
 246 csd_par:  stz       pds$cpar_info                 initialize cache parity info structure
 247           cana      4,dl                          is it cache store parity?
 248           tnz       cstr_par                      xfer if yes
 249           tsx0      fim_util$check_fault          no cache dir parity
 250           tsx0      save_cache                    go save cache enable bits
 251           tra       onc_par_join                  and join common code
 252 
 253 cstr_par: lda       bp|mc.scu.cpu_no_word         Get the cpu number in A
 254           ana       scu.cpu_no_mask,dl
 255           arl       scu.cpu_shift                 right justify in AL
 256           ldx1      scs$processor_data,al         Get cache size
 257           anx1      7,du                          in X1
 258           eax1      -1,1                          can't have 0 size at this point
 259           epaq      fim_abs_seg$                  get ptr to abs seg
 260           als       1                             multiply by 2
 261           eax7      0,au                          copy segno to x7
 262           eppap     fim_abs_seg$                  set ap with abs_seg ptr
 263           eax2      15*2                          set initial cu hreg index
 264 cuhrlp:   eax5      15*2                          set initial apu hreg index
 265           tsx0      fnd_crd                       go check for cache read cycle
 266           tra       apuhrlp                       return ic+1, cache read (L68)
 267           tra       dps8_hit                      return ic+2, cache read (DPS8)
 268 dec_cux:  eax2      -2,2                          return ic+3, not cache read
 269           tmi       no_find                       exit if no more cu hregs
 270           tra       cuhrlp                        go get next cu hreg
 271 
 272 apuhrlp:  ldaq      bb|apu_hreg,5                 load next apu hreg
 273           cana      apuhra.fap+apuhra.fanp,dl     is this final address (fanp or fap)?
 274           tze       dec_apx                       xfer if no, skip to next apu hreg
 275           qrl       apuhra.finadd_shift           right justify abs addr
 276           anq       =o777,dl                      and out upper addr bits
 277           cmpq      bp|mc.fim_temp                is this the same as cu addr?
 278           tze       addmatch                      xfer if yes
 279 dec_apx:  eax5      -2,5                          no, go to nxt apu hreg
 280           tmi       dec_cux                       get nxt cu hreg is apu hregs exhausted
 281           tra       apuhrlp                       get nxt apu hreg
 282 
 283 addmatch: lda       bb|apu_hreg+1,5               matching cu and apu address
 284           cana      apuhra.encache,dl             is segment encacheable?
 285           tze       dec_cux                       xfer if no, go to nxt cu/apu match
 286 dps8_hit:                                         " Enter here if dps8 cache read
 287           arl       12                            zero out all but 24 bit address
 288           sta       pds$cpar_info                 and save
 289           eax6      0,al                          copy lower 256k address to x6
 290           anx6      c_256k_mask,1                 make mod <cache size> address
 291           ana       c_abs_addr_mask,1             make absaddr mod <cache size>
 292           als       12                            shift into position
 293           ora       sdw.valid,dl                  set directed fault bit
 294           ldq       c_sdw_bounds,1                set up rest of sdw
 295           staq      dseg$,7                       set sdw in dseg
 296           cams                                    "clear associative memory
 297           camp
 298           ldaq      ap|0,6                        get memory contents
 299           staq      pds$cpar_mem_data             and save
 300           anx6      c_lv_st_mask,1                make address start at level 0
 301           eax3      -4                            x3 counts levels
 302 cparlvlp: ldi       scu.ir.parm,dl                set parity mask
 303           lcpr      cache_to_reg_mode,02          set cache dump mode
 304           ldaq      ap|0,6                        dump cache contents
 305           lcpr      cache_off,02                  reset cache dump mode
 306           sti       bp|mc.fim_temp                save indicators
 307           eraq      pds$cpar_mem_data             exclusive or it with data in mem
 308           staq      pds$cpar_err_data             save it
 309           ldi       0,dl                          reset parity mask
 310           lda       bp|mc.fim_temp                load indicators
 311           cana      scu.ir.par,dl                 parity error?
 312           tnz       cpar_hit                      xfer if yes
 313 nxt_lvl:  adx6      c_lv_inc_tab,1                get set for nxt level
 314           eax3      1,3                           any more levels?
 315           tmi       cparlvlp                      yes, go to nxt level
 316           tra       dec_cux                       no, go check previous read
 317 
 318 cpar_hit: ldi       scu.ir.oflm,dl                mask overflows
 319           lcaq      pds$cpar_err_data             get compliment of XOR data
 320           ldi       0,dl                          reset overflow mask
 321           anaq      pds$cpar_err_data             and 2s compliment data with itself
 322           cmpaq     pds$cpar_err_data             if single bit failure, it should compare
 323           tnz       nxt_lvl                       multiple bit failure, go try nxt level
 324           ldi       scu.ir.parm,dl                set parity mask
 325           lcpr      cache_to_reg_mode,02          set cache dump mode
 326           ldaq      ap|0,6                        dump cache contents
 327           lcpr      cache_off,02                  reset cache dump mode
 328           staq      pds$cpar_err_data             save it
 329           ldi       0,dl                          reset parity mask
 330           eaa       0,6                           copy level info to a
 331           arl       c_lv_shift,1                  position per cache size
 332           ana       =o300,du                      and out all but level
 333           ora       =o400000,du                   set flag for data capture
 334           orsa      pds$cpar_info                 and save
 335 no_find:  lda       0,du
 336           ldq       0,du                          zero out abs seg sdw
 337           staq      dseg$,7
 338           cams      4                             clear assosiative memory and cache
 339           camp
 340           tsx0      save_cache                    go save cache enable bits
 341           tsx0      fim_util$check_fault          now go check to see if fault in hardcore
 342           tra       onc_par_join                  and go join common code
 343 " ^L
 344 " signal_entry - entry to handle faults that are directly signalable
 345 " in the outer rings (not ring 0)
 346 
 347           segdef    signal_entry
 348 
 349           even
 350 signal_entry:
 351           spri      sig_prs,*                     save prs
 352           eppbp     sig_prs,*                     bp -> machine conditions
 353           sreg      bp|mc.regs                    save registers
 354           epplp     lp,*                          set lp value
 355           spl       bp|mc.eis_info                save eis ptrs and lengths
 356 drl_join:
 357           tsx0      fim_util$fim_v_time_init      remember accrued virtual time
 358           tsx0      fim_util$check_fault          kill Multics if not legal fault
 359           lda       bp|mc.scu.fault_data_word
 360           ana       scu.fi_num_mask,dl            get fault address
 361 signal_it:
 362           sta       bp|mc.errcode                 temporarily save fault code
 363           arl       1                             divide by 2
 364           ldq       prds$processor_tag            get cpu num
 365           xec       fault_ctr_tab,ql              BB => per-cpu fault ctr array
 366           aos       bb|0,al                       and increment the fault ctr
 367           als       1                             multiply by 2
 368           ldaq      fault_table,al                pick up table entry
 369           anq       access_audit_flag,dl          do we need to audit this event?
 370           tze       no_sig_audit                  xfer if no.
 371           tsx1      call_audit_for_signal         yes, go do it (will push frame)
 372 no_sig_audit:
 373           tra       0,au                          dispatch on entry value
 374 
 375 call_signaller:                                   "most signalable faults come here directly
 376           eppbb     pds$history_reg_data          bb -> place to store history regs
 377           tsx0      fim_util$check_mct            go save M. C.'s and hregs if required
 378           tsx0      fim_util$hist_regs            (ret ic +1) save hregs in pds
 379           tsx0      fim_util$reset_mode_reg       (ret ic +2) turn them back on now
 380           lda       bp|mc.errcode                 get fault code for retrieving name
 381           arl       1                             divide by 2
 382           sta       bp|mc.fim_temp                save the sct index for signal_
 383           als       1                             multiply by 2
 384           stz       bp|mc.errcode                 initialize error code
 385           lda       fault_table+1,al              pick up second word of fault table entry
 386           eppbb     0,au                          get pointer to name from its left half word
 387           eppab     pds$condition_name            get pointer to place to store name
 388           ldq       bb|0                          get first word of string for ACC size
 389           qrl       27                            right justify size of string
 390           adlq      1,dl                          add 1 for count character
 391           mlr       (pr,rl),(pr),fill(0)
 392           desc9a    bb|0,ql
 393           desc9a    ab|0,32
 394           eppsb     pds$stack_0_ptr,*             set SB to the ring 0 stack
 395           tra       signaller$signaller           now give control to the signaller
 396 "^L
 397 call_audit_for_signal:                  " security auditing for signal_entry
 398           ldq       audit_flags.faults,dl get process's audit flags
 399           canq      pds$audit_flags     Check appropriate audit flag
 400           tze       0,1                 Not auditing, go back
 401 
 402           eppsb     pds$stack_0_ptr,*   make FIM's stack frame on the ring 0 stack
 403           ldx7      push                ..
 404           tsx0      fim_util$push_stack ..
 405           eppap     mach_cond           ap -> place for machine conditions
 406           tsx0      fim_util$copy_mc    copy machine conditions into stack frame
 407           inhibit   off       <-><-><-><-><-><-><-><-><-><-><-><->
 408           spribp    mc_ptr              set mc_ptr in stack frame
 409           eppap     mc_ptr              Get machine conditions pointer
 410           spriap    arglist+2           Stuff it in arg list
 411           fld       =1b24,dl            One argument
 412           ora       =o4,dl              Make arglist header
 413           staq      arglist             Stuff it where it belongs
 414           call      access_audit_log_fault_$log_fault(arglist)        Call fault entry in auditor
 415           eppap     pds$signal_data     copy M.C.s back to signal data
 416           tsx0      fim_util$copy_mc
 417           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
 418           sprisp    sb|stack_header.stack_end_ptr reset stack end pointer (and pop frame)
 419           lda       bp|mc.errcode       restore the fault code from the MC
 420           lda       fault_table,al      and pick up table entry
 421           tra       0,1                 and return
 422 " ^L
 423 " PRIMARY_FAULT_ENTRY - Most faults arrive at this entry.
 424 
 425           segdef    primary_fault_entry
 426 
 427           even
 428 primary_fault_entry:
 429           spri      prs,*                         save prs
 430           eppbp     prs,*                         bp -> machine conditions
 431           sreg      bp|mc.regs                    save registers
 432           epplp     lp,*                          set lp value
 433           spl       bp|mc.eis_info                save eis ptrs and lengths
 434           tsx0      fim_util$fim_v_time_init      remember accrued virtual time
 435           tsx0      fim_util$check_fault          kill Multics if not legal fault
 436 fault_join:
 437           eppbb     pds$history_reg_data  bb -> place to store history regs
 438           tsx0      fim_util$check_mct  go save M.C.'s an hregs if required
 439           tsx0      fim_util$hist_regs  (ret ic +1) save hregs (if not saved by check_mct)
 440 onc_par_join:
 441           tsx0      fim_util$reset_mode_reg   (ret ic +2) turn them back on now
 442           eppsb     pds$stack_0_ptr,*   make FIM's stack frame on the ring 0 stack
 443           ldx7      push                ..
 444           tsx0      fim_util$push_stack ..
 445           eppap     mach_cond           ap -> place for machine conditions
 446           tsx0      fim_util$copy_mc    copy machine conditions into stack frame
 447           spribp    mc_ptr              set mc_ptr in stack frame
 448           ldaq      pds$fim_v_temp      save CPU time at start of fault
 449           staq      v_temp              ..
 450           ldaq      pds$fim_v_delta     save virtual delta at start of fault
 451           staq      v_delta             ..
 452           szn       pds$hregs_saved     do we want to copy hregs?
 453           tze       no_hist
 454           eppap     history_registers   bb -> hregs either in mc_trace buffer or pds
 455           mlr       (pr),(pr)           copy hregs into stack frame
 456           desc9a    bb|0,128*4
 457           desc9a    ap|0,128*4
 458 no_hist:  inhibit   off       <-><-><-><-><-><-><-><-><-><-><-><->
 459 
 460 " Dispatch on Fault Code.
 461 
 462           stz       bp|mc.errcode       clear the error code
 463           lda       bp|mc.scu.fault_data_word get fault number
 464           ana       scu.fi_num_mask,dl
 465 set_fault:
 466           sta       fcode               save the fault code
 467           arl       1                   divide by 2
 468           ldq       prds$processor_tag  get cpu num in QL
 469           xec       fault_ctr_tab,ql    BB=> per-cpu fault counter
 470           aos       bb|0,al             increment the fault counter
 471           sta       bp|mc.fim_temp      save the fault code in the MC
 472           als       1                   multiply by 2
 473           ldaq      fault_table,al      pick up table entry
 474           anq       access_audit_flag,dl          get special action code for this fault
 475           tze       no_pri_audit        xfer if no need to audit
 476           tsx1      call_audit_for_primary        we need to audit this event
 477 no_pri_audit:
 478           tra       0,au                dispatch on entry value
 479 
 480 fault_ctr_tab:
 481           eppbb     wired_hardcore_data$cpu_a_flt_ctr_array
 482           eppbb     wired_hardcore_data$cpu_b_flt_ctr_array
 483           eppbb     wired_hardcore_data$cpu_c_flt_ctr_array
 484           eppbb     wired_hardcore_data$cpu_d_flt_ctr_array
 485           eppbb     wired_hardcore_data$cpu_e_flt_ctr_array
 486           eppbb     wired_hardcore_data$cpu_f_flt_ctr_array
 487           eppbb     wired_hardcore_data$cpu_g_flt_ctr_array
 488           eppbb     wired_hardcore_data$cpu_h_flt_ctr_array
 489 " ^L
 490 
 491 call_audit_for_primary:                 " security auditing for primary_fault_entry
 492           ldq       audit_flags.faults,dl get process's audit flags
 493           canq      pds$audit_flags     Check appropriate audit flag
 494           tze       0,1                 Not auditing, go back
 495           eppap     mc_ptr              Get machine conditions pointer
 496           spriap    arglist+2           Stuff it in arg list
 497           fld       =1b24,dl            One argument
 498           ora       =o4,dl              Make arglist header
 499           staq      arglist             Stuff it where it belongs
 500           call      access_audit_log_fault_$log_fault(arglist)  Call fault entry in auditor
 501           lda       fcode               Pick up the fault code again
 502           lda       fault_table,al      Pick up the table entry
 503           tra       0,1                 Go back
 504 
 505 "^L
 506 
 507 "         Set up the call to the appropriate handler.
 508 "
 509 "         The right half of the accumulator contains an offset
 510 "         in the fim's linkage section of the procedure to call
 511 "         to handle the fault.
 512 "
 513 "         All handlers are called in the following way:
 514 "
 515 "         call handler (mc_ptr)
 516 "
 517 "         where mc_ptr points to the machine conditions, not the
 518 "         SCU data.
 519 "
 520 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 521 
 522 
 523 call_signaller_signal:
 524           arg       call_signaller
 525           arg       call_signal
 526 
 527 standard.signal_check_coll:
 528           eax0      1
 529           tra       standard.check_common
 530 
 531 standard.signaller_check_coll:
 532           eax0      0
 533 standard.check_common:
 534           ldq       sys_info$initialization_state
 535           cmpq      1,dl
 536           tmoz      call_signaller_signal,x0*
 537 
 538 standard:
 539           eppap     lp|0,al*            generate pointer to the handler
 540           spriap    call_ptr            save the handler pointer
 541 
 542           fld       =1b24,dl            set up argument list header (1 argument)
 543           ora       =o4,dl
 544           staq      arglist
 545 
 546           eppap     mc_ptr              set up argument list (1st arg is mc_ptr)
 547           spriap    arglist+2
 548 
 549           tra       call
 550 
 551 " ^L
 552 "         Access Violation faults
 553 "
 554 "         All access violation subcases are separated out
 555 "         in the next sequence of code. Some are signalled, some are handled
 556 "         by the system.
 557 "
 558 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 559 
 560 
 561 access_violation:
 562           lda       bp|mc.scu.fault_data_word get sub-class of access violation fault
 563           ana       -1,du               leave only sub-class bits
 564           eax7      0                    Determine which is highest bit on.
 565 acv_bit_loop:
 566           cana      =o400000,du          Test bit.
 567           tnz       acv_bit_end
 568 
 569           eax7      2,7                  On to next bit.
 570           als       1
 571           tnz       acv_bit_loop         Unless all bits off.
 572 
 573 acv_bit_end:
 574           eaa       avf,7     generate simulated code word
 575           cmpa      oob,du    see if bound fault (if so make special checks)
 576           tze       check_special_oob   yes, make tests
 577 
 578           tra       fixindex_1          must be normal access violation of some type
 579 
 580 check_special_oob:
 581           ldq       bp|mc.scu.tpr.tsr_word "fetch the TSR
 582           anq       scu.tpr.tsr_mask,du leave only segment number
 583           eax7      null                get set for simfault
 584           cmpq      =o077777,du         is it a null pointer?
 585           tze       fixindex            yes, handle the null pointer.
 586           cmpq      =o077776,du         is a terminate process?
 587           tze       term_it             yes, go handle it
 588           eax7      undefp              get set for undefined_pointer
 589           cmpq      =o077775,du         is it an undefined pointer?
 590           tze       fixindex            yes, handle it
 591           eax7      stk_oob             get set for out_of_bounds on stack
 592           erq       bp|mc.prs+6*2       exclusive or  stack segno with  tsr
 593           anq       =o077777,du         set indicators to note any difference
 594           tze       fixindex            no,  call handler to extend stack
 595           tra       fixindex_1          not special oob, treat as real oob
 596 
 597 
 598 fixindex:
 599           eaa       0,7                 new index in A
 600 fixindex_1:
 601           sbla      fault_table,du  get relative address
 602           arl       18                  right-justify
 603           tra       set_fault           back to the dispatch table
 604 
 605 "^L
 606 "         Command faults
 607 "
 608 "         The command fault could be either hardware oriented, configuration
 609 "         oriented, or an attempt to load a faulting packed pointer.
 610 "
 611 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 612 
 613 
 614 command_fault:
 615           eax7      com       assume normal command fault
 616           ldq       bp|mc.scu.port_stat_word check illegal action
 617           canq      scu.ial_mask,dl
 618           tnz       fixindex            nonzero, treat as normal case
 619           ldq       bp|scu.even_inst_word check for LPRPxx instruction
 620           anq       =o770400,dl
 621           cmpq      lprp_insts,dl
 622           tnz       fixindex            isn't LPRPxx, treat as normal
 623 
 624 "         It is packed pointer fault. See if system version.
 625 
 626           eax7      ppf
 627           ldq       bp|mc.scu.ca_word   pick up faulting pointer pair
 628           lda       bp|mc.scu.tpr.tsr_word
 629           ana       scu.tpr.tsr_mask,du
 630           easp3     0,au                generate pointer
 631           eawp3     0,qu
 632           lda       bb|0                pick up the packed pointer
 633           cana      =o100000,du         check system bit
 634           tze       fixindex            not ON. Treat as normal packed pointer fault
 635           ana       =o000777,du
 636           cmpa      3,du
 637           tpl       fixindex
 638           als       1                   multiply by 2
 639           eax7      sppf,au
 640           tra       fixindex
 641 " ^L
 642 "         Overflow faults
 643 "
 644 "         The overflow fault could result from one of:
 645 "
 646 "         fixedoverflow
 647 "         exponent overflow
 648 "         exponent underflow
 649 "         stringesize (EIS truncation fault)
 650 "
 651 "
 652 "         The following code looks at the indicators to see what kind
 653 "         of overflow fault occured and to remap the fault into the
 654 "         corresponding name.
 655 "
 656 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 657 
 658 
 659           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
 660 split_overflow:
 661           lda       scu.cu.rfi+scu.cu.if,dl       set rfi and if bits
 662           orsa      bp|mc.scu.cu_stat_word        in cu status word
 663           ldq       bp|mc.scu.indicators_word     get the indicators and ilc
 664           eax3      0                             set ^hex mode
 665           canq      scu.ir.hex,dl
 666           tze       sov_binary                    IR bit not set, so binary it is
 667           szn       pds$hfp_exponent_enabled      is per-process enablement on?
 668           tze       sov_binary                    nope
 669           eax3      1                             hex mode if exponent ufl/ofl
 670 sov_binary:
 671           canq      scu.ir.ovfl,dl                is it "fixedoverflow"?
 672           tnz       ck_eis_size                   yes go check for eis size.
 673           canq      scu.ir.eufl,dl                is it "underflow"?
 674           tze       ck_eovfl                      no, go check for exp overflow
 675           eax7      eufl                          yes, set exp underflow index
 676           tsx1      ck_str_rd                     go get op_code from object seg
 677           tra       sig_index                     return (ic+1), don't restart EIS
 678           tra       set_und_rfi                   return (ic+2) don't increment ic
 679           adlq      1,du                          return (ic+3) increment ic
 680           stq       bp|mc.scu.ilc_word            by one and restore ic word
 681 set_und_rfi:
 682           stz       bp|mc.regs+4                  zero out saved a
 683           stz       bp|mc.regs+5                  and q regs
 684           lda       minus_128,du                  and set e reg to -128
 685           sta       bp|mc.regs+6
 686           ldq       pds$exp_undfl_rest            restart fault in the fim?
 687           qls       0,x3                          shift according to bin/hex mode
 688           tpl       sig_index                     xfer if no, go signal fault
 689           ldq       prds$processor_tag            restarting so count fault here. get cpu num
 690           xec       fault_ctr_tab,ql              BB => per-cpu fault ctr array
 691           aos       bb|(eufl-fault_table)/2       and increment the fault ctr
 692           lda       bp|mc.scu.indicators_word     get indicator reg
 693           ana       -(scu.ir.neg+scu.ir.eufl+1),dl negative and exp underflow indicators off
 694           ora       scu.ir.zero,dl                and set zero indicator
 695 und_ovr_rest:
 696           stba      bp|mc.scu.indicators_word,14  and restore indicators
 697           lca       scu.ir.eufl+scu.ir.eovf+1,dl  reset exp over/under flow indicators
 698           ansa      bp|mc.scu.indicators_word
 699           tsx0      fim_util$reset_mode_reg       turn hregs back on
 700           sznc      pds$connect_pending           is connect pending?
 701           tze       no_con_pend                   if not, skip next
 702           lxl1      prds$processor_tag            CPU tag in X1
 703           cioc      scs$cow_ptrs,1*               do a connect now
 704           lra       =0                            prevent ring alarm before cioc takes
 705 no_con_pend:
 706           lreg      bp|mc.regs                    restore the registers
 707           lpri      bp|mc.prs                     and the prs
 708           rcu       sig_scu,*                     return to faulting location
 709 
 710 ck_eovfl:
 711           canq      scu.ir.eovf,dl                is it "overflow"?
 712           tze       ck_trunc                      no, go check truncation
 713           eax7      eovf                          yes, load table index
 714           tsx1      ck_str_rd                     check for fstr/dfstr instr
 715           tra       sig_index                     return (ic+1), don't restart EIS
 716           tra       ck_ovfl_rest                  return (ic+2), don't increment ic
 717           adlq      1,du                          return (ic+3) increment ic
 718           stq       bp|mc.scu.ilc_word            by one and restore ic word
 719 ck_ovfl_rest:
 720           ldq       pds$exp_ovfl_rest             restart fault in fim?
 721           qls       0,x3                          shift according to bin/hex
 722           tpl       sig_index                     xfer if no, go signal fault
 723           ldq       prds$processor_tag            restarting, so count fault here. get cpu num
 724           xec       fault_ctr_tab,ql              BB => per-cpu fault ctr array
 725           aos       bb|(eovf-fault_table)/2       and increment the fault ctr
 726           eax3      0,x3                          re-sex mode
 727           tnz       hex_ovfl
 728           canx5     dp_opcode,du                  yes, is this double precision?
 729           tnz       doub_prec                     xfer if yes
 730           fld       pds$eovfl_value               no, load sp restart value
 731           tra       str_rest_vlu                  and go store it
 732 
 733 doub_prec:
 734           dfld      pds$eovfl_value               load dp restart value
 735 str_rest_vlu:
 736           szn       bp|mc.regs+4                  is this a negative overflow?
 737           tpl       no_negate                     no, store value as is
 738           fneg      0                             yes, negate the value
 739 no_negate:
 740           staq      bp|mc.regs+4                  and store it
 741           ste       bp|mc.regs+6                  store exponent
 742           lda       scu.cu.rfi+scu.cu.if,dl       set rfi and if bits
 743           orsa      bp|mc.scu.cu_stat_word        in cu status word
 744           lda       bp|mc.scu.indicators_word     get indicator register
 745           ana       -(scu.ir.eovf+1),dl           turn off overflow indicator
 746           tra       und_ovr_rest                  go restart overflow
 747 
 748 hex_ovfl: ldi       scu.ir.hex,dl                 enable hex mode
 749           canx5     dp_opcode,du                  yes, is this double precision?
 750           tnz       hex_doub_prec                 xfer if yes
 751           fld       pds$hex_eovfl_value           no, load sp restart value
 752           ldi       0,dl                          clear hex mode
 753           tra       str_rest_vlu                  and go store it
 754 
 755 hex_doub_prec:
 756           dfld      pds$hex_eovfl_value           load dp restart value
 757           ldi       0,dl                          clear hex mode
 758           tra       str_rest_vlu
 759 
 760 ck_eis_size:
 761           eax7      ovfl                          set up for "fixedoverflow"
 762           canq      scu.ir.mif,dl                 is it EIS fault?
 763           tnz       ck_sz_loc                     xfer if yes
 764 sig_index:
 765           eaa       0,7                           copy  fault index to a
 766           sbla      fault_table,du                get relative address
 767           arl       18                            right justify
 768           tra       signal_it                     and go signal fault
 769 
 770 ck_sz_loc:
 771           lda       bp|scu.even_inst_word         is this potenialy eis instr?
 772           cana      inst_bit27_on,dl              if bit 27 is not on, can't be eis inst
 773           tze       sig_index                     no, signal fixedoverflow
 774           eax7      size_loc                      set size fault index
 775           tra       sig_index                     and go signal it
 776 
 777 ck_trunc:
 778           canq      scu.ir.tru,dl                 is it truncation?
 779           tze       fim_util$fault_trouble        hardware error id none of above
 780           eax7      trun                          yes, set truncation fault index
 781 "
 782 "         We have a "stringsize" condition. Set up the machine
 783 "         conditions so we can restart the instruction.
 784 "
 785           szn       pds$pl1_machine               can we alter apparent machine ops?
 786           tze       sig_index                     xfer if no, bare 6180 machine
 787           tsx1      get_instruction_size
 788           adla      bp|mc.scu.ilc_word            increment ic by eis instr size
 789           sta       bp|mc.scu.ilc_word            and restore ic word
 790           lca       scu.ir.mif+1,dl               we must turn OFF this indicator so the next
 791           ansa      bp|mc.scu.indicators_word     EIS instruction will be correctly initialized
 792           lda       scu.cu.rfi+scu.cu.if,dl       set rfi and if bits
 793           orsa      bp|mc.scu.cu_stat_word        in cu status word
 794           tra       sig_index                     go signal "stringsize"
 795 
 796 "^L
 797 "         Illegal procedure faults
 798 "
 799 "         There are several subcases which are distinguished
 800 "         They are:
 801 "                   illegal op code
 802 "                   illegal address and modifier
 803 "                   other illegal procedure faults
 804 "
 805 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 806 
 807 
 808 illegal_procedure:
 809 
 810           epaq      *                   get our segment number
 811           era       bp|mc.scu.ppr.psr_word  compare against procedure segment register
 812           ana       scu.ppr.psr_mask,du were we in the fim?
 813           tze       die_die_die_        suicide
 814           lda       bp|mc.scu.fault_data_word get the fault data word into a register
 815           eax7      foc       get set for illegal op code
 816           cana      scu.fd.ioc,du
 817           tnz       sig_index           yes, use the given index
 818 
 819           eax7      bam       get set for bad modifier or address
 820           cana      scu.fd.ia_im,du
 821           tnz       sig_index
 822 
 823           eax7      ipr       get set for all other illegal procedure
 824           tra       sig_index
 825 "^L
 826 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 827 "
 828 "         fnd_crd - subroutine to check for cache read cycle in current CU history reg
 829 "         for cache parity diagnostics.
 830 "         return is ic+1, if L68 cache read cycle,
 831 "                   ic+2, if dps8 cache read cycle (A reg contains abs addr, in upper)
 832 "                   ic+3, if not a cache read cycle
 833 "
 834 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 835 
 836 fnd_crd:  ldaq      bb|cu_hreg,2                  load next cu hreg
 837           cmpx4     1,du                          is this a dps8 cpu?
 838           tze       cu_dps8                       xfer if yes, otherwise  L68
 839           canq      cuhra.dir,dl                  is this direct cu cycle?
 840           tnz       2,0                           xfer if yes, skip to next cu hreg
 841           lls       18                            position addr in al
 842           anq       =o760000,du                   mem cmd in qu
 843           tze       l68_rd_cmd                    xfer if single precision read
 844           cmpq      =o40000,du                    no, is it D.P read?
 845           tze       l68_rd_cmd                    xfer if yes
 846           tra       2,0                           not cache read, return ic+3
 847 
 848 l68_rd_cmd:
 849           ana       =o777,dl                      discard upper address
 850           sta       bp|mc.fim_temp                save address
 851           tra       0,0                           return ic+1, L68 cache read
 852 
 853 cu_dps8:  cana      cuhr.pia,du                   dps8 pia cycle?
 854           tze       2,0                           No, return ic+3
 855           cana      cuhr.internal,du              dps8 cache cycle?
 856           tze       2,0                           No, return ic+3
 857           lda       bb|cu_hreg+1,2                got a hit, load abs addr in A
 858           tra       1,0                           return ic+2, DPS8 cache read
 859 
 860 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 861 "
 862 "         save_cache - subroutine to save current state of cache memory enable bits
 863 "         (csh1 and csh2) located in the prds$cache_luf_reg and then reset the bits
 864 "
 865 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 866 
 867 save_cache:
 868           lda       prds$cache_luf_reg            get current cache enable bits
 869           ana       =o600000,dl                   and out all but csh1 and csh2
 870           als       10                            position
 871           orsa      pds$cpar_info                 and save in pds
 872           lda       3,dl
 873           ansa      prds$cache_luf_reg            turn off all cache enable bits
 874           tra       0,0                           return to caller
 875 "^L
 876 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 877 "
 878 "         ck_str_rd - subroutine to check if faulting instruction is a
 879 "         FSTR or DFSTR by looking in the object segment at psr|ic.
 880 "         entry:    tsx1      ck_str_rd
 881 "         in regs:  QR =      ilc,indicator word from scu data
 882 "                   BP ->     machine conditions
 883 "         out regs: QR        is unchanged
 884 "                   x5  =     instruction op code
 885 "         return:   ic+1 if bit 27 is on (EIS instruction)
 886 "                   ic+2 if instruction is fstr or dfstr instruction
 887 "                   ic+3 if any other instruction
 888 "
 889 "         NOTE:
 890 "         Theory of touching the text segment, as of 82-10-26.
 891 "         Yes, we might take a page or segment fault on the load
 892 "         of the instruction word.  However, it is VERY unlikely, given
 893 "         selection algorithms for evicting a page/segment.
 894 "         Further, the SDW and PTW are almost certainly in our AM, and
 895 "         we haven't been listening to any connects to get them out.
 896 "         If we take a seg_fault, we'll be using fim_data for machine
 897 "         conditions, and the only fim routines that call this routine
 898 "         are supposed to have come in using signal_data/signal_entry.
 899 "         Thus, we don't have to worry about our data getting clobbered.
 900 "         If we end up taking a seg-fault error (seg deleted), or
 901 "         a page-fault error, we're just going to signal that error
 902 "         anyhow. For anything except the original fault being in
 903 "         ring zero, this means crawlout.
 904 "         For ring zero, we would conceivably have to worry about
 905 "         someone having a handler for such an error and actually
 906 "         wanting to restart the original fault. "It'll never happen."
 907 "
 908 "         All this makes us think that it isn't worth the expense
 909 "         of moving the machine conditions to a stack frame before
 910 "         touching the text instruction.
 911 "
 912 "
 913 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 914 
 915 ck_str_rd:
 916           lda       bp|mc.scu.ppr.psr_word
 917           ana       scu.ppr.psr_mask,du
 918           eppab     0,qu                          set word offset, pr.ringno=0
 919           easpab    0,au                          get segno from psr
 920           lxl5      ab|0                          load instruction op code in x5
 921           anx5      op_code_mask,du               just look at op code
 922           canx5     inst_bit27_on,du              is this an EIS instruction?
 923           tnz       0,1                           yes, return ic+1
 924           cmpx5     fstr_inst,du                  fstr instruction?
 925           tze       1,1                           return ic+2 if yes
 926           cmpx5     dfstr_inst,du                 no, dfstr instruction?
 927           tze       1,1                           return ic+2 if yes
 928           tra       2,1                           no, return ic+3
 929 
 930 "^L
 931 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 932 "
 933 "         get_instruction_size - subroutine to determine the size of an instruction
 934 "         by looking in the object segment at psr|ic.
 935 "         entry:    tsx1      get_instruction_size
 936 "         in regs:  QR =      ilc,indicator word from scu data
 937 "                   BP ->     machine conditions
 938 "         out regs: QR        is unchanged
 939 "                   X5  =     instruction op code
 940 "                   AU =      instruction size
 941 "
 942 "         See the NOTE in check_str_rd.
 943 "
 944 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 945 
 946 get_instruction_size:
 947           lda       bp|mc.scu.ppr.psr_word
 948           ana       scu.ppr.psr_mask,du
 949           eppab     0,qu                          get word offset from ilc, set PRab.ring = 0
 950           easpab    0,au                          get segno from psr
 951           lxl5      ab|0                          load instruction op code in x5
 952           anx5      op_code_mask,du               just look at op code
 953           lda       1,dl                          default to 1 word
 954           canx5     inst_bit27_on,du              is this an EIS instruction?
 955           tze       0,1                           no, return
 956           eaa       gis_table                     table pointer
 957 
 958 gis_loop: cmpx5     0,au                          gone far enough down the table?
 959           tnc       gis_found                     got it
 960           eaa       1,au                          get next entry
 961           tra       gis_loop
 962 
 963 gis_found:
 964           lda       0,au                          return the size
 965           als       18
 966           tra       0,1
 967 
 968 
 969 gis_table:
 970           vfd       9o/057,1/1,8/0,18/4           mve,mvne
 971           vfd       9o/117,1/1,8/0,18/3           csl,csr,sztl,sztr,cmpb,mlr,mrl,cmpc
 972           vfd       9o/127,1/1,8/0,18/4           scd,scdr,scm,scmr
 973           vfd       9o/157,1/1,8/0,18/1           sptr
 974           vfd       9o/167,1/1,8/0,18/4           mvt,tct,tctr
 975           vfd       9o/177,1/1,8/0,18/1           lptr
 976           vfd       9o/217,1/1,8/0,18/3           ad2d,sb2d,mp2d,dv2d
 977           vfd       9o/227,1/1,8/0,18/4           ad3d,sb3d,mp3d,dv3d
 978           vfd       9o/277,1/1,8/0,18/1           lsdr,sbpb0-3,ssdr,lptp
 979           vfd       9o/307,1/1,8/0,18/3           mvn,btd,cmpn,dtb
 980           vfd       9o/777,9o/777,18/1            easpN,epbpN,sareg,spl,lareg,
 981                                                   " and all the others...
 982 
 983 " ^L
 984           inhibit   off       <-><-><-><-><-><-><-><-><-><-><-><->
 985 
 986 " Make call to fault handler.
 987 
 988 call:
 989           call      call_ptr,*(arglist) make the call
 990 
 991 
 992 " Test for error .
 993 
 994           eppbp     mach_cond           bp -> machine conditions
 995           szn       bp|mc.errcode       test for error
 996           tnz       call_signal         ..
 997 
 998           inhibit   on        <+><+><+><+><+><+><+><+><+><+><+><+>
 999 
1000           eppap     prs,*               ap -> wired-down m.c.
1001           mlr       (pr),(pr)
1002           desc9a    bp|mc.scu,8*4
1003           desc9a    ap|mc.scu,8*4
1004 
1005           ldaq      v_temp              restore virtual time parameters
1006           staq      pds$fim_v_temp      ..
1007           ldaq      v_delta             ..
1008           staq      pds$fim_v_delta     ..
1009 
1010           lda       fcode               get fault code again
1011           ldaq      fault_table,al  load table entry
1012 
1013           sprisp    sb|stack_header.stack_end_ptr reset stack end pointer
1014 
1015           sznc      pds$connect_pending must we do connect?
1016           tze       no_connect          if not, skip next
1017           lxl1      prds$processor_tag  CPU tag in X1
1018           cioc      scs$cow_ptrs,1*     do a connect now
1019           lra       =0                  prevent ring alarm before connect takes
1020 no_connect:
1021 
1022           canq      =o1,dl              suspend virtual time?
1023           tze       no_v_time_meter     if not, don't meter
1024           odd
1025           tsx0      fim_util$fim_v_time_calc  compute virtual delta
1026 no_v_time_meter:
1027 
1028           lpl       bp|mc.eis_info                save eis ptrs and lengths
1029           lreg      bp|mc.regs          restore the registers
1030           lpri      bp|mc.prs           and the prs
1031           rcu       scu,*               return to faulting location
1032 " ^L
1033 "         Come here when time to signal the event.
1034 
1035 
1036 call_signal:
1037           lda       bp|mc.fim_temp      resignal?
1038           cana      =o400000,dl         ..
1039           tze       call_signal.1       no.
1040 
1041           als       1                   get new fault code
1042           stca      fcode,07
1043 
1044 call_signal.1:
1045           lxl7      fcode               get fault code for retrieving name
1046           lda       fault_table+1,7  pick up second word of fault table entry
1047           eppbb     0,au                get pointer to name from its left half word
1048           eppab     pds$condition_name  get pointer to place to store name
1049           ldq       bb|0                get first word of string for ACC size
1050           qrl       27                  right justify size of string
1051           adlq      1,dl                add 1 for count character
1052           mlr       (pr,rl),(pr),fill(0)
1053           desc9a    bb|0,ql
1054           desc9a    ab|0,32
1055 
1056           eppap     pds$signal_data
1057           tsx0      fim_util$copy_mc
1058           eppsb     pds$stack_0_ptr,*   get a pointer to the base of the ring 0 stack
1059           szn       pds$hregs_saved
1060           tze       signaller$signaller
1061 
1062           mlr       (pr),(pr)
1063           desc9a    history_registers,128*4
1064           desc9a    ap|48,128*4
1065           tra       signaller$signaller now give control to the signaller
1066 
1067 " ^L
1068 
1069 " Arrive Here If Fault Occurred While Running in the FIM.
1070 
1071 die_die_die_:
1072           eppsb     pds$stack_0_ptr,*   get a pointer to the base of the ring 0 stack
1073 " Try to preserve stack history in case the original fault was
1074 " on the ring 0 stack.
1075 
1076           eppsp     sb|stack_header.stack_end_ptr,*  " where does it think it is?
1077           eax0      sp|0
1078           cmpx0     =o30000,du          reasonable ?
1079           tmoz      die_die_die_.use_end_ptr
1080 
1081           eppsp     sb|stack_header.stack_begin_ptr,* lay down frame at first available place
1082           sprisp    sb|stack_header.stack_end_ptr
1083 
1084 die_die_die_.use_end_ptr:
1085           ldx7      push                get size of stack frame
1086           tsx0      fim_util$push_stack make frame at base of pds
1087 
1088           lda       -1,du
1089           tra       die_die_die_.fake_ca
1090 
1091 term_it:
1092           lda       bp|mc.scu.ca_word   get computed address
1093 die_die_die_.fake_ca:
1094           ars       18                  convert to fixed bin
1095           sta       temp                save in stack (temporary cell)
1096           szn       tc_data$wait_enable
1097           tze       wired_fim$unexp_fault
1098           eppap     terminate_proc$terminate_proc  kill this process
1099           spriap    call_ptr            ..
1100           eppap     temp
1101           spriap    arglist+2
1102           fld       =1b24,dl            one argument
1103           ora       =o4,dl              make PL/1 calling sequence
1104           staq      arglist             ..
1105           tra       call                make the call
1106 
1107 
1108 " ^L
1109 
1110 " Storage and Constants.
1111 
1112 illegal_fault:                          "transfer vector for illegal fault
1113           tra       fim_util$fault_trouble
1114           inhibit   off       <-><-><-><-><-><-><-><-><-><-><-><->
1115 
1116 " The following items must be filled in at
1117 " system initialization time.
1118 
1119           segdef    lp,prs,scu,sig_prs,sig_scu
1120 
1121           even
1122 lp:       its       -1,1                lp value for fim
1123 prs:      its       -1,1                pointer to pds$fim_data
1124 scu:      its       -1,1                pointer to pds$fim_data+24
1125 sig_prs:  its       -1,1                pointer to pds$signal_data
1126 sig_scu:  its       -1,1                pointer to pds$signal_data+24
1127 
1128 push:     push                          " used to get size of stack frame
1129 cache_off:
1130           vfd       36/3                          constant to turn off cache, luf time max
1131 cache_to_reg_mode:
1132           oct       10003                         constant  to dump cache to aq, luf time max
1133 " ^L
1134 " Tables indexed by cache size used for cache parity error diagnosis
1135 
1136 c_sdw_bounds:                           "template for last half of abs_seg sdw
1137           vfd       1/,o14/177,3/sdw.read,o18/sdw.unpaged  for 2k (L68) cache
1138           vfd       1/,o14/777,3/sdw.read,o18/sdw.unpaged  for 8k (DPS8) cache
1139           vfd       1/,o14/777,3/sdw.read,o18/sdw.unpaged  for 8k (DPS8 VS & SC) cache
1140           vfd       1/,o14/1777,3/sdw.read,o18/sdw.unpaged  for 16k (DPS8 VS & SC) cache
1141           vfd       1/,o14/3777,3/sdw.read,o18/sdw.unpaged  for 32k (DPS8 VS & SC) cache
1142 c_lv_inc_tab:                           " to increment cache levels
1143           vfd       o18/1000,18/0       for 2k (L68) cache
1144           vfd       o18/4000,18/0       for 8k (DPS8) cache
1145           vfd       o18/4000,18/0       for 8k (DPS8 VS & SC) cache
1146           vfd       o18/10000,18/0      for 16k (DPS8 VS & SC) cache
1147           vfd       o18/20000,18/0      for 32k (DPS8 VS & SC) cache
1148 c_lv_st_mask:                           " to mask to level 0 for start
1149           vfd       o18/776,18/0        for 2k (L68) cache
1150           vfd       o18/3776,18/0       for 8k (DPS8) cache
1151           vfd       o18/3776,18/0       for 8k (DPS8 VS & SC) cache
1152           vfd       o18/7776,18/0       for 16k (DPS8 VS & SC) cache
1153           vfd       o18/17776,18/0      for 32k (DPS8 VS & SC) cache
1154 c_256k_mask:                            " to mask cache addr within mod cache size
1155           vfd       o18/3776,18/0       for 2k (L68) cache
1156           vfd       o18/17776,18/0      for 8k (DPS8) cache
1157           vfd       o18/17776,18/0      for 8k (DPS8 VS & SC) cache
1158           vfd       o18/37776,18/0      for 16k (DPS8 VS & SC) cache
1159           vfd       o18/77776,18/0      for 32k (DPS8 VS & SC) cache
1160 c_abs_addr_mask:                        " to mask abs addr to mod cache size for SDW
1161           vfd       12/0,o15/77774,9/0  for 2k (L68) cache
1162           vfd       12/0,o15/77760,9/0  for 8k (DPS8) cache
1163           vfd       12/0,o15/77760,9/0  for 8k (DPS8 VS & SC) cache
1164           vfd       12/0,o15/77740,9/0  for 16k (DPS8 VS & SC) cache
1165           vfd       12/0,o15/77700,9/0  for 32k (DPS8 VS & SC) cache
1166 c_lv_shift:                             " to shift level info for saving
1167           dec       3                   for 2k (L68) cache
1168           dec       5                   for 8k (DPS8) cache
1169           dec       5                   for 8k (DPS8 VS & SC) cache
1170           dec       6                   for 16k (DPS8 VS & SC) cache
1171           dec       7                   for 32k (DPS8 VS & SC) cache
1172 
1173 
1174 "^L
1175 " Dispatch Table for fim.
1176 "         modified 1/7/76 by D. M. Wells to add neti condition
1177 "         modified 2/26/76 by Noel I. Morris to place in separate segment.
1178 "         modified July 77 by T. Casey to add susp and term.
1179 "         modified Oct 77 by T. Casey to rename them to sus_ and trm_.
1180 "         modified 7/79 by J. A. Bush for new signal_entry of fim and to merge back into the fim
1181 
1182 
1183 
1184 "         Each entry in the dispatch table contains two words. The first
1185 "         word has an entrypoint in the fim to transfer to to handle the fault
1186 "         in the left half and a pointer relative to the linkage section of
1187 "         an external entry to call in the right half. If the left half
1188 "         is not standard, the right half is not defined.
1189 "         The second word contains a relative pointer to the ACC string name
1190 "         of the condition associated with the fault in the left half. The right
1191 "         half contains flags, which currently are used to indicate
1192 "         the necessity of auditing this fault
1193 "         (one or more bits in the left 15 bits of this field).
1194 "         The presence of the low-order bit indicates that the time
1195 "         for processing this fault should be accrued to virtual time.
1196 "
1197 "         ___________________________________________
1198 "         |                    |                    |
1199 "         |  FIM handler       |  External handler  |
1200 "         _^H|_____________________^H|_____________________^H|
1201 "         |                    |                    |
1202 "         |  ACC string ptr    |        FLAGS       |
1203 "         _^H|_____________________^H|_____________________^H|
1204 "
1205 "
1206 "         The following macro is used to generate entries in the dispatch table.
1207 "         The unique string (label) is the value of the SCT index.
1208 
1209           macro     table
1210           zero      &1,&2
1211           vfd       18/&U,18/&4
1212 
1213           use       names
1214 &U:       acc       "&3"
1215 
1216           use       main
1217 "
1218           &end
1219 
1220           use       names
1221           use       main
1222           join      /text/main,names
1223 
1224 " ^L
1225 
1226 
1227 " External Links.
1228 
1229           link      am_fault_link,access_viol$am_fault
1230           link      ring_alarm_fault_link,ring_alarm$fault
1231           link      seg_fault_link,seg_fault$seg_fault
1232           link      hardware_fault_link,hardware_fault$hardware_fault
1233           link      boundfault_link,boundfault$boundfault
1234           link      linkage_fault_link,link_snap$link_fault
1235           link      owc_link,outward_call_handler$outward_call_handler
1236           link      stack_oob_handler,stack_oob_handler$stack_oob_handler
1237 
1238 
1239 " ^L
1240 
1241           mod       8
1242 eight_angry_zeros:
1243           dec       0,0,0,0,0,0,0,0
1244 
1245           even
1246 fault_table:
1247           table     standard,hardware_fault_link,shutdown
1248           table     call_signaller,,store
1249           table     call_signaller,,mme1
1250           table     call_signaller,,fault_tag_1
1251           table     illegal_fault,,timer_runout
1252           table     command_fault,,command
1253           table     call_signaller,,derail
1254           table     call_signaller,,lockup
1255           table     illegal_fault,,connect
1256           table     standard,hardware_fault_link,parity
1257           table     illegal_procedure,,illegal_procedure
1258           table     standard,hardware_fault_link,op_not_complete
1259           table     standard,hardware_fault_link,startup
1260           table     split_overflow,,ovrflo
1261           table     call_signaller,,zerodivide
1262           table     illegal_fault,,execute
1263           table     standard.signaller_check_coll,seg_fault_link,seg_fault_error,1
1264 pf_loc:   table     illegal_fault,,page_fault_error
1265           table     illegal_fault,,directed_fault_2
1266           table     call_signaller,,directed_fault_3
1267           table     access_violation,,accessviolation
1268           table     call_signaller,,mme2
1269           table     call_signaller,,mme3
1270           table     call_signaller,,mme4
1271           table     standard.signaller_check_coll,linkage_fault_link,linkage_error
1272           table     call_signaller,,fault_tag_3
1273           table     illegal_fault,,undefined_fault
1274           table     illegal_fault,,undefined_fault
1275           table     illegal_fault,,undefined_fault
1276           table     illegal_fault,,undefined_fault
1277           table     illegal_fault,,undefined_fault
1278           table     illegal_fault,,trouble
1279 
1280 " ^L
1281 
1282 " Additional entries for subcases of faults.
1283 
1284 foc:      table     call_signaller,,illegal_opcode,access_audit_flag
1285 null:     table     call_signal,,null_pointer
1286 bam:      table     call_signaller,,illegal_modifier,access_audit_flag
1287 avf:      table     call_signal,,illegal_ring_order,access_audit_flag
1288           table     call_signal,,not_in_execute_bracket,access_audit_flag
1289           table     call_signal,,no_execute_permission,access_audit_flag
1290           table     call_signal,,not_in_read_bracket,access_audit_flag
1291           table     call_signal,,no_read_permission,access_audit_flag
1292           table     call_signal,,not_in_write_bracket,access_audit_flag
1293           table     call_signal,,no_write_permission,access_audit_flag
1294           table     call_signal,,not_a_gate,access_audit_flag
1295           table     call_signal,,not_in_call_bracket,access_audit_flag
1296           table     standard.signal_check_coll,owc_link,outward_call
1297           table     call_signal,,bad_outward_call,access_audit_flag
1298           table     call_signal,,inward_return,access_audit_flag
1299           table     call_signal,,cross_ring_transfer
1300           table     standard.signal_check_coll,ring_alarm_fault_link,ring_alarm_fault,1
1301           table     standard,am_fault_link,am_fault
1302 oob:      table     standard.signal_check_coll,boundfault_link,out_of_bounds,1
1303 ovfl:     table     call_signaller,,fixedoverflow
1304 eovf:     table     call_signaller,,overflow
1305 eufl:     table     call_signaller,,underflow
1306 trun:     table     call_signaller,,stringsize
1307 ipr:      table     call_signaller,,illegal_procedure
1308 stk_oob:  table     standard.signal_check_coll,stack_oob_handler,storage
1309 ppf:      table     call_signal,,packed_pointer_fault
1310 sppf:     table     call_signal,,lot_fault
1311           table     call_signal,,isot_fault
1312           table     call_signal,,system_packed_pointer
1313 quit_loc: table     call_signal,,quit
1314 alrm_loc: table     call_signal,,alrm
1315 cput_loc: table     call_signal,,cput
1316 rqo_loc:  table     call_signal,,record_quota_overflow
1317 size_loc: table     call_signaller,,size
1318           table     call_signal,,neti
1319 com:      table     standard,hardware_fault_link,command
1320           table     call_signal,,sus_
1321           table     call_signal,,trm_
1322           table     call_signal,,wkp_
1323 undefp:   table     call_signal,,undefined_pointer
1324           table     call_signal,,pgt_
1325           table     call_signal,,system_shutdown_scheduled_
1326           table     call_signal,,dm_shutdown_scheduled_
1327           table     call_signal,,system_message_
1328 " ^L
1329           include   mc
1330 " ^L
1331           include   stack_header
1332 " ^L
1333           include   access_audit_flags
1334 " ^L
1335           include   sdw
1336 " ^L
1337           include   history_regs_dps8
1338 " ^L
1339           include   history_regs_l68
1340 " ^L
1341           include   bce_breakpoint_page
1342 " ^L
1343           include   flagbox
1344 
1345 "  BEGIN MESSAGE DOCUMENTATION
1346 "
1347 "  Message:
1348 "  AUDIT (fim): access violation fault - ring ADDED_INFO
1349 "
1350 "  S:     $access_audit
1351 "
1352 "  T:     $run
1353 "
1354 "  M:     The specified process took an access violation fault
1355 "         due to ring brackets inconsistant with the operation.
1356 "
1357 "  A:     $ignore
1358 "
1359 "
1360 "  Message:
1361 "  AUDIT (fim): access violation fault - mode ADDED_INFO
1362 "
1363 "  S:     $access_audit
1364 "
1365 "  T:     $run
1366 "
1367 "  M:     The specified process took an access violation fault
1368 "         because the access mode was inconsistant with the operation.
1369 "
1370 "  A:     $ignore
1371 "
1372 "
1373 "  Message:
1374 "  AUDIT (fim): illegal procedure fault ADDED_INFO
1375 "
1376 "  S:     $access_audit
1377 "
1378 "  T:     $run
1379 "
1380 "  M:     The specified process took an illegal procedure fault.
1381 "
1382 "  A:     $ignore
1383 "
1384 "  END MESSAGE DOCUMENTATION
1385 "
1386           end