This source file includes following definitions.
- cpu_show_config
- cpu_set_config
- cpu_show_nunits
- cpu_set_nunits
- cpu_show_kips
- cpu_set_kips
- cpu_show_stall
- cpu_set_stall
- setCPUConfigL68
- setCPUConfigDPS8M
- cycle_str
- set_cpu_cycle
- set_cpu_idx
- cpu_reset_unit_idx
- simh_cpu_reset_and_clear_unit
- simh_cpu_reset_unit
- str_SDW0
- cpu_boot
- setup_scbank_map
- lookup_cpu_mem_map
- get_serial_number
- do_stats
- ev_poll_cb
- cpu_init
- cpu_reset
- sim_cpu_reset
- cpu_ex
- cpu_dep
- printPtid
- get_highest_intr
- sample_interrupts
- simh_hooks
- panel_process_event
- sim_instr
- cpu_thread_main
- do_LUF_fault
- set_temporary_absolute_mode
- clear_temporary_absolute_mode
- threadz_sim_instr
- operand_size
- readOperandRead
- readOperandRMW
- write_operand
- set_mem_watch
- nem_check
- core_read
- core_read_lock
- core_write
- core_write_unlock
- core_unlock_all
- core_write_zone
- core_read2
- core_write2
- decode_instruction
- is_priv_mode
- get_bar_mode
- get_addr_mode
- set_addr_mode
- get_BAR_address
- add_history
- add_history_force
- add_dps8m_CU_history
- add_dps8m_DU_OU_history
- add_dps8m_APU_history
- add_dps8m_EAPU_history
- add_l68_CU_history
- add_l68_DU_history
- add_l68_OU_history
- add_l68_APU_history
- get_dbg_verb
- dps8_sim_debug
- setupPROM
- cpuStats
- perfTest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <ctype.h>
35
36 #include "dps8.h"
37 #include "dps8_sys.h"
38 #include "dps8_iom.h"
39 #include "dps8_cable.h"
40 #include "dps8_cpu.h"
41 #include "dps8_addrmods.h"
42 #include "dps8_faults.h"
43 #include "dps8_scu.h"
44 #include "dps8_append.h"
45 #include "dps8_ins.h"
46 #include "dps8_state.h"
47 #include "dps8_math.h"
48 #include "dps8_iefp.h"
49 #include "dps8_console.h"
50 #include "dps8_fnp2.h"
51 #include "dps8_socket_dev.h"
52 #include "dps8_crdrdr.h"
53 #include "dps8_absi.h"
54 #include "dps8_mgp.h"
55 #include "dps8_utils.h"
56
57 #if defined(M_SHARED)
58 # include "shm.h"
59 #endif
60
61 #include "dps8_opcodetable.h"
62 #include "sim_defs.h"
63
64 #if defined(THREADZ) || defined(LOCKLESS)
65 # include "threadz.h"
66 __thread uint current_running_cpu_idx;
67 #endif
68
69 #include "ver.h"
70
71 #define DBG_CTR cpu.cycleCnt
72
73 #define ASSUME0 0
74
75 #define FREE(p) do \
76 { \
77 free((p)); \
78 (p) = NULL; \
79 } while(0)
80
81
82
83 static UNIT cpu_unit [N_CPU_UNITS_MAX] = {
84 #if defined(NO_C_ELLIPSIS)
85 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
86 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
87 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
88 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
89 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
90 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
91 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
92 { UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL }
93 #else
94 [0 ... N_CPU_UNITS_MAX - 1] = {
95 UDATA (NULL, UNIT_FIX|UNIT_BINK, MEMSIZE), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL
96 }
97 #endif
98 };
99
100 #define UNIT_IDX(uptr) ((uptr) - cpu_unit)
101
102
103 #define LOCKUP_KIPS 1000
104 static uint kips = LOCKUP_KIPS;
105 static uint64 luf_limits[] =
106 {
107 2000*LOCKUP_KIPS/1000,
108 4000*LOCKUP_KIPS/1000,
109 8000*LOCKUP_KIPS/1000,
110 16000*LOCKUP_KIPS/1000,
111 32000*LOCKUP_KIPS/1000
112 };
113
114 struct stall_point_s stall_points [N_STALL_POINTS];
115 bool stall_point_active = false;
116
117 #if defined(PANEL68)
118 static void panel_process_event (void);
119 #endif
120
121 static t_stat simh_cpu_reset_and_clear_unit (UNIT * uptr,
122 UNUSED int32 value,
123 UNUSED const char * cptr,
124 UNUSED void * desc);
125 static char * cycle_str (cycles_e cycle);
126
127 static t_stat cpu_show_config (UNUSED FILE * st, UNIT * uptr,
128 UNUSED int val, UNUSED const void * desc)
129 {
130 long cpu_unit_idx = UNIT_IDX (uptr);
131 if (cpu_unit_idx < 0 || cpu_unit_idx >= N_CPU_UNITS_MAX)
132 {
133 sim_warn ("error: Invalid unit number %ld\n", (long) cpu_unit_idx);
134 return SCPE_ARG;
135 }
136
137 #define PFC_INT8 "%c%c%c%c%c%c%c%c"
138
139 #define PBI_8(i) \
140 ( ((i) & 0x80ll) ? '1' : '0' ), \
141 ( ((i) & 0x40ll) ? '1' : '0' ), \
142 ( ((i) & 0x20ll) ? '1' : '0' ), \
143 ( ((i) & 0x10ll) ? '1' : '0' ), \
144 ( ((i) & 0x08ll) ? '1' : '0' ), \
145 ( ((i) & 0x04ll) ? '1' : '0' ), \
146 ( ((i) & 0x02ll) ? '1' : '0' ), \
147 ( ((i) & 0x01ll) ? '1' : '0' )
148
149 #define PFC_INT16 PFC_INT8 PFC_INT8
150 #define PFC_INT32 PFC_INT16 PFC_INT16
151 #define PFC_INT64 PFC_INT32 PFC_INT32
152
153 #define PBI_16(i) PBI_8((i) >> 8), PBI_8(i)
154 #define PBI_32(i) PBI_16((i) >> 16), PBI_16(i)
155 #define PBI_64(i) PBI_32((i) >> 32), PBI_32(i)
156
157 char dsbin[66], adbin[34];
158
159 sim_msg ("CPU unit number %ld\n", (long) cpu_unit_idx);
160
161 sim_msg ("Fault base: %03o(8)\n",
162 cpus[cpu_unit_idx].switches.FLT_BASE);
163 sim_msg ("CPU number: %01o(8)\n",
164 cpus[cpu_unit_idx].switches.cpu_num);
165 sim_msg ("Data switches: %012llo(8)\n",
166 (unsigned long long)cpus[cpu_unit_idx].switches.data_switches);
167 (void)snprintf (dsbin, 65, PFC_INT64,
168 PBI_64((unsigned long long)cpus[cpu_unit_idx].switches.data_switches));
169 sim_msg (" %36s(2)\n",
170 dsbin + strlen(dsbin) - 36);
171 sim_msg ("Address switches: %06o(8)\n",
172 cpus[cpu_unit_idx].switches.addr_switches);
173 (void)snprintf (adbin, 33, PFC_INT32,
174 PBI_32(cpus[cpu_unit_idx].switches.addr_switches));
175 sim_msg (" %18s(2)\n",
176 adbin + strlen(adbin) - 18);
177 for (int i = 0; i < (cpus[cpu_unit_idx].tweaks.l68_mode ? N_L68_CPU_PORTS : N_DPS8M_CPU_PORTS); i ++)
178 {
179 sim_msg ("Port%c enable: %01o(8)\n",
180 'A' + i, cpus[cpu_unit_idx].switches.enable [i]);
181 sim_msg ("Port%c init enable: %01o(8)\n",
182 'A' + i, cpus[cpu_unit_idx].switches.init_enable [i]);
183 sim_msg ("Port%c assignment: %01o(8)\n",
184 'A' + i, cpus[cpu_unit_idx].switches.assignment [i]);
185 sim_msg ("Port%c interlace: %01o(8)\n",
186 'A' + i, cpus[cpu_unit_idx].switches.interlace [i]);
187 sim_msg ("Port%c store size: %01o(8)\n",
188 'A' + i, cpus[cpu_unit_idx].switches.store_size [i]);
189 }
190 sim_msg ("Processor mode: %s [%o]\n",
191 cpus[cpu_unit_idx].switches.procMode == \
192 procModeMultics ? "Multics" : cpus[cpu_unit_idx].switches.procMode == procModeGCOS ? "GCOS" : "???",
193 cpus[cpu_unit_idx].switches.procMode);
194 sim_msg ("8K Cache: %s\n",
195 cpus[cpu_unit_idx].switches.enable_cache ? "Enabled" : "Disabled");
196 sim_msg ("SDWAM: %s\n",
197 cpus[cpu_unit_idx].switches.sdwam_enable ? "Enabled" : "Disabled");
198 sim_msg ("PTWAM: %s\n",
199 cpus[cpu_unit_idx].switches.ptwam_enable ? "Enabled" : "Disabled");
200
201 sim_msg ("Processor speed: %02o(8)\n",
202 cpus[cpu_unit_idx].options.proc_speed);
203 sim_msg ("DIS enable: %01o(8)\n",
204 cpus[cpu_unit_idx].tweaks.dis_enable);
205 sim_msg ("Steady clock: %01o(8)\n",
206 scu [0].steady_clock);
207 sim_msg ("Halt on unimplemented: %01o(8)\n",
208 cpus[cpu_unit_idx].tweaks.halt_on_unimp);
209 sim_msg ("Enable simulated SDWAM/PTWAM: %01o(8)\n",
210 cpus[cpu_unit_idx].tweaks.enable_wam);
211 sim_msg ("Report faults: %01o(8)\n",
212 cpus[cpu_unit_idx].tweaks.report_faults);
213 sim_msg ("TRO faults enabled: %01o(8)\n",
214 cpus[cpu_unit_idx].tweaks.tro_enable);
215 sim_msg ("Y2K enabled: %01o(8)\n",
216 scu [0].y2k);
217 sim_msg ("drl fatal enabled: %01o(8)\n",
218 cpus[cpu_unit_idx].tweaks.drl_fatal);
219 sim_msg ("useMap: %d\n",
220 cpus[cpu_unit_idx].tweaks.useMap);
221 sim_msg ("PROM installed: %01o(8)\n",
222 cpus[cpu_unit_idx].options.prom_installed);
223 sim_msg ("Hex mode installed: %01o(8)\n",
224 cpus[cpu_unit_idx].options.hex_mode_installed);
225 sim_msg ("8K cache installed: %01o(8)\n",
226 cpus[cpu_unit_idx].options.cache_installed);
227 sim_msg ("Clock slave installed: %01o(8)\n",
228 cpus[cpu_unit_idx].options.clock_slave_installed);
229 #if defined(AFFINITY)
230 if (cpus[cpu_unit_idx].set_affinity)
231 sim_msg ("CPU affinity: %d\n", cpus[cpu_unit_idx].affinity);
232 else
233 sim_msg ("CPU affinity: not set\n");
234 #endif
235 sim_msg ("ISOLTS mode: %01o(8)\n", cpus[cpu_unit_idx].tweaks.isolts_mode);
236 sim_msg ("NODIS mode: %01o(8)\n", cpus[cpu_unit_idx].tweaks.nodis);
237 sim_msg ("6180 mode: %01o(8) [%s]\n",
238 cpus[cpu_unit_idx].tweaks.l68_mode, cpus[cpu_unit_idx].tweaks.l68_mode ? "6180" : "DPS8/M");
239 return SCPE_OK;
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 static config_value_list_t cfg_multics_fault_base [] =
268 {
269 { "multics", 2 },
270 { NULL, 0 }
271 };
272
273 static config_value_list_t cfg_on_off [] =
274 {
275 { "off", 0 },
276 { "on", 1 },
277 { "disable", 0 },
278 { "enable", 1 },
279 { NULL, 0 }
280 };
281
282 static config_value_list_t cfg_l68_mode [] = {
283 { "dps8/m", 0 },
284 { "dps8m", 0 },
285 { "dps8", 0 },
286 { "l68", 1 },
287 { "l6180", 1 },
288 { "6180", 1 },
289 };
290
291 static config_value_list_t cfg_cpu_mode [] =
292 {
293 { "gcos", 0 },
294 { "multics", 1 },
295 { NULL, 0 }
296 };
297
298 static config_value_list_t cfg_port_letter [] =
299 {
300 { "a", 0 },
301 { "b", 1 },
302 { "c", 2 },
303 { "d", 3 },
304 { "e", 4 },
305 { "f", 5 },
306 { "g", 6 },
307 { "h", 7 },
308 { NULL, 0 }
309 };
310
311 static config_value_list_t cfg_interlace [] =
312 {
313 { "off", 0 },
314 { "2", 2 },
315 { "4", 4 },
316 { NULL, 0 }
317 };
318
319 #if defined(AFFINITY)
320 static config_value_list_t cfg_affinity [] =
321 {
322 { "off", -1 },
323 { NULL, 0 }
324 };
325 #endif
326
327 static config_value_list_t cfg_size_list [] =
328 {
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391 { "32", 8 },
392 { "32K", 8 },
393 { "64", 9 },
394 { "64K", 9 },
395 { "128", 10 },
396 { "128K", 10 },
397 { "256", 11 },
398 { "256K", 11 },
399 { "512", 12 },
400 { "512K", 12 },
401 { "1024", 13 },
402 { "1024K", 13 },
403 { "1M", 13 },
404 { "2048", 14 },
405 { "2048K", 14 },
406 { "2M", 14 },
407 { "4096", 15 },
408 { "4096K", 15 },
409 { "4M", 15 },
410 { NULL, 0 }
411 };
412
413 static config_list_t cpu_config_list [] =
414 {
415 { "faultbase", 0, 0177, cfg_multics_fault_base },
416 { "num", 0, 07, NULL },
417 { "data", 0, 0777777777777, NULL },
418 { "stopnum", 0, 999999, NULL },
419 { "mode", 0, 01, cfg_cpu_mode },
420 { "speed", 0, 017, NULL },
421 { "port", 0, N_CPU_PORTS - 1, cfg_port_letter },
422 { "assignment", 0, 7, NULL },
423 { "interlace", 0, 1, cfg_interlace },
424 { "enable", 0, 1, cfg_on_off },
425 { "init_enable", 0, 1, cfg_on_off },
426 { "store_size", 0, 7, cfg_size_list },
427 { "enable_cache", 0, 1, cfg_on_off },
428 { "sdwam", 0, 1, cfg_on_off },
429 { "ptwam", 0, 1, cfg_on_off },
430
431
432 { "dis_enable", 0, 1, cfg_on_off },
433
434 { "steady_clock", 0, 1, cfg_on_off },
435 { "halt_on_unimplemented", 0, 1, cfg_on_off },
436 { "enable_wam", 0, 1, cfg_on_off },
437 { "report_faults", 0, 1, cfg_on_off },
438 { "tro_enable", 0, 1, cfg_on_off },
439
440 { "y2k", 0, 1, cfg_on_off },
441 { "drl_fatal", 0, 1, cfg_on_off },
442 { "useMap", 0, 1, cfg_on_off },
443 { "address", 0, 0777777, NULL },
444 { "prom_installed", 0, 1, cfg_on_off },
445 { "hex_mode_installed", 0, 1, cfg_on_off },
446 { "cache_installed", 0, 1, cfg_on_off },
447 { "clock_slave_installed", 0, 1, cfg_on_off },
448 { "enable_emcall", 0, 1, cfg_on_off },
449
450
451 #if defined(AFFINITY)
452 { "affinity", -1, 32767, cfg_affinity },
453 #endif
454 { "isolts_mode", 0, 1, cfg_on_off },
455 { "nodis", 0, 1, cfg_on_off },
456 { "l68_mode", 0, 1, cfg_l68_mode },
457 { NULL, 0, 0, NULL }
458 };
459
460 static t_stat cpu_set_config (UNIT * uptr, UNUSED int32 value,
461 const char * cptr, UNUSED void * desc)
462 {
463 long cpu_unit_idx = UNIT_IDX (uptr);
464 if (cpu_unit_idx < 0 || cpu_unit_idx >= N_CPU_UNITS_MAX)
465 {
466 sim_warn ("error: cpu_set_config: Invalid unit number %ld\n",
467 (long) cpu_unit_idx);
468 return SCPE_ARG;
469 }
470
471 static int port_num = 0;
472
473 config_state_t cfg_state = { NULL, NULL };
474
475 for (;;)
476 {
477 int64_t v;
478 int rc = cfg_parse (__func__, cptr, cpu_config_list,
479 & cfg_state, & v);
480 if (rc == -1)
481 {
482 break;
483 }
484 if (rc == -2)
485 {
486 cfg_parse_done (& cfg_state);
487 return SCPE_ARG;
488 }
489
490 const char * p = cpu_config_list [rc] . name;
491 if (strcmp (p, "faultbase") == 0)
492 cpus[cpu_unit_idx].switches.FLT_BASE = (uint) v;
493 else if (strcmp (p, "num") == 0)
494 cpus[cpu_unit_idx].switches.cpu_num = (uint) v;
495 else if (strcmp (p, "data") == 0)
496 cpus[cpu_unit_idx].switches.data_switches = (word36) v;
497 else if (strcmp (p, "stopnum") == 0)
498 {
499
500
501 int64_t d1 = (v / 1000) % 10;
502 int64_t d2 = (v / 100) % 10;
503 int64_t d3 = (v / 10) % 10;
504 int64_t d4 = (v / 1) % 10;
505 word36 d = 0123000000000;
506 putbits36_6 (& d, 9, (word4) d1);
507 putbits36_6 (& d, 15, (word4) d2);
508 putbits36_6 (& d, 21, (word4) d3);
509 putbits36_6 (& d, 27, (word4) d4);
510 cpus[cpu_unit_idx].switches.data_switches = d;
511 }
512 else if (strcmp (p, "address") == 0)
513 cpus[cpu_unit_idx].switches.addr_switches = (word18) v;
514 else if (strcmp (p, "mode") == 0)
515 cpus[cpu_unit_idx].switches.procMode = v ? procModeMultics : procModeGCOS;
516 else if (strcmp (p, "speed") == 0)
517 cpus[cpu_unit_idx].options.proc_speed = (uint) v;
518 else if (strcmp (p, "port") == 0) {
519 if ((! cpus[cpu_unit_idx].tweaks.l68_mode) && (int) v > 4) {
520 cfg_parse_done (& cfg_state);
521 return SCPE_ARG;
522 }
523 port_num = (int) v;
524 }
525 else if (strcmp (p, "assignment") == 0)
526 cpus[cpu_unit_idx].switches.assignment [port_num] = (uint) v;
527 else if (strcmp (p, "interlace") == 0)
528 cpus[cpu_unit_idx].switches.interlace [port_num] = (uint) v;
529 else if (strcmp (p, "enable") == 0)
530 cpus[cpu_unit_idx].switches.enable [port_num] = (uint) v;
531 else if (strcmp (p, "init_enable") == 0)
532 cpus[cpu_unit_idx].switches.init_enable [port_num] = (uint) v;
533 else if (strcmp (p, "store_size") == 0) {
534 if (v > 7) {
535 if (cpus[cpu_unit_idx].tweaks.l68_mode) {
536 switch (v) {
537 case 8: v = 0; break;
538 case 9: v = 1; break;
539 case 10: v = 3; break;
540 case 11: v = 7; break;
541 case 12: v = 4; break;
542 case 13: v = 5; break;
543 case 14: v = 6; break;
544 case 15: v = 2; break;
545 }
546 } else {
547 switch (v) {
548 case 8: v = 0; break;
549 case 9: v = 1; break;
550 case 10: v = 2; break;
551 case 11: v = 3; break;
552 case 12: v = 4; break;
553 case 13: v = 5; break;
554 case 14: v = 6; break;
555 case 15: v = 7; break;
556 }
557 }
558 }
559 cpus[cpu_unit_idx].switches.store_size [port_num] = (uint) v;
560 }
561 else if (strcmp (p, "enable_cache") == 0)
562 cpus[cpu_unit_idx].switches.enable_cache = (uint) v ? true : false;
563 else if (strcmp (p, "sdwam") == 0)
564 cpus[cpu_unit_idx].switches.sdwam_enable = (uint) v ? true : false;
565 else if (strcmp (p, "ptwam") == 0)
566 cpus[cpu_unit_idx].switches.ptwam_enable = (uint) v ? true : false;
567 else if (strcmp (p, "dis_enable") == 0)
568 cpus[cpu_unit_idx].tweaks.dis_enable = (uint) v;
569 else if (strcmp (p, "steady_clock") == 0)
570 scu [0].steady_clock = (uint) v;
571 else if (strcmp (p, "halt_on_unimplemented") == 0)
572 cpus[cpu_unit_idx].tweaks.halt_on_unimp = (uint) v;
573 else if (strcmp (p, "enable_wam") == 0)
574 cpus[cpu_unit_idx].tweaks.enable_wam = (uint) v;
575 else if (strcmp (p, "report_faults") == 0)
576 cpus[cpu_unit_idx].tweaks.report_faults = (uint) v;
577 else if (strcmp (p, "tro_enable") == 0)
578 cpus[cpu_unit_idx].tweaks.tro_enable = (uint) v;
579 else if (strcmp (p, "y2k") == 0)
580 scu [0].y2k = (uint) v;
581 else if (strcmp (p, "drl_fatal") == 0)
582 cpus[cpu_unit_idx].tweaks.drl_fatal = (uint) v;
583 else if (strcmp (p, "useMap") == 0)
584 cpus[cpu_unit_idx].tweaks.useMap = v;
585 else if (strcmp (p, "prom_installed") == 0)
586 cpus[cpu_unit_idx].options.prom_installed = v;
587 else if (strcmp (p, "hex_mode_installed") == 0)
588 cpus[cpu_unit_idx].options.hex_mode_installed = v;
589 else if (strcmp (p, "cache_installed") == 0)
590 cpus[cpu_unit_idx].options.cache_installed = v;
591 else if (strcmp (p, "clock_slave_installed") == 0)
592 cpus[cpu_unit_idx].options.clock_slave_installed = v;
593 else if (strcmp (p, "enable_emcall") == 0)
594 cpus[cpu_unit_idx].tweaks.enable_emcall = v;
595 #if defined(AFFINITY)
596 else if (strcmp (p, "affinity") == 0)
597 if (v < 0)
598 {
599 cpus[cpu_unit_idx].set_affinity = false;
600 }
601 else
602 {
603 cpus[cpu_unit_idx].set_affinity = true;
604 cpus[cpu_unit_idx].affinity = (uint) v;
605 }
606 #endif
607 else if (strcmp (p, "isolts_mode") == 0)
608 {
609 cpus[cpu_unit_idx].tweaks.isolts_mode = v;
610 if (v)
611 {
612 uint store_sz;
613 if (cpus[cpu_unit_idx].tweaks.l68_mode)
614 store_sz = 3;
615 else
616 store_sz = 2;
617 cpus[cpu_unit_idx].isolts_switches_save = cpus[cpu_unit_idx].switches;
618 cpus[cpu_unit_idx].isolts_switches_saved = true;
619
620 cpus[cpu_unit_idx].switches.data_switches = 00000030714000;
621 cpus[cpu_unit_idx].switches.addr_switches = 0100150;
622 cpus[cpu_unit_idx].tweaks.useMap = true;
623 cpus[cpu_unit_idx].tweaks.enable_wam = true;
624 cpus[cpu_unit_idx].switches.assignment [0] = 0;
625 cpus[cpu_unit_idx].switches.interlace [0] = false;
626 cpus[cpu_unit_idx].switches.enable [0] = false;
627 cpus[cpu_unit_idx].switches.init_enable [0] = false;
628 cpus[cpu_unit_idx].switches.store_size [0] = store_sz;
629
630 cpus[cpu_unit_idx].switches.assignment [1] = 0;
631 cpus[cpu_unit_idx].switches.interlace [1] = false;
632 cpus[cpu_unit_idx].switches.enable [1] = true;
633 cpus[cpu_unit_idx].switches.init_enable [1] = false;
634 cpus[cpu_unit_idx].switches.store_size [1] = store_sz;
635
636 cpus[cpu_unit_idx].switches.assignment [2] = 0;
637 cpus[cpu_unit_idx].switches.interlace [2] = false;
638 cpus[cpu_unit_idx].switches.enable [2] = false;
639 cpus[cpu_unit_idx].switches.init_enable [2] = false;
640 cpus[cpu_unit_idx].switches.store_size [2] = store_sz;
641
642 cpus[cpu_unit_idx].switches.assignment [3] = 0;
643 cpus[cpu_unit_idx].switches.interlace [3] = false;
644 cpus[cpu_unit_idx].switches.enable [3] = false;
645 cpus[cpu_unit_idx].switches.init_enable [3] = false;
646 cpus[cpu_unit_idx].switches.store_size [3] = store_sz;
647
648 if (cpus[cpu_unit_idx].tweaks.l68_mode) {
649 cpus[cpu_unit_idx].switches.assignment [4] = 0;
650 cpus[cpu_unit_idx].switches.interlace [4] = false;
651 cpus[cpu_unit_idx].switches.enable [4] = false;
652 cpus[cpu_unit_idx].switches.init_enable [4] = false;
653 cpus[cpu_unit_idx].switches.store_size [4] = 3;
654
655 cpus[cpu_unit_idx].switches.assignment [5] = 0;
656 cpus[cpu_unit_idx].switches.interlace [5] = false;
657 cpus[cpu_unit_idx].switches.enable [5] = false;
658 cpus[cpu_unit_idx].switches.init_enable [5] = false;
659 cpus[cpu_unit_idx].switches.store_size [5] = 3;
660
661 cpus[cpu_unit_idx].switches.assignment [6] = 0;
662 cpus[cpu_unit_idx].switches.interlace [6] = false;
663 cpus[cpu_unit_idx].switches.enable [6] = false;
664 cpus[cpu_unit_idx].switches.init_enable [6] = false;
665 cpus[cpu_unit_idx].switches.store_size [6] = 3;
666
667 cpus[cpu_unit_idx].switches.assignment [7] = 0;
668 cpus[cpu_unit_idx].switches.interlace [7] = false;
669 cpus[cpu_unit_idx].switches.enable [7] = false;
670 cpus[cpu_unit_idx].switches.init_enable [7] = false;
671 cpus[cpu_unit_idx].switches.store_size [7] = 3;
672 }
673 cpu_reset_unit_idx ((uint) cpu_unit_idx, false);
674 simh_cpu_reset_and_clear_unit (cpu_unit + cpu_unit_idx, 0, NULL, NULL);
675 cpus[cpu_unit_idx].switches.enable [1] = true;
676 }
677 else
678 {
679 cpus[cpu_unit_idx].switches = cpus[cpu_unit_idx].isolts_switches_save;
680 cpus[cpu_unit_idx].isolts_switches_saved = false;
681
682 cpu_reset_unit_idx ((uint) cpu_unit_idx, false);
683 simh_cpu_reset_and_clear_unit (cpu_unit + cpu_unit_idx, 0, NULL, NULL);
684 }
685 }
686 else if (strcmp (p, "nodis") == 0)
687 cpus[cpu_unit_idx].tweaks.nodis = v;
688 else if (strcmp (p, "l68_mode") == 0)
689 cpus[cpu_unit_idx].tweaks.l68_mode= v;
690 else
691 {
692 sim_warn ("error: cpu_set_config: Invalid cfg_parse rc <%ld>\n",
693 (long) rc);
694 cfg_parse_done (& cfg_state);
695 return SCPE_ARG;
696 }
697 }
698 cfg_parse_done (& cfg_state);
699
700 return SCPE_OK;
701 }
702
703 static t_stat cpu_show_nunits (UNUSED FILE * st, UNUSED UNIT * uptr,
704 UNUSED int val, UNUSED const void * desc)
705 {
706 sim_msg ("Number of CPUs in system is %d\n", cpu_dev.numunits);
707 return SCPE_OK;
708 }
709
710 static t_stat cpu_set_nunits (UNUSED UNIT * uptr, UNUSED int32 value,
711 const char * cptr, UNUSED void * desc)
712 {
713 if (! cptr)
714 return SCPE_ARG;
715 int n = atoi (cptr);
716 if (n < 1 || n > N_CPU_UNITS_MAX)
717 return SCPE_ARG;
718 cpu_dev.numunits = (uint32) n;
719 return SCPE_OK;
720 }
721
722 static t_stat cpu_show_kips (UNUSED FILE * st, UNUSED UNIT * uptr,
723 UNUSED int val, UNUSED const void * desc)
724 {
725 sim_msg ("CPU KIPS %u\n", kips);
726 return SCPE_OK;
727 }
728
729 static t_stat cpu_set_kips (UNUSED UNIT * uptr, UNUSED int32 value,
730 const char * cptr, UNUSED void * desc)
731 {
732 if (! cptr)
733 return SCPE_ARG;
734 int n = atoi (cptr);
735 if (n < 1 || n > 4000000)
736 return SCPE_ARG;
737 kips = (uint) n;
738 luf_limits[0] = 2000*kips/1000;
739 luf_limits[1] = 4000*kips/1000;
740 luf_limits[2] = 8000*kips/1000;
741 luf_limits[3] = 16000*kips/1000;
742 luf_limits[4] = 32000*kips/1000;
743 return SCPE_OK;
744 }
745
746 static t_stat cpu_show_stall (UNUSED FILE * st, UNUSED UNIT * uptr,
747 UNUSED int val, UNUSED const void * desc)
748 {
749 if (! stall_point_active)
750 {
751 sim_printf ("No stall points\n");
752 return SCPE_OK;
753 }
754
755 sim_printf ("Stall points\n");
756 for (int i = 0; i < N_STALL_POINTS; i ++)
757 if (stall_points[i].segno || stall_points[i].offset)
758 {
759 #if defined(WIN_STDIO)
760 sim_printf ("%2ld %05o:%06o %10lu\n",
761 #else
762 sim_printf ("%2ld %05o:%06o %'10lu\n",
763 #endif
764 (long)i, stall_points[i].segno, stall_points[i].offset,
765 (unsigned long)stall_points[i].time);
766 }
767 return SCPE_OK;
768 }
769
770
771
772
773
774
775
776 static t_stat cpu_set_stall (UNUSED UNIT * uptr, UNUSED int32 value,
777 const char * cptr, UNUSED void * desc)
778 {
779 if (! cptr)
780 return SCPE_ARG;
781
782 long n, s, o, t;
783
784 char * end;
785 n = strtol (cptr, & end, 0);
786 if (* end != '=')
787 return SCPE_ARG;
788 if (n < 0 || n >= N_STALL_POINTS)
789 return SCPE_ARG;
790
791 s = strtol (end + 1, & end, 8);
792 if (* end != ':')
793 return SCPE_ARG;
794 if (s < 0 || s > MASK15)
795 return SCPE_ARG;
796
797 o = strtol (end + 1, & end, 8);
798 if (* end != '=')
799 return SCPE_ARG;
800 if (o < 0 || o > MASK18)
801 return SCPE_ARG;
802
803 t = strtol (end + 1, & end, 0);
804 if (* end != 0)
805 return SCPE_ARG;
806 if (t < 0 || t > 30000000)
807 return SCPE_ARG;
808
809 stall_points[n].segno = (word15) s;
810 stall_points[n].offset = (word18) o;
811 stall_points[n].time = (unsigned int) t;
812 stall_point_active = false;
813
814 for (int i = 0; i < N_STALL_POINTS; i ++)
815 if (stall_points[n].segno && stall_points[n].offset)
816 stall_point_active = true;
817
818 return SCPE_OK;
819 }
820
821 static t_stat setCPUConfigL68 (UNIT * uptr, UNUSED int32 value, UNUSED const char * cptr, UNUSED void * desc) {
822 long cpuUnitIdx = UNIT_IDX (uptr);
823 if (cpuUnitIdx < 0 || cpuUnitIdx >= N_CPU_UNITS_MAX)
824 return SCPE_ARG;
825 cpu_state_t * cpun = cpus + cpuUnitIdx;
826
827 cpun->tweaks.l68_mode = 1;
828 cpun->options.hex_mode_installed = 0;
829 for (uint port_num = 0; port_num < N_DPS8M_CPU_PORTS; port_num ++) {
830 cpun->switches.assignment[port_num] = port_num;
831 cpun->switches.interlace[port_num] = 0;
832 cpun->switches.store_size[port_num] = 2;
833 cpun->switches.enable[port_num] = 1;
834 cpun->switches.init_enable[port_num] = 1;
835 }
836 for (uint port_num = N_DPS8M_CPU_PORTS; port_num < N_L68_CPU_PORTS; port_num ++) {
837 cpun->switches.assignment[port_num] = 0;
838 cpun->switches.interlace[port_num] = 0;
839 cpun->switches.store_size[port_num] = 0;
840 cpun->switches.enable[port_num] = 0;
841 cpun->switches.init_enable[port_num] = 0;
842 }
843 return SCPE_OK;
844 }
845
846 static t_stat setCPUConfigDPS8M (UNIT * uptr, UNUSED int32 value, UNUSED const char * cptr, UNUSED void * desc) {
847 long cpuUnitIdx = UNIT_IDX (uptr);
848 if (cpuUnitIdx < 0 || cpuUnitIdx >= N_CPU_UNITS_MAX)
849 return SCPE_ARG;
850 cpu_state_t * cpun = cpus + cpuUnitIdx;
851
852 cpun->tweaks.l68_mode = 0;
853 cpun->options.hex_mode_installed = 0;
854 for (uint port_num = 0; port_num < N_DPS8M_CPU_PORTS; port_num ++) {
855 cpun->switches.assignment[port_num] = port_num;
856 cpun->switches.interlace[port_num] = 0;
857 cpun->switches.store_size[port_num] = 7;
858 cpun->switches.enable[port_num] = 1;
859 cpun->switches.init_enable[port_num] = 1;
860 }
861 for (uint port_num = N_DPS8M_CPU_PORTS; port_num < N_L68_CPU_PORTS; port_num ++) {
862 cpun->switches.assignment[port_num] = 0;
863 cpun->switches.interlace[port_num] = 0;
864 cpun->switches.store_size[port_num] = 0;
865 cpun->switches.enable[port_num] = 0;
866 cpun->switches.init_enable[port_num] = 0;
867 }
868 return SCPE_OK;
869 }
870
871 static char * cycle_str (cycles_e cycle)
872 {
873 switch (cycle)
874 {
875
876
877 case FAULT_cycle:
878 return "FAULT_cycle";
879 case EXEC_cycle:
880 return "EXEC_cycle";
881 case FAULT_EXEC_cycle:
882 return "FAULT_EXEC_cycle";
883 case INTERRUPT_cycle:
884 return "INTERRUPT_cycle";
885 case INTERRUPT_EXEC_cycle:
886 return "INTERRUPT_EXEC_cycle";
887 case FETCH_cycle:
888 return "FETCH_cycle";
889 case PSEUDO_FETCH_cycle:
890 return "PSEUDO_FETCH_cycle";
891 case SYNC_FAULT_RTN_cycle:
892 return "SYNC_FAULT_RTN_cycle";
893 default:
894 return "unknown cycle";
895 }
896 }
897
898 static void set_cpu_cycle (cpu_state_t * cpup, cycles_e cycle)
899 {
900 sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to %s\n",
901 cycle_str (cycle));
902 cpu.cycle = cycle;
903 }
904
905
906
907 #define MEM_UNINITIALIZED (1LLU<<62)
908
909 uint set_cpu_idx (UNUSED uint cpu_idx)
910 {
911 uint prev = current_running_cpu_idx;
912 #if defined(THREADZ) || defined(LOCKLESS)
913 current_running_cpu_idx = cpu_idx;
914 #endif
915 #if defined(ROUND_ROBIN)
916 current_running_cpu_idx = cpu_idx;
917 #endif
918 _cpup = & cpus [current_running_cpu_idx];
919 return prev;
920 }
921
922 void cpu_reset_unit_idx (UNUSED uint cpun, bool clear_mem)
923 {
924 uint save = set_cpu_idx (cpun);
925 cpu_state_t * cpup = _cpup;
926 if (clear_mem)
927 {
928 for (uint i = 0; i < MEMSIZE; i ++)
929 {
930
931 #if defined(LOCKLESS)
932 M[i] = (M[i] & ~(MASK36 | MEM_LOCKED)) | MEM_UNINITIALIZED;
933 #else
934 M[i] = (M[i] & ~(MASK36)) | MEM_UNINITIALIZED;
935 #endif
936 }
937 }
938 cpu.rA = 0;
939 cpu.rQ = 0;
940
941 cpu.PPR.IC = 0;
942 cpu.PPR.PRR = 0;
943 cpu.PPR.PSR = 0;
944 cpu.PPR.P = 1;
945 cpu.RSDWH_R1 = 0;
946 cpu.rTR = MASK27;
947
948 if (cpu.tweaks.isolts_mode)
949 {
950 cpu.shadowTR = 0;
951 cpu.rTRlsb = 0;
952 }
953 cpu.rTRticks = 0;
954
955 set_addr_mode (cpup, ABSOLUTE_mode);
956 SET_I_NBAR;
957
958 cpu.CMR.luf = 3;
959 cpu.cu.SD_ON = cpu.switches.sdwam_enable ? 1 : 0;
960 cpu.cu.PT_ON = cpu.switches.ptwam_enable ? 1 : 0;
961
962 if (cpu.tweaks.nodis) {
963 set_cpu_cycle (cpup, FETCH_cycle);
964 } else {
965 set_cpu_cycle (cpup, EXEC_cycle);
966 cpu.cu.IWB = 0000000616000;
967 }
968 #if defined(PERF_STRIP)
969 set_cpu_cycle (cpup, FETCH_cycle);
970 #endif
971 cpu.wasXfer = false;
972 cpu.wasInhibited = false;
973
974 cpu.interrupt_flag = false;
975 cpu.g7_flag = false;
976
977 cpu.faultRegister [0] = 0;
978 cpu.faultRegister [1] = 0;
979
980 #if defined(RAPRx)
981 cpu.apu.lastCycle = UNKNOWN_CYCLE;
982 #endif
983
984 (void)memset (& cpu.PPR, 0, sizeof (struct ppr_s));
985
986 setup_scbank_map (cpup);
987
988 tidy_cu (cpup);
989 set_cpu_idx (save);
990 }
991
992 static t_stat simh_cpu_reset_and_clear_unit (UNIT * uptr,
993 UNUSED int32 value,
994 UNUSED const char * cptr,
995 UNUSED void * desc)
996 {
997 long cpu_unit_idx = UNIT_IDX (uptr);
998 cpu_state_t * cpun = cpus + cpu_unit_idx;
999 if (cpun->tweaks.isolts_mode)
1000 {
1001
1002 if (cpun->tweaks.useMap)
1003 {
1004 for (uint pgnum = 0; pgnum < N_SCBANKS; pgnum ++)
1005 {
1006 int base = cpun->sc_addr_map [pgnum];
1007 if (base < 0)
1008 continue;
1009 for (uint addr = 0; addr < SCBANK_SZ; addr ++)
1010 M [addr + (uint) base] = MEM_UNINITIALIZED;
1011 }
1012 }
1013 }
1014
1015 cpu_reset_unit_idx ((uint) cpu_unit_idx, false);
1016 return SCPE_OK;
1017 }
1018
1019 static t_stat simh_cpu_reset_unit (UNIT * uptr,
1020 UNUSED int32 value,
1021 UNUSED const char * cptr,
1022 UNUSED void * desc)
1023 {
1024 long cpu_unit_idx = UNIT_IDX (uptr);
1025 cpu_reset_unit_idx ((uint) cpu_unit_idx, false);
1026 return SCPE_OK;
1027 }
1028
1029 #if !defined(PERF_STRIP)
1030 static uv_loop_t * ev_poll_loop;
1031 static uv_timer_t ev_poll_handle;
1032 #endif
1033
1034 static MTAB cpu_mod[] =
1035 {
1036 {
1037 MTAB_unit_value,
1038 0,
1039 "CONFIG",
1040 "CONFIG",
1041 cpu_set_config,
1042 cpu_show_config,
1043 NULL,
1044 NULL
1045 },
1046
1047
1048
1049 {
1050 MTAB_unit_value,
1051 0,
1052 "RESET",
1053 "RESET",
1054 simh_cpu_reset_unit,
1055 NULL,
1056 NULL,
1057 NULL
1058 },
1059
1060 {
1061 MTAB_unit_value,
1062 0,
1063 "INITIALIZE",
1064 "INITIALIZE",
1065 simh_cpu_reset_unit,
1066 NULL,
1067 NULL,
1068 NULL
1069 },
1070
1071
1072
1073 {
1074 MTAB_unit_value,
1075 0,
1076 "INITIALIZEANDCLEAR",
1077 "INITIALIZEANDCLEAR",
1078 simh_cpu_reset_and_clear_unit,
1079 NULL,
1080 NULL,
1081 NULL
1082 },
1083
1084 {
1085 MTAB_unit_value,
1086 0,
1087 "IAC",
1088 "IAC",
1089 simh_cpu_reset_and_clear_unit,
1090 NULL,
1091 NULL,
1092 NULL
1093 },
1094
1095 {
1096 MTAB_dev_value,
1097 0,
1098 "NUNITS",
1099 "NUNITS",
1100 cpu_set_nunits,
1101 cpu_show_nunits,
1102 NULL,
1103 NULL
1104 },
1105
1106 {
1107 MTAB_dev_value,
1108 0,
1109 "KIPS",
1110 "KIPS",
1111 cpu_set_kips,
1112 cpu_show_kips,
1113 NULL,
1114 NULL
1115 },
1116
1117 {
1118 MTAB_dev_value,
1119 0,
1120 "STALL",
1121 "STALL",
1122 cpu_set_stall,
1123 cpu_show_stall,
1124 NULL,
1125 NULL
1126 },
1127
1128 {
1129 MTAB_unit_value,
1130 0,
1131 "DPS8M",
1132 "DPS8M",
1133 setCPUConfigDPS8M,
1134 NULL,
1135 NULL,
1136 NULL
1137 },
1138
1139 {
1140 MTAB_unit_value,
1141 0,
1142 "L68",
1143 "L68",
1144 setCPUConfigL68,
1145 NULL,
1146 NULL,
1147 NULL
1148 },
1149
1150 { 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
1151 };
1152
1153 static DEBTAB cpu_dt[] =
1154 {
1155 { "TRACE", DBG_TRACE, NULL },
1156 { "TRACEEXT", DBG_TRACEEXT, NULL },
1157 { "MESSAGES", DBG_MSG, NULL },
1158
1159 { "REGDUMPAQI", DBG_REGDUMPAQI, NULL },
1160 { "REGDUMPIDX", DBG_REGDUMPIDX, NULL },
1161 { "REGDUMPPR", DBG_REGDUMPPR, NULL },
1162 { "REGDUMPPPR", DBG_REGDUMPPPR, NULL },
1163 { "REGDUMPDSBR", DBG_REGDUMPDSBR, NULL },
1164 { "REGDUMPFLT", DBG_REGDUMPFLT, NULL },
1165 { "REGDUMP", DBG_REGDUMP, NULL },
1166
1167 { "ADDRMOD", DBG_ADDRMOD, NULL },
1168 { "APPENDING", DBG_APPENDING, NULL },
1169
1170 { "NOTIFY", DBG_NOTIFY, NULL },
1171 { "INFO", DBG_INFO, NULL },
1172 { "ERR", DBG_ERR, NULL },
1173 { "WARN", DBG_WARN, NULL },
1174 { "DEBUG", DBG_DEBUG, NULL },
1175 { "ALL", DBG_ALL, NULL },
1176
1177 { "FAULT", DBG_FAULT, NULL },
1178 { "INTR", DBG_INTR, NULL },
1179 { "CORE", DBG_CORE, NULL },
1180 { "CYCLE", DBG_CYCLE, NULL },
1181 { "CAC", DBG_CAC, NULL },
1182 { "FINAL", DBG_FINAL, NULL },
1183 { "AVC", DBG_AVC, NULL },
1184 { NULL, 0, NULL }
1185 };
1186
1187
1188 const char *sim_stop_messages[] =
1189 {
1190 "Unknown error",
1191 "Simulation stop",
1192 "Breakpoint",
1193 };
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 #if !defined(SPEED)
1224 static bool watch_bits [MEMSIZE];
1225 #endif
1226
1227 char * str_SDW0 (char * buf, sdw0_s * SDW)
1228 {
1229 (void)sprintf (buf, "ADDR=%06o R1=%o R2=%o R3=%o F=%o FC=%o BOUND=%o R=%o "
1230 "E=%o W=%o P=%o U=%o G=%o C=%o EB=%o",
1231 SDW->ADDR, SDW->R1, SDW->R2, SDW->R3, SDW->DF,
1232 SDW->FC, SDW->BOUND, SDW->R, SDW->E, SDW->W,
1233 SDW->P, SDW->U, SDW->G, SDW->C, SDW->EB);
1234 return buf;
1235 }
1236
1237 static t_stat cpu_boot (UNUSED int32 cpu_unit_idx, UNUSED DEVICE * dptr)
1238 {
1239 sim_warn ("Try 'BOOT IOMn'\n");
1240 return SCPE_ARG;
1241 }
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265 #define ZONE_SZ (MEM_SIZE_MAX / 4)
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279 void setup_scbank_map (cpu_state_t * cpup)
1280 {
1281
1282 for (uint pg = 0; pg < N_SCBANKS; pg ++)
1283 {
1284 cpu.sc_addr_map [pg] = -1;
1285 cpu.sc_scu_map [pg] = -1;
1286 }
1287 for (uint u = 0; u < N_SCU_UNITS_MAX; u ++)
1288 cpu.sc_num_banks[u] = 0;
1289
1290
1291 for (int port_num = 0; port_num < (cpu.tweaks.l68_mode ? N_L68_CPU_PORTS : N_DPS8M_CPU_PORTS); port_num ++)
1292 {
1293
1294 if (! cpu.switches.enable [port_num])
1295 continue;
1296
1297
1298
1299
1300 if (! cables->cpu_to_scu[current_running_cpu_idx][port_num].in_use)
1301 {
1302 continue;
1303 }
1304
1305
1306 uint store_size = cpu.switches.store_size [port_num];
1307 uint dps8m_store_table [8] =
1308 { 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304 };
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323 uint l68_store_table [8] =
1324 { 32768, 65536, 4194304, 131072, 524288, 1048576, 2097152, 262144 };
1325 uint l68_isolts_store_table [8] =
1326 { 32768, 65536, 4194304, 65536, 524288, 1048576, 2097152, 262144 };
1327
1328 uint sz_wds =
1329 cpu.tweaks.l68_mode ?
1330 cpu.tweaks.isolts_mode ?
1331 l68_isolts_store_table [store_size] :
1332 l68_store_table [store_size] :
1333 dps8m_store_table [store_size];
1334
1335
1336 uint base_addr_wds = sz_wds * cpu.switches.assignment[port_num];
1337
1338
1339 uint num_banks = sz_wds / SCBANK_SZ;
1340 cpu.sc_num_banks[port_num] = num_banks;
1341 uint base_addr_bks = base_addr_wds / SCBANK_SZ;
1342
1343
1344 for (uint pg = 0; pg < num_banks; pg ++)
1345 {
1346
1347 uint addr_bks = base_addr_bks + pg;
1348
1349 if (addr_bks < N_SCBANKS)
1350 {
1351
1352 if (cpu.sc_addr_map [addr_bks] != -1)
1353 {
1354 sim_warn ("scbank overlap addr_bks %d (%o) old port %d "
1355 "newport %d\n",
1356 addr_bks, addr_bks, cpu.sc_addr_map [addr_bks], port_num);
1357 }
1358 else
1359 {
1360
1361 cpu.sc_addr_map[addr_bks] = (int)((int)port_num * (int)ZONE_SZ + (int)pg * (int)SCBANK_SZ);
1362 cpu.sc_scu_map[addr_bks] = port_num;
1363 }
1364 }
1365 else
1366 {
1367 sim_warn ("addr_bks too big port %d addr_bks %d (%o), "
1368 "limit %d (%o)\n",
1369 port_num, addr_bks, addr_bks, N_SCBANKS, N_SCBANKS);
1370 }
1371 }
1372
1373 }
1374
1375
1376
1377 }
1378
1379 int lookup_cpu_mem_map (cpu_state_t * cpup, word24 addr)
1380 {
1381 uint scpg = addr / SCBANK_SZ;
1382 if (scpg < N_SCBANKS)
1383 {
1384 return cpu.sc_scu_map[scpg];
1385 }
1386 return -1;
1387 }
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397 #if !defined(PERF_STRIP)
1398 static void get_serial_number (cpu_state_t * cpup)
1399 {
1400 bool havesn = false;
1401 FILE * fp = fopen ("./serial.txt", "r");
1402 while (fp && ! feof (fp))
1403 {
1404 char buffer [81] = "";
1405 # if !defined(__clang_analyzer__)
1406 char * checksn = fgets (buffer, sizeof (buffer), fp);
1407 (void)checksn;
1408 # endif
1409 uint cpun, sn;
1410 if (sscanf (buffer, "sn: %u", & cpu.switches.serno) == 1)
1411 {
1412 if (!sim_quiet)
1413 {
1414 sim_msg ("%s CPU serial number: %u\n", sim_name, cpu.switches.serno);
1415 }
1416 havesn = true;
1417 }
1418 else if (sscanf (buffer, "sn%u: %u", & cpun, & sn) == 2)
1419 {
1420 if (cpun < N_CPU_UNITS_MAX)
1421 {
1422 cpus[cpun].switches.serno = sn;
1423 if (!sim_quiet)
1424 {
1425 sim_msg ("%s CPU %u serial number: %u\n",
1426 sim_name, cpun, cpus[cpun].switches.serno);
1427 }
1428 havesn = true;
1429 }
1430 }
1431 }
1432 if (!havesn)
1433 {
1434 if (!sim_quiet)
1435 {
1436 sim_msg ("\r\nPlease register your system at "
1437 "https://ringzero.wikidot.com/wiki:register\n");
1438 sim_msg ("or create the file 'serial.txt' containing the line "
1439 "'sn: 0'.\r\n\r\n");
1440 }
1441 }
1442 if (fp)
1443 fclose (fp);
1444 }
1445 #endif
1446
1447 #if defined(STATS)
1448 static void do_stats (void)
1449 {
1450 static struct timespec stats_time;
1451 static bool first = true;
1452 if (first)
1453 {
1454 first = false;
1455 clock_gettime (CLOCK_BOOTTIME, & stats_time);
1456 sim_msg ("stats started\r\n");
1457 }
1458 else
1459 {
1460 struct timespec now, delta;
1461 clock_gettime (CLOCK_BOOTTIME, & now);
1462 timespec_diff (& stats_time, & now, & delta);
1463 stats_time = now;
1464 sim_msg ("stats %6ld.%02ld\r\n", delta.tv_sec,
1465 delta.tv_nsec / 10000000);
1466
1467 sim_msg ("Instruction counts\r\n");
1468 for (uint i = 0; i < 8; i ++)
1469 {
1470 # if defined(WIN_STDIO)
1471 sim_msg (" %9lld\r\n", (long long int) cpus[i].instrCnt);
1472 # else
1473 sim_msg (" %'9lld\r\n", (long long int) cpus[i].instrCnt);
1474 # endif
1475 cpus[i].instrCnt = 0;
1476 }
1477 sim_msg ("\r\n");
1478 }
1479 }
1480 #endif
1481
1482
1483
1484 #if !defined(PERF_STRIP)
1485 static void ev_poll_cb (UNUSED uv_timer_t * handle)
1486 {
1487 cpu_state_t * cpup = _cpup;
1488
1489
1490 static uint oneHz = 0;
1491 if (oneHz ++ >= sys_opts.sys_slow_poll_interval)
1492 {
1493 oneHz = 0;
1494 rdrProcessEvent ();
1495 # if defined(STATS)
1496 do_stats ();
1497 # endif
1498 cpu.instrCntT0 = cpu.instrCntT1;
1499 cpu.instrCntT1 = cpu.instrCnt;
1500 }
1501 fnpProcessEvent ();
1502 # if defined(WITH_SOCKET_DEV)
1503 # if !defined(__MINGW64__) && !defined(__MINGW32__) && !defined(CROSS_MINGW32) && !defined(CROSS_MINGW64)
1504 sk_process_event ();
1505 # endif
1506 # endif
1507 consoleProcess ();
1508 # if defined(IO_ASYNC_PAYLOAD_CHAN)
1509 iomProcess ();
1510 # endif
1511 # if defined(WITH_ABSI_DEV)
1512 # if !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(CROSS_MINGW32) && !defined(CROSS_MINGW64)
1513 absi_process_event ();
1514 # endif
1515 # endif
1516 # if defined(WITH_MGP_DEV)
1517 # if !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(CROSS_MINGW32) && !defined(CROSS_MINGW64)
1518 mgp_process_event ();
1519 # endif
1520 # endif
1521 PNL (panel_process_event ());
1522 }
1523 #endif
1524
1525
1526
1527 void cpu_init (void)
1528 {
1529
1530
1531
1532 M = system_state->M;
1533 #if defined(M_SHARED)
1534 cpus = system_state->cpus;
1535 #endif
1536
1537 #if !defined(SPEED)
1538 (void)memset (& watch_bits, 0, sizeof (watch_bits));
1539 #endif
1540
1541 set_cpu_idx (0);
1542
1543 (void)memset (cpus, 0, sizeof (cpu_state_t) * N_CPU_UNITS_MAX);
1544 cpus [0].switches.FLT_BASE = 2;
1545
1546 #if !defined(PERF_STRIP)
1547 get_serial_number (_cpup);
1548
1549 ev_poll_loop = uv_default_loop ();
1550 uv_timer_init (ev_poll_loop, & ev_poll_handle);
1551
1552 uv_timer_start (& ev_poll_handle, ev_poll_cb, sys_opts.sys_poll_interval, sys_opts.sys_poll_interval);
1553 #endif
1554
1555
1556 cpu_state_t * cpup = _cpup;
1557
1558 cpu.instrCnt = 0;
1559 cpu.cycleCnt = 0;
1560 for (int i = 0; i < N_FAULTS; i ++)
1561 cpu.faultCnt [i] = 0;
1562
1563 #if defined(MATRIX)
1564 initializeTheMatrix ();
1565 #endif
1566 }
1567
1568 static void cpu_reset (void)
1569 {
1570 for (uint i = 0; i < N_CPU_UNITS_MAX; i ++)
1571 {
1572 cpu_reset_unit_idx (i, true);
1573 }
1574
1575 set_cpu_idx (0);
1576
1577 #if defined(TESTING)
1578 cpu_state_t * cpup = _cpup;
1579 sim_debug (DBG_INFO, & cpu_dev, "CPU reset: Running\n");
1580 #endif
1581 }
1582
1583 static t_stat sim_cpu_reset (UNUSED DEVICE *dptr)
1584 {
1585
1586
1587
1588
1589
1590 cpu_reset ();
1591 return SCPE_OK;
1592 }
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602 static t_stat cpu_ex (t_value *vptr, t_addr addr, UNUSED UNIT * uptr,
1603 UNUSED int32 sw)
1604 {
1605 if (addr>= MEMSIZE)
1606 return SCPE_NXM;
1607 if (vptr != NULL)
1608 {
1609 *vptr = M[addr] & DMASK;
1610 }
1611 return SCPE_OK;
1612 }
1613
1614
1615
1616 static t_stat cpu_dep (t_value val, t_addr addr, UNUSED UNIT * uptr,
1617 UNUSED int32 sw)
1618 {
1619 if (addr >= MEMSIZE) return SCPE_NXM;
1620 M[addr] = val & DMASK;
1621 return SCPE_OK;
1622 }
1623
1624
1625
1626
1627
1628 #if defined(M_SHARED)
1629
1630 static word18 dummy_IC;
1631 #endif
1632
1633 static REG cpu_reg[] =
1634 {
1635
1636 #if defined(M_SHARED)
1637 { ORDATA (IC, dummy_IC, VASIZE), 0, 0, 0 },
1638 #else
1639 { ORDATA (IC, cpus[0].PPR.IC, VASIZE), 0, 0, 0 },
1640 #endif
1641 { NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0, 0, 0 }
1642 };
1643
1644
1645
1646
1647
1648 REG *sim_PC = & cpu_reg[0];
1649
1650
1651
1652 DEVICE cpu_dev =
1653 {
1654 "CPU",
1655 cpu_unit,
1656 cpu_reg,
1657 cpu_mod,
1658 N_CPU_UNITS,
1659 8,
1660 PASIZE,
1661 1,
1662 8,
1663 36,
1664 & cpu_ex,
1665 & cpu_dep,
1666 & sim_cpu_reset,
1667 & cpu_boot,
1668 NULL,
1669 NULL,
1670 NULL,
1671 DEV_DEBUG,
1672 0,
1673 cpu_dt,
1674 NULL,
1675 NULL,
1676 NULL,
1677 NULL,
1678 NULL,
1679 NULL,
1680 NULL
1681 };
1682
1683 void printPtid(pthread_t pt)
1684 {
1685 unsigned char *ptc = (unsigned char*)(void*)(&pt);
1686 sim_msg ("\r Thread ID: 0x");
1687 for (size_t i=0; i < sizeof( pt ); i++)
1688 {
1689 sim_msg ("%02x", (unsigned)(ptc[i]));
1690 }
1691 sim_msg ("\r\n");
1692 #if defined(__APPLE__)
1693 sim_msg ("\r Mach TID: 0x%x\r\n",
1694 pthread_mach_thread_np( pt ));
1695 #endif
1696 }
1697
1698 #if defined(M_SHARED)
1699 cpu_state_t * cpus = NULL;
1700 #else
1701 cpu_state_t cpus [N_CPU_UNITS_MAX];
1702 #endif
1703 #if defined(THREADZ) || defined(LOCKLESS)
1704 __thread cpu_state_t * restrict _cpup;
1705 #else
1706 cpu_state_t * restrict _cpup;
1707 #endif
1708 #if defined(ROUND_ROBIN)
1709 uint current_running_cpu_idx;
1710 #endif
1711
1712
1713
1714
1715
1716
1717
1718 static uint get_highest_intr (cpu_state_t *cpup)
1719 {
1720 uint fp = 1;
1721 for (uint scu_unit_idx = 0; scu_unit_idx < N_SCU_UNITS_MAX; scu_unit_idx ++)
1722 {
1723 if (cpu.events.XIP [scu_unit_idx])
1724 {
1725 fp = scu_get_highest_intr (scu_unit_idx);
1726 if (fp != 1)
1727 break;
1728 }
1729 }
1730 return fp;
1731 }
1732
1733 bool sample_interrupts (cpu_state_t * cpup)
1734 {
1735 cpu.lufCounter = 0;
1736 for (uint scu_unit_idx = 0; scu_unit_idx < N_SCU_UNITS_MAX; scu_unit_idx ++)
1737 {
1738 if (cpu.events.XIP [scu_unit_idx])
1739 {
1740 return true;
1741 }
1742 }
1743 return false;
1744 }
1745
1746 t_stat simh_hooks (cpu_state_t * cpup)
1747 {
1748 int reason = 0;
1749
1750 if (breakEnable && stop_cpu)
1751 return STOP_STOP;
1752
1753 if (cpu.tweaks.isolts_mode == 0)
1754 {
1755
1756 if (sim_interval <= 0)
1757 {
1758 reason = sim_process_event ();
1759 if ((! breakEnable) && reason == SCPE_STOP)
1760 reason = SCPE_OK;
1761 if (reason)
1762 return reason;
1763 }
1764 }
1765
1766 sim_interval --;
1767
1768 #if !defined(THREADZ) && !defined(LOCKLESS)
1769
1770
1771
1772 if (sim_brk_summ &&
1773 sim_brk_test ((cpu.PPR.IC & 0777777) |
1774 ((((t_addr) cpu.PPR.PSR) & 037777) << 18),
1775 SWMASK ('E')))
1776 return STOP_BKPT;
1777 # if !defined(SPEED)
1778 if (sim_deb_break && cpu.cycleCnt >= sim_deb_break)
1779 return STOP_BKPT;
1780 # endif
1781 #endif
1782
1783 return reason;
1784 }
1785
1786 #if defined(PANEL68)
1787 static void panel_process_event (void)
1788 {
1789 cpu_state_t * cpup = _cpup;
1790
1791 if (cpu.panelInitialize && cpu.DATA_panel_s_trig_sw == 0)
1792 {
1793
1794 while (cpu.panelInitialize)
1795 ;
1796 if (cpu.DATA_panel_init_sw)
1797 cpu_reset_unit_idx (ASSUME0, true);
1798 else
1799 cpu_reset_unit_idx (ASSUME0, false);
1800
1801 do_boot ();
1802 }
1803
1804 if (cpu.DATA_panel_s_trig_sw == 0 &&
1805 cpu.DATA_panel_execute_sw &&
1806 cpu.DATA_panel_scope_sw &&
1807 cpu.DATA_panel_exec_sw == 0)
1808
1809 {
1810
1811 while (cpu.DATA_panel_execute_sw)
1812 ;
1813
1814 if (cpu.DATA_panel_exec_sw)
1815 {
1816 cpu_reset_unit_idx (ASSUME0, false);
1817 cpu.cu.IWB = cpu.switches.data_switches;
1818 set_cpu_cycle (cpup, EXEC_cycle);
1819 }
1820 else
1821 {
1822 setG7fault (current_running_cpu_idx, FAULT_EXF, fst_zero);
1823 }
1824 }
1825 }
1826 #endif
1827
1828 #if defined(THREADZ) || defined(LOCKLESS)
1829 bool bce_dis_called = false;
1830
1831
1832 t_stat sim_instr (void)
1833 {
1834 cpu_state_t * cpup = _cpup;
1835 t_stat reason = 0;
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881 if (cpuThreadz[0].run == false)
1882 createCPUThread (0);
1883 do
1884 {
1885
1886 reason = simh_hooks (cpup);
1887 if (reason)
1888 {
1889 break;
1890 }
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918 if (bce_dis_called) {
1919
1920 reason = STOP_STOP;
1921 break;
1922 }
1923
1924 # if !defined(PERF_STRIP)
1925
1926
1927 # if defined(LOCKLESS)
1928 lock_iom();
1929 # endif
1930 lock_libuv ();
1931 uv_run (ev_poll_loop, UV_RUN_NOWAIT);
1932 unlock_libuv ();
1933 # if defined(LOCKLESS)
1934 unlock_iom();
1935 # endif
1936 PNL (panel_process_event ());
1937
1938 int con_unit_idx = check_attn_key ();
1939 if (con_unit_idx != -1)
1940 console_attn_idx (con_unit_idx);
1941 # endif
1942
1943 # if defined(IO_ASYNC_PAYLOAD_CHAN_THREAD)
1944 struct timespec next_time;
1945 clock_gettime (CLOCK_REALTIME, & next_time);
1946 next_time.tv_nsec += 1000l * 1000l;
1947 if (next_time.tv_nsec >= 1000l * 1000l *1000l)
1948 {
1949 next_time.tv_nsec -= 1000l * 1000l *1000l;
1950 next_time.tv_sec += (time_t) 1;
1951 }
1952 struct timespec new_time;
1953 do
1954 {
1955 pthread_mutex_lock (& iom_start_lock);
1956 pthread_cond_timedwait (& iomCond,
1957 & iom_start_lock,
1958 & next_time);
1959 pthread_mutex_unlock (& iom_start_lock);
1960 lock_iom();
1961 lock_libuv ();
1962
1963 iomProcess ();
1964
1965 unlock_libuv ();
1966 unlock_iom ();
1967
1968 clock_gettime (CLOCK_REALTIME, & new_time);
1969 }
1970 while ((next_time.tv_sec == new_time.tv_sec) ? (next_time.tv_nsec > new_time.tv_nsec) : \
1971 (next_time.tv_sec > new_time.tv_sec));
1972 # else
1973 sim_usleep (1000);
1974 # endif
1975 }
1976 while (reason == 0);
1977
1978 for (uint cpuNo = 0; cpuNo < N_CPU_UNITS_MAX; cpuNo ++) {
1979 cpuStats (cpuNo);
1980 }
1981
1982 # if defined(TESTING)
1983 HDBGPrint ();
1984 # endif
1985 return reason;
1986 }
1987 #endif
1988
1989 #if !defined(THREADZ) && !defined(LOCKLESS)
1990 static uint fast_queue_subsample = 0;
1991 #endif
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041 #if defined(THREADZ) || defined(LOCKLESS)
2042 void * cpu_thread_main (void * arg)
2043 {
2044 int myid = * (int *) arg;
2045 set_cpu_idx ((uint) myid);
2046 unsigned char umyid = (unsigned char)toupper('a' + (int)myid);
2047
2048 sim_msg ("\rCPU %c thread created.\r\n", (unsigned int)umyid);
2049 # if defined(TESTING)
2050 printPtid(pthread_self());
2051 # endif
2052
2053 sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
2054 setSignals ();
2055 threadz_sim_instr ();
2056 return NULL;
2057 }
2058 #endif
2059
2060 static void do_LUF_fault (cpu_state_t * cpup)
2061 {
2062 CPT (cpt1U, 16);
2063 cpu.lufCounter = 0;
2064 cpu.lufOccurred = false;
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083 if (cpu.tweaks.isolts_mode)
2084 cpu.shadowTR = (word27) cpu.TR0 - (1024u << (is_priv_mode (cpup) ? 4 : cpu.CMR.luf));
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097 doFault (FAULT_LUF, fst_zero, "instruction cycle lockup");
2098 }
2099
2100 #if !defined(THREADZ) && !defined(LOCKLESS)
2101 # define threadz_sim_instr sim_instr
2102 #endif
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114 static void set_temporary_absolute_mode (cpu_state_t * cpup)
2115 {
2116 CPT (cpt1L, 20);
2117 cpu.secret_addressing_mode = true;
2118 cpu.cu.XSF = false;
2119 sim_debug (DBG_TRACEEXT, & cpu_dev, "set_temporary_absolute_mode bit 29 sets XSF to 0\n");
2120
2121 }
2122
2123 static bool clear_temporary_absolute_mode (cpu_state_t * cpup)
2124 {
2125 CPT (cpt1L, 21);
2126 cpu.secret_addressing_mode = false;
2127 return cpu.cu.XSF;
2128
2129 }
2130
2131 t_stat threadz_sim_instr (void)
2132 {
2133
2134
2135 #if !defined(SCHED_NEVER_YIELD)
2136 unsigned long long lockYieldAll = 0;
2137 #endif
2138 unsigned long long lockWaitMaxAll = 0;
2139 unsigned long long lockWaitAll = 0;
2140 unsigned long long lockImmediateAll = 0;
2141 unsigned long long lockCntAll = 0;
2142 unsigned long long instrCntAll = 0;
2143 unsigned long long cycleCntAll = 0;
2144
2145 t_stat reason = 0;
2146
2147 #if !defined(THREADZ) && !defined(LOCKLESS)
2148 set_cpu_idx (0);
2149 # if defined(M_SHARED)
2150
2151
2152
2153
2154 cpus [0].PPR.IC = dummy_IC;
2155 # endif
2156
2157 # if defined(ROUND_ROBIN)
2158 cpu_state_t * cpup = _cpup;
2159 cpup->isRunning = true;
2160 set_cpu_idx (cpu_dev.numunits - 1);
2161
2162 setCPU:;
2163 uint current = current_running_cpu_idx;
2164 uint c;
2165 for (c = 0; c < cpu_dev.numunits; c ++)
2166 {
2167 set_cpu_idx (c);
2168 if (cpu.isRunning)
2169 break;
2170 }
2171 if (c == cpu_dev.numunits)
2172 {
2173 sim_msg ("All CPUs stopped\n");
2174 goto leave;
2175 }
2176 set_cpu_idx ((current + 1) % cpu_dev.numunits);
2177 if (! _cpup-> isRunning)
2178 goto setCPU;
2179 # endif
2180 #endif
2181
2182
2183 #if !defined(ROUND_ROBIN)
2184 cpu_state_t * cpup = _cpup;
2185 #endif
2186 int val = setjmp (cpu.jmpMain);
2187
2188 switch (val)
2189 {
2190 case JMP_ENTRY:
2191 case JMP_REENTRY:
2192 reason = 0;
2193 break;
2194 case JMP_SYNC_FAULT_RETURN:
2195 set_cpu_cycle (cpup, SYNC_FAULT_RTN_cycle);
2196 break;
2197 case JMP_STOP:
2198 reason = STOP_STOP;
2199 goto leave;
2200 case JMP_REFETCH:
2201
2202
2203
2204
2205
2206
2207
2208 cpu.wasXfer = false;
2209
2210 set_cpu_cycle (cpup, FETCH_cycle);
2211 break;
2212 case JMP_RESTART:
2213 set_cpu_cycle (cpup, EXEC_cycle);
2214 break;
2215 default:
2216 sim_warn ("longjmp value of %d unhandled\n", val);
2217 goto leave;
2218 }
2219
2220
2221
2222 DCDstruct * ci = & cpu.currentInstruction;
2223
2224 if (cpu.restart)
2225 {
2226 set_cpu_cycle (cpup, FAULT_cycle);
2227 }
2228
2229 do
2230 {
2231 reason = 0;
2232
2233 #if !defined(THREADZ) && !defined(LOCKLESS)
2234
2235 reason = simh_hooks (cpup);
2236 if (reason)
2237 {
2238 break;
2239 }
2240
2241
2242
2243
2244
2245
2246
2247
2248 if (fast_queue_subsample ++ > sys_opts.sys_poll_check_rate)
2249 {
2250 fast_queue_subsample = 0;
2251 # if defined(CONSOLE_FIX)
2252 # if defined(THREADZ) || defined(LOCKLESS)
2253 lock_libuv ();
2254 # endif
2255 # endif
2256 uv_run (ev_poll_loop, UV_RUN_NOWAIT);
2257 # if defined(CONSOLE_FIX)
2258 # if defined(THREADZ) || defined(LOCKLESS)
2259 unlock_libuv ();
2260 # endif
2261 # endif
2262 PNL (panel_process_event ());
2263 }
2264 #endif
2265
2266 cpu.cycleCnt ++;
2267
2268 #if defined(THREADZ)
2269
2270 unlock_mem_force ();
2271
2272
2273 cpuRunningWait ();
2274 #endif
2275 #if defined(LOCKLESS)
2276 core_unlock_all (cpup);
2277 #endif
2278
2279 #if defined(LOCKLESS)
2280 core_unlock_all(cpup);
2281 #endif
2282
2283 #if !defined(THREADZ) && !defined(LOCKLESS)
2284 if (cpu.tweaks.isolts_mode)
2285 {
2286 if (cpu.cycle != FETCH_cycle)
2287 {
2288
2289 cpu.rTRlsb ++;
2290 if (cpu.rTRlsb >= 4)
2291 {
2292 cpu.rTRlsb = 0;
2293 cpu.shadowTR = (cpu.shadowTR - 1) & MASK27;
2294 if (cpu.shadowTR == 0)
2295 {
2296 if (cpu.tweaks.tro_enable)
2297 setG7fault (current_running_cpu_idx, FAULT_TRO, fst_zero);
2298 }
2299 }
2300 }
2301 }
2302 #endif
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316 # define TR_RATE 2
2317
2318
2319
2320 cpu.rTR = (word27) (((word27s) cpu.rTR) - (word27s) (cpu.rTRticks / TR_RATE));
2321 cpu.rTRticks %= TR_RATE;
2322
2323
2324
2325 if (cpu.rTR & ~MASK27)
2326 {
2327 cpu.rTR &= MASK27;
2328 if (cpu.tweaks.tro_enable) {
2329 setG7fault (current_running_cpu_idx, FAULT_TRO, fst_zero);
2330 }
2331 }
2332
2333 sim_debug (DBG_CYCLE, & cpu_dev, "Cycle is %s\n",
2334 cycle_str (cpu.cycle));
2335
2336 switch (cpu.cycle)
2337 {
2338 case INTERRUPT_cycle:
2339 {
2340 CPT (cpt1U, 0);
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352 uint intr_pair_addr = get_highest_intr (cpup);
2353 #if defined(TESTING)
2354 HDBGIntr (intr_pair_addr, "");
2355 #endif
2356 cpu.cu.FI_ADDR = (word5) (intr_pair_addr / 2);
2357 cu_safe_store (cpup);
2358
2359
2360
2361 CPT (cpt1U, 1);
2362
2363 set_temporary_absolute_mode (cpup);
2364
2365
2366 cpu.PPR.PRR = 0;
2367 cpu.TPR.TRR = 0;
2368
2369 sim_debug (DBG_INTR, & cpu_dev, "intr_pair_addr %u flag %d\n",
2370 intr_pair_addr, cpu.interrupt_flag);
2371 #if !defined(SPEED)
2372 if_sim_debug (DBG_INTR, & cpu_dev)
2373 traceInstruction (DBG_INTR);
2374 #endif
2375
2376 if (cpu.interrupt_flag)
2377 {
2378 CPT (cpt1U, 2);
2379
2380
2381
2382
2383
2384
2385 if (intr_pair_addr != 1)
2386 {
2387 CPT (cpt1U, 3);
2388
2389
2390 core_read2 (cpup, intr_pair_addr,
2391 & cpu.cu.IWB, & cpu.cu.IRODD, __func__);
2392 #if defined(TESTING)
2393 HDBGMRead (intr_pair_addr, cpu.cu.IWB, "intr even");
2394 HDBGMRead (intr_pair_addr + 1, cpu.cu.IRODD, "intr odd");
2395 #endif
2396 cpu.cu.xde = 1;
2397 cpu.cu.xdo = 1;
2398 cpu.isExec = true;
2399 cpu.isXED = true;
2400
2401 CPT (cpt1U, 4);
2402 cpu.interrupt_flag = false;
2403 set_cpu_cycle (cpup, INTERRUPT_EXEC_cycle);
2404 break;
2405 }
2406 }
2407
2408
2409
2410 CPT (cpt1U, 5);
2411 cpu.interrupt_flag = false;
2412 clear_temporary_absolute_mode (cpup);
2413
2414 cu_safe_restore (cpup);
2415
2416
2417 cpu.wasXfer = false;
2418
2419
2420 set_cpu_cycle (cpup, FETCH_cycle);
2421 }
2422 break;
2423
2424 case FETCH_cycle:
2425 #if defined(PANEL68)
2426 (void)memset (cpu.cpt, 0, sizeof (cpu.cpt));
2427 #endif
2428 CPT (cpt1U, 13);
2429
2430 PNL (L68_ (cpu.INS_FETCH = false;))
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467 if (get_bar_mode (cpup))
2468 get_BAR_address (cpup, cpu.PPR.IC);
2469
2470
2471
2472
2473 bool tmp_priv_mode = is_priv_mode (cpup);
2474 bool is_dis = cpu.currentInstruction.opcode == 0616 &&
2475 cpu.currentInstruction.opcodeX == 0;
2476 bool noCheckTR = tmp_priv_mode &&
2477 !(is_dis && GET_I (cpu.cu.IWB) == 0);
2478
2479 if (is_dis)
2480 {
2481
2482
2483 cpu.interrupt_flag = sample_interrupts (cpup);
2484 cpu.g7_flag =
2485 noCheckTR ? bG7PendingNoTRO (cpup) : bG7Pending (cpup);
2486 }
2487 else if (! (cpu.cu.xde | cpu.cu.xdo |
2488 cpu.cu.rpt | cpu.cu.rd | cpu.cu.rl))
2489 {
2490 if ((!cpu.wasInhibited) &&
2491 (cpu.PPR.IC & 1) == 0 &&
2492 (! cpu.wasXfer))
2493 {
2494 CPT (cpt1U, 14);
2495 cpu.interrupt_flag = sample_interrupts (cpup);
2496 cpu.g7_flag =
2497 noCheckTR ? bG7PendingNoTRO (cpup) : bG7Pending (cpup);
2498 }
2499 cpu.wasInhibited = false;
2500 }
2501 else
2502 {
2503
2504
2505
2506
2507
2508 if ((cpu.PPR.IC & 1) == 1)
2509 {
2510 cpu.wasInhibited = true;
2511 }
2512 }
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548 if (cpu.g7_flag)
2549 {
2550 cpu.g7_flag = false;
2551 cpu.interrupt_flag = false;
2552 sim_debug (DBG_CYCLE, & cpu_dev,
2553 "call doG7Fault (%d)\n", !noCheckTR);
2554 doG7Fault (cpup, !noCheckTR);
2555 }
2556 if (cpu.interrupt_flag)
2557 {
2558
2559
2560
2561 CPT (cpt1U, 15);
2562 set_cpu_cycle (cpup, INTERRUPT_cycle);
2563 break;
2564 }
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574 case PSEUDO_FETCH_cycle:
2575
2576 tmp_priv_mode = is_priv_mode (cpup);
2577 if (! (luf_flag && tmp_priv_mode))
2578 cpu.lufCounter ++;
2579
2580 if (cpu.lufCounter > luf_limits[cpu.CMR.luf])
2581 {
2582 if (tmp_priv_mode)
2583 {
2584
2585 cpu.lufOccurred = true;
2586 }
2587 else
2588 {
2589 do_LUF_fault (cpup);
2590 }
2591 }
2592
2593
2594 if (cpu.lufCounter > luf_limits[4])
2595 {
2596 do_LUF_fault (cpup);
2597 }
2598
2599
2600
2601 if (! tmp_priv_mode && cpu.lufOccurred)
2602 {
2603 do_LUF_fault (cpup);
2604 }
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637 if (cpu.cycle == PSEUDO_FETCH_cycle)
2638 {
2639 cpu.apu.lastCycle = INSTRUCTION_FETCH;
2640 cpu.cu.XSF = 0;
2641 cpu.cu.TSN_VALID [0] = 0;
2642 cpu.TPR.TSR = cpu.PPR.PSR;
2643 cpu.TPR.TRR = cpu.PPR.PRR;
2644 cpu.wasInhibited = false;
2645 }
2646 else
2647 {
2648 CPT (cpt1U, 20);
2649 cpu.isExec = false;
2650 cpu.isXED = false;
2651
2652
2653
2654 cpu.cu.XSF = 0;
2655 sim_debug (DBG_TRACEEXT, & cpu_dev, "fetchCycle bit 29 sets XSF to 0\n");
2656 cpu.cu.TSN_VALID [0] = 0;
2657 cpu.TPR.TSR = cpu.PPR.PSR;
2658 cpu.TPR.TRR = cpu.PPR.PRR;
2659 PNL (cpu.prepare_state = ps_PIA);
2660 PNL (L68_ (cpu.INS_FETCH = true;))
2661 fetchInstruction (cpup, cpu.PPR.IC);
2662 }
2663
2664 CPT (cpt1U, 21);
2665 advanceG7Faults (cpup);
2666 set_cpu_cycle (cpup, EXEC_cycle);
2667 break;
2668
2669 case EXEC_cycle:
2670 case FAULT_EXEC_cycle:
2671 case INTERRUPT_EXEC_cycle:
2672 {
2673 CPT (cpt1U, 22);
2674
2675 #if defined(LOCKLESS)
2676 if (stall_point_active)
2677 {
2678 for (int i = 0; i < N_STALL_POINTS; i ++)
2679 if (stall_points[i].segno && stall_points[i].segno == cpu.PPR.PSR &&
2680 stall_points[i].offset && stall_points[i].offset == cpu.PPR.IC)
2681 {
2682 # if defined(CTRACE)
2683 (void)fprintf (stderr, "%10lu %s stall %d\n", seqno (), cpunstr[current_running_cpu_idx], i);
2684 # endif
2685
2686 sim_usleep(stall_points[i].time);
2687 break;
2688 }
2689 }
2690 #endif
2691
2692
2693
2694
2695 if (GET_I (cpu.cu.IWB))
2696 cpu.wasInhibited = true;
2697
2698 t_stat ret = executeInstruction (cpup);
2699 #if defined(TR_WORK_EXEC)
2700 cpu.rTRticks ++;
2701 #endif
2702 CPT (cpt1U, 23);
2703
2704 if (cpu.tweaks.l68_mode)
2705 add_l68_CU_history (cpup);
2706 else
2707 add_dps8m_CU_history (cpup);
2708
2709 if (ret > 0)
2710 {
2711 reason = ret;
2712 break;
2713 }
2714
2715 if (ret == CONT_XEC)
2716 {
2717 CPT (cpt1U, 27);
2718 cpu.wasXfer = false;
2719 cpu.isExec = true;
2720 if (cpu.cu.xdo)
2721 cpu.isXED = true;
2722
2723 cpu.cu.XSF = 0;
2724 cpu.cu.TSN_VALID [0] = 0;
2725 cpu.TPR.TSR = cpu.PPR.PSR;
2726 cpu.TPR.TRR = cpu.PPR.PRR;
2727 break;
2728 }
2729
2730 if (ret == CONT_TRA || ret == CONT_RET)
2731 {
2732 CPT (cpt1U, 24);
2733 cpu.cu.xde = cpu.cu.xdo = 0;
2734 cpu.isExec = false;
2735 cpu.isXED = false;
2736
2737 cpu.wasXfer = true;
2738
2739 if (cpu.cycle != EXEC_cycle)
2740 {
2741 clearFaultCycle (cpup);
2742
2743
2744
2745
2746
2747 if (! (cpu.currentInstruction.opcode == 0715 &&
2748 cpu.currentInstruction.opcodeX == 0))
2749 {
2750 CPT (cpt1U, 9);
2751 SET_I_NBAR;
2752 }
2753
2754 if (!clear_temporary_absolute_mode (cpup))
2755 {
2756
2757 sim_debug (DBG_TRACEEXT, & cpu_dev,
2758 "setting ABS mode\n");
2759 CPT (cpt1U, 10);
2760 set_addr_mode (cpup, ABSOLUTE_mode);
2761 }
2762 else
2763 {
2764
2765 sim_debug (DBG_TRACEEXT, & cpu_dev,
2766 "not setting ABS mode\n");
2767 }
2768
2769 }
2770
2771
2772 if (TST_I_ABS && cpu.cu.XSF)
2773 {
2774 set_addr_mode (cpup, APPEND_mode);
2775 }
2776
2777 if (ret == CONT_TRA)
2778 {
2779
2780 cpu.wasXfer = false;
2781 set_cpu_cycle (cpup, PSEUDO_FETCH_cycle);
2782 }
2783 else
2784 set_cpu_cycle (cpup, FETCH_cycle);
2785 break;
2786 }
2787
2788 if (ret == CONT_DIS)
2789 {
2790 CPT (cpt1U, 25);
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824 #if !defined(ROUND_ROBIN)
2825
2826
2827
2828
2829 # if defined(THREADZ) || defined(LOCKLESS)
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839 # if defined(NO_TIMEWAIT)
2840
2841 struct timespec req, rem;
2842 uint ms = sys_opts.sys_poll_interval;
2843 long int nsec = (long int) ms * 1000L * 1000L;
2844 req.tv_nsec = nsec;
2845 req.tv_sec += req.tv_nsec / 1000000000L;
2846 req.tv_nsec %= 1000000000L;
2847 int rc = nanosleep (& req, & rem);
2848
2849 if (rc == -1)
2850 {
2851 ms = (uint) (rem.tv_nsec / 1000 + req.tv_sec * 1000);
2852 }
2853 word27 ticks = ms * 512;
2854 if (cpu.rTR <= ticks)
2855 {
2856 if (cpu.tweaks.tro_enable) {
2857 setG7fault (current_running_cpu_idx, FAULT_TRO, fst_zero);
2858 }
2859 cpu.rTR = (cpu.rTR - ticks) & MASK27;
2860 }
2861 else
2862 cpu.rTR = (cpu.rTR - ticks) & MASK27;
2863
2864 if (cpu.rTR == 0)
2865 cpu.rTR = MASK27;
2866 # else
2867
2868
2869 unsigned long left = (unsigned long) ((uint64) (cpu.rTR) * 125u / 64u);
2870 unsigned long nowLeft = left;
2871 lock_scu ();
2872 if (!sample_interrupts (cpup))
2873 {
2874 nowLeft = sleepCPU (left);
2875 }
2876 unlock_scu ();
2877 if (nowLeft)
2878 {
2879
2880
2881 if (nowLeft <= left) {
2882 cpu.rTR = (word27) (left * 64 / 125);
2883 }
2884 }
2885 else
2886 {
2887
2888 if (cpu.tweaks.tro_enable)
2889 {
2890 lock_scu ();
2891 setG7fault (current_running_cpu_idx, FAULT_TRO, fst_zero);
2892 unlock_scu ();
2893 }
2894 cpu.rTR = MASK27;
2895 }
2896 # endif
2897 cpu.rTRticks = 0;
2898 break;
2899 # else
2900
2901 sim_usleep (sys_opts.sys_poll_interval * 1000);
2902
2903 # if defined(CONSOLE_FIX)
2904 # if defined(THREADZ) || defined(LOCKLESS)
2905 lock_libuv ();
2906 # endif
2907 # endif
2908 uv_run (ev_poll_loop, UV_RUN_NOWAIT);
2909 # if defined(CONSOLE_FIX)
2910 # if defined(THREADZ) || defined(LOCKLESS)
2911 unlock_libuv ();
2912 # endif
2913 # endif
2914 fast_queue_subsample = 0;
2915
2916 sim_interval = 0;
2917
2918
2919
2920
2921 cpu.rTRticks = 0;
2922
2923
2924
2925
2926
2927
2928 if (cpu.rTR <= sys_opts.sys_poll_interval * 512)
2929 {
2930 if (cpu.tweaks.tro_enable) {
2931 setG7fault (current_running_cpu_idx, FAULT_TRO,
2932 fst_zero);
2933 }
2934 cpu.rTR = (cpu.rTR - sys_opts.sys_poll_interval * 512) & MASK27;
2935 }
2936 else
2937 cpu.rTR = (cpu.rTR - sys_opts.sys_poll_interval * 512) & MASK27;
2938 if (cpu.rTR == 0)
2939 cpu.rTR = MASK27;
2940 # endif
2941 #endif
2942
2943 break;
2944 }
2945
2946 cpu.wasXfer = false;
2947
2948 if (ret < 0)
2949 {
2950 sim_warn ("executeInstruction returned %d?\n", ret);
2951 break;
2952 }
2953
2954 if ((! cpu.cu.repeat_first) &&
2955 (cpu.cu.rpt ||
2956 (cpu.cu.rd && (cpu.PPR.IC & 1)) ||
2957 cpu.cu.rl))
2958 {
2959 CPT (cpt1U, 26);
2960 if (cpu.cu.rd)
2961 -- cpu.PPR.IC;
2962 cpu.wasXfer = false;
2963 set_cpu_cycle (cpup, FETCH_cycle);
2964 break;
2965 }
2966
2967
2968 if (cpu.cycle == FAULT_EXEC_cycle &&
2969 !cpu.cu.xde && cpu.cu.xdo)
2970 {
2971 clear_temporary_absolute_mode (cpup);
2972 cu_safe_restore (cpup);
2973 CPT (cpt1U, 12);
2974 clearFaultCycle (cpup);
2975
2976
2977
2978 cpu.wasXfer = false;
2979 cpu.isExec = false;
2980 cpu.isXED = false;
2981
2982 cpu.PPR.IC += ci->info->ndes;
2983 cpu.PPR.IC ++;
2984
2985 set_cpu_cycle (cpup, FETCH_cycle);
2986 break;
2987 }
2988
2989
2990 if (cpu.cycle == INTERRUPT_EXEC_cycle &&
2991 !cpu.cu.xde && cpu.cu.xdo)
2992 {
2993 clear_temporary_absolute_mode (cpup);
2994 cu_safe_restore (cpup);
2995
2996
2997
2998 CPT (cpt1U, 12);
2999 cpu.wasXfer = false;
3000 cpu.isExec = false;
3001 cpu.isXED = false;
3002
3003 set_cpu_cycle (cpup, FETCH_cycle);
3004 break;
3005 }
3006
3007
3008 if (cpu.cu.xde && cpu.cu.xdo)
3009 {
3010
3011 cpu.cu.IWB = cpu.cu.IRODD;
3012 cpu.cu.xde = 0;
3013 cpu.isExec = true;
3014 cpu.isXED = true;
3015 cpu.cu.XSF = 0;
3016 cpu.cu.TSN_VALID [0] = 0;
3017 cpu.TPR.TSR = cpu.PPR.PSR;
3018 cpu.TPR.TRR = cpu.PPR.PRR;
3019 break;
3020 }
3021
3022 if (cpu.cu.xde || cpu.cu.xdo)
3023 {
3024 cpu.cu.xde = cpu.cu.xdo = 0;
3025 cpu.isExec = false;
3026 cpu.isXED = false;
3027 CPT (cpt1U, 27);
3028 cpu.wasXfer = false;
3029 cpu.PPR.IC ++;
3030 if (ci->info->ndes > 0)
3031 cpu.PPR.IC += ci->info->ndes;
3032 cpu.wasInhibited = true;
3033 set_cpu_cycle (cpup, FETCH_cycle);
3034 break;
3035 }
3036
3037
3038 if (cpu.cycle != EXEC_cycle)
3039 sim_warn ("expected EXEC_cycle (%d)\n", cpu.cycle);
3040
3041 cpu.cu.xde = cpu.cu.xdo = 0;
3042 cpu.isExec = false;
3043 cpu.isXED = false;
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054 if ((cpu.PPR.IC & 1) == 0 &&
3055 ci->info->ndes == 0 &&
3056 !cpu.cu.repeat_first && !cpu.cu.rpt && !cpu.cu.rd && !cpu.cu.rl &&
3057 !(cpu.currentInstruction.opcode == 0616 && cpu.currentInstruction.opcodeX == 0) &&
3058 (cpu.PPR.IC & ~3u) != (cpu.last_write & ~3u))
3059 {
3060 cpu.PPR.IC ++;
3061 cpu.wasXfer = false;
3062 cpu.cu.IWB = cpu.cu.IRODD;
3063 set_cpu_cycle (cpup, PSEUDO_FETCH_cycle);
3064 break;
3065 }
3066
3067 cpu.PPR.IC ++;
3068 if (ci->info->ndes > 0)
3069 cpu.PPR.IC += ci->info->ndes;
3070
3071 CPT (cpt1U, 28);
3072 cpu.wasXfer = false;
3073 set_cpu_cycle (cpup, FETCH_cycle);
3074 }
3075 break;
3076
3077 case SYNC_FAULT_RTN_cycle:
3078 {
3079 CPT (cpt1U, 29);
3080
3081
3082
3083
3084 cpu.PPR.IC += ci->info->ndes;
3085 cpu.PPR.IC ++;
3086 cpu.wasXfer = false;
3087 set_cpu_cycle (cpup, FETCH_cycle);
3088 }
3089 break;
3090
3091 case FAULT_cycle:
3092 {
3093 CPT (cpt1U, 30);
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115 if ((cpu.cu.APUCycleBits & 060) || cpu.secret_addressing_mode)
3116 set_apu_status (cpup, apuStatus_FABS);
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128 if (cpu.faultNumber != FAULT_TRB || cpu.cu.xde == 0)
3129 {
3130 cu_safe_store (cpup);
3131 }
3132 else
3133 {
3134 word36 tmpIRODD = cpu.scu_data[7];
3135 cu_safe_store (cpup);
3136 cpu.scu_data[7] = tmpIRODD;
3137 }
3138 CPT (cpt1U, 31);
3139
3140
3141 set_temporary_absolute_mode (cpup);
3142
3143
3144 cpu.PPR.PRR = 0;
3145 cpu.TPR.TRR = 0;
3146
3147
3148 uint fltAddress = (cpu.switches.FLT_BASE << 5) & 07740;
3149 L68_ (
3150 if (cpu.is_FFV)
3151 {
3152 cpu.is_FFV = false;
3153 CPTUR (cptUseMR);
3154
3155 fltAddress = (cpu.MR.FFV & MASK15) << 3;
3156 }
3157 )
3158
3159
3160 word24 addr = fltAddress + 2 * cpu.faultNumber;
3161
3162 if (cpu.restart)
3163 {
3164 cpu.restart = false;
3165 addr = cpu.restart_address;
3166 }
3167
3168 core_read2 (cpup, addr, & cpu.cu.IWB, & cpu.cu.IRODD, __func__);
3169 #if defined(TESTING)
3170 HDBGMRead (addr, cpu.cu.IWB, "fault even");
3171 HDBGMRead (addr + 1, cpu.cu.IRODD, "fault odd");
3172 #endif
3173 cpu.cu.xde = 1;
3174 cpu.cu.xdo = 1;
3175 cpu.isExec = true;
3176 cpu.isXED = true;
3177
3178 CPT (cpt1U, 33);
3179 set_cpu_cycle (cpup, FAULT_EXEC_cycle);
3180
3181 break;
3182 }
3183
3184 }
3185 }
3186 #if defined(ROUND_ROBIN)
3187 while (0);
3188 if (reason == 0)
3189 goto setCPU;
3190 #else
3191 while (reason == 0);
3192 #endif
3193
3194 leave:
3195 #if defined(TESTING)
3196 HDBGPrint ();
3197 #endif
3198
3199 for (unsigned short n = 0; n < N_CPU_UNITS_MAX; n++)
3200 {
3201 #if !defined(SCHED_NEVER_YIELD)
3202 lockYieldAll = lockYieldAll + (unsigned long long)cpus[n].coreLockState.lockYield;
3203 #endif
3204 lockWaitMaxAll = lockWaitMaxAll + (unsigned long long)cpus[n].coreLockState.lockWaitMax;
3205 lockWaitAll = lockWaitAll + (unsigned long long)cpus[n].coreLockState.lockWait;
3206 lockImmediateAll = lockImmediateAll + (unsigned long long)cpus[n].coreLockState.lockImmediate;
3207 lockCntAll = lockCntAll + (unsigned long long)cpus[n].coreLockState.lockCnt;
3208 instrCntAll = instrCntAll + (unsigned long long)cpus[n].instrCnt;
3209 cycleCntAll = cycleCntAll + (unsigned long long)cpus[n].cycleCnt;
3210 }
3211
3212 (void)fflush(stderr);
3213 (void)fflush(stdout);
3214
3215 # if !defined(PERF_STRIP)
3216 if (cycleCntAll > (unsigned long long)cpu.cycleCnt)
3217 {
3218 # endif
3219 sim_msg ("\r\n");
3220 sim_msg ("\r+---------------------------------+\r\n");
3221 sim_msg ("\r| Aggregate CPU Statistics |\r\n");
3222 sim_msg ("\r+---------------------------------+\r\n");
3223 (void)fflush(stderr);
3224 (void)fflush(stdout);
3225 # if defined(WIN_STDIO)
3226 sim_msg ("\r| cycles %15llu |\r\n", cycleCntAll);
3227 sim_msg ("\r| instructions %15llu |\r\n", instrCntAll);
3228 (void)fflush(stderr);
3229 (void)fflush(stdout);
3230 sim_msg ("\r+---------------------------------+\r\n");
3231 sim_msg ("\r| lockCnt %15llu |\r\n", lockCntAll);
3232 sim_msg ("\r| lockImmediate %15llu |\r\n", lockImmediateAll);
3233 (void)fflush(stderr);
3234 (void)fflush(stdout);
3235 sim_msg ("\r+---------------------------------+\r\n");
3236 sim_msg ("\r| lockWait %15llu |\r\n", lockWaitAll);
3237 sim_msg ("\r| lockWaitMax %15llu |\r\n", lockWaitMaxAll);
3238 (void)fflush(stderr);
3239 (void)fflush(stdout);
3240 # if !defined(SCHED_NEVER_YIELD)
3241 sim_msg ("\r| lockYield %15llu |\r\n", lockYieldAll);
3242 # else
3243 sim_msg ("\r| lockYield ---- |\r\n");
3244 # endif
3245 sim_msg ("\r+---------------------------------+\r\n");
3246 (void)fflush(stderr);
3247 (void)fflush(stdout);
3248 # else
3249 sim_msg ("\r| cycles %'15llu |\r\n", cycleCntAll);
3250 sim_msg ("\r| instructions %'15llu |\r\n", instrCntAll);
3251 (void)fflush(stderr);
3252 (void)fflush(stdout);
3253 sim_msg ("\r+---------------------------------+\r\n");
3254 sim_msg ("\r| lockCnt %'15llu |\r\n", lockCntAll);
3255 sim_msg ("\r| lockImmediate %'15llu |\r\n", lockImmediateAll);
3256 (void)fflush(stderr);
3257 (void)fflush(stdout);
3258 sim_msg ("\r+---------------------------------+\r\n");
3259 sim_msg ("\r| lockWait %'15llu |\r\n", lockWaitAll);
3260 sim_msg ("\r| lockWaitMax %'15llu |\r\n", lockWaitMaxAll);
3261 (void)fflush(stderr);
3262 (void)fflush(stdout);
3263 # if !defined(SCHED_NEVER_YIELD)
3264 sim_msg ("\r| lockYield %'15llu |\r\n", lockYieldAll);
3265 # else
3266 sim_msg ("\r| lockYield ---- |\r\n");
3267 # endif
3268 sim_msg ("\r+---------------------------------+\r\n");
3269 (void)fflush(stderr);
3270 (void)fflush(stdout);
3271 # endif
3272 # if !defined(PERF_STRIP)
3273 }
3274 # else
3275 sim_msg("\r\n");
3276 # endif
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288 #if defined(THREADZ) || defined(LOCKLESS)
3289 stopCPUThread();
3290 #endif
3291
3292 #if defined(M_SHARED)
3293
3294
3295
3296
3297 set_cpu_idx (0);
3298 dummy_IC = cpu.PPR.IC;
3299 #endif
3300
3301 return reason;
3302 }
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318 int operand_size (cpu_state_t * cpup)
3319 {
3320 DCDstruct * i = & cpu.currentInstruction;
3321 if (i->info->flags & (READ_OPERAND | STORE_OPERAND))
3322 return 1;
3323 else if (i->info->flags & (READ_YPAIR | STORE_YPAIR))
3324 return 2;
3325 else if (i->info->flags & (READ_YBLOCK8 | STORE_YBLOCK8))
3326 return 8;
3327 else if (i->info->flags & (READ_YBLOCK16 | STORE_YBLOCK16))
3328 return 16;
3329 else if (i->info->flags & (READ_YBLOCK32 | STORE_YBLOCK32))
3330 return 32;
3331 return 0;
3332 }
3333
3334
3335
3336 void readOperandRead (cpu_state_t * cpup, word18 addr) {
3337 CPT (cpt1L, 6);
3338
3339 #if defined(THREADZ)
3340 DCDstruct * i = & cpu.currentInstruction;
3341 if (RMWOP (i))
3342 lock_rmw ();
3343 #endif
3344
3345 switch (operand_size (cpup)) {
3346 case 1:
3347 CPT (cpt1L, 7);
3348 ReadOperandRead (cpup, addr, & cpu.CY);
3349 break;
3350 case 2:
3351 CPT (cpt1L, 8);
3352 addr &= 0777776;
3353 Read2OperandRead (cpup, addr, cpu.Ypair);
3354 break;
3355 case 8:
3356 CPT (cpt1L, 9);
3357 addr &= 0777770;
3358 Read8 (cpup, addr, cpu.Yblock8, cpu.currentInstruction.b29);
3359 break;
3360 case 16:
3361 CPT (cpt1L, 10);
3362 addr &= 0777770;
3363 Read16 (cpup, addr, cpu.Yblock16);
3364 break;
3365 case 32:
3366 CPT (cpt1L, 11);
3367 addr &= 0777740;
3368 for (uint j = 0 ; j < 32 ; j += 1)
3369 ReadOperandRead (cpup, addr + j, cpu.Yblock32 + j);
3370 break;
3371 }
3372 }
3373
3374 void readOperandRMW (cpu_state_t * cpup, word18 addr) {
3375 CPT (cpt1L, 6);
3376 switch (operand_size (cpup)) {
3377 case 1:
3378 CPT (cpt1L, 7);
3379 ReadOperandRMW (cpup, addr, & cpu.CY);
3380 break;
3381 case 2:
3382 CPT (cpt1L, 8);
3383 addr &= 0777776;
3384 Read2OperandRead (cpup, addr, cpu.Ypair);
3385 break;
3386 case 8:
3387 CPT (cpt1L, 9);
3388 addr &= 0777770;
3389 Read8 (cpup, addr, cpu.Yblock8, cpu.currentInstruction.b29);
3390 break;
3391 case 16:
3392 CPT (cpt1L, 10);
3393 addr &= 0777770;
3394 Read16 (cpup, addr, cpu.Yblock16);
3395 break;
3396 case 32:
3397 CPT (cpt1L, 11);
3398 addr &= 0777740;
3399 for (uint j = 0 ; j < 32 ; j += 1)
3400 ReadOperandRMW (cpup, addr + j, cpu.Yblock32 + j);
3401 break;
3402 }
3403 }
3404
3405
3406
3407 t_stat write_operand (cpu_state_t * cpup, word18 addr, UNUSED processor_cycle_type cyctyp)
3408 {
3409 switch (operand_size (cpup))
3410 {
3411 case 1:
3412 CPT (cpt1L, 12);
3413 WriteOperandStore (cpup, addr, cpu.CY);
3414 break;
3415 case 2:
3416 CPT (cpt1L, 13);
3417 addr &= 0777776;
3418 Write2OperandStore (cpup, addr + 0, cpu.Ypair);
3419 break;
3420 case 8:
3421 CPT (cpt1L, 14);
3422 addr &= 0777770;
3423 Write8 (cpup, addr, cpu.Yblock8, cpu.currentInstruction.b29);
3424 break;
3425 case 16:
3426 CPT (cpt1L, 15);
3427 addr &= 0777770;
3428 Write16 (cpup, addr, cpu.Yblock16);
3429 break;
3430 case 32:
3431 CPT (cpt1L, 16);
3432 addr &= 0777740;
3433
3434
3435 Write32 (cpup, addr, cpu.Yblock32);
3436 break;
3437 }
3438
3439 #if defined(THREADZ)
3440 if (cyctyp == OPERAND_STORE)
3441 {
3442 DCDstruct * i = & cpu.currentInstruction;
3443 if (RMWOP (i))
3444 unlock_mem ();
3445 }
3446 #endif
3447 return SCPE_OK;
3448
3449 }
3450
3451 #if !defined(SPEED)
3452 t_stat set_mem_watch (int32 arg, const char * buf)
3453 {
3454 if (strlen (buf) == 0)
3455 {
3456 if (arg)
3457 {
3458 sim_warn ("no argument to watch?\n");
3459 return SCPE_ARG;
3460 }
3461 sim_msg ("Clearing all watch points\n");
3462 (void)memset (& watch_bits, 0, sizeof (watch_bits));
3463 return SCPE_OK;
3464 }
3465 char * end;
3466 long int n = strtol (buf, & end, 0);
3467 if (* end || n < 0 || n >= MEMSIZE)
3468 {
3469 sim_warn ("Invalid argument to watch? %ld\n", (long) n);
3470 return SCPE_ARG;
3471 }
3472 watch_bits [n] = arg != 0;
3473 return SCPE_OK;
3474 }
3475 #endif
3476
3477
3478
3479
3480
3481 #if !defined(SPEED)
3482 static void nem_check (word24 addr, const char * context)
3483 {
3484 cpu_state_t * cpup = _cpup;
3485 if (lookup_cpu_mem_map (cpup, addr) < 0)
3486 {
3487 doFault (FAULT_STR, fst_str_nea, context);
3488 }
3489 }
3490 #endif
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503 #if !defined(SPEED) || !defined(INLINE_CORE)
3504 int core_read (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx)
3505 {
3506 PNL (cpu.portBusy = true;)
3507 SC_MAP_ADDR (addr, addr);
3508 # if !defined(LOCKLESS)
3509 if (M[addr] & MEM_UNINITIALIZED)
3510 {
3511 sim_debug (DBG_WARN, & cpu_dev,
3512 "Uninitialized memory accessed at address %08o; "
3513 "IC is 0%06o:0%06o (%s(\n",
3514 addr, cpu.PPR.PSR, cpu.PPR.IC, ctx);
3515 }
3516 # endif
3517 # if !defined(SPEED)
3518 if (watch_bits [addr])
3519 {
3520 sim_msg ("WATCH [%llu] %05o:%06o read %08o %012llo (%s)\n",
3521 (long long unsigned int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
3522 (long long unsigned int)M [addr], ctx);
3523 traceInstruction (0);
3524 }
3525 # endif
3526 # if defined(LOCKLESS)
3527 # if !defined(SUNLINT)
3528 word36 v;
3529 LOAD_ACQ_CORE_WORD(v, addr);
3530 *data = v & DMASK;
3531 # endif
3532 # else
3533 *data = M[addr] & DMASK;
3534 # endif
3535
3536 # if defined(TR_WORK_MEM)
3537 cpu.rTRticks ++;
3538 # endif
3539 sim_debug (DBG_CORE, & cpu_dev,
3540 "core_read %08o %012"PRIo64" (%s)\n",
3541 addr, * data, ctx);
3542 PNL (trackport (addr, * data));
3543 return 0;
3544 }
3545 #endif
3546
3547 #if defined(LOCKLESS)
3548 int core_read_lock (cpu_state_t * cpup, word24 addr, word36 *data, UNUSED const char * ctx)
3549 {
3550 SC_MAP_ADDR (addr, addr);
3551 LOCK_CORE_WORD(addr, & cpu.coreLockState);
3552 if (cpu.coreLockState.locked_addr != 0) {
3553 sim_warn ("core_read_lock: locked %08o locked_addr %08o %c %05o:%06o\n",
3554 addr, cpu.coreLockState.locked_addr, current_running_cpu_idx + 'A',
3555 cpu.PPR.PSR, cpu.PPR.IC);
3556 core_unlock_all (cpup);
3557 }
3558 cpu.coreLockState.locked_addr = addr;
3559 # if !defined(SUNLINT)
3560 word36 v;
3561 LOAD_ACQ_CORE_WORD(v, addr);
3562 * data = v & DMASK;
3563 # endif
3564 return 0;
3565 }
3566 #endif
3567
3568 #if !defined(SPEED) || !defined(INLINE_CORE)
3569 int core_write (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx)
3570 {
3571 PNL (cpu.portBusy = true;)
3572 SC_MAP_ADDR (addr, addr);
3573 if (cpu.tweaks.isolts_mode)
3574 {
3575 if (cpu.MR.sdpap)
3576 {
3577 sim_warn ("failing to implement sdpap\n");
3578 cpu.MR.sdpap = 0;
3579 }
3580 if (cpu.MR.separ)
3581 {
3582 sim_warn ("failing to implement separ\n");
3583 cpu.MR.separ = 0;
3584 }
3585 }
3586 # if defined(LOCKLESS)
3587 LOCK_CORE_WORD(addr, & cpu.coreLockState);
3588 # if !defined(SUNLINT)
3589 STORE_REL_CORE_WORD(addr, data);
3590 # endif
3591 # else
3592 M[addr] = data & DMASK;
3593 # endif
3594 # if !defined(SPEED)
3595 if (watch_bits [addr])
3596 {
3597 sim_msg ("WATCH [%llu] %05o:%06o write %08llo %012llo (%s)\n",
3598 (long long unsigned int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC,
3599 (long long unsigned int)addr, (unsigned long long int)M [addr], ctx);
3600 traceInstruction (0);
3601 }
3602 # endif
3603 # if defined(TR_WORK_MEM)
3604 cpu.rTRticks ++;
3605 # endif
3606 sim_debug (DBG_CORE, & cpu_dev,
3607 "core_write %08o %012"PRIo64" (%s)\n",
3608 addr, data, ctx);
3609 PNL (trackport (addr, data));
3610 return 0;
3611 }
3612 #endif
3613
3614 #if defined(LOCKLESS)
3615 int core_write_unlock (cpu_state_t * cpup, word24 addr, word36 data, UNUSED const char * ctx)
3616 {
3617 SC_MAP_ADDR (addr, addr);
3618 if (cpu.coreLockState.locked_addr != addr)
3619 {
3620 sim_warn ("core_write_unlock: locked %08o locked_addr %08o %c %05o:%06o\n",
3621 addr, cpu.coreLockState.locked_addr, current_running_cpu_idx + 'A',
3622 cpu.PPR.PSR, cpu.PPR.IC);
3623 core_unlock_all (cpup);
3624 }
3625
3626 # if !defined(SUNLINT)
3627 STORE_REL_CORE_WORD(addr, data);
3628 # endif
3629 cpu.coreLockState.locked_addr = 0;
3630 return 0;
3631 }
3632
3633 int core_unlock_all (cpu_state_t * cpup)
3634 {
3635 if (cpu.coreLockState.locked_addr != 0) {
3636 sim_warn ("core_unlock_all: locked %08o %c %05o:%06o\n",
3637 cpu.coreLockState.locked_addr, current_running_cpu_idx + 'A',
3638 cpu.PPR.PSR, cpu.PPR.IC);
3639 # if !defined(SUNLINT)
3640 STORE_REL_CORE_WORD(cpu.coreLockState.locked_addr, M[cpu.coreLockState.locked_addr]);
3641 # endif
3642 cpu.coreLockState.locked_addr = 0;
3643 }
3644 return 0;
3645 }
3646 #endif
3647
3648 #if !defined(SPEED) || !defined(INLINE_CORE)
3649 int core_write_zone (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx)
3650 {
3651 PNL (cpu.portBusy = true;)
3652 if (cpu.tweaks.isolts_mode)
3653 {
3654 if (cpu.MR.sdpap)
3655 {
3656 sim_warn ("failing to implement sdpap\n");
3657 cpu.MR.sdpap = 0;
3658 }
3659 if (cpu.MR.separ)
3660 {
3661 sim_warn ("failing to implement separ\n");
3662 cpu.MR.separ = 0;
3663 }
3664 }
3665 word24 mapAddr = 0;
3666 SC_MAP_ADDR (addr, mapAddr);
3667 # if defined(LOCKLESS)
3668 word36 v;
3669 core_read_lock(cpup, addr, &v, ctx);
3670 v = (v & ~cpu.zone) | (data & cpu.zone);
3671 core_write_unlock(cpup, addr, v, ctx);
3672 # else
3673 M[mapAddr] = (M[mapAddr] & ~cpu.zone) | (data & cpu.zone);
3674 # endif
3675 cpu.useZone = false;
3676 # if !defined(SPEED)
3677 if (watch_bits [mapAddr])
3678 {
3679 sim_msg ("WATCH [%llu] %05o:%06o writez %08llo %012llo (%s)\n",
3680 (unsigned long long int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC,
3681 (unsigned long long int)mapAddr, (unsigned long long int)M [mapAddr], ctx);
3682 traceInstruction (0);
3683 }
3684 # endif
3685 # if defined(TR_WORK_MEM)
3686 cpu.rTRticks ++;
3687 # endif
3688 sim_debug (DBG_CORE, & cpu_dev,
3689 "core_write_zone %08o %012"PRIo64" (%s)\n",
3690 mapAddr, data, ctx);
3691 PNL (trackport (mapAddr, data));
3692 return 0;
3693 }
3694 #endif
3695
3696 #if !defined(SPEED) || !defined(INLINE_CORE)
3697 int core_read2 (cpu_state_t * cpup, word24 addr, word36 *even, word36 *odd, const char * ctx)
3698 {
3699 PNL (cpu.portBusy = true;)
3700 # if defined(LOCKLESS)
3701
3702 word36 v;
3703 # endif
3704 if (addr & 1)
3705 {
3706 sim_debug (DBG_MSG, & cpu_dev,
3707 "warning: subtracting 1 from pair at %o in "
3708 "core_read2 (%s)\n", addr, ctx);
3709 addr &= (word24)~1;
3710 }
3711 SC_MAP_ADDR (addr, addr);
3712 # if !defined(LOCKLESS)
3713 if (M[addr] & MEM_UNINITIALIZED)
3714 {
3715 sim_debug (DBG_WARN, & cpu_dev,
3716 "Uninitialized memory accessed at address %08o; "
3717 "IC is 0%06o:0%06o (%s)\n",
3718 addr, cpu.PPR.PSR, cpu.PPR.IC, ctx);
3719 }
3720 # endif
3721 # if !defined(SPEED)
3722 if (watch_bits [addr])
3723 {
3724 sim_msg ("WATCH [%llu] %05o:%06o read2 %08llo %012llo (%s)\n",
3725 (unsigned long long int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC,
3726 (unsigned long long int)addr, (unsigned long long int)M [addr], ctx);
3727 traceInstruction (0);
3728 }
3729 # endif
3730 # if defined(LOCKLESS)
3731 # if !defined(SUNLINT)
3732 LOAD_ACQ_CORE_WORD(v, addr);
3733 if (v & MEM_LOCKED)
3734 sim_warn ("core_read2: even locked %08o locked_addr %08o %c %05o:%06o\n",
3735 addr, cpu.coreLockState.locked_addr, current_running_cpu_idx + 'A',
3736 cpu.PPR.PSR, cpu.PPR.IC);
3737 *even = v & DMASK;
3738 addr++;
3739 # endif
3740 # else
3741 *even = M[addr++] & DMASK;
3742 # endif
3743 sim_debug (DBG_CORE, & cpu_dev,
3744 "core_read2 %08o %012"PRIo64" (%s)\n",
3745 addr - 1, * even, ctx);
3746
3747
3748
3749 # if !defined(LOCKLESS)
3750 if (M[addr] & MEM_UNINITIALIZED)
3751 {
3752 sim_debug (DBG_WARN, & cpu_dev,
3753 "Uninitialized memory accessed at address %08o; "
3754 "IC is 0%06o:0%06o (%s)\n",
3755 addr, cpu.PPR.PSR, cpu.PPR.IC, ctx);
3756 }
3757 # endif
3758 # if !defined(SPEED)
3759 if (watch_bits [addr])
3760 {
3761 sim_msg ("WATCH [%llu] %05o:%06o read2 %08llo %012llo (%s)\n",
3762 (unsigned long long int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC,
3763 (unsigned long long int)addr, (unsigned long long int)M [addr], ctx);
3764 traceInstruction (0);
3765 }
3766 # endif
3767 # if defined(LOCKLESS)
3768 # if !defined(SUNLINT)
3769 LOAD_ACQ_CORE_WORD(v, addr);
3770 if (v & MEM_LOCKED)
3771 sim_warn ("core_read2: odd locked %08o locked_addr %08o %c %05o:%06o\n",
3772 addr, cpu.coreLockState.locked_addr, current_running_cpu_idx + 'A',
3773 cpu.PPR.PSR, cpu.PPR.IC);
3774 *odd = v & DMASK;
3775 # endif
3776 # else
3777 *odd = M[addr] & DMASK;
3778 # endif
3779 sim_debug (DBG_CORE, & cpu_dev,
3780 "core_read2 %08o %012"PRIo64" (%s)\n",
3781 addr, * odd, ctx);
3782 # if defined(TR_WORK_MEM)
3783 cpu.rTRticks ++;
3784 # endif
3785 PNL (trackport (addr - 1, * even));
3786 return 0;
3787 }
3788 #endif
3789
3790 #if !defined(SPEED) || !defined(INLINE_CORE)
3791 int core_write2 (cpu_state_t * cpup, word24 addr, word36 even, word36 odd, const char * ctx) {
3792 PNL (cpu.portBusy = true;)
3793 if (addr & 1) {
3794 sim_debug (DBG_MSG, & cpu_dev,
3795 "warning: subtracting 1 from pair at %o in core_write2 " "(%s)\n",
3796 addr, ctx);
3797 addr &= (word24)~1;
3798 }
3799 SC_MAP_ADDR (addr, addr);
3800 if (cpu.tweaks.isolts_mode) {
3801 if (cpu.MR.sdpap) {
3802 sim_warn ("failing to implement sdpap\n");
3803 cpu.MR.sdpap = 0;
3804 }
3805 if (cpu.MR.separ) {
3806 sim_warn ("failing to implement separ\n");
3807 cpu.MR.separ = 0;
3808 }
3809 }
3810
3811 # if !defined(SPEED)
3812 if (watch_bits [addr]) {
3813 sim_msg ("WATCH [%llu] %05o:%06o write2 %08llo %012llo (%s)\n",
3814 (unsigned long long int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC,
3815 (unsigned long long int)addr, (unsigned long long int)even, ctx);
3816 traceInstruction (0);
3817 }
3818 # endif
3819 # if defined(LOCKLESS)
3820 LOCK_CORE_WORD(addr, & cpu.coreLockState);
3821 # if !defined(SUNLINT)
3822 STORE_REL_CORE_WORD(addr, even);
3823 # endif
3824 addr++;
3825 # else
3826 M[addr++] = even & DMASK;
3827 # endif
3828 sim_debug (DBG_CORE, & cpu_dev, "core_write2 %08o %012llo (%s)\n", addr - 1,
3829 (long long unsigned int)even, ctx);
3830
3831
3832
3833
3834 # if !defined(SPEED)
3835 if (watch_bits [addr]) {
3836 sim_msg ("WATCH [%llu] %05o:%06o write2 %08llo %012llo (%s)\n",
3837 (long long unsigned int)cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC,
3838 (long long unsigned int)addr, (long long unsigned int)odd, ctx);
3839 traceInstruction (0);
3840 }
3841 # endif
3842 # if defined(LOCKLESS)
3843 LOCK_CORE_WORD(addr, & cpu.coreLockState);
3844 # if !defined(SUNLINT)
3845 STORE_REL_CORE_WORD(addr, odd);
3846 # endif
3847 # else
3848 M[addr] = odd & DMASK;
3849 # endif
3850 # if defined(TR_WORK_MEM)
3851 cpu.rTRticks ++;
3852 # endif
3853 PNL (trackport (addr - 1, even));
3854 sim_debug (DBG_CORE, & cpu_dev, "core_write2 %08o %012"PRIo64" (%s)\n", addr, odd, ctx);
3855 return 0;
3856 }
3857 #endif
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868 void decode_instruction (cpu_state_t * cpup, word36 inst, DCDstruct * p)
3869 {
3870 CPT (cpt1L, 17);
3871 (void)memset (p, 0, sizeof (DCDstruct));
3872
3873 p->opcode = GET_OP (inst);
3874 p->opcodeX = GET_OPX(inst);
3875 p->opcode10 = p->opcode | (p->opcodeX ? 01000 : 0);
3876 p->address = GET_ADDR (inst);
3877 p->b29 = GET_A (inst);
3878 p->i = GET_I (inst);
3879 p->tag = GET_TAG (inst);
3880
3881 p->info = get_iwb_info (p);
3882
3883 if (p->info->flags & IGN_B29)
3884 p->b29 = 0;
3885
3886 if (p->info->ndes > 0)
3887 {
3888 p->b29 = 0;
3889 p->tag = 0;
3890 if (p->info->ndes > 1)
3891 {
3892 (void)memset (& cpu.currentEISinstruction, 0,
3893 sizeof (cpu.currentEISinstruction));
3894 }
3895 }
3896 }
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917 int is_priv_mode (cpu_state_t * cpup)
3918 {
3919
3920
3921
3922 if (get_bar_mode (cpup))
3923 return 0;
3924
3925
3926 if (get_addr_mode (cpup) == ABSOLUTE_mode)
3927 return 1;
3928 else if (cpu.PPR.P)
3929 return 1;
3930
3931 return 0;
3932 }
3933
3934
3935
3936
3937
3938
3939
3940
3941 bool get_bar_mode (cpu_state_t * cpup)
3942 {
3943 return ! (cpu.secret_addressing_mode || TST_I_NBAR);
3944 }
3945
3946 addr_modes_e get_addr_mode (cpu_state_t * cpup)
3947 {
3948 if (cpu.secret_addressing_mode)
3949 return ABSOLUTE_mode;
3950
3951
3952
3953
3954
3955
3956
3957 if (TST_I_ABS)
3958 {
3959 return ABSOLUTE_mode;
3960 }
3961 else
3962 {
3963 return APPEND_mode;
3964 }
3965 }
3966
3967
3968
3969
3970
3971
3972
3973
3974 void set_addr_mode (cpu_state_t * cpup, addr_modes_e mode)
3975 {
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986 cpu.secret_addressing_mode = false;
3987 if (mode == ABSOLUTE_mode)
3988 {
3989 CPT (cpt1L, 22);
3990 sim_debug (DBG_DEBUG, & cpu_dev, "APU: Setting absolute mode.\n");
3991
3992 SET_I_ABS;
3993 cpu.PPR.P = 1;
3994 }
3995 else if (mode == APPEND_mode)
3996 {
3997 CPT (cpt1L, 23);
3998 if (! TST_I_ABS && TST_I_NBAR)
3999 sim_debug (DBG_DEBUG, & cpu_dev, "APU: Keeping append mode.\n");
4000 else
4001 sim_debug (DBG_DEBUG, & cpu_dev, "APU: Setting append mode.\n");
4002
4003 CLR_I_ABS;
4004 }
4005 else
4006 {
4007 sim_debug (DBG_ERR, & cpu_dev,
4008 "APU: Unable to determine address mode.\n");
4009 sim_warn ("APU: Unable to determine address mode. Can't happen!\n");
4010 }
4011 }
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039 word18 get_BAR_address (cpu_state_t * cpup, word18 addr)
4040 {
4041 if (cpu . BAR.BOUND == 0)
4042
4043 doFault (FAULT_STR, fst_str_oob, "BAR store fault; out of bounds");
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054 if (addr >= (((word18) cpu . BAR.BOUND) << 9))
4055
4056 doFault (FAULT_STR, fst_str_oob, "BAR store fault; out of bounds");
4057
4058 word18 barAddr = (addr + (((word18) cpu . BAR.BASE) << 9)) & 0777777;
4059 return barAddr;
4060 }
4061
4062
4063
4064 static void add_history (cpu_state_t * cpup, uint hset, word36 w0, word36 w1)
4065 {
4066
4067 {
4068 cpu.history [hset] [cpu.history_cyclic[hset]] [0] = w0;
4069 cpu.history [hset] [cpu.history_cyclic[hset]] [1] = w1;
4070 cpu.history_cyclic[hset] = (cpu.history_cyclic[hset] + 1) % N_MODEL_HIST_SIZE;
4071 }
4072 }
4073
4074 void add_history_force (cpu_state_t * cpup, uint hset, word36 w0, word36 w1)
4075 {
4076 cpu.history [hset] [cpu.history_cyclic[hset]] [0] = w0;
4077 cpu.history [hset] [cpu.history_cyclic[hset]] [1] = w1;
4078 cpu.history_cyclic[hset] = (cpu.history_cyclic[hset] + 1) % N_MODEL_HIST_SIZE;
4079 }
4080
4081 void add_dps8m_CU_history (cpu_state_t * cpup)
4082 {
4083 if (cpu.skip_cu_hist)
4084 return;
4085 if (! cpu.MR_cache.emr)
4086 return;
4087 if (! cpu.MR_cache.ihr)
4088 return;
4089 if (cpu.MR_cache.hrxfr && ! cpu.wasXfer)
4090 return;
4091
4092 word36 flags = 0;
4093 word5 proccmd = 0;
4094 word7 flags2 = 0;
4095 word36 w0 = 0, w1 = 0;
4096 w0 |= flags & 0777777000000;
4097 w0 |= IWB_IRODD & MASK18;
4098 w1 |= (cpu.iefpFinalAddress & MASK24) << 12;
4099 w1 |= (proccmd & MASK5) << 7;
4100 w1 |= flags2 & 0176;
4101 add_history (cpup, CU_HIST_REG, w0, w1);
4102 }
4103
4104 #if !defined(QUIET_UNUSED)
4105 void add_dps8m_DU_OU_history (cpu_state_t * cpup, word36 flags, word18 ICT, word9 RS_REG, word9 flags2)
4106 {
4107 word36 w0 = flags, w1 = 0;
4108 w1 |= (ICT & MASK18) << 18;
4109 w1 |= (RS_REG & MASK9) << 9;
4110 w1 |= flags2 & MASK9;
4111 add_history (cpup, DPS8M_DU_OU_HIST_REG, w0, w1);
4112 }
4113
4114 void add_dps8m_APU_history (cpu_state_t * cpup, word15 ESN, word21 flags, word24 RMA, word3 RTRR, word9 flags2)
4115 {
4116 word36 w0 = 0, w1 = 0;
4117 w0 |= (ESN & MASK15) << 21;
4118 w0 |= flags & MASK21;
4119 w1 |= (RMA & MASK24) << 12;
4120 w1 |= (RTRR & MASK3) << 9;
4121 w1 |= flags2 & MASK9;
4122 add_history (cpu.tweaks.l68_mode ? L68_APU_HIST_REG : DPS8M_APU_HIST_REG, w0, w1);
4123 }
4124
4125 void add_dps8m_EAPU_history (word18 ZCA, word18 opcode)
4126 {
4127 word36 w0 = 0;
4128 w0 |= (ZCA & MASK18) << 18;
4129 w0 |= opcode & MASK18;
4130 add_history (DPS8M_EAPU_HIST_REG, w0, 0);
4131
4132
4133
4134
4135 }
4136 #endif
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172 void add_l68_CU_history (cpu_state_t * cpup)
4173 {
4174 CPT (cpt1L, 24);
4175
4176 if (cpu.skip_cu_hist)
4177 return;
4178 if (! cpu.MR_cache.emr)
4179 return;
4180 if (! cpu.MR_cache.ihr)
4181 return;
4182
4183 word36 w0 = 0, w1 = 0;
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193 PNL (putbits36_8 (& w0, 0, cpu.prepare_state);)
4194
4195 putbits36_1 (& w0, 8, cpu.wasXfer);
4196
4197 putbits36_1 (& w0, 9, cpu.cu.xde);
4198
4199 putbits36_1 (& w0, 10, cpu.cu.xdo);
4200
4201 putbits36_1 (& w0, 11, USE_IRODD?1:0);
4202
4203 putbits36_1 (& w0, 12, cpu.cu.rpt);
4204
4205
4206 PNL (putbits36_1 (& w0, 14, cpu.AR_F_E);)
4207
4208 putbits36_1 (& w0, 15, cpu.cycle != INTERRUPT_cycle?1:0);
4209
4210 putbits36_1 (& w0, 16, cpu.cycle != FAULT_cycle?1:0);
4211
4212 putbits36_1 (& w0, 17, TSTF (cpu.cu.IR, I_NBAR)?1:0);
4213
4214 putbits36_18 (& w0, 18, (word18) (IWB_IRODD & MASK18));
4215
4216
4217 putbits36_18 (& w1, 0, cpu.TPR.CA);
4218
4219
4220 PNL (putbits36_1 (& w1, 59-36, (cpu.portSelect == 0)?1:0);)
4221 PNL (putbits36_1 (& w1, 60-36, (cpu.portSelect == 1)?1:0);)
4222 PNL (putbits36_1 (& w1, 61-36, (cpu.portSelect == 2)?1:0);)
4223 PNL (putbits36_1 (& w1, 62-36, (cpu.portSelect == 3)?1:0);)
4224
4225 putbits36_1 (& w1, 63-36, cpu.interrupt_flag?1:0);
4226
4227 PNL (putbits36_1 (& w1, 64-36, cpu.INS_FETCH?1:0);)
4228
4229
4230
4231
4232
4233
4234
4235
4236 add_history (cpup, CU_HIST_REG, w0, w1);
4237
4238
4239 CPTUR (cptUseMR);
4240 if (cpu.MR.hrhlt && cpu.history_cyclic[CU_HIST_REG] == 0)
4241 {
4242
4243 if (cpu.MR.ihrrs)
4244 {
4245 cpu.MR.ihr = 0;
4246 }
4247 set_FFV_fault (cpup, 4);
4248 return;
4249 }
4250 }
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290 void add_l68_DU_history (cpu_state_t * cpup)
4291 {
4292 CPT (cpt1L, 25);
4293 PNL (add_history (cpup, L68_DU_HIST_REG, cpu.du.cycle1, cpu.du.cycle2);)
4294 }
4295
4296 void add_l68_OU_history (cpu_state_t * cpup)
4297 {
4298 CPT (cpt1L, 26);
4299 word36 w0 = 0, w1 = 0;
4300
4301
4302
4303 PNL (putbits36_9 (& w0, 0, cpu.ou.RS);)
4304
4305
4306 putbits36_1 (& w0, 9, cpu.ou.characterOperandSize ? 1 : 0);
4307
4308
4309 putbits36_3 (& w0, 10, cpu.ou.characterOperandOffset);
4310
4311
4312 putbits36_1 (& w0, 13, cpu.ou.crflag);
4313
4314
4315 putbits36_1 (& w0, 14, cpu.ou.directOperandFlag ? 1 : 0);
4316
4317
4318 putbits36_2 (& w0, 15, cpu.ou.eac);
4319
4320
4321
4322 PNL (putbits36_9 (& w0, 18, cpu.ou.RS);)
4323
4324
4325 putbits36_1 (& w0, 27, cpu.ou.RB1_FULL);
4326
4327
4328 putbits36_1 (& w0, 28, cpu.ou.RP_FULL);
4329
4330
4331 putbits36_1 (& w0, 29, cpu.ou.RS_FULL);
4332
4333
4334 putbits36_6 (& w0, 30, (word6) (cpu.ou.cycle >> 3));
4335
4336
4337 putbits36_3 (& w1, 36-36, (word3) cpu.ou.cycle);
4338
4339
4340 putbits36_1 (& w1, 39-36, cpu.ou.STR_OP);
4341
4342
4343
4344
4345 PNL (putbits36_10 (& w1, 41-36,
4346 (word10) ~opcodes10 [cpu.ou.RS].reg_use);)
4347
4348
4349
4350
4351 putbits36_18 (& w1, 54 - 36, cpu.PPR.IC);
4352
4353 add_history (cpup, L68_OU_HIST_REG, w0, w1);
4354 }
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405 void add_l68_APU_history (cpu_state_t * cpup, enum APUH_e op)
4406 {
4407 CPT (cpt1L, 28);
4408 word36 w0 = 0, w1 = 0;
4409
4410 w0 = op;
4411
4412
4413 putbits36_15 (& w0, 0, cpu.TPR.TSR);
4414
4415 PNL (putbits36_1 (& w0, 15, (cpu.apu.state & apu_ESN_SNR) ? 1 : 0);)
4416 PNL (putbits36_1 (& w0, 16, (cpu.apu.state & apu_ESN_TSR) ? 1 : 0);)
4417
4418 putbits36_1 (& w0, 25, cpu.cu.SDWAMM);
4419
4420 putbits36_4 (& w0, 26, (word4) cpu.SDWAMR);
4421
4422 putbits36_1 (& w0, 30, cpu.cu.PTWAMM);
4423
4424 putbits36_4 (& w0, 31, (word4) cpu.PTWAMR);
4425
4426 PNL (putbits36_1 (& w0, 35, (cpu.apu.state & apu_FLT) ? 1 : 0);)
4427
4428
4429 PNL (putbits36_24 (& w1, 0, cpu.APUMemAddr);)
4430
4431 putbits36_3 (& w1, 24, cpu.TPR.TRR);
4432
4433
4434 putbits36_1 (& w1, 34, cpu.SDW0.C);
4435
4436
4437 add_history (cpup, L68_APU_HIST_REG, w0, w1);
4438 }
4439
4440 #if defined(THREADZ) || defined(LOCKLESS)
4441
4442
4443 static const char * get_dbg_verb (uint32 dbits, DEVICE * dptr)
4444 {
4445 static const char * debtab_none = "DEBTAB_ISNULL";
4446 static const char * debtab_nomatch = "DEBTAB_NOMATCH";
4447 const char * some_match = NULL;
4448 int32 offset = 0;
4449
4450 if (dptr->debflags == 0)
4451 return debtab_none;
4452
4453 dbits &= dptr->dctrl;
4454
4455
4456 while ((offset < 32) && dptr->debflags[offset].name)
4457 {
4458 if (dptr->debflags[offset].mask == dbits)
4459 return dptr->debflags[offset].name;
4460 if (dptr->debflags[offset].mask & dbits)
4461 some_match = dptr->debflags[offset].name;
4462 offset ++;
4463 }
4464 return some_match ? some_match : debtab_nomatch;
4465 }
4466
4467 void dps8_sim_debug (uint32 dbits, DEVICE * dptr, unsigned long long cnt, const char* fmt, ...)
4468 {
4469
4470 if (sim_deb && dptr && (dptr->dctrl & dbits))
4471 {
4472 const char * debug_type = get_dbg_verb (dbits, dptr);
4473 char stackbuf[STACKBUFSIZE];
4474 int32 bufsize = sizeof (stackbuf);
4475 char * buf = stackbuf;
4476 va_list arglist;
4477 int32 i, j, len;
4478 struct timespec t;
4479 clock_gettime(CLOCK_REALTIME, &t);
4480
4481 buf [bufsize-1] = '\0';
4482
4483 while (1)
4484 {
4485 va_start (arglist, fmt);
4486 # if defined(NO_vsnprintf)
4487 len = vsprintf (buf, fmt, arglist);
4488 # else
4489 len = vsnprintf (buf, (int)((unsigned long)(bufsize)-1), fmt, arglist);
4490 # endif
4491 va_end (arglist);
4492
4493
4494
4495 if ((len < 0) || (len >= bufsize-1))
4496 {
4497 if (buf != stackbuf)
4498 FREE (buf);
4499 bufsize = bufsize * 2;
4500 if (bufsize < len + 2)
4501 bufsize = len + 2;
4502 buf = (char *) malloc ((unsigned long) bufsize);
4503 if (buf == NULL)
4504 return;
4505 buf[bufsize-1] = '\0';
4506 continue;
4507 }
4508 break;
4509 }
4510
4511
4512
4513 for (i = j = 0; i < len; ++i)
4514 {
4515 if ('\n' == buf[i])
4516 {
4517 if (i >= j)
4518 {
4519 if ((i != j) || (i == 0))
4520 {
4521 (void)fprintf (sim_deb, "%lld.%06ld: DBG(%lld) %o: %s %s %.*s\r\n",
4522 (long long)t.tv_sec, t.tv_nsec/1000, cnt,
4523 current_running_cpu_idx, dptr->name, debug_type, i-j, &buf[j]);
4524 }
4525 }
4526 j = i + 1;
4527 }
4528 }
4529
4530
4531 if (buf != stackbuf)
4532 FREE (buf);
4533 }
4534
4535 }
4536 #endif
4537
4538 void setupPROM (uint cpuNo, unsigned char * PROM) {
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578 word36 rsw2 = 0;
4579
4580
4581
4582
4583
4584
4585
4586 putbits36_4 (& rsw2, 0, 0);
4587
4588 putbits36_2 (& rsw2, 4, 001);
4589
4590 putbits36_7 (& rsw2, 6, 2);
4591
4592 putbits36_1 (& rsw2, 13, 1);
4593
4594 putbits36_5 (& rsw2, 14, 0);
4595
4596 putbits36_1 (& rsw2, 19, 1);
4597
4598 putbits36_1 (& rsw2, 20, cpus[cpuNo].options.cache_installed ? 1 : 0);
4599
4600 putbits36_2 (& rsw2, 21, 0);
4601
4602 putbits36_1 (& rsw2, 23, 1);
4603
4604 putbits36_1 (& rsw2, 24, 0);
4605
4606 putbits36_4 (& rsw2, 25, 0);
4607
4608 putbits36_4 (& rsw2, 29, cpus[cpuNo].options.proc_speed & 017LL);
4609
4610 putbits36_3 (& rsw2, 33, cpus[cpuNo].switches.cpu_num & 07LL);
4611
4612 word4 rsw2Ext = 0;
4613 if (cpus[cpuNo].options.hex_mode_installed)
4614 rsw2Ext |= 010;
4615 if (cpus[cpuNo].options.clock_slave_installed)
4616 rsw2Ext |= 004;
4617
4618
4619 char serial[12];
4620 (void)sprintf (serial, "%-11u", cpus[cpuNo].switches.serno);
4621
4622 #if defined(VER_H_PROM_SHIP)
4623 char * ship = VER_H_PROM_SHIP;
4624 #else
4625 char * ship = "200101";
4626 #endif
4627
4628 #if !defined(VER_H_PROM_MAJOR_VER)
4629 # define VER_H_PROM_MAJOR_VER "999"
4630 #endif
4631
4632 #if !defined(VER_H_PROM_MINOR_VER)
4633 # define VER_H_PROM_MINOR_VER "999"
4634 #endif
4635
4636 #if !defined(VER_H_PROM_PATCH_VER)
4637 # define VER_H_PROM_PATCH_VER "999"
4638 #endif
4639
4640 #if !defined(VER_H_PROM_OTHER_VER)
4641 # define VER_H_PROM_OTHER_VER "999"
4642 #endif
4643
4644 #if !defined(VER_H_GIT_RELT)
4645 # define VER_H_GIT_RELT "X"
4646 #endif
4647
4648 #if !defined(VER_H_PROM_VER_TEXT)
4649 # define VER_H_PROM_VER_TEXT "Unknown "
4650 #endif
4651
4652 #if defined(BUILD_PROM_OSA_TEXT)
4653 # define BURN_PROM_OSA_TEXT BUILD_PROM_OSA_TEXT
4654 #else
4655 # if !defined(VER_H_PROM_OSA_TEXT)
4656 # define BURN_PROM_OSA_TEXT "Unknown Build Op Sys"
4657 # else
4658 # define BURN_PROM_OSA_TEXT VER_H_PROM_OSA_TEXT
4659 # endif
4660 #endif
4661
4662 #if defined(BUILD_PROM_OSV_TEXT)
4663 # define BURN_PROM_OSV_TEXT BUILD_PROM_OSV_TEXT
4664 #else
4665 # if !defined(VER_H_PROM_OSV_TEXT)
4666 # define BURN_PROM_OSV_TEXT "Unknown Build Arch. "
4667 # else
4668 # define BURN_PROM_OSV_TEXT VER_H_PROM_OSV_TEXT
4669 # endif
4670 #endif
4671
4672 #if defined(BUILD_PROM_TSA_TEXT)
4673 # define BURN_PROM_TSA_TEXT BUILD_PROM_TSA_TEXT
4674 #else
4675 # if defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64)
4676 # define VER_H_PROM_TSA_TEXT "Intel x86_64 (AMD64)"
4677 # elif defined(_M_IX86) || defined(__i386) || defined(__i486) || defined(__i586) || defined(__i686) || defined(__ix86)
4678 # define VER_H_PROM_TSA_TEXT "Intel ix86 (32-bit) "
4679 # elif defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64__)
4680 # define VER_H_PROM_TSA_TEXT "AArch64/ARM64/64-bit"
4681 # elif defined(_M_ARM) || defined(__arm__)
4682 # define VER_H_PROM_TSA_TEXT "AArch32/ARM32/32-bit"
4683 # elif defined(__ia64__) || defined(_M_IA64) || defined(__itanium__)
4684 # define VER_H_PROM_TSA_TEXT "Intel Itanium (IA64)"
4685 # elif defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__) || defined(__powerpc64__) || \
4686 defined(__POWERPC64__) || \
4687 defined(_M_PPC64) || \
4688 defined(__PPC64) || \
4689 defined(_ARCH_PPC64)
4690 # define VER_H_PROM_TSA_TEXT "Power ISA (64-bit) "
4691 # elif defined(__ppc__) || defined(__PPC__) || defined(__powerpc__) || defined(__POWERPC__) || defined(_M_PPC) || \
4692 defined(__PPC) || \
4693 defined(__ppc32__) || \
4694 defined(__PPC32__) || \
4695 defined(__powerpc32__) || \
4696 defined(__POWERPC32__) || \
4697 defined(_M_PPC32) || \
4698 defined(__PPC32)
4699 # define VER_H_PROM_TSA_TEXT "PowerPC ISA (32-bit)"
4700 # elif defined(__s390x__)
4701 # define VER_H_PROM_TSA_TEXT "IBM z/Architecture "
4702 # elif defined(__s390__)
4703 # define VER_H_PROM_TSA_TEXT "IBM ESA System/390 "
4704 # elif defined(__J2__) || defined(__J2P__) || defined(__j2__) || defined(__j2p__)
4705 # define VER_H_PROM_TSA_TEXT "J-Core J2 Open CPU "
4706 # elif defined(__SH4__) || defined(__sh4__) || defined(__SH4) || defined(__sh4)
4707 # define VER_H_PROM_TSA_TEXT "Hitachi/Renesas SH-4"
4708 # elif defined(__SH2__) || defined(__sh2__) || defined(__SH2) || defined(__sh2)
4709 # define VER_H_PROM_TSA_TEXT "Hitachi/Renesas SH-2"
4710 # elif defined(__alpha__)
4711 # define VER_H_PROM_TSA_TEXT "Alpha AXP "
4712 # elif defined(__hppa__) || defined(__HPPA__) || defined(__PARISC__) || defined(__parisc__)
4713 # define VER_H_PROM_TSA_TEXT "HP PA-RISC "
4714 # elif defined(__ICE9__) || defined(__ice9__) || defined(__ICE9) || defined(__ice9)
4715 # define VER_H_PROM_TSA_TEXT "SiCortex ICE-9 "
4716 # elif defined(mips64) || defined(__mips64__) || defined(MIPS64) || defined(_MIPS64_) || defined(__mips64)
4717 # define VER_H_PROM_TSA_TEXT "MIPS64 "
4718 # elif defined(mips) || defined(__mips__) || defined(MIPS) || defined(_MIPS_) || defined(__mips)
4719 # define VER_H_PROM_TSA_TEXT "MIPS "
4720 # elif defined(__OpenRISC__) || defined(__OPENRISC__) || defined(__openrisc__) || defined(__OR1K__) || defined(__OPENRISC1K__)
4721 # define VER_H_PROM_TSA_TEXT "OpenRISC "
4722 # elif defined(__sparc64) || defined(__SPARC64) || defined(__SPARC64__) || defined(__sparc64__)
4723 # define VER_H_PROM_TSA_TEXT "SPARC64 "
4724 # elif defined(__sparc) || defined(__SPARC) || defined(__SPARC__) || defined(__sparc__)
4725 # define VER_H_PROM_TSA_TEXT "SPARC "
4726 # elif defined(__riscv) || defined(__riscv__)
4727 # define VER_H_PROM_TSA_TEXT "RISC-V "
4728 # elif defined(__myriad2__)
4729 # define VER_H_PROM_TSA_TEXT "Myriad2 "
4730 # elif defined(__loongarch64) || defined(__loongarch__)
4731 # define VER_H_PROM_TSA_TEXT "LoongArch "
4732 # elif defined(_m68851) || defined(__m68k__) || defined(__m68000__) || defined(__M68K)
4733 # define VER_H_PROM_TSA_TEXT "Motorola m68k "
4734 # elif defined(__m88k__) || defined(__m88000__) || defined(__M88K)
4735 # define VER_H_PROM_TSA_TEXT "Motorola m88k "
4736 # elif defined(__VAX__) || defined(__vax__)
4737 # define VER_H_PROM_TSA_TEXT "VAX "
4738 # elif defined(__NIOS2__) || defined(__nios2__)
4739 # define VER_H_PROM_TSA_TEXT "Altera Nios II "
4740 # elif defined(__MICROBLAZE__) || defined(__microblaze__)
4741 # define VER_H_PROM_TSA_TEXT "Xilinx MicroBlaze "
4742 # endif
4743 # if !defined(VER_H_PROM_TSA_TEXT)
4744 # define BURN_PROM_TSA_TEXT "Unknown Target Arch."
4745 # else
4746 # define BURN_PROM_TSA_TEXT VER_H_PROM_TSA_TEXT
4747 # endif
4748 #endif
4749
4750 #if (defined(__WIN__) || defined(_WIN32) || defined(IS_WINDOWS) || defined(_MSC_VER) || defined(__MINGW32__) || \
4751 defined(__MINGW64__) || defined(CROSS_MINGW32) || defined(CROSS_MINGW64)) && !defined(__CYGWIN__)
4752 # define DC_IS_WINDOWS 1
4753 #else
4754 # define DC_IS_WINDOWS 0
4755 #endif
4756
4757 #if defined(BUILD_PROM_TSV_TEXT)
4758 # define BURN_PROM_TSV_TEXT BUILD_PROM_TSV_TEXT
4759 #else
4760 # if DC_IS_WINDOWS
4761 # define VER_H_PROM_TSV_TEXT "Microsoft Windows "
4762 # elif defined(__CYGWIN__)
4763 # define VER_H_PROM_TSV_TEXT "Windows/Cygwin "
4764 # elif (defined(__sunos) || defined(__sun) || defined(__sun__)) && (defined(SYSV) || defined(__SVR4) || defined(__SVR4__) || \
4765 defined(__svr4__))
4766 # if defined(__illumos__)
4767 # define VER_H_PROM_TSV_TEXT "illumos "
4768 # else
4769 # define VER_H_PROM_TSV_TEXT "Solaris "
4770 # endif
4771 # elif defined(__APPLE__) && defined(__MACH__)
4772 # define VER_H_PROM_TSV_TEXT "Apple macOS "
4773 # elif defined(__GNU__) && !defined(__linux__)
4774 # define VER_H_PROM_TSV_TEXT "GNU/Hurd "
4775 # elif defined(__ANDROID__) && defined(__ANDROID_API__)
4776 # if defined(__linux__)
4777 # define VER_H_PROM_TSV_TEXT "Android/Linux "
4778 # else
4779 # define VER_H_PROM_TSV_TEXT "Android "
4780 # endif
4781 # elif defined(__lynxOS__) || defined(__LYNXOS__) || defined(LynxOS) || defined(LYNXOS)
4782 # define VER_H_PROM_TSV_TEXT "LynxOS "
4783 # elif defined(__HELENOS__)
4784 # define VER_H_PROM_TSV_TEXT "HelenOS "
4785 # elif defined(__linux__)
4786 # if defined(__BIONIC__)
4787 # define VER_H_PROM_TSV_TEXT "Linux/Bionic-libc "
4788 # elif defined(__UCLIBC__) || defined(UCLIBC)
4789 # define VER_H_PROM_TSV_TEXT "Linux/uClibc "
4790 # elif defined(__NEWLIB__)
4791 # define VER_H_PROM_TSV_TEXT "Linux/Newlib "
4792 # elif defined(__dietlibc__)
4793 # define VER_H_PROM_TSV_TEXT "Linux/Diet-libc "
4794 # elif defined(__GLIBC__)
4795 # define VER_H_PROM_TSV_TEXT "GNU/Linux "
4796 # else
4797 # define VER_H_PROM_TSV_TEXT "Linux "
4798 # endif
4799 # elif defined(__HAIKU__)
4800 # define VER_H_PROM_TSV_TEXT "Haiku "
4801 # elif defined(__serenity__)
4802 # define VER_H_PROM_TSV_TEXT "SerenityOS "
4803 # elif defined(__FreeBSD__)
4804 # define VER_H_PROM_TSV_TEXT "FreeBSD "
4805 # elif defined(__NetBSD__)
4806 # define VER_H_PROM_TSV_TEXT "NetBSD "
4807 # elif defined(__OpenBSD__)
4808 # define VER_H_PROM_TSV_TEXT "OpenBSD "
4809 # elif defined(__DragonFly__)
4810 # define VER_H_PROM_TSV_TEXT "DragonFly BSD "
4811 # elif defined(_AIX)
4812 # if !defined(__PASE__)
4813 # define VER_H_PROM_TSV_TEXT "IBM AIX "
4814 # else
4815 # define VER_H_PROM_TSV_TEXT "IBM OS/400 (PASE) "
4816 # endif
4817 # elif defined(__VXWORKS__) || defined(__VXWORKS) || defined(__vxworks) || defined(__vxworks__) || defined(_VxWorks)
4818 # if !defined(__RTP__)
4819 # define VER_H_PROM_TSV_TEXT "VxWorks "
4820 # else
4821 # define VER_H_PROM_TSV_TEXT "VxWorks RTP "
4822 # endif
4823 # elif defined(__rtems__)
4824 # if defined(__FreeBSD_version)
4825 # define VER_H_PROM_TSV_TEXT "RTEMS/LibBSD "
4826 # else
4827 # define VER_H_PROM_TSV_TEXT "RTEMS "
4828 # endif
4829 # elif defined(__ZEPHYR__)
4830 # define VER_H_PROM_TSV_TEXT "Zephyr "
4831 # elif defined(ti_sysbios_BIOS___VERS) || defined(ti_sysbios_BIOS__top__)
4832 # define VER_H_PROM_TSV_TEXT "TI-RTOS (SYS/BIOS) "
4833 # elif defined(__OSV__)
4834 # define VER_H_PROM_TSV_TEXT "OSv "
4835 # elif defined(MINIX) || defined(MINIX3) || defined(MINIX315) || defined(__minix__) || defined(__minix3__) || defined(__minix315__)
4836 # define VER_H_PROM_TSV_TEXT "Minix "
4837 # elif defined(__QNX__)
4838 # if defined(__QNXNTO__)
4839 # define VER_H_PROM_TSV_TEXT "QNX Neutrino "
4840 # else
4841 # define VER_H_PROM_TSV_TEXT "QNX "
4842 # endif
4843 # endif
4844 # if !defined(VER_H_PROM_TSV_TEXT)
4845 # define BURN_PROM_TSV_TEXT "Unknown Target OpSys"
4846 # else
4847 # define BURN_PROM_TSV_TEXT VER_H_PROM_TSV_TEXT
4848 # endif
4849 #endif
4850
4851 #if !defined(VER_H_GIT_DATE_SHORT)
4852 # define VER_H_GIT_DATE_SHORT "2021-01-01"
4853 #endif
4854
4855 #if !defined(BURN_PROM_BUILD_NUM)
4856 # define BURN_PROM_BUILD_NUM " "
4857 #endif
4858
4859 #define BURN(offset, length, string) memcpy ((char *) PROM + (offset), string, length)
4860 #define BURN1(offset, byte) PROM[offset] = (char) (byte)
4861
4862 (void)memset (PROM, 255, 1024);
4863
4864
4865 BURN ( 00, 11, "DPS 8/SIM M");
4866 BURN (013, 11, serial);
4867 BURN (026, 6, ship);
4868 BURN1 (034, getbits36_8 (rsw2, 0));
4869 BURN1 (035, getbits36_8 (rsw2, 8));
4870 BURN1 (036, getbits36_8 (rsw2, 16));
4871 BURN1 (037, getbits36_8 (rsw2, 24));
4872 BURN1 (040, ((getbits36_4 (rsw2, 32) << 4) \
4873 | rsw2Ext));
4874
4875
4876 BURN ( 60, 1, "2");
4877 BURN ( 70, 10, VER_H_GIT_DATE_SHORT);
4878 BURN ( 80, 3, VER_H_PROM_MAJOR_VER);
4879 BURN ( 83, 3, VER_H_PROM_MINOR_VER);
4880 BURN ( 86, 3, VER_H_PROM_PATCH_VER);
4881 BURN ( 89, 3, VER_H_PROM_OTHER_VER);
4882 BURN ( 92, 8, BURN_PROM_BUILD_NUM);
4883 BURN (100, 1, VER_H_GIT_RELT);
4884 BURN (101, 29, VER_H_PROM_VER_TEXT);
4885 BURN (130, 20, BURN_PROM_OSA_TEXT);
4886 BURN (150, 20, BURN_PROM_OSV_TEXT);
4887 BURN (170, 20, BURN_PROM_TSA_TEXT);
4888 BURN (190, 20, BURN_PROM_TSV_TEXT);
4889 }
4890
4891 void cpuStats (uint cpuNo) {
4892 if (! cpus[cpuNo].cycleCnt)
4893 return;
4894
4895 (void)fflush(stderr);
4896 (void)fflush(stdout);
4897 sim_msg ("\r\n");
4898 (void)fflush(stdout);
4899 (void)fflush(stderr);
4900 sim_msg ("\r+---------------------------------+\r\n");
4901 sim_msg ("\r| CPU %c Statistics |\r\n", 'A' + cpuNo);
4902 sim_msg ("\r+---------------------------------+\r\n");
4903 (void)fflush(stdout);
4904 (void)fflush(stderr);
4905 #if defined(WIN_STDIO)
4906 sim_msg ("\r| cycles %15llu |\r\n", (unsigned long long)cpus[cpuNo].cycleCnt);
4907 sim_msg ("\r| instructions %15llu |\r\n", (unsigned long long)cpus[cpuNo].instrCnt);
4908 (void)fflush(stdout);
4909 (void)fflush(stderr);
4910 sim_msg ("\r+---------------------------------+\r\n");
4911 sim_msg ("\r| lockCnt %15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockCnt);
4912 sim_msg ("\r| lockImmediate %15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockImmediate);
4913 (void)fflush(stdout);
4914 (void)fflush(stderr);
4915 sim_msg ("\r+---------------------------------+\r\n");
4916 sim_msg ("\r| lockWait %15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockWait);
4917 sim_msg ("\r| lockWaitMax %15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockWaitMax);
4918 (void)fflush(stdout);
4919 (void)fflush(stderr);
4920 # if !defined(SCHED_NEVER_YIELD)
4921 sim_msg ("\r| lockYield %15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockYield);
4922 (void)fflush(stdout);
4923 (void)fflush(stderr);
4924 # else
4925 sim_msg ("\r| lockYield ---- |\r\n");
4926 (void)fflush(stdout);
4927 (void)fflush(stderr);
4928 # endif
4929 sim_msg ("\r+---------------------------------+");
4930 (void)fflush(stdout);
4931 (void)fflush(stderr);
4932 # if !defined(UCACHE)
4933 # if !defined(UCACHE_STATS)
4934 sim_msg ("\r\n");
4935 # endif
4936 # endif
4937 (void)fflush(stdout);
4938 (void)fflush(stderr);
4939 #else
4940 sim_msg ("\r| cycles %'15llu |\r\n", (unsigned long long)cpus[cpuNo].cycleCnt);
4941 sim_msg ("\r| instructions %'15llu |\r\n", (unsigned long long)cpus[cpuNo].instrCnt);
4942 (void)fflush(stdout);
4943 (void)fflush(stderr);
4944 sim_msg ("\r+---------------------------------+\r\n");
4945 sim_msg ("\r| lockCnt %'15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockCnt);
4946 sim_msg ("\r| lockImmediate %'15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockImmediate);
4947 (void)fflush(stdout);
4948 (void)fflush(stderr);
4949 sim_msg ("\r+---------------------------------+\r\n");
4950 sim_msg ("\r| lockWait %'15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockWait);
4951 sim_msg ("\r| lockWaitMax %'15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockWaitMax);
4952 (void)fflush(stdout);
4953 (void)fflush(stderr);
4954 # if !defined(SCHED_NEVER_YIELD)
4955 sim_msg ("\r| lockYield %'15llu |\r\n", (unsigned long long)cpus[cpuNo].coreLockState.lockYield);
4956 (void)fflush(stdout);
4957 (void)fflush(stderr);
4958 # else
4959 sim_msg ("\r| lockYield ---- |\r\n");
4960 (void)fflush(stdout);
4961 (void)fflush(stderr);
4962 # endif
4963 sim_msg ("\r+---------------------------------+");
4964 (void)fflush(stdout);
4965 (void)fflush(stderr);
4966 # if !defined(UCACHE)
4967 # if !defined(UCACHE_STATS)
4968 sim_msg ("\r\n");
4969 # endif
4970 # endif
4971 (void)fflush(stderr);
4972 (void)fflush(stdout);
4973 #endif
4974
4975 #if defined(UCACHE_STATS)
4976 ucacheStats (cpuNo);
4977 #endif
4978
4979
4980
4981
4982
4983
4984
4985 }
4986
4987 #if defined(THREADZ) || defined(LOCKLESS)
4988 # include <locale.h>
4989 # include "segldr.h"
4990
4991 void perfTest (char * testName) {
4992 if (testName == NULL)
4993 testName = "strip.mem";
4994
4995 (void) setlocale(LC_NUMERIC, "");
4996
4997
4998 system_state = malloc (sizeof (struct system_state_s));
4999 if (!system_state)
5000 {
5001 (void)fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
5002 __func__, __FILE__, __LINE__);
5003 # if defined(USE_BACKTRACE)
5004 # if defined(SIGUSR2)
5005 (void)raise(SIGUSR2);
5006
5007 # endif
5008 # endif
5009 abort();
5010 }
5011 M = system_state->M;
5012 # if defined(M_SHARED)
5013 cpus = system_state->cpus;
5014 # endif
5015 (void) memset (cpus, 0, sizeof (cpu_state_t) * N_CPU_UNITS_MAX);
5016 for (int i = 0; i < N_CPU_UNITS_MAX; i ++) {
5017 cpus[i].switches.FLT_BASE = 2;
5018 cpus[i].instrCnt = 0;
5019 cpus[i].cycleCnt = 0;
5020 for (int j = 0; j < N_FAULTS; j ++)
5021 cpus[i].faultCnt [j] = 0;
5022 }
5023
5024 cpus[0].tweaks.enable_emcall = 1;
5025 opc_dev.numunits = 1;
5026 cpu_reset_unit_idx (0, false);
5027 set_cpu_cycle (& cpus[0], FETCH_cycle);
5028 mrestore (testName);
5029 _cpup = & cpus[0];
5030 threadz_sim_instr ();
5031 }
5032 #endif
5033