157103Sakito /*
257103Sakito * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic * Copyright (c) 1992, 1993
4*63199Sbostic * The Regents of the University of California. All rights reserved.
557103Sakito *
657103Sakito * This code is derived from software contributed to Berkeley by
757103Sakito * OMRON Corporation.
857103Sakito *
957103Sakito * %sccs.include.redist.c%
1057103Sakito *
11*63199Sbostic * @(#)subr_prf.c 8.1 (Berkeley) 06/10/93
1257103Sakito */
1357103Sakito
1457103Sakito #include <sys/param.h>
1557103Sakito #include <luna68k/stand/romvec.h>
1657103Sakito
1757103Sakito #define TOCONS 0x1
1857103Sakito #define TOTTY 0x2
1957103Sakito #define TOLOG 0x4
2057103Sakito
2157103Sakito /*
2257103Sakito * In case console is off,
2357103Sakito * panicstr contains argument to last
2457103Sakito * call to panic.
2557103Sakito */
2657103Sakito char *panicstr;
2757103Sakito
2857103Sakito extern cnputc(); /* standard console putc */
2957103Sakito int (*v_putc)() = cnputc; /* routine to putc on virtual console */
3057103Sakito
3157103Sakito /*
3257103Sakito * Scaled down version of C Library printf.
3357103Sakito * Used to print diagnostic information directly on console tty.
3457103Sakito * Since it is not interrupt driven, all system activities are
3557103Sakito * suspended. Printf should not be used for chit-chat.
3657103Sakito *
3757103Sakito * One additional format: %b is supported to decode error registers.
3857103Sakito * Usage is:
3957103Sakito * printf("reg=%b\n", regval, "<base><arg>*");
4057103Sakito * Where <base> is the output base expressed as a control character,
4157103Sakito * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of
4257103Sakito * characters, the first of which gives the bit number to be inspected
4357103Sakito * (origin 1), and the next characters (up to a control character, i.e.
4457103Sakito * a character <= 32), give the name of the register. Thus
4557103Sakito * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
4657103Sakito * would produce output:
4757103Sakito * reg=3<BITTWO,BITONE>
4857103Sakito *
4957103Sakito * Another additional format: %r is used to pass an additional format string
5057103Sakito * and argument list recursively. Usage is typically:
5157103Sakito *
5257103Sakito * fn(otherstuff, fmt [, arg1, ... ] )
5357103Sakito * char *fmt;
5457103Sakito * u_int arg1, ...;
5557103Sakito *
5657103Sakito * printf("prefix: %r, other stuff\n", fmt, &arg1);
5757103Sakito */
5857103Sakito #if defined(tahoe)
5957103Sakito int consintr;
6057103Sakito #endif
6157103Sakito
6257103Sakito /*VARARGS1*/
printf(fmt,x1)6357103Sakito printf(fmt, x1)
6457103Sakito char *fmt;
6557103Sakito unsigned x1;
6657103Sakito {
6757103Sakito #if defined(tahoe)
6857103Sakito register int savintr;
6957103Sakito
7057103Sakito savintr = consintr, consintr = 0; /* disable interrupts */
7157103Sakito #endif
7257103Sakito prf(fmt, &x1, TOCONS , (struct tty *)NULL);
7357103Sakito
7457103Sakito
7557103Sakito #if defined(tahoe)
7657103Sakito consintr = savintr; /* reenable interrupts */
7757103Sakito #endif
7857103Sakito }
7957103Sakito
prf(fmt,adx,flags,ttyp)8057103Sakito prf(fmt, adx, flags, ttyp)
8157103Sakito register char *fmt;
8257103Sakito register u_int *adx;
8357103Sakito struct tty *ttyp;
8457103Sakito {
8557103Sakito register int b, c, i;
8657103Sakito char *s;
8757103Sakito int any;
8857103Sakito
8957103Sakito loop:
9057103Sakito while ((c = *fmt++) != '%') {
9157103Sakito if (c == '\0')
9257103Sakito return;
9357103Sakito putchar(c, flags, ttyp);
9457103Sakito }
9557103Sakito again:
9657103Sakito c = *fmt++;
9757103Sakito /* THIS CODE IS MACHINE DEPENDENT IN HANDLING %l? AND %c */
9857103Sakito switch (c) {
9957103Sakito
10057103Sakito case 'l':
10157103Sakito goto again;
10257103Sakito case 'x': case 'X':
10357103Sakito b = 16;
10457103Sakito goto number;
10557103Sakito case 'd': case 'D':
10657103Sakito b = -10;
10757103Sakito goto number;
10857103Sakito case 'u':
10957103Sakito b = 10;
11057103Sakito goto number;
11157103Sakito case 'o': case 'O':
11257103Sakito b = 8;
11357103Sakito number:
11457103Sakito printn((u_long)*adx, b, flags, ttyp);
11557103Sakito break;
11657103Sakito case 'c':
11757103Sakito b = *adx;
11857103Sakito #if BYTE_ORDER == LITTLE_ENDIAN
11957103Sakito for (i = 24; i >= 0; i -= 8)
12057103Sakito if (c = (b >> i) & 0x7f)
12157103Sakito putchar(c, flags, ttyp);
12257103Sakito #endif
12357103Sakito #if BYTE_ORDER == BIG_ENDIAN
12457103Sakito if (c = (b & 0x7f))
12557103Sakito putchar(c, flags, ttyp);
12657103Sakito #endif
12757103Sakito break;
12857103Sakito case 'b':
12957103Sakito b = *adx++;
13057103Sakito s = (char *)*adx;
13157103Sakito printn((u_long)b, *s++, flags, ttyp);
13257103Sakito any = 0;
13357103Sakito if (b) {
13457103Sakito while (i = *s++) {
13557103Sakito if (b & (1 << (i-1))) {
13657103Sakito putchar(any ? ',' : '<', flags, ttyp);
13757103Sakito any = 1;
13857103Sakito for (; (c = *s) > 32; s++)
13957103Sakito putchar(c, flags, ttyp);
14057103Sakito } else
14157103Sakito for (; *s > 32; s++)
14257103Sakito ;
14357103Sakito }
14457103Sakito if (any)
14557103Sakito putchar('>', flags, ttyp);
14657103Sakito }
14757103Sakito break;
14857103Sakito
14957103Sakito case 's':
15057103Sakito s = (char *)*adx;
15157103Sakito while (c = *s++)
15257103Sakito putchar(c, flags, ttyp);
15357103Sakito break;
15457103Sakito
15557103Sakito case 'r':
15657103Sakito s = (char *)*adx++;
15757103Sakito prf(s, (u_int *)*adx, flags, ttyp);
15857103Sakito break;
15957103Sakito
16057103Sakito case '%':
16157103Sakito putchar('%', flags, ttyp);
16257103Sakito break;
16357103Sakito
16457103Sakito default:
16557103Sakito break;
16657103Sakito }
16757103Sakito adx++;
16857103Sakito goto loop;
16957103Sakito }
17057103Sakito
17157103Sakito /*
17257103Sakito * Printn prints a number n in base b.
17357103Sakito * We don't use recursion to avoid deep kernel stacks.
17457103Sakito */
printn(n,b,flags,ttyp)17557103Sakito printn(n, b, flags, ttyp)
17657103Sakito u_long n;
17757103Sakito struct tty *ttyp;
17857103Sakito {
17957103Sakito char prbuf[11];
18057103Sakito register char *cp;
18157103Sakito
18257103Sakito if (b == -10) {
18357103Sakito if ((int)n < 0) {
18457103Sakito putchar('-', flags, ttyp);
18557103Sakito n = (unsigned)(-(int)n);
18657103Sakito }
18757103Sakito b = -b;
18857103Sakito }
18957103Sakito cp = prbuf;
19057103Sakito do {
19157103Sakito *cp++ = "0123456789abcdef"[n%b];
19257103Sakito n /= b;
19357103Sakito } while (n);
19457103Sakito do
19557103Sakito putchar(*--cp, flags, ttyp);
19657103Sakito while (cp > prbuf);
19757103Sakito }
19857103Sakito
19957103Sakito /*
20057103Sakito * Panic is called on unresolvable fatal errors.
20157103Sakito * It prints "panic: mesg", and then reboots.
20257103Sakito * If we are called twice, then we avoid trying to
20357103Sakito * sync the disks as this often leads to recursive panics.
20457103Sakito */
panic(s)20557103Sakito panic(s)
20657103Sakito char *s;
20757103Sakito {
20857103Sakito if (!panicstr) {
20957103Sakito panicstr = s;
21057103Sakito }
21157103Sakito printf("panic: %s\n", s);
21257103Sakito
21357103Sakito ROM_abort();
21457103Sakito }
21557103Sakito
21657103Sakito /*
21757103Sakito * Print a character on console or users terminal.
21857103Sakito * If destination is console then the last MSGBUFS characters
21957103Sakito * are saved in msgbuf for inspection later.
22057103Sakito */
22157103Sakito /*ARGSUSED*/
putchar(c,flags,ttyp)22257103Sakito putchar(c, flags, ttyp)
22357103Sakito register int c;
22457103Sakito struct tty *ttyp;
22557103Sakito {
22657103Sakito
22757103Sakito
22857103Sakito
22957103Sakito
23057103Sakito
23157103Sakito
23257103Sakito
23357103Sakito
23457103Sakito
23557103Sakito
23657103Sakito
23757103Sakito
23857103Sakito
23957103Sakito
24057103Sakito
24157103Sakito
24257103Sakito
24357103Sakito
24457103Sakito
24557103Sakito
24657103Sakito
24757103Sakito
24857103Sakito
24957103Sakito
25057103Sakito
25157103Sakito
25257103Sakito (*v_putc)(c);
25357103Sakito }
254