summaryrefslogtreecommitdiffstats
path: root/lib/libpmc
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2011-12-24 19:34:52 +0000
committerjhibbits <jhibbits@FreeBSD.org>2011-12-24 19:34:52 +0000
commit8eb9e6b5487506b4d0f3e50d440fac3e93baf702 (patch)
treecfe656c61e3dc2689d74c276ee2249f54a375705 /lib/libpmc
parent710f17be3ba715e7a297bf62e3944f4b95dd9fef (diff)
downloadFreeBSD-src-8eb9e6b5487506b4d0f3e50d440fac3e93baf702.zip
FreeBSD-src-8eb9e6b5487506b4d0f3e50d440fac3e93baf702.tar.gz
Implement hwpmc counting PMC support for PowerPC G4+ (MPC745x/MPC744x).
Sampling is in progress. Approved by: nwhitehorn (mentor) MFC after: 9.0-RELEASE
Diffstat (limited to 'lib/libpmc')
-rw-r--r--lib/libpmc/libpmc.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index efdabc8..ba63ace 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -83,6 +83,10 @@ static int mips24k_allocate_pmc(enum pmc_event _pe, char* ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif /* __mips__ */
+#if defined(__powerpc__)
+static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
+#endif /* __powerpc__ */
#define PMC_CALL(cmd, params) \
syscall(pmc_syscall, PMC_OP_##cmd, (params))
@@ -149,6 +153,7 @@ PMC_CLASSDEP_TABLE(p6, P6);
PMC_CLASSDEP_TABLE(xscale, XSCALE);
PMC_CLASSDEP_TABLE(mips24k, MIPS24K);
PMC_CLASSDEP_TABLE(ucf, UCF);
+PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
#undef __PMC_EV_ALIAS
#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },
@@ -211,6 +216,7 @@ 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(ppc7450, PPC7450, PMC_CLASS_PPC7450);
static const struct pmc_event_descr tsc_event_table[] =
{
@@ -263,6 +269,10 @@ PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips24k);
#endif /* __mips__ */
+#if defined(__powerpc__)
+PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450);
+#endif
+
#undef PMC_CLASS_TABLE_DESC
static const struct pmc_class_descr **pmc_class_table;
@@ -2212,6 +2222,44 @@ mips24k_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
}
#endif /* __mips__ */
+#if defined(__powerpc__)
+
+static struct pmc_event_alias ppc7450_aliases[] = {
+ EV_ALIAS("instructions", "INSTR_COMPLETED"),
+ EV_ALIAS("branches", "BRANCHES_COMPLETED"),
+ EV_ALIAS("branch-mispredicts", "MISPREDICTED_BRANCHES"),
+ EV_ALIAS(NULL, NULL)
+};
+
+#define PPC7450_KW_OS "os"
+#define PPC7450_KW_USR "usr"
+#define PPC7450_KW_ANYTHREAD "anythread"
+
+static int
+ppc7450_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
+ struct pmc_op_pmcallocate *pmc_config __unused)
+{
+ char *p;
+
+ (void) pe;
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+ if (KWMATCH(p, PPC7450_KW_OS))
+ pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+ else if (KWMATCH(p, PPC7450_KW_USR))
+ pmc_config->pm_caps |= PMC_CAP_USER;
+ else if (KWMATCH(p, PPC7450_KW_ANYTHREAD))
+ pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM);
+ else
+ return (-1);
+ }
+
+ return (0);
+}
+#endif /* __powerpc__ */
+
/*
* Match an event name `name' with its canonical form.
@@ -2573,6 +2621,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = mips24k_event_table;
count = PMC_EVENT_TABLE_SIZE(mips24k);
break;
+ case PMC_CLASS_PPC7450:
+ ev = ppc7450_event_table;
+ count = PMC_EVENT_TABLE_SIZE(ppc7450);
+ break;
default:
errno = EINVAL;
return (-1);
@@ -2784,6 +2836,12 @@ pmc_init(void)
pmc_class_table[n] = &mips24k_class_table_descr;
break;
#endif /* __mips__ */
+#if defined(__powerpc__)
+ case PMC_CPU_PPC_7450:
+ PMC_MDEP_INIT(ppc7450);
+ pmc_class_table[n] = &ppc7450_class_table_descr;
+ break;
+#endif
default:
/*
* Some kind of CPU this version of the library knows nothing
@@ -2924,6 +2982,10 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
ev = mips24k_event_table;
evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k
);
+ } 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
+);
} else if (pe == PMC_EV_TSC_TSC) {
ev = tsc_event_table;
evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
OpenPOWER on IntegriCloud