Subject: IXP425 QMGR bug on slug
To: None <port-arm@netbsd.org>
From: rtos <rtos@rogers.com>
List: port-arm
Date: 06/04/2007 03:15:10
--=-72FQR3AMdiOmzlFrdm80
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

I am getting a couple of data abort's on my slug at boot time. 

In  /usr/src/sys/arch/arm/xscale/ixp425_qmgr.c  there is an array index
overflow in ixpqmgr_intr() because there is in an incorrect assumption
that all bits will be clear before the end of the array is reached.

.. and ixpqmgr_init() should initialize ixpqmgr_sc before
ixp425_intr_establish otherwise an interrupt arrives before ixpqmgr_sc
has a valid value.

A patch is attached.  



--=-72FQR3AMdiOmzlFrdm80
Content-Disposition: attachment; filename=ixp425_qmgr.c.diff
Content-Type: text/x-patch; name=ixp425_qmgr.c.diff; charset=UTF-8
Content-Transfer-Encoding: 7bit

*** /work/bsd/head270507.org/usr/src/sys/arch/arm/xscale/ixp425_qmgr.c	2007-06-04 01:01:09.000000000 -0400
--- ixp425_qmgr.c	2007-06-04 01:56:12.000000000 -0400
***************
*** 250,255 ****
--- 250,256 ----
  	bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE,
  		ixpqmgr_intr, NULL, &sc->sc_ih);
  #else
+     ixpqmgr_sc = sc;
  	sc->sc_ih[0] = ixp425_intr_establish(IXP425_INT_QUE1_32, IPL_NET,
  	    ixpqmgr_intr, sc);
  	if (sc->sc_ih[0] == NULL) {
***************
*** 264,270 ****
  		return (NULL);
  	}
  
- 	ixpqmgr_sc = sc;
  #endif
  
  	/* NB: softc is pre-zero'd */
--- 265,270 ----
***************
*** 804,809 ****
--- 804,812 ----
  		      */
  		     do {
  			 qIndex = sc->priorityTable[priorityTableIndex++];
+              if(qIndex >= IX_QMGR_MAX_NUM_QUEUES){
+                  break;
+              }
  			 qi = &sc->qinfo[qIndex];
  
  			 /* If this queue caused this interrupt to be raised */
***************
*** 813,819 ****
  			     /* Clear the interrupt register bit */
  			     intRegVal &= ~qi->intRegCheckMask;
  			 }
! 		      } while (intRegVal);
  		 }
  	 }
  
--- 816,822 ----
  			     /* Clear the interrupt register bit */
  			     intRegVal &= ~qi->intRegCheckMask;
  			 }
!              } while (intRegVal && priorityTableIndex < IX_QMGR_MAX_NUM_QUEUES);
  		 }
  	 }
  

--=-72FQR3AMdiOmzlFrdm80--