This source file includes following definitions.
- SET_PR_BITNO
- SET_AR_CHAR_BITNO
- trackport
- doFault
- core_write
- core_write_zone
- core_read2
- core_write2
- core_readN
- core_writeN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #if !defined(__STDC_WANT_IEC_60559_BFP_EXT__)
21 # define __STDC_WANT_IEC_60559_BFP_EXT__ 1
22 #endif
23
24 #include <sys/types.h>
25
26 #if defined(__APPLE__)
27 # undef SCHED_NEVER_YIELD
28 # define SCHED_NEVER_YIELD 1
29 # include <mach/thread_policy.h>
30 # include <mach/task_info.h>
31 # include <sys/types.h>
32 # include <sys/sysctl.h>
33 # include <mach/thread_policy.h>
34 # include <mach/thread_act.h>
35 #endif
36
37 #include "../simh/sim_timer.h"
38 #include "hdbg.h"
39
40 #define N_CPU_UNITS 1
41
42
43 #define JMP_ENTRY 0
44 #define JMP_REENTRY 1
45 #define JMP_STOP 2
46 #define JMP_SYNC_FAULT_RETURN 3
47 #define JMP_REFETCH 4
48 #define JMP_RESTART 5
49
50
51
52
53
54 typedef enum
55 {
56 ABSOLUTE_mode,
57 APPEND_mode,
58 } addr_modes_e;
59
60
61
62
63
64 typedef enum
65 {
66 FAULT_cycle,
67 EXEC_cycle,
68 FAULT_EXEC_cycle,
69 INTERRUPT_cycle,
70 INTERRUPT_EXEC_cycle,
71 FETCH_cycle,
72 PSEUDO_FETCH_cycle,
73 SYNC_FAULT_RTN_cycle,
74 } cycles_e;
75
76 struct tpr_s
77 {
78 word3 TRR;
79 word15 TSR;
80 word6 TBR;
81
82 word18 CA;
83
84 };
85
86 struct ppr_s
87 {
88 word3 PRR;
89
90
91 word15 PSR;
92 word1 P;
93
94
95
96
97 word18 IC;
98
99 };
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 struct par_s
158 {
159 word15 SNR;
160
161 word3 RNR;
162
163
164 word6 PR_BITNO;
165
166
167
168 word2 AR_CHAR;
169 word4 AR_BITNO;
170
171 word18 WORDNO;
172
173 };
174
175
176
177 #define AR PAR
178 #define PR PAR
179
180 struct bar_s
181 {
182 word9 BASE;
183
184
185 word9 BOUND;
186
187
188
189
190 };
191
192 struct dsbr_s
193 {
194 word24 ADDR;
195
196
197
198 word14 BND;
199
200
201
202 word1 U;
203
204 word12 STACK;
205
206
207
208 };
209
210
211
212
213
214
215 struct sdw_s
216 {
217 word24 ADDR;
218
219
220
221 word3 R1;
222 word3 R2;
223 word3 R3;
224 word14 BOUND;
225
226
227 word1 R;
228
229 word1 E;
230
231
232
233 word1 W;
234
235 word1 P;
236
237
238 word1 U;
239
240
241
242
243
244 word1 G;
245
246
247
248 word1 C;
249
250
251 word14 EB;
252
253
254 word15 POINTER;
255
256 word1 DF;
257
258
259
260 word2 FC;
261 word1 FE;
262
263
264
265
266
267 word6 USE;
268
269
270
271
272
273
274
275 };
276
277 typedef struct sdw_s sdw_s;
278 typedef struct sdw_s sdw0_s;
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 struct ptw_s
337 {
338 word18 ADDR;
339
340 word1 U;
341 word1 M;
342
343
344
345
346 word1 DF;
347
348
349 word2 FC;
350 word15 POINTER;
351
352 word12 PAGENO;
353
354
355 word1 FE;
356
357
358
359
360
361 word6 USE;
362
363
364
365
366
367
368
369
370 };
371
372 typedef struct ptw_s ptw_s;
373 typedef struct ptw_s ptw0_s;
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398 struct cache_mode_register_s
399 {
400 word15 cache_dir_address;
401 word1 par_bit;
402 word1 lev_ful;
403 word1 csh1_on;
404
405 word1 csh2_on;
406
407
408 word1 opnd_on;
409
410 word1 inst_on;
411
412
413
414
415
416
417
418 word1 csh_reg;
419 word1 str_asd;
420 word1 col_ful;
421 word2 rro_AB;
422 word1 bypass_cache;
423 word2 luf;
424
425
426
427
428
429 };
430
431 typedef struct cache_mode_register_s cache_mode_register_s;
432
433 typedef struct mode_register_s
434 {
435 word36 r;
436
437
438 word15 FFV;
439 word1 OC_TRAP;
440 word1 ADR_TRAP;
441 word9 OPCODE;
442 word1 OPCODEX;
443
444
445
446 word1 sdpap;
447 word1 separ;
448
449
450
451
452 word1 hrhlt;
453
454
455 word1 hrxfr;
456
457
458 word1 ihr;
459 word1 ihrrs;
460
461
462
463
464 word1 hexfp;
465
466 word1 emr;
467 } mode_register_s;
468
469 extern DEVICE cpu_dev;
470
471
472 typedef struct EISaddr_s
473 {
474 #if !defined(EIS_PTR)
475 word18 address;
476 #endif
477
478 word36 data;
479 word1 bit;
480 eRW mode;
481
482 int last_bit_posn;
483
484
485
486
487
488 #if !defined(EIS_PTR3)
489 int TA;
490 #endif
491 int TN;
492 int cPos;
493 int bPos;
494
495 #if !defined(EIS_PTR4)
496
497 word15 SNR;
498
499 word3 RNR;
500
501 MemoryAccessType mat;
502 #endif
503
504
505
506
507
508
509
510
511
512
513
514
515
516 bool cacheValid;
517 bool cacheDirty;
518 #define paragraphSz 8
519 #define paragraphMask 077777770
520 #define paragraphOffsetMask 07
521 word36 cachedParagraph [paragraphSz];
522 bool wordDirty [paragraphSz];
523 word18 cachedAddr;
524
525 } EISaddr;
526
527 typedef struct EISstruct_s
528 {
529 word36 op [3];
530 #define OP1 op [0]
531 #define OP2 op [1]
532 #define OP3 op [2]
533
534 bool P;
535
536 uint MF [3];
537 #define MF1 MF [0]
538 #define MF2 MF [1]
539 #define MF3 MF [2]
540
541 uint CN [3];
542 #define CN1 CN [0]
543 #define CN2 CN [1]
544 #define CN3 CN [2]
545
546 uint WN [3];
547 #define WN1 WN [0]
548 #define WN2 WN [1]
549 #define WN3 CN [2]
550
551 uint C [3];
552 #define C1 C [0]
553 #define C2 C [1]
554 #define C3 C [2]
555
556 uint B [3];
557 #define B1 B [0]
558 #define B2 B [1]
559 #define B3 B [2]
560
561 uint N [3];
562 #define N1 N [0]
563 #define N2 N [1]
564 #define N3 N [2]
565
566 uint TN [3];
567 #define TN1 TN [0]
568 #define TN2 TN [1]
569 #define TN3 TN [2]
570
571 #if defined(EIS_PTR3)
572 # define TA1 cpu.du.TAk[0]
573 # define TA2 cpu.du.TAk[1]
574 # define TA3 cpu.du.TAk[2]
575 #else
576
577 uint TA [3];
578 # define TA1 TA [0]
579 # define TA2 TA [1]
580 # define TA3 TA [2]
581 #endif
582
583 uint S [3];
584 #define S1 S [0]
585 #define S2 S [1]
586 #define S3 S [2]
587
588 int SF [3];
589 #define SF1 SF [0]
590 #define SF2 SF [1]
591 #define SF3 SF [2]
592
593 word18 _flags;
594 word18 _faults;
595
596 word72s x;
597
598
599
600 word9 editInsertionTable [8];
601
602 int mopIF;
603 struct MOP_struct_s *m;
604
605 word9 inBuffer [64];
606 word9 *in;
607 uint inBufferCnt;
608 word9 outBuffer [64];
609 word9 *out;
610
611 int exponent;
612 int sign;
613
614 #if defined(EIS_PTR2)
615 # define KMOP 1
616 #else
617 EISaddr *mopAddress;
618 #endif
619
620 int mopTally;
621 int mopPos;
622
623
624
625
626
627 bool mopES;
628
629 bool mopSN;
630
631
632
633
634
635
636
637
638
639
640 bool mopZ;
641
642
643 bool mopBZ;
644
645
646
647
648
649
650 EISaddr addr [3];
651
652 #define ADDR1 addr [0]
653 int srcTally;
654 int srcTA;
655 int srcSZ;
656
657 #define ADDR2 addr [1]
658
659 #define ADDR3 addr [2]
660 int dstTally;
661 int dstSZ;
662
663 bool mvne;
664 } EISstruct;
665
666
667
668 typedef struct DCDstruct_s
669 {
670 struct opcode_s * info;
671 uint32 opcode;
672 bool opcodeX;
673 uint32 opcode10;
674 word18 address;
675 word1 b29;
676 bool i;
677 word6 tag;
678
679 bool stiTally;
680 bool restart;
681 } DCDstruct;
682
683
684
685 typedef struct
686 {
687 vol int fault [N_FAULT_GROUPS];
688
689 vol bool XIP [N_SCU_UNITS_MAX];
690 } events_t;
691
692
693
694 enum procModeSettings { procModeGCOS = 1, procModeMultics = 0 };
695
696
697 typedef struct
698 {
699 uint FLT_BASE;
700 uint cpu_num;
701 word36 data_switches;
702 word18 addr_switches;
703 uint assignment [N_CPU_PORTS];
704 uint interlace [N_CPU_PORTS];
705 uint enable [N_CPU_PORTS];
706 uint init_enable [N_CPU_PORTS];
707 uint store_size [N_CPU_PORTS];
708 enum procModeSettings procMode;
709
710 bool enable_cache;
711 bool sdwam_enable;
712 bool ptwam_enable;
713
714
715 uint serno;
716 } switches_t;
717
718
719 typedef struct {
720 uint proc_speed;
721 bool hex_mode_installed;
722 bool prom_installed;
723 bool cache_installed;
724 bool clock_slave_installed;
725 } optionsType;
726
727
728 typedef struct {
729 uint report_faults;
730 uint tro_enable;
731 uint drl_fatal;
732 bool useMap;
733
734 uint dis_enable;
735 uint halt_on_unimp;
736 bool isolts_mode;
737 uint enable_wam;
738
739 bool enable_emcall;
740 bool nodis;
741 bool l68_mode;
742 } tweaksType;
743
744 enum ou_cycle_e
745 {
746 ou_GIN = 0400,
747 ou_GOS = 0200,
748 ou_GD1 = 0100,
749 ou_GD2 = 0040,
750 ou_GOE = 0020,
751 ou_GOA = 0010,
752 ou_GOM = 0004,
753 ou_GON = 0002,
754 ou_GOF = 0001
755 };
756
757 typedef struct
758 {
759
760 bool directOperandFlag;
761 word36 directOperand;
762 word6 characterOperandSize;
763 word3 characterOperandOffset;
764 word18 character_address;
765 word36 character_data;
766 bool crflag;
767
768
769 word2 eac;
770 word1 RB1_FULL;
771 word1 RP_FULL;
772 word1 RS_FULL;
773 word9 cycle;
774 word1 STR_OP;
775
776
777 #if defined(PANEL68)
778 word9 RS;
779 word4 opsz;
780 word10 reguse;
781 #endif
782 } ou_unit_data_t;
783
784
785
786 enum APUH_e
787 {
788 APUH_FDSPTW = 1llu << (35 - 17),
789 APUH_MDSPTW = 1llu << (35 - 18),
790 APUH_FSDWP = 1llu << (35 - 19),
791 APUH_FPTW = 1llu << (35 - 20),
792 APUH_FPTW2 = 1llu << (35 - 21),
793 APUH_MPTW = 1llu << (35 - 22),
794 APUH_FANP = 1llu << (35 - 23),
795 APUH_FAP = 1llu << (35 - 24)
796 };
797
798 enum {
799
800 apu_FLT = 1ll << (33 - 0),
801
802
803 apu_ESN_PSR = 0,
804 apu_ESN_SNR = 1ll << (33 - 1),
805 apu_ESN_TSR = 1ll << (33 - 2),
806
807
808 apu_HOLD = 1ll << (33 - 4),
809
810
811
812
813 apu_TP_P = 1ll << (33 - 8),
814
815 apu_PP_P = 1ll << (33 - 9),
816
817
818
819
820
821
822
823
824
825
826 apu_FDPT = 1ll << (33 - 20),
827 apu_MDPT = 1ll << (33 - 21),
828 apu_FSDP = 1ll << (33 - 22),
829 apu_FSDN = 1ll << (33 - 23),
830 apu_FPTW = 1ll << (33 - 24),
831 apu_MPTW = 1ll << (33 - 25),
832 apu_FPTW2 = 1ll << (33 - 26),
833 apu_FAP = 1ll << (33 - 27),
834
835 apu_FANP = 1ll << (33 - 28),
836
837
838 apu_FA = 1ll << (33 - 30),
839
840 apu_PIAU = 1ll << (33 - 32)
841
842 };
843
844 typedef struct
845 {
846 processor_cycle_type lastCycle;
847 #if defined(PANEL68)
848 word34 state;
849 #endif
850 } apu_unit_data_t;
851
852 typedef struct
853 {
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881 word1 XSF;
882 word1 SDWAMM;
883 word1 SD_ON;
884 word1 PTWAMM;
885 word1 PT_ON;
886
887
888
889
890
891
892
893
894
895
896
897
898
899 word12 APUCycleBits;
900
901
902
903
904
905
906
907 word1 IRO_ISN;
908
909 word1 OEB_IOC;
910
911
912 word1 EOFF_IAIM;
913
914
915 word1 ORB_ISP;
916
917 word1 ROFF_IPR;
918
919 word1 OWB_NEA;
920
921 word1 WOFF_OOB;
922
923 word1 NO_GA;
924 word1 OCB;
925 word1 OCALL;
926 word1 BOC;
927
928 word1 PTWAM_ER;
929 word1 CRT;
930 word1 RALR;
931
932 word1 SDWAM_ER;
933 word1 OOSB;
934 word1 PARU;
935 word1 PARL;
936 word1 ONC1;
937 word1 ONC2;
938 word4 IA;
939 word3 IACHN;
940 word3 CNCHN;
941 word5 FI_ADDR;
942 word1 FLT_INT;
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959 word6 delta;
960
961
962
963
964
965
966
967
968
969
970
971
972
973 word3 TSN_PRNO [3];
974 word1 TSN_VALID [3];
975
976
977
978
979
980 word18 IR;
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001 word1 repeat_first;
1002
1003 word1 rpt;
1004 word1 rd;
1005 word1 rl;
1006 word1 pot;
1007
1008
1009
1010
1011
1012
1013 word1 xde;
1014
1015 word1 xdo;
1016 word1 itp;
1017 word1 rfi;
1018 word1 its;
1019 word1 FIF;
1020 word6 CT_HOLD;
1021
1022
1023 word36 IWB;
1024
1025
1026 word36 IRODD;
1027 } ctl_unit_data_t;
1028
1029 #define USE_IRODD (cpu.cu.rd && ((cpu. PPR.IC & 1) != 0))
1030 #define IWB_IRODD (USE_IRODD ? cpu.cu.IRODD : cpu.cu.IWB)
1031
1032
1033 enum du_cycle1_e
1034 {
1035
1036 du1_nFPOL = 0400000000000ull,
1037
1038 du1_nFPOP = 0200000000000ull,
1039
1040 du1_nNEED_DESC = 0100000000000ull,
1041
1042 du1_nSEL_DIR = 0040000000000ull,
1043
1044 du1_nDLEN_DIRECT = 0020000000000ull,
1045
1046 du1_nDFRST = 0010000000000ull,
1047
1048 du1_nFEXR = 0004000000000ull,
1049
1050 du1_nLAST_DFRST = 0002000000000ull,
1051
1052 du1_nDDU_LDEA = 0001000000000ull,
1053
1054 du1_nDDU_STEA = 0000400000000ull,
1055
1056 du1_nDREDO = 0000200000000ull,
1057
1058 du1_nDLVL_WD_SZ = 0000100000000ull,
1059
1060 du1_nEXH = 0000040000000ull,
1061
1062 du1_DEND_SEQ = 0000020000000ull,
1063
1064 du1_nEND = 0000010000000ull,
1065
1066 du1_nDU_RD_WRT = 0000004000000ull,
1067
1068 du1_nPTRA00 = 0000002000000ull,
1069
1070 du1_nPTRA01 = 0000001000000ull,
1071
1072 du1_FA_I1 = 0000000400000ull,
1073
1074 du1_FA_I2 = 0000000200000ull,
1075
1076 du1_FA_I3 = 0000000100000ull,
1077
1078 du1_nWRD = 0000000040000ull,
1079
1080 du1_nNINE = 0000000020000ull,
1081
1082 du1_nSIX = 0000000010000ull,
1083
1084 du1_nFOUR = 0000000004000ull,
1085
1086 du1_nBIT = 0000000002000ull,
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096 du1_FSAMPL = 0000000000040ull,
1097
1098 du1_nDFRST_CT = 0000000000020ull,
1099
1100 du1_nADJ_LENTGH = 0000000000010ull,
1101
1102 du1_nINTRPTD = 0000000000004ull,
1103
1104 du1_nINHIB = 0000000000002ull,
1105
1106
1107 };
1108
1109
1110 enum du_cycle2_e
1111 {
1112
1113 du2_DUD = 0400000000000ull,
1114
1115 du2_nGDLDA = 0200000000000ull,
1116
1117 du2_nGDLDB = 0100000000000ull,
1118
1119 du2_nGDLDC = 0040000000000ull,
1120
1121 du2_NLD1 = 0020000000000ull,
1122
1123 du2_GLDP1 = 0010000000000ull,
1124
1125 du2_NLD2 = 0004000000000ull,
1126
1127 du2_GLDP2 = 0002000000000ull,
1128
1129 du2_ANLD1 = 0001000000000ull,
1130
1131 du2_ANLD2 = 0000400000000ull,
1132
1133 du2_LDWRT1 = 0000200000000ull,
1134
1135 du2_LDWRT2 = 0000100000000ull,
1136
1137 du2_nDATA_AVLDU = 0000040000000ull,
1138
1139 du2_WRT1 = 0000020000000ull,
1140
1141 du2_GSTR = 0000010000000ull,
1142
1143 du2_ANSTR = 0000004000000ull,
1144
1145 du2_FSTR_OP_AV = 0000002000000ull,
1146
1147 du2_nFEND_SEQ = 0000001000000ull,
1148
1149 du2_nFLEN_128 = 0000000400000ull,
1150
1151 du2_FGCH = 0000000200000ull,
1152
1153 du2_FANPK = 0000000100000ull,
1154
1155 du2_FEXOP = 0000000040000ull,
1156
1157 du2_FBLNK = 0000000020000ull,
1158
1159
1160
1161 du2_DGBD = 0000000004000ull,
1162
1163 du2_DGDB = 0000000002000ull,
1164
1165 du2_DGSP = 0000000001000ull,
1166
1167 du2_FFLTG = 0000000000400ull,
1168
1169 du2_FRND = 0000000000200ull,
1170
1171 du2_DADD_GATE = 0000000000100ull,
1172
1173 du2_DMP_DV_GATE = 0000000000040ull,
1174
1175 du2_DXPN_GATE = 0000000000020ull,
1176
1177
1178
1179
1180
1181
1182
1183
1184 };
1185
1186
1187 #define DU_CYCLE_GDLDA { clrmask (& cpu.du.cycle2, du2_nGDLDA); \
1188 setmask (& cpu.du.cycle2, du2_nGDLDB | du2_nGDLDC); }
1189 #define DU_CYCLE_GDLDB { clrmask (& cpu.du.cycle2, du2_nGDLDB); \
1190 setmask (& cpu.du.cycle2, du2_nGDLDA | du2_nGDLDC); }
1191 #define DU_CYCLE_GDLDC { clrmask (& cpu.du.cycle2, du2_nGDLDC); \
1192 setmask (& cpu.du.cycle2, du2_nGDLDA | du2_nGDLDB); }
1193 #define DU_CYCLE_FA_I1 setmask (& cpu.du.cycle1, du1_FA_I1)
1194 #define DU_CYCLE_FA_I2 setmask (& cpu.du.cycle1, du1_FA_I2)
1195 #define DU_CYCLE_FA_I3 setmask (& cpu.du.cycle1, du1_FA_I3)
1196 #define DU_CYCLE_ANLD1 setmask (& cpu.du.cycle2, du2_ANLD1)
1197 #define DU_CYCLE_ANLD2 setmask (& cpu.du.cycle2, du2_ANLD2)
1198 #define DU_CYCLE_NLD1 setmask (& cpu.du.cycle2, du2_NLD1)
1199 #define DU_CYCLE_NLD2 setmask (& cpu.du.cycle2, du2_NLD2)
1200 #define DU_CYCLE_FRND setmask (& cpu.du.cycle2, du2_FRND)
1201 #define DU_CYCLE_DGBD setmask (& cpu.du.cycle2, du2_DGBD)
1202 #define DU_CYCLE_DGDB setmask (& cpu.du.cycle2, du2_DGDB)
1203 #define DU_CYCLE_DDU_LDEA clrmask (& cpu.du.cycle1, du1_nDDU_LDEA)
1204 #define DU_CYCLE_DDU_STEA clrmask (& cpu.du.cycle1, du1_nDDU_STEA)
1205 #define DU_CYCLE_END clrmask (& cpu.du.cycle1, du1_nEND)
1206 #define DU_CYCLE_LDWRT1 setmask (& cpu.du.cycle2, du2_LDWRT1)
1207 #define DU_CYCLE_LDWRT2 setmask (& cpu.du.cycle2, du2_LDWRT2)
1208 #define DU_CYCLE_FEXOP setmask (& cpu.du.cycle2, du2_FEXOP)
1209 #define DU_CYCLE_ANSTR setmask (& cpu.du.cycle2, du2_ANSTR)
1210 #define DU_CYCLE_GSTR setmask (& cpu.du.cycle2, du2_GSTR)
1211 #define DU_CYCLE_FLEN_128 clrmask (& cpu.du.cycle2, du2_nFLEN_128)
1212 #define DU_CYCLE_FDUD { cpu.du.cycle1 = \
1213 du1_nFPOL | \
1214 du1_nFPOP | \
1215 du1_nNEED_DESC | \
1216 du1_nSEL_DIR | \
1217 du1_nDLEN_DIRECT | \
1218 du1_nDFRST | \
1219 du1_nFEXR | \
1220 du1_nLAST_DFRST | \
1221 du1_nDDU_LDEA | \
1222 du1_nDDU_STEA | \
1223 du1_nDREDO | \
1224 du1_nDLVL_WD_SZ | \
1225 du1_nEXH | \
1226 du1_nEND | \
1227 du1_nDU_RD_WRT | \
1228 du1_nWRD | \
1229 du1_nNINE | \
1230 du1_nSIX | \
1231 du1_nFOUR | \
1232 du1_nBIT | \
1233 du1_nINTRPTD | \
1234 du1_nINHIB; \
1235 cpu.du.cycle2 = \
1236 du2_DUD | \
1237 du2_nGDLDA | \
1238 du2_nGDLDB | \
1239 du2_nGDLDC | \
1240 du2_nDATA_AVLDU | \
1241 du2_nFEND_SEQ | \
1242 du2_nFLEN_128; \
1243 }
1244 #define DU_CYCLE_nDUD clrmask (& cpu.du.cycle2, du2_DUD)
1245
1246 #if defined(PANEL68)
1247
1248 # define CPT(R,C) cpu.cpt[R][C]=1
1249 # define CPTUR(C) cpu.cpt[cpt5L][C]=1
1250 #else
1251 # define CPT(R,C)
1252 # define CPTUR(C)
1253 #endif
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346 typedef struct du_unit_data_t
1347 {
1348
1349
1350
1351 word1 Z;
1352
1353 word1 NOP;
1354
1355 word24 CHTALLY;
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384 word10 LEVEL1;
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401 word1 R;
1402
1403
1404
1405
1406
1407
1408
1409
1410 word10 LEVEL2;
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432 word3 JMP;
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444 word2 TAk [3];
1445
1446
1447
1448
1449 word18 Dk_PTR_W [3];
1450 #define D1_PTR_W Dk_PTR_W [0]
1451 #define D2_PTR_W Dk_PTR_W [1]
1452 #define D3_PTR_W Dk_PTR_W [2]
1453
1454 word6 Dk_PTR_B [3];
1455 #define D1_PTR_B Dk_PTR_B [0]
1456 #define D2_PTR_B Dk_PTR_B [1]
1457 #define D3_PTR_B Dk_PTR_B [2]
1458
1459 word24 Dk_RES [3];
1460 #define D_RES Dk_RES
1461 #define D1_RES Dk_RES [0]
1462 #define D2_RES Dk_RES [1]
1463 #define D3_RES Dk_RES [2]
1464
1465 word1 Fk [3];
1466
1467 #define F1 Fk [0]
1468 #define F2 Fk [0]
1469 #define F3 Fk [0]
1470
1471 word1 Ak [3];
1472
1473
1474
1475
1476 word7 MF [3];
1477
1478
1479 word36 image [8];
1480
1481 #if defined(PANEL68)
1482 word37 cycle1;
1483 word37 cycle2;
1484 word1 POL;
1485 word1 POP;
1486 #endif
1487 } du_unit_data_t;
1488
1489 #if defined(PANEL68)
1490
1491 enum
1492 {
1493 ps_PIA = 0200,
1494 ps_POA = 0100,
1495 ps_RIW = 0040,
1496 ps_SIW = 0020,
1497 ps_POT = 0010,
1498 ps_PON = 0004,
1499 ps_RAW = 0002,
1500 ps_SAW = 0001
1501 };
1502 #endif
1503
1504
1505
1506
1507
1508 enum
1509 {
1510 CUH_XINT = 0100,
1511 CUH_IFT = 040,
1512 CUH_CRD = 020,
1513 CUH_MRD = 010,
1514 CUH_MSTO = 04,
1515 CUH_PIB = 02
1516 };
1517
1518 #define N_DPS8M_WAM_ENTRIES 64
1519 #define N_DPS8M_WAM_MASK 077
1520 #define N_L68_WAM_ENTRIES 16
1521 #define N_L68_WAM_MASK 017
1522 #define N_NAX_WAM_ENTRIES 64
1523 #define N_MODEL_WAM_ENTRIES (cpu.tweaks.l68_mode ? N_L68_WAM_ENTRIES : N_DPS8M_WAM_ENTRIES)
1524
1525 #include "ucache.h"
1526
1527 typedef struct cpu_state_s
1528 {
1529 EISstruct currentEISinstruction;
1530
1531 uCache_t uCache;
1532
1533 unsigned long long cycleCnt;
1534 unsigned long long instrCnt;
1535 unsigned long long instrCntT0;
1536 unsigned long long instrCntT1;
1537 unsigned long long lockCnt;
1538 unsigned long long lockImmediate;
1539 unsigned long long lockWait;
1540 unsigned long long lockWaitMax;
1541 #if !defined(SCHED_NEVER_YIELD)
1542 unsigned long long lockYield;
1543 #endif
1544
1545
1546 _fault_subtype subFault;
1547
1548 word36 rA;
1549 word36 rQ;
1550
1551 fault_acv_subtype_ acvFaults;
1552
1553 sdw_s * SDW;
1554
1555
1556 word36 zone;
1557
1558 ptw_s * PTW;
1559
1560 word36 CY;
1561
1562 uint64 lufCounter;
1563
1564 _fault_subtype dlySubFltNum;
1565
1566 const char * dlyCtx;
1567
1568 word36 faultRegister [2];
1569
1570 word36 itxPair [2];
1571
1572
1573
1574
1575
1576 mode_register_s MR;
1577
1578
1579
1580 mode_register_s MR_cache;
1581
1582 DCDstruct currentInstruction;
1583
1584 ou_unit_data_t ou;
1585
1586 word36 Ypair[2];
1587 word36 Yblock8[8];
1588 word36 Yblock16[16];
1589 word36 Yblock32[32];
1590
1591 word36 scu_data[8];
1592
1593 ctl_unit_data_t cu;
1594 du_unit_data_t du;
1595
1596 switches_t switches;
1597 optionsType options;
1598 tweaksType tweaks;
1599 switches_t isolts_switches_save;
1600
1601 jmp_buf jmpMain;
1602
1603 unsigned long faultCnt [N_FAULTS];
1604
1605 _fault_subtype g7SubFaults [N_FAULTS];
1606
1607 word36 history [N_HIST_SETS] [N_MAX_HIST_SIZE] [2];
1608
1609 cycles_e cycle;
1610
1611 _fault faultNumber;
1612
1613 apu_unit_data_t apu;
1614
1615 word27 rTR;
1616 #if defined(THREADZ) || defined(LOCKLESS)
1617 uint rTRsample;
1618 #endif
1619 word24 rY;
1620
1621 word18 lnk;
1622
1623 uint g7FaultsPreset;
1624 uint g7Faults;
1625
1626 word24 iefpFinalAddress;
1627
1628
1629 uint rTRlsb;
1630 uint shadowTR;
1631 uint TR0;
1632
1633
1634 _fault dlyFltNum;
1635
1636 word18 last_write;
1637
1638 #if defined(LOCKLESS)
1639 word24 locked_addr;
1640 word24 char_word_address;
1641 #endif
1642
1643 word24 rmw_address;
1644
1645 uint restart_address;
1646
1647 struct
1648 {
1649 word15 PSR;
1650 word3 PRR;
1651 word18 IC;
1652 } cu_data;
1653 uint rTRticks;
1654
1655 struct tpr_s TPR;
1656 struct ppr_s PPR;
1657 struct dsbr_s DSBR;
1658 ptw0_s PTW0;
1659
1660 uint history_cyclic [N_HIST_SETS];
1661
1662 sdw_s SDW0;
1663 sdw_s _s;
1664
1665 word18 rX [8];
1666
1667
1668 uint sc_num_banks [N_SCU_UNITS_MAX];
1669
1670
1671
1672
1673
1674
1675 uint scu_port[N_SCU_UNITS_MAX];
1676
1677
1678
1679 uint FFV_faults_preset;
1680 uint FFV_faults;
1681 uint FFV_fault_number;
1682
1683 #if defined(AFFINITY)
1684 uint affinity;
1685 #endif
1686
1687 events_t events;
1688
1689 word24 pad[16];
1690
1691 struct par_s PAR [8];
1692
1693 ptw_s PTWAM [N_NAX_WAM_ENTRIES];
1694
1695
1696
1697
1698
1699 int sc_addr_map [N_SCBANKS];
1700
1701 int sc_scu_map [N_SCBANKS];
1702
1703 sdw_s SDWAM [N_NAX_WAM_ENTRIES];
1704
1705
1706 word12 AM_tally;
1707
1708 struct bar_s BAR;
1709
1710 cache_mode_register_s CMR;
1711
1712
1713
1714 bool interrupt_flag;
1715 bool g7_flag;
1716
1717 bool wasXfer;
1718
1719 bool wasInhibited;
1720
1721
1722 bool isExec;
1723
1724 bool isXED;
1725
1726
1727 bool isolts_switches_saved;
1728
1729 word8 rE;
1730
1731 word6 rTAG;
1732 word3 rRALR;
1733 word3 RSDWH_R1;
1734
1735
1736
1737 word6 SDWAMR;
1738
1739
1740 bool useZone;
1741
1742
1743
1744 word6 PTWAMR;
1745
1746
1747 bool bTroubleFaultCycle;
1748
1749 bool lufOccurred;
1750 bool secret_addressing_mode;
1751
1752
1753 bool skip_cu_hist;
1754
1755
1756 bool dlyFlt;
1757
1758 bool restart;
1759
1760
1761 bool is_FFV;
1762
1763 #if defined(ROUND_ROBIN)
1764 bool isRunning;
1765 #endif
1766
1767 #if defined(AFFINITY)
1768 bool set_affinity;
1769 #endif
1770
1771 #if defined(SPEED)
1772 # define SC_MAP_ADDR(addr,real_addr) \
1773 if (cpu.tweaks.useMap) \
1774 { \
1775 uint pgnum = addr / SCBANK_SZ; \
1776 uint os = addr % SCBANK_SZ; \
1777 int base = cpu.sc_addr_map[pgnum]; \
1778 if (base < 0) \
1779 { \
1780 doFault (FAULT_STR, fst_str_nea, __func__); \
1781 } \
1782 real_addr = (uint) base + os; \
1783 } \
1784 else \
1785 real_addr = addr;
1786 #else
1787 # define SC_MAP_ADDR(addr,real_addr) \
1788 if (cpu.tweaks.useMap) \
1789 { \
1790 uint pgnum = addr / SCBANK_SZ; \
1791 uint os = addr % SCBANK_SZ; \
1792 int base = cpu.sc_addr_map[pgnum]; \
1793 if (base < 0) \
1794 { \
1795 doFault (FAULT_STR, fst_str_nea, __func__); \
1796 } \
1797 real_addr = (uint) base + os; \
1798 } \
1799 else \
1800 { \
1801 nem_check (addr, __func__); \
1802 real_addr = addr; \
1803 }
1804 #endif
1805
1806 #if defined(PANEL68)
1807
1808 word18 lastPTWOffset;
1809
1810
1811
1812 bool lastPTWIsDS;
1813 word18 APUDataBusOffset;
1814 word24 APUDataBusAddr;
1815 word24 APUMemAddr;
1816 word1 panel4_red_ready_light_state;
1817 word1 panel7_enabled_light_state;
1818
1819 volatile word15 APU_panel_segno_sw;
1820 volatile word1 APU_panel_enable_match_ptw_sw;
1821 volatile word1 APU_panel_enable_match_sdw_sw;
1822 volatile word1 APU_panel_scroll_select_ul_sw;
1823 volatile word4 APU_panel_scroll_select_n_sw;
1824 volatile word4 APU_panel_scroll_wheel_sw;
1825
1826 volatile word18 APU_panel_enter_sw;
1827 volatile word18 APU_panel_display_sw;
1828 volatile word4 CP_panel_wheel_sw;
1829 volatile word4 DATA_panel_ds_sw;
1830 volatile word4 DATA_panel_d1_sw;
1831 volatile word4 DATA_panel_d2_sw;
1832 volatile word4 DATA_panel_d3_sw;
1833 volatile word4 DATA_panel_d4_sw;
1834 volatile word4 DATA_panel_d5_sw;
1835 volatile word4 DATA_panel_d6_sw;
1836 volatile word4 DATA_panel_d7_sw;
1837 volatile word4 DATA_panel_wheel_sw;
1838 volatile word4 DATA_panel_addr_stop_sw;
1839 volatile word1 DATA_panel_enable_sw;
1840 volatile word1 DATA_panel_validate_sw;
1841 volatile word1 DATA_panel_auto_fast_sw;
1842 volatile word1 DATA_panel_auto_slow_sw;
1843 volatile word4 DATA_panel_cycle_sw;
1844 volatile word1 DATA_panel_step_sw;
1845 volatile word1 DATA_panel_s_trig_sw;
1846 volatile word1 DATA_panel_execute_sw;
1847 volatile word1 DATA_panel_scope_sw;
1848 volatile word1 DATA_panel_init_sw;
1849 volatile word1 DATA_panel_exec_sw;
1850 volatile word4 DATA_panel_hr_sel_sw;
1851 volatile word4 DATA_panel_trackers_sw;
1852 volatile bool panelInitialize;
1853
1854
1855 bool portBusy;
1856 word2 portSelect;
1857 word36 portAddr [N_CPU_PORTS];
1858 word36 portData [N_CPU_PORTS];
1859
1860 word36 IWRAddr;
1861 word7 dataMode;
1862
1863
1864
1865
1866
1867
1868 word8 prepare_state;
1869 bool DACVpDF;
1870 bool AR_F_E;
1871 bool INS_FETCH;
1872
1873 word1 cpt [28] [36];
1874 #endif
1875 #define cpt1U 0
1876 #define cpt1L 1
1877 #define cpt2U 2
1878 #define cpt2L 3
1879 #define cpt3U 4
1880 #define cpt3L 5
1881 #define cpt4U 6
1882 #define cpt4L 7
1883 #define cpt5U 8
1884 #define cpt5L 9
1885 #define cpt6U 10
1886 #define cpt6L 11
1887 #define cpt7U 12
1888 #define cpt7L 13
1889 #define cpt8U 14
1890 #define cpt8L 15
1891 #define cpt9U 16
1892 #define cpt9L 17
1893 #define cpt10U 18
1894 #define cpt10L 19
1895 #define cpt11U 20
1896 #define cpt11L 21
1897 #define cpt12U 22
1898 #define cpt12L 23
1899 #define cpt13U 24
1900 #define cpt13L 25
1901 #define cpt14U 26
1902 #define cpt14L 27
1903
1904 #define cptUseE 0
1905 #define cptUseBAR 1
1906 #define cptUseTR 2
1907 #define cptUseRALR 3
1908 #define cptUsePRn 4
1909 #define cptUseDSBR 12
1910 #define cptUseFR 13
1911 #define cptUseMR 14
1912 #define cptUseCMR 15
1913 #define cptUseIR 16
1914 } cpu_state_t;
1915
1916 typedef struct MOP_struct_s
1917 {
1918 char * mopName;
1919 int (* f) (cpu_state_t *);
1920 } MOP_struct;
1921
1922 #if defined(M_SHARED)
1923 extern cpu_state_t * cpus;
1924 #else
1925 extern cpu_state_t cpus [N_CPU_UNITS_MAX];
1926 #endif
1927
1928 #if defined(THREADZ) || defined(LOCKLESS)
1929 extern __thread cpu_state_t * restrict _cpup;
1930 #else
1931 extern cpu_state_t * restrict _cpup;
1932 #endif
1933
1934 #define cpu (* cpup)
1935
1936 #define N_STALL_POINTS 16
1937 struct stall_point_s
1938 {
1939 word15 segno;
1940 word18 offset;
1941 useconds_t time;
1942 };
1943 extern struct stall_point_s stall_points [N_STALL_POINTS];
1944 extern bool stall_point_active;
1945
1946 uint set_cpu_idx (uint cpuNum);
1947 #if defined(THREADZ) || defined(LOCKLESS)
1948 extern __thread uint current_running_cpu_idx;
1949 extern bool bce_dis_called;
1950 #else
1951 # if defined(ROUND_ROBIN)
1952 extern uint current_running_cpu_idx;
1953 # else
1954 # define current_running_cpu_idx 0
1955 # endif
1956 #endif
1957
1958
1959
1960 #define GET_PR_BITNO(n) (cpu.PAR[n].PR_BITNO)
1961 #define GET_AR_BITNO(n) (cpu.PAR[n].AR_BITNO)
1962 #define GET_AR_CHAR(n) (cpu.PAR[n].AR_CHAR)
1963 static inline void SET_PR_BITNO (cpu_state_t * restrict cpup, uint n, word6 b)
1964 {
1965 cpu.PAR[n].PR_BITNO = b;
1966 cpu.PAR[n].AR_BITNO = (b % 9) & MASK4;
1967 cpu.PAR[n].AR_CHAR = (b / 9) & MASK2;
1968 }
1969 #define SET_PR_BITNO(n, b) SET_PR_BITNO(cpup, n, b)
1970 static inline void SET_AR_CHAR_BITNO (cpu_state_t * restrict cpup, uint n, word2 c, word4 b)
1971 {
1972 cpu.PAR[n].PR_BITNO = c * 9 + b;
1973 cpu.PAR[n].AR_BITNO = b & MASK4;
1974 cpu.PAR[n].AR_CHAR = c & MASK2;
1975 }
1976 #define SET_AR_CHAR_BITNO(n, c, b) SET_AR_CHAR_BITNO(cpup, n, c, b)
1977
1978 bool sample_interrupts (cpu_state_t * cpup);
1979 t_stat simh_hooks (cpu_state_t * cpup);
1980 int operand_size (cpu_state_t * cpup);
1981
1982 void readOperandRead (cpu_state_t * cpup, word18 addr);
1983 void readOperandRMW (cpu_state_t * cpup, word18 addr);
1984 t_stat write_operand (cpu_state_t * cpup, word18 addr, processor_cycle_type acctyp);
1985
1986 #if defined(PANEL68)
1987 static inline void trackport (word24 a, word36 d)
1988 {
1989 cpu_state_t * cpup = _cpup;
1990
1991 word2 port = (a >> 22) & MASK2;
1992 cpu.portSelect = port;
1993 cpu.portAddr [port] = a;
1994 cpu.portData [port] = d;
1995 cpu.portBusy = false;
1996 }
1997 #endif
1998
1999 #if defined(SPEED) && defined(INLINE_CORE)
2000 # error INLINE_CORE has known issues.
2001
2002 void doFault (_fault faultNumber, _fault_subtype faultSubtype,
2003 const char * faultMsg) NO_RETURN;
2004 extern const _fault_subtype fst_str_nea;
2005
2006 static inline int core_read (word24 addr, word36 *data, \
2007 UNUSED const char * ctx)
2008 {
2009 PNL (cpu.portBusy = true;)
2010 SC_MAP_ADDR (addr, addr);
2011 * data = M[addr] & DMASK;
2012 # if defined(TR_WORK_MEM)
2013 cpu.rTRticks ++;
2014 # endif
2015 PNL (trackport (addr, * data);)
2016 return 0;
2017 }
2018
2019 static inline int core_write (word24 addr, word36 data, \
2020 UNUSED const char * ctx)
2021 {
2022 PNL (cpu.portBusy = true;)
2023 SC_MAP_ADDR (addr, addr);
2024 if (cpu.tweaks.isolts_mode)
2025 {
2026 if (cpu.MR.sdpap)
2027 {
2028 sim_warn ("failing to implement sdpap\n");
2029 cpu.MR.sdpap = 0;
2030 }
2031 if (cpu.MR.separ)
2032 {
2033 sim_warn ("failing to implement separ\n");
2034 cpu.MR.separ = 0;
2035 }
2036 }
2037 M[addr] = data & DMASK;
2038 # if defined(TR_WORK_MEM)
2039 cpu.rTRticks ++;
2040 # endif
2041 PNL (trackport (addr, data);)
2042 return 0;
2043 }
2044
2045 static inline int core_write_zone (word24 addr, word36 data, \
2046 UNUSED const char * ctx)
2047 {
2048 PNL (cpu.portBusy = true;)
2049 SC_MAP_ADDR (addr, addr);
2050 if (cpu.tweaks.isolts_mode)
2051 {
2052 if (cpu.MR.sdpap)
2053 {
2054 sim_warn ("failing to implement sdpap\n");
2055 cpu.MR.sdpap = 0;
2056 }
2057 if (cpu.MR.separ)
2058 {
2059 sim_warn ("failing to implement separ\n");
2060 cpu.MR.separ = 0;
2061 }
2062 }
2063 M[addr] = (M[addr] & ~cpu.zone) | (data & cpu.zone);
2064 cpu.useZone = false;
2065 # if defined(TR_WORK_MEM)
2066 cpu.rTRticks ++;
2067 # endif
2068 PNL (trackport (addr, data);)
2069 return 0;
2070 }
2071
2072 static inline int core_read2 (word24 addr, word36 *even, word36 *odd,
2073 UNUSED const char * ctx)
2074 {
2075 PNL (cpu.portBusy = true;)
2076 SC_MAP_ADDR (addr, addr);
2077 *even = M[addr++] & DMASK;
2078 *odd = M[addr] & DMASK;
2079 # if defined(TR_WORK_MEM)
2080 cpu.rTRticks ++;
2081 # endif
2082 PNL (trackport (addr - 1, * even);)
2083 return 0;
2084 }
2085
2086 static inline int core_write2 (word24 addr, word36 even, word36 odd,
2087 UNUSED const char * ctx)
2088 {
2089 PNL (cpu.portBusy = true;)
2090 SC_MAP_ADDR (addr, addr);
2091 if (cpu.tweaks.isolts_mode)
2092 {
2093 if (cpu.MR.sdpap)
2094 {
2095 sim_warn ("failing to implement sdpap\n");
2096 cpu.MR.sdpap = 0;
2097 }
2098 if (cpu.MR.separ)
2099 {
2100 sim_warn ("failing to implement separ\n");
2101 cpu.MR.separ = 0;
2102 }
2103 }
2104 M[addr++] = even;
2105 M[addr] = odd;
2106 PNL (trackport (addr - 1, even);)
2107 # if defined(TR_WORK_MEM)
2108 cpu.rTRticks ++;
2109 # endif
2110 return 0;
2111 }
2112 #else
2113 int core_read (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx);
2114 int core_write (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2115 int core_write_zone (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2116 int core_read2 (cpu_state_t * cpup, word24 addr, word36 *even, word36 *odd, const char * ctx);
2117 int core_write2 (cpu_state_t * cpup, word24 addr, word36 even, word36 odd, const char * ctx);
2118 #endif
2119
2120 #if defined(LOCKLESS)
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159 # if ( defined (AIX_ATOMICS) && \
2160 (! (defined (SYNC_ATOMICS))))
2161 # define SYNC_ATOMICS 1
2162 # endif
2163
2164
2165 # if (! defined (GNU_ATOMICS)) && (! defined (SYNC_ATOMICS)) && \
2166 (! defined (BSD_ATOMICS)) && (! defined (AIX_ATOMICS))
2167 # if defined(__FreeBSD__) \
2168 || defined(__DragonFly__)
2169 # undef BSD_ATOMICS
2170 # define BSD_ATOMICS 1
2171 # endif
2172 # endif
2173
2174
2175 # if (! defined (GNU_ATOMICS)) && (! defined (BSD_ATOMICS)) && \
2176 (! defined (SYNC_ATOMICS)) && (! defined (AIX_ATOMICS))
2177 # undef GNU_ATOMICS
2178 # define GNU_ATOMICS 1
2179 # endif
2180
2181 int core_read_lock (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx);
2182 int core_write_unlock (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2183 int core_unlock_all(cpu_state_t * cpup);
2184
2185 # define DEADLOCK_DETECT 0x40000000U
2186 # define MEM_LOCKED_BIT 61
2187 # define MEM_LOCKED (1LLU<<MEM_LOCKED_BIT)
2188
2189 # if !defined(SCHED_NEVER_YIELD)
2190 # undef SCHED_YIELD
2191 # define SCHED_YIELD \
2192 do \
2193 { \
2194 if ((i & 0xff) == 0) \
2195 { \
2196 sched_yield(); \
2197 cpu.lockYield++; \
2198 } \
2199 } \
2200 while(0)
2201 # else
2202 # undef SCHED_YIELD
2203 # define SCHED_YIELD \
2204 do \
2205 { \
2206 } \
2207 while(0)
2208 # endif
2209
2210 # if defined (BSD_ATOMICS)
2211 # include <machine/atomic.h>
2212
2213 # define LOCK_CORE_WORD(addr) \
2214 do \
2215 { \
2216 unsigned int i = DEADLOCK_DETECT; \
2217 while ( atomic_testandset_64((volatile uint64_t *)&M[addr], \
2218 MEM_LOCKED_BIT) == 1 && i > 0) \
2219 { \
2220 i--; \
2221 SCHED_YIELD; \
2222 } \
2223 if (i == 0) \
2224 { \
2225 sim_warn ("%s: locked %x addr %x deadlock\n", __func__, \
2226 cpu.locked_addr, addr); \
2227 } \
2228 cpu.lockCnt++; \
2229 if (i == DEADLOCK_DETECT) \
2230 cpu.lockImmediate++; \
2231 cpu.lockWait += (DEADLOCK_DETECT-i); \
2232 cpu.lockWaitMax = ((DEADLOCK_DETECT-i) > cpu.lockWaitMax) ? \
2233 (DEADLOCK_DETECT-i) : cpu.lockWaitMax; \
2234 } \
2235 while (0)
2236
2237 # define LOAD_ACQ_CORE_WORD(res, addr) \
2238 do \
2239 { \
2240 res = atomic_load_acq_64((volatile uint64_t *)&M[addr]); \
2241 } \
2242 while (0)
2243
2244 # define STORE_REL_CORE_WORD(addr, data) \
2245 do \
2246 { \
2247 atomic_store_rel_64((volatile uint64_t *)&M[addr], data & DMASK); \
2248 } \
2249 while (0)
2250
2251 # endif
2252
2253 # if defined(GNU_ATOMICS)
2254
2255 # define LOCK_CORE_WORD(addr) \
2256 do \
2257 { \
2258 unsigned int i = DEADLOCK_DETECT; \
2259 while ((__atomic_fetch_or((volatile uint64_t *)&M[addr], \
2260 MEM_LOCKED, __ATOMIC_ACQ_REL) & MEM_LOCKED) \
2261 && i > 0) \
2262 { \
2263 i--; \
2264 SCHED_YIELD; \
2265 } \
2266 if (i == 0) \
2267 { \
2268 sim_warn ("%s: locked %x addr %x deadlock\n", \
2269 __func__, cpu.locked_addr, addr); \
2270 } \
2271 cpu.lockCnt++; \
2272 if (i == DEADLOCK_DETECT) \
2273 cpu.lockImmediate++; \
2274 cpu.lockWait += (DEADLOCK_DETECT-i); \
2275 cpu.lockWaitMax = ((DEADLOCK_DETECT-i) > \
2276 cpu.lockWaitMax) ? (DEADLOCK_DETECT-i) : \
2277 cpu.lockWaitMax; \
2278 } \
2279 while (0)
2280
2281 # define LOAD_ACQ_CORE_WORD(res, addr) \
2282 do \
2283 { \
2284 res = __atomic_load_n((volatile uint64_t *)&M[addr], \
2285 __ATOMIC_ACQUIRE); \
2286 } \
2287 while (0)
2288
2289 # define STORE_REL_CORE_WORD(addr, data) \
2290 do \
2291 { \
2292 __atomic_store_n((volatile uint64_t *)&M[addr], data & \
2293 DMASK, __ATOMIC_RELEASE); \
2294 } \
2295 while (0)
2296
2297 # endif
2298
2299 # if defined(SYNC_ATOMICS)
2300 # if defined(MEMORY_ACCESS_NOT_STRONGLY_ORDERED)
2301 # define MEM_BARRIER() do { __sync_synchronize(); } while (0)
2302 # else
2303 # define MEM_BARRIER() do {} while (0)
2304 # endif
2305
2306 # define LOCK_CORE_WORD(addr) \
2307 do \
2308 { \
2309 unsigned int i = DEADLOCK_DETECT; \
2310 while ((__sync_fetch_and_or((volatile uint64_t *)&M[addr], \
2311 MEM_LOCKED) & MEM_LOCKED) && i > 0) \
2312 { \
2313 i--; \
2314 SCHED_YIELD; \
2315 } \
2316 if (i == 0) \
2317 { \
2318 sim_warn ("%s: locked %x addr %x deadlock\n", __func__, \
2319 cpu.locked_addr, addr); \
2320 } \
2321 cpu.lockCnt++; \
2322 if (i == DEADLOCK_DETECT) \
2323 cpu.lockImmediate++; \
2324 cpu.lockWait += (DEADLOCK_DETECT-i); \
2325 cpu.lockWaitMax = ((DEADLOCK_DETECT-i) > cpu.lockWaitMax) ? \
2326 (DEADLOCK_DETECT-i) : cpu.lockWaitMax; \
2327 } \
2328 while (0)
2329
2330 # define LOAD_ACQ_CORE_WORD(res, addr) \
2331 do \
2332 { \
2333 res = M[addr]; \
2334 MEM_BARRIER(); \
2335 } \
2336 while (0)
2337
2338 # define STORE_REL_CORE_WORD(addr, data) \
2339 do \
2340 { \
2341 MEM_BARRIER(); \
2342 M[addr] = data & DMASK; \
2343 } \
2344 while (0)
2345
2346 # endif
2347 #endif
2348
2349 static inline void core_readN (cpu_state_t * cpup, word24 addr, word36 * data, uint n,
2350 UNUSED const char * ctx)
2351 {
2352 for (uint i = 0; i < n; i ++)
2353 {
2354 core_read (cpup, addr + i, data + i, ctx);
2355
2356 }
2357 }
2358
2359 static inline void core_writeN (cpu_state_t * cpup, word24 addr, word36 * data, uint n,
2360 UNUSED const char * ctx)
2361 {
2362 for (uint i = 0; i < n; i ++)
2363 {
2364 core_write (cpup, addr + i, data [i], ctx);
2365
2366 }
2367 }
2368
2369 int is_priv_mode (cpu_state_t * cpup);
2370
2371
2372
2373 bool get_bar_mode (cpu_state_t * cpup);
2374 addr_modes_e get_addr_mode (cpu_state_t * cpup);
2375 void set_addr_mode (cpu_state_t * cpup, addr_modes_e mode);
2376 void decode_instruction (cpu_state_t * cpup, word36 inst, DCDstruct * p);
2377 #if !defined(SPEED)
2378 t_stat set_mem_watch (int32 arg, const char * buf);
2379 #endif
2380 char *str_SDW0 (char * buf, sdw_s *SDW);
2381 int lookup_cpu_mem_map (cpu_state_t * cpup, word24 addr);
2382 void cpu_init (void);
2383 void setup_scbank_map (cpu_state_t * cpup);
2384 void add_dps8m_CU_history (cpu_state_t * cpup);
2385 void add_dps8m_DUOU_history (word36 flags, word18 ICT, word9 RS_REG, word9 flags2);
2386 void add_dps8m_APU_history (word15 ESN, word21 flags, word24 RMA, word3 RTRR, word9 flags2);
2387 void add_dps8m_EAPU_history (word18 ZCA, word18 opcode);
2388 void add_l68_CU_history (cpu_state_t * cpup);
2389 void add_l68_OU_history (cpu_state_t * cpup);
2390 void add_l68_DU_history (cpu_state_t * cpup);
2391 void add_l68_APU_history (cpu_state_t * cpup, enum APUH_e op);
2392 void add_history_force (cpu_state_t * cpup, uint hset, word36 w0, word36 w1);
2393 void printPtid(pthread_t pt);
2394 word18 get_BAR_address(cpu_state_t * cpup, word18 addr);
2395 #if defined(THREADZ) || defined(LOCKLESS)
2396 t_stat threadz_sim_instr (void);
2397 void * cpu_thread_main (void * arg);
2398 #endif
2399 void cpu_reset_unit_idx (UNUSED uint cpun, bool clear_mem);
2400 void setupPROM (uint cpuNo, unsigned char * PROM);
2401 void cpuStats (uint cpuNo);