162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ 362306a36Sopenharmony_ci#define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/perf_event.h> 662306a36Sopenharmony_ci#include <linux/stringify.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef REQUEST_FILE 962306a36Sopenharmony_ci#error "REQUEST_FILE must be defined before including" 1062306a36Sopenharmony_ci#endif 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#ifndef NAME_LOWER 1362306a36Sopenharmony_ci#error "NAME_LOWER must be defined before including" 1462306a36Sopenharmony_ci#endif 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#ifndef NAME_UPPER 1762306a36Sopenharmony_ci#error "NAME_UPPER must be defined before including" 1862306a36Sopenharmony_ci#endif 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define BE_TYPE_b1 __u8 2162306a36Sopenharmony_ci#define BE_TYPE_b2 __be16 2262306a36Sopenharmony_ci#define BE_TYPE_b4 __be32 2362306a36Sopenharmony_ci#define BE_TYPE_b8 __be64 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define BYTES_TO_BE_TYPE(bytes) \ 2662306a36Sopenharmony_ci BE_TYPE_b##bytes 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define CAT2_(a, b) a ## b 2962306a36Sopenharmony_ci#define CAT2(a, b) CAT2_(a, b) 3062306a36Sopenharmony_ci#define CAT3_(a, b, c) a ## b ## c 3162306a36Sopenharmony_ci#define CAT3(a, b, c) CAT3_(a, b, c) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* 3462306a36Sopenharmony_ci * enumerate the request values as 3562306a36Sopenharmony_ci * <NAME_UPPER>_<request name> = <request value> 3662306a36Sopenharmony_ci */ 3762306a36Sopenharmony_ci#define REQUEST_VALUE__(name_upper, r_name) name_upper ## _ ## r_name 3862306a36Sopenharmony_ci#define REQUEST_VALUE_(name_upper, r_name) REQUEST_VALUE__(name_upper, r_name) 3962306a36Sopenharmony_ci#define REQUEST_VALUE(r_name) REQUEST_VALUE_(NAME_UPPER, r_name) 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#include "_clear.h" 4262306a36Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 4362306a36Sopenharmony_ci REQUEST_VALUE(r_name) = r_value, 4462306a36Sopenharmony_cienum CAT2(NAME_LOWER, _requests) { 4562306a36Sopenharmony_ci#include REQUEST_FILE 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* 4962306a36Sopenharmony_ci * For each request: 5062306a36Sopenharmony_ci * struct <NAME_LOWER>_<request name> { 5162306a36Sopenharmony_ci * r_fields 5262306a36Sopenharmony_ci * }; 5362306a36Sopenharmony_ci */ 5462306a36Sopenharmony_ci#include "_clear.h" 5562306a36Sopenharmony_ci#define STRUCT_NAME__(name_lower, r_name) name_lower ## _ ## r_name 5662306a36Sopenharmony_ci#define STRUCT_NAME_(name_lower, r_name) STRUCT_NAME__(name_lower, r_name) 5762306a36Sopenharmony_ci#define STRUCT_NAME(r_name) STRUCT_NAME_(NAME_LOWER, r_name) 5862306a36Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 5962306a36Sopenharmony_cistruct STRUCT_NAME(r_name) { \ 6062306a36Sopenharmony_ci r_fields \ 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \ 6362306a36Sopenharmony_ci BYTES_TO_BE_TYPE(f_bytes) f_name; 6462306a36Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \ 6562306a36Sopenharmony_ci __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) 6662306a36Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_bytes, a_name) \ 6762306a36Sopenharmony_ci __u8 a_name[a_bytes]; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#include REQUEST_FILE 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* 7262306a36Sopenharmony_ci * Generate a check of the field offsets 7362306a36Sopenharmony_ci * <NAME_LOWER>_assert_offsets_correct() 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_ci#include "_clear.h" 7662306a36Sopenharmony_ci#define REQUEST_(r_name, r_value, index, r_fields) \ 7762306a36Sopenharmony_cir_fields 7862306a36Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) \ 7962306a36Sopenharmony_ci BUILD_BUG_ON(offsetof(struct STRUCT_NAME(r_name), f_name) != f_offset); 8062306a36Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ 8162306a36Sopenharmony_ci __field_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) 8262306a36Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) \ 8362306a36Sopenharmony_ci __field_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic inline void CAT2(NAME_LOWER, _assert_offsets_correct)(void) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci#include REQUEST_FILE 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* 9162306a36Sopenharmony_ci * Generate event attributes: 9262306a36Sopenharmony_ci * PMU_EVENT_ATTR_STRING(<request name>_<field name>, 9362306a36Sopenharmony_ci * <NAME_LOWER>_event_attr_<request name>_<field name>, 9462306a36Sopenharmony_ci * "request=<request value>" 9562306a36Sopenharmony_ci * "starting_index=<starting index type>" 9662306a36Sopenharmony_ci * "counter_info_version=CURRENT_COUNTER_INFO_VERSION" 9762306a36Sopenharmony_ci * "length=<f_size>" 9862306a36Sopenharmony_ci * "offset=<f_offset>") 9962306a36Sopenharmony_ci * 10062306a36Sopenharmony_ci * TODO: counter_info_version may need to vary, we should interperate the 10162306a36Sopenharmony_ci * value to some extent 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci#define EVENT_ATTR_NAME__(name, r_name, c_name) \ 10462306a36Sopenharmony_ci name ## _event_attr_ ## r_name ## _ ## c_name 10562306a36Sopenharmony_ci#define EVENT_ATTR_NAME_(name, r_name, c_name) \ 10662306a36Sopenharmony_ci EVENT_ATTR_NAME__(name, r_name, c_name) 10762306a36Sopenharmony_ci#define EVENT_ATTR_NAME(r_name, c_name) \ 10862306a36Sopenharmony_ci EVENT_ATTR_NAME_(NAME_LOWER, r_name, c_name) 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#include "_clear.h" 11162306a36Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) 11262306a36Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) 11362306a36Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ 11462306a36Sopenharmony_ciPMU_EVENT_ATTR_STRING( \ 11562306a36Sopenharmony_ci CAT3(r_name, _, c_name), \ 11662306a36Sopenharmony_ci EVENT_ATTR_NAME(r_name, c_name), \ 11762306a36Sopenharmony_ci "request=" __stringify(r_value) "," \ 11862306a36Sopenharmony_ci r_idx_1 "," \ 11962306a36Sopenharmony_ci "counter_info_version=" \ 12062306a36Sopenharmony_ci __stringify(COUNTER_INFO_VERSION_CURRENT) "," \ 12162306a36Sopenharmony_ci "length=" #c_size "," \ 12262306a36Sopenharmony_ci "offset=" #c_offset) 12362306a36Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 12462306a36Sopenharmony_ci r_fields 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#include REQUEST_FILE 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/* 12962306a36Sopenharmony_ci * Define event attribute array 13062306a36Sopenharmony_ci * static struct attribute *hv_gpci_event_attrs[] = { 13162306a36Sopenharmony_ci * &<NAME_LOWER>_event_attr_<request name>_<field name>.attr, 13262306a36Sopenharmony_ci * }; 13362306a36Sopenharmony_ci */ 13462306a36Sopenharmony_ci#include "_clear.h" 13562306a36Sopenharmony_ci#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) 13662306a36Sopenharmony_ci#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ 13762306a36Sopenharmony_ci &EVENT_ATTR_NAME(r_name, c_name).attr.attr, 13862306a36Sopenharmony_ci#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) 13962306a36Sopenharmony_ci#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ 14062306a36Sopenharmony_ci r_fields 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* Generate event list for platforms with counter_info_version 0x6 or below */ 14362306a36Sopenharmony_cistatic __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = { 14462306a36Sopenharmony_ci#include REQUEST_FILE 14562306a36Sopenharmony_ci NULL 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* 14962306a36Sopenharmony_ci * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci 15062306a36Sopenharmony_ci * events were deprecated for platform firmware that supports 15162306a36Sopenharmony_ci * counter_info_version 0x8 or above. 15262306a36Sopenharmony_ci * Those deprecated events are still part of platform firmware that 15362306a36Sopenharmony_ci * support counter_info_version 0x6 and below. As per the getPerfCountInfo 15462306a36Sopenharmony_ci * v1.018 documentation there is no counter_info_version 0x7. 15562306a36Sopenharmony_ci * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of 15662306a36Sopenharmony_ci * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms 15762306a36Sopenharmony_ci * that supports counter_info_version 0x8 or above. 15862306a36Sopenharmony_ci */ 15962306a36Sopenharmony_ci#undef ENABLE_EVENTS_COUNTERINFO_V6 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* Generate event list for platforms with counter_info_version 0x8 or above*/ 16262306a36Sopenharmony_cistatic __maybe_unused struct attribute *hv_gpci_event_attrs[] = { 16362306a36Sopenharmony_ci#include REQUEST_FILE 16462306a36Sopenharmony_ci NULL 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* cleanup */ 16862306a36Sopenharmony_ci#include "_clear.h" 16962306a36Sopenharmony_ci#undef EVENT_ATTR_NAME 17062306a36Sopenharmony_ci#undef EVENT_ATTR_NAME_ 17162306a36Sopenharmony_ci#undef BIT_NAME 17262306a36Sopenharmony_ci#undef BIT_NAME_ 17362306a36Sopenharmony_ci#undef STRUCT_NAME 17462306a36Sopenharmony_ci#undef REQUEST_VALUE 17562306a36Sopenharmony_ci#undef REQUEST_VALUE_ 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci#endif 178