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