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>