core-fsl-emb.c (14673B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Performance event support - Freescale Embedded Performance Monitor 4 * 5 * Copyright 2008-2009 Paul Mackerras, IBM Corporation. 6 * Copyright 2010 Freescale Semiconductor, Inc. 7 */ 8#include <linux/kernel.h> 9#include <linux/sched.h> 10#include <linux/perf_event.h> 11#include <linux/percpu.h> 12#include <linux/hardirq.h> 13#include <asm/reg_fsl_emb.h> 14#include <asm/pmc.h> 15#include <asm/machdep.h> 16#include <asm/firmware.h> 17#include <asm/ptrace.h> 18 19struct cpu_hw_events { 20 int n_events; 21 int disabled; 22 u8 pmcs_enabled; 23 struct perf_event *event[MAX_HWEVENTS]; 24}; 25static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); 26 27static struct fsl_emb_pmu *ppmu; 28 29/* Number of perf_events counting hardware events */ 30static atomic_t num_events; 31/* Used to avoid races in calling reserve/release_pmc_hardware */ 32static DEFINE_MUTEX(pmc_reserve_mutex); 33 34static void perf_event_interrupt(struct pt_regs *regs); 35 36/* 37 * Read one performance monitor counter (PMC). 38 */ 39static unsigned long read_pmc(int idx) 40{ 41 unsigned long val; 42 43 switch (idx) { 44 case 0: 45 val = mfpmr(PMRN_PMC0); 46 break; 47 case 1: 48 val = mfpmr(PMRN_PMC1); 49 break; 50 case 2: 51 val = mfpmr(PMRN_PMC2); 52 break; 53 case 3: 54 val = mfpmr(PMRN_PMC3); 55 break; 56 case 4: 57 val = mfpmr(PMRN_PMC4); 58 break; 59 case 5: 60 val = mfpmr(PMRN_PMC5); 61 break; 62 default: 63 printk(KERN_ERR "oops trying to read PMC%d\n", idx); 64 val = 0; 65 } 66 return val; 67} 68 69/* 70 * Write one PMC. 71 */ 72static void write_pmc(int idx, unsigned long val) 73{ 74 switch (idx) { 75 case 0: 76 mtpmr(PMRN_PMC0, val); 77 break; 78 case 1: 79 mtpmr(PMRN_PMC1, val); 80 break; 81 case 2: 82 mtpmr(PMRN_PMC2, val); 83 break; 84 case 3: 85 mtpmr(PMRN_PMC3, val); 86 break; 87 case 4: 88 mtpmr(PMRN_PMC4, val); 89 break; 90 case 5: 91 mtpmr(PMRN_PMC5, val); 92 break; 93 default: 94 printk(KERN_ERR "oops trying to write PMC%d\n", idx); 95 } 96 97 isync(); 98} 99 100/* 101 * Write one local control A register 102 */ 103static void write_pmlca(int idx, unsigned long val) 104{ 105 switch (idx) { 106 case 0: 107 mtpmr(PMRN_PMLCA0, val); 108 break; 109 case 1: 110 mtpmr(PMRN_PMLCA1, val); 111 break; 112 case 2: 113 mtpmr(PMRN_PMLCA2, val); 114 break; 115 case 3: 116 mtpmr(PMRN_PMLCA3, val); 117 break; 118 case 4: 119 mtpmr(PMRN_PMLCA4, val); 120 break; 121 case 5: 122 mtpmr(PMRN_PMLCA5, val); 123 break; 124 default: 125 printk(KERN_ERR "oops trying to write PMLCA%d\n", idx); 126 } 127 128 isync(); 129} 130 131/* 132 * Write one local control B register 133 */ 134static void write_pmlcb(int idx, unsigned long val) 135{ 136 switch (idx) { 137 case 0: 138 mtpmr(PMRN_PMLCB0, val); 139 break; 140 case 1: 141 mtpmr(PMRN_PMLCB1, val); 142 break; 143 case 2: 144 mtpmr(PMRN_PMLCB2, val); 145 break; 146 case 3: 147 mtpmr(PMRN_PMLCB3, val); 148 break; 149 case 4: 150 mtpmr(PMRN_PMLCB4, val); 151 break; 152 case 5: 153 mtpmr(PMRN_PMLCB5, val); 154 break; 155 default: 156 printk(KERN_ERR "oops trying to write PMLCB%d\n", idx); 157 } 158 159 isync(); 160} 161 162static void fsl_emb_pmu_read(struct perf_event *event) 163{ 164 s64 val, delta, prev; 165 166 if (event->hw.state & PERF_HES_STOPPED) 167 return; 168 169 /* 170 * Performance monitor interrupts come even when interrupts 171 * are soft-disabled, as long as interrupts are hard-enabled. 172 * Therefore we treat them like NMIs. 173 */ 174 do { 175 prev = local64_read(&event->hw.prev_count); 176 barrier(); 177 val = read_pmc(event->hw.idx); 178 } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev); 179 180 /* The counters are only 32 bits wide */ 181 delta = (val - prev) & 0xfffffffful; 182 local64_add(delta, &event->count); 183 local64_sub(delta, &event->hw.period_left); 184} 185 186/* 187 * Disable all events to prevent PMU interrupts and to allow 188 * events to be added or removed. 189 */ 190static void fsl_emb_pmu_disable(struct pmu *pmu) 191{ 192 struct cpu_hw_events *cpuhw; 193 unsigned long flags; 194 195 local_irq_save(flags); 196 cpuhw = this_cpu_ptr(&cpu_hw_events); 197 198 if (!cpuhw->disabled) { 199 cpuhw->disabled = 1; 200 201 /* 202 * Check if we ever enabled the PMU on this cpu. 203 */ 204 if (!cpuhw->pmcs_enabled) { 205 ppc_enable_pmcs(); 206 cpuhw->pmcs_enabled = 1; 207 } 208 209 if (atomic_read(&num_events)) { 210 /* 211 * Set the 'freeze all counters' bit, and disable 212 * interrupts. The barrier is to make sure the 213 * mtpmr has been executed and the PMU has frozen 214 * the events before we return. 215 */ 216 217 mtpmr(PMRN_PMGC0, PMGC0_FAC); 218 isync(); 219 } 220 } 221 local_irq_restore(flags); 222} 223 224/* 225 * Re-enable all events if disable == 0. 226 * If we were previously disabled and events were added, then 227 * put the new config on the PMU. 228 */ 229static void fsl_emb_pmu_enable(struct pmu *pmu) 230{ 231 struct cpu_hw_events *cpuhw; 232 unsigned long flags; 233 234 local_irq_save(flags); 235 cpuhw = this_cpu_ptr(&cpu_hw_events); 236 if (!cpuhw->disabled) 237 goto out; 238 239 cpuhw->disabled = 0; 240 ppc_set_pmu_inuse(cpuhw->n_events != 0); 241 242 if (cpuhw->n_events > 0) { 243 mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE); 244 isync(); 245 } 246 247 out: 248 local_irq_restore(flags); 249} 250 251static int collect_events(struct perf_event *group, int max_count, 252 struct perf_event *ctrs[]) 253{ 254 int n = 0; 255 struct perf_event *event; 256 257 if (!is_software_event(group)) { 258 if (n >= max_count) 259 return -1; 260 ctrs[n] = group; 261 n++; 262 } 263 for_each_sibling_event(event, group) { 264 if (!is_software_event(event) && 265 event->state != PERF_EVENT_STATE_OFF) { 266 if (n >= max_count) 267 return -1; 268 ctrs[n] = event; 269 n++; 270 } 271 } 272 return n; 273} 274 275/* context locked on entry */ 276static int fsl_emb_pmu_add(struct perf_event *event, int flags) 277{ 278 struct cpu_hw_events *cpuhw; 279 int ret = -EAGAIN; 280 int num_counters = ppmu->n_counter; 281 u64 val; 282 int i; 283 284 perf_pmu_disable(event->pmu); 285 cpuhw = &get_cpu_var(cpu_hw_events); 286 287 if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) 288 num_counters = ppmu->n_restricted; 289 290 /* 291 * Allocate counters from top-down, so that restricted-capable 292 * counters are kept free as long as possible. 293 */ 294 for (i = num_counters - 1; i >= 0; i--) { 295 if (cpuhw->event[i]) 296 continue; 297 298 break; 299 } 300 301 if (i < 0) 302 goto out; 303 304 event->hw.idx = i; 305 cpuhw->event[i] = event; 306 ++cpuhw->n_events; 307 308 val = 0; 309 if (event->hw.sample_period) { 310 s64 left = local64_read(&event->hw.period_left); 311 if (left < 0x80000000L) 312 val = 0x80000000L - left; 313 } 314 local64_set(&event->hw.prev_count, val); 315 316 if (unlikely(!(flags & PERF_EF_START))) { 317 event->hw.state = PERF_HES_STOPPED | PERF_HES_UPTODATE; 318 val = 0; 319 } else { 320 event->hw.state &= ~(PERF_HES_STOPPED | PERF_HES_UPTODATE); 321 } 322 323 write_pmc(i, val); 324 perf_event_update_userpage(event); 325 326 write_pmlcb(i, event->hw.config >> 32); 327 write_pmlca(i, event->hw.config_base); 328 329 ret = 0; 330 out: 331 put_cpu_var(cpu_hw_events); 332 perf_pmu_enable(event->pmu); 333 return ret; 334} 335 336/* context locked on entry */ 337static void fsl_emb_pmu_del(struct perf_event *event, int flags) 338{ 339 struct cpu_hw_events *cpuhw; 340 int i = event->hw.idx; 341 342 perf_pmu_disable(event->pmu); 343 if (i < 0) 344 goto out; 345 346 fsl_emb_pmu_read(event); 347 348 cpuhw = &get_cpu_var(cpu_hw_events); 349 350 WARN_ON(event != cpuhw->event[event->hw.idx]); 351 352 write_pmlca(i, 0); 353 write_pmlcb(i, 0); 354 write_pmc(i, 0); 355 356 cpuhw->event[i] = NULL; 357 event->hw.idx = -1; 358 359 /* 360 * TODO: if at least one restricted event exists, and we 361 * just freed up a non-restricted-capable counter, and 362 * there is a restricted-capable counter occupied by 363 * a non-restricted event, migrate that event to the 364 * vacated counter. 365 */ 366 367 cpuhw->n_events--; 368 369 out: 370 perf_pmu_enable(event->pmu); 371 put_cpu_var(cpu_hw_events); 372} 373 374static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags) 375{ 376 unsigned long flags; 377 unsigned long val; 378 s64 left; 379 380 if (event->hw.idx < 0 || !event->hw.sample_period) 381 return; 382 383 if (!(event->hw.state & PERF_HES_STOPPED)) 384 return; 385 386 if (ef_flags & PERF_EF_RELOAD) 387 WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); 388 389 local_irq_save(flags); 390 perf_pmu_disable(event->pmu); 391 392 event->hw.state = 0; 393 left = local64_read(&event->hw.period_left); 394 val = 0; 395 if (left < 0x80000000L) 396 val = 0x80000000L - left; 397 write_pmc(event->hw.idx, val); 398 399 perf_event_update_userpage(event); 400 perf_pmu_enable(event->pmu); 401 local_irq_restore(flags); 402} 403 404static void fsl_emb_pmu_stop(struct perf_event *event, int ef_flags) 405{ 406 unsigned long flags; 407 408 if (event->hw.idx < 0 || !event->hw.sample_period) 409 return; 410 411 if (event->hw.state & PERF_HES_STOPPED) 412 return; 413 414 local_irq_save(flags); 415 perf_pmu_disable(event->pmu); 416 417 fsl_emb_pmu_read(event); 418 event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; 419 write_pmc(event->hw.idx, 0); 420 421 perf_event_update_userpage(event); 422 perf_pmu_enable(event->pmu); 423 local_irq_restore(flags); 424} 425 426/* 427 * Release the PMU if this is the last perf_event. 428 */ 429static void hw_perf_event_destroy(struct perf_event *event) 430{ 431 if (!atomic_add_unless(&num_events, -1, 1)) { 432 mutex_lock(&pmc_reserve_mutex); 433 if (atomic_dec_return(&num_events) == 0) 434 release_pmc_hardware(); 435 mutex_unlock(&pmc_reserve_mutex); 436 } 437} 438 439/* 440 * Translate a generic cache event_id config to a raw event_id code. 441 */ 442static int hw_perf_cache_event(u64 config, u64 *eventp) 443{ 444 unsigned long type, op, result; 445 int ev; 446 447 if (!ppmu->cache_events) 448 return -EINVAL; 449 450 /* unpack config */ 451 type = config & 0xff; 452 op = (config >> 8) & 0xff; 453 result = (config >> 16) & 0xff; 454 455 if (type >= PERF_COUNT_HW_CACHE_MAX || 456 op >= PERF_COUNT_HW_CACHE_OP_MAX || 457 result >= PERF_COUNT_HW_CACHE_RESULT_MAX) 458 return -EINVAL; 459 460 ev = (*ppmu->cache_events)[type][op][result]; 461 if (ev == 0) 462 return -EOPNOTSUPP; 463 if (ev == -1) 464 return -EINVAL; 465 *eventp = ev; 466 return 0; 467} 468 469static int fsl_emb_pmu_event_init(struct perf_event *event) 470{ 471 u64 ev; 472 struct perf_event *events[MAX_HWEVENTS]; 473 int n; 474 int err; 475 int num_restricted; 476 int i; 477 478 if (ppmu->n_counter > MAX_HWEVENTS) { 479 WARN(1, "No. of perf counters (%d) is higher than max array size(%d)\n", 480 ppmu->n_counter, MAX_HWEVENTS); 481 ppmu->n_counter = MAX_HWEVENTS; 482 } 483 484 switch (event->attr.type) { 485 case PERF_TYPE_HARDWARE: 486 ev = event->attr.config; 487 if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) 488 return -EOPNOTSUPP; 489 ev = ppmu->generic_events[ev]; 490 break; 491 492 case PERF_TYPE_HW_CACHE: 493 err = hw_perf_cache_event(event->attr.config, &ev); 494 if (err) 495 return err; 496 break; 497 498 case PERF_TYPE_RAW: 499 ev = event->attr.config; 500 break; 501 502 default: 503 return -ENOENT; 504 } 505 506 event->hw.config = ppmu->xlate_event(ev); 507 if (!(event->hw.config & FSL_EMB_EVENT_VALID)) 508 return -EINVAL; 509 510 /* 511 * If this is in a group, check if it can go on with all the 512 * other hardware events in the group. We assume the event 513 * hasn't been linked into its leader's sibling list at this point. 514 */ 515 n = 0; 516 if (event->group_leader != event) { 517 n = collect_events(event->group_leader, 518 ppmu->n_counter - 1, events); 519 if (n < 0) 520 return -EINVAL; 521 } 522 523 if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) { 524 num_restricted = 0; 525 for (i = 0; i < n; i++) { 526 if (events[i]->hw.config & FSL_EMB_EVENT_RESTRICTED) 527 num_restricted++; 528 } 529 530 if (num_restricted >= ppmu->n_restricted) 531 return -EINVAL; 532 } 533 534 event->hw.idx = -1; 535 536 event->hw.config_base = PMLCA_CE | PMLCA_FCM1 | 537 (u32)((ev << 16) & PMLCA_EVENT_MASK); 538 539 if (event->attr.exclude_user) 540 event->hw.config_base |= PMLCA_FCU; 541 if (event->attr.exclude_kernel) 542 event->hw.config_base |= PMLCA_FCS; 543 if (event->attr.exclude_idle) 544 return -ENOTSUPP; 545 546 event->hw.last_period = event->hw.sample_period; 547 local64_set(&event->hw.period_left, event->hw.last_period); 548 549 /* 550 * See if we need to reserve the PMU. 551 * If no events are currently in use, then we have to take a 552 * mutex to ensure that we don't race with another task doing 553 * reserve_pmc_hardware or release_pmc_hardware. 554 */ 555 err = 0; 556 if (!atomic_inc_not_zero(&num_events)) { 557 mutex_lock(&pmc_reserve_mutex); 558 if (atomic_read(&num_events) == 0 && 559 reserve_pmc_hardware(perf_event_interrupt)) 560 err = -EBUSY; 561 else 562 atomic_inc(&num_events); 563 mutex_unlock(&pmc_reserve_mutex); 564 565 mtpmr(PMRN_PMGC0, PMGC0_FAC); 566 isync(); 567 } 568 event->destroy = hw_perf_event_destroy; 569 570 return err; 571} 572 573static struct pmu fsl_emb_pmu = { 574 .pmu_enable = fsl_emb_pmu_enable, 575 .pmu_disable = fsl_emb_pmu_disable, 576 .event_init = fsl_emb_pmu_event_init, 577 .add = fsl_emb_pmu_add, 578 .del = fsl_emb_pmu_del, 579 .start = fsl_emb_pmu_start, 580 .stop = fsl_emb_pmu_stop, 581 .read = fsl_emb_pmu_read, 582}; 583 584/* 585 * A counter has overflowed; update its count and record 586 * things if requested. Note that interrupts are hard-disabled 587 * here so there is no possibility of being interrupted. 588 */ 589static void record_and_restart(struct perf_event *event, unsigned long val, 590 struct pt_regs *regs) 591{ 592 u64 period = event->hw.sample_period; 593 s64 prev, delta, left; 594 int record = 0; 595 596 if (event->hw.state & PERF_HES_STOPPED) { 597 write_pmc(event->hw.idx, 0); 598 return; 599 } 600 601 /* we don't have to worry about interrupts here */ 602 prev = local64_read(&event->hw.prev_count); 603 delta = (val - prev) & 0xfffffffful; 604 local64_add(delta, &event->count); 605 606 /* 607 * See if the total period for this event has expired, 608 * and update for the next period. 609 */ 610 val = 0; 611 left = local64_read(&event->hw.period_left) - delta; 612 if (period) { 613 if (left <= 0) { 614 left += period; 615 if (left <= 0) 616 left = period; 617 record = 1; 618 event->hw.last_period = event->hw.sample_period; 619 } 620 if (left < 0x80000000LL) 621 val = 0x80000000LL - left; 622 } 623 624 write_pmc(event->hw.idx, val); 625 local64_set(&event->hw.prev_count, val); 626 local64_set(&event->hw.period_left, left); 627 perf_event_update_userpage(event); 628 629 /* 630 * Finally record data if requested. 631 */ 632 if (record) { 633 struct perf_sample_data data; 634 635 perf_sample_data_init(&data, 0, event->hw.last_period); 636 637 if (perf_event_overflow(event, &data, regs)) 638 fsl_emb_pmu_stop(event, 0); 639 } 640} 641 642static void perf_event_interrupt(struct pt_regs *regs) 643{ 644 int i; 645 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); 646 struct perf_event *event; 647 unsigned long val; 648 int found = 0; 649 650 for (i = 0; i < ppmu->n_counter; ++i) { 651 event = cpuhw->event[i]; 652 653 val = read_pmc(i); 654 if ((int)val < 0) { 655 if (event) { 656 /* event has overflowed */ 657 found = 1; 658 record_and_restart(event, val, regs); 659 } else { 660 /* 661 * Disabled counter is negative, 662 * reset it just in case. 663 */ 664 write_pmc(i, 0); 665 } 666 } 667 } 668 669 /* PMM will keep counters frozen until we return from the interrupt. */ 670 mtmsr(mfmsr() | MSR_PMM); 671 mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE); 672 isync(); 673} 674 675void hw_perf_event_setup(int cpu) 676{ 677 struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); 678 679 memset(cpuhw, 0, sizeof(*cpuhw)); 680} 681 682int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu) 683{ 684 if (ppmu) 685 return -EBUSY; /* something's already registered */ 686 687 ppmu = pmu; 688 pr_info("%s performance monitor hardware support registered\n", 689 pmu->name); 690 691 perf_pmu_register(&fsl_emb_pmu, "cpu", PERF_TYPE_RAW); 692 693 return 0; 694}