linux/drivers/perf/arm-ccn.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * Copyright (C) 2014 ARM Limited
 */

#include <linux/ctype.h>
#include <linux/hrtimer.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define CCN_NUM_XP_PORTS
#define CCN_NUM_VCS
#define CCN_NUM_REGIONS
#define CCN_REGION_SIZE

#define CCN_ALL_OLY_ID
#define CCN_ALL_OLY_ID__OLY_ID__SHIFT
#define CCN_ALL_OLY_ID__OLY_ID__MASK
#define CCN_ALL_OLY_ID__NODE_ID__SHIFT
#define CCN_ALL_OLY_ID__NODE_ID__MASK

#define CCN_MN_ERRINT_STATUS
#define CCN_MN_ERRINT_STATUS__INTREQ__DESSERT
#define CCN_MN_ERRINT_STATUS__ALL_ERRORS__ENABLE
#define CCN_MN_ERRINT_STATUS__ALL_ERRORS__DISABLED
#define CCN_MN_ERRINT_STATUS__ALL_ERRORS__DISABLE
#define CCN_MN_ERRINT_STATUS__CORRECTED_ERRORS_ENABLE
#define CCN_MN_ERRINT_STATUS__CORRECTED_ERRORS_DISABLED
#define CCN_MN_ERRINT_STATUS__CORRECTED_ERRORS_DISABLE
#define CCN_MN_ERRINT_STATUS__PMU_EVENTS__ENABLE
#define CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLED
#define CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE
#define CCN_MN_OLY_COMP_LIST_63_0
#define CCN_MN_ERR_SIG_VAL_63_0
#define CCN_MN_ERR_SIG_VAL_63_0__DT

#define CCN_DT_ACTIVE_DSM
#define CCN_DT_ACTIVE_DSM__DSM_ID__SHIFT(n)
#define CCN_DT_ACTIVE_DSM__DSM_ID__MASK
#define CCN_DT_CTL
#define CCN_DT_CTL__DT_EN
#define CCN_DT_PMEVCNT(n)
#define CCN_DT_PMCCNTR
#define CCN_DT_PMCCNTRSR
#define CCN_DT_PMOVSR
#define CCN_DT_PMOVSR_CLR
#define CCN_DT_PMOVSR_CLR__MASK
#define CCN_DT_PMCR
#define CCN_DT_PMCR__OVFL_INTR_EN
#define CCN_DT_PMCR__PMU_EN
#define CCN_DT_PMSR
#define CCN_DT_PMSR_REQ
#define CCN_DT_PMSR_CLR

#define CCN_HNF_PMU_EVENT_SEL
#define CCN_HNF_PMU_EVENT_SEL__ID__SHIFT(n)
#define CCN_HNF_PMU_EVENT_SEL__ID__MASK

#define CCN_XP_DT_CONFIG
#define CCN_XP_DT_CONFIG__DT_CFG__SHIFT(n)
#define CCN_XP_DT_CONFIG__DT_CFG__MASK
#define CCN_XP_DT_CONFIG__DT_CFG__PASS_THROUGH
#define CCN_XP_DT_CONFIG__DT_CFG__WATCHPOINT_0_OR_1
#define CCN_XP_DT_CONFIG__DT_CFG__WATCHPOINT(n)
#define CCN_XP_DT_CONFIG__DT_CFG__XP_PMU_EVENT(n)
#define CCN_XP_DT_CONFIG__DT_CFG__DEVICE_PMU_EVENT(d, n)
#define CCN_XP_DT_INTERFACE_SEL
#define CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__SHIFT(n)
#define CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__MASK
#define CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__SHIFT(n)
#define CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__MASK
#define CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__SHIFT(n)
#define CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__MASK
#define CCN_XP_DT_CMP_VAL_L(n)
#define CCN_XP_DT_CMP_VAL_H(n)
#define CCN_XP_DT_CMP_MASK_L(n)
#define CCN_XP_DT_CMP_MASK_H(n)
#define CCN_XP_DT_CONTROL
#define CCN_XP_DT_CONTROL__DT_ENABLE
#define CCN_XP_DT_CONTROL__WP_ARM_SEL__SHIFT(n)
#define CCN_XP_DT_CONTROL__WP_ARM_SEL__MASK
#define CCN_XP_DT_CONTROL__WP_ARM_SEL__ALWAYS
#define CCN_XP_PMU_EVENT_SEL
#define CCN_XP_PMU_EVENT_SEL__ID__SHIFT(n)
#define CCN_XP_PMU_EVENT_SEL__ID__MASK

