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 struct pmu_caps { 37 u8 version; 38 u8 nr_fixed_counters; 39 u8 fixed_counter_width; 40 u8 nr_gp_counters; 41 u8 gp_counter_width; 42 u8 gp_counter_mask_length; 43 u32 gp_counter_available; 44 u32 msr_gp_counter_base; 45 u32 msr_gp_event_select_base; 46 47 u64 perf_cap; 48 }; 49 50 extern struct pmu_caps pmu; 51 52 void pmu_init(void); 53 54 static inline u32 MSR_GP_COUNTERx(unsigned int i) 55 { 56 return pmu.msr_gp_counter_base + i; 57 } 58 59 static inline u32 MSR_GP_EVENT_SELECTx(unsigned int i) 60 { 61 return pmu.msr_gp_event_select_base + i; 62 } 63 64 static inline bool this_cpu_has_pmu(void) 65 { 66 return !!pmu.version; 67 } 68 69 static inline bool this_cpu_has_perf_global_ctrl(void) 70 { 71 return pmu.version > 1; 72 } 73 74 static inline bool pmu_gp_counter_is_available(int i) 75 { 76 return pmu.gp_counter_available & BIT(i); 77 } 78 79 static inline u64 pmu_lbr_version(void) 80 { 81 return pmu.perf_cap & PMU_CAP_LBR_FMT; 82 } 83 84 static inline bool pmu_has_full_writes(void) 85 { 86 return pmu.perf_cap & PMU_CAP_FW_WRITES; 87 } 88 89 static inline bool pmu_use_full_writes(void) 90 { 91 return pmu.msr_gp_counter_base == MSR_IA32_PMC0; 92 } 93 94 static inline u32 MSR_PERF_FIXED_CTRx(unsigned int i) 95 { 96 return MSR_CORE_PERF_FIXED_CTR0 + i; 97 } 98 99 #endif /* _X86_PMU_H_ */ 100