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