2 * Copyright (c) 2009 Google, Inc
3 * Contributed by Stephane Eranian <eranian@gmail.com>
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:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
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.
22 * This file is part of libpfm, a performance monitoring support library for
23 * applications on Linux.
25 #ifndef __PFMLIB_INTEL_X86_PRIV_H__
26 #define __PFMLIB_INTEL_X86_PRIV_H__
29 * This file contains the definitions used for all Intel X86 processors
34 * maximum number of unit masks groups per event
36 #define INTEL_X86_NUM_GRP 8
37 #define INTEL_X86_MAX_FILTERS 3
40 * unit mask description
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 */
56 #define INTEL_X86_MAX_GRPID (~0U)
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 */
76 * pme_flags value (event and unit mask)
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 */
91 typedef union pfm_intel_x86_reg {
92 unsigned long long val; /* complete register value */
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;
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 */
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;
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 */
146 } pfm_intel_x86_reg_t;
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 */
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)
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)
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)
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
194 * shift relative to start of register
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
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)
205 /* intel x86 core PMU supported plm */
206 #define INTEL_X86_PLM (PFM_PLM0|PFM_PLM3)
209 * Intel x86 specific pmu flags (pmu->flags 16 MSB)
211 #define INTEL_X86_PMU_FL_ECMASK 0x10000 /* edge requires cmask >=1 */
214 * default ldlat value for PEBS-LL events. Used when ldlat= is missing
216 #define INTEL_X86_LDLAT_DEFAULT 3 /* default ldlat value in core cycles */
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;
226 unsigned int num_cnt:6;
227 unsigned int cnt_width:6;
228 unsigned int reserved:20;
229 } intel_x86_pmu_edx_t;
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;
244 int family; /* 0 means nothing detected yet */
247 } pfm_intel_x86_config_t;
249 extern pfm_intel_x86_config_t pfm_intel_x86_cfg;
251 extern const pfmlib_attr_desc_t intel_x86_mods[];
254 intel_x86_eflag(void *this, int idx, int flag)
256 const intel_x86_entry_t *pe = this_pe(this);
257 return !!(pe[idx].flags & flag);
261 is_model_umask(void *this, int pidx, int attr)
263 pfmlib_pmu_t *pmu = this;
264 const intel_x86_entry_t *pe = this_pe(this);
265 const intel_x86_entry_t *ent;
269 model = ent->umasks[attr].umodel;
271 return model == 0 || model == pmu->pmu;
275 intel_x86_uflag(void *this, int idx, int attr, int flag)
277 const intel_x86_entry_t *pe = this_pe(this);
278 return !!(pe[idx].umasks[attr].uflags & flag);
281 static inline unsigned int
282 intel_x86_num_umasks(void *this, int pidx)
284 pfmlib_pmu_t *pmu = this;
285 const intel_x86_entry_t *pe = this_pe(this);
286 unsigned int i, n = 0, model;
289 * some umasks may be model specific
291 for (i = 0; i < pe[pidx].numasks; i++) {
292 model = pe[pidx].umasks[i].umodel;
293 if (model && model != pmu->pmu)
301 * find actual index of umask based on attr_idx
304 intel_x86_attr2umask(void *this, int pidx, int attr_idx)
306 const intel_x86_entry_t *pe = this_pe(this);
309 for (i = 0; i < pe[pidx].numasks; i++) {
311 if (!is_model_umask(this, pidx, i))
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);
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);
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);
345 #endif /* __PFMLIB_INTEL_X86_PRIV_H__ */