This source file includes following definitions.
- emCallReportFault
- clearFaultCycle
- doFault
- do_FFV_fault
- dlyDoFault
- bG7Pending
- bG7PendingNoTRO
- setG7fault
- set_FFV_fault
- clearTROFault
- doG7Fault
- advanceG7Faults
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <stdio.h>
35
36 #include "dps8.h"
37 #include "dps8_sys.h"
38 #include "dps8_faults.h"
39 #include "dps8_scu.h"
40 #include "dps8_iom.h"
41 #include "dps8_cable.h"
42 #include "dps8_cpu.h"
43 #include "dps8_append.h"
44 #include "dps8_ins.h"
45 #include "dps8_utils.h"
46 #if defined(THREADZ) || defined(LOCKLESS)
47 # include "threadz.h"
48 #endif
49
50 #define DBG_CTR cpu.cycleCnt
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 #ifndef QUIET_UNUSED
113 static dps8faults _faultsP[] = {
114
115 { 12, 030, "suf", "Startup", 1, 1, false },
116 { 15, 036, "exf", "Execute", 2, 1, false },
117 { 31, 076, "trb", "Trouble", 3, 2, false },
118 { 11, 026, "onc", "Operation not complete", 4, 2, false },
119 { 7, 016, "luf", "Lockup", 5, 4, false },
120 { 14, 034, "div", "Divide check", 6, 3, false },
121 { 13, 032, "ofl", "Overflow", 7, 3, false },
122 { 9, 022, "par", "Parity", 8, 4, false },
123 { 5, 012, "cmd", "Command", 9, 4, false },
124 { 1, 2, "str", "Store", 10, 4, false },
125 { 2, 4, "mme", "Master mode entry 1", 11, 5, false },
126 { 21, 052, "mme2", "Master mode entry 2", 12, 5, false },
127 { 22, 054, "mme3", "Master mode entry 3", 13, 5, false },
128 { 23, 056, "mme4", "Master mode entry 4", 14, 5, false },
129 { 6, 014, "drl", "Derail", 15, 5, false },
130 { 10, 024, "ipr", "Illegal procedure", 16, 5, false },
131 { 3, 06, "f1", "Fault tag 1", 17, 5, false },
132 { 24, 060, "f2", "Fault tag 2", 18, 5, false },
133 { 25, 062, "f3", "Fault tag 3", 19, 5, false },
134 { 16, 040, "df0", "Directed fault 0", 20, 6, false },
135 { 17, 042, "df1", "Directed fault 1", 21, 6, false },
136 { 18, 044, "df2", "Directed fault 2", 22, 6, false },
137 { 19, 046, "df3", "Directed fault 3", 23, 6, false },
138 { 20, 050, "acv", "Access violation", 24, 6, false },
139 { 8, 020, "con", "Connect", 25, 7, false },
140 { 4, 010, "tro", "Timer runout", 26, 7, false },
141 { 0, 0, "sdf", "Shutdown", 27, 7, false },
142 { 26, 064, "???", "Unassigned", -1, -1, false },
143 { 27, 066, "???", "Unassigned", -1, -1, false },
144 { -1, -1, NULL, NULL, -1, -1, false }
145 };
146 #endif
147 #ifndef QUIET_UNUSED
148 static dps8faults _faults[] = {
149
150 { 0, 0, "sdf", "Shutdown", 27, 7, false },
151 { 1, 2, "str", "Store", 10, 4, false },
152 { 2, 4, "mme", "Master mode entry 1", 11, 5, false },
153 { 3, 06, "f1", "Fault tag 1", 17, 5, false },
154 { 4, 010, "tro", "Timer runout", 26, 7, false },
155 { 5, 012, "cmd", "Command", 9, 4, false },
156 { 6, 014, "drl", "Derail", 15, 5, false },
157 { 7, 016, "luf", "Lockup", 5, 4, false },
158 { 8, 020, "con", "Connect", 25, 7, false },
159 { 9, 022, "par", "Parity", 8, 4, false },
160 { 10, 024, "ipr", "Illegal procedure", 16, 5, false },
161 { 11, 026, "onc", "Operation not complete", 4, 2, false },
162 { 12, 030, "suf", "Startup", 1, 1, false },
163 { 13, 032, "ofl", "Overflow", 7, 3, false },
164 { 14, 034, "div", "Divide check", 6, 3, false },
165 { 15, 036, "exf", "Execute", 2, 1, false },
166 { 16, 040, "df0", "Directed fault 0", 20, 6, false },
167 { 17, 042, "df1", "Directed fault 1", 21, 6, false },
168 { 18, 044, "df2", "Directed fault 2", 22, 6, false },
169 { 19, 046, "df3", "Directed fault 3", 23, 6, false },
170 { 20, 050, "acv", "Access violation", 24, 6, false },
171 { 21, 052, "mme2", "Master mode entry 2", 12, 5, false },
172 { 22, 054, "mme3", "Master mode entry 3", 13, 5, false },
173 { 23, 056, "mme4", "Master mode entry 4", 14, 5, false },
174 { 24, 060, "f2", "Fault tag 2", 18, 5, false },
175 { 25, 062, "f3", "Fault tag 3", 19, 5, false },
176 { 26, 064, "???", "Unassigned", -1, -1, false },
177 { 27, 066, "???", "Unassigned", -1, -1, false },
178 { 28, 070, "???", "Unassigned", -1, -1, false },
179 { 29, 072, "???", "Unassigned", -1, -1, false },
180 { 30, 074, "???", "Unassigned", -1, -1, false },
181 { 31, 076, "trb", "Trouble", 3, 2, false },
182 { -1, -1, NULL, NULL, -1, -1, false }
183 };
184 #endif
185
186 char * faultNames [N_FAULTS] =
187 {
188 "Shutdown",
189 "Store",
190 "Master mode entry 1",
191 "Fault tag 1",
192 "Timer runout",
193 "Command",
194 "Derail",
195 "Lockup",
196 "Connect",
197 "Parity",
198 "Illegal procedure",
199 "Operation not complete",
200 "Startup",
201 "Overflow",
202 "Divide check",
203 "Execute",
204 "Directed fault 0",
205 "Directed fault 1",
206 "Directed fault 2",
207 "Directed fault 3",
208 "Access violation",
209 "Master mode entry 2",
210 "Master mode entry 3",
211 "Master mode entry 4",
212 "Fault tag 2",
213 "Fault tag 3",
214 "Unassigned 26",
215 "Unassigned 27",
216 "Unassigned 28",
217 "Unassigned 29",
218 "Unassigned 30",
219 "Trouble"
220 };
221
222
223 #ifndef QUIET_UNUSED
224 static bool port_interrupts[8] = { false, false, false, false, false, false, false, false };
225 #endif
226
227
228
229
230 #ifndef QUIET_UNUSED
231 static int fault2group[32] = {
232
233 7, 4, 5, 5, 7, 4, 5, 4,
234 7, 4, 5, 2, 1, 3, 3, 1,
235 6, 6, 6, 6, 6, 5, 5, 5,
236 5, 5, 0, 0, 0, 0, 0, 2
237 };
238
239 static int fault2prio[32] = {
240
241 27, 10, 11, 17, 26, 9, 15, 5,
242 25, 8, 16, 4, 1, 7, 6, 2,
243 20, 21, 22, 23, 24, 12, 13, 14,
244 18, 19, 0, 0, 0, 0, 0, 3
245 };
246 #endif
247
248
249
250
251
252 #ifdef TESTING
253
254 static word18 fault_ic;
255 static word15 fault_psr;
256 static char fault_msg [1024];
257
258 void emCallReportFault (void)
259 {
260 sim_printf ("fault report:\n");
261 sim_printf (" fault number %d (%o)\n", cpu . faultNumber, cpu . faultNumber);
262 sim_printf (" subfault number %llu (%llo)\n", (unsigned long long) cpu.subFault.bits,
263 (unsigned long long)cpu.subFault.bits);
264 sim_printf (" faulting address %05o:%06o\n", fault_psr, fault_ic);
265 sim_printf (" msg %s\n", fault_msg);
266 }
267 #endif
268
269 void clearFaultCycle (void)
270 {
271 cpu . bTroubleFaultCycle = false;
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353 #ifdef LOOPTRC
354 # include <time.h>
355 void elapsedtime (void);
356 #endif
357
358 #ifndef NEED_128
359 const _fault_subtype fst_zero = (_fault_subtype) {.bits=0};
360 const _fault_subtype fst_acv9 = (_fault_subtype) {.fault_acv_subtype=ACV9};
361 const _fault_subtype fst_acv15 = (_fault_subtype) {.fault_acv_subtype=ACV15};
362 const _fault_subtype fst_ill_mod = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_MOD};
363 const _fault_subtype fst_ill_proc = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC};
364 const _fault_subtype fst_ill_dig = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_DIG};
365 const _fault_subtype fst_ill_op = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP};
366 const _fault_subtype fst_str_oob = (_fault_subtype) {.fault_str_subtype=flt_str_oob};
367 const _fault_subtype fst_str_nea = (_fault_subtype) {.fault_str_subtype=flt_str_nea};
368 const _fault_subtype fst_str_ptr = (_fault_subtype) {.fault_str_subtype=flt_str_ill_ptr};
369 const _fault_subtype fst_cmd_lprpn = (_fault_subtype) {.fault_cmd_subtype=flt_cmd_lprpn_bits};
370 const _fault_subtype fst_cmd_ctl = (_fault_subtype) {.fault_cmd_subtype=flt_cmd_not_control};
371 const _fault_subtype fst_onc_nem = (_fault_subtype) {.fault_onc_subtype=flt_onc_nem};
372 #endif
373
374 void doFault (_fault faultNumber, _fault_subtype subFault,
375 const char * faultMsg)
376 {
377 #ifdef LOOPTRC
378 if (faultNumber == FAULT_TRO)
379 {
380 elapsedtime ();
381 sim_printf (" TRO PSR:IC %05o:%06o\r\n", cpu.PPR.PSR, cpu.PPR.IC);
382 }
383 else if (faultNumber == FAULT_ACV)
384 {
385 elapsedtime ();
386 sim_printf (" ACV %012llo PSR:IC %05o:%06o\r\n", subFault.bits, cpu.PPR.PSR, cpu.PPR.IC);
387 }
388 #endif
389
390
391
392
393
394
395 sim_debug (DBG_FAULT, & cpu_dev,
396 "Fault %d(0%0o), sub %"PRIu64"(0%"PRIo64"), dfc %c, '%s'\n",
397 faultNumber, faultNumber, subFault.bits, subFault.bits,
398 cpu . bTroubleFaultCycle ? 'Y' : 'N', faultMsg);
399 #ifdef PROFILER
400 # ifndef GNU_ATOMICS
401 # error PROFILER requires GNU_ATOMICS
402 # endif
403 __atomic_add_fetch (& cpu.faults[faultNumber], 1u, __ATOMIC_ACQUIRE);
404 #endif
405 #ifdef TESTING
406 HDBGFault (faultNumber, subFault, faultMsg, "");
407 #endif
408 #ifndef SPEED
409 if_sim_debug (DBG_FAULT, & cpu_dev)
410 traceInstruction (DBG_FAULT);
411 #endif
412
413 PNL (cpu.DACVpDF = faultNumber >= FAULT_DF0 && faultNumber <= FAULT_ACV;)
414
415 #ifdef TESTING
416
417 fault_psr = cpu . PPR.PSR;
418 fault_ic = cpu . PPR.IC;
419 strcpy (fault_msg, faultMsg);
420 #endif
421
422
423 if (faultNumber & ~037U)
424 {
425 sim_printf ("fault(out-of-range): %d %llo '%s'\n",
426 faultNumber, (unsigned long long)subFault.bits,
427 faultMsg ? faultMsg : "?");
428 sim_warn ("fault out-of-range\n");
429 faultNumber = FAULT_TRB;
430 }
431
432 cpu.faultNumber = faultNumber;
433 cpu.subFault = subFault;
434 cpu.faultCnt [faultNumber] ++;
435
436
437 CPTUR (cptUseCMR);
438 cpu.CMR.csh_reg = 0;
439
440
441
442 word3 FCT = cpu.cu.APUCycleBits & MASK3;
443 FCT = (FCT + 1u) & MASK3;
444 cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | FCT);
445
446
447
448 CPTUR (cptUseFR);
449 if (faultNumber == FAULT_IPR)
450 {
451
452
453
454
455
456
457
458
459
460
461 cpu . faultRegister [0] |= subFault.bits;
462
463 }
464 else if (faultNumber == FAULT_ONC && subFault.fault_onc_subtype == flt_onc_nem)
465 {
466 cpu . faultRegister [0] |= FR_NEM;
467 }
468 else if (faultNumber == FAULT_STR)
469 {
470 if (subFault.fault_str_subtype == flt_str_oob)
471 cpu . faultRegister [0] |= FR_OOB;
472
473
474
475
476 }
477 else if (faultNumber == FAULT_CON)
478 {
479 switch (subFault.fault_con_subtype)
480 {
481 case con_a:
482 cpu . faultRegister [0] |= FR_CON_A;
483 break;
484 case con_b:
485 cpu . faultRegister [0] |= FR_CON_B;
486 break;
487 case con_c:
488 cpu . faultRegister [0] |= FR_CON_C;
489 break;
490 case con_d:
491 cpu . faultRegister [0] |= FR_CON_D;
492 break;
493 default:
494 sim_warn ("FAULT_CON can't map port %lo\n", (long unsigned) subFault.fault_con_subtype);
495 break;
496 }
497 }
498
499
500
501 cpu . cu . IRO_ISN = 0;
502 cpu . cu . OEB_IOC = 0;
503 cpu . cu . EOFF_IAIM = 0;
504 cpu . cu . ORB_ISP = 0;
505 cpu . cu . ROFF_IPR = 0;
506 cpu . cu . OWB_NEA = 0;
507 cpu . cu . WOFF_OOB = 0;
508 cpu . cu . NO_GA = 0;
509 cpu . cu . OCB = 0;
510 cpu . cu . OCALL = 0;
511 cpu . cu . BOC = 0;
512 DPS8M_ (cpu . cu . PTWAM_ER = 0;)
513 cpu . cu . CRT = 0;
514 cpu . cu . RALR = 0;
515 cpu . cu . SDWAM_ER = 0;
516 cpu . cu . OOSB = 0;
517 cpu . cu . PARU = 0;
518 cpu . cu . PARL = 0;
519 cpu . cu . ONC1 = 0;
520 cpu . cu . ONC2 = 0;
521 cpu . cu . IA = 0;
522 cpu . cu . IACHN = 0;
523 cpu . cu . CNCHN = (faultNumber == FAULT_CON) ? subFault.fault_con_subtype & MASK3 : 0;
524
525
526 cpu . cu . FIF = cpu . cycle == FETCH_cycle ? 1 : 0;
527 cpu . cu . FI_ADDR = (word5) faultNumber;
528
529
530
531
532
533 cpu . cu . rfi = 0;
534
535
536
537
538
539
540
541 SC_I_MIF (cpu.cycle == EXEC_cycle &&
542 (cpu.currentInstruction.info->ndes > 0 ||
543 (faultNumber == FAULT_IPR && (subFault.fault_ipr_subtype & FR_ILL_OP_CONST) &&
544 cpu.currentInstruction.opcodeX &&
545 (cpu.currentInstruction.opcode & 0410) == 0)));
546 sim_debug (DBG_TRACEEXT, & cpu_dev, "MIF %o\n", TST_I_MIF);
547
548
549
550
551
552
553
554
555
556
557
558
559 if (faultNumber == FAULT_ACV)
560 {
561
562
563
564
565
566 if (subFault.fault_acv_subtype & ACV0)
567 cpu . cu . IRO_ISN = 1;
568 if (subFault.fault_acv_subtype & ACV1)
569 cpu . cu . OEB_IOC = 1;
570 if (subFault.fault_acv_subtype & ACV2)
571 cpu . cu . EOFF_IAIM = 1;
572 if (subFault.fault_acv_subtype & ACV3)
573 cpu . cu . ORB_ISP = 1;
574 if (subFault.fault_acv_subtype & ACV4)
575 cpu . cu . ROFF_IPR = 1;
576 if (subFault.fault_acv_subtype & ACV5)
577 cpu . cu . OWB_NEA = 1;
578 if (subFault.fault_acv_subtype & ACV6)
579 cpu . cu . WOFF_OOB = 1;
580 if (subFault.fault_acv_subtype & ACV7)
581 cpu . cu . NO_GA = 1;
582 if (subFault.fault_acv_subtype & ACV8)
583 cpu . cu . OCB = 1;
584 if (subFault.fault_acv_subtype & ACV9)
585 cpu . cu . OCALL = 1;
586 if (subFault.fault_acv_subtype & ACV10)
587 cpu . cu . BOC = 1;
588 if (subFault.fault_acv_subtype & ACV11)
589 cpu . cu . PTWAM_ER = 1;
590 if (subFault.fault_acv_subtype & ACV12)
591 cpu . cu . CRT = 1;
592 if (subFault.fault_acv_subtype & ACV13)
593 cpu . cu . RALR = 1;
594 if (subFault.fault_acv_subtype & ACV14)
595 cpu . cu . SDWAM_ER = 1;
596 if (subFault.fault_acv_subtype & ACV15)
597 cpu . cu . OOSB = 1;
598 }
599 else if (faultNumber == FAULT_STR)
600 {
601 if (subFault.fault_str_subtype == flt_str_oob)
602 cpu . cu . WOFF_OOB = 1;
603
604
605 else if (subFault.fault_str_subtype == flt_str_nea)
606 cpu . cu . OWB_NEA = 1;
607 }
608 else if (faultNumber == FAULT_IPR)
609 {
610 if (subFault.fault_ipr_subtype & FR_ILL_OP_CONST)
611 cpu . cu . OEB_IOC = 1;
612 if (subFault.fault_ipr_subtype & FR_ILL_MOD_CONST)
613 cpu . cu . EOFF_IAIM = 1;
614 if (subFault.fault_ipr_subtype & FR_ILL_SLV_CONST)
615 cpu . cu . ORB_ISP = 1;
616 if (subFault.fault_ipr_subtype & FR_ILL_DIG)
617 cpu . cu . ROFF_IPR = 1;
618 }
619 else if (faultNumber == FAULT_CMD)
620 {
621 if (subFault.fault_cmd_subtype == flt_cmd_lprpn_bits)
622 cpu . cu . IA = 0;
623 else if (subFault.fault_cmd_subtype == flt_cmd_not_control)
624 cpu . cu . IA = 010;
625 }
626
627 L68_ (
628
629
630
631
632
633 CPTUR (cptUseMR);
634 if (cpu.MR.emr && cpu.MR.ihrrs)
635 {
636 cpu.MR.ihr = 0;
637 }
638 )
639 DPS8M_ (
640
641
642
643
644
645
646
647
648
649
650 if (cpu.MR.emr && cpu.MR.ihrrs)
651 {
652 if (faultNumber == FAULT_LUF ||
653 faultNumber == FAULT_PAR ||
654 faultNumber == FAULT_CMD ||
655 faultNumber == FAULT_STR ||
656 faultNumber == FAULT_IPR ||
657 faultNumber == FAULT_SDF)
658 {
659 cpu.MR.ihr = 0;
660 }
661 }
662
663
664 if (faultNumber == FAULT_ONC)
665 {
666 cpu.MR.ihr = 0;
667 }
668 )
669
670
671
672 if (cpu.cycle == FAULT_EXEC_cycle)
673 {
674 sim_debug (DBG_CYCLE, & cpu_dev, "Changing fault number to Trouble fault\n");
675
676 cpu.faultNumber = FAULT_TRB;
677 cpu.cu.FI_ADDR = FAULT_TRB;
678 cpu.subFault.bits = 0;
679 if (cpu . bTroubleFaultCycle)
680 {
681 #if !defined(THREADZ) && !defined(LOCKLESS)
682 # ifndef PANEL68
683 # ifndef ROUND_ROBIN
684 if ((! sample_interrupts ()) &&
685 (sim_qcount () == 0))
686
687 {
688 sim_printf \
689 ("Fault cascade @0%06o with no interrupts pending and no events in queue\n",
690 cpu . PPR.IC);
691 sim_printf("\nCycles = %"PRId64"\n", cpu.cycleCnt);
692 sim_printf("\nInstructions = %"PRId64"\n", cpu.instrCnt);
693
694 longjmp (cpu.jmpMain, JMP_STOP);
695 }
696 # endif
697 # endif
698 #endif
699 }
700 else
701 {
702
703 cpu . bTroubleFaultCycle = true;
704 }
705 }
706 else
707 {
708 cpu . bTroubleFaultCycle = false;
709 }
710
711
712
713 if (cpu . cycle == EXEC_cycle)
714 cpu.instrCnt ++;
715
716 cpu . cycle = FAULT_cycle;
717 sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to FAULT_cycle\n");
718 longjmp (cpu.jmpMain, JMP_REENTRY);
719
720 abort();
721 }
722
723 void do_FFV_fault (uint fault_number, const char * fault_msg)
724 {
725 sim_debug (DBG_FAULT, & cpu_dev,
726 "Floating fault %d '%s'\n",
727 fault_number, fault_msg);
728 #ifndef SPEED
729 if_sim_debug (DBG_FAULT, & cpu_dev)
730 traceInstruction (DBG_FAULT);
731 #endif
732
733 if (fault_number < 1 || fault_number > 3)
734 {
735 sim_printf ("floating fault(out-of-range): %d '%s'\n",
736 fault_number, fault_msg ? fault_msg : "?");
737 sim_warn ("fault out-of-range\n");
738 }
739
740 cpu.FFV_fault_number = fault_number;
741 cpu.faultNumber = fault_number;
742
743
744
745 CPTUR (cptUseCMR);
746 cpu.CMR.csh_reg = 0;
747
748
749
750 word3 FCT = cpu.cu.APUCycleBits & MASK3;
751 FCT = (FCT + 1) & MASK3;
752 cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | FCT);
753
754
755 CPTUR (cptUseFR);
756 cpu.faultRegister [0] = 0;
757
758
759
760 cpu.cu.IRO_ISN = 0;
761 cpu.cu.OEB_IOC = 0;
762 cpu.cu.EOFF_IAIM = 0;
763 cpu.cu.ORB_ISP = 0;
764 cpu.cu.ROFF_IPR = 0;
765 cpu.cu.OWB_NEA = 0;
766 cpu.cu.WOFF_OOB = 0;
767 cpu.cu.NO_GA = 0;
768 cpu.cu.OCB = 0;
769 cpu.cu.OCALL = 0;
770 cpu.cu.BOC = 0;
771
772
773
774
775 cpu.cu.CRT = 0;
776 cpu.cu.RALR = 0;
777 cpu.cu.SDWAM_ER = 0;
778 cpu.cu.OOSB = 0;
779 cpu.cu.PARU = 0;
780 cpu.cu.PARL = 0;
781 cpu.cu.ONC1 = 0;
782 cpu.cu.ONC2 = 0;
783 cpu.cu.IA = 0;
784 cpu.cu.IACHN = 0;
785 cpu.cu.CNCHN = 0;
786
787
788 cpu.cu.FIF = 0;
789 cpu.cu.FI_ADDR = (word5) fault_number & MASK5;
790
791
792
793
794
795 cpu.cu.rfi = 0;
796
797
798
799
800
801
802 SC_I_MIF (cpu.cycle == EXEC_cycle &&
803 cpu.currentInstruction.info->ndes > 0);
804 sim_debug (DBG_TRACEEXT, & cpu_dev, "MIF %o\n", TST_I_MIF);
805
806
807
808
809
810
811
812 CPTUR (cptUseMR);
813 if (cpu.MR.emr && cpu.MR.ihrrs)
814 {
815 cpu.MR.ihr = 0;
816 }
817
818 if (cpu.cycle == FAULT_EXEC_cycle)
819 {
820 cpu.faultNumber = FAULT_TRB;
821 cpu.cu.FI_ADDR = FAULT_TRB;
822 cpu.subFault.bits = 0;
823 if (cpu.bTroubleFaultCycle)
824 {
825 #if !defined(THREADZ) && !defined(LOCKLESS)
826 # ifndef PANEL68
827 # ifndef ROUND_ROBIN
828 if ((! sample_interrupts ()) &&
829 (sim_qcount () == 0))
830
831 {
832 sim_printf \
833 ("Fault cascade @0%06o with no interrupts pending and no events in queue\n",
834 cpu.PPR.IC);
835 sim_printf("\nCycles = %"PRId64"\n", cpu.cycleCnt);
836 sim_printf("\nInstructions = %"PRId64"\n", cpu.instrCnt);
837 longjmp (cpu.jmpMain, JMP_STOP);
838 }
839 # endif
840 # endif
841 #endif
842 }
843 else
844 {
845 cpu.bTroubleFaultCycle = true;
846 }
847 cpu.cycle = FAULT_cycle;
848 sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to FAULT_cycle\n");
849 longjmp (cpu.jmpMain, JMP_REENTRY);
850 }
851 cpu.bTroubleFaultCycle = false;
852
853
854
855 if (cpu . cycle == EXEC_cycle)
856 cpu.instrCnt ++;
857
858 cpu.is_FFV = true;
859 cpu.cycle = FAULT_cycle;
860 longjmp (cpu.jmpMain, JMP_REENTRY);
861 }
862
863 void dlyDoFault (_fault faultNumber, _fault_subtype subFault,
864 const char * faultMsg)
865 {
866 cpu.dlyFlt = true;
867 cpu.dlyFltNum = faultNumber;
868 cpu.dlySubFltNum = subFault;
869 cpu.dlyCtx = faultMsg;
870 }
871
872
873
874
875
876
877
878
879 bool bG7Pending (void)
880 {
881 if (cpu.tweaks.l68_mode)
882 return cpu.g7Faults != 0 || cpu.FFV_faults != 0;
883
884 return cpu.g7Faults != 0;
885 }
886
887 bool bG7PendingNoTRO (void)
888 {
889 if (cpu.tweaks.l68_mode)
890 return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0 || cpu.FFV_faults != 0;
891
892 return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0;
893 }
894
895 void setG7fault (uint cpuNo, _fault faultNo, _fault_subtype subFault)
896 {
897 sim_debug (DBG_FAULT, & cpu_dev, "setG7fault CPU %d fault %d (%o) sub %"PRId64" %"PRIo64"\n",
898 cpuNo, faultNo, faultNo, subFault.bits, subFault.bits);
899 cpus[cpuNo].g7FaultsPreset |= (1u << faultNo);
900
901 cpus[cpuNo].g7SubFaults [faultNo] = subFault;
902 #if defined(THREADZ) || defined(LOCKLESS)
903 wakeCPU(cpuNo);
904 #endif
905 }
906
907 void set_FFV_fault (uint f_fault_no)
908 {
909 sim_debug (DBG_FAULT, & cpu_dev, "set_FFV_fault CPU f_fault_no %u\n",
910 f_fault_no);
911
912 cpu.FFV_faults_preset |= 1u << ((f_fault_no / 2) - 1);
913 }
914
915 void clearTROFault (void)
916 {
917 cpu . g7Faults &= ~(1u << FAULT_TRO);
918 }
919
920 void doG7Fault (bool allowTR)
921 {
922
923
924
925
926
927
928
929 #if defined(THREADZ) || defined(LOCKLESS)
930 lock_scu ();
931 #endif
932 if (cpu.g7Faults & (1u << FAULT_CON))
933 {
934 cpu.g7Faults &= ~(1u << FAULT_CON);
935
936 #if defined(THREADZ) || defined(LOCKLESS)
937 unlock_scu ();
938 #endif
939 doFault (FAULT_CON, cpu.g7SubFaults [FAULT_CON], "Connect");
940 }
941
942 if (allowTR && (cpu.g7Faults & (1u << FAULT_TRO)))
943 {
944 cpu . g7Faults &= ~(1u << FAULT_TRO);
945
946
947 #if defined(THREADZ) || defined(LOCKLESS)
948 unlock_scu ();
949 #endif
950 doFault (FAULT_TRO, fst_zero, "Timer runout");
951 }
952
953
954
955
956 if (cpu . g7Faults & (1u << FAULT_EXF))
957 {
958 cpu . g7Faults &= ~(1u << FAULT_EXF);
959
960 #if defined(THREADZ) || defined(LOCKLESS)
961 unlock_scu ();
962 #endif
963 doFault (FAULT_EXF, fst_zero, "Execute fault");
964 }
965
966 if (cpu.tweaks.l68_mode) {
967 if (cpu.FFV_faults & 1u)
968 {
969 cpu.FFV_faults &= ~1u;
970 #if defined(THREADZ) || defined(LOCKLESS)
971 unlock_scu ();
972 #endif
973 do_FFV_fault (1, "OC TRAP");
974 }
975 if (cpu.FFV_faults & 2u)
976 {
977 cpu.FFV_faults &= ~2u;
978 #if defined(THREADZ) || defined(LOCKLESS)
979 unlock_scu ();
980 #endif
981 do_FFV_fault (2, "CU HIST OVF TRAP");
982 }
983 if (cpu.FFV_faults & 4u)
984 {
985 cpu.FFV_faults &= ~4u;
986 #if defined(THREADZ) || defined(LOCKLESS)
987 unlock_scu ();
988 #endif
989 do_FFV_fault (3, "ADR TRAP");
990 }
991 }
992 #if defined(THREADZ) || defined(LOCKLESS)
993 unlock_scu ();
994 #endif
995 doFault (FAULT_TRB, (_fault_subtype) {.bits=cpu.g7Faults}, "Dazed and confused in doG7Fault");
996 }
997
998 void advanceG7Faults (void)
999 {
1000 #if defined(THREADZ) || defined(LOCKLESS)
1001 lock_scu ();
1002 #endif
1003 cpu.g7Faults |= cpu.g7FaultsPreset;
1004 cpu.g7FaultsPreset = 0;
1005
1006 L68_ (
1007 cpu.FFV_faults |= cpu.FFV_faults_preset;
1008 cpu.FFV_faults_preset = 0;
1009 )
1010 #if defined(THREADZ) || defined(LOCKLESS)
1011 unlock_scu ();
1012 #endif
1013 }