# /* */ #include "../defines.h" #include "../param.h" #include "../seg.h" #include "../buf.h" #include "../conf.h" #ifdef ERROR_LOG | NICE_PUTCHAR | UPRINTS #include "../tty.h" #endif #ifdef UPRINTS #include "../user.h" #include "../proc.h" #endif #ifdef ERROR_LOG #define FULL 1 /* flag bits */ #define OPEN 2 #define HIWATER 100 struct errorlog { int flag; struct tty errtty; } errlog; #endif /* * Address and structure of the * KL-11 console device registers. */ struct { int rsr; int rbr; int xsr; int xbr; }; /* * In case console is off, #ifndef BETTER_PANIC * panicstr contains argument to last #else * panicstr contains argument to first #endif BETTER_PANIC * call to panic. */ char *panicstr; /* * Scaled down version of C Library printf. * Only %s %l %d (==%l) %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. */ printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9,xa,xb,xc) char fmt[]; { register char *s; register *adx, c; adx = &x1; loop: while((c = *fmt++) != '%') { if(c == '\0') return; putchar(c); } c = *fmt++; if(c == 'd' || c == 'l' || c == 'o') printn(*adx, c=='o'? 8: 10); if(c == 's') { s = *adx; while(c = *s++) putchar(c); } adx++; goto loop; } /* * Print an unsigned integer in base b. */ printn(n, b) { register a; if(a = ldiv(n, b)) printn(a, b); putchar(lrem(n, b) + '0'); } /* * Print a character on console. * Attempts to save and restore device * status. * If the switches are 0, all * printing is inhibited. */ putchar(c) register c; /* fix000 */ { register s; register sps = PS->integ; #ifdef NICE_PUTCHAR extern cfreelist; extern struct tty kl11; #endif #ifdef POWER_FAIL extern powflag; /* set if power fail in progress */ if( powflag ) goto nofrills; #endif POWER_FAIL #ifdef ERROR_LOG | NICE_PUTCHAR /* if panicing or current prty greater than 5 use direct output */ if((sps&0340)>0240) goto nofrills; spl5(); if(panicstr) goto nofrills; #endif ERROR_LOG | NICE_PUTCHAR #ifdef ERROR_LOG if ( (errlog.flag & (OPEN|FULL)) == OPEN ) { while( cfreelist == 0 ) /* don't lose messages */ { spl0(); /* devices beware ... multiple interrupts */ idle(); spl5(); } ttyinput( c , &errlog.errtty ); if ( c == '\n' ) { if ( errlog.errtty.t_rawq.c_cc > HIWATER ) errlog.flag =| FULL; } goto out; } #endif if(SW->integ == 0) /* fix016 */ goto out; #ifdef NICE_PUTCHAR if ( kl11.t_state&ISOPEN ) { while( cfreelist == 0 ) /* don't lose messages */ { spl0(); idle(); spl5(); } uputchar( c , &kl11 ); goto out; } #endif #ifdef POWER_FAIL | ERROR_LOG | NICE_PUTCHAR nofrills: #endif POWER_FAIL | ERROR_LOG | NICE_PUTCHAR while((KL->xsr&0200) == 0) ; if(c == 0) goto out; s = KL->xsr; KL->xsr = 0; KL->xbr = c; if(c == '\n') { putchar('\r'); #ifdef SLOW_CONSOLE putchar(0177); putchar(0177); putchar(0177); putchar(0177); #endif } putchar(0); KL->xsr = s; out: PS->integ = sps; } /* * Panic is called on unresolvable * fatal errors. * It syncs, prints "panic: mesg" and * then loops. */ panic(s) char *s; { #ifdef SYS_TIME char hhmm[6]; #endif SYS_TIME #ifndef BETTER_PANIC panicstr = s; #else if( panicstr < 0400 ) panicstr = s; #endif BETTER_PANIC update(); #ifdef SYS_TIME printf("time = %s\n", systime(hhmm) ); #endif SYS_TIME printf("panic: %s\n", s); for(;;) idle(); } /* * 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) { printf("%s on dev %l/%l\n", str, dev.d_major, dev.d_minor); } /* * 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) int *bp; { register *rbp; rbp = bp; prdev("err", rbp->b_dev); printf("bn%l er%o %o\n", rbp->b_blkno, o1, o2); } #ifdef ERROR_LOG /* * this pseudo device driver implements the read-only device * "errlog" which sucks off all non-panic "putchar" output. */ elopen() { errlog.flag = OPEN; errlog.errtty.t_state = (ISOPEN|CARR_ON); } elread() { ttread( &errlog.errtty ); errlog.flag =& ~FULL; } elclose() { errlog.flag = 0; flushtty( &errlog.errtty ); } #endif #ifdef UPRINTS /* * uprints provides a facility for warning messages from deep within * system to be presented to a particular user. */ uprints( s ) register char *s; { register c; register struct tty *ttyp; /* if cpu prty greater then five don't */ if( (PS->integ&0340)>0240 ) return; if ( ttyp = u.u_procp->p_ttyp ) while ( c = *s++ ) uputchar( c , ttyp ); } #endif #ifdef UPRINTS | NICE_PUTCHAR /* * uputchar directs a character to the appropriate tty queue * via "ttyoutput", and guarantees not to sleep. * N.B. high water marks are disregarded -- so don't be verbose ! */ uputchar( c , ttyp ) register struct tty *ttyp; { register sps; sps = PS->integ; spl5(); ttyoutput( c , ttyp ); ttstart( ttyp ); PS->integ = sps; } #endif