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