1*1401Sbill /* subr_prf.c 3.5 10/11/80 */ 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" 1031Sbill 11285Sbill #ifdef TRACE 12285Sbill #define TRCBUFS 4096 13285Sbill char trcbuf[TRCBUFS]; 14285Sbill char *trcbufp = trcbuf; 15285Sbill int trcwrap; 16285Sbill int trcprt = TRCBUFS; 17285Sbill #endif 18285Sbill 1931Sbill /* 2031Sbill * In case console is off, 2131Sbill * panicstr contains argument to last 2231Sbill * call to panic. 2331Sbill */ 2431Sbill 2531Sbill char *panicstr; 2631Sbill 2731Sbill /* 2831Sbill * Scaled down version of C Library printf. 2931Sbill * Only %s %u %d (==%u) %o %x %D are recognized. 3031Sbill * Used to print diagnostic information 3131Sbill * directly on console tty. 3231Sbill * Since it is not interrupt driven, 3331Sbill * all system activities are pretty much 3431Sbill * suspended. 3531Sbill * Printf should not be used for chit-chat. 3631Sbill */ 3731Sbill /*VARARGS1*/ 3831Sbill printf(fmt, x1) 3931Sbill register char *fmt; 4031Sbill unsigned x1; 4131Sbill { 42285Sbill 43285Sbill prf(fmt, &x1, 0); 44285Sbill } 45285Sbill 46285Sbill #ifdef TRACE 47285Sbill trace(fmt, x1) 48285Sbill register char *fmt; 49285Sbill unsigned x1; 50285Sbill { 51285Sbill 52285Sbill prf(fmt, &x1, 1); 53285Sbill } 54285Sbill 55285Sbill #endif 56285Sbill 57285Sbill prf(fmt, adx, trace) 58285Sbill register char *fmt; 59285Sbill register unsigned int *adx; 60285Sbill { 6131Sbill register c; 6231Sbill char *s; 6331Sbill 6431Sbill loop: 6531Sbill while((c = *fmt++) != '%') { 6631Sbill if(c == '\0') 6731Sbill return; 68285Sbill putchar(c, trace); 6931Sbill } 7031Sbill c = *fmt++; 71285Sbill if (c == 'X') 72285Sbill printx((long)*adx, trace); 73285Sbill else if (c == 'd' || c == 'u' || c == 'o' || c == 'x') 74285Sbill printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace); 75285Sbill else if (c == 's') { 7631Sbill s = (char *)*adx; 77285Sbill while (c = *s++) 78285Sbill #ifdef TRACE 79285Sbill if (trace) { 80285Sbill *trcbufp++ = c; 81285Sbill if (trcbufp >= &trcbuf[TRCBUFS]) { 82285Sbill trcbufp = trcbuf; 83285Sbill trcwrap = 1; 84285Sbill } 85285Sbill } else 86285Sbill #endif 87285Sbill putchar(c, trace); 8831Sbill } else if (c == 'D') { 89285Sbill printn(*(long *)adx, 10, trace); 9031Sbill adx += (sizeof(long) / sizeof(int)) - 1; 9131Sbill } 9231Sbill adx++; 9331Sbill goto loop; 9431Sbill } 9531Sbill 96285Sbill printx(x, trace) 9731Sbill long x; 9831Sbill { 9931Sbill int i; 10031Sbill 10131Sbill for (i = 0; i < 8; i++) 102285Sbill putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace); 10331Sbill } 10431Sbill 10531Sbill /* 10631Sbill * Print an unsigned integer in base b. 10731Sbill */ 108285Sbill printn(n, b, trace) 10931Sbill long n; 11031Sbill { 11131Sbill register long a; 11231Sbill 11331Sbill if (n<0) { /* shouldn't happen */ 114285Sbill putchar('-', trace); 11531Sbill n = -n; 11631Sbill } 11731Sbill if(a = n/b) 118285Sbill printn(a, b, trace); 119285Sbill putchar("0123456789ABCDEF"[(int)(n%b)], trace); 12031Sbill } 12131Sbill 12231Sbill /* 1231184Sbill * Panic is called on unresolvable fatal errors. 1241184Sbill * It syncs, prints "panic: mesg", and then reboots. 12531Sbill */ 12631Sbill panic(s) 12731Sbill char *s; 12831Sbill { 12931Sbill panicstr = s; 13031Sbill printf("panic: %s\n", s); 13131Sbill spl0(); 13231Sbill for(;;) 133*1401Sbill boot(RB_PANIC, RB_AUTOBOOT); 13431Sbill } 13531Sbill 13631Sbill /* 13731Sbill * prdev prints a warning message of the 13831Sbill * form "mesg on dev x/y". 13931Sbill * x and y are the major and minor parts of 14031Sbill * the device argument. 14131Sbill */ 14231Sbill prdev(str, dev) 14331Sbill char *str; 14431Sbill dev_t dev; 14531Sbill { 14631Sbill 14731Sbill printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); 14831Sbill } 14931Sbill 15031Sbill /* 15131Sbill * deverr prints a diagnostic from 15231Sbill * a device driver. 15331Sbill * It prints the device, block number, 15431Sbill * and an octal word (usually some error 15531Sbill * status register) passed as argument. 15631Sbill */ 15731Sbill deverror(bp, o1, o2) 15831Sbill register struct buf *bp; 15931Sbill { 16031Sbill 16131Sbill prdev("err", bp->b_dev); 16231Sbill printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2); 16331Sbill } 164285Sbill 165285Sbill #ifdef TRACE 166285Sbill dumptrc() 167285Sbill { 168285Sbill register char *cp; 169285Sbill register int pos, nch; 170285Sbill 171285Sbill nch = trcprt; 172285Sbill if (nch < 0 || nch > TRCBUFS) 173285Sbill nch = TRCBUFS; 174285Sbill pos = (trcbufp - trcbuf) - nch; 175285Sbill if (pos < 0) 176285Sbill if (trcwrap) 177285Sbill pos += TRCBUFS; 178285Sbill else { 179285Sbill nch += pos; 180285Sbill pos = 0; 181285Sbill } 182285Sbill for (cp = &trcbuf[pos]; nch > 0; nch--) { 183285Sbill putchar(*cp++, 0); 184285Sbill if (cp >= &trcbuf[TRCBUFS]) 185285Sbill cp = trcbuf; 186285Sbill } 187285Sbill } 188285Sbill #else 189285Sbill /*ARGSUSED*/ 190285Sbill dumptrc(nch) 191285Sbill int nch; 192285Sbill { 193285Sbill 194285Sbill } 195285Sbill #endif 196285Sbill 197285Sbill char *msgbufp = msgbuf; /* Next saved printf character */ 198285Sbill /* 199285Sbill * Print a character on console or in internal trace buffer. 200285Sbill * If destination is console then the last MSGBUFS characters 201285Sbill * are saved in msgbuf for inspection later. 202285Sbill */ 203285Sbill putchar(c, trace) 204285Sbill register c; 205285Sbill { 206285Sbill register s, timo; 207285Sbill 208285Sbill #ifdef TRACE 209285Sbill if (trace) { 210285Sbill *trcbufp++ = c; 211285Sbill if (trcbufp >= &trcbuf[TRCBUFS]) { 212285Sbill trcbufp = trcbuf; 213285Sbill trcwrap = 1; 214285Sbill } 215285Sbill return; 216285Sbill } 217285Sbill #endif 218285Sbill if (c != '\0' && c != '\r' && c != 0177) { 219285Sbill *msgbufp++ = c; 220285Sbill if (msgbufp >= &msgbuf[MSGBUFS]) 221285Sbill msgbufp = msgbuf; 222285Sbill } 223285Sbill if (c == 0) 224285Sbill return; 225285Sbill cnputc(c); 226285Sbill } 227