radix: Implement radix_tree_destroy()
[akaros.git] / user / perfmon / tests / validate_arm64.c
1 /*
2  * validate_arm64.c - validate ARM64 event tables + encodings
3  *
4  * Copyright (c) 2014 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 arm64_test_events[]={
47         { SRC_LINE,
48           .name = "arm_ac57::CPU_CYCLES",
49           .ret  = PFM_SUCCESS,
50           .count = 1,
51           .codes[0] = 0x8000011,
52           .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0",
53         },
54         { SRC_LINE,
55           .name = "arm_ac57::CPU_CYCLES:k",
56           .ret  = PFM_SUCCESS,
57           .count = 1,
58           .codes[0] = 0x88000011,
59           .fstr = "arm_ac57::CPU_CYCLES:k=1:u=0:hv=0",
60         },
61         { SRC_LINE,
62           .name = "arm_ac57::CPU_CYCLES:k:u",
63           .ret  = PFM_SUCCESS,
64           .count = 1,
65           .codes[0] = 0x8000011,
66           .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0",
67         },
68         { SRC_LINE,
69           .name = "arm_ac57::INST_RETIRED",
70           .ret  = PFM_SUCCESS,
71           .count = 1,
72           .codes[0] = 0x8000008,
73           .fstr = "arm_ac57::INST_RETIRED:k=1:u=1:hv=0",
74         },
75         { SRC_LINE,
76           .name = "arm_ac53::CPU_CYCLES",
77           .ret  = PFM_SUCCESS,
78           .count = 1,
79           .codes[0] = 0x8000011,
80           .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0",
81         },
82         { SRC_LINE,
83           .name = "arm_ac53::CPU_CYCLES:k",
84           .ret  = PFM_SUCCESS,
85           .count = 1,
86           .codes[0] = 0x88000011,
87           .fstr = "arm_ac53::CPU_CYCLES:k=1:u=0:hv=0",
88         },
89         { SRC_LINE,
90           .name = "arm_ac53::CPU_CYCLES:k:u",
91           .ret  = PFM_SUCCESS,
92           .count = 1,
93           .codes[0] = 0x8000011,
94           .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0",
95         },
96         { SRC_LINE,
97           .name = "arm_ac53::INST_RETIRED",
98           .ret  = PFM_SUCCESS,
99           .count = 1,
100           .codes[0] = 0x8000008,
101           .fstr = "arm_ac53::INST_RETIRED:k=1:u=1:hv=0",
102         },
103         { SRC_LINE,
104           .name = "arm_ac53::LD_RETIRED",
105           .ret  = PFM_SUCCESS,
106           .count = 1,
107           .codes[0] = 0x8000006,
108           .fstr = "arm_ac53::LD_RETIRED:k=1:u=1:hv=0",
109         },
110         { SRC_LINE,
111           .name = "arm_ac53::ST_RETIRED",
112           .ret  = PFM_SUCCESS,
113           .count = 1,
114           .codes[0] = 0x8000007,
115           .fstr = "arm_ac53::ST_RETIRED:k=1:u=1:hv=0",
116         },
117         { SRC_LINE,
118           .name = "arm_xgene::CPU_CYCLES",
119           .ret  = PFM_SUCCESS,
120           .count = 1,
121           .codes[0] = 0x8000011,
122           .fstr = "arm_xgene::CPU_CYCLES:k=1:u=1:hv=0",
123         },
124         { SRC_LINE,
125           .name = "arm_xgene::CPU_CYCLES:k",
126           .ret  = PFM_SUCCESS,
127           .count = 1,
128           .codes[0] = 0x88000011,
129           .fstr = "arm_xgene::CPU_CYCLES:k=1:u=0:hv=0",
130         },
131         { SRC_LINE,
132           .name = "arm_xgene::CPU_CYCLES:k:u",
133           .ret  = PFM_SUCCESS,
134           .count = 1,
135           .codes[0] = 0x8000011,
136           .fstr = "arm_xgene::CPU_CYCLES:k=1:u=1:hv=0",
137         },
138         { SRC_LINE,
139           .name = "arm_xgene::INST_RETIRED",
140           .ret  = PFM_SUCCESS,
141           .count = 1,
142           .codes[0] = 0x8000008,
143           .fstr = "arm_xgene::INST_RETIRED:k=1:u=1:hv=0",
144         },
145 };
146 #define NUM_TEST_EVENTS (int)(sizeof(arm64_test_events)/sizeof(test_event_t))
147
148 static int check_test_events(FILE *fp)
149 {
150         const test_event_t *e;
151         char *fstr;
152         uint64_t *codes;
153         int count, i, j;
154         int ret, errors = 0;
155
156         for (i = 0, e = arm64_test_events; i < NUM_TEST_EVENTS; i++, e++) {
157                 codes = NULL;
158                 count = 0;
159                 fstr = NULL;
160                 ret = pfm_get_event_encoding(e->name, PFM_PLM0 | PFM_PLM3, &fstr, NULL, &codes, &count);
161                 if (ret != e->ret) {
162                         fprintf(fp,"Line %d, Event%d %s, ret=%s(%d) expected %s(%d)\n", e->line, i, e->name, pfm_strerror(ret), ret, pfm_strerror(e->ret), e->ret);
163                         errors++;
164                 } else {
165                         if (ret != PFM_SUCCESS) {
166                                 if (fstr) {
167                                         fprintf(fp,"Line %d, Event%d %s, expected fstr NULL but it is not\n", e->line, i, e->name);
168                                         errors++;
169                                 }
170                                 if (count != 0) {
171                                         fprintf(fp,"Line %d, Event%d %s, expected count=0 instead of %d\n", e->line, i, e->name, count);
172                                         errors++;
173                                 }
174                                 if (codes) {
175                                         fprintf(fp,"Line %d, Event%d %s, expected codes[] NULL but it is not\n", e->line, i, e->name);
176                                         errors++;
177                                 }
178                         } else {
179                                 if (count != e->count) {
180                                         fprintf(fp,"Line %d, Event%d %s, count=%d expected %d\n", e->line, i, e->name, count, e->count);
181                                         errors++;
182                                 }
183                                 for (j=0; j < count; j++) {
184                                         if (codes[j] != e->codes[j]) {
185                                                 fprintf(fp,"Line %d, Event%d %s, codes[%d]=%#"PRIx64" expected %#"PRIx64"\n", e->line, i, e->name, j, codes[j], e->codes[j]);
186                                                 errors++;
187                                         }
188                                 }
189                                 if (e->fstr && strcmp(fstr, e->fstr)) {
190                                         fprintf(fp,"Line %d, Event%d %s, fstr=%s expected %s\n", e->line, i, e->name, fstr, e->fstr);
191                                         errors++;
192                                 }
193                         }
194                 }
195                 if (codes)
196                         free(codes);
197                 if (fstr)
198                         free(fstr);
199         }
200         printf("\t %d ARM64 events: %d errors\n", i, errors);
201         return errors;
202 }
203
204 int
205 validate_arch(FILE *fp)
206 {
207         return check_test_events(fp);
208 }