This source file includes following definitions.
- createBuffer
- hdbg_inc
- hdbgTrace
- hdbgMRead
- hdbgMWrite
- hdbgAPURead
- hdbgAPUWrite
- hdbgFault
- hdbgIntrSet
- hdbgIntr
- hdbgRegR
- hdbgRegW
- hdbgPARegR
- hdbgPARegW
- hdbgIEFP
- hdbgNote
- printM
- printAPU
- printTrace
- printFault
- printIntrSet
- printIntr
- printReg
- printPAReg
- printDSBRReg
- printIEFP
- printNote
- hdbgPrint
- hdbg_cpu_mask
- hdbg_size
- hdbgSegmentNumber
- hdbgBlacklist
- hdbg_print
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #if defined(TESTING)
20
21 # include <unistd.h>
22 # include <sys/types.h>
23 # include <sys/stat.h>
24 # include <fcntl.h>
25
26 # include "dps8.h"
27 # include "dps8_sys.h"
28 # include "dps8_cpu.h"
29 # include "dps8_utils.h"
30 # include "hdbg.h"
31
32 # include "dps8_faults.h"
33
34 # if defined(FREE)
35 # undef FREE
36 # endif
37 # define FREE(p) do \
38 { \
39 free((p)); \
40 (p) = NULL; \
41 } while(0)
42
43 enum hevtType {
44 hevtEmpty = 0,
45 hevtTrace,
46 hevtM,
47 hevtAPU,
48 hevtFault,
49 hevtIntrSet,
50 hevtIntr,
51 hevtReg,
52 hevtPAReg,
53 hevtDSBRReg,
54 hevtIEFP,
55 hevtNote,
56 };
57
58 struct hevt {
59 enum hevtType type;
60 uint64 time;
61 uint cpu_idx;
62 char ctx[16];
63 bool rw;
64 union {
65 struct {
66 addr_modes_e addrMode;
67 word15 segno;
68 word18 ic;
69 word3 ring;
70 word36 inst;
71 } trace;
72
73 struct {
74 word24 addr;
75 word36 data;
76 } memref;
77
78 struct {
79 _fault faultNumber;
80 _fault_subtype subFault;
81 char faultMsg [64];
82 } fault;
83
84 struct {
85 uint inum;
86 uint cpuUnitIdx;
87 uint scuUnitIdx;
88 } intrSet;
89
90 struct {
91 uint intr_pair_addr;
92 } intr;
93
94 struct {
95 enum hregs_t type;
96 word36 data;
97 } reg;
98
99 struct {
100 enum hregs_t type;
101 struct par_s data;
102 } par;
103
104 struct {
105 enum hdbgIEFP_e type;
106 word15 segno;
107 word18 offset;
108 } iefp;
109
110 struct {
111 enum hregs_t type;
112 struct dsbr_s data;
113 } dsbr;
114
115 struct {
116 enum hregs_t type;
117 word15 segno;
118 word18 offset;
119 word24 final;
120 word36 data;
121 } apu;
122 struct {
123 # define NOTE_SZ 64
124 char noteBody [NOTE_SZ];
125 } note;
126 };
127 };
128
129 static struct hevt * hevents = NULL;
130 static long hdbgSize = 0;
131 static long hevtPtr = 0;
132 static long hevtMark = 0;
133 static long hdbgSegNum = -1;
134 static bool blacklist[MAX18];
135 static long hdbgCPUMask = 0;
136
137 static void createBuffer (void) {
138 if (hevents) {
139 FREE (hevents);
140 hevents = NULL;
141 }
142 if (hdbgSize <= 0)
143 return;
144 hevents = malloc (sizeof (struct hevt) * hdbgSize);
145 if (! hevents) {
146 sim_printf ("hdbg createBuffer failed\n");
147 return;
148 }
149 (void)memset (hevents, 0, sizeof (struct hevt) * hdbgSize);
150
151 hevtPtr = 0;
152 }
153
154 static long hdbg_inc (void) {
155
156 long ret = __sync_fetch_and_add (& hevtPtr, 1l) % hdbgSize;
157
158 if (hevtMark > 0) {
159 long ret = __sync_fetch_and_sub (& hevtMark, 1l);
160 if (ret <= 0)
161 hdbgPrint ();
162 }
163 return ret;
164 }
165
166 # define hev(t, tf, filter) \
167 if (! hevents) \
168 goto done; \
169 if (filter && hdbgSegNum >= 0 && hdbgSegNum != cpu.PPR.PSR) \
170 goto done; \
171 if (filter && hdbgSegNum > 0 && blacklist[cpu.PPR.IC]) \
172 goto done; \
173 if (hdbgCPUMask && (hdbgCPUMask & (1 << current_running_cpu_idx))) \
174 goto done; \
175 unsigned long p = hdbg_inc (); \
176 hevents[p].type = t; \
177 hevents[p].cpu_idx = current_running_cpu_idx; \
178 hevents[p].time = cpu.cycleCnt; \
179 strncpy (hevents[p].ctx, ctx, 15); \
180 hevents[p].ctx[15] = 0; \
181 hevents[p].rw = tf;
182
183 # define FILTER true
184 # define NO_FILTER false
185
186 # define WR true
187 # define RD false
188
189 void hdbgTrace (const char * ctx) {
190 cpu_state_t * cpup = _cpup;
191 hev (hevtTrace, RD, FILTER);
192 hevents[p].trace.addrMode = get_addr_mode (cpup);
193 hevents[p].trace.segno = cpu.PPR.PSR;
194 hevents[p].trace.ic = cpu.PPR.IC;
195 hevents[p].trace.ring = cpu.PPR.PRR;
196 hevents[p].trace.inst = IWB_IRODD;
197 done: ;
198 }
199
200 void hdbgMRead (word24 addr, word36 data, const char * ctx) {
201 cpu_state_t * cpup = _cpup;
202 hev (hevtM, RD, FILTER);
203 hevents[p].memref.addr = addr;
204 hevents[p].memref.data = data;
205 done: ;
206 }
207
208 void hdbgMWrite (word24 addr, word36 data, const char * ctx) {
209 cpu_state_t * cpup = _cpup;
210 hev (hevtM, WR, FILTER);
211 hevents[p].memref.addr = addr;
212 hevents[p].memref.data = data;
213 done: ;
214 }
215
216 void hdbgAPURead (word15 segno, word18 offset, word24 final, word36 data, const char * ctx) {
217 cpu_state_t * cpup = _cpup;
218 hev (hevtAPU, RD, FILTER);
219 hevents[p].apu.segno = segno;
220 hevents[p].apu.offset = offset;
221 hevents[p].apu.final = final;
222 hevents[p].apu.data = data;
223 done: ;
224 }
225
226 void hdbgAPUWrite (word15 segno, word18 offset, word24 final, word36 data, const char * ctx) {
227 cpu_state_t * cpup = _cpup;
228 hev (hevtAPU, WR, FILTER);
229 hevents[p].apu.segno = segno;
230 hevents[p].apu.offset = offset;
231 hevents[p].apu.final = final;
232 hevents[p].apu.data = data;
233 done: ;
234 }
235
236 void hdbgFault (_fault faultNumber, _fault_subtype subFault, const char * faultMsg, const char * ctx) {
237 cpu_state_t * cpup = _cpup;
238 hev (hevtFault, RD, FILTER);
239 hevents[p].fault.faultNumber = faultNumber;
240 hevents[p].fault.subFault = subFault;
241 strncpy (hevents[p].fault.faultMsg, faultMsg, 63);
242 hevents[p].fault.faultMsg[63] = 0;
243 done: ;
244 }
245
246 void hdbgIntrSet (uint inum, uint cpuUnitIdx, uint scuUnitIdx, const char * ctx) {
247 cpu_state_t * cpup = _cpup;
248 hev (hevtIntrSet, RD, FILTER);
249 hevents[p].intrSet.inum = inum;
250 hevents[p].intrSet.cpuUnitIdx = cpuUnitIdx;
251 hevents[p].intrSet.scuUnitIdx = scuUnitIdx;
252 done: ;
253 }
254
255 void hdbgIntr (uint intr_pair_addr, const char * ctx) {
256 cpu_state_t * cpup = _cpup;
257 hev (hevtIntr, RD, FILTER);
258 hevents[p].cpu_idx = current_running_cpu_idx;
259 hevents[p].time = cpu.cycleCnt;
260 strncpy (hevents[p].ctx, ctx, 15);
261 hevents[p].ctx[15] = 0;
262 hevents[p].intr.intr_pair_addr = intr_pair_addr;
263 done: ;
264 }
265
266 void hdbgRegR (enum hregs_t type, word36 data, const char * ctx) {
267 cpu_state_t * cpup = _cpup;
268 hev (hevtReg, RD, FILTER);
269 hevents[p].reg.type = type;
270 hevents[p].reg.data = data;
271 done: ;
272 }
273
274 void hdbgRegW (enum hregs_t type, word36 data, const char * ctx) {
275 cpu_state_t * cpup = _cpup;
276 hev (hevtReg, WR, FILTER);
277 hevents[p].reg.type = type;
278 hevents[p].reg.data = data;
279 done: ;
280 }
281
282 void hdbgPARegR (enum hregs_t type, struct par_s * data, const char * ctx) {
283 cpu_state_t * cpup = _cpup;
284 hev (hevtPAReg, RD, FILTER);
285 hevents[p].par.type = type;
286 hevents[p].par.data = * data;
287 done: ;
288 }
289
290 void hdbgPARegW (enum hregs_t type, struct par_s * data, const char * ctx) {
291 cpu_state_t * cpup = _cpup;
292 hev (hevtPAReg, WR, FILTER);
293 hevents[p].par.type = type;
294 hevents[p].par.data = * data;
295 done: ;
296 }
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314 void hdbgIEFP (enum hdbgIEFP_e type, word15 segno, word18 offset, const char * ctx) {
315 cpu_state_t * cpup = _cpup;
316 hev (hevtIEFP, RD, FILTER);
317 hevents [p].iefp.type = type;
318 hevents [p].iefp.segno = segno;
319 hevents [p].iefp.offset = offset;
320 done: ;
321 }
322
323 void hdbgNote (const char * ctx, const char * fmt, ...) {
324 cpu_state_t * cpup = _cpup;
325 hev (hevtNote, RD, NO_FILTER);
326 va_list arglist;
327 va_start (arglist, fmt);
328 (void)vsnprintf (hevents [p].note.noteBody, NOTE_SZ - 1, fmt, arglist);
329 va_end (arglist);
330 done: ;
331 }
332
333 static FILE * hdbgOut = NULL;
334
335 static void printM (struct hevt * p) {
336 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d FINAL: %s %s %08o %012llo\n",
337 (unsigned long long int)p->time,
338 p->cpu_idx,
339 p->ctx,
340 p->rw ? "write" : "read ",
341 p->memref.addr,
342 (unsigned long long int)p->memref.data);
343 }
344
345 static void printAPU (struct hevt * p) {
346 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d APU: %s %s %05o:%06o %08o %012llo\n",
347 (unsigned long long int)p->time,
348 p->cpu_idx,
349 p->ctx,
350 p->rw ? "write" : "read ",
351 p->apu.segno,
352 p->apu.offset,
353 p->apu.final,
354 (unsigned long long int)p->apu.data);
355 }
356
357 static void printTrace (struct hevt * p) {
358 char buf[256];
359 if (p -> trace.addrMode == ABSOLUTE_mode) {
360 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d TRACE: %s %06o %o %012llo (%s)\n",
361 (unsigned long long int)p->time,
362 p->cpu_idx,
363 p->ctx,
364 p->trace.ic,
365 p->trace.ring,
366 (unsigned long long int)p->trace.inst,
367 disassemble (buf, p->trace.inst));
368 } else {
369 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d TRACE: %s %05o:%06o %o %012llo (%s)\n",
370 (unsigned long long int)p->time,
371 p->cpu_idx,
372 p->ctx,
373 p->trace.segno,
374 p->trace.ic,
375 p->trace.ring,
376 (unsigned long long int)p->trace.inst,
377 disassemble (buf, p->trace.inst));
378 }
379 }
380
381 static void printFault (struct hevt * p) {
382 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d FAULT: %s Fault %d(0%o), sub %llu(0%llo), '%s'\n",
383 (unsigned long long int)p->time,
384 p->cpu_idx,
385 p->ctx,
386 p->fault.faultNumber,
387 p->fault.faultNumber,
388 (unsigned long long int)p->fault.subFault.bits,
389 (unsigned long long int)p->fault.subFault.bits,
390 p->fault.faultMsg);
391 }
392
393 static void printIntrSet (struct hevt * p) {
394 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d INTR_SET: %s number %d(0%o), CPU %u SCU %u\n",
395 (unsigned long long int)p->time,
396 p->cpu_idx,
397 p->ctx,
398 p->intrSet.inum,
399 p->intrSet.inum,
400 p->intrSet.cpuUnitIdx,
401 p->intrSet.scuUnitIdx);
402 }
403
404 static void printIntr (struct hevt * p) {
405 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d INTR: %s Interrupt pair address %o\n",
406 (unsigned long long int)p->time,
407 p->cpu_idx,
408 p->ctx,
409 p->intr.intr_pair_addr);
410 }
411
412
413 static char * regNames[] = {
414 "A ",
415 "Q ",
416 "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7",
417 "AR0", "AR1", "AR2", "AR3", "AR4", "AR5", "AR6", "AR7",
418 "PR0", "PR1", "PR2", "PR3", "PR4", "PR5", "PR6", "PR7",
419 "Y ", "Z ",
420 "IR ",
421 "DSBR",
422 };
423
424 static void printReg (struct hevt * p) {
425 if (p->reg.type == hreg_IR)
426 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %012llo Z%o N%o C %o O%o T%o \n",
427 (unsigned long long int)p->time,
428 p->cpu_idx,
429 p->ctx,
430 p->rw ? "write" : "read ",
431 regNames[p->reg.type],
432 (unsigned long long int)p->reg.data,
433 TSTF (p->reg.data, I_ZERO),
434 TSTF (p->reg.data, I_NEG),
435 TSTF (p->reg.data, I_CARRY),
436 TSTF (p->reg.data, I_OFLOW),
437 TSTF (p->reg.data, I_TALLY));
438 else if (p->reg.type >= hreg_X0 && p->reg.type <= hreg_X7)
439 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %06llo\n",
440 (unsigned long long int)p->time,
441 p->cpu_idx,
442 p->ctx,
443 p->rw ? "write" : "read ",
444 regNames[p->reg.type],
445 (unsigned long long int)p->reg.data);
446 else
447 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %012llo\n",
448 (unsigned long long int)p->time,
449 p->cpu_idx,
450 p->ctx,
451 p->rw ? "write" : "read ",
452 regNames[p->reg.type],
453 (unsigned long long int)p->reg.data);
454 }
455
456 static void printPAReg (struct hevt * p)
457 {
458 if (p->reg.type >= hreg_PR0 && p->reg.type <= hreg_PR7)
459 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %05o:%06o BIT %2o RNR %o\n",
460 (unsigned long long int)p->time,
461 p->cpu_idx,
462 p->ctx,
463 p->rw ? "write" : "read ",
464 regNames[p->reg.type],
465 p->par.data.SNR,
466 p->par.data.WORDNO,
467 p->par.data.PR_BITNO,
468 p->par.data.RNR);
469 else
470 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s write %s %05o:%06o CHAR %o BIT %2o RNR %o\n",
471 (unsigned long long int)p->time,
472 p->cpu_idx,
473 p->ctx,
474 regNames[p->reg.type],
475 p->par.data.SNR,
476 p->par.data.WORDNO,
477 p->par.data.AR_CHAR,
478 p->par.data.AR_BITNO,
479 p->par.data.RNR);
480 }
481
482 static void printDSBRReg (struct hevt * p) {
483 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %05o:%06o BIT %2o RNR %o\n",
484 (unsigned long long int)p->time,
485 p->cpu_idx,
486 p->ctx,
487 p->rw ? "write" : "read ",
488 regNames[p->reg.type],
489 p->par.data.SNR,
490 p->par.data.WORDNO,
491 p->par.data.PR_BITNO,
492 p->par.data.RNR);
493 }
494
495 static void printIEFP (struct hevt * p) {
496 switch (p->iefp.type) {
497 case hdbgIEFP_abs_bar_read:
498 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS BAR READ: |%06o\n",
499 (unsigned long long int)p->time,
500 p->cpu_idx,
501 p->iefp.offset);
502 break;
503
504 case hdbgIEFP_abs_read:
505 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS READ: :%06o\n",
506 (unsigned long long int)p->time,
507 p->cpu_idx,
508 p->iefp.offset);
509 break;
510
511 case hdbgIEFP_bar_read:
512 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP BAR READ: %05o|%06o\n",
513 (unsigned long long int)p->time,
514 p->cpu_idx,
515 p->iefp.segno,
516 p->iefp.offset);
517 break;
518
519 case hdbgIEFP_read:
520 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP READ: %05o:%06o\n",
521 (unsigned long long int)p->time,
522 p->cpu_idx,
523 p->iefp.segno,
524 p->iefp.offset);
525 break;
526
527 case hdbgIEFP_abs_bar_write:
528 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS BAR WRITE: |%06o\n",
529 (long long unsigned int)p->time,
530 p->cpu_idx,
531 p->iefp.offset);
532 break;
533
534 case hdbgIEFP_abs_write:
535 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS WRITE: :%06o\n",
536 (long long unsigned int)p->time,
537 p->cpu_idx,
538 p->iefp.offset);
539 break;
540
541 case hdbgIEFP_bar_write:
542 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP BAR WRITE: %05o|%06o\n",
543 (unsigned long long int)p->time,
544 p->cpu_idx,
545 p->iefp.segno,
546 p->iefp.offset);
547 break;
548
549 case hdbgIEFP_write:
550 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP WRITE: %05o:%06o\n",
551 (unsigned long long int)p->time,
552 p->cpu_idx,
553 p->iefp.segno,
554 p->iefp.offset);
555 break;
556
557 default:
558 (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ??? ??? WRITE: %05o?%06o\n",
559 (long long unsigned int)p->time,
560 p->cpu_idx,
561 p->iefp.segno,
562 p->iefp.offset);
563 break;
564 }
565 }
566
567 static void printNote (struct hevt * p) {
568 (void)fprintf (hdbgOut, "DBG(%llu)> Note: %s\n",
569 (long long unsigned int)p->time,
570 p->note.noteBody);
571 }
572
573 void hdbgPrint (void) {
574 sim_printf ("hdbg print\n");
575 if (! hevents)
576 goto done;
577 struct hevt * t = hevents;
578 hevents = NULL;
579 hdbgOut = fopen ("hdbg.list", "w");
580 if (! hdbgOut) {
581 sim_printf ("can't open hdbg.list\n");
582 goto done;
583 }
584 time_t curtime;
585 time (& curtime);
586 (void)fprintf (hdbgOut, "%s\n", ctime (& curtime));
587
588 for (unsigned long p = 0; p < hdbgSize; p ++) {
589 unsigned long q = (hevtPtr + p) % hdbgSize;
590 struct hevt * evtp = t + q;
591 switch (evtp -> type) {
592 case hevtEmpty:
593 break;
594
595 case hevtTrace:
596 printTrace (evtp);
597 break;
598
599 case hevtM:
600 printM (evtp);
601 break;
602
603 case hevtAPU:
604 printAPU (evtp);
605 break;
606
607
608
609
610
611
612
613
614
615
616
617
618
619 case hevtFault:
620 printFault (evtp);
621 break;
622
623 case hevtIntrSet:
624 printIntrSet (evtp);
625 break;
626
627 case hevtIntr:
628 printIntr (evtp);
629 break;
630
631 case hevtReg:
632 printReg (evtp);
633 break;
634
635 case hevtPAReg:
636 printPAReg (evtp);
637 break;
638
639 case hevtDSBRReg:
640 printDSBRReg (evtp);
641 break;
642
643 case hevtIEFP:
644 printIEFP (evtp);
645 break;
646
647 case hevtNote:
648 printNote (evtp);
649 break;
650
651 default:
652 (void)fprintf (hdbgOut, "hdbgPrint ? %d\n", evtp -> type);
653 break;
654 }
655 }
656 fclose (hdbgOut);
657
658 int fd = open ("M.dump", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
659 if (fd == -1) {
660 sim_printf ("can't open M.dump\n");
661 goto done;
662 }
663
664 write (fd, (const void *) M, MEMSIZE * sizeof (word36));
665 close (fd);
666 done: ;
667 }
668
669
670
671
672
673
674
675
676 t_stat hdbg_cpu_mask (UNUSED int32 arg, const char * buf)
677 {
678 hdbgCPUMask = strtoul (buf, NULL, 0);
679 sim_printf ("hdbg CPU mask set to %ld\n", (long) hdbgCPUMask);
680 return SCPE_OK;
681 }
682
683
684 t_stat hdbg_size (UNUSED int32 arg, const char * buf) {
685 hdbgSize = strtoul (buf, NULL, 0);
686 sim_printf ("hdbg size set to %ld\n", (long) hdbgSize);
687 createBuffer ();
688 return SCPE_OK;
689 }
690
691
692 t_stat hdbgSegmentNumber (UNUSED int32 arg, const char * buf) {
693 hdbgSegNum = strtoul (buf, NULL, 8);
694 sim_printf ("hdbg target segment number set to %lu\n", hdbgSize);
695 createBuffer ();
696 return SCPE_OK;
697 }
698
699 t_stat hdbgBlacklist (UNUSED int32 arg, const char * buf) {
700 char work[strlen (buf) + 1];
701 if (sscanf (buf, "%s", work) != 1)
702 return SCPE_ARG;
703 if (strcasecmp (work, "init") == 0) {
704 (void)memset (blacklist, 0, sizeof (blacklist));
705 return SCPE_OK;
706 }
707 uint low, high;
708 if (sscanf (work, "%o-%o", & low, & high) != 2)
709 return SCPE_ARG;
710 if (low > MAX18 || high > MAX18)
711 return SCPE_ARG;
712 for (uint addr = low; addr <= high; addr ++)
713 blacklist[addr] = true;
714 return SCPE_OK;
715 }
716
717 t_stat hdbg_print (UNUSED int32 arg, const char * buf) {
718 hdbgPrint ();
719 return SCPE_OK;
720 }
721
722 #endif