This source file includes following definitions.
- p970_marked_instr_event
- p970_get_constraint
- p970_get_alternatives
- p970_compute_mmcr
- p970_disable_pmc
- init_ppc970_pmu
   1 
   2 
   3 
   4 
   5 
   6 
   7 #include <linux/string.h>
   8 #include <linux/perf_event.h>
   9 #include <asm/reg.h>
  10 #include <asm/cputable.h>
  11 
  12 
  13 
  14 
  15 #define PM_PMC_SH       12      
  16 #define PM_PMC_MSK      0xf
  17 #define PM_UNIT_SH      8       
  18 #define PM_UNIT_MSK     0xf
  19 #define PM_SPCSEL_SH    6
  20 #define PM_SPCSEL_MSK   3
  21 #define PM_BYTE_SH      4       
  22 #define PM_BYTE_MSK     3
  23 #define PM_PMCSEL_MSK   0xf
  24 
  25 
  26 #define PM_NONE         0
  27 #define PM_FPU          1
  28 #define PM_VPU          2
  29 #define PM_ISU          3
  30 #define PM_IFU          4
  31 #define PM_IDU          5
  32 #define PM_STS          6
  33 #define PM_LSU0         7
  34 #define PM_LSU1U        8
  35 #define PM_LSU1L        9
  36 #define PM_LASTUNIT     9
  37 
  38 
  39 
  40 
  41 #define MMCR0_PMC1SEL_SH        8
  42 #define MMCR0_PMC2SEL_SH        1
  43 #define MMCR_PMCSEL_MSK         0x1f
  44 
  45 
  46 
  47 
  48 #define MMCR1_TTM0SEL_SH        62
  49 #define MMCR1_TTM1SEL_SH        59
  50 #define MMCR1_TTM3SEL_SH        53
  51 #define MMCR1_TTMSEL_MSK        3
  52 #define MMCR1_TD_CP_DBG0SEL_SH  50
  53 #define MMCR1_TD_CP_DBG1SEL_SH  48
  54 #define MMCR1_TD_CP_DBG2SEL_SH  46
  55 #define MMCR1_TD_CP_DBG3SEL_SH  44
  56 #define MMCR1_PMC1_ADDER_SEL_SH 39
  57 #define MMCR1_PMC2_ADDER_SEL_SH 38
  58 #define MMCR1_PMC6_ADDER_SEL_SH 37
  59 #define MMCR1_PMC5_ADDER_SEL_SH 36
  60 #define MMCR1_PMC8_ADDER_SEL_SH 35
  61 #define MMCR1_PMC7_ADDER_SEL_SH 34
  62 #define MMCR1_PMC3_ADDER_SEL_SH 33
  63 #define MMCR1_PMC4_ADDER_SEL_SH 32
  64 #define MMCR1_PMC3SEL_SH        27
  65 #define MMCR1_PMC4SEL_SH        22
  66 #define MMCR1_PMC5SEL_SH        17
  67 #define MMCR1_PMC6SEL_SH        12
  68 #define MMCR1_PMC7SEL_SH        7
  69 #define MMCR1_PMC8SEL_SH        2
  70 
  71 static short mmcr1_adder_bits[8] = {
  72         MMCR1_PMC1_ADDER_SEL_SH,
  73         MMCR1_PMC2_ADDER_SEL_SH,
  74         MMCR1_PMC3_ADDER_SEL_SH,
  75         MMCR1_PMC4_ADDER_SEL_SH,
  76         MMCR1_PMC5_ADDER_SEL_SH,
  77         MMCR1_PMC6_ADDER_SEL_SH,
  78         MMCR1_PMC7_ADDER_SEL_SH,
  79         MMCR1_PMC8_ADDER_SEL_SH
  80 };
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 
 122 
 123 
 124 
 125 
 126 
 127 static unsigned char direct_marked_event[8] = {
 128         (1<<2) | (1<<3),        
 129         (1<<3) | (1<<5),        
 130         (1<<3) | (1<<5),        
 131         (1<<4) | (1<<5),        
 132         (1<<4) | (1<<5),        
 133         (1<<3) | (1<<4) | (1<<5),
 134                 
 135         (1<<4) | (1<<5),        
 136         (1<<4)                  
 137 };
 138 
 139 
 140 
 141 
 142 
 143 static int p970_marked_instr_event(u64 event)
 144 {
 145         int pmc, psel, unit, byte, bit;
 146         unsigned int mask;
 147 
 148         pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
 149         psel = event & PM_PMCSEL_MSK;
 150         if (pmc) {
 151                 if (direct_marked_event[pmc - 1] & (1 << psel))
 152                         return 1;
 153                 if (psel == 0)          
 154                         bit = (pmc <= 4)? pmc - 1: 8 - pmc;
 155                 else if (psel == 7 || psel == 13)       
 156                         bit = 4;
 157                 else
 158                         return 0;
 159         } else
 160                 bit = psel;
 161 
 162         byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
 163         unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
 164         mask = 0;
 165         switch (unit) {
 166         case PM_VPU:
 167                 mask = 0x4c;            
 168                 break;
 169         case PM_LSU0:
 170                 
 171                 mask = 0x085dff00;
 172                 break;
 173         case PM_LSU1L:
 174                 mask = 0x50 << 24;      
 175                 break;
 176         }
 177         return (mask >> (byte * 8 + bit)) & 1;
 178 }
 179 
 180 
 181 static unsigned long unit_cons[PM_LASTUNIT+1][2] = {
 182         [PM_FPU] =   { 0xc80000000000ull, 0x040000000000ull },
 183         [PM_VPU] =   { 0xc80000000000ull, 0xc40000000000ull },
 184         [PM_ISU] =   { 0x080000000000ull, 0x020000000000ull },
 185         [PM_IFU] =   { 0xc80000000000ull, 0x840000000000ull },
 186         [PM_IDU] =   { 0x380000000000ull, 0x010000000000ull },
 187         [PM_STS] =   { 0x380000000000ull, 0x310000000000ull },
 188 };
 189 
 190 static int p970_get_constraint(u64 event, unsigned long *maskp,
 191                                unsigned long *valp)
 192 {
 193         int pmc, byte, unit, sh, spcsel;
 194         unsigned long mask = 0, value = 0;
 195         int grp = -1;
 196 
 197         pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
 198         if (pmc) {
 199                 if (pmc > 8)
 200                         return -1;
 201                 sh = (pmc - 1) * 2;
 202                 mask |= 2 << sh;
 203                 value |= 1 << sh;
 204                 grp = ((pmc - 1) >> 1) & 1;
 205         }
 206         unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
 207         if (unit) {
 208                 if (unit > PM_LASTUNIT)
 209                         return -1;
 210                 mask |= unit_cons[unit][0];
 211                 value |= unit_cons[unit][1];
 212                 byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK;
 213                 
 214 
 215 
 216 
 217                 if (!pmc)
 218                         grp = byte & 1;
 219                 
 220                 mask  |= 0xfULL << (28 - 4 * byte);
 221                 value |= (unsigned long)unit << (28 - 4 * byte);
 222         }
 223         if (grp == 0) {
 224                 
 225                 mask  |= 0x8000000000ull;
 226                 value |= 0x1000000000ull;
 227         } else if (grp == 1) {
 228                 
 229                 mask  |= 0x800000000ull;
 230                 value |= 0x100000000ull;
 231         }
 232         spcsel = (event >> PM_SPCSEL_SH) & PM_SPCSEL_MSK;
 233         if (spcsel) {
 234                 mask  |= 3ull << 48;
 235                 value |= (unsigned long)spcsel << 48;
 236         }
 237         *maskp = mask;
 238         *valp = value;
 239         return 0;
 240 }
 241 
 242 static int p970_get_alternatives(u64 event, unsigned int flags, u64 alt[])
 243 {
 244         alt[0] = event;
 245 
 246         
 247         if (event == 0x2002 || event == 0x3002) {
 248                 alt[1] = event ^ 0x1000;
 249                 return 2;
 250         }
 251 
 252         return 1;
 253 }
 254 
 255 static int p970_compute_mmcr(u64 event[], int n_ev,
 256                              unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[])
 257 {
 258         unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0;
 259         unsigned int pmc, unit, byte, psel;
 260         unsigned int ttm, grp;
 261         unsigned int pmc_inuse = 0;
 262         unsigned int pmc_grp_use[2];
 263         unsigned char busbyte[4];
 264         unsigned char unituse[16];
 265         unsigned char unitmap[] = { 0, 0<<3, 3<<3, 1<<3, 2<<3, 0|4, 3|4 };
 266         unsigned char ttmuse[2];
 267         unsigned char pmcsel[8];
 268         int i;
 269         int spcsel;
 270 
 271         if (n_ev > 8)
 272                 return -1;
 273 
 274         
 275         pmc_grp_use[0] = pmc_grp_use[1] = 0;
 276         memset(busbyte, 0, sizeof(busbyte));
 277         memset(unituse, 0, sizeof(unituse));
 278         for (i = 0; i < n_ev; ++i) {
 279                 pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
 280                 if (pmc) {
 281                         if (pmc_inuse & (1 << (pmc - 1)))
 282                                 return -1;
 283                         pmc_inuse |= 1 << (pmc - 1);
 284                         
 285                         ++pmc_grp_use[((pmc - 1) >> 1) & 1];
 286                 }
 287                 unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
 288                 byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
 289                 if (unit) {
 290                         if (unit > PM_LASTUNIT)
 291                                 return -1;
 292                         if (!pmc)
 293                                 ++pmc_grp_use[byte & 1];
 294                         if (busbyte[byte] && busbyte[byte] != unit)
 295                                 return -1;
 296                         busbyte[byte] = unit;
 297                         unituse[unit] = 1;
 298                 }
 299         }
 300         if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4)
 301                 return -1;
 302 
 303         
 304 
 305 
 306 
 307 
 308 
 309         if (unituse[PM_ISU] &
 310             (unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_VPU]))
 311                 unitmap[PM_ISU] = 2 | 4;        
 312         
 313         ttmuse[0] = ttmuse[1] = 0;
 314         for (i = PM_FPU; i <= PM_STS; ++i) {
 315                 if (!unituse[i])
 316                         continue;
 317                 ttm = unitmap[i];
 318                 ++ttmuse[(ttm >> 2) & 1];
 319                 mmcr1 |= (unsigned long)(ttm & ~4) << MMCR1_TTM1SEL_SH;
 320         }
 321         
 322         if (ttmuse[0] > 1 || ttmuse[1] > 1)
 323                 return -1;
 324 
 325         
 326         for (byte = 0; byte < 4; ++byte) {
 327                 unit = busbyte[byte];
 328                 if (!unit)
 329                         continue;
 330                 if (unit <= PM_STS)
 331                         ttm = (unitmap[unit] >> 2) & 1;
 332                 else if (unit == PM_LSU0)
 333                         ttm = 2;
 334                 else {
 335                         ttm = 3;
 336                         if (unit == PM_LSU1L && byte >= 2)
 337                                 mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte);
 338                 }
 339                 mmcr1 |= (unsigned long)ttm
 340                         << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte);
 341         }
 342 
 343         
 344         memset(pmcsel, 0x8, sizeof(pmcsel));    
 345         for (i = 0; i < n_ev; ++i) {
 346                 pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK;
 347                 unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK;
 348                 byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK;
 349                 psel = event[i] & PM_PMCSEL_MSK;
 350                 if (!pmc) {
 351                         
 352                         if (unit)
 353                                 psel |= 0x10 | ((byte & 2) << 2);
 354                         else
 355                                 psel |= 8;
 356                         for (pmc = 0; pmc < 8; ++pmc) {
 357                                 if (pmc_inuse & (1 << pmc))
 358                                         continue;
 359                                 grp = (pmc >> 1) & 1;
 360                                 if (unit) {
 361                                         if (grp == (byte & 1))
 362                                                 break;
 363                                 } else if (pmc_grp_use[grp] < 4) {
 364                                         ++pmc_grp_use[grp];
 365                                         break;
 366                                 }
 367                         }
 368                         pmc_inuse |= 1 << pmc;
 369                 } else {
 370                         
 371                         --pmc;
 372                         if (psel == 0 && (byte & 2))
 373                                 
 374                                 mmcr1 |= 1ull << mmcr1_adder_bits[pmc];
 375                 }
 376                 pmcsel[pmc] = psel;
 377                 hwc[i] = pmc;
 378                 spcsel = (event[i] >> PM_SPCSEL_SH) & PM_SPCSEL_MSK;
 379                 mmcr1 |= spcsel;
 380                 if (p970_marked_instr_event(event[i]))
 381                         mmcra |= MMCRA_SAMPLE_ENABLE;
 382         }
 383         for (pmc = 0; pmc < 2; ++pmc)
 384                 mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc);
 385         for (; pmc < 8; ++pmc)
 386                 mmcr1 |= (unsigned long)pmcsel[pmc]
 387                         << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2));
 388         if (pmc_inuse & 1)
 389                 mmcr0 |= MMCR0_PMC1CE;
 390         if (pmc_inuse & 0xfe)
 391                 mmcr0 |= MMCR0_PMCjCE;
 392 
 393         mmcra |= 0x2000;        
 394 
 395         
 396         mmcr[0] = mmcr0;
 397         mmcr[1] = mmcr1;
 398         mmcr[2] = mmcra;
 399         return 0;
 400 }
 401 
 402 static void p970_disable_pmc(unsigned int pmc, unsigned long mmcr[])
 403 {
 404         int shift, i;
 405 
 406         if (pmc <= 1) {
 407                 shift = MMCR0_PMC1SEL_SH - 7 * pmc;
 408                 i = 0;
 409         } else {
 410                 shift = MMCR1_PMC3SEL_SH - 5 * (pmc - 2);
 411                 i = 1;
 412         }
 413         
 414 
 415 
 416         mmcr[i] = (mmcr[i] & ~(0x1fUL << shift)) | (0x08UL << shift);
 417 }
 418 
 419 static int ppc970_generic_events[] = {
 420         [PERF_COUNT_HW_CPU_CYCLES]              = 7,
 421         [PERF_COUNT_HW_INSTRUCTIONS]            = 1,
 422         [PERF_COUNT_HW_CACHE_REFERENCES]        = 0x8810, 
 423         [PERF_COUNT_HW_CACHE_MISSES]            = 0x3810, 
 424         [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = 0x431,  
 425         [PERF_COUNT_HW_BRANCH_MISSES]           = 0x327,  
 426 };
 427 
 428 #define C(x)    PERF_COUNT_HW_CACHE_##x
 429 
 430 
 431 
 432 
 433 
 434 
 435 static int ppc970_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
 436         [C(L1D)] = {            
 437                 [C(OP_READ)] = {        0x8810,         0x3810  },
 438                 [C(OP_WRITE)] = {       0x7810,         0x813   },
 439                 [C(OP_PREFETCH)] = {    0x731,          0       },
 440         },
 441         [C(L1I)] = {            
 442                 [C(OP_READ)] = {        0,              0       },
 443                 [C(OP_WRITE)] = {       -1,             -1      },
 444                 [C(OP_PREFETCH)] = {    0,              0       },
 445         },
 446         [C(LL)] = {             
 447                 [C(OP_READ)] = {        0,              0       },
 448                 [C(OP_WRITE)] = {       0,              0       },
 449                 [C(OP_PREFETCH)] = {    0x733,          0       },
 450         },
 451         [C(DTLB)] = {           
 452                 [C(OP_READ)] = {        0,              0x704   },
 453                 [C(OP_WRITE)] = {       -1,             -1      },
 454                 [C(OP_PREFETCH)] = {    -1,             -1      },
 455         },
 456         [C(ITLB)] = {           
 457                 [C(OP_READ)] = {        0,              0x700   },
 458                 [C(OP_WRITE)] = {       -1,             -1      },
 459                 [C(OP_PREFETCH)] = {    -1,             -1      },
 460         },
 461         [C(BPU)] = {            
 462                 [C(OP_READ)] = {        0x431,          0x327   },
 463                 [C(OP_WRITE)] = {       -1,             -1      },
 464                 [C(OP_PREFETCH)] = {    -1,             -1      },
 465         },
 466         [C(NODE)] = {           
 467                 [C(OP_READ)] = {        -1,             -1      },
 468                 [C(OP_WRITE)] = {       -1,             -1      },
 469                 [C(OP_PREFETCH)] = {    -1,             -1      },
 470         },
 471 };
 472 
 473 static struct power_pmu ppc970_pmu = {
 474         .name                   = "PPC970/FX/MP",
 475         .n_counter              = 8,
 476         .max_alternatives       = 2,
 477         .add_fields             = 0x001100005555ull,
 478         .test_adder             = 0x013300000000ull,
 479         .compute_mmcr           = p970_compute_mmcr,
 480         .get_constraint         = p970_get_constraint,
 481         .get_alternatives       = p970_get_alternatives,
 482         .disable_pmc            = p970_disable_pmc,
 483         .n_generic              = ARRAY_SIZE(ppc970_generic_events),
 484         .generic_events         = ppc970_generic_events,
 485         .cache_events           = &ppc970_cache_events,
 486         .flags                  = PPMU_NO_SIPR | PPMU_NO_CONT_SAMPLING,
 487 };
 488 
 489 int init_ppc970_pmu(void)
 490 {
 491         if (!cur_cpu_spec->oprofile_cpu_type ||
 492             (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970")
 493              && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970MP")))
 494                 return -ENODEV;
 495 
 496         return register_power_pmu(&ppc970_pmu);
 497 }