radix: Implement radix_tree_destroy()
[akaros.git] / user / perfmon / tests / validate_arm.c
1 /*
2  * validate_arm.c - validate ARM event tables + encodings
3  *
4  * Copyright (c) 2011 Google, Inc
5  * Contributed by Stephane Eranian <eranian@gmail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11  * of the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  */
25 #include <sys/types.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <inttypes.h>
29 #include <stdarg.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <string.h>
33
34 #include <perfmon/pfmlib.h>
35
36 #define MAX_ENCODING    1
37 #define SRC_LINE        .line = __LINE__
38
39 typedef struct {
40         const char *name;
41         const char *fstr;
42         uint64_t codes[MAX_ENCODING];
43         int ret, count, line;
44 } test_event_t;
45
46 static const test_event_t arm_test_events[]={
47         { SRC_LINE,
48           .name = "arm_ac7::CPU_CYCLES",
49           .ret  = PFM_SUCCESS,
50           .count = 1,
51           .codes[0] = 0x8000011,
52           .fstr = "arm_ac7::CPU_CYCLES:k=1:u=1:hv=0",
53         },
54         { SRC_LINE,
55           .name = "arm_ac7::CPU_CYCLES:k",
56           .ret  = PFM_SUCCESS,
57           .count = 1,
58           .codes[0] = 0x88000011,
59           .fstr = "arm_ac7::CPU_CYCLES:k=1:u=0:hv=0",
60         },
61         { SRC_LINE,
62           .name = "arm_ac7::CPU_CYCLES:k:u",
63           .ret  = PFM_SUCCESS,
64           .count = 1,
65           .codes[0] = 0x8000011,
66           .fstr = "arm_ac7::CPU_CYCLES:k=1:u=1:hv=0",
67         },
68         { SRC_LINE,
69           .name = "arm_ac7::INST_RETIRED",
70           .ret  = PFM_SUCCESS,
71           .count = 1,
72           .codes[0] = 0x8000008,
73           .fstr = "arm_ac7::INST_RETIRED:k=1:u=1:hv=0",
74         },
75
76         { SRC_LINE,
77           .name = "arm_ac8::NEON_CYCLES",
78           .ret  = PFM_SUCCESS,
79           .count = 1,
80           .codes[0] = 0x5a,
81           .fstr = "arm_ac8::NEON_CYCLES",
82         },
83         { SRC_LINE,
84           .name = "arm_ac8::NEON_CYCLES:k",
85           .ret  = PFM_ERR_ATTR,
86         },
87         { SRC_LINE,
88           .name = "arm_ac8::CPU_CYCLES",
89           .ret  = PFM_SUCCESS,
90           .count = 1,
91           .codes[0] = 0xff,
92           .fstr = "arm_ac8::CPU_CYCLES",
93         },
94         { SRC_LINE,
95           .name = "arm_ac8::CPU_CYCLES_HALTED",
96           .ret  = PFM_ERR_NOTFOUND,
97         },
98
99         { SRC_LINE,
100           .name = "arm_ac9::CPU_CYCLES",
101           .ret  = PFM_SUCCESS,
102           .count = 1,
103           .codes[0] = 0xff,
104           .fstr = "arm_ac9::CPU_CYCLES",
105         },
106         { SRC_LINE,
107           .name = "arm_ac9::DMB_DEP_STALL_CYCLES",
108           .ret  = PFM_SUCCESS,
109           .count = 1,
110           .codes[0] = 0x86,
111           .fstr = "arm_ac9::DMB_DEP_STALL_CYCLES",
112         },
113         { SRC_LINE,
114           .name = "arm_ac9::CPU_CYCLES:u",
115           .ret  = PFM_ERR_ATTR,
116         },
117         { SRC_LINE,
118           .name = "arm_ac9::JAVA_HW_BYTECODE_EXEC",
119           .ret  = PFM_SUCCESS,
120           .count = 1,
121           .codes[0] = 0x40,
122           .fstr = "arm_ac9::JAVA_HW_BYTECODE_EXEC",
123         },
124         { SRC_LINE,
125           .name = "arm_ac15::CPU_CYCLES",
126           .ret  = PFM_SUCCESS,
127           .count = 1,
128           .codes[0] = 0x8000011,
129           .fstr = "arm_ac15::CPU_CYCLES:k=1:u=1:hv=0",
130         },
131         { SRC_LINE,
132           .name = "arm_ac15::CPU_CYCLES:k",
133           .ret  = PFM_SUCCESS,
134           .count = 1,
135           .codes[0] = 0x88000011,
136           .fstr = "arm_ac15::CPU_CYCLES:k=1:u=0:hv=0",
137         },
138         { SRC_LINE,
139           .name = "arm_ac15::CPU_CYCLES:k:u",
140           .ret  = PFM_SUCCESS,
141           .count = 1,
142           .codes[0] = 0x8000011,
143           .fstr = "arm_ac15::CPU_CYCLES:k=1:u=1:hv=0",
144         },
145         { SRC_LINE,
146           .name = "arm_ac15::INST_RETIRED",
147           .ret  = PFM_SUCCESS,
148           .count = 1,
149           .codes[0] = 0x8000008,
150           .fstr = "arm_ac15::INST_RETIRED:k=1:u=1:hv=0",
151         },
152         { SRC_LINE,
153           .name = "arm_1176::CPU_CYCLES",
154           .ret  = PFM_SUCCESS,
155           .count = 1,
156           .codes[0] = 0xff,
157           .fstr = "arm_1176::CPU_CYCLES",
158         },
159         { SRC_LINE,
160           .name = "arm_1176::CPU_CYCLES:k",
161           .ret  = PFM_ERR_ATTR,
162         },
163         { SRC_LINE,
164           .name = "arm_1176::INSTR_EXEC",
165           .ret  = PFM_SUCCESS,
166           .count = 1,
167           .codes[0] = 0x07,
168           .fstr = "arm_1176::INSTR_EXEC",
169         },
170         { SRC_LINE,
171           .name = "qcom_krait::CPU_CYCLES",
172           .ret  = PFM_SUCCESS,
173           .count = 1,
174           .codes[0] = 0x80000ff,
175           .fstr = "qcom_krait::CPU_CYCLES:k=1:u=1:hv=0",
176         },
177         { SRC_LINE,
178           .name = "qcom_krait::CPU_CYCLES:k:u",
179           .ret  = PFM_SUCCESS,
180           .count = 1,
181           .codes[0] = 0x80000ff,
182           .fstr = "qcom_krait::CPU_CYCLES:k=1:u=1:hv=0",
183         },
184         { SRC_LINE,
185           .name = "qcom_krait::CPU_CYCLES:u",
186           .ret  = PFM_SUCCESS,
187           .count = 1,
188           .codes[0] = 0x480000ff,
189           .fstr = "qcom_krait::CPU_CYCLES:k=0:u=1:hv=0",
190         },
191         { SRC_LINE,
192           .name = "arm_ac57::CPU_CYCLES",
193           .ret  = PFM_SUCCESS,
194           .count = 1,
195           .codes[0] = 0x8000011,
196           .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0",
197         },
198         { SRC_LINE,
199           .name = "arm_ac57::CPU_CYCLES:k",
200           .ret  = PFM_SUCCESS,
201           .count = 1,
202           .codes[0] = 0x88000011,
203           .fstr = "arm_ac57::CPU_CYCLES:k=1:u=0:hv=0",
204         },
205         { SRC_LINE,
206           .name = "arm_ac57::CPU_CYCLES:k:u",
207           .ret  = PFM_SUCCESS,
208           .count = 1,
209           .codes[0] = 0x8000011,
210           .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0",
211         },
212         { SRC_LINE,
213           .name = "arm_ac57::INST_RETIRED",
214           .ret  = PFM_SUCCESS,
215           .count = 1,
216           .codes[0] = 0x8000008,
217           .fstr = "arm_ac57::INST_RETIRED:k=1:u=1:hv=0",
218         },
219         { SRC_LINE,
220           .name = "arm_ac53::CPU_CYCLES",
221           .ret  = PFM_SUCCESS,
222           .count = 1,
223           .codes[0] = 0x8000011,
224           .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0",
225         },
226         { SRC_LINE,
227           .name = "arm_ac53::CPU_CYCLES:k",
228           .ret  = PFM_SUCCESS,
229           .count = 1,
230           .codes[0] = 0x88000011,
231           .fstr = "arm_ac53::CPU_CYCLES:k=1:u=0:hv=0",
232         },
233         { SRC_LINE,
234           .name = "arm_ac53::CPU_CYCLES:k:u",
235           .ret  = PFM_SUCCESS,
236           .count = 1,
237           .codes[0] = 0x8000011,
238           .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0",
239         },
240         { SRC_LINE,
241           .name = "arm_ac53::INST_RETIRED",
242           .ret  = PFM_SUCCESS,
243           .count = 1,
244           .codes[0] = 0x8000008,
245           .fstr = "arm_ac53::INST_RETIRED:k=1:u=1:hv=0",
246         },
247         { SRC_LINE,
248           .name = "arm_ac53::LD_RETIRED",
249           .ret  = PFM_SUCCESS,
250           .count = 1,
251           .codes[0] = 0x8000006,
252           .fstr = "arm_ac53::LD_RETIRED:k=1:u=1:hv=0",
253         },
254         { SRC_LINE,
255           .name = "arm_ac53::ST_RETIRED",
256           .ret  = PFM_SUCCESS,
257           .count = 1,
258           .codes[0] = 0x8000007,
259           .fstr = "arm_ac53::ST_RETIRED:k=1:u=1:hv=0",
260         },
261 };
262 #define NUM_TEST_EVENTS (int)(sizeof(arm_test_events)/sizeof(test_event_t))
263
264 static int check_test_events(FILE *fp)
265 {
266         const test_event_t *e;
267         char *fstr;
268         uint64_t *codes;
269         int count, i, j;
270         int ret, errors = 0;
271
272         for (i = 0, e = arm_test_events; i < NUM_TEST_EVENTS; i++, e++) {
273                 codes = NULL;
274                 count = 0;
275                 fstr = NULL;
276                 ret = pfm_get_event_encoding(e->name, PFM_PLM0 | PFM_PLM3, &fstr, NULL, &codes, &count);
277                 if (ret != e->ret) {
278                         fprintf(fp,"Event%d %s, ret=%s(%d) expected %s(%d)\n", i, e->name, pfm_strerror(ret), ret, pfm_strerror(e->ret), e->ret);
279                         errors++;
280                 } else {
281                         if (ret != PFM_SUCCESS) {
282                                 if (fstr) {
283                                         fprintf(fp,"Event%d %s, expected fstr NULL but it is not\n", i, e->name);
284                                         errors++;
285                                 }
286                                 if (count != 0) {
287                                         fprintf(fp,"Event%d %s, expected count=0 instead of %d\n", i, e->name, count);
288                                         errors++;
289                                 }
290                                 if (codes) {
291                                         fprintf(fp,"Event%d %s, expected codes[] NULL but it is not\n", i, e->name);
292                                         errors++;
293                                 }
294                         } else {
295                                 if (count != e->count) {
296                                         fprintf(fp,"Event%d %s, count=%d expected %d\n", i, e->name, count, e->count);
297                                         errors++;
298                                 }
299                                 for (j=0; j < count; j++) {
300                                         if (codes[j] != e->codes[j]) {
301                                                 fprintf(fp,"Event%d %s, codes[%d]=%#"PRIx64" expected %#"PRIx64"\n", i, e->name, j, codes[j], e->codes[j]);
302                                                 errors++;
303                                         }
304                                 }
305                                 if (e->fstr && strcmp(fstr, e->fstr)) {
306                                         fprintf(fp,"Event%d %s, fstr=%s expected %s\n", i, e->name, fstr, e->fstr);
307                                         errors++;
308                                 }
309                         }
310                 }
311                 if (codes)
312                         free(codes);
313                 if (fstr)
314                         free(fstr);
315         }
316         printf("\t %d ARM events: %d errors\n", i, errors);
317         return errors;
318 }
319
320 int
321 validate_arch(FILE *fp)
322 {
323         return check_test_events(fp);
324 }