xref: /original-bsd/sys/kern/subr_prf.c (revision ba72ef4c)
1 /*	subr_prf.c	3.5	10/11/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 	printf("panic: %s\n", s);
131 	spl0();
132 	for(;;)
133 		boot(RB_PANIC, RB_AUTOBOOT);
134 }
135 
136 /*
137  * prdev prints a warning message of the
138  * form "mesg on dev x/y".
139  * x and y are the major and minor parts of
140  * the device argument.
141  */
142 prdev(str, dev)
143 char *str;
144 dev_t dev;
145 {
146 
147 	printf("%s on dev %u/%u\n", str, major(dev), minor(dev));
148 }
149 
150 /*
151  * deverr prints a diagnostic from
152  * a device driver.
153  * It prints the device, block number,
154  * and an octal word (usually some error
155  * status register) passed as argument.
156  */
157 deverror(bp, o1, o2)
158 register struct buf *bp;
159 {
160 
161 	prdev("err", bp->b_dev);
162 	printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2);
163 }
164 
165 #ifdef TRACE
166 dumptrc()
167 {
168 	register char *cp;
169 	register int pos, nch;
170 
171 	nch = trcprt;
172 	if (nch < 0 || nch > TRCBUFS)
173 		nch = TRCBUFS;
174 	pos = (trcbufp - trcbuf) - nch;
175 	if (pos < 0)
176 		if (trcwrap)
177 			pos += TRCBUFS;
178 		else {
179 			nch += pos;
180 			pos = 0;
181 		}
182 	for (cp = &trcbuf[pos]; nch > 0; nch--) {
183 		putchar(*cp++, 0);
184 		if (cp >= &trcbuf[TRCBUFS])
185 			cp = trcbuf;
186 	}
187 }
188 #else
189 /*ARGSUSED*/
190 dumptrc(nch)
191 	int nch;
192 {
193 
194 }
195 #endif
196 
197 char	*msgbufp = msgbuf;	/* Next saved printf character */
198 /*
199  * Print a character on console or in internal trace buffer.
200  * If destination is console then the last MSGBUFS characters
201  * are saved in msgbuf for inspection later.
202  */
203 putchar(c, trace)
204 register c;
205 {
206 	register s, timo;
207 
208 #ifdef TRACE
209 	if (trace) {
210 		*trcbufp++ = c;
211 		if (trcbufp >= &trcbuf[TRCBUFS]) {
212 			trcbufp = trcbuf;
213 			trcwrap = 1;
214 		}
215 		return;
216 	}
217 #endif
218 	if (c != '\0' && c != '\r' && c != 0177) {
219 		*msgbufp++ = c;
220 		if (msgbufp >= &msgbuf[MSGBUFS])
221 			msgbufp = msgbuf;
222 	}
223 	if (c == 0)
224 		return;
225 	cnputc(c);
226 }
227