]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/x86/kernel/cpu/perf_event_intel_uncore.c
perf/x86/uncore: Move SNB/IVB-EP specific code to seperate file
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / kernel / cpu / perf_event_intel_uncore.c
CommitLineData
087bfbb0
YZ
1#include "perf_event_intel_uncore.h"
2
3static struct intel_uncore_type *empty_uncore[] = { NULL, };
514b2346
YZ
4struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
5struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
14371cce 6
514b2346
YZ
7static bool pcidrv_registered;
8struct pci_driver *uncore_pci_driver;
9/* pci bus to socket mapping */
10int uncore_pcibus_to_physid[256] = { [0 ... 255] = -1, };
11struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
899396cf 12
14371cce 13static DEFINE_RAW_SPINLOCK(uncore_box_lock);
087bfbb0
YZ
14/* mask of cpus that collect uncore events */
15static cpumask_t uncore_cpu_mask;
16
17/* constraint for the fixed counter */
514b2346 18static struct event_constraint uncore_constraint_fixed =
087bfbb0 19 EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
514b2346 20struct event_constraint uncore_constraint_empty =
6a67943a 21 EVENT_CONSTRAINT(0, 0, 0);
087bfbb0 22
514b2346
YZ
23ssize_t uncore_event_show(struct kobject *kobj,
24 struct kobj_attribute *attr, char *buf)
25{
26 struct uncore_event_desc *event =
27 container_of(attr, struct uncore_event_desc, attr);
28 return sprintf(buf, "%s", event->config);
29}
30
46bdd905
YZ
31#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \
32 ((1ULL << (n)) - 1)))
33
fcde10e9
YZ
34DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
35DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
36DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
37DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
7c94ee2e 38DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
7c94ee2e 39
514b2346 40struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
001e413f
SE
41{
42 return container_of(event->pmu, struct intel_uncore_pmu, pmu);
43}
44
514b2346 45struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
001e413f
SE
46{
47 struct intel_uncore_box *box;
48
49 box = *per_cpu_ptr(pmu->box, cpu);
50 if (box)
51 return box;
52
53 raw_spin_lock(&uncore_box_lock);
54 list_for_each_entry(box, &pmu->box_list, list) {
55 if (box->phys_id == topology_physical_package_id(cpu)) {
56 atomic_inc(&box->refcnt);
57 *per_cpu_ptr(pmu->box, cpu) = box;
58 break;
59 }
60 }
61 raw_spin_unlock(&uncore_box_lock);
62
63 return *per_cpu_ptr(pmu->box, cpu);
64}
65
514b2346 66struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
001e413f
SE
67{
68 /*
69 * perf core schedules event on the basis of cpu, uncore events are
70 * collected by one of the cpus inside a physical package.
71 */
72 return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id());
73}
74
514b2346 75u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
254298c7
YZ
76{
77 u64 count;
78
79 rdmsrl(event->hw.event_base, count);
80
81 return count;
82}
83
84/*
85 * generic get constraint function for shared match/mask registers.
86 */
514b2346 87struct event_constraint *
254298c7
YZ
88uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
89{
90 struct intel_uncore_extra_reg *er;
91 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
92 struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
93 unsigned long flags;
94 bool ok = false;
95
96 /*
97 * reg->alloc can be set due to existing state, so for fake box we
98 * need to ignore this, otherwise we might fail to allocate proper
99 * fake state for this extra reg constraint.
100 */
101 if (reg1->idx == EXTRA_REG_NONE ||
102 (!uncore_box_is_fake(box) && reg1->alloc))
103 return NULL;
104
105 er = &box->shared_regs[reg1->idx];
106 raw_spin_lock_irqsave(&er->lock, flags);
107 if (!atomic_read(&er->ref) ||
108 (er->config1 == reg1->config && er->config2 == reg2->config)) {
109 atomic_inc(&er->ref);
110 er->config1 = reg1->config;
111 er->config2 = reg2->config;
112 ok = true;
113 }
114 raw_spin_unlock_irqrestore(&er->lock, flags);
115
116 if (ok) {
117 if (!uncore_box_is_fake(box))
118 reg1->alloc = 1;
119 return NULL;
120 }
121
514b2346 122 return &uncore_constraint_empty;
254298c7
YZ
123}
124
514b2346 125void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
254298c7
YZ
126{
127 struct intel_uncore_extra_reg *er;
128 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
129
130 /*
131 * Only put constraint if extra reg was actually allocated. Also
132 * takes care of event which do not use an extra shared reg.
133 *
134 * Also, if this is a fake box we shouldn't touch any event state
135 * (reg->alloc) and we don't care about leaving inconsistent box
136 * state either since it will be thrown out.
137 */
138 if (uncore_box_is_fake(box) || !reg1->alloc)
139 return;
140
141 er = &box->shared_regs[reg1->idx];
142 atomic_dec(&er->ref);
143 reg1->alloc = 0;
144}
145
514b2346 146u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx)
46bdd905
YZ
147{
148 struct intel_uncore_extra_reg *er;
149 unsigned long flags;
150 u64 config;
151
152 er = &box->shared_regs[idx];
153
154 raw_spin_lock_irqsave(&er->lock, flags);
155 config = er->config;
156 raw_spin_unlock_irqrestore(&er->lock, flags);
157
158 return config;
159}
160
254298c7 161/* Nehalem-EX uncore support */
254298c7
YZ
162DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
163DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
254298c7
YZ
164DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
165DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
166
167static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
168{
169 wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
170}
171
172static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
173{
174 unsigned msr = uncore_msr_box_ctl(box);
175 u64 config;
176
177 if (msr) {
178 rdmsrl(msr, config);
179 config &= ~((1ULL << uncore_num_counters(box)) - 1);
180 /* WBox has a fixed counter */
181 if (uncore_msr_fixed_ctl(box))
182 config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
183 wrmsrl(msr, config);
184 }
185}
186
187static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
188{
189 unsigned msr = uncore_msr_box_ctl(box);
190 u64 config;
191
192 if (msr) {
193 rdmsrl(msr, config);
194 config |= (1ULL << uncore_num_counters(box)) - 1;
195 /* WBox has a fixed counter */
196 if (uncore_msr_fixed_ctl(box))
197 config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
198 wrmsrl(msr, config);
199 }
200}
201
202static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
203{
204 wrmsrl(event->hw.config_base, 0);
205}
206
207static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
208{
209 struct hw_perf_event *hwc = &event->hw;
210
211 if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
212 wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
213 else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
214 wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
215 else
216 wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
217}
218
219#define NHMEX_UNCORE_OPS_COMMON_INIT() \
220 .init_box = nhmex_uncore_msr_init_box, \
221 .disable_box = nhmex_uncore_msr_disable_box, \
222 .enable_box = nhmex_uncore_msr_enable_box, \
223 .disable_event = nhmex_uncore_msr_disable_event, \
224 .read_counter = uncore_msr_read_counter
225
226static struct intel_uncore_ops nhmex_uncore_ops = {
227 NHMEX_UNCORE_OPS_COMMON_INIT(),
228 .enable_event = nhmex_uncore_msr_enable_event,
229};
230
231static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
232 &format_attr_event.attr,
233 &format_attr_edge.attr,
234 NULL,
235};
236
237static struct attribute_group nhmex_uncore_ubox_format_group = {
238 .name = "format",
239 .attrs = nhmex_uncore_ubox_formats_attr,
240};
241
242static struct intel_uncore_type nhmex_uncore_ubox = {
243 .name = "ubox",
244 .num_counters = 1,
245 .num_boxes = 1,
246 .perf_ctr_bits = 48,
247 .event_ctl = NHMEX_U_MSR_PMON_EV_SEL,
248 .perf_ctr = NHMEX_U_MSR_PMON_CTR,
249 .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK,
250 .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL,
251 .ops = &nhmex_uncore_ops,
252 .format_group = &nhmex_uncore_ubox_format_group
253};
254
255static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
256 &format_attr_event.attr,
257 &format_attr_umask.attr,
258 &format_attr_edge.attr,
259 &format_attr_inv.attr,
260 &format_attr_thresh8.attr,
261 NULL,
262};
263
264static struct attribute_group nhmex_uncore_cbox_format_group = {
265 .name = "format",
266 .attrs = nhmex_uncore_cbox_formats_attr,
267};
268
cb37af77
YZ
269/* msr offset for each instance of cbox */
270static unsigned nhmex_cbox_msr_offsets[] = {
271 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
272};
273
254298c7
YZ
274static struct intel_uncore_type nhmex_uncore_cbox = {
275 .name = "cbox",
276 .num_counters = 6,
cb37af77 277 .num_boxes = 10,
254298c7
YZ
278 .perf_ctr_bits = 48,
279 .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0,
280 .perf_ctr = NHMEX_C0_MSR_PMON_CTR0,
281 .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
282 .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL,
cb37af77 283 .msr_offsets = nhmex_cbox_msr_offsets,
254298c7
YZ
284 .pair_ctr_ctl = 1,
285 .ops = &nhmex_uncore_ops,
286 .format_group = &nhmex_uncore_cbox_format_group
287};
288
289static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
290 INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
291 { /* end: all zeroes */ },
292};
293
294static struct intel_uncore_type nhmex_uncore_wbox = {
295 .name = "wbox",
296 .num_counters = 4,
297 .num_boxes = 1,
298 .perf_ctr_bits = 48,
299 .event_ctl = NHMEX_W_MSR_PMON_CNT0,
300 .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0,
301 .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR,
302 .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL,
303 .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
304 .box_ctl = NHMEX_W_MSR_GLOBAL_CTL,
305 .pair_ctr_ctl = 1,
306 .event_descs = nhmex_uncore_wbox_events,
307 .ops = &nhmex_uncore_ops,
308 .format_group = &nhmex_uncore_cbox_format_group
309};
310
311static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
312{
313 struct hw_perf_event *hwc = &event->hw;
314 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
315 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
316 int ctr, ev_sel;
317
318 ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
319 NHMEX_B_PMON_CTR_SHIFT;
320 ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
321 NHMEX_B_PMON_CTL_EV_SEL_SHIFT;
322
323 /* events that do not use the match/mask registers */
324 if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
325 (ctr == 2 && ev_sel != 0x4) || ctr == 3)
326 return 0;
327
328 if (box->pmu->pmu_idx == 0)
329 reg1->reg = NHMEX_B0_MSR_MATCH;
330 else
331 reg1->reg = NHMEX_B1_MSR_MATCH;
332 reg1->idx = 0;
333 reg1->config = event->attr.config1;
334 reg2->config = event->attr.config2;
335 return 0;
336}
337
338static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
339{
340 struct hw_perf_event *hwc = &event->hw;
341 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
342 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
343
344 if (reg1->idx != EXTRA_REG_NONE) {
345 wrmsrl(reg1->reg, reg1->config);
346 wrmsrl(reg1->reg + 1, reg2->config);
347 }
348 wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
349 (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
350}
351
352/*
353 * The Bbox has 4 counters, but each counter monitors different events.
354 * Use bits 6-7 in the event config to select counter.
355 */
356static struct event_constraint nhmex_uncore_bbox_constraints[] = {
357 EVENT_CONSTRAINT(0 , 1, 0xc0),
358 EVENT_CONSTRAINT(0x40, 2, 0xc0),
359 EVENT_CONSTRAINT(0x80, 4, 0xc0),
360 EVENT_CONSTRAINT(0xc0, 8, 0xc0),
361 EVENT_CONSTRAINT_END,
362};
363
364static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
365 &format_attr_event5.attr,
366 &format_attr_counter.attr,
367 &format_attr_match.attr,
368 &format_attr_mask.attr,
369 NULL,
370};
371
372static struct attribute_group nhmex_uncore_bbox_format_group = {
373 .name = "format",
374 .attrs = nhmex_uncore_bbox_formats_attr,
375};
376
377static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
378 NHMEX_UNCORE_OPS_COMMON_INIT(),
379 .enable_event = nhmex_bbox_msr_enable_event,
380 .hw_config = nhmex_bbox_hw_config,
381 .get_constraint = uncore_get_constraint,
382 .put_constraint = uncore_put_constraint,
383};
384
385static struct intel_uncore_type nhmex_uncore_bbox = {
386 .name = "bbox",
387 .num_counters = 4,
388 .num_boxes = 2,
389 .perf_ctr_bits = 48,
390 .event_ctl = NHMEX_B0_MSR_PMON_CTL0,
391 .perf_ctr = NHMEX_B0_MSR_PMON_CTR0,
392 .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK,
393 .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL,
394 .msr_offset = NHMEX_B_MSR_OFFSET,
395 .pair_ctr_ctl = 1,
396 .num_shared_regs = 1,
397 .constraints = nhmex_uncore_bbox_constraints,
398 .ops = &nhmex_uncore_bbox_ops,
399 .format_group = &nhmex_uncore_bbox_format_group
400};
401
402static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
403{
ebb6cc03
YZ
404 struct hw_perf_event *hwc = &event->hw;
405 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
406 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
254298c7 407
ebb6cc03
YZ
408 /* only TO_R_PROG_EV event uses the match/mask register */
409 if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) !=
410 NHMEX_S_EVENT_TO_R_PROG_EV)
411 return 0;
254298c7
YZ
412
413 if (box->pmu->pmu_idx == 0)
414 reg1->reg = NHMEX_S0_MSR_MM_CFG;
415 else
416 reg1->reg = NHMEX_S1_MSR_MM_CFG;
254298c7 417 reg1->idx = 0;
ebb6cc03
YZ
418 reg1->config = event->attr.config1;
419 reg2->config = event->attr.config2;
254298c7
YZ
420 return 0;
421}
422
423static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
424{
425 struct hw_perf_event *hwc = &event->hw;
426 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
427 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
428
ebb6cc03
YZ
429 if (reg1->idx != EXTRA_REG_NONE) {
430 wrmsrl(reg1->reg, 0);
254298c7
YZ
431 wrmsrl(reg1->reg + 1, reg1->config);
432 wrmsrl(reg1->reg + 2, reg2->config);
433 wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
434 }
435 wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
436}
437
438static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
439 &format_attr_event.attr,
440 &format_attr_umask.attr,
441 &format_attr_edge.attr,
442 &format_attr_inv.attr,
443 &format_attr_thresh8.attr,
254298c7
YZ
444 &format_attr_match.attr,
445 &format_attr_mask.attr,
446 NULL,
447};
448
449static struct attribute_group nhmex_uncore_sbox_format_group = {
450 .name = "format",
451 .attrs = nhmex_uncore_sbox_formats_attr,
452};
453
454static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
455 NHMEX_UNCORE_OPS_COMMON_INIT(),
456 .enable_event = nhmex_sbox_msr_enable_event,
457 .hw_config = nhmex_sbox_hw_config,
458 .get_constraint = uncore_get_constraint,
459 .put_constraint = uncore_put_constraint,
460};
461
462static struct intel_uncore_type nhmex_uncore_sbox = {
463 .name = "sbox",
464 .num_counters = 4,
465 .num_boxes = 2,
466 .perf_ctr_bits = 48,
467 .event_ctl = NHMEX_S0_MSR_PMON_CTL0,
468 .perf_ctr = NHMEX_S0_MSR_PMON_CTR0,
469 .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
470 .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL,
471 .msr_offset = NHMEX_S_MSR_OFFSET,
472 .pair_ctr_ctl = 1,
473 .num_shared_regs = 1,
474 .ops = &nhmex_uncore_sbox_ops,
475 .format_group = &nhmex_uncore_sbox_format_group
476};
477
478enum {
479 EXTRA_REG_NHMEX_M_FILTER,
480 EXTRA_REG_NHMEX_M_DSP,
481 EXTRA_REG_NHMEX_M_ISS,
482 EXTRA_REG_NHMEX_M_MAP,
483 EXTRA_REG_NHMEX_M_MSC_THR,
484 EXTRA_REG_NHMEX_M_PGT,
485 EXTRA_REG_NHMEX_M_PLD,
486 EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
487};
488
489static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
490 MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
491 MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
492 MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
493 MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
494 /* event 0xa uses two extra registers */
495 MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
496 MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
497 MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
498 /* events 0xd ~ 0x10 use the same extra register */
499 MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
500 MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
501 MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
502 MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
503 MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
504 MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
505 MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
506 MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
507 MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
508 EVENT_EXTRA_END
509};
510
cb37af77 511/* Nehalem-EX or Westmere-EX ? */
46bdd905 512static bool uncore_nhmex;
cb37af77 513
254298c7
YZ
514static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
515{
516 struct intel_uncore_extra_reg *er;
517 unsigned long flags;
518 bool ret = false;
519 u64 mask;
520
521 if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
522 er = &box->shared_regs[idx];
523 raw_spin_lock_irqsave(&er->lock, flags);
524 if (!atomic_read(&er->ref) || er->config == config) {
525 atomic_inc(&er->ref);
526 er->config = config;
527 ret = true;
528 }
529 raw_spin_unlock_irqrestore(&er->lock, flags);
530
531 return ret;
532 }
533 /*
534 * The ZDP_CTL_FVC MSR has 4 fields which are used to control
535 * events 0xd ~ 0x10. Besides these 4 fields, there are additional
536 * fields which are shared.
537 */
538 idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
539 if (WARN_ON_ONCE(idx >= 4))
540 return false;
541
542 /* mask of the shared fields */
cb37af77
YZ
543 if (uncore_nhmex)
544 mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
545 else
546 mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
254298c7
YZ
547 er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
548
549 raw_spin_lock_irqsave(&er->lock, flags);
550 /* add mask of the non-shared field if it's in use */
cb37af77
YZ
551 if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
552 if (uncore_nhmex)
553 mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
554 else
555 mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
556 }
254298c7
YZ
557
558 if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
559 atomic_add(1 << (idx * 8), &er->ref);
cb37af77
YZ
560 if (uncore_nhmex)
561 mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
562 NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
563 else
564 mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
565 WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
254298c7
YZ
566 er->config &= ~mask;
567 er->config |= (config & mask);
568 ret = true;
569 }
570 raw_spin_unlock_irqrestore(&er->lock, flags);
571
572 return ret;
573}
574
575static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
576{
577 struct intel_uncore_extra_reg *er;
578
579 if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
580 er = &box->shared_regs[idx];
581 atomic_dec(&er->ref);
582 return;
583 }
584
585 idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
586 er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
587 atomic_sub(1 << (idx * 8), &er->ref);
588}
589
46bdd905 590static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
254298c7
YZ
591{
592 struct hw_perf_event *hwc = &event->hw;
593 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
13acac30 594 u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
254298c7
YZ
595 u64 config = reg1->config;
596
597 /* get the non-shared control bits and shift them */
598 idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
cb37af77
YZ
599 if (uncore_nhmex)
600 config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
601 else
602 config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
254298c7
YZ
603 if (new_idx > orig_idx) {
604 idx = new_idx - orig_idx;
605 config <<= 3 * idx;
606 } else {
607 idx = orig_idx - new_idx;
608 config >>= 3 * idx;
609 }
610
611 /* add the shared control bits back */
cb37af77
YZ
612 if (uncore_nhmex)
613 config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
614 else
615 config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
254298c7
YZ
616 config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
617 if (modify) {
618 /* adjust the main event selector */
619 if (new_idx > orig_idx)
620 hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
621 else
622 hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
623 reg1->config = config;
624 reg1->idx = ~0xff | new_idx;
625 }
626 return config;
627}
628
629static struct event_constraint *
630nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
631{
632 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
633 struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
634 int i, idx[2], alloc = 0;
635 u64 config1 = reg1->config;
636
637 idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
638 idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
639again:
640 for (i = 0; i < 2; i++) {
641 if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
642 idx[i] = 0xff;
643
644 if (idx[i] == 0xff)
645 continue;
646
647 if (!nhmex_mbox_get_shared_reg(box, idx[i],
648 __BITS_VALUE(config1, i, 32)))
649 goto fail;
650 alloc |= (0x1 << i);
651 }
652
653 /* for the match/mask registers */
ebb6cc03
YZ
654 if (reg2->idx != EXTRA_REG_NONE &&
655 (uncore_box_is_fake(box) || !reg2->alloc) &&
254298c7
YZ
656 !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
657 goto fail;
658
659 /*
660 * If it's a fake box -- as per validate_{group,event}() we
661 * shouldn't touch event state and we can avoid doing so
662 * since both will only call get_event_constraints() once
663 * on each event, this avoids the need for reg->alloc.
664 */
665 if (!uncore_box_is_fake(box)) {
666 if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
667 nhmex_mbox_alter_er(event, idx[0], true);
668 reg1->alloc |= alloc;
ebb6cc03
YZ
669 if (reg2->idx != EXTRA_REG_NONE)
670 reg2->alloc = 1;
254298c7
YZ
671 }
672 return NULL;
673fail:
674 if (idx[0] != 0xff && !(alloc & 0x1) &&
675 idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
676 /*
677 * events 0xd ~ 0x10 are functional identical, but are
678 * controlled by different fields in the ZDP_CTL_FVC
679 * register. If we failed to take one field, try the
680 * rest 3 choices.
7c94ee2e 681 */
254298c7
YZ
682 BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
683 idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
684 idx[0] = (idx[0] + 1) % 4;
685 idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
686 if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
687 config1 = nhmex_mbox_alter_er(event, idx[0], false);
688 goto again;
7c94ee2e 689 }
254298c7 690 }
7c94ee2e 691
254298c7
YZ
692 if (alloc & 0x1)
693 nhmex_mbox_put_shared_reg(box, idx[0]);
694 if (alloc & 0x2)
695 nhmex_mbox_put_shared_reg(box, idx[1]);
514b2346 696 return &uncore_constraint_empty;
254298c7 697}
fcde10e9 698
254298c7 699static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
fcde10e9 700{
254298c7
YZ
701 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
702 struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
fcde10e9 703
254298c7
YZ
704 if (uncore_box_is_fake(box))
705 return;
706
707 if (reg1->alloc & 0x1)
708 nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
709 if (reg1->alloc & 0x2)
710 nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
711 reg1->alloc = 0;
712
713 if (reg2->alloc) {
714 nhmex_mbox_put_shared_reg(box, reg2->idx);
715 reg2->alloc = 0;
716 }
fcde10e9
YZ
717}
718
254298c7 719static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
fcde10e9 720{
254298c7
YZ
721 if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
722 return er->idx;
723 return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
fcde10e9
YZ
724}
725
254298c7 726static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
fcde10e9 727{
254298c7
YZ
728 struct intel_uncore_type *type = box->pmu->type;
729 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
730 struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
731 struct extra_reg *er;
732 unsigned msr;
733 int reg_idx = 0;
254298c7
YZ
734 /*
735 * The mbox events may require 2 extra MSRs at the most. But only
736 * the lower 32 bits in these MSRs are significant, so we can use
737 * config1 to pass two MSRs' config.
738 */
739 for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
740 if (er->event != (event->hw.config & er->config_mask))
741 continue;
742 if (event->attr.config1 & ~er->valid_mask)
743 return -EINVAL;
254298c7
YZ
744
745 msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
746 if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
747 return -EINVAL;
748
749 /* always use the 32~63 bits to pass the PLD config */
750 if (er->idx == EXTRA_REG_NHMEX_M_PLD)
751 reg_idx = 1;
ebb6cc03
YZ
752 else if (WARN_ON_ONCE(reg_idx > 0))
753 return -EINVAL;
254298c7
YZ
754
755 reg1->idx &= ~(0xff << (reg_idx * 8));
756 reg1->reg &= ~(0xffff << (reg_idx * 16));
757 reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
758 reg1->reg |= msr << (reg_idx * 16);
759 reg1->config = event->attr.config1;
760 reg_idx++;
761 }
ebb6cc03
YZ
762 /*
763 * The mbox only provides ability to perform address matching
764 * for the PLD events.
765 */
766 if (reg_idx == 2) {
767 reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
768 if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
769 reg2->config = event->attr.config2;
770 else
771 reg2->config = ~0ULL;
772 if (box->pmu->pmu_idx == 0)
773 reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
774 else
775 reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
776 }
254298c7 777 return 0;
fcde10e9
YZ
778}
779
254298c7 780static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
fcde10e9 781{
254298c7
YZ
782 struct intel_uncore_extra_reg *er;
783 unsigned long flags;
784 u64 config;
785
786 if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
787 return box->shared_regs[idx].config;
788
789 er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
790 raw_spin_lock_irqsave(&er->lock, flags);
791 config = er->config;
792 raw_spin_unlock_irqrestore(&er->lock, flags);
793 return config;
794}
795
796static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
797{
798 struct hw_perf_event *hwc = &event->hw;
799 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
800 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
801 int idx;
802
803 idx = __BITS_VALUE(reg1->idx, 0, 8);
804 if (idx != 0xff)
805 wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
806 nhmex_mbox_shared_reg_config(box, idx));
807 idx = __BITS_VALUE(reg1->idx, 1, 8);
808 if (idx != 0xff)
809 wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
810 nhmex_mbox_shared_reg_config(box, idx));
811
ebb6cc03
YZ
812 if (reg2->idx != EXTRA_REG_NONE) {
813 wrmsrl(reg2->reg, 0);
814 if (reg2->config != ~0ULL) {
815 wrmsrl(reg2->reg + 1,
816 reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
817 wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
818 (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
819 wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
820 }
fcde10e9 821 }
254298c7
YZ
822
823 wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
fcde10e9
YZ
824}
825
ebb6cc03
YZ
826DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3");
827DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5");
828DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6");
829DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7");
830DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13");
831DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21");
832DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63");
833DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33");
834DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61");
835DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31");
836DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31");
837DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31");
838DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31");
839DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31");
840DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31");
841DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63");
254298c7
YZ
842
843static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
844 &format_attr_count_mode.attr,
845 &format_attr_storage_mode.attr,
846 &format_attr_wrap_mode.attr,
847 &format_attr_flag_mode.attr,
848 &format_attr_inc_sel.attr,
849 &format_attr_set_flag_sel.attr,
ebb6cc03 850 &format_attr_filter_cfg_en.attr,
254298c7
YZ
851 &format_attr_filter_match.attr,
852 &format_attr_filter_mask.attr,
853 &format_attr_dsp.attr,
854 &format_attr_thr.attr,
855 &format_attr_fvc.attr,
856 &format_attr_pgt.attr,
857 &format_attr_map.attr,
858 &format_attr_iss.attr,
859 &format_attr_pld.attr,
fcde10e9
YZ
860 NULL,
861};
862
254298c7
YZ
863static struct attribute_group nhmex_uncore_mbox_format_group = {
864 .name = "format",
865 .attrs = nhmex_uncore_mbox_formats_attr,
fcde10e9
YZ
866};
867
254298c7
YZ
868static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
869 INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
870 INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
871 { /* end: all zeroes */ },
fcde10e9
YZ
872};
873
cb37af77
YZ
874static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
875 INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
876 INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
877 { /* end: all zeroes */ },
878};
879
254298c7
YZ
880static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
881 NHMEX_UNCORE_OPS_COMMON_INIT(),
882 .enable_event = nhmex_mbox_msr_enable_event,
883 .hw_config = nhmex_mbox_hw_config,
884 .get_constraint = nhmex_mbox_get_constraint,
885 .put_constraint = nhmex_mbox_put_constraint,
fcde10e9
YZ
886};
887
254298c7
YZ
888static struct intel_uncore_type nhmex_uncore_mbox = {
889 .name = "mbox",
890 .num_counters = 6,
891 .num_boxes = 2,
892 .perf_ctr_bits = 48,
893 .event_ctl = NHMEX_M0_MSR_PMU_CTL0,
894 .perf_ctr = NHMEX_M0_MSR_PMU_CNT0,
895 .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK,
896 .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL,
897 .msr_offset = NHMEX_M_MSR_OFFSET,
898 .pair_ctr_ctl = 1,
899 .num_shared_regs = 8,
900 .event_descs = nhmex_uncore_mbox_events,
901 .ops = &nhmex_uncore_mbox_ops,
902 .format_group = &nhmex_uncore_mbox_format_group,
fcde10e9
YZ
903};
904
46bdd905 905static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
254298c7
YZ
906{
907 struct hw_perf_event *hwc = &event->hw;
908 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
fcde10e9 909
ebb6cc03 910 /* adjust the main event selector and extra register index */
254298c7
YZ
911 if (reg1->idx % 2) {
912 reg1->idx--;
913 hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
914 } else {
915 reg1->idx++;
916 hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
917 }
918
ebb6cc03 919 /* adjust extra register config */
254298c7 920 switch (reg1->idx % 6) {
254298c7 921 case 2:
ebb6cc03 922 /* shift the 8~15 bits to the 0~7 bits */
254298c7
YZ
923 reg1->config >>= 8;
924 break;
925 case 3:
ebb6cc03 926 /* shift the 0~7 bits to the 8~15 bits */
254298c7
YZ
927 reg1->config <<= 8;
928 break;
254298c7
YZ
929 };
930}
931
932/*
933 * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
934 * An event set consists of 6 events, the 3rd and 4th events in
935 * an event set use the same extra register. So an event set uses
936 * 5 extra registers.
937 */
938static struct event_constraint *
939nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
fcde10e9 940{
254298c7
YZ
941 struct hw_perf_event *hwc = &event->hw;
942 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
943 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
944 struct intel_uncore_extra_reg *er;
945 unsigned long flags;
946 int idx, er_idx;
947 u64 config1;
948 bool ok = false;
949
950 if (!uncore_box_is_fake(box) && reg1->alloc)
951 return NULL;
952
953 idx = reg1->idx % 6;
954 config1 = reg1->config;
955again:
956 er_idx = idx;
957 /* the 3rd and 4th events use the same extra register */
958 if (er_idx > 2)
959 er_idx--;
960 er_idx += (reg1->idx / 6) * 5;
961
962 er = &box->shared_regs[er_idx];
963 raw_spin_lock_irqsave(&er->lock, flags);
964 if (idx < 2) {
965 if (!atomic_read(&er->ref) || er->config == reg1->config) {
966 atomic_inc(&er->ref);
967 er->config = reg1->config;
968 ok = true;
969 }
970 } else if (idx == 2 || idx == 3) {
971 /*
972 * these two events use different fields in a extra register,
973 * the 0~7 bits and the 8~15 bits respectively.
974 */
975 u64 mask = 0xff << ((idx - 2) * 8);
976 if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
977 !((er->config ^ config1) & mask)) {
978 atomic_add(1 << ((idx - 2) * 8), &er->ref);
979 er->config &= ~mask;
980 er->config |= config1 & mask;
981 ok = true;
982 }
983 } else {
984 if (!atomic_read(&er->ref) ||
985 (er->config == (hwc->config >> 32) &&
986 er->config1 == reg1->config &&
987 er->config2 == reg2->config)) {
988 atomic_inc(&er->ref);
989 er->config = (hwc->config >> 32);
990 er->config1 = reg1->config;
991 er->config2 = reg2->config;
992 ok = true;
993 }
994 }
995 raw_spin_unlock_irqrestore(&er->lock, flags);
996
997 if (!ok) {
998 /*
999 * The Rbox events are always in pairs. The paired
1000 * events are functional identical, but use different
1001 * extra registers. If we failed to take an extra
1002 * register, try the alternative.
1003 */
2172c1f5 1004 idx ^= 1;
254298c7
YZ
1005 if (idx != reg1->idx % 6) {
1006 if (idx == 2)
1007 config1 >>= 8;
1008 else if (idx == 3)
1009 config1 <<= 8;
1010 goto again;
1011 }
1012 } else {
1013 if (!uncore_box_is_fake(box)) {
1014 if (idx != reg1->idx % 6)
1015 nhmex_rbox_alter_er(box, event);
1016 reg1->alloc = 1;
1017 }
1018 return NULL;
1019 }
514b2346 1020 return &uncore_constraint_empty;
fcde10e9
YZ
1021}
1022
254298c7 1023static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
fcde10e9 1024{
254298c7
YZ
1025 struct intel_uncore_extra_reg *er;
1026 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1027 int idx, er_idx;
1028
1029 if (uncore_box_is_fake(box) || !reg1->alloc)
1030 return;
1031
1032 idx = reg1->idx % 6;
1033 er_idx = idx;
1034 if (er_idx > 2)
1035 er_idx--;
1036 er_idx += (reg1->idx / 6) * 5;
1037
1038 er = &box->shared_regs[er_idx];
1039 if (idx == 2 || idx == 3)
1040 atomic_sub(1 << ((idx - 2) * 8), &er->ref);
1041 else
1042 atomic_dec(&er->ref);
1043
1044 reg1->alloc = 0;
fcde10e9
YZ
1045}
1046
254298c7 1047static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
fcde10e9
YZ
1048{
1049 struct hw_perf_event *hwc = &event->hw;
254298c7
YZ
1050 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1051 struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
ebb6cc03 1052 int idx;
fcde10e9 1053
254298c7
YZ
1054 idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
1055 NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
1056 if (idx >= 0x18)
1057 return -EINVAL;
1058
1059 reg1->idx = idx;
1060 reg1->config = event->attr.config1;
1061
ebb6cc03 1062 switch (idx % 6) {
254298c7
YZ
1063 case 4:
1064 case 5:
254298c7 1065 hwc->config |= event->attr.config & (~0ULL << 32);
ebb6cc03 1066 reg2->config = event->attr.config2;
254298c7
YZ
1067 break;
1068 };
1069 return 0;
fcde10e9
YZ
1070}
1071
254298c7
YZ
1072static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1073{
1074 struct hw_perf_event *hwc = &event->hw;
1075 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1076 struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
ebb6cc03 1077 int idx, port;
254298c7 1078
ebb6cc03
YZ
1079 idx = reg1->idx;
1080 port = idx / 6 + box->pmu->pmu_idx * 4;
254298c7 1081
ebb6cc03 1082 switch (idx % 6) {
254298c7 1083 case 0:
ebb6cc03
YZ
1084 wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config);
1085 break;
254298c7 1086 case 1:
ebb6cc03 1087 wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config);
254298c7
YZ
1088 break;
1089 case 2:
1090 case 3:
ebb6cc03 1091 wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port),
46bdd905 1092 uncore_shared_reg_config(box, 2 + (idx / 6) * 5));
254298c7
YZ
1093 break;
1094 case 4:
ebb6cc03
YZ
1095 wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port),
1096 hwc->config >> 32);
1097 wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config);
1098 wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config);
1099 break;
254298c7 1100 case 5:
ebb6cc03
YZ
1101 wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port),
1102 hwc->config >> 32);
1103 wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config);
1104 wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config);
254298c7
YZ
1105 break;
1106 };
1107
1108 wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
1109 (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
1110}
1111
ebb6cc03
YZ
1112DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63");
1113DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63");
254298c7
YZ
1114DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
1115DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
1116DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
1117
1118static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
1119 &format_attr_event5.attr,
1120 &format_attr_xbr_mm_cfg.attr,
1121 &format_attr_xbr_match.attr,
1122 &format_attr_xbr_mask.attr,
1123 &format_attr_qlx_cfg.attr,
1124 &format_attr_iperf_cfg.attr,
fcde10e9
YZ
1125 NULL,
1126};
1127
254298c7 1128static struct attribute_group nhmex_uncore_rbox_format_group = {
fcde10e9 1129 .name = "format",
254298c7 1130 .attrs = nhmex_uncore_rbox_formats_attr,
fcde10e9
YZ
1131};
1132
254298c7
YZ
1133static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
1134 INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"),
1135 INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"),
1136 INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"),
1137 INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"),
1138 INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"),
1139 INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"),
fcde10e9
YZ
1140 { /* end: all zeroes */ },
1141};
1142
254298c7
YZ
1143static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
1144 NHMEX_UNCORE_OPS_COMMON_INIT(),
1145 .enable_event = nhmex_rbox_msr_enable_event,
1146 .hw_config = nhmex_rbox_hw_config,
1147 .get_constraint = nhmex_rbox_get_constraint,
1148 .put_constraint = nhmex_rbox_put_constraint,
fcde10e9
YZ
1149};
1150
254298c7
YZ
1151static struct intel_uncore_type nhmex_uncore_rbox = {
1152 .name = "rbox",
1153 .num_counters = 8,
1154 .num_boxes = 2,
1155 .perf_ctr_bits = 48,
1156 .event_ctl = NHMEX_R_MSR_PMON_CTL0,
1157 .perf_ctr = NHMEX_R_MSR_PMON_CNT0,
1158 .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK,
1159 .box_ctl = NHMEX_R_MSR_GLOBAL_CTL,
1160 .msr_offset = NHMEX_R_MSR_OFFSET,
1161 .pair_ctr_ctl = 1,
1162 .num_shared_regs = 20,
1163 .event_descs = nhmex_uncore_rbox_events,
1164 .ops = &nhmex_uncore_rbox_ops,
1165 .format_group = &nhmex_uncore_rbox_format_group
fcde10e9
YZ
1166};
1167
254298c7
YZ
1168static struct intel_uncore_type *nhmex_msr_uncores[] = {
1169 &nhmex_uncore_ubox,
1170 &nhmex_uncore_cbox,
1171 &nhmex_uncore_bbox,
1172 &nhmex_uncore_sbox,
1173 &nhmex_uncore_mbox,
1174 &nhmex_uncore_rbox,
1175 &nhmex_uncore_wbox,
fcde10e9
YZ
1176 NULL,
1177};
254298c7 1178/* end of Nehalem-EX uncore support */
fcde10e9 1179
254298c7 1180static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx)
087bfbb0
YZ
1181{
1182 struct hw_perf_event *hwc = &event->hw;
1183
1184 hwc->idx = idx;
1185 hwc->last_tag = ++box->tags[idx];
1186
1187 if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
14371cce
YZ
1188 hwc->event_base = uncore_fixed_ctr(box);
1189 hwc->config_base = uncore_fixed_ctl(box);
087bfbb0
YZ
1190 return;
1191 }
1192
14371cce
YZ
1193 hwc->config_base = uncore_event_ctl(box, hwc->idx);
1194 hwc->event_base = uncore_perf_ctr(box, hwc->idx);
087bfbb0
YZ
1195}
1196
514b2346 1197void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
087bfbb0
YZ
1198{
1199 u64 prev_count, new_count, delta;
1200 int shift;
1201
1202 if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
1203 shift = 64 - uncore_fixed_ctr_bits(box);
1204 else
1205 shift = 64 - uncore_perf_ctr_bits(box);
1206
1207 /* the hrtimer might modify the previous event value */
1208again:
1209 prev_count = local64_read(&event->hw.prev_count);
1210 new_count = uncore_read_counter(box, event);
1211 if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
1212 goto again;
1213
1214 delta = (new_count << shift) - (prev_count << shift);
1215 delta >>= shift;
1216
1217 local64_add(delta, &event->count);
1218}
1219
1220/*
1221 * The overflow interrupt is unavailable for SandyBridge-EP, is broken
1222 * for SandyBridge. So we use hrtimer to periodically poll the counter
1223 * to avoid overflow.
1224 */
1225static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
1226{
1227 struct intel_uncore_box *box;
ced2efb0 1228 struct perf_event *event;
087bfbb0
YZ
1229 unsigned long flags;
1230 int bit;
1231
1232 box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
1233 if (!box->n_active || box->cpu != smp_processor_id())
1234 return HRTIMER_NORESTART;
1235 /*
1236 * disable local interrupt to prevent uncore_pmu_event_start/stop
1237 * to interrupt the update process
1238 */
1239 local_irq_save(flags);
1240
ced2efb0
SE
1241 /*
1242 * handle boxes with an active event list as opposed to active
1243 * counters
1244 */
1245 list_for_each_entry(event, &box->active_list, active_entry) {
1246 uncore_perf_event_update(box, event);
1247 }
1248
087bfbb0
YZ
1249 for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
1250 uncore_perf_event_update(box, box->events[bit]);
1251
1252 local_irq_restore(flags);
1253
79859cce 1254 hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration));
087bfbb0
YZ
1255 return HRTIMER_RESTART;
1256}
1257
514b2346 1258void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
087bfbb0
YZ
1259{
1260 __hrtimer_start_range_ns(&box->hrtimer,
79859cce 1261 ns_to_ktime(box->hrtimer_duration), 0,
087bfbb0
YZ
1262 HRTIMER_MODE_REL_PINNED, 0);
1263}
1264
514b2346 1265void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
087bfbb0
YZ
1266{
1267 hrtimer_cancel(&box->hrtimer);
1268}
1269
1270static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
1271{
1272 hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1273 box->hrtimer.function = uncore_pmu_hrtimer;
1274}
1275
73c4427c 1276static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int node)
087bfbb0
YZ
1277{
1278 struct intel_uncore_box *box;
6a67943a 1279 int i, size;
087bfbb0 1280
254298c7 1281 size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
6a67943a 1282
73c4427c 1283 box = kzalloc_node(size, GFP_KERNEL, node);
087bfbb0
YZ
1284 if (!box)
1285 return NULL;
1286
6a67943a
YZ
1287 for (i = 0; i < type->num_shared_regs; i++)
1288 raw_spin_lock_init(&box->shared_regs[i].lock);
1289
087bfbb0
YZ
1290 uncore_pmu_init_hrtimer(box);
1291 atomic_set(&box->refcnt, 1);
1292 box->cpu = -1;
1293 box->phys_id = -1;
1294
79859cce
SE
1295 /* set default hrtimer timeout */
1296 box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
087bfbb0 1297
ced2efb0 1298 INIT_LIST_HEAD(&box->active_list);
14371cce 1299
087bfbb0 1300 return box;
087bfbb0
YZ
1301}
1302
254298c7
YZ
1303static int
1304uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp)
087bfbb0
YZ
1305{
1306 struct perf_event *event;
1307 int n, max_count;
1308
1309 max_count = box->pmu->type->num_counters;
1310 if (box->pmu->type->fixed_ctl)
1311 max_count++;
1312
1313 if (box->n_events >= max_count)
1314 return -EINVAL;
1315
1316 n = box->n_events;
1317 box->event_list[n] = leader;
1318 n++;
1319 if (!dogrp)
1320 return n;
1321
1322 list_for_each_entry(event, &leader->sibling_list, group_entry) {
1323 if (event->state <= PERF_EVENT_STATE_OFF)
1324 continue;
1325
1326 if (n >= max_count)
1327 return -EINVAL;
1328
1329 box->event_list[n] = event;
1330 n++;
1331 }
1332 return n;
1333}
1334
1335static struct event_constraint *
254298c7 1336uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
087bfbb0 1337{
6a67943a 1338 struct intel_uncore_type *type = box->pmu->type;
087bfbb0
YZ
1339 struct event_constraint *c;
1340
6a67943a
YZ
1341 if (type->ops->get_constraint) {
1342 c = type->ops->get_constraint(box, event);
1343 if (c)
1344 return c;
1345 }
1346
dbc33f70 1347 if (event->attr.config == UNCORE_FIXED_EVENT)
514b2346 1348 return &uncore_constraint_fixed;
087bfbb0
YZ
1349
1350 if (type->constraints) {
1351 for_each_event_constraint(c, type->constraints) {
1352 if ((event->hw.config & c->cmask) == c->code)
1353 return c;
1354 }
1355 }
1356
1357 return &type->unconstrainted;
1358}
1359
254298c7 1360static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
6a67943a
YZ
1361{
1362 if (box->pmu->type->ops->put_constraint)
1363 box->pmu->type->ops->put_constraint(box, event);
1364}
1365
254298c7 1366static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
087bfbb0
YZ
1367{
1368 unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
43b45780 1369 struct event_constraint *c;
6a67943a 1370 int i, wmin, wmax, ret = 0;
087bfbb0
YZ
1371 struct hw_perf_event *hwc;
1372
1373 bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
1374
1375 for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
43b45780 1376 hwc = &box->event_list[i]->hw;
6a67943a 1377 c = uncore_get_event_constraint(box, box->event_list[i]);
43b45780 1378 hwc->constraint = c;
087bfbb0
YZ
1379 wmin = min(wmin, c->weight);
1380 wmax = max(wmax, c->weight);
1381 }
1382
1383 /* fastpath, try to reuse previous register */
1384 for (i = 0; i < n; i++) {
1385 hwc = &box->event_list[i]->hw;
43b45780 1386 c = hwc->constraint;
087bfbb0
YZ
1387
1388 /* never assigned */
1389 if (hwc->idx == -1)
1390 break;
1391
1392 /* constraint still honored */
1393 if (!test_bit(hwc->idx, c->idxmsk))
1394 break;
1395
1396 /* not already used */
1397 if (test_bit(hwc->idx, used_mask))
1398 break;
1399
1400 __set_bit(hwc->idx, used_mask);
6a67943a
YZ
1401 if (assign)
1402 assign[i] = hwc->idx;
087bfbb0 1403 }
087bfbb0 1404 /* slow path */
6a67943a 1405 if (i != n)
43b45780
AH
1406 ret = perf_assign_events(box->event_list, n,
1407 wmin, wmax, assign);
6a67943a
YZ
1408
1409 if (!assign || ret) {
1410 for (i = 0; i < n; i++)
1411 uncore_put_event_constraint(box, box->event_list[i]);
1412 }
087bfbb0
YZ
1413 return ret ? -EINVAL : 0;
1414}
1415
1416static void uncore_pmu_event_start(struct perf_event *event, int flags)
1417{
1418 struct intel_uncore_box *box = uncore_event_to_box(event);
1419 int idx = event->hw.idx;
1420
1421 if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
1422 return;
1423
1424 if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
1425 return;
1426
1427 event->hw.state = 0;
1428 box->events[idx] = event;
1429 box->n_active++;
1430 __set_bit(idx, box->active_mask);
1431
1432 local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
1433 uncore_enable_event(box, event);
1434
1435 if (box->n_active == 1) {
1436 uncore_enable_box(box);
1437 uncore_pmu_start_hrtimer(box);
1438 }
1439}
1440
1441static void uncore_pmu_event_stop(struct perf_event *event, int flags)
1442{
1443 struct intel_uncore_box *box = uncore_event_to_box(event);
1444 struct hw_perf_event *hwc = &event->hw;
1445
1446 if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
1447 uncore_disable_event(box, event);
1448 box->n_active--;
1449 box->events[hwc->idx] = NULL;
1450 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
1451 hwc->state |= PERF_HES_STOPPED;
1452
1453 if (box->n_active == 0) {
1454 uncore_disable_box(box);
1455 uncore_pmu_cancel_hrtimer(box);
1456 }
1457 }
1458
1459 if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
1460 /*
1461 * Drain the remaining delta count out of a event
1462 * that we are disabling:
1463 */
1464 uncore_perf_event_update(box, event);
1465 hwc->state |= PERF_HES_UPTODATE;
1466 }
1467}
1468
1469static int uncore_pmu_event_add(struct perf_event *event, int flags)
1470{
1471 struct intel_uncore_box *box = uncore_event_to_box(event);
1472 struct hw_perf_event *hwc = &event->hw;
1473 int assign[UNCORE_PMC_IDX_MAX];
1474 int i, n, ret;
1475
1476 if (!box)
1477 return -ENODEV;
1478
1479 ret = n = uncore_collect_events(box, event, false);
1480 if (ret < 0)
1481 return ret;
1482
1483 hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
1484 if (!(flags & PERF_EF_START))
1485 hwc->state |= PERF_HES_ARCH;
1486
1487 ret = uncore_assign_events(box, assign, n);
1488 if (ret)
1489 return ret;
1490
1491 /* save events moving to new counters */
1492 for (i = 0; i < box->n_events; i++) {
1493 event = box->event_list[i];
1494 hwc = &event->hw;
1495
1496 if (hwc->idx == assign[i] &&
1497 hwc->last_tag == box->tags[assign[i]])
1498 continue;
1499 /*
1500 * Ensure we don't accidentally enable a stopped
1501 * counter simply because we rescheduled.
1502 */
1503 if (hwc->state & PERF_HES_STOPPED)
1504 hwc->state |= PERF_HES_ARCH;
1505
1506 uncore_pmu_event_stop(event, PERF_EF_UPDATE);
1507 }
1508
1509 /* reprogram moved events into new counters */
1510 for (i = 0; i < n; i++) {
1511 event = box->event_list[i];
1512 hwc = &event->hw;
1513
1514 if (hwc->idx != assign[i] ||
1515 hwc->last_tag != box->tags[assign[i]])
1516 uncore_assign_hw_event(box, event, assign[i]);
1517 else if (i < box->n_events)
1518 continue;
1519
1520 if (hwc->state & PERF_HES_ARCH)
1521 continue;
1522
1523 uncore_pmu_event_start(event, 0);
1524 }
1525 box->n_events = n;
1526
1527 return 0;
1528}
1529
1530static void uncore_pmu_event_del(struct perf_event *event, int flags)
1531{
1532 struct intel_uncore_box *box = uncore_event_to_box(event);
1533 int i;
1534
1535 uncore_pmu_event_stop(event, PERF_EF_UPDATE);
1536
1537 for (i = 0; i < box->n_events; i++) {
1538 if (event == box->event_list[i]) {
6a67943a
YZ
1539 uncore_put_event_constraint(box, event);
1540
087bfbb0
YZ
1541 while (++i < box->n_events)
1542 box->event_list[i - 1] = box->event_list[i];
1543
1544 --box->n_events;
1545 break;
1546 }
1547 }
1548
1549 event->hw.idx = -1;
1550 event->hw.last_tag = ~0ULL;
1551}
1552
514b2346 1553void uncore_pmu_event_read(struct perf_event *event)
087bfbb0
YZ
1554{
1555 struct intel_uncore_box *box = uncore_event_to_box(event);
1556 uncore_perf_event_update(box, event);
1557}
1558
1559/*
1560 * validation ensures the group can be loaded onto the
1561 * PMU if it was the only group available.
1562 */
1563static int uncore_validate_group(struct intel_uncore_pmu *pmu,
1564 struct perf_event *event)
1565{
1566 struct perf_event *leader = event->group_leader;
1567 struct intel_uncore_box *fake_box;
087bfbb0
YZ
1568 int ret = -EINVAL, n;
1569
73c4427c 1570 fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
087bfbb0
YZ
1571 if (!fake_box)
1572 return -ENOMEM;
1573
1574 fake_box->pmu = pmu;
1575 /*
1576 * the event is not yet connected with its
1577 * siblings therefore we must first collect
1578 * existing siblings, then add the new event
1579 * before we can simulate the scheduling
1580 */
1581 n = uncore_collect_events(fake_box, leader, true);
1582 if (n < 0)
1583 goto out;
1584
1585 fake_box->n_events = n;
1586 n = uncore_collect_events(fake_box, event, false);
1587 if (n < 0)
1588 goto out;
1589
1590 fake_box->n_events = n;
1591
6a67943a 1592 ret = uncore_assign_events(fake_box, NULL, n);
087bfbb0
YZ
1593out:
1594 kfree(fake_box);
1595 return ret;
1596}
1597
46bdd905 1598static int uncore_pmu_event_init(struct perf_event *event)
087bfbb0
YZ
1599{
1600 struct intel_uncore_pmu *pmu;
1601 struct intel_uncore_box *box;
1602 struct hw_perf_event *hwc = &event->hw;
1603 int ret;
1604
1605 if (event->attr.type != event->pmu->type)
1606 return -ENOENT;
1607
1608 pmu = uncore_event_to_pmu(event);
1609 /* no device found for this pmu */
1610 if (pmu->func_id < 0)
1611 return -ENOENT;
1612
1613 /*
1614 * Uncore PMU does measure at all privilege level all the time.
1615 * So it doesn't make sense to specify any exclude bits.
1616 */
1617 if (event->attr.exclude_user || event->attr.exclude_kernel ||
1618 event->attr.exclude_hv || event->attr.exclude_idle)
1619 return -EINVAL;
1620
1621 /* Sampling not supported yet */
1622 if (hwc->sample_period)
1623 return -EINVAL;
1624
1625 /*
1626 * Place all uncore events for a particular physical package
1627 * onto a single cpu
1628 */
1629 if (event->cpu < 0)
1630 return -EINVAL;
1631 box = uncore_pmu_to_box(pmu, event->cpu);
1632 if (!box || box->cpu < 0)
1633 return -EINVAL;
1634 event->cpu = box->cpu;
1635
6a67943a
YZ
1636 event->hw.idx = -1;
1637 event->hw.last_tag = ~0ULL;
1638 event->hw.extra_reg.idx = EXTRA_REG_NONE;
ebb6cc03 1639 event->hw.branch_reg.idx = EXTRA_REG_NONE;
6a67943a 1640
087bfbb0
YZ
1641 if (event->attr.config == UNCORE_FIXED_EVENT) {
1642 /* no fixed counter */
1643 if (!pmu->type->fixed_ctl)
1644 return -EINVAL;
1645 /*
1646 * if there is only one fixed counter, only the first pmu
1647 * can access the fixed counter
1648 */
1649 if (pmu->type->single_fixed && pmu->pmu_idx > 0)
1650 return -EINVAL;
dbc33f70
SE
1651
1652 /* fixed counters have event field hardcoded to zero */
1653 hwc->config = 0ULL;
087bfbb0
YZ
1654 } else {
1655 hwc->config = event->attr.config & pmu->type->event_mask;
6a67943a
YZ
1656 if (pmu->type->ops->hw_config) {
1657 ret = pmu->type->ops->hw_config(box, event);
1658 if (ret)
1659 return ret;
1660 }
087bfbb0
YZ
1661 }
1662
087bfbb0
YZ
1663 if (event->group_leader != event)
1664 ret = uncore_validate_group(pmu, event);
1665 else
1666 ret = 0;
1667
1668 return ret;
1669}
1670
314d9f63
YZ
1671static ssize_t uncore_get_attr_cpumask(struct device *dev,
1672 struct device_attribute *attr, char *buf)
1673{
1674 int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &uncore_cpu_mask);
1675
1676 buf[n++] = '\n';
1677 buf[n] = '\0';
1678 return n;
1679}
1680
1681static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
1682
1683static struct attribute *uncore_pmu_attrs[] = {
1684 &dev_attr_cpumask.attr,
1685 NULL,
1686};
1687
1688static struct attribute_group uncore_pmu_attr_group = {
1689 .attrs = uncore_pmu_attrs,
1690};
1691
087bfbb0
YZ
1692static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
1693{
1694 int ret;
1695
d64b25b6
SE
1696 if (!pmu->type->pmu) {
1697 pmu->pmu = (struct pmu) {
1698 .attr_groups = pmu->type->attr_groups,
1699 .task_ctx_nr = perf_invalid_context,
1700 .event_init = uncore_pmu_event_init,
1701 .add = uncore_pmu_event_add,
1702 .del = uncore_pmu_event_del,
1703 .start = uncore_pmu_event_start,
1704 .stop = uncore_pmu_event_stop,
1705 .read = uncore_pmu_event_read,
1706 };
1707 } else {
1708 pmu->pmu = *pmu->type->pmu;
1709 pmu->pmu.attr_groups = pmu->type->attr_groups;
1710 }
087bfbb0
YZ
1711
1712 if (pmu->type->num_boxes == 1) {
1713 if (strlen(pmu->type->name) > 0)
1714 sprintf(pmu->name, "uncore_%s", pmu->type->name);
1715 else
1716 sprintf(pmu->name, "uncore");
1717 } else {
1718 sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
1719 pmu->pmu_idx);
1720 }
1721
1722 ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
1723 return ret;
1724}
1725
1726static void __init uncore_type_exit(struct intel_uncore_type *type)
1727{
1728 int i;
1729
1730 for (i = 0; i < type->num_boxes; i++)
1731 free_percpu(type->pmus[i].box);
1732 kfree(type->pmus);
1733 type->pmus = NULL;
314d9f63
YZ
1734 kfree(type->events_group);
1735 type->events_group = NULL;
087bfbb0
YZ
1736}
1737
cffa59ba 1738static void __init uncore_types_exit(struct intel_uncore_type **types)
14371cce
YZ
1739{
1740 int i;
1741 for (i = 0; types[i]; i++)
1742 uncore_type_exit(types[i]);
1743}
1744
087bfbb0
YZ
1745static int __init uncore_type_init(struct intel_uncore_type *type)
1746{
1747 struct intel_uncore_pmu *pmus;
1b0dac2a 1748 struct attribute_group *attr_group;
087bfbb0
YZ
1749 struct attribute **attrs;
1750 int i, j;
1751
1752 pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
1753 if (!pmus)
1754 return -ENOMEM;
1755
b7b4839d
DJ
1756 type->pmus = pmus;
1757
087bfbb0
YZ
1758 type->unconstrainted = (struct event_constraint)
1759 __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
9fac2cf3 1760 0, type->num_counters, 0, 0);
087bfbb0
YZ
1761
1762 for (i = 0; i < type->num_boxes; i++) {
1763 pmus[i].func_id = -1;
1764 pmus[i].pmu_idx = i;
1765 pmus[i].type = type;
14371cce 1766 INIT_LIST_HEAD(&pmus[i].box_list);
087bfbb0
YZ
1767 pmus[i].box = alloc_percpu(struct intel_uncore_box *);
1768 if (!pmus[i].box)
1769 goto fail;
1770 }
1771
1772 if (type->event_descs) {
1773 i = 0;
1774 while (type->event_descs[i].attr.attr.name)
1775 i++;
1776
1b0dac2a
JSM
1777 attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
1778 sizeof(*attr_group), GFP_KERNEL);
1779 if (!attr_group)
087bfbb0
YZ
1780 goto fail;
1781
1b0dac2a
JSM
1782 attrs = (struct attribute **)(attr_group + 1);
1783 attr_group->name = "events";
1784 attr_group->attrs = attrs;
087bfbb0
YZ
1785
1786 for (j = 0; j < i; j++)
1787 attrs[j] = &type->event_descs[j].attr.attr;
1788
1b0dac2a 1789 type->events_group = attr_group;
087bfbb0
YZ
1790 }
1791
314d9f63 1792 type->pmu_group = &uncore_pmu_attr_group;
087bfbb0
YZ
1793 return 0;
1794fail:
1795 uncore_type_exit(type);
1796 return -ENOMEM;
1797}
1798
1799static int __init uncore_types_init(struct intel_uncore_type **types)
1800{
1801 int i, ret;
1802
1803 for (i = 0; types[i]; i++) {
1804 ret = uncore_type_init(types[i]);
1805 if (ret)
1806 goto fail;
1807 }
1808 return 0;
1809fail:
1810 while (--i >= 0)
1811 uncore_type_exit(types[i]);
1812 return ret;
1813}
1814
14371cce
YZ
1815/*
1816 * add a pci uncore device
1817 */
899396cf 1818static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
14371cce
YZ
1819{
1820 struct intel_uncore_pmu *pmu;
1821 struct intel_uncore_box *box;
899396cf
YZ
1822 struct intel_uncore_type *type;
1823 int phys_id;
14371cce 1824
514b2346 1825 phys_id = uncore_pcibus_to_physid[pdev->bus->number];
14371cce
YZ
1826 if (phys_id < 0)
1827 return -ENODEV;
1828
899396cf 1829 if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
514b2346
YZ
1830 int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
1831 uncore_extra_pci_dev[phys_id][idx] = pdev;
899396cf
YZ
1832 pci_set_drvdata(pdev, NULL);
1833 return 0;
1834 }
1835
514b2346 1836 type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
73c4427c 1837 box = uncore_alloc_box(type, NUMA_NO_NODE);
14371cce
YZ
1838 if (!box)
1839 return -ENOMEM;
1840
1841 /*
1842 * for performance monitoring unit with multiple boxes,
1843 * each box has a different function id.
1844 */
899396cf
YZ
1845 pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
1846 if (pmu->func_id < 0)
1847 pmu->func_id = pdev->devfn;
1848 else
1849 WARN_ON_ONCE(pmu->func_id != pdev->devfn);
14371cce
YZ
1850
1851 box->phys_id = phys_id;
1852 box->pci_dev = pdev;
1853 box->pmu = pmu;
1854 uncore_box_init(box);
1855 pci_set_drvdata(pdev, box);
1856
1857 raw_spin_lock(&uncore_box_lock);
1858 list_add_tail(&box->list, &pmu->box_list);
1859 raw_spin_unlock(&uncore_box_lock);
1860
1861 return 0;
1862}
1863
357398e9 1864static void uncore_pci_remove(struct pci_dev *pdev)
14371cce
YZ
1865{
1866 struct intel_uncore_box *box = pci_get_drvdata(pdev);
899396cf 1867 struct intel_uncore_pmu *pmu;
514b2346 1868 int i, cpu, phys_id = uncore_pcibus_to_physid[pdev->bus->number];
899396cf
YZ
1869
1870 box = pci_get_drvdata(pdev);
1871 if (!box) {
1872 for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
514b2346
YZ
1873 if (uncore_extra_pci_dev[phys_id][i] == pdev) {
1874 uncore_extra_pci_dev[phys_id][i] = NULL;
899396cf
YZ
1875 break;
1876 }
1877 }
1878 WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
1879 return;
1880 }
14371cce 1881
899396cf 1882 pmu = box->pmu;
14371cce
YZ
1883 if (WARN_ON_ONCE(phys_id != box->phys_id))
1884 return;
1885
e850f9c3
YZ
1886 pci_set_drvdata(pdev, NULL);
1887
14371cce
YZ
1888 raw_spin_lock(&uncore_box_lock);
1889 list_del(&box->list);
1890 raw_spin_unlock(&uncore_box_lock);
1891
1892 for_each_possible_cpu(cpu) {
1893 if (*per_cpu_ptr(pmu->box, cpu) == box) {
1894 *per_cpu_ptr(pmu->box, cpu) = NULL;
1895 atomic_dec(&box->refcnt);
1896 }
1897 }
1898
1899 WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
1900 kfree(box);
1901}
1902
14371cce
YZ
1903static int __init uncore_pci_init(void)
1904{
1905 int ret;
1906
1907 switch (boot_cpu_data.x86_model) {
7c94ee2e 1908 case 45: /* Sandy Bridge-EP */
8268fdfc 1909 ret = snbep_uncore_pci_init();
7c94ee2e 1910 break;
e850f9c3 1911 case 62: /* IvyTown */
8268fdfc 1912 ret = ivt_uncore_pci_init();
e850f9c3 1913 break;
b9e1ab6d 1914 case 42: /* Sandy Bridge */
92807ffd 1915 ret = snb_uncore_pci_init();
b9e1ab6d
SE
1916 break;
1917 case 58: /* Ivy Bridge */
92807ffd 1918 ret = ivb_uncore_pci_init();
b9e1ab6d
SE
1919 break;
1920 case 60: /* Haswell */
1921 case 69: /* Haswell Celeron */
92807ffd 1922 ret = hsw_uncore_pci_init();
b9e1ab6d 1923 break;
14371cce
YZ
1924 default:
1925 return 0;
1926 }
1927
92807ffd
YZ
1928 if (ret)
1929 return ret;
1930
514b2346 1931 ret = uncore_types_init(uncore_pci_uncores);
14371cce
YZ
1932 if (ret)
1933 return ret;
1934
1935 uncore_pci_driver->probe = uncore_pci_probe;
1936 uncore_pci_driver->remove = uncore_pci_remove;
1937
1938 ret = pci_register_driver(uncore_pci_driver);
1939 if (ret == 0)
1940 pcidrv_registered = true;
1941 else
514b2346 1942 uncore_types_exit(uncore_pci_uncores);
14371cce
YZ
1943
1944 return ret;
1945}
1946
1947static void __init uncore_pci_exit(void)
1948{
1949 if (pcidrv_registered) {
1950 pcidrv_registered = false;
1951 pci_unregister_driver(uncore_pci_driver);
514b2346 1952 uncore_types_exit(uncore_pci_uncores);
14371cce
YZ
1953 }
1954}
1955
22cc4ccf
YZ
1956/* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
1957static LIST_HEAD(boxes_to_free);
1958
148f9bb8 1959static void uncore_kfree_boxes(void)
22cc4ccf
YZ
1960{
1961 struct intel_uncore_box *box;
1962
1963 while (!list_empty(&boxes_to_free)) {
1964 box = list_entry(boxes_to_free.next,
1965 struct intel_uncore_box, list);
1966 list_del(&box->list);
1967 kfree(box);
1968 }
1969}
1970
148f9bb8 1971static void uncore_cpu_dying(int cpu)
087bfbb0
YZ
1972{
1973 struct intel_uncore_type *type;
1974 struct intel_uncore_pmu *pmu;
1975 struct intel_uncore_box *box;
1976 int i, j;
1977
514b2346
YZ
1978 for (i = 0; uncore_msr_uncores[i]; i++) {
1979 type = uncore_msr_uncores[i];
087bfbb0
YZ
1980 for (j = 0; j < type->num_boxes; j++) {
1981 pmu = &type->pmus[j];
1982 box = *per_cpu_ptr(pmu->box, cpu);
1983 *per_cpu_ptr(pmu->box, cpu) = NULL;
1984 if (box && atomic_dec_and_test(&box->refcnt))
22cc4ccf 1985 list_add(&box->list, &boxes_to_free);
087bfbb0
YZ
1986 }
1987 }
1988}
1989
148f9bb8 1990static int uncore_cpu_starting(int cpu)
087bfbb0
YZ
1991{
1992 struct intel_uncore_type *type;
1993 struct intel_uncore_pmu *pmu;
1994 struct intel_uncore_box *box, *exist;
1995 int i, j, k, phys_id;
1996
1997 phys_id = topology_physical_package_id(cpu);
1998
514b2346
YZ
1999 for (i = 0; uncore_msr_uncores[i]; i++) {
2000 type = uncore_msr_uncores[i];
087bfbb0
YZ
2001 for (j = 0; j < type->num_boxes; j++) {
2002 pmu = &type->pmus[j];
2003 box = *per_cpu_ptr(pmu->box, cpu);
2004 /* called by uncore_cpu_init? */
2005 if (box && box->phys_id >= 0) {
2006 uncore_box_init(box);
2007 continue;
2008 }
2009
2010 for_each_online_cpu(k) {
2011 exist = *per_cpu_ptr(pmu->box, k);
2012 if (exist && exist->phys_id == phys_id) {
2013 atomic_inc(&exist->refcnt);
2014 *per_cpu_ptr(pmu->box, cpu) = exist;
22cc4ccf
YZ
2015 if (box) {
2016 list_add(&box->list,
2017 &boxes_to_free);
2018 box = NULL;
2019 }
087bfbb0
YZ
2020 break;
2021 }
2022 }
2023
2024 if (box) {
2025 box->phys_id = phys_id;
2026 uncore_box_init(box);
2027 }
2028 }
2029 }
2030 return 0;
2031}
2032
148f9bb8 2033static int uncore_cpu_prepare(int cpu, int phys_id)
087bfbb0
YZ
2034{
2035 struct intel_uncore_type *type;
2036 struct intel_uncore_pmu *pmu;
2037 struct intel_uncore_box *box;
2038 int i, j;
2039
514b2346
YZ
2040 for (i = 0; uncore_msr_uncores[i]; i++) {
2041 type = uncore_msr_uncores[i];
087bfbb0
YZ
2042 for (j = 0; j < type->num_boxes; j++) {
2043 pmu = &type->pmus[j];
2044 if (pmu->func_id < 0)
2045 pmu->func_id = j;
2046
73c4427c 2047 box = uncore_alloc_box(type, cpu_to_node(cpu));
087bfbb0
YZ
2048 if (!box)
2049 return -ENOMEM;
2050
2051 box->pmu = pmu;
2052 box->phys_id = phys_id;
2053 *per_cpu_ptr(pmu->box, cpu) = box;
2054 }
2055 }
2056 return 0;
2057}
2058
148f9bb8 2059static void
254298c7 2060uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu)
087bfbb0
YZ
2061{
2062 struct intel_uncore_type *type;
2063 struct intel_uncore_pmu *pmu;
2064 struct intel_uncore_box *box;
2065 int i, j;
2066
2067 for (i = 0; uncores[i]; i++) {
2068 type = uncores[i];
2069 for (j = 0; j < type->num_boxes; j++) {
2070 pmu = &type->pmus[j];
2071 if (old_cpu < 0)
2072 box = uncore_pmu_to_box(pmu, new_cpu);
2073 else
2074 box = uncore_pmu_to_box(pmu, old_cpu);
2075 if (!box)
2076 continue;
2077
2078 if (old_cpu < 0) {
2079 WARN_ON_ONCE(box->cpu != -1);
2080 box->cpu = new_cpu;
2081 continue;
2082 }
2083
2084 WARN_ON_ONCE(box->cpu != old_cpu);
2085 if (new_cpu >= 0) {
2086 uncore_pmu_cancel_hrtimer(box);
2087 perf_pmu_migrate_context(&pmu->pmu,
2088 old_cpu, new_cpu);
2089 box->cpu = new_cpu;
2090 } else {
2091 box->cpu = -1;
2092 }
2093 }
2094 }
2095}
2096
148f9bb8 2097static void uncore_event_exit_cpu(int cpu)
087bfbb0
YZ
2098{
2099 int i, phys_id, target;
2100
2101 /* if exiting cpu is used for collecting uncore events */
2102 if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
2103 return;
2104
2105 /* find a new cpu to collect uncore events */
2106 phys_id = topology_physical_package_id(cpu);
2107 target = -1;
2108 for_each_online_cpu(i) {
2109 if (i == cpu)
2110 continue;
2111 if (phys_id == topology_physical_package_id(i)) {
2112 target = i;
2113 break;
2114 }
2115 }
2116
2117 /* migrate uncore events to the new cpu */
2118 if (target >= 0)
2119 cpumask_set_cpu(target, &uncore_cpu_mask);
2120
514b2346
YZ
2121 uncore_change_context(uncore_msr_uncores, cpu, target);
2122 uncore_change_context(uncore_pci_uncores, cpu, target);
087bfbb0
YZ
2123}
2124
148f9bb8 2125static void uncore_event_init_cpu(int cpu)
087bfbb0
YZ
2126{
2127 int i, phys_id;
2128
2129 phys_id = topology_physical_package_id(cpu);
2130 for_each_cpu(i, &uncore_cpu_mask) {
2131 if (phys_id == topology_physical_package_id(i))
2132 return;
2133 }
2134
2135 cpumask_set_cpu(cpu, &uncore_cpu_mask);
2136
514b2346
YZ
2137 uncore_change_context(uncore_msr_uncores, -1, cpu);
2138 uncore_change_context(uncore_pci_uncores, -1, cpu);
087bfbb0
YZ
2139}
2140
148f9bb8
PG
2141static int uncore_cpu_notifier(struct notifier_block *self,
2142 unsigned long action, void *hcpu)
087bfbb0
YZ
2143{
2144 unsigned int cpu = (long)hcpu;
2145
2146 /* allocate/free data structure for uncore box */
2147 switch (action & ~CPU_TASKS_FROZEN) {
2148 case CPU_UP_PREPARE:
2149 uncore_cpu_prepare(cpu, -1);
2150 break;
2151 case CPU_STARTING:
2152 uncore_cpu_starting(cpu);
2153 break;
2154 case CPU_UP_CANCELED:
2155 case CPU_DYING:
2156 uncore_cpu_dying(cpu);
2157 break;
22cc4ccf
YZ
2158 case CPU_ONLINE:
2159 case CPU_DEAD:
2160 uncore_kfree_boxes();
2161 break;
087bfbb0
YZ
2162 default:
2163 break;
2164 }
2165
2166 /* select the cpu that collects uncore events */
2167 switch (action & ~CPU_TASKS_FROZEN) {
2168 case CPU_DOWN_FAILED:
2169 case CPU_STARTING:
2170 uncore_event_init_cpu(cpu);
2171 break;
2172 case CPU_DOWN_PREPARE:
2173 uncore_event_exit_cpu(cpu);
2174 break;
2175 default:
2176 break;
2177 }
2178
2179 return NOTIFY_OK;
2180}
2181
148f9bb8 2182static struct notifier_block uncore_cpu_nb = {
254298c7 2183 .notifier_call = uncore_cpu_notifier,
087bfbb0
YZ
2184 /*
2185 * to migrate uncore events, our notifier should be executed
2186 * before perf core's notifier.
2187 */
254298c7 2188 .priority = CPU_PRI_PERF + 1,
087bfbb0
YZ
2189};
2190
2191static void __init uncore_cpu_setup(void *dummy)
2192{
2193 uncore_cpu_starting(smp_processor_id());
2194}
2195
2196static int __init uncore_cpu_init(void)
2197{
411cf180 2198 int ret, max_cores;
087bfbb0 2199
42089697 2200 max_cores = boot_cpu_data.x86_max_cores;
087bfbb0 2201 switch (boot_cpu_data.x86_model) {
fcde10e9
YZ
2202 case 26: /* Nehalem */
2203 case 30:
2204 case 37: /* Westmere */
2205 case 44:
92807ffd 2206 nhm_uncore_cpu_init();
fcde10e9
YZ
2207 break;
2208 case 42: /* Sandy Bridge */
9a6bc143 2209 case 58: /* Ivy Bridge */
92807ffd 2210 snb_uncore_cpu_init();
fcde10e9 2211 break;
80e217e9 2212 case 45: /* Sandy Bridge-EP */
8268fdfc 2213 snbep_uncore_cpu_init();
7c94ee2e 2214 break;
cb37af77
YZ
2215 case 46: /* Nehalem-EX */
2216 uncore_nhmex = true;
2217 case 47: /* Westmere-EX aka. Xeon E7 */
2218 if (!uncore_nhmex)
2219 nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
2220 if (nhmex_uncore_cbox.num_boxes > max_cores)
2221 nhmex_uncore_cbox.num_boxes = max_cores;
514b2346 2222 uncore_msr_uncores = nhmex_msr_uncores;
254298c7 2223 break;
e850f9c3 2224 case 62: /* IvyTown */
8268fdfc 2225 ivt_uncore_cpu_init();
e850f9c3
YZ
2226 break;
2227
087bfbb0
YZ
2228 default:
2229 return 0;
2230 }
2231
514b2346 2232 ret = uncore_types_init(uncore_msr_uncores);
087bfbb0
YZ
2233 if (ret)
2234 return ret;
2235
087bfbb0
YZ
2236 return 0;
2237}
2238
2239static int __init uncore_pmus_register(void)
2240{
2241 struct intel_uncore_pmu *pmu;
2242 struct intel_uncore_type *type;
2243 int i, j;
2244
514b2346
YZ
2245 for (i = 0; uncore_msr_uncores[i]; i++) {
2246 type = uncore_msr_uncores[i];
087bfbb0
YZ
2247 for (j = 0; j < type->num_boxes; j++) {
2248 pmu = &type->pmus[j];
2249 uncore_pmu_register(pmu);
2250 }
2251 }
2252
514b2346
YZ
2253 for (i = 0; uncore_pci_uncores[i]; i++) {
2254 type = uncore_pci_uncores[i];
14371cce
YZ
2255 for (j = 0; j < type->num_boxes; j++) {
2256 pmu = &type->pmus[j];
2257 uncore_pmu_register(pmu);
2258 }
2259 }
2260
087bfbb0
YZ
2261 return 0;
2262}
2263
ef11dadb 2264static void __init uncore_cpumask_init(void)
411cf180
SE
2265{
2266 int cpu;
2267
2268 /*
2269 * ony invoke once from msr or pci init code
2270 */
2271 if (!cpumask_empty(&uncore_cpu_mask))
2272 return;
2273
467a9e16 2274 cpu_notifier_register_begin();
411cf180
SE
2275
2276 for_each_online_cpu(cpu) {
2277 int i, phys_id = topology_physical_package_id(cpu);
2278
2279 for_each_cpu(i, &uncore_cpu_mask) {
2280 if (phys_id == topology_physical_package_id(i)) {
2281 phys_id = -1;
2282 break;
2283 }
2284 }
2285 if (phys_id < 0)
2286 continue;
2287
2288 uncore_cpu_prepare(cpu, phys_id);
2289 uncore_event_init_cpu(cpu);
2290 }
2291 on_each_cpu(uncore_cpu_setup, NULL, 1);
2292
467a9e16 2293 __register_cpu_notifier(&uncore_cpu_nb);
411cf180 2294
467a9e16 2295 cpu_notifier_register_done();
411cf180
SE
2296}
2297
2298
087bfbb0
YZ
2299static int __init intel_uncore_init(void)
2300{
2301 int ret;
2302
2303 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
2304 return -ENODEV;
2305
a05123bd
YZ
2306 if (cpu_has_hypervisor)
2307 return -ENODEV;
2308
14371cce 2309 ret = uncore_pci_init();
087bfbb0
YZ
2310 if (ret)
2311 goto fail;
14371cce
YZ
2312 ret = uncore_cpu_init();
2313 if (ret) {
2314 uncore_pci_exit();
2315 goto fail;
2316 }
411cf180 2317 uncore_cpumask_init();
087bfbb0
YZ
2318
2319 uncore_pmus_register();
2320 return 0;
2321fail:
2322 return ret;
2323}
2324device_initcall(intel_uncore_init);