(no message)
[unix-history] / usr / src / sys / kern / subr_prf.c
CommitLineData
d11b28dc 1/* subr_prf.c 4.6 %G% */
8cbb423c
BJ
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"
96d38f03 8#include "../h/mtpr.h"
0dc06be8 9#include "../h/reboot.h"
90f8d91f
BJ
10#include "../h/vm.h"
11#include "../h/msgbuf.h"
d11b28dc
RE
12#include "../h/dir.h"
13#include "../h/user.h"
14#include "../h/tty.h"
96d38f03
BJ
15
16#ifdef TRACE
17#define TRCBUFS 4096
18char trcbuf[TRCBUFS];
19char *trcbufp = trcbuf;
20int trcwrap;
21int trcprt = TRCBUFS;
22#endif
8cbb423c
BJ
23
24/*
25 * In case console is off,
26 * panicstr contains argument to last
27 * call to panic.
28 */
29
30char *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*/
43printf(fmt, x1)
44register char *fmt;
45unsigned x1;
96d38f03
BJ
46{
47
48 prf(fmt, &x1, 0);
49}
50
51#ifdef TRACE
52trace(fmt, x1)
53register char *fmt;
54unsigned x1;
55{
56
57 prf(fmt, &x1, 1);
58}
59
60#endif
61
62prf(fmt, adx, trace)
63register char *fmt;
64register unsigned int *adx;
8cbb423c
BJ
65{
66 register c;
8cbb423c
BJ
67 char *s;
68
8cbb423c
BJ
69loop:
70 while((c = *fmt++) != '%') {
71 if(c == '\0')
72 return;
96d38f03 73 putchar(c, trace);
8cbb423c
BJ
74 }
75 c = *fmt++;
96d38f03
BJ
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') {
8cbb423c 81 s = (char *)*adx;
96d38f03
BJ
82 while (c = *s++)
83#ifdef TRACE
d11b28dc 84 if (trace == 1) {
96d38f03
BJ
85 *trcbufp++ = c;
86 if (trcbufp >= &trcbuf[TRCBUFS]) {
87 trcbufp = trcbuf;
88 trcwrap = 1;
89 }
90 } else
91#endif
92 putchar(c, trace);
8cbb423c 93 } else if (c == 'D') {
96d38f03 94 printn(*(long *)adx, 10, trace);
8cbb423c
BJ
95 adx += (sizeof(long) / sizeof(int)) - 1;
96 }
97 adx++;
98 goto loop;
99}
100
96d38f03 101printx(x, trace)
8cbb423c
BJ
102long x;
103{
104 int i;
105
106 for (i = 0; i < 8; i++)
96d38f03 107 putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace);
8cbb423c
BJ
108}
109
110/*
c97b3362
MT
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.
8cbb423c 113 */
96d38f03 114printn(n, b, trace)
c97b3362 115unsigned long n;
8cbb423c 116{
c97b3362
MT
117 register unsigned long a;
118 register long a1 = n;
8cbb423c 119
c97b3362 120 if (b == 10 && a1 < 0) {
96d38f03 121 putchar('-', trace);
c97b3362 122 n = -a1;
8cbb423c
BJ
123 }
124 if(a = n/b)
96d38f03
BJ
125 printn(a, b, trace);
126 putchar("0123456789ABCDEF"[(int)(n%b)], trace);
8cbb423c
BJ
127}
128
129/*
0dc06be8
BJ
130 * Panic is called on unresolvable fatal errors.
131 * It syncs, prints "panic: mesg", and then reboots.
8cbb423c
BJ
132 */
133panic(s)
134char *s;
135{
136 panicstr = s;
8cbb423c 137 printf("panic: %s\n", s);
934e4ecf 138 (void) spl0();
8cbb423c 139 for(;;)
9bd7e93d 140 boot(RB_PANIC, RB_AUTOBOOT);
8cbb423c
BJ
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 */
149prdev(str, dev)
150char *str;
151dev_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 */
164deverror(bp, o1, o2)
165register struct buf *bp;
166{
167
d11b28dc
RE
168 printf("bn=%d er=%x,%x", bp->b_blkno, o1,o2);
169 prdev("", bp->b_dev);
8cbb423c 170}
96d38f03
BJ
171
172#ifdef TRACE
173dumptrc()
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*/
197dumptrc(nch)
198 int nch;
199{
200
201}
202#endif
203
96d38f03
BJ
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 */
49c84d3f 209/*ARGSUSED*/
96d38f03
BJ
210putchar(c, trace)
211register c;
212{
96d38f03 213
d11b28dc
RE
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 }
96d38f03
BJ
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) {
90f8d91f
BJ
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;
96d38f03
BJ
244 }
245 if (c == 0)
246 return;
247 cnputc(c);
248}
d11b28dc
RE
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*/
257uprintf(fmt, x1)
258char *fmt;
259unsigned x1;
260{
261 prf(fmt, &x1, 2);
262}