Page MenuHomeFreeBSD

D3837.diff
No OneTemporary

D3837.diff

Index: head/sys/arm/arm/pmu.c
===================================================================
--- head/sys/arm/arm/pmu.c
+++ head/sys/arm/arm/pmu.c
@@ -94,16 +94,44 @@
{ -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 @@
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 @@
}
}
+#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);
}
Index: head/sys/arm/conf/BEAGLEBONE
===================================================================
--- head/sys/arm/conf/BEAGLEBONE
+++ head/sys/arm/conf/BEAGLEBONE
@@ -102,6 +102,9 @@
# 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.
Index: head/sys/arm/include/cpu.h
===================================================================
--- head/sys/arm/include/cpu.h
+++ head/sys/arm/include/cpu.h
@@ -14,12 +14,42 @@
#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;
Index: head/sys/conf/options.arm
===================================================================
--- head/sys/conf/options.arm
+++ head/sys/conf/options.arm
@@ -23,6 +23,7 @@
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

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 13, 1:44 AM (7 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23650561
Default Alt Text
D3837.diff (3 KB)

Event Timeline