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