Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Mar 2012 01:23:09 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232847 - head/sys/mips/atheros
Message-ID:  <201203120123.q2C1N9Mc035711@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Mon Mar 12 01:23:09 2012
New Revision: 232847
URL: http://svn.freebsd.org/changeset/base/232847

Log:
  - Rename apb_intr to apb_filter since it's a filter handler
  - Pass interrupt trapframe for handlers dow the chain
  - Add PMC interrupt handler
      PMC interrupt is a special case, so we want handle it as soon as possible
      with minimum overhead. So we handle it apb filter routine.

Modified:
  head/sys/mips/atheros/apb.c

Modified: head/sys/mips/atheros/apb.c
==============================================================================
--- head/sys/mips/atheros/apb.c	Mon Mar 12 01:19:41 2012	(r232846)
+++ head/sys/mips/atheros/apb.c	Mon Mar 12 01:23:09 2012	(r232847)
@@ -36,6 +36,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/rman.h>
 #include <sys/malloc.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/pmc.h>
+#include <sys/pmckern.h>
 
 #include <machine/bus.h>
 #include <machine/intr_machdep.h>
@@ -44,6 +48,8 @@ __FBSDID("$FreeBSD$");
 #include <mips/atheros/ar71xxreg.h>
 #include <mips/atheros/ar71xx_setup.h>
 
+#define	APB_INTR_PMC	5
+
 #undef APB_DEBUG
 #ifdef APB_DEBUG
 #define dprintf printf
@@ -63,7 +69,7 @@ static int	apb_deactivate_resource(devic
 static struct resource_list *
 		apb_get_resource_list(device_t, device_t);
 static void	apb_hinted_child(device_t, const char *, int);
-static int	apb_intr(void *);
+static int	apb_filter(void *);
 static int	apb_probe(device_t);
 static int	apb_release_resource(device_t, device_t, int, int,
 		    struct resource *);
@@ -132,7 +138,7 @@ apb_attach(device_t dev)
 	}
 
 	if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, 
-	    apb_intr, NULL, sc, &sc->sc_misc_ih))) {
+	    apb_filter, NULL, sc, &sc->sc_misc_ih))) {
 		device_printf(dev,
 		    "WARNING: unable to register interrupt handler\n");
 		return (ENXIO);
@@ -142,6 +148,12 @@ apb_attach(device_t dev)
 	bus_enumerate_hinted_children(dev);
 	bus_generic_attach(dev);
 
+	/*
+	 * Unmask performance counter IRQ
+	 */
+	apb_unmask_irq((void*)APB_INTR_PMC);
+	sc->sc_intr_counter[APB_INTR_PMC] = mips_intrcnt_create("apb irq5: pmc");
+
 	return (0);
 }
 
@@ -329,11 +341,12 @@ apb_teardown_intr(device_t dev, device_t
 }
 
 static int
-apb_intr(void *arg)
+apb_filter(void *arg)
 {
 	struct apb_softc *sc = arg;
 	struct intr_event *event;
 	uint32_t reg, irq;
+	struct thread *td;
 
 	reg = ATH_READ_REG(AR71XX_MISC_INTR_STATUS);
 	for (irq = 0; irq < APB_NIRQS; irq++) {
@@ -354,14 +367,34 @@ apb_intr(void *arg)
 
 			event = sc->sc_eventstab[irq];
 			if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
+				if (irq == APB_INTR_PMC) {
+					register_t s;
+					struct trapframe *tf = PCPU_GET(curthread)->td_intr_frame;
+					s = intr_disable();
+					mips_intrcnt_inc(sc->sc_intr_counter[irq]);
+
+					if (pmc_intr && (*pmc_intr)(PCPU_GET(cpuid), tf)) {
+						intr_restore(s);
+						continue;
+					}
+
+					intr_restore(s);
+					td = PCPU_GET(curthread);
+
+					if (pmc_hook && (td->td_pflags & TDP_CALLCHAIN))
+						pmc_hook(PCPU_GET(curthread),
+							PMC_FN_USER_CALLCHAIN, tf);
+				
+					continue;
+
+				}
 				/* Ignore timer interrupts */
 				if (irq != 0)
 					printf("Stray APB IRQ %d\n", irq);
 				continue;
 			}
 
-			/* TODO: frame instead of NULL? */
-			intr_event_handle(event, NULL);
+			intr_event_handle(event, PCPU_GET(curthread)->td_intr_frame);
 			mips_intrcnt_inc(sc->sc_intr_counter[irq]);
 		}
 	}



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