]>
Commit | Line | Data |
---|---|---|
ac20de6f | 1 | %pure-parser |
46010ab2 | 2 | %parse-param {void *_data} |
ac20de6f ZY |
3 | %parse-param {void *scanner} |
4 | %lex-param {void* scanner} | |
89812fc8 JO |
5 | |
6 | %{ | |
7 | ||
8 | #define YYDEBUG 1 | |
9 | ||
10 | #include <linux/compiler.h> | |
11 | #include <linux/list.h> | |
d944c4ee | 12 | #include <linux/types.h> |
89812fc8 JO |
13 | #include "util.h" |
14 | #include "parse-events.h" | |
ac20de6f | 15 | #include "parse-events-bison.h" |
89812fc8 | 16 | |
ac20de6f | 17 | extern int parse_events_lex (YYSTYPE* lvalp, void* scanner); |
89812fc8 JO |
18 | |
19 | #define ABORT_ON(val) \ | |
20 | do { \ | |
21 | if (val) \ | |
22 | YYABORT; \ | |
23 | } while (0) | |
24 | ||
c5cd8ac0 DA |
25 | #define ALLOC_LIST(list) \ |
26 | do { \ | |
27 | list = malloc(sizeof(*list)); \ | |
28 | ABORT_ON(!list); \ | |
29 | INIT_LIST_HEAD(list); \ | |
30 | } while (0) | |
31 | ||
97f63e4a NK |
32 | static inc_group_count(struct list_head *list, |
33 | struct parse_events_evlist *data) | |
34 | { | |
35 | /* Count groups only have more than 1 members */ | |
36 | if (!list_is_last(list->next, list)) | |
37 | data->nr_groups++; | |
38 | } | |
39 | ||
89812fc8 JO |
40 | %} |
41 | ||
90e2b22d | 42 | %token PE_START_EVENTS PE_START_TERMS |
cf3506dc | 43 | %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM |
ac2ba9f3 | 44 | %token PE_EVENT_NAME |
89812fc8 JO |
45 | %token PE_NAME |
46 | %token PE_MODIFIER_EVENT PE_MODIFIER_BP | |
47 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT | |
89efb029 | 48 | %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP |
89812fc8 | 49 | %token PE_ERROR |
ba32a451 | 50 | %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT |
89812fc8 | 51 | %type <num> PE_VALUE |
cf3506dc JO |
52 | %type <num> PE_VALUE_SYM_HW |
53 | %type <num> PE_VALUE_SYM_SW | |
89812fc8 | 54 | %type <num> PE_RAW |
8f707d84 | 55 | %type <num> PE_TERM |
89812fc8 JO |
56 | %type <str> PE_NAME |
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 | |
ac2ba9f3 | 61 | %type <str> PE_EVENT_NAME |
ba32a451 | 62 | %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT |
cf3506dc | 63 | %type <num> value_sym |
8f707d84 JO |
64 | %type <head> event_config |
65 | %type <term> event_term | |
b847cbdc JO |
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 | |
ac2ba9f3 RR |
74 | %type <head> event_mod |
75 | %type <head> event_name | |
89efb029 JO |
76 | %type <head> event |
77 | %type <head> events | |
78 | %type <head> group_def | |
79 | %type <head> group | |
80 | %type <head> groups | |
89812fc8 JO |
81 | |
82 | %union | |
83 | { | |
84 | char *str; | |
b527bab5 | 85 | u64 num; |
8f707d84 | 86 | struct list_head *head; |
6cee6cd3 | 87 | struct parse_events_term *term; |
89812fc8 JO |
88 | } |
89 | %% | |
90 | ||
90e2b22d | 91 | start: |
89efb029 | 92 | PE_START_EVENTS start_events |
90e2b22d | 93 | | |
89efb029 JO |
94 | PE_START_TERMS start_terms |
95 | ||
96 | start_events: groups | |
97 | { | |
23b6339b | 98 | struct parse_events_evlist *data = _data; |
89efb029 JO |
99 | |
100 | parse_events_update_lists($1, &data->list); | |
101 | } | |
102 | ||
103 | groups: | |
104 | groups ',' group | |
105 | { | |
106 | struct list_head *list = $1; | |
107 | struct list_head *group = $3; | |
108 | ||
109 | parse_events_update_lists(group, list); | |
110 | $$ = list; | |
111 | } | |
112 | | | |
113 | groups ',' event | |
114 | { | |
115 | struct list_head *list = $1; | |
116 | struct list_head *event = $3; | |
117 | ||
118 | parse_events_update_lists(event, list); | |
119 | $$ = list; | |
120 | } | |
121 | | | |
122 | group | |
123 | | | |
124 | event | |
125 | ||
126 | group: | |
127 | group_def ':' PE_MODIFIER_EVENT | |
128 | { | |
129 | struct list_head *list = $1; | |
130 | ||
131 | ABORT_ON(parse_events__modifier_group(list, $3)); | |
132 | $$ = list; | |
133 | } | |
134 | | | |
135 | group_def | |
136 | ||
137 | group_def: | |
138 | PE_NAME '{' events '}' | |
139 | { | |
140 | struct list_head *list = $3; | |
141 | ||
97f63e4a | 142 | inc_group_count(list, _data); |
63dab225 | 143 | parse_events__set_leader($1, list); |
89efb029 JO |
144 | $$ = list; |
145 | } | |
146 | | | |
147 | '{' events '}' | |
148 | { | |
149 | struct list_head *list = $2; | |
150 | ||
97f63e4a | 151 | inc_group_count(list, _data); |
63dab225 | 152 | parse_events__set_leader(NULL, list); |
89efb029 JO |
153 | $$ = list; |
154 | } | |
90e2b22d | 155 | |
89812fc8 | 156 | events: |
89efb029 JO |
157 | events ',' event |
158 | { | |
159 | struct list_head *event = $3; | |
160 | struct list_head *list = $1; | |
161 | ||
162 | parse_events_update_lists(event, list); | |
163 | $$ = list; | |
164 | } | |
165 | | | |
166 | event | |
89812fc8 | 167 | |
ac2ba9f3 RR |
168 | event: event_mod |
169 | ||
170 | event_mod: | |
171 | event_name PE_MODIFIER_EVENT | |
89812fc8 | 172 | { |
89efb029 | 173 | struct list_head *list = $1; |
46010ab2 | 174 | |
5d7be90e JO |
175 | /* |
176 | * Apply modifier on all events added by single event definition | |
177 | * (there could be more events added for multiple tracepoint | |
178 | * definitions via '*?'. | |
179 | */ | |
f5b1135b | 180 | ABORT_ON(parse_events__modifier_event(list, $2, false)); |
89efb029 | 181 | $$ = list; |
89812fc8 JO |
182 | } |
183 | | | |
ac2ba9f3 RR |
184 | event_name |
185 | ||
186 | event_name: | |
187 | PE_EVENT_NAME event_def | |
188 | { | |
189 | ABORT_ON(parse_events_name($2, $1)); | |
190 | free($1); | |
191 | $$ = $2; | |
192 | } | |
193 | | | |
89812fc8 JO |
194 | event_def |
195 | ||
5f537a26 JO |
196 | event_def: event_pmu | |
197 | event_legacy_symbol | | |
89812fc8 JO |
198 | event_legacy_cache sep_dc | |
199 | event_legacy_mem | | |
200 | event_legacy_tracepoint sep_dc | | |
201 | event_legacy_numeric sep_dc | | |
202 | event_legacy_raw sep_dc | |
203 | ||
5f537a26 JO |
204 | event_pmu: |
205 | PE_NAME '/' event_config '/' | |
206 | { | |
23b6339b | 207 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 208 | struct list_head *list; |
b847cbdc | 209 | |
c5cd8ac0 DA |
210 | ALLOC_LIST(list); |
211 | ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, $3)); | |
5f537a26 | 212 | parse_events__free_terms($3); |
b847cbdc | 213 | $$ = list; |
5f537a26 | 214 | } |
ad962273 AH |
215 | | |
216 | PE_NAME '/' '/' | |
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(list, &data->idx, $1, NULL)); | |
223 | $$ = list; | |
224 | } | |
ba32a451 KL |
225 | | |
226 | PE_KERNEL_PMU_EVENT sep_dc | |
227 | { | |
228 | struct parse_events_evlist *data = _data; | |
229 | struct list_head *head; | |
230 | struct parse_events_term *term; | |
231 | struct list_head *list; | |
232 | ||
233 | ALLOC_LIST(head); | |
234 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, | |
235 | $1, 1)); | |
236 | list_add_tail(&term->list, head); | |
237 | ||
238 | ALLOC_LIST(list); | |
239 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | |
240 | parse_events__free_terms(head); | |
241 | $$ = list; | |
242 | } | |
243 | | | |
244 | PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc | |
245 | { | |
246 | struct parse_events_evlist *data = _data; | |
247 | struct list_head *head; | |
248 | struct parse_events_term *term; | |
249 | struct list_head *list; | |
250 | char pmu_name[128]; | |
251 | snprintf(&pmu_name, 128, "%s-%s", $1, $3); | |
252 | ||
253 | ALLOC_LIST(head); | |
254 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, | |
255 | &pmu_name, 1)); | |
256 | list_add_tail(&term->list, head); | |
257 | ||
258 | ALLOC_LIST(list); | |
259 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | |
260 | parse_events__free_terms(head); | |
261 | $$ = list; | |
262 | } | |
5f537a26 | 263 | |
cf3506dc JO |
264 | value_sym: |
265 | PE_VALUE_SYM_HW | |
266 | | | |
267 | PE_VALUE_SYM_SW | |
268 | ||
89812fc8 | 269 | event_legacy_symbol: |
cf3506dc | 270 | value_sym '/' event_config '/' |
89812fc8 | 271 | { |
23b6339b | 272 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 273 | struct list_head *list; |
89812fc8 JO |
274 | int type = $1 >> 16; |
275 | int config = $1 & 255; | |
276 | ||
c5cd8ac0 DA |
277 | ALLOC_LIST(list); |
278 | ABORT_ON(parse_events_add_numeric(list, &data->idx, | |
46010ab2 | 279 | type, config, $3)); |
8f707d84 | 280 | parse_events__free_terms($3); |
b847cbdc | 281 | $$ = list; |
8f707d84 JO |
282 | } |
283 | | | |
cf3506dc | 284 | value_sym sep_slash_dc |
8f707d84 | 285 | { |
23b6339b | 286 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 287 | struct list_head *list; |
8f707d84 JO |
288 | int type = $1 >> 16; |
289 | int config = $1 & 255; | |
290 | ||
c5cd8ac0 DA |
291 | ALLOC_LIST(list); |
292 | ABORT_ON(parse_events_add_numeric(list, &data->idx, | |
46010ab2 | 293 | type, config, NULL)); |
b847cbdc | 294 | $$ = list; |
89812fc8 JO |
295 | } |
296 | ||
297 | event_legacy_cache: | |
298 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT | |
299 | { | |
23b6339b | 300 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 301 | struct list_head *list; |
b847cbdc | 302 | |
c5cd8ac0 DA |
303 | ALLOC_LIST(list); |
304 | ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5)); | |
b847cbdc | 305 | $$ = list; |
89812fc8 JO |
306 | } |
307 | | | |
308 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT | |
309 | { | |
23b6339b | 310 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 311 | struct list_head *list; |
b847cbdc | 312 | |
c5cd8ac0 DA |
313 | ALLOC_LIST(list); |
314 | ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL)); | |
b847cbdc | 315 | $$ = list; |
89812fc8 JO |
316 | } |
317 | | | |
318 | PE_NAME_CACHE_TYPE | |
319 | { | |
23b6339b | 320 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 321 | struct list_head *list; |
b847cbdc | 322 | |
c5cd8ac0 DA |
323 | ALLOC_LIST(list); |
324 | ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL)); | |
b847cbdc | 325 | $$ = list; |
89812fc8 JO |
326 | } |
327 | ||
328 | event_legacy_mem: | |
329 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc | |
330 | { | |
23b6339b | 331 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 332 | struct list_head *list; |
b847cbdc | 333 | |
c5cd8ac0 DA |
334 | ALLOC_LIST(list); |
335 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | |
46010ab2 | 336 | (void *) $2, $4)); |
b847cbdc | 337 | $$ = list; |
89812fc8 JO |
338 | } |
339 | | | |
340 | PE_PREFIX_MEM PE_VALUE sep_dc | |
341 | { | |
23b6339b | 342 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 343 | struct list_head *list; |
b847cbdc | 344 | |
c5cd8ac0 DA |
345 | ALLOC_LIST(list); |
346 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | |
46010ab2 | 347 | (void *) $2, NULL)); |
b847cbdc | 348 | $$ = list; |
89812fc8 JO |
349 | } |
350 | ||
351 | event_legacy_tracepoint: | |
2b9032e0 AY |
352 | PE_NAME '-' PE_NAME ':' PE_NAME |
353 | { | |
354 | struct parse_events_evlist *data = _data; | |
355 | struct list_head *list; | |
356 | char sys_name[128]; | |
357 | snprintf(&sys_name, 128, "%s-%s", $1, $3); | |
358 | ||
359 | ALLOC_LIST(list); | |
360 | ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5)); | |
361 | $$ = list; | |
362 | } | |
363 | | | |
89812fc8 JO |
364 | PE_NAME ':' PE_NAME |
365 | { | |
23b6339b | 366 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 367 | struct list_head *list; |
b847cbdc | 368 | |
c5cd8ac0 DA |
369 | ALLOC_LIST(list); |
370 | ABORT_ON(parse_events_add_tracepoint(list, &data->idx, $1, $3)); | |
b847cbdc | 371 | $$ = list; |
89812fc8 JO |
372 | } |
373 | ||
374 | event_legacy_numeric: | |
375 | PE_VALUE ':' PE_VALUE | |
376 | { | |
23b6339b | 377 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 378 | struct list_head *list; |
b847cbdc | 379 | |
c5cd8ac0 DA |
380 | ALLOC_LIST(list); |
381 | ABORT_ON(parse_events_add_numeric(list, &data->idx, (u32)$1, $3, NULL)); | |
b847cbdc | 382 | $$ = list; |
89812fc8 JO |
383 | } |
384 | ||
385 | event_legacy_raw: | |
386 | PE_RAW | |
387 | { | |
23b6339b | 388 | struct parse_events_evlist *data = _data; |
c5cd8ac0 | 389 | struct list_head *list; |
b847cbdc | 390 | |
c5cd8ac0 DA |
391 | ALLOC_LIST(list); |
392 | ABORT_ON(parse_events_add_numeric(list, &data->idx, | |
46010ab2 | 393 | PERF_TYPE_RAW, $1, NULL)); |
b847cbdc | 394 | $$ = list; |
8f707d84 JO |
395 | } |
396 | ||
89efb029 | 397 | start_terms: event_config |
90e2b22d | 398 | { |
23b6339b | 399 | struct parse_events_terms *data = _data; |
90e2b22d JO |
400 | data->terms = $1; |
401 | } | |
402 | ||
8f707d84 JO |
403 | event_config: |
404 | event_config ',' event_term | |
405 | { | |
406 | struct list_head *head = $1; | |
6cee6cd3 | 407 | struct parse_events_term *term = $3; |
8f707d84 JO |
408 | |
409 | ABORT_ON(!head); | |
410 | list_add_tail(&term->list, head); | |
411 | $$ = $1; | |
412 | } | |
413 | | | |
414 | event_term | |
415 | { | |
416 | struct list_head *head = malloc(sizeof(*head)); | |
6cee6cd3 | 417 | struct parse_events_term *term = $1; |
8f707d84 JO |
418 | |
419 | ABORT_ON(!head); | |
420 | INIT_LIST_HEAD(head); | |
421 | list_add_tail(&term->list, head); | |
422 | $$ = head; | |
423 | } | |
424 | ||
425 | event_term: | |
426 | PE_NAME '=' PE_NAME | |
427 | { | |
6cee6cd3 | 428 | struct parse_events_term *term; |
8f707d84 | 429 | |
6cee6cd3 | 430 | ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
16fa7e82 | 431 | $1, $3)); |
8f707d84 JO |
432 | $$ = term; |
433 | } | |
434 | | | |
435 | PE_NAME '=' PE_VALUE | |
436 | { | |
6cee6cd3 | 437 | struct parse_events_term *term; |
8f707d84 | 438 | |
6cee6cd3 | 439 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
16fa7e82 | 440 | $1, $3)); |
8f707d84 JO |
441 | $$ = term; |
442 | } | |
443 | | | |
1d33d6dc JO |
444 | PE_NAME '=' PE_VALUE_SYM_HW |
445 | { | |
6cee6cd3 | 446 | struct parse_events_term *term; |
1d33d6dc JO |
447 | int config = $3 & 255; |
448 | ||
6cee6cd3 | 449 | ABORT_ON(parse_events_term__sym_hw(&term, $1, config)); |
1d33d6dc JO |
450 | $$ = term; |
451 | } | |
452 | | | |
8f707d84 JO |
453 | PE_NAME |
454 | { | |
6cee6cd3 | 455 | struct parse_events_term *term; |
8f707d84 | 456 | |
6cee6cd3 | 457 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
16fa7e82 | 458 | $1, 1)); |
8f707d84 JO |
459 | $$ = term; |
460 | } | |
461 | | | |
1d33d6dc JO |
462 | PE_VALUE_SYM_HW |
463 | { | |
6cee6cd3 | 464 | struct parse_events_term *term; |
1d33d6dc JO |
465 | int config = $1 & 255; |
466 | ||
6cee6cd3 | 467 | ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); |
1d33d6dc JO |
468 | $$ = term; |
469 | } | |
470 | | | |
6b5fc39b JO |
471 | PE_TERM '=' PE_NAME |
472 | { | |
6cee6cd3 | 473 | struct parse_events_term *term; |
6b5fc39b | 474 | |
6cee6cd3 | 475 | ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3)); |
6b5fc39b JO |
476 | $$ = term; |
477 | } | |
478 | | | |
8f707d84 JO |
479 | PE_TERM '=' PE_VALUE |
480 | { | |
6cee6cd3 | 481 | struct parse_events_term *term; |
8f707d84 | 482 | |
6cee6cd3 | 483 | ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3)); |
8f707d84 JO |
484 | $$ = term; |
485 | } | |
486 | | | |
487 | PE_TERM | |
488 | { | |
6cee6cd3 | 489 | struct parse_events_term *term; |
8f707d84 | 490 | |
6cee6cd3 | 491 | ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1)); |
8f707d84 | 492 | $$ = term; |
89812fc8 JO |
493 | } |
494 | ||
495 | sep_dc: ':' | | |
496 | ||
8f707d84 JO |
497 | sep_slash_dc: '/' | ':' | |
498 | ||
89812fc8 JO |
499 | %% |
500 | ||
1d037ca1 IT |
501 | void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused, |
502 | char const *msg __maybe_unused) | |
89812fc8 JO |
503 | { |
504 | } |