diff options
Diffstat (limited to 'lib/libpmc/libpmc.c')
-rw-r--r-- | lib/libpmc/libpmc.c | 118 |
1 files changed, 92 insertions, 26 deletions
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 4323171..3b7dc37 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++) |