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