commit b1a3bf942376a3eaddc6f089c74bf5e322295822 Author: Stephane Eranian Date: Tue May 6 14:42:23 2014 +0200 Add ARM Cortex A57 support This patch adds support for ARM Cortex A57 processor for both 64 and 32 bit modes (armv8). Based on Table 11-24 from the "Cortex A57 Technical Reference Manual" The validation tests for A57 in 64-bit mode is also added. Signed-off-by: Stephane Eranian diff --git a/config.mk b/config.mk index 457d943..9553cbe 100644 --- a/config.mk +++ b/config.mk @@ -66,6 +66,15 @@ endif ifeq (armv7,$(findstring armv7,$(ARCH))) override ARCH=arm endif +ifeq (armv7,$(findstring armv7,$(ARCH))) +override ARCH=arm +endif +ifeq (aarch32,$(findstring aarch32,$(ARCH))) +override ARCH=arm +endif +ifeq (armv8l,$(findstring armv8l,$(ARCH))) +override ARCH=arm +endif ifeq (mips64,$(findstring mips64,$(ARCH))) override ARCH=mips endif @@ -152,6 +161,14 @@ ifeq ($(ARCH),arm) CONFIG_PFMLIB_ARCH_ARM=y endif +ifeq ($(ARCH),aarch64) +CONFIG_PFMLIB_ARCH_ARM64=y +endif + +ifeq ($(ARCH),arm64) +CONFIG_PFMLIB_ARCH_ARM64=y +endif + ifeq ($(ARCH),s390x) CONFIG_PFMLIB_ARCH_S390X=y endif diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h index dfdd471..b08df66 100644 --- a/include/perfmon/pfmlib.h +++ b/include/perfmon/pfmlib.h @@ -237,6 +237,8 @@ typedef enum { PFM_PMU_INTEL_HSW_EP, /* Intel Haswell EP */ + PFM_PMU_ARM_CORTEX_A57, /* ARM Cortex A57 (ARMv8) */ + /* MUST ADD NEW PMU MODELS HERE */ PFM_PMU_MAX /* end marker */ diff --git a/lib/Makefile b/lib/Makefile index 531167e..6ca3287 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -139,10 +139,21 @@ SRCS += pfmlib_arm_perf_event.c endif INCARCH = $(INC_ARM) -SRCS += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c pfmlib_arm_armv6.c +SRCS += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c pfmlib_arm_armv6.c pfmlib_arm_armv8.c CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM endif +ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y) + +ifeq ($(SYS),Linux) +SRCS += pfmlib_arm_perf_event.c +endif + +INCARCH = $(INC_ARM64) +SRCS += pfmlib_arm.c pfmlib_arm_armv8.c +CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM64 +endif + ifeq ($(CONFIG_PFMLIB_ARCH_MIPS),y) ifeq ($(SYS),Linux) @@ -272,6 +283,8 @@ INC_ARM=pfmlib_arm_priv.h \ events/arm_cortex_a9_events.h \ events/arm_cortex_a15_events.h +INC_ARM64=events/arm_cortex_a57_events.h + INCDEP=$(INC_COMMON) $(INCARCH) all: $(TARGETS) diff --git a/lib/events/arm_cortex_a57_events.h b/lib/events/arm_cortex_a57_events.h new file mode 100644 index 0000000..9d1d407 --- /dev/null +++ b/lib/events/arm_cortex_a57_events.h @@ -0,0 +1,440 @@ +/* + * 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 A57 r1p1 + * based on Table 11-24 from the "Cortex A57 Technical Reference Manual" + */ + +static const arm_entry_t arm_cortex_a57_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 = "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 = "Instruction architecturally executed (condition check pass) Write to CONTEXTIDR" + }, + + {.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 = "INST_SPEC_EXEC", + .modmsk = ARMV8_ATTRS, + .code = 0x1b, + .desc = "Instruction speculatively executed" + }, + {.name = "TTBR_WRITE_RETIRED", + .modmsk = ARMV8_ATTRS, + .code = 0x1c, + .desc = "Instruction architecturally executed (condition check pass) Write to translation table base" + }, + {.name = "BUS_CYCLES", + .modmsk = ARMV8_ATTRS, + .code = 0x1d, + .desc = "Bus cycle" + }, + {.name = "L1D_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x40, + .desc = "Level 1 data cache read access" + }, + {.name = "L1D_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x41, + .desc = "Level 1 data cache write access" + }, + {.name = "L1D_READ_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x42, + .desc = "Level 1 data cache read refill" + }, + {.name = "L1D_WRITE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x43, + .desc = "Level 1 data cache write refill" + }, + {.name = "L1D_WB_VICTIM", + .modmsk = ARMV8_ATTRS, + .code = 0x46, + .desc = "Level 1 data cache writeback victim" + }, + {.name = "L1D_WB_CLEAN_COHERENCY", + .modmsk = ARMV8_ATTRS, + .code = 0x47, + .desc = "Level 1 data cache writeback cleaning and coherency" + }, + {.name = "L1D_INVALIDATE", + .modmsk = ARMV8_ATTRS, + .code = 0x48, + .desc = "Level 1 data cache invalidate" + }, + {.name = "L1D_TLB_READ_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x4c, + .desc = "Level 1 data TLB read refill" + }, + {.name = "L1D_TLB_WRITE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x4d, + .desc = "Level 1 data TLB write refill" + }, + {.name = "L2D_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x50, + .desc = "Level 2 data cache read access" + }, + {.name = "L2D_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x51, + .desc = "Level 2 data cache write access" + }, + {.name = "L2D_READ_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x52, + .desc = "Level 2 data cache read refill" + }, + {.name = "L2D_WRITE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x53, + .desc = "Level 2 data cache write refill" + }, + {.name = "L2D_WB_VICTIM", + .modmsk = ARMV8_ATTRS, + .code = 0x56, + .desc = "Level 2 data cache writeback victim" + }, + {.name = "L2D_WB_CLEAN_COHERENCY", + .modmsk = ARMV8_ATTRS, + .code = 0x57, + .desc = "Level 2 data cache writeback cleaning and coherency" + }, + {.name = "L2D_INVALIDATE", + .modmsk = ARMV8_ATTRS, + .code = 0x58, + .desc = "Level 2 data cache invalidate" + }, + {.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 = "BUS_NORMAL_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x62, + .desc = "Bus normal access" + }, + {.name = "BUS_NOT_NORMAL_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x63, + .desc = "Bus not normal access" + }, + {.name = "BUS_NORMAL_ACCESS_2", + .modmsk = ARMV8_ATTRS, + .code = 0x64, + .desc = "Bus normal access" + }, + {.name = "BUS_PERIPH_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x65, + .desc = "Bus peripheral access" + }, + {.name = "DATA_MEM_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x66, + .desc = "Data memory read access" + }, + {.name = "DATA_MEM_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x67, + .desc = "Data memory write access" + }, + {.name = "UNALIGNED_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x68, + .desc = "Unaligned read access" + }, + {.name = "UNALIGNED_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x69, + .desc = "Unaligned read access" + }, + {.name = "UNALIGNED_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x6a, + .desc = "Unaligned access" + }, + {.name = "INST_SPEC_EXEC_LDREX", + .modmsk = ARMV8_ATTRS, + .code = 0x6c, + .desc = "LDREX exclusive instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_STREX_PASS", + .modmsk = ARMV8_ATTRS, + .code = 0x6d, + .desc = "STREX pass exclusive instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_STREX_FAIL", + .modmsk = ARMV8_ATTRS, + .code = 0x6e, + .desc = "STREX fail exclusive instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_LOAD", + .modmsk = ARMV8_ATTRS, + .code = 0x70, + .desc = "Load instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_STORE", + .modmsk = ARMV8_ATTRS, + .code = 0x71, + .desc = "Store instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_LOAD_STORE", + .modmsk = ARMV8_ATTRS, + .code = 0x72, + .desc = "Load or store instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_INTEGER_INST", + .modmsk = ARMV8_ATTRS, + .code = 0x73, + .desc = "Integer data processing instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_SIMD", + .modmsk = ARMV8_ATTRS, + .code = 0x74, + .desc = "Advanced SIMD instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_VFP", + .modmsk = ARMV8_ATTRS, + .code = 0x75, + .desc = "VFP instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_SOFT_PC", + .modmsk = ARMV8_ATTRS, + .code = 0x76, + .desc = "Software of the PC instruction speculatively executed" + }, + {.name = "BRANCH_SPEC_EXEC_IMM_BRANCH", + .modmsk = ARMV8_ATTRS, + .code = 0x78, + .desc = "Immediate branch speculatively executed" + }, + {.name = "BRANCH_SPEC_EXEC_RET", + .modmsk = ARMV8_ATTRS, + .code = 0x79, + .desc = "Return branch speculatively executed" + }, + {.name = "BRANCH_SPEC_EXEC_IND", + .modmsk = ARMV8_ATTRS, + .code = 0x7a, + .desc = "Indirect branch speculatively executed" + }, + {.name = "BARRIER_SPEC_EXEC_ISB", + .modmsk = ARMV8_ATTRS, + .code = 0x7c, + .desc = "ISB barrier speculatively executed" + }, + {.name = "BARRIER_SPEC_EXEC_DSB", + .modmsk = ARMV8_ATTRS, + .code = 0x7d, + .desc = "DSB barrier speculatively executed" + }, + {.name = "BARRIER_SPEC_EXEC_DMB", + .modmsk = ARMV8_ATTRS, + .code = 0x7e, + .desc = "DMB barrier speculatively executed" + }, + {.name = "EXCEPTION_UNDEF", + .modmsk = ARMV8_ATTRS, + .code = 0x81, + .desc = "Exception taken, other synchronous" + }, + {.name = "EXCEPTION_SVC", + .modmsk = ARMV8_ATTRS, + .code = 0x82, + .desc = "Exception taken, supervisor call" + }, + {.name = "EXCEPTION_PABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x83, + .desc = "Exception taken, instruction abort" + }, + {.name = "EXCEPTION_DABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x84, + .desc = "Exception taken, data abort or SError" + }, + {.name = "EXCEPTION_IRQ", + .modmsk = ARMV8_ATTRS, + .code = 0x86, + .desc = "Exception taken, irq" + }, + {.name = "EXCEPTION_FIQ", + .modmsk = ARMV8_ATTRS, + .code = 0x87, + .desc = "Exception taken, irq" + }, + {.name = "EXCEPTION_SMC", + .modmsk = ARMV8_ATTRS, + .code = 0x88, + .desc = "Exception taken, secure monitor call" + }, + {.name = "EXCEPTION_HVC", + .modmsk = ARMV8_ATTRS, + .code = 0x8a, + .desc = "Exception taken, hypervisor call" + }, + {.name = "EXCEPTION_TRAP_PABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x8b, + .desc = "Exception taken, instruction abort not taken locally" + }, + {.name = "EXCEPTION_TRAP_DABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x8c, + .desc = "Exception taken, data abort or SError not taken locally" + }, + {.name = "EXCEPTION_TRAP_OTHER", + .modmsk = ARMV8_ATTRS, + .code = 0x8d, + .desc = "Exception taken, other traps not taken locally" + }, + {.name = "EXCEPTION_TRAP_IRQ", + .modmsk = ARMV8_ATTRS, + .code = 0x8e, + .desc = "Exception taken, irq not taken locally" + }, + {.name = "EXCEPTION_TRAP_FIQ", + .modmsk = ARMV8_ATTRS, + .code = 0x8f, + .desc = "Exception taken, fiq not taken locally" + }, + {.name = "RC_LD_SPEC", + .modmsk = ARMV8_ATTRS, + .code = 0x90, + .desc = "Release consistency instruction speculatively executed (load-acquire)", + }, + {.name = "RC_ST_SPEC", + .modmsk = ARMV8_ATTRS, + .code = 0x91, + .desc = "Release consistency instruction speculatively executed (store-release)", + }, + /* END Cortex A47 specific events */ +}; diff --git a/lib/pfmlib_arm_armv8.c b/lib/pfmlib_arm_armv8.c new file mode 100644 index 0000000..880d566 --- /dev/null +++ b/lib/pfmlib_arm_armv8.c @@ -0,0 +1,74 @@ +/* + * pfmlib_arm_armv8.c : support for ARMv8 processors + * + * 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. + * + */ +#include +#include +#include + +/* private headers */ +#include "pfmlib_priv.h" /* library private */ +#include "pfmlib_arm_priv.h" + +#include "events/arm_cortex_a57_events.h" /* event tables */ + +static int +pfm_arm_detect_cortex_a57(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 == 0xc00)) { /* Cortex A57 */ + return PFM_SUCCESS; + } + return PFM_ERR_NOTSUPP; +} + +/* ARM Cortex A57 support */ +pfmlib_pmu_t arm_cortex_a57_support={ + .desc = "ARM Cortex A57", + .name = "arm_ac57", + .pmu = PFM_PMU_ARM_CORTEX_A57, + .pme_count = LIBPFM_ARRAY_SIZE(arm_cortex_a57_pe), + .type = PFM_PMU_TYPE_CORE, + .pe = arm_cortex_a57_pe, + + .pmu_detect = pfm_arm_detect_cortex_a57, + .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_arm_priv.h b/lib/pfmlib_arm_priv.h index ef367b7..227508b 100644 --- a/lib/pfmlib_arm_priv.h +++ b/lib/pfmlib_arm_priv.h @@ -86,6 +86,9 @@ extern int pfm_arm_get_perf_encoding(void *this, pfmlib_event_desc_t *e); #define ARMV7_A15_ATTRS (_ARM_ATTR_K|_ARM_ATTR_U|_ARM_ATTR_HV) #define ARMV7_A15_PLM (PFM_PLM0|PFM_PLM3|PFM_PLMH) +#define ARMV8_ATTRS (_ARM_ATTR_K|_ARM_ATTR_U|_ARM_ATTR_HV) +#define ARMV8_PLM (PFM_PLM0|PFM_PLM3|PFM_PLMH) + static inline int arm_has_plm(void *this, pfmlib_event_desc_t *e) { diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c index 8e4b1a1..900d7de 100644 --- a/lib/pfmlib_common.c +++ b/lib/pfmlib_common.c @@ -199,7 +199,12 @@ static pfmlib_pmu_t *pfmlib_pmus[]= &arm_cortex_a9_support, &arm_cortex_a15_support, &arm_1176_support, + &arm_cortex_a57_support, #endif +#ifdef CONFIG_PFMLIB_ARCH_ARM64 + &arm_cortex_a57_support, +#endif + #ifdef CONFIG_PFMLIB_ARCH_S390X &s390x_cpum_cf_support, #endif diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h index 715c4b0..3031d3b 100644 --- a/lib/pfmlib_priv.h +++ b/lib/pfmlib_priv.h @@ -332,6 +332,7 @@ extern pfmlib_pmu_t arm_cortex_a9_support; extern pfmlib_pmu_t arm_cortex_a9_support; extern pfmlib_pmu_t arm_cortex_a15_support; extern pfmlib_pmu_t arm_1176_support; +extern pfmlib_pmu_t arm_cortex_a57_support; extern pfmlib_pmu_t mips_74k_support; extern pfmlib_pmu_t s390x_cpum_cf_support; diff --git a/tests/Makefile b/tests/Makefile index 7076fb7..7dd82c3 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -39,6 +39,10 @@ ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y) SRCS += validate_arm.c endif +ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y) +SRCS += validate_arm64.c +endif + ifeq ($(CONFIG_PFMLIB_ARCH_POWERPC),y) SRCS += validate_power.c endif diff --git a/tests/validate_arm.c b/tests/validate_arm.c index fe97aa9..d6c0168 100644 --- a/tests/validate_arm.c +++ b/tests/validate_arm.c @@ -159,6 +159,34 @@ static const test_event_t arm_test_events[]={ .codes[0] = 0x07, .fstr = "arm_1176::INSTR_EXEC", }, + { SRC_LINE, + .name = "arm_ac57::CPU_CYCLES", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac57::CPU_CYCLES:k", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x88000011, + .fstr = "arm_ac57::CPU_CYCLES:k=1:u=0:hv=0", + }, + { SRC_LINE, + .name = "arm_ac57::CPU_CYCLES:k:u", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac57::INST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000008, + .fstr = "arm_ac57::INST_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 new file mode 100644 index 0000000..0f0174c --- /dev/null +++ b/tests/validate_arm64.c @@ -0,0 +1,138 @@ +/* + * validate_arm64.c - validate ARM64 event tables + encodings + * + * Copyright (c) 2014 Google, Inc + * 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_ENCODING 1 +#define SRC_LINE .line = __LINE__ + +typedef struct { + const char *name; + const char *fstr; + uint64_t codes[MAX_ENCODING]; + int ret, count, line; +} test_event_t; + +static const test_event_t arm64_test_events[]={ + { SRC_LINE, + .name = "arm_ac57::CPU_CYCLES", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac57::CPU_CYCLES:k", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x88000011, + .fstr = "arm_ac57::CPU_CYCLES:k=1:u=0:hv=0", + }, + { SRC_LINE, + .name = "arm_ac57::CPU_CYCLES:k:u", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_ac57::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_ac57::INST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000008, + .fstr = "arm_ac57::INST_RETIRED:k=1:u=1:hv=0", + }, +}; +#define NUM_TEST_EVENTS (int)(sizeof(arm64_test_events)/sizeof(test_event_t)) + +static int check_test_events(FILE *fp) +{ + const test_event_t *e; + char *fstr; + uint64_t *codes; + int count, i, j; + int ret, errors = 0; + + for (i = 0, e = arm64_test_events; i < NUM_TEST_EVENTS; i++, e++) { + codes = NULL; + count = 0; + fstr = NULL; + ret = pfm_get_event_encoding(e->name, PFM_PLM0 | PFM_PLM3, &fstr, NULL, &codes, &count); + if (ret != e->ret) { + fprintf(fp,"Line %d, Event%d %s, ret=%s(%d) expected %s(%d)\n", e->line, i, e->name, pfm_strerror(ret), ret, pfm_strerror(e->ret), e->ret); + errors++; + } else { + if (ret != PFM_SUCCESS) { + if (fstr) { + fprintf(fp,"Line %d, Event%d %s, expected fstr NULL but it is not\n", e->line, i, e->name); + errors++; + } + if (count != 0) { + fprintf(fp,"Line %d, Event%d %s, expected count=0 instead of %d\n", e->line, i, e->name, count); + errors++; + } + if (codes) { + fprintf(fp,"Line %d, Event%d %s, expected codes[] NULL but it is not\n", e->line, i, e->name); + errors++; + } + } else { + if (count != e->count) { + fprintf(fp,"Line %d, Event%d %s, count=%d expected %d\n", e->line, i, e->name, count, e->count); + errors++; + } + for (j=0; j < count; j++) { + if (codes[j] != e->codes[j]) { + fprintf(fp,"Line %d, Event%d %s, codes[%d]=%#"PRIx64" expected %#"PRIx64"\n", e->line, i, e->name, j, codes[j], e->codes[j]); + errors++; + } + } + if (e->fstr && strcmp(fstr, e->fstr)) { + fprintf(fp,"Line %d, Event%d %s, fstr=%s expected %s\n", e->line, i, e->name, fstr, e->fstr); + errors++; + } + } + } + if (codes) + free(codes); + if (fstr) + free(fstr); + } + printf("\t %d ARM64 events: %d errors\n", i, errors); + return errors; +} + +int +validate_arch(FILE *fp) +{ + return check_test_events(fp); +} commit b95de18085dd74738752341e0004b3dd11f00a53 Author: Stephane Eranian Date: Mon May 12 14:15:57 2014 +0200 Add ARM Cortex A57 documentation Signed-off-by: Stephane Eranian diff --git a/docs/Makefile b/docs/Makefile index ecf6769..9b79ec7 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -76,7 +76,11 @@ endif endif ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y) -ARCH_MAN += libpfm_arm_ac15.3 libpfm_arm_ac8.3 libpfm_arm_ac9.3 +ARCH_MAN += libpfm_arm_ac57.3 libpfm_arm_ac15.3 libpfm_arm_ac8.3 libpfm_arm_ac9.3 +endif + +ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y) +ARCH_MAN += libpfm_arm_ac57.3 endif diff --git a/docs/man3/libpfm_arm_ac57.3 b/docs/man3/libpfm_arm_ac57.3 new file mode 100644 index 0000000..c471ff1 --- /dev/null +++ b/docs/man3/libpfm_arm_ac57.3 @@ -0,0 +1,36 @@ +.TH LIBPFM 4 "May, 2014" "" "Linux Programmer's Manual" +.SH NAME +libpfm_arm_ac57 - support for Arm Cortex A57 PMU +.SH SYNOPSIS +.nf +.B #include +.sp +.B PMU name: arm_ac57 +.B PMU desc: ARM Cortex A57 +.sp +.SH DESCRIPTION +The library supports the ARM Cortex A57 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 A57: +.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 commit 399aa947ca6f4c58acac8c6be52d2ad4e5268210 Author: Stephane Eranian Date: Fri May 16 15:42:40 2014 +0200 fix the ARM Cortex A57 detection This patch fixes the detection of ARM Cortex A57. Was using the wrong part number. Correct number is 0xD07. Signed-off-by: Stephane Eranian diff --git a/lib/pfmlib_arm_armv8.c b/lib/pfmlib_arm_armv8.c index 880d566..4bc863b 100644 --- a/lib/pfmlib_arm_armv8.c +++ b/lib/pfmlib_arm_armv8.c @@ -42,7 +42,7 @@ pfm_arm_detect_cortex_a57(void *this) return PFM_ERR_NOTSUPP; if ((pfm_arm_cfg.implementer == 0x41) && /* ARM */ - (pfm_arm_cfg.part == 0xc00)) { /* Cortex A57 */ + (pfm_arm_cfg.part == 0xd07)) { /* Cortex A57 */ return PFM_SUCCESS; } return PFM_ERR_NOTSUPP; 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 - For SPARC Ultra I, II diff --git a/docs/Makefile b/docs/Makefile index 9b79ec7..c7d797e 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -76,11 +76,16 @@ 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 +ARCH_MAN += libpfm_arm_ac57.3 \ + libpfm_arm_ac53.3 \ + libpfm_arm_ac15.3 \ + libpfm_arm_ac8.3 \ + libpfm_arm_ac9.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 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_INTEL_HSW_EP, /* Intel Haswell EP */ 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_cortex_a15_support, &arm_1176_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_cortex_a15_support; extern pfmlib_pmu_t arm_1176_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; 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)) Return-Path: wcohen@redhat.com Received: from zmta06.collab.prod.int.phx2.redhat.com (LHLO zmta06.collab.prod.int.phx2.redhat.com) (10.5.81.13) by zmail12.collab.prod.int.phx2.redhat.com with LMTP; Wed, 4 Jun 2014 10:54:07 -0400 (EDT) Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by zmta06.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 1EC57167B59 for ; Wed, 4 Jun 2014 10:54:07 -0400 (EDT) Received: from santana.rdu.redhat.com (dhcp129-21.rdu.redhat.com [10.13.129.21]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s54Es62r009804; Wed, 4 Jun 2014 10:54:06 -0400 From: William Cohen To: perfmon2-devel@lists.sourceforge.net Cc: William Cohen Subject: [PATCH] Add support for Applied Micro X-Gene processor Date: Wed, 4 Jun 2014 10:54:04 -0400 Message-Id: <1401893644-22326-1-git-send-email-wcohen@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 --- README | 1 + docs/Makefile | 6 +- docs/man3/libpfm_arm_xgene.3 | 39 ++++ include/perfmon/pfmlib.h | 1 + lib/events/arm_xgene_events.h | 515 ++++++++++++++++++++++++++++++++++++++++++ lib/pfmlib_arm_armv8.c | 42 ++++ lib/pfmlib_common.c | 2 + lib/pfmlib_priv.h | 1 + tests/validate_arm64.c | 28 +++ 9 files changed, 633 insertions(+), 2 deletions(-) create mode 100644 docs/man3/libpfm_arm_xgene.3 create mode 100644 lib/events/arm_xgene_events.h diff --git a/README b/README index e74238f..f6f45c9 100644 --- a/README +++ b/README @@ -58,6 +58,7 @@ The library supports many PMUs. The current version can handle: ARMV7 Cortex A9 ARMV7 Cortex A15 ARMV8 Cortex A57, A53 + Applied Micro X-Gene - For SPARC Ultra I, II diff --git a/docs/Makefile b/docs/Makefile index c7d797e..4ae4bae 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -76,7 +76,8 @@ endif endif ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y) -ARCH_MAN += libpfm_arm_ac57.3 \ +ARCH_MAN += libpfm_arm_xgene.3 \ + libpfm_arm_ac57.3 \ libpfm_arm_ac53.3 \ libpfm_arm_ac15.3 \ libpfm_arm_ac8.3 \ @@ -85,7 +86,8 @@ ARCH_MAN += libpfm_arm_ac57.3 \ endif ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y) -ARCH_MAN += libpfm_arm_ac57.3 \ +ARCH_MAN += libpfm_arm_xgene.3 \ + libpfm_arm_ac57.3 \ libpfm_arm_ac53.3 endif diff --git a/docs/man3/libpfm_arm_xgene.3 b/docs/man3/libpfm_arm_xgene.3 new file mode 100644 index 0000000..a0a84bc --- /dev/null +++ b/docs/man3/libpfm_arm_xgene.3 @@ -0,0 +1,39 @@ +.TH LIBPFM 4 "May, 2014" "" "Linux Programmer's Manual" +.SH NAME +libpfm_arm_ac57 - support for Applied Micro X-Gene PMU +.SH SYNOPSIS +.nf +.B #include +.sp +.B PMU name: arm_xgene +.B PMU desc: Applied Micro X-Gene +.sp +.SH DESCRIPTION +The library supports the Applied Micro X-Gene 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 Applied Micro X-Gene: +.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 +.nf +William Cohen +.if +.PP diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h index a7ec026..b7b312e 100644 --- a/include/perfmon/pfmlib.h +++ b/include/perfmon/pfmlib.h @@ -239,6 +239,7 @@ typedef enum { PFM_PMU_ARM_CORTEX_A57, /* ARM Cortex A57 (ARMv8) */ PFM_PMU_ARM_CORTEX_A53, /* ARM Cortex A53 (ARMv8) */ + PFM_PMU_ARM_XGENE, /* Applied Micro X-Gene (ARMv8) */ /* MUST ADD NEW PMU MODELS HERE */ diff --git a/lib/events/arm_xgene_events.h b/lib/events/arm_xgene_events.h new file mode 100644 index 0000000..856dac1 --- /dev/null +++ b/lib/events/arm_xgene_events.h @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2014 Google Inc. All rights reserved + * Copyright (c) 2014 Red Hat Inc. All rights reserved + * Contributed by William Cohen + * + * 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. + * + * Applied Micro X-Gene + * based on Mustang (X-Gene) Software User Guide 15.1.2 CPU PMU Event list + */ + +static const arm_entry_t arm_xgene_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 = "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 = "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 = "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 = "L1D_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x40, + .desc = "Level 1 data cache read access" + }, + {.name = "L1D_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x41, + .desc = "Level 1 data cache write access" + }, + {.name = "L1D_READ_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x42, + .desc = "Level 1 data cache read refill" + }, + {.name = "L1D_INVALIDATE", + .modmsk = ARMV8_ATTRS, + .code = 0x48, + .desc = "Level 1 data cache invalidate" + }, + {.name = "L1D_TLB_READ_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x4c, + .desc = "Level 1 data TLB read refill" + }, + {.name = "L1D_TLB_WRITE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x4d, + .desc = "Level 1 data TLB write refill" + }, + {.name = "L2D_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x50, + .desc = "Level 2 data cache read access" + }, + {.name = "L2D_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x51, + .desc = "Level 2 data cache write access" + }, + {.name = "L2D_READ_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x52, + .desc = "Level 2 data cache read refill" + }, + {.name = "L2D_WRITE_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x53, + .desc = "Level 2 data cache write refill" + }, + {.name = "L2D_WB_VICTIM", + .modmsk = ARMV8_ATTRS, + .code = 0x56, + .desc = "Level 2 data cache writeback victim" + }, + {.name = "L2D_WB_CLEAN_COHERENCY", + .modmsk = ARMV8_ATTRS, + .code = 0x57, + .desc = "Level 2 data cache writeback cleaning and coherency" + }, + {.name = "L2D_INVALIDATE", + .modmsk = ARMV8_ATTRS, + .code = 0x58, + .desc = "Level 2 data cache invalidate" + }, + {.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 = "BUS_NORMAL_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x62, + .desc = "Bus normal access" + }, + {.name = "BUS_NOT_NORMAL_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x63, + .desc = "Bus not normal access" + }, + {.name = "BUS_NORMAL_ACCESS_2", + .modmsk = ARMV8_ATTRS, + .code = 0x64, + .desc = "Bus normal access" + }, + {.name = "BUS_PERIPH_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x65, + .desc = "Bus peripheral access" + }, + {.name = "DATA_MEM_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x66, + .desc = "Data memory read access" + }, + {.name = "DATA_MEM_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x67, + .desc = "Data memory write access" + }, + {.name = "UNALIGNED_READ_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x68, + .desc = "Unaligned read access" + }, + {.name = "UNALIGNED_WRITE_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x69, + .desc = "Unaligned read access" + }, + {.name = "UNALIGNED_ACCESS", + .modmsk = ARMV8_ATTRS, + .code = 0x6a, + .desc = "Unaligned access" + }, + {.name = "INST_SPEC_EXEC_LDREX", + .modmsk = ARMV8_ATTRS, + .code = 0x6c, + .desc = "LDREX exclusive instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_STREX_PASS", + .modmsk = ARMV8_ATTRS, + .code = 0x6d, + .desc = "STREX pass exclusive instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_STREX_FAIL", + .modmsk = ARMV8_ATTRS, + .code = 0x6e, + .desc = "STREX fail exclusive instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_LOAD", + .modmsk = ARMV8_ATTRS, + .code = 0x70, + .desc = "Load instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_STORE", + .modmsk = ARMV8_ATTRS, + .code = 0x71, + .desc = "Store instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_LOAD_STORE", + .modmsk = ARMV8_ATTRS, + .code = 0x72, + .desc = "Load or store instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_INTEGER_INST", + .modmsk = ARMV8_ATTRS, + .code = 0x73, + .desc = "Integer data processing instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_SIMD", + .modmsk = ARMV8_ATTRS, + .code = 0x74, + .desc = "Advanced SIMD instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_VFP", + .modmsk = ARMV8_ATTRS, + .code = 0x75, + .desc = "VFP instruction speculatively executed" + }, + {.name = "INST_SPEC_EXEC_SOFT_PC", + .modmsk = ARMV8_ATTRS, + .code = 0x76, + .desc = "Software of the PC instruction speculatively executed" + }, + {.name = "BRANCH_SPEC_EXEC_IMM_BRANCH", + .modmsk = ARMV8_ATTRS, + .code = 0x78, + .desc = "Immediate branch speculatively executed" + }, + {.name = "BRANCH_SPEC_EXEC_RET", + .modmsk = ARMV8_ATTRS, + .code = 0x79, + .desc = "Return branch speculatively executed" + }, + {.name = "BRANCH_SPEC_EXEC_IND", + .modmsk = ARMV8_ATTRS, + .code = 0x7a, + .desc = "Indirect branch speculatively executed" + }, + {.name = "BARRIER_SPEC_EXEC_ISB", + .modmsk = ARMV8_ATTRS, + .code = 0x7c, + .desc = "ISB barrier speculatively executed" + }, + {.name = "BARRIER_SPEC_EXEC_DSB", + .modmsk = ARMV8_ATTRS, + .code = 0x7d, + .desc = "DSB barrier speculatively executed" + }, + {.name = "BARRIER_SPEC_EXEC_DMB", + .modmsk = ARMV8_ATTRS, + .code = 0x7e, + .desc = "DMB barrier speculatively executed" + }, + {.name = "EXCEPTION_UNDEF", + .modmsk = ARMV8_ATTRS, + .code = 0x81, + .desc = "Exception taken, other synchronous" + }, + {.name = "EXCEPTION_SVC", + .modmsk = ARMV8_ATTRS, + .code = 0x82, + .desc = "Exception taken, supervisor call" + }, + {.name = "EXCEPTION_PABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x83, + .desc = "Exception taken, instruction abort" + }, + {.name = "EXCEPTION_DABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x84, + .desc = "Exception taken, data abort or SError" + }, + {.name = "EXCEPTION_IRQ", + .modmsk = ARMV8_ATTRS, + .code = 0x86, + .desc = "Exception taken, irq" + }, + {.name = "EXCEPTION_FIQ", + .modmsk = ARMV8_ATTRS, + .code = 0x87, + .desc = "Exception taken, irq" + }, + {.name = "EXCEPTION_HVC", + .modmsk = ARMV8_ATTRS, + .code = 0x8a, + .desc = "Exception taken, hypervisor call" + }, + {.name = "EXCEPTION_TRAP_PABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x8b, + .desc = "Exception taken, instruction abort not taken locally" + }, + {.name = "EXCEPTION_TRAP_DABORT", + .modmsk = ARMV8_ATTRS, + .code = 0x8c, + .desc = "Exception taken, data abort or SError not taken locally" + }, + {.name = "EXCEPTION_TRAP_OTHER", + .modmsk = ARMV8_ATTRS, + .code = 0x8d, + .desc = "Exception taken, other traps not taken locally" + }, + {.name = "EXCEPTION_TRAP_IRQ", + .modmsk = ARMV8_ATTRS, + .code = 0x8e, + .desc = "Exception taken, irq not taken locally" + }, + {.name = "EXCEPTION_TRAP_FIQ", + .modmsk = ARMV8_ATTRS, + .code = 0x8f, + .desc = "Exception taken, fiq not taken locally" + }, + {.name = "RC_LD_SPEC", + .modmsk = ARMV8_ATTRS, + .code = 0x90, + .desc = "Release consistency instruction speculatively executed (load-acquire)", + }, + {.name = "RC_ST_SPEC", + .modmsk = ARMV8_ATTRS, + .code = 0x91, + .desc = "Release consistency instruction speculatively executed (store-release)", + }, + {.name = "INST_SPEC_EXEC_NOP", + .modmsk = ARMV8_ATTRS, + .code = 0x100, + .desc = "Operation speculatively executed - NOP", + }, + {.name = "FSU_CLOCK_OFF", + .modmsk = ARMV8_ATTRS, + .code = 0x101, + .desc = "FSU clocking gated off cycle", + }, + {.name = "BTB_MISPREDICT", + .modmsk = ARMV8_ATTRS, + .code = 0x102, + .desc = "BTB misprediction", + }, + {.name = "ITB_MISS", + .modmsk = ARMV8_ATTRS, + .code = 0x103, + .desc = "ITB miss", + }, + {.name = "DTB_MISS", + .modmsk = ARMV8_ATTRS, + .code = 0x104, + .desc = "DTB miss", + }, + {.name = "L1D_CACHE_LATE_MISS", + .modmsk = ARMV8_ATTRS, + .code = 0x105, + .desc = "L1 data cache late miss", + }, + {.name = "L1D_CACHE_PREFETCH", + .modmsk = ARMV8_ATTRS, + .code = 0x106, + .desc = "L1 data cache prefetch request", + }, + {.name = "L2_CACHE_PREFETCH", + .modmsk = ARMV8_ATTRS, + .code = 0x107, + .desc = "L2 data prefetch request", + }, + {.name = "STALLED_CYCLES_FRONTEND", + .modmsk = ARMV8_ATTRS, + .code = 0x108, + .desc = "Decode starved for instruction cycle", + }, + {.name = "STALLED_CYCLES_BACKEND", + .modmsk = ARMV8_ATTRS, + .code = 0x109, + .desc = "Op dispatch stalled cycle", + }, + {.name = "IXA_NO_ISSUE", + .modmsk = ARMV8_ATTRS, + .code = 0x10A, + .desc = "IXA Op non-issue", + }, + {.name = "IXB_NO_ISSUE", + .modmsk = ARMV8_ATTRS, + .code = 0x10B, + .desc = "IXB Op non-issue", + }, + {.name = "BX_NO_ISSUE", + .modmsk = ARMV8_ATTRS, + .code = 0x10C, + .desc = "BX Op non-issue", + }, + {.name = "LX_NO_ISSUE", + .modmsk = ARMV8_ATTRS, + .code = 0x10D, + .desc = "LX Op non-issue", + }, + {.name = "SX_NO_ISSUE", + .modmsk = ARMV8_ATTRS, + .code = 0x10E, + .desc = "SX Op non-issue", + }, + {.name = "FX_NO_ISSUE", + .modmsk = ARMV8_ATTRS, + .code = 0x10F, + .desc = "FX Op non-issue", + }, + {.name = "WAIT_CYCLES", + .modmsk = ARMV8_ATTRS, + .code = 0x110, + .desc = "Wait state cycle", + }, + {.name = "L1_STAGE2_TLB_REFILL", + .modmsk = ARMV8_ATTRS, + .code = 0x111, + .desc = "L1 stage-2 TLB refill", + }, + {.name = "PAGE_WALK_L0_STAGE1_HIT", + .modmsk = ARMV8_ATTRS, + .code = 0x112, + .desc = "Page Walk Cache level-0 stage-1 hit", + }, + {.name = "PAGE_WALK_L1_STAGE1_HIT", + .modmsk = ARMV8_ATTRS, + .code = 0x113, + .desc = "Page Walk Cache level-1 stage-1 hit", + }, + {.name = "PAGE_WALK_L2_STAGE1_HIT", + .modmsk = ARMV8_ATTRS, + .code = 0x114, + .desc = "Page Walk Cache level-2 stage-1 hit", + }, + {.name = "PAGE_WALK_L1_STAGE2_HIT", + .modmsk = ARMV8_ATTRS, + .code = 0x115, + .desc = "Page Walk Cache level-1 stage-2 hit", + }, + {.name = "PAGE_WALK_L2_STAGE2_HIT", + .modmsk = ARMV8_ATTRS, + .code = 0x116, + .desc = "Page Walk Cache level-2 stage-2 hit", + }, + /* END Applied Micro X-Gene specific events */ +}; diff --git a/lib/pfmlib_arm_armv8.c b/lib/pfmlib_arm_armv8.c index c38bd9b..3619508 100644 --- a/lib/pfmlib_arm_armv8.c +++ b/lib/pfmlib_arm_armv8.c @@ -32,6 +32,7 @@ #include "events/arm_cortex_a57_events.h" /* A57 event tables */ #include "events/arm_cortex_a53_events.h" /* A53 event tables */ +#include "events/arm_xgene_events.h" /* Applied Micro X-Gene tables */ static int pfm_arm_detect_cortex_a57(void *this) @@ -65,6 +66,22 @@ pfm_arm_detect_cortex_a53(void *this) return PFM_ERR_NOTSUPP; } +static int +pfm_arm_detect_xgene(void *this) +{ + int ret; + + ret = pfm_arm_detect(this); + if (ret != PFM_SUCCESS) + return PFM_ERR_NOTSUPP; + + if ((pfm_arm_cfg.implementer == 0x50) && /* Applied Micro */ + (pfm_arm_cfg.part == 0x000)) { /* Applied Micro X-Gene */ + return PFM_SUCCESS; + } + return PFM_ERR_NOTSUPP; +} + /* ARM Cortex A57 support */ pfmlib_pmu_t arm_cortex_a57_support={ .desc = "ARM Cortex A57", @@ -114,3 +131,28 @@ pfmlib_pmu_t arm_cortex_a53_support={ PFMLIB_VALID_PERF_PATTRS(pfm_arm_perf_validate_pattrs), .get_event_nattrs = pfm_arm_get_event_nattrs, }; + +/* Applied Micro X-Gene support */ +pfmlib_pmu_t arm_xgene_support={ + .desc = "Applied Micro X-Gene", + .name = "arm_xgene", + .pmu = PFM_PMU_ARM_XGENE, + .pme_count = LIBPFM_ARRAY_SIZE(arm_xgene_pe), + .type = PFM_PMU_TYPE_CORE, + .pe = arm_xgene_pe, + + .pmu_detect = pfm_arm_detect_xgene, + .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 ebe20da..569ce85 100644 --- a/lib/pfmlib_common.c +++ b/lib/pfmlib_common.c @@ -201,10 +201,12 @@ static pfmlib_pmu_t *pfmlib_pmus[]= &arm_1176_support, &arm_cortex_a57_support, &arm_cortex_a53_support, + &arm_xgene_support, #endif #ifdef CONFIG_PFMLIB_ARCH_ARM64 &arm_cortex_a57_support, &arm_cortex_a53_support, + &arm_xgene_support, #endif #ifdef CONFIG_PFMLIB_ARCH_S390X diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h index 5678cc0..1666bcb 100644 --- a/lib/pfmlib_priv.h +++ b/lib/pfmlib_priv.h @@ -334,6 +334,7 @@ extern pfmlib_pmu_t arm_1176_support; extern pfmlib_pmu_t arm_1176_support; extern pfmlib_pmu_t arm_cortex_a57_support; extern pfmlib_pmu_t arm_cortex_a53_support; +extern pfmlib_pmu_t arm_xgene_support; extern pfmlib_pmu_t mips_74k_support; extern pfmlib_pmu_t s390x_cpum_cf_support; diff --git a/tests/validate_arm64.c b/tests/validate_arm64.c index 61400ac..f4593de 100644 --- a/tests/validate_arm64.c +++ b/tests/validate_arm64.c @@ -114,6 +114,34 @@ static const test_event_t arm64_test_events[]={ .codes[0] = 0x8000007, .fstr = "arm_ac53::ST_RETIRED:k=1:u=1:hv=0", }, + { SRC_LINE, + .name = "arm_xgene::CPU_CYCLES", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_xgene::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_xgene::CPU_CYCLES:k", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x88000011, + .fstr = "arm_xgene::CPU_CYCLES:k=1:u=0:hv=0", + }, + { SRC_LINE, + .name = "arm_xgene::CPU_CYCLES:k:u", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000011, + .fstr = "arm_xgene::CPU_CYCLES:k=1:u=1:hv=0", + }, + { SRC_LINE, + .name = "arm_xgene::INST_RETIRED", + .ret = PFM_SUCCESS, + .count = 1, + .codes[0] = 0x8000008, + .fstr = "arm_xgene::INST_RETIRED:k=1:u=1:hv=0", + }, }; #define NUM_TEST_EVENTS (int)(sizeof(arm64_test_events)/sizeof(test_event_t)) -- 1.9.3