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