xref: /csrg-svn/sys/luna68k/stand/subr_prf.c (revision 57103)
1*57103Sakito /*
2*57103Sakito  * Copyright (c) 1992 OMRON Corporation.
3*57103Sakito  * Copyright (c) 1992 The Regents of the University of California.
4*57103Sakito  * All rights reserved.
5*57103Sakito  *
6*57103Sakito  * This code is derived from software contributed to Berkeley by
7*57103Sakito  * OMRON Corporation.
8*57103Sakito  *
9*57103Sakito  * %sccs.include.redist.c%
10*57103Sakito  *
11*57103Sakito  *	@(#)subr_prf.c	7.1 (Berkeley) 12/13/92
12*57103Sakito  */
13*57103Sakito 
14*57103Sakito #include <sys/param.h>
15*57103Sakito #include <luna68k/stand/romvec.h>
16*57103Sakito 
17*57103Sakito #define TOCONS	0x1
18*57103Sakito #define TOTTY	0x2
19*57103Sakito #define TOLOG	0x4
20*57103Sakito 
21*57103Sakito /*
22*57103Sakito  * In case console is off,
23*57103Sakito  * panicstr contains argument to last
24*57103Sakito  * call to panic.
25*57103Sakito  */
26*57103Sakito char	*panicstr;
27*57103Sakito 
28*57103Sakito extern	cnputc();			/* standard console putc */
29*57103Sakito int	(*v_putc)() = cnputc;		/* routine to putc on virtual console */
30*57103Sakito 
31*57103Sakito /*
32*57103Sakito  * Scaled down version of C Library printf.
33*57103Sakito  * Used to print diagnostic information directly on console tty.
34*57103Sakito  * Since it is not interrupt driven, all system activities are
35*57103Sakito  * suspended.  Printf should not be used for chit-chat.
36*57103Sakito  *
37*57103Sakito  * One additional format: %b is supported to decode error registers.
38*57103Sakito  * Usage is:
39*57103Sakito  *	printf("reg=%b\n", regval, "<base><arg>*");
40*57103Sakito  * Where <base> is the output base expressed as a control character,
41*57103Sakito  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
42*57103Sakito  * characters, the first of which gives the bit number to be inspected
43*57103Sakito  * (origin 1), and the next characters (up to a control character, i.e.
44*57103Sakito  * a character <= 32), give the name of the register.  Thus
45*57103Sakito  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
46*57103Sakito  * would produce output:
47*57103Sakito  *	reg=3<BITTWO,BITONE>
48*57103Sakito  *
49*57103Sakito  * Another additional format: %r is used to pass an additional format string
50*57103Sakito  * and argument list recursively.  Usage is typically:
51*57103Sakito  *
52*57103Sakito  * fn(otherstuff, fmt [, arg1, ... ] )
53*57103Sakito  *	char *fmt;
54*57103Sakito  *	u_int arg1, ...;
55*57103Sakito  *
56*57103Sakito  *	printf("prefix: %r, other stuff\n", fmt, &arg1);
57*57103Sakito  */
58*57103Sakito #if defined(tahoe)
59*57103Sakito int	consintr;
60*57103Sakito #endif
61*57103Sakito 
62*57103Sakito /*VARARGS1*/
63*57103Sakito printf(fmt, x1)
64*57103Sakito 	char *fmt;
65*57103Sakito 	unsigned x1;
66*57103Sakito {
67*57103Sakito #if defined(tahoe)
68*57103Sakito 	register int savintr;
69*57103Sakito 
70*57103Sakito 	savintr = consintr, consintr = 0;	/* disable interrupts */
71*57103Sakito #endif
72*57103Sakito 	prf(fmt, &x1, TOCONS        , (struct tty *)NULL);
73*57103Sakito 
74*57103Sakito 
75*57103Sakito #if defined(tahoe)
76*57103Sakito 	consintr = savintr;			/* reenable interrupts */
77*57103Sakito #endif
78*57103Sakito }
79*57103Sakito 
80*57103Sakito prf(fmt, adx, flags, ttyp)
81*57103Sakito 	register char *fmt;
82*57103Sakito 	register u_int *adx;
83*57103Sakito 	struct tty *ttyp;
84*57103Sakito {
85*57103Sakito 	register int b, c, i;
86*57103Sakito 	char *s;
87*57103Sakito 	int any;
88*57103Sakito 
89*57103Sakito loop:
90*57103Sakito 	while ((c = *fmt++) != '%') {
91*57103Sakito 		if (c == '\0')
92*57103Sakito 			return;
93*57103Sakito 		putchar(c, flags, ttyp);
94*57103Sakito 	}
95*57103Sakito again:
96*57103Sakito 	c = *fmt++;
97*57103Sakito 	/* THIS CODE IS MACHINE DEPENDENT IN HANDLING %l? AND %c */
98*57103Sakito 	switch (c) {
99*57103Sakito 
100*57103Sakito 	case 'l':
101*57103Sakito 		goto again;
102*57103Sakito 	case 'x': case 'X':
103*57103Sakito 		b = 16;
104*57103Sakito 		goto number;
105*57103Sakito 	case 'd': case 'D':
106*57103Sakito 		b = -10;
107*57103Sakito 		goto number;
108*57103Sakito 	case 'u':
109*57103Sakito 		b = 10;
110*57103Sakito 		goto number;
111*57103Sakito 	case 'o': case 'O':
112*57103Sakito 		b = 8;
113*57103Sakito number:
114*57103Sakito 		printn((u_long)*adx, b, flags, ttyp);
115*57103Sakito 		break;
116*57103Sakito 	case 'c':
117*57103Sakito 		b = *adx;
118*57103Sakito #if BYTE_ORDER == LITTLE_ENDIAN
119*57103Sakito 		for (i = 24; i >= 0; i -= 8)
120*57103Sakito 			if (c = (b >> i) & 0x7f)
121*57103Sakito 				putchar(c, flags, ttyp);
122*57103Sakito #endif
123*57103Sakito #if BYTE_ORDER == BIG_ENDIAN
124*57103Sakito 		if (c = (b & 0x7f))
125*57103Sakito 			putchar(c, flags, ttyp);
126*57103Sakito #endif
127*57103Sakito 		break;
128*57103Sakito 	case 'b':
129*57103Sakito 		b = *adx++;
130*57103Sakito 		s = (char *)*adx;
131*57103Sakito 		printn((u_long)b, *s++, flags, ttyp);
132*57103Sakito 		any = 0;
133*57103Sakito 		if (b) {
134*57103Sakito 			while (i = *s++) {
135*57103Sakito 				if (b & (1 << (i-1))) {
136*57103Sakito 					putchar(any ? ',' : '<', flags, ttyp);
137*57103Sakito 					any = 1;
138*57103Sakito 					for (; (c = *s) > 32; s++)
139*57103Sakito 						putchar(c, flags, ttyp);
140*57103Sakito 				} else
141*57103Sakito 					for (; *s > 32; s++)
142*57103Sakito 						;
143*57103Sakito 			}
144*57103Sakito 			if (any)
145*57103Sakito 				putchar('>', flags, ttyp);
146*57103Sakito 		}
147*57103Sakito 		break;
148*57103Sakito 
149*57103Sakito 	case 's':
150*57103Sakito 		s = (char *)*adx;
151*57103Sakito 		while (c = *s++)
152*57103Sakito 			putchar(c, flags, ttyp);
153*57103Sakito 		break;
154*57103Sakito 
155*57103Sakito 	case 'r':
156*57103Sakito 		s = (char *)*adx++;
157*57103Sakito 		prf(s, (u_int *)*adx, flags, ttyp);
158*57103Sakito 		break;
159*57103Sakito 
160*57103Sakito 	case '%':
161*57103Sakito 		putchar('%', flags, ttyp);
162*57103Sakito 		break;
163*57103Sakito 
164*57103Sakito 	default:
165*57103Sakito 		break;
166*57103Sakito 	}
167*57103Sakito 	adx++;
168*57103Sakito 	goto loop;
169*57103Sakito }
170*57103Sakito 
171*57103Sakito /*
172*57103Sakito  * Printn prints a number n in base b.
173*57103Sakito  * We don't use recursion to avoid deep kernel stacks.
174*57103Sakito  */
175*57103Sakito printn(n, b, flags, ttyp)
176*57103Sakito 	u_long n;
177*57103Sakito 	struct tty *ttyp;
178*57103Sakito {
179*57103Sakito 	char prbuf[11];
180*57103Sakito 	register char *cp;
181*57103Sakito 
182*57103Sakito 	if (b == -10) {
183*57103Sakito 		if ((int)n < 0) {
184*57103Sakito 			putchar('-', flags, ttyp);
185*57103Sakito 			n = (unsigned)(-(int)n);
186*57103Sakito 		}
187*57103Sakito 		b = -b;
188*57103Sakito 	}
189*57103Sakito 	cp = prbuf;
190*57103Sakito 	do {
191*57103Sakito 		*cp++ = "0123456789abcdef"[n%b];
192*57103Sakito 		n /= b;
193*57103Sakito 	} while (n);
194*57103Sakito 	do
195*57103Sakito 		putchar(*--cp, flags, ttyp);
196*57103Sakito 	while (cp > prbuf);
197*57103Sakito }
198*57103Sakito 
199*57103Sakito /*
200*57103Sakito  * Panic is called on unresolvable fatal errors.
201*57103Sakito  * It prints "panic: mesg", and then reboots.
202*57103Sakito  * If we are called twice, then we avoid trying to
203*57103Sakito  * sync the disks as this often leads to recursive panics.
204*57103Sakito  */
205*57103Sakito panic(s)
206*57103Sakito 	char *s;
207*57103Sakito {
208*57103Sakito 	if (!panicstr) {
209*57103Sakito 		panicstr = s;
210*57103Sakito 	}
211*57103Sakito 	printf("panic: %s\n", s);
212*57103Sakito 
213*57103Sakito 	ROM_abort();
214*57103Sakito }
215*57103Sakito 
216*57103Sakito /*
217*57103Sakito  * Print a character on console or users terminal.
218*57103Sakito  * If destination is console then the last MSGBUFS characters
219*57103Sakito  * are saved in msgbuf for inspection later.
220*57103Sakito  */
221*57103Sakito /*ARGSUSED*/
222*57103Sakito putchar(c, flags, ttyp)
223*57103Sakito 	register int c;
224*57103Sakito 	struct tty *ttyp;
225*57103Sakito {
226*57103Sakito 
227*57103Sakito 
228*57103Sakito 
229*57103Sakito 
230*57103Sakito 
231*57103Sakito 
232*57103Sakito 
233*57103Sakito 
234*57103Sakito 
235*57103Sakito 
236*57103Sakito 
237*57103Sakito 
238*57103Sakito 
239*57103Sakito 
240*57103Sakito 
241*57103Sakito 
242*57103Sakito 
243*57103Sakito 
244*57103Sakito 
245*57103Sakito 
246*57103Sakito 
247*57103Sakito 
248*57103Sakito 
249*57103Sakito 
250*57103Sakito 
251*57103Sakito 
252*57103Sakito 		(*v_putc)(c);
253*57103Sakito }
254