linux/arch/powerpc/kernel/power6-pmu.c
<<
>>
Prefs
   1/*
   2 * Performance counter support for POWER6 processors.
   3 *
   4 * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11#include <linux/kernel.h>
  12#include <linux/perf_event.h>
  13#include <linux/string.h>
  14#include <asm/reg.h>
  15#include <asm/cputable.h>
  16
  17/*
  18 * Bits in event code for POWER6
  19 */
  20#define PM_PMC_SH       20      /* PMC number (1-based) for direct events */
  21#define PM_PMC_MSK      0x7
  22#define PM_PMC_MSKS     (PM_PMC_MSK << PM_PMC_SH)
  23#define PM_UNIT_SH      16      /* Unit event comes (TTMxSEL encoding) */
  24#define PM_UNIT_MSK     0xf
  25#define PM_UNIT_MSKS    (PM_UNIT_MSK << PM_UNIT_SH)
  26#define PM_LLAV         0x8000  /* Load lookahead match value */
  27#define PM_LLA          0x4000  /* Load lookahead match enable */
  28#define PM_BYTE_SH      12      /* Byte of event bus to use */
  29#define PM_BYTE_MSK     3
  30#define PM_SUBUNIT_SH   8       /* Subunit event comes from (NEST_SEL enc.) */
  31#define PM_SUBUNIT_MSK  7
  32#define PM_SUBUNIT_MSKS (PM_SUBUNIT_MSK << PM_SUBUNIT_SH)
  33#define PM_PMCSEL_MSK   0xff    /* PMCxSEL value */
  34#define PM_BUSEVENT_MSK 0xf3700
  35
  36/*
  37 * Bits in MMCR1 for POWER6
  38 */
  39#define MMCR1_TTM0SEL_SH        60
  40#define MMCR1_TTMSEL_SH(n)      (MMCR1_TTM0SEL_SH - (n) * 4)
  41#define MMCR1_TTMSEL_MSK        0xf
  42#define MMCR1_TTMSEL(m, n)      (((m) >> MMCR1_TTMSEL_SH(n)) & MMCR1_TTMSEL_MSK)
  43#define MMCR1_NESTSEL_SH        45
  44#define MMCR1_NESTSEL_MSK       0x7
  45#define MMCR1_NESTSEL(m)        (((m) >> MMCR1_NESTSEL_SH) & MMCR1_NESTSEL_MSK)
  46#define MMCR1_PMC1_LLA          (1ul << 44)
  47#define MMCR1_PMC1_LLA_VALUE    (1ul << 39)
  48#define MMCR1_PMC1_ADDR_SEL     (1ul << 35)
  49#define MMCR1_PMC1SEL_SH        24
  50#define MMCR1_PMCSEL_SH(n)      (MMCR1_PMC1SEL_SH - (n) * 8)
  51#define MMCR1_PMCSEL_MSK        0xff
  52
  53/*
  54 * Map of which direct events on which PMCs are marked instruction events.
  55 * Indexed by PMCSEL value >> 1.
  56 * Bottom 4 bits are a map of which PMCs are interesting,
  57 * top 4 bits say what sort of event:
  58 *   0 = direct marked event,
  59 *   1 = byte decode event,
  60 *   4 = add/and event (PMC1 -> bits 0 & 4),
  61 *   5 = add/and event (PMC1 -> bits 1 & 5),
  62 *   6 = add/and event (PMC1 -> bits 2 & 6),
  63 *   7 = add/and event (PMC1 -> bits 3 & 7).
  64 */
  65static unsigned char direct_event_is_marked[0x60 >> 1] = {
  66        0,      /* 00 */
  67        0,      /* 02 */
  68        0,      /* 04 */
  69        0x07,   /* 06 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */
  70        0x04,   /* 08 PM_MRK_DFU_FIN */
  71        0x06,   /* 0a PM_MRK_IFU_FIN, PM_MRK_INST_FIN */
  72        0,      /* 0c */
  73        0,      /* 0e */
  74        0x02,   /* 10 PM_MRK_INST_DISP */
  75        0x08,   /* 12 PM_MRK_LSU_DERAT_MISS */
  76        0,      /* 14 */
  77        0,      /* 16 */
  78        0x0c,   /* 18 PM_THRESH_TIMEO, PM_MRK_INST_FIN */
  79        0x0f,   /* 1a PM_MRK_INST_DISP, PM_MRK_{FXU,FPU,LSU}_FIN */
  80        0x01,   /* 1c PM_MRK_INST_ISSUED */
  81        0,      /* 1e */
  82        0,      /* 20 */
  83        0,      /* 22 */
  84        0,      /* 24 */
  85        0,      /* 26 */
  86        0x15,   /* 28 PM_MRK_DATA_FROM_L2MISS, PM_MRK_DATA_FROM_L3MISS */
  87        0,      /* 2a */
  88        0,      /* 2c */
  89        0,      /* 2e */
  90        0x4f,   /* 30 */
  91        0x7f,   /* 32 */
  92        0x4f,   /* 34 */
  93        0x5f,   /* 36 */
  94        0x6f,   /* 38 */
  95        0x4f,   /* 3a */
  96        0,      /* 3c */
  97        0x08,   /* 3e PM_MRK_INST_TIMEO */
  98        0x1f,   /* 40 */
  99        0x1f,   /* 42 */
 100        0x1f,   /* 44 */
 101        0x1f,   /* 46 */
 102        0x1f,   /* 48 */
 103        0x1f,   /* 4a */
 104        0x1f,   /* 4c */
 105        0x1f,   /* 4e */
 106        0,      /* 50 */
 107        0x05,   /* 52 PM_MRK_BR_TAKEN, PM_MRK_BR_MPRED */
 108        0x1c,   /* 54 PM_MRK_PTEG_FROM_L3MISS, PM_MRK_PTEG_FROM_L2MISS */
 109        0x02,   /* 56 PM_MRK_LD_MISS_L1 */
 110        0,      /* 58 */
 111        0,      /* 5a */
 112        0,      /* 5c */
 113        0,      /* 5e */
 114};
 115
 116/*
 117 * Masks showing for each unit which bits are marked events.
 118 * These masks are in LE order, i.e. 0x00000001 is byte 0, bit 0.
 119 */
 120static u32 marked_bus_events[16] = {
 121        0x01000000,     /* direct events set 1: byte 3 bit 0 */
 122        0x00010000,     /* direct events set 2: byte 2 bit 0 */
 123        0, 0, 0, 0,     /* IDU, IFU, nest: nothing */
 124        0x00000088,     /* VMX set 1: byte 0 bits 3, 7 */
 125        0x000000c0,     /* VMX set 2: byte 0 bits 4-7 */
 126        0x04010000,     /* LSU set 1: byte 2 bit 0, byte 3 bit 2 */
 127        0xff010000u,    /* LSU set 2: byte 2 bit 0, all of byte 3 */
 128        0,              /* LSU set 3 */
 129        0x00000010,     /* VMX set 3: byte 0 bit 4 */
 130        0,              /* BFP set 1 */
 131        0x00000022,     /* BFP set 2: byte 0 bits 1, 5 */
 132        0, 0
 133};
 134        
 135/*
 136 * Returns 1 if event counts things relating to marked instructions
 137 * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not.
 138 */
 139static int power6_marked_instr_event(u64 event)
 140{
 141        int pmc, psel, ptype;
 142        int bit, byte, unit;
 143        u32 mask;
 144
 145        pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
 146        psel = (event & PM_PMCSEL_MSK) >> 1;    /* drop edge/level bit */
 147        if (pmc >= 5)
 148                return 0;
 149
 150        bit = -1;
 151        if (psel < sizeof(direct_event_is_marked)) {
 152                ptype = direct_event_is_marked[psel];
 153                if (pmc == 0 || !(ptype & (1 << (pmc - 1))))
 154                        return 0;
 155                ptype >>= 4;
 156                if (ptype == 0)
 157                        return 1;
 158                if (ptype == 1)
 159                        bit = 0;
 160                else
 161                        bit = ptype ^ (pmc - 1);
 162        } else if ((psel & 0x48) == 0x40)
 163                bit = psel & 7;
 164
 165        if (!(event & PM_BUSEVENT_MSK) || bit == -1)
 166                return 0;
 167
 168        byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
 169        unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
 170        mask = marked_bus_events[unit];
 171        return (mask >> (byte * 8 + bit)) & 1;
 172}
 173
 174/*
 175 * Assign PMC numbers and compute MMCR1 value for a set of events
 176 */
 177static int p6_compute_mmcr(u64 event[], int n_ev,
 178                           unsigned int hwc[], unsigned long mmcr[])
 179{
 180        unsigned long mmcr1 = 0;
 181        unsigned long mmcra = 0;
 182        int i;
 183        unsigned int pmc, ev, b, u, s, psel;
 184        unsigned int ttmset = 0;
 185        unsigned int pmc_inuse = 0;
 186
 187        if (n_ev > 6)
 188                return -1;
 189        for (i = 0; i < n_ev; ++i) {
 190                pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
 191                if (pmc) {
 192                        if (pmc_inuse & (1 << (pmc - 1)))
 193                                return -1;      /* collision! */
 194                        pmc_inuse |= 1 << (pmc - 1);
 195                }
 196        }
 197        for (i = 0; i < n_ev; ++i) {
 198                ev = event[i];
 199                pmc = (ev >> PM_PMC_SH) & PM_PMC_MSK;
 200                if (pmc) {
 201                        --pmc;
 202                } else {
 203                        /* can go on any PMC; find a free one */
 204                        for (pmc = 0; pmc < 4; ++pmc)
 205                                if (!(pmc_inuse & (1 << pmc)))
 206                                        break;
 207                        if (pmc >= 4)
 208                                return -1;
 209                        pmc_inuse |= 1 << pmc;
 210                }
 211                hwc[i] = pmc;
 212                psel = ev & PM_PMCSEL_MSK;
 213                if (ev & PM_BUSEVENT_MSK) {
 214                        /* this event uses the event bus */
 215                        b = (ev >> PM_BYTE_SH) & PM_BYTE_MSK;
 216                        u = (ev >> PM_UNIT_SH) & PM_UNIT_MSK;
 217                        /* check for conflict on this byte of event bus */
 218                        if ((ttmset & (1 << b)) && MMCR1_TTMSEL(mmcr1, b) != u)
 219                                return -1;
 220                        mmcr1 |= (unsigned long)u << MMCR1_TTMSEL_SH(b);
 221                        ttmset |= 1 << b;
 222                        if (u == 5) {
 223                                /* Nest events have a further mux */
 224                                s = (ev >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK;
 225                                if ((ttmset & 0x10) &&
 226                                    MMCR1_NESTSEL(mmcr1) != s)
 227                                        return -1;
 228                                ttmset |= 0x10;
 229                                mmcr1 |= (unsigned long)s << MMCR1_NESTSEL_SH;
 230                        }
 231                        if (0x30 <= psel && psel <= 0x3d) {
 232                                /* these need the PMCx_ADDR_SEL bits */
 233                                if (b >= 2)
 234                                        mmcr1 |= MMCR1_PMC1_ADDR_SEL >> pmc;
 235                        }
 236                        /* bus select values are different for PMC3/4 */
 237                        if (pmc >= 2 && (psel & 0x90) == 0x80)
 238                                psel ^= 0x20;
 239                }
 240                if (ev & PM_LLA) {
 241                        mmcr1 |= MMCR1_PMC1_LLA >> pmc;
 242                        if (ev & PM_LLAV)
 243                                mmcr1 |= MMCR1_PMC1_LLA_VALUE >> pmc;
 244                }
 245                if (power6_marked_instr_event(event[i]))
 246                        mmcra |= MMCRA_SAMPLE_ENABLE;
 247                if (pmc < 4)
 248                        mmcr1 |= (unsigned long)psel << MMCR1_PMCSEL_SH(pmc);
 249        }
 250        mmcr[0] = 0;
 251        if (pmc_inuse & 1)
 252                mmcr[0] = MMCR0_PMC1CE;
 253        if (pmc_inuse & 0xe)
 254                mmcr[0] |= MMCR0_PMCjCE;
 255        mmcr[1] = mmcr1;
 256        mmcr[2] = mmcra;
 257        return 0;
 258}
 259
 260/*
 261 * Layout of constraint bits:
 262 *
 263 *      0-1     add field: number of uses of PMC1 (max 1)
 264 *      2-3, 4-5, 6-7, 8-9, 10-11: ditto for PMC2, 3, 4, 5, 6
 265 *      12-15   add field: number of uses of PMC1-4 (max 4)
 266 *      16-19   select field: unit on byte 0 of event bus
 267 *      20-23, 24-27, 28-31 ditto for bytes 1, 2, 3
 268 *      32-34   select field: nest (subunit) event selector
 269 */
 270static int p6_get_constraint(u64 event, unsigned long *maskp,
 271                             unsigned long *valp)
 272{
 273        int pmc, byte, sh, subunit;
 274        unsigned long mask = 0, value = 0;
 275
 276        pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
 277        if (pmc) {
 278                if (pmc > 4 && !(event == 0x500009 || event == 0x600005))
 279                        return -1;
 280                sh = (pmc - 1) * 2;
 281                mask |= 2 << sh;
 282                value |= 1 << sh;
 283        }
 284        if (event & PM_BUSEVENT_MSK) {
 285                byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
 286                sh = byte * 4 + (16 - PM_UNIT_SH);
 287                mask |= PM_UNIT_MSKS << sh;
 288                value |= (unsigned long)(event & PM_UNIT_MSKS) << sh;
 289                if ((event & PM_UNIT_MSKS) == (5 << PM_UNIT_SH)) {
 290                        subunit = (event >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK;
 291                        mask  |= (unsigned long)PM_SUBUNIT_MSK << 32;
 292                        value |= (unsigned long)subunit << 32;
 293                }
 294        }
 295        if (pmc <= 4) {
 296                mask  |= 0x8000;        /* add field for count of PMC1-4 uses */
 297                value |= 0x1000;
 298        }
 299        *maskp = mask;
 300        *valp = value;
 301        return 0;
 302}
 303
 304static int p6_limited_pmc_event(u64 event)
 305{
 306        int pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
 307
 308        return pmc == 5 || pmc == 6;
 309}
 310
 311#define MAX_ALT 4       /* at most 4 alternatives for any event */
 312
 313static const unsigned int event_alternatives[][MAX_ALT] = {
 314        { 0x0130e8, 0x2000f6, 0x3000fc },       /* PM_PTEG_RELOAD_VALID */
 315        { 0x080080, 0x10000d, 0x30000c, 0x4000f0 }, /* PM_LD_MISS_L1 */
 316        { 0x080088, 0x200054, 0x3000f0 },       /* PM_ST_MISS_L1 */
 317        { 0x10000a, 0x2000f4, 0x600005 },       /* PM_RUN_CYC */
 318        { 0x10000b, 0x2000f5 },                 /* PM_RUN_COUNT */
 319        { 0x10000e, 0x400010 },                 /* PM_PURR */
 320        { 0x100010, 0x4000f8 },                 /* PM_FLUSH */
 321        { 0x10001a, 0x200010 },                 /* PM_MRK_INST_DISP */
 322        { 0x100026, 0x3000f8 },                 /* PM_TB_BIT_TRANS */
 323        { 0x100054, 0x2000f0 },                 /* PM_ST_FIN */
 324        { 0x100056, 0x2000fc },                 /* PM_L1_ICACHE_MISS */
 325        { 0x1000f0, 0x40000a },                 /* PM_INST_IMC_MATCH_CMPL */
 326        { 0x1000f8, 0x200008 },                 /* PM_GCT_EMPTY_CYC */
 327        { 0x1000fc, 0x400006 },                 /* PM_LSU_DERAT_MISS_CYC */
 328        { 0x20000e, 0x400007 },                 /* PM_LSU_DERAT_MISS */
 329        { 0x200012, 0x300012 },                 /* PM_INST_DISP */
 330        { 0x2000f2, 0x3000f2 },                 /* PM_INST_DISP */
 331        { 0x2000f8, 0x300010 },                 /* PM_EXT_INT */
 332        { 0x2000fe, 0x300056 },                 /* PM_DATA_FROM_L2MISS */
 333        { 0x2d0030, 0x30001a },                 /* PM_MRK_FPU_FIN */
 334        { 0x30000a, 0x400018 },                 /* PM_MRK_INST_FIN */
 335        { 0x3000f6, 0x40000e },                 /* PM_L1_DCACHE_RELOAD_VALID */
 336        { 0x3000fe, 0x400056 },                 /* PM_DATA_FROM_L3MISS */
 337};
 338
 339/*
 340 * This could be made more efficient with a binary search on
 341 * a presorted list, if necessary
 342 */
 343static int find_alternatives_list(u64 event)
 344{
 345        int i, j;
 346        unsigned int alt;
 347
 348        for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) {
 349                if (event < event_alternatives[i][0])
 350                        return -1;
 351                for (j = 0; j < MAX_ALT; ++j) {
 352                        alt = event_alternatives[i][j];
 353                        if (!alt || event < alt)
 354                                break;
 355                        if (event == alt)
 356                                return i;
 357                }
 358        }
 359        return -1;
 360}
 361
 362static int p6_get_alternatives(u64 event, unsigned int flags, u64 alt[])
 363{
 364        int i, j, nlim;
 365        unsigned int psel, pmc;
 366        unsigned int nalt = 1;
 367        u64 aevent;
 368
 369        alt[0] = event;
 370        nlim = p6_limited_pmc_event(event);
 371
 372        /* check the alternatives table */
 373        i = find_alternatives_list(event);
 374        if (i >= 0) {
 375                /* copy out alternatives from list */
 376                for (j = 0; j < MAX_ALT; ++j) {
 377                        aevent = event_alternatives[i][j];
 378                        if (!aevent)
 379                                break;
 380                        if (aevent != event)
 381                                alt[nalt++] = aevent;
 382                        nlim += p6_limited_pmc_event(aevent);
 383                }
 384
 385        } else {
 386                /* Check for alternative ways of computing sum events */
 387                /* PMCSEL 0x32 counter N == PMCSEL 0x34 counter 5-N */
 388                psel = event & (PM_PMCSEL_MSK & ~1);    /* ignore edge bit */
 389                pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
 390                if (pmc && (psel == 0x32 || psel == 0x34))
 391                        alt[nalt++] = ((event ^ 0x6) & ~PM_PMC_MSKS) |
 392                                ((5 - pmc) << PM_PMC_SH);
 393
 394                /* PMCSEL 0x38 counter N == PMCSEL 0x3a counter N+/-2 */
 395                if (pmc && (psel == 0x38 || psel == 0x3a))
 396                        alt[nalt++] = ((event ^ 0x2) & ~PM_PMC_MSKS) |
 397                                ((pmc > 2? pmc - 2: pmc + 2) << PM_PMC_SH);
 398        }
 399
 400        if (flags & PPMU_ONLY_COUNT_RUN) {
 401                /*
 402                 * We're only counting in RUN state,
 403                 * so PM_CYC is equivalent to PM_RUN_CYC,
 404                 * PM_INST_CMPL === PM_RUN_INST_CMPL, PM_PURR === PM_RUN_PURR.
 405                 * This doesn't include alternatives that don't provide
 406                 * any extra flexibility in assigning PMCs (e.g.
 407                 * 0x10000a for PM_RUN_CYC vs. 0x1e for PM_CYC).
 408                 * Note that even with these additional alternatives
 409                 * we never end up with more than 4 alternatives for any event.
 410                 */
 411                j = nalt;
 412                for (i = 0; i < nalt; ++i) {
 413                        switch (alt[i]) {
 414                        case 0x1e:      /* PM_CYC */
 415                                alt[j++] = 0x600005;    /* PM_RUN_CYC */
 416                                ++nlim;
 417                                break;
 418                        case 0x10000a:  /* PM_RUN_CYC */
 419                                alt[j++] = 0x1e;        /* PM_CYC */
 420                                break;
 421                        case 2:         /* PM_INST_CMPL */
 422                                alt[j++] = 0x500009;    /* PM_RUN_INST_CMPL */
 423                                ++nlim;
 424                                break;
 425                        case 0x500009:  /* PM_RUN_INST_CMPL */
 426                                alt[j++] = 2;           /* PM_INST_CMPL */
 427                                break;
 428                        case 0x10000e:  /* PM_PURR */
 429                                alt[j++] = 0x4000f4;    /* PM_RUN_PURR */
 430                                break;
 431                        case 0x4000f4:  /* PM_RUN_PURR */
 432                                alt[j++] = 0x10000e;    /* PM_PURR */
 433                                break;
 434                        }
 435                }
 436                nalt = j;
 437        }
 438
 439        if (!(flags & PPMU_LIMITED_PMC_OK) && nlim) {
 440                /* remove the limited PMC events */
 441                j = 0;
 442                for (i = 0; i < nalt; ++i) {
 443                        if (!p6_limited_pmc_event(alt[i])) {
 444                                alt[j] = alt[i];
 445                                ++j;
 446                        }
 447                }
 448                nalt = j;
 449        } else if ((flags & PPMU_LIMITED_PMC_REQD) && nlim < nalt) {
 450                /* remove all but the limited PMC events */
 451                j = 0;
 452                for (i = 0; i < nalt; ++i) {
 453                        if (p6_limited_pmc_event(alt[i])) {
 454                                alt[j] = alt[i];
 455                                ++j;
 456                        }
 457                }
 458                nalt = j;
 459        }
 460
 461        return nalt;
 462}
 463
 464static void p6_disable_pmc(unsigned int pmc, unsigned long mmcr[])
 465{
 466        /* Set PMCxSEL to 0 to disable PMCx */
 467        if (pmc <= 3)
 468                mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SH(pmc));
 469}
 470
 471static int power6_generic_events[] = {
 472        [PERF_COUNT_HW_CPU_CYCLES]              = 0x1e,
 473        [PERF_COUNT_HW_INSTRUCTIONS]            = 2,
 474        [PERF_COUNT_HW_CACHE_REFERENCES]        = 0x280030, /* LD_REF_L1 */
 475        [PERF_COUNT_HW_CACHE_MISSES]            = 0x30000c, /* LD_MISS_L1 */
 476        [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = 0x410a0,  /* BR_PRED */
 477        [PERF_COUNT_HW_BRANCH_MISSES]           = 0x400052, /* BR_MPRED */
 478};
 479
 480#define C(x)    PERF_COUNT_HW_CACHE_##x
 481
 482/*
 483 * Table of generalized cache-related events.
 484 * 0 means not supported, -1 means nonsensical, other values
 485 * are event codes.
 486 * The "DTLB" and "ITLB" events relate to the DERAT and IERAT.
 487 */
 488static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
 489        [C(L1D)] = {            /*      RESULT_ACCESS   RESULT_MISS */
 490                [C(OP_READ)] = {        0x80082,        0x80080         },
 491                [C(OP_WRITE)] = {       0x80086,        0x80088         },
 492                [C(OP_PREFETCH)] = {    0x810a4,        0               },
 493        },
 494        [C(L1I)] = {            /*      RESULT_ACCESS   RESULT_MISS */
 495                [C(OP_READ)] = {        0,              0x100056        },
 496                [C(OP_WRITE)] = {       -1,             -1              },
 497                [C(OP_PREFETCH)] = {    0x4008c,        0               },
 498        },
 499        [C(LL)] = {             /*      RESULT_ACCESS   RESULT_MISS */
 500                [C(OP_READ)] = {        0x150730,       0x250532        },
 501                [C(OP_WRITE)] = {       0x250432,       0x150432        },
 502                [C(OP_PREFETCH)] = {    0x810a6,        0               },
 503        },
 504        [C(DTLB)] = {           /*      RESULT_ACCESS   RESULT_MISS */
 505                [C(OP_READ)] = {        0,              0x20000e        },
 506                [C(OP_WRITE)] = {       -1,             -1              },
 507                [C(OP_PREFETCH)] = {    -1,             -1              },
 508        },
 509        [C(ITLB)] = {           /*      RESULT_ACCESS   RESULT_MISS */
 510                [C(OP_READ)] = {        0,              0x420ce         },
 511                [C(OP_WRITE)] = {       -1,             -1              },
 512                [C(OP_PREFETCH)] = {    -1,             -1              },
 513        },
 514        [C(BPU)] = {            /*      RESULT_ACCESS   RESULT_MISS */
 515                [C(OP_READ)] = {        0x430e6,        0x400052        },
 516                [C(OP_WRITE)] = {       -1,             -1              },
 517                [C(OP_PREFETCH)] = {    -1,             -1              },
 518        },
 519};
 520
 521static struct power_pmu power6_pmu = {
 522        .name                   = "POWER6",
 523        .n_counter              = 6,
 524        .max_alternatives       = MAX_ALT,
 525        .add_fields             = 0x1555,
 526        .test_adder             = 0x3000,
 527        .compute_mmcr           = p6_compute_mmcr,
 528        .get_constraint         = p6_get_constraint,
 529        .get_alternatives       = p6_get_alternatives,
 530        .disable_pmc            = p6_disable_pmc,
 531        .limited_pmc_event      = p6_limited_pmc_event,
 532        .flags                  = PPMU_LIMITED_PMC5_6 | PPMU_ALT_SIPR,
 533        .n_generic              = ARRAY_SIZE(power6_generic_events),
 534        .generic_events         = power6_generic_events,
 535        .cache_events           = &power6_cache_events,
 536};
 537
 538static int init_power6_pmu(void)
 539{
 540        if (!cur_cpu_spec->oprofile_cpu_type ||
 541            strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power6"))
 542                return -ENODEV;
 543
 544        return register_power_pmu(&power6_pmu);
 545}
 546
 547arch_initcall(init_power6_pmu);
 548