Merge tag 'v4.4.28' into linux-linaro-lsk-v4.4
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / parse-events.y
1 %pure-parser
2 %parse-param {void *_data}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
5 %locations
6
7 %{
8
9 #define YYDEBUG 1
10
11 #include <linux/compiler.h>
12 #include <linux/list.h>
13 #include <linux/types.h>
14 #include "util.h"
15 #include "parse-events.h"
16 #include "parse-events-bison.h"
17
18 #define ABORT_ON(val) \
19 do { \
20         if (val) \
21                 YYABORT; \
22 } while (0)
23
24 #define ALLOC_LIST(list) \
25 do { \
26         list = malloc(sizeof(*list)); \
27         ABORT_ON(!list);              \
28         INIT_LIST_HEAD(list);         \
29 } while (0)
30
31 static inc_group_count(struct list_head *list,
32                        struct parse_events_evlist *data)
33 {
34         /* Count groups only have more than 1 members */
35         if (!list_is_last(list->next, list))
36                 data->nr_groups++;
37 }
38
39 %}
40
41 %token PE_START_EVENTS PE_START_TERMS
42 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
43 %token PE_EVENT_NAME
44 %token PE_NAME
45 %token PE_BPF_OBJECT PE_BPF_SOURCE
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
49 %token PE_ERROR
50 %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
51 %token PE_DRV_CFG_TERM
52 %type <num> PE_VALUE
53 %type <num> PE_VALUE_SYM_HW
54 %type <num> PE_VALUE_SYM_SW
55 %type <num> PE_RAW
56 %type <num> PE_TERM
57 %type <str> PE_NAME
58 %type <str> PE_BPF_OBJECT
59 %type <str> PE_BPF_SOURCE
60 %type <str> PE_NAME_CACHE_TYPE
61 %type <str> PE_NAME_CACHE_OP_RESULT
62 %type <str> PE_MODIFIER_EVENT
63 %type <str> PE_MODIFIER_BP
64 %type <str> PE_EVENT_NAME
65 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
66 %type <str> PE_DRV_CFG_TERM
67 %type <num> value_sym
68 %type <head> event_config
69 %type <term> event_term
70 %type <head> event_pmu
71 %type <head> event_legacy_symbol
72 %type <head> event_legacy_cache
73 %type <head> event_legacy_mem
74 %type <head> event_legacy_tracepoint
75 %type <tracepoint_name> tracepoint_name
76 %type <head> event_legacy_numeric
77 %type <head> event_legacy_raw
78 %type <head> event_bpf_file
79 %type <head> event_def
80 %type <head> event_mod
81 %type <head> event_name
82 %type <head> event
83 %type <head> events
84 %type <head> group_def
85 %type <head> group
86 %type <head> groups
87
88 %union
89 {
90         char *str;
91         u64 num;
92         struct list_head *head;
93         struct parse_events_term *term;
94         struct tracepoint_name {
95                 char *sys;
96                 char *event;
97         } tracepoint_name;
98 }
99 %%
100
101 start:
102 PE_START_EVENTS start_events
103 |
104 PE_START_TERMS  start_terms
105
106 start_events: groups
107 {
108         struct parse_events_evlist *data = _data;
109
110         parse_events_update_lists($1, &data->list);
111 }
112
113 groups:
114 groups ',' group
115 {
116         struct list_head *list  = $1;
117         struct list_head *group = $3;
118
119         parse_events_update_lists(group, list);
120         $$ = list;
121 }
122 |
123 groups ',' event
124 {
125         struct list_head *list  = $1;
126         struct list_head *event = $3;
127
128         parse_events_update_lists(event, list);
129         $$ = list;
130 }
131 |
132 group
133 |
134 event
135
136 group:
137 group_def ':' PE_MODIFIER_EVENT
138 {
139         struct list_head *list = $1;
140
141         ABORT_ON(parse_events__modifier_group(list, $3));
142         $$ = list;
143 }
144 |
145 group_def
146
147 group_def:
148 PE_NAME '{' events '}'
149 {
150         struct list_head *list = $3;
151
152         inc_group_count(list, _data);
153         parse_events__set_leader($1, list);
154         $$ = list;
155 }
156 |
157 '{' events '}'
158 {
159         struct list_head *list = $2;
160
161         inc_group_count(list, _data);
162         parse_events__set_leader(NULL, list);
163         $$ = list;
164 }
165
166 events:
167 events ',' event
168 {
169         struct list_head *event = $3;
170         struct list_head *list  = $1;
171
172         parse_events_update_lists(event, list);
173         $$ = list;
174 }
175 |
176 event
177
178 event: event_mod
179
180 event_mod:
181 event_name PE_MODIFIER_EVENT
182 {
183         struct list_head *list = $1;
184
185         /*
186          * Apply modifier on all events added by single event definition
187          * (there could be more events added for multiple tracepoint
188          * definitions via '*?'.
189          */
190         ABORT_ON(parse_events__modifier_event(list, $2, false));
191         $$ = list;
192 }
193 |
194 event_name
195
196 event_name:
197 PE_EVENT_NAME event_def
198 {
199         ABORT_ON(parse_events_name($2, $1));
200         free($1);
201         $$ = $2;
202 }
203 |
204 event_def
205
206 event_def: event_pmu |
207            event_legacy_symbol |
208            event_legacy_cache sep_dc |
209            event_legacy_mem |
210            event_legacy_tracepoint sep_dc |
211            event_legacy_numeric sep_dc |
212            event_legacy_raw sep_dc |
213            event_bpf_file
214
215 event_pmu:
216 PE_NAME '/' event_config '/'
217 {
218         struct parse_events_evlist *data = _data;
219         struct list_head *list;
220
221         ALLOC_LIST(list);
222         ABORT_ON(parse_events_add_pmu(data, list, $1, $3));
223         parse_events__free_terms($3);
224         $$ = list;
225 }
226 |
227 PE_NAME '/' '/'
228 {
229         struct parse_events_evlist *data = _data;
230         struct list_head *list;
231
232         ALLOC_LIST(list);
233         ABORT_ON(parse_events_add_pmu(data, list, $1, NULL));
234         $$ = list;
235 }
236 |
237 PE_KERNEL_PMU_EVENT sep_dc
238 {
239         struct parse_events_evlist *data = _data;
240         struct list_head *head;
241         struct parse_events_term *term;
242         struct list_head *list;
243
244         ALLOC_LIST(head);
245         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
246                                         $1, 1, &@1, NULL));
247         list_add_tail(&term->list, head);
248
249         ALLOC_LIST(list);
250         ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
251         parse_events__free_terms(head);
252         $$ = list;
253 }
254 |
255 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
256 {
257         struct parse_events_evlist *data = _data;
258         struct list_head *head;
259         struct parse_events_term *term;
260         struct list_head *list;
261         char pmu_name[128];
262         snprintf(&pmu_name, 128, "%s-%s", $1, $3);
263
264         ALLOC_LIST(head);
265         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
266                                         &pmu_name, 1, &@1, NULL));
267         list_add_tail(&term->list, head);
268
269         ALLOC_LIST(list);
270         ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
271         parse_events__free_terms(head);
272         $$ = list;
273 }
274
275 value_sym:
276 PE_VALUE_SYM_HW
277 |
278 PE_VALUE_SYM_SW
279
280 event_legacy_symbol:
281 value_sym '/' event_config '/'
282 {
283         struct parse_events_evlist *data = _data;
284         struct list_head *list;
285         int type = $1 >> 16;
286         int config = $1 & 255;
287
288         ALLOC_LIST(list);
289         ABORT_ON(parse_events_add_numeric(data, list, type, config, $3));
290         parse_events__free_terms($3);
291         $$ = list;
292 }
293 |
294 value_sym sep_slash_dc
295 {
296         struct parse_events_evlist *data = _data;
297         struct list_head *list;
298         int type = $1 >> 16;
299         int config = $1 & 255;
300
301         ALLOC_LIST(list);
302         ABORT_ON(parse_events_add_numeric(data, list, type, config, NULL));
303         $$ = list;
304 }
305
306 event_legacy_cache:
307 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
308 {
309         struct parse_events_evlist *data = _data;
310         struct list_head *list;
311
312         ALLOC_LIST(list);
313         ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5));
314         $$ = list;
315 }
316 |
317 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
318 {
319         struct parse_events_evlist *data = _data;
320         struct list_head *list;
321
322         ALLOC_LIST(list);
323         ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL));
324         $$ = list;
325 }
326 |
327 PE_NAME_CACHE_TYPE
328 {
329         struct parse_events_evlist *data = _data;
330         struct list_head *list;
331
332         ALLOC_LIST(list);
333         ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL));
334         $$ = list;
335 }
336
337 event_legacy_mem:
338 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
339 {
340         struct parse_events_evlist *data = _data;
341         struct list_head *list;
342
343         ALLOC_LIST(list);
344         ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
345                                              (void *) $2, $6, $4));
346         $$ = list;
347 }
348 |
349 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
350 {
351         struct parse_events_evlist *data = _data;
352         struct list_head *list;
353
354         ALLOC_LIST(list);
355         ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
356                                              (void *) $2, NULL, $4));
357         $$ = list;
358 }
359 |
360 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
361 {
362         struct parse_events_evlist *data = _data;
363         struct list_head *list;
364
365         ALLOC_LIST(list);
366         ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
367                                              (void *) $2, $4, 0));
368         $$ = list;
369 }
370 |
371 PE_PREFIX_MEM PE_VALUE sep_dc
372 {
373         struct parse_events_evlist *data = _data;
374         struct list_head *list;
375
376         ALLOC_LIST(list);
377         ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
378                                              (void *) $2, NULL, 0));
379         $$ = list;
380 }
381
382 event_legacy_tracepoint:
383 tracepoint_name
384 {
385         struct parse_events_evlist *data = _data;
386         struct parse_events_error *error = data->error;
387         struct list_head *list;
388
389         ALLOC_LIST(list);
390         if (error)
391                 error->idx = @1.first_column;
392
393         if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event,
394                                         error, NULL))
395                 return -1;
396
397         $$ = list;
398 }
399 |
400 tracepoint_name '/' event_config '/'
401 {
402         struct parse_events_evlist *data = _data;
403         struct parse_events_error *error = data->error;
404         struct list_head *list;
405
406         ALLOC_LIST(list);
407         if (error)
408                 error->idx = @1.first_column;
409
410         if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event,
411                                         error, $3))
412                 return -1;
413
414         $$ = list;
415 }
416
417 tracepoint_name:
418 PE_NAME '-' PE_NAME ':' PE_NAME
419 {
420         char sys_name[128];
421         struct tracepoint_name tracepoint;
422
423         snprintf(&sys_name, 128, "%s-%s", $1, $3);
424         tracepoint.sys = &sys_name;
425         tracepoint.event = $5;
426
427         $$ = tracepoint;
428 }
429 |
430 PE_NAME ':' PE_NAME
431 {
432         struct tracepoint_name tracepoint = {$1, $3};
433
434         $$ = tracepoint;
435 }
436
437 event_legacy_numeric:
438 PE_VALUE ':' PE_VALUE
439 {
440         struct parse_events_evlist *data = _data;
441         struct list_head *list;
442
443         ALLOC_LIST(list);
444         ABORT_ON(parse_events_add_numeric(data, list, (u32)$1, $3, NULL));
445         $$ = list;
446 }
447
448 event_legacy_raw:
449 PE_RAW
450 {
451         struct parse_events_evlist *data = _data;
452         struct list_head *list;
453
454         ALLOC_LIST(list);
455         ABORT_ON(parse_events_add_numeric(data, list, PERF_TYPE_RAW, $1, NULL));
456         $$ = list;
457 }
458
459 event_bpf_file:
460 PE_BPF_OBJECT
461 {
462         struct parse_events_evlist *data = _data;
463         struct parse_events_error *error = data->error;
464         struct list_head *list;
465
466         ALLOC_LIST(list);
467         ABORT_ON(parse_events_load_bpf(data, list, $1, false));
468         $$ = list;
469 }
470 |
471 PE_BPF_SOURCE
472 {
473         struct parse_events_evlist *data = _data;
474         struct list_head *list;
475
476         ALLOC_LIST(list);
477         ABORT_ON(parse_events_load_bpf(data, list, $1, true));
478         $$ = list;
479 }
480
481 start_terms: event_config
482 {
483         struct parse_events_terms *data = _data;
484         data->terms = $1;
485 }
486
487 event_config:
488 event_config ',' event_term
489 {
490         struct list_head *head = $1;
491         struct parse_events_term *term = $3;
492
493         ABORT_ON(!head);
494         list_add_tail(&term->list, head);
495         $$ = $1;
496 }
497 |
498 event_term
499 {
500         struct list_head *head = malloc(sizeof(*head));
501         struct parse_events_term *term = $1;
502
503         ABORT_ON(!head);
504         INIT_LIST_HEAD(head);
505         list_add_tail(&term->list, head);
506         $$ = head;
507 }
508
509 event_term:
510 PE_NAME '=' PE_NAME
511 {
512         struct parse_events_term *term;
513
514         ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
515                                         $1, $3, &@1, &@3));
516         $$ = term;
517 }
518 |
519 PE_NAME '=' PE_VALUE
520 {
521         struct parse_events_term *term;
522
523         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
524                                         $1, $3, &@1, &@3));
525         $$ = term;
526 }
527 |
528 PE_NAME '=' PE_VALUE_SYM_HW
529 {
530         struct parse_events_term *term;
531         int config = $3 & 255;
532
533         ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
534         $$ = term;
535 }
536 |
537 PE_NAME
538 {
539         struct parse_events_term *term;
540
541         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
542                                         $1, 1, &@1, NULL));
543         $$ = term;
544 }
545 |
546 PE_VALUE_SYM_HW
547 {
548         struct parse_events_term *term;
549         int config = $1 & 255;
550
551         ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
552         $$ = term;
553 }
554 |
555 PE_TERM '=' PE_NAME
556 {
557         struct parse_events_term *term;
558
559         ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3));
560         $$ = term;
561 }
562 |
563 PE_TERM '=' PE_VALUE
564 {
565         struct parse_events_term *term;
566
567         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, &@1, &@3));
568         $$ = term;
569 }
570 |
571 PE_TERM
572 {
573         struct parse_events_term *term;
574
575         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL));
576         $$ = term;
577 }
578 |
579 PE_DRV_CFG_TERM
580 {
581         struct parse_events_term *term;
582
583         ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG,
584                                        $1, $1, &@1, NULL));
585         $$ = term;
586 }
587
588 sep_dc: ':' |
589
590 sep_slash_dc: '/' | ':' |
591
592 %%
593
594 void parse_events_error(YYLTYPE *loc, void *data,
595                         void *scanner __maybe_unused,
596                         char const *msg __maybe_unused)
597 {
598         parse_events_evlist_error(data, loc->last_column, "parser error");
599 }