diff options
| -rw-r--r-- | arch/arm/include/asm/perf_event.h | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/perf_event.c | 3 | ||||
| -rw-r--r-- | arch/arm/kernel/perf_event_v7.c | 153 |
3 files changed, 157 insertions, 0 deletions
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 207bd3c79ab..0f8e3827a89 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
| @@ -25,6 +25,7 @@ enum arm_perf_pmu_ids { | |||
| 25 | ARM_PERF_PMU_ID_CA8, | 25 | ARM_PERF_PMU_ID_CA8, |
| 26 | ARM_PERF_PMU_ID_CA9, | 26 | ARM_PERF_PMU_ID_CA9, |
| 27 | ARM_PERF_PMU_ID_CA5, | 27 | ARM_PERF_PMU_ID_CA5, |
| 28 | ARM_PERF_PMU_ID_CA15, | ||
| 28 | ARM_NUM_PMU_IDS, | 29 | ARM_NUM_PMU_IDS, |
| 29 | }; | 30 | }; |
| 30 | 31 | ||
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index df4e517687b..262ea67f60a 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
| @@ -663,6 +663,9 @@ init_hw_perf_events(void) | |||
| 663 | case 0xC050: /* Cortex-A5 */ | 663 | case 0xC050: /* Cortex-A5 */ |
| 664 | armpmu = armv7_a5_pmu_init(); | 664 | armpmu = armv7_a5_pmu_init(); |
| 665 | break; | 665 | break; |
| 666 | case 0xC0F0: /* Cortex-A15 */ | ||
| 667 | armpmu = armv7_a15_pmu_init(); | ||
| 668 | break; | ||
| 666 | } | 669 | } |
| 667 | /* Intel CPUs [xscale]. */ | 670 | /* Intel CPUs [xscale]. */ |
| 668 | } else if (0x69 == implementor) { | 671 | } else if (0x69 == implementor) { |
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index db1d6c4a32a..963317896c8 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
| @@ -168,6 +168,24 @@ enum armv7_a5_perf_types { | |||
| 168 | ARMV7_PERFCTR_STALL_SB_FULL = 0xc9, | 168 | ARMV7_PERFCTR_STALL_SB_FULL = 0xc9, |
| 169 | }; | 169 | }; |
| 170 | 170 | ||
| 171 | /* ARMv7 Cortex-A15 specific event types */ | ||
| 172 | enum armv7_a15_perf_types { | ||
| 173 | ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS = 0x40, | ||
| 174 | ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS = 0x41, | ||
| 175 | ARMV7_PERFCTR_L1_DCACHE_READ_REFILL = 0x42, | ||
| 176 | ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL = 0x43, | ||
| 177 | |||
| 178 | ARMV7_PERFCTR_L1_DTLB_READ_REFILL = 0x4C, | ||
| 179 | ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL = 0x4D, | ||
| 180 | |||
| 181 | ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS = 0x50, | ||
| 182 | ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS = 0x51, | ||
| 183 | ARMV7_PERFCTR_L2_DCACHE_READ_REFILL = 0x52, | ||
| 184 | ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL = 0x53, | ||
| 185 | |||
| 186 | ARMV7_PERFCTR_SPEC_PC_WRITE = 0x76, | ||
| 187 | }; | ||
| 188 | |||
| 171 | /* | 189 | /* |
| 172 | * Cortex-A8 HW events mapping | 190 | * Cortex-A8 HW events mapping |
| 173 | * | 191 | * |
| @@ -510,6 +528,126 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | |||
| 510 | }; | 528 | }; |
| 511 | 529 | ||
| 512 | /* | 530 | /* |
| 531 | * Cortex-A15 HW events mapping | ||
| 532 | */ | ||
| 533 | static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = { | ||
| 534 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, | ||
| 535 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, | ||
| 536 | [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, | ||
| 537 | [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, | ||
| 538 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE, | ||
| 539 | [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
| 540 | [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, | ||
| 541 | }; | ||
| 542 | |||
| 543 | static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] | ||
| 544 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
| 545 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
| 546 | [C(L1D)] = { | ||
| 547 | [C(OP_READ)] = { | ||
| 548 | [C(RESULT_ACCESS)] | ||
| 549 | = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS, | ||
| 550 | [C(RESULT_MISS)] | ||
| 551 | = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL, | ||
| 552 | }, | ||
| 553 | [C(OP_WRITE)] = { | ||
| 554 | [C(RESULT_ACCESS)] | ||
| 555 | = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS, | ||
| 556 | [C(RESULT_MISS)] | ||
| 557 | = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL, | ||
| 558 | }, | ||
| 559 | [C(OP_PREFETCH)] = { | ||
| 560 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 561 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
| 562 | }, | ||
| 563 | }, | ||
| 564 | [C(L1I)] = { | ||
| 565 | /* | ||
| 566 | * Not all performance counters differentiate between read | ||
| 567 | * and write accesses/misses so we're not always strictly | ||
| 568 | * correct, but it's the best we can do. Writes and reads get | ||
| 569 | * combined in these cases. | ||
| 570 | */ | ||
| 571 | [C(OP_READ)] = { | ||
| 572 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, | ||
| 573 | [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, | ||
| 574 | }, | ||
| 575 | [C(OP_WRITE)] = { | ||
| 576 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, | ||
| 577 | [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, | ||
| 578 | }, | ||
| 579 | [C(OP_PREFETCH)] = { | ||
| 580 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 581 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
| 582 | }, | ||
| 583 | }, | ||
| 584 | [C(LL)] = { | ||
| 585 | [C(OP_READ)] = { | ||
| 586 | [C(RESULT_ACCESS)] | ||
| 587 | = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS, | ||
| 588 | [C(RESULT_MISS)] | ||
| 589 | = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL, | ||
| 590 | }, | ||
| 591 | [C(OP_WRITE)] = { | ||
| 592 | [C(RESULT_ACCESS)] | ||
| 593 | = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS, | ||
| 594 | [C(RESULT_MISS)] | ||
| 595 | = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL, | ||
| 596 | }, | ||
| 597 | [C(OP_PREFETCH)] = { | ||
| 598 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 599 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
| 600 | }, | ||
| 601 | }, | ||
| 602 | [C(DTLB)] = { | ||
| 603 | [C(OP_READ)] = { | ||
| 604 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 605 | [C(RESULT_MISS)] | ||
| 606 | = ARMV7_PERFCTR_L1_DTLB_READ_REFILL, | ||
| 607 | }, | ||
| 608 | [C(OP_WRITE)] = { | ||
| 609 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 610 | [C(RESULT_MISS)] | ||
| 611 | = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL, | ||
| 612 | }, | ||
| 613 | [C(OP_PREFETCH)] = { | ||
| 614 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 615 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
| 616 | }, | ||
| 617 | }, | ||
| 618 | [C(ITLB)] = { | ||
| 619 | [C(OP_READ)] = { | ||
| 620 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 621 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
| 622 | }, | ||
| 623 | [C(OP_WRITE)] = { | ||
| 624 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 625 | [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, | ||
| 626 | }, | ||
| 627 | [C(OP_PREFETCH)] = { | ||
| 628 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 629 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
| 630 | }, | ||
| 631 | }, | ||
| 632 | [C(BPU)] = { | ||
| 633 | [C(OP_READ)] = { | ||
| 634 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, | ||
| 635 | [C(RESULT_MISS)] | ||
| 636 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
| 637 | }, | ||
| 638 | [C(OP_WRITE)] = { | ||
| 639 | [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, | ||
| 640 | [C(RESULT_MISS)] | ||
| 641 | = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, | ||
| 642 | }, | ||
| 643 | [C(OP_PREFETCH)] = { | ||
| 644 | [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, | ||
| 645 | [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, | ||
| 646 | }, | ||
| 647 | }, | ||
| 648 | }; | ||
| 649 | |||
| 650 | /* | ||
| 513 | * Perf Events counters | 651 | * Perf Events counters |
| 514 | */ | 652 | */ |
| 515 | enum armv7_counters { | 653 | enum armv7_counters { |
| @@ -1051,6 +1189,16 @@ static const struct arm_pmu *__init armv7_a5_pmu_init(void) | |||
| 1051 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | 1189 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
| 1052 | return &armv7pmu; | 1190 | return &armv7pmu; |
| 1053 | } | 1191 | } |
| 1192 | |||
| 1193 | static const struct arm_pmu *__init armv7_a15_pmu_init(void) | ||
| 1194 | { | ||
| 1195 | armv7pmu.id = ARM_PERF_PMU_ID_CA15; | ||
| 1196 | armv7pmu.name = "ARMv7 Cortex-A15"; | ||
| 1197 | armv7pmu.cache_map = &armv7_a15_perf_cache_map; | ||
| 1198 | armv7pmu.event_map = &armv7_a15_perf_map; | ||
| 1199 | armv7pmu.num_events = armv7_read_num_pmnc_events(); | ||
| 1200 | return &armv7pmu; | ||
| 1201 | } | ||
| 1054 | #else | 1202 | #else |
| 1055 | static const struct arm_pmu *__init armv7_a8_pmu_init(void) | 1203 | static const struct arm_pmu *__init armv7_a8_pmu_init(void) |
| 1056 | { | 1204 | { |
| @@ -1066,4 +1214,9 @@ static const struct arm_pmu *__init armv7_a5_pmu_init(void) | |||
| 1066 | { | 1214 | { |
| 1067 | return NULL; | 1215 | return NULL; |
| 1068 | } | 1216 | } |
| 1217 | |||
| 1218 | static const struct arm_pmu *__init armv7_a15_pmu_init(void) | ||
| 1219 | { | ||
| 1220 | return NULL; | ||
| 1221 | } | ||
| 1069 | #endif /* CONFIG_CPU_V7 */ | 1222 | #endif /* CONFIG_CPU_V7 */ |
