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