Commit | Line | Data |
---|---|---|
9e9f6010 CS |
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 |