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, 42enum 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) \ 57struct 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) \ 75r_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 83static 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) \ 112PMU_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 140static __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