.. | .. |
---|
2 | 2 | #include <linux/slab.h> |
---|
3 | 3 | #include <linux/pci.h> |
---|
4 | 4 | #include <asm/apicdef.h> |
---|
| 5 | +#include <linux/io-64-nonatomic-lo-hi.h> |
---|
5 | 6 | |
---|
6 | 7 | #include <linux/perf_event.h> |
---|
7 | 8 | #include "../perf_event.h" |
---|
.. | .. |
---|
56 | 57 | unsigned fixed_ctr; |
---|
57 | 58 | unsigned fixed_ctl; |
---|
58 | 59 | unsigned box_ctl; |
---|
59 | | - unsigned msr_offset; |
---|
| 60 | + union { |
---|
| 61 | + unsigned msr_offset; |
---|
| 62 | + unsigned mmio_offset; |
---|
| 63 | + }; |
---|
| 64 | + unsigned mmio_map_size; |
---|
60 | 65 | unsigned num_shared_regs:8; |
---|
61 | 66 | unsigned single_fixed:1; |
---|
62 | 67 | unsigned pair_ctr_ctl:1; |
---|
.. | .. |
---|
68 | 73 | struct uncore_event_desc *event_descs; |
---|
69 | 74 | struct freerunning_counters *freerunning; |
---|
70 | 75 | const struct attribute_group *attr_groups[4]; |
---|
| 76 | + const struct attribute_group **attr_update; |
---|
71 | 77 | struct pmu *pmu; /* for custom pmu ops */ |
---|
| 78 | + /* |
---|
| 79 | + * Uncore PMU would store relevant platform topology configuration here |
---|
| 80 | + * to identify which platform component each PMON block of that type is |
---|
| 81 | + * supposed to monitor. |
---|
| 82 | + */ |
---|
| 83 | + u64 *topology; |
---|
| 84 | + /* |
---|
| 85 | + * Optional callbacks for managing mapping of Uncore units to PMONs |
---|
| 86 | + */ |
---|
| 87 | + int (*get_topology)(struct intel_uncore_type *type); |
---|
| 88 | + int (*set_mapping)(struct intel_uncore_type *type); |
---|
| 89 | + void (*cleanup_mapping)(struct intel_uncore_type *type); |
---|
72 | 90 | }; |
---|
73 | 91 | |
---|
74 | 92 | #define pmu_group attr_groups[0] |
---|
.. | .. |
---|
108 | 126 | |
---|
109 | 127 | struct intel_uncore_box { |
---|
110 | 128 | int pci_phys_id; |
---|
111 | | - int pkgid; /* Logical package ID */ |
---|
| 129 | + int dieid; /* Logical die ID */ |
---|
112 | 130 | int n_active; /* number of active events */ |
---|
113 | 131 | int n_events; |
---|
114 | 132 | int cpu; /* cpu to collect events */ |
---|
.. | .. |
---|
125 | 143 | struct hrtimer hrtimer; |
---|
126 | 144 | struct list_head list; |
---|
127 | 145 | struct list_head active_list; |
---|
128 | | - void *io_addr; |
---|
129 | | - struct intel_uncore_extra_reg shared_regs[0]; |
---|
| 146 | + void __iomem *io_addr; |
---|
| 147 | + struct intel_uncore_extra_reg shared_regs[]; |
---|
130 | 148 | }; |
---|
131 | 149 | |
---|
132 | | -#define UNCORE_BOX_FLAG_INITIATED 0 |
---|
133 | | -#define UNCORE_BOX_FLAG_CTL_OFFS8 1 /* event config registers are 8-byte apart */ |
---|
| 150 | +/* CFL uncore 8th cbox MSRs */ |
---|
| 151 | +#define CFL_UNC_CBO_7_PERFEVTSEL0 0xf70 |
---|
| 152 | +#define CFL_UNC_CBO_7_PER_CTR0 0xf76 |
---|
| 153 | + |
---|
| 154 | +#define UNCORE_BOX_FLAG_INITIATED 0 |
---|
| 155 | +/* event config registers are 8-byte apart */ |
---|
| 156 | +#define UNCORE_BOX_FLAG_CTL_OFFS8 1 |
---|
| 157 | +/* CFL 8th CBOX has different MSR space */ |
---|
| 158 | +#define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS 2 |
---|
134 | 159 | |
---|
135 | 160 | struct uncore_event_desc { |
---|
136 | 161 | struct device_attribute attr; |
---|
.. | .. |
---|
143 | 168 | unsigned int box_offset; |
---|
144 | 169 | unsigned int num_counters; |
---|
145 | 170 | unsigned int bits; |
---|
| 171 | + unsigned *box_offsets; |
---|
146 | 172 | }; |
---|
147 | 173 | |
---|
148 | 174 | struct pci2phy_map { |
---|
.. | .. |
---|
152 | 178 | }; |
---|
153 | 179 | |
---|
154 | 180 | struct pci2phy_map *__find_pci2phy_map(int segment); |
---|
| 181 | +int uncore_pcibus_to_physid(struct pci_bus *bus); |
---|
155 | 182 | |
---|
156 | 183 | ssize_t uncore_event_show(struct device *dev, |
---|
157 | 184 | struct device_attribute *attr, char *buf); |
---|
| 185 | + |
---|
| 186 | +static inline struct intel_uncore_pmu *dev_to_uncore_pmu(struct device *dev) |
---|
| 187 | +{ |
---|
| 188 | + return container_of(dev_get_drvdata(dev), struct intel_uncore_pmu, pmu); |
---|
| 189 | +} |
---|
| 190 | + |
---|
| 191 | +#define to_device_attribute(n) container_of(n, struct device_attribute, attr) |
---|
| 192 | +#define to_dev_ext_attribute(n) container_of(n, struct dev_ext_attribute, attr) |
---|
| 193 | +#define attr_to_ext_attr(n) to_dev_ext_attribute(to_device_attribute(n)) |
---|
| 194 | + |
---|
| 195 | +extern int __uncore_max_dies; |
---|
| 196 | +#define uncore_max_dies() (__uncore_max_dies) |
---|
158 | 197 | |
---|
159 | 198 | #define INTEL_UNCORE_EVENT_DESC(_name, _config) \ |
---|
160 | 199 | { \ |
---|
.. | .. |
---|
181 | 220 | static inline bool uncore_pmc_freerunning(int idx) |
---|
182 | 221 | { |
---|
183 | 222 | return idx == UNCORE_PMC_IDX_FREERUNNING; |
---|
| 223 | +} |
---|
| 224 | + |
---|
| 225 | +static inline bool uncore_mmio_is_valid_offset(struct intel_uncore_box *box, |
---|
| 226 | + unsigned long offset) |
---|
| 227 | +{ |
---|
| 228 | + if (offset < box->pmu->type->mmio_map_size) |
---|
| 229 | + return true; |
---|
| 230 | + |
---|
| 231 | + pr_warn_once("perf uncore: Invalid offset 0x%lx exceeds mapped area of %s.\n", |
---|
| 232 | + offset, box->pmu->type->name); |
---|
| 233 | + |
---|
| 234 | + return false; |
---|
| 235 | +} |
---|
| 236 | + |
---|
| 237 | +static inline |
---|
| 238 | +unsigned int uncore_mmio_box_ctl(struct intel_uncore_box *box) |
---|
| 239 | +{ |
---|
| 240 | + return box->pmu->type->box_ctl + |
---|
| 241 | + box->pmu->type->mmio_offset * box->pmu->pmu_idx; |
---|
184 | 242 | } |
---|
185 | 243 | |
---|
186 | 244 | static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box) |
---|
.. | .. |
---|
291 | 349 | |
---|
292 | 350 | return pmu->type->freerunning[type].counter_base + |
---|
293 | 351 | pmu->type->freerunning[type].counter_offset * idx + |
---|
294 | | - pmu->type->freerunning[type].box_offset * pmu->pmu_idx; |
---|
| 352 | + (pmu->type->freerunning[type].box_offsets ? |
---|
| 353 | + pmu->type->freerunning[type].box_offsets[pmu->pmu_idx] : |
---|
| 354 | + pmu->type->freerunning[type].box_offset * pmu->pmu_idx); |
---|
295 | 355 | } |
---|
296 | 356 | |
---|
297 | 357 | static inline |
---|
298 | 358 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) |
---|
299 | 359 | { |
---|
300 | | - return box->pmu->type->event_ctl + |
---|
301 | | - (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
---|
302 | | - uncore_msr_box_offset(box); |
---|
| 360 | + if (test_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags)) { |
---|
| 361 | + return CFL_UNC_CBO_7_PERFEVTSEL0 + |
---|
| 362 | + (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx); |
---|
| 363 | + } else { |
---|
| 364 | + return box->pmu->type->event_ctl + |
---|
| 365 | + (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
---|
| 366 | + uncore_msr_box_offset(box); |
---|
| 367 | + } |
---|
303 | 368 | } |
---|
304 | 369 | |
---|
305 | 370 | static inline |
---|
306 | 371 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) |
---|
307 | 372 | { |
---|
308 | | - return box->pmu->type->perf_ctr + |
---|
309 | | - (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
---|
310 | | - uncore_msr_box_offset(box); |
---|
| 373 | + if (test_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags)) { |
---|
| 374 | + return CFL_UNC_CBO_7_PER_CTR0 + |
---|
| 375 | + (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx); |
---|
| 376 | + } else { |
---|
| 377 | + return box->pmu->type->perf_ctr + |
---|
| 378 | + (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
---|
| 379 | + uncore_msr_box_offset(box); |
---|
| 380 | + } |
---|
311 | 381 | } |
---|
312 | 382 | |
---|
313 | 383 | static inline |
---|
314 | 384 | unsigned uncore_fixed_ctl(struct intel_uncore_box *box) |
---|
315 | 385 | { |
---|
316 | | - if (box->pci_dev) |
---|
| 386 | + if (box->pci_dev || box->io_addr) |
---|
317 | 387 | return uncore_pci_fixed_ctl(box); |
---|
318 | 388 | else |
---|
319 | 389 | return uncore_msr_fixed_ctl(box); |
---|
.. | .. |
---|
322 | 392 | static inline |
---|
323 | 393 | unsigned uncore_fixed_ctr(struct intel_uncore_box *box) |
---|
324 | 394 | { |
---|
325 | | - if (box->pci_dev) |
---|
| 395 | + if (box->pci_dev || box->io_addr) |
---|
326 | 396 | return uncore_pci_fixed_ctr(box); |
---|
327 | 397 | else |
---|
328 | 398 | return uncore_msr_fixed_ctr(box); |
---|
.. | .. |
---|
331 | 401 | static inline |
---|
332 | 402 | unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx) |
---|
333 | 403 | { |
---|
334 | | - if (box->pci_dev) |
---|
| 404 | + if (box->pci_dev || box->io_addr) |
---|
335 | 405 | return uncore_pci_event_ctl(box, idx); |
---|
336 | 406 | else |
---|
337 | 407 | return uncore_msr_event_ctl(box, idx); |
---|
.. | .. |
---|
340 | 410 | static inline |
---|
341 | 411 | unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx) |
---|
342 | 412 | { |
---|
343 | | - if (box->pci_dev) |
---|
| 413 | + if (box->pci_dev || box->io_addr) |
---|
344 | 414 | return uncore_pci_perf_ctr(box, idx); |
---|
345 | 415 | else |
---|
346 | 416 | return uncore_msr_perf_ctr(box, idx); |
---|
.. | .. |
---|
448 | 518 | |
---|
449 | 519 | static inline bool uncore_box_is_fake(struct intel_uncore_box *box) |
---|
450 | 520 | { |
---|
451 | | - return (box->pkgid < 0); |
---|
| 521 | + return (box->dieid < 0); |
---|
452 | 522 | } |
---|
453 | 523 | |
---|
454 | 524 | static inline struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) |
---|
.. | .. |
---|
463 | 533 | |
---|
464 | 534 | struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu); |
---|
465 | 535 | u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event); |
---|
| 536 | +void uncore_mmio_exit_box(struct intel_uncore_box *box); |
---|
| 537 | +u64 uncore_mmio_read_counter(struct intel_uncore_box *box, |
---|
| 538 | + struct perf_event *event); |
---|
466 | 539 | void uncore_pmu_start_hrtimer(struct intel_uncore_box *box); |
---|
467 | 540 | void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box); |
---|
468 | 541 | void uncore_pmu_event_start(struct perf_event *event, int flags); |
---|
.. | .. |
---|
478 | 551 | |
---|
479 | 552 | extern struct intel_uncore_type **uncore_msr_uncores; |
---|
480 | 553 | extern struct intel_uncore_type **uncore_pci_uncores; |
---|
| 554 | +extern struct intel_uncore_type **uncore_mmio_uncores; |
---|
481 | 555 | extern struct pci_driver *uncore_pci_driver; |
---|
| 556 | +extern struct pci_driver *uncore_pci_sub_driver; |
---|
482 | 557 | extern raw_spinlock_t pci2phy_map_lock; |
---|
483 | 558 | extern struct list_head pci2phy_map_head; |
---|
484 | 559 | extern struct pci_extra_dev *uncore_extra_pci_dev; |
---|
.. | .. |
---|
493 | 568 | void snb_uncore_cpu_init(void); |
---|
494 | 569 | void nhm_uncore_cpu_init(void); |
---|
495 | 570 | void skl_uncore_cpu_init(void); |
---|
| 571 | +void icl_uncore_cpu_init(void); |
---|
| 572 | +void tgl_uncore_cpu_init(void); |
---|
| 573 | +void tgl_uncore_mmio_init(void); |
---|
| 574 | +void tgl_l_uncore_mmio_init(void); |
---|
496 | 575 | int snb_pci2phy_map_init(int devid); |
---|
497 | 576 | |
---|
498 | 577 | /* uncore_snbep.c */ |
---|
.. | .. |
---|
508 | 587 | void knl_uncore_cpu_init(void); |
---|
509 | 588 | int skx_uncore_pci_init(void); |
---|
510 | 589 | void skx_uncore_cpu_init(void); |
---|
| 590 | +int snr_uncore_pci_init(void); |
---|
| 591 | +void snr_uncore_cpu_init(void); |
---|
| 592 | +void snr_uncore_mmio_init(void); |
---|
| 593 | +int icx_uncore_pci_init(void); |
---|
| 594 | +void icx_uncore_cpu_init(void); |
---|
| 595 | +void icx_uncore_mmio_init(void); |
---|
511 | 596 | |
---|
512 | 597 | /* uncore_nhmex.c */ |
---|
513 | 598 | void nhmex_uncore_cpu_init(void); |
---|