162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __PMU_H 362306a36Sopenharmony_ci#define __PMU_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/bitmap.h> 662306a36Sopenharmony_ci#include <linux/compiler.h> 762306a36Sopenharmony_ci#include <linux/perf_event.h> 862306a36Sopenharmony_ci#include <linux/list.h> 962306a36Sopenharmony_ci#include <stdbool.h> 1062306a36Sopenharmony_ci#include <stdio.h> 1162306a36Sopenharmony_ci#include "parse-events.h" 1262306a36Sopenharmony_ci#include "pmu-events/pmu-events.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct evsel_config_term; 1562306a36Sopenharmony_cistruct perf_cpu_map; 1662306a36Sopenharmony_cistruct print_callbacks; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cienum { 1962306a36Sopenharmony_ci PERF_PMU_FORMAT_VALUE_CONFIG, 2062306a36Sopenharmony_ci PERF_PMU_FORMAT_VALUE_CONFIG1, 2162306a36Sopenharmony_ci PERF_PMU_FORMAT_VALUE_CONFIG2, 2262306a36Sopenharmony_ci PERF_PMU_FORMAT_VALUE_CONFIG3, 2362306a36Sopenharmony_ci PERF_PMU_FORMAT_VALUE_CONFIG_END, 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define PERF_PMU_FORMAT_BITS 64 2762306a36Sopenharmony_ci#define MAX_PMU_NAME_LEN 128 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct perf_event_attr; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct perf_pmu_caps { 3262306a36Sopenharmony_ci char *name; 3362306a36Sopenharmony_ci char *value; 3462306a36Sopenharmony_ci struct list_head list; 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/** 3862306a36Sopenharmony_ci * struct perf_pmu 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_cistruct perf_pmu { 4162306a36Sopenharmony_ci /** @name: The name of the PMU such as "cpu". */ 4262306a36Sopenharmony_ci const char *name; 4362306a36Sopenharmony_ci /** 4462306a36Sopenharmony_ci * @alias_name: Optional alternate name for the PMU determined in 4562306a36Sopenharmony_ci * architecture specific code. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci char *alias_name; 4862306a36Sopenharmony_ci /** 4962306a36Sopenharmony_ci * @id: Optional PMU identifier read from 5062306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/identifier. 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ci const char *id; 5362306a36Sopenharmony_ci /** 5462306a36Sopenharmony_ci * @type: Perf event attributed type value, read from 5562306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/type. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_ci __u32 type; 5862306a36Sopenharmony_ci /** 5962306a36Sopenharmony_ci * @selectable: Can the PMU name be selected as if it were an event? 6062306a36Sopenharmony_ci */ 6162306a36Sopenharmony_ci bool selectable; 6262306a36Sopenharmony_ci /** 6362306a36Sopenharmony_ci * @is_core: Is the PMU the core CPU PMU? Determined by the name being 6462306a36Sopenharmony_ci * "cpu" or by the presence of 6562306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/cpus. There may be >1 core 6662306a36Sopenharmony_ci * PMU on systems like Intel hybrid. 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_ci bool is_core; 6962306a36Sopenharmony_ci /** 7062306a36Sopenharmony_ci * @is_uncore: Is the PMU not within the CPU core? Determined by the 7162306a36Sopenharmony_ci * presence of <sysfs>/bus/event_source/devices/<name>/cpumask. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci bool is_uncore; 7462306a36Sopenharmony_ci /** 7562306a36Sopenharmony_ci * @auxtrace: Are events auxiliary events? Determined in architecture 7662306a36Sopenharmony_ci * specific code. 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_ci bool auxtrace; 7962306a36Sopenharmony_ci /** 8062306a36Sopenharmony_ci * @formats_checked: Only check PMU's formats are valid for 8162306a36Sopenharmony_ci * perf_event_attr once. 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_ci bool formats_checked; 8462306a36Sopenharmony_ci /** @config_masks_present: Are there config format values? */ 8562306a36Sopenharmony_ci bool config_masks_present; 8662306a36Sopenharmony_ci /** @config_masks_computed: Set when masks are lazily computed. */ 8762306a36Sopenharmony_ci bool config_masks_computed; 8862306a36Sopenharmony_ci /** 8962306a36Sopenharmony_ci * @max_precise: Number of levels of :ppp precision supported by the 9062306a36Sopenharmony_ci * PMU, read from 9162306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/caps/max_precise. 9262306a36Sopenharmony_ci */ 9362306a36Sopenharmony_ci int max_precise; 9462306a36Sopenharmony_ci /** 9562306a36Sopenharmony_ci * @default_config: Optional default perf_event_attr determined in 9662306a36Sopenharmony_ci * architecture specific code. 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ci struct perf_event_attr *default_config; 9962306a36Sopenharmony_ci /** 10062306a36Sopenharmony_ci * @cpus: Empty or the contents of either of: 10162306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/cpumask. 10262306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<cpu>/cpus. 10362306a36Sopenharmony_ci */ 10462306a36Sopenharmony_ci struct perf_cpu_map *cpus; 10562306a36Sopenharmony_ci /** 10662306a36Sopenharmony_ci * @format: Holds the contents of files read from 10762306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/format/. The contents specify 10862306a36Sopenharmony_ci * which event parameter changes what config, config1 or config2 bits. 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci struct list_head format; 11162306a36Sopenharmony_ci /** 11262306a36Sopenharmony_ci * @aliases: List of struct perf_pmu_alias. Each alias corresponds to an 11362306a36Sopenharmony_ci * event read from <sysfs>/bus/event_source/devices/<name>/events/ or 11462306a36Sopenharmony_ci * from json events in pmu-events.c. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_ci struct list_head aliases; 11762306a36Sopenharmony_ci /** 11862306a36Sopenharmony_ci * @events_table: The events table for json events in pmu-events.c. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci const struct pmu_events_table *events_table; 12162306a36Sopenharmony_ci /** @sysfs_aliases: Number of sysfs aliases loaded. */ 12262306a36Sopenharmony_ci uint32_t sysfs_aliases; 12362306a36Sopenharmony_ci /** @sysfs_aliases: Number of json event aliases loaded. */ 12462306a36Sopenharmony_ci uint32_t loaded_json_aliases; 12562306a36Sopenharmony_ci /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */ 12662306a36Sopenharmony_ci bool sysfs_aliases_loaded; 12762306a36Sopenharmony_ci /** 12862306a36Sopenharmony_ci * @cpu_aliases_added: Have all json events table entries for the PMU 12962306a36Sopenharmony_ci * been added? 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_ci bool cpu_aliases_added; 13262306a36Sopenharmony_ci /** @caps_initialized: Has the list caps been initialized? */ 13362306a36Sopenharmony_ci bool caps_initialized; 13462306a36Sopenharmony_ci /** @nr_caps: The length of the list caps. */ 13562306a36Sopenharmony_ci u32 nr_caps; 13662306a36Sopenharmony_ci /** 13762306a36Sopenharmony_ci * @caps: Holds the contents of files read from 13862306a36Sopenharmony_ci * <sysfs>/bus/event_source/devices/<name>/caps/. 13962306a36Sopenharmony_ci * 14062306a36Sopenharmony_ci * The contents are pairs of the filename with the value of its 14162306a36Sopenharmony_ci * contents, for example, max_precise (see above) may have a value of 3. 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_ci struct list_head caps; 14462306a36Sopenharmony_ci /** @list: Element on pmus list in pmu.c. */ 14562306a36Sopenharmony_ci struct list_head list; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci /** 14862306a36Sopenharmony_ci * @config_masks: Derived from the PMU's format data, bits that are 14962306a36Sopenharmony_ci * valid within the config value. 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_ci __u64 config_masks[PERF_PMU_FORMAT_VALUE_CONFIG_END]; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci /** 15462306a36Sopenharmony_ci * @missing_features: Features to inhibit when events on this PMU are 15562306a36Sopenharmony_ci * opened. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_ci struct { 15862306a36Sopenharmony_ci /** 15962306a36Sopenharmony_ci * @exclude_guest: Disables perf_event_attr exclude_guest and 16062306a36Sopenharmony_ci * exclude_host. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci bool exclude_guest; 16362306a36Sopenharmony_ci } missing_features; 16462306a36Sopenharmony_ci}; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci/** @perf_pmu__fake: A special global PMU used for testing. */ 16762306a36Sopenharmony_ciextern struct perf_pmu perf_pmu__fake; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistruct perf_pmu_info { 17062306a36Sopenharmony_ci const char *unit; 17162306a36Sopenharmony_ci double scale; 17262306a36Sopenharmony_ci bool per_pkg; 17362306a36Sopenharmony_ci bool snapshot; 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistruct pmu_event_info { 17762306a36Sopenharmony_ci const struct perf_pmu *pmu; 17862306a36Sopenharmony_ci const char *name; 17962306a36Sopenharmony_ci const char* alias; 18062306a36Sopenharmony_ci const char *scale_unit; 18162306a36Sopenharmony_ci const char *desc; 18262306a36Sopenharmony_ci const char *long_desc; 18362306a36Sopenharmony_ci const char *encoding_desc; 18462306a36Sopenharmony_ci const char *topic; 18562306a36Sopenharmony_ci const char *pmu_name; 18662306a36Sopenharmony_ci const char *str; 18762306a36Sopenharmony_ci bool deprecated; 18862306a36Sopenharmony_ci}; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_citypedef int (*pmu_event_callback)(void *state, struct pmu_event_info *info); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_civoid pmu_add_sys_aliases(struct perf_pmu *pmu); 19362306a36Sopenharmony_ciint perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 19462306a36Sopenharmony_ci struct list_head *head_terms, 19562306a36Sopenharmony_ci struct parse_events_error *error); 19662306a36Sopenharmony_ciint perf_pmu__config_terms(struct perf_pmu *pmu, 19762306a36Sopenharmony_ci struct perf_event_attr *attr, 19862306a36Sopenharmony_ci struct list_head *head_terms, 19962306a36Sopenharmony_ci bool zero, struct parse_events_error *error); 20062306a36Sopenharmony_ci__u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name); 20162306a36Sopenharmony_ciint perf_pmu__format_type(struct perf_pmu *pmu, const char *name); 20262306a36Sopenharmony_ciint perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 20362306a36Sopenharmony_ci struct perf_pmu_info *info, struct parse_events_error *err); 20462306a36Sopenharmony_ciint perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *state, pmu_event_callback cb); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ciint perf_pmu__format_parse(struct perf_pmu *pmu, int dirfd, bool eager_load); 20762306a36Sopenharmony_civoid perf_pmu_format__set_value(void *format, int config, unsigned long *bits); 20862306a36Sopenharmony_cibool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cibool is_pmu_core(const char *name); 21162306a36Sopenharmony_cibool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu); 21262306a36Sopenharmony_cibool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu); 21362306a36Sopenharmony_cibool perf_pmu__have_event(struct perf_pmu *pmu, const char *name); 21462306a36Sopenharmony_cisize_t perf_pmu__num_events(struct perf_pmu *pmu); 21562306a36Sopenharmony_ciint perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus, 21662306a36Sopenharmony_ci void *state, pmu_event_callback cb); 21762306a36Sopenharmony_cibool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci/** 22062306a36Sopenharmony_ci * perf_pmu_is_software - is the PMU a software PMU as in it uses the 22162306a36Sopenharmony_ci * perf_sw_context in the kernel? 22262306a36Sopenharmony_ci */ 22362306a36Sopenharmony_cibool perf_pmu__is_software(const struct perf_pmu *pmu); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ciFILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name); 22662306a36Sopenharmony_ciFILE *perf_pmu__open_file_at(struct perf_pmu *pmu, int dirfd, const char *name); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ciint perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4); 22962306a36Sopenharmony_ciint perf_pmu__scan_file_at(struct perf_pmu *pmu, int dirfd, const char *name, 23062306a36Sopenharmony_ci const char *fmt, ...) __scanf(4, 5); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cibool perf_pmu__file_exists(struct perf_pmu *pmu, const char *name); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ciint perf_pmu__test(void); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistruct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu); 23762306a36Sopenharmony_civoid pmu_add_cpu_aliases_table(struct perf_pmu *pmu, 23862306a36Sopenharmony_ci const struct pmu_events_table *table); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cichar *perf_pmu__getcpuid(struct perf_pmu *pmu); 24162306a36Sopenharmony_ciconst struct pmu_events_table *pmu_events_table__find(void); 24262306a36Sopenharmony_ciconst struct pmu_metrics_table *pmu_metrics_table__find(void); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ciint perf_pmu__convert_scale(const char *scale, char **end, double *sval); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ciint perf_pmu__caps_parse(struct perf_pmu *pmu); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_civoid perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, 24962306a36Sopenharmony_ci const char *name, int config_num, 25062306a36Sopenharmony_ci const char *config_name); 25162306a36Sopenharmony_civoid perf_pmu__warn_invalid_formats(struct perf_pmu *pmu); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciint perf_pmu__match(const char *pattern, const char *name, const char *tok); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ciconst char *pmu_find_real_name(const char *name); 25662306a36Sopenharmony_ciconst char *pmu_find_alias_name(const char *name); 25762306a36Sopenharmony_cidouble perf_pmu__cpu_slots_per_cycle(void); 25862306a36Sopenharmony_ciint perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size); 25962306a36Sopenharmony_ciint perf_pmu__pathname_scnprintf(char *buf, size_t size, 26062306a36Sopenharmony_ci const char *pmu_name, const char *filename); 26162306a36Sopenharmony_ciint perf_pmu__event_source_devices_fd(void); 26262306a36Sopenharmony_ciint perf_pmu__pathname_fd(int dirfd, const char *pmu_name, const char *filename, int flags); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistruct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char *lookup_name); 26562306a36Sopenharmony_cistruct perf_pmu *perf_pmu__create_placeholder_core_pmu(struct list_head *core_pmus); 26662306a36Sopenharmony_civoid perf_pmu__delete(struct perf_pmu *pmu); 26762306a36Sopenharmony_cistruct perf_pmu *pmu__find_core_pmu(void); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci#endif /* __PMU_H */ 270