2 %parse-param {void *_data}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
10 #include <linux/compiler.h>
11 #include <linux/list.h>
12 #include <linux/types.h>
14 #include "parse-events.h"
15 #include "parse-events-bison.h"
17 extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
19 #define ABORT_ON(val) \
25 #define ALLOC_LIST(list) \
27 list = malloc(sizeof(*list)); \
29 INIT_LIST_HEAD(list); \
32 static inc_group_count(struct list_head *list,
33 struct parse_events_evlist *data)
35 /* Count groups only have more than 1 members */
36 if (!list_is_last(list->next, list))
42 %token PE_START_EVENTS PE_START_TERMS
43 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
46 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
47 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
48 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
50 %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
52 %type <num> PE_VALUE_SYM_HW
53 %type <num> PE_VALUE_SYM_SW
57 %type <str> PE_NAME_CACHE_TYPE
58 %type <str> PE_NAME_CACHE_OP_RESULT
59 %type <str> PE_MODIFIER_EVENT
60 %type <str> PE_MODIFIER_BP
61 %type <str> PE_EVENT_NAME
62 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
64 %type <head> event_config
65 %type <term> event_term
66 %type <head> event_pmu
67 %type <head> event_legacy_symbol
68 %type <head> event_legacy_cache
69 %type <head> event_legacy_mem
70 %type <head> event_legacy_tracepoint
71 %type <head> event_legacy_numeric
72 %type <head> event_legacy_raw
73 %type <head> event_def
74 %type <head> event_mod
75 %type <head> event_name
78 %type <head> group_def
86 struct list_head *head;
87 struct parse_events_term *term;
92 PE_START_EVENTS start_events
94 PE_START_TERMS start_terms
98 struct parse_events_evlist *data = _data;
100 parse_events_update_lists($1, &data->list);
106 struct list_head *list = $1;
107 struct list_head *group = $3;
109 parse_events_update_lists(group, list);
115 struct list_head *list = $1;
116 struct list_head *event = $3;
118 parse_events_update_lists(event, list);
127 group_def ':' PE_MODIFIER_EVENT
129 struct list_head *list = $1;
131 ABORT_ON(parse_events__modifier_group(list, $3));
138 PE_NAME '{' events '}'
140 struct list_head *list = $3;
142 inc_group_count(list, _data);
143 parse_events__set_leader($1, list);
149 struct list_head *list = $2;
151 inc_group_count(list, _data);
152 parse_events__set_leader(NULL, list);
159 struct list_head *event = $3;
160 struct list_head *list = $1;
162 parse_events_update_lists(event, list);
171 event_name PE_MODIFIER_EVENT
173 struct list_head *list = $1;
176 * Apply modifier on all events added by single event definition
177 * (there could be more events added for multiple tracepoint
178 * definitions via '*?'.
180 ABORT_ON(parse_events__modifier_event(list, $2, false));
187 PE_EVENT_NAME event_def
189 ABORT_ON(parse_events_name($2, $1));
196 event_def: event_pmu |
197 event_legacy_symbol |
198 event_legacy_cache sep_dc |
200 event_legacy_tracepoint sep_dc |
201 event_legacy_numeric sep_dc |
202 event_legacy_raw sep_dc
205 PE_NAME '/' event_config '/'
207 struct parse_events_evlist *data = _data;
208 struct list_head *list;
211 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, $3));
212 parse_events__free_terms($3);
218 struct parse_events_evlist *data = _data;
219 struct list_head *list;
222 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL));
226 PE_KERNEL_PMU_EVENT sep_dc
228 struct parse_events_evlist *data = _data;
229 struct list_head *head;
230 struct parse_events_term *term;
231 struct list_head *list;
234 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
236 list_add_tail(&term->list, head);
239 ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
240 parse_events__free_terms(head);
244 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
246 struct parse_events_evlist *data = _data;
247 struct list_head *head;
248 struct parse_events_term *term;
249 struct list_head *list;
251 snprintf(&pmu_name, 128, "%s-%s", $1, $3);
254 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
256 list_add_tail(&term->list, head);
259 ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
260 parse_events__free_terms(head);
270 value_sym '/' event_config '/'
272 struct parse_events_evlist *data = _data;
273 struct list_head *list;
275 int config = $1 & 255;
278 ABORT_ON(parse_events_add_numeric(list, &data->idx,
280 parse_events__free_terms($3);
284 value_sym sep_slash_dc
286 struct parse_events_evlist *data = _data;
287 struct list_head *list;
289 int config = $1 & 255;
292 ABORT_ON(parse_events_add_numeric(list, &data->idx,
293 type, config, NULL));
298 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
300 struct parse_events_evlist *data = _data;
301 struct list_head *list;
304 ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5));
308 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
310 struct parse_events_evlist *data = _data;
311 struct list_head *list;
314 ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL));
320 struct parse_events_evlist *data = _data;
321 struct list_head *list;
324 ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL));
329 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
331 struct parse_events_evlist *data = _data;
332 struct list_head *list;
335 ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
340 PE_PREFIX_MEM PE_VALUE sep_dc
342 struct parse_events_evlist *data = _data;
343 struct list_head *list;
346 ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
351 event_legacy_tracepoint:
352 PE_NAME '-' PE_NAME ':' PE_NAME
354 struct parse_events_evlist *data = _data;
355 struct list_head *list;
357 snprintf(&sys_name, 128, "%s-%s", $1, $3);
360 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5));
366 struct parse_events_evlist *data = _data;
367 struct list_head *list;
370 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, $1, $3));
374 event_legacy_numeric:
375 PE_VALUE ':' PE_VALUE
377 struct parse_events_evlist *data = _data;
378 struct list_head *list;
381 ABORT_ON(parse_events_add_numeric(list, &data->idx, (u32)$1, $3, NULL));
388 struct parse_events_evlist *data = _data;
389 struct list_head *list;
392 ABORT_ON(parse_events_add_numeric(list, &data->idx,
393 PERF_TYPE_RAW, $1, NULL));
397 start_terms: event_config
399 struct parse_events_terms *data = _data;
404 event_config ',' event_term
406 struct list_head *head = $1;
407 struct parse_events_term *term = $3;
410 list_add_tail(&term->list, head);
416 struct list_head *head = malloc(sizeof(*head));
417 struct parse_events_term *term = $1;
420 INIT_LIST_HEAD(head);
421 list_add_tail(&term->list, head);
428 struct parse_events_term *term;
430 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
437 struct parse_events_term *term;
439 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
444 PE_NAME '=' PE_VALUE_SYM_HW
446 struct parse_events_term *term;
447 int config = $3 & 255;
449 ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
455 struct parse_events_term *term;
457 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
464 struct parse_events_term *term;
465 int config = $1 & 255;
467 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
473 struct parse_events_term *term;
475 ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3));
481 struct parse_events_term *term;
483 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3));
489 struct parse_events_term *term;
491 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1));
497 sep_slash_dc: '/' | ':' |
501 void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused,
502 char const *msg __maybe_unused)