Re: [perfmon2] [patch] ARM Cortex A7 Support
Status: Beta
Brought to you by:
seranian
From: Stephane E. <er...@go...> - 2014-06-17 21:32:26
|
Vince, Patch applied. Thanks On Mon, Jun 9, 2014 at 10:15 PM, Vince Weaver <vin...@ma...> wrote: > Hello, > > the following patch adds support for the ARM Cortex A7 PMU, as described > in table 11-5 of the Cortex-A7 MPCore Technical Reference Manual. > > A more interesting issue is big.LITTLE support. I have a > Samsung Exynos 5 Octa board, and it will transparently switch from > a Cortex A15 CPU to a Cortex A7 CPU automatically. With this patch > libpfm4 supports both configurations, but I'm not sure what happens if > the switch happens after libpfm4 has already detected the CPU. > Especially as the events available and number of counters differs > between the CPU types. > > Signed-off-by: Vince Weaver <vin...@ma...> > > diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h > index a7ec026..0169511 100644 > --- a/include/perfmon/pfmlib.h > +++ b/include/perfmon/pfmlib.h > @@ -240,6 +240,8 @@ typedef enum { > PFM_PMU_ARM_CORTEX_A57, /* ARM Cortex A57 (ARMv8) */ > PFM_PMU_ARM_CORTEX_A53, /* ARM Cortex A53 (ARMv8) */ > > + PFM_PMU_ARM_CORTEX_A7, /* ARM Cortex A7 */ > + > /* MUST ADD NEW PMU MODELS HERE */ > > PFM_PMU_MAX /* end marker */ > diff --git a/lib/Makefile b/lib/Makefile > index 5aaf4b3..14a6d0d 100644 > --- a/lib/Makefile > +++ b/lib/Makefile > @@ -279,6 +279,7 @@ INC_ARM=events/arm_cortex_a8_events.h \ > events/arm_cortex_a9_events.h > > INC_ARM=pfmlib_arm_priv.h \ > + events/arm_cortex_a7_events.h \ > events/arm_cortex_a8_events.h \ > events/arm_cortex_a9_events.h \ > events/arm_cortex_a15_events.h \ > diff --git a/lib/pfmlib_arm_armv7_pmuv1.c b/lib/pfmlib_arm_armv7_pmuv1.c > index 5fb14ca..c930781 100644 > --- a/lib/pfmlib_arm_armv7_pmuv1.c > +++ b/lib/pfmlib_arm_armv7_pmuv1.c > @@ -33,12 +33,30 @@ > #include "pfmlib_priv.h" /* library private */ > #include "pfmlib_arm_priv.h" > > -#include "events/arm_cortex_a8_events.h" /* event tables */ > +#include "events/arm_cortex_a7_events.h" /* event tables */ > +#include "events/arm_cortex_a8_events.h" > #include "events/arm_cortex_a9_events.h" > #include "events/arm_cortex_a15_events.h" > #include "events/arm_qcom_krait_events.h" > > static int > +pfm_arm_detect_cortex_a7(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 == 0xc07)) { /* Cortex-A7 */ > + return PFM_SUCCESS; > + } > + return PFM_ERR_NOTSUPP; > +} > + > +static int > pfm_arm_detect_cortex_a8(void *this) > { > > @@ -112,6 +130,32 @@ pfm_arm_detect_krait(void *this) > } > > > +/* Cortex A7 support */ > +pfmlib_pmu_t arm_cortex_a7_support={ > + .desc = "ARM Cortex A7", > + .name = "arm_ac7", > + .pmu = PFM_PMU_ARM_CORTEX_A7, > + .pme_count = LIBPFM_ARRAY_SIZE(arm_cortex_a7_pe), > + .type = PFM_PMU_TYPE_CORE, > + .pe = arm_cortex_a7_pe, > + > + .pmu_detect = pfm_arm_detect_cortex_a7, > + .max_encoding = 1, > + .num_cntrs = 4, > + .supported_plm = ARMV7_A7_PLM, > + > + .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, > +}; > + > /* Cortex A8 support */ > pfmlib_pmu_t arm_cortex_a8_support={ > .desc = "ARM Cortex A8", > diff --git a/lib/pfmlib_arm_priv.h b/lib/pfmlib_arm_priv.h > index 227508b..81a9df9 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 ARMV7_A7_ATTRS (_ARM_ATTR_K|_ARM_ATTR_U|_ARM_ATTR_HV) > +#define ARMV7_A7_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) > > diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c > index ebe20da..a16e4f5 100644 > --- a/lib/pfmlib_common.c > +++ b/lib/pfmlib_common.c > @@ -194,6 +194,7 @@ static pfmlib_pmu_t *pfmlib_pmus[]= > #endif > > #ifdef CONFIG_PFMLIB_ARCH_ARM > + &arm_cortex_a7_support, > &arm_cortex_a8_support, > &arm_cortex_a9_support, > &arm_cortex_a15_support, > diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h > index 5678cc0..aa974e0 100644 > --- a/lib/pfmlib_priv.h > +++ b/lib/pfmlib_priv.h > @@ -327,6 +327,7 @@ extern pfmlib_pmu_t perf_event_raw_support; > extern pfmlib_pmu_t intel_wsm_sp_support; > extern pfmlib_pmu_t intel_wsm_dp_support; > extern pfmlib_pmu_t intel_wsm_unc_support; > +extern pfmlib_pmu_t arm_cortex_a7_support; > extern pfmlib_pmu_t arm_cortex_a8_support; > extern pfmlib_pmu_t arm_cortex_a9_support; > extern pfmlib_pmu_t arm_cortex_a15_support; > diff --git a/tests/validate_arm.c b/tests/validate_arm.c > index 44eefd4..db0439f 100644 > --- a/tests/validate_arm.c > +++ b/tests/validate_arm.c > @@ -45,6 +45,35 @@ typedef struct { > > static const test_event_t arm_test_events[]={ > { SRC_LINE, > + .name = "arm_ac7::CPU_CYCLES", > + .ret = PFM_SUCCESS, > + .count = 1, > + .codes[0] = 0x8000011, > + .fstr = "arm_ac7::CPU_CYCLES:k=1:u=1:hv=0", > + }, > + { SRC_LINE, > + .name = "arm_ac7::CPU_CYCLES:k", > + .ret = PFM_SUCCESS, > + .count = 1, > + .codes[0] = 0x88000011, > + .fstr = "arm_ac7::CPU_CYCLES:k=1:u=0:hv=0", > + }, > + { SRC_LINE, > + .name = "arm_ac7::CPU_CYCLES:k:u", > + .ret = PFM_SUCCESS, > + .count = 1, > + .codes[0] = 0x8000011, > + .fstr = "arm_ac7::CPU_CYCLES:k=1:u=1:hv=0", > + }, > + { SRC_LINE, > + .name = "arm_ac7::INST_RETIRED", > + .ret = PFM_SUCCESS, > + .count = 1, > + .codes[0] = 0x8000008, > + .fstr = "arm_ac7::INST_RETIRED:k=1:u=1:hv=0", > + }, > + > + { SRC_LINE, > .name = "arm_ac8::NEON_CYCLES", > .ret = PFM_SUCCESS, > .count = 1, > diff --git a/docs/man3/libpfm_arm_ac7.3 b/docs/man3/libpfm_arm_ac7.3 > new file mode 100644 > index 0000000..89d06e9 > --- /dev/null > +++ b/docs/man3/libpfm_arm_ac7.3 > @@ -0,0 +1,35 @@ > +.TH LIBPFM 3 "August, 2012" "" "Linux Programmer's Manual" > +.SH NAME > +libpfm_arm_ac7 - support for Arm Cortex A7 PMU > +.SH SYNOPSIS > +.nf > +.B #include <perfmon/pfmlib.h> > +.sp > +.B PMU name: arm_ac7 > +.B PMU desc: ARM Cortex A7 > +.sp > +.SH DESCRIPTION > +The library supports the ARM Cortex A7 core PMU. > + > +This PMU supports 4 counters and privilege levels filtering. > + > +.SH MODIFIERS > +The following modifiers are supported on ARM Cortex A7: > +.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 <er...@gm...> > +.if > +.PP > diff --git a/lib/events/arm_cortex_a7_events.h > b/lib/events/arm_cortex_a7_events.h > new file mode 100644 > index 0000000..f7197f9 > --- /dev/null > +++ b/lib/events/arm_cortex_a7_events.h > @@ -0,0 +1,231 @@ > +/* > + * Copyright (c) 2014 by Vince Weaver <vin...@ma...> > + * > + * 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 A7 MPCore > + * based on Table 11-5 from the "Cortex-A7 MPCore Technical Reference > Manual" > + */ > +static const arm_entry_t arm_cortex_a7_pe[]={ > + {.name = "SW_INCR", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x00, > + .desc = "Incremented on writes to the Software Increment Register" > + }, > + {.name = "L1I_CACHE_REFILL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x01, > + .desc = "Level 1 instruction cache refill" > + }, > + {.name = "L1I_TLB_REFILL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x02, > + .desc = "Level 1 instruction TLB refill" > + }, > + {.name = "L1D_CACHE_REFILL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x03, > + .desc = "Level 1 data cache refill" > + }, > + {.name = "L1D_CACHE_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x04, > + .desc = "Level 1 data cache access" > + }, > + {.name = "L1D_TLB_REFILL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x05, > + .desc = "Level 1 data TLB refill" > + }, > + {.name = "DATA_READS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x06, > + .desc = "Data reads architecturally executed" > + }, > + {.name = "DATA_WRITES", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x07, > + .desc = "Data writes architecturally executed" > + }, > + {.name = "INST_RETIRED", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x08, > + .desc = "Instruction architecturally executed" > + }, > + {.name = "EXCEPTION_TAKEN", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x09, > + .desc = "Exception taken" > + }, > + {.name = "EXCEPTION_RETURN", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x0a, > + .desc = "Instruction architecturally executed" > + }, > + {.name = "CID_WRITE_RETIRED", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x0b, > + .desc = "Change to ContextID retired" > + }, > + {.name = "SW_CHANGE_PC", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x0c, > + .desc = "Software change of PC" > + }, > + {.name = "IMMEDIATE_BRANCHES", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x0d, > + .desc = "Immediate branch architecturally executed" > + }, > + {.name = "PROCEDURE_RETURNS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x0e, > + .desc = "Procedure returns architecturally executed" > + }, > + {.name = "UNALIGNED_LOAD_STORE", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x0f, > + .desc = "Unaligned load-store" > + }, > + {.name = "BRANCH_MISPRED", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x10, > + .desc = "Branches mispredicted/not predicted" > + }, > + {.name = "CPU_CYCLES", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x11, > + .desc = "Cycles" > + }, > + {.name = "BRANCH_PRED", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x12, > + .desc = "Predictable branch speculatively executed" > + }, > + {.name = "DATA_MEM_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x13, > + .desc = "Data memory access" > + }, > + {.name = "L1I_CACHE_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x14, > + .desc = "Level 1 instruction cache access" > + }, > + {.name = "L1D_CACHE_EVICTION", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x15, > + .desc = "Level 1 data cache eviction" > + }, > + {.name = "L2D_CACHE_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x16, > + .desc = "Level 2 data cache access" > + }, > + {.name = "L2D_CACHE_REFILL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x17, > + .desc = "Level 2 data cache refill" > + }, > + {.name = "L2D_CACHE_WB", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x18, > + .desc = "Level 2 data cache WriteBack" > + }, > + {.name = "BUS_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x19, > + .desc = "Bus accesses" > + }, > + {.name = "BUS_CYCLES", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x1d, > + .desc = "Bus cycle" > + }, > + {.name = "BUS_READ_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x60, > + .desc = "Bus read access" > + }, > + {.name = "BUS_WRITE_ACCESS", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x61, > + .desc = "Bus write access" > + }, > + {.name = "IRQ_EXCEPTION_TAKEN", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x86, > + .desc = "IRQ Exception Taken" > + }, > + {.name = "FIQ_EXCEPTION_TAKEN", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0x87, > + .desc = "FIQ Exception Taken" > + }, > + {.name = "EXTERNAL_MEMORY_REQUEST", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc0, > + .desc = "External memory request" > + }, > + {.name = "NONCACHE_EXTERNAL_MEMORY_REQUEST", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc1, > + .desc = "Non-cacheable xternal memory request" > + }, > + {.name = "PREFETCH_LINEFILL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc2, > + .desc = "Linefill due to prefetch" > + }, > + {.name = "PREFETCH_LINEFILL_DROPPED", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc3, > + .desc = "Prefetch linefill dropped" > + }, > + {.name = "ENTERING_READ_ALLOC", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc4, > + .desc = "Entering read allocate mode" > + }, > + {.name = "READ_ALLOC", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc5, > + .desc = "Read allocate mode" > + }, > + /* 0xc6 is Reserved */ > + {.name = "ETM_EXT_OUT_0", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc7, > + .desc = "ETM Ext Out[0]" > + }, > + {.name = "ETM_EXT_OUT_1", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc8, > + .desc = "ETM Ext Out[1]" > + }, > + {.name = "DATA_WRITE_STALL", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xc9, > + .desc = "Data write operation that stalls pipeline due to full > store buffer" > + }, > + {.name = "DATA_SNOOPED", > + .modmsk = ARMV7_A7_ATTRS, > + .code = 0xca, > + .desc = "Data snooped from other processor" > + }, > +}; > |