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