xref: /kvm-unit-tests/lib/x86/pmu.h (revision f85e94a291503fc7ae991830be13c84a240cb0ff)
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 	u64 perf_cap;
45 };
46 
47 extern struct pmu_caps pmu;
48 
49 void pmu_init(void);
50 
51 static inline u8 pmu_version(void)
52 {
53 	return pmu.version;
54 }
55 
56 static inline bool this_cpu_has_pmu(void)
57 {
58 	return !!pmu_version();
59 }
60 
61 static inline bool this_cpu_has_perf_global_ctrl(void)
62 {
63 	return pmu_version() > 1;
64 }
65 
66 static inline u8 pmu_nr_gp_counters(void)
67 {
68 	return pmu.nr_gp_counters;
69 }
70 
71 static inline u8 pmu_gp_counter_width(void)
72 {
73 	return pmu.gp_counter_width;
74 }
75 
76 static inline u8 pmu_gp_counter_mask_length(void)
77 {
78 	return pmu.gp_counter_mask_length;
79 }
80 
81 static inline u8 pmu_nr_fixed_counters(void)
82 {
83 	return pmu.nr_fixed_counters;
84 }
85 
86 static inline u8 pmu_fixed_counter_width(void)
87 {
88 	return pmu.fixed_counter_width;
89 }
90 
91 static inline bool pmu_gp_counter_is_available(int i)
92 {
93 	return pmu.gp_counter_available & BIT(i);
94 }
95 
96 static inline u64 this_cpu_perf_capabilities(void)
97 {
98 	return pmu.perf_cap;
99 }
100 
101 static inline u64 pmu_lbr_version(void)
102 {
103 	return this_cpu_perf_capabilities() & PMU_CAP_LBR_FMT;
104 }
105 
106 static inline bool pmu_has_full_writes(void)
107 {
108 	return this_cpu_perf_capabilities() & PMU_CAP_FW_WRITES;
109 }
110 
111 #endif /* _X86_PMU_H_ */
112