vmm: Added more syscalls and helpers to linuxemu
[akaros.git] / user / perfmon / pfmlib_intel_x86_priv.h
1 /*
2  * Copyright (c) 2009 Google, Inc
3  * Contributed by Stephane Eranian <eranian@gmail.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_INTEL_X86_PRIV_H__
26 #define __PFMLIB_INTEL_X86_PRIV_H__
27
28 /*
29  * This file contains the definitions used for all Intel X86 processors
30  */
31
32
33 /*
34  * maximum number of unit masks groups per event
35  */
36 #define INTEL_X86_NUM_GRP       8
37 #define INTEL_X86_MAX_FILTERS   3
38
39 /*
40  * unit mask description
41  */
42 typedef struct {
43         const char              *uname; /* unit mask name */
44         const char              *udesc; /* unit umask description */
45         const char              *uequiv;/* name of event from which this one is derived, NULL if none */
46         uint64_t                ucntmsk;/* supported counters for umask (if set, supersedes cntmsk) */
47         uint64_t                ucode;  /* unit mask code */
48         uint64_t                ufilters[INTEL_X86_MAX_FILTERS]; /* extra encoding for event */
49         unsigned int            uflags; /* unit mask flags */
50         unsigned int            umodel; /* only available on this PMU model */
51         unsigned int            grpid;  /* unit mask group id */
52         unsigned int            modhw;  /* hardwired modifiers, cannot be changed */
53         unsigned int            umodmsk_req; /* bitmask of required modifiers */
54 } intel_x86_umask_t;
55
56 #define INTEL_X86_MAX_GRPID     (~0U)
57
58 /*
59  * event description
60  */
61 typedef struct {
62         const char                      *name;  /* event name */
63         const char                      *desc;  /* event description */
64         const char                      *equiv; /* name of event from which this one is derived, NULL if none */
65         uint64_t                        cntmsk; /* supported counters */
66         unsigned int                    code;   /* event code */
67         unsigned int                    numasks;/* number of umasks */
68         unsigned int                    flags;  /* flags */
69         unsigned int                    modmsk; /* bitmask of modifiers for this event */
70         unsigned int                    modmsk_req; /* bitmask of required modifiers */
71         unsigned int                    ngrp;   /* number of unit masks groups */
72         const intel_x86_umask_t         *umasks; /* umask desc */
73 } intel_x86_entry_t;
74
75 /*
76  * pme_flags value (event and unit mask)
77  */
78 #define INTEL_X86_NCOMBO                0x01    /* unit masks within group cannot be combined */
79 #define INTEL_X86_FALLBACK_GEN          0x02    /* fallback from fixed to generic counter possible */
80 #define INTEL_X86_PEBS                  0x04    /* event supports PEBS or at least one umask supports PEBS */
81 #define INTEL_X86_DFL                   0x08    /* unit mask is default choice */
82 #define INTEL_X86_GRP_EXCL              0x10    /* only one unit mask group can be selected */
83 #define INTEL_X86_NHM_OFFCORE           0x20    /* Nehalem/Westmere offcore_response */
84 #define INTEL_X86_EXCL_GRP_GT           0x40    /* exclude use of grp with id > own grp */
85 #define INTEL_X86_FIXED                 0x80    /* fixed counter only event */
86 #define INTEL_X86_NO_AUTOENCODE         0x100   /* does not support auto encoding validation */
87 #define INTEL_X86_CODE_OVERRIDE         0x200   /* umask overrides event code */
88 #define INTEL_X86_LDLAT                 0x400   /* needs load latency modifier (ldlat) */
89 #define INTEL_X86_GRP_DFL_NONE          0x800   /* ok if umask group defaults to no umask */
90
91 typedef union pfm_intel_x86_reg {
92         unsigned long long val;                 /* complete register value */
93         struct {
94                 unsigned long sel_event_select:8;       /* event mask */
95                 unsigned long sel_unit_mask:8;          /* unit mask */
96                 unsigned long sel_usr:1;                /* user level */
97                 unsigned long sel_os:1;                 /* system level */
98                 unsigned long sel_edge:1;               /* edge detec */
99                 unsigned long sel_pc:1;                 /* pin control */
100                 unsigned long sel_int:1;                /* enable APIC intr */
101                 unsigned long sel_anythr:1;             /* measure any thread */
102                 unsigned long sel_en:1;                 /* enable */
103                 unsigned long sel_inv:1;                /* invert counter mask */
104                 unsigned long sel_cnt_mask:8;           /* counter mask */
105                 unsigned long sel_intx:1;               /* only in tx region */
106                 unsigned long sel_intxcp:1;             /* excl. aborted tx region */
107                 unsigned long sel_res2:30;
108         } perfevtsel;
109
110         struct {
111                 unsigned long usel_event:8;     /* event select */
112                 unsigned long usel_umask:8;     /* event unit mask */
113                 unsigned long usel_res1:1;      /* reserved */
114                 unsigned long usel_occ:1;       /* occupancy reset */
115                 unsigned long usel_edge:1;      /* edge detection */
116                 unsigned long usel_res2:1;      /* reserved */
117                 unsigned long usel_int:1;       /* PMI enable */
118                 unsigned long usel_res3:1;      /* reserved */
119                 unsigned long usel_en:1;        /* enable */
120                 unsigned long usel_inv:1;       /* invert */
121                 unsigned long usel_cnt_mask:8;  /* counter mask */
122                 unsigned long usel_res4:32;     /* reserved */
123         } nhm_unc;
124
125         struct {
126                 unsigned long usel_en:1;        /* enable */
127                 unsigned long usel_res1:1;
128                 unsigned long usel_int:1;       /* PMI enable */
129                 unsigned long usel_res2:32;
130                 unsigned long usel_res3:29;
131         } nhm_unc_fixed;
132
133         struct {
134                 unsigned long cpl_eq0:1;        /* filter out branches at pl0 */
135                 unsigned long cpl_neq0:1;       /* filter out branches at pl1-pl3 */
136                 unsigned long jcc:1;            /* filter out condition branches */
137                 unsigned long near_rel_call:1;  /* filter out near relative calls */
138                 unsigned long near_ind_call:1;  /* filter out near indirect calls */
139                 unsigned long near_ret:1;       /* filter out near returns */
140                 unsigned long near_ind_jmp:1;   /* filter out near unconditional jmp/calls */
141                 unsigned long near_rel_jmp:1;   /* filter out near uncoditional relative jmp */
142                 unsigned long far_branch:1;     /* filter out far branches */ 
143                 unsigned long reserved1:23;     /* reserved */
144                 unsigned long reserved2:32;     /* reserved */
145         } nhm_lbr_select;
146 } pfm_intel_x86_reg_t;
147
148 #define INTEL_X86_ATTR_K        0 /* kernel (0) */
149 #define INTEL_X86_ATTR_U        1 /* user (1, 2, 3) */
150 #define INTEL_X86_ATTR_E        2 /* edge */
151 #define INTEL_X86_ATTR_I        3 /* invert */
152 #define INTEL_X86_ATTR_C        4 /* counter mask */
153 #define INTEL_X86_ATTR_T        5 /* any thread */
154 #define INTEL_X86_ATTR_LDLAT    6 /* load latency threshold */
155 #define INTEL_X86_ATTR_INTX     7 /* in transaction */
156 #define INTEL_X86_ATTR_INTXCP   8 /* not aborted transaction */
157
158 #define _INTEL_X86_ATTR_U       (1 << INTEL_X86_ATTR_U)
159 #define _INTEL_X86_ATTR_K       (1 << INTEL_X86_ATTR_K)
160 #define _INTEL_X86_ATTR_I       (1 << INTEL_X86_ATTR_I)
161 #define _INTEL_X86_ATTR_E       (1 << INTEL_X86_ATTR_E)
162 #define _INTEL_X86_ATTR_C       (1 << INTEL_X86_ATTR_C)
163 #define _INTEL_X86_ATTR_T       (1 << INTEL_X86_ATTR_T)
164 #define _INTEL_X86_ATTR_INTX    (1 << INTEL_X86_ATTR_INTX)
165 #define _INTEL_X86_ATTR_INTXCP  (1 << INTEL_X86_ATTR_INTXCP)
166 #define _INTEL_X86_ATTR_LDLAT   (1 << INTEL_X86_ATTR_LDLAT)
167
168 #define INTEL_X86_ATTRS \
169         (_INTEL_X86_ATTR_I|_INTEL_X86_ATTR_E|_INTEL_X86_ATTR_C|_INTEL_X86_ATTR_U|_INTEL_X86_ATTR_K)
170
171 #define INTEL_V1_ATTRS          INTEL_X86_ATTRS
172 #define INTEL_V2_ATTRS          INTEL_X86_ATTRS
173 #define INTEL_FIXED2_ATTRS      (_INTEL_X86_ATTR_U|_INTEL_X86_ATTR_K)
174 #define INTEL_FIXED3_ATTRS      (INTEL_FIXED2_ATTRS|_INTEL_X86_ATTR_T)
175 #define INTEL_V3_ATTRS          (INTEL_V2_ATTRS|_INTEL_X86_ATTR_T)
176 #define INTEL_V4_ATTRS          (INTEL_V3_ATTRS | _INTEL_X86_ATTR_INTX | _INTEL_X86_ATTR_INTXCP)
177
178 /* let's define some handy shortcuts! */
179 #define sel_event_select perfevtsel.sel_event_select
180 #define sel_unit_mask    perfevtsel.sel_unit_mask
181 #define sel_usr          perfevtsel.sel_usr
182 #define sel_os           perfevtsel.sel_os
183 #define sel_edge         perfevtsel.sel_edge
184 #define sel_pc           perfevtsel.sel_pc
185 #define sel_int          perfevtsel.sel_int
186 #define sel_en           perfevtsel.sel_en
187 #define sel_inv          perfevtsel.sel_inv
188 #define sel_cnt_mask     perfevtsel.sel_cnt_mask
189 #define sel_anythr       perfevtsel.sel_anythr
190 #define sel_intx         perfevtsel.sel_intx
191 #define sel_intxcp       perfevtsel.sel_intxcp
192
193 /*
194  * shift relative to start of register
195  */
196 #define INTEL_X86_EDGE_BIT      18
197 #define INTEL_X86_ANY_BIT       21
198 #define INTEL_X86_INV_BIT       23
199 #define INTEL_X86_CMASK_BIT     24
200
201 #define INTEL_X86_MOD_EDGE      (1 << INTEL_X86_EDGE_BIT)
202 #define INTEL_X86_MOD_ANY       (1 << INTEL_X86_ANY_BIT)
203 #define INTEL_X86_MOD_INV       (1 << INTEL_X86_INV_BIT)
204
205 /* intel x86 core PMU supported plm */
206 #define INTEL_X86_PLM   (PFM_PLM0|PFM_PLM3)
207
208 /*
209  * Intel x86 specific pmu flags (pmu->flags 16 MSB)
210  */
211 #define INTEL_X86_PMU_FL_ECMASK 0x10000 /* edge requires cmask >=1 */
212
213 /*
214  * default ldlat value for PEBS-LL events. Used when ldlat= is missing
215  */
216 #define INTEL_X86_LDLAT_DEFAULT 3 /* default ldlat value in core cycles */
217
218 typedef struct {
219         unsigned int version:8;
220         unsigned int num_cnt:8;
221         unsigned int cnt_width:8;
222         unsigned int ebx_length:8;
223 } intel_x86_pmu_eax_t;
224
225 typedef struct {
226         unsigned int num_cnt:6;
227         unsigned int cnt_width:6;
228         unsigned int reserved:20;
229 } intel_x86_pmu_edx_t;
230
231 typedef struct {
232         unsigned int no_core_cycle:1;
233         unsigned int no_inst_retired:1;
234         unsigned int no_ref_cycle:1;
235         unsigned int no_llc_ref:1;
236         unsigned int no_llc_miss:1;
237         unsigned int no_br_retired:1;
238         unsigned int no_br_mispred_retired:1;
239         unsigned int reserved:25;
240 } intel_x86_pmu_ebx_t;
241
242 typedef struct {
243         int model;
244         int family; /* 0 means nothing detected yet */
245         int arch_version;
246         int stepping;
247 } pfm_intel_x86_config_t;
248
249 extern pfm_intel_x86_config_t pfm_intel_x86_cfg;
250
251 extern const pfmlib_attr_desc_t intel_x86_mods[];
252
253 static inline int
254 intel_x86_eflag(void *this, int idx, int flag)
255 {
256         const intel_x86_entry_t *pe = this_pe(this);
257         return !!(pe[idx].flags & flag);
258 }
259
260 static inline int
261 is_model_umask(void *this, int pidx, int attr)
262 {
263         pfmlib_pmu_t *pmu = this;
264         const intel_x86_entry_t *pe = this_pe(this);
265         const intel_x86_entry_t *ent;
266         unsigned int model;
267
268         ent = pe + pidx;
269         model = ent->umasks[attr].umodel;
270
271         return model == 0 || model == pmu->pmu;
272 }
273
274 static inline int
275 intel_x86_uflag(void *this, int idx, int attr, int flag)
276 {
277         const intel_x86_entry_t *pe = this_pe(this);
278         return !!(pe[idx].umasks[attr].uflags & flag);
279 }
280
281 static inline unsigned int
282 intel_x86_num_umasks(void *this, int pidx)
283 {
284         pfmlib_pmu_t *pmu = this;
285         const intel_x86_entry_t *pe = this_pe(this);
286         unsigned int i, n = 0, model;
287
288         /*
289          * some umasks may be model specific
290          */
291         for (i = 0; i < pe[pidx].numasks; i++) {
292                 model = pe[pidx].umasks[i].umodel;
293                 if (model && model != pmu->pmu)
294                         continue;
295                 n++;
296         }
297         return n;
298 }
299
300 /*
301  * find actual index of umask based on attr_idx
302  */
303 static inline int
304 intel_x86_attr2umask(void *this, int pidx, int attr_idx)
305 {
306         const intel_x86_entry_t *pe = this_pe(this);
307         unsigned int i;
308
309         for (i = 0; i < pe[pidx].numasks; i++) {
310
311                 if (!is_model_umask(this, pidx, i))
312                         continue;
313
314                 if (attr_idx == 0)
315                         break;
316                 attr_idx--;
317         }
318         return i;
319 }
320
321 extern int pfm_intel_x86_detect(void);
322 extern int pfm_intel_x86_add_defaults(void *this, pfmlib_event_desc_t *e, unsigned int msk, uint64_t *umask, unsigned int max_grpid);
323
324 extern int pfm_intel_x86_event_is_valid(void *this, int pidx);
325 extern int pfm_intel_x86_get_encoding(void *this, pfmlib_event_desc_t *e);
326 extern int pfm_intel_x86_get_event_first(void *this);
327 extern int pfm_intel_x86_get_event_next(void *this, int idx);
328 extern int pfm_intel_x86_get_event_umask_first(void *this, int idx);
329 extern int pfm_intel_x86_get_event_umask_next(void *this, int idx, int attr);
330 extern int pfm_intel_x86_validate_table(void *this, FILE *fp);
331 extern int pfm_intel_x86_get_event_attr_info(void *this, int idx, int attr_idx, pfm_event_attr_info_t *info);
332 extern int pfm_intel_x86_get_event_info(void *this, int idx, pfm_event_info_t *info);
333 extern int pfm_intel_x86_valid_pebs(pfmlib_event_desc_t *e);
334 extern int pfm_intel_x86_perf_event_encoding(pfmlib_event_desc_t *e, void *data);
335 extern int pfm_intel_x86_perf_detect(void *this);
336 extern unsigned int pfm_intel_x86_get_event_nattrs(void *this, int pidx);
337 extern int intel_x86_attr2mod(void *this, int pidx, int attr_idx);
338
339 extern int pfm_intel_x86_get_perf_encoding(void *this, pfmlib_event_desc_t *e);
340 extern int pfm_intel_nhm_unc_get_perf_encoding(void *this, pfmlib_event_desc_t *e);
341 extern void pfm_intel_x86_perf_validate_pattrs(void *this, pfmlib_event_desc_t *e);
342 extern int pfm_intel_x86_can_auto_encode(void *this, int pidx, int uidx);
343 extern int pfm_intel_x86_model_detect(void *this);
344
345 #endif /* __PFMLIB_INTEL_X86_PRIV_H__ */