Use const for readstr() and readmem() source args
[akaros.git] / user / perfmon / pfmlib_priv.h
1 /*
2  * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
3  * Contributed by Stephane Eranian <eranian@hpl.hp.com>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
17  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
20  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * This file is part of libpfm, a performance monitoring support library for
23  * applications on Linux.
24  */
25 #ifndef __PFMLIB_PRIV_H__
26 #define __PFMLIB_PRIV_H__
27 #include <perfmon/pfmlib.h>
28 #include <string.h>
29
30 #define PFM_PLM_ALL (PFM_PLM0|PFM_PLM1|PFM_PLM2|PFM_PLM3|PFM_PLMH)
31
32 #define PFMLIB_ATTR_DELIM       ':'     /* event attribute delimiter */
33 #define PFMLIB_PMU_DELIM        "::"    /* pmu to event delimiter */
34 #define PFMLIB_EVENT_DELIM      ','     /* event to event delimiter */
35
36 #define PFM_ATTR_I(y, d) { .name = (y), .type = PFM_ATTR_MOD_INTEGER, .desc = (d) }
37 #define PFM_ATTR_B(y, d) { .name = (y), .type = PFM_ATTR_MOD_BOOL, .desc = (d) }
38 #define PFM_ATTR_SKIP    { .name = "" } /* entry not populated (skipped) */
39 #define PFM_ATTR_NULL   { .name = NULL }
40
41 #define PFMLIB_EVT_MAX_NAME_LEN 256
42
43 /*
44  * event identifier encoding:
45  * bit 00-20 : event table specific index (2097152 possibilities)
46  * bit 21-30 : PMU identifier (1024 possibilities)
47  * bit 31    : reserved (to distinguish from a negative error code)
48  */
49 #define PFMLIB_PMU_SHIFT        21
50 #define PFMLIB_PMU_MASK         0x3ff /* must fit PFM_PMU_MAX */
51 #define PFMLIB_PMU_PIDX_MASK    ((1<< PFMLIB_PMU_SHIFT)-1)
52
53 typedef struct {
54         const char      *name;  /* name */
55         const char      *desc;  /* description */
56         pfm_attr_t      type;   /* used to validate value (if any) */
57 } pfmlib_attr_desc_t;
58
59 /*
60  * attribute description passed to model-specific layer
61  */
62 typedef struct {
63         int     id;                     /* attribute index */
64         union {
65                 uint64_t        ival;   /* integer value (incl. bool) */
66                 char            *sval;  /* string */
67         };
68 } pfmlib_attr_t;
69
70 /*
71  * must be big enough to hold all possible priv level attributes
72  */
73 #define PFMLIB_MAX_ATTRS        64 /* max attributes per event desc */
74 #define PFMLIB_MAX_ENCODING     4  /* max encoding length */
75
76 /*
77  * we add one entry to hold any raw umask users may specify
78  * the last entry in pattrs[] hold that raw umask info
79  */
80 #define PFMLIB_MAX_PATTRS       (PFMLIB_MAX_ATTRS+1)
81
82 struct pfmlib_pmu;
83 typedef struct {
84         struct pfmlib_pmu       *pmu;                           /* pmu */
85         int                     dfl_plm;                        /* default priv level mask */
86         int                     event;                          /* pidx */
87         int                     npattrs;                        /* number of attrs in pattrs[] */
88         int                     nattrs;                         /* number of attrs in attrs[] */
89         pfm_os_t                osid;                           /* OS API requested */
90         int                     count;                          /* number of entries in codes[] */
91         pfmlib_attr_t           attrs[PFMLIB_MAX_ATTRS];        /* list of requested attributes */
92
93         pfm_event_attr_info_t   *pattrs;                        /* list of possible attributes */
94         char                    fstr[PFMLIB_EVT_MAX_NAME_LEN];  /* fully qualified event string */
95         uint64_t                codes[PFMLIB_MAX_ENCODING];     /* event encoding */
96         void                    *os_data;
97 } pfmlib_event_desc_t;
98 #define modx(atdesc, a, z)      (atdesc[(a)].z)
99 #define attr(e, k)              ((e)->pattrs + (e)->attrs[k].id)
100
101 typedef struct pfmlib_pmu {
102         const char      *desc;                  /* PMU description */
103         const char      *name;                  /* pmu short name */
104         const char      *perf_name;             /* perf_event pmu name (optional) */
105         pfm_pmu_t       pmu;                    /* PMU model */
106         int             pme_count;              /* number of events */
107         int             max_encoding;           /* max number of uint64_t to encode an event */
108         int             flags;                  /* 16 LSB: common, 16 MSB: arch spec*/
109         int             pmu_rev;                /* PMU model specific revision */
110         int             num_cntrs;              /* number of generic counters */
111         int             num_fixed_cntrs;        /* number of fixed counters */
112         int             supported_plm;          /* supported priv levels */
113
114         pfm_pmu_type_t  type;                   /* PMU type */
115         const void      *pe;                    /* pointer to event table */
116
117         const pfmlib_attr_desc_t *atdesc;       /* pointer to attrs table */
118
119         const int       cpu_family;             /* cpu family number for detection */
120         const int       *cpu_models;            /* cpu model numbers for detection (zero terminated) */
121
122         int              (*pmu_detect)(void *this);
123         int              (*pmu_init)(void *this);       /* optional */
124         void             (*pmu_terminate)(void *this); /* optional */
125         int              (*get_event_first)(void *this);
126         int              (*get_event_next)(void *this, int pidx);
127         int              (*get_event_info)(void *this, int pidx, pfm_event_info_t *info);
128         unsigned int     (*get_event_nattrs)(void *this, int pidx);
129         int              (*event_is_valid)(void *this, int pidx);
130         int              (*can_auto_encode)(void *this, int pidx, int uidx);
131
132         int              (*get_event_attr_info)(void *this, int pidx, int umask_idx, pfm_event_attr_info_t *info);
133         int              (*get_event_encoding[PFM_OS_MAX])(void *this, pfmlib_event_desc_t *e);
134
135         void             (*validate_pattrs[PFM_OS_MAX])(void *this, pfmlib_event_desc_t *e);
136         int              (*os_detect[PFM_OS_MAX])(void *this);
137         int              (*validate_table)(void *this, FILE *fp);
138         /*
139          * optional callbacks
140          */
141         int              (*get_num_events)(void *this);
142         void             (*display_reg)(void *this, pfmlib_event_desc_t *e, void *val);
143         int              (*match_event)(void *this, pfmlib_event_desc_t *d, const char *e, const char *s);
144 } pfmlib_pmu_t;
145
146 typedef struct {
147         const char                      *name;
148         const pfmlib_attr_desc_t        *atdesc;
149         pfm_os_t                        id;
150         int                             flags;
151         int                             (*detect)(void *this);
152         int                             (*get_os_attr_info)(void *this, pfmlib_event_desc_t *e);
153         int                             (*get_os_nattrs)(void *this, pfmlib_event_desc_t *e);
154         int                             (*encode)(void *this, const char *str, int dfl_plm, void *args);
155 } pfmlib_os_t;
156
157 #define PFMLIB_OS_FL_ACTIVATED  0x1     /* OS layer detected */
158
159 /*
160  * pfmlib_pmu_t common flags (LSB 16 bits)
161  */
162 #define PFMLIB_PMU_FL_INIT      0x1     /* PMU initialized correctly */
163 #define PFMLIB_PMU_FL_ACTIVE    0x2     /* PMU is initialized + detected on host */
164 #define PFMLIB_PMU_FL_RAW_UMASK 0x4     /* PMU supports PFM_ATTR_RAW_UMASKS */
165 #define PFMLIB_PMU_FL_ARCH_DFL  0x8     /* PMU is arch default */
166 #define PFMLIB_PMU_FL_NO_SMPL   0x10    /* PMU does not support sampling */
167
168 typedef struct {
169         int     initdone;
170         int     verbose;
171         int     debug;
172         int     inactive;
173         char    *forced_pmu;
174         char    *blacklist_pmus;
175         FILE    *fp;    /* verbose and debug file descriptor, default stderr or PFMLIB_DEBUG_STDOUT */
176 } pfmlib_config_t;      
177
178 #define PFMLIB_INITIALIZED()    (pfm_cfg.initdone)
179
180 extern pfmlib_config_t pfm_cfg;
181
182 extern void __pfm_vbprintf(const char *fmt,...);
183 extern void __pfm_dbprintf(const char *fmt,...);
184 extern void pfmlib_strconcat(char *str, size_t max, const char *fmt, ...);
185 extern int pfmlib_getl(char **buffer, size_t *len, FILE *fp);
186 extern void pfmlib_compact_pattrs(pfmlib_event_desc_t *e, int i);
187 #define evt_strcat(str, fmt, a...) pfmlib_strconcat(str, PFMLIB_EVT_MAX_NAME_LEN, fmt, a)
188
189 extern int pfmlib_parse_event(const char *event, pfmlib_event_desc_t *d);
190 extern int pfmlib_build_fstr(pfmlib_event_desc_t *e, char **fstr);
191 extern void pfmlib_sort_attr(pfmlib_event_desc_t *e);
192 extern pfmlib_pmu_t * pfmlib_get_pmu_by_type(pfm_pmu_type_t t);
193 extern void pfmlib_release_event(pfmlib_event_desc_t *e);
194
195 extern size_t pfmlib_check_struct(void *st, size_t usz, size_t refsz, size_t sz);
196
197 #ifdef CONFIG_PFMLIB_DEBUG
198 #define DPRINT(fmt, a...) \
199         do { \
200                 __pfm_dbprintf("%s (%s.%d): " fmt, __FILE__, __func__, __LINE__, ## a); \
201         } while (0)
202 #else
203 #define DPRINT(fmt, a...) do { } while (0)
204 #endif
205
206 extern pfmlib_pmu_t montecito_support;
207 extern pfmlib_pmu_t itanium2_support;
208 extern pfmlib_pmu_t itanium_support;
209 extern pfmlib_pmu_t generic_ia64_support;
210 extern pfmlib_pmu_t amd64_k7_support;
211 extern pfmlib_pmu_t amd64_k8_revb_support;
212 extern pfmlib_pmu_t amd64_k8_revc_support;
213 extern pfmlib_pmu_t amd64_k8_revd_support;
214 extern pfmlib_pmu_t amd64_k8_reve_support;
215 extern pfmlib_pmu_t amd64_k8_revf_support;
216 extern pfmlib_pmu_t amd64_k8_revg_support;
217 extern pfmlib_pmu_t amd64_fam10h_barcelona_support;
218 extern pfmlib_pmu_t amd64_fam10h_shanghai_support;
219 extern pfmlib_pmu_t amd64_fam10h_istanbul_support;
220 extern pfmlib_pmu_t amd64_fam11h_turion_support;
221 extern pfmlib_pmu_t amd64_fam12h_llano_support;
222 extern pfmlib_pmu_t amd64_fam14h_bobcat_support;
223 extern pfmlib_pmu_t amd64_fam15h_interlagos_support;
224 extern pfmlib_pmu_t amd64_fam15h_nb_support;
225 extern pfmlib_pmu_t intel_p6_support;
226 extern pfmlib_pmu_t intel_ppro_support;
227 extern pfmlib_pmu_t intel_pii_support;
228 extern pfmlib_pmu_t intel_pm_support;
229 extern pfmlib_pmu_t sicortex_support;
230 extern pfmlib_pmu_t netburst_support;
231 extern pfmlib_pmu_t netburst_p_support;
232 extern pfmlib_pmu_t intel_coreduo_support;
233 extern pfmlib_pmu_t intel_core_support;
234 extern pfmlib_pmu_t intel_x86_arch_support;
235 extern pfmlib_pmu_t intel_atom_support;
236 extern pfmlib_pmu_t intel_nhm_support;
237 extern pfmlib_pmu_t intel_nhm_ex_support;
238 extern pfmlib_pmu_t intel_nhm_unc_support;
239 extern pfmlib_pmu_t intel_snb_support;
240 extern pfmlib_pmu_t intel_snb_unc_cbo0_support;
241 extern pfmlib_pmu_t intel_snb_unc_cbo1_support;
242 extern pfmlib_pmu_t intel_snb_unc_cbo2_support;
243 extern pfmlib_pmu_t intel_snb_unc_cbo3_support;
244 extern pfmlib_pmu_t intel_snb_ep_support;
245 extern pfmlib_pmu_t intel_ivb_support;
246 extern pfmlib_pmu_t intel_ivb_unc_cbo0_support;
247 extern pfmlib_pmu_t intel_ivb_unc_cbo1_support;
248 extern pfmlib_pmu_t intel_ivb_unc_cbo2_support;
249 extern pfmlib_pmu_t intel_ivb_unc_cbo3_support;
250 extern pfmlib_pmu_t intel_ivb_ep_support;
251 extern pfmlib_pmu_t intel_hsw_support;
252 extern pfmlib_pmu_t intel_hsw_ep_support;
253 extern pfmlib_pmu_t intel_bdw_support;
254 extern pfmlib_pmu_t intel_rapl_support;
255 extern pfmlib_pmu_t intel_snbep_unc_cb0_support;
256 extern pfmlib_pmu_t intel_snbep_unc_cb1_support;
257 extern pfmlib_pmu_t intel_snbep_unc_cb2_support;
258 extern pfmlib_pmu_t intel_snbep_unc_cb3_support;
259 extern pfmlib_pmu_t intel_snbep_unc_cb4_support;
260 extern pfmlib_pmu_t intel_snbep_unc_cb5_support;
261 extern pfmlib_pmu_t intel_snbep_unc_cb6_support;
262 extern pfmlib_pmu_t intel_snbep_unc_cb7_support;
263 extern pfmlib_pmu_t intel_snbep_unc_ha_support;
264 extern pfmlib_pmu_t intel_snbep_unc_imc0_support;
265 extern pfmlib_pmu_t intel_snbep_unc_imc1_support;
266 extern pfmlib_pmu_t intel_snbep_unc_imc2_support;
267 extern pfmlib_pmu_t intel_snbep_unc_imc3_support;
268 extern pfmlib_pmu_t intel_snbep_unc_pcu_support;
269 extern pfmlib_pmu_t intel_snbep_unc_qpi0_support;
270 extern pfmlib_pmu_t intel_snbep_unc_qpi1_support;
271 extern pfmlib_pmu_t intel_snbep_unc_ubo_support;
272 extern pfmlib_pmu_t intel_snbep_unc_r2pcie_support;
273 extern pfmlib_pmu_t intel_snbep_unc_r3qpi0_support;
274 extern pfmlib_pmu_t intel_snbep_unc_r3qpi1_support;
275 extern pfmlib_pmu_t intel_ivbep_unc_cb0_support;
276 extern pfmlib_pmu_t intel_ivbep_unc_cb1_support;
277 extern pfmlib_pmu_t intel_ivbep_unc_cb2_support;
278 extern pfmlib_pmu_t intel_ivbep_unc_cb3_support;
279 extern pfmlib_pmu_t intel_ivbep_unc_cb4_support;
280 extern pfmlib_pmu_t intel_ivbep_unc_cb5_support;
281 extern pfmlib_pmu_t intel_ivbep_unc_cb6_support;
282 extern pfmlib_pmu_t intel_ivbep_unc_cb7_support;
283 extern pfmlib_pmu_t intel_ivbep_unc_cb8_support;
284 extern pfmlib_pmu_t intel_ivbep_unc_cb9_support;
285 extern pfmlib_pmu_t intel_ivbep_unc_cb10_support;
286 extern pfmlib_pmu_t intel_ivbep_unc_cb11_support;
287 extern pfmlib_pmu_t intel_ivbep_unc_cb12_support;
288 extern pfmlib_pmu_t intel_ivbep_unc_cb13_support;
289 extern pfmlib_pmu_t intel_ivbep_unc_cb14_support;
290 extern pfmlib_pmu_t intel_ivbep_unc_ha0_support;
291 extern pfmlib_pmu_t intel_ivbep_unc_ha1_support;
292 extern pfmlib_pmu_t intel_ivbep_unc_imc0_support;
293 extern pfmlib_pmu_t intel_ivbep_unc_imc1_support;
294 extern pfmlib_pmu_t intel_ivbep_unc_imc2_support;
295 extern pfmlib_pmu_t intel_ivbep_unc_imc3_support;
296 extern pfmlib_pmu_t intel_ivbep_unc_imc4_support;
297 extern pfmlib_pmu_t intel_ivbep_unc_imc5_support;
298 extern pfmlib_pmu_t intel_ivbep_unc_imc6_support;
299 extern pfmlib_pmu_t intel_ivbep_unc_imc7_support;
300 extern pfmlib_pmu_t intel_ivbep_unc_pcu_support;
301 extern pfmlib_pmu_t intel_ivbep_unc_qpi0_support;
302 extern pfmlib_pmu_t intel_ivbep_unc_qpi1_support;
303 extern pfmlib_pmu_t intel_ivbep_unc_qpi2_support;
304 extern pfmlib_pmu_t intel_ivbep_unc_ubo_support;
305 extern pfmlib_pmu_t intel_ivbep_unc_r2pcie_support;
306 extern pfmlib_pmu_t intel_ivbep_unc_r3qpi0_support;
307 extern pfmlib_pmu_t intel_ivbep_unc_r3qpi1_support;
308 extern pfmlib_pmu_t intel_ivbep_unc_r3qpi2_support;
309 extern pfmlib_pmu_t intel_ivbep_unc_irp_support;
310 extern pfmlib_pmu_t intel_knc_support;
311 extern pfmlib_pmu_t intel_slm_support;
312 extern pfmlib_pmu_t power4_support;
313 extern pfmlib_pmu_t ppc970_support;
314 extern pfmlib_pmu_t ppc970mp_support;
315 extern pfmlib_pmu_t power5_support;
316 extern pfmlib_pmu_t power5p_support;
317 extern pfmlib_pmu_t power6_support;
318 extern pfmlib_pmu_t power7_support;
319 extern pfmlib_pmu_t power8_support;
320 extern pfmlib_pmu_t torrent_support;
321 extern pfmlib_pmu_t sparc_support;
322 extern pfmlib_pmu_t sparc_ultra12_support;
323 extern pfmlib_pmu_t sparc_ultra3_support;
324 extern pfmlib_pmu_t sparc_ultra3i_support;
325 extern pfmlib_pmu_t sparc_ultra3plus_support;
326 extern pfmlib_pmu_t sparc_ultra4plus_support;
327 extern pfmlib_pmu_t sparc_niagara1_support;
328 extern pfmlib_pmu_t sparc_niagara2_support;
329 extern pfmlib_pmu_t cell_support;
330 extern pfmlib_pmu_t perf_event_support;
331 extern pfmlib_pmu_t perf_event_raw_support;
332 extern pfmlib_pmu_t intel_wsm_sp_support;
333 extern pfmlib_pmu_t intel_wsm_dp_support;
334 extern pfmlib_pmu_t intel_wsm_unc_support;
335 extern pfmlib_pmu_t arm_cortex_a7_support;
336 extern pfmlib_pmu_t arm_cortex_a8_support;
337 extern pfmlib_pmu_t arm_cortex_a9_support;
338 extern pfmlib_pmu_t arm_cortex_a15_support;
339 extern pfmlib_pmu_t arm_1176_support;
340 extern pfmlib_pmu_t arm_qcom_krait_support;
341 extern pfmlib_pmu_t arm_cortex_a57_support;
342 extern pfmlib_pmu_t arm_cortex_a53_support;
343 extern pfmlib_pmu_t arm_xgene_support;
344 extern pfmlib_pmu_t mips_74k_support;
345 extern pfmlib_pmu_t s390x_cpum_cf_support;
346 extern pfmlib_pmu_t s390x_cpum_sf_support;
347
348 extern pfmlib_os_t *pfmlib_os;
349 extern pfmlib_os_t pfmlib_os_perf;
350 extern pfmlib_os_t pfmlib_os_perf_ext;
351
352 extern char *pfmlib_forced_pmu;
353
354 #define this_pe(t)              (((pfmlib_pmu_t *)t)->pe)
355 #define this_atdesc(t)          (((pfmlib_pmu_t *)t)->atdesc)
356
357 #define LIBPFM_ARRAY_SIZE(a) (sizeof(a) / sizeof(typeof(*(a))))
358 /*
359  * population count (number of bits set)
360  */
361 static inline int
362 pfmlib_popcnt(unsigned long v)
363 {
364         int sum = 0;
365
366         for(; v ; v >>=1) {
367                 if (v & 0x1) sum++;
368         }
369         return sum;
370 }
371
372 /*
373  * find next bit set
374  */
375 static inline size_t
376 pfmlib_fnb(unsigned long value, size_t nbits, int p)
377 {
378         unsigned long m;
379         size_t i;
380
381         for(i=p; i < nbits; i++) {
382                 m = 1 << i;
383                 if (value & m)
384                         return i;
385         }
386         return i;
387 }
388
389 /*
390  * PMU + internal idx -> external opaque idx
391  */
392 static inline int
393 pfmlib_pidx2idx(pfmlib_pmu_t *pmu, int pidx)
394 {
395         int idx;
396
397         idx = pmu->pmu << PFMLIB_PMU_SHIFT;
398         idx |= pidx;
399
400         return  idx;
401 }
402
403 #define pfmlib_for_each_bit(x, m) \
404         for((x) = pfmlib_fnb((m), (sizeof(m)<<3), 0); (x) < (sizeof(m)<<3); (x) = pfmlib_fnb((m), (sizeof(m)<<3), (x)+1))
405
406 #ifdef __linux__
407
408 #define PFMLIB_VALID_PERF_PATTRS(f)  \
409         .validate_pattrs[PFM_OS_PERF_EVENT] = f, \
410         .validate_pattrs[PFM_OS_PERF_EVENT_EXT] = f
411
412 #define PFMLIB_ENCODE_PERF(f)  \
413         .get_event_encoding[PFM_OS_PERF_EVENT] = f, \
414         .get_event_encoding[PFM_OS_PERF_EVENT_EXT] = f
415
416 #define PFMLIB_OS_DETECT(f)  \
417         .os_detect[PFM_OS_PERF_EVENT] = f, \
418         .os_detect[PFM_OS_PERF_EVENT_EXT] = f
419 #else
420 #define PFMLIB_VALID_PERF_PATTRS(f) \
421         .validate_pattrs[PFM_OS_PERF_EVENT] = NULL, \
422         .validate_pattrs[PFM_OS_PERF_EVENT_EXT] = NULL
423
424 #define PFMLIB_ENCODE_PERF(f)  \
425         .get_event_encoding[PFM_OS_PERF_EVENT] = NULL, \
426         .get_event_encoding[PFM_OS_PERF_EVENT_EXT] = NULL
427
428 #define PFMLIB_OS_DETECT(f)  \
429         .os_detect[PFM_OS_PERF_EVENT] = NULL, \
430         .os_detect[PFM_OS_PERF_EVENT_EXT] = NULL
431 #endif
432
433 static inline int
434 is_empty_attr(const pfmlib_attr_desc_t *a)
435 {
436         return !a || !a->name || strlen(a->name) == 0 ? 1 : 0;
437 }
438
439 #endif /* __PFMLIB_PRIV_H__ */