~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/perf/arm_pmu.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  *  linux/arch/arm/include/asm/pmu.h
  4  *
  5  *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
  6  */
  7 
  8 #ifndef __ARM_PMU_H__
  9 #define __ARM_PMU_H__
 10 
 11 #include <linux/interrupt.h>
 12 #include <linux/perf_event.h>
 13 #include <linux/platform_device.h>
 14 #include <linux/sysfs.h>
 15 #include <asm/cputype.h>
 16 
 17 #ifdef CONFIG_ARM_PMU
 18 
 19 /*
 20  * The ARMv7 CPU PMU supports up to 32 event counters.
 21  */
 22 #define ARMPMU_MAX_HWEVENTS             32
 23 
 24 /*
 25  * ARM PMU hw_event flags
 26  */
 27 #define ARMPMU_EVT_64BIT                0x00001 /* Event uses a 64bit counter */
 28 #define ARMPMU_EVT_47BIT                0x00002 /* Event uses a 47bit counter */
 29 #define ARMPMU_EVT_63BIT                0x00004 /* Event uses a 63bit counter */
 30 
 31 static_assert((PERF_EVENT_FLAG_ARCH & ARMPMU_EVT_64BIT) == ARMPMU_EVT_64BIT);
 32 static_assert((PERF_EVENT_FLAG_ARCH & ARMPMU_EVT_47BIT) == ARMPMU_EVT_47BIT);
 33 static_assert((PERF_EVENT_FLAG_ARCH & ARMPMU_EVT_63BIT) == ARMPMU_EVT_63BIT);
 34 
 35 #define HW_OP_UNSUPPORTED               0xFFFF
 36 #define C(_x)                           PERF_COUNT_HW_CACHE_##_x
 37 #define CACHE_OP_UNSUPPORTED            0xFFFF
 38 
 39 #define PERF_MAP_ALL_UNSUPPORTED                                        \
 40         [0 ... PERF_COUNT_HW_MAX - 1] = HW_OP_UNSUPPORTED
 41 
 42 #define PERF_CACHE_MAP_ALL_UNSUPPORTED                                  \
 43 [0 ... C(MAX) - 1] = {                                                  \
 44         [0 ... C(OP_MAX) - 1] = {                                       \
 45                 [0 ... C(RESULT_MAX) - 1] = CACHE_OP_UNSUPPORTED,       \
 46         },                                                              \
 47 }
 48 
 49 /* The events for a given PMU register set. */
 50 struct pmu_hw_events {
 51         /*
 52          * The events that are active on the PMU for the given index.
 53          */
 54         struct perf_event       *events[ARMPMU_MAX_HWEVENTS];
 55 
 56         /*
 57          * A 1 bit for an index indicates that the counter is being used for
 58          * an event. A 0 means that the counter can be used.
 59          */
 60         DECLARE_BITMAP(used_mask, ARMPMU_MAX_HWEVENTS);
 61 
 62         /*
 63          * When using percpu IRQs, we need a percpu dev_id. Place it here as we
 64          * already have to allocate this struct per cpu.
 65          */
 66         struct arm_pmu          *percpu_pmu;
 67 
 68         int irq;
 69 };
 70 
 71 enum armpmu_attr_groups {
 72         ARMPMU_ATTR_GROUP_COMMON,
 73         ARMPMU_ATTR_GROUP_EVENTS,
 74         ARMPMU_ATTR_GROUP_FORMATS,
 75         ARMPMU_ATTR_GROUP_CAPS,
 76         ARMPMU_NR_ATTR_GROUPS
 77 };
 78 
 79 struct arm_pmu {
 80         struct pmu      pmu;
 81         cpumask_t       supported_cpus;
 82         char            *name;
 83         int             pmuver;
 84         irqreturn_t     (*handle_irq)(struct arm_pmu *pmu);
 85         void            (*enable)(struct perf_event *event);
 86         void            (*disable)(struct perf_event *event);
 87         int             (*get_event_idx)(struct pmu_hw_events *hw_events,
 88                                          struct perf_event *event);
 89         void            (*clear_event_idx)(struct pmu_hw_events *hw_events,
 90                                          struct perf_event *event);
 91         int             (*set_event_filter)(struct hw_perf_event *evt,
 92                                             struct perf_event_attr *attr);
 93         u64             (*read_counter)(struct perf_event *event);
 94         void            (*write_counter)(struct perf_event *event, u64 val);
 95         void            (*start)(struct arm_pmu *);
 96         void            (*stop)(struct arm_pmu *);
 97         void            (*reset)(void *);
 98         int             (*map_event)(struct perf_event *event);
 99         int             num_events;
100         bool            secure_access; /* 32-bit ARM only */
101 #define ARMV8_PMUV3_MAX_COMMON_EVENTS           0x40
102         DECLARE_BITMAP(pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
103 #define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE       0x4000
104         DECLARE_BITMAP(pmceid_ext_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
105         struct platform_device  *plat_device;
106         struct pmu_hw_events    __percpu *hw_events;
107         struct hlist_node       node;
108         struct notifier_block   cpu_pm_nb;
109         /* the attr_groups array must be NULL-terminated */
110         const struct attribute_group *attr_groups[ARMPMU_NR_ATTR_GROUPS + 1];
111         /* store the PMMIR_EL1 to expose slots */
112         u64             reg_pmmir;
113 
114         /* Only to be used by ACPI probing code */
115         unsigned long acpi_cpuid;
116 };
117 
118 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
119 
120 u64 armpmu_event_update(struct perf_event *event);
121 
122 int armpmu_event_set_period(struct perf_event *event);
123 
124 int armpmu_map_event(struct perf_event *event,
125                      const unsigned (*event_map)[PERF_COUNT_HW_MAX],
126                      const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
127                                                 [PERF_COUNT_HW_CACHE_OP_MAX]
128                                                 [PERF_COUNT_HW_CACHE_RESULT_MAX],
129                      u32 raw_event_mask);
130 
131 typedef int (*armpmu_init_fn)(struct arm_pmu *);
132 
133 struct pmu_probe_info {
134         unsigned int cpuid;
135         unsigned int mask;
136         armpmu_init_fn init;
137 };
138 
139 #define PMU_PROBE(_cpuid, _mask, _fn)   \
140 {                                       \
141         .cpuid = (_cpuid),              \
142         .mask = (_mask),                \
143         .init = (_fn),                  \
144 }
145 
146 #define ARM_PMU_PROBE(_cpuid, _fn) \
147         PMU_PROBE(_cpuid, ARM_CPU_PART_MASK, _fn)
148 
149 #define ARM_PMU_XSCALE_MASK     ((0xff << 24) | ARM_CPU_XSCALE_ARCH_MASK)
150 
151 #define XSCALE_PMU_PROBE(_version, _fn) \
152         PMU_PROBE(ARM_CPU_IMP_INTEL << 24 | _version, ARM_PMU_XSCALE_MASK, _fn)
153 
154 int arm_pmu_device_probe(struct platform_device *pdev,
155                          const struct of_device_id *of_table,
156                          const struct pmu_probe_info *probe_table);
157 
158 #ifdef CONFIG_ACPI
159 int arm_pmu_acpi_probe(armpmu_init_fn init_fn);
160 #else
161 static inline int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { return 0; }
162 #endif
163 
164 #ifdef CONFIG_KVM
165 void kvm_host_pmu_init(struct arm_pmu *pmu);
166 #else
167 #define kvm_host_pmu_init(x)    do { } while(0)
168 #endif
169 
170 bool arm_pmu_irq_is_nmi(void);
171 
172 /* Internal functions only for core arm_pmu code */
173 struct arm_pmu *armpmu_alloc(void);
174 void armpmu_free(struct arm_pmu *pmu);
175 int armpmu_register(struct arm_pmu *pmu);
176 int armpmu_request_irq(int irq, int cpu);
177 void armpmu_free_irq(int irq, int cpu);
178 
179 #define ARMV8_PMU_PDEV_NAME "armv8-pmu"
180 
181 #endif /* CONFIG_ARM_PMU */
182 
183 #define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
184 #define ARMV8_TRBE_PDEV_NAME "arm,trbe"
185 
186 /* Why does everything I do descend into this? */
187 #define __GEN_PMU_FORMAT_ATTR(cfg, lo, hi)                              \
188         (lo) == (hi) ? #cfg ":" #lo "\n" : #cfg ":" #lo "-" #hi
189 
190 #define _GEN_PMU_FORMAT_ATTR(cfg, lo, hi)                               \
191         __GEN_PMU_FORMAT_ATTR(cfg, lo, hi)
192 
193 #define GEN_PMU_FORMAT_ATTR(name)                                       \
194         PMU_FORMAT_ATTR(name,                                           \
195         _GEN_PMU_FORMAT_ATTR(ATTR_CFG_FLD_##name##_CFG,                 \
196                              ATTR_CFG_FLD_##name##_LO,                  \
197                              ATTR_CFG_FLD_##name##_HI))
198 
199 #define _ATTR_CFG_GET_FLD(attr, cfg, lo, hi)                            \
200         ((((attr)->cfg) >> lo) & GENMASK_ULL(hi - lo, 0))
201 
202 #define ATTR_CFG_GET_FLD(attr, name)                                    \
203         _ATTR_CFG_GET_FLD(attr,                                         \
204                           ATTR_CFG_FLD_##name##_CFG,                    \
205                           ATTR_CFG_FLD_##name##_LO,                     \
206                           ATTR_CFG_FLD_##name##_HI)
207 
208 #endif /* __ARM_PMU_H__ */
209 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php