1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Support Intel uncore PerfMon discovery mechanism.
4 * Copyright(c) 2021 Intel Corporation.
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 #include "uncore_discovery.h"
11 static struct rb_root discovery_tables
= RB_ROOT
;
12 static int num_discovered_types
[UNCORE_ACCESS_MAX
];
14 static bool has_generic_discovery_table(void)
19 dev
= pci_get_device(PCI_VENDOR_ID_INTEL
, UNCORE_DISCOVERY_TABLE_DEVICE
, NULL
);
23 /* A discovery table device has the unique capability ID. */
24 dvsec
= pci_find_next_ext_capability(dev
, 0, UNCORE_EXT_CAP_ID_DISCOVERY
);
32 static int logical_die_id
;
34 static int get_device_die_id(struct pci_dev
*dev
)
36 int node
= pcibus_to_node(dev
->bus
);
39 * If the NUMA info is not available, assume that the logical die id is
40 * continuous in the order in which the discovery table devices are
44 return logical_die_id
++;
46 return uncore_device_to_die(dev
);
49 #define __node_2_type(cur) \
50 rb_entry((cur), struct intel_uncore_discovery_type, node)
52 static inline int __type_cmp(const void *key
, const struct rb_node
*b
)
54 struct intel_uncore_discovery_type
*type_b
= __node_2_type(b
);
55 const u16
*type_id
= key
;
57 if (type_b
->type
> *type_id
)
59 else if (type_b
->type
< *type_id
)
65 static inline struct intel_uncore_discovery_type
*
66 search_uncore_discovery_type(u16 type_id
)
68 struct rb_node
*node
= rb_find(&type_id
, &discovery_tables
, __type_cmp
);
70 return (node
) ? __node_2_type(node
) : NULL
;
73 static inline bool __type_less(struct rb_node
*a
, const struct rb_node
*b
)
75 return (__node_2_type(a
)->type
< __node_2_type(b
)->type
);
78 static struct intel_uncore_discovery_type
*
79 add_uncore_discovery_type(struct uncore_unit_discovery
*unit
)
81 struct intel_uncore_discovery_type
*type
;
83 if (unit
->access_type
>= UNCORE_ACCESS_MAX
) {
84 pr_warn("Unsupported access type %d\n", unit
->access_type
);
88 type
= kzalloc(sizeof(struct intel_uncore_discovery_type
), GFP_KERNEL
);
92 type
->units
= RB_ROOT
;
94 type
->access_type
= unit
->access_type
;
95 num_discovered_types
[type
->access_type
]++;
96 type
->type
= unit
->box_type
;
98 rb_add(&type
->node
, &discovery_tables
, __type_less
);
103 static struct intel_uncore_discovery_type
*
104 get_uncore_discovery_type(struct uncore_unit_discovery
*unit
)
106 struct intel_uncore_discovery_type
*type
;
108 type
= search_uncore_discovery_type(unit
->box_type
);
112 return add_uncore_discovery_type(unit
);
115 static inline int pmu_idx_cmp(const void *key
, const struct rb_node
*b
)
117 struct intel_uncore_discovery_unit
*unit
;
118 const unsigned int *id
= key
;
120 unit
= rb_entry(b
, struct intel_uncore_discovery_unit
, node
);
122 if (unit
->pmu_idx
> *id
)
124 else if (unit
->pmu_idx
< *id
)
130 static struct intel_uncore_discovery_unit
*
131 intel_uncore_find_discovery_unit(struct rb_root
*units
, int die
,
132 unsigned int pmu_idx
)
134 struct intel_uncore_discovery_unit
*unit
;
140 pos
= rb_find_first(&pmu_idx
, units
, pmu_idx_cmp
);
143 unit
= rb_entry(pos
, struct intel_uncore_discovery_unit
, node
);
148 for (; pos
; pos
= rb_next(pos
)) {
149 unit
= rb_entry(pos
, struct intel_uncore_discovery_unit
, node
);
151 if (unit
->pmu_idx
!= pmu_idx
)
154 if (unit
->die
== die
)
161 int intel_uncore_find_discovery_unit_id(struct rb_root
*units
, int die
,
162 unsigned int pmu_idx
)
164 struct intel_uncore_discovery_unit
*unit
;
166 unit
= intel_uncore_find_discovery_unit(units
, die
, pmu_idx
);
173 static inline bool unit_less(struct rb_node
*a
, const struct rb_node
*b
)
175 struct intel_uncore_discovery_unit
*a_node
, *b_node
;
177 a_node
= rb_entry(a
, struct intel_uncore_discovery_unit
, node
);
178 b_node
= rb_entry(b
, struct intel_uncore_discovery_unit
, node
);
180 if (a_node
->pmu_idx
< b_node
->pmu_idx
)
182 if (a_node
->pmu_idx
> b_node
->pmu_idx
)
185 if (a_node
->die
< b_node
->die
)
187 if (a_node
->die
> b_node
->die
)
193 static inline struct intel_uncore_discovery_unit
*
194 uncore_find_unit(struct rb_root
*root
, unsigned int id
)
196 struct intel_uncore_discovery_unit
*unit
;
197 struct rb_node
*node
;
199 for (node
= rb_first(root
); node
; node
= rb_next(node
)) {
200 unit
= rb_entry(node
, struct intel_uncore_discovery_unit
, node
);
208 void uncore_find_add_unit(struct intel_uncore_discovery_unit
*node
,
209 struct rb_root
*root
, u16
*num_units
)
211 struct intel_uncore_discovery_unit
*unit
= uncore_find_unit(root
, node
->id
);
214 node
->pmu_idx
= unit
->pmu_idx
;
216 node
->pmu_idx
= (*num_units
)++;
218 rb_add(&node
->node
, root
, unit_less
);
222 uncore_insert_box_info(struct uncore_unit_discovery
*unit
,
225 struct intel_uncore_discovery_unit
*node
;
226 struct intel_uncore_discovery_type
*type
;
228 if (!unit
->ctl
|| !unit
->ctl_offset
|| !unit
->ctr_offset
) {
229 pr_info("Invalid address is detected for uncore type %d box %d, "
230 "Disable the uncore unit.\n",
231 unit
->box_type
, unit
->box_id
);
235 node
= kzalloc(sizeof(*node
), GFP_KERNEL
);
240 node
->id
= unit
->box_id
;
241 node
->addr
= unit
->ctl
;
243 type
= get_uncore_discovery_type(unit
);
249 uncore_find_add_unit(node
, &type
->units
, &type
->num_units
);
251 /* Store generic information for the first box */
252 if (type
->num_units
== 1) {
253 type
->num_counters
= unit
->num_regs
;
254 type
->counter_width
= unit
->bit_width
;
255 type
->ctl_offset
= unit
->ctl_offset
;
256 type
->ctr_offset
= unit
->ctr_offset
;
261 uncore_ignore_unit(struct uncore_unit_discovery
*unit
, int *ignore
)
268 for (i
= 0; ignore
[i
] != UNCORE_IGNORE_END
; i
++) {
269 if (unit
->box_type
== ignore
[i
])
276 static int parse_discovery_table(struct pci_dev
*dev
, int die
,
277 u32 bar_offset
, bool *parsed
,
280 struct uncore_global_discovery global
;
281 struct uncore_unit_discovery unit
;
282 void __iomem
*io_addr
;
283 resource_size_t addr
;
288 pci_read_config_dword(dev
, bar_offset
, &val
);
290 if (val
& ~PCI_BASE_ADDRESS_MEM_MASK
& ~PCI_BASE_ADDRESS_MEM_TYPE_64
)
293 addr
= (resource_size_t
)(val
& PCI_BASE_ADDRESS_MEM_MASK
);
294 #ifdef CONFIG_PHYS_ADDR_T_64BIT
295 if ((val
& PCI_BASE_ADDRESS_MEM_TYPE_MASK
) == PCI_BASE_ADDRESS_MEM_TYPE_64
) {
298 pci_read_config_dword(dev
, bar_offset
+ 4, &val2
);
299 addr
|= ((resource_size_t
)val2
) << 32;
302 size
= UNCORE_DISCOVERY_GLOBAL_MAP_SIZE
;
303 io_addr
= ioremap(addr
, size
);
307 /* Read Global Discovery State */
308 memcpy_fromio(&global
, io_addr
, sizeof(struct uncore_global_discovery
));
309 if (uncore_discovery_invalid_unit(global
)) {
310 pr_info("Invalid Global Discovery State: 0x%llx 0x%llx 0x%llx\n",
311 global
.table1
, global
.ctl
, global
.table3
);
317 size
= (1 + global
.max_units
) * global
.stride
* 8;
318 io_addr
= ioremap(addr
, size
);
322 /* Parsing Unit Discovery State */
323 for (i
= 0; i
< global
.max_units
; i
++) {
324 memcpy_fromio(&unit
, io_addr
+ (i
+ 1) * (global
.stride
* 8),
325 sizeof(struct uncore_unit_discovery
));
327 if (uncore_discovery_invalid_unit(unit
))
330 if (unit
.access_type
>= UNCORE_ACCESS_MAX
)
333 if (uncore_ignore_unit(&unit
, ignore
))
336 uncore_insert_box_info(&unit
, die
);
344 bool intel_uncore_has_discovery_tables(int *ignore
)
346 u32 device
, val
, entry_id
, bar_offset
;
347 int die
, dvsec
= 0, ret
= true;
348 struct pci_dev
*dev
= NULL
;
351 if (has_generic_discovery_table())
352 device
= UNCORE_DISCOVERY_TABLE_DEVICE
;
357 * Start a new search and iterates through the list of
358 * the discovery table devices.
360 while ((dev
= pci_get_device(PCI_VENDOR_ID_INTEL
, device
, dev
)) != NULL
) {
361 while ((dvsec
= pci_find_next_ext_capability(dev
, dvsec
, UNCORE_EXT_CAP_ID_DISCOVERY
))) {
362 pci_read_config_dword(dev
, dvsec
+ UNCORE_DISCOVERY_DVSEC_OFFSET
, &val
);
363 entry_id
= val
& UNCORE_DISCOVERY_DVSEC_ID_MASK
;
364 if (entry_id
!= UNCORE_DISCOVERY_DVSEC_ID_PMON
)
367 pci_read_config_dword(dev
, dvsec
+ UNCORE_DISCOVERY_DVSEC2_OFFSET
, &val
);
369 if (val
& ~UNCORE_DISCOVERY_DVSEC2_BIR_MASK
) {
373 bar_offset
= UNCORE_DISCOVERY_BIR_BASE
+
374 (val
& UNCORE_DISCOVERY_DVSEC2_BIR_MASK
) * UNCORE_DISCOVERY_BIR_STEP
;
376 die
= get_device_die_id(dev
);
380 parse_discovery_table(dev
, die
, bar_offset
, &parsed
, ignore
);
384 /* None of the discovery tables are available */
393 void intel_uncore_clear_discovery_tables(void)
395 struct intel_uncore_discovery_type
*type
, *next
;
396 struct intel_uncore_discovery_unit
*pos
;
397 struct rb_node
*node
;
399 rbtree_postorder_for_each_entry_safe(type
, next
, &discovery_tables
, node
) {
400 while (!RB_EMPTY_ROOT(&type
->units
)) {
401 node
= rb_first(&type
->units
);
402 pos
= rb_entry(node
, struct intel_uncore_discovery_unit
, node
);
403 rb_erase(node
, &type
->units
);
410 DEFINE_UNCORE_FORMAT_ATTR(event
, event
, "config:0-7");
411 DEFINE_UNCORE_FORMAT_ATTR(umask
, umask
, "config:8-15");
412 DEFINE_UNCORE_FORMAT_ATTR(edge
, edge
, "config:18");
413 DEFINE_UNCORE_FORMAT_ATTR(inv
, inv
, "config:23");
414 DEFINE_UNCORE_FORMAT_ATTR(thresh
, thresh
, "config:24-31");
416 static struct attribute
*generic_uncore_formats_attr
[] = {
417 &format_attr_event
.attr
,
418 &format_attr_umask
.attr
,
419 &format_attr_edge
.attr
,
420 &format_attr_inv
.attr
,
421 &format_attr_thresh
.attr
,
425 static const struct attribute_group generic_uncore_format_group
= {
427 .attrs
= generic_uncore_formats_attr
,
430 static u64
intel_generic_uncore_box_ctl(struct intel_uncore_box
*box
)
432 struct intel_uncore_discovery_unit
*unit
;
434 unit
= intel_uncore_find_discovery_unit(box
->pmu
->type
->boxes
,
435 -1, box
->pmu
->pmu_idx
);
436 if (WARN_ON_ONCE(!unit
))
442 void intel_generic_uncore_msr_init_box(struct intel_uncore_box
*box
)
444 wrmsrl(intel_generic_uncore_box_ctl(box
), GENERIC_PMON_BOX_CTL_INT
);
447 void intel_generic_uncore_msr_disable_box(struct intel_uncore_box
*box
)
449 wrmsrl(intel_generic_uncore_box_ctl(box
), GENERIC_PMON_BOX_CTL_FRZ
);
452 void intel_generic_uncore_msr_enable_box(struct intel_uncore_box
*box
)
454 wrmsrl(intel_generic_uncore_box_ctl(box
), 0);
457 static void intel_generic_uncore_msr_enable_event(struct intel_uncore_box
*box
,
458 struct perf_event
*event
)
460 struct hw_perf_event
*hwc
= &event
->hw
;
462 wrmsrl(hwc
->config_base
, hwc
->config
);
465 static void intel_generic_uncore_msr_disable_event(struct intel_uncore_box
*box
,
466 struct perf_event
*event
)
468 struct hw_perf_event
*hwc
= &event
->hw
;
470 wrmsrl(hwc
->config_base
, 0);
473 static struct intel_uncore_ops generic_uncore_msr_ops
= {
474 .init_box
= intel_generic_uncore_msr_init_box
,
475 .disable_box
= intel_generic_uncore_msr_disable_box
,
476 .enable_box
= intel_generic_uncore_msr_enable_box
,
477 .disable_event
= intel_generic_uncore_msr_disable_event
,
478 .enable_event
= intel_generic_uncore_msr_enable_event
,
479 .read_counter
= uncore_msr_read_counter
,
482 bool intel_generic_uncore_assign_hw_event(struct perf_event
*event
,
483 struct intel_uncore_box
*box
)
485 struct hw_perf_event
*hwc
= &event
->hw
;
488 if (!box
->pmu
->type
->boxes
)
492 hwc
->config_base
= uncore_pci_event_ctl(box
, hwc
->idx
);
493 hwc
->event_base
= uncore_pci_perf_ctr(box
, hwc
->idx
);
497 box_ctl
= intel_generic_uncore_box_ctl(box
);
502 box_ctl
= UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl
);
503 hwc
->config_base
= box_ctl
+ uncore_pci_event_ctl(box
, hwc
->idx
);
504 hwc
->event_base
= box_ctl
+ uncore_pci_perf_ctr(box
, hwc
->idx
);
508 hwc
->config_base
= box_ctl
+ box
->pmu
->type
->event_ctl
+ hwc
->idx
;
509 hwc
->event_base
= box_ctl
+ box
->pmu
->type
->perf_ctr
+ hwc
->idx
;
514 static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box
*box
)
516 return UNCORE_DISCOVERY_PCI_BOX_CTRL(intel_generic_uncore_box_ctl(box
));
519 void intel_generic_uncore_pci_init_box(struct intel_uncore_box
*box
)
521 struct pci_dev
*pdev
= box
->pci_dev
;
522 int box_ctl
= intel_pci_uncore_box_ctl(box
);
524 __set_bit(UNCORE_BOX_FLAG_CTL_OFFS8
, &box
->flags
);
525 pci_write_config_dword(pdev
, box_ctl
, GENERIC_PMON_BOX_CTL_INT
);
528 void intel_generic_uncore_pci_disable_box(struct intel_uncore_box
*box
)
530 struct pci_dev
*pdev
= box
->pci_dev
;
531 int box_ctl
= intel_pci_uncore_box_ctl(box
);
533 pci_write_config_dword(pdev
, box_ctl
, GENERIC_PMON_BOX_CTL_FRZ
);
536 void intel_generic_uncore_pci_enable_box(struct intel_uncore_box
*box
)
538 struct pci_dev
*pdev
= box
->pci_dev
;
539 int box_ctl
= intel_pci_uncore_box_ctl(box
);
541 pci_write_config_dword(pdev
, box_ctl
, 0);
544 static void intel_generic_uncore_pci_enable_event(struct intel_uncore_box
*box
,
545 struct perf_event
*event
)
547 struct pci_dev
*pdev
= box
->pci_dev
;
548 struct hw_perf_event
*hwc
= &event
->hw
;
550 pci_write_config_dword(pdev
, hwc
->config_base
, hwc
->config
);
553 void intel_generic_uncore_pci_disable_event(struct intel_uncore_box
*box
,
554 struct perf_event
*event
)
556 struct pci_dev
*pdev
= box
->pci_dev
;
557 struct hw_perf_event
*hwc
= &event
->hw
;
559 pci_write_config_dword(pdev
, hwc
->config_base
, 0);
562 u64
intel_generic_uncore_pci_read_counter(struct intel_uncore_box
*box
,
563 struct perf_event
*event
)
565 struct pci_dev
*pdev
= box
->pci_dev
;
566 struct hw_perf_event
*hwc
= &event
->hw
;
569 pci_read_config_dword(pdev
, hwc
->event_base
, (u32
*)&count
);
570 pci_read_config_dword(pdev
, hwc
->event_base
+ 4, (u32
*)&count
+ 1);
575 static struct intel_uncore_ops generic_uncore_pci_ops
= {
576 .init_box
= intel_generic_uncore_pci_init_box
,
577 .disable_box
= intel_generic_uncore_pci_disable_box
,
578 .enable_box
= intel_generic_uncore_pci_enable_box
,
579 .disable_event
= intel_generic_uncore_pci_disable_event
,
580 .enable_event
= intel_generic_uncore_pci_enable_event
,
581 .read_counter
= intel_generic_uncore_pci_read_counter
,
584 #define UNCORE_GENERIC_MMIO_SIZE 0x4000
586 void intel_generic_uncore_mmio_init_box(struct intel_uncore_box
*box
)
588 static struct intel_uncore_discovery_unit
*unit
;
589 struct intel_uncore_type
*type
= box
->pmu
->type
;
590 resource_size_t addr
;
592 unit
= intel_uncore_find_discovery_unit(type
->boxes
, box
->dieid
, box
->pmu
->pmu_idx
);
594 pr_warn("Uncore type %d id %d: Cannot find box control address.\n",
595 type
->type_id
, box
->pmu
->pmu_idx
);
600 pr_warn("Uncore type %d box %d: Invalid box control address.\n",
601 type
->type_id
, unit
->id
);
606 box
->io_addr
= ioremap(addr
, UNCORE_GENERIC_MMIO_SIZE
);
608 pr_warn("Uncore type %d box %d: ioremap error for 0x%llx.\n",
609 type
->type_id
, unit
->id
, (unsigned long long)addr
);
613 writel(GENERIC_PMON_BOX_CTL_INT
, box
->io_addr
);
616 void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box
*box
)
621 writel(GENERIC_PMON_BOX_CTL_FRZ
, box
->io_addr
);
624 void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box
*box
)
629 writel(0, box
->io_addr
);
632 void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box
*box
,
633 struct perf_event
*event
)
635 struct hw_perf_event
*hwc
= &event
->hw
;
640 writel(hwc
->config
, box
->io_addr
+ hwc
->config_base
);
643 void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box
*box
,
644 struct perf_event
*event
)
646 struct hw_perf_event
*hwc
= &event
->hw
;
651 writel(0, box
->io_addr
+ hwc
->config_base
);
654 static struct intel_uncore_ops generic_uncore_mmio_ops
= {
655 .init_box
= intel_generic_uncore_mmio_init_box
,
656 .exit_box
= uncore_mmio_exit_box
,
657 .disable_box
= intel_generic_uncore_mmio_disable_box
,
658 .enable_box
= intel_generic_uncore_mmio_enable_box
,
659 .disable_event
= intel_generic_uncore_mmio_disable_event
,
660 .enable_event
= intel_generic_uncore_mmio_enable_event
,
661 .read_counter
= uncore_mmio_read_counter
,
664 static bool uncore_update_uncore_type(enum uncore_access_type type_id
,
665 struct intel_uncore_type
*uncore
,
666 struct intel_uncore_discovery_type
*type
)
668 uncore
->type_id
= type
->type
;
669 uncore
->num_counters
= type
->num_counters
;
670 uncore
->perf_ctr_bits
= type
->counter_width
;
671 uncore
->perf_ctr
= (unsigned int)type
->ctr_offset
;
672 uncore
->event_ctl
= (unsigned int)type
->ctl_offset
;
673 uncore
->boxes
= &type
->units
;
674 uncore
->num_boxes
= type
->num_units
;
677 case UNCORE_ACCESS_MSR
:
678 uncore
->ops
= &generic_uncore_msr_ops
;
680 case UNCORE_ACCESS_PCI
:
681 uncore
->ops
= &generic_uncore_pci_ops
;
683 case UNCORE_ACCESS_MMIO
:
684 uncore
->ops
= &generic_uncore_mmio_ops
;
685 uncore
->mmio_map_size
= UNCORE_GENERIC_MMIO_SIZE
;
694 struct intel_uncore_type
**
695 intel_uncore_generic_init_uncores(enum uncore_access_type type_id
, int num_extra
)
697 struct intel_uncore_discovery_type
*type
;
698 struct intel_uncore_type
**uncores
;
699 struct intel_uncore_type
*uncore
;
700 struct rb_node
*node
;
703 uncores
= kcalloc(num_discovered_types
[type_id
] + num_extra
+ 1,
704 sizeof(struct intel_uncore_type
*), GFP_KERNEL
);
708 for (node
= rb_first(&discovery_tables
); node
; node
= rb_next(node
)) {
709 type
= rb_entry(node
, struct intel_uncore_discovery_type
, node
);
710 if (type
->access_type
!= type_id
)
713 uncore
= kzalloc(sizeof(struct intel_uncore_type
), GFP_KERNEL
);
717 uncore
->event_mask
= GENERIC_PMON_RAW_EVENT_MASK
;
718 uncore
->format_group
= &generic_uncore_format_group
;
720 if (!uncore_update_uncore_type(type_id
, uncore
, type
)) {
724 uncores
[i
++] = uncore
;
730 void intel_uncore_generic_uncore_cpu_init(void)
732 uncore_msr_uncores
= intel_uncore_generic_init_uncores(UNCORE_ACCESS_MSR
, 0);
735 int intel_uncore_generic_uncore_pci_init(void)
737 uncore_pci_uncores
= intel_uncore_generic_init_uncores(UNCORE_ACCESS_PCI
, 0);
742 void intel_uncore_generic_uncore_mmio_init(void)
744 uncore_mmio_uncores
= intel_uncore_generic_init_uncores(UNCORE_ACCESS_MMIO
, 0);