PERFORCE change 117957 for review

Oleksandr Tymoshenko gonzo at FreeBSD.org
Thu Apr 12 12:28:04 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=117957

Change 117957 by gonzo at gonzo_jeeves on 2007/04/12 12:27:08

	o Migrate on new inetrrupt filtering API.
	o Replace "magic numbers" with named constants and export them
	    through genassym.c.

Affected files ...

.. //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 edit
.. //depot/projects/mips2/src/sys/mips/mips/cpu.c#18 edit
.. //depot/projects/mips2/src/sys/mips/mips/genassym.c#7 edit
.. //depot/projects/mips2/src/sys/mips/mips/intr_machdep.c#3 edit
.. //depot/projects/mips2/src/sys/mips/mips/nexus.c#4 edit
.. //depot/projects/mips2/src/sys/mips/mips/tick.c#5 edit
.. //depot/projects/mips2/src/sys/mips/mips4k/malta/gt_pci.c#5 edit

Differences ...

==== //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 (text+ko) ====

@@ -23,26 +23,21 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#2 $
+ * $P4: //depot/projects/mips2/src/sys/mips/include/intr_machdep.h#3 $
  */
 
 #ifndef	_MACHINE_INTR_H_
 #define	_MACHINE_INTR_H_
 
+#define NHARD_IRQS	6
+#define NSOFT_IRQS	2
+
 struct trapframe;
 
-/*
- * Include the platform-specific MD interrupt header.
- */
-/*
- * XXXMIPS: We don't have this file.
- */
-#if 0
-#include <platform/intr.h>
-#endif
-
-void cpu_establish_hardintr(int, void (*)(void *), void *);
-void cpu_establish_softintr(int, void (*)(void *), void *);
+void cpu_establish_hardintr(const char *, int (*)(void*), void (*)(void*), 
+    void *, int, int, void **);
+void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*), 
+    void *, int, int, void **);
 void cpu_intr(struct trapframe *);
 
 #endif /* !_MACHINE_INTR_H_ */

==== //depot/projects/mips2/src/sys/mips/mips/cpu.c#18 (text+ko) ====

@@ -83,6 +83,9 @@
 	size_t len, max;
 
 	max = 0x80;
+	if(bootverbose)
+		printf("Installing exception vector:\n\t[%p..%p] <- [%p..%p]\n",
+		    (void *)addr, (void *)(addr+max), begin, end);
 	len = end - begin;
 	if (len > max)
 		panic("exception code too big for vector %jx", (intmax_t) addr);
@@ -263,7 +266,8 @@
 static struct resource *cpu_alloc_resource(device_t, device_t, int, int *,
 					   u_long, u_long, u_long, u_int);
 static int cpu_setup_intr(device_t, device_t, struct resource *, int,
-			  driver_intr_t *, void *, void **);
+			  driver_filter_t *f, driver_intr_t *, void *, 
+			  void **);
 
 static device_method_t cpu_methods[] = {
 	/* Device interface */
@@ -345,7 +349,8 @@
 
 static int
 cpu_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
-	       driver_intr_t *handler, void *arg, void **cookiep)
+	       driver_filter_t *filt, driver_intr_t *handler, void *arg, 
+	       void **cookiep)
 {
 	int error;
 	int intr;
@@ -358,7 +363,8 @@
 
 	intr = rman_get_start(res);
 
-	cpu_establish_hardintr(intr, handler, arg);
+	cpu_establish_hardintr(device_get_nameunit(child), filt, handler, arg, 
+	    intr, flags, cookiep);
 	device_printf(child, "established CPU interrupt %d\n", intr);
 	return (0);
 }

==== //depot/projects/mips2/src/sys/mips/mips/genassym.c#7 (text+ko) ====

@@ -60,6 +60,7 @@
 #include <net/if.h>
 #include <netinet/in.h>
 
+#include <machine/intr_machdep.h>
 #include <machine/locore.h>
 #include <machine/pcb.h>
 #include <machine/reg.h>
