This patch adds support for the ARM 1176 armv6 processor found in the Raspberry Pi.
I've tested that libpfm4 with this patch works on a Raspberry Pi, but the kernel installed on the board has broken perf_event support so I haven't actually measured any performance events yet. --- config.mk | 3 + include/perfmon/pfmlib.h | 2 + lib/Makefile | 2 +- lib/events/arm_1176_events.h | 136 ++++++++++++++++++++++++++++++++++++++++++ lib/pfmlib_arm_armv6.c | 77 ++++++++++++++++++++++++ lib/pfmlib_common.c | 1 + lib/pfmlib_priv.h | 1 + 7 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 lib/events/arm_1176_events.h create mode 100644 lib/pfmlib_arm_armv6.c diff --git a/config.mk b/config.mk index 5f6adf2..b5cefc3 100644 --- a/config.mk +++ b/config.mk @@ -57,6 +57,9 @@ endif ifeq (sparc64,$(findstring sparc64,$(ARCH))) override ARCH=sparc endif +ifeq (armv6,$(findstring armv6,$(ARCH))) +override ARCH=arm +endif ifeq (armv7,$(findstring armv7,$(ARCH))) override ARCH=arm endif diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h index b122ca5..ac8f31e 100644 --- a/include/perfmon/pfmlib.h +++ b/include/perfmon/pfmlib.h @@ -180,6 +180,8 @@ typedef enum { PFM_PMU_S390X_CPUM_CF, /* s390x: CPU-M counter facility */ + PFM_PMU_ARM_1176, /* ARM 1176 */ + /* MUST ADD NEW PMU MODELS HERE */ PFM_PMU_MAX /* end marker */ diff --git a/lib/Makefile b/lib/Makefile index d2f00a9..0c288d3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -127,7 +127,7 @@ SRCS += pfmlib_arm_perf_event.c endif INCARCH = $(INC_ARM) -SRCS += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c +SRCS += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c pfmlib_arm_armv6.c CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM endif diff --git a/lib/events/arm_1176_events.h b/lib/events/arm_1176_events.h new file mode 100644 index 0000000..35a43fa --- /dev/null +++ b/lib/events/arm_1176_events.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 by Vince Weaver <vincent.wea...@maine.edu> + * + * 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. + * + * This file is part of libpfm, a performance monitoring support library for + * applications on Linux. + */ + +/* + * the various event names are the same as those given in the + * file linux-2.6/arch/arm/kernel/perf_event_v6.c + */ + +/* + * ARM1176 Event Table + */ +static const arm_entry_t arm_1176_pe []={ + {.name = "ICACHE_MISS", + .code = 0x00, + .desc = "Instruction cache miss (includes speculative accesses)" + }, + {.name = "IBUF_STALL", + .code = 0x01, + .desc = "Stall because instruction buffer cannot deliver an instruction" + }, + {.name = "DDEP_STALL", + .code = 0x02, + .desc = "Stall because of data dependency" + }, + {.name = "ITLB_MISS", + .code = 0x03, + .desc = "Instruction MicroTLB miss" + }, + {.name = "DTLB_MISS", + .code = 0x04, + .desc = "Data MicroTLB miss" + }, + {.name = "BR_EXEC", + .code = 0x05, + .desc = "Branch instruction executed" + }, + {.name = "BR_MISPREDICT", + .code = 0x06, + .desc = "Branch mispredicted" + }, + {.name = "INSTR_EXEC", + .code = 0x07, + .desc = "Instruction executed" + }, + {.name = "DCACHE_HIT", + .code = 0x09, + .desc = "Data cache hit" + }, + {.name = "DCACHE_ACCESS", + .code = 0x0a, + .desc = "Data cache access" + }, + {.name = "DCACHE_MISS", + .code = 0x0b, + .desc = "Data cache miss" + }, + {.name = "DCACHE_WBACK", + .code = 0x0c, + .desc = "Data cache writeback" + }, + {.name = "SW_PC_CHANGE", + .code = 0x0d, + .desc = "Software changed the PC." + }, + {.name = "MAIN_TLB_MISS", + .code = 0x0f, + .desc = "Main TLB miss" + }, + {.name = "EXPL_D_ACCESS", + .code = 0x10, + .desc = "Explicit external data cache access " + }, + {.name = "LSU_FULL_STALL", + .code = 0x11, + .desc = "Stall because of a full Load Store Unit request queue." + }, + {.name = "WBUF_DRAINED", + .code = 0x12, + .desc = "Write buffer drained due to data synchronization barrier or strongly ordered operation" + }, + {.name = "ETMEXTOUT_0", + .code = 0x20, + .desc = "ETMEXTOUT[0] was asserted" + }, + {.name = "ETMEXTOUT_1", + .code = 0x21, + .desc = "ETMEXTOUT[1] was asserted" + }, + {.name = "ETMEXTOUT", + .code = 0x22, + .desc = "Increment once for each of ETMEXTOUT[0] or ETMEXTOUT[1]" + }, + {.name = "PROC_CALL_EXEC", + .code = 0x23, + .desc = "Procedure call instruction executed" + }, + {.name = "PROC_RET_EXEC", + .code = 0x24, + .desc = "Procedure return instruction executed" + }, + {.name = "PROC_RET_EXEC_PRED", + .code = 0x25, + .desc = "Proceudre return instruction executed and address predicted" + }, + {.name = "PROC_RET_EXEC_PRED_INCORRECT", + .code = 0x26, + .desc = "Procedure return instruction executed and address predicted incorrectly" + }, + {.name = "CPU_CYCLES", + .code = 0xff, + .desc = "CPU cycles" + }, +}; + +#define ARM_1176_EVENT_COUNT (sizeof(arm_1176_pe)/sizeof(arm_entry_t)) diff --git a/lib/pfmlib_arm_armv6.c b/lib/pfmlib_arm_armv6.c new file mode 100644 index 0000000..d59b402 --- /dev/null +++ b/lib/pfmlib_arm_armv6.c @@ -0,0 +1,77 @@ +/* + * pfmlib_arm_armv6.c : support for ARMv6 chips + * + * Copyright (c) 2013 by Vince Weaver <vincent.wea...@maine.edu> + * + * 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 <sys/types.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + +/* private headers */ +#include "pfmlib_priv.h" /* library private */ +#include "pfmlib_arm_priv.h" + +#include "events/arm_1176_events.h" /* event tables */ + +static int +pfm_arm_detect_1176(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==0xb76)) { /* 1176 */ + return PFM_SUCCESS; + } + return PFM_ERR_NOTSUPP; +} + +/* ARM1176 support */ +pfmlib_pmu_t arm_1176_support={ + .desc = "ARM1176", + .name = "arm_1176", + .pmu = PFM_PMU_ARM_1176, + .pme_count = LIBPFM_ARRAY_SIZE(arm_1176_pe), + .type = PFM_PMU_TYPE_CORE, + .pe = arm_1176_pe, + + .pmu_detect = pfm_arm_detect_1176, + .max_encoding = 1, + .num_cntrs = 2, + + .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 c29a325..87f6a01 100644 --- a/lib/pfmlib_common.c +++ b/lib/pfmlib_common.c @@ -152,6 +152,7 @@ static pfmlib_pmu_t *pfmlib_pmus[]= &arm_cortex_a8_support, &arm_cortex_a9_support, &arm_cortex_a15_support, + &arm_1176_support, #endif #ifdef CONFIG_PFMLIB_ARCH_S390X &s390x_cpum_cf_support, diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h index 8d3353d..b57aa10 100644 --- a/lib/pfmlib_priv.h +++ b/lib/pfmlib_priv.h @@ -274,6 +274,7 @@ extern pfmlib_pmu_t intel_wsm_unc_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; +extern pfmlib_pmu_t arm_1176_support; extern pfmlib_pmu_t mips_74k_support; extern pfmlib_pmu_t s390x_cpum_cf_support; -- 1.7.10.4 ------------------------------------------------------------------------------ Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb _______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel