1*1184Sbill /* subr_prf.c 3.4 10/02/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" 9*1184Sbill #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 /* 123*1184Sbill * Panic is called on unresolvable fatal errors. 124*1184Sbill * It syncs, prints "panic: mesg", and then reboots. 12531Sbill */ 12631Sbill panic(s) 12731Sbill char *s; 12831Sbill { 12931Sbill panicstr = s; 13031Sbill update(); 13131Sbill printf("panic: %s\n", s); 13231Sbill spl0(); 13331Sbill for(;;) 134*1184Sbill boot(RB_PANIC, RB_AUTOBOOT); /* 0 = automatic */ 13531Sbill } 13631Sbill 13731Sbill /* 13831Sbill * prdev prints a warning message of the 13931Sbill * form "mesg on dev x/y". 14031Sbill * x and y are the major and minor parts of 14131Sbill * the device argument. 14231Sbill */ 14331Sbill prdev(str, dev) 14431Sbill char *str; 14531Sbill dev_t dev; 14631Sbill { 14731Sbill 14831Sbill printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); 14931Sbill } 15031Sbill 15131Sbill /* 15231Sbill * deverr prints a diagnostic from 15331Sbill * a device driver. 15431Sbill * It prints the device, block number, 15531Sbill * and an octal word (usually some error 15631Sbill * status register) passed as argument. 15731Sbill */ 15831Sbill deverror(bp, o1, o2) 15931Sbill register struct buf *bp; 16031Sbill { 16131Sbill 16231Sbill prdev("err", bp->b_dev); 16331Sbill printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2); 16431Sbill } 165285Sbill 166285Sbill #ifdef TRACE 167285Sbill dumptrc() 168285Sbill { 169285Sbill register char *cp; 170285Sbill register int pos, nch; 171285Sbill 172285Sbill nch = trcprt; 173285Sbill if (nch < 0 || nch > TRCBUFS) 174285Sbill nch = TRCBUFS; 175285Sbill pos = (trcbufp - trcbuf) - nch; 176285Sbill if (pos < 0) 177285Sbill if (trcwrap) 178285Sbill pos += TRCBUFS; 179285Sbill else { 180285Sbill nch += pos; 181285Sbill pos = 0; 182285Sbill } 183285Sbill for (cp = &trcbuf[pos]; nch > 0; nch--) { 184285Sbill putchar(*cp++, 0); 185285Sbill if (cp >= &trcbuf[TRCBUFS]) 186285Sbill cp = trcbuf; 187285Sbill } 188285Sbill } 189285Sbill #else 190285Sbill /*ARGSUSED*/ 191285Sbill dumptrc(nch) 192285Sbill int nch; 193285Sbill { 194285Sbill 195285Sbill } 196285Sbill #endif 197285Sbill 198285Sbill char *msgbufp = msgbuf; /* Next saved printf character */ 199285Sbill /* 200285Sbill * Print a character on console or in internal trace buffer. 201285Sbill * If destination is console then the last MSGBUFS characters 202285Sbill * are saved in msgbuf for inspection later. 203285Sbill */ 204285Sbill putchar(c, trace) 205285Sbill register c; 206285Sbill { 207285Sbill register s, timo; 208285Sbill 209285Sbill #ifdef TRACE 210285Sbill if (trace) { 211285Sbill *trcbufp++ = c; 212285Sbill if (trcbufp >= &trcbuf[TRCBUFS]) { 213285Sbill trcbufp = trcbuf; 214285Sbill trcwrap = 1; 215285Sbill } 216285Sbill return; 217285Sbill } 218285Sbill #endif 219285Sbill if (c != '\0' && c != '\r' && c != 0177) { 220285Sbill *msgbufp++ = c; 221285Sbill if (msgbufp >= &msgbuf[MSGBUFS]) 222285Sbill msgbufp = msgbuf; 223285Sbill } 224285Sbill if (c == 0) 225285Sbill return; 226285Sbill cnputc(c); 227285Sbill } 228