Commit | Line | Data |
---|---|---|
0dc06be8 | 1 | /* subr_prf.c 3.4 %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; | |
130 | update(); | |
131 | printf("panic: %s\n", s); | |
132 | spl0(); | |
133 | for(;;) | |
0dc06be8 | 134 | boot(RB_PANIC, RB_AUTOBOOT); /* 0 = automatic */ |
8cbb423c BJ |
135 | } |
136 | ||
137 | /* | |
138 | * prdev prints a warning message of the | |
139 | * form "mesg on dev x/y". | |
140 | * x and y are the major and minor parts of | |
141 | * the device argument. | |
142 | */ | |
143 | prdev(str, dev) | |
144 | char *str; | |
145 | dev_t dev; | |
146 | { | |
147 | ||
148 | printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); | |
149 | } | |
150 | ||
151 | /* | |
152 | * deverr prints a diagnostic from | |
153 | * a device driver. | |
154 | * It prints the device, block number, | |
155 | * and an octal word (usually some error | |
156 | * status register) passed as argument. | |
157 | */ | |
158 | deverror(bp, o1, o2) | |
159 | register struct buf *bp; | |
160 | { | |
161 | ||
162 | prdev("err", bp->b_dev); | |
163 | printf("bn=%d er=%x,%x\n", bp->b_blkno, o1,o2); | |
164 | } | |
96d38f03 BJ |
165 | |
166 | #ifdef TRACE | |
167 | dumptrc() | |
168 | { | |
169 | register char *cp; | |
170 | register int pos, nch; | |
171 | ||
172 | nch = trcprt; | |
173 | if (nch < 0 || nch > TRCBUFS) | |
174 | nch = TRCBUFS; | |
175 | pos = (trcbufp - trcbuf) - nch; | |
176 | if (pos < 0) | |
177 | if (trcwrap) | |
178 | pos += TRCBUFS; | |
179 | else { | |
180 | nch += pos; | |
181 | pos = 0; | |
182 | } | |
183 | for (cp = &trcbuf[pos]; nch > 0; nch--) { | |
184 | putchar(*cp++, 0); | |
185 | if (cp >= &trcbuf[TRCBUFS]) | |
186 | cp = trcbuf; | |
187 | } | |
188 | } | |
189 | #else | |
190 | /*ARGSUSED*/ | |
191 | dumptrc(nch) | |
192 | int nch; | |
193 | { | |
194 | ||
195 | } | |
196 | #endif | |
197 | ||
198 | char *msgbufp = msgbuf; /* Next saved printf character */ | |
199 | /* | |
200 | * Print a character on console or in internal trace buffer. | |
201 | * If destination is console then the last MSGBUFS characters | |
202 | * are saved in msgbuf for inspection later. | |
203 | */ | |
204 | putchar(c, trace) | |
205 | register c; | |
206 | { | |
207 | register s, timo; | |
208 | ||
209 | #ifdef TRACE | |
210 | if (trace) { | |
211 | *trcbufp++ = c; | |
212 | if (trcbufp >= &trcbuf[TRCBUFS]) { | |
213 | trcbufp = trcbuf; | |
214 | trcwrap = 1; | |
215 | } | |
216 | return; | |
217 | } | |
218 | #endif | |
219 | if (c != '\0' && c != '\r' && c != 0177) { | |
220 | *msgbufp++ = c; | |
221 | if (msgbufp >= &msgbuf[MSGBUFS]) | |
222 | msgbufp = msgbuf; | |
223 | } | |
224 | if (c == 0) | |
225 | return; | |
226 | cnputc(c); | |
227 | } |