#include "../h/local.h" #ifdef SCCS_ID static char SCCS_ID [] = "@(#)prf.c 3.2 01:50:16 - 81/12/10 "; #endif SCCS_ID #include "../h/param.h" #include "../h/systm.h" #include "../h/seg.h" #include "../h/buf.h" #include "../h/conf.h" #ifdef UCB_FSNAM #include "../h/mount.h" #include "../h/filsys.h" #endif UCB_FSNAM /* * In case console is off, * panicstr contains argument to last * call to panic. */ char *panicstr; /* * Scaled down version of C Library printf. * Only %s %u %d (==%u) %o %x %D %O are recognized. * Used to print diagnostic information * directly on console tty. * Since it is not interrupt driven, * all system activities are pretty much * suspended. * Printf should not be used for chit-chat. */ /* VARARGS 1 */ printf(fmt, x1) register char *fmt; unsigned x1; { register c; register unsigned int *adx; char *s; adx = &x1; loop: while((c = *fmt++) != '%') { if(c == '\0') return; putchar(c); } c = *fmt++; if(c == 'd' || c == 'u' || c == 'o' || c == 'x') printn((long)*adx, c=='o'? 8: (c=='x'? 16:10)); else if(c == 's') { s = (char *)*adx; while(c = *s++) putchar(c); #ifdef UCB_DEVERR } else if (c == 'D' || c == 'O') { printn(*(long *)adx, c=='D'?10:8); #else UCB_DEVERR } else if (c == 'D') { printn(*(long *)adx, 10); #endif UCB_DEVERR adx += (sizeof(long) / sizeof(int)) - 1; } #ifdef UCB_DEVERR /* * Additional format: %b for decoding error registers. * Usage is: * printf("reg=%b\n", regval, "*"); * Where is the output base expressed as a control character, * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of * characters, the first of which gives the bit number to be inspected * (origin 1), and the next characters (up to a control character, i.e. * a character <=16), give the name of the register. Thus * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE"); * would produce output: * reg=3 */ else if (c == 'b') { unsigned b; int i, any; b = *adx++; s = (char *)*adx; printn((long)b, *s++); any = 0; if (b) { putchar('<'); while (i = *s++) { if (b & (1 << (i-1))) { if (any) putchar(','); any = 1; for (; (c = *s) > 16; s++) putchar(c); } else for (; *s > 16; s++) ; } putchar('>'); } } #endif UCB_DEVERR adx++; goto loop; } /* * Print an unsigned integer in base b. */ printn(n, b) long n; { register long a; if (n<0) { /* shouldn't happen */ putchar('-'); n = -n; } if(a = n/b) printn(a, b); putchar("0123456789ABCDEF"[(int)(n%b)]); } /* * Panic is called on unresolvable * fatal errors. * It syncs, prints "panic: mesg" and * then loops. */ panic(s) char *s; { #ifdef CGL_AUTOB int i, j; #endif CGL_AUTOB panicstr = s; #ifdef CGL_AUTOB printf("\007\007\007\007\n\nSYSTEM FAULT\n\n"); printf("panic: %s\n", s); spl0(); printf("syncing disks..."); for (i=j=0; i<15; i++) while(--j); /* wait for sync to finish */ printf("done\n"); autoboot(1); #else UCB_AUTOB update(); printf("panic: %s\n", s); for(;;) idle(); #endif UCB_AUTOB } #ifdef CGL_AUTOB #define HPCS1 ((physadr)0176700) /* csr of boot disk */ #define LOC2 ((physadr)02) #define JMPI 0137 /* jmp (pc)+ */ autoboot(flag) { int reboot(), reboot1(); if (CSW->r[0] == SNGLU) /* magic csr setting for manual intervention */ for(;;) idle(); spl7(); while ((HPCS1->r[0] & 0200) == 0); /* wait for xfer to finish */ LOC2->r[0] = JMPI; if (flag) LOC2->r[1] = (int)reboot; /* dump memory first */ else LOC2->r[1] = (int)reboot1; /* no memory dump */ reset(); /* (in l.s) */ /* NOTREACHED */ } #endif UCB_AUTOB /* * prdev prints a warning message of the * form "mesg on dev x/y". * x and y are the major and minor parts of * the device argument. */ prdev(str, dev) char *str; dev_t dev; { #ifdef UCB_FSNAM register struct mount *mp; register struct filsys *fp; for (mp = &mount[0]; mp < mountNMOUNT; mp++) if (mp->m_bufp!=NULL && mp->m_dev==dev) { #ifdef UCB_MOUNT fp = mp->m_caddr; #else UCB_MOUNT fp = mp->m_bufp->b_un.b_filsys; #endif UCB_MOUNT printf("%s on %s (%u/%u)\n", str, fp->s_fsmnt, major(dev), minor(dev)); return; } #endif UCB_FSNAM printf("%s on dev %u/%u\n", str, major(dev), minor(dev)); } /* * deverr prints a diagnostic from * a device driver. * It prints the device, block number, * and an octal word (usually some error * status register) passed as argument. */ deverror(bp, o1, o2) register struct buf *bp; { prdev("err", bp->b_dev); #ifdef DEC printf("bn=%D er=%o,%o\n", bp->b_blkno, o1, o2); #else printf("bn=%D er=%x ad=%x\n", bp->b_blkno, o1, o2); #endif }