1 /* subr_prf.c 4.4 01/15/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 unsigned integer in base b. 109 */ 110 printn(n, b, trace) 111 long n; 112 { 113 register long a; 114 115 if (n<0) { /* shouldn't happen */ 116 putchar('-', trace); 117 n = -n; 118 } 119 if(a = n/b) 120 printn(a, b, trace); 121 putchar("0123456789ABCDEF"[(int)(n%b)], trace); 122 } 123 124 /* 125 * Panic is called on unresolvable fatal errors. 126 * It syncs, prints "panic: mesg", and then reboots. 127 */ 128 panic(s) 129 char *s; 130 { 131 panicstr = s; 132 printf("panic: %s\n", s); 133 (void) spl0(); 134 for(;;) 135 boot(RB_PANIC, RB_AUTOBOOT); 136 } 137 138 /* 139 * prdev prints a warning message of the 140 * form "mesg on dev x/y". 141 * x and y are the major and minor parts of 142 * the device argument. 143 */ 144 prdev(str, dev) 145 char *str; 146 dev_t dev; 147 { 148 149 printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); 150 } 151 152 /* 153 * deverr prints a diagnostic from 154 * a device driver. 155 * It prints the device, block number, 156 * and an octal word (usually some error 157 * status register) passed as argument. 158 */ 159 deverror(bp, o1, o2) 160 register struct buf *bp; 161 { 162 163 prdev("err", bp->b_dev); 164 printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2); 165 } 166 167 #ifdef TRACE 168 dumptrc() 169 { 170 register char *cp; 171 register int pos, nch; 172 173 nch = trcprt; 174 if (nch < 0 || nch > TRCBUFS) 175 nch = TRCBUFS; 176 pos = (trcbufp - trcbuf) - nch; 177 if (pos < 0) 178 if (trcwrap) 179 pos += TRCBUFS; 180 else { 181 nch += pos; 182 pos = 0; 183 } 184 for (cp = &trcbuf[pos]; nch > 0; nch--) { 185 putchar(*cp++, 0); 186 if (cp >= &trcbuf[TRCBUFS]) 187 cp = trcbuf; 188 } 189 } 190 #else 191 /*ARGSUSED*/ 192 dumptrc(nch) 193 int nch; 194 { 195 196 } 197 #endif 198 199 /* 200 * Print a character on console or in internal trace buffer. 201 * If destination is console then the last MSGBUFS characters 202 * are saved in msgbuf for inspection later. 203 */ 204 /*ARGSUSED*/ 205 putchar(c, trace) 206 register c; 207 { 208 209 #ifdef TRACE 210 if (trace) { 211 *trcbufp++ = c; 212 if (trcbufp >= &trcbuf[TRCBUFS]) { 213 trcbufp = trcbuf; 214 trcwrap = 1; 215 } 216 return; 217 } 218 #endif 219 if (c != '\0' && c != '\r' && c != 0177) { 220 if (msgbuf.msg_magic != MSG_MAGIC) { 221 msgbuf.msg_bufx = 0; 222 msgbuf.msg_magic = MSG_MAGIC; 223 } 224 if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE) 225 msgbuf.msg_bufx = 0; 226 msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; 227 } 228 if (c == 0) 229 return; 230 cnputc(c); 231 } 232