@@ -67,6 +68,7 @@
 ASSYM(MIPS_KSEG0_START, MIPS_KSEG0_START);
 ASSYM(MIPS_KSSEG_START, MIPS_KSSEG_START);
 ASSYM(MIPS_PG_G, PG_G);
+
 ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
 ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
 ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
@@ -76,7 +78,6 @@
 ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
 
 ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
-
 ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
 ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack));
 ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
@@ -191,3 +192,6 @@
 ASSYM(VM_MIN_KERNEL_ADDRESS, VM_MIN_KERNEL_ADDRESS);
 ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
 
+ASSYM(NHARD_IRQS, NHARD_IRQS);
+ASSYM(NSOFT_IRQS, NSOFT_IRQS);
+ASSYM(MAXCOMLEN, MAXCOMLEN);

==== //depot/projects/mips2/src/sys/mips/mips/intr_machdep.c#3 (text+ko) ====

@@ -32,6 +32,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
+#include <sys/interrupt.h>
 
 #include <machine/cpu.h>
 #include <machine/cpufunc.h>
@@ -42,53 +43,87 @@
 #include <machine/md_var.h>
 #include <machine/trap.h>
 
-struct intrhand {
-	void (*handler)(void *);
-	void *arg;
-};
-static struct intrhand intrhard[6];
-static struct intrhand intrsoft[2];
+static struct intr_event *hardintr_events[NHARD_IRQS];
+static struct intr_event *softintr_events[NSOFT_IRQS];
+
+#ifdef notyet
+static int intrcnt_tab[NHARD_IRQS + NSOFT_IRQS];
+static int intrcnt_index = 0;
+static int last_printed = 0;
+#endif
 
 void
-cpu_establish_hardintr(int intr, void (*handler)(void *), void *arg)
+cpu_establish_hardintr(const char *name, driver_filter_t *filt, 
+    void (*handler)(void*), void *arg, int irq, int flags, 
+    void **cookiep)
 {
-	struct intrhand *ih;
+        struct intr_event *event;
+        int error;
+
+	if (irq < 0 || irq > NHARD_IRQS)
+		panic("%s called for unknown hard intr %d", __func__, irq);
+
+        event = hardintr_events[irq];
+        if (event == NULL) {
+                error = intr_event_create(&event, (void *)irq, 0,
+                    (void (*)(void *))NULL, "hard intr%d:", irq);
+                if (error)
+                        return;
+                hardintr_events[irq] = event;
+#ifdef notyet
+                last_printed += 
+                    snprintf(intrnames + last_printed,
+                    MAXCOMLEN + 1,
+                    "hard irq%d: %s", irq, name);
+                last_printed++;
+                intrcnt_tab[irq] = intrcnt_index;
+                intrcnt_index++;
+#endif
+                
+        }
 
-	if (intr < 0 || intr > 5)
-		panic("%s called for unknown hard intr %d", __func__, intr);
-	ih = &intrhard[intr];
-	if (ih->handler != NULL && ih->handler != handler)
-		panic("%s cannot share hard intr %d", __func__, intr);
-	ih->handler = handler;
-	ih->arg = arg;
+        intr_event_add_handler(event, name, filt, handler, arg,
+            intr_priority(flags), flags, cookiep);
 
-	mips_wr_status(mips_rd_status() | (((1<< intr) << 8) << 2));
+	mips_wr_status(mips_rd_status() | (((1<< irq) << 8) << 2));
 }
 
 void
