1 /*
2 * Copyright (c) 1992 OMRON Corporation.
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * OMRON Corporation.
8 *
9 * %sccs.include.redist.c%
10 *
11 * @(#)subr_prf.c 8.1 (Berkeley) 06/10/93
12 */
13
14 #include <sys/param.h>
15 #include <luna68k/stand/romvec.h>
16
17 #define TOCONS 0x1
18 #define TOTTY 0x2
19 #define TOLOG 0x4
20
21 /*
22 * In case console is off,
23 * panicstr contains argument to last
24 * call to panic.
25 */
26 char *panicstr;
27
28 extern cnputc(); /* standard console putc */
29 int (*v_putc)() = cnputc; /* routine to putc on virtual console */
30
31 /*
32 * Scaled down version of C Library printf.
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=3<BITTWO,BITONE>
48 *
49 * Another additional format: %r is used to pass an additional format string
50 * and argument list recursively. Usage is typically:
51 *
52 * fn(otherstuff, fmt [, arg1, ... ] )
53 * char *fmt;
54 * u_int arg1, ...;
55 *
56 * printf("prefix: %r, other stuff\n", fmt, &arg1);
57 */
58 #if defined(tahoe)
59 int consintr;
60 #endif
61
62 /*VARARGS1*/
printf(fmt,x1)63 printf(fmt, x1)
64 char *fmt;
65 unsigned x1;
66 {
67 #if defined(tahoe)
68 register int savintr;
69
70 savintr = consintr, consintr = 0; /* disable interrupts */
71 #endif
72 prf(fmt, &x1, TOCONS , (struct tty *)NULL);
73
74
75 #if defined(tahoe)
76 consintr = savintr; /* reenable interrupts */
77 #endif
78 }
79
prf(fmt,adx,flags,ttyp)80 prf(fmt, adx, flags, ttyp)
81 register char *fmt;
82 register u_int *adx;
83 struct tty *ttyp;
84 {
85 register int b, c, i;
86 char *s;
87 int any;
88
89 loop:
90 while ((c = *fmt++) != '%') {
91 if (c == '\0')
92 return;
93 putchar(c, flags, ttyp);
94 }
95 again:
96 c = *fmt++;
97 /* THIS CODE IS MACHINE DEPENDENT IN HANDLING %l? AND %c */
98 switch (c) {
99
100 case 'l':
101 goto again;
102 case 'x': case 'X':
103 b = 16;
104 goto number;
105 case 'd': case 'D':
106 b = -10;
107 goto number;
108 case 'u':
109 b = 10;
110 goto number;
111 case 'o': case 'O':
112 b = 8;
113 number:
114 printn((u_long)*adx, b, flags, ttyp);
115 break;
116 case 'c':
117 b = *adx;
118 #if BYTE_ORDER == LITTLE_ENDIAN
119 for (i = 24; i >= 0; i -= 8)
120 if (c = (b >> i) & 0x7f)
121 putchar(c, flags, ttyp);
122 #endif
123 #if BYTE_ORDER == BIG_ENDIAN
124 if (c = (b & 0x7f))
125 putchar(c, flags, ttyp);
126 #endif
127 break;
128 case 'b':
129 b = *adx++;
130 s = (char *)*adx;
131 printn((u_long)b, *s++, flags, ttyp);
132 any = 0;
133 if (b) {
134 while (i = *s++) {
135 if (b & (1 << (i-1))) {
136 putchar(any ? ',' : '<', flags, ttyp);
137 any = 1;
138 for (; (c = *s) > 32; s++)
139 putchar(c, flags, ttyp);
140 } else
141 for (; *s > 32; s++)
142 ;
143 }
144 if (any)
145 putchar('>', flags, ttyp);
146 }
147 break;
148
149 case 's':
150 s = (char *)*adx;
151 while (c = *s++)
152 putchar(c, flags, ttyp);
153 break;
154
155 case 'r':
156 s = (char *)*adx++;
157 prf(s, (u_int *)*adx, flags, ttyp);
158 break;
159
160 case '%':
161 putchar('%', flags, ttyp);
162 break;
163
164 default:
165 break;
166 }
167 adx++;
168 goto loop;
169 }
170
171 /*
172 * Printn prints a number n in base b.
173 * We don't use recursion to avoid deep kernel stacks.
174 */
printn(n,b,flags,ttyp)175 printn(n, b, flags, ttyp)
176 u_long n;
177 struct tty *ttyp;
178 {
179 char prbuf[11];
180 register char *cp;
181
182 if (b == -10) {
183 if ((int)n < 0) {
184 putchar('-', flags, ttyp);
185 n = (unsigned)(-(int)n);
186 }
187 b = -b;
188 }
189 cp = prbuf;
190 do {
191 *cp++ = "0123456789abcdef"[n%b];
192 n /= b;
193 } while (n);
194 do
195 putchar(*--cp, flags, ttyp);
196 while (cp > prbuf);
197 }
198
199 /*
200 * Panic is called on unresolvable fatal errors.
201 * It prints "panic: mesg", and then reboots.
202 * If we are called twice, then we avoid trying to
203 * sync the disks as this often leads to recursive panics.
204 */
panic(s)205 panic(s)
206 char *s;
207 {
208 if (!panicstr) {
209 panicstr = s;
210 }
211 printf("panic: %s\n", s);
212
213 ROM_abort();
214 }
215
216 /*
217 * Print a character on console or users terminal.
218 * If destination is console then the last MSGBUFS characters
219 * are saved in msgbuf for inspection later.
220 */
221 /*ARGSUSED*/
putchar(c,flags,ttyp)222 putchar(c, flags, ttyp)
223 register int c;
224 struct tty *ttyp;
225 {
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 (*v_putc)(c);
253 }
254