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