1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 trace_mc: proc;
 14           return;                                           /* should never enter here */
 15 
 16 /* trace_mc - primitive to turn on/off the hardcore machine condition trace mechanism
 17    initially coded by James A. Bush March 1977 */
 18 
 19 dcl (a_segptr, segptr) ptr;
 20 dcl (a_trace_sw, trace_sw) bit (1) aligned;
 21 dcl (a_code, code) fixed bin (35);
 22 dcl (p, a_bp) ptr;
 23 dcl  dirname char (168);
 24 dcl (i, a_buf_size, buf_size) fixed bin;
 25 dcl  ename char (32);
 26 dcl  vl fixed bin (3);
 27 dcl  based_segno fixed bin (35);
 28 dcl  rba (3) fixed bin (3);                                 /* ring bracket array */
 29 dcl  init_buf (0 : buf_size) bit (36) based (bp);
 30 dcl 1 bseg based (addr (based_segno)) aligned,
 31     2 seg fixed bin unal,
 32     2 pad1 fixed bin unal;
 33 
 34 dcl  level$set entry (fixed bin (3));
 35 dcl  level$get entry returns (fixed bin (3));
 36 dcl  unique_chars_ entry (bit (*)) returns (char (15));
 37 dcl  append$branch entry (char (*), char (*), fixed bin (5), fixed bin (35));
 38 dcl  initiate entry (char (*), char (*), char (*), fixed bin (1), fixed bin (1), ptr, fixed bin (35));
 39 dcl  ringbr_$set entry (char (*), char (*), (3) fixed bin (3), fixed bin (35));
 40 dcl  delentry$dseg entry (ptr, fixed bin (35));
 41 dcl  user_wire entry (ptr, bit (1) aligned, fixed bin (18), fixed bin (18), fixed bin (35));
 42 dcl  set$bc_seg entry (ptr, fixed bin (24), fixed bin (35));
 43 
 44 dcl  pds$process_dir_name char (32) ext;
 45 dcl  pds$mc_trace_buf ptr unaligned ext;                    /* Note packed pointer */
 46 dcl  pds$mc_trace_seg fixed bin (35) ext;
 47 dcl 1 pds$mc_trace_sw aligned ext,
 48     2 hc_trace_sw bit (1) unaligned,
 49     2 init_sw bit (1) unaligned;
 50 dcl  error_table_$action_not_performed fixed bin (35) ext;
 51 dcl  error_table_$buffer_big fixed bin (35) ext;
 52 
 53 dcl (addr, fixed, addrel, null, rel, ptr, divide) builtin;
 54 
 55 /* ^L */
 56 % include mc_trace_buf;
 57 % include its;
 58 
 59 /* ^L */
 60 
 61 /* trace_buffer_init - entry to create and init M. C. buff | delete M. C. trace buff, per state of a_trace_sw */
 62 
 63 trace_buffer_init: entry (a_segptr, a_trace_sw, a_buf_size, a_bp, a_code);
 64 
 65 /* copy args */
 66 
 67           segptr = a_segptr;
 68           trace_sw = a_trace_sw;
 69           a_bp = null;
 70           a_code = 0;
 71 
 72           vl = level$get ();                                /* Save current validation level. */
 73           call level$set (0);                               /* Set hardcore ring validation level. */
 74           if trace_sw then do;                              /* are we turning trace on? */
 75                if a_buf_size <= 0 | a_buf_size > max_buf_size then do; /* user requested invalid buffer size */
 76                     code = error_table_$buffer_big;
 77                     go to erret;
 78                end;
 79                ename = unique_chars_ ("0"b) || ".mct";      /* Create unique buffer segment name. */
 80                call append$branch (pds$process_dir_name, ename, 01010b, code);
 81                if code ^= 0 then go to erret;               /* Create the buffer segment. */
 82                call initiate (pds$process_dir_name, ename, "", 0b, 1b, bp, code);
 83                if bp = null then go to erret;               /* Initiate the segment. */
 84                rba (1) = 0;                                 /* set ring brackets to 0 N N */
 85                rba (2), rba (3) = vl;
 86                call ringbr_$set (pds$process_dir_name, ename, rba, code); /* Change the ring brackets of the buf seg. */
 87                if code ^= 0 then go to erret;
 88                buf_size = a_buf_size * 1024;                /* set up buffer size */
 89                call set$bc_seg (bp, buf_size * 36, code);   /* set bit count  */
 90                if code ^= 0 then go to erret;
 91 
 92 /* initialize buffer */
 93 
 94                do i = 0 to buf_size - 1;
 95                     init_buf (i) = buf_init;                /* set up constant in entire buffer */
 96                end;
 97 
 98 /* initialize trace buffer header */
 99 
