2 #include <linux/list.h>
14 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
25 static int pmu_format_parse(
char *dir,
struct list_head *
head)
31 format_dir = opendir(dir);
35 while (!ret && (evt_ent = readdir(format_dir))) {
37 char *
name = evt_ent->d_name;
46 file = fopen(path,
"r");
80 if (pmu_format_parse(path, format))
86 static int perf_pmu__new_alias(
struct list_head *
list,
char *name, FILE *file)
92 ret = fread(buf, 1,
sizeof(buf), file);
97 alias =
malloc(
sizeof(*alias));
101 INIT_LIST_HEAD(&alias->
terms);
108 alias->
name = strdup(name);
117 static int pmu_aliases_parse(
char *dir,
struct list_head *head)
123 event_dir = opendir(dir);
127 while (!ret && (evt_ent = readdir(event_dir))) {
129 char *name = evt_ent->d_name;
138 file = fopen(path,
"r");
141 ret = perf_pmu__new_alias(head, name, file);
153 static int pmu_aliases(
char *name,
struct list_head *head)
164 "%s/bus/event_source/devices/%s/events", sysfs, name);
169 if (pmu_aliases_parse(path, head))
190 list_splice(&list, terms);
199 static int pmu_type(
char *name,
__u32 *
type)
217 file = fopen(path,
"r");
221 if (1 != fscanf(file,
"%u", type))
229 static void pmu_read_sysfs(
void)
247 while ((dent = readdir(dir))) {
248 if (!
strcmp(dent->d_name,
".") || !
strcmp(dent->d_name,
".."))
257 static struct cpu_map *pmu_cpumask(
char *name)
270 "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
275 file = fopen(path,
"r");
284 static struct perf_pmu *pmu_lookup(
char *name)
296 if (pmu_format(name, &format))
299 if (pmu_type(name, &type))
302 pmu =
zalloc(
sizeof(*pmu));
306 pmu->
cpus = pmu_cpumask(name);
310 INIT_LIST_HEAD(&pmu->
format);
312 list_splice(&format, &pmu->
format);
314 pmu->
name = strdup(name);
320 static struct perf_pmu *pmu_find(
char *name)
355 pmu = pmu_find(name);
359 return pmu_lookup(name);
363 pmu_find_format(
struct list_head *formats,
char *name)
382 unsigned long fbit, vbit;
390 if (!(value & (1
llu << vbit++)))
403 static int pmu_config_term(
struct list_head *formats,
421 format = pmu_find_format(formats, term->
config);
425 switch (format->
value) {
444 *vp |= pmu_format_value(format->bits, term->
val.
num);
454 if (pmu_config_term(formats, attr, term))
468 attr->type = pmu->type;
469 return pmu_config(&pmu->format, attr, head_terms);
513 alias = pmu_find_alias(pmu, term);
516 ret = pmu_alias_terms(alias, &term->
list);
530 format =
zalloc(
sizeof(*format));
534 format->
name = strdup(name);
536 memcpy(format->bits, bits,
sizeof(format->bits));
550 for (b = from; b <= to; b++)
555 static struct test_format {
559 {
"krava01",
"config:0-1,62-63\n", },
560 {
"krava02",
"config:10-17\n", },
561 {
"krava03",
"config:5\n", },
562 {
"krava11",
"config1:0,2,4,6,8,20-28\n", },
563 {
"krava12",
"config1:63\n", },
564 {
"krava13",
"config1:45-47\n", },
565 {
"krava21",
"config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
566 {
"krava22",
"config2:8,18,48,58\n", },
567 {
"krava23",
"config2:28-29,38\n", },
570 #define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format))
575 .config = (
char *)
"krava01",
581 .config = (
char *)
"krava02",
587 .config = (
char *)
"krava03",
593 .config = (
char *)
"krava11",
599 .config = (
char *)
"krava12",
605 .config = (
char *)
"krava13",
611 .config = (
char *)
"krava21",
617 .config = (
char *)
"krava22",
623 .config = (
char *)
"krava23",
629 #define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term))
635 static char *test_format_dir_get(
void)
646 struct test_format *format = &test_formats[
i];
651 file = fopen(name,
"w");
655 if (1 != fwrite(format->value,
strlen(format->value), 1, file))
665 static int test_format_dir_put(
char *dir)
676 static struct list_head *test_terms_list(
void)
691 char *format = test_format_dir_get();
693 struct list_head *terms = test_terms_list();
702 memset(&attr, 0,
sizeof(attr));
704 ret = pmu_format_parse(format, &formats);
708 ret = pmu_config(&formats, &attr, terms);
714 if (attr.
config != 0xc00000000002a823)
716 if (attr.
config1 != 0x8000400000000145)
718 if (attr.
config2 != 0x0400000020041d07)
724 test_format_dir_put(format);