18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// Copyright 2019 Madhavan Srinivasan, IBM Corporation. 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "generic-compat-pmu: " fmt 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include "isa207-common.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* 108c2ecf20Sopenharmony_ci * Raw event encoding: 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * 60 56 52 48 44 40 36 32 138c2ecf20Sopenharmony_ci * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * 28 24 20 16 12 8 4 0 168c2ecf20Sopenharmony_ci * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | 178c2ecf20Sopenharmony_ci * [ pmc ] [unit ] [ ] m [ pmcxsel ] 188c2ecf20Sopenharmony_ci * | | 198c2ecf20Sopenharmony_ci * | *- mark 208c2ecf20Sopenharmony_ci * | 218c2ecf20Sopenharmony_ci * | 228c2ecf20Sopenharmony_ci * *- combine 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * Below uses IBM bit numbering. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * MMCR1[x:y] = unit (PMCxUNIT) 278c2ecf20Sopenharmony_ci * MMCR1[24] = pmc1combine[0] 288c2ecf20Sopenharmony_ci * MMCR1[25] = pmc1combine[1] 298c2ecf20Sopenharmony_ci * MMCR1[26] = pmc2combine[0] 308c2ecf20Sopenharmony_ci * MMCR1[27] = pmc2combine[1] 318c2ecf20Sopenharmony_ci * MMCR1[28] = pmc3combine[0] 328c2ecf20Sopenharmony_ci * MMCR1[29] = pmc3combine[1] 338c2ecf20Sopenharmony_ci * MMCR1[30] = pmc4combine[0] 348c2ecf20Sopenharmony_ci * MMCR1[31] = pmc4combine[1] 358c2ecf20Sopenharmony_ci * 368c2ecf20Sopenharmony_ci */ 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* 398c2ecf20Sopenharmony_ci * Some power9 event codes. 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_ci#define EVENT(_name, _code) _name = _code, 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cienum { 448c2ecf20Sopenharmony_ciEVENT(PM_CYC, 0x0001e) 458c2ecf20Sopenharmony_ciEVENT(PM_INST_CMPL, 0x00002) 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#undef EVENT 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciGENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); 518c2ecf20Sopenharmony_ciGENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic struct attribute *generic_compat_events_attr[] = { 548c2ecf20Sopenharmony_ci GENERIC_EVENT_PTR(PM_CYC), 558c2ecf20Sopenharmony_ci GENERIC_EVENT_PTR(PM_INST_CMPL), 568c2ecf20Sopenharmony_ci NULL 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic struct attribute_group generic_compat_pmu_events_group = { 608c2ecf20Sopenharmony_ci .name = "events", 618c2ecf20Sopenharmony_ci .attrs = generic_compat_events_attr, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ciPMU_FORMAT_ATTR(event, "config:0-19"); 658c2ecf20Sopenharmony_ciPMU_FORMAT_ATTR(pmcxsel, "config:0-7"); 668c2ecf20Sopenharmony_ciPMU_FORMAT_ATTR(mark, "config:8"); 678c2ecf20Sopenharmony_ciPMU_FORMAT_ATTR(combine, "config:10-11"); 688c2ecf20Sopenharmony_ciPMU_FORMAT_ATTR(unit, "config:12-15"); 698c2ecf20Sopenharmony_ciPMU_FORMAT_ATTR(pmc, "config:16-19"); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic struct attribute *generic_compat_pmu_format_attr[] = { 728c2ecf20Sopenharmony_ci &format_attr_event.attr, 738c2ecf20Sopenharmony_ci &format_attr_pmcxsel.attr, 748c2ecf20Sopenharmony_ci &format_attr_mark.attr, 758c2ecf20Sopenharmony_ci &format_attr_combine.attr, 768c2ecf20Sopenharmony_ci &format_attr_unit.attr, 778c2ecf20Sopenharmony_ci &format_attr_pmc.attr, 788c2ecf20Sopenharmony_ci NULL, 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic struct attribute_group generic_compat_pmu_format_group = { 828c2ecf20Sopenharmony_ci .name = "format", 838c2ecf20Sopenharmony_ci .attrs = generic_compat_pmu_format_attr, 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic const struct attribute_group *generic_compat_pmu_attr_groups[] = { 878c2ecf20Sopenharmony_ci &generic_compat_pmu_format_group, 888c2ecf20Sopenharmony_ci &generic_compat_pmu_events_group, 898c2ecf20Sopenharmony_ci NULL, 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic int compat_generic_events[] = { 938c2ecf20Sopenharmony_ci [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, 948c2ecf20Sopenharmony_ci [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, 958c2ecf20Sopenharmony_ci}; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci#define C(x) PERF_COUNT_HW_CACHE_##x 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* 1008c2ecf20Sopenharmony_ci * Table of generalized cache-related events. 1018c2ecf20Sopenharmony_ci * 0 means not supported, -1 means nonsensical, other values 1028c2ecf20Sopenharmony_ci * are event codes. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_cistatic u64 generic_compat_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { 1058c2ecf20Sopenharmony_ci [ C(L1D) ] = { 1068c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1078c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1088c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1098c2ecf20Sopenharmony_ci }, 1108c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1118c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1128c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1138c2ecf20Sopenharmony_ci }, 1148c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1158c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1168c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1178c2ecf20Sopenharmony_ci }, 1188c2ecf20Sopenharmony_ci }, 1198c2ecf20Sopenharmony_ci [ C(L1I) ] = { 1208c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1218c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1228c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1238c2ecf20Sopenharmony_ci }, 1248c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1258c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1268c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1278c2ecf20Sopenharmony_ci }, 1288c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1298c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1308c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1318c2ecf20Sopenharmony_ci }, 1328c2ecf20Sopenharmony_ci }, 1338c2ecf20Sopenharmony_ci [ C(LL) ] = { 1348c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1358c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1368c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1378c2ecf20Sopenharmony_ci }, 1388c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1398c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1408c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1418c2ecf20Sopenharmony_ci }, 1428c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1438c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1448c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1458c2ecf20Sopenharmony_ci }, 1468c2ecf20Sopenharmony_ci }, 1478c2ecf20Sopenharmony_ci [ C(DTLB) ] = { 1488c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1498c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1508c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1518c2ecf20Sopenharmony_ci }, 1528c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1538c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1548c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1558c2ecf20Sopenharmony_ci }, 1568c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1578c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1588c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1598c2ecf20Sopenharmony_ci }, 1608c2ecf20Sopenharmony_ci }, 1618c2ecf20Sopenharmony_ci [ C(ITLB) ] = { 1628c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1638c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1648c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1658c2ecf20Sopenharmony_ci }, 1668c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1678c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1688c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1698c2ecf20Sopenharmony_ci }, 1708c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1718c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1728c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1738c2ecf20Sopenharmony_ci }, 1748c2ecf20Sopenharmony_ci }, 1758c2ecf20Sopenharmony_ci [ C(BPU) ] = { 1768c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1778c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = 0, 1788c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = 0, 1798c2ecf20Sopenharmony_ci }, 1808c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1818c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1828c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1838c2ecf20Sopenharmony_ci }, 1848c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1858c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1868c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1878c2ecf20Sopenharmony_ci }, 1888c2ecf20Sopenharmony_ci }, 1898c2ecf20Sopenharmony_ci [ C(NODE) ] = { 1908c2ecf20Sopenharmony_ci [ C(OP_READ) ] = { 1918c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1928c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1938c2ecf20Sopenharmony_ci }, 1948c2ecf20Sopenharmony_ci [ C(OP_WRITE) ] = { 1958c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 1968c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 1978c2ecf20Sopenharmony_ci }, 1988c2ecf20Sopenharmony_ci [ C(OP_PREFETCH) ] = { 1998c2ecf20Sopenharmony_ci [ C(RESULT_ACCESS) ] = -1, 2008c2ecf20Sopenharmony_ci [ C(RESULT_MISS) ] = -1, 2018c2ecf20Sopenharmony_ci }, 2028c2ecf20Sopenharmony_ci }, 2038c2ecf20Sopenharmony_ci}; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#undef C 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistatic struct power_pmu generic_compat_pmu = { 2088c2ecf20Sopenharmony_ci .name = "GENERIC_COMPAT", 2098c2ecf20Sopenharmony_ci .n_counter = MAX_PMU_COUNTERS, 2108c2ecf20Sopenharmony_ci .add_fields = ISA207_ADD_FIELDS, 2118c2ecf20Sopenharmony_ci .test_adder = ISA207_TEST_ADDER, 2128c2ecf20Sopenharmony_ci .compute_mmcr = isa207_compute_mmcr, 2138c2ecf20Sopenharmony_ci .get_constraint = isa207_get_constraint, 2148c2ecf20Sopenharmony_ci .disable_pmc = isa207_disable_pmc, 2158c2ecf20Sopenharmony_ci .flags = PPMU_HAS_SIER | PPMU_ARCH_207S, 2168c2ecf20Sopenharmony_ci .n_generic = ARRAY_SIZE(compat_generic_events), 2178c2ecf20Sopenharmony_ci .generic_events = compat_generic_events, 2188c2ecf20Sopenharmony_ci .cache_events = &generic_compat_cache_events, 2198c2ecf20Sopenharmony_ci .attr_groups = generic_compat_pmu_attr_groups, 2208c2ecf20Sopenharmony_ci}; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ciint init_generic_compat_pmu(void) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci int rc = 0; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci rc = register_power_pmu(&generic_compat_pmu); 2278c2ecf20Sopenharmony_ci if (rc) 2288c2ecf20Sopenharmony_ci return rc; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci /* Tell userspace that EBB is supported */ 2318c2ecf20Sopenharmony_ci cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci return 0; 2348c2ecf20Sopenharmony_ci} 235