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 | |
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>
-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 | }; |