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