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