commit 6d1faa5bd1c0564b24cf030f118cd9782e1b4e0c Author: Stephane Eranian Date: Thu May 22 18:44:47 2014 +0200 Add missing arm_cortex_a57.h header dependency Was missing. We compile A57 for 32-bit arm as well. Signed-off-by: Stephane Eranian diff --git a/lib/Makefile b/lib/Makefile index 6ca3287..585cc3e 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -281,7 +281,8 @@ INC_ARM=events/arm_cortex_a8_events.h \ INC_ARM=pfmlib_arm_priv.h \ events/arm_cortex_a8_events.h \ events/arm_cortex_a9_events.h \ - events/arm_cortex_a15_events.h + events/arm_cortex_a15_events.h \ + events/arm_cortex_a57_events.h INC_ARM64=events/arm_cortex_a57_events.h commit 6af79d5186b7593c4f7e41024b78453debceb45f Author: Stephane Eranian Date: Thu May 22 19:14:52 2014 +0200 Add ARM Cortex A53 support This patch adds support for the ARM Cortex A53 core PMU as documented in r0p2 version f the Cortex-A53 MPCore processor technical reference manual Table 12.28. Support is provided for both 32 and 64-bit modes. Includes man page, and validation tests. Signed-off-by: Stephane Eranian diff --git a/README b/README index 334c78a..e74238f 100644 --- a/README +++ b/README @@ -57,6 +57,7 @@ The library supports many PMUs. The current version can handle: ARMV7 Cortex A8 ARMV7 Cortex A9 ARMV7 Cortex A15 + ARMV8 Cortex A57, A53 Qualcomm Krait - For SPARC diff --git a/docs/Makefile b/docs/Makefile index 9b79ec7..c7d797e 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -76,11 +76,17 @@ endif endif ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y) -ARCH_MAN += libpfm_arm_ac57.3 libpfm_arm_ac15.3 libpfm_arm_ac8.3 libpfm_arm_ac9.3 libpfm_arm_qcom_krait.3 +ARCH_MAN += libpfm_arm_ac57.3 \ + libpfm_arm_ac53.3 \ + libpfm_arm_ac15.3 \ + libpfm_arm_ac8.3 \ + libpfm_arm_ac9.3 \ + libpfm_arm_qcom_krait.3 endif ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y) -ARCH_MAN += libpfm_arm_ac57.3 +ARCH_MAN += libpfm_arm_ac57.3 \ + libpfm_arm_ac53.3 endif ifeq ($(CONFIG_PFMLIB_ARCH_MIPS),y) diff --git a/docs/man3/libpfm_arm_ac53.3 b/docs/man3/libpfm_arm_ac53.3 new file mode 100644 index 0000000..319accc --- /dev/null +++ b/docs/man3/libpfm_arm_ac53.3 @@ -0,0 +1,36 @@ +.TH LIBPFM 4 "May, 2014" "" "Linux Programmer's Manual" +.SH NAME +libpfm_arm_ac53 - support for ARM Cortex A53 PMU +.SH SYNOPSIS +.nf +.B #include +.sp +.B PMU name: arm_ac53 +.B PMU desc: ARM Cortex A53 +.sp +.SH DESCRIPTION +The library supports the ARM Cortex A53 core PMU. + +This PMU supports 6 counters and privilege levels filtering. +It can operate in both 32 and 64 bit modes. + +.SH MODIFIERS +The following modifiers are supported on ARM Cortex A53: +.TP +.B u +Measure at the user level. This corresponds to \fBPFM_PLM3\fR. +This is a boolean modifier. +.TP +.B k +Measure at the kernel level. This corresponds to \fBPFM_PLM0\fR. +This is a boolean modifier. +.TP +.B hv +Measure at the hypervisor level. This corresponds to \fBPFM_PLMH\fR. +This is a boolean modifier. + +.SH AUTHORS +.nf +Stephane Eranian +.if +.PP diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h index b08df66..a7ec026 100644 --- a/include/perfmon/pfmlib.h +++ b/include/perfmon/pfmlib.h @@ -238,6 +238,7 @@ typedef enum { PFM_PMU_S390X_CPUM_SF, /* s390x: CPU-M sampling facility */ PFM_PMU_ARM_CORTEX_A57, /* ARM Cortex A57 (ARMv8) */ + PFM_PMU_ARM_CORTEX_A53, /* ARM Cortex A53 (ARMv8) */ /* MUST ADD NEW PMU MODELS HERE */ diff --git a/lib/Makefile b/lib/Makefile index 585cc3e..5aaf4b3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -282,9 +282,11 @@ INC_ARM=pfmlib_arm_priv.h \ events/arm_cortex_a8_events.h \ events/arm_cortex_a9_events.h \ events/arm_cortex_a15_events.h \ - events/arm_cortex_a57_events.h + events/arm_cortex_a57_events.h \ + events/arm_cortex_a53_events.h -INC_ARM64=events/arm_cortex_a57_events.h +INC_ARM64=events/arm_cortex_a57_events.h \ + events/arm_cortex_a53_events.h INCDEP=$(INC_COMMON) $(INCARCH) diff --git a/lib/events/arm_cortex_a53_events.h b/lib/events/arm_cortex_a53_events.h new file mode 100644 index 0000000..c0d2bb6 --- /dev/null +++ b/lib/events/arm_cortex_a53_events.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2014 Google Inc. All rights reserved + * Contributed by Stephane Eranian + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Cortex A53 r0p2 + * based on Table 12.9 from the "Cortex A53 Technical Reference Manual" + */ + +static const arm_entry_t arm_cortex_a53_pe[]={ + {.name = "SW_INCR", + .modmsk = ARMV8_ATTRS, + .code = 0x00, + .desc = "Instruction architecturally executed (condition check pass) Software increment" + }, + {.name = "L1I_CACHE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x01, + .desc = "Level 1 instruction cache refill" + }, + {.name = "L1I_TLB_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x02, + .desc = "Level 1 instruction TLB refill" + }, + {.name = "L1D_CACHE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x03, + .desc = "Level 1 data cache refill" + }, + {.name = "L1D_CACHE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x04, + .desc = "Level 1 data cache access" + }, + {.name = "L1D_TLB_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x05, + .desc = "Level 1 data TLB refill" + }, + {.name = "LD_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x06, + .desc = "Load Instruction architecturally executed, condition check", + }, + {.name = "ST_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x07, + .desc = "Store Instruction architecturally executed, condition check", + }, + {.name = "INST_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x08, + .desc = "Instruction architecturally executed" + }, + {.name = "EXCEPTION_TAKEN", + .modmsk = ARMV8_ATTRS, + .code = 0x09, + .desc = "Exception taken" + }, + {.name = "EXCEPTION_RETURN", + .modmsk = ARMV8_ATTRS, + .code = 0x0a, + .desc = "Instruction architecturally executed (condition check pass) Exception return" + }, + {.name = "CID_WRITE_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x0b, + .desc = "Change to Context ID retired", + }, + {.name = "PC_WRITE_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x0c, + .desc = "Write to CONTEXTIDR, instruction architecturally executed, condition check pass" + }, + {.name = "BR_IMMED_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x0d, + .desc = "Software chnage of the PC, instruction architecturally executed, condition check pass" + }, + {.name = "UNALIGNED_LDST_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x0f, + .desc = "Procedure return, instruction architecturally executed, condition check pass" + }, + {.name = "BRANCH_MISPRED", + .modmsk = ARMV8_ATTRS, + .code = 0x10, + .desc = "Mispredicted or not predicted branch speculatively executed" + }, + {.name = "CPU_CYCLES", + .modmsk = ARMV8_ATTRS, + .code = 0x11, + .desc = "Cycles" + }, + {.name = "BRANCH_PRED", + .modmsk = ARMV8_ATTRS, + .code = 0x12, + .desc = "Predictable branch speculatively executed" + }, + {.name = "DATA_MEM_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x13, + .desc = "Data memory access" + }, + {.name = "L1I_CACHE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x14, + .desc = "Level 1 instruction cache access" + }, + {.name = "L1D_CACHE_WB", + .modmsk = ARMV8_ATTRS, + .code = 0x15, + .desc = "Level 1 data cache WriteBack" + }, + {.name = "L2D_CACHE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x16, + .desc = "Level 2 data cache access" + }, + {.name = "L2D_CACHE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x17, + .desc = "Level 2 data cache refill" + }, + {.name = "L2D_CACHE_WB", + .modmsk = ARMV8_ATTRS, + .code = 0x18, + .desc = "Level 2 data cache WriteBack" + }, + {.name = "BUS_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x19, + .desc = "Bus access" + }, + {.name = "LOCAL_MEMORY_ERROR", + .modmsk = ARMV8_ATTRS, + .code = 0x1a, + .desc = "Local memory error" + }, + {.name = "BUS_CYCLES", + .modmsk = ARMV8_ATTRS, + .code = 0x1d, + .desc = "Bus cycle" + }, + + {.name = "BUS_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x60, + .desc = "Bus read access" + }, + {.name = "BUS_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x61, + .desc = "Bus write access" + }, + + {.name = "BRANCH_SPEC_EXEC_IND", + .modmsk = ARMV8_ATTRS, + .code = 0x7a, + .desc = "Indirect branch speculatively executed" + }, + + {.name = "EXCEPTION_IRQ", + .modmsk = ARMV8_ATTRS, + .code = 0x86, + .desc = "Exception taken, irq" + }, + {.name = "EXCEPTION_FIQ", + .modmsk = ARMV8_ATTRS, + .code = 0x87, + .desc = "Exception taken, irq" + }, +}; diff --git a/lib/pfmlib_arm_armv8.c b/lib/pfmlib_arm_armv8.c index 4bc863b..c38bd9b 100644 --- a/lib/pfmlib_arm_armv8.c +++ b/lib/pfmlib_arm_armv8.c @@ -30,7 +30,8 @@ #include "pfmlib_priv.h" /* library private */ #include "pfmlib_arm_priv.h" -#include "events/arm_cortex_a57_events.h" /* event tables */ +#include "events/arm_cortex_a57_events.h" /* A57 event tables */ +#include "events/arm_cortex_a53_events.h" /* A53 event tables */ static int pfm_arm_detect_cortex_a57(void *this) @@ -48,6 +49,22 @@ pfm_arm_detect_cortex_a57(void *this) return PFM_ERR_NOTSUPP; } +static int +pfm_arm_detect_cortex_a53(void *this) +{ + int ret; + + ret = pfm_arm_detect(this); + if (ret != PFM_SUCCESS) + return PFM_ERR_NOTSUPP; + + if ((pfm_arm_cfg.implementer == 0x41) && /* ARM */ + (pfm_arm_cfg.part == 0xd03)) { /* Cortex A53 */ + return PFM_SUCCESS; + } + return PFM_ERR_NOTSUPP; +} + /* ARM Cortex A57 support */ pfmlib_pmu_t arm_cortex_a57_support={ .desc = "ARM Cortex A57", @@ -72,3 +89,28 @@ pfmlib_pmu_t arm_cortex_a57_support={ PFMLIB_VALID_PERF_PATTRS(pfm_arm_perf_validate_pattrs), .get_event_nattrs = pfm_arm_get_event_nattrs, }; + +/* ARM Cortex A53 support */ +pfmlib_pmu_t arm_cortex_a53_support={ + .desc = "ARM Cortex A53", + .name = "arm_ac53", + .pmu = PFM_PMU_ARM_CORTEX_A53, + .pme_count = LIBPFM_ARRAY_SIZE(arm_cortex_a53_pe), + .type = PFM_PMU_TYPE_CORE, + .pe = arm_cortex_a53_pe, + + .pmu_detect = pfm_arm_detect_cortex_a53, + .max_encoding = 1, + .num_cntrs = 6, + + .get_event_encoding[PFM_OS_NONE] = pfm_arm_get_encoding, + PFMLIB_ENCODE_PERF(pfm_arm_get_perf_encoding), + .get_event_first = pfm_arm_get_event_first, + .get_event_next = pfm_arm_get_event_next, + .event_is_valid = pfm_arm_event_is_valid, + .validate_table = pfm_arm_validate_table, + .get_event_info = pfm_arm_get_event_info, + .get_event_attr_info = pfm_arm_get_event_attr_info, + PFMLIB_VALID_PERF_PATTRS(pfm_arm_perf_validate_pattrs), + .get_event_nattrs = pfm_arm_get_event_nattrs, +}; diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c index 900d7de..ebe20da 100644 --- a/lib/pfmlib_common.c +++ b/lib/pfmlib_common.c @@ -200,9 +200,11 @@ static pfmlib_pmu_t *pfmlib_pmus[]= &arm_1176_support, &arm_qcom_krait_support, &arm_cortex_a57_support, + &arm_cortex_a53_support, #endif #ifdef CONFIG_PFMLIB_ARCH_ARM64 &arm_cortex_a57_support, + &arm_cortex_a53_support, #endif #ifdef CONFIG_PFMLIB_ARCH_S390X diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h index 3031d3b..5678cc0 100644 --- a/lib/pfmlib_priv.h +++ b/lib/pfmlib_priv.h @@ -333,6 +333,7 @@ extern pfmlib_pmu_t arm_cortex_a15_support; extern pfmlib_pmu_t arm_1176_support; extern pfmlib_pmu_t arm_qcom_krait_support; extern pfmlib_pmu_t arm_cortex_a57_support; +extern pfmlib_pmu_t arm_cortex_a53_support; extern pfmlib_pmu_t mips_74k_support; extern pfmlib_pmu_t s390x_cpum_cf_support; extern pfmlib_pmu_t s390x_cpum_sf_support; diff --git a/tests/validate_arm.c b/tests/validate_arm.c index d6c0168..44eefd4 100644 --- a/tests/validate_arm.c +++ b/tests/validate_arm.c @@ -187,6 +187,48 @@ static const test_event_t arm_test_events[]={ .codes[0] = 0x8000008, .fstr = "arm_ac57::INST_RETIRED:k=1:u=1:hv=0", }, + { SRC_LINE, + .name = "arm_ac53::CPU_CYCLES", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::CPU_CYCLES:k", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x88000011, + .fstr = "arm_ac53::CPU_CYCLES:k=1:u=0:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::CPU_CYCLES:k:u", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::INST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000008, + .fstr = "arm_ac53::INST_RETIRED:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::LD_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000006, + .fstr = "arm_ac53::LD_RETIRED:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::ST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000007, + .fstr = "arm_ac53::ST_RETIRED:k=1:u=1:hv=0", + }, }; #define NUM_TEST_EVENTS (int)(sizeof(arm_test_events)/sizeof(test_event_t)) diff --git a/tests/validate_arm64.c b/tests/validate_arm64.c index 0f0174c..61400ac 100644 --- a/tests/validate_arm64.c +++ b/tests/validate_arm64.c @@ -72,6 +72,48 @@ static const test_event_t arm64_test_events[]={ .codes[0] = 0x8000008, .fstr = "arm_ac57::INST_RETIRED:k=1:u=1:hv=0", }, + { SRC_LINE, + .name = "arm_ac53::CPU_CYCLES", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::CPU_CYCLES:k", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x88000011, + .fstr = "arm_ac53::CPU_CYCLES:k=1:u=0:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::CPU_CYCLES:k:u", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac53::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::INST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000008, + .fstr = "arm_ac53::INST_RETIRED:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::LD_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000006, + .fstr = "arm_ac53::LD_RETIRED:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac53::ST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000007, + .fstr = "arm_ac53::ST_RETIRED:k=1:u=1:hv=0", + }, }; #define NUM_TEST_EVENTS (int)(sizeof(arm64_test_events)/sizeof(test_event_t))