-cpu_establish_softintr(int intr, void (*handler)(void *), void *arg)
+cpu_establish_softintr(const char *name, driver_filter_t *filt, 
+    void (*handler)(void*), void *arg, int irq, int flags, 
+    void **cookiep)
 {
-	struct intrhand *ih;
+        struct intr_event *event;
+        int error;
+
+	if (irq < 0 || irq > NSOFT_IRQS)
+		panic("%s called for unknown hard intr %d", __func__, irq);
+
+        event = softintr_events[irq];
+        if (event == NULL) {
+                error = intr_event_create(&event, (void *)irq, 0,
+                    (void (*)(void *))NULL, "intr%d:", irq);
+                if (error)
+                        return;
+                softintr_events[irq] = event;
+        }
 
-	if (intr < 0 || intr > 1)
-		panic("%s called for unknown soft intr %d", __func__, intr);
-	ih = &intrsoft[intr];
-	if (ih->handler != NULL && ih->handler != handler)
-		panic("%s cannot share soft intr %d", __func__, intr);
-	ih->handler = handler;
-	ih->arg = arg;
+        intr_event_add_handler(event, name, filt, handler, arg,
+            intr_priority(flags), flags, cookiep);
 
-	mips_wr_status(mips_rd_status() | ((1 << intr) << 8));
+	mips_wr_status(mips_rd_status() | (((1<< irq) << 8)));
 }
 
 void
 cpu_intr(struct trapframe *tf)
 {
-	struct intrhand *ih;
+	struct intr_handler *ih;
+	struct intr_event *event;
 	register_t cause;
 	int hard;
 	int intr;
 	int i;
+	int thread;
 
 	critical_enter();
 
@@ -104,25 +139,39 @@
 			/* Software interrupt. */
 			i--; /* Get a 0-offset interrupt. */
 			hard = 0;
-			ih = &intrsoft[i];
+			event = softintr_events[i];
 			break;
 		default:
 			/* Hardware interrupt. */
 			i -= 2; /* Trim software interrupt bits. */
 			i--; /* Get a 0-offset interrupt. */
 			hard = 1;
-			ih = &intrhard[i];
+			event = hardintr_events[i];
 			break;
 		}
-		if (ih->handler != NULL) {
-			if (ih->arg == NULL)
-				(*ih->handler)(tf);
+
+		if (!event || TAILQ_EMPTY(&event->ie_handlers))
+		{
+			printf("stray %s interrupt %d\n",
+			    hard ? "hard" : "soft", i);
+			continue;
+		}
+
+		/* Execute fast handlers. */
+		thread = 0;
+		TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
+			if (ih->ih_filter == NULL)
+				thread = 1;
 			else
-				(*ih->handler)(ih->arg);
-		} else
-			printf("stray %s interrupt %d\n",
-			       hard ? "hard" : "soft", i);
+				ih->ih_filter(ih->ih_argument ?
+				    ih->ih_argument : tf);
+		}
+
+		/* Schedule thread if needed. */
+		if (thread)
+			intr_event_schedule_thread(event);
 	}
+
 	KASSERT(i == 0, ("all interrupts handled"));
 
 	critical_exit();

==== //depot/projects/mips2/src/sys/mips/mips/nexus.c#4 (text+ko) ====

@@ -80,7 +80,7 @@
 	struct resource *);
 static int
 nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
-        driver_intr_t *intr, void *arg, void **cookiep);
+        driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep);
 static int
 nexus_teardown_intr(device_t, device_t, struct resource *, void *);
 
@@ -124,7 +124,7 @@
 
 static int
 nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
-    driver_intr_t *intr, void *arg, void **cookiep)
+    driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
 {
 	int irq;
 
@@ -132,7 +132,9 @@
 	irq = rman_get_start(res);
 	if(irq > 5)
 		return(0);
-	cpu_establish_hardintr(irq, intr, arg);
+	
+	cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, 
+	    irq, flags, cookiep);
 	intr_restore(sr);
 	return (0);
 }

==== //depot/projects/mips2/src/sys/mips/mips/tick.c#5 (text+ko) ====

@@ -203,7 +203,6 @@
 	/*
 	 * Set next clock edge.
 	 */
