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
680 if (cpu . bTroubleFaultCycle)
681 {
682 #if !defined(THREADZ) && !defined(LOCKLESS)
683 # ifndef PANEL68
684 # ifndef ROUND_ROBIN
685 if ((! sample_interrupts ()) &&
686 (sim_qcount () == 0))
687
688 {
689 sim_printf \
690 ("Fault cascade @0%06o with no interrupts pending and no events in queue\n",
691 cpu . PPR.IC);
692 sim_printf("\nCycles = %"PRId64"\n", cpu.cycleCnt);
693 sim_printf("\nInstructions = %"PRId64"\n", cpu.instrCnt);
694
695 longjmp (cpu.jmpMain, JMP_STOP);
696 }
697 # endif
698 # endif
699 #endif
700 }
701 else
702 {
703
704 cpu . bTroubleFaultCycle = true;
705 }
706 }
707 else
708 {
709 cpu . bTroubleFaultCycle = false;
710 }
711
712
713
714 if (cpu . cycle == EXEC_cycle)
715 cpu.instrCnt ++;
716
717 cpu . cycle = FAULT_cycle;
718 sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to FAULT_cycle\n");
719 longjmp (cpu.jmpMain, JMP_REENTRY);
720 }
721
722 void do_FFV_fault (uint fault_number, const char * fault_msg)
723 {
724 sim_debug (DBG_FAULT, & cpu_dev,
725 "Floating fault %d '%s'\n",
726 fault_number, fault_msg);
727 #ifndef SPEED
728 if_sim_debug (DBG_FAULT, & cpu_dev)
729 traceInstruction (DBG_FAULT);
730 #endif
731
732 if (fault_number < 1 || fault_number > 3)
733 {
734 sim_printf ("floating fault(out-of-range): %d '%s'\n",
735 fault_number, fault_msg ? fault_msg : "?");
736 sim_warn ("fault out-of-range\n");
737 }
738
739 cpu.FFV_fault_number = fault_number;
740 cpu.faultNumber = fault_number;
741
742
743
744 CPTUR (cptUseCMR);
745 cpu.CMR.csh_reg = 0;
746
747
748
749 word3 FCT = cpu.cu.APUCycleBits & MASK3;
750 FCT = (FCT + 1) & MASK3;
751 cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | FCT);
752
753
754 CPTUR (cptUseFR);
755 cpu.faultRegister [0] = 0;
756
757
758
759 cpu.cu.IRO_ISN = 0;
760 cpu.cu.OEB_IOC = 0;
761 cpu.cu.EOFF_IAIM = 0;
762 cpu.cu.ORB_ISP = 0;
763 cpu.cu.ROFF_IPR = 0;
764 cpu.cu.OWB_NEA = 0;
765 cpu.cu.WOFF_OOB = 0;
766 cpu.cu.NO_GA = 0;
767 cpu.cu.OCB = 0;
768 cpu.cu.OCALL = 0;
769 cpu.cu.BOC = 0;
770
771
772
773
774 cpu.cu.CRT = 0;
775 cpu.cu.RALR = 0;
776 cpu.cu.SDWAM_ER = 0;
777 cpu.cu.OOSB = 0;
778 cpu.cu.PARU = 0;
779 cpu.cu.PARL = 0;
780 cpu.cu.ONC1 = 0;
781 cpu.cu.ONC2 = 0;
782 cpu.cu.IA = 0;
783 cpu.cu.IACHN = 0;
784 cpu.cu.CNCHN = 0;
785
786
787 cpu.cu.FIF = 0;
788 cpu.cu.FI_ADDR = (word5) fault_number & MASK5;
789
790
791
792
793
794 cpu.cu.rfi = 0;
795
796
797
798
799
800
801 SC_I_MIF (cpu.cycle == EXEC_cycle &&
802 cpu.currentInstruction.info->ndes > 0);
803 sim_debug (DBG_TRACEEXT, & cpu_dev, "MIF %o\n", TST_I_MIF);
804
805
806
807
808
809
810
811 CPTUR (cptUseMR);
812 if (cpu.MR.emr && cpu.MR.ihrrs)
813 {
814 cpu.MR.ihr = 0;
815 }
816
817 if (cpu.cycle == FAULT_EXEC_cycle)
818 {
819 cpu.faultNumber = FAULT_TRB;
820 cpu.cu.FI_ADDR = FAULT_TRB;
821 cpu.subFault.bits = 0;
822
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 return cpu.g7Faults != 0;
884 }
885
886 bool bG7PendingNoTRO (void)
887 {
888 if (cpu.tweaks.l68_mode)
889 return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0 || cpu.FFV_faults != 0;
890 return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0;
891 }
892
893 void setG7fault (uint cpuNo, _fault faultNo, _fault_subtype subFault)
894 {
895 sim_debug (DBG_FAULT, & cpu_dev, "setG7fault CPU %d fault %d (%o) sub %"PRId64" %"PRIo64"\n",
896 cpuNo, faultNo, faultNo, subFault.bits, subFault.bits);
897 cpus[cpuNo].g7FaultsPreset |= (1u << faultNo);
898
899 cpus[cpuNo].g7SubFaults [faultNo] = subFault;
900 #if defined(THREADZ) || defined(LOCKLESS)
901 wakeCPU(cpuNo);
902 #endif
903 }
904
905 void set_FFV_fault (uint f_fault_no)
906 {
907 sim_debug (DBG_FAULT, & cpu_dev, "set_FFV_fault CPU f_fault_no %u\n",
908 f_fault_no);
909
910 cpu.FFV_faults_preset |= 1u << ((f_fault_no / 2) - 1);
911 }
912
913 void clearTROFault (void)
914 {
915 cpu . g7Faults &= ~(1u << FAULT_TRO);
916 }
917
918 void doG7Fault (bool allowTR)
919 {
920
921
922
923
924
925
926
927 #if defined(THREADZ) || defined(LOCKLESS)
928 lock_scu ();
929 #endif
930 if (cpu.g7Faults & (1u << FAULT_CON))
931 {
932 cpu.g7Faults &= ~(1u << FAULT_CON);
933
934 #if defined(THREADZ) || defined(LOCKLESS)
935 unlock_scu ();
936 #endif
937 doFault (FAULT_CON, cpu.g7SubFaults [FAULT_CON], "Connect");
938 }
939
940 if (allowTR && (cpu.g7Faults & (1u << FAULT_TRO)))
941 {
942 cpu . g7Faults &= ~(1u << FAULT_TRO);
943
944
945 #if defined(THREADZ) || defined(LOCKLESS)
946 unlock_scu ();
947 #endif
948 doFault (FAULT_TRO, fst_zero, "Timer runout");
949 }
950
951
952
953
954 if (cpu . g7Faults & (1u << FAULT_EXF))
955 {
956 cpu . g7Faults &= ~(1u << FAULT_EXF);
957
958 #if defined(THREADZ) || defined(LOCKLESS)
959 unlock_scu ();
960 #endif
961 doFault (FAULT_EXF, fst_zero, "Execute fault");
962 }
963
964 if (cpu.tweaks.l68_mode) {
965 if (cpu.FFV_faults & 1u)
966 {
967 cpu.FFV_faults &= ~1u;
968 #if defined(THREADZ) || defined(LOCKLESS)
969 unlock_scu ();
970 #endif
971 do_FFV_fault (1, "OC TRAP");
972 }
973 if (cpu.FFV_faults & 2u)
974 {
975 cpu.FFV_faults &= ~2u;
976 #if defined(THREADZ) || defined(LOCKLESS)
977 unlock_scu ();
978 #endif
979 do_FFV_fault (2, "CU HIST OVF TRAP");
980 }
981 if (cpu.FFV_faults & 4u)
982 {
983 cpu.FFV_faults &= ~4u;
984 #if defined(THREADZ) || defined(LOCKLESS)
985 unlock_scu ();
986 #endif
987 do_FFV_fault (3, "ADR TRAP");
988 }
989 }
990 #if defined(THREADZ) || defined(LOCKLESS)
991 unlock_scu ();
992 #endif
993 doFault (FAULT_TRB, (_fault_subtype) {.bits=cpu.g7Faults}, "Dazed and confused in doG7Fault");
994 }
995
996 void advanceG7Faults (void)
997 {
998 #if defined(THREADZ) || defined(LOCKLESS)
999 lock_scu ();
1000 #endif
1001 cpu.g7Faults |= cpu.g7FaultsPreset;
1002 cpu.g7FaultsPreset = 0;
1003
1004 L68_ (
1005 cpu.FFV_faults |= cpu.FFV_faults_preset;
1006 cpu.FFV_faults_preset = 0;
1007 )
1008 #if defined(THREADZ) || defined(LOCKLESS)
1009 unlock_scu ();
1010 #endif
1011 }