100                mc_trace_buf.hr_cnt = buf_size / ((8 * mc_size) + hr_size); /* 8:1 ratio mc's to hr's */
101                mc_trace_buf.mc_cnt = (mc_trace_buf.hr_cnt * 8) - 1; /* have to have room for header */
102                mc_trace_buf.hr_strt = fixed (rel (addr (mc_trace_buf.h_regs (1)))); /* figure out starting loc's */
103                mc_trace_buf.mc_strt = fixed (rel (addr (mc_trace_buf.mach_cond (1))));
104                mc_trace_buf.hr_lim = (mc_trace_buf.hr_cnt * hr_size) + hr_strt;
105                mc_trace_buf.mc_lim = (mc_trace_buf.mc_cnt * mc_size) + mc_strt;
106                mc_trace_buf.hr_nxtad = mc_trace_buf.hr_strt;
107                mc_trace_buf.mc_nxtad = mc_trace_buf.mc_strt;
108 
109 /* wire trace buffer */
110 
111                call user_wire (bp, "1"b, 0, -1, code);
112                if code = 0 then do;
113 
114 /* set up trace buffer pointer, segno to trace and turn on trace switch in pds */
115 
116                     a_bp = bp;                              /* set buffer pointer for user */
117                     p = addr (segptr);
118                     bseg.seg = fixed (p -> its.segno, 15);  /* set up seg  number in upper half of word */
119                     bseg.pad1 = 0;                          /* set lower half of word to zero */
120                     pds$mc_trace_buf = bp;
121                     pds$mc_trace_seg = based_segno;
122                     pds$mc_trace_sw.init_sw = "1"b;         /* let user turn on trace */
123                end;
124           end;
125           else do;                                          /* user wants to turn trace off */
126                pds$mc_trace_sw.init_sw = "0"b;              /* don't let user turn on trace */
127                pds$mc_trace_sw.hc_trace_sw = "0"b;          /*  must turn switch off first */
128                pds$mc_trace_seg = 0;
129                bp = pds$mc_trace_buf;                       /* save buffer pointer */
130                pds$mc_trace_buf = null;                     /* this makes it cleaner */
131 
132 /* Unwire trace buffer */
133 
134                call user_wire (bp, "0"b, 0, 0, code);
135                if code ^= 0 then go to erret;
136                call delentry$dseg (bp, code);               /* delete buffer segment */
137 
138           end;
139 erret:
140           a_code = code;
141           call level$set (vl);                              /* Restore original validation level. */
142           return;
143 
144 /* hc_trace_on_off - entry to turn the hc_trace_sw in the pds on or off */
145 
146 hc_trace_on_off: entry (a_trace_sw, a_code);
147 
148           a_code = 0;                                       /* preset good return code */
149           if a_trace_sw then                                /* user wants to turn trace on */
150                if ^pds$mc_trace_sw.init_sw then             /* if we haven't initialized the trace buffer */
151                     a_code = error_table_$action_not_performed; /* don't let user turn trace on */
152                else pds$mc_trace_sw.hc_trace_sw = "1"b;
153           else pds$mc_trace_sw.hc_trace_sw = "0"b;          /* user wants to turn hc_trace_sw off */
154           return;
155 
156      end trace_mc;