Commit | Line | Data |
---|---|---|
94368568 | 1 | /* subr_prf.c 6.3 84/08/29 */ |
8cbb423c | 2 | |
94368568 JB |
3 | #include "param.h" |
4 | #include "systm.h" | |
5 | #include "seg.h" | |
6 | #include "buf.h" | |
7 | #include "conf.h" | |
8 | #include "reboot.h" | |
9 | #include "vm.h" | |
10 | #include "msgbuf.h" | |
11 | #include "dir.h" | |
12 | #include "user.h" | |
13 | #include "proc.h" | |
14 | #include "tty.h" | |
96d38f03 | 15 | |
e3d5bfde SL |
16 | #ifdef vax |
17 | #include "../vax/mtpr.h" | |
18 | #endif | |
19 | ||
34ef3482 RC |
20 | #define TOCONS 0x1 |
21 | #define TOTTY 0x2 | |
22 | #define TOLOG 0x4 | |
23 | ||
8cbb423c BJ |
24 | /* |
25 | * In case console is off, | |
26 | * panicstr contains argument to last | |
27 | * call to panic. | |
28 | */ | |
8cbb423c BJ |
29 | char *panicstr; |
30 | ||
31 | /* | |
32 | * Scaled down version of C Library printf. | |
b725a0ca BJ |
33 | * Used to print diagnostic information directly on console tty. |
34 | * Since it is not interrupt driven, all system activities are | |
35 | * suspended. Printf should not be used for chit-chat. | |
36 | * | |
37 | * One additional format: %b is supported to decode error registers. | |
38 | * Usage is: | |
39 | * printf("reg=%b\n", regval, "<base><arg>*"); | |
40 | * Where <base> is the output base expressed as a control character, | |
41 | * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of | |
42 | * characters, the first of which gives the bit number to be inspected | |
43 | * (origin 1), and the next characters (up to a control character, i.e. | |
44 | * a character <= 32), give the name of the register. Thus | |
45 | * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); | |
46 | * would produce output: | |
47 | * reg=2<BITTWO,BITONE> | |
8cbb423c BJ |
48 | */ |
49 | /*VARARGS1*/ | |
50 | printf(fmt, x1) | |
b725a0ca BJ |
51 | char *fmt; |
52 | unsigned x1; | |
96d38f03 BJ |
53 | { |
54 | ||
34ef3482 RC |
55 | prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0); |
56 | logwakeup(); | |
96d38f03 BJ |
57 | } |
58 | ||
843267b1 | 59 | /* |
b725a0ca BJ |
60 | * Uprintf prints to the current user's terminal, |
61 | * guarantees not to sleep (so can be called by interrupt routines) | |
62 | * and does no watermark checking - (so no verbose messages). | |
843267b1 BJ |
63 | */ |
64 | /*VARARGS1*/ | |
65 | uprintf(fmt, x1) | |
b725a0ca | 66 | char *fmt; |
843267b1 | 67 | unsigned x1; |
96d38f03 BJ |
68 | { |
69 | ||
34ef3482 RC |
70 | prf(fmt, &x1, TOTTY, u.u_ttyp); |
71 | } | |
72 | ||
73 | /*VARARGS2*/ | |
74 | tprintf(ttyp, fmt, x1) | |
75 | struct tty *ttyp; | |
76 | char *fmt; | |
77 | unsigned x1; | |
78 | { | |
79 | ||
80 | prf(fmt, &x1, TOTTY, ttyp); | |
81 | } | |
82 | ||
83 | /* | |
84 | * Log writes to the log buffer, | |
85 | * guarantees not to sleep (so can be called by interrupt routines) | |
86 | * and does no watermark checking - (so no verbose messages). | |
87 | */ | |
88 | /*VARARGS2*/ | |
89 | log(level, fmt, x1) | |
90 | char *fmt; | |
91 | unsigned x1; | |
92 | { | |
93 | register s = splhigh(); | |
94 | ||
95 | putchar('<', TOLOG, (struct tty *)0); | |
96 | printn(level, 10, TOLOG, (struct tty *)0); | |
97 | putchar('>', TOLOG, (struct tty *)0); | |
98 | prf(fmt, &x1, TOLOG, (struct tty *)0); | |
99 | splx(s); | |
100 | logwakeup(); | |
96d38f03 BJ |
101 | } |
102 | ||
34ef3482 | 103 | prf(fmt, adx, flags, ttyp) |
b725a0ca BJ |
104 | register char *fmt; |
105 | register u_int *adx; | |
34ef3482 | 106 | struct tty *ttyp; |
8cbb423c | 107 | { |
d5726689 | 108 | register int b, c, i; |
8cbb423c | 109 | char *s; |
3c79e4ff | 110 | int any; |
8cbb423c | 111 | |
8cbb423c | 112 | loop: |
843267b1 | 113 | while ((c = *fmt++) != '%') { |
34ef3482 | 114 | if (c == '\0') |
8cbb423c | 115 | return; |
34ef3482 | 116 | putchar(c, flags, ttyp); |
8cbb423c | 117 | } |
843267b1 | 118 | again: |
8cbb423c | 119 | c = *fmt++; |
b725a0ca | 120 | /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ |
843267b1 BJ |
121 | switch (c) { |
122 | ||
123 | case 'l': | |
124 | goto again; | |
125 | case 'x': case 'X': | |
126 | b = 16; | |
127 | goto number; | |
128 | case 'd': case 'D': | |
129 | case 'u': /* what a joke */ | |
130 | b = 10; | |
131 | goto number; | |
132 | case 'o': case 'O': | |
133 | b = 8; | |
134 | number: | |
34ef3482 | 135 | printn((u_long)*adx, b, flags, ttyp); |
843267b1 BJ |
136 | break; |
137 | case 'c': | |
d5726689 BJ |
138 | b = *adx; |
139 | for (i = 24; i >= 0; i -= 8) | |
140 | if (c = (b >> i) & 0x7f) | |
34ef3482 | 141 | putchar(c, flags, ttyp); |
843267b1 | 142 | break; |
3c79e4ff BJ |
143 | case 'b': |
144 | b = *adx++; | |
145 | s = (char *)*adx; | |
34ef3482 | 146 | printn((u_long)b, *s++, flags, ttyp); |
3c79e4ff BJ |
147 | any = 0; |
148 | if (b) { | |
34ef3482 | 149 | putchar('<', flags, ttyp); |
3c79e4ff BJ |
150 | while (i = *s++) { |
151 | if (b & (1 << (i-1))) { | |
152 | if (any) | |
34ef3482 | 153 | putchar(',', flags, ttyp); |
3c79e4ff BJ |
154 | any = 1; |
155 | for (; (c = *s) > 32; s++) | |
34ef3482 | 156 | putchar(c, flags, ttyp); |
3c79e4ff BJ |
157 | } else |
158 | for (; *s > 32; s++) | |
159 | ; | |
160 | } | |
1ce587f2 | 161 | if (any) |
34ef3482 | 162 | putchar('>', flags, ttyp); |
3c79e4ff BJ |
163 | } |
164 | break; | |
165 | ||
843267b1 | 166 | case 's': |
8cbb423c | 167 | s = (char *)*adx; |
96d38f03 | 168 | while (c = *s++) |
34ef3482 | 169 | putchar(c, flags, ttyp); |
843267b1 | 170 | break; |
2bb8d359 BJ |
171 | |
172 | case '%': | |
34ef3482 | 173 | putchar('%', flags, ttyp); |
2bb8d359 | 174 | break; |
8cbb423c BJ |
175 | } |
176 | adx++; | |
177 | goto loop; | |
178 | } | |
179 | ||
b725a0ca BJ |
180 | /* |
181 | * Printn prints a number n in base b. | |
182 | * We don't use recursion to avoid deep kernel stacks. | |
183 | */ | |
34ef3482 | 184 | printn(n, b, flags, ttyp) |
a0eab615 | 185 | u_long n; |
34ef3482 | 186 | struct tty *ttyp; |
8cbb423c | 187 | { |
d5726689 | 188 | char prbuf[11]; |
843267b1 | 189 | register char *cp; |
8cbb423c | 190 | |
843267b1 | 191 | if (b == 10 && (int)n < 0) { |
34ef3482 | 192 | putchar('-', flags, ttyp); |
843267b1 | 193 | n = (unsigned)(-(int)n); |
8cbb423c | 194 | } |
d5726689 | 195 | cp = prbuf; |
843267b1 BJ |
196 | do { |
197 | *cp++ = "0123456789abcdef"[n%b]; | |
198 | n /= b; | |
199 | } while (n); | |
200 | do | |
34ef3482 | 201 | putchar(*--cp, flags, ttyp); |
d5726689 | 202 | while (cp > prbuf); |
8cbb423c BJ |
203 | } |
204 | ||
205 | /* | |
0dc06be8 | 206 | * Panic is called on unresolvable fatal errors. |
b725a0ca BJ |
207 | * It prints "panic: mesg", and then reboots. |
208 | * If we are called twice, then we avoid trying to | |
209 | * sync the disks as this often leads to recursive panics. | |
8cbb423c BJ |
210 | */ |
211 | panic(s) | |
b725a0ca | 212 | char *s; |
8cbb423c | 213 | { |
68503f9a | 214 | int bootopt = RB_AUTOBOOT; |
843267b1 | 215 | |
68503f9a BJ |
216 | if (panicstr) |
217 | bootopt |= RB_NOSYNC; | |
cddce008 | 218 | else { |
961945a8 | 219 | panicstr = s; |
961945a8 | 220 | } |
a9c526c1 | 221 | printf("panic: %s\n", s); |
b725a0ca | 222 | boot(RB_PANIC, bootopt); |
8cbb423c BJ |
223 | } |
224 | ||
fdd11a14 BJ |
225 | /* |
226 | * Warn that a system table is full. | |
227 | */ | |
228 | tablefull(tab) | |
229 | char *tab; | |
230 | { | |
231 | ||
232 | printf("%s: table is full\n", tab); | |
233 | } | |
234 | ||
b725a0ca BJ |
235 | /* |
236 | * Hard error is the preface to plaintive error messages | |
fdd11a14 | 237 | * about failing disk transfers. |
b725a0ca | 238 | */ |
fdd11a14 | 239 | harderr(bp, cp) |
3c79e4ff | 240 | struct buf *bp; |
fdd11a14 | 241 | char *cp; |
8cbb423c BJ |
242 | { |
243 | ||
fdd11a14 BJ |
244 | printf("%s%d%c: hard error sn%d ", cp, |
245 | dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno); | |
8cbb423c | 246 | } |
b725a0ca | 247 | |
96d38f03 | 248 | /* |
843267b1 | 249 | * Print a character on console or users terminal. |
96d38f03 BJ |
250 | * If destination is console then the last MSGBUFS characters |
251 | * are saved in msgbuf for inspection later. | |
252 | */ | |
49c84d3f | 253 | /*ARGSUSED*/ |
34ef3482 | 254 | putchar(c, flags, ttyp) |
843267b1 | 255 | register int c; |
34ef3482 | 256 | struct tty *ttyp; |
96d38f03 | 257 | { |
96d38f03 | 258 | |
34ef3482 RC |
259 | if (flags & TOTTY) { |
260 | register struct tty *tp = ttyp; | |
d11b28dc | 261 | |
34ef3482 | 262 | if (tp && (tp->t_state & TS_CARR_ON)) { |
843267b1 BJ |
263 | register s = spl6(); |
264 | if (c == '\n') | |
2752c877 BJ |
265 | (void) ttyoutput('\r', tp); |
266 | (void) ttyoutput(c, tp); | |
d11b28dc RE |
267 | ttstart(tp); |
268 | splx(s); | |
269 | } | |
d11b28dc | 270 | } |
34ef3482 | 271 | if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177 |
b4e32d36 | 272 | #ifdef vax |
cddce008 BJ |
273 | && mfpr(MAPEN) |
274 | #endif | |
275 | ) { | |
90f8d91f | 276 | if (msgbuf.msg_magic != MSG_MAGIC) { |
76db4195 SL |
277 | register int i; |
278 | ||
90f8d91f | 279 | msgbuf.msg_magic = MSG_MAGIC; |
34ef3482 | 280 | msgbuf.msg_bufx = msgbuf.msg_bufr = 0; |
76db4195 SL |
281 | for (i=0; i < MSG_BSIZE; i++) |
282 | msgbuf.msg_bufc[i] = 0; | |
90f8d91f BJ |
283 | } |
284 | if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE) | |
285 | msgbuf.msg_bufx = 0; | |
286 | msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; | |
96d38f03 | 287 | } |
34ef3482 RC |
288 | if ((flags & TOCONS) && c != '\0') |
289 | cnputc(c); | |
96d38f03 | 290 | } |