18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __PERF_PARSE_EVENTS_H
38c2ecf20Sopenharmony_ci#define __PERF_PARSE_EVENTS_H
48c2ecf20Sopenharmony_ci/*
58c2ecf20Sopenharmony_ci * Parse symbolic events/counts passed in as options:
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/list.h>
98c2ecf20Sopenharmony_ci#include <stdbool.h>
108c2ecf20Sopenharmony_ci#include <linux/types.h>
118c2ecf20Sopenharmony_ci#include <linux/perf_event.h>
128c2ecf20Sopenharmony_ci#include <string.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistruct list_head;
158c2ecf20Sopenharmony_cistruct evsel;
168c2ecf20Sopenharmony_cistruct evlist;
178c2ecf20Sopenharmony_cistruct parse_events_error;
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistruct option;
208c2ecf20Sopenharmony_cistruct perf_pmu;
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct tracepoint_path {
238c2ecf20Sopenharmony_ci	char *system;
248c2ecf20Sopenharmony_ci	char *name;
258c2ecf20Sopenharmony_ci	struct tracepoint_path *next;
268c2ecf20Sopenharmony_ci};
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistruct tracepoint_path *tracepoint_id_to_path(u64 config);
298c2ecf20Sopenharmony_cistruct tracepoint_path *tracepoint_name_to_path(const char *name);
308c2ecf20Sopenharmony_cibool have_tracepoints(struct list_head *evlist);
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ciconst char *event_type(int type);
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciint parse_events_option(const struct option *opt, const char *str, int unset);
358c2ecf20Sopenharmony_ciint parse_events_option_new_evlist(const struct option *opt, const char *str, int unset);
368c2ecf20Sopenharmony_ciint __parse_events(struct evlist *evlist, const char *str, struct parse_events_error *error,
378c2ecf20Sopenharmony_ci		   struct perf_pmu *fake_pmu);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic inline int parse_events(struct evlist *evlist, const char *str,
408c2ecf20Sopenharmony_ci			       struct parse_events_error *err)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	return __parse_events(evlist, str, err, NULL);
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciint parse_events_terms(struct list_head *terms, const char *str);
468c2ecf20Sopenharmony_ciint parse_filter(const struct option *opt, const char *str, int unset);
478c2ecf20Sopenharmony_ciint exclude_perf(const struct option *opt, const char *arg, int unset);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#define EVENTS_HELP_MAX (128*1024)
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cienum perf_pmu_event_symbol_type {
528c2ecf20Sopenharmony_ci	PMU_EVENT_SYMBOL_ERR,		/* not a PMU EVENT */
538c2ecf20Sopenharmony_ci	PMU_EVENT_SYMBOL,		/* normal style PMU event */
548c2ecf20Sopenharmony_ci	PMU_EVENT_SYMBOL_PREFIX,	/* prefix of pre-suf style event */
558c2ecf20Sopenharmony_ci	PMU_EVENT_SYMBOL_SUFFIX,	/* suffix of pre-suf style event */
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistruct perf_pmu_event_symbol {
598c2ecf20Sopenharmony_ci	char	*symbol;
608c2ecf20Sopenharmony_ci	enum perf_pmu_event_symbol_type	type;
618c2ecf20Sopenharmony_ci};
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cienum {
648c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_NUM,
658c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_STR,
668c2ecf20Sopenharmony_ci};
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cienum {
698c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_USER,
708c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_CONFIG,
718c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_CONFIG1,
728c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_CONFIG2,
738c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_NAME,
748c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
758c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ,
768c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
778c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_TIME,
788c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_CALLGRAPH,
798c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_STACKSIZE,
808c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_NOINHERIT,
818c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_INHERIT,
828c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_MAX_STACK,
838c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_MAX_EVENTS,
848c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
858c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_OVERWRITE,
868c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_DRV_CFG,
878c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_PERCORE,
888c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT,
898c2ecf20Sopenharmony_ci	PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE,
908c2ecf20Sopenharmony_ci	__PARSE_EVENTS__TERM_TYPE_NR,
918c2ecf20Sopenharmony_ci};
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_cistruct parse_events_array {
948c2ecf20Sopenharmony_ci	size_t nr_ranges;
958c2ecf20Sopenharmony_ci	struct {
968c2ecf20Sopenharmony_ci		unsigned int start;
978c2ecf20Sopenharmony_ci		size_t length;
988c2ecf20Sopenharmony_ci	} *ranges;
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistruct parse_events_term {
1028c2ecf20Sopenharmony_ci	char *config;
1038c2ecf20Sopenharmony_ci	struct parse_events_array array;
1048c2ecf20Sopenharmony_ci	union {
1058c2ecf20Sopenharmony_ci		char *str;
1068c2ecf20Sopenharmony_ci		u64  num;
1078c2ecf20Sopenharmony_ci	} val;
1088c2ecf20Sopenharmony_ci	int type_val;
1098c2ecf20Sopenharmony_ci	int type_term;
1108c2ecf20Sopenharmony_ci	struct list_head list;
1118c2ecf20Sopenharmony_ci	bool used;
1128c2ecf20Sopenharmony_ci	bool no_value;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	/* error string indexes for within parsed string */
1158c2ecf20Sopenharmony_ci	int err_term;
1168c2ecf20Sopenharmony_ci	int err_val;
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	/* Coming from implicit alias */
1198c2ecf20Sopenharmony_ci	bool weak;
1208c2ecf20Sopenharmony_ci};
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistruct parse_events_error {
1238c2ecf20Sopenharmony_ci	int   num_errors;       /* number of errors encountered */
1248c2ecf20Sopenharmony_ci	int   idx;	/* index in the parsed string */
1258c2ecf20Sopenharmony_ci	char *str;      /* string to display at the index */
1268c2ecf20Sopenharmony_ci	char *help;	/* optional help string */
1278c2ecf20Sopenharmony_ci	int   first_idx;/* as above, but for the first encountered error */
1288c2ecf20Sopenharmony_ci	char *first_str;
1298c2ecf20Sopenharmony_ci	char *first_help;
1308c2ecf20Sopenharmony_ci};
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_cistruct parse_events_state {
1338c2ecf20Sopenharmony_ci	struct list_head	   list;
1348c2ecf20Sopenharmony_ci	int			   idx;
1358c2ecf20Sopenharmony_ci	int			   nr_groups;
1368c2ecf20Sopenharmony_ci	struct parse_events_error *error;
1378c2ecf20Sopenharmony_ci	struct evlist		  *evlist;
1388c2ecf20Sopenharmony_ci	struct list_head	  *terms;
1398c2ecf20Sopenharmony_ci	int			   stoken;
1408c2ecf20Sopenharmony_ci	struct perf_pmu		  *fake_pmu;
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_civoid parse_events__handle_error(struct parse_events_error *err, int idx,
1448c2ecf20Sopenharmony_ci				char *str, char *help);
1458c2ecf20Sopenharmony_civoid parse_events__shrink_config_terms(void);
1468c2ecf20Sopenharmony_ciint parse_events__is_hardcoded_term(struct parse_events_term *term);
1478c2ecf20Sopenharmony_ciint parse_events_term__num(struct parse_events_term **term,
1488c2ecf20Sopenharmony_ci			   int type_term, char *config, u64 num,
1498c2ecf20Sopenharmony_ci			   bool novalue,
1508c2ecf20Sopenharmony_ci			   void *loc_term, void *loc_val);
1518c2ecf20Sopenharmony_ciint parse_events_term__str(struct parse_events_term **term,
1528c2ecf20Sopenharmony_ci			   int type_term, char *config, char *str,
1538c2ecf20Sopenharmony_ci			   void *loc_term, void *loc_val);
1548c2ecf20Sopenharmony_ciint parse_events_term__sym_hw(struct parse_events_term **term,
1558c2ecf20Sopenharmony_ci			      char *config, unsigned idx);
1568c2ecf20Sopenharmony_ciint parse_events_term__clone(struct parse_events_term **new,
1578c2ecf20Sopenharmony_ci			     struct parse_events_term *term);
1588c2ecf20Sopenharmony_civoid parse_events_term__delete(struct parse_events_term *term);
1598c2ecf20Sopenharmony_civoid parse_events_terms__delete(struct list_head *terms);
1608c2ecf20Sopenharmony_civoid parse_events_terms__purge(struct list_head *terms);
1618c2ecf20Sopenharmony_civoid parse_events__clear_array(struct parse_events_array *a);
1628c2ecf20Sopenharmony_ciint parse_events__modifier_event(struct list_head *list, char *str, bool add);
1638c2ecf20Sopenharmony_ciint parse_events__modifier_group(struct list_head *list, char *event_mod);
1648c2ecf20Sopenharmony_ciint parse_events_name(struct list_head *list, char *name);
1658c2ecf20Sopenharmony_ciint parse_events_add_tracepoint(struct list_head *list, int *idx,
1668c2ecf20Sopenharmony_ci				const char *sys, const char *event,
1678c2ecf20Sopenharmony_ci				struct parse_events_error *error,
1688c2ecf20Sopenharmony_ci				struct list_head *head_config);
1698c2ecf20Sopenharmony_ciint parse_events_load_bpf(struct parse_events_state *parse_state,
1708c2ecf20Sopenharmony_ci			  struct list_head *list,
1718c2ecf20Sopenharmony_ci			  char *bpf_file_name,
1728c2ecf20Sopenharmony_ci			  bool source,
1738c2ecf20Sopenharmony_ci			  struct list_head *head_config);
1748c2ecf20Sopenharmony_ci/* Provide this function for perf test */
1758c2ecf20Sopenharmony_cistruct bpf_object;
1768c2ecf20Sopenharmony_ciint parse_events_load_bpf_obj(struct parse_events_state *parse_state,
1778c2ecf20Sopenharmony_ci			      struct list_head *list,
1788c2ecf20Sopenharmony_ci			      struct bpf_object *obj,
1798c2ecf20Sopenharmony_ci			      struct list_head *head_config);
1808c2ecf20Sopenharmony_ciint parse_events_add_numeric(struct parse_events_state *parse_state,
1818c2ecf20Sopenharmony_ci			     struct list_head *list,
1828c2ecf20Sopenharmony_ci			     u32 type, u64 config,
1838c2ecf20Sopenharmony_ci			     struct list_head *head_config);
1848c2ecf20Sopenharmony_cienum perf_tool_event;
1858c2ecf20Sopenharmony_ciint parse_events_add_tool(struct parse_events_state *parse_state,
1868c2ecf20Sopenharmony_ci			  struct list_head *list,
1878c2ecf20Sopenharmony_ci			  enum perf_tool_event tool_event);
1888c2ecf20Sopenharmony_ciint parse_events_add_cache(struct list_head *list, int *idx,
1898c2ecf20Sopenharmony_ci			   char *type, char *op_result1, char *op_result2,
1908c2ecf20Sopenharmony_ci			   struct parse_events_error *error,
1918c2ecf20Sopenharmony_ci			   struct list_head *head_config);
1928c2ecf20Sopenharmony_ciint parse_events_add_breakpoint(struct list_head *list, int *idx,
1938c2ecf20Sopenharmony_ci				u64 addr, char *type, u64 len);
1948c2ecf20Sopenharmony_ciint parse_events_add_pmu(struct parse_events_state *parse_state,
1958c2ecf20Sopenharmony_ci			 struct list_head *list, char *name,
1968c2ecf20Sopenharmony_ci			 struct list_head *head_config,
1978c2ecf20Sopenharmony_ci			 bool auto_merge_stats,
1988c2ecf20Sopenharmony_ci			 bool use_alias);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistruct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
2018c2ecf20Sopenharmony_ci					char *name, struct perf_pmu *pmu);
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ciint parse_events_multi_pmu_add(struct parse_events_state *parse_state,
2048c2ecf20Sopenharmony_ci			       char *str,
2058c2ecf20Sopenharmony_ci			       struct list_head **listp);
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ciint parse_events_copy_term_list(struct list_head *old,
2088c2ecf20Sopenharmony_ci				 struct list_head **new);
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cienum perf_pmu_event_symbol_type
2118c2ecf20Sopenharmony_ciperf_pmu__parse_check(const char *name);
2128c2ecf20Sopenharmony_civoid parse_events__set_leader(char *name, struct list_head *list,
2138c2ecf20Sopenharmony_ci			      struct parse_events_state *parse_state);
2148c2ecf20Sopenharmony_civoid parse_events_update_lists(struct list_head *list_event,
2158c2ecf20Sopenharmony_ci			       struct list_head *list_all);
2168c2ecf20Sopenharmony_civoid parse_events_evlist_error(struct parse_events_state *parse_state,
2178c2ecf20Sopenharmony_ci			       int idx, const char *str);
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_civoid print_events(const char *event_glob, bool name_only, bool quiet,
2208c2ecf20Sopenharmony_ci		  bool long_desc, bool details_flag, bool deprecated);
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistruct event_symbol {
2238c2ecf20Sopenharmony_ci	const char	*symbol;
2248c2ecf20Sopenharmony_ci	const char	*alias;
2258c2ecf20Sopenharmony_ci};
2268c2ecf20Sopenharmony_ciextern struct event_symbol event_symbols_hw[];
2278c2ecf20Sopenharmony_ciextern struct event_symbol event_symbols_sw[];
2288c2ecf20Sopenharmony_civoid print_symbol_events(const char *event_glob, unsigned type,
2298c2ecf20Sopenharmony_ci				struct event_symbol *syms, unsigned max,
2308c2ecf20Sopenharmony_ci				bool name_only);
2318c2ecf20Sopenharmony_civoid print_tool_events(const char *event_glob, bool name_only);
2328c2ecf20Sopenharmony_civoid print_tracepoint_events(const char *subsys_glob, const char *event_glob,
2338c2ecf20Sopenharmony_ci			     bool name_only);
2348c2ecf20Sopenharmony_ciint print_hwcache_events(const char *event_glob, bool name_only);
2358c2ecf20Sopenharmony_civoid print_sdt_events(const char *subsys_glob, const char *event_glob,
2368c2ecf20Sopenharmony_ci		      bool name_only);
2378c2ecf20Sopenharmony_ciint is_valid_tracepoint(const char *event_string);
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ciint valid_event_mount(const char *eventfs);
2408c2ecf20Sopenharmony_cichar *parse_events_formats_error_string(char *additional_terms);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_civoid parse_events_print_error(struct parse_events_error *err,
2438c2ecf20Sopenharmony_ci			      const char *event);
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci#ifdef HAVE_LIBELF_SUPPORT
2468c2ecf20Sopenharmony_ci/*
2478c2ecf20Sopenharmony_ci * If the probe point starts with '%',
2488c2ecf20Sopenharmony_ci * or starts with "sdt_" and has a ':' but no '=',
2498c2ecf20Sopenharmony_ci * then it should be a SDT/cached probe point.
2508c2ecf20Sopenharmony_ci */
2518c2ecf20Sopenharmony_cistatic inline bool is_sdt_event(char *str)
2528c2ecf20Sopenharmony_ci{
2538c2ecf20Sopenharmony_ci	return (str[0] == '%' ||
2548c2ecf20Sopenharmony_ci		(!strncmp(str, "sdt_", 4) &&
2558c2ecf20Sopenharmony_ci		 !!strchr(str, ':') && !strchr(str, '=')));
2568c2ecf20Sopenharmony_ci}
2578c2ecf20Sopenharmony_ci#else
2588c2ecf20Sopenharmony_cistatic inline bool is_sdt_event(char *str __maybe_unused)
2598c2ecf20Sopenharmony_ci{
2608c2ecf20Sopenharmony_ci	return false;
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci#endif /* HAVE_LIBELF_SUPPORT */
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ciint perf_pmu__test_parse_init(void);
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci#endif /* __PERF_PARSE_EVENTS_H */
267