-
 	mips_wr_compare(mips_rd_count() + counter_freq / hz);
 
 	/*
@@ -218,7 +217,7 @@
 		hardclock(usermode, pc);
 	}
 
-	return (FILTER_HANDLED);
+	return FILTER_HANDLED;
 }
 
 static int
@@ -250,9 +249,10 @@
 		device_printf(dev, "failed to allocate irq\n");
 		return (ENXIO);
 	}
-	error = bus_setup_intr(dev, irq,
-				   INTR_TYPE_CLK | INTR_MPSAFE | INTR_FAST,
-				   clock_intr, NULL, NULL, NULL);
+
+	error = bus_setup_intr(dev, irq, INTR_TYPE_CLK, clock_intr, NULL,
+	    NULL, NULL);
+
 	if (error != 0) {
 		device_printf(dev, "bus_setup_intr returned %d\n", error);
 		return (error);

==== //depot/projects/mips2/src/sys/mips/mips4k/malta/gt_pci.c#5 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <sys/systm.h>
 
 #include <sys/bus.h>
+#include <sys/interrupt.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
@@ -90,17 +91,6 @@
 #define OCW3_POLL_IRQ(x) ((x) & 0x7f)
 #define OCW3_POLL_PENDING (1U << 7)
 
-struct intrhand {
-	LIST_ENTRY(intrhand)	ih_list;
-	driver_intr_t		*ih_func;
-	void			*ih_arg;
-	int			ih_irq;
-};
-
-struct pci_intrhead {
-	LIST_HEAD(, intrhand) intr_list;
-};
-
 struct gt_pci_softc {
 	device_t 		sc_dev;
 	bus_space_tag_t 	sc_st;
@@ -118,7 +108,7 @@
 	uint32_t		sc_io;
 
 	struct resource		*sc_irq;
-	struct pci_intrhead	sc_intrtab[ICU_LEN];
+	struct intr_event	*sc_eventstab[ICU_LEN];
 	uint16_t		sc_imask;
 	uint16_t		sc_elcr;
 
@@ -151,8 +141,9 @@
 gt_pci_intr(void *v)
 {
 	struct gt_pci_softc *sc = v;
-	struct intrhand *ih;
-	int irq;
+	struct intr_event *event;
+	struct intr_handler *ih;
+	int irq, thread;
 
 	for (;;) {
 		bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3,
@@ -176,8 +167,23 @@
 				irq = 2;
 		}
 
-		LIST_FOREACH(ih, &sc->sc_intrtab[irq].intr_list, ih_list)
-			(*ih->ih_func)(ih->ih_arg);
+		event = sc->sc_eventstab[irq];
+		thread = 0;
+
+		if (event && !TAILQ_EMPTY(&event->ie_handlers))
+		{
+			/* Execute fast handlers. */
+			TAILQ_FOREACH(ih, &event->ie_handlers, ih_next) {
+				if (ih->ih_filter == NULL)
+					thread = 1;
+				else
+					ih->ih_filter(ih->ih_argument);
+			}
+		}
+
+		/* Schedule thread if needed. */
+		if (thread)
+			intr_event_schedule_thread(event);
 
 		/* Send a specific EOI to the 8259. */
 		if (irq > 7) {
@@ -192,8 +198,6 @@
 	}
 }
 
-
-
 static int
 gt_pci_probe(device_t dev)
 {
@@ -205,9 +209,9 @@
 gt_pci_attach(device_t dev)
 {
 
-	uint32_t busno;                                       
+	uint32_t busno;				       
 	struct gt_pci_softc *sc = device_get_softc(dev);
-	int rid, i;
+	int rid;
 
 	busno = 0;
 	sc->sc_dev = dev;
@@ -270,7 +274,7 @@
 	    ICW1_RESET | ICW1_IC4);
 	/*
 	 * XXX: values from NetBSD's <dev/ic/i8259reg.h>
-         */	 
+	 */	 
 	bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
 	    0/*XXX*/);
 	bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
@@ -338,30 +342,20 @@
 		(1U << 14) |    /* IDE primary */
 		(1U << 15);     /* IDE secondary */
 
