Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Feb 2010 16:30:29 +0000 (UTC)
From:      Randall Stewart <rrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r204130 - in head/sys/mips: include rmi
Message-ID:  <201002201630.o1KGUTlQ056893@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rrs
Date: Sat Feb 20 16:30:29 2010
New Revision: 204130
URL: http://svn.freebsd.org/changeset/base/204130

Log:
  Some fixes to the current RMI interrupt handling, changes in this patch are:
  - (cleanup) remove rmi specific 'struct mips_intrhand' - this is no
  longer needed since 'struct intr_event' have all the required hooks
  - add xlr_cpu_establish_hardintr, which has args for pre/post ithread
  and filter hooks, so that the PCI code can add the PCI controller
  interrupt ack code here
  - make 'cpu_establish_hardintr' use the above function.
  - (fix) change type of eirr/eimr from register_t to uint64_t. These
  have to be 64bit otherwise we cannot handle interrupts from 32.
  - (fix) use eimr to mask eirr before checking interrupts, so that we
  will not handle masked interrupts.
  
  Obtained from:  C. Jayachandran - c.jayachandran@gmail.com

Modified:
  head/sys/mips/include/intr_machdep.h
  head/sys/mips/rmi/interrupt.h
  head/sys/mips/rmi/intr_machdep.c

Modified: head/sys/mips/include/intr_machdep.h
==============================================================================
--- head/sys/mips/include/intr_machdep.h	Sat Feb 20 16:28:37 2010	(r204129)
+++ head/sys/mips/include/intr_machdep.h	Sat Feb 20 16:30:29 2010	(r204130)
@@ -30,21 +30,7 @@
 #define	_MACHINE_INTR_MACHDEP_H_
 
 #ifdef TARGET_XLR_XLS
-/*
- * XLR/XLS uses its own intr_machdep.c and has
- * a different number of interupts. This probably
- * should be placed somewhere else.
- */
-
-struct mips_intrhand {
-        struct  intr_event *mih_event;
-        driver_intr_t      *mih_disable;
-        volatile long       *cntp;  /* interrupt counter */
-};
-
-extern struct mips_intrhand mips_intr_handlers[];
 #define XLR_MAX_INTR 64 
-
 #else
 #define NHARD_IRQS	6
 #define NSOFT_IRQS	2

Modified: head/sys/mips/rmi/interrupt.h
==============================================================================
--- head/sys/mips/rmi/interrupt.h	Sat Feb 20 16:28:37 2010	(r204129)
+++ head/sys/mips/rmi/interrupt.h	Sat Feb 20 16:30:29 2010	(r204130)
@@ -25,7 +25,7 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
+ *__FBSDID("$FreeBSD$")
  * RMI_BSD */
 #ifndef _RMI_INTERRUPT_H_
 #define _RMI_INTERRUPT_H_
@@ -39,4 +39,14 @@
 #define IRQ_MSGRING              6
 #define IRQ_TIMER                7
 
+/*
+ * XLR needs custom pre and post handlers for PCI/PCI-e interrupts
+ * XXX: maybe follow i386 intsrc model
+ */
+void xlr_cpu_establish_hardintr(const char *, driver_filter_t *,
+    driver_intr_t *, void *, int, int, void **, void (*)(void *),
+    void (*)(void *), void (*)(void *), int (*)(void *, u_char));
+void xlr_mask_hard_irq(void *);
+void xlr_unmask_hard_irq(void *);
+
 #endif				/* _RMI_INTERRUPT_H_ */

Modified: head/sys/mips/rmi/intr_machdep.c
==============================================================================
--- head/sys/mips/rmi/intr_machdep.c	Sat Feb 20 16:28:37 2010	(r204129)
+++ head/sys/mips/rmi/intr_machdep.c	Sat Feb 20 16:30:29 2010	(r204130)
@@ -51,19 +51,19 @@ __FBSDID("$FreeBSD$");
 
 /*#include <machine/intrcnt.h>*/
 static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
-struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR];
+static struct intr_event *mips_intr_events[XLR_MAX_INTR];
 static int intrcnt_index;
 
