@@ -67,6 +67,19 @@ static int attr(yyscan_t scanner, u64 idx)
return PE_TERM_ATTR;
}
+static int attr_parse(yyscan_t scanner)
+{
+ YYSTYPE *yylval = parse_events_get_lval(scanner);
+ char *text = parse_events_get_text(scanner);
+
+ errno = 0;
+ yylval->num = strtoull(text + 4, NULL, 10);
+ if (errno)
+ return PE_ERROR;
+
+ return PE_TERM_ATTR;
+}
+
%}
%x cond_mem
@@ -127,6 +140,7 @@ modifier_bp [rwx]{1,3}
}
<cond_config>{
+attr[0-9]* { return attr_parse(yyscanner); }
config { return attr(yyscanner, PERF_ATTR_IDX(config)); }
config1 { return attr(yyscanner, PERF_ATTR_IDX(config1)); }
config2 { return attr(yyscanner, PERF_ATTR_IDX(config2)); }
@@ -21,8 +21,8 @@ struct perf_pmu_alias {
};
struct perf_pmu_format {
- char *name;
- int value;
+ char *name;
+ u64 idx;
DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
struct list_head list;
};
@@ -512,7 +512,6 @@ static int pmu_config_term(struct list_head *formats,
struct parse_events_term *term)
{
struct perf_pmu_format *format;
- __u64 *vp;
/*
* Support only for hardcoded and numnerial terms.
@@ -529,27 +528,8 @@ static int pmu_config_term(struct list_head *formats,
if (!format)
return -EINVAL;
- switch (format->value) {
- case PERF_PMU_FORMAT_VALUE_CONFIG:
- vp = &attr->config;
- break;
- case PERF_PMU_FORMAT_VALUE_CONFIG1:
- vp = &attr->config1;
- break;
- case PERF_PMU_FORMAT_VALUE_CONFIG2:
- vp = &attr->config2;
- break;
- default:
- return -EINVAL;
- }
-
- /*
- * XXX If we ever decide to go with string values for
- * non-hardcoded terms, here's the place to translate
- * them into value.
- */
- *vp |= pmu_format_value(format->bits, term->val.num);
- return 0;
+ return parse_events__set_attr(attr, format->idx,
+ pmu_format_value(format->bits, term->val.num));
}
int perf_pmu__config_terms(struct list_head *formats,
@@ -678,7 +658,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
}
int perf_pmu__new_format(struct list_head *list, char *name,
- int config, unsigned long *bits)
+ __u64 idx, unsigned long *bits)
{
struct perf_pmu_format *format;
@@ -687,7 +667,7 @@ int perf_pmu__new_format(struct list_head *list, char *name,
return -ENOMEM;
format->name = strdup(name);
- format->value = config;
+ format->idx = idx;
memcpy(format->bits, bits, sizeof(format->bits));
list_add_tail(&format->list, list);
@@ -4,12 +4,7 @@
#include <linux/bitops.h>
#include <linux/perf_event.h>
#include <stdbool.h>
-
-enum {
- PERF_PMU_FORMAT_VALUE_CONFIG,
- PERF_PMU_FORMAT_VALUE_CONFIG1,
- PERF_PMU_FORMAT_VALUE_CONFIG2,
-};
+#include "parse-events.h"
#define PERF_PMU_FORMAT_BITS 64
@@ -36,7 +31,7 @@ int perf_pmu_wrap(void);
void perf_pmu_error(struct list_head *list, char *name, char const *msg);
int perf_pmu__new_format(struct list_head *list, char *name,
- int config, unsigned long *bits);
+ __u64 idx, unsigned long *bits);
void perf_pmu__set_format(unsigned long *bits, long from, long to);
int perf_pmu__format_parse(char *dir, struct list_head *head);
@@ -26,6 +26,7 @@ num_dec [0-9]+
%%
{num_dec} { return value(10); }
+attr { return PP_ATTR; }
config { return PP_CONFIG; }
config1 { return PP_CONFIG1; }
config2 { return PP_CONFIG2; }
@@ -20,7 +20,7 @@ do { \
%}
-%token PP_CONFIG PP_CONFIG1 PP_CONFIG2
+%token PP_ATTR PP_CONFIG PP_CONFIG1 PP_CONFIG2
%token PP_VALUE PP_ERROR
%type <num> PP_VALUE
%type <bits> bit_term
@@ -40,24 +40,34 @@ format format_term
format_term
format_term:
+PP_ATTR ':' bits
+{
+ ABORT_ON(perf_pmu__new_format(format, name, 0, $3));
+}
+|
+PP_ATTR PP_VALUE ':' bits
+{
+ ABORT_ON(perf_pmu__new_format(format, name, $2, $4));
+}
+|
PP_CONFIG ':' bits
{
ABORT_ON(perf_pmu__new_format(format, name,
- PERF_PMU_FORMAT_VALUE_CONFIG,
+ PERF_ATTR_IDX(config),
$3));
}
|
PP_CONFIG1 ':' bits
{
ABORT_ON(perf_pmu__new_format(format, name,
- PERF_PMU_FORMAT_VALUE_CONFIG1,
+ PERF_ATTR_IDX(config1),
$3));
}
|
PP_CONFIG2 ':' bits
{
ABORT_ON(perf_pmu__new_format(format, name,
- PERF_PMU_FORMAT_VALUE_CONFIG2,
+ PERF_ATTR_IDX(config2),
$3));
}