1*9f17508dSLike Xu #ifndef _X86_PMU_H_ 2*9f17508dSLike Xu #define _X86_PMU_H_ 3*9f17508dSLike Xu 4*9f17508dSLike Xu #include "processor.h" 5*9f17508dSLike Xu #include "libcflat.h" 6*9f17508dSLike Xu 7*9f17508dSLike Xu #define FIXED_CNT_INDEX 32 8*9f17508dSLike Xu #define MAX_NUM_LBR_ENTRY 32 9*9f17508dSLike Xu 10*9f17508dSLike Xu /* Performance Counter Vector for the LVT PC Register */ 11*9f17508dSLike Xu #define PMI_VECTOR 32 12*9f17508dSLike Xu 13*9f17508dSLike Xu #define DEBUGCTLMSR_LBR (1UL << 0) 14*9f17508dSLike Xu 15*9f17508dSLike Xu #define PMU_CAP_LBR_FMT 0x3f 16*9f17508dSLike Xu #define PMU_CAP_FW_WRITES (1ULL << 13) 17*9f17508dSLike Xu 18*9f17508dSLike Xu #define EVNSEL_EVENT_SHIFT 0 19*9f17508dSLike Xu #define EVNTSEL_UMASK_SHIFT 8 20*9f17508dSLike Xu #define EVNTSEL_USR_SHIFT 16 21*9f17508dSLike Xu #define EVNTSEL_OS_SHIFT 17 22*9f17508dSLike Xu #define EVNTSEL_EDGE_SHIFT 18 23*9f17508dSLike Xu #define EVNTSEL_PC_SHIFT 19 24*9f17508dSLike Xu #define EVNTSEL_INT_SHIFT 20 25*9f17508dSLike Xu #define EVNTSEL_EN_SHIF 22 26*9f17508dSLike Xu #define EVNTSEL_INV_SHIF 23 27*9f17508dSLike Xu #define EVNTSEL_CMASK_SHIFT 24 28*9f17508dSLike Xu 29*9f17508dSLike Xu #define EVNTSEL_EN (1 << EVNTSEL_EN_SHIF) 30*9f17508dSLike Xu #define EVNTSEL_USR (1 << EVNTSEL_USR_SHIFT) 31*9f17508dSLike Xu #define EVNTSEL_OS (1 << EVNTSEL_OS_SHIFT) 32*9f17508dSLike Xu #define EVNTSEL_PC (1 << EVNTSEL_PC_SHIFT) 33*9f17508dSLike Xu #define EVNTSEL_INT (1 << EVNTSEL_INT_SHIFT) 34*9f17508dSLike Xu #define EVNTSEL_INV (1 << EVNTSEL_INV_SHIF) 35*9f17508dSLike Xu 36*9f17508dSLike Xu static inline u8 pmu_version(void) 37*9f17508dSLike Xu { 38*9f17508dSLike Xu return cpuid(10).a & 0xff; 39*9f17508dSLike Xu } 40*9f17508dSLike Xu 41*9f17508dSLike Xu static inline bool this_cpu_has_pmu(void) 42*9f17508dSLike Xu { 43*9f17508dSLike Xu return !!pmu_version(); 44*9f17508dSLike Xu } 45*9f17508dSLike Xu 46*9f17508dSLike Xu static inline bool this_cpu_has_perf_global_ctrl(void) 47*9f17508dSLike Xu { 48*9f17508dSLike Xu return pmu_version() > 1; 49*9f17508dSLike Xu } 50*9f17508dSLike Xu 51*9f17508dSLike Xu static inline u8 pmu_nr_gp_counters(void) 52*9f17508dSLike Xu { 53*9f17508dSLike Xu return (cpuid(10).a >> 8) & 0xff; 54*9f17508dSLike Xu } 55*9f17508dSLike Xu 56*9f17508dSLike Xu static inline u8 pmu_gp_counter_width(void) 57*9f17508dSLike Xu { 58*9f17508dSLike Xu return (cpuid(10).a >> 16) & 0xff; 59*9f17508dSLike Xu } 60*9f17508dSLike Xu 61*9f17508dSLike Xu static inline u8 pmu_gp_counter_mask_length(void) 62*9f17508dSLike Xu { 63*9f17508dSLike Xu return (cpuid(10).a >> 24) & 0xff; 64*9f17508dSLike Xu } 65*9f17508dSLike Xu 66*9f17508dSLike Xu static inline u8 pmu_nr_fixed_counters(void) 67*9f17508dSLike Xu { 68*9f17508dSLike Xu struct cpuid id = cpuid(10); 69*9f17508dSLike Xu 70*9f17508dSLike Xu if ((id.a & 0xff) > 1) 71*9f17508dSLike Xu return id.d & 0x1f; 72*9f17508dSLike Xu else 73*9f17508dSLike Xu return 0; 74*9f17508dSLike Xu } 75*9f17508dSLike Xu 76*9f17508dSLike Xu static inline u8 pmu_fixed_counter_width(void) 77*9f17508dSLike Xu { 78*9f17508dSLike Xu struct cpuid id = cpuid(10); 79*9f17508dSLike Xu 80*9f17508dSLike Xu if ((id.a & 0xff) > 1) 81*9f17508dSLike Xu return (id.d >> 5) & 0xff; 82*9f17508dSLike Xu else 83*9f17508dSLike Xu return 0; 84*9f17508dSLike Xu } 85*9f17508dSLike Xu 86*9f17508dSLike Xu static inline bool pmu_gp_counter_is_available(int i) 87*9f17508dSLike Xu { 88*9f17508dSLike Xu /* CPUID.0xA.EBX bit is '1 if they counter is NOT available. */ 89*9f17508dSLike Xu return !(cpuid(10).b & BIT(i)); 90*9f17508dSLike Xu } 91*9f17508dSLike Xu 92*9f17508dSLike Xu static inline u64 this_cpu_perf_capabilities(void) 93*9f17508dSLike Xu { 94*9f17508dSLike Xu if (!this_cpu_has(X86_FEATURE_PDCM)) 95*9f17508dSLike Xu return 0; 96*9f17508dSLike Xu 97*9f17508dSLike Xu return rdmsr(MSR_IA32_PERF_CAPABILITIES); 98*9f17508dSLike Xu } 99*9f17508dSLike Xu 100*9f17508dSLike Xu #endif /* _X86_PMU_H_ */ 101