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