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