From owner-svn-src-head@FreeBSD.ORG Sat Apr 18 21:39:20 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 261C0B3C; Sat, 18 Apr 2015 21:39:20 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1253267E; Sat, 18 Apr 2015 21:39:20 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t3ILdKdZ093391; Sat, 18 Apr 2015 21:39:20 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t3ILdHjO093364; Sat, 18 Apr 2015 21:39:17 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201504182139.t3ILdHjO093364@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits Date: Sat, 18 Apr 2015 21:39:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281713 - in head: lib/libpmc sys/conf sys/dev/hwpmc sys/modules/hwpmc sys/powerpc/booke sys/powerpc/include X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Apr 2015 21:39:20 -0000 Author: jhibbits Date: Sat Apr 18 21:39:17 2015 New Revision: 281713 URL: https://svnweb.freebsd.org/changeset/base/281713 Log: Implement hwpmc(4) for Freescale e500 core. This supports e500v1, e500v2, and e500mc. Tested only on e500v2, but the performance counters are identical across all, with e500mc having some additional events. Relnotes: Yes Added: head/sys/dev/hwpmc/hwpmc_e500.c (contents, props changed) Modified: head/lib/libpmc/libpmc.c head/sys/conf/files.powerpc head/sys/dev/hwpmc/hwpmc_mpc7xxx.c head/sys/dev/hwpmc/hwpmc_powerpc.c head/sys/dev/hwpmc/hwpmc_powerpc.h head/sys/dev/hwpmc/hwpmc_ppc970.c head/sys/dev/hwpmc/pmc_events.h head/sys/modules/hwpmc/Makefile head/sys/powerpc/booke/interrupt.c head/sys/powerpc/booke/locore.S head/sys/powerpc/booke/machdep.c head/sys/powerpc/booke/trap_subr.S head/sys/powerpc/include/pmc_mdep.h Modified: head/lib/libpmc/libpmc.c ============================================================================== --- head/lib/libpmc/libpmc.c Sat Apr 18 21:35:41 2015 (r281712) +++ head/lib/libpmc/libpmc.c Sat Apr 18 21:39:17 2015 (r281713) @@ -164,6 +164,7 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON); PMC_CLASSDEP_TABLE(ucf, UCF); PMC_CLASSDEP_TABLE(ppc7450, PPC7450); PMC_CLASSDEP_TABLE(ppc970, PPC970); +PMC_CLASSDEP_TABLE(e500, E500); static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT]; @@ -296,8 +297,9 @@ PMC_MDEP_TABLE(armv7, ARMV7, PMC_CLASS_S PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K); PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); -PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); -PMC_MDEP_TABLE(ppc970, PPC970, PMC_CLASS_SOFT, PMC_CLASS_PPC970); +PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450, PMC_CLASS_TSC); +PMC_MDEP_TABLE(ppc970, PPC970, PMC_CLASS_SOFT, PMC_CLASS_PPC970, PMC_CLASS_TSC); +PMC_MDEP_TABLE(e500, E500, PMC_CLASS_SOFT, PMC_CLASS_E500, PMC_CLASS_TSC); PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT); static const struct pmc_event_descr tsc_event_table[] = @@ -368,6 +370,7 @@ PMC_CLASS_TABLE_DESC(octeon, OCTEON, oct #if defined(__powerpc__) PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, powerpc); PMC_CLASS_TABLE_DESC(ppc970, PPC970, ppc970, powerpc); +PMC_CLASS_TABLE_DESC(e500, E500, e500, powerpc); #endif static struct pmc_class_descr soft_class_table_descr = @@ -2494,6 +2497,12 @@ static struct pmc_event_alias ppc970_ali EV_ALIAS(NULL, NULL) }; +static struct pmc_event_alias e500_aliases[] = { + EV_ALIAS("instructions", "INSTR_COMPLETED"), + EV_ALIAS("cycles", "CYCLES"), + EV_ALIAS(NULL, NULL) +}; + #define POWERPC_KW_OS "os" #define POWERPC_KW_USR "usr" #define POWERPC_KW_ANYTHREAD "anythread" @@ -2949,6 +2958,10 @@ pmc_event_names_of_class(enum pmc_class ev = ppc970_event_table; count = PMC_EVENT_TABLE_SIZE(ppc970); break; + case PMC_CLASS_E500: + ev = e500_event_table; + count = PMC_EVENT_TABLE_SIZE(e500); + break; case PMC_CLASS_SOFT: ev = soft_event_table; count = soft_event_info.pm_nevent; @@ -3245,6 +3258,10 @@ pmc_init(void) PMC_MDEP_INIT(ppc970); pmc_class_table[n] = &ppc970_class_table_descr; break; + case PMC_CPU_PPC_E500: + PMC_MDEP_INIT(e500); + pmc_class_table[n] = &e500_class_table_descr; + break; #endif default: /* @@ -3444,6 +3461,9 @@ _pmc_name_of_event(enum pmc_event pe, en } else if (pe >= PMC_EV_PPC970_FIRST && pe <= PMC_EV_PPC970_LAST) { ev = ppc970_event_table; evfence = ppc970_event_table + PMC_EVENT_TABLE_SIZE(ppc970); + } else if (pe >= PMC_EV_E500_FIRST && pe <= PMC_EV_E500_LAST) { + ev = e500_event_table; + evfence = e500_event_table + PMC_EVENT_TABLE_SIZE(e500); } else if (pe == PMC_EV_TSC_TSC) { ev = tsc_event_table; evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc); Modified: head/sys/conf/files.powerpc ============================================================================== --- head/sys/conf/files.powerpc Sat Apr 18 21:35:41 2015 (r281712) +++ head/sys/conf/files.powerpc Sat Apr 18 21:39:17 2015 (r281713) @@ -31,8 +31,9 @@ dev/fb/fb.c optional sc dev/fdt/fdt_powerpc.c optional fdt # ofwbus depends on simplebus. dev/fdt/simplebus.c optional aim | fdt -dev/hwpmc/hwpmc_powerpc.c optional hwpmc +dev/hwpmc/hwpmc_e500.c optional hwpmc dev/hwpmc/hwpmc_mpc7xxx.c optional hwpmc +dev/hwpmc/hwpmc_powerpc.c optional hwpmc dev/hwpmc/hwpmc_ppc970.c optional hwpmc dev/iicbus/ad7417.c optional ad7417 powermac dev/iicbus/adm1030.c optional powermac windtunnel | adm1030 powermac Added: head/sys/dev/hwpmc/hwpmc_e500.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/hwpmc/hwpmc_e500.c Sat Apr 18 21:39:17 2015 (r281713) @@ -0,0 +1,660 @@ +/*- + * Copyright (c) 2015 Justin Hibbits + * Copyright (c) 2005, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +#include "hwpmc_powerpc.h" + +#define POWERPC_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | \ + PMC_CAP_SYSTEM | PMC_CAP_EDGE | \ + PMC_CAP_THRESHOLD | PMC_CAP_READ | \ + PMC_CAP_WRITE | PMC_CAP_INVERT | \ + PMC_CAP_QUALIFIER) + +#define E500_PMC_HAS_OVERFLOWED(x) (e500_pmcn_read(x) & (0x1 << 31)) + +struct e500_event_code_map { + enum pmc_event pe_ev; /* enum value */ + uint8_t pe_counter_mask; /* Which counter this can be counted in. */ + uint8_t pe_code; /* numeric code */ + uint8_t pe_cpu; /* e500 core (v1,v2,mc), mask */ +}; + +#define E500_MAX_PMCS 4 +#define PMC_PPC_MASK0 0 +#define PMC_PPC_MASK1 1 +#define PMC_PPC_MASK2 2 +#define PMC_PPC_MASK3 3 +#define PMC_PPC_MASK_ALL 0x0f +#define PMC_PPC_E500V1 1 +#define PMC_PPC_E500V2 2 +#define PMC_PPC_E500MC 4 +#define PMC_PPC_E500_ANY 7 +#define PMC_E500_EVENT(id, mask, number, core) \ + [PMC_EV_E500_##id - PMC_EV_E500_FIRST] = \ + { .pe_ev = PMC_EV_E500_##id, .pe_counter_mask = mask, \ + .pe_code = number, .pe_cpu = core } +#define PMC_E500MC_ONLY(id, number) \ + PMC_E500_EVENT(id, PMC_PPC_MASK_ALL, number, PMC_PPC_E500MC) +#define PMC_E500_COMMON(id, number) \ + PMC_E500_EVENT(id, PMC_PPC_MASK_ALL, number, PMC_PPC_E500_ANY) + +static struct e500_event_code_map e500_event_codes[] = { + PMC_E500_COMMON(CYCLES, 1), + PMC_E500_COMMON(INSTR_COMPLETED, 2), + PMC_E500_COMMON(UOPS_COMPLETED, 3), + PMC_E500_COMMON(INSTR_FETCHED, 4), + PMC_E500_COMMON(UOPS_DECODED, 5), + PMC_E500_COMMON(PM_EVENT_TRANSITIONS, 6), + PMC_E500_COMMON(PM_EVENT_CYCLES, 7), + PMC_E500_COMMON(BRANCH_INSTRS_COMPLETED, 8), + PMC_E500_COMMON(LOAD_UOPS_COMPLETED, 9), + PMC_E500_COMMON(STORE_UOPS_COMPLETED, 10), + PMC_E500_COMMON(CQ_REDIRECTS, 11), + PMC_E500_COMMON(BRANCHES_FINISHED, 12), + PMC_E500_COMMON(TAKEN_BRANCHES_FINISHED, 13), + PMC_E500_COMMON(FINISHED_UNCOND_BRANCHES_MISS_BTB, 14), + PMC_E500_COMMON(BRANCH_MISPRED, 15), + PMC_E500_COMMON(BTB_BRANCH_MISPRED_FROM_DIRECTION, 16), + PMC_E500_COMMON(BTB_HITS_PSEUDO_HITS, 17), + PMC_E500_COMMON(CYCLES_DECODE_STALLED, 18), + PMC_E500_COMMON(CYCLES_ISSUE_STALLED, 19), + PMC_E500_COMMON(CYCLES_BRANCH_ISSUE_STALLED, 20), + PMC_E500_COMMON(CYCLES_SU1_SCHED_STALLED, 21), + PMC_E500_COMMON(CYCLES_SU2_SCHED_STALLED, 22), + PMC_E500_COMMON(CYCLES_MU_SCHED_STALLED, 23), + PMC_E500_COMMON(CYCLES_LRU_SCHED_STALLED, 24), + PMC_E500_COMMON(CYCLES_BU_SCHED_STALLED, 25), + PMC_E500_COMMON(TOTAL_TRANSLATED, 26), + PMC_E500_COMMON(LOADS_TRANSLATED, 27), + PMC_E500_COMMON(STORES_TRANSLATED, 28), + PMC_E500_COMMON(TOUCHES_TRANSLATED, 29), + PMC_E500_COMMON(CACHEOPS_TRANSLATED, 30), + PMC_E500_COMMON(CACHE_INHIBITED_ACCESS_TRANSLATED, 31), + PMC_E500_COMMON(GUARDED_LOADS_TRANSLATED, 32), + PMC_E500_COMMON(WRITE_THROUGH_STORES_TRANSLATED, 33), + PMC_E500_COMMON(MISALIGNED_LOAD_STORE_ACCESS_TRANSLATED, 34), + PMC_E500_COMMON(TOTAL_ALLOCATED_TO_DLFB, 35), + PMC_E500_COMMON(LOADS_TRANSLATED_ALLOCATED_TO_DLFB, 36), + PMC_E500_COMMON(STORES_COMPLETED_ALLOCATED_TO_DLFB, 37), + PMC_E500_COMMON(TOUCHES_TRANSLATED_ALLOCATED_TO_DLFB, 38), + PMC_E500_COMMON(STORES_COMPLETED, 39), + PMC_E500_COMMON(DATA_L1_CACHE_LOCKS, 40), + PMC_E500_COMMON(DATA_L1_CACHE_RELOADS, 41), + PMC_E500_COMMON(DATA_L1_CACHE_CASTOUTS, 42), + PMC_E500_COMMON(LOAD_MISS_DLFB_FULL, 43), + PMC_E500_COMMON(LOAD_MISS_LDQ_FULL, 44), + PMC_E500_COMMON(LOAD_GUARDED_MISS, 45), + PMC_E500_COMMON(STORE_TRANSLATE_WHEN_QUEUE_FULL, 46), + PMC_E500_COMMON(ADDRESS_COLLISION, 47), + PMC_E500_COMMON(DATA_MMU_MISS, 48), + PMC_E500_COMMON(DATA_MMU_BUSY, 49), + PMC_E500_COMMON(PART2_MISALIGNED_CACHE_ACCESS, 50), + PMC_E500_COMMON(LOAD_MISS_DLFB_FULL_CYCLES, 51), + PMC_E500_COMMON(LOAD_MISS_LDQ_FULL_CYCLES, 52), + PMC_E500_COMMON(LOAD_GUARDED_MISS_CYCLES, 53), + PMC_E500_COMMON(STORE_TRANSLATE_WHEN_QUEUE_FULL_CYCLES, 54), + PMC_E500_COMMON(ADDRESS_COLLISION_CYCLES, 55), + PMC_E500_COMMON(DATA_MMU_MISS_CYCLES, 56), + PMC_E500_COMMON(DATA_MMU_BUSY_CYCLES, 57), + PMC_E500_COMMON(PART2_MISALIGNED_CACHE_ACCESS_CYCLES, 58), + PMC_E500_COMMON(INSTR_L1_CACHE_LOCKS, 59), + PMC_E500_COMMON(INSTR_L1_CACHE_RELOADS, 60), + PMC_E500_COMMON(INSTR_L1_CACHE_FETCHES, 61), + PMC_E500_COMMON(INSTR_MMU_TLB4K_RELOADS, 62), + PMC_E500_COMMON(INSTR_MMU_VSP_RELOADS, 63), + PMC_E500_COMMON(DATA_MMU_TLB4K_RELOADS, 64), + PMC_E500_COMMON(DATA_MMU_VSP_RELOADS, 65), + PMC_E500_COMMON(L2MMU_MISSES, 66), + PMC_E500_COMMON(BIU_MASTER_REQUESTS, 67), + PMC_E500_COMMON(BIU_MASTER_INSTR_SIDE_REQUESTS, 68), + PMC_E500_COMMON(BIU_MASTER_DATA_SIDE_REQUESTS, 69), + PMC_E500_COMMON(BIU_MASTER_DATA_SIDE_CASTOUT_REQUESTS, 70), + PMC_E500_COMMON(BIU_MASTER_RETRIES, 71), + PMC_E500_COMMON(SNOOP_REQUESTS, 72), + PMC_E500_COMMON(SNOOP_HITS, 73), + PMC_E500_COMMON(SNOOP_PUSHES, 74), + PMC_E500_COMMON(SNOOP_RETRIES, 75), + PMC_E500_EVENT(DLFB_LOAD_MISS_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1, + 76, PMC_PPC_E500_ANY), + PMC_E500_EVENT(ILFB_FETCH_MISS_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1, + 77, PMC_PPC_E500_ANY), + PMC_E500_EVENT(EXT_INPU_INTR_LATENCY_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1, + 78, PMC_PPC_E500_ANY), + PMC_E500_EVENT(CRIT_INPUT_INTR_LATENCY_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1, + 79, PMC_PPC_E500_ANY), + PMC_E500_EVENT(EXT_INPUT_INTR_PENDING_LATENCY_CYCLES, + PMC_PPC_MASK0|PMC_PPC_MASK1, 80, PMC_PPC_E500_ANY), + PMC_E500_EVENT(CRIT_INPUT_INTR_PENDING_LATENCY_CYCLES, + PMC_PPC_MASK0|PMC_PPC_MASK1, 81, PMC_PPC_E500_ANY), + PMC_E500_COMMON(PMC0_OVERFLOW, 82), + PMC_E500_COMMON(PMC1_OVERFLOW, 83), + PMC_E500_COMMON(PMC2_OVERFLOW, 84), + PMC_E500_COMMON(PMC3_OVERFLOW, 85), + PMC_E500_COMMON(INTERRUPTS_TAKEN, 86), + PMC_E500_COMMON(EXT_INPUT_INTR_TAKEN, 87), + PMC_E500_COMMON(CRIT_INPUT_INTR_TAKEN, 88), + PMC_E500_COMMON(SYSCALL_TRAP_INTR, 89), + PMC_E500_EVENT(TLB_BIT_TRANSITIONS, PMC_PPC_MASK_ALL, 90, + PMC_PPC_E500V2 | PMC_PPC_E500MC), + PMC_E500MC_ONLY(L2_LINEFILL_BUFFER, 91), + PMC_E500MC_ONLY(LV2_VS, 92), + PMC_E500MC_ONLY(CASTOUTS_RELEASED, 93), + PMC_E500MC_ONLY(INTV_ALLOCATIONS, 94), + PMC_E500MC_ONLY(DLFB_RETRIES_TO_MBAR, 95), + PMC_E500MC_ONLY(STORE_RETRIES, 96), + PMC_E500MC_ONLY(STASH_L1_HITS, 97), + PMC_E500MC_ONLY(STASH_L2_HITS, 98), + PMC_E500MC_ONLY(STASH_BUSY_1, 99), + PMC_E500MC_ONLY(STASH_BUSY_2, 100), + PMC_E500MC_ONLY(STASH_BUSY_3, 101), + PMC_E500MC_ONLY(STASH_HITS, 102), + PMC_E500MC_ONLY(STASH_HIT_DLFB, 103), + PMC_E500MC_ONLY(STASH_REQUESTS, 106), + PMC_E500MC_ONLY(STASH_REQUESTS_L1, 107), + PMC_E500MC_ONLY(STASH_REQUESTS_L2, 108), + PMC_E500MC_ONLY(STALLS_NO_CAQ_OR_COB, 109), + PMC_E500MC_ONLY(L2_CACHE_ACCESSES, 110), + PMC_E500MC_ONLY(L2_HIT_CACHE_ACCESSES, 111), + PMC_E500MC_ONLY(L2_CACHE_DATA_ACCESSES, 112), + PMC_E500MC_ONLY(L2_CACHE_DATA_HITS, 113), + PMC_E500MC_ONLY(L2_CACHE_INSTR_ACCESSES, 114), + PMC_E500MC_ONLY(L2_CACHE_INSTR_HITS, 115), + PMC_E500MC_ONLY(L2_CACHE_ALLOCATIONS, 116), + PMC_E500MC_ONLY(L2_CACHE_DATA_ALLOCATIONS, 117), + PMC_E500MC_ONLY(L2_CACHE_DIRTY_DATA_ALLOCATIONS, 118), + PMC_E500MC_ONLY(L2_CACHE_INSTR_ALLOCATIONS, 119), + PMC_E500MC_ONLY(L2_CACHE_UPDATES, 120), + PMC_E500MC_ONLY(L2_CACHE_CLEAN_UPDATES, 121), + PMC_E500MC_ONLY(L2_CACHE_DIRTY_UPDATES, 122), + PMC_E500MC_ONLY(L2_CACHE_CLEAN_REDUNDANT_UPDATES, 123), + PMC_E500MC_ONLY(L2_CACHE_DIRTY_REDUNDANT_UPDATES, 124), + PMC_E500MC_ONLY(L2_CACHE_LOCKS, 125), + PMC_E500MC_ONLY(L2_CACHE_CASTOUTS, 126), + PMC_E500MC_ONLY(L2_CACHE_DATA_DIRTY_HITS, 127), + PMC_E500MC_ONLY(INSTR_LFB_WENT_HIGH_PRIORITY, 128), + PMC_E500MC_ONLY(SNOOP_THROTTLING_TURNED_ON, 129), + PMC_E500MC_ONLY(L2_CLEAN_LINE_INVALIDATIONS, 130), + PMC_E500MC_ONLY(L2_INCOHERENT_LINE_INVALIDATIONS, 131), + PMC_E500MC_ONLY(L2_COHERENT_LINE_INVALIDATIONS, 132), + PMC_E500MC_ONLY(COHERENT_LOOKUP_MISS_DUE_TO_VALID_BUT_INCOHERENT_MATCHES, 133), + PMC_E500MC_ONLY(IAC1S_DETECTED, 140), + PMC_E500MC_ONLY(IAC2S_DETECTED, 141), + PMC_E500MC_ONLY(DAC1S_DTECTED, 144), + PMC_E500MC_ONLY(DAC2S_DTECTED, 145), + PMC_E500MC_ONLY(DVT0_DETECTED, 148), + PMC_E500MC_ONLY(DVT1_DETECTED, 149), + PMC_E500MC_ONLY(DVT2_DETECTED, 150), + PMC_E500MC_ONLY(DVT3_DETECTED, 151), + PMC_E500MC_ONLY(DVT4_DETECTED, 152), + PMC_E500MC_ONLY(DVT5_DETECTED, 153), + PMC_E500MC_ONLY(DVT6_DETECTED, 154), + PMC_E500MC_ONLY(DVT7_DETECTED, 155), + PMC_E500MC_ONLY(CYCLES_COMPLETION_STALLED_NEXUS_FIFO_FULL, 156), + PMC_E500MC_ONLY(FPU_DOUBLE_PUMP, 160), + PMC_E500MC_ONLY(FPU_FINISH, 161), + PMC_E500MC_ONLY(FPU_DIVIDE_CYCLES, 162), + PMC_E500MC_ONLY(FPU_DENORM_INPUT_CYCLES, 163), + PMC_E500MC_ONLY(FPU_RESULT_STALL_CYCLES, 164), + PMC_E500MC_ONLY(FPU_FPSCR_FULL_STALL, 165), + PMC_E500MC_ONLY(FPU_PIPE_SYNC_STALLS, 166), + PMC_E500MC_ONLY(FPU_INPUT_DATA_STALLS, 167), + PMC_E500MC_ONLY(DECORATED_LOADS, 176), + PMC_E500MC_ONLY(DECORATED_STORES, 177), + PMC_E500MC_ONLY(LOAD_RETRIES, 178), + PMC_E500MC_ONLY(STWCX_SUCCESSES, 179), + PMC_E500MC_ONLY(STWCX_FAILURES, 180), +}; + +const size_t e500_event_codes_size = + sizeof(e500_event_codes) / sizeof(e500_event_codes[0]); + +static pmc_value_t +e500_pmcn_read(unsigned int pmc) +{ + switch (pmc) { + case 0: + return mfpmr(PMR_PMC0); + break; + case 1: + return mfpmr(PMR_PMC1); + break; + case 2: + return mfpmr(PMR_PMC2); + break; + case 3: + return mfpmr(PMR_PMC3); + break; + default: + panic("Invalid PMC number: %d\n", pmc); + } +} + +static void +e500_pmcn_write(unsigned int pmc, uint32_t val) +{ + switch (pmc) { + case 0: + mtpmr(PMR_PMC0, val); + break; + case 1: + mtpmr(PMR_PMC1, val); + break; + case 2: + mtpmr(PMR_PMC2, val); + break; + case 3: + mtpmr(PMR_PMC3, val); + break; + default: + panic("Invalid PMC number: %d\n", pmc); + } +} + +static int +e500_read_pmc(int cpu, int ri, pmc_value_t *v) +{ + struct pmc *pm; + pmc_value_t tmp; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < E500_MAX_PMCS, + ("[powerpc,%d] illegal row index %d", __LINE__, ri)); + + pm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; + KASSERT(pm, + ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, + ri)); + + tmp = e500_pmcn_read(ri); + PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); + if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) + *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); + else + *v = tmp; + + return 0; +} + +static int +e500_write_pmc(int cpu, int ri, pmc_value_t v) +{ + struct pmc *pm; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < E500_MAX_PMCS, + ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); + + pm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; + + if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) + v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v); + + PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); + + e500_pmcn_write(ri, v); + + return 0; +} + +static int +e500_config_pmc(int cpu, int ri, struct pmc *pm) +{ + struct pmc_hw *phw; + + PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < E500_MAX_PMCS, + ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + + KASSERT(pm == NULL || phw->phw_pmc == NULL, + ("[powerpc,%d] pm=%p phw->pm=%p hwpmc not unconfigured", + __LINE__, pm, phw->phw_pmc)); + + phw->phw_pmc = pm; + + return 0; +} + +static int +e500_start_pmc(int cpu, int ri) +{ + uint32_t config; + struct pmc *pm; + struct pmc_hw *phw; + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + pm = phw->phw_pmc; + config = pm->pm_md.pm_powerpc.pm_powerpc_evsel; + + if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) + config |= PMLCax_CE; + + /* Enable the PMC. */ + switch (ri) { + case 0: + mtpmr(PMR_PMLCa0, config); + break; + case 1: + mtpmr(PMR_PMLCa1, config); + break; + case 2: + mtpmr(PMR_PMLCa2, config); + break; + case 3: + mtpmr(PMR_PMLCa3, config); + break; + default: + break; + } + + return 0; +} + +static int +e500_stop_pmc(int cpu, int ri) +{ + struct pmc *pm; + struct pmc_hw *phw; + register_t pmc_pmlc; + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + pm = phw->phw_pmc; + + /* + * Disable the PMCs. + */ + switch (ri) { + case 0: + pmc_pmlc = mfpmr(PMR_PMLCa0); + pmc_pmlc |= PMLCax_FC; + mtpmr(PMR_PMLCa0, pmc_pmlc); + break; + case 1: + pmc_pmlc = mfpmr(PMR_PMLCa1); + pmc_pmlc |= PMLCax_FC; + mtpmr(PMR_PMLCa1, pmc_pmlc); + break; + case 2: + pmc_pmlc = mfpmr(PMR_PMLCa2); + pmc_pmlc |= PMLCax_FC; + mtpmr(PMR_PMLCa2, pmc_pmlc); + break; + case 3: + pmc_pmlc = mfpmr(PMR_PMLCa3); + pmc_pmlc |= PMLCax_FC; + mtpmr(PMR_PMLCa3, pmc_pmlc); + break; + default: + break; + } + return 0; +} + +static int +e500_pcpu_init(struct pmc_mdep *md, int cpu) +{ + int first_ri, i; + struct pmc_cpu *pc; + struct powerpc_cpu *pac; + struct pmc_hw *phw; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu)); + PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu); + + /* Freeze all counters. */ + mtpmr(PMR_PMGC0, PMGC_FAC | PMGC_PMIE | PMGC_FCECE); + + powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC, + M_WAITOK|M_ZERO); + pac->pc_ppcpmcs = malloc(sizeof(struct pmc_hw) * E500_MAX_PMCS, + M_PMC, M_WAITOK|M_ZERO); + pac->pc_class = PMC_CLASS_E500; + pc = pmc_pcpu[cpu]; + first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC].pcd_ri; + KASSERT(pc != NULL, ("[powerpc,%d] NULL per-cpu pointer", __LINE__)); + + for (i = 0, phw = pac->pc_ppcpmcs; i < E500_MAX_PMCS; i++, phw++) { + phw->phw_state = PMC_PHW_FLAG_IS_ENABLED | + PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i); + phw->phw_pmc = NULL; + pc->pc_hwpmcs[i + first_ri] = phw; + + /* Initialize the PMC to stopped */ + e500_stop_pmc(cpu, i); + } + /* Unfreeze global register. */ + mtpmr(PMR_PMGC0, PMGC_PMIE | PMGC_FCECE); + + return 0; +} + +static int +e500_pcpu_fini(struct pmc_mdep *md, int cpu) +{ + uint32_t pmgc0 = mfpmr(PMR_PMGC0); + + pmgc0 |= PMGC_FAC; + mtpmr(PMR_PMGC0, pmgc0); + mtmsr(mfmsr() & ~PSL_PMM); + + free(powerpc_pcpu[cpu]->pc_ppcpmcs, M_PMC); + free(powerpc_pcpu[cpu], M_PMC); + + return 0; +} + +static int +e500_allocate_pmc(int cpu, int ri, struct pmc *pm, + const struct pmc_op_pmcallocate *a) +{ + enum pmc_event pe; + uint32_t caps, config, counter; + struct e500_event_code_map *ev; + uint16_t vers; + uint8_t pe_cpu_mask; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < E500_MAX_PMCS, + ("[powerpc,%d] illegal row index %d", __LINE__, ri)); + + caps = a->pm_caps; + + pe = a->pm_ev; + config = PMLCax_FCS | PMLCax_FCU | + PMLCax_FCM1 | PMLCax_FCM1; + if (pe < PMC_EV_E500_FIRST || pe > PMC_EV_E500_LAST) + return (EINVAL); + + ev = &e500_event_codes[pe-PMC_EV_E500_FIRST]; + if (ev->pe_code == 0) + return (EINVAL); + + vers = mfpvr() >> 16; + switch (vers) { + case FSL_E500v1: + pe_cpu_mask = ev->pe_code & PMC_PPC_E500V1; + break; + case FSL_E500v2: + pe_cpu_mask = ev->pe_code & PMC_PPC_E500V2; + break; + case FSL_E500mc: + pe_cpu_mask = ev->pe_code & PMC_PPC_E500MC; + break; + } + if (pe_cpu_mask == 0) + return (EINVAL); + + config |= PMLCax_EVENT(ev->pe_code); + counter = ev->pe_counter_mask; + if ((counter & (1 << ri)) == 0) + return (EINVAL); + + if (caps & PMC_CAP_SYSTEM) + config &= ~PMLCax_FCS; + if (caps & PMC_CAP_USER) + config &= ~PMLCax_FCU; + if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0) + config &= ~(PMLCax_FCS|PMLCax_FCU); + + pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; + + PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); + + return 0; +} + +static int +e500_release_pmc(int cpu, int ri, struct pmc *pmc) +{ + struct pmc_hw *phw; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < E500_MAX_PMCS, + ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + KASSERT(phw->phw_pmc == NULL, + ("[powerpc,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc)); + + return 0; +} + +static int +e500_intr(int cpu, struct trapframe *tf) +{ + int i, error, retval; + uint32_t config; + struct pmc *pm; + struct powerpc_cpu *pac; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] out of range CPU %d", __LINE__, cpu)); + + PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, + TRAPF_USERMODE(tf)); + + retval = 0; + + pac = powerpc_pcpu[cpu]; + + config = mfpmr(PMR_PMGC0) & ~PMGC_FAC; + + /* + * look for all PMCs that have interrupted: + * - look for a running, sampling PMC which has overflowed + * and which has a valid 'struct pmc' association + * + * If found, we call a helper to process the interrupt. + */ + + for (i = 0; i < E500_MAX_PMCS; i++) { + if ((pm = pac->pc_ppcpmcs[i].phw_pmc) == NULL || + !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { + continue; + } + + if (!E500_PMC_HAS_OVERFLOWED(i)) + continue; + + retval = 1; /* Found an interrupting PMC. */ + + if (pm->pm_state != PMC_STATE_RUNNING) + continue; + + /* Stop the counter if logging fails. */ + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, + TRAPF_USERMODE(tf)); + if (error != 0) + e500_stop_pmc(cpu, i); + + /* reload count. */ + e500_write_pmc(cpu, i, pm->pm_sc.pm_reloadcount); + } + + atomic_add_int(retval ? &pmc_stats.pm_intr_processed : + &pmc_stats.pm_intr_ignored, 1); + + /* Re-enable PERF exceptions. */ + if (retval) + mtpmr(PMR_PMGC0, config | PMGC_PMIE); + + return (retval); +} + +int +pmc_e500_initialize(struct pmc_mdep *pmc_mdep) +{ + struct pmc_classdep *pcd; + + pmc_mdep->pmd_cputype = PMC_CPU_PPC_E500; + + pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC]; + pcd->pcd_caps = POWERPC_PMC_CAPS; + pcd->pcd_class = PMC_CLASS_E500; + pcd->pcd_num = E500_MAX_PMCS; + pcd->pcd_ri = pmc_mdep->pmd_npmc; + pcd->pcd_width = 32; + + pcd->pcd_allocate_pmc = e500_allocate_pmc; + pcd->pcd_config_pmc = e500_config_pmc; + pcd->pcd_pcpu_fini = e500_pcpu_fini; + pcd->pcd_pcpu_init = e500_pcpu_init; + pcd->pcd_describe = powerpc_describe; + pcd->pcd_get_config = powerpc_get_config; + pcd->pcd_read_pmc = e500_read_pmc; + pcd->pcd_release_pmc = e500_release_pmc; + pcd->pcd_start_pmc = e500_start_pmc; + pcd->pcd_stop_pmc = e500_stop_pmc; + pcd->pcd_write_pmc = e500_write_pmc; + + pmc_mdep->pmd_npmc += E500_MAX_PMCS; + pmc_mdep->pmd_intr = e500_intr; + + return (0); +} Modified: head/sys/dev/hwpmc/hwpmc_mpc7xxx.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_mpc7xxx.c Sat Apr 18 21:35:41 2015 (r281712) +++ head/sys/dev/hwpmc/hwpmc_mpc7xxx.c Sat Apr 18 21:39:17 2015 (r281713) @@ -567,7 +567,7 @@ mpc7xxx_pcpu_init(struct pmc_mdep *md, i M_PMC, M_WAITOK|M_ZERO); pac->pc_class = PMC_CLASS_PPC7450; pc = pmc_pcpu[cpu]; - first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC7450].pcd_ri; + first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC].pcd_ri; KASSERT(pc != NULL, ("[powerpc,%d] NULL per-cpu pointer", __LINE__)); for (i = 0, phw = pac->pc_ppcpmcs; i < MPC7XXX_MAX_PMCS; i++, phw++) { @@ -729,7 +729,7 @@ pmc_mpc7xxx_initialize(struct pmc_mdep * pmc_mdep->pmd_cputype = PMC_CPU_PPC_7450; - pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC7450]; + pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC]; pcd->pcd_caps = POWERPC_PMC_CAPS; pcd->pcd_class = PMC_CLASS_PPC7450; pcd->pcd_num = MPC7XXX_MAX_PMCS; Modified: head/sys/dev/hwpmc/hwpmc_powerpc.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_powerpc.c Sat Apr 18 21:35:41 2015 (r281712) +++ head/sys/dev/hwpmc/hwpmc_powerpc.c Sat Apr 18 21:39:17 2015 (r281713) @@ -175,6 +175,11 @@ pmc_md_initialize() case IBM970MP: error = pmc_ppc970_initialize(pmc_mdep); break; + case FSL_E500v1: + case FSL_E500v2: + case FSL_E500mc: + error = pmc_e500_initialize(pmc_mdep); + break; default: error = -1; break; Modified: head/sys/dev/hwpmc/hwpmc_powerpc.h ============================================================================== --- head/sys/dev/hwpmc/hwpmc_powerpc.h Sat Apr 18 21:35:41 2015 (r281712) +++ head/sys/dev/hwpmc/hwpmc_powerpc.h Sat Apr 18 21:39:17 2015 (r281713) @@ -51,6 +51,7 @@ struct powerpc_cpu { extern struct powerpc_cpu **powerpc_pcpu; +extern int pmc_e500_initialize(struct pmc_mdep *pmc_mdep); extern int pmc_mpc7xxx_initialize(struct pmc_mdep *pmc_mdep); extern int pmc_ppc970_initialize(struct pmc_mdep *pmc_mdep); Modified: head/sys/dev/hwpmc/hwpmc_ppc970.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_ppc970.c Sat Apr 18 21:35:41 2015 (r281712) +++ head/sys/dev/hwpmc/hwpmc_ppc970.c Sat Apr 18 21:39:17 2015 (r281713) @@ -555,7 +555,7 @@ ppc970_pcpu_init(struct pmc_mdep *md, in pac->pc_class = PMC_CLASS_PPC970; pc = pmc_pcpu[cpu]; - first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC970].pcd_ri; + first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC].pcd_ri; KASSERT(pc != NULL, ("[powerpc,%d] NULL per-cpu pointer", __LINE__)); for (i = 0, phw = pac->pc_ppcpmcs; i < PPC970_MAX_PMCS; i++, phw++) { @@ -661,7 +661,7 @@ pmc_ppc970_initialize(struct pmc_mdep *p pmc_mdep->pmd_cputype = PMC_CPU_PPC_970; - pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC970]; + pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC]; pcd->pcd_caps = POWERPC_PMC_CAPS; pcd->pcd_class = PMC_CLASS_PPC970; pcd->pcd_num = PPC970_MAX_PMCS; Modified: head/sys/dev/hwpmc/pmc_events.h ============================================================================== --- head/sys/dev/hwpmc/pmc_events.h Sat Apr 18 21:35:41 2015 (r281712) +++ head/sys/dev/hwpmc/pmc_events.h Sat Apr 18 21:39:17 2015 (r281713) @@ -5379,6 +5379,168 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL #define PMC_EV_PPC970_FIRST PMC_EV_PPC970_INSTR_COMPLETED #define PMC_EV_PPC970_LAST PMC_EV_PPC970_ADDER + +#define __PMC_EV_E500() \ + __PMC_EV(E500, CYCLES) \ + __PMC_EV(E500, INSTR_COMPLETED) \ + __PMC_EV(E500, UOPS_COMPLETED) \ + __PMC_EV(E500, INSTR_FETCHED) \ + __PMC_EV(E500, UOPS_DECODED) \ + __PMC_EV(E500, PM_EVENT_TRANSITIONS) \ + __PMC_EV(E500, PM_EVENT_CYCLES) \ + __PMC_EV(E500, BRANCH_INSTRS_COMPLETED) \ + __PMC_EV(E500, LOAD_UOPS_COMPLETED) \ + __PMC_EV(E500, STORE_UOPS_COMPLETED) \ + __PMC_EV(E500, CQ_REDIRECTS) \ + __PMC_EV(E500, BRANCHES_FINISHED) \ + __PMC_EV(E500, TAKEN_BRANCHES_FINISHED) \ + __PMC_EV(E500, FINISHED_UNCOND_BRANCHES_MISS_BTB) \ + __PMC_EV(E500, BRANCH_MISPRED) \ + __PMC_EV(E500, BTB_BRANCH_MISPRED_FROM_DIRECTION) \ + __PMC_EV(E500, BTB_HITS_PSEUDO_HITS) \ + __PMC_EV(E500, CYCLES_DECODE_STALLED) \ + __PMC_EV(E500, CYCLES_ISSUE_STALLED) \ + __PMC_EV(E500, CYCLES_BRANCH_ISSUE_STALLED) \ + __PMC_EV(E500, CYCLES_SU1_SCHED_STALLED) \ + __PMC_EV(E500, CYCLES_SU2_SCHED_STALLED) \ + __PMC_EV(E500, CYCLES_MU_SCHED_STALLED) \ + __PMC_EV(E500, CYCLES_LRU_SCHED_STALLED) \ + __PMC_EV(E500, CYCLES_BU_SCHED_STALLED) \ + __PMC_EV(E500, TOTAL_TRANSLATED) \ + __PMC_EV(E500, LOADS_TRANSLATED) \ + __PMC_EV(E500, STORES_TRANSLATED) \ + __PMC_EV(E500, TOUCHES_TRANSLATED) \ + __PMC_EV(E500, CACHEOPS_TRANSLATED) \ + __PMC_EV(E500, CACHE_INHIBITED_ACCESS_TRANSLATED) \ + __PMC_EV(E500, GUARDED_LOADS_TRANSLATED) \ + __PMC_EV(E500, WRITE_THROUGH_STORES_TRANSLATED) \ + __PMC_EV(E500, MISALIGNED_LOAD_STORE_ACCESS_TRANSLATED) \ + __PMC_EV(E500, TOTAL_ALLOCATED_TO_DLFB) \ + __PMC_EV(E500, LOADS_TRANSLATED_ALLOCATED_TO_DLFB) \ + __PMC_EV(E500, STORES_COMPLETED_ALLOCATED_TO_DLFB) \ + __PMC_EV(E500, TOUCHES_TRANSLATED_ALLOCATED_TO_DLFB) \ + __PMC_EV(E500, STORES_COMPLETED) \ + __PMC_EV(E500, DATA_L1_CACHE_LOCKS) \ + __PMC_EV(E500, DATA_L1_CACHE_RELOADS) \ + __PMC_EV(E500, DATA_L1_CACHE_CASTOUTS) \ + __PMC_EV(E500, LOAD_MISS_DLFB_FULL) \ + __PMC_EV(E500, LOAD_MISS_LDQ_FULL) \ + __PMC_EV(E500, LOAD_GUARDED_MISS) \ + __PMC_EV(E500, STORE_TRANSLATE_WHEN_QUEUE_FULL) \ + __PMC_EV(E500, ADDRESS_COLLISION) \ + __PMC_EV(E500, DATA_MMU_MISS) \ + __PMC_EV(E500, DATA_MMU_BUSY) \ + __PMC_EV(E500, PART2_MISALIGNED_CACHE_ACCESS) \ + __PMC_EV(E500, LOAD_MISS_DLFB_FULL_CYCLES) \ + __PMC_EV(E500, LOAD_MISS_LDQ_FULL_CYCLES) \ + __PMC_EV(E500, LOAD_GUARDED_MISS_CYCLES) \ + __PMC_EV(E500, STORE_TRANSLATE_WHEN_QUEUE_FULL_CYCLES) \ + __PMC_EV(E500, ADDRESS_COLLISION_CYCLES) \ + __PMC_EV(E500, DATA_MMU_MISS_CYCLES) \ + __PMC_EV(E500, DATA_MMU_BUSY_CYCLES) \ + __PMC_EV(E500, PART2_MISALIGNED_CACHE_ACCESS_CYCLES) \ + __PMC_EV(E500, INSTR_L1_CACHE_LOCKS) \ + __PMC_EV(E500, INSTR_L1_CACHE_RELOADS) \ + __PMC_EV(E500, INSTR_L1_CACHE_FETCHES) \ + __PMC_EV(E500, INSTR_MMU_TLB4K_RELOADS) \ + __PMC_EV(E500, INSTR_MMU_VSP_RELOADS) \ + __PMC_EV(E500, DATA_MMU_TLB4K_RELOADS) \ + __PMC_EV(E500, DATA_MMU_VSP_RELOADS) \ + __PMC_EV(E500, L2MMU_MISSES) \ + __PMC_EV(E500, BIU_MASTER_REQUESTS) \ + __PMC_EV(E500, BIU_MASTER_INSTR_SIDE_REQUESTS) \ + __PMC_EV(E500, BIU_MASTER_DATA_SIDE_REQUESTS) \ + __PMC_EV(E500, BIU_MASTER_DATA_SIDE_CASTOUT_REQUESTS) \ + __PMC_EV(E500, BIU_MASTER_RETRIES) \ + __PMC_EV(E500, SNOOP_REQUESTS) \ + __PMC_EV(E500, SNOOP_HITS) \ + __PMC_EV(E500, SNOOP_PUSHES) \ + __PMC_EV(E500, SNOOP_RETRIES) \ + __PMC_EV(E500, DLFB_LOAD_MISS_CYCLES) \ + __PMC_EV(E500, ILFB_FETCH_MISS_CYCLES) \ + __PMC_EV(E500, EXT_INPU_INTR_LATENCY_CYCLES) \ + __PMC_EV(E500, CRIT_INPUT_INTR_LATENCY_CYCLES) \ + __PMC_EV(E500, EXT_INPUT_INTR_PENDING_LATENCY_CYCLES) \ + __PMC_EV(E500, CRIT_INPUT_INTR_PENDING_LATENCY_CYCLES) \ + __PMC_EV(E500, PMC0_OVERFLOW) \ + __PMC_EV(E500, PMC1_OVERFLOW) \ + __PMC_EV(E500, PMC2_OVERFLOW) \ + __PMC_EV(E500, PMC3_OVERFLOW) \ + __PMC_EV(E500, INTERRUPTS_TAKEN) \ + __PMC_EV(E500, EXT_INPUT_INTR_TAKEN) \ + __PMC_EV(E500, CRIT_INPUT_INTR_TAKEN) \ + __PMC_EV(E500, SYSCALL_TRAP_INTR) \ + __PMC_EV(E500, TLB_BIT_TRANSITIONS) \ + __PMC_EV(E500, L2_LINEFILL_BUFFER) \ + __PMC_EV(E500, LV2_VS) \ + __PMC_EV(E500, CASTOUTS_RELEASED) \ + __PMC_EV(E500, INTV_ALLOCATIONS) \ + __PMC_EV(E500, DLFB_RETRIES_TO_MBAR) \ + __PMC_EV(E500, STORE_RETRIES) \ + __PMC_EV(E500, STASH_L1_HITS) \ + __PMC_EV(E500, STASH_L2_HITS) \ + __PMC_EV(E500, STASH_BUSY_1) \ + __PMC_EV(E500, STASH_BUSY_2) \ + __PMC_EV(E500, STASH_BUSY_3) \ + __PMC_EV(E500, STASH_HITS) \ + __PMC_EV(E500, STASH_HIT_DLFB) \ + __PMC_EV(E500, STASH_REQUESTS) \ + __PMC_EV(E500, STASH_REQUESTS_L1) \ + __PMC_EV(E500, STASH_REQUESTS_L2) \ + __PMC_EV(E500, STALLS_NO_CAQ_OR_COB) \ + __PMC_EV(E500, L2_CACHE_ACCESSES) \ + __PMC_EV(E500, L2_HIT_CACHE_ACCESSES) \ + __PMC_EV(E500, L2_CACHE_DATA_ACCESSES) \ + __PMC_EV(E500, L2_CACHE_DATA_HITS) \ + __PMC_EV(E500, L2_CACHE_INSTR_ACCESSES) \ + __PMC_EV(E500, L2_CACHE_INSTR_HITS) \ + __PMC_EV(E500, L2_CACHE_ALLOCATIONS) \ + __PMC_EV(E500, L2_CACHE_DATA_ALLOCATIONS) \ + __PMC_EV(E500, L2_CACHE_DIRTY_DATA_ALLOCATIONS) \ + __PMC_EV(E500, L2_CACHE_INSTR_ALLOCATIONS) \ + __PMC_EV(E500, L2_CACHE_UPDATES) \ + __PMC_EV(E500, L2_CACHE_CLEAN_UPDATES) \ + __PMC_EV(E500, L2_CACHE_DIRTY_UPDATES) \ + __PMC_EV(E500, L2_CACHE_CLEAN_REDUNDANT_UPDATES) \ + __PMC_EV(E500, L2_CACHE_DIRTY_REDUNDANT_UPDATES) \ + __PMC_EV(E500, L2_CACHE_LOCKS) \ + __PMC_EV(E500, L2_CACHE_CASTOUTS) \ + __PMC_EV(E500, L2_CACHE_DATA_DIRTY_HITS) \ + __PMC_EV(E500, INSTR_LFB_WENT_HIGH_PRIORITY) \ + __PMC_EV(E500, SNOOP_THROTTLING_TURNED_ON) \ + __PMC_EV(E500, L2_CLEAN_LINE_INVALIDATIONS) \ + __PMC_EV(E500, L2_INCOHERENT_LINE_INVALIDATIONS) \ + __PMC_EV(E500, L2_COHERENT_LINE_INVALIDATIONS) \ + __PMC_EV(E500, COHERENT_LOOKUP_MISS_DUE_TO_VALID_BUT_INCOHERENT_MATCHES) \ + __PMC_EV(E500, IAC1S_DETECTED) \ + __PMC_EV(E500, IAC2S_DETECTED) \ + __PMC_EV(E500, DAC1S_DTECTED) \ + __PMC_EV(E500, DAC2S_DTECTED) \ + __PMC_EV(E500, DVT0_DETECTED) \ + __PMC_EV(E500, DVT1_DETECTED) \ + __PMC_EV(E500, DVT2_DETECTED) \ + __PMC_EV(E500, DVT3_DETECTED) \ + __PMC_EV(E500, DVT4_DETECTED) \ + __PMC_EV(E500, DVT5_DETECTED) \ + __PMC_EV(E500, DVT6_DETECTED) \ + __PMC_EV(E500, DVT7_DETECTED) \ + __PMC_EV(E500, CYCLES_COMPLETION_STALLED_NEXUS_FIFO_FULL) \ + __PMC_EV(E500, FPU_DOUBLE_PUMP) \ + __PMC_EV(E500, FPU_FINISH) \ + __PMC_EV(E500, FPU_DIVIDE_CYCLES) \ + __PMC_EV(E500, FPU_DENORM_INPUT_CYCLES) \ + __PMC_EV(E500, FPU_RESULT_STALL_CYCLES) \ + __PMC_EV(E500, FPU_FPSCR_FULL_STALL) \ + __PMC_EV(E500, FPU_PIPE_SYNC_STALLS) \ + __PMC_EV(E500, FPU_INPUT_DATA_STALLS) \ + __PMC_EV(E500, DECORATED_LOADS) \ + __PMC_EV(E500, DECORATED_STORES) \ + __PMC_EV(E500, LOAD_RETRIES) \ + __PMC_EV(E500, STWCX_SUCCESSES) \ + __PMC_EV(E500, STWCX_FAILURES) \ + +#define PMC_EV_E500_FIRST PMC_EV_E500_CYCLES +#define PMC_EV_E500_LAST PMC_EV_E500_STWCX_FAILURES /* * All known PMC events. * @@ -5400,6 +5562,9 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL * 0x11300 0x00FF MIPS 24K events * 0x11400 0x00FF Octeon events * 0x11500 0x00FF MIPS 74K events + * 0x13000 0x00FF MPC7450 events + * 0x13100 0x00FF IBM PPC970 events + * 0x13300 0x00FF Freescale e500 events * 0x14000 0x0100 ARMv7 events * 0x20000 0x1000 Software events */ @@ -5436,6 +5601,8 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL __PMC_EV_PPC7450() \ __PMC_EV_BLOCK(PPC970, 0x13100) \ __PMC_EV_PPC970() \ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***