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