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