0001
0002
0003
0004
0005 #define pr_fmt(fmt) "generic-compat-pmu: " fmt
0006
0007 #include "isa207-common.h"
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #define EVENT(_name, _code) _name = _code,
0024
0025 enum {
0026
0027 EVENT(PM_CYC_ALT, 0x100f0)
0028
0029 EVENT(PM_CYC_INST_CMPL, 0x100f2)
0030
0031 EVENT(PM_FLOP_CMPL, 0x100f4)
0032
0033 EVENT(PM_L1_ITLB_MISS, 0x100f6)
0034
0035 EVENT(PM_NO_INST_AVAIL, 0x100f8)
0036
0037 EVENT(PM_LD_CMPL, 0x100fc)
0038
0039 EVENT(PM_INST_CMPL_ALT, 0x100fe)
0040
0041 EVENT(PM_ST_CMPL, 0x200f0)
0042
0043 EVENT(PM_INST_DISP, 0x200f2)
0044
0045 EVENT(PM_RUN_CYC, 0x200f4)
0046
0047 EVENT(PM_L1_DTLB_RELOAD, 0x200f6)
0048
0049 EVENT(PM_BR_TAKEN_CMPL, 0x200fa)
0050
0051 EVENT(PM_L1_ICACHE_MISS, 0x200fc)
0052
0053 EVENT(PM_L1_RELOAD_FROM_MEM, 0x200fe)
0054
0055 EVENT(PM_ST_MISS_L1, 0x300f0)
0056
0057 EVENT(PM_INST_DISP_ALT, 0x300f2)
0058
0059 EVENT(PM_BR_MISPREDICT, 0x300f6)
0060
0061 EVENT(PM_DTLB_MISS, 0x300fc)
0062
0063 EVENT(PM_DATA_FROM_L3MISS, 0x300fe)
0064
0065 EVENT(PM_LD_MISS_L1, 0x400f0)
0066
0067 EVENT(PM_CYC_INST_DISP, 0x400f2)
0068
0069 EVENT(PM_BR_MPRED_CMPL, 0x400f6)
0070
0071 EVENT(PM_RUN_INST_CMPL, 0x400fa)
0072
0073 EVENT(PM_ITLB_MISS, 0x400fc)
0074
0075 EVENT(PM_LD_NOT_CACHED, 0x400fe)
0076
0077 EVENT(PM_INST_CMPL, 0x500fa)
0078
0079 EVENT(PM_CYC, 0x600f4)
0080 };
0081
0082 #undef EVENT
0083
0084
0085
0086 static const unsigned int generic_event_alternatives[][MAX_ALT] = {
0087 { PM_CYC_ALT, PM_CYC },
0088 { PM_INST_CMPL_ALT, PM_INST_CMPL },
0089 { PM_INST_DISP, PM_INST_DISP_ALT },
0090 };
0091
0092 static int generic_get_alternatives(u64 event, unsigned int flags, u64 alt[])
0093 {
0094 int num_alt = 0;
0095
0096 num_alt = isa207_get_alternatives(event, alt,
0097 ARRAY_SIZE(generic_event_alternatives), flags,
0098 generic_event_alternatives);
0099
0100 return num_alt;
0101 }
0102
0103 GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
0104 GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);
0105 GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_NO_INST_AVAIL);
0106 GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);
0107 GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1);
0108
0109 CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1);
0110 CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1);
0111 CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS);
0112 CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS);
0113 CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL);
0114 CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);
0115 CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
0116
0117 static struct attribute *generic_compat_events_attr[] = {
0118 GENERIC_EVENT_PTR(PM_CYC),
0119 GENERIC_EVENT_PTR(PM_INST_CMPL),
0120 GENERIC_EVENT_PTR(PM_NO_INST_AVAIL),
0121 GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
0122 GENERIC_EVENT_PTR(PM_LD_MISS_L1),
0123 CACHE_EVENT_PTR(PM_LD_MISS_L1),
0124 CACHE_EVENT_PTR(PM_ST_MISS_L1),
0125 CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),
0126 CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),
0127 CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),
0128 CACHE_EVENT_PTR(PM_DTLB_MISS),
0129 CACHE_EVENT_PTR(PM_ITLB_MISS),
0130 NULL
0131 };
0132
0133 static const struct attribute_group generic_compat_pmu_events_group = {
0134 .name = "events",
0135 .attrs = generic_compat_events_attr,
0136 };
0137
0138 PMU_FORMAT_ATTR(event, "config:0-19");
0139 PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
0140 PMU_FORMAT_ATTR(pmc, "config:16-19");
0141
0142 static struct attribute *generic_compat_pmu_format_attr[] = {
0143 &format_attr_event.attr,
0144 &format_attr_pmcxsel.attr,
0145 &format_attr_pmc.attr,
0146 NULL,
0147 };
0148
0149 static const struct attribute_group generic_compat_pmu_format_group = {
0150 .name = "format",
0151 .attrs = generic_compat_pmu_format_attr,
0152 };
0153
0154 static struct attribute *generic_compat_pmu_caps_attrs[] = {
0155 NULL
0156 };
0157
0158 static struct attribute_group generic_compat_pmu_caps_group = {
0159 .name = "caps",
0160 .attrs = generic_compat_pmu_caps_attrs,
0161 };
0162
0163 static const struct attribute_group *generic_compat_pmu_attr_groups[] = {
0164 &generic_compat_pmu_format_group,
0165 &generic_compat_pmu_events_group,
0166 &generic_compat_pmu_caps_group,
0167 NULL,
0168 };
0169
0170 static int compat_generic_events[] = {
0171 [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
0172 [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
0173 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_NO_INST_AVAIL,
0174 [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
0175 [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1,
0176 };
0177
0178 #define C(x) PERF_COUNT_HW_CACHE_##x
0179
0180
0181
0182
0183
0184
0185 static u64 generic_compat_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
0186 [ C(L1D) ] = {
0187 [ C(OP_READ) ] = {
0188 [ C(RESULT_ACCESS) ] = 0,
0189 [ C(RESULT_MISS) ] = PM_LD_MISS_L1,
0190 },
0191 [ C(OP_WRITE) ] = {
0192 [ C(RESULT_ACCESS) ] = 0,
0193 [ C(RESULT_MISS) ] = PM_ST_MISS_L1,
0194 },
0195 [ C(OP_PREFETCH) ] = {
0196 [ C(RESULT_ACCESS) ] = 0,
0197 [ C(RESULT_MISS) ] = 0,
0198 },
0199 },
0200 [ C(L1I) ] = {
0201 [ C(OP_READ) ] = {
0202 [ C(RESULT_ACCESS) ] = 0,
0203 [ C(RESULT_MISS) ] = PM_L1_ICACHE_MISS,
0204 },
0205 [ C(OP_WRITE) ] = {
0206 [ C(RESULT_ACCESS) ] = 0,
0207 [ C(RESULT_MISS) ] = -1,
0208 },
0209 [ C(OP_PREFETCH) ] = {
0210 [ C(RESULT_ACCESS) ] = 0,
0211 [ C(RESULT_MISS) ] = 0,
0212 },
0213 },
0214 [ C(LL) ] = {
0215 [ C(OP_READ) ] = {
0216 [ C(RESULT_ACCESS) ] = 0,
0217 [ C(RESULT_MISS) ] = PM_DATA_FROM_L3MISS,
0218 },
0219 [ C(OP_WRITE) ] = {
0220 [ C(RESULT_ACCESS) ] = 0,
0221 [ C(RESULT_MISS) ] = 0,
0222 },
0223 [ C(OP_PREFETCH) ] = {
0224 [ C(RESULT_ACCESS) ] = 0,
0225 [ C(RESULT_MISS) ] = 0,
0226 },
0227 },
0228 [ C(DTLB) ] = {
0229 [ C(OP_READ) ] = {
0230 [ C(RESULT_ACCESS) ] = 0,
0231 [ C(RESULT_MISS) ] = PM_DTLB_MISS,
0232 },
0233 [ C(OP_WRITE) ] = {
0234 [ C(RESULT_ACCESS) ] = -1,
0235 [ C(RESULT_MISS) ] = -1,
0236 },
0237 [ C(OP_PREFETCH) ] = {
0238 [ C(RESULT_ACCESS) ] = -1,
0239 [ C(RESULT_MISS) ] = -1,
0240 },
0241 },
0242 [ C(ITLB) ] = {
0243 [ C(OP_READ) ] = {
0244 [ C(RESULT_ACCESS) ] = 0,
0245 [ C(RESULT_MISS) ] = PM_ITLB_MISS,
0246 },
0247 [ C(OP_WRITE) ] = {
0248 [ C(RESULT_ACCESS) ] = -1,
0249 [ C(RESULT_MISS) ] = -1,
0250 },
0251 [ C(OP_PREFETCH) ] = {
0252 [ C(RESULT_ACCESS) ] = -1,
0253 [ C(RESULT_MISS) ] = -1,
0254 },
0255 },
0256 [ C(BPU) ] = {
0257 [ C(OP_READ) ] = {
0258 [ C(RESULT_ACCESS) ] = 0,
0259 [ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL,
0260 },
0261 [ C(OP_WRITE) ] = {
0262 [ C(RESULT_ACCESS) ] = -1,
0263 [ C(RESULT_MISS) ] = -1,
0264 },
0265 [ C(OP_PREFETCH) ] = {
0266 [ C(RESULT_ACCESS) ] = -1,
0267 [ C(RESULT_MISS) ] = -1,
0268 },
0269 },
0270 [ C(NODE) ] = {
0271 [ C(OP_READ) ] = {
0272 [ C(RESULT_ACCESS) ] = -1,
0273 [ C(RESULT_MISS) ] = -1,
0274 },
0275 [ C(OP_WRITE) ] = {
0276 [ C(RESULT_ACCESS) ] = -1,
0277 [ C(RESULT_MISS) ] = -1,
0278 },
0279 [ C(OP_PREFETCH) ] = {
0280 [ C(RESULT_ACCESS) ] = -1,
0281 [ C(RESULT_MISS) ] = -1,
0282 },
0283 },
0284 };
0285
0286 #undef C
0287
0288
0289
0290
0291
0292 static int generic_compute_mmcr(u64 event[], int n_ev,
0293 unsigned int hwc[], struct mmcr_regs *mmcr,
0294 struct perf_event *pevents[], u32 flags)
0295 {
0296 int ret;
0297
0298 ret = isa207_compute_mmcr(event, n_ev, hwc, mmcr, pevents, flags);
0299 if (!ret)
0300 mmcr->mmcr0 |= MMCR0_C56RUN;
0301 return ret;
0302 }
0303
0304 static struct power_pmu generic_compat_pmu = {
0305 .name = "ISAv3",
0306 .n_counter = MAX_PMU_COUNTERS,
0307 .add_fields = ISA207_ADD_FIELDS,
0308 .test_adder = ISA207_TEST_ADDER,
0309 .compute_mmcr = generic_compute_mmcr,
0310 .get_constraint = isa207_get_constraint,
0311 .get_alternatives = generic_get_alternatives,
0312 .disable_pmc = isa207_disable_pmc,
0313 .flags = PPMU_HAS_SIER | PPMU_ARCH_207S,
0314 .n_generic = ARRAY_SIZE(compat_generic_events),
0315 .generic_events = compat_generic_events,
0316 .cache_events = &generic_compat_cache_events,
0317 .attr_groups = generic_compat_pmu_attr_groups,
0318 };
0319
0320 int __init init_generic_compat_pmu(void)
0321 {
0322 int rc = 0;
0323
0324
0325
0326
0327
0328
0329
0330
0331 if (!cpu_has_feature(CPU_FTR_ARCH_300))
0332 return -ENODEV;
0333
0334 rc = register_power_pmu(&generic_compat_pmu);
0335 if (rc)
0336 return rc;
0337
0338
0339 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
0340
0341 return 0;
0342 }