perf/x86/intel/uncore: Move uncore_box_init() out of driver initialization
[linux-2.6-block.git] / arch / x86 / kernel / cpu / perf_event_intel_uncore.h
CommitLineData
087bfbb0
YZ
1#include <linux/module.h>
2#include <linux/slab.h>
14371cce 3#include <linux/pci.h>
087bfbb0
YZ
4#include <linux/perf_event.h>
5#include "perf_event.h"
6
7#define UNCORE_PMU_NAME_LEN 32
7740dfc0 8#define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC)
ced2efb0 9#define UNCORE_SNB_IMC_HRTIMER_INTERVAL (5ULL * NSEC_PER_SEC)
087bfbb0 10
eca26c99 11#define UNCORE_FIXED_EVENT 0xff
087bfbb0
YZ
12#define UNCORE_PMC_IDX_MAX_GENERIC 8
13#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC
14#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1)
15
899396cf
YZ
16#define UNCORE_PCI_DEV_DATA(type, idx) ((type << 8) | idx)
17#define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff)
18#define UNCORE_PCI_DEV_IDX(data) (data & 0xff)
19#define UNCORE_EXTRA_PCI_DEV 0xff
5306c31c 20#define UNCORE_EXTRA_PCI_DEV_MAX 3
899396cf
YZ
21
22/* support up to 8 sockets */
23#define UNCORE_SOCKET_MAX 8
24
087bfbb0
YZ
25#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
26
27struct intel_uncore_ops;
28struct intel_uncore_pmu;
29struct intel_uncore_box;
30struct uncore_event_desc;
31
32struct intel_uncore_type {
33 const char *name;
34 int num_counters;
35 int num_boxes;
36 int perf_ctr_bits;
37 int fixed_ctr_bits;
087bfbb0
YZ
38 unsigned perf_ctr;
39 unsigned event_ctl;
40 unsigned event_mask;
41 unsigned fixed_ctr;
42 unsigned fixed_ctl;
43 unsigned box_ctl;
44 unsigned msr_offset;
6a67943a
YZ
45 unsigned num_shared_regs:8;
46 unsigned single_fixed:1;
254298c7 47 unsigned pair_ctr_ctl:1;
cb37af77 48 unsigned *msr_offsets;
087bfbb0
YZ
49 struct event_constraint unconstrainted;
50 struct event_constraint *constraints;
51 struct intel_uncore_pmu *pmus;
52 struct intel_uncore_ops *ops;
53 struct uncore_event_desc *event_descs;
314d9f63 54 const struct attribute_group *attr_groups[4];
d64b25b6 55 struct pmu *pmu; /* for custom pmu ops */
087bfbb0
YZ
56};
57
314d9f63
YZ
58#define pmu_group attr_groups[0]
59#define format_group attr_groups[1]
60#define events_group attr_groups[2]
087bfbb0
YZ
61
62struct intel_uncore_ops {
63 void (*init_box)(struct intel_uncore_box *);
64 void (*disable_box)(struct intel_uncore_box *);
65 void (*enable_box)(struct intel_uncore_box *);
66 void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
67 void (*enable_event)(struct intel_uncore_box *, struct perf_event *);
68 u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *);
6a67943a
YZ
69 int (*hw_config)(struct intel_uncore_box *, struct perf_event *);
70 struct event_constraint *(*get_constraint)(struct intel_uncore_box *,
71 struct perf_event *);
72 void (*put_constraint)(struct intel_uncore_box *, struct perf_event *);
087bfbb0
YZ
73};
74
75struct intel_uncore_pmu {
76 struct pmu pmu;
77 char name[UNCORE_PMU_NAME_LEN];
78 int pmu_idx;
79 int func_id;
80 struct intel_uncore_type *type;
81 struct intel_uncore_box ** __percpu box;
14371cce 82 struct list_head box_list;
087bfbb0
YZ
83};
84
6a67943a
YZ
85struct intel_uncore_extra_reg {
86 raw_spinlock_t lock;
254298c7 87 u64 config, config1, config2;
6a67943a
YZ
88 atomic_t ref;
89};
90
087bfbb0
YZ
91struct intel_uncore_box {
92 int phys_id;
93 int n_active; /* number of active events */
94 int n_events;
95 int cpu; /* cpu to collect events */
96 unsigned long flags;
97 atomic_t refcnt;
98 struct perf_event *events[UNCORE_PMC_IDX_MAX];
99 struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
100 unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
101 u64 tags[UNCORE_PMC_IDX_MAX];
14371cce 102 struct pci_dev *pci_dev;
087bfbb0 103 struct intel_uncore_pmu *pmu;
79859cce 104 u64 hrtimer_duration; /* hrtimer timeout for this box */
087bfbb0
YZ
105 struct hrtimer hrtimer;
106 struct list_head list;
ced2efb0 107 struct list_head active_list;
b9e1ab6d 108 void *io_addr;
6a67943a 109 struct intel_uncore_extra_reg shared_regs[0];
087bfbb0
YZ
110};
111
112#define UNCORE_BOX_FLAG_INITIATED 0
113
114struct uncore_event_desc {
115 struct kobj_attribute attr;
116 const char *config;
117};
118
514b2346
YZ
119ssize_t uncore_event_show(struct kobject *kobj,
120 struct kobj_attribute *attr, char *buf);
121
087bfbb0
YZ
122#define INTEL_UNCORE_EVENT_DESC(_name, _config) \
123{ \
124 .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \
125 .config = _config, \
126}
127
128#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
129static ssize_t __uncore_##_var##_show(struct kobject *kobj, \
130 struct kobj_attribute *attr, \
131 char *page) \
132{ \
133 BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
134 return sprintf(page, _format "\n"); \
135} \
136static struct kobj_attribute format_attr_##_var = \
137 __ATTR(_name, 0444, __uncore_##_var##_show, NULL)
138
14371cce
YZ
139static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
140{
141 return box->pmu->type->box_ctl;
142}
143
144static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box)
145{
146 return box->pmu->type->fixed_ctl;
147}
148
149static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box)
150{
151 return box->pmu->type->fixed_ctr;
152}
153
154static inline
155unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx)
156{
157 return idx * 4 + box->pmu->type->event_ctl;
158}
159
160static inline
161unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
162{
163 return idx * 8 + box->pmu->type->perf_ctr;
164}
165
cb37af77
YZ
166static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
167{
168 struct intel_uncore_pmu *pmu = box->pmu;
169 return pmu->type->msr_offsets ?
170 pmu->type->msr_offsets[pmu->pmu_idx] :
171 pmu->type->msr_offset * pmu->pmu_idx;
172}
173
174static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
087bfbb0
YZ
175{
176 if (!box->pmu->type->box_ctl)
177 return 0;
cb37af77 178 return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
087bfbb0
YZ
179}
180
cb37af77 181static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
087bfbb0
YZ
182{
183 if (!box->pmu->type->fixed_ctl)
184 return 0;
cb37af77 185 return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
087bfbb0
YZ
186}
187
cb37af77 188static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
087bfbb0 189{
cb37af77 190 return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
087bfbb0
YZ
191}
192
193static inline
194unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
195{
254298c7
YZ
196 return box->pmu->type->event_ctl +
197 (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
cb37af77 198 uncore_msr_box_offset(box);
087bfbb0
YZ
199}
200
201static inline
202unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
203{
254298c7
YZ
204 return box->pmu->type->perf_ctr +
205 (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
cb37af77 206 uncore_msr_box_offset(box);
087bfbb0
YZ
207}
208
14371cce
YZ
209static inline
210unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
211{
212 if (box->pci_dev)
213 return uncore_pci_fixed_ctl(box);
214 else
215 return uncore_msr_fixed_ctl(box);
216}
217
218static inline
219unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
220{
221 if (box->pci_dev)
222 return uncore_pci_fixed_ctr(box);
223 else
224 return uncore_msr_fixed_ctr(box);
225}
226
227static inline
228unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
229{
230 if (box->pci_dev)
231 return uncore_pci_event_ctl(box, idx);
232 else
233 return uncore_msr_event_ctl(box, idx);
234}
235
236static inline
237unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
238{
239 if (box->pci_dev)
240 return uncore_pci_perf_ctr(box, idx);
241 else
242 return uncore_msr_perf_ctr(box, idx);
243}
244
087bfbb0
YZ
245static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box)
246{
247 return box->pmu->type->perf_ctr_bits;
248}
249
250static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box)
251{
252 return box->pmu->type->fixed_ctr_bits;
253}
254
255static inline int uncore_num_counters(struct intel_uncore_box *box)
256{
257 return box->pmu->type->num_counters;
258}
259
c05199e5
KL
260static inline void uncore_box_init(struct intel_uncore_box *box)
261{
262 if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
263 if (box->pmu->type->ops->init_box)
264 box->pmu->type->ops->init_box(box);
265 }
266}
267
087bfbb0
YZ
268static inline void uncore_disable_box(struct intel_uncore_box *box)
269{
270 if (box->pmu->type->ops->disable_box)
271 box->pmu->type->ops->disable_box(box);
272}
273
274static inline void uncore_enable_box(struct intel_uncore_box *box)
275{
c05199e5
KL
276 uncore_box_init(box);
277
087bfbb0
YZ
278 if (box->pmu->type->ops->enable_box)
279 box->pmu->type->ops->enable_box(box);
280}
281
282static inline void uncore_disable_event(struct intel_uncore_box *box,
283 struct perf_event *event)
284{
285 box->pmu->type->ops->disable_event(box, event);
286}
287
288static inline void uncore_enable_event(struct intel_uncore_box *box,
289 struct perf_event *event)
290{
291 box->pmu->type->ops->enable_event(box, event);
292}
293
294static inline u64 uncore_read_counter(struct intel_uncore_box *box,
295 struct perf_event *event)
296{
297 return box->pmu->type->ops->read_counter(box, event);
298}
299
254298c7
YZ
300static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
301{
302 return (box->phys_id < 0);
303}
514b2346
YZ
304
305struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event);
306struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu);
307struct intel_uncore_box *uncore_event_to_box(struct perf_event *event);
308u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event);
309void uncore_pmu_start_hrtimer(struct intel_uncore_box *box);
310void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box);
311void uncore_pmu_event_read(struct perf_event *event);
312void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event);
313struct event_constraint *
314uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
315void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
316u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
317
318extern struct intel_uncore_type **uncore_msr_uncores;
319extern struct intel_uncore_type **uncore_pci_uncores;
320extern struct pci_driver *uncore_pci_driver;
321extern int uncore_pcibus_to_physid[256];
322extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
323extern struct event_constraint uncore_constraint_empty;
92807ffd
YZ
324
325/* perf_event_intel_uncore_snb.c */
326int snb_uncore_pci_init(void);
327int ivb_uncore_pci_init(void);
328int hsw_uncore_pci_init(void);
329void snb_uncore_cpu_init(void);
330void nhm_uncore_cpu_init(void);
8268fdfc
YZ
331
332/* perf_event_intel_uncore_snbep.c */
333int snbep_uncore_pci_init(void);
334void snbep_uncore_cpu_init(void);
ddcd0973
PZ
335int ivbep_uncore_pci_init(void);
336void ivbep_uncore_cpu_init(void);
e735b9db
YZ
337int hswep_uncore_pci_init(void);
338void hswep_uncore_cpu_init(void);
c1e46580
YZ
339
340/* perf_event_intel_uncore_nhmex.c */
341void nhmex_uncore_cpu_init(void);