diff options
| -rw-r--r-- | sys/dev/hwpmc/hwpmc_core.c | 51 | ||||
| -rw-r--r-- | sys/dev/hwpmc/pmc_events.h | 23 |
2 files changed, 49 insertions, 25 deletions
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 287a652b2924..1f0b784eca02 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -60,6 +60,10 @@ __FBSDID("$FreeBSD$"); PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \ PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE) +#define EV_IS_NOTARCH 0 +#define EV_IS_ARCH_SUPP 1 +#define EV_IS_ARCH_NOTSUPP -1 + /* * "Architectural" events defined by Intel. The values of these * symbols correspond to positions in the bitmask returned by @@ -1723,43 +1727,53 @@ iap_pmc_has_overflowed(int ri) /* * Check an event against the set of supported architectural events. * - * Returns 1 if the event is architectural and unsupported on this - * CPU. Returns 0 otherwise. + * If the event is not architectural EV_IS_NOTARCH is returned. + * If the event is architectural and supported on this CPU, the correct + * event+umask mapping is returned in map, and EV_IS_ARCH_SUPP is returned. + * Otherwise, the function returns EV_IS_ARCH_NOTSUPP. */ static int -iap_architectural_event_is_unsupported(enum pmc_event pe) +iap_is_event_architectural(enum pmc_event pe, enum pmc_event *map) { enum core_arch_events ae; switch (pe) { - case PMC_EV_IAP_EVENT_3CH_00H: + case PMC_EV_IAP_ARCH_UNH_COR_CYC: ae = CORE_AE_UNHALTED_CORE_CYCLES; + *map = PMC_EV_IAP_EVENT_C4H_00H; break; - case PMC_EV_IAP_EVENT_C0H_00H: + case PMC_EV_IAP_ARCH_INS_RET: ae = CORE_AE_INSTRUCTION_RETIRED; + *map = PMC_EV_IAP_EVENT_C0H_00H; break; - case PMC_EV_IAP_EVENT_3CH_01H: + case PMC_EV_IAP_ARCH_UNH_REF_CYC: ae = CORE_AE_UNHALTED_REFERENCE_CYCLES; + *map = PMC_EV_IAP_EVENT_3CH_01H; break; - case PMC_EV_IAP_EVENT_2EH_4FH: + case PMC_EV_IAP_ARCH_LLC_REF: ae = CORE_AE_LLC_REFERENCE; + *map = PMC_EV_IAP_EVENT_2EH_4FH; break; - case PMC_EV_IAP_EVENT_2EH_41H: + case PMC_EV_IAP_ARCH_LLC_MIS: ae = CORE_AE_LLC_MISSES; + *map = PMC_EV_IAP_EVENT_2EH_41H; break; - case PMC_EV_IAP_EVENT_C4H_00H: + case PMC_EV_IAP_ARCH_BR_INS_RET: ae = CORE_AE_BRANCH_INSTRUCTION_RETIRED; + *map = PMC_EV_IAP_EVENT_C4H_00H; break; - case PMC_EV_IAP_EVENT_C5H_00H: + case PMC_EV_IAP_ARCH_BR_MIS_RET: ae = CORE_AE_BRANCH_MISSES_RETIRED; + *map = PMC_EV_IAP_EVENT_C5H_00H; break; default: /* Non architectural event. */ - return (0); + return (EV_IS_NOTARCH); } - return ((core_architectural_events & (1 << ae)) == 0); + return (((core_architectural_events & (1 << ae)) == 0) ? + EV_IS_ARCH_NOTSUPP : EV_IS_ARCH_SUPP); } static int @@ -1917,8 +1931,8 @@ static int iap_allocate_pmc(int cpu, int ri, struct pmc *pm, const struct pmc_op_pmcallocate *a) { - int n, model; - enum pmc_event ev; + int arch, n, model; + enum pmc_event ev, map; struct iap_event_descr *ie; uint32_t c, caps, config, cpuflag, evsel, mask; @@ -1932,10 +1946,13 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm, if ((IAP_PMC_CAPS & caps) != caps) return (EPERM); - ev = pm->pm_event; - - if (iap_architectural_event_is_unsupported(ev)) + arch = iap_is_event_architectural(pm->pm_event, &map); + if (arch == EV_IS_ARCH_NOTSUPP) return (EOPNOTSUPP); + else if (arch == EV_IS_ARCH_SUPP) + ev = map; + else + ev = pm->pm_event; /* * A small number of events are not supported in all the diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index 8d664f54eccf..b8c97c65b0e4 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -468,6 +468,13 @@ __PMC_EV_ALIAS("unhalted-reference-cycles", IAF_CPU_CLK_UNHALTED_REF) * the CPU model happens inside hwpmc(4). */ #define __PMC_EV_IAP() \ +__PMC_EV(IAP, ARCH_BR_INS_RET) \ +__PMC_EV(IAP, ARCH_BR_MIS_RET) \ +__PMC_EV(IAP, ARCH_INS_RET) \ +__PMC_EV(IAP, ARCH_LLC_MIS) \ +__PMC_EV(IAP, ARCH_LLC_REF) \ +__PMC_EV(IAP, ARCH_UNH_REF_CYC) \ +__PMC_EV(IAP, ARCH_UNH_COR_CYC) \ __PMC_EV(IAP, EVENT_02H_01H) \ __PMC_EV(IAP, EVENT_02H_81H) \ __PMC_EV(IAP, EVENT_03H_00H) \ @@ -1157,20 +1164,20 @@ __PMC_EV(IAP, EVENT_FDH_10H) \ __PMC_EV(IAP, EVENT_FDH_20H) \ __PMC_EV(IAP, EVENT_FDH_40H) -#define PMC_EV_IAP_FIRST PMC_EV_IAP_EVENT_02H_01H +#define PMC_EV_IAP_FIRST PMC_EV_IAP_ARCH_BR_INS_RET #define PMC_EV_IAP_LAST PMC_EV_IAP_EVENT_FDH_40H /* * Map "architectural" event names to event ids. */ #define __PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \ -__PMC_EV_ALIAS("branch-instruction-retired", IAP_EVENT_C4H_00H) \ -__PMC_EV_ALIAS("branch-misses-retired", IAP_EVENT_C5H_00H) \ -__PMC_EV_ALIAS("instruction-retired", IAP_EVENT_C0H_00H) \ -__PMC_EV_ALIAS("llc-misses", IAP_EVENT_2EH_41H) \ -__PMC_EV_ALIAS("llc-reference", IAP_EVENT_2EH_4FH) \ -__PMC_EV_ALIAS("unhalted-reference-cycles", IAP_EVENT_3CH_01H) \ -__PMC_EV_ALIAS("unhalted-core-cycles", IAP_EVENT_3CH_00H) +__PMC_EV_ALIAS("branch-instruction-retired", IAP_ARCH_BR_INS_RET) \ +__PMC_EV_ALIAS("branch-misses-retired", IAP_ARCH_BR_MIS_RET) \ +__PMC_EV_ALIAS("instruction-retired", IAP_ARCH_INS_RET) \ +__PMC_EV_ALIAS("llc-misses", IAP_ARCH_LLC_MIS) \ +__PMC_EV_ALIAS("llc-reference", IAP_ARCH_LLC_REF) \ +__PMC_EV_ALIAS("unhalted-reference-cycles", IAP_ARCH_UNH_REF_CYC) \ +__PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) /* * Aliases for Atom PMCs. |
