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
403 (void)atomic_fetch_add_explicit(&cpu.faults[faultNumber], 1u, memory_order_acquire);
404 #endif
405 #if defined(TESTING)
406 HDBGFault (faultNumber, subFault, faultMsg, "");
407 #endif
408 #if !defined(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 #if defined(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 # if !defined(PANEL68)
683 # if !defined(ROUND_ROBIN)
684 if ((! sample_interrupts (cpup)) &&
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 #if !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
720
721 abort();
722 #endif
723 }
724
725 void do_FFV_fault (cpu_state_t * cpup, uint fault_number, const char * fault_msg)
726 {
727 sim_debug (DBG_FAULT, & cpu_dev,
728 "Floating fault %d '%s'\n",
729 fault_number, fault_msg);
730 #if !defined(SPEED)
731 if_sim_debug (DBG_FAULT, & cpu_dev)
732 traceInstruction (DBG_FAULT);
733 #endif
734
735 if (fault_number < 1 || fault_number > 3)
736 {
737 sim_printf ("floating fault(out-of-range): %d '%s'\n",
738 fault_number, fault_msg ? fault_msg : "?");
739 sim_warn ("fault out-of-range\n");
740 }
741
742 cpu.FFV_fault_number = fault_number;
743 cpu.faultNumber = fault_number;
744
745
746
747 CPTUR (cptUseCMR);
748 cpu.CMR.csh_reg = 0;
749
750
751
752 word3 FCT = cpu.cu.APUCycleBits & MASK3;
753 FCT = (FCT + 1) & MASK3;
754 cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | FCT);
755
756
757 CPTUR (cptUseFR);
758 cpu.faultRegister [0] = 0;
759
760
761
762 cpu.cu.IRO_ISN = 0;
763 cpu.cu.OEB_IOC = 0;
764 cpu.cu.EOFF_IAIM = 0;
765 cpu.cu.ORB_ISP = 0;
766 cpu.cu.ROFF_IPR = 0;
767 cpu.cu.OWB_NEA = 0;
768 cpu.cu.WOFF_OOB = 0;
769 cpu.cu.NO_GA = 0;
770 cpu.cu.OCB = 0;
771 cpu.cu.OCALL = 0;
772 cpu.cu.BOC = 0;
773
774
775
776
777 cpu.cu.CRT = 0;
778 cpu.cu.RALR = 0;
779 cpu.cu.SDWAM_ER = 0;
780 cpu.cu.OOSB = 0;
781 cpu.cu.PARU = 0;
782 cpu.cu.PARL = 0;
783 cpu.cu.ONC1 = 0;
784 cpu.cu.ONC2 = 0;
785 cpu.cu.IA = 0;
786 cpu.cu.IACHN = 0;
787 cpu.cu.CNCHN = 0;
788
789
790 cpu.cu.FIF = 0;
791 cpu.cu.FI_ADDR = (word5) fault_number & MASK5;
792
793
794
795
796
797 cpu.cu.rfi = 0;
798
799
800
801
802
803
804 SC_I_MIF (cpu.cycle == EXEC_cycle &&
805 cpu.currentInstruction.info->ndes > 0);
806 sim_debug (DBG_TRACEEXT, & cpu_dev, "MIF %o\n", TST_I_MIF);
807
808
809
810
811
812
813
814 CPTUR (cptUseMR);
815 if (cpu.MR.emr && cpu.MR.ihrrs)
816 {
817 cpu.MR.ihr = 0;
818 }
819
820 if (cpu.cycle == FAULT_EXEC_cycle)
821 {
822 cpu.faultNumber = FAULT_TRB;
823 cpu.cu.FI_ADDR = FAULT_TRB;
824 cpu.subFault.bits = 0;
825 if (cpu.bTroubleFaultCycle)
826 {
827 #if !defined(THREADZ) && !defined(LOCKLESS)
828 # if !defined(PANEL68)
829 # if !defined(ROUND_ROBIN)
830 if ((! sample_interrupts (cpup)) &&
831 (sim_qcount () == 0))
832
833 {
834 sim_printf \
835 ("Fault cascade @0%06o with no interrupts pending and no events in queue\n",
836 cpu.PPR.IC);
837 sim_printf("\nCycles = %"PRId64"\n", cpu.cycleCnt);
838 sim_printf("\nInstructions = %"PRId64"\n", cpu.instrCnt);
839 longjmp (cpu.jmpMain, JMP_STOP);
840 }
841 # endif
842 # endif
843 #endif
844 }
845 else
846 {
847 cpu.bTroubleFaultCycle = true;
848 }
849 cpu.cycle = FAULT_cycle;
850 sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to FAULT_cycle\n");
851 longjmp (cpu.jmpMain, JMP_REENTRY);
852 }
853 cpu.bTroubleFaultCycle = false;
854
855
856
857 if (cpu . cycle == EXEC_cycle)
858 cpu.instrCnt ++;
859
860 cpu.is_FFV = true;
861 cpu.cycle = FAULT_cycle;
862 longjmp (cpu.jmpMain, JMP_REENTRY);
863 }
864
865 void dlyDoFault (_fault faultNumber, _fault_subtype subFault,
866 const char * faultMsg)
867 {
868 cpu_state_t * cpup = _cpup;
869 cpu.dlyFlt = true;
870 cpu.dlyFltNum = faultNumber;
871 cpu.dlySubFltNum = subFault;
872 cpu.dlyCtx = faultMsg;
873 }
874
875
876
877
878
879
880
881
882 bool bG7Pending (cpu_state_t * cpup)
883 {
884 if (cpu.tweaks.l68_mode)
885 return cpu.g7Faults != 0 || cpu.FFV_faults != 0;
886
887 return cpu.g7Faults != 0;
888 }
889
890 bool bG7PendingNoTRO (cpu_state_t * cpup)
891 {
892 if (cpu.tweaks.l68_mode)
893 return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0 || cpu.FFV_faults != 0;
894
895 return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0;
896 }
897
898 void setG7fault (uint cpuNo, _fault faultNo)
899 {
900 cpu_state_t * cpup = &cpus[cpuNo];
901 sim_debug (DBG_FAULT, & cpu_dev, "setG7fault CPU %d fault %d (%o)\n",
902 cpuNo, faultNo, faultNo);
903 #if defined(THREADZ) || defined(LOCKLESS)
904
905 (void)atomic_fetch_or_explicit(&cpup->g7FaultsPreset, (1u << faultNo), memory_order_acquire);
906 #else
907 cpup->g7FaultsPreset |= (1u << faultNo);
908 #endif
909 #if defined(THREADZ) || defined(LOCKLESS)
910 if (cpuNo != current_running_cpu_idx)
911 wakeCPU(cpuNo);
912 #endif
913 }
914
915 void set_FFV_fault (cpu_state_t * cpup, uint f_fault_no)
916 {
917 sim_debug (DBG_FAULT, & cpu_dev, "set_FFV_fault CPU f_fault_no %u\n",
918 f_fault_no);
919
920 cpu.FFV_faults_preset |= 1u << ((f_fault_no / 2) - 1);
921 }
922
923 void clearTROFault (cpu_state_t * cpup)
924 {
925 cpu . g7Faults &= ~(1u << FAULT_TRO);
926 }
927
928 void doG7Fault (cpu_state_t * cpup, bool allowTR)
929 {
930
931
932
933
934
935
936
937 #if defined(THREADZ) || defined(LOCKLESS)
938 lock_scu ();
939 #endif
940 if (cpu.g7Faults & (1u << FAULT_CON))
941 {
942 cpu.g7Faults &= ~(1u << FAULT_CON);
943
944 #if defined(THREADZ) || defined(LOCKLESS)
945 unlock_scu ();
946 #endif
947 doFault (FAULT_CON, fst_zero, "Connect");
948 }
949
950 if (allowTR && (cpu.g7Faults & (1u << FAULT_TRO)))
951 {
952 cpu . g7Faults &= ~(1u << FAULT_TRO);
953
954
955 #if defined(THREADZ) || defined(LOCKLESS)
956 unlock_scu ();
957 #endif
958 doFault (FAULT_TRO, fst_zero, "Timer runout");
959 }
960
961
962
963
964 if (cpu . g7Faults & (1u << FAULT_EXF))
965 {
966 cpu . g7Faults &= ~(1u << FAULT_EXF);
967
968 #if defined(THREADZ) || defined(LOCKLESS)
969 unlock_scu ();
970 #endif
971 doFault (FAULT_EXF, fst_zero, "Execute fault");
972 }
973
974 if (cpu.tweaks.l68_mode) {
975 if (cpu.FFV_faults & 1u)
976 {
977 cpu.FFV_faults &= ~1u;
978 #if defined(THREADZ) || defined(LOCKLESS)
979 unlock_scu ();
980 #endif
981 do_FFV_fault (cpup, 1, "OC TRAP");
982 }
983 if (cpu.FFV_faults & 2u)
984 {
985 cpu.FFV_faults &= ~2u;
986 #if defined(THREADZ) || defined(LOCKLESS)
987 unlock_scu ();
988 #endif
989 do_FFV_fault (cpup, 2, "CU HIST OVF TRAP");
990 }
991 if (cpu.FFV_faults & 4u)
992 {
993 cpu.FFV_faults &= ~4u;
994 #if defined(THREADZ) || defined(LOCKLESS)
995 unlock_scu ();
996 #endif
997 do_FFV_fault (cpup, 3, "ADR TRAP");
998 }
999 }
1000 #if defined(THREADZ) || defined(LOCKLESS)
1001 unlock_scu ();
1002 #endif
1003 doFault (FAULT_TRB, (_fault_subtype) {.bits=cpu.g7Faults}, "Dazed and confused in doG7Fault");
1004 }
1005
1006 void advanceG7Faults (cpu_state_t * cpup)
1007 {
1008
1009 if (!cpu.g7FaultsPreset && !cpu.FFV_faults_preset)
1010 return;
1011
1012 #if defined(THREADZ) || defined(LOCKLESS)
1013 lock_scu ();
1014 uint zero = 0;
1015
1016 cpu.g7Faults = atomic_exchange_explicit(&cpu.g7FaultsPreset, zero, memory_order_acquire);
1017 #else
1018 cpu.g7Faults |= cpu.g7FaultsPreset;
1019 cpu.g7FaultsPreset = 0;
1020 #endif
1021 L68_ (
1022 cpu.FFV_faults |= cpu.FFV_faults_preset;
1023 cpu.FFV_faults_preset = 0;
1024 )
1025 #if defined(THREADZ) || defined(LOCKLESS)
1026 unlock_scu ();
1027 #endif
1028 }