#define CCN_SBAS_PMU_EVENT_SEL
#define CCN_SBAS_PMU_EVENT_SEL__ID__SHIFT(n)
#define CCN_SBAS_PMU_EVENT_SEL__ID__MASK

#define CCN_RNI_PMU_EVENT_SEL
#define CCN_RNI_PMU_EVENT_SEL__ID__SHIFT(n)
#define CCN_RNI_PMU_EVENT_SEL__ID__MASK

#define CCN_TYPE_MN
#define CCN_TYPE_DT
#define CCN_TYPE_HNF
#define CCN_TYPE_HNI
#define CCN_TYPE_XP
#define CCN_TYPE_SBSX
#define CCN_TYPE_SBAS
#define CCN_TYPE_RNI_1P
#define CCN_TYPE_RNI_2P
#define CCN_TYPE_RNI_3P
#define CCN_TYPE_RND_1P
#define CCN_TYPE_RND_2P
#define CCN_TYPE_RND_3P
#define CCN_TYPE_CYCLES

#define CCN_EVENT_WATCHPOINT

#define CCN_NUM_PMU_EVENTS
#define CCN_NUM_XP_WATCHPOINTS
#define CCN_NUM_PMU_EVENT_COUNTERS
#define CCN_IDX_PMU_CYCLE_COUNTER

#define CCN_NUM_PREDEFINED_MASKS
#define CCN_IDX_MASK_ANY
#define CCN_IDX_MASK_EXACT
#define CCN_IDX_MASK_ORDER
#define CCN_IDX_MASK_OPCODE

struct arm_ccn_component {};

#define pmu_to_arm_ccn(_pmu)

struct arm_ccn_dt {};

struct arm_ccn {};

static int arm_ccn_node_to_xp(int node)
{}

static int arm_ccn_node_to_xp_port(int node)
{}


/*
 * Bit shifts and masks in these defines must be kept in sync with
 * arm_ccn_pmu_config_set() and CCN_FORMAT_ATTRs below!
 */
#define CCN_CONFIG_NODE(_config)
#define CCN_CONFIG_XP(_config)
#define CCN_CONFIG_TYPE(_config)
#define CCN_CONFIG_EVENT(_config)
#define CCN_CONFIG_PORT(_config)
#define CCN_CONFIG_BUS(_config)
#define CCN_CONFIG_VC(_config)
#define CCN_CONFIG_DIR(_config)
#define CCN_CONFIG_MASK(_config)

static void arm_ccn_pmu_config_set(u64 *config, u32 node_xp, u32 type, u32 port)
{}

#define CCN_FORMAT_ATTR(_name, _config)

static CCN_FORMAT_ATTR(node, "config:0-7");
static CCN_FORMAT_ATTR(xp, "config:0-7");
static CCN_FORMAT_ATTR(type, "config:8-15");
static CCN_FORMAT_ATTR(event, "config:16-23");
static CCN_FORMAT_ATTR(port, "config:24-25");
static CCN_FORMAT_ATTR(bus, "config:24-25");
static CCN_FORMAT_ATTR(vc, "config:26-28");
static CCN_FORMAT_ATTR(dir, "config:29-29");
static CCN_FORMAT_ATTR(mask, "config:30-33");
static CCN_FORMAT_ATTR(cmp_l, "config1:0-62");
static CCN_FORMAT_ATTR(cmp_h, "config2:0-59");

