Changeset View
Changeset View
Standalone View
Standalone View
lib/libpmc/libpmc.c
Show First 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | static const struct pmc_event_descr cortex_a57_event_table[] = | ||||
__PMC_EV_ALIAS_ARMV8_CORTEX_A57() | __PMC_EV_ALIAS_ARMV8_CORTEX_A57() | ||||
}; | }; | ||||
static const struct pmc_event_descr cortex_a76_event_table[] = | static const struct pmc_event_descr cortex_a76_event_table[] = | ||||
{ | { | ||||
__PMC_EV_ALIAS_ARMV8_CORTEX_A76() | __PMC_EV_ALIAS_ARMV8_CORTEX_A76() | ||||
}; | }; | ||||
/* | |||||
* PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...) | |||||
* | |||||
* Map a CPU to the PMC classes it supports. | |||||
*/ | |||||
#define PMC_MDEP_TABLE(N,C,...) \ | |||||
static const enum pmc_class N##_pmc_classes[] = { \ | |||||
PMC_CLASS_##C, __VA_ARGS__ \ | |||||
} | |||||
PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC); | |||||
PMC_MDEP_TABLE(beri, BERI, PMC_CLASS_SOFT, PMC_CLASS_BERI); | |||||
PMC_MDEP_TABLE(cortex_a8, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); | |||||
PMC_MDEP_TABLE(cortex_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); | |||||
PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); | |||||
PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); | |||||
PMC_MDEP_TABLE(cortex_a76, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); | |||||
PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); | |||||
PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K); | |||||
PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); | |||||
PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450, PMC_CLASS_TSC); | |||||
PMC_MDEP_TABLE(ppc970, PPC970, PMC_CLASS_SOFT, PMC_CLASS_PPC970, PMC_CLASS_TSC); | |||||
PMC_MDEP_TABLE(power8, POWER8, PMC_CLASS_SOFT, PMC_CLASS_POWER8, PMC_CLASS_TSC); | |||||
PMC_MDEP_TABLE(e500, E500, PMC_CLASS_SOFT, PMC_CLASS_E500, PMC_CLASS_TSC); | |||||
PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); | |||||
static const struct pmc_event_descr tsc_event_table[] = | static const struct pmc_event_descr tsc_event_table[] = | ||||
{ | { | ||||
__PMC_EV_TSC() | __PMC_EV_TSC() | ||||
}; | }; | ||||
#undef PMC_CLASS_TABLE_DESC | #undef PMC_CLASS_TABLE_DESC | ||||
#define PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR) \ | #define PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR) \ | ||||
static const struct pmc_class_descr NAME##_class_table_descr = \ | static const struct pmc_class_descr NAME##_class_table_descr = \ | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | static struct pmc_class_descr soft_class_table_descr = | ||||
.pm_evc_allocate_pmc = soft_allocate_pmc | .pm_evc_allocate_pmc = soft_allocate_pmc | ||||
}; | }; | ||||
#undef PMC_CLASS_TABLE_DESC | #undef PMC_CLASS_TABLE_DESC | ||||
static const struct pmc_class_descr **pmc_class_table; | static const struct pmc_class_descr **pmc_class_table; | ||||
#define PMC_CLASS_TABLE_SIZE cpu_info.pm_nclass | #define PMC_CLASS_TABLE_SIZE cpu_info.pm_nclass | ||||
static const enum pmc_class *pmc_mdep_class_list; | |||||
static size_t pmc_mdep_class_list_size; | |||||
/* | /* | ||||
* Mapping tables, mapping enumeration values to human readable | * Mapping tables, mapping enumeration values to human readable | ||||
* strings. | * strings. | ||||
*/ | */ | ||||
static const char * pmc_capability_names[] = { | static const char * pmc_capability_names[] = { | ||||
#undef __PMC_CAP | #undef __PMC_CAP | ||||
#define __PMC_CAP(N,V,D) #N , | #define __PMC_CAP(N,V,D) #N , | ||||
▲ Show 20 Lines • Show All 702 Lines • ▼ Show 20 Lines | pmc_match_event_class(const char *name, | ||||
ev = pcd->pm_evc_event_table; | ev = pcd->pm_evc_event_table; | ||||
for (n = 0; n < pcd->pm_evc_event_table_size; n++, ev++) | for (n = 0; n < pcd->pm_evc_event_table_size; n++, ev++) | ||||
if (pmc_match_event_name(name, ev->pm_ev_name)) | if (pmc_match_event_name(name, ev->pm_ev_name)) | ||||
return (ev); | return (ev); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
static int | |||||
pmc_mdep_is_compatible_class(enum pmc_class pc) | |||||
{ | |||||
size_t n; | |||||
for (n = 0; n < pmc_mdep_class_list_size; n++) | |||||
if (pmc_mdep_class_list[n] == pc) | |||||
return (1); | |||||
return (0); | |||||
} | |||||
/* | /* | ||||
* API entry points | * API entry points | ||||
*/ | */ | ||||
int | int | ||||
pmc_allocate(const char *ctrspec, enum pmc_mode mode, | pmc_allocate(const char *ctrspec, enum pmc_mode mode, | ||||
uint32_t flags, int cpu, pmc_id_t *pmcid, | uint32_t flags, int cpu, pmc_id_t *pmcid, | ||||
uint64_t count) | uint64_t count) | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | pmc_allocate(const char *ctrspec, enum pmc_mode mode, | ||||
/* | /* | ||||
* If a explicit class prefix was given by the user, restrict the | * If a explicit class prefix was given by the user, restrict the | ||||
* search for the event to the specified PMC class. | * search for the event to the specified PMC class. | ||||
*/ | */ | ||||
ev = NULL; | ev = NULL; | ||||
for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++) { | for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++) { | ||||
pcd = pmc_class_table[n]; | pcd = pmc_class_table[n]; | ||||
if (pcd && pmc_mdep_is_compatible_class(pcd->pm_evc_class) && | if (pcd != NULL && strncasecmp(ctrname, pcd->pm_evc_name, | ||||
strncasecmp(ctrname, pcd->pm_evc_name, | |||||
pcd->pm_evc_name_size) == 0) { | pcd->pm_evc_name_size) == 0) { | ||||
if ((ev = pmc_match_event_class(ctrname + | if ((ev = pmc_match_event_class(ctrname + | ||||
pcd->pm_evc_name_size, pcd)) == NULL) { | pcd->pm_evc_name_size, pcd)) == NULL) { | ||||
errno = EINVAL; | errno = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Otherwise, search for this event in all compatible PMC | * Otherwise, search for this event in all compatible PMC | ||||
* classes. | * classes. | ||||
*/ | */ | ||||
for (n = 0; ev == NULL && n < PMC_CLASS_TABLE_SIZE; n++) { | for (n = 0; ev == NULL && n < PMC_CLASS_TABLE_SIZE; n++) { | ||||
pcd = pmc_class_table[n]; | pcd = pmc_class_table[n]; | ||||
if (pcd && pmc_mdep_is_compatible_class(pcd->pm_evc_class)) | if (pcd != NULL) | ||||
ev = pmc_match_event_class(ctrname, pcd); | ev = pmc_match_event_class(ctrname, pcd); | ||||
} | } | ||||
if (ev == NULL) { | if (ev == NULL) { | ||||
errno = EINVAL; | errno = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 339 Lines • ▼ Show 20 Lines | pmc_init(void) | ||||
/* Fill soft events information. */ | /* Fill soft events information. */ | ||||
pmc_class_table[n++] = &soft_class_table_descr; | pmc_class_table[n++] = &soft_class_table_descr; | ||||
#if defined(__amd64__) || defined(__i386__) | #if defined(__amd64__) || defined(__i386__) | ||||
if (cpu_info.pm_cputype != PMC_CPU_GENERIC) | if (cpu_info.pm_cputype != PMC_CPU_GENERIC) | ||||
pmc_class_table[n++] = &tsc_class_table_descr; | pmc_class_table[n++] = &tsc_class_table_descr; | ||||
#endif | #endif | ||||
#define PMC_MDEP_INIT(C) do { \ | #define PMC_MDEP_INIT(C) pmc_mdep_event_aliases = C##_aliases | ||||
pmc_mdep_event_aliases = C##_aliases; \ | |||||
pmc_mdep_class_list = C##_pmc_classes; \ | |||||
pmc_mdep_class_list_size = \ | |||||
PMC_TABLE_SIZE(C##_pmc_classes); \ | |||||
} while (0) | |||||
/* Configure the event name parser. */ | /* Configure the event name parser. */ | ||||
switch (cpu_info.pm_cputype) { | switch (cpu_info.pm_cputype) { | ||||
#if defined(__amd64__) || defined(__i386__) | #if defined(__amd64__) || defined(__i386__) | ||||
case PMC_CPU_AMD_K8: | case PMC_CPU_AMD_K8: | ||||
PMC_MDEP_INIT(k8); | PMC_MDEP_INIT(k8); | ||||
pmc_class_table[n] = &k8_class_table_descr; | pmc_class_table[n] = &k8_class_table_descr; | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 410 Lines • Show Last 20 Lines |