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