diff options
| author | Paul Mackerras <paulus@samba.org> | 2009-06-11 00:55:42 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-06-11 10:48:37 -0400 |
| commit | 106b506c3a8b74daa5751e83ed3e46438fcf9a52 (patch) | |
| tree | ad141aa86b020501823c7e2c7ac0abb9f27cf5a1 /arch | |
| parent | 4da52960fd1ae3ddd14901bc88b608cbeaa4b9a6 (diff) | |
perf_counter: powerpc: Implement generalized cache events for POWER processors
This adds tables of event codes for the generalized cache events for
all the currently supported powerpc processors: POWER{4,5,5+,6,7} and
PPC970*, plus powerpc-specific code to use these tables when a
generalized cache event is requested.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <18992.36430.933526.742969@drongo.ozlabs.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/powerpc/include/asm/perf_counter.h | 3 | ||||
| -rw-r--r-- | arch/powerpc/kernel/perf_counter.c | 42 | ||||
| -rw-r--r-- | arch/powerpc/kernel/power4-pmu.c | 41 | ||||
| -rw-r--r-- | arch/powerpc/kernel/power5+-pmu.c | 45 | ||||
| -rw-r--r-- | arch/powerpc/kernel/power5-pmu.c | 41 | ||||
| -rw-r--r-- | arch/powerpc/kernel/power6-pmu.c | 46 | ||||
| -rw-r--r-- | arch/powerpc/kernel/power7-pmu.c | 41 | ||||
| -rw-r--r-- | arch/powerpc/kernel/ppc970-pmu.c | 41 |
8 files changed, 294 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/perf_counter.h b/arch/powerpc/include/asm/perf_counter.h index 1c60f0ca7920..cc7c887705b8 100644 --- a/arch/powerpc/include/asm/perf_counter.h +++ b/arch/powerpc/include/asm/perf_counter.h | |||
| @@ -33,6 +33,9 @@ struct power_pmu { | |||
| 33 | u32 flags; | 33 | u32 flags; |
| 34 | int n_generic; | 34 | int n_generic; |
| 35 | int *generic_events; | 35 | int *generic_events; |
| 36 | int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] | ||
| 37 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
| 38 | [PERF_COUNT_HW_CACHE_RESULT_MAX]; | ||
| 36 | }; | 39 | }; |
| 37 | 40 | ||
| 38 | extern struct power_pmu *ppmu; | 41 | extern struct power_pmu *ppmu; |
diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 5d12e68aac1c..bb202388170e 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c | |||
| @@ -856,6 +856,36 @@ static void hw_perf_counter_destroy(struct perf_counter *counter) | |||
| 856 | } | 856 | } |
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | /* | ||
| 860 | * Translate a generic cache event config to a raw event code. | ||
| 861 | */ | ||
| 862 | static int hw_perf_cache_event(u64 config, u64 *eventp) | ||
| 863 | { | ||
| 864 | unsigned long type, op, result; | ||
| 865 | int ev; | ||
| 866 | |||
| 867 | if (!ppmu->cache_events) | ||
| 868 | return -EINVAL; | ||
| 869 | |||
| 870 | /* unpack config */ | ||
| 871 | type = config & 0xff; | ||
| 872 | op = (config >> 8) & 0xff; | ||
| 873 | result = (config >> 16) & 0xff; | ||
| 874 | |||
| 875 | if (type >= PERF_COUNT_HW_CACHE_MAX || | ||
| 876 | op >= PERF_COUNT_HW_CACHE_OP_MAX || | ||
| 877 | result >= PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
| 878 | return -EINVAL; | ||
| 879 | |||
| 880 | ev = (*ppmu->cache_events)[type][op][result]; | ||
| 881 | if (ev == 0) | ||
| 882 | return -EOPNOTSUPP; | ||
| 883 | if (ev == -1) | ||
| 884 | return -EINVAL; | ||
| 885 | *eventp = ev; | ||
| 886 | return 0; | ||
| 887 | } | ||
| 888 | |||
| 859 | const struct pmu *hw_perf_counter_init(struct perf_counter *counter) | 889 | const struct pmu *hw_perf_counter_init(struct perf_counter *counter) |
| 860 | { | 890 | { |
| 861 | u64 ev; | 891 | u64 ev; |
| @@ -868,13 +898,21 @@ const struct pmu *hw_perf_counter_init(struct perf_counter *counter) | |||
| 868 | 898 | ||
| 869 | if (!ppmu) | 899 | if (!ppmu) |
| 870 | return ERR_PTR(-ENXIO); | 900 | return ERR_PTR(-ENXIO); |
| 871 | if (counter->attr.type != PERF_TYPE_RAW) { | 901 | switch (counter->attr.type) { |
| 902 | case PERF_TYPE_HARDWARE: | ||
| 872 | ev = counter->attr.config; | 903 | ev = counter->attr.config; |
| 873 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) | 904 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) |
| 874 | return ERR_PTR(-EOPNOTSUPP); | 905 | return ERR_PTR(-EOPNOTSUPP); |
| 875 | ev = ppmu->generic_events[ev]; | 906 | ev = ppmu->generic_events[ev]; |
| 876 | } else { | 907 | break; |
| 908 | case PERF_TYPE_HW_CACHE: | ||
| 909 | err = hw_perf_cache_event(counter->attr.config, &ev); | ||
| 910 | if (err) | ||
| 911 | return ERR_PTR(err); | ||
| 912 | break; | ||
| 913 | case PERF_TYPE_RAW: | ||
| 877 | ev = counter->attr.config; | 914 | ev = counter->attr.config; |
| 915 | break; | ||
| 878 | } | 916 | } |
| 879 | counter->hw.config_base = ev; | 917 | counter->hw.config_base = ev; |
| 880 | counter->hw.idx = 0; | 918 | counter->hw.idx = 0; |
diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c index 836fa118eb1e..0e94b6857220 100644 --- a/arch/powerpc/kernel/power4-pmu.c +++ b/arch/powerpc/kernel/power4-pmu.c | |||
| @@ -543,6 +543,46 @@ static int p4_generic_events[] = { | |||
| 543 | [PERF_COUNT_BRANCH_MISSES] = 0x331, /* PM_BR_MPRED_CR */ | 543 | [PERF_COUNT_BRANCH_MISSES] = 0x331, /* PM_BR_MPRED_CR */ |
| 544 | }; | 544 | }; |
| 545 | 545 | ||
| 546 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 547 | |||
| 548 | /* | ||
| 549 | * Table of generalized cache-related events. | ||
| 550 | * 0 means not supported, -1 means nonsensical, other values | ||
| 551 | * are event codes. | ||
| 552 | */ | ||
| 553 | static int power4_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | ||
| 554 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 555 | [C(OP_READ)] = { 0x8c10, 0x3c10 }, | ||
| 556 | [C(OP_WRITE)] = { 0x7c10, 0xc13 }, | ||
| 557 | [C(OP_PREFETCH)] = { 0xc35, 0 }, | ||
| 558 | }, | ||
| 559 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 560 | [C(OP_READ)] = { 0, 0 }, | ||
| 561 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 562 | [C(OP_PREFETCH)] = { 0, 0 }, | ||
| 563 | }, | ||
| 564 | [C(L2)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 565 | [C(OP_READ)] = { 0, 0 }, | ||
| 566 | [C(OP_WRITE)] = { 0, 0 }, | ||
| 567 | [C(OP_PREFETCH)] = { 0xc34, 0 }, | ||
| 568 | }, | ||
| 569 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 570 | [C(OP_READ)] = { 0, 0x904 }, | ||
| 571 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 572 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 573 | }, | ||
| 574 | [C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 575 | [C(OP_READ)] = { 0, 0x900 }, | ||
| 576 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 577 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 578 | }, | ||
| 579 | [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 580 | [C(OP_READ)] = { 0x330, 0x331 }, | ||
| 581 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 582 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 583 | }, | ||
| 584 | }; | ||
| 585 | |||
| 546 | struct power_pmu power4_pmu = { | 586 | struct power_pmu power4_pmu = { |
| 547 | .n_counter = 8, | 587 | .n_counter = 8, |
| 548 | .max_alternatives = 5, | 588 | .max_alternatives = 5, |
| @@ -554,4 +594,5 @@ struct power_pmu power4_pmu = { | |||
| 554 | .disable_pmc = p4_disable_pmc, | 594 | .disable_pmc = p4_disable_pmc, |
| 555 | .n_generic = ARRAY_SIZE(p4_generic_events), | 595 | .n_generic = ARRAY_SIZE(p4_generic_events), |
| 556 | .generic_events = p4_generic_events, | 596 | .generic_events = p4_generic_events, |
| 597 | .cache_events = &power4_cache_events, | ||
| 557 | }; | 598 | }; |
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c index 8471e3c2e465..bbf2cbb07388 100644 --- a/arch/powerpc/kernel/power5+-pmu.c +++ b/arch/powerpc/kernel/power5+-pmu.c | |||
| @@ -614,6 +614,46 @@ static int power5p_generic_events[] = { | |||
| 614 | [PERF_COUNT_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */ | 614 | [PERF_COUNT_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */ |
| 615 | }; | 615 | }; |
| 616 | 616 | ||
| 617 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 618 | |||
| 619 | /* | ||
| 620 | * Table of generalized cache-related events. | ||
| 621 | * 0 means not supported, -1 means nonsensical, other values | ||
| 622 | * are event codes. | ||
| 623 | */ | ||
| 624 | static int power5p_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | ||
| 625 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 626 | [C(OP_READ)] = { 0x1c10a8, 0x3c1088 }, | ||
| 627 | [C(OP_WRITE)] = { 0x2c10a8, 0xc10c3 }, | ||
| 628 | [C(OP_PREFETCH)] = { 0xc70e7, -1 }, | ||
| 629 | }, | ||
| 630 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 631 | [C(OP_READ)] = { 0, 0 }, | ||
| 632 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 633 | [C(OP_PREFETCH)] = { 0, 0 }, | ||
| 634 | }, | ||
| 635 | [C(L2)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 636 | [C(OP_READ)] = { 0, 0 }, | ||
| 637 | [C(OP_WRITE)] = { 0, 0 }, | ||
| 638 | [C(OP_PREFETCH)] = { 0xc50c3, 0 }, | ||
| 639 | }, | ||
| 640 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 641 | [C(OP_READ)] = { 0xc20e4, 0x800c4 }, | ||
| 642 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 643 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 644 | }, | ||
| 645 | [C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 646 | [C(OP_READ)] = { 0, 0x800c0 }, | ||
| 647 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 648 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 649 | }, | ||
| 650 | [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 651 | [C(OP_READ)] = { 0x230e4, 0x230e5 }, | ||
| 652 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 653 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 654 | }, | ||
| 655 | }; | ||
| 656 | |||
| 617 | struct power_pmu power5p_pmu = { | 657 | struct power_pmu power5p_pmu = { |
| 618 | .n_counter = 6, | 658 | .n_counter = 6, |
| 619 | .max_alternatives = MAX_ALT, | 659 | .max_alternatives = MAX_ALT, |
| @@ -623,8 +663,9 @@ struct power_pmu power5p_pmu = { | |||
| 623 | .get_constraint = power5p_get_constraint, | 663 | .get_constraint = power5p_get_constraint, |
| 624 | .get_alternatives = power5p_get_alternatives, | 664 | .get_alternatives = power5p_get_alternatives, |
| 625 | .disable_pmc = power5p_disable_pmc, | 665 | .disable_pmc = power5p_disable_pmc, |
| 666 | .limited_pmc_event = power5p_limited_pmc_event, | ||
| 667 | .flags = PPMU_LIMITED_PMC5_6, | ||
| 626 | .n_generic = ARRAY_SIZE(power5p_generic_events), | 668 | .n_generic = ARRAY_SIZE(power5p_generic_events), |
| 627 | .generic_events = power5p_generic_events, | 669 | .generic_events = power5p_generic_events, |
| 628 | .flags = PPMU_LIMITED_PMC5_6, | 670 | .cache_events = &power5p_cache_events, |
| 629 | .limited_pmc_event = power5p_limited_pmc_event, | ||
| 630 | }; | 671 | }; |
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c index 1b44c5fca189..670cf10b91e8 100644 --- a/arch/powerpc/kernel/power5-pmu.c +++ b/arch/powerpc/kernel/power5-pmu.c | |||
| @@ -556,6 +556,46 @@ static int power5_generic_events[] = { | |||
| 556 | [PERF_COUNT_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */ | 556 | [PERF_COUNT_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */ |
| 557 | }; | 557 | }; |
| 558 | 558 | ||
| 559 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 560 | |||
| 561 | /* | ||
| 562 | * Table of generalized cache-related events. | ||
| 563 | * 0 means not supported, -1 means nonsensical, other values | ||
| 564 | * are event codes. | ||
| 565 | */ | ||
| 566 | static int power5_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | ||
| 567 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 568 | [C(OP_READ)] = { 0x4c1090, 0x3c1088 }, | ||
| 569 | [C(OP_WRITE)] = { 0x3c1090, 0xc10c3 }, | ||
| 570 | [C(OP_PREFETCH)] = { 0xc70e7, 0 }, | ||
| 571 | }, | ||
| 572 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 573 | [C(OP_READ)] = { 0, 0 }, | ||
| 574 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 575 | [C(OP_PREFETCH)] = { 0, 0 }, | ||
| 576 | }, | ||
| 577 | [C(L2)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 578 | [C(OP_READ)] = { 0, 0x3c309b }, | ||
| 579 | [C(OP_WRITE)] = { 0, 0 }, | ||
| 580 | [C(OP_PREFETCH)] = { 0xc50c3, 0 }, | ||
| 581 | }, | ||
| 582 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 583 | [C(OP_READ)] = { 0x2c4090, 0x800c4 }, | ||
| 584 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 585 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 586 | }, | ||
| 587 | [C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 588 | [C(OP_READ)] = { 0, 0x800c0 }, | ||
| 589 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 590 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 591 | }, | ||
| 592 | [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 593 | [C(OP_READ)] = { 0x230e4, 0x230e5 }, | ||
| 594 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 595 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 596 | }, | ||
| 597 | }; | ||
| 598 | |||
| 559 | struct power_pmu power5_pmu = { | 599 | struct power_pmu power5_pmu = { |
| 560 | .n_counter = 6, | 600 | .n_counter = 6, |
| 561 | .max_alternatives = MAX_ALT, | 601 | .max_alternatives = MAX_ALT, |
| @@ -567,4 +607,5 @@ struct power_pmu power5_pmu = { | |||
| 567 | .disable_pmc = power5_disable_pmc, | 607 | .disable_pmc = power5_disable_pmc, |
| 568 | .n_generic = ARRAY_SIZE(power5_generic_events), | 608 | .n_generic = ARRAY_SIZE(power5_generic_events), |
| 569 | .generic_events = power5_generic_events, | 609 | .generic_events = power5_generic_events, |
| 610 | .cache_events = &power5_cache_events, | ||
| 570 | }; | 611 | }; |
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index cd4fbe06c35d..4da707866097 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c | |||
| @@ -474,6 +474,47 @@ static int power6_generic_events[] = { | |||
| 474 | [PERF_COUNT_BRANCH_MISSES] = 0x400052, /* BR_MPRED */ | 474 | [PERF_COUNT_BRANCH_MISSES] = 0x400052, /* BR_MPRED */ |
| 475 | }; | 475 | }; |
| 476 | 476 | ||
| 477 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 478 | |||
| 479 | /* | ||
| 480 | * Table of generalized cache-related events. | ||
| 481 | * 0 means not supported, -1 means nonsensical, other values | ||
| 482 | * are event codes. | ||
| 483 | * The "DTLB" and "ITLB" events relate to the DERAT and IERAT. | ||
| 484 | */ | ||
| 485 | static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | ||
| 486 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 487 | [C(OP_READ)] = { 0x80082, 0x80080 }, | ||
| 488 | [C(OP_WRITE)] = { 0x80086, 0x80088 }, | ||
| 489 | [C(OP_PREFETCH)] = { 0x810a4, 0 }, | ||
| 490 | }, | ||
| 491 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 492 | [C(OP_READ)] = { 0, 0x100056 }, | ||
| 493 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 494 | [C(OP_PREFETCH)] = { 0x4008c, 0 }, | ||
| 495 | }, | ||
| 496 | [C(L2)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 497 | [C(OP_READ)] = { 0x150730, 0x250532 }, | ||
| 498 | [C(OP_WRITE)] = { 0x250432, 0x150432 }, | ||
| 499 | [C(OP_PREFETCH)] = { 0x810a6, 0 }, | ||
| 500 | }, | ||
| 501 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 502 | [C(OP_READ)] = { 0, 0x20000e }, | ||
| 503 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 504 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 505 | }, | ||
| 506 | [C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 507 | [C(OP_READ)] = { 0, 0x420ce }, | ||
| 508 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 509 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 510 | }, | ||
| 511 | [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 512 | [C(OP_READ)] = { 0x430e6, 0x400052 }, | ||
| 513 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 514 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 515 | }, | ||
| 516 | }; | ||
| 517 | |||
| 477 | struct power_pmu power6_pmu = { | 518 | struct power_pmu power6_pmu = { |
| 478 | .n_counter = 6, | 519 | .n_counter = 6, |
| 479 | .max_alternatives = MAX_ALT, | 520 | .max_alternatives = MAX_ALT, |
| @@ -483,8 +524,9 @@ struct power_pmu power6_pmu = { | |||
| 483 | .get_constraint = p6_get_constraint, | 524 | .get_constraint = p6_get_constraint, |
| 484 | .get_alternatives = p6_get_alternatives, | 525 | .get_alternatives = p6_get_alternatives, |
| 485 | .disable_pmc = p6_disable_pmc, | 526 | .disable_pmc = p6_disable_pmc, |
| 527 | .limited_pmc_event = p6_limited_pmc_event, | ||
| 528 | .flags = PPMU_LIMITED_PMC5_6 | PPMU_ALT_SIPR, | ||
| 486 | .n_generic = ARRAY_SIZE(power6_generic_events), | 529 | .n_generic = ARRAY_SIZE(power6_generic_events), |
| 487 | .generic_events = power6_generic_events, | 530 | .generic_events = power6_generic_events, |
| 488 | .flags = PPMU_LIMITED_PMC5_6 | PPMU_ALT_SIPR, | 531 | .cache_events = &power6_cache_events, |
| 489 | .limited_pmc_event = p6_limited_pmc_event, | ||
| 490 | }; | 532 | }; |
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c index dfac48d8ff45..060e0deb399e 100644 --- a/arch/powerpc/kernel/power7-pmu.c +++ b/arch/powerpc/kernel/power7-pmu.c | |||
| @@ -302,6 +302,46 @@ static int power7_generic_events[] = { | |||
| 302 | [PERF_COUNT_BRANCH_MISSES] = 0x400f6, /* BR_MPRED */ | 302 | [PERF_COUNT_BRANCH_MISSES] = 0x400f6, /* BR_MPRED */ |
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 306 | |||
| 307 | /* | ||
| 308 | * Table of generalized cache-related events. | ||
| 309 | * 0 means not supported, -1 means nonsensical, other values | ||
| 310 | * are event codes. | ||
| 311 | */ | ||
| 312 | static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | ||
| 313 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 314 | [C(OP_READ)] = { 0x400f0, 0xc880 }, | ||
| 315 | [C(OP_WRITE)] = { 0, 0x300f0 }, | ||
| 316 | [C(OP_PREFETCH)] = { 0xd8b8, 0 }, | ||
| 317 | }, | ||
| 318 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 319 | [C(OP_READ)] = { 0, 0x200fc }, | ||
| 320 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 321 | [C(OP_PREFETCH)] = { 0x408a, 0 }, | ||
| 322 | }, | ||
| 323 | [C(L2)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 324 | [C(OP_READ)] = { 0x6080, 0x6084 }, | ||
| 325 | [C(OP_WRITE)] = { 0x6082, 0x6086 }, | ||
| 326 | [C(OP_PREFETCH)] = { 0, 0 }, | ||
| 327 | }, | ||
| 328 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 329 | [C(OP_READ)] = { 0, 0x300fc }, | ||
| 330 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 331 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 332 | }, | ||
| 333 | [C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 334 | [C(OP_READ)] = { 0, 0x400fc }, | ||
| 335 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 336 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 337 | }, | ||
| 338 | [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 339 | [C(OP_READ)] = { 0x10068, 0x400f6 }, | ||
| 340 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 341 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 342 | }, | ||
| 343 | }; | ||
| 344 | |||
| 305 | struct power_pmu power7_pmu = { | 345 | struct power_pmu power7_pmu = { |
| 306 | .n_counter = 6, | 346 | .n_counter = 6, |
| 307 | .max_alternatives = MAX_ALT + 1, | 347 | .max_alternatives = MAX_ALT + 1, |
| @@ -313,4 +353,5 @@ struct power_pmu power7_pmu = { | |||
| 313 | .disable_pmc = power7_disable_pmc, | 353 | .disable_pmc = power7_disable_pmc, |
| 314 | .n_generic = ARRAY_SIZE(power7_generic_events), | 354 | .n_generic = ARRAY_SIZE(power7_generic_events), |
| 315 | .generic_events = power7_generic_events, | 355 | .generic_events = power7_generic_events, |
| 356 | .cache_events = &power7_cache_events, | ||
| 316 | }; | 357 | }; |
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index eed47c4523f1..336adf1736af 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c | |||
| @@ -427,6 +427,46 @@ static int ppc970_generic_events[] = { | |||
| 427 | [PERF_COUNT_BRANCH_MISSES] = 0x327, /* PM_GRP_BR_MPRED */ | 427 | [PERF_COUNT_BRANCH_MISSES] = 0x327, /* PM_GRP_BR_MPRED */ |
| 428 | }; | 428 | }; |
| 429 | 429 | ||
| 430 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
| 431 | |||
| 432 | /* | ||
| 433 | * Table of generalized cache-related events. | ||
| 434 | * 0 means not supported, -1 means nonsensical, other values | ||
| 435 | * are event codes. | ||
| 436 | */ | ||
| 437 | static int ppc970_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | ||
| 438 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 439 | [C(OP_READ)] = { 0x8810, 0x3810 }, | ||
| 440 | [C(OP_WRITE)] = { 0x7810, 0x813 }, | ||
| 441 | [C(OP_PREFETCH)] = { 0x731, 0 }, | ||
| 442 | }, | ||
| 443 | [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 444 | [C(OP_READ)] = { 0, 0 }, | ||
| 445 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 446 | [C(OP_PREFETCH)] = { 0, 0 }, | ||
| 447 | }, | ||
| 448 | [C(L2)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 449 | [C(OP_READ)] = { 0, 0 }, | ||
| 450 | [C(OP_WRITE)] = { 0, 0 }, | ||
| 451 | [C(OP_PREFETCH)] = { 0x733, 0 }, | ||
| 452 | }, | ||
| 453 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 454 | [C(OP_READ)] = { 0, 0x704 }, | ||
| 455 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 456 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 457 | }, | ||
| 458 | [C(ITLB)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 459 | [C(OP_READ)] = { 0, 0x700 }, | ||
| 460 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 461 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 462 | }, | ||
| 463 | [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */ | ||
| 464 | [C(OP_READ)] = { 0x431, 0x327 }, | ||
| 465 | [C(OP_WRITE)] = { -1, -1 }, | ||
| 466 | [C(OP_PREFETCH)] = { -1, -1 }, | ||
| 467 | }, | ||
| 468 | }; | ||
| 469 | |||
| 430 | struct power_pmu ppc970_pmu = { | 470 | struct power_pmu ppc970_pmu = { |
| 431 | .n_counter = 8, | 471 | .n_counter = 8, |
| 432 | .max_alternatives = 2, | 472 | .max_alternatives = 2, |
| @@ -438,4 +478,5 @@ struct power_pmu ppc970_pmu = { | |||
| 438 | .disable_pmc = p970_disable_pmc, | 478 | .disable_pmc = p970_disable_pmc, |
| 439 | .n_generic = ARRAY_SIZE(ppc970_generic_events), | 479 | .n_generic = ARRAY_SIZE(ppc970_generic_events), |
| 440 | .generic_events = ppc970_generic_events, | 480 | .generic_events = ppc970_generic_events, |
| 481 | .cache_events = &ppc970_cache_events, | ||
| 441 | }; | 482 | }; |