static struct attribute *arm_ccn_pmu_format_attrs[] =;

static const struct attribute_group arm_ccn_pmu_format_attr_group =;


struct arm_ccn_pmu_event {};

#define CCN_EVENT_ATTR(_name)

/*
 * Events defined in TRM for MN, HN-I and SBSX are actually watchpoints set on
 * their ports in XP they are connected to. For the sake of usability they are
 * explicitly defined here (and translated into a relevant watchpoint in
 * arm_ccn_pmu_event_init()) so the user can easily request them without deep
 * knowledge of the flit format.
 */

#define CCN_EVENT_MN(_name, _def, _mask)

#define CCN_EVENT_HNI(_name, _def, _mask)

#define CCN_EVENT_SBSX(_name, _def, _mask)

#define CCN_EVENT_HNF(_name, _event)

#define CCN_EVENT_XP(_name, _event)

/*
 * RN-I & RN-D (RN-D = RN-I + DVM) nodes have different type ID depending
 * on configuration. One of them is picked to represent the whole group,
 * as they all share the same event types.
 */
#define CCN_EVENT_RNI(_name, _event)

#define CCN_EVENT_SBAS(_name, _event)

#define CCN_EVENT_CYCLES(_name)


static ssize_t arm_ccn_pmu_event_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static umode_t arm_ccn_pmu_events_is_visible(struct kobject *kobj,
				     struct attribute *attr, int index)
{}

static struct arm_ccn_pmu_event arm_ccn_pmu_events[] =;

/* Populated in arm_ccn_init() */
static struct attribute
		*arm_ccn_pmu_events_attrs[ARRAY_SIZE(arm_ccn_pmu_events) + 1];

static const struct attribute_group arm_ccn_pmu_events_attr_group =;


static u64 *arm_ccn_pmu_get_cmp_mask(struct arm_ccn *ccn, const char *name)
{}

static ssize_t arm_ccn_pmu_cmp_mask_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static ssize_t arm_ccn_pmu_cmp_mask_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{}

#define CCN_CMP_MASK_ATTR(_name)

#define CCN_CMP_MASK_ATTR_RO(_name)

static CCN_CMP_MASK_ATTR(0l);
static CCN_CMP_MASK_ATTR(0h);
static CCN_CMP_MASK_ATTR(1l);
static CCN_CMP_MASK_ATTR(1h);
static CCN_CMP_MASK_ATTR(2l);
static CCN_CMP_MASK_ATTR(2h);
static CCN_CMP_MASK_ATTR(3l);
static CCN_CMP_MASK_ATTR(3h);
static CCN_CMP_MASK_ATTR(4l);
static CCN_CMP_MASK_ATTR(4h);
static CCN_CMP_MASK_ATTR(5l);
static CCN_CMP_MASK_ATTR(5h);
static CCN_CMP_MASK_ATTR(6l);
static CCN_CMP_MASK_ATTR(6h);
static CCN_CMP_MASK_ATTR(7l);
static CCN_CMP_MASK_ATTR(7h);
static CCN_CMP_MASK_ATTR_RO(8l);
static CCN_CMP_MASK_ATTR_RO(8h);
static CCN_CMP_MASK_ATTR_RO(9l);
static CCN_CMP_MASK_ATTR_RO(9h);
static CCN_CMP_MASK_ATTR_RO(al);
static CCN_CMP_MASK_ATTR_RO(ah);
static CCN_CMP_MASK_ATTR_RO(bl);
static CCN_CMP_MASK_ATTR_RO(bh);

static struct attribute *arm_ccn_pmu_cmp_mask_attrs[] =;

static const struct attribute_group arm_ccn_pmu_cmp_mask_attr_group =;

static ssize_t arm_ccn_pmu_cpumask_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{}

static struct device_attribute arm_ccn_pmu_cpumask_attr =;

static struct attribute *arm_ccn_pmu_cpumask_attrs[] =;

