xref: /csrg-svn/sys/kern/subr_prf.c (revision 2360)
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