cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hisi_uncore_pmu.h (4475B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * HiSilicon SoC Hardware event counters support
      4 *
      5 * Copyright (C) 2017 HiSilicon Limited
      6 * Author: Anurup M <anurup.m@huawei.com>
      7 *         Shaokun Zhang <zhangshaokun@hisilicon.com>
      8 *
      9 * This code is based on the uncore PMUs like arm-cci and arm-ccn.
     10 */
     11#ifndef __HISI_UNCORE_PMU_H__
     12#define __HISI_UNCORE_PMU_H__
     13
     14#include <linux/bitfield.h>
     15#include <linux/cpumask.h>
     16#include <linux/device.h>
     17#include <linux/kernel.h>
     18#include <linux/module.h>
     19#include <linux/perf_event.h>
     20#include <linux/platform_device.h>
     21#include <linux/types.h>
     22
     23#undef pr_fmt
     24#define pr_fmt(fmt)     "hisi_pmu: " fmt
     25
     26#define HISI_PMU_V2		0x30
     27#define HISI_MAX_COUNTERS 0x10
     28#define to_hisi_pmu(p)	(container_of(p, struct hisi_pmu, pmu))
     29
     30#define HISI_PMU_ATTR(_name, _func, _config)				\
     31	(&((struct dev_ext_attribute[]) {				\
     32		{ __ATTR(_name, 0444, _func, NULL), (void *)_config }   \
     33	})[0].attr.attr)
     34
     35#define HISI_PMU_FORMAT_ATTR(_name, _config)		\
     36	HISI_PMU_ATTR(_name, hisi_format_sysfs_show, (void *)_config)
     37#define HISI_PMU_EVENT_ATTR(_name, _config)		\
     38	HISI_PMU_ATTR(_name, hisi_event_sysfs_show, (unsigned long)_config)
     39
     40#define HISI_PMU_EVENT_ATTR_EXTRACTOR(name, config, hi, lo)        \
     41	static inline u32 hisi_get_##name(struct perf_event *event)            \
     42	{                                                                  \
     43		return FIELD_GET(GENMASK_ULL(hi, lo), event->attr.config);  \
     44	}
     45
     46struct hisi_pmu;
     47
     48struct hisi_uncore_ops {
     49	void (*write_evtype)(struct hisi_pmu *, int, u32);
     50	int (*get_event_idx)(struct perf_event *);
     51	u64 (*read_counter)(struct hisi_pmu *, struct hw_perf_event *);
     52	void (*write_counter)(struct hisi_pmu *, struct hw_perf_event *, u64);
     53	void (*enable_counter)(struct hisi_pmu *, struct hw_perf_event *);
     54	void (*disable_counter)(struct hisi_pmu *, struct hw_perf_event *);
     55	void (*enable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
     56	void (*disable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
     57	void (*start_counters)(struct hisi_pmu *);
     58	void (*stop_counters)(struct hisi_pmu *);
     59	u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
     60	void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
     61	void (*enable_filter)(struct perf_event *event);
     62	void (*disable_filter)(struct perf_event *event);
     63};
     64
     65struct hisi_pmu_hwevents {
     66	struct perf_event *hw_events[HISI_MAX_COUNTERS];
     67	DECLARE_BITMAP(used_mask, HISI_MAX_COUNTERS);
     68	const struct attribute_group **attr_groups;
     69};
     70
     71/* Generic pmu struct for different pmu types */
     72struct hisi_pmu {
     73	struct pmu pmu;
     74	const struct hisi_uncore_ops *ops;
     75	struct hisi_pmu_hwevents pmu_events;
     76	/* associated_cpus: All CPUs associated with the PMU */
     77	cpumask_t associated_cpus;
     78	/* CPU used for counting */
     79	int on_cpu;
     80	int irq;
     81	struct device *dev;
     82	struct hlist_node node;
     83	int sccl_id;
     84	int sicl_id;
     85	int ccl_id;
     86	void __iomem *base;
     87	/* the ID of the PMU modules */
     88	u32 index_id;
     89	/* For DDRC PMU v2: each DDRC has more than one DMC */
     90	u32 sub_id;
     91	int num_counters;
     92	int counter_bits;
     93	/* check event code range */
     94	int check_event;
     95	u32 identifier;
     96};
     97
     98int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
     99void hisi_uncore_pmu_read(struct perf_event *event);
    100int hisi_uncore_pmu_add(struct perf_event *event, int flags);
    101void hisi_uncore_pmu_del(struct perf_event *event, int flags);
    102void hisi_uncore_pmu_start(struct perf_event *event, int flags);
    103void hisi_uncore_pmu_stop(struct perf_event *event, int flags);
    104void hisi_uncore_pmu_set_event_period(struct perf_event *event);
    105void hisi_uncore_pmu_event_update(struct perf_event *event);
    106int hisi_uncore_pmu_event_init(struct perf_event *event);
    107void hisi_uncore_pmu_enable(struct pmu *pmu);
    108void hisi_uncore_pmu_disable(struct pmu *pmu);
    109ssize_t hisi_event_sysfs_show(struct device *dev,
    110			      struct device_attribute *attr, char *buf);
    111ssize_t hisi_format_sysfs_show(struct device *dev,
    112			       struct device_attribute *attr, char *buf);
    113ssize_t hisi_cpumask_sysfs_show(struct device *dev,
    114				struct device_attribute *attr, char *buf);
    115int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node);
    116int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
    117
    118ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
    119					     struct device_attribute *attr,
    120					     char *page);
    121int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
    122			     struct platform_device *pdev);
    123
    124#endif /* __HISI_UNCORE_PMU_H__ */