-	/* Initialize our interrupt table. */
-	for (i = 0; i < ICU_LEN; i++) {
-		LIST_INIT(&sc->sc_intrtab[i].intr_list);
-	}
-
 	/* Hook up our interrupt handler. */
-        if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 
+	if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 
 	    MALTA_SOUTHBRIDGE_INTR, MALTA_SOUTHBRIDGE_INTR, 1, 
 	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
 		device_printf(dev, "unable to allocate IRQ resource\n");
 		return ENXIO;
-        }
+	}
 
-        if ((bus_setup_intr(dev, sc->sc_irq, INTR_FAST | INTR_MPSAFE,
-                            NULL, gt_pci_intr, sc, &sc->sc_ih))) {
+	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC,
+			    NULL, gt_pci_intr, sc, &sc->sc_ih))) {
 		device_printf(dev, 
 		    "WARNING: unable to register interrupt handler\n");
 		return ENXIO;
-        }
-
-	if (sc->sc_ih == NULL)
-
-
-
+	}
 
 	/* Initialize memory and i/o rmans. */
 	device_add_child(dev, "pci", busno);
@@ -392,8 +386,8 @@
 	uint32_t addr;
 	uint32_t shift, mask;
 
-        if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
-                return (uint32_t)(-1);
+	if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
+		return (uint32_t)(-1);
 
 	/* Clear cause register bits. */
 	GT_REGVAL(GT_INTR_CAUSE) = 0;
@@ -644,37 +638,36 @@
 }
 
 static int
-gt_pci_setup_intr(device_t dev, device_t child,
-    struct resource *ires, int flags, driver_intr_t *intr, void *arg,
-    void **cookiep)
+gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires, 
+		int flags, driver_filter_t *filt, driver_intr_t *handler, 
+		void *arg, void **cookiep)
 {
 	struct gt_pci_softc *sc = device_get_softc(dev);
-	struct intrhand *ih;
-	int irq;
+	struct intr_event *event;
+	int irq, error;
 
 	irq = rman_get_start(ires);
 	if (irq >= ICU_LEN || irq == 2)
 		panic("%s: bad irq or type", __func__);
 
-	ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
-	if (ih == NULL)
-		return ENOMEM;
+	event = sc->sc_eventstab[irq];
+	if (event == NULL) {
+		error = intr_event_create(&event, (void *)irq, 0,
+		    (void (*)(void *))NULL, "gt_pci intr%d:", irq);
+		if (error)
+			return 0;
+		sc->sc_eventstab[irq] = event;
+	}
 
-	ih->ih_func = intr;
-	ih->ih_arg = arg;
-	ih->ih_irq = irq;
+	intr_event_add_handler(event, device_get_nameunit(child), filt, 
+	    handler, arg, intr_priority(flags), flags, cookiep);
 
-	/* Insert the handler into the table. */
-	LIST_INSERT_HEAD(&sc->sc_intrtab[irq].intr_list, ih, ih_list);
-
 	/* Enable it, set trigger mode. */
 	sc->sc_imask &= ~(1 << irq);
 	sc->sc_elcr &= ~(1 << irq);
 
 	gt_pci_set_icus(sc);
 
-	*cookiep = (void *)ih;
-
 	return 0;
 }
 
@@ -682,19 +675,7 @@
 gt_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
     void *cookie)
 {
-	struct gt_pci_softc *sc = device_get_softc(dev);
-	struct intrhand *ih = cookie;
-	LIST_REMOVE(ih, ih_list);
-
-	/* If there are no more handlers on this IRQ, disable it. */
-	if (LIST_FIRST(&sc->sc_intrtab[ih->ih_irq].intr_list) == NULL) {
-		sc->sc_imask |= (1 << ih->ih_irq);
-		gt_pci_set_icus(sc);
-	}
-
-	free(ih, M_DEVBUF);
-
-	return 0;
+	return (intr_event_remove_handler(cookie));
 }
 
 static device_method_t gt_pci_methods[] = {


More information about the p4-projects mailing list