mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
perf: arm_cspmu: Add support for ARM CoreSight PMU driver
Add support for ARM CoreSight PMU driver framework and interfaces. The driver provides generic implementation to operate uncore PMU based on ARM CoreSight PMU architecture. The driver also provides interface to get vendor/implementation specific information, for example event attributes and formating. The specification used in this implementation can be found below: * ACPI Arm Performance Monitoring Unit table: https://developer.arm.com/documentation/den0117/latest * ARM Coresight PMU architecture: https://developer.arm.com/documentation/ihi0091/latest Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Besar Wicaksono <bwicaksono@nvidia.com> Link: https://lore.kernel.org/r/20221111222330.48602-2-bwicaksono@nvidia.com Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
6f2d566b46
commit
e37dfd6573
@ -199,4 +199,6 @@ config MARVELL_CN10K_DDR_PMU
|
|||||||
Enable perf support for Marvell DDR Performance monitoring
|
Enable perf support for Marvell DDR Performance monitoring
|
||||||
event on CN10K platform.
|
event on CN10K platform.
|
||||||
|
|
||||||
|
source "drivers/perf/arm_cspmu/Kconfig"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -21,3 +21,4 @@ obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
|
|||||||
obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
|
obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
|
||||||
obj-$(CONFIG_APPLE_M1_CPU_PMU) += apple_m1_cpu_pmu.o
|
obj-$(CONFIG_APPLE_M1_CPU_PMU) += apple_m1_cpu_pmu.o
|
||||||
obj-$(CONFIG_ALIBABA_UNCORE_DRW_PMU) += alibaba_uncore_drw_pmu.o
|
obj-$(CONFIG_ALIBABA_UNCORE_DRW_PMU) += alibaba_uncore_drw_pmu.o
|
||||||
|
obj-$(CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU) += arm_cspmu/
|
||||||
|
13
drivers/perf/arm_cspmu/Kconfig
Normal file
13
drivers/perf/arm_cspmu/Kconfig
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
config ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU
|
||||||
|
tristate "ARM Coresight Architecture PMU"
|
||||||
|
depends on ACPI
|
||||||
|
depends on ACPI_APMT || COMPILE_TEST
|
||||||
|
help
|
||||||
|
Provides support for performance monitoring unit (PMU) devices
|
||||||
|
based on ARM CoreSight PMU architecture. Note that this PMU
|
||||||
|
architecture does not have relationship with the ARM CoreSight
|
||||||
|
Self-Hosted Tracing.
|
6
drivers/perf/arm_cspmu/Makefile
Normal file
6
drivers/perf/arm_cspmu/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
obj-$(CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU) += \
|
||||||
|
arm_cspmu.o
|
1292
drivers/perf/arm_cspmu/arm_cspmu.c
Normal file
1292
drivers/perf/arm_cspmu/arm_cspmu.c
Normal file
File diff suppressed because it is too large
Load Diff
151
drivers/perf/arm_cspmu/arm_cspmu.h
Normal file
151
drivers/perf/arm_cspmu/arm_cspmu.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* ARM CoreSight Architecture PMU driver.
|
||||||
|
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ARM_CSPMU_H__
|
||||||
|
#define __ARM_CSPMU_H__
|
||||||
|
|
||||||
|
#include <linux/acpi.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, arm_cspmu_sysfs_format_show, (char *)_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")
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 (0x1ULL << 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
|
||||||
|
|
||||||
|
/* PMIIDR register field */
|
||||||
|
#define ARM_CSPMU_PMIIDR_IMPLEMENTER GENMASK(11, 0)
|
||||||
|
#define ARM_CSPMU_PMIIDR_PRODUCTID GENMASK(31, 20)
|
||||||
|
|
||||||
|
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);
|
||||||
|
/* Decode filter value from configs */
|
||||||
|
u32 (*event_filter)(const struct perf_event *event);
|
||||||
|
/* Hide/show unsupported events */
|
||||||
|
umode_t (*event_attr_is_visible)(struct kobject *kobj,
|
||||||
|
struct attribute *attr, int unused);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Vendor/implementer descriptor. */
|
||||||
|
struct arm_cspmu_impl {
|
||||||
|
u32 pmiidr;
|
||||||
|
struct arm_cspmu_impl_ops ops;
|
||||||
|
void *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Coresight PMU descriptor. */
|
||||||
|
struct arm_cspmu {
|
||||||
|
struct pmu pmu;
|
||||||
|
struct device *dev;
|
||||||
|
struct acpi_apmt_node *apmt_node;
|
||||||
|
const char *name;
|
||||||
|
const char *identifier;
|
||||||
|
void __iomem *base0;
|
||||||
|
void __iomem *base1;
|
||||||
|
int irq;
|
||||||
|
cpumask_t associated_cpus;
|
||||||
|
cpumask_t active_cpu;
|
||||||
|
struct hlist_node cpuhp_node;
|
||||||
|
|
||||||
|
u32 pmcfgr;
|
||||||
|
u32 num_logical_ctrs;
|
||||||
|
u32 num_set_clr_reg;
|
||||||
|
int cycle_counter_logical_idx;
|
||||||
|
|
||||||
|
struct arm_cspmu_hw_events hw_events;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Default function to show format attribute in sysfs. */
|
||||||
|
ssize_t arm_cspmu_sysfs_format_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf);
|
||||||
|
|
||||||
|
#endif /* __ARM_CSPMU_H__ */
|
Loading…
Reference in New Issue
Block a user