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\r\n",
577 (long long unsigned int)p->time,
578 p->note.noteBody);
579 }
580
581 void hdbgPrint (void) {
582 sim_printf ("hdbg print\r\n");
583 if (! hevents)
584 goto done;
585 struct hevt * t = hevents;
586 hevents = NULL;
587 hdbgOut = fopen ("hdbg.list", "w");
588 if (! hdbgOut) {
589 sim_printf ("can't open hdbg.list\r\n");
590 goto done;
591 }
592 time_t curtime;
593 time (& curtime);
594 (void)fprintf (hdbgOut, "%s\r\n", ctime (& curtime));
595
596 for (unsigned long p = 0; p < hdbgSize; p ++) {
597 unsigned long q = (hevtPtr + p) % hdbgSize;
598 struct hevt * evtp = t + q;
599 switch (evtp -> type) {
600 case hevtEmpty:
601 break;
602
603 case hevtTrace:
604 printTrace (evtp);
605 break;
606
607 case hevtM:
608 printM (evtp);
609 break;
610
611 case hevtAPU:
612 printAPU (evtp);
613 break;
614
615
616
617
618
619
620
621
622
623
624
625
626
627 case hevtFault:
628 printFault (evtp);
629 break;
630
631 case hevtIntrSet:
632 printIntrSet (evtp);
633 break;
634
635 case hevtIntr:
636 printIntr (evtp);
637 break;
638
639 case hevtReg:
640 printReg (evtp);
641 break;
642
643 case hevtPAReg:
644 printPAReg (evtp);
645 break;
646
647 case hevtDSBRReg:
648 printDSBRReg (evtp);
649 break;
650
651 case hevtIEFP:
652 printIEFP (evtp);
653 break;
654
655 case hevtNote:
656 printNote (evtp);
657 break;
658
659 default:
660 (void)fprintf (hdbgOut, "hdbgPrint ? %d\r\n", evtp -> type);
661 break;
662 }
663 }
664 fclose (hdbgOut);
665
666 int fd = open ("M.dump", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
667 if (fd == -1) {
668 sim_printf ("can't open M.dump\r\n");
669 goto done;
670 }
671
672 write (fd, (const void *) M, MEMSIZE * sizeof (word36));
673 close (fd);
674 done: ;
675 }
676
677
678
679
680
681
682
683
684 t_stat hdbg_cpu_mask (UNUSED int32 arg, const char * buf)
685 {
686 hdbgCPUMask = strtoul (buf, NULL, 0);
687 sim_printf ("hdbg CPU mask set to %ld\r\n", (long) hdbgCPUMask);
688 return SCPE_OK;
689 }
690
691
692 t_stat hdbg_size (UNUSED int32 arg, const char * buf) {
693 hdbgSize = strtoul (buf, NULL, 0);
694 sim_printf ("hdbg size set to %ld\r\n", (long) hdbgSize);
695 createBuffer ();
696 return SCPE_OK;
697 }
698
699
700 t_stat hdbgSegmentNumber (UNUSED int32 arg, const char * buf) {
701 hdbgSegNum = strtoul (buf, NULL, 8);
702 sim_printf ("hdbg target segment number set to %lu\r\n", hdbgSize);
703 createBuffer ();
704 return SCPE_OK;
705 }
706
707 t_stat hdbgBlacklist (UNUSED int32 arg, const char * buf) {
708 char work[strlen (buf) + 1];
709 if (sscanf (buf, "%s", work) != 1)
710 return SCPE_ARG;
711 if (strcasecmp (work, "init") == 0) {
712 (void)memset (blacklist, 0, sizeof (blacklist));
713 return SCPE_OK;
714 }
715 uint low, high;
716 if (sscanf (work, "%o-%o", & low, & high) != 2)
717 return SCPE_ARG;
718 if (low > MAX18 || high > MAX18)
719 return SCPE_ARG;
720 for (uint addr = low; addr <= high; addr ++)
721 blacklist[addr] = true;
722 return SCPE_OK;
723 }
724
725 t_stat hdbg_print (UNUSED int32 arg, const char * buf) {
726 hdbgPrint ();
727 return SCPE_OK;
728 }
729
730 #endif