1*2360Skre /* subr_prf.c 4.6 02/07/81 */ 231Sbill 331Sbill #include "../h/param.h" 431Sbill #include "../h/systm.h" 531Sbill #include "../h/seg.h" 631Sbill #include "../h/buf.h" 731Sbill #include "../h/conf.h" 8285Sbill #include "../h/mtpr.h" 91184Sbill #include "../h/reboot.h" 102172Swnj #include "../h/vm.h" 112172Swnj #include "../h/msgbuf.h" 12*2360Skre #include "../h/dir.h" 13*2360Skre #include "../h/user.h" 14*2360Skre #include "../h/tty.h" 1531Sbill 16285Sbill #ifdef TRACE 17285Sbill #define TRCBUFS 4096 18285Sbill char trcbuf[TRCBUFS]; 19285Sbill char *trcbufp = trcbuf; 20285Sbill int trcwrap; 21285Sbill int trcprt = TRCBUFS; 22285Sbill #endif 23285Sbill 2431Sbill /* 2531Sbill * In case console is off, 2631Sbill * panicstr contains argument to last 2731Sbill * call to panic. 2831Sbill */ 2931Sbill 3031Sbill char *panicstr; 3131Sbill 3231Sbill /* 3331Sbill * Scaled down version of C Library printf. 3431Sbill * Only %s %u %d (==%u) %o %x %D are recognized. 3531Sbill * Used to print diagnostic information 3631Sbill * directly on console tty. 3731Sbill * Since it is not interrupt driven, 3831Sbill * all system activities are pretty much 3931Sbill * suspended. 4031Sbill * Printf should not be used for chit-chat. 4131Sbill */ 4231Sbill /*VARARGS1*/ 4331Sbill printf(fmt, x1) 4431Sbill register char *fmt; 4531Sbill unsigned x1; 4631Sbill { 47285Sbill 48285Sbill prf(fmt, &x1, 0); 49285Sbill } 50285Sbill 51285Sbill #ifdef TRACE 52285Sbill trace(fmt, x1) 53285Sbill register char *fmt; 54285Sbill unsigned x1; 55285Sbill { 56285Sbill 57285Sbill prf(fmt, &x1, 1); 58285Sbill } 59285Sbill 60285Sbill #endif 61285Sbill 62285Sbill prf(fmt, adx, trace) 63285Sbill register char *fmt; 64285Sbill register unsigned int *adx; 65285Sbill { 6631Sbill register c; 6731Sbill char *s; 6831Sbill 6931Sbill loop: 7031Sbill while((c = *fmt++) != '%') { 7131Sbill if(c == '\0') 7231Sbill return; 73285Sbill putchar(c, trace); 7431Sbill } 7531Sbill c = *fmt++; 76285Sbill if (c == 'X') 77285Sbill printx((long)*adx, trace); 78285Sbill else if (c == 'd' || c == 'u' || c == 'o' || c == 'x') 79285Sbill printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace); 80285Sbill else if (c == 's') { 8131Sbill s = (char *)*adx; 82285Sbill while (c = *s++) 83285Sbill #ifdef TRACE 84*2360Skre if (trace == 1) { 85285Sbill *trcbufp++ = c; 86285Sbill if (trcbufp >= &trcbuf[TRCBUFS]) { 87285Sbill trcbufp = trcbuf; 88285Sbill trcwrap = 1; 89285Sbill } 90285Sbill } else 91285Sbill #endif 92285Sbill putchar(c, trace); 9331Sbill } else if (c == 'D') { 94285Sbill printn(*(long *)adx, 10, trace); 9531Sbill adx += (sizeof(long) / sizeof(int)) - 1; 9631Sbill } 9731Sbill adx++; 9831Sbill goto loop; 9931Sbill } 10031Sbill 101285Sbill printx(x, trace) 10231Sbill long x; 10331Sbill { 10431Sbill int i; 10531Sbill 10631Sbill for (i = 0; i < 8; i++) 107285Sbill putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace); 10831Sbill } 10931Sbill 11031Sbill /* 1112303Stoy * Print an integer in base b. If the base is ten it is condidered a 1122303Stoy * signed integer otherwise it is treated as unsigned. 11331Sbill */ 114285Sbill printn(n, b, trace) 1152303Stoy unsigned long n; 11631Sbill { 1172303Stoy register unsigned long a; 1182303Stoy register long a1 = n; 11931Sbill 1202303Stoy if (b == 10 && a1 < 0) { 121285Sbill putchar('-', trace); 1222303Stoy n = -a1; 12331Sbill } 12431Sbill if(a = n/b) 125285Sbill printn(a, b, trace); 126285Sbill putchar("0123456789ABCDEF"[(int)(n%b)], trace); 12731Sbill } 12831Sbill 12931Sbill /* 1301184Sbill * Panic is called on unresolvable fatal errors. 1311184Sbill * It syncs, prints "panic: mesg", and then reboots. 13231Sbill */ 13331Sbill panic(s) 13431Sbill char *s; 13531Sbill { 13631Sbill panicstr = s; 13731Sbill printf("panic: %s\n", s); 1381787Sbill (void) spl0(); 13931Sbill for(;;) 1401401Sbill boot(RB_PANIC, RB_AUTOBOOT); 14131Sbill } 14231Sbill 14331Sbill /* 14431Sbill * prdev prints a warning message of the 14531Sbill * form "mesg on dev x/y". 14631Sbill * x and y are the major and minor parts of 14731Sbill * the device argument. 14831Sbill */ 14931Sbill prdev(str, dev) 15031Sbill char *str; 15131Sbill dev_t dev; 15231Sbill { 15331Sbill 15431Sbill printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); 15531Sbill } 15631Sbill 15731Sbill /* 15831Sbill * deverr prints a diagnostic from 15931Sbill * a device driver. 16031Sbill * It prints the device, block number, 16131Sbill * and an octal word (usually some error 16231Sbill * status register) passed as argument. 16331Sbill */ 16431Sbill deverror(bp, o1, o2) 16531Sbill register struct buf *bp; 16631Sbill { 16731Sbill 168*2360Skre printf("bn=%d er=%x,%x", bp->b_blkno, o1,o2); 169*2360Skre prdev("", bp->b_dev); 17031Sbill } 171285Sbill 172285Sbill #ifdef TRACE 173285Sbill dumptrc() 174285Sbill { 175285Sbill register char *cp; 176285Sbill register int pos, nch; 177285Sbill 178285Sbill nch = trcprt; 179285Sbill if (nch < 0 || nch > TRCBUFS) 180285Sbill nch = TRCBUFS; 181285Sbill pos = (trcbufp - trcbuf) - nch; 182285Sbill if (pos < 0) 183285Sbill if (trcwrap) 184285Sbill pos += TRCBUFS; 185285Sbill else { 186285Sbill nch += pos; 187285Sbill pos = 0; 188285Sbill } 189285Sbill for (cp = &trcbuf[pos]; nch > 0; nch--) { 190285Sbill putchar(*cp++, 0); 191285Sbill if (cp >= &trcbuf[TRCBUFS]) 192285Sbill cp = trcbuf; 193285Sbill } 194285Sbill } 195285Sbill #else 196285Sbill /*ARGSUSED*/ 197285Sbill dumptrc(nch) 198285Sbill int nch; 199285Sbill { 200285Sbill 201285Sbill } 202285Sbill #endif 203285Sbill 204285Sbill /* 205285Sbill * Print a character on console or in internal trace buffer. 206285Sbill * If destination is console then the last MSGBUFS characters 207285Sbill * are saved in msgbuf for inspection later. 208285Sbill */ 2091785Sbill /*ARGSUSED*/ 210285Sbill putchar(c, trace) 211285Sbill register c; 212285Sbill { 213285Sbill 214*2360Skre if (trace == 2) { 215*2360Skre register struct tty *tp; 216*2360Skre register s; 217*2360Skre 218*2360Skre if ((tp = u.u_ttyp) && (tp->t_state&CARR_ON)) { 219*2360Skre s = spl7(); 220*2360Skre ttyoutput(c, tp); 221*2360Skre ttstart(tp); 222*2360Skre splx(s); 223*2360Skre } 224*2360Skre return; 225*2360Skre } 226285Sbill #ifdef TRACE 227285Sbill if (trace) { 228285Sbill *trcbufp++ = c; 229285Sbill if (trcbufp >= &trcbuf[TRCBUFS]) { 230285Sbill trcbufp = trcbuf; 231285Sbill trcwrap = 1; 232285Sbill } 233285Sbill return; 234285Sbill } 235285Sbill #endif 236285Sbill if (c != '\0' && c != '\r' && c != 0177) { 2372172Swnj if (msgbuf.msg_magic != MSG_MAGIC) { 2382172Swnj msgbuf.msg_bufx = 0; 2392172Swnj msgbuf.msg_magic = MSG_MAGIC; 2402172Swnj } 2412172Swnj if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE) 2422172Swnj msgbuf.msg_bufx = 0; 2432172Swnj msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; 244285Sbill } 245285Sbill if (c == 0) 246285Sbill return; 247285Sbill cnputc(c); 248285Sbill } 249*2360Skre 250*2360Skre /* 251*2360Skre * print to the current users terminal, 252*2360Skre * guarantee not to sleep (so can be called by intr routine) 253*2360Skre * no watermark checking - so no verbose messages 254*2360Skre */ 255*2360Skre 256*2360Skre /*VARARGS1*/ 257*2360Skre uprintf(fmt, x1) 258*2360Skre char *fmt; 259*2360Skre unsigned x1; 260*2360Skre { 261*2360Skre prf(fmt, &x1, 2); 262*2360Skre } 263