Vince, I am looking at removing any OS dependencies from libpfm4. In particular, I'd like to get rid of pfmlib_getcpuinfo_attr() and replace with a processor specific call , e.g., cpuid(). I noticed that in the new arm code, you are relying on pfmlib_getcpuinfo_attr(). I wonder if it would not be possible to add some cpuid()-style calls to get to the same information. Would you know about this?
I will fix the X86 code. Thanks. On Sat, Aug 28, 2010 at 6:51 PM, stephane eranian <eran...@googlemail.com> wrote: > Vince, > > Patch applied with some minor cosmetic changes. > Now we need to improve the Makefile structure to > allow for easy cross compilation. > > Thanks for your contribution. > > > On Fri, Aug 27, 2010 at 11:57 PM, Vince Weaver <vweav...@eecs.utk.edu> wrote: >> Hello >> >> here's an updated patch. I think I've addressed all of your comments. >> >> Some things that are different: >> >> + I added descriptions for the Coretex A9 events >> + I named the cortex specific file with the awkward >> pfmlib_arm_armv7_pmuv1.c rather than arm_cortex.c, because >> techncially what is implemented by the Cortex chips is >> the ARMv7 PMUv1 counter interface. >> >> It turns out there is a PMUv2 on the way that does have >> separate user/kernel specifiers among other things, but >> I don't know of any chips that support that yet. >> >> Vince >> >> diff -urpN libpfm4.stock/config.mk libpfm4.vmw/config.mk >> --- libpfm4.stock/config.mk 2010-08-27 15:12:22.650348609 -0400 >> +++ libpfm4.vmw/config.mk 2010-08-27 15:16:00.285929701 -0400 >> @@ -51,6 +51,9 @@ endif >> ifeq (sparc64,$(findstring sparc64,$(ARCH))) >> override ARCH=sparc >> endif >> +ifeq (armv7,$(findstring armv7,$(ARCH))) >> +override ARCH=arm >> +endif >> >> # >> # CONFIG_PFMLIB_SHARED: y=compile static and shared versions, n=static only >> @@ -122,6 +125,10 @@ ifeq ($(ARCH),sparc) >> CONFIG_PFMLIB_ARCH_SPARC=y >> endif >> >> +ifeq ($(ARCH),arm) >> +CONFIG_PFMLIB_ARCH_ARM=y >> +endif >> + >> ifeq ($(XTPE_COMPILE_TARGET),linux) >> CONFIG_PFMLIB_ARCH_CRAYXT=y >> endif >> diff -urpN libpfm4.stock/include/perfmon/pfmlib.h >> libpfm4.vmw/include/perfmon/pfmlib.h >> --- libpfm4.stock/include/perfmon/pfmlib.h 2010-08-27 >> 15:12:26.133952131 -0400 >> +++ libpfm4.vmw/include/perfmon/pfmlib.h 2010-08-27 >> 15:16:00.473938170 -0400 >> @@ -126,6 +126,9 @@ typedef enum { >> PFM_PMU_AMD64_FAM10H_SHANGHAI, /* AMD AMD64 Fam10h Shanghai RevC */ >> PFM_PMU_AMD64_FAM10H_ISTANBUL, /* AMD AMD64 Fam10h Istanbul RevD */ >> >> + PFM_PMU_ARM_CORTEX_A8, /* ARM Cortex A8 */ >> + PFM_PMU_ARM_CORTEX_A9, /* ARM Cortex A9 */ >> + >> /* MUST ADD NEW PMU MODELS HERE */ >> >> PFM_PMU_MAX /* end marker */ >> >> diff -urpN libpfm4.stock/lib/events/arm_cortex_a8_events.h >> libpfm4.vmw/lib/events/arm_cortex_a8_events.h >> --- libpfm4.stock/lib/events/arm_cortex_a8_events.h 1969-12-31 >> 19:00:00.000000000 -0500 >> +++ libpfm4.vmw/lib/events/arm_cortex_a8_events.h 2010-08-27 >> 16:39:17.998023806 -0400 >> @@ -0,0 +1,235 @@ >> +/* >> + * Copyright (c) 2010 University of Tennessee >> + * Contributed by Vince Weaver <vweav...@utk.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 counter names are the same as those given in the */ >> +/* file linux-2.6/arch/arm/kernel/perf_event.c */ >> + >> +/* >> + * Cortex A8 Event Table >> + */ >> +static const arm_entry_t arm_cortex_a8_pe []={ >> + {.name = "PMNC_SW_INCR", >> + .code = 0x00, >> + .desc = "Incremented by writes to the Software Increment Register" >> + }, >> + {.name = "IFETCH_MISS", >> + .code = 0x01, >> + .desc = "Instruction fetches that cause lowest-level cache miss" >> + }, >> + {.name = "ITLB_MISS", >> + .code = 0x02, >> + .desc = "Instruction fetches that cause lowest-level TLB miss" >> + }, >> + {.name = "DCACHE_REFILL", >> + .code = 0x03, >> + .desc = "Data read or writes that cause lowest-level cache miss" >> + }, >> + {.name = "DCACHE_ACCESS", >> + .code = 0x04, >> + .desc = "Data read or writes that cause lowest-level cache access" >> + }, >> + {.name = "DTLB_REFILL", >> + .code = 0x05, >> + .desc = "Data read or writes that cause lowest-level TLB refill" >> + }, >> + {.name = "DREAD", >> + .code = 0x06, >> + .desc = "Data read architecturally executed" >> + }, >> + {.name = "DWRITE", >> + .code = 0x07, >> + .desc = "Data write architecturally executed" >> + }, >> + {.name = "INSTR_EXECUTED", >> + .code = 0x08, >> + .desc = "Instructions architecturally executed" >> + }, >> + {.name = "EXC_TAKEN", >> + .code = 0x09, >> + .desc = "Counts each exception taken" >> + }, >> + {.name = "EXC_EXECUTED", >> + .code = 0x0a, >> + .desc = "Exception returns architecturally executed" >> + }, >> + {.name = "CID_WRITE", >> + .code = 0x0b, >> + .desc = "Instruction writes to Context ID Register, architecturally >> executed" >> + }, >> + {.name = "PC_WRITE", >> + .code = 0x0c, >> + .desc = "Software change of PC. Equivelant to branches" >> + }, >> + {.name = "PC_IMM_BRANCH", >> + .code = 0x0d, >> + .desc = "Immedidate branches architecturally executed" >> + }, >> + {.name = "PC_PROC_RETURN", >> + .code = 0x0e, >> + .desc = "Procedure returns architecturally executed" >> + }, >> + {.name = "UNALIGNED_ACCESS", >> + .code = 0x0f, >> + .desc = "Unaligned accesses architecturally executed" >> + }, >> + {.name = "PC_BRANCH_MIS_PRED", >> + .code = 0x10, >> + .desc = "Branches mispredicted or not predicted" >> + }, >> + {.name = "CLOCK_CYCLES", /* this isn't in the Cortex-A8 tech doc */ >> + .code = 0x11, /* but is in linux kernel */ >> + .desc = "Clock cycles" >> + }, >> + {.name = "PC_BRANCH_MIS_USED", >> + .code = 0x12, >> + .desc = "Branches that could have been predicted" >> + }, >> + {.name = "WRITE_BUFFER_FULL", >> + .code = 0x40, >> + .desc = "Cycles Write buffer full" >> + }, >> + {.name = "L2_STORE_MERGED", >> + .code = 0x41, >> + .desc = "Stores merged in L2" >> + }, >> + {.name = "L2_STORE_BUFF", >> + .code = 0x42, >> + .desc = "Bufferable store transactions to L2" >> + }, >> + {.name = "L2_ACCESS", >> + .code = 0x43, >> + .desc = "Accesses to L2 cache" >> + }, >> + {.name = "L2_CACHE_MISS", >> + .code = 0x44, >> + .desc = "L2 cache misses" >> + }, >> + {.name = "AXI_READ_CYCLES", >> + .code = 0x45, >> + .desc = "Cycles with active AXI read channel transactions" >> + }, >> + {.name = "AXI_WRITE_CYCLES", >> + .code = 0x46, >> + .desc = "Cycles with Active AXI write channel transactions" >> + }, >> + {.name = "MEMORY_REPLAY", >> + .code = 0x47, >> + .desc = "Memory replay events" >> + }, >> + {.name = "UNALIGNED_ACCESS_REPLAY", >> + .code = 0x48, >> + .desc = "Unaligned accesses causing replays" >> + }, >> + {.name = "L1_DATA_MISS", >> + .code = 0x49, >> + .desc = "L1 data misses due to hashing algorithm" >> + }, >> + {.name = "L1_INST_MISS", >> + .code = 0x4a, >> + .desc = "L1 instruction misses due to hashing algorithm" >> + }, >> + {.name = "L1_DATA_COLORING", >> + .code = 0x4b, >> + .desc = "L1 data access where page color alias occurs" >> + }, >> + {.name = "L1_NEON_DATA", >> + .code = 0x4c, >> + .desc = "NEON accesses that hit in L1 cache" >> + }, >> + {.name = "L1_NEON_CACH_DATA", >> + .code = 0x4d, >> + .desc = "NEON cache accesses for L1 cache" >> + }, >> + {.name = "L2_NEON", >> + .code = 0x4e, >> + .desc = "L2 accesses caused by NEON" >> + }, >> + {.name = "L2_NEON_HIT", >> + .code = 0x4f, >> + .desc = "L2 hits caused by NEON" >> + }, >> + {.name = "L1_INST", >> + .code = 0x50, >> + .desc = "L1 instruction cache accesses" >> + }, >> + {.name = "PC_RETURN_MIS_PRED", >> + .code = 0x51, >> + .desc = "Return stack mispredictions" >> + }, >> + {.name = "PC_BRANCH_FAILED", >> + .code = 0x52, >> + .desc = "Branch prediction failures" >> + }, >> + {.name = "PC_BRANCH_TAKEN", >> + .code = 0x53, >> + .desc = "Branches predicted taken" >> + }, >> + {.name = "PC_BRANCH_EXECUTED", >> + .code = 0x54, >> + .desc = "Taken branches executed" >> + }, >> + {.name = "OP_EXECUTED", >> + .code = 0x55, >> + .desc = "Operations excuted (includes sub-ops in multi-cycle >> instructions)" >> + }, >> + {.name = "CYCLES_INST_STALL", >> + .code = 0x56, >> + .desc = "Cycles no instruction is available for issue" >> + }, >> + {.name = "CYCLES_INST", >> + .code = 0x57, >> + .desc = "Number of instructions issued in cycle" >> + }, >> + {.name = "CYCLES_NEON_DATA_STALL", >> + .code = 0x58, >> + .desc = "Cycles stalled waiting on NEON MRC data" >> + }, >> + {.name = "CYCLES_NEON_INST_STALL", >> + .code = 0x59, >> + .desc = "Cycles stalled due to full NEON queues" >> + }, >> + {.name = "NEON_CYCLES", >> + .code = 0x5a, >> + .desc = "Cycles NEON and integer processors both not idle" >> + }, >> + {.name = "PMU0_EVENTS", >> + .code = 0x70, >> + .desc = "External PMUEXTIN[0] event" >> + }, >> + {.name = "PMU1_EVENTS", >> + .code = 0x71, >> + .desc = "External PMUEXTIN[1] event" >> + }, >> + {.name = "PMU_EVENTS", >> + .code = 0x72, >> + .desc = "External PMUEXTIN[0] or PMUEXTIN[1] event" >> + }, >> + {.name = "CPU_CYCLES", >> + .code = 0xff, >> + .desc = "CPU cycles" >> + }, >> +}; >> + >> +#define ARM_CORTEX_A8_EVENT_COUNT >> (sizeof(arm_cortex_a8_pe)/sizeof(arm_entry_t)) >> diff -urpN libpfm4.stock/lib/events/arm_cortex_a9_events.h >> libpfm4.vmw/lib/events/arm_cortex_a9_events.h >> --- libpfm4.stock/lib/events/arm_cortex_a9_events.h 1969-12-31 >> 19:00:00.000000000 -0500 >> +++ libpfm4.vmw/lib/events/arm_cortex_a9_events.h 2010-08-27 >> 17:07:43.763543623 -0400 >> @@ -0,0 +1,264 @@ >> +/* >> + * Copyright (c) 2010 University of Tennessee >> + * Contributed by Vince Weaver <vweav...@utk.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 counter names are the same as those given in the */ >> +/* file linux-2.6/arch/arm/kernel/perf_event.c */ >> + >> +/* >> + * Cortex A9 Event Table >> + * based on Table 9-2 from the "Cortex A9 Technical Reference Manual >> + */ >> +static const arm_entry_t arm_cortex_a9_pe []={ >> + {.name = "PMNC_SW_INCR", >> + .code = 0x00, >> + .desc = "Incremented by writes to the Software Increment Register" >> + }, >> + {.name = "IFETCH_MISS", >> + .code = 0x01, >> + .desc = "Instruction fetches that cause lowest-level cache miss" >> + }, >> + {.name = "ITLB_MISS", >> + .code = 0x02, >> + .desc = "Instruction fetches that cause lowest-level TLB miss" >> + }, >> + {.name = "DCACHE_REFILL", >> + .code = 0x03, >> + .desc = "Data read or writes that cause lowest-level cache miss" >> + }, >> + {.name = "DCACHE_ACCESS", >> + .code = 0x04, >> + .desc = "Data read or writes that cause lowest-level cache access" >> + }, >> + {.name = "DTLB_REFILL", >> + .code = 0x05, >> + .desc = "Data read or writes that cause lowest-level TLB refill" >> + }, >> + {.name = "DREAD", >> + .code = 0x06, >> + .desc = "Data read architecturally executed" >> + }, >> + {.name = "DWRITE", >> + .code = 0x07, >> + .desc = "Data write architecturally executed" >> + }, >> + {.name = "EXC_TAKEN", >> + .code = 0x09, >> + .desc = "Counts each exception taken" >> + }, >> + {.name = "EXC_EXECUTED", >> + .code = 0x0a, >> + .desc = "Exception returns architecturally executed" >> + }, >> + {.name = "CID_WRITE", >> + .code = 0x0b, >> + .desc = "Instruction writes to Context ID Register, architecturally >> executed" >> + }, >> + {.name = "PC_WRITE", >> + .code = 0x0c, >> + .desc = "Software change of PC. Equivelant to branches" >> + }, >> + {.name = "PC_IMM_BRANCH", >> + .code = 0x0d, >> + .desc = "Immedidate branches architecturally executed" >> + }, >> + {.name = "UNALIGNED_ACCESS", >> + .code = 0x0f, >> + .desc = "Unaligned accesses architecturally executed" >> + }, >> + {.name = "PC_BRANCH_MIS_PRED", >> + .code = 0x10, >> + .desc = "Branches mispredicted or not predicted" >> + }, >> + {.name = "CLOCK_CYCLES", >> + .code = 0x11, >> + .desc = "Clock cycles" >> + }, >> + {.name = "PC_BRANCH_MIS_USED", >> + .code = 0x12, >> + .desc = "Branches that could have been predicted" >> + }, >> + {.name = "JAVA_HW_BYTECODE_EXEC", >> + .code = 0x40, >> + .desc = "Java bytecodes decoded, including speculative" >> + }, >> + {.name = "JAVA_SW_BYTECODE_EXEC", >> + .code = 0x41, >> + .desc = "Software Java bytecodes decoded, including speculative" >> + }, >> + {.name = "JAZELLE_BRANCH_EXEC", >> + .code = 0x42, >> + .desc = "Jazelle backward branches executed" >> + }, >> + {.name = "COHERENT_LINE_MISS", >> + .code = 0x50, >> + .desc = "Coherent linefill misses which also miss on other processors" >> + }, >> + {.name = "COHERENT_LINE_HIT", >> + .code = 0x51, >> + .desc = "Coherent linefill requests that hit on another processor" >> + }, >> + {.name = "ICACHE_DEP_STALL_CYCLES", >> + .code = 0x60, >> + .desc = "Cycles processor is stalled waiting for instruction cache" >> + }, >> + {.name = "DCACHE_DEP_STALL_CYCLES", >> + .code = 0x61, >> + .desc = "Cycles processor is stalled waiting for data cache" >> + }, >> + {.name = "TLB_MISS_DEP_STALL_CYCLES", >> + .code = 0x62, >> + .desc = "Cycles processor is stalled waiting for completion of TLB walk" >> + }, >> + {.name = "STREX_EXECUTED_PASSED", >> + .code = 0x63, >> + .desc = "Number of STREX instructions executed and passed" >> + }, >> + {.name = "STREX_EXECUTED_FAILED", >> + .code = 0x64, >> + .desc = "Number of STREX instructions executed and failed" >> + }, >> + {.name = "DATA_EVICTION", >> + .code = 0x65, >> + .desc = "Data eviction requests due to linefill in data cache" >> + }, >> + {.name = "ISSUE_STAGE_NO_INST", >> + .code = 0x66, >> + .desc = "Cycles the issue stage does not dispatch any instructions" >> + }, >> + {.name = "ISSUE_STAGE_EMPTY", >> + .code = 0x67, >> + .desc = "Cycles where issue stage is empty" >> + }, >> + {.name = "INST_OUT_OF_RENAME_STAGE", >> + .code = 0x68, >> + .desc = "Number of instructions going through register renaming stage" >> + }, >> + {.name = "PREDICTABLE_FUNCT_RETURNS", >> + .code = 0x6e, >> + .desc = "Number of predictable function returns whose condition codes >> do not fail" >> + }, >> + {.name = "MAIN_UNIT_EXECUTED_INST", >> + .code = 0x70, >> + .desc = "Instructions executed in the main execution pipeline" >> + }, >> + {.name = "SECOND_UNIT_EXECUTED_INST", >> + .code = 0x71, >> + .desc = "Instructions executed in the second execution pipeline" >> + }, >> + {.name = "LD_ST_UNIT_EXECUTED_INST", >> + .code = 0x72, >> + .desc = "Instructions executed in the Load/Store unit" >> + }, >> + {.name = "FP_EXECUTED_INST", >> + .code = 0x73, >> + .desc = "Floating point instructions going through register renaming >> stage" >> + }, >> + {.name = "NEON_EXECUTED_INST", >> + .code = 0x74, >> + .desc = "NEON instructions going through register renaming stage" >> + }, >> + {.name = "PLD_FULL_DEP_STALL_CYCLES", >> + .code = 0x80, >> + .desc = "Cycles processor is stalled because PLD slots are full" >> + }, >> + {.name = "DATA_WR_DEP_STALL_CYCLES", >> + .code = 0x81, >> + .desc = "Cycles processor is stalled due to writes to external memory" >> + }, >> + {.name = "ITLB_MISS_DEP_STALL_CYCLES", >> + .code = 0x82, >> + .desc = "Cycles stalled due to main instruction TLB miss" >> + }, >> + {.name = "DTLB_MISS_DEP_STALL_CYCLES", >> + .code = 0x83, >> + .desc = "Cycles stalled due to main data TLB miss" >> + }, >> + {.name = "MICRO_ITLB_MISS_DEP_STALL_CYCLES", >> + .code = 0x84, >> + .desc = "Cycles stalled due to micro instruction TLB miss" >> + }, >> + {.name = "MICRO_DTLB_MISS_DEP_STALL_CYCLES", >> + .code = 0x85, >> + .desc = "Cycles stalled due to micro data TLB miss" >> + }, >> + {.name = "DMB_DEP_STALL_CYCLES", >> + .code = 0x86, >> + .desc = "Cycles stalled due to DMB memory barrier" >> + }, >> + {.name = "INTGR_CLK_ENABLED_CYCLES", >> + .code = 0x8a, >> + .desc = "Cycles during which integer core clock is enabled" >> + }, >> + {.name = "DATA_ENGINE_CLK_EN_CYCLES", >> + .code = 0x8b, >> + .desc = "Cycles during which Data Engine clock is enabled" >> + }, >> + {.name = "ISB_INST", >> + .code = 0x90, >> + .desc = "Number of ISB instructions architecturally executed" >> + }, >> + {.name = "DSB_INST", >> + .code = 0x91, >> + .desc = "Number of DSB instructions architecturally executed" >> + }, >> + {.name = "DMB_INST", >> + .code = 0x92, >> + .desc = "Number of DMB instructions architecturally executed" >> + }, >> + {.name = "EXT_INTERRUPTS", >> + .code = 0x93, >> + .desc = "Number of External interrupts" >> + }, >> + {.name = "PLE_CACHE_LINE_RQST_COMPLETED", >> + .code = 0xa0, >> + .desc = "PLE cache line requests completed" >> + }, >> + {.name = "PLE_CACHE_LINE_RQST_SKIPPED", >> + .code = 0xa1, >> + .desc = "PLE cache line requests skipped" >> + }, >> + {.name = "PLE_FIFO_FLUSH", >> + .code = 0xa2, >> + .desc = "PLE FIFO flushes" >> + }, >> + {.name = "PLE_RQST_COMPLETED", >> + .code = 0xa3, >> + .desc = "PLE requests completed" >> + }, >> + {.name = "PLE_FIFO_OVERFLOW", >> + .code = 0xa4, >> + .desc = "PLE FIFO overflows" >> + }, >> + {.name = "PLE_RQST_PROG", >> + .code = 0xa5, >> + .desc = "PLE requests programmed" >> + }, >> + {.name = "CPU_CYCLES", >> + .code = 0xff, >> + .desc = "CPU cycles" >> + }, >> +}; >> + >> +#define ARM_CORTEX_A9_EVENT_COUNT >> (sizeof(arm_cortex_a9_pe)/sizeof(arm_entry_t)) >> diff -urpN libpfm4.stock/lib/Makefile libpfm4.vmw/lib/Makefile >> --- libpfm4.stock/lib/Makefile 2010-08-27 15:12:26.386017639 -0400 >> +++ libpfm4.vmw/lib/Makefile 2010-08-27 17:33:54.222017393 -0400 >> @@ -96,6 +96,12 @@ INCARCH = $(INC_SPARC) >> CFLAGS += -DCONFIG_PFMLIB_ARCH_SPARC >> endif >> >> +ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y) >> +INCARCH = $(INC_ARM) >> +SRCS += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c >> +CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM >> +endif >> + >> ifeq ($(CONFIG_PFMLIB_ARCH_CRAYXT),y) >> CFLAGS += -DCONFIG_PFMLIB_ARCH_CRAYXT >> endif >> >> diff -urpN libpfm4.stock/lib/pfmlib_arm_armv7_pmuv1.c >> libpfm4.vmw/lib/pfmlib_arm_armv7_pmuv1.c >> --- libpfm4.stock/lib/pfmlib_arm_armv7_pmuv1.c 1969-12-31 >> 19:00:00.000000000 -0500 >> +++ libpfm4.vmw/lib/pfmlib_arm_armv7_pmuv1.c 2010-08-27 >> 17:28:40.110016564 -0400 >> @@ -0,0 +1,117 @@ >> +/* >> + * pfmlib_arm.c : support for ARM chips >> + * >> + * Copyright (c) 2010 University of Tennessee >> + * Contributed by Vince Weaver <vweav...@utk.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_cortex_a8_events.h" /* event tables */ >> +#include "events/arm_cortex_a9_events.h" >> + >> +pfm_arm_config_t pfm_arm_cfg; >> + >> +int >> +pfm_arm_detect_cortex_a8(void *this) >> +{ >> + >> + int ret; >> + >> + ret=pfm_arm_detect(); >> + if (ret!=PFM_SUCCESS) return PFM_ERR_NOTSUPP; >> + >> + if ((pfm_arm_cfg.implementer==0x41) && /* ARM */ >> + (pfm_arm_cfg.part==0xc08)) { /* Cortex-A8 */ >> + return PFM_SUCCESS; >> + } >> + >> + return PFM_ERR_NOTSUPP; >> +} >> + >> +int >> +pfm_arm_detect_cortex_a9(void *this) >> +{ >> + >> + int ret; >> + >> + ret=pfm_arm_detect(); >> + if (ret!=PFM_SUCCESS) return PFM_ERR_NOTSUPP; >> + >> + if ((pfm_arm_cfg.implementer==0x41) && /* ARM */ >> + (pfm_arm_cfg.part==0xc09)) { /* Cortex-A8 */ >> + return PFM_SUCCESS; >> + } >> + >> + return PFM_ERR_NOTSUPP; >> +} >> + >> +/* Cortex A8 support */ >> +pfmlib_pmu_t arm_cortex_a8_support={ >> + .desc = "ARM Cortex A8", >> + .name = "ac8", >> + .pmu = PFM_PMU_ARM_CORTEX_A8, >> + .pme_count = ARM_CORTEX_A8_EVENT_COUNT, >> + .pe = arm_cortex_a8_pe, >> + >> + .pmu_detect = pfm_arm_detect_cortex_a8, >> + .max_encoding = 1, >> + >> + .get_event_encoding = pfm_arm_get_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, >> + .get_event_perf_type = pfm_arm_get_event_perf_type, >> + .validate_table = pfm_arm_validate_table, >> + .get_event_info = pfm_arm_get_event_info, >> + .get_event_attr_info = pfm_arm_get_event_attr_info, >> +}; >> + >> + >> + >> +/* Cortex A9 support */ >> +pfmlib_pmu_t arm_cortex_a9_support={ >> + .desc = "ARM Cortex A9", >> + .name = "ac9", >> + .pmu = PFM_PMU_ARM_CORTEX_A9, >> + .pme_count = ARM_CORTEX_A9_EVENT_COUNT, >> + .pe = arm_cortex_a9_pe, >> + >> + .pmu_detect = pfm_arm_detect_cortex_a9, >> + .max_encoding = 1, >> + >> + .get_event_encoding = pfm_arm_get_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, >> + .get_event_perf_type = pfm_arm_get_event_perf_type, >> + .validate_table = pfm_arm_validate_table, >> + .get_event_info = pfm_arm_get_event_info, >> + .get_event_attr_info = pfm_arm_get_event_attr_info, >> +}; >> + >> diff -urpN libpfm4.stock/lib/pfmlib_arm.c libpfm4.vmw/lib/pfmlib_arm.c >> --- libpfm4.stock/lib/pfmlib_arm.c 1969-12-31 19:00:00.000000000 -0500 >> +++ libpfm4.vmw/lib/pfmlib_arm.c 2010-08-27 17:33:34.454016763 -0400 >> @@ -0,0 +1,186 @@ >> +/* >> + * pfmlib_arm.c : support for ARM chips >> + * >> + * Copyright (c) 2010 University of Tennessee >> + * Contributed by Vince Weaver <vweav...@utk.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" >> + >> +pfm_arm_config_t pfm_arm_cfg; >> + >> +int >> +pfm_arm_detect(void) >> +{ >> + >> + int ret; >> + char buffer[128]; >> + >> + ret = pfmlib_getcpuinfo_attr("CPU implementer", buffer, >> sizeof(buffer)); >> + if (ret == -1) >> + return PFM_ERR_NOTSUPP; >> + >> + pfm_arm_cfg.implementer = strtol(buffer, NULL, 16); >> + >> + >> + ret = pfmlib_getcpuinfo_attr("CPU part", buffer, sizeof(buffer)); >> + if (ret == -1) >> + return PFM_ERR_NOTSUPP; >> + >> + pfm_arm_cfg.part = strtol(buffer, NULL, 16); >> + >> + ret = pfmlib_getcpuinfo_attr("CPU architecture", buffer, >> sizeof(buffer)); >> + if (ret == -1) >> + return PFM_ERR_NOTSUPP; >> + >> + pfm_arm_cfg.architecture = strtol(buffer, NULL, 16); >> + >> + return PFM_SUCCESS; >> +} >> + >> +int >> +pfm_arm_get_encoding(void *this, pfmlib_event_desc_t *e, uint64_t *codes, >> int *count, pfmlib_perf_attr_t *attrs) >> +{ >> + >> + const arm_entry_t *pe = this_pe(this); >> + pfm_arm_reg_t reg; >> + >> + reg.val = pe[e->event].code; >> + evt_strcat(e->fstr, "%s", pe[e->event].name); >> + >> + *codes = reg.val; >> + *count = 1; >> + >> + pfm_arm_display_reg(reg, e->fstr); >> + >> + return PFM_SUCCESS; >> +} >> + >> +int >> +pfm_arm_get_event_first(void *this) >> +{ >> + return 0; >> +} >> + >> +int >> +pfm_arm_get_event_next(void *this, int idx) >> +{ >> + pfmlib_pmu_t *p = this; >> + >> + if (idx >= (p->pme_count-1)) >> + return -1; >> + >> + return idx+1; >> +} >> + >> +int >> +pfm_arm_event_is_valid(void *this, int pidx) >> +{ >> + pfmlib_pmu_t *p = this; >> + return pidx >= 0 && pidx < p->pme_count; >> +} >> + >> +void >> +pfm_arm_display_reg(pfm_arm_reg_t reg, char *fstr) >> +{ >> + >> + /* >> + * handle generic counters >> + */ >> + __pfm_vbprintf("[0x%"PRIx64" ", >> + reg.val); >> + __pfm_vbprintf("] %s\n", fstr); >> + >> +} >> + >> +int >> +pfm_arm_get_event_perf_type(void *this, int pidx) >> +{ >> + return PERF_TYPE_RAW; >> +} >> + >> +int >> +pfm_arm_validate_table(void *this, FILE *fp) >> +{ >> + >> + pfmlib_pmu_t *pmu = this; >> + const arm_entry_t *pe = this_pe(this); >> + int i, error = 0; >> + >> + for(i=0; i < pmu->pme_count; i++) { >> + >> + if (!pe[i].name) { >> + fprintf(fp, "pmu: %s event%d: :: no name\n", >> pmu->name, i); >> + error++; >> + } >> + >> + if (!pe[i].desc) { >> + fprintf(fp, "pmu: %s event%d: %s :: no >> description\n", pmu->name, i, pe[i].name); >> + error++; >> + } >> + >> + } >> + >> + return error ? PFM_ERR_INVAL : PFM_SUCCESS; >> +} >> + >> +int >> +pfm_arm_get_event_attr_info(void *this, int pidx, int attr_idx, >> pfm_event_attr_info_t *info) >> +{ >> + >> + int numasks; >> + >> + numasks = 0; >> + >> + info->idx = attr_idx; >> + info->dfl_val64 = 0; >> + >> + return PFM_SUCCESS; >> +} >> + >> +int >> +pfm_arm_get_event_info(void *this, int idx, pfm_event_info_t *info) >> +{ >> + >> + const arm_entry_t *pe = this_pe(this); >> + >> + /* >> + * pmu and idx filled out by caller >> + */ >> + info->name = pe[idx].name; >> + info->desc = pe[idx].desc; >> + info->code = pe[idx].code; >> + info->equiv = pe[idx].equiv; >> + >> + /* unit masks + modifiers */ >> + info->nattrs = 0; >> + >> + return PFM_SUCCESS; >> +} >> + >> diff -urpN libpfm4.stock/lib/pfmlib_arm_priv.h >> libpfm4.vmw/lib/pfmlib_arm_priv.h >> --- libpfm4.stock/lib/pfmlib_arm_priv.h 1969-12-31 19:00:00.000000000 -0500 >> +++ libpfm4.vmw/lib/pfmlib_arm_priv.h 2010-08-27 17:34:40.850993990 -0400 >> @@ -0,0 +1,77 @@ >> +/* >> + * Copyright (c) 2010 University of Tennessee >> + * Contributed by Vince Weaver <vweav...@utk.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. >> + */ >> +#ifndef __PFMLIB_ARM_PRIV_H__ >> +#define __PFMLIB_ARM_PRIV_H__ >> + >> +/* >> + * This file contains the definitions used for ARM processors >> + */ >> + >> + >> +/* >> + * event description >> + */ >> +typedef struct { >> + const char *name; /* event name */ >> + const char *desc; /* event description */ >> + const char *equiv; /* name of event from which >> this one is derived, NULL if none */ >> + unsigned int code; /* event code */ >> +} arm_entry_t; >> + >> +typedef union pfm_arm_reg { >> + unsigned int val; /* complete register value */ >> + >> + struct { >> + unsigned int sel:8; /* counter */ >> + unsigned int reserved:24; >> + } evtsel; >> +} pfm_arm_reg_t; >> + >> +typedef struct { >> + int implementer; >> + int architecture; >> + int part; >> +} pfm_arm_config_t; >> + >> +extern pfm_arm_config_t pfm_arm_cfg; >> + >> +extern int pfm_arm_detect_cortex_a8(void *this); >> +extern int pfm_arm_detect_cortex_a9(void *this); >> +extern int pfm_arm_detect(); >> +extern void pfm_arm_display_reg(pfm_arm_reg_t reg, char *fstr); >> +extern int pfm_arm_add_defaults(void *this, int pidx, char *umask_str, >> unsigned int msk, unsigned int *umask); >> + >> +extern int pfm_arm_event_is_valid(void *this, int pidx); >> +extern int pfm_arm_get_encoding(void *this, pfmlib_event_desc_t *e, >> uint64_t *codes, int *count, pfmlib_perf_attr_t *attrs); >> +extern int pfm_arm_get_event_first(void *this); >> +extern int pfm_arm_get_event_next(void *this, int idx); >> +extern int pfm_arm_get_event_umask_first(void *this, int idx); >> +extern int pfm_arm_get_event_umask_next(void *this, int idx, int attr); >> +extern int pfm_arm_get_event_perf_type(void *this, int pidx); >> +extern int pfm_arm_validate_table(void *this, FILE *fp); >> +extern int pfm_arm_get_event_attr_info(void *this, int idx, int attr_idx, >> pfm_event_attr_info_t *info); >> +extern int pfm_arm_get_event_info(void *this, int idx, pfm_event_info_t >> *info); >> +extern int pfm_arm_attr2mod(void *this, int pidx, int attr_idx); >> +#endif /* __PFMLIB_ARM_PRIV_H__ */ >> diff -urpN libpfm4.stock/lib/pfmlib_common.c libpfm4.vmw/lib/pfmlib_common.c >> --- libpfm4.stock/lib/pfmlib_common.c 2010-08-27 15:12:30.689928686 -0400 >> +++ libpfm4.vmw/lib/pfmlib_common.c 2010-08-27 15:16:00.957951330 -0400 >> @@ -119,6 +119,11 @@ static pfmlib_pmu_t *pfmlib_pmus[]= >> &cell_support, >> #endif >> >> +#ifdef CONFIG_PFMLIB_ARCH_ARM >> + &arm_cortex_a8_support, >> + &arm_cortex_a9_support, >> +#endif >> + >> #ifdef __linux__ >> &perf_event_support, >> #endif >> >> diff -urpN libpfm4.stock/lib/pfmlib_priv.h libpfm4.vmw/lib/pfmlib_priv.h >> --- libpfm4.stock/lib/pfmlib_priv.h 2010-08-27 15:12:33.758024225 -0400 >> +++ libpfm4.vmw/lib/pfmlib_priv.h 2010-08-27 15:16:01.085929694 -0400 >> @@ -185,6 +185,8 @@ extern pfmlib_pmu_t cell_support; >> extern pfmlib_pmu_t perf_event_support; >> extern pfmlib_pmu_t intel_wsm_support; >> 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 char *pfmlib_forced_pmu; >> >> > ------------------------------------------------------------------------------ This SF.net Dev2Dev email is sponsored by: Show off your parallel programming skills. Enter the Intel(R) Threading Challenge 2010. http://p.sf.net/sfu/intel-thread-sfd _______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel