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