xref: /csrg-svn/sys/kern/subr_prf.c (revision 2172)
1*2172Swnj /*	subr_prf.c	4.4	01/15/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"
10*2172Swnj #include "../h/vm.h"
11*2172Swnj #include "../h/msgbuf.h"
1231Sbill 
13285Sbill #ifdef TRACE
14285Sbill #define	TRCBUFS	4096
15285Sbill char	trcbuf[TRCBUFS];
16285Sbill char	*trcbufp = trcbuf;
17285Sbill int	trcwrap;
18285Sbill int	trcprt = TRCBUFS;
19285Sbill #endif
20285Sbill 
2131Sbill /*
2231Sbill  * In case console is off,
2331Sbill  * panicstr contains argument to last
2431Sbill  * call to panic.
2531Sbill  */
2631Sbill 
2731Sbill char	*panicstr;
2831Sbill 
2931Sbill /*
3031Sbill  * Scaled down version of C Library printf.
3131Sbill  * Only %s %u %d (==%u) %o %x %D are recognized.
3231Sbill  * Used to print diagnostic information
3331Sbill  * directly on console tty.
3431Sbill  * Since it is not interrupt driven,
3531Sbill  * all system activities are pretty much
3631Sbill  * suspended.
3731Sbill  * Printf should not be used for chit-chat.
3831Sbill  */
3931Sbill /*VARARGS1*/
4031Sbill printf(fmt, x1)
4131Sbill register char *fmt;
4231Sbill unsigned x1;
4331Sbill {
44285Sbill 
45285Sbill 	prf(fmt, &x1, 0);
46285Sbill }
47285Sbill 
48285Sbill #ifdef TRACE
49285Sbill trace(fmt, x1)
50285Sbill register char *fmt;
51285Sbill unsigned x1;
52285Sbill {
53285Sbill 
54285Sbill 	prf(fmt, &x1, 1);
55285Sbill }
56285Sbill 
57285Sbill #endif
58285Sbill 
59285Sbill prf(fmt, adx, trace)
60285Sbill register char *fmt;
61285Sbill register unsigned int *adx;
62285Sbill {
6331Sbill 	register c;
6431Sbill 	char *s;
6531Sbill 
6631Sbill loop:
6731Sbill 	while((c = *fmt++) != '%') {
6831Sbill 		if(c == '\0')
6931Sbill 			return;
70285Sbill 		putchar(c, trace);
7131Sbill 	}
7231Sbill 	c = *fmt++;
73285Sbill 	if (c == 'X')
74285Sbill 		printx((long)*adx, trace);
75285Sbill 	else if (c == 'd' || c == 'u' || c == 'o' || c == 'x')
76285Sbill 		printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace);
77285Sbill 	else if (c == 's') {
7831Sbill 		s = (char *)*adx;
79285Sbill 		while (c = *s++)
80285Sbill #ifdef TRACE
81285Sbill 			if (trace) {
82285Sbill 				*trcbufp++ = c;
83285Sbill 				if (trcbufp >= &trcbuf[TRCBUFS]) {
84285Sbill 					trcbufp = trcbuf;
85285Sbill 					trcwrap = 1;
86285Sbill 				}
87285Sbill 			} else
88285Sbill #endif
89285Sbill 				putchar(c, trace);
9031Sbill 	} else if (c == 'D') {
91285Sbill 		printn(*(long *)adx, 10, trace);
9231Sbill 		adx += (sizeof(long) / sizeof(int)) - 1;
9331Sbill 	}
9431Sbill 	adx++;
9531Sbill 	goto loop;
9631Sbill }
9731Sbill 
98285Sbill printx(x, trace)
9931Sbill long x;
10031Sbill {
10131Sbill 	int i;
10231Sbill 
10331Sbill 	for (i = 0; i < 8; i++)
104285Sbill 		putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace);
10531Sbill }
10631Sbill 
10731Sbill /*
10831Sbill  * Print an unsigned integer in base b.
10931Sbill  */
110285Sbill printn(n, b, trace)
11131Sbill long n;
11231Sbill {
11331Sbill 	register long a;
11431Sbill 
11531Sbill 	if (n<0) {	/* shouldn't happen */
116285Sbill 		putchar('-', trace);
11731Sbill 		n = -n;
11831Sbill 	}
11931Sbill 	if(a = n/b)
120285Sbill 		printn(a, b, trace);
121285Sbill 	putchar("0123456789ABCDEF"[(int)(n%b)], trace);
12231Sbill }
12331Sbill 
12431Sbill /*
1251184Sbill  * Panic is called on unresolvable fatal errors.
1261184Sbill  * It syncs, prints "panic: mesg", and then reboots.
12731Sbill  */
12831Sbill panic(s)
12931Sbill char *s;
13031Sbill {
13131Sbill 	panicstr = s;
13231Sbill 	printf("panic: %s\n", s);
1331787Sbill 	(void) spl0();
13431Sbill 	for(;;)
1351401Sbill 		boot(RB_PANIC, RB_AUTOBOOT);
13631Sbill }
13731Sbill 
13831Sbill /*
13931Sbill  * prdev prints a warning message of the
14031Sbill  * form "mesg on dev x/y".
14131Sbill  * x and y are the major and minor parts of
14231Sbill  * the device argument.
14331Sbill  */
14431Sbill prdev(str, dev)
14531Sbill char *str;
14631Sbill dev_t dev;
14731Sbill {
14831Sbill 
14931Sbill 	printf("%s on dev %u/%u\n", str, major(dev), minor(dev));
15031Sbill }
15131Sbill 
15231Sbill /*
15331Sbill  * deverr prints a diagnostic from
15431Sbill  * a device driver.
15531Sbill  * It prints the device, block number,
15631Sbill  * and an octal word (usually some error
15731Sbill  * status register) passed as argument.
15831Sbill  */
15931Sbill deverror(bp, o1, o2)
16031Sbill register struct buf *bp;
16131Sbill {
16231Sbill 
16331Sbill 	prdev("err", bp->b_dev);
16431Sbill 	printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2);
16531Sbill }
166285Sbill 
167285Sbill #ifdef TRACE
168285Sbill dumptrc()
169285Sbill {
170285Sbill 	register char *cp;
171285Sbill 	register int pos, nch;
172285Sbill 
173285Sbill 	nch = trcprt;
174285Sbill 	if (nch < 0 || nch > TRCBUFS)
175285Sbill 		nch = TRCBUFS;
176285Sbill 	pos = (trcbufp - trcbuf) - nch;
177285Sbill 	if (pos < 0)
178285Sbill 		if (trcwrap)
179285Sbill 			pos += TRCBUFS;
180285Sbill 		else {
181285Sbill 			nch += pos;
182285Sbill 			pos = 0;
183285Sbill 		}
184285Sbill 	for (cp = &trcbuf[pos]; nch > 0; nch--) {
185285Sbill 		putchar(*cp++, 0);
186285Sbill 		if (cp >= &trcbuf[TRCBUFS])
187285Sbill 			cp = trcbuf;
188285Sbill 	}
189285Sbill }
190285Sbill #else
191285Sbill /*ARGSUSED*/
192285Sbill dumptrc(nch)
193285Sbill 	int nch;
194285Sbill {
195285Sbill 
196285Sbill }
197285Sbill #endif
198285Sbill 
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  */
2041785Sbill /*ARGSUSED*/
205285Sbill putchar(c, trace)
206285Sbill register c;
207285Sbill {
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) {
220*2172Swnj 		if (msgbuf.msg_magic != MSG_MAGIC) {
221*2172Swnj 			msgbuf.msg_bufx = 0;
222*2172Swnj 			msgbuf.msg_magic = MSG_MAGIC;
223*2172Swnj 		}
224*2172Swnj 		if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
225*2172Swnj 			msgbuf.msg_bufx = 0;
226*2172Swnj 		msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
227285Sbill 	}
228285Sbill 	if (c == 0)
229285Sbill 		return;
230285Sbill 	cnputc(c);
231285Sbill }
232