xref: /csrg-svn/sys/kern/subr_prf.c (revision 17094)
1*17094Sbloom /*	subr_prf.c	6.3	84/08/29	*/
231Sbill 
3*17094Sbloom #include "param.h"
4*17094Sbloom #include "systm.h"
5*17094Sbloom #include "seg.h"
6*17094Sbloom #include "buf.h"
7*17094Sbloom #include "conf.h"
8*17094Sbloom #include "reboot.h"
9*17094Sbloom #include "vm.h"
10*17094Sbloom #include "msgbuf.h"
11*17094Sbloom #include "dir.h"
12*17094Sbloom #include "user.h"
13*17094Sbloom #include "proc.h"
14*17094Sbloom #include "tty.h"
1531Sbill 
1613531Ssam #ifdef vax
1713531Ssam #include "../vax/mtpr.h"
1813531Ssam #endif
1913531Ssam 
2016724Sralph #define TOCONS	0x1
2116724Sralph #define TOTTY	0x2
2216724Sralph #define TOLOG	0x4
2316724Sralph 
2431Sbill /*
2531Sbill  * In case console is off,
2631Sbill  * panicstr contains argument to last
2731Sbill  * call to panic.
2831Sbill  */
2931Sbill char	*panicstr;
3031Sbill 
3131Sbill /*
3231Sbill  * Scaled down version of C Library printf.
332781Swnj  * Used to print diagnostic information directly on console tty.
342781Swnj  * Since it is not interrupt driven, all system activities are
352781Swnj  * suspended.  Printf should not be used for chit-chat.
362781Swnj  *
372781Swnj  * One additional format: %b is supported to decode error registers.
382781Swnj  * Usage is:
392781Swnj  *	printf("reg=%b\n", regval, "<base><arg>*");
402781Swnj  * Where <base> is the output base expressed as a control character,
412781Swnj  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
422781Swnj  * characters, the first of which gives the bit number to be inspected
432781Swnj  * (origin 1), and the next characters (up to a control character, i.e.
442781Swnj  * a character <= 32), give the name of the register.  Thus
452781Swnj  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
462781Swnj  * would produce output:
472781Swnj  *	reg=2<BITTWO,BITONE>
4831Sbill  */
4931Sbill /*VARARGS1*/
5031Sbill printf(fmt, x1)
512781Swnj 	char *fmt;
522781Swnj 	unsigned x1;
5331Sbill {
54285Sbill 
5516724Sralph 	prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0);
5616724Sralph 	logwakeup();
57285Sbill }
58285Sbill 
592377Swnj /*
602781Swnj  * Uprintf prints to the current user's terminal,
612781Swnj  * guarantees not to sleep (so can be called by interrupt routines)
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,
8516724Sralph  * guarantees not to sleep (so can be called by interrupt routines)
8616724Sralph  * and does no watermark checking - (so no verbose messages).
8716724Sralph  */
8816724Sralph /*VARARGS2*/
8916724Sralph log(level, fmt, x1)
9016724Sralph 	char *fmt;
9116724Sralph 	unsigned x1;
9216724Sralph {
9316724Sralph 	register s = splhigh();
9416724Sralph 
9516724Sralph 	putchar('<', TOLOG, (struct tty *)0);
9616724Sralph 	printn(level, 10, TOLOG, (struct tty *)0);
9716724Sralph 	putchar('>', TOLOG, (struct tty *)0);
9816724Sralph 	prf(fmt, &x1, TOLOG, (struct tty *)0);
9916724Sralph 	splx(s);
10016724Sralph 	logwakeup();
10116724Sralph }
10216724Sralph 
10316724Sralph prf(fmt, adx, flags, ttyp)
1042781Swnj 	register char *fmt;
1052781Swnj 	register u_int *adx;
10616724Sralph 	struct tty *ttyp;
107285Sbill {
1082434Swnj 	register int b, c, i;
10931Sbill 	char *s;
1102678Swnj 	int any;
11131Sbill 
11231Sbill loop:
1132377Swnj 	while ((c = *fmt++) != '%') {
11416724Sralph 		if (c == '\0')
11531Sbill 			return;
11616724Sralph 		putchar(c, flags, ttyp);
11731Sbill 	}
1182377Swnj again:
11931Sbill 	c = *fmt++;
1202781Swnj 	/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
1212377Swnj 	switch (c) {
1222377Swnj 
1232377Swnj 	case 'l':
1242377Swnj 		goto again;
1252377Swnj 	case 'x': case 'X':
1262377Swnj 		b = 16;
1272377Swnj 		goto number;
1282377Swnj 	case 'd': case 'D':
1292377Swnj 	case 'u':		/* what a joke */
1302377Swnj 		b = 10;
1312377Swnj 		goto number;
1322377Swnj 	case 'o': case 'O':
1332377Swnj 		b = 8;
1342377Swnj number:
13516724Sralph 		printn((u_long)*adx, b, flags, ttyp);
1362377Swnj 		break;
1372377Swnj 	case 'c':
1382434Swnj 		b = *adx;
1392434Swnj 		for (i = 24; i >= 0; i -= 8)
1402434Swnj 			if (c = (b >> i) & 0x7f)
14116724Sralph 				putchar(c, flags, ttyp);
1422377Swnj 		break;
1432678Swnj 	case 'b':
1442678Swnj 		b = *adx++;
1452678Swnj 		s = (char *)*adx;
14616724Sralph 		printn((u_long)b, *s++, flags, ttyp);
1472678Swnj 		any = 0;
1482678Swnj 		if (b) {
14916724Sralph 			putchar('<', flags, ttyp);
1502678Swnj 			while (i = *s++) {
1512678Swnj 				if (b & (1 << (i-1))) {
1522678Swnj 					if (any)
15316724Sralph 						putchar(',', flags, ttyp);
1542678Swnj 					any = 1;
1552678Swnj 					for (; (c = *s) > 32; s++)
15616724Sralph 						putchar(c, flags, ttyp);
1572678Swnj 				} else
1582678Swnj 					for (; *s > 32; s++)
1592678Swnj 						;
1602678Swnj 			}
1613878Swnj 			if (any)
16216724Sralph 				putchar('>', flags, ttyp);
1632678Swnj 		}
1642678Swnj 		break;
1652678Swnj 
1662377Swnj 	case 's':
16731Sbill 		s = (char *)*adx;
168285Sbill 		while (c = *s++)
16916724Sralph 			putchar(c, flags, ttyp);
1702377Swnj 		break;
1713736Sroot 
1723736Sroot 	case '%':
17316724Sralph 		putchar('%', flags, ttyp);
1743736Sroot 		break;
17531Sbill 	}
17631Sbill 	adx++;
17731Sbill 	goto loop;
17831Sbill }
17931Sbill 
1802781Swnj /*
1812781Swnj  * Printn prints a number n in base b.
1822781Swnj  * We don't use recursion to avoid deep kernel stacks.
1832781Swnj  */
18416724Sralph printn(n, b, flags, ttyp)
1853101Swnj 	u_long n;
18616724Sralph 	struct tty *ttyp;
18731Sbill {
1882434Swnj 	char prbuf[11];
1892377Swnj 	register char *cp;
19031Sbill 
1912377Swnj 	if (b == 10 && (int)n < 0) {
19216724Sralph 		putchar('-', flags, ttyp);
1932377Swnj 		n = (unsigned)(-(int)n);
19431Sbill 	}
1952434Swnj 	cp = prbuf;
1962377Swnj 	do {
1972377Swnj 		*cp++ = "0123456789abcdef"[n%b];
1982377Swnj 		n /= b;
1992377Swnj 	} while (n);
2002377Swnj 	do
20116724Sralph 		putchar(*--cp, flags, ttyp);
2022434Swnj 	while (cp > prbuf);
20331Sbill }
20431Sbill 
20531Sbill /*
2061184Sbill  * Panic is called on unresolvable fatal errors.
2072781Swnj  * It prints "panic: mesg", and then reboots.
2082781Swnj  * If we are called twice, then we avoid trying to
2092781Swnj  * sync the disks as this often leads to recursive panics.
21031Sbill  */
21131Sbill panic(s)
2122781Swnj 	char *s;
21331Sbill {
2145416Swnj 	int bootopt = RB_AUTOBOOT;
2152377Swnj 
2165416Swnj 	if (panicstr)
2175416Swnj 		bootopt |= RB_NOSYNC;
2189758Ssam 	else {
2199758Ssam 		panicstr = s;
2208950Sroot 	}
2213285Swnj 	printf("panic: %s\n", s);
2222781Swnj 	boot(RB_PANIC, bootopt);
22331Sbill }
22431Sbill 
22531Sbill /*
2262941Swnj  * Warn that a system table is full.
2272941Swnj  */
2282941Swnj tablefull(tab)
2292941Swnj 	char *tab;
2302941Swnj {
2312941Swnj 
2322941Swnj 	printf("%s: table is full\n", tab);
2332941Swnj }
2342941Swnj 
2352941Swnj /*
2362781Swnj  * Hard error is the preface to plaintive error messages
2372941Swnj  * about failing disk transfers.
2382781Swnj  */
2392941Swnj harderr(bp, cp)
2402678Swnj 	struct buf *bp;
2412941Swnj 	char *cp;
24231Sbill {
24331Sbill 
2442941Swnj 	printf("%s%d%c: hard error sn%d ", cp,
2452941Swnj 	    dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
24631Sbill }
2472781Swnj 
248285Sbill /*
2492377Swnj  * Print a character on console or users terminal.
250285Sbill  * If destination is console then the last MSGBUFS characters
251285Sbill  * are saved in msgbuf for inspection later.
252285Sbill  */
2531785Sbill /*ARGSUSED*/
25416724Sralph putchar(c, flags, ttyp)
2552377Swnj 	register int c;
25616724Sralph 	struct tty *ttyp;
257285Sbill {
258285Sbill 
25916724Sralph 	if (flags & TOTTY) {
26016724Sralph 		register struct tty *tp = ttyp;
2612360Skre 
26216724Sralph 		if (tp && (tp->t_state & TS_CARR_ON)) {
2632377Swnj 			register s = spl6();
2642377Swnj 			if (c == '\n')
2654970Swnj 				(void) ttyoutput('\r', tp);
2664970Swnj 			(void) ttyoutput(c, tp);
2672360Skre 			ttstart(tp);
2682360Skre 			splx(s);
2692360Skre 		}
2702360Skre 	}
27116724Sralph 	if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177
2728966Sroot #ifdef vax
2738950Sroot 	    && mfpr(MAPEN)
2748950Sroot #endif
2758950Sroot 	    ) {
2762172Swnj 		if (msgbuf.msg_magic != MSG_MAGIC) {
27712494Ssam 			register int i;
27812494Ssam 
2792172Swnj 			msgbuf.msg_magic = MSG_MAGIC;
28016724Sralph 			msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
28112494Ssam 			for (i=0; i < MSG_BSIZE; i++)
28212494Ssam 				msgbuf.msg_bufc[i] = 0;
2832172Swnj 		}
2842172Swnj 		if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
2852172Swnj 			msgbuf.msg_bufx = 0;
2862172Swnj 		msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
287285Sbill 	}
28816724Sralph 	if ((flags & TOCONS) && c != '\0')
28916724Sralph 		cnputc(c);
290285Sbill }
291