xref: /csrg-svn/sys/kern/subr_prf.c (revision 17594)
1*17594Skarels /*	subr_prf.c	6.5	84/12/27	*/
231Sbill 
317094Sbloom #include "param.h"
417094Sbloom #include "systm.h"
517094Sbloom #include "seg.h"
617094Sbloom #include "buf.h"
717094Sbloom #include "conf.h"
817094Sbloom #include "reboot.h"
917094Sbloom #include "vm.h"
1017094Sbloom #include "msgbuf.h"
1117094Sbloom #include "dir.h"
1217094Sbloom #include "user.h"
1317094Sbloom #include "proc.h"
1417577Sbloom #include "ioctl.h"
1517094Sbloom #include "tty.h"
1631Sbill 
1713531Ssam #ifdef vax
1813531Ssam #include "../vax/mtpr.h"
1913531Ssam #endif
2013531Ssam 
2116724Sralph #define TOCONS	0x1
2216724Sralph #define TOTTY	0x2
2316724Sralph #define TOLOG	0x4
2416724Sralph 
2531Sbill /*
2631Sbill  * In case console is off,
2731Sbill  * panicstr contains argument to last
2831Sbill  * call to panic.
2931Sbill  */
3031Sbill char	*panicstr;
3131Sbill 
3231Sbill /*
3331Sbill  * Scaled down version of C Library printf.
342781Swnj  * Used to print diagnostic information directly on console tty.
352781Swnj  * Since it is not interrupt driven, all system activities are
362781Swnj  * suspended.  Printf should not be used for chit-chat.
372781Swnj  *
382781Swnj  * One additional format: %b is supported to decode error registers.
392781Swnj  * Usage is:
402781Swnj  *	printf("reg=%b\n", regval, "<base><arg>*");
412781Swnj  * Where <base> is the output base expressed as a control character,
422781Swnj  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
432781Swnj  * characters, the first of which gives the bit number to be inspected
442781Swnj  * (origin 1), and the next characters (up to a control character, i.e.
452781Swnj  * a character <= 32), give the name of the register.  Thus
462781Swnj  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
472781Swnj  * would produce output:
48*17594Skarels  *	reg=3<BITTWO,BITONE>
4931Sbill  */
5031Sbill /*VARARGS1*/
5131Sbill printf(fmt, x1)
522781Swnj 	char *fmt;
532781Swnj 	unsigned x1;
5431Sbill {
55285Sbill 
5616724Sralph 	prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0);
5716724Sralph 	logwakeup();
58285Sbill }
59285Sbill 
602377Swnj /*
61*17594Skarels  * Uprintf prints to the current user's terminal
622781Swnj  * and does no watermark checking - (so no verbose messages).
632377Swnj  */
642377Swnj /*VARARGS1*/
652377Swnj uprintf(fmt, x1)
662781Swnj 	char *fmt;
672377Swnj 	unsigned x1;
68285Sbill {
69285Sbill 
7016724Sralph 	prf(fmt, &x1, TOTTY, u.u_ttyp);
71285Sbill }
72285Sbill 
7316724Sralph /*VARARGS2*/
7416724Sralph tprintf(ttyp, fmt, x1)
7516724Sralph 	struct tty *ttyp;
7616724Sralph 	char *fmt;
7716724Sralph 	unsigned x1;
7816724Sralph {
7916724Sralph 
8016724Sralph 	prf(fmt, &x1, TOTTY, ttyp);
8116724Sralph }
8216724Sralph 
8316724Sralph /*
8416724Sralph  * Log writes to the log buffer,
85*17594Skarels  * and guarantees not to sleep (so can be called by interrupt routines).
8616724Sralph  */
8716724Sralph /*VARARGS2*/
8816724Sralph log(level, fmt, x1)
8916724Sralph 	char *fmt;
9016724Sralph 	unsigned x1;
9116724Sralph {
9216724Sralph 	register s = splhigh();
9316724Sralph 
9416724Sralph 	putchar('<', TOLOG, (struct tty *)0);
9516724Sralph 	printn(level, 10, TOLOG, (struct tty *)0);
9616724Sralph 	putchar('>', TOLOG, (struct tty *)0);
9716724Sralph 	prf(fmt, &x1, TOLOG, (struct tty *)0);
9816724Sralph 	splx(s);
9916724Sralph 	logwakeup();
10016724Sralph }
10116724Sralph 
10216724Sralph prf(fmt, adx, flags, ttyp)
1032781Swnj 	register char *fmt;
1042781Swnj 	register u_int *adx;
10516724Sralph 	struct tty *ttyp;
106285Sbill {
1072434Swnj 	register int b, c, i;
10831Sbill 	char *s;
1092678Swnj 	int any;
11031Sbill 
11131Sbill loop:
1122377Swnj 	while ((c = *fmt++) != '%') {
11316724Sralph 		if (c == '\0')
11431Sbill 			return;
11516724Sralph 		putchar(c, flags, ttyp);
11631Sbill 	}
1172377Swnj again:
11831Sbill 	c = *fmt++;
1192781Swnj 	/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
1202377Swnj 	switch (c) {
1212377Swnj 
1222377Swnj 	case 'l':
1232377Swnj 		goto again;
1242377Swnj 	case 'x': case 'X':
1252377Swnj 		b = 16;
1262377Swnj 		goto number;
1272377Swnj 	case 'd': case 'D':
1282377Swnj 	case 'u':		/* what a joke */
1292377Swnj 		b = 10;
1302377Swnj 		goto number;
1312377Swnj 	case 'o': case 'O':
1322377Swnj 		b = 8;
1332377Swnj number:
13416724Sralph 		printn((u_long)*adx, b, flags, ttyp);
1352377Swnj 		break;
1362377Swnj 	case 'c':
1372434Swnj 		b = *adx;
1382434Swnj 		for (i = 24; i >= 0; i -= 8)
1392434Swnj 			if (c = (b >> i) & 0x7f)
14016724Sralph 				putchar(c, flags, ttyp);
1412377Swnj 		break;
1422678Swnj 	case 'b':
1432678Swnj 		b = *adx++;
1442678Swnj 		s = (char *)*adx;
14516724Sralph 		printn((u_long)b, *s++, flags, ttyp);
1462678Swnj 		any = 0;
1472678Swnj 		if (b) {
1482678Swnj 			while (i = *s++) {
1492678Swnj 				if (b & (1 << (i-1))) {
150*17594Skarels 					putchar(any? ',' : '<', flags, ttyp);
1512678Swnj 					any = 1;
1522678Swnj 					for (; (c = *s) > 32; s++)
15316724Sralph 						putchar(c, flags, ttyp);
1542678Swnj 				} else
1552678Swnj 					for (; *s > 32; s++)
1562678Swnj 						;
1572678Swnj 			}
1583878Swnj 			if (any)
15916724Sralph 				putchar('>', flags, ttyp);
1602678Swnj 		}
1612678Swnj 		break;
1622678Swnj 
1632377Swnj 	case 's':
16431Sbill 		s = (char *)*adx;
165285Sbill 		while (c = *s++)
16616724Sralph 			putchar(c, flags, ttyp);
1672377Swnj 		break;
1683736Sroot 
1693736Sroot 	case '%':
17016724Sralph 		putchar('%', flags, ttyp);
1713736Sroot 		break;
17231Sbill 	}
17331Sbill 	adx++;
17431Sbill 	goto loop;
17531Sbill }
17631Sbill 
1772781Swnj /*
1782781Swnj  * Printn prints a number n in base b.
1792781Swnj  * We don't use recursion to avoid deep kernel stacks.
1802781Swnj  */
18116724Sralph printn(n, b, flags, ttyp)
1823101Swnj 	u_long n;
18316724Sralph 	struct tty *ttyp;
18431Sbill {
1852434Swnj 	char prbuf[11];
1862377Swnj 	register char *cp;
18731Sbill 
1882377Swnj 	if (b == 10 && (int)n < 0) {
18916724Sralph 		putchar('-', flags, ttyp);
1902377Swnj 		n = (unsigned)(-(int)n);
19131Sbill 	}
1922434Swnj 	cp = prbuf;
1932377Swnj 	do {
1942377Swnj 		*cp++ = "0123456789abcdef"[n%b];
1952377Swnj 		n /= b;
1962377Swnj 	} while (n);
1972377Swnj 	do
19816724Sralph 		putchar(*--cp, flags, ttyp);
1992434Swnj 	while (cp > prbuf);
20031Sbill }
20131Sbill 
20231Sbill /*
2031184Sbill  * Panic is called on unresolvable fatal errors.
2042781Swnj  * It prints "panic: mesg", and then reboots.
2052781Swnj  * If we are called twice, then we avoid trying to
2062781Swnj  * sync the disks as this often leads to recursive panics.
20731Sbill  */
20831Sbill panic(s)
2092781Swnj 	char *s;
21031Sbill {
2115416Swnj 	int bootopt = RB_AUTOBOOT;
2122377Swnj 
2135416Swnj 	if (panicstr)
2145416Swnj 		bootopt |= RB_NOSYNC;
2159758Ssam 	else {
2169758Ssam 		panicstr = s;
2178950Sroot 	}
2183285Swnj 	printf("panic: %s\n", s);
2192781Swnj 	boot(RB_PANIC, bootopt);
22031Sbill }
22131Sbill 
22231Sbill /*
2232941Swnj  * Warn that a system table is full.
2242941Swnj  */
2252941Swnj tablefull(tab)
2262941Swnj 	char *tab;
2272941Swnj {
2282941Swnj 
2292941Swnj 	printf("%s: table is full\n", tab);
2302941Swnj }
2312941Swnj 
2322941Swnj /*
2332781Swnj  * Hard error is the preface to plaintive error messages
2342941Swnj  * about failing disk transfers.
2352781Swnj  */
2362941Swnj harderr(bp, cp)
2372678Swnj 	struct buf *bp;
2382941Swnj 	char *cp;
23931Sbill {
24031Sbill 
2412941Swnj 	printf("%s%d%c: hard error sn%d ", cp,
2422941Swnj 	    dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
24331Sbill }
2442781Swnj 
245285Sbill /*
2462377Swnj  * Print a character on console or users terminal.
247285Sbill  * If destination is console then the last MSGBUFS characters
248285Sbill  * are saved in msgbuf for inspection later.
249285Sbill  */
2501785Sbill /*ARGSUSED*/
251*17594Skarels putchar(c, flags, tp)
2522377Swnj 	register int c;
253*17594Skarels 	struct tty *tp;
254285Sbill {
255*17594Skarels 	extern struct tty cons;
256285Sbill 
25716724Sralph 	if (flags & TOTTY) {
258*17594Skarels 		if (tp == (struct tty *)NULL && (flags & TOCONS) == 0)
259*17594Skarels 			tp = &cons;
26016724Sralph 		if (tp && (tp->t_state & TS_CARR_ON)) {
2612377Swnj 			register s = spl6();
2622377Swnj 			if (c == '\n')
2634970Swnj 				(void) ttyoutput('\r', tp);
2644970Swnj 			(void) ttyoutput(c, tp);
2652360Skre 			ttstart(tp);
2662360Skre 			splx(s);
2672360Skre 		}
2682360Skre 	}
26916724Sralph 	if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177
2708966Sroot #ifdef vax
2718950Sroot 	    && mfpr(MAPEN)
2728950Sroot #endif
2738950Sroot 	    ) {
2742172Swnj 		if (msgbuf.msg_magic != MSG_MAGIC) {
27512494Ssam 			register int i;
27612494Ssam 
2772172Swnj 			msgbuf.msg_magic = MSG_MAGIC;
27816724Sralph 			msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
27912494Ssam 			for (i=0; i < MSG_BSIZE; i++)
28012494Ssam 				msgbuf.msg_bufc[i] = 0;
2812172Swnj 		}
2822172Swnj 		if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
2832172Swnj 			msgbuf.msg_bufx = 0;
2842172Swnj 		msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
285285Sbill 	}
28616724Sralph 	if ((flags & TOCONS) && c != '\0')
28716724Sralph 		cnputc(c);
288285Sbill }
289