aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/hwpmc
diff options
context:
space:
mode:
authorDavide Italiano <davide@FreeBSD.org>2013-04-30 15:31:45 +0000
committerDavide Italiano <davide@FreeBSD.org>2013-04-30 15:31:45 +0000
commit38179e6e76be8cd6e534bc38b91ea705768dc970 (patch)
tree2c7e11d0a971e87cfc1482611ede9e0e624a6104 /sys/dev/hwpmc
parentcd31b6dd088b444c343015b21fd67c3f11dda492 (diff)
Notes
Diffstat (limited to 'sys/dev/hwpmc')
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c51
-rw-r--r--sys/dev/hwpmc/pmc_events.h23
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.