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