linux/arch/arm/kernel/perf_event_v6.c
<<
>>
Prefs
   1/*
   2 * ARMv6 Performance counter handling code.
   3 *
   4 * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
   5 *
   6 * ARMv6 has 2 configurable performance counters and a single cycle counter.
   7 * They all share a single reset bit but can be written to zero so we can use
   8 * that for a reset.
   9 *
  10 * The counters can't be individually enabled or disabled so when we remove
  11 * one event and replace it with another we could get spurious counts from the
  12 * wrong event. However, we can take advantage of the fact that the
  13 * performance counters can export events to the event bus, and the event bus
  14 * itself can be monitored. This requires that we *don't* export the events to
  15 * the event bus. The procedure for disabling a configurable counter is:
  16 *      - change the counter to count the ETMEXTOUT[0] signal (0x20). This
  17 *        effectively stops the counter from counting.
  18 *      - disable the counter's interrupt generation (each counter has it's
  19 *        own interrupt enable bit).
  20 * Once stopped, the counter value can be written as 0 to reset.
  21 *
  22 * To enable a counter:
  23 *      - enable the counter's interrupt generation.
  24 *      - set the new event type.
  25 *
  26 * Note: the dedicated cycle counter only counts cycles and can't be
  27 * enabled/disabled independently of the others. When we want to disable the
  28 * cycle counter, we have to just disable the interrupt reporting and start
  29 * ignoring that counter. When re-enabling, we have to reset the value and
  30 * enable the interrupt.
  31 */
  32
  33#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
  34enum armv6_perf_types {
  35        ARMV6_PERFCTR_ICACHE_MISS           = 0x0,
  36        ARMV6_PERFCTR_IBUF_STALL            = 0x1,
  37        ARMV6_PERFCTR_DDEP_STALL            = 0x2,
  38        ARMV6_PERFCTR_ITLB_MISS             = 0x3,
  39        ARMV6_PERFCTR_DTLB_MISS             = 0x4,
  40        ARMV6_PERFCTR_BR_EXEC               = 0x5,
  41        ARMV6_PERFCTR_BR_MISPREDICT         = 0x6,
  42        ARMV6_PERFCTR_INSTR_EXEC            = 0x7,
  43        ARMV6_PERFCTR_DCACHE_HIT            = 0x9,
  44        ARMV6_PERFCTR_DCACHE_ACCESS         = 0xA,
  45        ARMV6_PERFCTR_DCACHE_MISS           = 0xB,
  46        ARMV6_PERFCTR_DCACHE_WBACK          = 0xC,
  47        ARMV6_PERFCTR_SW_PC_CHANGE          = 0xD,
  48        ARMV6_PERFCTR_MAIN_TLB_MISS         = 0xF,
  49        ARMV6_PERFCTR_EXPL_D_ACCESS         = 0x10,
  50        ARMV6_PERFCTR_LSU_FULL_STALL        = 0x11,
  51        ARMV6_PERFCTR_WBUF_DRAINED          = 0x12,
  52        ARMV6_PERFCTR_CPU_CYCLES            = 0xFF,
  53        ARMV6_PERFCTR_NOP                   = 0x20,
  54};
  55
  56enum armv6_counters {
  57        ARMV6_CYCLE_COUNTER = 0,
  58        ARMV6_COUNTER0,
  59        ARMV6_COUNTER1,
  60};
  61
  62/*
  63 * The hardware events that we support. We do support cache operations but
  64 * we have harvard caches and no way to combine instruction and data
  65 * accesses/misses in hardware.
  66 */
  67static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
  68        [PERF_COUNT_HW_CPU_CYCLES]          = ARMV6_PERFCTR_CPU_CYCLES,
  69        [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV6_PERFCTR_INSTR_EXEC,
  70        [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
  71        [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
  72        [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
  73        [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV6_PERFCTR_BR_MISPREDICT,
  74        [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
  75};
  76
  77static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  78                                          [PERF_COUNT_HW_CACHE_OP_MAX]
  79                                          [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  80        [C(L1D)] = {
  81                /*
  82                 * The performance counters don't differentiate between read
  83                 * and write accesses/misses so this isn't strictly correct,
  84                 * but it's the best we can do. Writes and reads get
  85                 * combined.
  86                 */
  87                [C(OP_READ)] = {
  88                        [C(RESULT_ACCESS)]      = ARMV6_PERFCTR_DCACHE_ACCESS,
  89                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_DCACHE_MISS,
  90                },
  91                [C(OP_WRITE)] = {
  92                        [C(RESULT_ACCESS)]      = ARMV6_PERFCTR_DCACHE_ACCESS,
  93                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_DCACHE_MISS,
  94                },
  95                [C(OP_PREFETCH)] = {
  96                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
  97                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
  98                },
  99        },
 100        [C(L1I)] = {
 101                [C(OP_READ)] = {
 102                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 103                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_ICACHE_MISS,
 104                },
 105                [C(OP_WRITE)] = {
 106                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 107                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_ICACHE_MISS,
 108                },
 109                [C(OP_PREFETCH)] = {
 110                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 111                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 112                },
 113        },
 114        [C(LL)] = {
 115                [C(OP_READ)] = {
 116                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 117                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 118                },
 119                [C(OP_WRITE)] = {
 120                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 121                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 122                },
 123                [C(OP_PREFETCH)] = {
 124                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 125                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 126                },
 127        },
 128        [C(DTLB)] = {
 129                /*
 130                 * The ARM performance counters can count micro DTLB misses,
 131                 * micro ITLB misses and main TLB misses. There isn't an event
 132                 * for TLB misses, so use the micro misses here and if users
 133                 * want the main TLB misses they can use a raw counter.
 134                 */
 135                [C(OP_READ)] = {
 136                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 137                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_DTLB_MISS,
 138                },
 139                [C(OP_WRITE)] = {
 140                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 141                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_DTLB_MISS,
 142                },
 143                [C(OP_PREFETCH)] = {
 144                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 145                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 146                },
 147        },
 148        [C(ITLB)] = {
 149                [C(OP_READ)] = {
 150                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 151                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_ITLB_MISS,
 152                },
 153                [C(OP_WRITE)] = {
 154                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 155                        [C(RESULT_MISS)]        = ARMV6_PERFCTR_ITLB_MISS,
 156                },
 157                [C(OP_PREFETCH)] = {
 158                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 159                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 160                },
 161        },
 162        [C(BPU)] = {
 163                [C(OP_READ)] = {
 164                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 165                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 166                },
 167                [C(OP_WRITE)] = {
 168                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 169                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 170                },
 171                [C(OP_PREFETCH)] = {
 172                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 173                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 174                },
 175        },
 176        [C(NODE)] = {
 177                [C(OP_READ)] = {
 178                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 179                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 180                },
 181                [C(OP_WRITE)] = {
 182                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 183                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 184                },
 185                [C(OP_PREFETCH)] = {
 186                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 187                        [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 188                },
 189        },
 190};
 191
 192enum armv6mpcore_perf_types {
 193        ARMV6MPCORE_PERFCTR_ICACHE_MISS     = 0x0,
 194        ARMV6MPCORE_PERFCTR_IBUF_STALL      = 0x1,
 195        ARMV6MPCORE_PERFCTR_DDEP_STALL      = 0x2,
 196        ARMV6MPCORE_PERFCTR_ITLB_MISS       = 0x3,
 197        ARMV6MPCORE_PERFCTR_DTLB_MISS       = 0x4,
 198        ARMV6MPCORE_PERFCTR_BR_EXEC         = 0x5,
 199        ARMV6MPCORE_PERFCTR_BR_NOTPREDICT   = 0x6,
 200        ARMV6MPCORE_PERFCTR_BR_MISPREDICT   = 0x7,
 201        ARMV6MPCORE_PERFCTR_INSTR_EXEC      = 0x8,
 202        ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
 203        ARMV6MPCORE_PERFCTR_DCACHE_RDMISS   = 0xB,
 204        ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
 205        ARMV6MPCORE_PERFCTR_DCACHE_WRMISS   = 0xD,
 206        ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
 207        ARMV6MPCORE_PERFCTR_SW_PC_CHANGE    = 0xF,
 208        ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS   = 0x10,
 209        ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
 210        ARMV6MPCORE_PERFCTR_LSU_FULL_STALL  = 0x12,
 211        ARMV6MPCORE_PERFCTR_WBUF_DRAINED    = 0x13,
 212        ARMV6MPCORE_PERFCTR_CPU_CYCLES      = 0xFF,
 213};
 214
 215/*
 216 * The hardware events that we support. We do support cache operations but
 217 * we have harvard caches and no way to combine instruction and data
 218 * accesses/misses in hardware.
 219 */
 220static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
 221        [PERF_COUNT_HW_CPU_CYCLES]          = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
 222        [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
 223        [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
 224        [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
 225        [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
 226        [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
 227        [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
 228};
 229
 230static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 231                                        [PERF_COUNT_HW_CACHE_OP_MAX]
 232                                        [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
 233        [C(L1D)] = {
 234                [C(OP_READ)] = {
 235                        [C(RESULT_ACCESS)]  =
 236                                ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
 237                        [C(RESULT_MISS)]    =
 238                                ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
 239                },
 240                [C(OP_WRITE)] = {
 241                        [C(RESULT_ACCESS)]  =
 242                                ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
 243                        [C(RESULT_MISS)]    =
 244                                ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
 245                },
 246                [C(OP_PREFETCH)] = {
 247                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 248                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 249                },
 250        },
 251        [C(L1I)] = {
 252                [C(OP_READ)] = {
 253                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 254                        [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
 255                },
 256                [C(OP_WRITE)] = {
 257                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 258                        [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
 259                },
 260                [C(OP_PREFETCH)] = {
 261                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 262                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 263                },
 264        },
 265        [C(LL)] = {
 266                [C(OP_READ)] = {
 267                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 268                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 269                },
 270                [C(OP_WRITE)] = {
 271                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 272                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 273                },
 274                [C(OP_PREFETCH)] = {
 275                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 276                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 277                },
 278        },
 279        [C(DTLB)] = {
 280                /*
 281                 * The ARM performance counters can count micro DTLB misses,
 282                 * micro ITLB misses and main TLB misses. There isn't an event
 283                 * for TLB misses, so use the micro misses here and if users
 284                 * want the main TLB misses they can use a raw counter.
 285                 */
 286                [C(OP_READ)] = {
 287                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 288                        [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
 289                },
 290                [C(OP_WRITE)] = {
 291                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 292                        [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
 293                },
 294                [C(OP_PREFETCH)] = {
 295                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 296                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 297                },
 298        },
 299        [C(ITLB)] = {
 300                [C(OP_READ)] = {
 301                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 302                        [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
 303                },
 304                [C(OP_WRITE)] = {
 305                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 306                        [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
 307                },
 308                [C(OP_PREFETCH)] = {
 309                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 310                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 311                },
 312        },
 313        [C(BPU)] = {
 314                [C(OP_READ)] = {
 315                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 316                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 317                },
 318                [C(OP_WRITE)] = {
 319                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 320                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 321                },
 322                [C(OP_PREFETCH)] = {
 323                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 324                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 325                },
 326        },
 327        [C(NODE)] = {
 328                [C(OP_READ)] = {
 329                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 330                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 331                },
 332                [C(OP_WRITE)] = {
 333                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 334                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 335                },
 336                [C(OP_PREFETCH)] = {
 337                        [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
 338                        [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
 339                },
 340        },
 341};
 342
 343static inline unsigned long
 344armv6_pmcr_read(void)
 345{
 346        u32 val;
 347        asm volatile("mrc   p15, 0, %0, c15, c12, 0" : "=r"(val));
 348        return val;
 349}
 350
 351static inline void
 352armv6_pmcr_write(unsigned long val)
 353{
 354        asm volatile("mcr   p15, 0, %0, c15, c12, 0" : : "r"(val));
 355}
 356
 357#define ARMV6_PMCR_ENABLE               (1 << 0)
 358#define ARMV6_PMCR_CTR01_RESET          (1 << 1)
 359#define ARMV6_PMCR_CCOUNT_RESET         (1 << 2)
 360#define ARMV6_PMCR_CCOUNT_DIV           (1 << 3)
 361#define ARMV6_PMCR_COUNT0_IEN           (1 << 4)
 362#define ARMV6_PMCR_COUNT1_IEN           (1 << 5)
 363#define ARMV6_PMCR_CCOUNT_IEN           (1 << 6)
 364#define ARMV6_PMCR_COUNT0_OVERFLOW      (1 << 8)
 365#define ARMV6_PMCR_COUNT1_OVERFLOW      (1 << 9)
 366#define ARMV6_PMCR_CCOUNT_OVERFLOW      (1 << 10)
 367#define ARMV6_PMCR_EVT_COUNT0_SHIFT     20
 368#define ARMV6_PMCR_EVT_COUNT0_MASK      (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
 369#define ARMV6_PMCR_EVT_COUNT1_SHIFT     12
 370#define ARMV6_PMCR_EVT_COUNT1_MASK      (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
 371
 372#define ARMV6_PMCR_OVERFLOWED_MASK \
 373        (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
 374         ARMV6_PMCR_CCOUNT_OVERFLOW)
 375
 376static inline int
 377armv6_pmcr_has_overflowed(unsigned long pmcr)
 378{
 379        return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
 380}
 381
 382static inline int
 383armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
 384                                  enum armv6_counters counter)
 385{
 386        int ret = 0;
 387
 388        if (ARMV6_CYCLE_COUNTER == counter)
 389                ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
 390        else if (ARMV6_COUNTER0 == counter)
 391                ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
 392        else if (ARMV6_COUNTER1 == counter)
 393                ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
 394        else
 395                WARN_ONCE(1, "invalid counter number (%d)\n", counter);
 396
 397        return ret;
 398}
 399
 400static inline u32
 401armv6pmu_read_counter(int counter)
 402{
 403        unsigned long value = 0;
 404
 405        if (ARMV6_CYCLE_COUNTER == counter)
 406                asm volatile("mrc   p15, 0, %0, c15, c12, 1" : "=r"(value));
 407        else if (ARMV6_COUNTER0 == counter)
 408                asm volatile("mrc   p15, 0, %0, c15, c12, 2" : "=r"(value));
 409        else if (ARMV6_COUNTER1 == counter)
 410                asm volatile("mrc   p15, 0, %0, c15, c12, 3" : "=r"(value));
 411        else
 412                WARN_ONCE(1, "invalid counter number (%d)\n", counter);
 413
 414        return value;
 415}
 416
 417static inline void
 418armv6pmu_write_counter(int counter,
 419                       u32 value)
 420{
 421        if (ARMV6_CYCLE_COUNTER == counter)
 422                asm volatile("mcr   p15, 0, %0, c15, c12, 1" : : "r"(value));
 423        else if (ARMV6_COUNTER0 == counter)
 424                asm volatile("mcr   p15, 0, %0, c15, c12, 2" : : "r"(value));
 425        else if (ARMV6_COUNTER1 == counter)
 426                asm volatile("mcr   p15, 0, %0, c15, c12, 3" : : "r"(value));
 427        else
 428                WARN_ONCE(1, "invalid counter number (%d)\n", counter);
 429}
 430
 431static void
 432armv6pmu_enable_event(struct hw_perf_event *hwc,
 433                      int idx)
 434{
 435        unsigned long val, mask, evt, flags;
 436        struct pmu_hw_events *events = cpu_pmu->get_hw_events();
 437
 438        if (ARMV6_CYCLE_COUNTER == idx) {
 439                mask    = 0;
 440                evt     = ARMV6_PMCR_CCOUNT_IEN;
 441        } else if (ARMV6_COUNTER0 == idx) {
 442                mask    = ARMV6_PMCR_EVT_COUNT0_MASK;
 443                evt     = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
 444                          ARMV6_PMCR_COUNT0_IEN;
 445        } else if (ARMV6_COUNTER1 == idx) {
 446                mask    = ARMV6_PMCR_EVT_COUNT1_MASK;
 447                evt     = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
 448                          ARMV6_PMCR_COUNT1_IEN;
 449        } else {
 450                WARN_ONCE(1, "invalid counter number (%d)\n", idx);
 451                return;
 452        }
 453
 454        /*
 455         * Mask out the current event and set the counter to count the event
 456         * that we're interested in.
 457         */
 458        raw_spin_lock_irqsave(&events->pmu_lock, flags);
 459        val = armv6_pmcr_read();
 460        val &= ~mask;
 461        val |= evt;
 462        armv6_pmcr_write(val);
 463        raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 464}
 465
 466static int counter_is_active(unsigned long pmcr, int idx)
 467{
 468        unsigned long mask = 0;
 469        if (idx == ARMV6_CYCLE_COUNTER)
 470                mask = ARMV6_PMCR_CCOUNT_IEN;
 471        else if (idx == ARMV6_COUNTER0)
 472                mask = ARMV6_PMCR_COUNT0_IEN;
 473        else if (idx == ARMV6_COUNTER1)
 474                mask = ARMV6_PMCR_COUNT1_IEN;
 475
 476        if (mask)
 477                return pmcr & mask;
 478
 479        WARN_ONCE(1, "invalid counter number (%d)\n", idx);
 480        return 0;
 481}
 482
 483static irqreturn_t
 484armv6pmu_handle_irq(int irq_num,
 485                    void *dev)
 486{
 487        unsigned long pmcr = armv6_pmcr_read();
 488        struct perf_sample_data data;
 489        struct pmu_hw_events *cpuc;
 490        struct pt_regs *regs;
 491        int idx;
 492
 493        if (!armv6_pmcr_has_overflowed(pmcr))
 494                return IRQ_NONE;
 495
 496        regs = get_irq_regs();
 497
 498        /*
 499         * The interrupts are cleared by writing the overflow flags back to
 500         * the control register. All of the other bits don't have any effect
 501         * if they are rewritten, so write the whole value back.
 502         */
 503        armv6_pmcr_write(pmcr);
 504
 505        perf_sample_data_init(&data, 0);
 506
 507        cpuc = &__get_cpu_var(cpu_hw_events);
 508        for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
 509                struct perf_event *event = cpuc->events[idx];
 510                struct hw_perf_event *hwc;
 511
 512                if (!counter_is_active(pmcr, idx))
 513                        continue;
 514
 515                /*
 516                 * We have a single interrupt for all counters. Check that
 517                 * each counter has overflowed before we process it.
 518                 */
 519                if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
 520                        continue;
 521
 522                hwc = &event->hw;
 523                armpmu_event_update(event, hwc, idx, 1);
 524                data.period = event->hw.last_period;
 525                if (!armpmu_event_set_period(event, hwc, idx))
 526                        continue;
 527
 528                if (perf_event_overflow(event, &data, regs))
 529                        cpu_pmu->disable(hwc, idx);
 530        }
 531
 532        /*
 533         * Handle the pending perf events.
 534         *
 535         * Note: this call *must* be run with interrupts disabled. For
 536         * platforms that can have the PMU interrupts raised as an NMI, this
 537         * will not work.
 538         */
 539        irq_work_run();
 540
 541        return IRQ_HANDLED;
 542}
 543
 544static void
 545armv6pmu_start(void)
 546{
 547        unsigned long flags, val;
 548        struct pmu_hw_events *events = cpu_pmu->get_hw_events();
 549
 550        raw_spin_lock_irqsave(&events->pmu_lock, flags);
 551        val = armv6_pmcr_read();
 552        val |= ARMV6_PMCR_ENABLE;
 553        armv6_pmcr_write(val);
 554        raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 555}
 556
 557static void
 558armv6pmu_stop(void)
 559{
 560        unsigned long flags, val;
 561        struct pmu_hw_events *events = cpu_pmu->get_hw_events();
 562
 563        raw_spin_lock_irqsave(&events->pmu_lock, flags);
 564        val = armv6_pmcr_read();
 565        val &= ~ARMV6_PMCR_ENABLE;
 566        armv6_pmcr_write(val);
 567        raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 568}
 569
 570static int
 571armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,
 572                       struct hw_perf_event *event)
 573{
 574        /* Always place a cycle counter into the cycle counter. */
 575        if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
 576                if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
 577                        return -EAGAIN;
 578
 579                return ARMV6_CYCLE_COUNTER;
 580        } else {
 581                /*
 582                 * For anything other than a cycle counter, try and use
 583                 * counter0 and counter1.
 584                 */
 585                if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
 586                        return ARMV6_COUNTER1;
 587
 588                if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
 589                        return ARMV6_COUNTER0;
 590
 591                /* The counters are all in use. */
 592                return -EAGAIN;
 593        }
 594}
 595
 596static void
 597armv6pmu_disable_event(struct hw_perf_event *hwc,
 598                       int idx)
 599{
 600        unsigned long val, mask, evt, flags;
 601        struct pmu_hw_events *events = cpu_pmu->get_hw_events();
 602
 603        if (ARMV6_CYCLE_COUNTER == idx) {
 604                mask    = ARMV6_PMCR_CCOUNT_IEN;
 605                evt     = 0;
 606        } else if (ARMV6_COUNTER0 == idx) {
 607                mask    = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
 608                evt     = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
 609        } else if (ARMV6_COUNTER1 == idx) {
 610                mask    = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
 611                evt     = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
 612        } else {
 613                WARN_ONCE(1, "invalid counter number (%d)\n", idx);
 614                return;
 615        }
 616
 617        /*
 618         * Mask out the current event and set the counter to count the number
 619         * of ETM bus signal assertion cycles. The external reporting should
 620         * be disabled and so this should never increment.
 621         */
 622        raw_spin_lock_irqsave(&events->pmu_lock, flags);
 623        val = armv6_pmcr_read();
 624        val &= ~mask;
 625        val |= evt;
 626        armv6_pmcr_write(val);
 627        raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 628}
 629
 630static void
 631armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
 632                              int idx)
 633{
 634        unsigned long val, mask, flags, evt = 0;
 635        struct pmu_hw_events *events = cpu_pmu->get_hw_events();
 636
 637        if (ARMV6_CYCLE_COUNTER == idx) {
 638                mask    = ARMV6_PMCR_CCOUNT_IEN;
 639        } else if (ARMV6_COUNTER0 == idx) {
 640                mask    = ARMV6_PMCR_COUNT0_IEN;
 641        } else if (ARMV6_COUNTER1 == idx) {
 642                mask    = ARMV6_PMCR_COUNT1_IEN;
 643        } else {
 644                WARN_ONCE(1, "invalid counter number (%d)\n", idx);
 645                return;
 646        }
 647
 648        /*
 649         * Unlike UP ARMv6, we don't have a way of stopping the counters. We
 650         * simply disable the interrupt reporting.
 651         */
 652        raw_spin_lock_irqsave(&events->pmu_lock, flags);
 653        val = armv6_pmcr_read();
 654        val &= ~mask;
 655        val |= evt;
 656        armv6_pmcr_write(val);
 657        raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 658}
 659
 660static int armv6_map_event(struct perf_event *event)
 661{
 662        return map_cpu_event(event, &armv6_perf_map,
 663                                &armv6_perf_cache_map, 0xFF);
 664}
 665
 666static struct arm_pmu armv6pmu = {
 667        .id                     = ARM_PERF_PMU_ID_V6,
 668        .name                   = "v6",
 669        .handle_irq             = armv6pmu_handle_irq,
 670        .enable                 = armv6pmu_enable_event,
 671        .disable                = armv6pmu_disable_event,
 672        .read_counter           = armv6pmu_read_counter,
 673        .write_counter          = armv6pmu_write_counter,
 674        .get_event_idx          = armv6pmu_get_event_idx,
 675        .start                  = armv6pmu_start,
 676        .stop                   = armv6pmu_stop,
 677        .map_event              = armv6_map_event,
 678        .num_events             = 3,
 679        .max_period             = (1LLU << 32) - 1,
 680};
 681
 682static struct arm_pmu *__init armv6pmu_init(void)
 683{
 684        return &armv6pmu;
 685}
 686
 687/*
 688 * ARMv6mpcore is almost identical to single core ARMv6 with the exception
 689 * that some of the events have different enumerations and that there is no
 690 * *hack* to stop the programmable counters. To stop the counters we simply
 691 * disable the interrupt reporting and update the event. When unthrottling we
 692 * reset the period and enable the interrupt reporting.
 693 */
 694
 695static int armv6mpcore_map_event(struct perf_event *event)
 696{
 697        return map_cpu_event(event, &armv6mpcore_perf_map,
 698                                &armv6mpcore_perf_cache_map, 0xFF);
 699}
 700
 701static struct arm_pmu armv6mpcore_pmu = {
 702        .id                     = ARM_PERF_PMU_ID_V6MP,
 703        .name                   = "v6mpcore",
 704        .handle_irq             = armv6pmu_handle_irq,
 705        .enable                 = armv6pmu_enable_event,
 706        .disable                = armv6mpcore_pmu_disable_event,
 707        .read_counter           = armv6pmu_read_counter,
 708        .write_counter          = armv6pmu_write_counter,
 709        .get_event_idx          = armv6pmu_get_event_idx,
 710        .start                  = armv6pmu_start,
 711        .stop                   = armv6pmu_stop,
 712        .map_event              = armv6mpcore_map_event,
 713        .num_events             = 3,
 714        .max_period             = (1LLU << 32) - 1,
 715};
 716
 717static struct arm_pmu *__init armv6mpcore_pmu_init(void)
 718{
 719        return &armv6mpcore_pmu;
 720}
 721#else
 722static struct arm_pmu *__init armv6pmu_init(void)
 723{
 724        return NULL;
 725}
 726
 727static struct arm_pmu *__init armv6mpcore_pmu_init(void)
 728{
 729        return NULL;
 730}
 731#endif  /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
 732