/* SPDX-License-Identifier: GPL-2.0
*
* ARM CoreSight Architecture PMU driver .
* Copyright ( c ) 2022 - 2023 , NVIDIA CORPORATION & AFFILIATES . All rights reserved .
*
*/
#ifndef __ARM_CSPMU_H__
#define __ARM_CSPMU_H__
#include <linux/bitfield.h>
#include <linux/cpumask.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#define to_arm_cspmu(p) (container_of(p, struct arm_cspmu, pmu))
#define ARM_CSPMU_EXT_ATTR(_name, _func, _config) \
(&((struct dev_ext_attribute[]){ \
{ \
.attr = __ATTR(_name, 0444 , _func, NULL), \
.var = (void *)_config \
} \
})[0 ].attr.attr)
#define ARM_CSPMU_FORMAT_ATTR(_name, _config) \
ARM_CSPMU_EXT_ATTR(_name, device_show_string, _config)
#define ARM_CSPMU_EVENT_ATTR(_name, _config) \
PMU_EVENT_ATTR_ID(_name, arm_cspmu_sysfs_event_show, _config)
/* Default event id mask */
#define ARM_CSPMU_EVENT_MASK GENMASK_ULL(63 , 0 )
/* Default filter value mask */
#define ARM_CSPMU_FILTER_MASK GENMASK_ULL(63 , 0 )
/* Default event format */
#define ARM_CSPMU_FORMAT_EVENT_ATTR \
ARM_CSPMU_FORMAT_ATTR(event, "config:0-32" )
/* Default filter format */
#define ARM_CSPMU_FORMAT_FILTER_ATTR \
ARM_CSPMU_FORMAT_ATTR(filter, "config1:0-31" )
#define ARM_CSPMU_FORMAT_FILTER2_ATTR \
ARM_CSPMU_FORMAT_ATTR(filter2, "config2:0-31" )
/*
* This is the default event number for cycle count , if supported , since the
* ARM Coresight PMU specification does not define a standard event code
* for cycle count .
*/
#define ARM_CSPMU_EVT_CYCLES_DEFAULT (0 x1ULL << 32 )
/*
* The ARM Coresight PMU supports up to 256 event counters .
* If the counters are larger - than 32 - bits , then the PMU includes at
* most 128 counters .
*/
#define ARM_CSPMU_MAX_HW_CNTRS 256
/* The cycle counter, if implemented, is located at counter[31]. */
#define ARM_CSPMU_CYCLE_CNTR_IDX 31
/*
* CoreSight PMU Arch register offsets .
*/
#define PMEVCNTR_LO 0 x0
#define PMEVCNTR_HI 0 x4
#define PMEVTYPER 0 x400
#define PMCCFILTR 0 x47C
#define PMEVFILT2R 0 x800
#define PMEVFILTR 0 xA00
#define PMCNTENSET 0 xC00
#define PMCNTENCLR 0 xC20
#define PMINTENSET 0 xC40
#define PMINTENCLR 0 xC60
#define PMOVSCLR 0 xC80
#define PMOVSSET 0 xCC0
#define PMIMPDEF 0 xD80
#define PMCFGR 0 xE00
#define PMCR 0 xE04
#define PMIIDR 0 xE08
/* PMCFGR register field */
#define PMCFGR_NCG GENMASK(31 , 28 )
#define PMCFGR_HDBG BIT(24 )
#define PMCFGR_TRO BIT(23 )
#define PMCFGR_SS BIT(22 )
#define PMCFGR_FZO BIT(21 )
#define PMCFGR_MSI BIT(20 )
#define PMCFGR_UEN BIT(19 )
#define PMCFGR_NA BIT(17 )
#define PMCFGR_EX BIT(16 )
#define PMCFGR_CCD BIT(15 )
#define PMCFGR_CC BIT(14 )
#define PMCFGR_SIZE GENMASK(13 , 8 )
#define PMCFGR_N GENMASK(7 , 0 )
/* PMCR register field */
#define PMCR_TRO BIT(11 )
#define PMCR_HDBG BIT(10 )
#define PMCR_FZO BIT(9 )
#define PMCR_NA BIT(8 )
#define PMCR_DP BIT(5 )
#define PMCR_X BIT(4 )
#define PMCR_D BIT(3 )
#define PMCR_C BIT(2 )
#define PMCR_P BIT(1 )
#define PMCR_E BIT(0 )
/* PMIIDR register field */
#define ARM_CSPMU_PMIIDR_IMPLEMENTER GENMASK(11 , 0 )
#define ARM_CSPMU_PMIIDR_PRODUCTID GENMASK(31 , 20 )
/* JEDEC-assigned JEP106 identification code */
#define ARM_CSPMU_IMPL_ID_NVIDIA 0 x36B
#define ARM_CSPMU_IMPL_ID_AMPERE 0 xA16
struct arm_cspmu;
/* This tracks the events assigned to each counter in the PMU. */
struct arm_cspmu_hw_events {
/* The events that are active on the PMU for a given logical index. */
struct perf_event **events;
/*
* Each bit indicates a logical counter is being used ( or not ) for an
* event . If cycle counter is supported and there is a gap between
* regular and cycle counter , the last logical counter is mapped to
* cycle counter . Otherwise , logical and physical have 1 - to - 1 mapping .
*/
DECLARE_BITMAP(used_ctrs, ARM_CSPMU_MAX_HW_CNTRS);
};
/* Contains ops to query vendor/implementer specific attribute. */
struct arm_cspmu_impl_ops {
/* Get event attributes */
struct attribute **(*get_event_attrs)(const struct arm_cspmu *cspmu);
/* Get format attributes */
struct attribute **(*get_format_attrs)(const struct arm_cspmu *cspmu);
/* Get string identifier */
const char *(*get_identifier)(const struct arm_cspmu *cspmu);
/* Get PMU name to register to core perf */
const char *(*get_name)(const struct arm_cspmu *cspmu);
/* Check if the event corresponds to cycle count event */
bool (*is_cycle_counter_event)(const struct perf_event *event);
/* Decode event type/id from configs */
u32 (*event_type)(const struct perf_event *event);
/* Set event filters */
void (*set_cc_filter)(struct arm_cspmu *cspmu,
const struct perf_event *event);
void (*set_ev_filter)(struct arm_cspmu *cspmu,
const struct perf_event *event);
/* Implementation specific event validation */
int (*validate_event)(struct arm_cspmu *cspmu,
struct perf_event *event);
/* Hide/show unsupported events */
umode_t (*event_attr_is_visible)(struct kobject *kobj,
struct attribute *attr, int unused);
};
/* Vendor/implementer registration parameter. */
struct arm_cspmu_impl_match {
/* Backend module. */
struct module *module;
const char *module_name;
/* PMIIDR value/mask. */
u32 pmiidr_val;
u32 pmiidr_mask;
/* Callback to vendor backend to init arm_cspmu_impl::ops. */
int (*impl_init_ops)(struct arm_cspmu *cspmu);
};
/* Vendor/implementer descriptor. */
struct arm_cspmu_impl {
u32 pmiidr;
struct module *module;
struct arm_cspmu_impl_match *match;
struct arm_cspmu_impl_ops ops;
void *ctx;
};
/* Coresight PMU descriptor. */
struct arm_cspmu {
struct pmu pmu;
struct device *dev;
const char *name;
const char *identifier;
void __iomem *base0;
void __iomem *base1;
cpumask_t associated_cpus;
cpumask_t active_cpu;
struct hlist_node cpuhp_node;
int irq;
bool has_atomic_dword;
u32 pmcfgr;
u32 num_logical_ctrs;
u32 num_set_clr_reg;
int cycle_counter_logical_idx;
struct arm_cspmu_hw_events hw_events;
const struct attribute_group *attr_groups[5 ];
struct arm_cspmu_impl impl;
};
/* Default function to show event attribute in sysfs. */
ssize_t arm_cspmu_sysfs_event_show(struct device *dev,
struct device_attribute *attr,
char *buf);
/* Register vendor backend. */
int arm_cspmu_impl_register(const struct arm_cspmu_impl_match *impl_match);
/* Unregister vendor backend. */
void arm_cspmu_impl_unregister(const struct arm_cspmu_impl_match *impl_match);
#endif /* __ARM_CSPMU_H__ */
Messung V0.5 in Prozent C=95 H=93 G=93
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet am 2026-10-11)
¤
*© Formatika GbR, Deutschland