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