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