aboutsummaryrefslogtreecommitdiff
path: root/lib/libpmc/libpmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpmc/libpmc.c')
-rw-r--r--lib/libpmc/libpmc.c118
1 files changed, 92 insertions, 26 deletions
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 4323171e7443..3b7dc376ed27 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif
-
#if defined(__mips__)
static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif /* __mips__ */
+static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
#if defined(__powerpc__)
static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec,
@@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON);
PMC_CLASSDEP_TABLE(ucf, UCF);
PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
+static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
+
#undef __PMC_EV_ALIAS
#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },
@@ -215,21 +218,22 @@ static const struct pmc_event_descr westmereuc_event_table[] =
PMC_CLASS_##C, __VA_ARGS__ \
}
-PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE);
-PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K);
-PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON);
-PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450);
+PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE);
+PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
+PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
+PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450);
+PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT);
static const struct pmc_event_descr tsc_event_table[] =
{
@@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
#if defined(__XSCALE__)
PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
#endif
-
#if defined(__mips__)
PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips);
#endif /* __mips__ */
-
#if defined(__powerpc__)
PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450);
#endif
+static struct pmc_class_descr soft_class_table_descr =
+{
+ .pm_evc_name = "SOFT-",
+ .pm_evc_name_size = sizeof("SOFT-") - 1,
+ .pm_evc_class = PMC_CLASS_SOFT,
+ .pm_evc_event_table = NULL,
+ .pm_evc_event_table_size = 0,
+ .pm_evc_allocate_pmc = soft_allocate_pmc
+};
+
#undef PMC_CLASS_TABLE_DESC
static const struct pmc_class_descr **pmc_class_table;
@@ -343,9 +355,12 @@ static const char * pmc_state_names[] = {
__PMC_STATES()
};
-static int pmc_syscall = -1; /* filled in by pmc_init() */
-
-static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */
+/*
+ * Filled in by pmc_init().
+ */
+static int pmc_syscall = -1;
+static struct pmc_cpuinfo cpu_info;
+static struct pmc_op_getdyneventinfo soft_event_info;
/* Event masks for events */
struct pmc_masks {
@@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char *ctrspec,
}
#endif
+static struct pmc_event_alias generic_aliases[] = {
+ EV_ALIAS("instructions", "SOFT-CLOCK.HARD"),
+ EV_ALIAS(NULL, NULL)
+};
+
+static int
+soft_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ (void)ctrspec;
+ (void)pmc_config;
+
+ if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST)
+ return (-1);
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+ return (0);
+}
+
#if defined(__XSCALE__)
static struct pmc_event_alias xscale_aliases[] = {
@@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = ppc7450_event_table;
count = PMC_EVENT_TABLE_SIZE(ppc7450);
break;
+ case PMC_CLASS_SOFT:
+ ev = soft_event_table;
+ count = soft_event_info.pm_nevent;
+ break;
default:
errno = EINVAL;
return (-1);
@@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
for (;count--; ev++, names++)
*names = ev->pm_ev_name;
+
return (0);
}
@@ -2780,11 +2819,34 @@ pmc_init(void)
pmc_class_table[n] = NULL;
/*
+ * Get soft events list.
+ */
+ soft_event_info.pm_class = PMC_CLASS_SOFT;
+ if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0)
+ return (pmc_syscall = -1);
+
+ /* Map soft events to static list. */
+ for (n = 0; n < soft_event_info.pm_nevent; n++) {
+ soft_event_table[n].pm_ev_name =
+ soft_event_info.pm_events[n].pm_ev_name;
+ soft_event_table[n].pm_ev_code =
+ soft_event_info.pm_events[n].pm_ev_code;
+ }
+ soft_class_table_descr.pm_evc_event_table_size = \
+ soft_event_info.pm_nevent;
+ soft_class_table_descr.pm_evc_event_table = \
+ soft_event_table;
+
+ /*
* Fill in the class table.
*/
n = 0;
+
+ /* Fill soft events information. */
+ pmc_class_table[n++] = &soft_class_table_descr;
#if defined(__amd64__) || defined(__i386__)
- pmc_class_table[n++] = &tsc_class_table_descr;
+ if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
+ pmc_class_table[n++] = &tsc_class_table_descr;
/*
* Check if this CPU has fixed function counters.
@@ -2867,6 +2929,9 @@ pmc_init(void)
pmc_class_table[n] = &p4_class_table_descr;
break;
#endif
+ case PMC_CPU_GENERIC:
+ PMC_MDEP_INIT(generic);
+ break;
#if defined(__XSCALE__)
case PMC_CPU_INTEL_XSCALE:
PMC_MDEP_INIT(xscale);
@@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale);
} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
ev = mips24k_event_table;
- evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k
-);
+ evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);
} else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) {
ev = octeon_event_table;
evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon);
} else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
ev = ppc7450_event_table;
- evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450
-);
+ evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
} else if (pe == PMC_EV_TSC_TSC) {
ev = tsc_event_table;
evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
+ } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) {
+ ev = soft_event_table;
+ evfence = soft_event_table + soft_event_info.pm_nevent;
}
for (; ev != evfence; ev++)