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