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_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,
336 (void *) $2, $6, $4));
340 PE_PREFIX_MEM PE_VALUE '/' 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,
347 (void *) $2, NULL, $4));
351 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
353 struct parse_events_evlist *data = _data;
354 struct list_head *list;
357 ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
358 (void *) $2, $4, 0));
362 PE_PREFIX_MEM PE_VALUE sep_dc
364 struct parse_events_evlist *data = _data;
365 struct list_head *list;
368 ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
369 (void *) $2, NULL, 0));
373 event_legacy_tracepoint:
374 PE_NAME '-' PE_NAME ':' PE_NAME
376 struct parse_events_evlist *data = _data;
377 struct list_head *list;
379 snprintf(&sys_name, 128, "%s-%s", $1, $3);
382 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5));
388 struct parse_events_evlist *data = _data;
389 struct list_head *list;
392 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, $1, $3));
396 event_legacy_numeric:
397 PE_VALUE ':' PE_VALUE
399 struct parse_events_evlist *data = _data;
400 struct list_head *list;
403 ABORT_ON(parse_events_add_numeric(list, &data->idx, (u32)$1, $3, NULL));
410 struct parse_events_evlist *data = _data;
411 struct list_head *list;
414 ABORT_ON(parse_events_add_numeric(list, &data->idx,
415 PERF_TYPE_RAW, $1, NULL));
419 start_terms: event_config
421 struct parse_events_terms *data = _data;
426 event_config ',' event_term
428 struct list_head *head = $1;
429 struct parse_events_term *term = $3;
432 list_add_tail(&term->list, head);
438 struct list_head *head = malloc(sizeof(*head));
439 struct parse_events_term *term = $1;
442 INIT_LIST_HEAD(head);
443 list_add_tail(&term->list, head);
450 struct parse_events_term *term;
452 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
459 struct parse_events_term *term;
461 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
466 PE_NAME '=' PE_VALUE_SYM_HW
468 struct parse_events_term *term;
469 int config = $3 & 255;
471 ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
477 struct parse_events_term *term;
479 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
486 struct parse_events_term *term;
487 int config = $1 & 255;
489 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
495 struct parse_events_term *term;
497 ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3));
503 struct parse_events_term *term;
505 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3));
511 struct parse_events_term *term;
513 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1));
519 sep_slash_dc: '/' | ':' |
523 void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused,
524 char const *msg __maybe_unused)