svn commit: r226336 - user/adrian/if_ath_tx/sys/mips/atheros

Adrian Chadd adrian at FreeBSD.org
Thu Oct 13 08:36:11 UTC 2011


Author: adrian
Date: Thu Oct 13 08:36:11 2011
New Revision: 226336
URL: http://svn.freebsd.org/changeset/base/226336

Log:
  Add in some _very dirty_ stuff to get the mips24k performance counter
  stuff working in interrupt mode.
  
  This is very _very_ local and mustn't be merged into -HEAD.
  
  If the relevant bit is set in the APB misc interrupt word, an interrupt
  is generated (APB IRQ 5) on each performance counter event.
  
  This at least generates sampling events but it's:
  
  * absolutely wrong looking;
  * since callchains aren't implemented, any testing _must_ involve
    disabling callchain events (pmcstat -N) or things will crash.
  
  The mips24k spec sets a specific bit in the trap cause register
  whenever a performance counter event occurs. But since I'm not yet
  sure whether we should just use that or the irq (or how to do
  mips24k specific stuff in the general mips trap frame handling code),
  I'll just abuse the interrupt code for now.

Modified:
  user/adrian/if_ath_tx/sys/mips/atheros/apb.c

Modified: user/adrian/if_ath_tx/sys/mips/atheros/apb.c
==============================================================================
--- user/adrian/if_ath_tx/sys/mips/atheros/apb.c	Thu Oct 13 08:29:47 2011	(r226335)
+++ user/adrian/if_ath_tx/sys/mips/atheros/apb.c	Thu Oct 13 08:36:11 2011	(r226336)
@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/rman.h>
 #include <sys/malloc.h>
+#include <sys/pcpu.h>
+#include <sys/pmckern.h>
 
 #include <machine/bus.h>
 #include <machine/intr_machdep.h>
@@ -142,6 +144,10 @@ apb_attach(device_t dev)
 	bus_enumerate_hinted_children(dev);
 	bus_generic_attach(dev);
 
+	/* Enable performance interrupts for testing */
+	ATH_WRITE_REG(AR71XX_MISC_INTR_MASK,
+	    ATH_READ_REG(AR71XX_MISC_INTR_MASK) | (1 << 5));
+
 	return (0);
 }
 
@@ -354,6 +360,34 @@ apb_intr(void *arg)
 
 			event = sc->sc_eventstab[irq];
 			if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
+				/* IRQ 5: perf counter */
+				if (irq == 5) {
+					register_t s;
+					struct trapframe *tf =
+					    PCPU_GET(curthread)->td_intr_frame;
+					s = intr_disable();
+					if (pmc_intr &&
+					    (*pmc_intr)(PCPU_GET(cpuid), tf)) {
+						continue;
+						mips_intrcnt_inc(sc->sc_intr_counter[irq]);
+					}
+					/* Call pmc_hook with the current trapframe */
+					/* XXX this should use the kernel SP? */
+#if 0
+					if (pmc_hook) {
+						pmc_hook(PCPU_GET(curthread),
+						    PMC_FN_USER_CALLCHAIN,
+						tf);
+					}
+#endif
+					/*
+					 * Sometimes I see PC ints occur which
+					 * aren't caused by an overflow.
+					 * Investigate this at a later date.
+					 */
+					intr_restore(s);
+					continue;
+				}
 				/* Ignore timer interrupts */
 				if (irq != 0)
 					printf("Stray APB IRQ %d\n", irq);


More information about the svn-src-user mailing list