Commit | Line | Data |
---|---|---|
49c84d3f | 1 | /* subr_prf.c 4.2 %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" |
96d38f03 BJ |
10 | |
11 | #ifdef TRACE | |
12 | #define TRCBUFS 4096 | |
13 | char trcbuf[TRCBUFS]; | |
14 | char *trcbufp = trcbuf; | |
15 | int trcwrap; | |
16 | int trcprt = TRCBUFS; | |
17 | #endif | |
8cbb423c BJ |
18 | |
19 | /* | |
20 | * In case console is off, | |
21 | * panicstr contains argument to last | |
22 | * call to panic. | |
23 | */ | |
24 | ||
25 | char *panicstr; | |
26 | ||
27 | /* | |
28 | * Scaled down version of C Library printf. | |
29 | * Only %s %u %d (==%u) %o %x %D are recognized. | |
30 | * Used to print diagnostic information | |
31 | * directly on console tty. | |
32 | * Since it is not interrupt driven, | |
33 | * all system activities are pretty much | |
34 | * suspended. | |
35 | * Printf should not be used for chit-chat. | |
36 | */ | |
37 | /*VARARGS1*/ | |
38 | printf(fmt, x1) | |
39 | register char *fmt; | |
40 | unsigned x1; | |
96d38f03 BJ |
41 | { |
42 | ||
43 | prf(fmt, &x1, 0); | |
44 | } | |
45 | ||
46 | #ifdef TRACE | |
47 | trace(fmt, x1) | |
48 | register char *fmt; | |
49 | unsigned x1; | |
50 | { | |
51 | ||
52 | prf(fmt, &x1, 1); | |
53 | } | |
54 | ||
55 | #endif | |
56 | ||
57 | prf(fmt, adx, trace) | |
58 | register char *fmt; | |
59 | register unsigned int *adx; | |
8cbb423c BJ |
60 | { |
61 | register c; | |
8cbb423c BJ |
62 | char *s; |
63 | ||
8cbb423c BJ |
64 | loop: |
65 | while((c = *fmt++) != '%') { | |
66 | if(c == '\0') | |
67 | return; | |
96d38f03 | 68 | putchar(c, trace); |
8cbb423c BJ |
69 | } |
70 | c = *fmt++; | |
96d38f03 BJ |
71 | if (c == 'X') |
72 | printx((long)*adx, trace); | |
73 | else if (c == 'd' || c == 'u' || c == 'o' || c == 'x') | |
74 | printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), trace); | |
75 | else if (c == 's') { | |
8cbb423c | 76 | s = (char *)*adx; |
96d38f03 BJ |
77 | while (c = *s++) |
78 | #ifdef TRACE | |
79 | if (trace) { | |
80 | *trcbufp++ = c; | |
81 | if (trcbufp >= &trcbuf[TRCBUFS]) { | |
82 | trcbufp = trcbuf; | |
83 | trcwrap = 1; | |
84 | } | |
85 | } else | |
86 | #endif | |
87 | putchar(c, trace); | |
8cbb423c | 88 | } else if (c == 'D') { |
96d38f03 | 89 | printn(*(long *)adx, 10, trace); |
8cbb423c BJ |
90 | adx += (sizeof(long) / sizeof(int)) - 1; |
91 | } | |
92 | adx++; | |
93 | goto loop; | |
94 | } | |
95 | ||
96d38f03 | 96 | printx(x, trace) |
8cbb423c BJ |
97 | long x; |
98 | { | |
99 | int i; | |
100 | ||
101 | for (i = 0; i < 8; i++) | |
96d38f03 | 102 | putchar("0123456789ABCDEF"[(x>>((7-i)*4))&0xf], trace); |
8cbb423c BJ |
103 | } |
104 | ||
105 | /* | |
106 | * Print an unsigned integer in base b. | |
107 | */ | |
96d38f03 | 108 | printn(n, b, trace) |
8cbb423c BJ |
109 | long n; |
110 | { | |
111 | register long a; | |
112 | ||
113 | if (n<0) { /* shouldn't happen */ | |
96d38f03 | 114 | putchar('-', trace); |
8cbb423c BJ |
115 | n = -n; |
116 | } | |
117 | if(a = n/b) | |
96d38f03 BJ |
118 | printn(a, b, trace); |
119 | putchar("0123456789ABCDEF"[(int)(n%b)], trace); | |
8cbb423c BJ |
120 | } |
121 | ||
122 | /* | |
0dc06be8 BJ |
123 | * Panic is called on unresolvable fatal errors. |
124 | * It syncs, prints "panic: mesg", and then reboots. | |
8cbb423c BJ |
125 | */ |
126 | panic(s) | |
127 | char *s; | |
128 | { | |
129 | panicstr = s; | |
8cbb423c BJ |
130 | printf("panic: %s\n", s); |
131 | spl0(); | |
132 | for(;;) | |
9bd7e93d | 133 | boot(RB_PANIC, RB_AUTOBOOT); |
8cbb423c BJ |
134 | } |
135 | ||
136 | /* | |
137 | * prdev prints a warning message of the | |
138 | * form "mesg on dev x/y". | |
139 | * x and y are the major and minor parts of | |
140 | * the device argument. | |
141 | */ | |
142 | prdev(str, dev) | |
143 | char *str; | |
144 | dev_t dev; | |
145 | { | |
146 | ||
147 | printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); | |
148 | } | |
149 | ||
150 | /* | |
151 | * deverr prints a diagnostic from | |
152 | * a device driver. | |
153 | * It prints the device, block number, | |
154 | * and an octal word (usually some error | |
155 | * status register) passed as argument. | |
156 | */ | |
157 | deverror(bp, o1, o2) | |
158 | register struct buf *bp; | |
159 | { | |
160 | ||
161 | prdev("err", bp->b_dev); | |
162 | printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2); | |
163 | } | |
96d38f03 BJ |
164 | |
165 | #ifdef TRACE | |
166 | dumptrc() | |
167 | { | |
168 | register char *cp; | |
169 | register int pos, nch; | |
170 | ||
171 | nch = trcprt; | |
172 | if (nch < 0 || nch > TRCBUFS) | |
173 | nch = TRCBUFS; | |
174 | pos = (trcbufp - trcbuf) - nch; | |
175 | if (pos < 0) | |
176 | if (trcwrap) | |
177 | pos += TRCBUFS; | |
178 | else { | |
179 | nch += pos; | |
180 | pos = 0; | |
181 | } | |
182 | for (cp = &trcbuf[pos]; nch > 0; nch--) { | |
183 | putchar(*cp++, 0); | |
184 | if (cp >= &trcbuf[TRCBUFS]) | |
185 | cp = trcbuf; | |
186 | } | |
187 | } | |
188 | #else | |
189 | /*ARGSUSED*/ | |
190 | dumptrc(nch) | |
191 | int nch; | |
192 | { | |
193 | ||
194 | } | |
195 | #endif | |
196 | ||
197 | char *msgbufp = msgbuf; /* Next saved printf character */ | |
198 | /* | |
199 | * Print a character on console or in internal trace buffer. | |
200 | * If destination is console then the last MSGBUFS characters | |
201 | * are saved in msgbuf for inspection later. | |
202 | */ | |
49c84d3f | 203 | /*ARGSUSED*/ |
96d38f03 BJ |
204 | putchar(c, trace) |
205 | register c; | |
206 | { | |
96d38f03 BJ |
207 | |
208 | #ifdef TRACE | |
209 | if (trace) { | |
210 | *trcbufp++ = c; | |
211 | if (trcbufp >= &trcbuf[TRCBUFS]) { | |
212 | trcbufp = trcbuf; | |
213 | trcwrap = 1; | |
214 | } | |
215 | return; | |
216 | } | |
217 | #endif | |
218 | if (c != '\0' && c != '\r' && c != 0177) { | |
219 | *msgbufp++ = c; | |
220 | if (msgbufp >= &msgbuf[MSGBUFS]) | |
221 | msgbufp = msgbuf; | |
222 | } | |
223 | if (c == 0) | |
224 | return; | |
225 | cnputc(c); | |
226 | } |