The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hwpmc/hwpmc_e500.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2015 Justin Hibbits
    3  * Copyright (c) 2005, Joseph Koshy
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/pmc.h>
   34 #include <sys/pmckern.h>
   35 #include <sys/systm.h>
   36 
   37 #include <machine/pmc_mdep.h>
   38 #include <machine/cpu.h>
   39 
   40 #include <ddb/ddb.h>
   41 
   42 #include "hwpmc_powerpc.h"
   43 
   44 struct e500_event_code_map {
   45         enum pmc_event  pe_ev;       /* enum value */
   46         uint8_t         pe_counter_mask;  /* Which counter this can be counted in. */
   47         uint8_t         pe_code;     /* numeric code */
   48         uint8_t         pe_cpu;      /* e500 core (v1,v2,mc), mask */
   49 };
   50 
   51 #define E500_MAX_PMCS   4
   52 #define PMC_PPC_MASK0   0
   53 #define PMC_PPC_MASK1   1
   54 #define PMC_PPC_MASK2   2
   55 #define PMC_PPC_MASK3   3
   56 #define PMC_PPC_MASK_ALL        0x0f
   57 #define PMC_PPC_E500V1          1
   58 #define PMC_PPC_E500V2          2
   59 #define PMC_PPC_E500MC          4
   60 #define PMC_PPC_E500_ANY        7
   61 #define PMC_E500_EVENT(id, mask, number, core) \
   62         [PMC_EV_E500_##id - PMC_EV_E500_FIRST] = \
   63             { .pe_ev = PMC_EV_E500_##id, .pe_counter_mask = mask, \
   64               .pe_code = number, .pe_cpu = core }
   65 #define PMC_E500MC_ONLY(id, number) \
   66         PMC_E500_EVENT(id, PMC_PPC_MASK_ALL, number, PMC_PPC_E500MC)
   67 #define PMC_E500_COMMON(id, number) \
   68         PMC_E500_EVENT(id, PMC_PPC_MASK_ALL, number, PMC_PPC_E500_ANY)
   69 
   70 static struct e500_event_code_map e500_event_codes[] = {
   71         PMC_E500_COMMON(CYCLES, 1),
   72         PMC_E500_COMMON(INSTR_COMPLETED, 2),
   73         PMC_E500_COMMON(UOPS_COMPLETED, 3),
   74         PMC_E500_COMMON(INSTR_FETCHED, 4),
   75         PMC_E500_COMMON(UOPS_DECODED, 5),
   76         PMC_E500_COMMON(PM_EVENT_TRANSITIONS, 6),
   77         PMC_E500_COMMON(PM_EVENT_CYCLES, 7),
   78         PMC_E500_COMMON(BRANCH_INSTRS_COMPLETED, 8),
   79         PMC_E500_COMMON(LOAD_UOPS_COMPLETED, 9),
   80         PMC_E500_COMMON(STORE_UOPS_COMPLETED, 10),
   81         PMC_E500_COMMON(CQ_REDIRECTS, 11),
   82         PMC_E500_COMMON(BRANCHES_FINISHED, 12),
   83         PMC_E500_COMMON(TAKEN_BRANCHES_FINISHED, 13),
   84         PMC_E500_COMMON(FINISHED_UNCOND_BRANCHES_MISS_BTB, 14),
   85         PMC_E500_COMMON(BRANCH_MISPRED, 15),
   86         PMC_E500_COMMON(BTB_BRANCH_MISPRED_FROM_DIRECTION, 16),
   87         PMC_E500_COMMON(BTB_HITS_PSEUDO_HITS, 17),
   88         PMC_E500_COMMON(CYCLES_DECODE_STALLED, 18),
   89         PMC_E500_COMMON(CYCLES_ISSUE_STALLED, 19),
   90         PMC_E500_COMMON(CYCLES_BRANCH_ISSUE_STALLED, 20),
   91         PMC_E500_COMMON(CYCLES_SU1_SCHED_STALLED, 21),
   92         PMC_E500_COMMON(CYCLES_SU2_SCHED_STALLED, 22),
   93         PMC_E500_COMMON(CYCLES_MU_SCHED_STALLED, 23),
   94         PMC_E500_COMMON(CYCLES_LRU_SCHED_STALLED, 24),
   95         PMC_E500_COMMON(CYCLES_BU_SCHED_STALLED, 25),
   96         PMC_E500_COMMON(TOTAL_TRANSLATED, 26),
   97         PMC_E500_COMMON(LOADS_TRANSLATED, 27),
   98         PMC_E500_COMMON(STORES_TRANSLATED, 28),
   99         PMC_E500_COMMON(TOUCHES_TRANSLATED, 29),
  100         PMC_E500_COMMON(CACHEOPS_TRANSLATED, 30),
  101         PMC_E500_COMMON(CACHE_INHIBITED_ACCESS_TRANSLATED, 31),
  102         PMC_E500_COMMON(GUARDED_LOADS_TRANSLATED, 32),
  103         PMC_E500_COMMON(WRITE_THROUGH_STORES_TRANSLATED, 33),
  104         PMC_E500_COMMON(MISALIGNED_LOAD_STORE_ACCESS_TRANSLATED, 34),
  105         PMC_E500_COMMON(TOTAL_ALLOCATED_TO_DLFB, 35),
  106         PMC_E500_COMMON(LOADS_TRANSLATED_ALLOCATED_TO_DLFB, 36),
  107         PMC_E500_COMMON(STORES_COMPLETED_ALLOCATED_TO_DLFB, 37),
  108         PMC_E500_COMMON(TOUCHES_TRANSLATED_ALLOCATED_TO_DLFB, 38),
  109         PMC_E500_COMMON(STORES_COMPLETED, 39),
  110         PMC_E500_COMMON(DATA_L1_CACHE_LOCKS, 40),
  111         PMC_E500_COMMON(DATA_L1_CACHE_RELOADS, 41),
  112         PMC_E500_COMMON(DATA_L1_CACHE_CASTOUTS, 42),
  113         PMC_E500_COMMON(LOAD_MISS_DLFB_FULL, 43),
  114         PMC_E500_COMMON(LOAD_MISS_LDQ_FULL, 44),
  115         PMC_E500_COMMON(LOAD_GUARDED_MISS, 45),
  116         PMC_E500_COMMON(STORE_TRANSLATE_WHEN_QUEUE_FULL, 46),
  117         PMC_E500_COMMON(ADDRESS_COLLISION, 47),
  118         PMC_E500_COMMON(DATA_MMU_MISS, 48),
  119         PMC_E500_COMMON(DATA_MMU_BUSY, 49),
  120         PMC_E500_COMMON(PART2_MISALIGNED_CACHE_ACCESS, 50),
  121         PMC_E500_COMMON(LOAD_MISS_DLFB_FULL_CYCLES, 51),
  122         PMC_E500_COMMON(LOAD_MISS_LDQ_FULL_CYCLES, 52),
  123         PMC_E500_COMMON(LOAD_GUARDED_MISS_CYCLES, 53),
  124         PMC_E500_COMMON(STORE_TRANSLATE_WHEN_QUEUE_FULL_CYCLES, 54),
  125         PMC_E500_COMMON(ADDRESS_COLLISION_CYCLES, 55),
  126         PMC_E500_COMMON(DATA_MMU_MISS_CYCLES, 56),
  127         PMC_E500_COMMON(DATA_MMU_BUSY_CYCLES, 57),
  128         PMC_E500_COMMON(PART2_MISALIGNED_CACHE_ACCESS_CYCLES, 58),
  129         PMC_E500_COMMON(INSTR_L1_CACHE_LOCKS, 59),
  130         PMC_E500_COMMON(INSTR_L1_CACHE_RELOADS, 60),
  131         PMC_E500_COMMON(INSTR_L1_CACHE_FETCHES, 61),
  132         PMC_E500_COMMON(INSTR_MMU_TLB4K_RELOADS, 62),
  133         PMC_E500_COMMON(INSTR_MMU_VSP_RELOADS, 63),
  134         PMC_E500_COMMON(DATA_MMU_TLB4K_RELOADS, 64),
  135         PMC_E500_COMMON(DATA_MMU_VSP_RELOADS, 65),
  136         PMC_E500_COMMON(L2MMU_MISSES, 66),
  137         PMC_E500_COMMON(BIU_MASTER_REQUESTS, 67),
  138         PMC_E500_COMMON(BIU_MASTER_INSTR_SIDE_REQUESTS, 68),
  139         PMC_E500_COMMON(BIU_MASTER_DATA_SIDE_REQUESTS, 69),
  140         PMC_E500_COMMON(BIU_MASTER_DATA_SIDE_CASTOUT_REQUESTS, 70),
  141         PMC_E500_COMMON(BIU_MASTER_RETRIES, 71),
  142         PMC_E500_COMMON(SNOOP_REQUESTS, 72),
  143         PMC_E500_COMMON(SNOOP_HITS, 73),
  144         PMC_E500_COMMON(SNOOP_PUSHES, 74),
  145         PMC_E500_COMMON(SNOOP_RETRIES, 75),
  146         PMC_E500_EVENT(DLFB_LOAD_MISS_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1,
  147             76, PMC_PPC_E500_ANY),
  148         PMC_E500_EVENT(ILFB_FETCH_MISS_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1,
  149             77, PMC_PPC_E500_ANY),
  150         PMC_E500_EVENT(EXT_INPU_INTR_LATENCY_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1,
  151             78, PMC_PPC_E500_ANY),
  152         PMC_E500_EVENT(CRIT_INPUT_INTR_LATENCY_CYCLES, PMC_PPC_MASK0|PMC_PPC_MASK1,
  153             79, PMC_PPC_E500_ANY),
  154         PMC_E500_EVENT(EXT_INPUT_INTR_PENDING_LATENCY_CYCLES,
  155             PMC_PPC_MASK0|PMC_PPC_MASK1, 80, PMC_PPC_E500_ANY),
  156         PMC_E500_EVENT(CRIT_INPUT_INTR_PENDING_LATENCY_CYCLES,
  157             PMC_PPC_MASK0|PMC_PPC_MASK1, 81, PMC_PPC_E500_ANY),
  158         PMC_E500_COMMON(PMC0_OVERFLOW, 82),
  159         PMC_E500_COMMON(PMC1_OVERFLOW, 83),
  160         PMC_E500_COMMON(PMC2_OVERFLOW, 84),
  161         PMC_E500_COMMON(PMC3_OVERFLOW, 85),
  162         PMC_E500_COMMON(INTERRUPTS_TAKEN, 86),
  163         PMC_E500_COMMON(EXT_INPUT_INTR_TAKEN, 87),
  164         PMC_E500_COMMON(CRIT_INPUT_INTR_TAKEN, 88),
  165         PMC_E500_COMMON(SYSCALL_TRAP_INTR, 89),
  166         PMC_E500_EVENT(TLB_BIT_TRANSITIONS, PMC_PPC_MASK_ALL, 90,
  167             PMC_PPC_E500V2 | PMC_PPC_E500MC),
  168         PMC_E500MC_ONLY(L2_LINEFILL_BUFFER, 91),
  169         PMC_E500MC_ONLY(LV2_VS, 92),
  170         PMC_E500MC_ONLY(CASTOUTS_RELEASED, 93),
  171         PMC_E500MC_ONLY(INTV_ALLOCATIONS, 94),
  172         PMC_E500MC_ONLY(DLFB_RETRIES_TO_MBAR, 95),
  173         PMC_E500MC_ONLY(STORE_RETRIES, 96),
  174         PMC_E500MC_ONLY(STASH_L1_HITS, 97),
  175         PMC_E500MC_ONLY(STASH_L2_HITS, 98),
  176         PMC_E500MC_ONLY(STASH_BUSY_1, 99),
  177         PMC_E500MC_ONLY(STASH_BUSY_2, 100),
  178         PMC_E500MC_ONLY(STASH_BUSY_3, 101),
  179         PMC_E500MC_ONLY(STASH_HITS, 102),
  180         PMC_E500MC_ONLY(STASH_HIT_DLFB, 103),
  181         PMC_E500MC_ONLY(STASH_REQUESTS, 106),
  182         PMC_E500MC_ONLY(STASH_REQUESTS_L1, 107),
  183         PMC_E500MC_ONLY(STASH_REQUESTS_L2, 108),
  184         PMC_E500MC_ONLY(STALLS_NO_CAQ_OR_COB, 109),
  185         PMC_E500MC_ONLY(L2_CACHE_ACCESSES, 110),
  186         PMC_E500MC_ONLY(L2_HIT_CACHE_ACCESSES, 111),
  187         PMC_E500MC_ONLY(L2_CACHE_DATA_ACCESSES, 112),
  188         PMC_E500MC_ONLY(L2_CACHE_DATA_HITS, 113),
  189         PMC_E500MC_ONLY(L2_CACHE_INSTR_ACCESSES, 114),
  190         PMC_E500MC_ONLY(L2_CACHE_INSTR_HITS, 115),
  191         PMC_E500MC_ONLY(L2_CACHE_ALLOCATIONS, 116),
  192         PMC_E500MC_ONLY(L2_CACHE_DATA_ALLOCATIONS, 117),
  193         PMC_E500MC_ONLY(L2_CACHE_DIRTY_DATA_ALLOCATIONS, 118),
  194         PMC_E500MC_ONLY(L2_CACHE_INSTR_ALLOCATIONS, 119),
  195         PMC_E500MC_ONLY(L2_CACHE_UPDATES, 120),
  196         PMC_E500MC_ONLY(L2_CACHE_CLEAN_UPDATES, 121),
  197         PMC_E500MC_ONLY(L2_CACHE_DIRTY_UPDATES, 122),
  198         PMC_E500MC_ONLY(L2_CACHE_CLEAN_REDUNDANT_UPDATES, 123),
  199         PMC_E500MC_ONLY(L2_CACHE_DIRTY_REDUNDANT_UPDATES, 124),
  200         PMC_E500MC_ONLY(L2_CACHE_LOCKS, 125),
  201         PMC_E500MC_ONLY(L2_CACHE_CASTOUTS, 126),
  202         PMC_E500MC_ONLY(L2_CACHE_DATA_DIRTY_HITS, 127),
  203         PMC_E500MC_ONLY(INSTR_LFB_WENT_HIGH_PRIORITY, 128),
  204         PMC_E500MC_ONLY(SNOOP_THROTTLING_TURNED_ON, 129),
  205         PMC_E500MC_ONLY(L2_CLEAN_LINE_INVALIDATIONS, 130),
  206         PMC_E500MC_ONLY(L2_INCOHERENT_LINE_INVALIDATIONS, 131),
  207         PMC_E500MC_ONLY(L2_COHERENT_LINE_INVALIDATIONS, 132),
  208         PMC_E500MC_ONLY(COHERENT_LOOKUP_MISS_DUE_TO_VALID_BUT_INCOHERENT_MATCHES, 133),
  209         PMC_E500MC_ONLY(IAC1S_DETECTED, 140),
  210         PMC_E500MC_ONLY(IAC2S_DETECTED, 141),
  211         PMC_E500MC_ONLY(DAC1S_DTECTED, 144),
  212         PMC_E500MC_ONLY(DAC2S_DTECTED, 145),
  213         PMC_E500MC_ONLY(DVT0_DETECTED, 148),
  214         PMC_E500MC_ONLY(DVT1_DETECTED, 149),
  215         PMC_E500MC_ONLY(DVT2_DETECTED, 150),
  216         PMC_E500MC_ONLY(DVT3_DETECTED, 151),
  217         PMC_E500MC_ONLY(DVT4_DETECTED, 152),
  218         PMC_E500MC_ONLY(DVT5_DETECTED, 153),
  219         PMC_E500MC_ONLY(DVT6_DETECTED, 154),
  220         PMC_E500MC_ONLY(DVT7_DETECTED, 155),
  221         PMC_E500MC_ONLY(CYCLES_COMPLETION_STALLED_NEXUS_FIFO_FULL, 156),
  222         PMC_E500MC_ONLY(FPU_DOUBLE_PUMP, 160),
  223         PMC_E500MC_ONLY(FPU_FINISH, 161),
  224         PMC_E500MC_ONLY(FPU_DIVIDE_CYCLES, 162),
  225         PMC_E500MC_ONLY(FPU_DENORM_INPUT_CYCLES, 163),
  226         PMC_E500MC_ONLY(FPU_RESULT_STALL_CYCLES, 164),
  227         PMC_E500MC_ONLY(FPU_FPSCR_FULL_STALL, 165),
  228         PMC_E500MC_ONLY(FPU_PIPE_SYNC_STALLS, 166),
  229         PMC_E500MC_ONLY(FPU_INPUT_DATA_STALLS, 167),
  230         PMC_E500MC_ONLY(DECORATED_LOADS, 176),
  231         PMC_E500MC_ONLY(DECORATED_STORES, 177),
  232         PMC_E500MC_ONLY(LOAD_RETRIES, 178),
  233         PMC_E500MC_ONLY(STWCX_SUCCESSES, 179),
  234         PMC_E500MC_ONLY(STWCX_FAILURES, 180),
  235 };
  236 
  237 static pmc_value_t
  238 e500_pmcn_read(unsigned int pmc)
  239 {
  240         switch (pmc) {
  241         case 0:
  242                 return (mfpmr(PMR_PMC0));
  243         case 1:
  244                 return (mfpmr(PMR_PMC1));
  245         case 2:
  246                 return (mfpmr(PMR_PMC2));
  247         case 3:
  248                 return (mfpmr(PMR_PMC3));
  249         default:
  250                 panic("Invalid PMC number: %d\n", pmc);
  251         }
  252 }
  253 
  254 static void
  255 e500_pmcn_write(unsigned int pmc, uint32_t val)
  256 {
  257         switch (pmc) {
  258         case 0:
  259                 mtpmr(PMR_PMC0, val);
  260                 break;
  261         case 1:
  262                 mtpmr(PMR_PMC1, val);
  263                 break;
  264         case 2:
  265                 mtpmr(PMR_PMC2, val);
  266                 break;
  267         case 3:
  268                 mtpmr(PMR_PMC3, val);
  269                 break;
  270         default:
  271                 panic("Invalid PMC number: %d\n", pmc);
  272         }
  273 }
  274 
  275 static void
  276 e500_set_pmc(int cpu, int ri, int config)
  277 {
  278         struct pmc *pm;
  279         struct pmc_hw *phw;
  280         register_t pmc_pmlc;
  281 
  282         phw    = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri];
  283         pm     = phw->phw_pmc;
  284         config &= ~POWERPC_PMC_ENABLE;
  285 
  286         if (config != PMCN_NONE) {
  287                 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
  288                         config |= PMLCax_CE;
  289 
  290                 /* Enable the PMC. */
  291                 switch (ri) {
  292                 case 0:
  293                         mtpmr(PMR_PMLCa0, config);
  294                         break;
  295                 case 1:
  296                         mtpmr(PMR_PMLCa1, config);
  297                         break;
  298                 case 2:
  299                         mtpmr(PMR_PMLCa2, config);
  300                         break;
  301                 case 3:
  302                         mtpmr(PMR_PMLCa3, config);
  303                         break;
  304                 }
  305         } else {
  306                 /* Disable the PMC. */
  307                 switch (ri) {
  308                 case 0:
  309                         pmc_pmlc = mfpmr(PMR_PMLCa0);
  310                         pmc_pmlc |= PMLCax_FC;
  311                         mtpmr(PMR_PMLCa0, pmc_pmlc);
  312                         break;
  313                 case 1:
  314                         pmc_pmlc = mfpmr(PMR_PMLCa1);
  315                         pmc_pmlc |= PMLCax_FC;
  316                         mtpmr(PMR_PMLCa1, pmc_pmlc);
  317                         break;
  318                 case 2:
  319                         pmc_pmlc = mfpmr(PMR_PMLCa2);
  320                         pmc_pmlc |= PMLCax_FC;
  321                         mtpmr(PMR_PMLCa2, pmc_pmlc);
  322                         break;
  323                 case 3:
  324                         pmc_pmlc = mfpmr(PMR_PMLCa3);
  325                         pmc_pmlc |= PMLCax_FC;
  326                         mtpmr(PMR_PMLCa3, pmc_pmlc);
  327                         break;
  328                 }
  329         }
  330 }
  331 
  332 static int
  333 e500_pcpu_init(struct pmc_mdep *md, int cpu)
  334 {
  335         int i;
  336 
  337         powerpc_pcpu_init(md, cpu);
  338 
  339         /* Freeze all counters. */
  340         mtpmr(PMR_PMGC0, PMGC_FAC | PMGC_PMIE | PMGC_FCECE);
  341 
  342         for (i = 0; i < E500_MAX_PMCS; i++)
  343                 /* Initialize the PMC to stopped */
  344                 powerpc_stop_pmc(cpu, i);
  345 
  346         /* Unfreeze global register. */
  347         mtpmr(PMR_PMGC0, PMGC_PMIE | PMGC_FCECE);
  348 
  349         return (0);
  350 }
  351 
  352 static int
  353 e500_pcpu_fini(struct pmc_mdep *md, int cpu)
  354 {
  355         uint32_t pmgc0 = mfpmr(PMR_PMGC0);
  356 
  357         pmgc0 |= PMGC_FAC;
  358         mtpmr(PMR_PMGC0, pmgc0);
  359         mtmsr(mfmsr() & ~PSL_PMM);
  360 
  361         return (powerpc_pcpu_fini(md, cpu));
  362 }
  363 
  364 static int
  365 e500_allocate_pmc(int cpu, int ri, struct pmc *pm,
  366   const struct pmc_op_pmcallocate *a)
  367 {
  368         enum pmc_event pe;
  369         uint32_t caps, config, counter;
  370         struct e500_event_code_map *ev;
  371         uint16_t vers;
  372         uint8_t pe_cpu_mask;
  373 
  374         KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
  375             ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu));
  376         KASSERT(ri >= 0 && ri < E500_MAX_PMCS,
  377             ("[powerpc,%d] illegal row index %d", __LINE__, ri));
  378 
  379         if (a->pm_class != PMC_CLASS_E500)
  380                 return (EINVAL);
  381 
  382         caps = a->pm_caps;
  383 
  384         pe = a->pm_ev;
  385         config = PMLCax_FCS | PMLCax_FCU |
  386             PMLCax_FCM1 | PMLCax_FCM1;
  387 
  388         if (pe < PMC_EV_E500_FIRST || pe > PMC_EV_E500_LAST)
  389                 return (EINVAL);
  390 
  391         ev = &e500_event_codes[pe-PMC_EV_E500_FIRST];
  392         if (ev->pe_code == 0)
  393                 return (EINVAL);
  394 
  395         vers = mfpvr() >> 16;
  396         switch (vers) {
  397         case FSL_E500v1:
  398                 pe_cpu_mask = ev->pe_cpu & PMC_PPC_E500V1;
  399                 break;
  400         case FSL_E500v2:
  401                 pe_cpu_mask = ev->pe_cpu & PMC_PPC_E500V2;
  402                 break;
  403         case FSL_E500mc:
  404         case FSL_E5500:
  405                 pe_cpu_mask = ev->pe_cpu & PMC_PPC_E500MC;
  406                 break;
  407         }
  408         if (pe_cpu_mask == 0)
  409                 return (EINVAL);
  410 
  411         config |= PMLCax_EVENT(ev->pe_code);
  412         counter =  ev->pe_counter_mask;
  413         if ((counter & (1 << ri)) == 0)
  414                 return (EINVAL);
  415 
  416         if (caps & PMC_CAP_SYSTEM)
  417                 config &= ~PMLCax_FCS;
  418         if (caps & PMC_CAP_USER)
  419                 config &= ~PMLCax_FCU;
  420         if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0)
  421                 config &= ~(PMLCax_FCS|PMLCax_FCU);
  422 
  423         pm->pm_md.pm_powerpc.pm_powerpc_evsel = config;
  424 
  425         PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config);
  426 
  427         return 0;
  428 }
  429 
  430 static void
  431 e500_resume_pmc(bool ie)
  432 {
  433         /* Re-enable PERF exceptions. */
  434         if (ie)
  435                 mtpmr(PMR_PMGC0, (mfpmr(PMR_PMGC0) & ~PMGC_FAC) | PMGC_PMIE);
  436 }
  437 
  438 int
  439 pmc_e500_initialize(struct pmc_mdep *pmc_mdep)
  440 {
  441         struct pmc_classdep *pcd;
  442 
  443         pmc_mdep->pmd_cputype = PMC_CPU_PPC_E500;
  444 
  445         pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_POWERPC];
  446         pcd->pcd_caps  = POWERPC_PMC_CAPS;
  447         pcd->pcd_class = PMC_CLASS_E500;
  448         pcd->pcd_num   = E500_MAX_PMCS;
  449         pcd->pcd_ri    = pmc_mdep->pmd_npmc;
  450         pcd->pcd_width = 32;
  451 
  452         pcd->pcd_allocate_pmc   = e500_allocate_pmc;
  453         pcd->pcd_config_pmc     = powerpc_config_pmc;
  454         pcd->pcd_pcpu_fini      = e500_pcpu_fini;
  455         pcd->pcd_pcpu_init      = e500_pcpu_init;
  456         pcd->pcd_describe       = powerpc_describe;
  457         pcd->pcd_get_config     = powerpc_get_config;
  458         pcd->pcd_read_pmc       = powerpc_read_pmc;
  459         pcd->pcd_release_pmc    = powerpc_release_pmc;
  460         pcd->pcd_start_pmc      = powerpc_start_pmc;
  461         pcd->pcd_stop_pmc       = powerpc_stop_pmc;
  462         pcd->pcd_write_pmc      = powerpc_write_pmc;
  463 
  464         pmc_mdep->pmd_npmc   += E500_MAX_PMCS;
  465         pmc_mdep->pmd_intr   =  powerpc_pmc_intr;
  466 
  467         ppc_max_pmcs = E500_MAX_PMCS;
  468 
  469         powerpc_set_pmc = e500_set_pmc;
  470         powerpc_pmcn_read = e500_pmcn_read;
  471         powerpc_pmcn_write = e500_pmcn_write;
  472         powerpc_resume_pmc = e500_resume_pmc;
  473 
  474         return (0);
  475 }

Cache object: 2b9ea434606ee140b4ce1cb674c43705


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.