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) change88-05-24Farley, approve88-06-30MCR7927,
34 " audit88-07-12Fawcett, install88-08-02MR12.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 00
417 " if conditions are met for machine condition tracing, then
418 " return is ic +2 tra 10, 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