Commit | Line | Data |
---|---|---|
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 | |
18 | char trcbuf[TRCBUFS]; | |
19 | char *trcbufp = trcbuf; | |
20 | int trcwrap; | |
21 | int 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 | ||
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; | |
96d38f03 BJ |
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; | |
8cbb423c BJ |
65 | { |
66 | register c; | |
8cbb423c BJ |
67 | char *s; |
68 | ||
8cbb423c BJ |
69 | loop: |
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 | 101 | printx(x, trace) |
8cbb423c BJ |
102 | long 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 | 114 | printn(n, b, trace) |
c97b3362 | 115 | unsigned 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 | */ |
133 | panic(s) | |
134 | char *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 | */ | |
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 | ||
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 | |
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 | ||
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 |
210 | putchar(c, trace) |
211 | register 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*/ | |
257 | uprintf(fmt, x1) | |
258 | char *fmt; | |
259 | unsigned x1; | |
260 | { | |
261 | prf(fmt, &x1, 2); | |
262 | } |