Subject: Re: MMU fault
To: <>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-hp300
Date: 07/19/1998 12:14:09
On Sun, 19 Jul 1998 11:24:12 -0400 (EDT) 
 "Matthew N. Dodd" <winter@jurai.net> wrote:

 > On Sun, 19 Jul 1998, Mike Hibler wrote:
 > > I haven't been following this very closely so I may be stating the
 > > obvious (or totally off base, take your pick :-) but it looks like you
 > > may be getting a serial line interrupt before the kernel has configured
 > > the dca (serial) device.  If the interrupt handler hasn't been
 > > registered, this could cause bad things to happen (though it should
 > > catch unexpected interrupts more gracefully I would think).  This might
 > > not happen with the graphics device as console since the boot ROM would
 > > then not be configuring the serial port (as it must when using the
 > > serial console). 
 > 
 > This would be consistent with observed behavior.

Not quite... The interrupt handlers are initialized early, and if you
get a serial interrupt before its driver is attached, you'll just get
a spurious interrupt warning (the interrupt code is different than it
was in the stock Utah code, which is what Mike might be referencing...)

I finally had a chance to take a quick look at this, and it's fairly obvious
to me what's going on.  The DCA interrupt routine _is_ getting called, and
because the port hasn't been open'd yet, it's dereferencing a NULL tty
pointer.

 > Can someone compile a kernel which probes and attaches the serial devices
 > before anything else?  I'm not even sure this would solve the problem but
 > its as good a shot in the dark as any.

Better yet, can you try this patch?  (Yes, eventually I will toss the dca
driver in favor of the MI com driver...)

Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                            Home: +1 408 866 1912
NAS: M/S 258-5                                       Work: +1 650 604 0935
Moffett Field, CA 94035                             Pager: +1 650 940 5942

Index: dca.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/dca.c,v
retrieving revision 1.38
diff -c -r1.38 dca.c
*** dca.c	1998/03/28 23:49:06	1.38
--- dca.c	1998/07/19 19:26:15
***************
*** 529,535 ****
  #ifdef KGDB
  #define	RCVBYTE() \
  			code = dca->dca_data; \
! 			if ((tp->t_state & TS_ISOPEN) == 0) { \
  				if (code == FRAME_END && \
  				    kgdb_dev == makedev(dcamajor, unit)) \
  					kgdb_connect(0); /* trap into kgdb */ \
--- 529,535 ----
  #ifdef KGDB
  #define	RCVBYTE() \
  			code = dca->dca_data; \
! 			if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) { \
  				if (code == FRAME_END && \
  				    kgdb_dev == makedev(dcamajor, unit)) \
  					kgdb_connect(0); /* trap into kgdb */ \
***************
*** 538,544 ****
  #else
  #define	RCVBYTE() \
  			code = dca->dca_data; \
! 			if ((tp->t_state & TS_ISOPEN) != 0) \
  				(*linesw[tp->t_line].l_rint)(code, tp)
  #endif
  			RCVBYTE();
--- 538,544 ----
  #else
  #define	RCVBYTE() \
  			code = dca->dca_data; \
! 			if (tp != NULL && (tp->t_state & TS_ISOPEN) != 0) \
  				(*linesw[tp->t_line].l_rint)(code, tp)
  #endif
  			RCVBYTE();
***************
*** 562,574 ****
  					fifoin[fifocnt]++;
  #endif
  			}
! 			if (!iflowdone && (tp->t_cflag&CRTS_IFLOW) &&
  			    tp->t_rawq.c_cc > TTYHOG/2) {
  				dca->dca_mcr &= ~MCR_RTS;
  				iflowdone = 1;
  			}
  			break;
  		case IIR_TXRDY:
  			tp->t_state &=~ (TS_BUSY|TS_FLUSH);
  			if (tp->t_line)
  				(*linesw[tp->t_line].l_start)(tp);
--- 562,577 ----
  					fifoin[fifocnt]++;
  #endif
  			}
! 			if (!iflowdone && tp != NULL &&
! 			    (tp->t_cflag&CRTS_IFLOW) &&
  			    tp->t_rawq.c_cc > TTYHOG/2) {
  				dca->dca_mcr &= ~MCR_RTS;
  				iflowdone = 1;
  			}
  			break;
  		case IIR_TXRDY:
+ 			if (tp == NULL)
+ 				break;
  			tp->t_state &=~ (TS_BUSY|TS_FLUSH);
  			if (tp->t_line)
  				(*linesw[tp->t_line].l_start)(tp);
***************
*** 601,607 ****
  	int c;
  
  	c = dca->dca_data;
! 	if ((tp->t_state & TS_ISOPEN) == 0) {
  #ifdef KGDB
  		/* we don't care about parity errors */
  		if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) &&
--- 604,610 ----
  	int c;
  
  	c = dca->dca_data;
! 	if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) {
  #ifdef KGDB
  		/* we don't care about parity errors */
  		if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) &&
***************
*** 632,637 ****
--- 635,642 ----
  #ifdef DEBUG
  	dcamintcount[stat & 0xf]++;
  #endif
+ 	if (tp == NULL)
+ 		return;
  	if ((stat & MSR_DDCD) &&
  	    (sc->sc_flags & DCA_SOFTCAR) == 0) {
  		if (stat & MSR_DCD)