19f17508dSLike Xu #ifndef _X86_PMU_H_ 29f17508dSLike Xu #define _X86_PMU_H_ 39f17508dSLike Xu 49f17508dSLike Xu #include "processor.h" 59f17508dSLike Xu #include "libcflat.h" 69f17508dSLike Xu 79f17508dSLike Xu #define FIXED_CNT_INDEX 32 89f17508dSLike Xu #define MAX_NUM_LBR_ENTRY 32 99f17508dSLike Xu 109f17508dSLike Xu /* Performance Counter Vector for the LVT PC Register */ 119f17508dSLike Xu #define PMI_VECTOR 32 129f17508dSLike Xu 139f17508dSLike Xu #define DEBUGCTLMSR_LBR (1UL << 0) 149f17508dSLike Xu 159f17508dSLike Xu #define PMU_CAP_LBR_FMT 0x3f 169f17508dSLike Xu #define PMU_CAP_FW_WRITES (1ULL << 13) 179f17508dSLike Xu 189f17508dSLike Xu #define EVNSEL_EVENT_SHIFT 0 199f17508dSLike Xu #define EVNTSEL_UMASK_SHIFT 8 209f17508dSLike Xu #define EVNTSEL_USR_SHIFT 16 219f17508dSLike Xu #define EVNTSEL_OS_SHIFT 17 229f17508dSLike Xu #define EVNTSEL_EDGE_SHIFT 18 239f17508dSLike Xu #define EVNTSEL_PC_SHIFT 19 249f17508dSLike Xu #define EVNTSEL_INT_SHIFT 20 259f17508dSLike Xu #define EVNTSEL_EN_SHIF 22 269f17508dSLike Xu #define EVNTSEL_INV_SHIF 23 279f17508dSLike Xu #define EVNTSEL_CMASK_SHIFT 24 289f17508dSLike Xu 299f17508dSLike Xu #define EVNTSEL_EN (1 << EVNTSEL_EN_SHIF) 309f17508dSLike Xu #define EVNTSEL_USR (1 << EVNTSEL_USR_SHIFT) 319f17508dSLike Xu #define EVNTSEL_OS (1 << EVNTSEL_OS_SHIFT) 329f17508dSLike Xu #define EVNTSEL_PC (1 << EVNTSEL_PC_SHIFT) 339f17508dSLike Xu #define EVNTSEL_INT (1 << EVNTSEL_INT_SHIFT) 349f17508dSLike Xu #define EVNTSEL_INV (1 << EVNTSEL_INV_SHIF) 359f17508dSLike Xu 36879e7f07SLike Xu struct pmu_caps { 37f85e94a2SSean Christopherson u8 version; 38f85e94a2SSean Christopherson u8 nr_fixed_counters; 39f85e94a2SSean Christopherson u8 fixed_counter_width; 40f85e94a2SSean Christopherson u8 nr_gp_counters; 41f85e94a2SSean Christopherson u8 gp_counter_width; 42f85e94a2SSean Christopherson u8 gp_counter_mask_length; 43f85e94a2SSean Christopherson u32 gp_counter_available; 44*cda64e80SLike Xu u32 msr_gp_counter_base; 45*cda64e80SLike Xu u32 msr_gp_event_select_base; 46*cda64e80SLike Xu 47879e7f07SLike Xu u64 perf_cap; 48879e7f07SLike Xu }; 49879e7f07SLike Xu 50879e7f07SLike Xu extern struct pmu_caps pmu; 51879e7f07SLike Xu 52879e7f07SLike Xu void pmu_init(void); 53879e7f07SLike Xu 54*cda64e80SLike Xu static inline u32 MSR_GP_COUNTERx(unsigned int i) 55*cda64e80SLike Xu { 56*cda64e80SLike Xu return pmu.msr_gp_counter_base + i; 57*cda64e80SLike Xu } 58*cda64e80SLike Xu 59*cda64e80SLike Xu static inline u32 MSR_GP_EVENT_SELECTx(unsigned int i) 60*cda64e80SLike Xu { 61*cda64e80SLike Xu return pmu.msr_gp_event_select_base + i; 62*cda64e80SLike Xu } 63*cda64e80SLike Xu 649f17508dSLike Xu static inline bool this_cpu_has_pmu(void) 659f17508dSLike Xu { 66414ee7d1SSean Christopherson return !!pmu.version; 679f17508dSLike Xu } 689f17508dSLike Xu 699f17508dSLike Xu static inline bool this_cpu_has_perf_global_ctrl(void) 709f17508dSLike Xu { 71414ee7d1SSean Christopherson return pmu.version > 1; 729f17508dSLike Xu } 739f17508dSLike Xu 749f17508dSLike Xu static inline bool pmu_gp_counter_is_available(int i) 759f17508dSLike Xu { 76f85e94a2SSean Christopherson return pmu.gp_counter_available & BIT(i); 779f17508dSLike Xu } 789f17508dSLike Xu 79879e7f07SLike Xu static inline u64 pmu_lbr_version(void) 80879e7f07SLike Xu { 81414ee7d1SSean Christopherson return pmu.perf_cap & PMU_CAP_LBR_FMT; 82879e7f07SLike Xu } 83879e7f07SLike Xu 84879e7f07SLike Xu static inline bool pmu_has_full_writes(void) 85879e7f07SLike Xu { 86414ee7d1SSean Christopherson return pmu.perf_cap & PMU_CAP_FW_WRITES; 879f17508dSLike Xu } 889f17508dSLike Xu 89*cda64e80SLike Xu static inline bool pmu_use_full_writes(void) 90*cda64e80SLike Xu { 91*cda64e80SLike Xu return pmu.msr_gp_counter_base == MSR_IA32_PMC0; 92*cda64e80SLike Xu } 93*cda64e80SLike Xu 949f17508dSLike Xu #endif /* _X86_PMU_H_ */ 95