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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to