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
This commit is contained in:
parent
3b383c9ede
commit
eeaf6acbfd
@ -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;
|
||||
#endif
|
||||
uint32_t r;
|
||||
#if defined(__arm__) && (__ARM_ARCH > 6)
|
||||
u_int cpu;
|
||||
|
||||
tf = arg;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user