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