1 /* subr_prf.c 4.5 01/28/81 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/seg.h" 6 #include "../h/buf.h" 7 #include "../h/conf.h" 8 #include "../h/mtpr.h" 9 #include "../h/reboot.h" 10 #include "../h/vm.h" 11 #include "../h/msgbuf.h" 12 13 #ifdef TRACE 14 #define TRCBUFS 4096 15 char trcbuf[TRCBUFS]; 16 char *trcbufp = trcbuf; 17 int trcwrap; 18 int trcprt = TRCBUFS; 19 #endif 20 21 /* 22 * In case console is off, 23 * panicstr contains argument to last 24 * call to panic. 25 */ 26 27 char *panicstr; 28 29 /* 30 * Scaled down version of C Library printf. 31 * Only %s %u %d (==%u) %o %x %D are recognized. 32 * Used to print diagnostic information 33 * directly on console tty. 34 * Since it is not interrupt driven, 35 * all system activities are pretty much 36 * suspended. 37 * Printf should not be used for chit-chat. 38 */ 39 /*VARARGS1*/ 40 printf(fmt, x1) 41 register char *fmt; 42 unsigned x1; 43 { 44 45 prf(fmt, &x1, 0); 46 } 47 48 #ifdef TRACE 49 trace(fmt, x1) 50 register char *fmt; 51 unsigned x1; 52 { 53 54 prf(fmt, &x1, 1); 55 } 56 57 #endif 58 59 prf(fmt, adx, trace) 60 register char *fmt; 61 register unsigned int *adx; 62 { 63 register c; 64 char *s; 65 66 loop: 67 while((c = *fmt++) != '%') { 68 if(c == '\0') 69 return; 70 putchar(c, trace); 71 } 72 c = *fmt++; 73 if (c == 'X') 74 printx((long)*adx, trace); 75 else if (c == 'd' || c == 'u' || c == 'o' || c == 'x') 76 printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace); 77 else if (c == 's') { 78 s = (char *)*adx; 79 while (c = *s++) 80 #ifdef TRACE 81 if (trace) { 82 *trcbufp++ = c; 83 if (trcbufp >= &trcbuf[TRCBUFS]) { 84 trcbufp = trcbuf; 85 trcwrap = 1; 86 } 87 } else 88 #endif 89 putchar(c, trace); 90 } else if (c == 'D') { 91 printn(*(long *)adx, 10, trace); 92 adx += (sizeof(long) / sizeof(int)) - 1; 93 } 94 adx++; 95 goto loop; 96 } 97 98 printx(x, trace) 99 long x; 100 { 101 int i; 102 103 for (i = 0; i < 8; i++) 104 putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace); 105 } 106 107 /* 108 * Print an integer in base b. If the base is ten it is condidered a 109 * signed integer otherwise it is treated as unsigned. 110 */ 111 printn(n, b, trace) 112 unsigned long n; 113 { 114 register unsigned long a; 115 register long a1 = n; 116 117 if (b == 10 && a1 < 0) { 118 putchar('-', trace); 119 n = -a1; 120 } 121 if(a = n/b) 122 printn(a, b, trace); 123 putchar("0123456789ABCDEF"[(int)(n%b)], trace); 124 } 125 126 /* 127 * Panic is called on unresolvable fatal errors. 128 * It syncs, prints "panic: mesg", and then reboots. 129 */ 130 panic(s) 131 char *s; 132 { 133 panicstr = s; 134 printf("panic: %s\n", s); 135 (void) spl0(); 136 for(;;) 137 boot(RB_PANIC, RB_AUTOBOOT); 138 } 139 140 /* 141 * prdev prints a warning message of the 142 * form "mesg on dev x/y". 143 * x and y are the major and minor parts of 144 * the device argument. 145 */ 146 prdev(str, dev) 147 char *str; 148 dev_t dev; 149 { 150 151 printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); 152 } 153 154 /* 155 * deverr prints a diagnostic from 156 * a device driver. 157 * It prints the device, block number, 158 * and an octal word (usually some error 159 * status register) passed as argument. 160 */ 161 deverror(bp, o1, o2) 162 register struct buf *bp; 163 { 164 165 prdev("err", bp->b_dev); 166 printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2); 167 } 168 169 #ifdef TRACE 170 dumptrc() 171 { 172 register char *cp; 173 register int pos, nch; 174 175 nch = trcprt; 176 if (nch < 0 || nch > TRCBUFS) 177 nch = TRCBUFS; 178 pos = (trcbufp - trcbuf) - nch; 179 if (pos < 0) 180 if (trcwrap) 181 pos += TRCBUFS; 182 else { 183 nch += pos; 184 pos = 0; 185 } 186 for (cp = &trcbuf[pos]; nch > 0; nch--) { 187 putchar(*cp++, 0); 188 if (cp >= &trcbuf[TRCBUFS]) 189 cp = trcbuf; 190 } 191 } 192 #else 193 /*ARGSUSED*/ 194 dumptrc(nch) 195 int nch; 196 { 197 198 } 199 #endif 200 201 /* 202 * Print a character on console or in internal trace buffer. 203 * If destination is console then the last MSGBUFS characters 204 * are saved in msgbuf for inspection later. 205 */ 206 /*ARGSUSED*/ 207 putchar(c, trace) 208 register c; 209 { 210 211 #ifdef TRACE 212 if (trace) { 213 *trcbufp++ = c; 214 if (trcbufp >= &trcbuf[TRCBUFS]) { 215 trcbufp = trcbuf; 216 trcwrap = 1; 217 } 218 return; 219 } 220 #endif 221 if (c != '\0' && c != '\r' && c != 0177) { 222 if (msgbuf.msg_magic != MSG_MAGIC) { 223 msgbuf.msg_bufx = 0; 224 msgbuf.msg_magic = MSG_MAGIC; 225 } 226 if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE) 227 msgbuf.msg_bufx = 0; 228 msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; 229 } 230 if (c == 0) 231 return; 232 cnputc(c); 233 } 234