xref: /openbmc/linux/tools/perf/util/parse-events.y (revision fea88a0c)
1 
2 %name-prefix "parse_events_"
3 %parse-param {struct list_head *list_all}
4 %parse-param {struct list_head *list_event}
5 %parse-param {int *idx}
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"
16 
17 extern int parse_events_lex (void);
18 
19 #define ABORT_ON(val) \
20 do { \
21 	if (val) \
22 		YYABORT; \
23 } while (0)
24 
25 %}
26 
27 %token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM
28 %token PE_NAME
29 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
30 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
31 %token PE_PREFIX_MEM PE_PREFIX_RAW
32 %token PE_ERROR
33 %type <num> PE_VALUE
34 %type <num> PE_VALUE_SYM
35 %type <num> PE_RAW
36 %type <num> PE_TERM
37 %type <str> PE_NAME
38 %type <str> PE_NAME_CACHE_TYPE
39 %type <str> PE_NAME_CACHE_OP_RESULT
40 %type <str> PE_MODIFIER_EVENT
41 %type <str> PE_MODIFIER_BP
42 %type <head> event_config
43 %type <term> event_term
44 
45 %union
46 {
47 	char *str;
48 	unsigned long num;
49 	struct list_head *head;
50 	struct parse_events__term *term;
51 }
52 %%
53 
54 events:
55 events ',' event | event
56 
57 event:
58 event_def PE_MODIFIER_EVENT
59 {
60 	/*
61 	 * Apply modifier on all events added by single event definition
62 	 * (there could be more events added for multiple tracepoint
63 	 * definitions via '*?'.
64 	 */
65 	ABORT_ON(parse_events_modifier(list_event, $2));
66 	parse_events_update_lists(list_event, list_all);
67 }
68 |
69 event_def
70 {
71 	parse_events_update_lists(list_event, list_all);
72 }
73 
74 event_def: event_pmu |
75 	   event_legacy_symbol |
76 	   event_legacy_cache sep_dc |
77 	   event_legacy_mem |
78 	   event_legacy_tracepoint sep_dc |
79 	   event_legacy_numeric sep_dc |
80 	   event_legacy_raw sep_dc
81 
82 event_pmu:
83 PE_NAME '/' event_config '/'
84 {
85 	ABORT_ON(parse_events_add_pmu(list_event, idx, $1, $3));
86 	parse_events__free_terms($3);
87 }
88 
89 event_legacy_symbol:
90 PE_VALUE_SYM '/' event_config '/'
91 {
92 	int type = $1 >> 16;
93 	int config = $1 & 255;
94 
95 	ABORT_ON(parse_events_add_numeric(list_event, idx, type, config, $3));
96 	parse_events__free_terms($3);
97 }
98 |
99 PE_VALUE_SYM sep_slash_dc
100 {
101 	int type = $1 >> 16;
102 	int config = $1 & 255;
103 
104 	ABORT_ON(parse_events_add_numeric(list_event, idx, type, config, NULL));
105 }
106 
107 event_legacy_cache:
108 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
109 {
110 	ABORT_ON(parse_events_add_cache(list_event, idx, $1, $3, $5));
111 }
112 |
113 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
114 {
115 	ABORT_ON(parse_events_add_cache(list_event, idx, $1, $3, NULL));
116 }
117 |
118 PE_NAME_CACHE_TYPE
119 {
120 	ABORT_ON(parse_events_add_cache(list_event, idx, $1, NULL, NULL));
121 }
122 
123 event_legacy_mem:
124 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
125 {
126 	ABORT_ON(parse_events_add_breakpoint(list_event, idx, (void *) $2, $4));
127 }
128 |
129 PE_PREFIX_MEM PE_VALUE sep_dc
130 {
131 	ABORT_ON(parse_events_add_breakpoint(list_event, idx, (void *) $2, NULL));
132 }
133 
134 event_legacy_tracepoint:
135 PE_NAME ':' PE_NAME
136 {
137 	ABORT_ON(parse_events_add_tracepoint(list_event, idx, $1, $3));
138 }
139 
140 event_legacy_numeric:
141 PE_VALUE ':' PE_VALUE
142 {
143 	ABORT_ON(parse_events_add_numeric(list_event, idx, $1, $3, NULL));
144 }
145 
146 event_legacy_raw:
147 PE_RAW
148 {
149 	ABORT_ON(parse_events_add_numeric(list_event, idx, PERF_TYPE_RAW, $1, NULL));
150 }
151 
152 event_config:
153 event_config ',' event_term
154 {
155 	struct list_head *head = $1;
156 	struct parse_events__term *term = $3;
157 
158 	ABORT_ON(!head);
159 	list_add_tail(&term->list, head);
160 	$$ = $1;
161 }
162 |
163 event_term
164 {
165 	struct list_head *head = malloc(sizeof(*head));
166 	struct parse_events__term *term = $1;
167 
168 	ABORT_ON(!head);
169 	INIT_LIST_HEAD(head);
170 	list_add_tail(&term->list, head);
171 	$$ = head;
172 }
173 
174 event_term:
175 PE_NAME '=' PE_NAME
176 {
177 	struct parse_events__term *term;
178 
179 	ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR,
180 		 $1, $3, 0));
181 	$$ = term;
182 }
183 |
184 PE_NAME '=' PE_VALUE
185 {
186 	struct parse_events__term *term;
187 
188 	ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
189 		 $1, NULL, $3));
190 	$$ = term;
191 }
192 |
193 PE_NAME
194 {
195 	struct parse_events__term *term;
196 
197 	ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
198 		 $1, NULL, 1));
199 	$$ = term;
200 }
201 |
202 PE_TERM '=' PE_VALUE
203 {
204 	struct parse_events__term *term;
205 
206 	ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, $3));
207 	$$ = term;
208 }
209 |
210 PE_TERM
211 {
212 	struct parse_events__term *term;
213 
214 	ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, 1));
215 	$$ = term;
216 }
217 
218 sep_dc: ':' |
219 
220 sep_slash_dc: '/' | ':' |
221 
222 %%
223 
224 void parse_events_error(struct list_head *list_all __used,
225 			struct list_head *list_event __used,
226 			int *idx __used,
227 			char const *msg __used)
228 {
229 }
230