18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ 38c2ecf20Sopenharmony_ci#define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/perf_event.h> 68c2ecf20Sopenharmony_ci#include <linux/stringify.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef REQUEST_FILE 98c2ecf20Sopenharmony_ci#error "REQUEST_FILE must be defined before including" 108c2ecf20Sopenharmony_ci#endif 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifndef NAME_LOWER 138c2ecf20Sopenharmony_ci#error "NAME_LOWER must be defined before including" 148c2ecf20Sopenharmony_ci#endif 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#ifndef NAME_UPPER 178c2ecf20Sopenharmony_ci#error "NAME_UPPER must be defined before including" 188c2ecf20Sopenharmony_ci#endif 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define BE_TYPE_b1 __u8 218c2ecf20Sopenharmony_ci#define BE_TYPE_b2 __be16 228c2ecf20Sopenharmony_ci#define BE_TYPE_b4 __be32 238c2ecf20Sopenharmony_ci#define BE_TYPE_b8 __be64 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define BYTES_TO_BE_TYPE(bytes) \ 268c2ecf20Sopenharmony_ci BE_TYPE_b##bytes 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define CAT2_(a, b) a ## b 298c2ecf20Sopenharmony_ci#define CAT2(a, b) CAT2_(a, b) 308c2ecf20Sopenharmony_ci#define CAT3_(a, b, c) a ## b ## c 318c2ecf20Sopenharmony_ci#define CAT3(a, b, c) CAT3_(a, b, c) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* 348c2ecf20Sopenharmony_ci * enumerate the request values as 358c2ecf20Sopenharmony_ci * <NAME_UPPER>_<request name> = <request value> 368c2ecf20Sopenharmony_ci */ 378c2ecf20Sopenharmony_ci#define REQUEST_VALUE__(name_upper, r_name) name_upper ## _ ## r_name 388c2ecf20Sopenharmony_ci#define REQUEST_VALUE_(name_upper, r_name) REQUEST_VALUE__(name_upper, r_name) 398c2ecf20Sopenharmony_ci#define REQUEST_VALUE(r_name) REQUEST_VALUE_(NAME_UPPER, r_name) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#include "_clear.h" 428c2ecf20Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 438c2ecf20Sopenharmony_ci REQUEST_VALUE(r_name) = r_value, 448c2ecf20Sopenharmony_cienum CAT2(NAME_LOWER, _requests) { 458c2ecf20Sopenharmony_ci#include REQUEST_FILE 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * For each request: 508c2ecf20Sopenharmony_ci * struct <NAME_LOWER>_<request name> { 518c2ecf20Sopenharmony_ci * r_fields 528c2ecf20Sopenharmony_ci * }; 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_ci#include "_clear.h" 558c2ecf20Sopenharmony_ci#define STRUCT_NAME__(name_lower, r_name) name_lower ## _ ## r_name 568c2ecf20Sopenharmony_ci#define STRUCT_NAME_(name_lower, r_name) STRUCT_NAME__(name_lower, r_name) 578c2ecf20Sopenharmony_ci#define STRUCT_NAME(r_name) STRUCT_NAME_(NAME_LOWER, r_name) 588c2ecf20Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 598c2ecf20Sopenharmony_cistruct STRUCT_NAME(r_name) { \ 608c2ecf20Sopenharmony_ci r_fields \ 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \ 638c2ecf20Sopenharmony_ci BYTES_TO_BE_TYPE(f_bytes) f_name; 648c2ecf20Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \ 658c2ecf20Sopenharmony_ci __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) 668c2ecf20Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_bytes, a_name) \ 678c2ecf20Sopenharmony_ci __u8 a_name[a_bytes]; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#include REQUEST_FILE 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* 728c2ecf20Sopenharmony_ci * Generate a check of the field offsets 738c2ecf20Sopenharmony_ci * <NAME_LOWER>_assert_offsets_correct() 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci#include "_clear.h" 768c2ecf20Sopenharmony_ci#define REQUEST_(r_name, r_value, index, r_fields) \ 778c2ecf20Sopenharmony_cir_fields 788c2ecf20Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) \ 798c2ecf20Sopenharmony_ci BUILD_BUG_ON(offsetof(struct STRUCT_NAME(r_name), f_name) != f_offset); 808c2ecf20Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ 818c2ecf20Sopenharmony_ci __field_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) 828c2ecf20Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) \ 838c2ecf20Sopenharmony_ci __field_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic inline void CAT2(NAME_LOWER, _assert_offsets_correct)(void) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci#include REQUEST_FILE 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* 918c2ecf20Sopenharmony_ci * Generate event attributes: 928c2ecf20Sopenharmony_ci * PMU_EVENT_ATTR_STRING(<request name>_<field name>, 938c2ecf20Sopenharmony_ci * <NAME_LOWER>_event_attr_<request name>_<field name>, 948c2ecf20Sopenharmony_ci * "request=<request value>" 958c2ecf20Sopenharmony_ci * "starting_index=<starting index type>" 968c2ecf20Sopenharmony_ci * "counter_info_version=CURRENT_COUNTER_INFO_VERSION" 978c2ecf20Sopenharmony_ci * "length=<f_size>" 988c2ecf20Sopenharmony_ci * "offset=<f_offset>") 998c2ecf20Sopenharmony_ci * 1008c2ecf20Sopenharmony_ci * TODO: counter_info_version may need to vary, we should interperate the 1018c2ecf20Sopenharmony_ci * value to some extent 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci#define EVENT_ATTR_NAME__(name, r_name, c_name) \ 1048c2ecf20Sopenharmony_ci name ## _event_attr_ ## r_name ## _ ## c_name 1058c2ecf20Sopenharmony_ci#define EVENT_ATTR_NAME_(name, r_name, c_name) \ 1068c2ecf20Sopenharmony_ci EVENT_ATTR_NAME__(name, r_name, c_name) 1078c2ecf20Sopenharmony_ci#define EVENT_ATTR_NAME(r_name, c_name) \ 1088c2ecf20Sopenharmony_ci EVENT_ATTR_NAME_(NAME_LOWER, r_name, c_name) 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci#include "_clear.h" 1118c2ecf20Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) 1128c2ecf20Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) 1138c2ecf20Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ 1148c2ecf20Sopenharmony_ciPMU_EVENT_ATTR_STRING( \ 1158c2ecf20Sopenharmony_ci CAT3(r_name, _, c_name), \ 1168c2ecf20Sopenharmony_ci EVENT_ATTR_NAME(r_name, c_name), \ 1178c2ecf20Sopenharmony_ci "request=" __stringify(r_value) "," \ 1188c2ecf20Sopenharmony_ci r_idx_1 "," \ 1198c2ecf20Sopenharmony_ci "counter_info_version=" \ 1208c2ecf20Sopenharmony_ci __stringify(COUNTER_INFO_VERSION_CURRENT) "," \ 1218c2ecf20Sopenharmony_ci "length=" #c_size "," \ 1228c2ecf20Sopenharmony_ci "offset=" #c_offset) 1238c2ecf20Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 1248c2ecf20Sopenharmony_ci r_fields 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#include REQUEST_FILE 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/* 1298c2ecf20Sopenharmony_ci * Define event attribute array 1308c2ecf20Sopenharmony_ci * static struct attribute *hv_gpci_event_attrs[] = { 1318c2ecf20Sopenharmony_ci * &<NAME_LOWER>_event_attr_<request name>_<field name>.attr, 1328c2ecf20Sopenharmony_ci * }; 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci#include "_clear.h" 1358c2ecf20Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) 1368c2ecf20Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ 1378c2ecf20Sopenharmony_ci &EVENT_ATTR_NAME(r_name, c_name).attr.attr, 1388c2ecf20Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) 1398c2ecf20Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 1408c2ecf20Sopenharmony_ci r_fields 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci/* Generate event list for platforms with counter_info_version 0x6 or below */ 1438c2ecf20Sopenharmony_cistatic __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = { 1448c2ecf20Sopenharmony_ci#include REQUEST_FILE 1458c2ecf20Sopenharmony_ci NULL 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* 1498c2ecf20Sopenharmony_ci * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci 1508c2ecf20Sopenharmony_ci * events were deprecated for platform firmware that supports 1518c2ecf20Sopenharmony_ci * counter_info_version 0x8 or above. 1528c2ecf20Sopenharmony_ci * Those deprecated events are still part of platform firmware that 1538c2ecf20Sopenharmony_ci * support counter_info_version 0x6 and below. As per the getPerfCountInfo 1548c2ecf20Sopenharmony_ci * v1.018 documentation there is no counter_info_version 0x7. 1558c2ecf20Sopenharmony_ci * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of 1568c2ecf20Sopenharmony_ci * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms 1578c2ecf20Sopenharmony_ci * that supports counter_info_version 0x8 or above. 1588c2ecf20Sopenharmony_ci */ 1598c2ecf20Sopenharmony_ci#undef ENABLE_EVENTS_COUNTERINFO_V6 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/* Generate event list for platforms with counter_info_version 0x8 or above*/ 1628c2ecf20Sopenharmony_cistatic __maybe_unused struct attribute *hv_gpci_event_attrs[] = { 1638c2ecf20Sopenharmony_ci#include REQUEST_FILE 1648c2ecf20Sopenharmony_ci NULL 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci/* cleanup */ 1688c2ecf20Sopenharmony_ci#include "_clear.h" 1698c2ecf20Sopenharmony_ci#undef EVENT_ATTR_NAME 1708c2ecf20Sopenharmony_ci#undef EVENT_ATTR_NAME_ 1718c2ecf20Sopenharmony_ci#undef BIT_NAME 1728c2ecf20Sopenharmony_ci#undef BIT_NAME_ 1738c2ecf20Sopenharmony_ci#undef STRUCT_NAME 1748c2ecf20Sopenharmony_ci#undef REQUEST_VALUE 1758c2ecf20Sopenharmony_ci#undef REQUEST_VALUE_ 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#endif 178