162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Stage 1 of the trace events.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Override the macros in the event tracepoint header <trace/events/XXX.h>
662306a36Sopenharmony_ci * to include the following:
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * struct trace_event_raw_<call> {
962306a36Sopenharmony_ci *	struct trace_entry		ent;
1062306a36Sopenharmony_ci *	<type>				<item>;
1162306a36Sopenharmony_ci *	<type2>				<item2>[<len>];
1262306a36Sopenharmony_ci *	[...]
1362306a36Sopenharmony_ci * };
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * The <type> <item> is created by the __field(type, item) macro or
1662306a36Sopenharmony_ci * the __array(type2, item2, len) macro.
1762306a36Sopenharmony_ci * We simply do "type item;", and that will create the fields
1862306a36Sopenharmony_ci * in the structure.
1962306a36Sopenharmony_ci */
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include <linux/trace_events.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#ifndef TRACE_SYSTEM_VAR
2462306a36Sopenharmony_ci#define TRACE_SYSTEM_VAR TRACE_SYSTEM
2562306a36Sopenharmony_ci#endif
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include "stages/init.h"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/*
3062306a36Sopenharmony_ci * DECLARE_EVENT_CLASS can be used to add a generic function
3162306a36Sopenharmony_ci * handlers for events. That is, if all events have the same
3262306a36Sopenharmony_ci * parameters and just have distinct trace points.
3362306a36Sopenharmony_ci * Each tracepoint can be defined with DEFINE_EVENT and that
3462306a36Sopenharmony_ci * will map the DECLARE_EVENT_CLASS to the tracepoint.
3562306a36Sopenharmony_ci *
3662306a36Sopenharmony_ci * TRACE_EVENT is a one to one mapping between tracepoint and template.
3762306a36Sopenharmony_ci */
3862306a36Sopenharmony_ci#undef TRACE_EVENT
3962306a36Sopenharmony_ci#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
4062306a36Sopenharmony_ci	DECLARE_EVENT_CLASS(name,			       \
4162306a36Sopenharmony_ci			     PARAMS(proto),		       \
4262306a36Sopenharmony_ci			     PARAMS(args),		       \
4362306a36Sopenharmony_ci			     PARAMS(tstruct),		       \
4462306a36Sopenharmony_ci			     PARAMS(assign),		       \
4562306a36Sopenharmony_ci			     PARAMS(print));		       \
4662306a36Sopenharmony_ci	DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#include "stages/stage1_struct_define.h"
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
5162306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)	\
5262306a36Sopenharmony_ci	struct trace_event_raw_##name {					\
5362306a36Sopenharmony_ci		struct trace_entry	ent;				\
5462306a36Sopenharmony_ci		tstruct							\
5562306a36Sopenharmony_ci		char			__data[];			\
5662306a36Sopenharmony_ci	};								\
5762306a36Sopenharmony_ci									\
5862306a36Sopenharmony_ci	static struct trace_event_class event_class_##name;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#undef DEFINE_EVENT
6162306a36Sopenharmony_ci#define DEFINE_EVENT(template, name, proto, args)	\
6262306a36Sopenharmony_ci	static struct trace_event_call	__used		\
6362306a36Sopenharmony_ci	__attribute__((__aligned__(4))) event_##name
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#undef DEFINE_EVENT_FN
6662306a36Sopenharmony_ci#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)	\
6762306a36Sopenharmony_ci	DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT
7062306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print)	\
7162306a36Sopenharmony_ci	DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* Callbacks are meaningless to ftrace. */
7462306a36Sopenharmony_ci#undef TRACE_EVENT_FN
7562306a36Sopenharmony_ci#define TRACE_EVENT_FN(name, proto, args, tstruct,			\
7662306a36Sopenharmony_ci		assign, print, reg, unreg)				\
7762306a36Sopenharmony_ci	TRACE_EVENT(name, PARAMS(proto), PARAMS(args),			\
7862306a36Sopenharmony_ci		PARAMS(tstruct), PARAMS(assign), PARAMS(print))		\
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#undef TRACE_EVENT_FN_COND
8162306a36Sopenharmony_ci#define TRACE_EVENT_FN_COND(name, proto, args, cond, tstruct,	\
8262306a36Sopenharmony_ci		assign, print, reg, unreg)				\
8362306a36Sopenharmony_ci	TRACE_EVENT_CONDITION(name, PARAMS(proto), PARAMS(args), PARAMS(cond),		\
8462306a36Sopenharmony_ci		PARAMS(tstruct), PARAMS(assign), PARAMS(print))		\
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#undef TRACE_EVENT_FLAGS
8762306a36Sopenharmony_ci#define TRACE_EVENT_FLAGS(name, value)					\
8862306a36Sopenharmony_ci	__TRACE_EVENT_FLAGS(name, value)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#undef TRACE_EVENT_PERF_PERM
9162306a36Sopenharmony_ci#define TRACE_EVENT_PERF_PERM(name, expr...)				\
9262306a36Sopenharmony_ci	__TRACE_EVENT_PERF_PERM(name, expr)
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/*
9762306a36Sopenharmony_ci * Stage 2 of the trace events.
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * Include the following:
10062306a36Sopenharmony_ci *
10162306a36Sopenharmony_ci * struct trace_event_data_offsets_<call> {
10262306a36Sopenharmony_ci *	u32				<item1>;
10362306a36Sopenharmony_ci *	u32				<item2>;
10462306a36Sopenharmony_ci *	[...]
10562306a36Sopenharmony_ci * };
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * The __dynamic_array() macro will create each u32 <item>, this is
10862306a36Sopenharmony_ci * to keep the offset of each array from the beginning of the event.
10962306a36Sopenharmony_ci * The size of an array is also encoded, in the higher 16 bits of <item>.
11062306a36Sopenharmony_ci */
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci#include "stages/stage2_data_offsets.h"
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
11562306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
11662306a36Sopenharmony_ci	struct trace_event_data_offsets_##call {			\
11762306a36Sopenharmony_ci		tstruct;						\
11862306a36Sopenharmony_ci	};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#undef DEFINE_EVENT
12162306a36Sopenharmony_ci#define DEFINE_EVENT(template, name, proto, args)
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT
12462306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print)
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#undef TRACE_EVENT_FLAGS
12762306a36Sopenharmony_ci#define TRACE_EVENT_FLAGS(event, flag)
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci#undef TRACE_EVENT_PERF_PERM
13062306a36Sopenharmony_ci#define TRACE_EVENT_PERF_PERM(event, expr...)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/*
13562306a36Sopenharmony_ci * Stage 3 of the trace events.
13662306a36Sopenharmony_ci *
13762306a36Sopenharmony_ci * Override the macros in the event tracepoint header <trace/events/XXX.h>
13862306a36Sopenharmony_ci * to include the following:
13962306a36Sopenharmony_ci *
14062306a36Sopenharmony_ci * enum print_line_t
14162306a36Sopenharmony_ci * trace_raw_output_<call>(struct trace_iterator *iter, int flags)
14262306a36Sopenharmony_ci * {
14362306a36Sopenharmony_ci *	struct trace_seq *s = &iter->seq;
14462306a36Sopenharmony_ci *	struct trace_event_raw_<call> *field; <-- defined in stage 1
14562306a36Sopenharmony_ci *	struct trace_seq *p = &iter->tmp_seq;
14662306a36Sopenharmony_ci *
14762306a36Sopenharmony_ci * -------(for event)-------
14862306a36Sopenharmony_ci *
14962306a36Sopenharmony_ci *	struct trace_entry *entry;
15062306a36Sopenharmony_ci *
15162306a36Sopenharmony_ci *	entry = iter->ent;
15262306a36Sopenharmony_ci *
15362306a36Sopenharmony_ci *	if (entry->type != event_<call>->event.type) {
15462306a36Sopenharmony_ci *		WARN_ON_ONCE(1);
15562306a36Sopenharmony_ci *		return TRACE_TYPE_UNHANDLED;
15662306a36Sopenharmony_ci *	}
15762306a36Sopenharmony_ci *
15862306a36Sopenharmony_ci *	field = (typeof(field))entry;
15962306a36Sopenharmony_ci *
16062306a36Sopenharmony_ci *	trace_seq_init(p);
16162306a36Sopenharmony_ci *	return trace_output_call(iter, <call>, <TP_printk> "\n");
16262306a36Sopenharmony_ci *
16362306a36Sopenharmony_ci * ------(or, for event class)------
16462306a36Sopenharmony_ci *
16562306a36Sopenharmony_ci *	int ret;
16662306a36Sopenharmony_ci *
16762306a36Sopenharmony_ci *	field = (typeof(field))iter->ent;
16862306a36Sopenharmony_ci *
16962306a36Sopenharmony_ci *	ret = trace_raw_output_prep(iter, trace_event);
17062306a36Sopenharmony_ci *	if (ret != TRACE_TYPE_HANDLED)
17162306a36Sopenharmony_ci *		return ret;
17262306a36Sopenharmony_ci *
17362306a36Sopenharmony_ci *	trace_event_printf(iter, <TP_printk> "\n");
17462306a36Sopenharmony_ci *
17562306a36Sopenharmony_ci *	return trace_handle_return(s);
17662306a36Sopenharmony_ci * -------
17762306a36Sopenharmony_ci *  }
17862306a36Sopenharmony_ci *
17962306a36Sopenharmony_ci * This is the method used to print the raw event to the trace
18062306a36Sopenharmony_ci * output format. Note, this is not needed if the data is read
18162306a36Sopenharmony_ci * in binary.
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#include "stages/stage3_trace_output.h"
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
18762306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
18862306a36Sopenharmony_cistatic notrace enum print_line_t					\
18962306a36Sopenharmony_citrace_raw_output_##call(struct trace_iterator *iter, int flags,		\
19062306a36Sopenharmony_ci			struct trace_event *trace_event)		\
19162306a36Sopenharmony_ci{									\
19262306a36Sopenharmony_ci	struct trace_seq *s = &iter->seq;				\
19362306a36Sopenharmony_ci	struct trace_seq __maybe_unused *p = &iter->tmp_seq;		\
19462306a36Sopenharmony_ci	struct trace_event_raw_##call *field;				\
19562306a36Sopenharmony_ci	int ret;							\
19662306a36Sopenharmony_ci									\
19762306a36Sopenharmony_ci	field = (typeof(field))iter->ent;				\
19862306a36Sopenharmony_ci									\
19962306a36Sopenharmony_ci	ret = trace_raw_output_prep(iter, trace_event);			\
20062306a36Sopenharmony_ci	if (ret != TRACE_TYPE_HANDLED)					\
20162306a36Sopenharmony_ci		return ret;						\
20262306a36Sopenharmony_ci									\
20362306a36Sopenharmony_ci	trace_event_printf(iter, print);				\
20462306a36Sopenharmony_ci									\
20562306a36Sopenharmony_ci	return trace_handle_return(s);					\
20662306a36Sopenharmony_ci}									\
20762306a36Sopenharmony_cistatic struct trace_event_functions trace_event_type_funcs_##call = {	\
20862306a36Sopenharmony_ci	.trace			= trace_raw_output_##call,		\
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT
21262306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, call, proto, args, print)		\
21362306a36Sopenharmony_cistatic notrace enum print_line_t					\
21462306a36Sopenharmony_citrace_raw_output_##call(struct trace_iterator *iter, int flags,		\
21562306a36Sopenharmony_ci			 struct trace_event *event)			\
21662306a36Sopenharmony_ci{									\
21762306a36Sopenharmony_ci	struct trace_event_raw_##template *field;			\
21862306a36Sopenharmony_ci	struct trace_entry *entry;					\
21962306a36Sopenharmony_ci	struct trace_seq *p = &iter->tmp_seq;				\
22062306a36Sopenharmony_ci									\
22162306a36Sopenharmony_ci	entry = iter->ent;						\
22262306a36Sopenharmony_ci									\
22362306a36Sopenharmony_ci	if (entry->type != event_##call.event.type) {			\
22462306a36Sopenharmony_ci		WARN_ON_ONCE(1);					\
22562306a36Sopenharmony_ci		return TRACE_TYPE_UNHANDLED;				\
22662306a36Sopenharmony_ci	}								\
22762306a36Sopenharmony_ci									\
22862306a36Sopenharmony_ci	field = (typeof(field))entry;					\
22962306a36Sopenharmony_ci									\
23062306a36Sopenharmony_ci	trace_seq_init(p);						\
23162306a36Sopenharmony_ci	return trace_output_call(iter, #call, print);			\
23262306a36Sopenharmony_ci}									\
23362306a36Sopenharmony_cistatic struct trace_event_functions trace_event_type_funcs_##call = {	\
23462306a36Sopenharmony_ci	.trace			= trace_raw_output_##call,		\
23562306a36Sopenharmony_ci};
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci#include "stages/stage4_event_fields.h"
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
24262306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print)	\
24362306a36Sopenharmony_cistatic struct trace_event_fields trace_event_fields_##call[] = {	\
24462306a36Sopenharmony_ci	tstruct								\
24562306a36Sopenharmony_ci	{} };
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT
24862306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, name, proto, args, print)
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci#include "stages/stage5_get_offsets.h"
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
25562306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
25662306a36Sopenharmony_cistatic inline notrace int trace_event_get_offsets_##call(		\
25762306a36Sopenharmony_ci	struct trace_event_data_offsets_##call *__data_offsets, proto)	\
25862306a36Sopenharmony_ci{									\
25962306a36Sopenharmony_ci	int __data_size = 0;						\
26062306a36Sopenharmony_ci	int __maybe_unused __item_length;				\
26162306a36Sopenharmony_ci	struct trace_event_raw_##call __maybe_unused *entry;		\
26262306a36Sopenharmony_ci									\
26362306a36Sopenharmony_ci	tstruct;							\
26462306a36Sopenharmony_ci									\
26562306a36Sopenharmony_ci	return __data_size;						\
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci/*
27162306a36Sopenharmony_ci * Stage 4 of the trace events.
27262306a36Sopenharmony_ci *
27362306a36Sopenharmony_ci * Override the macros in the event tracepoint header <trace/events/XXX.h>
27462306a36Sopenharmony_ci * to include the following:
27562306a36Sopenharmony_ci *
27662306a36Sopenharmony_ci * For those macros defined with TRACE_EVENT:
27762306a36Sopenharmony_ci *
27862306a36Sopenharmony_ci * static struct trace_event_call event_<call>;
27962306a36Sopenharmony_ci *
28062306a36Sopenharmony_ci * static void trace_event_raw_event_<call>(void *__data, proto)
28162306a36Sopenharmony_ci * {
28262306a36Sopenharmony_ci *	struct trace_event_file *trace_file = __data;
28362306a36Sopenharmony_ci *	struct trace_event_call *event_call = trace_file->event_call;
28462306a36Sopenharmony_ci *	struct trace_event_data_offsets_<call> __maybe_unused __data_offsets;
28562306a36Sopenharmony_ci *	unsigned long eflags = trace_file->flags;
28662306a36Sopenharmony_ci *	enum event_trigger_type __tt = ETT_NONE;
28762306a36Sopenharmony_ci *	struct ring_buffer_event *event;
28862306a36Sopenharmony_ci *	struct trace_event_raw_<call> *entry; <-- defined in stage 1
28962306a36Sopenharmony_ci *	struct trace_buffer *buffer;
29062306a36Sopenharmony_ci *	unsigned long irq_flags;
29162306a36Sopenharmony_ci *	int __data_size;
29262306a36Sopenharmony_ci *	int pc;
29362306a36Sopenharmony_ci *
29462306a36Sopenharmony_ci *	if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) {
29562306a36Sopenharmony_ci *		if (eflags & EVENT_FILE_FL_TRIGGER_MODE)
29662306a36Sopenharmony_ci *			event_triggers_call(trace_file, NULL);
29762306a36Sopenharmony_ci *		if (eflags & EVENT_FILE_FL_SOFT_DISABLED)
29862306a36Sopenharmony_ci *			return;
29962306a36Sopenharmony_ci *	}
30062306a36Sopenharmony_ci *
30162306a36Sopenharmony_ci *	local_save_flags(irq_flags);
30262306a36Sopenharmony_ci *	pc = preempt_count();
30362306a36Sopenharmony_ci *
30462306a36Sopenharmony_ci *	__data_size = trace_event_get_offsets_<call>(&__data_offsets, args);
30562306a36Sopenharmony_ci *
30662306a36Sopenharmony_ci *	event = trace_event_buffer_lock_reserve(&buffer, trace_file,
30762306a36Sopenharmony_ci *				  event_<call>->event.type,
30862306a36Sopenharmony_ci *				  sizeof(*entry) + __data_size,
30962306a36Sopenharmony_ci *				  irq_flags, pc);
31062306a36Sopenharmony_ci *	if (!event)
31162306a36Sopenharmony_ci *		return;
31262306a36Sopenharmony_ci *	entry	= ring_buffer_event_data(event);
31362306a36Sopenharmony_ci *
31462306a36Sopenharmony_ci *	{ <assign>; }  <-- Here we assign the entries by the __field and
31562306a36Sopenharmony_ci *			   __array macros.
31662306a36Sopenharmony_ci *
31762306a36Sopenharmony_ci *	if (eflags & EVENT_FILE_FL_TRIGGER_COND)
31862306a36Sopenharmony_ci *		__tt = event_triggers_call(trace_file, entry);
31962306a36Sopenharmony_ci *
32062306a36Sopenharmony_ci *	if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT,
32162306a36Sopenharmony_ci *		     &trace_file->flags))
32262306a36Sopenharmony_ci *		ring_buffer_discard_commit(buffer, event);
32362306a36Sopenharmony_ci *	else if (!filter_check_discard(trace_file, entry, buffer, event))
32462306a36Sopenharmony_ci *		trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
32562306a36Sopenharmony_ci *
32662306a36Sopenharmony_ci *	if (__tt)
32762306a36Sopenharmony_ci *		event_triggers_post_call(trace_file, __tt);
32862306a36Sopenharmony_ci * }
32962306a36Sopenharmony_ci *
33062306a36Sopenharmony_ci * static struct trace_event ftrace_event_type_<call> = {
33162306a36Sopenharmony_ci *	.trace			= trace_raw_output_<call>, <-- stage 2
33262306a36Sopenharmony_ci * };
33362306a36Sopenharmony_ci *
33462306a36Sopenharmony_ci * static char print_fmt_<call>[] = <TP_printk>;
33562306a36Sopenharmony_ci *
33662306a36Sopenharmony_ci * static struct trace_event_class __used event_class_<template> = {
33762306a36Sopenharmony_ci *	.system			= "<system>",
33862306a36Sopenharmony_ci *	.fields_array		= trace_event_fields_<call>,
33962306a36Sopenharmony_ci *	.fields			= LIST_HEAD_INIT(event_class_##call.fields),
34062306a36Sopenharmony_ci *	.raw_init		= trace_event_raw_init,
34162306a36Sopenharmony_ci *	.probe			= trace_event_raw_event_##call,
34262306a36Sopenharmony_ci *	.reg			= trace_event_reg,
34362306a36Sopenharmony_ci * };
34462306a36Sopenharmony_ci *
34562306a36Sopenharmony_ci * static struct trace_event_call event_<call> = {
34662306a36Sopenharmony_ci *	.class			= event_class_<template>,
34762306a36Sopenharmony_ci *	{
34862306a36Sopenharmony_ci *		.tp			= &__tracepoint_<call>,
34962306a36Sopenharmony_ci *	},
35062306a36Sopenharmony_ci *	.event			= &ftrace_event_type_<call>,
35162306a36Sopenharmony_ci *	.print_fmt		= print_fmt_<call>,
35262306a36Sopenharmony_ci *	.flags			= TRACE_EVENT_FL_TRACEPOINT,
35362306a36Sopenharmony_ci * };
35462306a36Sopenharmony_ci * // its only safe to use pointers when doing linker tricks to
35562306a36Sopenharmony_ci * // create an array.
35662306a36Sopenharmony_ci * static struct trace_event_call __used
35762306a36Sopenharmony_ci * __section("_ftrace_events") *__event_<call> = &event_<call>;
35862306a36Sopenharmony_ci *
35962306a36Sopenharmony_ci */
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci#ifdef CONFIG_PERF_EVENTS
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci#define _TRACE_PERF_PROTO(call, proto)					\
36462306a36Sopenharmony_ci	static notrace void						\
36562306a36Sopenharmony_ci	perf_trace_##call(void *__data, proto);
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci#define _TRACE_PERF_INIT(call)						\
36862306a36Sopenharmony_ci	.perf_probe		= perf_trace_##call,
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#else
37162306a36Sopenharmony_ci#define _TRACE_PERF_PROTO(call, proto)
37262306a36Sopenharmony_ci#define _TRACE_PERF_INIT(call)
37362306a36Sopenharmony_ci#endif /* CONFIG_PERF_EVENTS */
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci#include "stages/stage6_event_callback.h"
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
37862306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
37962306a36Sopenharmony_ci									\
38062306a36Sopenharmony_cistatic notrace void							\
38162306a36Sopenharmony_citrace_event_raw_event_##call(void *__data, proto)			\
38262306a36Sopenharmony_ci{									\
38362306a36Sopenharmony_ci	struct trace_event_file *trace_file = __data;			\
38462306a36Sopenharmony_ci	struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
38562306a36Sopenharmony_ci	struct trace_event_buffer fbuffer;				\
38662306a36Sopenharmony_ci	struct trace_event_raw_##call *entry;				\
38762306a36Sopenharmony_ci	int __data_size;						\
38862306a36Sopenharmony_ci									\
38962306a36Sopenharmony_ci	if (trace_trigger_soft_disabled(trace_file))			\
39062306a36Sopenharmony_ci		return;							\
39162306a36Sopenharmony_ci									\
39262306a36Sopenharmony_ci	__data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
39362306a36Sopenharmony_ci									\
39462306a36Sopenharmony_ci	entry = trace_event_buffer_reserve(&fbuffer, trace_file,	\
39562306a36Sopenharmony_ci				 sizeof(*entry) + __data_size);		\
39662306a36Sopenharmony_ci									\
39762306a36Sopenharmony_ci	if (!entry)							\
39862306a36Sopenharmony_ci		return;							\
39962306a36Sopenharmony_ci									\
40062306a36Sopenharmony_ci	tstruct								\
40162306a36Sopenharmony_ci									\
40262306a36Sopenharmony_ci	{ assign; }							\
40362306a36Sopenharmony_ci									\
40462306a36Sopenharmony_ci	trace_event_buffer_commit(&fbuffer);				\
40562306a36Sopenharmony_ci}
40662306a36Sopenharmony_ci/*
40762306a36Sopenharmony_ci * The ftrace_test_probe is compiled out, it is only here as a build time check
40862306a36Sopenharmony_ci * to make sure that if the tracepoint handling changes, the ftrace probe will
40962306a36Sopenharmony_ci * fail to compile unless it too is updated.
41062306a36Sopenharmony_ci */
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci#undef DEFINE_EVENT
41362306a36Sopenharmony_ci#define DEFINE_EVENT(template, call, proto, args)			\
41462306a36Sopenharmony_cistatic inline void ftrace_test_probe_##call(void)			\
41562306a36Sopenharmony_ci{									\
41662306a36Sopenharmony_ci	check_trace_callback_type_##call(trace_event_raw_event_##template); \
41762306a36Sopenharmony_ci}
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci#include "stages/stage7_class_define.h"
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci#undef DECLARE_EVENT_CLASS
42462306a36Sopenharmony_ci#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
42562306a36Sopenharmony_ci_TRACE_PERF_PROTO(call, PARAMS(proto));					\
42662306a36Sopenharmony_cistatic char print_fmt_##call[] = print;					\
42762306a36Sopenharmony_cistatic struct trace_event_class __used __refdata event_class_##call = { \
42862306a36Sopenharmony_ci	.system			= TRACE_SYSTEM_STRING,			\
42962306a36Sopenharmony_ci	.fields_array		= trace_event_fields_##call,		\
43062306a36Sopenharmony_ci	.fields			= LIST_HEAD_INIT(event_class_##call.fields),\
43162306a36Sopenharmony_ci	.raw_init		= trace_event_raw_init,			\
43262306a36Sopenharmony_ci	.probe			= trace_event_raw_event_##call,		\
43362306a36Sopenharmony_ci	.reg			= trace_event_reg,			\
43462306a36Sopenharmony_ci	_TRACE_PERF_INIT(call)						\
43562306a36Sopenharmony_ci};
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci#undef DEFINE_EVENT
43862306a36Sopenharmony_ci#define DEFINE_EVENT(template, call, proto, args)			\
43962306a36Sopenharmony_ci									\
44062306a36Sopenharmony_cistatic struct trace_event_call __used event_##call = {			\
44162306a36Sopenharmony_ci	.class			= &event_class_##template,		\
44262306a36Sopenharmony_ci	{								\
44362306a36Sopenharmony_ci		.tp			= &__tracepoint_##call,		\
44462306a36Sopenharmony_ci	},								\
44562306a36Sopenharmony_ci	.event.funcs		= &trace_event_type_funcs_##template,	\
44662306a36Sopenharmony_ci	.print_fmt		= print_fmt_##template,			\
44762306a36Sopenharmony_ci	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
44862306a36Sopenharmony_ci};									\
44962306a36Sopenharmony_cistatic struct trace_event_call __used					\
45062306a36Sopenharmony_ci__section("_ftrace_events") *__event_##call = &event_##call
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci#undef DEFINE_EVENT_PRINT
45362306a36Sopenharmony_ci#define DEFINE_EVENT_PRINT(template, call, proto, args, print)		\
45462306a36Sopenharmony_ci									\
45562306a36Sopenharmony_cistatic char print_fmt_##call[] = print;					\
45662306a36Sopenharmony_ci									\
45762306a36Sopenharmony_cistatic struct trace_event_call __used event_##call = {			\
45862306a36Sopenharmony_ci	.class			= &event_class_##template,		\
45962306a36Sopenharmony_ci	{								\
46062306a36Sopenharmony_ci		.tp			= &__tracepoint_##call,		\
46162306a36Sopenharmony_ci	},								\
46262306a36Sopenharmony_ci	.event.funcs		= &trace_event_type_funcs_##call,	\
46362306a36Sopenharmony_ci	.print_fmt		= print_fmt_##call,			\
46462306a36Sopenharmony_ci	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
46562306a36Sopenharmony_ci};									\
46662306a36Sopenharmony_cistatic struct trace_event_call __used					\
46762306a36Sopenharmony_ci__section("_ftrace_events") *__event_##call = &event_##call
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
470