mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
4.6 KiB
157 lines
4.6 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
#ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ |
|
#define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ |
|
|
|
#include <linux/perf_event.h> |
|
#include <linux/stringify.h> |
|
|
|
#ifndef REQUEST_FILE |
|
#error "REQUEST_FILE must be defined before including" |
|
#endif |
|
|
|
#ifndef NAME_LOWER |
|
#error "NAME_LOWER must be defined before including" |
|
#endif |
|
|
|
#ifndef NAME_UPPER |
|
#error "NAME_UPPER must be defined before including" |
|
#endif |
|
|
|
#define BE_TYPE_b1 __u8 |
|
#define BE_TYPE_b2 __be16 |
|
#define BE_TYPE_b4 __be32 |
|
#define BE_TYPE_b8 __be64 |
|
|
|
#define BYTES_TO_BE_TYPE(bytes) \ |
|
BE_TYPE_b##bytes |
|
|
|
#define CAT2_(a, b) a ## b |
|
#define CAT2(a, b) CAT2_(a, b) |
|
#define CAT3_(a, b, c) a ## b ## c |
|
#define CAT3(a, b, c) CAT3_(a, b, c) |
|
|
|
/* |
|
* enumerate the request values as |
|
* <NAME_UPPER>_<request name> = <request value> |
|
*/ |
|
#define REQUEST_VALUE__(name_upper, r_name) name_upper ## _ ## r_name |
|
#define REQUEST_VALUE_(name_upper, r_name) REQUEST_VALUE__(name_upper, r_name) |
|
#define REQUEST_VALUE(r_name) REQUEST_VALUE_(NAME_UPPER, r_name) |
|
|
|
#include "_clear.h" |
|
#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ |
|
REQUEST_VALUE(r_name) = r_value, |
|
enum CAT2(NAME_LOWER, _requests) { |
|
#include REQUEST_FILE |
|
}; |
|
|
|
/* |
|
* For each request: |
|
* struct <NAME_LOWER>_<request name> { |
|
* r_fields |
|
* }; |
|
*/ |
|
#include "_clear.h" |
|
#define STRUCT_NAME__(name_lower, r_name) name_lower ## _ ## r_name |
|
#define STRUCT_NAME_(name_lower, r_name) STRUCT_NAME__(name_lower, r_name) |
|
#define STRUCT_NAME(r_name) STRUCT_NAME_(NAME_LOWER, r_name) |
|
#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ |
|
struct STRUCT_NAME(r_name) { \ |
|
r_fields \ |
|
}; |
|
#define __field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \ |
|
BYTES_TO_BE_TYPE(f_bytes) f_name; |
|
#define __count_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) \ |
|
__field_(r_name, r_value, r_idx_1, f_offset, f_bytes, f_name) |
|
#define __array_(r_name, r_value, r_idx_1, a_offset, a_bytes, a_name) \ |
|
__u8 a_name[a_bytes]; |
|
|
|
#include REQUEST_FILE |
|
|
|
/* |
|
* Generate a check of the field offsets |
|
* <NAME_LOWER>_assert_offsets_correct() |
|
*/ |
|
#include "_clear.h" |
|
#define REQUEST_(r_name, r_value, index, r_fields) \ |
|
r_fields |
|
#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) \ |
|
BUILD_BUG_ON(offsetof(struct STRUCT_NAME(r_name), f_name) != f_offset); |
|
#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ |
|
__field_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) |
|
#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) \ |
|
__field_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) |
|
|
|
static inline void CAT2(NAME_LOWER, _assert_offsets_correct)(void) |
|
{ |
|
#include REQUEST_FILE |
|
} |
|
|
|
/* |
|
* Generate event attributes: |
|
* PMU_EVENT_ATTR_STRING(<request name>_<field name>, |
|
* <NAME_LOWER>_event_attr_<request name>_<field name>, |
|
* "request=<request value>" |
|
* "starting_index=<starting index type>" |
|
* "counter_info_version=CURRENT_COUNTER_INFO_VERSION" |
|
* "length=<f_size>" |
|
* "offset=<f_offset>") |
|
* |
|
* TODO: counter_info_version may need to vary, we should interperate the |
|
* value to some extent |
|
*/ |
|
#define EVENT_ATTR_NAME__(name, r_name, c_name) \ |
|
name ## _event_attr_ ## r_name ## _ ## c_name |
|
#define EVENT_ATTR_NAME_(name, r_name, c_name) \ |
|
EVENT_ATTR_NAME__(name, r_name, c_name) |
|
#define EVENT_ATTR_NAME(r_name, c_name) \ |
|
EVENT_ATTR_NAME_(NAME_LOWER, r_name, c_name) |
|
|
|
#include "_clear.h" |
|
#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) |
|
#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) |
|
#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ |
|
PMU_EVENT_ATTR_STRING( \ |
|
CAT3(r_name, _, c_name), \ |
|
EVENT_ATTR_NAME(r_name, c_name), \ |
|
"request=" __stringify(r_value) "," \ |
|
r_idx_1 "," \ |
|
"counter_info_version=" \ |
|
__stringify(COUNTER_INFO_VERSION_CURRENT) "," \ |
|
"length=" #c_size "," \ |
|
"offset=" #c_offset) |
|
#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ |
|
r_fields |
|
|
|
#include REQUEST_FILE |
|
|
|
/* |
|
* Define event attribute array |
|
* static struct attribute *hv_gpci_event_attrs[] = { |
|
* &<NAME_LOWER>_event_attr_<request name>_<field name>.attr, |
|
* }; |
|
*/ |
|
#include "_clear.h" |
|
#define __field_(r_name, r_value, r_idx_1, f_offset, f_size, f_name) |
|
#define __count_(r_name, r_value, r_idx_1, c_offset, c_size, c_name) \ |
|
&EVENT_ATTR_NAME(r_name, c_name).attr.attr, |
|
#define __array_(r_name, r_value, r_idx_1, a_offset, a_size, a_name) |
|
#define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ |
|
r_fields |
|
|
|
static __maybe_unused struct attribute *hv_gpci_event_attrs[] = { |
|
#include REQUEST_FILE |
|
NULL |
|
}; |
|
|
|
/* cleanup */ |
|
#include "_clear.h" |
|
#undef EVENT_ATTR_NAME |
|
#undef EVENT_ATTR_NAME_ |
|
#undef BIT_NAME |
|
#undef BIT_NAME_ |
|
#undef STRUCT_NAME |
|
#undef REQUEST_VALUE |
|
#undef REQUEST_VALUE_ |
|
|
|
#endif
|
|
|