Subject: Re: hmm.. :(
To: None <Chris_Mattingly@ncsu.edu>
From: Chris G Demetriou <Chris_G_Demetriou@BALVENIE.PDL.CS.CMU.EDU>
List: port-alpha
Date: 12/22/1995 01:51:46
> NetBSD 1.1A-NetBSD_Alpha-951127+ (GENERIC) #212: Wed Dec 20 08:16:13 EST 1995
>     cgd@bunnahabhain.pdl.cs.cmu.edu:/usr/src/sys/arch/alpha/compile/GENERIC
> DEC 3000/300LX ("Pelica+", 125MHz
> 8192 byte page size, 1 processor
> real mem = 33554432
> trap type 33, code = 0x0, v = 0x40120
> pc = 0xfffffc00003732ac
> [ ... ]
> 
> Any ideas?

I goofed.  8-)  I moved some code, but didn't think through what i was
doing.  actually, you're missing a few things from that dmesg output,
but with the PC and the faulting virtual address, finding the problem
was easy.

I've included the fix below, to be applied to the sources i kicked out
yesterday.  (Looks like i also goofed, and forgot to update the
version identification string...  i'm not going to bother with that. 8-)

I've put up some new kernels in .../951220/bin, put the patch in a
file in .../951220/src, and added the following text to the snapshot's
README_FIRST file:

> The DEC 3000/300 interrupt initialization code shipped in the sources
> for this snapshot is broken.  To fix it, you need to apply the patch
> found in src/3000_300_intrfix.  The kernels:
>
>         bin/netbsd.300fix.gz
>         bin/netbsd.300fix.gdb.gz
>         bin/netbsd_nfs.300fix.gz
>         bin/netbsd.300fix.gdb gz
>
> were built with the patch applied.  They should work on the other
> supported systems, as well, so you might as well just get and use
> them.

I've _NOT_ gotten rid of the old, broken, kernels, since that's the
kernel that's on the disk image, so i want it to be available.

These changes are now on ftp.netbsd.org.  They'll propagate out to
mirrors as usual.


sorry about the goofup!


later,

chris
--- cut here --
Index: src/sys/arch/alpha/tc/ioasic.c
===================================================================
RCS file: /usr/users/cgd/NetBSD/cvs/src/sys/arch/alpha/tc/ioasic.c,v
retrieving revision 1.4
diff -c -r1.4 ioasic.c
*** 1.4	1995/12/20 03:34:09
--- ioasic.c	1995/12/22 05:44:18
***************
*** 335,376 ****
  	    IOASIC_CSR_DMAEN_LANCE;
  	tc_mb();
  }
- 
- #ifdef DEC_3000_300
- void
- ioasic_intr_300_opt0_enable(enable)
- 	int enable;
- {
- 
- 	if (enable)
- 		*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
- 			IOASIC_INTR_300_OPT0;
- 	else
- 		*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
- 			~IOASIC_INTR_300_OPT0;
- }
- 
- void
- ioasic_intr_300_opt1_enable(enable)
- 	int enable;
- {
- 
- 	if (enable)
- 		*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
- 			IOASIC_INTR_300_OPT1;
- 	else
- 		*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
- 			~IOASIC_INTR_300_OPT1;
- }
- 
- void
- ioasic_300_opts_isintr(opt0, opt1)
- 	int *opt0, *opt1;
- {
- 	u_int32_t sir;
- 
- 	sir = *(volatile u_int32_t *)IOASIC_REG_INTR(ioasic_base);
- 	*opt0 = sir & IOASIC_INTR_300_OPT0;
- 	*opt1 = sir & IOASIC_INTR_300_OPT1;
- }
- #endif
--- 335,337 ----
Index: src/sys/arch/alpha/tc/tc_3000_300.c
===================================================================
RCS file: /usr/users/cgd/NetBSD/cvs/src/sys/arch/alpha/tc/tc_3000_300.c,v
retrieving revision 1.8
diff -c -r1.8 tc_3000_300.c
*** 1.8	1995/12/20 03:34:14
--- tc_3000_300.c	1995/12/22 06:21:16
***************
*** 36,41 ****
--- 36,42 ----
  #include <dev/tc/tcvar.h>
  #include <alpha/tc/tc_conf.h>
  #include <alpha/tc/tc_3000_300.h>
+ #include <alpha/tc/ioasicreg.h>
  
  void	tc_3000_300_intr_setup __P((void));
  void	tc_3000_300_intr_establish __P((struct device *, void *,
***************
*** 48,53 ****
--- 49,62 ----
  #define	C(x)	((void *)(u_long)x)
  #define	KV(x)	(phystok0seg(x))
  
+ /*
+  * We have to read and modify the IOASIC registers directly, because
+  * the TC option slot interrupt request and mask bits are stored there,
+  * and the ioasic code isn't initted when we need to frob some interrupt
+  * bits.
+  */
+ #define	DEC_3000_300_IOASIC_ADDR	KV(0x1a0000000)
+ 
  struct tc_slotdesc tc_3000_300_slots[] = {
  	{ KV(0x100000000), C(TC_3000_300_DEV_OPT0), },	/* 0 - opt slot 0 */
  	{ KV(0x120000000), C(TC_3000_300_DEV_OPT1), },	/* 1 - opt slot 1 */
***************
*** 71,91 ****
  	void	*tci_arg;
  } tc_3000_300_intr[TC_3000_300_NCOOKIES];
  
- /* XXX */
- void	ioasic_intr_300_opt0_enable __P((int));
- void	ioasic_intr_300_opt1_enable __P((int));
- void	ioasic_300_opts_isintr __P((int *, int *));
- 
  void
  tc_3000_300_intr_setup()
  {
  	u_long i;
  
  	/*
! 	 * Sisable all interrupts that we can (can't disable builtins).
  	 */
! 	ioasic_intr_300_opt0_enable(0);
! 	ioasic_intr_300_opt1_enable(0);
  
  	/*
  	 * Set up interrupt handlers.
--- 80,96 ----
  	void	*tci_arg;
  } tc_3000_300_intr[TC_3000_300_NCOOKIES];
  
  void
  tc_3000_300_intr_setup()
  {
+ 	volatile u_int32_t *imskp;
  	u_long i;
  
  	/*
! 	 * Disable all interrupts that we can (can't disable builtins).
  	 */
! 	imskp = (volatile u_int32_t *)IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
! 	*imskp &= ~(IOASIC_INTR_300_OPT0 | IOASIC_INTR_300_OPT1);
  
  	/*
  	 * Set up interrupt handlers.
***************
*** 103,108 ****
--- 108,114 ----
  	tc_intrlevel_t level;
  	int (*func) __P((void *));
  {
+ 	volatile u_int32_t *imskp;
  	u_long dev = (u_long)cookie;
  
  #ifdef DIAGNOSTIC
***************
*** 115,126 ****
  	tc_3000_300_intr[dev].tci_func = func;
  	tc_3000_300_intr[dev].tci_arg = arg;
  
  	switch (dev) {
  	case TC_3000_300_DEV_OPT0:
! 		ioasic_intr_300_opt0_enable(1);
  		break;
  	case TC_3000_300_DEV_OPT1:
! 		ioasic_intr_300_opt1_enable(1);
  		break;
  	default:
  		/* interrupts for builtins always enabled */
--- 121,133 ----
  	tc_3000_300_intr[dev].tci_func = func;
  	tc_3000_300_intr[dev].tci_arg = arg;
  
+ 	imskp = (volatile u_int32_t *)IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
  	switch (dev) {
  	case TC_3000_300_DEV_OPT0:
! 		*imskp |= IOASIC_INTR_300_OPT0;
  		break;
  	case TC_3000_300_DEV_OPT1:
! 		*imskp |= IOASIC_INTR_300_OPT1;
  		break;
  	default:
  		/* interrupts for builtins always enabled */
***************
*** 133,138 ****
--- 140,146 ----
  	struct device *tcadev;
  	void *cookie;
  {
+ 	volatile u_int32_t *imskp;
  	u_long dev = (u_long)cookie;
  
  #ifdef DIAGNOSTIC
***************
*** 143,154 ****
  		panic("tc_3000_300_intr_disestablish: cookie %d bad intr",
  		    dev);
  
  	switch (dev) {
  	case TC_3000_300_DEV_OPT0:
! 		ioasic_intr_300_opt0_enable(0);
  		break;
  	case TC_3000_300_DEV_OPT1:
! 		ioasic_intr_300_opt1_enable(0);
  		break;
  	default:
  		/* interrupts for builtins always enabled */
--- 151,163 ----
  		panic("tc_3000_300_intr_disestablish: cookie %d bad intr",
  		    dev);
  
+ 	imskp = (volatile u_int32_t *)IOASIC_REG_IMSK(DEC_3000_300_IOASIC_ADDR);
  	switch (dev) {
  	case TC_3000_300_DEV_OPT0:
! 		*imskp &= ~IOASIC_INTR_300_OPT0;
  		break;
  	case TC_3000_300_DEV_OPT1:
! 		*imskp &= ~IOASIC_INTR_300_OPT1;
  		break;
  	default:
  		/* interrupts for builtins always enabled */
***************
*** 173,179 ****
  	void *framep;
  	int vec;
  {
! 	u_int32_t ir;
  	int opt0intr, opt1intr, ifound;
  
  #ifdef DIAGNOSTIC
--- 182,188 ----
  	void *framep;
  	int vec;
  {
! 	u_int32_t tcir, ioasicir;
  	int opt0intr, opt1intr, ifound;
  
  #ifdef DIAGNOSTIC
***************
*** 190,201 ****
  		tc_syncbus();
  
  		/* find out what interrupts/errors occurred */
! 		ir = *(volatile u_int32_t *)TC_3000_300_IR;
! 		ioasic_300_opts_isintr(&opt0intr, &opt1intr);
  		tc_mb();
  
  		/* clear the interrupts/errors we found. */
! 		*(volatile u_int32_t *)TC_3000_300_IR = ir;
  		/* XXX can't clear TC option slot interrupts here? */
  		tc_wmb();
  
--- 199,211 ----
  		tc_syncbus();
  
  		/* find out what interrupts/errors occurred */
! 		tcir = *(volatile u_int32_t *)TC_3000_300_IR;
! 		ioasicir = *(volatile u_int32_t *)
! 		    IOASIC_REG_INTR(DEC_3000_300_IOASIC_ADDR);
  		tc_mb();
  
  		/* clear the interrupts/errors we found. */
! 		*(volatile u_int32_t *)TC_3000_300_IR = tcir;
  		/* XXX can't clear TC option slot interrupts here? */
  		tc_wmb();
  
***************
*** 207,222 ****
  			    (tc_3000_300_intr[slot].tci_arg);		\
  		}
  		/* Do them in order of priority; highest slot # first. */
! 		CHECKINTR(TC_3000_300_DEV_CXTURBO, ir & TC_3000_300_IR_CXTURBO);
! 		CHECKINTR(TC_3000_300_DEV_IOASIC, ir & TC_3000_300_IR_IOASIC);
! 		CHECKINTR(TC_3000_300_DEV_TCDS, ir & TC_3000_300_IR_TCDS);
! 		CHECKINTR(TC_3000_300_DEV_OPT1, opt1intr);
! 		CHECKINTR(TC_3000_300_DEV_OPT0, opt0intr);
  #undef CHECKINTR
  
  #ifdef DIAGNOSTIC
  #define PRINTINTR(msg, bits)						\
! 	if (ir & bits)							\
  		printf(msg);
  		PRINTINTR("BCache tag parity error\n",
  		    TC_3000_300_IR_BCTAGPARITY);
--- 217,235 ----
  			    (tc_3000_300_intr[slot].tci_arg);		\
  		}
  		/* Do them in order of priority; highest slot # first. */
! 		CHECKINTR(TC_3000_300_DEV_CXTURBO,
! 		    tcir & TC_3000_300_IR_CXTURBO);
! 		CHECKINTR(TC_3000_300_DEV_IOASIC, tcir & TC_3000_300_IR_IOASIC);
! 		CHECKINTR(TC_3000_300_DEV_TCDS, tcir & TC_3000_300_IR_TCDS);
! 		CHECKINTR(TC_3000_300_DEV_OPT1,
! 		    ioasicir & IOASIC_INTR_300_OPT0);
! 		CHECKINTR(TC_3000_300_DEV_OPT0,
! 		    ioasicir & IOASIC_INTR_300_OPT1);
  #undef CHECKINTR
  
  #ifdef DIAGNOSTIC
  #define PRINTINTR(msg, bits)						\
! 	if (tcir & bits)						\
  		printf(msg);
  		PRINTINTR("BCache tag parity error\n",
  		    TC_3000_300_IR_BCTAGPARITY);