xref: /csrg-svn/sys/kern/subr_prf.c (revision 2303)
1 /*	subr_prf.c	4.5	01/28/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 integer in base b.  If the base is ten it is condidered a
109  * signed integer otherwise it is treated as unsigned.
110  */
111 printn(n, b, trace)
112 unsigned long n;
113 {
114 	register unsigned long a;
115 	register long a1 = n;
116 
117 	if (b == 10 && a1 < 0) {
118 		putchar('-', trace);
119 		n = -a1;
120 	}
121 	if(a = n/b)
122 		printn(a, b, trace);
123 	putchar("0123456789ABCDEF"[(int)(n%b)], trace);
124 }
125 
126 /*
127  * Panic is called on unresolvable fatal errors.
128  * It syncs, prints "panic: mesg", and then reboots.
129  */
130 panic(s)
131 char *s;
132 {
133 	panicstr = s;
134 	printf("panic: %s\n", s);
135 	(void) spl0();
136 	for(;;)
137 		boot(RB_PANIC, RB_AUTOBOOT);
138 }
139 
140 /*
141  * prdev prints a warning message of the
142  * form "mesg on dev x/y".
143  * x and y are the major and minor parts of
144  * the device argument.
145  */
146 prdev(str, dev)
147 char *str;
148 dev_t dev;
149 {
150 
151 	printf("%s on dev %u/%u\n", str, major(dev), minor(dev));
152 }
153 
154 /*
155  * deverr prints a diagnostic from
156  * a device driver.
157  * It prints the device, block number,
158  * and an octal word (usually some error
159  * status register) passed as argument.
160  */
161 deverror(bp, o1, o2)
162 register struct buf *bp;
163 {
164 
165 	prdev("err", bp->b_dev);
166 	printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2);
167 }
168 
169 #ifdef TRACE
170 dumptrc()
171 {
172 	register char *cp;
173 	register int pos, nch;
174 
175 	nch = trcprt;
176 	if (nch < 0 || nch > TRCBUFS)
177 		nch = TRCBUFS;
178 	pos = (trcbufp - trcbuf) - nch;
179 	if (pos < 0)
180 		if (trcwrap)
181 			pos += TRCBUFS;
182 		else {
183 			nch += pos;
184 			pos = 0;
185 		}
186 	for (cp = &trcbuf[pos]; nch > 0; nch--) {
187 		putchar(*cp++, 0);
188 		if (cp >= &trcbuf[TRCBUFS])
189 			cp = trcbuf;
190 	}
191 }
192 #else
193 /*ARGSUSED*/
194 dumptrc(nch)
195 	int nch;
196 {
197 
198 }
199 #endif
200 
201 /*
202  * Print a character on console or in internal trace buffer.
203  * If destination is console then the last MSGBUFS characters
204  * are saved in msgbuf for inspection later.
205  */
206 /*ARGSUSED*/
207 putchar(c, trace)
208 register c;
209 {
210 
211 #ifdef TRACE
212 	if (trace) {
213 		*trcbufp++ = c;
214 		if (trcbufp >= &trcbuf[TRCBUFS]) {
215 			trcbufp = trcbuf;
216 			trcwrap = 1;
217 		}
218 		return;
219 	}
220 #endif
221 	if (c != '\0' && c != '\r' && c != 0177) {
222 		if (msgbuf.msg_magic != MSG_MAGIC) {
223 			msgbuf.msg_bufx = 0;
224 			msgbuf.msg_magic = MSG_MAGIC;
225 		}
226 		if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
227 			msgbuf.msg_bufx = 0;
228 		msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
229 	}
230 	if (c == 0)
231 		return;
232 	cnputc(c);
233 }
234