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