Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Oct 2011 08:36:11 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r226336 - user/adrian/if_ath_tx/sys/mips/atheros
Message-ID:  <201110130836.p9D8aBg1006930@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



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