linux/arch/powerpc/perf/isa207-common.c
<<
>>
Prefs
   1/*
   2 * Common Performance counter support functions for PowerISA v2.07 processors.
   3 *
   4 * Copyright 2009 Paul Mackerras, IBM Corporation.
   5 * Copyright 2013 Michael Ellerman, IBM Corporation.
   6 * Copyright 2016 Madhavan Srinivasan, IBM Corporation.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * as published by the Free Software Foundation; either version
  11 * 2 of the License, or (at your option) any later version.
  12 */
  13#include "isa207-common.h"
  14
  15PMU_FORMAT_ATTR(event,          "config:0-49");
  16PMU_FORMAT_ATTR(pmcxsel,        "config:0-7");
  17PMU_FORMAT_ATTR(mark,           "config:8");
  18PMU_FORMAT_ATTR(combine,        "config:11");
  19PMU_FORMAT_ATTR(unit,           "config:12-15");
  20PMU_FORMAT_ATTR(pmc,            "config:16-19");
  21PMU_FORMAT_ATTR(cache_sel,      "config:20-23");
  22PMU_FORMAT_ATTR(sample_mode,    "config:24-28");
  23PMU_FORMAT_ATTR(thresh_sel,     "config:29-31");
  24PMU_FORMAT_ATTR(thresh_stop,    "config:32-35");
  25PMU_FORMAT_ATTR(thresh_start,   "config:36-39");
  26PMU_FORMAT_ATTR(thresh_cmp,     "config:40-49");
  27
  28struct attribute *isa207_pmu_format_attr[] = {
  29        &format_attr_event.attr,
  30        &format_attr_pmcxsel.attr,
  31        &format_attr_mark.attr,
  32        &format_attr_combine.attr,
  33        &format_attr_unit.attr,
  34        &format_attr_pmc.attr,
  35        &format_attr_cache_sel.attr,
  36        &format_attr_sample_mode.attr,
  37        &format_attr_thresh_sel.attr,
  38        &format_attr_thresh_stop.attr,
  39        &format_attr_thresh_start.attr,
  40        &format_attr_thresh_cmp.attr,
  41        NULL,
  42};
  43
  44struct attribute_group isa207_pmu_format_group = {
  45        .name = "format",
  46        .attrs = isa207_pmu_format_attr,
  47};
  48
  49static inline bool event_is_fab_match(u64 event)
  50{
  51        /* Only check pmc, unit and pmcxsel, ignore the edge bit (0) */
  52        event &= 0xff0fe;
  53
  54        /* PM_MRK_FAB_RSP_MATCH & PM_MRK_FAB_RSP_MATCH_CYC */
  55        return (event == 0x30056 || event == 0x4f052);
  56}
  57
  58static bool is_event_valid(u64 event)
  59{
  60        u64 valid_mask = EVENT_VALID_MASK;
  61
  62        if (cpu_has_feature(CPU_FTR_ARCH_300) && !cpu_has_feature(CPU_FTR_POWER9_DD1))
  63                valid_mask = p9_EVENT_VALID_MASK;
  64
  65        return !(event & ~valid_mask);
  66}
  67
  68static u64 mmcra_sdar_mode(u64 event)
  69{
  70        if (cpu_has_feature(CPU_FTR_ARCH_300) && !cpu_has_feature(CPU_FTR_POWER9_DD1))
  71                return p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT;
  72
  73        return MMCRA_SDAR_MODE_TLB;
  74}
  75
  76static u64 thresh_cmp_val(u64 value)
  77{
  78        if (cpu_has_feature(CPU_FTR_ARCH_300) && !cpu_has_feature(CPU_FTR_POWER9_DD1))
  79                return value << p9_MMCRA_THR_CMP_SHIFT;
  80
  81        return value << MMCRA_THR_CMP_SHIFT;
  82}
  83
  84static unsigned long combine_from_event(u64 event)
  85{
  86        if (cpu_has_feature(CPU_FTR_ARCH_300) && !cpu_has_feature(CPU_FTR_POWER9_DD1))
  87                return p9_EVENT_COMBINE(event);
  88
  89        return EVENT_COMBINE(event);
  90}
  91
  92static unsigned long combine_shift(unsigned long pmc)
  93{
  94        if (cpu_has_feature(CPU_FTR_ARCH_300) && !cpu_has_feature(CPU_FTR_POWER9_DD1))
  95                return p9_MMCR1_COMBINE_SHIFT(pmc);
  96
  97        return MMCR1_COMBINE_SHIFT(pmc);
  98}
  99
 100int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp)
 101{
 102        unsigned int unit, pmc, cache, ebb;
 103        unsigned long mask, value;
 104
 105        mask = value = 0;
 106
 107        if (!is_event_valid(event))
 108                return -1;
 109
 110        pmc   = (event >> EVENT_PMC_SHIFT)        & EVENT_PMC_MASK;
 111        unit  = (event >> EVENT_UNIT_SHIFT)       & EVENT_UNIT_MASK;
 112        cache = (event >> EVENT_CACHE_SEL_SHIFT)  & EVENT_CACHE_SEL_MASK;
 113        ebb   = (event >> EVENT_EBB_SHIFT)        & EVENT_EBB_MASK;
 114
 115        if (pmc) {
 116                u64 base_event;
 117
 118                if (pmc > 6)
 119                        return -1;
 120
 121                /* Ignore Linux defined bits when checking event below */
 122                base_event = event & ~EVENT_LINUX_MASK;
 123
 124                if (pmc >= 5 && base_event != 0x500fa &&
 125                                base_event != 0x600f4)
 126                        return -1;
 127
 128                mask  |= CNST_PMC_MASK(pmc);
 129                value |= CNST_PMC_VAL(pmc);
 130        }
 131
 132        if (pmc <= 4) {
 133                /*
 134                 * Add to number of counters in use. Note this includes events with
 135                 * a PMC of 0 - they still need a PMC, it's just assigned later.
 136                 * Don't count events on PMC 5 & 6, there is only one valid event
 137                 * on each of those counters, and they are handled above.
 138                 */
 139                mask  |= CNST_NC_MASK;
 140                value |= CNST_NC_VAL;
 141        }
 142
 143        if (unit >= 6 && unit <= 9) {
 144                /*
 145                 * L2/L3 events contain a cache selector field, which is
 146                 * supposed to be programmed into MMCRC. However MMCRC is only
 147                 * HV writable, and there is no API for guest kernels to modify
 148                 * it. The solution is for the hypervisor to initialise the
 149                 * field to zeroes, and for us to only ever allow events that
 150                 * have a cache selector of zero. The bank selector (bit 3) is
 151                 * irrelevant, as long as the rest of the value is 0.
 152                 */
 153                if (cache & 0x7)
 154                        return -1;
 155
 156        } else if (event & EVENT_IS_L1) {
 157                mask  |= CNST_L1_QUAL_MASK;
 158                value |= CNST_L1_QUAL_VAL(cache);
 159        }
 160
 161        if (event & EVENT_IS_MARKED) {
 162                mask  |= CNST_SAMPLE_MASK;
 163                value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT);
 164        }
 165
 166        /*
 167         * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
 168         * the threshold control bits are used for the match value.
 169         */
 170        if (event_is_fab_match(event)) {
 171                mask  |= CNST_FAB_MATCH_MASK;
 172                value |= CNST_FAB_MATCH_VAL(event >> EVENT_THR_CTL_SHIFT);
 173        } else {
 174                /*
 175                 * Check the mantissa upper two bits are not zero, unless the
 176                 * exponent is also zero. See the THRESH_CMP_MANTISSA doc.
 177                 */
 178                unsigned int cmp, exp;
 179
 180                cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK;
 181                exp = cmp >> 7;
 182
 183                if (exp && (cmp & 0x60) == 0)
 184                        return -1;
 185
 186                mask  |= CNST_THRESH_MASK;
 187                value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT);
 188        }
 189
 190        if (!pmc && ebb)
 191                /* EBB events must specify the PMC */
 192                return -1;
 193
 194        if (event & EVENT_WANTS_BHRB) {
 195                if (!ebb)
 196                        /* Only EBB events can request BHRB */
 197                        return -1;
 198
 199                mask  |= CNST_IFM_MASK;
 200                value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT);
 201        }
 202
 203        /*
 204         * All events must agree on EBB, either all request it or none.
 205         * EBB events are pinned & exclusive, so this should never actually
 206         * hit, but we leave it as a fallback in case.
 207         */
 208        mask  |= CNST_EBB_VAL(ebb);
 209        value |= CNST_EBB_MASK;
 210
 211        *maskp = mask;
 212        *valp = value;
 213
 214        return 0;
 215}
 216
 217int isa207_compute_mmcr(u64 event[], int n_ev,
 218                               unsigned int hwc[], unsigned long mmcr[],
 219                               struct perf_event *pevents[])
 220{
 221        unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val;
 222        unsigned int pmc, pmc_inuse;
 223        int i;
 224
 225        pmc_inuse = 0;
 226
 227        /* First pass to count resource use */
 228        for (i = 0; i < n_ev; ++i) {
 229                pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
 230                if (pmc)
 231                        pmc_inuse |= 1 << pmc;
 232        }
 233
 234        mmcra = mmcr1 = mmcr2 = 0;
 235
 236        /* Second pass: assign PMCs, set all MMCR1 fields */
 237        for (i = 0; i < n_ev; ++i) {
 238                pmc     = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
 239                unit    = (event[i] >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
 240                combine = combine_from_event(event[i]);
 241                psel    =  event[i] & EVENT_PSEL_MASK;
 242
 243                if (!pmc) {
 244                        for (pmc = 1; pmc <= 4; ++pmc) {
 245                                if (!(pmc_inuse & (1 << pmc)))
 246                                        break;
 247                        }
 248
 249                        pmc_inuse |= 1 << pmc;
 250                }
 251
 252                if (pmc <= 4) {
 253                        mmcr1 |= unit << MMCR1_UNIT_SHIFT(pmc);
 254                        mmcr1 |= combine << combine_shift(pmc);
 255                        mmcr1 |= psel << MMCR1_PMCSEL_SHIFT(pmc);
 256                }
 257
 258                /* In continuous sampling mode, update SDAR on TLB miss */
 259                mmcra |= mmcra_sdar_mode(event[i]);
 260
 261                if (event[i] & EVENT_IS_L1) {
 262                        cache = event[i] >> EVENT_CACHE_SEL_SHIFT;
 263                        mmcr1 |= (cache & 1) << MMCR1_IC_QUAL_SHIFT;
 264                        cache >>= 1;
 265                        mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT;
 266                }
 267
 268                if (event[i] & EVENT_IS_MARKED) {
 269                        mmcra |= MMCRA_SAMPLE_ENABLE;
 270
 271                        val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK;
 272                        if (val) {
 273                                mmcra |= (val &  3) << MMCRA_SAMP_MODE_SHIFT;
 274                                mmcra |= (val >> 2) << MMCRA_SAMP_ELIG_SHIFT;
 275                        }
 276                }
 277
 278                /*
 279                 * PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
 280                 * the threshold bits are used for the match value.
 281                 */
 282                if (event_is_fab_match(event[i])) {
 283                        mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) &
 284                                  EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT;
 285                } else {
 286                        val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK;
 287                        mmcra |= val << MMCRA_THR_CTL_SHIFT;
 288                        val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK;
 289                        mmcra |= val << MMCRA_THR_SEL_SHIFT;
 290                        val = (event[i] >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK;
 291                        mmcra |= thresh_cmp_val(val);
 292                }
 293
 294                if (event[i] & EVENT_WANTS_BHRB) {
 295                        val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK;
 296                        mmcra |= val << MMCRA_IFM_SHIFT;
 297                }
 298
 299                if (pevents[i]->attr.exclude_user)
 300                        mmcr2 |= MMCR2_FCP(pmc);
 301
 302                if (pevents[i]->attr.exclude_hv)
 303                        mmcr2 |= MMCR2_FCH(pmc);
 304
 305                if (pevents[i]->attr.exclude_kernel) {
 306                        if (cpu_has_feature(CPU_FTR_HVMODE))
 307                                mmcr2 |= MMCR2_FCH(pmc);
 308                        else
 309                                mmcr2 |= MMCR2_FCS(pmc);
 310                }
 311
 312                hwc[i] = pmc - 1;
 313        }
 314
 315        /* Return MMCRx values */
 316        mmcr[0] = 0;
 317
 318        /* pmc_inuse is 1-based */
 319        if (pmc_inuse & 2)
 320                mmcr[0] = MMCR0_PMC1CE;
 321
 322        if (pmc_inuse & 0x7c)
 323                mmcr[0] |= MMCR0_PMCjCE;
 324
 325        /* If we're not using PMC 5 or 6, freeze them */
 326        if (!(pmc_inuse & 0x60))
 327                mmcr[0] |= MMCR0_FC56;
 328
 329        mmcr[1] = mmcr1;
 330        mmcr[2] = mmcra;
 331        mmcr[3] = mmcr2;
 332
 333        return 0;
 334}
 335
 336void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[])
 337{
 338        if (pmc <= 3)
 339                mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1));
 340}
 341