xref: /openbmc/linux/arch/powerpc/perf/req-gen/perf.h (revision f79e4d5f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_
3 #define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_
4 
5 #include <linux/perf_event.h>
6 
7 #ifndef REQUEST_FILE
8 #error "REQUEST_FILE must be defined before including"
9 #endif
10 
11 #ifndef NAME_LOWER
12 #error "NAME_LOWER must be defined before including"
13 #endif
14 
15 #ifndef NAME_UPPER
16 #error "NAME_UPPER must be defined before including"
17 #endif
18 
19 #define BE_TYPE_b1 __u8
20 #define BE_TYPE_b2 __be16
21 #define BE_TYPE_b4 __be32
22 #define BE_TYPE_b8 __be64
23 
24 #define BYTES_TO_BE_TYPE(bytes) \
25 		BE_TYPE_b##bytes
26 
27 #define CAT2_(a, b) a ## b
28 #define CAT2(a, b) CAT2_(a, b)
29 #define CAT3_(a, b, c) a ## b ## c
30 #define CAT3(a, b, c) CAT3_(a, b, c)
31 
32 /*
33  * enumerate the request values as
34  * <NAME_UPPER>_<request name> = <request value>
35  */
36 #define REQUEST_VALUE__(name_upper, r_name) name_upper ## _ ## r_name
37 #define REQUEST_VALUE_(name_upper, r_name) REQUEST_VALUE__(name_upper, r_name)
38 #define REQUEST_VALUE(r_name) REQUEST_VALUE_(NAME_UPPER, r_name)
39 
40 #include "_clear.h"
41 #define REQUEST_(r_name, r_value, r_idx_1, r_fields) \
42 	REQUEST_VALUE(r_name) = r_value,
43 enum CAT2(NAME_LOWER, _requests) {
44 #include REQUEST_FILE
45 };
46 
47 /*
48  * For each request:
49  * struct <NAME_LOWER>_<request name> {
50  *	r_fields
51  * };
52  */
53 #include "_clear.h"
54 #define STRUCT_NAME__(name_lower, r_name) name_lower ## _ ## r_name
55 #define STRUCT_NAME_(name_lower, r_name) STRUCT_NAME__(name_lower, r_name)
56 #define STRUCT_NAME(r_name) STRUCT_NAME_(NAME_LOWER, r_name)
57 #define REQUEST_(r_name, r_value, r_idx_1, r_fields)	\
58 struct STRUCT_NAME(r_name) {				\
59 	r_fields					\
60 };
61 #define __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \
62 	BYTES_TO_BE_TYPE(f_bytes) f_name;
63 #define __count_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \
64 	__field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name)
65 #define __array_(r_name, r_value, r_idx_1, a_offset, a_bytes, a_name) \
66 	__u8 a_name[a_bytes];
67 
68 #include REQUEST_FILE
69 
70 /*
71  * Generate a check of the field offsets
72  * <NAME_LOWER>_assert_offsets_correct()
73  */
74 #include "_clear.h"
75 #define REQUEST_(r_name, r_value, index, r_fields)			\
76 r_fields
77 #define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) \
78 	BUILD_BUG_ON(offsetof(struct STRUCT_NAME(r_name), f_name) != f_offset);
79 #define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \
80 	__field_(r_name, r_value, r_idx_1, c_offset, c_size, c_name)
81 #define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) \
82 	__field_(r_name, r_value, r_idx_1, a_offset, a_size, a_name)
83 
84 static inline void CAT2(NAME_LOWER, _assert_offsets_correct)(void)
85 {
86 #include REQUEST_FILE
87 }
88 
89 /*
90  * Generate event attributes:
91  * PMU_EVENT_ATTR_STRING(<request name>_<field name>,
92  *	<NAME_LOWER>_event_attr_<request name>_<field name>,
93  *		"request=<request value>"
94  *		"starting_index=<starting index type>"
95  *		"counter_info_version=CURRENT_COUNTER_INFO_VERSION"
96  *		"length=<f_size>"
97  *		"offset=<f_offset>")
98  *
99  *	TODO: counter_info_version may need to vary, we should interperate the
100  *	value to some extent
101  */
102 #define EVENT_ATTR_NAME__(name, r_name, c_name) \
103 	name ## _event_attr_ ## r_name ## _ ## c_name
104 #define EVENT_ATTR_NAME_(name, r_name, c_name) \
105 	EVENT_ATTR_NAME__(name, r_name, c_name)
106 #define EVENT_ATTR_NAME(r_name, c_name) \
107 	EVENT_ATTR_NAME_(NAME_LOWER, r_name, c_name)
108 
109 #include "_clear.h"
110 #define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name)
111 #define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name)
112 #define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name)	\
113 PMU_EVENT_ATTR_STRING(							\
114 		CAT3(r_name, _, c_name),				\
115 		EVENT_ATTR_NAME(r_name, c_name),			\
116 		"request=" __stringify(r_value) ","			\
117 		r_idx_1 ","						\
118 		"counter_info_version="					\
119 			__stringify(COUNTER_INFO_VERSION_CURRENT) ","	\
120 		"length=" #c_size ","					\
121 		"offset=" #c_offset)
122 #define REQUEST_(r_name, r_value, r_idx_1, r_fields)			\
123 	r_fields
124 
125 #include REQUEST_FILE
126 
127 /*
128  * Define event attribute array
129  * static struct attribute *hv_gpci_event_attrs[] = {
130  *	&<NAME_LOWER>_event_attr_<request name>_<field name>.attr,
131  * };
132  */
133 #include "_clear.h"
134 #define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name)
135 #define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name)	\
136 	&EVENT_ATTR_NAME(r_name, c_name).attr.attr,
137 #define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name)
138 #define REQUEST_(r_name, r_value, r_idx_1, r_fields)			\
139 	r_fields
140 
141 static __maybe_unused struct attribute *hv_gpci_event_attrs[] = {
142 #include REQUEST_FILE
143 	NULL
144 };
145 
146 /* cleanup */
147 #include "_clear.h"
148 #undef EVENT_ATTR_NAME
149 #undef EVENT_ATTR_NAME_
150 #undef BIT_NAME
151 #undef BIT_NAME_
152 #undef STRUCT_NAME
153 #undef REQUEST_VALUE
154 #undef REQUEST_VALUE_
155 
156 #endif
157