static const struct attribute_group arm_ccn_pmu_cpumask_attr_group =;

/*
 * Default poll period is 10ms, which is way over the top anyway,
 * as in the worst case scenario (an event every cycle), with 1GHz
 * clocked bus, the smallest, 32 bit counter will overflow in
 * more than 4s.
 */
static unsigned int arm_ccn_pmu_poll_period_us =;
module_param_named(pmu_poll_period_us, arm_ccn_pmu_poll_period_us, uint,
		S_IRUGO | S_IWUSR);

static ktime_t arm_ccn_pmu_timer_period(void)
{}


static const struct attribute_group *arm_ccn_pmu_attr_groups[] =;


static int arm_ccn_pmu_alloc_bit(unsigned long *bitmap, unsigned long size)
{}

/* All RN-I and RN-D nodes have identical PMUs */
static int arm_ccn_pmu_type_eq(u32 a, u32 b)
{}

static int arm_ccn_pmu_event_alloc(struct perf_event *event)
{}

static void arm_ccn_pmu_event_release(struct perf_event *event)
{}

static int arm_ccn_pmu_event_init(struct perf_event *event)
{}

static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx)
{}

static void arm_ccn_pmu_event_update(struct perf_event *event)
{}

static void arm_ccn_pmu_xp_dt_config(struct perf_event *event, int enable)
{}

static void arm_ccn_pmu_event_start(struct perf_event *event, int flags)
{}

static void arm_ccn_pmu_event_stop(struct perf_event *event, int flags)
{}

static void arm_ccn_pmu_xp_watchpoint_config(struct perf_event *event)
{}

static void arm_ccn_pmu_xp_event_config(struct perf_event *event)
{}

static void arm_ccn_pmu_node_event_config(struct perf_event *event)
{}

static void arm_ccn_pmu_event_config(struct perf_event *event)
{}

static int arm_ccn_pmu_active_counters(struct arm_ccn *ccn)
{}

static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
{}

static void arm_ccn_pmu_event_del(struct perf_event *event, int flags)
{}

static void arm_ccn_pmu_event_read(struct perf_event *event)
{}

static void arm_ccn_pmu_enable(struct pmu *pmu)
{}

static void arm_ccn_pmu_disable(struct pmu *pmu)
{}

static irqreturn_t arm_ccn_pmu_overflow_handler(struct arm_ccn_dt *dt)
{}

static enum hrtimer_restart arm_ccn_pmu_timer_handler(struct hrtimer *hrtimer)
{}


static int arm_ccn_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
{}

static DEFINE_IDA(arm_ccn_pmu_ida);

static int arm_ccn_pmu_init(struct arm_ccn *ccn)
{}

static void arm_ccn_pmu_cleanup(struct arm_ccn *ccn)
{}

static int arm_ccn_for_each_valid_region(struct arm_ccn *ccn,
		int (*callback)(struct arm_ccn *ccn, int region,
		void __iomem *base, u32 type, u32 id))
{}

static int arm_ccn_get_nodes_num(struct arm_ccn *ccn, int region,
		void __iomem *base, u32 type, u32 id)
{}

static int arm_ccn_init_nodes(struct arm_ccn *ccn, int region,
		void __iomem *base, u32 type, u32 id)
{}


static irqreturn_t arm_ccn_error_handler(struct arm_ccn *ccn,
		const u32 *err_sig_val)
{}


static irqreturn_t arm_ccn_irq_handler(int irq, void *dev_id)
{}


static int arm_ccn_probe(struct platform_device *pdev)
{}

static void arm_ccn_remove(struct platform_device *pdev)
{}

static const struct of_device_id arm_ccn_match[] =;
MODULE_DEVICE_TABLE(of, arm_ccn_match);

static struct platform_driver arm_ccn_driver =;

static int __init arm_ccn_init(void)
{}

static void __exit arm_ccn_exit(void)
{}

module_init();
module_exit(arm_ccn_exit);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();