Date: Mon, 9 Nov 2015 17:57:32 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r290614 - in head/sys: arm/arm arm/conf arm/include conf Message-ID: <201511091757.tA9HvWCk081852@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Mon Nov 9 17:57:32 2015 New Revision: 290614 URL: https://svnweb.freebsd.org/changeset/base/290614 Log: Now that the PMU implementation is independent of HWPMC as of r288992 use it to manage the CCNT. Use the CNNT for get_cyclecount() instead of binuptime() when device pmu is compiled in; if it fails to attach, fall back to the former method. Enable by default for the BeagleBoneBlack configuration. Optained from: Cambridge/L41 Sponsored by: DARPA/AFRL Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D3837 Modified: head/sys/arm/arm/pmu.c head/sys/arm/conf/BEAGLEBONE head/sys/arm/include/cpu.h head/sys/conf/options.arm Modified: head/sys/arm/arm/pmu.c ============================================================================== --- head/sys/arm/arm/pmu.c Mon Nov 9 16:50:42 2015 (r290613) +++ head/sys/arm/arm/pmu.c Mon Nov 9 17:57:32 2015 (r290614) @@ -94,16 +94,44 @@ static struct resource_spec pmu_spec[] = { -1, 0 } }; +/* CCNT */ +#if __ARM_ARCH > 6 +int pmu_attched = 0; +uint32_t ccnt_hi[MAXCPU]; +#endif + +#define PMU_OVSR_C 0x80000000 /* Cycle Counter */ +#define PMU_IESR_C 0x80000000 /* Cycle Counter */ + static int pmu_intr(void *arg) { +#ifdef HWPMC_HOOKS struct trapframe *tf; - - tf = arg; +#endif + uint32_t r; +#if defined(__arm__) && (__ARM_ARCH > 6) + u_int cpu; + + cpu = PCPU_GET(cpuid); + + r = cp15_pmovsr_get(); + if (r & PMU_OVSR_C) { + atomic_add_32(&ccnt_hi[cpu], 1); + /* Clear the event. */ + r &= ~PMU_OVSR_C; + cp15_pmovsr_set(PMU_OVSR_C); + } +#else + r = 1; +#endif #ifdef HWPMC_HOOKS - if (pmc_intr) + /* Only call into the HWPMC framework if we know there is work. */ + if (r != 0 && pmc_intr) { + tf = arg; (*pmc_intr)(PCPU_GET(cpuid), tf); + } #endif return (FILTER_HANDLED); @@ -128,6 +156,9 @@ static int pmu_attach(device_t dev) { struct pmu_softc *sc; +#if defined(__arm__) && (__ARM_ARCH > 6) + uint32_t iesr; +#endif int err; int i; @@ -152,6 +183,20 @@ pmu_attach(device_t dev) } } +#if defined(__arm__) && (__ARM_ARCH > 6) + /* Initialize to 0. */ + for (i = 0; i < MAXCPU; i++) + ccnt_hi[i] = 0; + + /* Enable the interrupt to fire on overflow. */ + iesr = cp15_pminten_get(); + iesr |= PMU_IESR_C; + cp15_pminten_set(iesr); + + /* Need this for getcyclecount() fast path. */ + pmu_attched |= 1; +#endif + return (0); } Modified: head/sys/arm/conf/BEAGLEBONE ============================================================================== --- head/sys/arm/conf/BEAGLEBONE Mon Nov 9 16:50:42 2015 (r290613) +++ head/sys/arm/conf/BEAGLEBONE Mon Nov 9 17:57:32 2015 (r290614) @@ -102,6 +102,9 @@ device ti_pruss # Mailbox support device ti_mbox +# PMU support (for CCNT). +device pmu + # USB support device usb options USB_HOST_ALIGN=64 # Align usb buffers to cache line size. Modified: head/sys/arm/include/cpu.h ============================================================================== --- head/sys/arm/include/cpu.h Mon Nov 9 16:50:42 2015 (r290613) +++ head/sys/arm/include/cpu.h Mon Nov 9 17:57:32 2015 (r290614) @@ -14,12 +14,42 @@ void swi_vm(void *); #ifdef _KERNEL #if __ARM_ARCH >= 6 #include <machine/cpu-v6.h> -#endif +#ifdef DEV_PMU +#include <sys/pcpu.h> +#define PMU_OVSR_C 0x80000000 /* Cycle Counter */ +extern uint32_t ccnt_hi[MAXCPU]; +extern int pmu_attched; +#endif /* DEV_PMU */ +#endif /* __ARM_ARCH >= 6 */ + static __inline uint64_t get_cyclecount(void) { #if __ARM_ARCH >= 6 - return cp15_pmccntr_get(); +#if (__ARM_ARCH > 6) && defined(DEV_PMU) + if (pmu_attched) { + u_int cpu; + uint64_t h, h2; + uint32_t l, r; + + cpu = PCPU_GET(cpuid); + h = (uint64_t)atomic_load_acq_32(&ccnt_hi[cpu]); + l = cp15_pmccntr_get(); + /* In case interrupts are disabled we need to check for overflow. */ + r = cp15_pmovsr_get(); + if (r & PMU_OVSR_C) { + atomic_add_32(&ccnt_hi[cpu], 1); + /* Clear the event. */ + cp15_pmovsr_set(PMU_OVSR_C); + } + /* Make sure there was no wrap-around while we read the lo half. */ + h2 = (uint64_t)atomic_load_acq_32(&ccnt_hi[cpu]); + if (h != h2) + l = cp15_pmccntr_get(); + return (h2 << 32 | l); + } else +#endif + return cp15_pmccntr_get(); #else /* No performance counters, so use binuptime(9). This is slooooow */ struct bintime bt; Modified: head/sys/conf/options.arm ============================================================================== --- head/sys/conf/options.arm Mon Nov 9 16:50:42 2015 (r290613) +++ head/sys/conf/options.arm Mon Nov 9 17:57:32 2015 (r290614) @@ -23,6 +23,7 @@ CPU_XSCALE_IXP425 opt_global.h CPU_XSCALE_IXP435 opt_global.h CPU_XSCALE_PXA2X0 opt_global.h DEV_GIC opt_global.h +DEV_PMU opt_global.h EFI opt_platform.h FLASHADDR opt_global.h GIC_DEFAULT_ICFGR_INIT opt_global.h
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511091757.tA9HvWCk081852>