akaros/user/perfmon/pfmlib_intel_x86_priv.h
<<
>>
Prefs
   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 */
  42typedef 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 */
  61typedef 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
  91typedef 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
 218typedef 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
 225typedef 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
 231typedef 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
 242typedef 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
 249extern pfm_intel_x86_config_t pfm_intel_x86_cfg;
 250
 251extern const pfmlib_attr_desc_t intel_x86_mods[];
 252
 253static inline int
 254intel_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
 260static inline int
 261is_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
 274static inline int
 275intel_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
 281static inline unsigned int
 282intel_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 */
 303static inline int
 304intel_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
 321extern int pfm_intel_x86_detect(void);
 322extern int pfm_intel_x86_add_defaults(void *this, pfmlib_event_desc_t *e, unsigned int msk, uint64_t *umask, unsigned int max_grpid);
 323
 324extern int pfm_intel_x86_event_is_valid(void *this, int pidx);
 325extern int pfm_intel_x86_get_encoding(void *this, pfmlib_event_desc_t *e);
 326extern int pfm_intel_x86_get_event_first(void *this);
 327extern int pfm_intel_x86_get_event_next(void *this, int idx);
 328extern int pfm_intel_x86_get_event_umask_first(void *this, int idx);
 329extern int pfm_intel_x86_get_event_umask_next(void *this, int idx, int attr);
 330extern int pfm_intel_x86_validate_table(void *this, FILE *fp);
 331extern int pfm_intel_x86_get_event_attr_info(void *this, int idx, int attr_idx, pfm_event_attr_info_t *info);
 332extern int pfm_intel_x86_get_event_info(void *this, int idx, pfm_event_info_t *info);
 333extern int pfm_intel_x86_valid_pebs(pfmlib_event_desc_t *e);
 334extern int pfm_intel_x86_perf_event_encoding(pfmlib_event_desc_t *e, void *data);
 335extern int pfm_intel_x86_perf_detect(void *this);
 336extern unsigned int pfm_intel_x86_get_event_nattrs(void *this, int pidx);
 337extern int intel_x86_attr2mod(void *this, int pidx, int attr_idx);
 338
 339extern int pfm_intel_x86_get_perf_encoding(void *this, pfmlib_event_desc_t *e);
 340extern int pfm_intel_nhm_unc_get_perf_encoding(void *this, pfmlib_event_desc_t *e);
 341extern void pfm_intel_x86_perf_validate_pattrs(void *this, pfmlib_event_desc_t *e);
 342extern int pfm_intel_x86_can_auto_encode(void *this, int pidx, int uidx);
 343extern int pfm_intel_x86_model_detect(void *this);
 344
 345#endif /* __PFMLIB_INTEL_X86_PRIV_H__ */
 346