xref: /original-bsd/sys/kern/subr_prf.c (revision 552e81d8)
1 /*	subr_prf.c	3.4	10/02/80	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/seg.h"
6 #include "../h/buf.h"
7 #include "../h/conf.h"
8 #include "../h/mtpr.h"
9 #include "../h/reboot.h"
10 
11 #ifdef TRACE
12 #define	TRCBUFS	4096
13 char	trcbuf[TRCBUFS];
14 char	*trcbufp = trcbuf;
15 int	trcwrap;
16 int	trcprt = TRCBUFS;
17 #endif
18 
19 /*
20  * In case console is off,
21  * panicstr contains argument to last
22  * call to panic.
23  */
24 
25 char	*panicstr;
26 
27 /*
28  * Scaled down version of C Library printf.
29  * Only %s %u %d (==%u) %o %x %D are recognized.
30  * Used to print diagnostic information
31  * directly on console tty.
32  * Since it is not interrupt driven,
33  * all system activities are pretty much
34  * suspended.
35  * Printf should not be used for chit-chat.
36  */
37 /*VARARGS1*/
38 printf(fmt, x1)
39 register char *fmt;
40 unsigned x1;
41 {
42 
43 	prf(fmt, &x1, 0);
44 }
45 
46 #ifdef TRACE
47 trace(fmt, x1)
48 register char *fmt;
49 unsigned x1;
50 {
51 
52 	prf(fmt, &x1, 1);
53 }
54 
55 #endif
56 
57 prf(fmt, adx, trace)
58 register char *fmt;
59 register unsigned int *adx;
60 {
61 	register c;
62 	char *s;
63 
64 loop:
65 	while((c = *fmt++) != '%') {
66 		if(c == '\0')
67 			return;
68 		putchar(c, trace);
69 	}
70 	c = *fmt++;
71 	if (c == 'X')
72 		printx((long)*adx, trace);
73 	else if (c == 'd' || c == 'u' || c == 'o' || c == 'x')
74 		printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace);
75 	else if (c == 's') {
76 		s = (char *)*adx;
77 		while (c = *s++)
78 #ifdef TRACE
79 			if (trace) {
80 				*trcbufp++ = c;
81 				if (trcbufp >= &trcbuf[TRCBUFS]) {
82 					trcbufp = trcbuf;
83 					trcwrap = 1;
84 				}
85 			} else
86 #endif
87 				putchar(c, trace);
88 	} else if (c == 'D') {
89 		printn(*(long *)adx, 10, trace);
90 		adx += (sizeof(long) / sizeof(int)) - 1;
91 	}
92 	adx++;
93 	goto loop;
94 }
95 
96 printx(x, trace)
97 long x;
98 {
99 	int i;
100 
101 	for (i = 0; i < 8; i++)
102 		putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace);
103 }
104 
105 /*
106  * Print an unsigned integer in base b.
107  */
108 printn(n, b, trace)
109 long n;
110 {
111 	register long a;
112 
113 	if (n<0) {	/* shouldn't happen */
114 		putchar('-', trace);
115 		n = -n;
116 	}
117 	if(a = n/b)
118 		printn(a, b, trace);
119 	putchar("0123456789ABCDEF"[(int)(n%b)], trace);
120 }
121 
122 /*
123  * Panic is called on unresolvable fatal errors.
124  * It syncs, prints "panic: mesg", and then reboots.
125  */
126 panic(s)
127 char *s;
128 {
129 	panicstr = s;
130 	update();
131 	printf("panic: %s\n", s);
132 	spl0();
133 	for(;;)
134 		boot(RB_PANIC, RB_AUTOBOOT);		/* 0 = automatic */
135 }
136 
137 /*
138  * prdev prints a warning message of the
139  * form "mesg on dev x/y".
140  * x and y are the major and minor parts of
141  * the device argument.
142  */
143 prdev(str, dev)
144 char *str;
145 dev_t dev;
146 {
147 
148 	printf("%s on dev %u/%u\n", str, major(dev), minor(dev));
149 }
150 
151 /*
152  * deverr prints a diagnostic from
153  * a device driver.
154  * It prints the device, block number,
155  * and an octal word (usually some error
156  * status register) passed as argument.
157  */
158 deverror(bp, o1, o2)
159 register struct buf *bp;
160 {
161 
162 	prdev("err", bp->b_dev);
163 	printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2);
164 }
165 
166 #ifdef TRACE
167 dumptrc()
168 {
169 	register char *cp;
170 	register int pos, nch;
171 
172 	nch = trcprt;
173 	if (nch < 0 || nch > TRCBUFS)
174 		nch = TRCBUFS;
175 	pos = (trcbufp - trcbuf) - nch;
176 	if (pos < 0)
177 		if (trcwrap)
178 			pos += TRCBUFS;
179 		else {
180 			nch += pos;
181 			pos = 0;
182 		}
183 	for (cp = &trcbuf[pos]; nch > 0; nch--) {
184 		putchar(*cp++, 0);
185 		if (cp >= &trcbuf[TRCBUFS])
186 			cp = trcbuf;
187 	}
188 }
189 #else
190 /*ARGSUSED*/
191 dumptrc(nch)
192 	int nch;
193 {
194 
195 }
196 #endif
197 
198 char	*msgbufp = msgbuf;	/* Next saved printf character */
199 /*
200  * Print a character on console or in internal trace buffer.
201  * If destination is console then the last MSGBUFS characters
202  * are saved in msgbuf for inspection later.
203  */
204 putchar(c, trace)
205 register c;
206 {
207 	register s, timo;
208 
209 #ifdef TRACE
210 	if (trace) {
211 		*trcbufp++ = c;
212 		if (trcbufp >= &trcbuf[TRCBUFS]) {
213 			trcbufp = trcbuf;
214 			trcwrap = 1;
215 		}
216 		return;
217 	}
218 #endif
219 	if (c != '\0' && c != '\r' && c != 0177) {
220 		*msgbufp++ = c;
221 		if (msgbufp >= &msgbuf[MSGBUFS])
222 			msgbufp = msgbuf;
223 	}
224 	if (c == 0)
225 		return;
226 	cnputc(c);
227 }
228