0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) "power9-pmu: " fmt
0011
0012 #include "isa207-common.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 #define EVENT(_name, _code) _name = _code,
0080
0081 enum {
0082 #include "power9-events-list.h"
0083 };
0084
0085 #undef EVENT
0086
0087
0088 #define POWER9_MMCRA_IFM1 0x0000000040000000UL
0089 #define POWER9_MMCRA_IFM2 0x0000000080000000UL
0090 #define POWER9_MMCRA_IFM3 0x00000000C0000000UL
0091 #define POWER9_MMCRA_BHRB_MASK 0x00000000C0000000UL
0092
0093 extern u64 PERF_REG_EXTENDED_MASK;
0094
0095
0096 #define PVR_POWER9_CUMULUS 0x00002000
0097
0098
0099 extern const struct attribute_group isa207_pmu_format_group;
0100
0101 static int p9_dd21_bl_ev[] = {
0102 PM_MRK_ST_DONE_L2,
0103 PM_RADIX_PWC_L1_HIT,
0104 PM_FLOP_CMPL,
0105 PM_MRK_NTF_FIN,
0106 PM_RADIX_PWC_L2_HIT,
0107 PM_IFETCH_THROTTLE,
0108 PM_MRK_L2_TM_ST_ABORT_SISTER,
0109 PM_RADIX_PWC_L3_HIT,
0110 PM_RUN_CYC_SMT2_MODE,
0111 PM_TM_TX_PASS_RUN_INST,
0112 PM_DISP_HELD_SYNC_HOLD,
0113 };
0114
0115 static int p9_dd22_bl_ev[] = {
0116 PM_DTLB_MISS_16G,
0117 PM_DERAT_MISS_2M,
0118 PM_DTLB_MISS_2M,
0119 PM_MRK_DTLB_MISS_1G,
0120 PM_DTLB_MISS_4K,
0121 PM_DERAT_MISS_1G,
0122 PM_MRK_DERAT_MISS_2M,
0123 PM_MRK_DTLB_MISS_4K,
0124 PM_MRK_DTLB_MISS_16G,
0125 PM_DTLB_MISS_64K,
0126 PM_MRK_DERAT_MISS_1G,
0127 PM_MRK_DTLB_MISS_64K,
0128 PM_DISP_HELD_SYNC_HOLD,
0129 PM_DTLB_MISS_16M,
0130 PM_DTLB_MISS_1G,
0131 PM_MRK_DTLB_MISS_16M,
0132 };
0133
0134
0135 static const unsigned int power9_event_alternatives[][MAX_ALT] = {
0136 { PM_BR_2PATH, PM_BR_2PATH_ALT },
0137 { PM_INST_DISP, PM_INST_DISP_ALT },
0138 { PM_RUN_CYC_ALT, PM_RUN_CYC },
0139 { PM_LD_MISS_L1, PM_LD_MISS_L1_ALT },
0140 { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL },
0141 };
0142
0143 static int power9_get_alternatives(u64 event, unsigned int flags, u64 alt[])
0144 {
0145 int num_alt = 0;
0146
0147 num_alt = isa207_get_alternatives(event, alt,
0148 ARRAY_SIZE(power9_event_alternatives), flags,
0149 power9_event_alternatives);
0150
0151 return num_alt;
0152 }
0153
0154 static int power9_check_attr_config(struct perf_event *ev)
0155 {
0156 u64 val;
0157 u64 event = ev->attr.config;
0158
0159 val = (event >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK;
0160 if (val == 0xC || isa3XX_check_attr_config(ev))
0161 return -EINVAL;
0162
0163 return 0;
0164 }
0165
0166 GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
0167 GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_ICT_NOSLOT_CYC);
0168 GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL);
0169 GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);
0170 GENERIC_EVENT_ATTR(branch-instructions, PM_BR_CMPL);
0171 GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);
0172 GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1);
0173 GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1_FIN);
0174 GENERIC_EVENT_ATTR(mem-loads, MEM_LOADS);
0175 GENERIC_EVENT_ATTR(mem-stores, MEM_STORES);
0176
0177 CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1_FIN);
0178 CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1);
0179 CACHE_EVENT_ATTR(L1-dcache-prefetches, PM_L1_PREF);
0180 CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1);
0181 CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS);
0182 CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1);
0183 CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_WRITE);
0184 CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS);
0185 CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3);
0186 CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL);
0187 CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL);
0188 CACHE_EVENT_ATTR(branch-loads, PM_BR_CMPL);
0189 CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);
0190 CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
0191
0192 static struct attribute *power9_events_attr[] = {
0193 GENERIC_EVENT_PTR(PM_CYC),
0194 GENERIC_EVENT_PTR(PM_ICT_NOSLOT_CYC),
0195 GENERIC_EVENT_PTR(PM_CMPLU_STALL),
0196 GENERIC_EVENT_PTR(PM_INST_CMPL),
0197 GENERIC_EVENT_PTR(PM_BR_CMPL),
0198 GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
0199 GENERIC_EVENT_PTR(PM_LD_REF_L1),
0200 GENERIC_EVENT_PTR(PM_LD_MISS_L1_FIN),
0201 GENERIC_EVENT_PTR(MEM_LOADS),
0202 GENERIC_EVENT_PTR(MEM_STORES),
0203 CACHE_EVENT_PTR(PM_LD_MISS_L1_FIN),
0204 CACHE_EVENT_PTR(PM_LD_REF_L1),
0205 CACHE_EVENT_PTR(PM_L1_PREF),
0206 CACHE_EVENT_PTR(PM_ST_MISS_L1),
0207 CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),
0208 CACHE_EVENT_PTR(PM_INST_FROM_L1),
0209 CACHE_EVENT_PTR(PM_IC_PREF_WRITE),
0210 CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),
0211 CACHE_EVENT_PTR(PM_DATA_FROM_L3),
0212 CACHE_EVENT_PTR(PM_L3_PREF_ALL),
0213 CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),
0214 CACHE_EVENT_PTR(PM_BR_CMPL),
0215 CACHE_EVENT_PTR(PM_DTLB_MISS),
0216 CACHE_EVENT_PTR(PM_ITLB_MISS),
0217 NULL
0218 };
0219
0220 static const struct attribute_group power9_pmu_events_group = {
0221 .name = "events",
0222 .attrs = power9_events_attr,
0223 };
0224
0225 PMU_FORMAT_ATTR(event, "config:0-51");
0226 PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
0227 PMU_FORMAT_ATTR(mark, "config:8");
0228 PMU_FORMAT_ATTR(combine, "config:10-11");
0229 PMU_FORMAT_ATTR(unit, "config:12-15");
0230 PMU_FORMAT_ATTR(pmc, "config:16-19");
0231 PMU_FORMAT_ATTR(cache_sel, "config:20-23");
0232 PMU_FORMAT_ATTR(sample_mode, "config:24-28");
0233 PMU_FORMAT_ATTR(thresh_sel, "config:29-31");
0234 PMU_FORMAT_ATTR(thresh_stop, "config:32-35");
0235 PMU_FORMAT_ATTR(thresh_start, "config:36-39");
0236 PMU_FORMAT_ATTR(thresh_cmp, "config:40-49");
0237 PMU_FORMAT_ATTR(sdar_mode, "config:50-51");
0238
0239 static struct attribute *power9_pmu_format_attr[] = {
0240 &format_attr_event.attr,
0241 &format_attr_pmcxsel.attr,
0242 &format_attr_mark.attr,
0243 &format_attr_combine.attr,
0244 &format_attr_unit.attr,
0245 &format_attr_pmc.attr,
0246 &format_attr_cache_sel.attr,
0247 &format_attr_sample_mode.attr,
0248 &format_attr_thresh_sel.attr,
0249 &format_attr_thresh_stop.attr,
0250 &format_attr_thresh_start.attr,
0251 &format_attr_thresh_cmp.attr,
0252 &format_attr_sdar_mode.attr,
0253 NULL,
0254 };
0255
0256 static const struct attribute_group power9_pmu_format_group = {
0257 .name = "format",
0258 .attrs = power9_pmu_format_attr,
0259 };
0260
0261 static struct attribute *power9_pmu_caps_attrs[] = {
0262 NULL
0263 };
0264
0265 static struct attribute_group power9_pmu_caps_group = {
0266 .name = "caps",
0267 .attrs = power9_pmu_caps_attrs,
0268 };
0269
0270 static const struct attribute_group *power9_pmu_attr_groups[] = {
0271 &power9_pmu_format_group,
0272 &power9_pmu_events_group,
0273 &power9_pmu_caps_group,
0274 NULL,
0275 };
0276
0277 static int power9_generic_events[] = {
0278 [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
0279 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_ICT_NOSLOT_CYC,
0280 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL,
0281 [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
0282 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL,
0283 [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
0284 [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
0285 [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1_FIN,
0286 };
0287
0288 static u64 power9_bhrb_filter_map(u64 branch_sample_type)
0289 {
0290 u64 pmu_bhrb_filter = 0;
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
0301 return pmu_bhrb_filter;
0302
0303
0304 if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
0305 return -1;
0306
0307 if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
0308 return -1;
0309
0310 if (branch_sample_type & PERF_SAMPLE_BRANCH_CALL)
0311 return -1;
0312
0313 if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
0314 pmu_bhrb_filter |= POWER9_MMCRA_IFM1;
0315 return pmu_bhrb_filter;
0316 }
0317
0318
0319 return -1;
0320 }
0321
0322 static void power9_config_bhrb(u64 pmu_bhrb_filter)
0323 {
0324 pmu_bhrb_filter &= POWER9_MMCRA_BHRB_MASK;
0325
0326
0327 mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
0328 }
0329
0330 #define C(x) PERF_COUNT_HW_CACHE_##x
0331
0332
0333
0334
0335
0336
0337 static u64 power9_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
0338 [ C(L1D) ] = {
0339 [ C(OP_READ) ] = {
0340 [ C(RESULT_ACCESS) ] = PM_LD_REF_L1,
0341 [ C(RESULT_MISS) ] = PM_LD_MISS_L1_FIN,
0342 },
0343 [ C(OP_WRITE) ] = {
0344 [ C(RESULT_ACCESS) ] = 0,
0345 [ C(RESULT_MISS) ] = PM_ST_MISS_L1,
0346 },
0347 [ C(OP_PREFETCH) ] = {
0348 [ C(RESULT_ACCESS) ] = PM_L1_PREF,
0349 [ C(RESULT_MISS) ] = 0,
0350 },
0351 },
0352 [ C(L1I) ] = {
0353 [ C(OP_READ) ] = {
0354 [ C(RESULT_ACCESS) ] = PM_INST_FROM_L1,
0355 [ C(RESULT_MISS) ] = PM_L1_ICACHE_MISS,
0356 },
0357 [ C(OP_WRITE) ] = {
0358 [ C(RESULT_ACCESS) ] = PM_L1_DEMAND_WRITE,
0359 [ C(RESULT_MISS) ] = -1,
0360 },
0361 [ C(OP_PREFETCH) ] = {
0362 [ C(RESULT_ACCESS) ] = PM_IC_PREF_WRITE,
0363 [ C(RESULT_MISS) ] = 0,
0364 },
0365 },
0366 [ C(LL) ] = {
0367 [ C(OP_READ) ] = {
0368 [ C(RESULT_ACCESS) ] = PM_DATA_FROM_L3,
0369 [ C(RESULT_MISS) ] = PM_DATA_FROM_L3MISS,
0370 },
0371 [ C(OP_WRITE) ] = {
0372 [ C(RESULT_ACCESS) ] = 0,
0373 [ C(RESULT_MISS) ] = 0,
0374 },
0375 [ C(OP_PREFETCH) ] = {
0376 [ C(RESULT_ACCESS) ] = PM_L3_PREF_ALL,
0377 [ C(RESULT_MISS) ] = 0,
0378 },
0379 },
0380 [ C(DTLB) ] = {
0381 [ C(OP_READ) ] = {
0382 [ C(RESULT_ACCESS) ] = 0,
0383 [ C(RESULT_MISS) ] = PM_DTLB_MISS,
0384 },
0385 [ C(OP_WRITE) ] = {
0386 [ C(RESULT_ACCESS) ] = -1,
0387 [ C(RESULT_MISS) ] = -1,
0388 },
0389 [ C(OP_PREFETCH) ] = {
0390 [ C(RESULT_ACCESS) ] = -1,
0391 [ C(RESULT_MISS) ] = -1,
0392 },
0393 },
0394 [ C(ITLB) ] = {
0395 [ C(OP_READ) ] = {
0396 [ C(RESULT_ACCESS) ] = 0,
0397 [ C(RESULT_MISS) ] = PM_ITLB_MISS,
0398 },
0399 [ C(OP_WRITE) ] = {
0400 [ C(RESULT_ACCESS) ] = -1,
0401 [ C(RESULT_MISS) ] = -1,
0402 },
0403 [ C(OP_PREFETCH) ] = {
0404 [ C(RESULT_ACCESS) ] = -1,
0405 [ C(RESULT_MISS) ] = -1,
0406 },
0407 },
0408 [ C(BPU) ] = {
0409 [ C(OP_READ) ] = {
0410 [ C(RESULT_ACCESS) ] = PM_BR_CMPL,
0411 [ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL,
0412 },
0413 [ C(OP_WRITE) ] = {
0414 [ C(RESULT_ACCESS) ] = -1,
0415 [ C(RESULT_MISS) ] = -1,
0416 },
0417 [ C(OP_PREFETCH) ] = {
0418 [ C(RESULT_ACCESS) ] = -1,
0419 [ C(RESULT_MISS) ] = -1,
0420 },
0421 },
0422 [ C(NODE) ] = {
0423 [ C(OP_READ) ] = {
0424 [ C(RESULT_ACCESS) ] = -1,
0425 [ C(RESULT_MISS) ] = -1,
0426 },
0427 [ C(OP_WRITE) ] = {
0428 [ C(RESULT_ACCESS) ] = -1,
0429 [ C(RESULT_MISS) ] = -1,
0430 },
0431 [ C(OP_PREFETCH) ] = {
0432 [ C(RESULT_ACCESS) ] = -1,
0433 [ C(RESULT_MISS) ] = -1,
0434 },
0435 },
0436 };
0437
0438 #undef C
0439
0440 static struct power_pmu power9_pmu = {
0441 .name = "POWER9",
0442 .n_counter = MAX_PMU_COUNTERS,
0443 .add_fields = ISA207_ADD_FIELDS,
0444 .test_adder = ISA207_TEST_ADDER,
0445 .group_constraint_mask = CNST_CACHE_PMC4_MASK,
0446 .group_constraint_val = CNST_CACHE_PMC4_VAL,
0447 .compute_mmcr = isa207_compute_mmcr,
0448 .config_bhrb = power9_config_bhrb,
0449 .bhrb_filter_map = power9_bhrb_filter_map,
0450 .get_constraint = isa207_get_constraint,
0451 .get_alternatives = power9_get_alternatives,
0452 .get_mem_data_src = isa207_get_mem_data_src,
0453 .get_mem_weight = isa207_get_mem_weight,
0454 .disable_pmc = isa207_disable_pmc,
0455 .flags = PPMU_HAS_SIER | PPMU_ARCH_207S,
0456 .n_generic = ARRAY_SIZE(power9_generic_events),
0457 .generic_events = power9_generic_events,
0458 .cache_events = &power9_cache_events,
0459 .attr_groups = power9_pmu_attr_groups,
0460 .bhrb_nr = 32,
0461 .capabilities = PERF_PMU_CAP_EXTENDED_REGS,
0462 .check_attr_config = power9_check_attr_config,
0463 };
0464
0465 int __init init_power9_pmu(void)
0466 {
0467 int rc = 0;
0468 unsigned int pvr = mfspr(SPRN_PVR);
0469
0470 if (PVR_VER(pvr) != PVR_POWER9)
0471 return -ENODEV;
0472
0473
0474 if (!(pvr & PVR_POWER9_CUMULUS)) {
0475 if ((PVR_CFG(pvr) == 2) && (PVR_MIN(pvr) == 1)) {
0476 power9_pmu.blacklist_ev = p9_dd21_bl_ev;
0477 power9_pmu.n_blacklist_ev = ARRAY_SIZE(p9_dd21_bl_ev);
0478 } else if ((PVR_CFG(pvr) == 2) && (PVR_MIN(pvr) == 2)) {
0479 power9_pmu.blacklist_ev = p9_dd22_bl_ev;
0480 power9_pmu.n_blacklist_ev = ARRAY_SIZE(p9_dd22_bl_ev);
0481 }
0482 }
0483
0484
0485 PERF_REG_EXTENDED_MASK = PERF_REG_PMU_MASK_300;
0486
0487 rc = register_power_pmu(&power9_pmu);
0488 if (rc)
0489 return rc;
0490
0491
0492 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
0493
0494 return 0;
0495 }