parlib: Expand our printf hacks
[akaros.git] / user / perfmon / tests / validate_power.c
1 /*
2  * validate_power.c - validate PowerPC event tables + encodings
3  *
4  * Copyright (c) 2012 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
38 #define SRC_LINE        .line = __LINE__
39
40 typedef struct {
41         const char *name;
42         const char *fstr;
43         uint64_t codes[MAX_ENCODING];
44         int ret, count, line;
45 } test_event_t;
46
47 static const test_event_t ppc_test_events[]={
48         { SRC_LINE,
49           .name = "ppc970::PM_CYC",
50           .ret  = PFM_SUCCESS,
51           .count = 1,
52           .codes[0] = 0x7,
53           .fstr = "ppc970::PM_CYC",
54         },
55         { SRC_LINE,
56           .name = "ppc970::PM_INST_DISP",
57           .ret  = PFM_SUCCESS,
58           .count = 1,
59           .codes[0] = 0x320,
60           .fstr = "ppc970::PM_INST_DISP",
61         },
62         { SRC_LINE,
63           .name = "ppc970mp::PM_CYC",
64           .ret  = PFM_SUCCESS,
65           .count = 1,
66           .codes[0] = 0x7,
67           .fstr = "ppc970mp::PM_CYC",
68         },
69         { SRC_LINE,
70           .name = "ppc970mp::PM_INST_DISP",
71           .ret  = PFM_SUCCESS,
72           .count = 1,
73           .codes[0] = 0x320,
74           .fstr = "ppc970mp::PM_INST_DISP",
75         },
76         { SRC_LINE,
77           .name = "power4::PM_CYC",
78           .ret  = PFM_SUCCESS,
79           .count = 1,
80           .codes[0] = 0x7,
81           .fstr = "power4::PM_CYC",
82         },
83         { SRC_LINE,
84           .name = "power4::PM_INST_DISP",
85           .ret  = PFM_SUCCESS,
86           .count = 1,
87           .codes[0] = 0x221,
88           .fstr = "power4::PM_INST_DISP",
89         },
90         { SRC_LINE,
91           .name = "power5::PM_CYC",
92           .ret  = PFM_SUCCESS,
93           .count = 1,
94           .codes[0] = 0xf,
95           .fstr = "power5::PM_CYC",
96         },
97         { SRC_LINE,
98           .name = "power5::PM_INST_DISP",
99           .ret  = PFM_SUCCESS,
100           .count = 1,
101           .codes[0] = 0x300009,
102           .fstr = "power5::PM_INST_DISP",
103         },
104         { SRC_LINE,
105           .name = "power5p::PM_CYC",
106           .ret  = PFM_SUCCESS,
107           .count = 1,
108           .codes[0] = 0xf,
109           .fstr = "power5p::PM_CYC",
110         },
111         { SRC_LINE,
112           .name = "power5p::PM_INST_DISP",
113           .ret  = PFM_SUCCESS,
114           .count = 1,
115           .codes[0] = 0x300009,
116           .fstr = "power5p::PM_INST_DISP",
117         },
118         { SRC_LINE,
119           .name = "power6::PM_INST_CMPL",
120           .ret  = PFM_SUCCESS,
121           .count = 1,
122           .codes[0] = 0x2,
123           .fstr = "power6::PM_INST_CMPL",
124         },
125         { SRC_LINE,
126           .name = "power6::PM_THRD_CONC_RUN_INST",
127           .ret  = PFM_SUCCESS,
128           .count = 1,
129           .codes[0] = 0x300026,
130           .fstr = "power6::PM_THRD_CONC_RUN_INST",
131         },
132         { SRC_LINE,
133           .name = "power7::PM_CYC",
134           .ret  = PFM_SUCCESS,
135           .count = 1,
136           .codes[0] = 0x1e,
137           .fstr = "power7::PM_CYC",
138         },
139         { SRC_LINE,
140           .name = "power7::PM_INST_DISP",
141           .ret  = PFM_SUCCESS,
142           .count = 1,
143           .codes[0] = 0x200f2,
144           .fstr = "power7::PM_INST_DISP",
145         },
146         { SRC_LINE,
147           .name = "power8::PM_L1MISS_LAT_EXC_1024",
148           .ret  = PFM_SUCCESS,
149           .count = 1,
150           .codes[0] = 0x67200301eaull,
151           .fstr = "power8::PM_L1MISS_LAT_EXC_1024",
152         },
153         { SRC_LINE,
154           .name = "power8::PM_RC_LIFETIME_EXC_32",
155           .ret  = PFM_SUCCESS,
156           .count = 1,
157           .codes[0] = 0xde200201e6ull,
158           .fstr = "power8::PM_RC_LIFETIME_EXC_32",
159         },
160 };
161 #define NUM_TEST_EVENTS (int)(sizeof(ppc_test_events)/sizeof(test_event_t))
162
163 static int check_test_events(FILE *fp)
164 {
165         const test_event_t *e;
166         char *fstr;
167         uint64_t *codes;
168         int count, i, j;
169         int ret, errors = 0;
170
171         for (i = 0, e = ppc_test_events; i < NUM_TEST_EVENTS; i++, e++) {
172                 codes = NULL;
173                 count = 0;
174                 fstr = NULL;
175                 ret = pfm_get_event_encoding(e->name, PFM_PLM0 | PFM_PLM3, &fstr, NULL, &codes, &count);
176                 if (ret != e->ret) {
177                         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);
178                         errors++;
179                 } else {
180                         if (ret != PFM_SUCCESS) {
181                                 if (fstr) {
182                                         fprintf(fp,"Event%d %s, expected fstr NULL but it is not\n", i, e->name);
183                                         errors++;
184                                 }
185                                 if (count != 0) {
186                                         fprintf(fp,"Event%d %s, expected count=0 instead of %d\n", i, e->name, count);
187                                         errors++;
188                                 }
189                                 if (codes) {
190                                         fprintf(fp,"Event%d %s, expected codes[] NULL but it is not\n", i, e->name);
191                                         errors++;
192                                 }
193                         } else {
194                                 if (count != e->count) {
195                                         fprintf(fp,"Event%d %s, count=%d expected %d\n", i, e->name, count, e->count);
196                                         errors++;
197                                 }
198                                 for (j=0; j < count; j++) {
199                                         if (codes[j] != e->codes[j]) {
200                                                 fprintf(fp,"Event%d %s, codes[%d]=%#"PRIx64" expected %#"PRIx64"\n", i, e->name, j, codes[j], e->codes[j]);
201                                                 errors++;
202                                         }
203                                 }
204                                 if (e->fstr && strcmp(fstr, e->fstr)) {
205                                         fprintf(fp,"Event%d %s, fstr=%s expected %s\n", i, e->name, fstr, e->fstr);
206                                         errors++;
207                                 }
208                         }
209                 }
210                 if (codes)
211                         free(codes);
212                 if (fstr)
213                         free(fstr);
214         }
215         printf("\t %d PowerPC events: %d errors\n", i, errors);
216         return errors;
217 }
218
219 int
220 validate_arch(FILE *fp)
221 {
222         return check_test_events(fp);
223 }