-static void
-mips_mask_hard_irq(void *source)
+void
+xlr_mask_hard_irq(void *source)
 {
 	uintptr_t irq = (uintptr_t) source;
 
 	write_c0_eimr64(read_c0_eimr64() & ~(1ULL << irq));
 }
 
-static void
-mips_unmask_hard_irq(void *source)
+void
+xlr_unmask_hard_irq(void *source)
 {
 	uintptr_t irq = (uintptr_t) source;
 
@@ -71,10 +71,11 @@ mips_unmask_hard_irq(void *source)
 }
 
 void
-cpu_establish_hardintr(const char *name, driver_filter_t * filt,
-    void (*handler) (void *), void *arg, int irq, int flags, void **cookiep)
+xlr_cpu_establish_hardintr(const char *name, driver_filter_t * filt,
+    void (*handler) (void *), void *arg, int irq, int flags, void **cookiep,
+    void (*pre_ithread)(void *), void (*post_ithread)(void *),
+    void (*post_filter)(void *), int (*assign_cpu)(void *, u_char))
 {
-	struct mips_intrhand *mih;	/* descriptor for the IRQ */
 	struct intr_event *ie;	/* descriptor for the IRQ */
 	int errcode;
 
@@ -85,25 +86,33 @@ cpu_establish_hardintr(const char *name,
 	 * FIXME locking - not needed now, because we do this only on
 	 * startup from CPU0
 	 */
-	mih = &mips_intr_handlers[irq];
+	ie = mips_intr_events[irq];
 	/* mih->cntp = &intrcnt[irq]; */
-	ie = mih->mih_event;
 	if (ie == NULL) {
 		errcode = intr_event_create(&ie, (void *)(uintptr_t) irq, 0,
-		    irq, mips_mask_hard_irq, mips_unmask_hard_irq,
-		    NULL, NULL, "hard intr%d:", irq);
+		    irq, pre_ithread, post_ithread, post_filter, assign_cpu,
+		    "hard intr%d:", irq);
 
 		if (errcode) {
 			printf("Could not create event for intr %d\n", irq);
 			return;
 		}
+		mips_intr_events[irq] = ie;
 	}
+
 	intr_event_add_handler(ie, name, filt, handler, arg,
 	    intr_priority(flags), flags, cookiep);
-	mih->mih_event = ie;
-	mips_unmask_hard_irq((void *)(uintptr_t) irq);
+	xlr_unmask_hard_irq((void *)(uintptr_t) irq);
 }
 
+void
+cpu_establish_hardintr(const char *name, driver_filter_t * filt,
+    void (*handler) (void *), void *arg, int irq, int flags, void **cookiep)
+{
+	xlr_cpu_establish_hardintr(name, filt, handler, arg, irq,
+		flags, cookiep, xlr_mask_hard_irq, xlr_unmask_hard_irq,
+		NULL, NULL);
+}
 
 void
 cpu_establish_softintr(const char *name, driver_filter_t * filt,
@@ -111,20 +120,26 @@ cpu_establish_softintr(const char *name,
     void **cookiep)
 {
 	/* we don't separate them into soft/hard like other mips */
-	cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep);
+	xlr_cpu_establish_hardintr(name, filt, handler, arg, irq,
+		flags, cookiep, xlr_mask_hard_irq, xlr_unmask_hard_irq,
+		NULL, NULL);
 }
 
 void
 cpu_intr(struct trapframe *tf)
 {
-	struct mips_intrhand *mih;
 	struct intr_event *ie;
-	register_t eirr;
+	uint64_t eirr, eimr;
 	int i;
 
 	critical_enter();
+
+	/* find a list of enabled interrupts */
 	eirr = read_c0_eirr64();
-	if (eirr == 0) {
+	eimr = read_c0_eimr64();
+	eirr &= eimr;
+	
+	if (eirr == 0) { 
 		critical_exit();
 		return;
 	}
@@ -162,9 +177,8 @@ cpu_intr(struct trapframe *tf)
 		}
 #endif
 #endif
-		mih = &mips_intr_handlers[i];
+		ie = mips_intr_events[i];
 		/* atomic_add_long(mih->cntp, 1); */
-		ie = mih->mih_event;
 
 		write_c0_eirr64(1ULL << i);
 		pic_ack(i, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002201630.o1KGUTlQ056893>