| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Common Performance counter support functions for PowerISA v2.07 processors. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2009 Paul Mackerras, IBM Corporation. |
|---|
| 5 | 6 | * Copyright 2013 Michael Ellerman, IBM Corporation. |
|---|
| 6 | 7 | * Copyright 2016 Madhavan Srinivasan, IBM Corporation. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or |
|---|
| 9 | | - * modify it under the terms of the GNU General Public License |
|---|
| 10 | | - * as published by the Free Software Foundation; either version |
|---|
| 11 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 12 | 8 | */ |
|---|
| 13 | 9 | #include "isa207-common.h" |
|---|
| 14 | 10 | |
|---|
| .. | .. |
|---|
| 59 | 55 | { |
|---|
| 60 | 56 | u64 valid_mask = EVENT_VALID_MASK; |
|---|
| 61 | 57 | |
|---|
| 62 | | - if (cpu_has_feature(CPU_FTR_ARCH_300)) |
|---|
| 58 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 59 | + valid_mask = p10_EVENT_VALID_MASK; |
|---|
| 60 | + else if (cpu_has_feature(CPU_FTR_ARCH_300)) |
|---|
| 63 | 61 | valid_mask = p9_EVENT_VALID_MASK; |
|---|
| 64 | 62 | |
|---|
| 65 | 63 | return !(event & ~valid_mask); |
|---|
| .. | .. |
|---|
| 73 | 71 | return false; |
|---|
| 74 | 72 | } |
|---|
| 75 | 73 | |
|---|
| 74 | +static unsigned long sdar_mod_val(u64 event) |
|---|
| 75 | +{ |
|---|
| 76 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 77 | + return p10_SDAR_MODE(event); |
|---|
| 78 | + |
|---|
| 79 | + return p9_SDAR_MODE(event); |
|---|
| 80 | +} |
|---|
| 81 | + |
|---|
| 76 | 82 | static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) |
|---|
| 77 | 83 | { |
|---|
| 78 | 84 | /* |
|---|
| .. | .. |
|---|
| 83 | 89 | * MMCRA[SDAR_MODE] will be programmed as "0b01" for continous sampling |
|---|
| 84 | 90 | * mode and will be un-changed when setting MMCRA[63] (Marked events). |
|---|
| 85 | 91 | * |
|---|
| 86 | | - * Incase of Power9: |
|---|
| 92 | + * Incase of Power9/power10: |
|---|
| 87 | 93 | * Marked event: MMCRA[SDAR_MODE] will be set to 0b00 ('No Updates'), |
|---|
| 88 | 94 | * or if group already have any marked events. |
|---|
| 89 | 95 | * For rest |
|---|
| .. | .. |
|---|
| 94 | 100 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { |
|---|
| 95 | 101 | if (is_event_marked(event) || (*mmcra & MMCRA_SAMPLE_ENABLE)) |
|---|
| 96 | 102 | *mmcra &= MMCRA_SDAR_MODE_NO_UPDATES; |
|---|
| 97 | | - else if (p9_SDAR_MODE(event)) |
|---|
| 98 | | - *mmcra |= p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT; |
|---|
| 103 | + else if (sdar_mod_val(event)) |
|---|
| 104 | + *mmcra |= sdar_mod_val(event) << MMCRA_SDAR_MODE_SHIFT; |
|---|
| 99 | 105 | else |
|---|
| 100 | 106 | *mmcra |= MMCRA_SDAR_MODE_DCACHE; |
|---|
| 101 | 107 | } else |
|---|
| .. | .. |
|---|
| 138 | 144 | /* |
|---|
| 139 | 145 | * Check the mantissa upper two bits are not zero, unless the |
|---|
| 140 | 146 | * exponent is also zero. See the THRESH_CMP_MANTISSA doc. |
|---|
| 147 | + * Power10: thresh_cmp is replaced by l2_l3 event select. |
|---|
| 141 | 148 | */ |
|---|
| 149 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 150 | + return false; |
|---|
| 151 | + |
|---|
| 142 | 152 | cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; |
|---|
| 143 | 153 | exp = cmp >> 7; |
|---|
| 144 | 154 | |
|---|
| .. | .. |
|---|
| 237 | 247 | u64 sier = mfspr(SPRN_SIER); |
|---|
| 238 | 248 | u64 val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; |
|---|
| 239 | 249 | |
|---|
| 250 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 251 | + mantissa = P10_MMCRA_THR_CTR_MANT(mmcra); |
|---|
| 252 | + |
|---|
| 240 | 253 | if (val == 0 || val == 7) |
|---|
| 241 | 254 | *weight = 0; |
|---|
| 242 | 255 | else |
|---|
| .. | .. |
|---|
| 255 | 268 | |
|---|
| 256 | 269 | pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; |
|---|
| 257 | 270 | unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; |
|---|
| 258 | | - cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK; |
|---|
| 271 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 272 | + cache = (event >> EVENT_CACHE_SEL_SHIFT) & |
|---|
| 273 | + p10_EVENT_CACHE_SEL_MASK; |
|---|
| 274 | + else |
|---|
| 275 | + cache = (event >> EVENT_CACHE_SEL_SHIFT) & |
|---|
| 276 | + EVENT_CACHE_SEL_MASK; |
|---|
| 259 | 277 | ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK; |
|---|
| 260 | 278 | |
|---|
| 261 | 279 | if (pmc) { |
|---|
| .. | .. |
|---|
| 296 | 314 | } |
|---|
| 297 | 315 | |
|---|
| 298 | 316 | if (unit >= 6 && unit <= 9) { |
|---|
| 299 | | - /* |
|---|
| 300 | | - * L2/L3 events contain a cache selector field, which is |
|---|
| 301 | | - * supposed to be programmed into MMCRC. However MMCRC is only |
|---|
| 302 | | - * HV writable, and there is no API for guest kernels to modify |
|---|
| 303 | | - * it. The solution is for the hypervisor to initialise the |
|---|
| 304 | | - * field to zeroes, and for us to only ever allow events that |
|---|
| 305 | | - * have a cache selector of zero. The bank selector (bit 3) is |
|---|
| 306 | | - * irrelevant, as long as the rest of the value is 0. |
|---|
| 307 | | - */ |
|---|
| 308 | | - if (!cpu_has_feature(CPU_FTR_ARCH_300) && (cache & 0x7)) |
|---|
| 317 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) { |
|---|
| 318 | + if (unit == 6) { |
|---|
| 319 | + mask |= CNST_L2L3_GROUP_MASK; |
|---|
| 320 | + value |= CNST_L2L3_GROUP_VAL(event >> p10_L2L3_EVENT_SHIFT); |
|---|
| 321 | + } |
|---|
| 322 | + } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { |
|---|
| 323 | + mask |= CNST_CACHE_GROUP_MASK; |
|---|
| 324 | + value |= CNST_CACHE_GROUP_VAL(event & 0xff); |
|---|
| 325 | + |
|---|
| 326 | + mask |= CNST_CACHE_PMC4_MASK; |
|---|
| 327 | + if (pmc == 4) |
|---|
| 328 | + value |= CNST_CACHE_PMC4_VAL; |
|---|
| 329 | + } else if (cache & 0x7) { |
|---|
| 330 | + /* |
|---|
| 331 | + * L2/L3 events contain a cache selector field, which is |
|---|
| 332 | + * supposed to be programmed into MMCRC. However MMCRC is only |
|---|
| 333 | + * HV writable, and there is no API for guest kernels to modify |
|---|
| 334 | + * it. The solution is for the hypervisor to initialise the |
|---|
| 335 | + * field to zeroes, and for us to only ever allow events that |
|---|
| 336 | + * have a cache selector of zero. The bank selector (bit 3) is |
|---|
| 337 | + * irrelevant, as long as the rest of the value is 0. |
|---|
| 338 | + */ |
|---|
| 309 | 339 | return -1; |
|---|
| 340 | + } |
|---|
| 310 | 341 | |
|---|
| 311 | 342 | } else if (cpu_has_feature(CPU_FTR_ARCH_300) || (event & EVENT_IS_L1)) { |
|---|
| 312 | 343 | mask |= CNST_L1_QUAL_MASK; |
|---|
| 313 | 344 | value |= CNST_L1_QUAL_VAL(cache); |
|---|
| 345 | + } |
|---|
| 346 | + |
|---|
| 347 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) { |
|---|
| 348 | + mask |= CNST_RADIX_SCOPE_GROUP_MASK; |
|---|
| 349 | + value |= CNST_RADIX_SCOPE_GROUP_VAL(event >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT); |
|---|
| 314 | 350 | } |
|---|
| 315 | 351 | |
|---|
| 316 | 352 | if (is_event_marked(event)) { |
|---|
| .. | .. |
|---|
| 318 | 354 | value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); |
|---|
| 319 | 355 | } |
|---|
| 320 | 356 | |
|---|
| 321 | | - if (cpu_has_feature(CPU_FTR_ARCH_300)) { |
|---|
| 357 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) { |
|---|
| 358 | + if (event_is_threshold(event)) { |
|---|
| 359 | + mask |= CNST_THRESH_CTL_SEL_MASK; |
|---|
| 360 | + value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); |
|---|
| 361 | + } |
|---|
| 362 | + } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { |
|---|
| 322 | 363 | if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { |
|---|
| 323 | 364 | mask |= CNST_THRESH_MASK; |
|---|
| 324 | 365 | value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); |
|---|
| 325 | | - } |
|---|
| 366 | + } else if (event_is_threshold(event)) |
|---|
| 367 | + return -1; |
|---|
| 326 | 368 | } else { |
|---|
| 327 | 369 | /* |
|---|
| 328 | 370 | * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, |
|---|
| .. | .. |
|---|
| 369 | 411 | } |
|---|
| 370 | 412 | |
|---|
| 371 | 413 | int isa207_compute_mmcr(u64 event[], int n_ev, |
|---|
| 372 | | - unsigned int hwc[], unsigned long mmcr[], |
|---|
| 414 | + unsigned int hwc[], struct mmcr_regs *mmcr, |
|---|
| 373 | 415 | struct perf_event *pevents[]) |
|---|
| 374 | 416 | { |
|---|
| 375 | 417 | unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val; |
|---|
| 418 | + unsigned long mmcr3; |
|---|
| 376 | 419 | unsigned int pmc, pmc_inuse; |
|---|
| 377 | 420 | int i; |
|---|
| 378 | 421 | |
|---|
| .. | .. |
|---|
| 385 | 428 | pmc_inuse |= 1 << pmc; |
|---|
| 386 | 429 | } |
|---|
| 387 | 430 | |
|---|
| 388 | | - mmcra = mmcr1 = mmcr2 = 0; |
|---|
| 431 | + mmcra = mmcr1 = mmcr2 = mmcr3 = 0; |
|---|
| 432 | + |
|---|
| 433 | + /* |
|---|
| 434 | + * Disable bhrb unless explicitly requested |
|---|
| 435 | + * by setting MMCRA (BHRBRD) bit. |
|---|
| 436 | + */ |
|---|
| 437 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 438 | + mmcra |= MMCRA_BHRB_DISABLE; |
|---|
| 389 | 439 | |
|---|
| 390 | 440 | /* Second pass: assign PMCs, set all MMCR1 fields */ |
|---|
| 391 | 441 | for (i = 0; i < n_ev; ++i) { |
|---|
| .. | .. |
|---|
| 422 | 472 | } |
|---|
| 423 | 473 | } |
|---|
| 424 | 474 | |
|---|
| 475 | + /* Set RADIX_SCOPE_QUAL bit */ |
|---|
| 476 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) { |
|---|
| 477 | + val = (event[i] >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT) & |
|---|
| 478 | + p10_EVENT_RADIX_SCOPE_QUAL_MASK; |
|---|
| 479 | + mmcr1 |= val << p10_MMCR1_RADIX_SCOPE_QUAL_SHIFT; |
|---|
| 480 | + } |
|---|
| 481 | + |
|---|
| 425 | 482 | if (is_event_marked(event[i])) { |
|---|
| 426 | 483 | mmcra |= MMCRA_SAMPLE_ENABLE; |
|---|
| 427 | 484 | |
|---|
| .. | .. |
|---|
| 444 | 501 | mmcra |= val << MMCRA_THR_CTL_SHIFT; |
|---|
| 445 | 502 | val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK; |
|---|
| 446 | 503 | mmcra |= val << MMCRA_THR_SEL_SHIFT; |
|---|
| 447 | | - val = (event[i] >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; |
|---|
| 448 | | - mmcra |= thresh_cmp_val(val); |
|---|
| 504 | + if (!cpu_has_feature(CPU_FTR_ARCH_31)) { |
|---|
| 505 | + val = (event[i] >> EVENT_THR_CMP_SHIFT) & |
|---|
| 506 | + EVENT_THR_CMP_MASK; |
|---|
| 507 | + mmcra |= thresh_cmp_val(val); |
|---|
| 508 | + } |
|---|
| 509 | + } |
|---|
| 510 | + |
|---|
| 511 | + if (cpu_has_feature(CPU_FTR_ARCH_31) && (unit == 6)) { |
|---|
| 512 | + val = (event[i] >> p10_L2L3_EVENT_SHIFT) & |
|---|
| 513 | + p10_EVENT_L2L3_SEL_MASK; |
|---|
| 514 | + mmcr2 |= val << p10_L2L3_SEL_SHIFT; |
|---|
| 449 | 515 | } |
|---|
| 450 | 516 | |
|---|
| 451 | 517 | if (event[i] & EVENT_WANTS_BHRB) { |
|---|
| 452 | 518 | val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK; |
|---|
| 453 | 519 | mmcra |= val << MMCRA_IFM_SHIFT; |
|---|
| 454 | 520 | } |
|---|
| 521 | + |
|---|
| 522 | + /* set MMCRA (BHRBRD) to 0 if there is user request for BHRB */ |
|---|
| 523 | + if (cpu_has_feature(CPU_FTR_ARCH_31) && |
|---|
| 524 | + (has_branch_stack(pevents[i]) || (event[i] & EVENT_WANTS_BHRB))) |
|---|
| 525 | + mmcra &= ~MMCRA_BHRB_DISABLE; |
|---|
| 455 | 526 | |
|---|
| 456 | 527 | if (pevents[i]->attr.exclude_user) |
|---|
| 457 | 528 | mmcr2 |= MMCR2_FCP(pmc); |
|---|
| .. | .. |
|---|
| 466 | 537 | mmcr2 |= MMCR2_FCS(pmc); |
|---|
| 467 | 538 | } |
|---|
| 468 | 539 | |
|---|
| 540 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) { |
|---|
| 541 | + if (pmc <= 4) { |
|---|
| 542 | + val = (event[i] >> p10_EVENT_MMCR3_SHIFT) & |
|---|
| 543 | + p10_EVENT_MMCR3_MASK; |
|---|
| 544 | + mmcr3 |= val << MMCR3_SHIFT(pmc); |
|---|
| 545 | + } |
|---|
| 546 | + } |
|---|
| 547 | + |
|---|
| 469 | 548 | hwc[i] = pmc - 1; |
|---|
| 470 | 549 | } |
|---|
| 471 | 550 | |
|---|
| 472 | 551 | /* Return MMCRx values */ |
|---|
| 473 | | - mmcr[0] = 0; |
|---|
| 552 | + mmcr->mmcr0 = 0; |
|---|
| 474 | 553 | |
|---|
| 475 | 554 | /* pmc_inuse is 1-based */ |
|---|
| 476 | 555 | if (pmc_inuse & 2) |
|---|
| 477 | | - mmcr[0] = MMCR0_PMC1CE; |
|---|
| 556 | + mmcr->mmcr0 = MMCR0_PMC1CE; |
|---|
| 478 | 557 | |
|---|
| 479 | 558 | if (pmc_inuse & 0x7c) |
|---|
| 480 | | - mmcr[0] |= MMCR0_PMCjCE; |
|---|
| 559 | + mmcr->mmcr0 |= MMCR0_PMCjCE; |
|---|
| 481 | 560 | |
|---|
| 482 | 561 | /* If we're not using PMC 5 or 6, freeze them */ |
|---|
| 483 | 562 | if (!(pmc_inuse & 0x60)) |
|---|
| 484 | | - mmcr[0] |= MMCR0_FC56; |
|---|
| 563 | + mmcr->mmcr0 |= MMCR0_FC56; |
|---|
| 485 | 564 | |
|---|
| 486 | | - mmcr[1] = mmcr1; |
|---|
| 487 | | - mmcr[2] = mmcra; |
|---|
| 488 | | - mmcr[3] = mmcr2; |
|---|
| 565 | + /* |
|---|
| 566 | + * Set mmcr0 (PMCCEXT) for p10 which |
|---|
| 567 | + * will restrict access to group B registers |
|---|
| 568 | + * when MMCR0 PMCC=0b00. |
|---|
| 569 | + */ |
|---|
| 570 | + if (cpu_has_feature(CPU_FTR_ARCH_31)) |
|---|
| 571 | + mmcr->mmcr0 |= MMCR0_PMCCEXT; |
|---|
| 572 | + |
|---|
| 573 | + mmcr->mmcr1 = mmcr1; |
|---|
| 574 | + mmcr->mmcra = mmcra; |
|---|
| 575 | + mmcr->mmcr2 = mmcr2; |
|---|
| 576 | + mmcr->mmcr3 = mmcr3; |
|---|
| 489 | 577 | |
|---|
| 490 | 578 | return 0; |
|---|
| 491 | 579 | } |
|---|
| 492 | 580 | |
|---|
| 493 | | -void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[]) |
|---|
| 581 | +void isa207_disable_pmc(unsigned int pmc, struct mmcr_regs *mmcr) |
|---|
| 494 | 582 | { |
|---|
| 495 | 583 | if (pmc <= 3) |
|---|
| 496 | | - mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); |
|---|
| 584 | + mmcr->mmcr1 &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); |
|---|
| 497 | 585 | } |
|---|
| 498 | 586 | |
|---|
| 499 | 587 | static int find_alternative(u64 event, const unsigned int ev_alt[][MAX_ALT], int size) |
|---|