Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 #ifndef __ASM_POWERPC_IMC_PMU_H
0003 #define __ASM_POWERPC_IMC_PMU_H
0004 
0005 /*
0006  * IMC Nest Performance Monitor counter support.
0007  *
0008  * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation.
0009  *           (C) 2017 Anju T Sudhakar, IBM Corporation.
0010  *           (C) 2017 Hemant K Shaw, IBM Corporation.
0011  */
0012 
0013 #include <linux/perf_event.h>
0014 #include <linux/slab.h>
0015 #include <linux/of.h>
0016 #include <linux/io.h>
0017 #include <asm/opal.h>
0018 
0019 /*
0020  * Compatibility macros for IMC devices
0021  */
0022 #define IMC_DTB_COMPAT          "ibm,opal-in-memory-counters"
0023 #define IMC_DTB_UNIT_COMPAT     "ibm,imc-counters"
0024 
0025 
0026 /*
0027  * LDBAR: Counter address and Enable/Disable macro.
0028  * perf/imc-pmu.c has the LDBAR layout information.
0029  */
0030 #define THREAD_IMC_LDBAR_MASK           0x0003ffffffffe000ULL
0031 #define THREAD_IMC_ENABLE               0x8000000000000000ULL
0032 #define TRACE_IMC_ENABLE        0x4000000000000000ULL
0033 
0034 /*
0035  * For debugfs interface for imc-mode and imc-command
0036  */
0037 #define IMC_CNTL_BLK_OFFSET     0x3FC00
0038 #define IMC_CNTL_BLK_CMD_OFFSET     8
0039 #define IMC_CNTL_BLK_MODE_OFFSET    32
0040 
0041 /*
0042  * Structure to hold memory address information for imc units.
0043  */
0044 struct imc_mem_info {
0045     u64 *vbase;
0046     u32 id;
0047 };
0048 
0049 /*
0050  * Place holder for nest pmu events and values.
0051  */
0052 struct imc_events {
0053     u32 value;
0054     char *name;
0055     char *unit;
0056     char *scale;
0057 };
0058 
0059 /*
0060  * Trace IMC hardware updates a 64bytes record on
0061  * Core Performance Monitoring Counter (CPMC)
0062  * overflow. Here is the layout for the trace imc record
0063  *
0064  * DW 0 : Timebase
0065  * DW 1 : Program Counter
0066  * DW 2 : PIDR information
0067  * DW 3 : CPMC1
0068  * DW 4 : CPMC2
0069  * DW 5 : CPMC3
0070  * Dw 6 : CPMC4
0071  * DW 7 : Timebase
0072  * .....
0073  *
0074  * The following is the data structure to hold trace imc data.
0075  */
0076 struct trace_imc_data {
0077     u64 tb1;
0078     u64 ip;
0079     u64 val;
0080     u64 cpmc1;
0081     u64 cpmc2;
0082     u64 cpmc3;
0083     u64 cpmc4;
0084     u64 tb2;
0085 };
0086 
0087 /* Event attribute array index */
0088 #define IMC_FORMAT_ATTR     0
0089 #define IMC_EVENT_ATTR      1
0090 #define IMC_CPUMASK_ATTR    2
0091 #define IMC_NULL_ATTR       3
0092 
0093 /* PMU Format attribute macros */
0094 #define IMC_EVENT_OFFSET_MASK   0xffffffffULL
0095 
0096 /*
0097  * Macro to mask bits 0:21 of first double word(which is the timebase) to
0098  * compare with 8th double word (timebase) of trace imc record data.
0099  */
0100 #define IMC_TRACE_RECORD_TB1_MASK      0x3ffffffffffULL
0101 
0102 /*
0103  * Bit 0:1 in third DW of IMC trace record
0104  * specifies the MSR[HV PR] values.
0105  */
0106 #define IMC_TRACE_RECORD_VAL_HVPR(x)    ((x) >> 62)
0107 
0108 /*
0109  * Device tree parser code detects IMC pmu support and
0110  * registers new IMC pmus. This structure will hold the
0111  * pmu functions, events, counter memory information
0112  * and attrs for each imc pmu and will be referenced at
0113  * the time of pmu registration.
0114  */
0115 struct imc_pmu {
0116     struct pmu pmu;
0117     struct imc_mem_info *mem_info;
0118     struct imc_events *events;
0119     /*
0120      * Attribute groups for the PMU. Slot 0 used for
0121      * format attribute, slot 1 used for cpusmask attribute,
0122      * slot 2 used for event attribute. Slot 3 keep as
0123      * NULL.
0124      */
0125     const struct attribute_group *attr_groups[4];
0126     u32 counter_mem_size;
0127     int domain;
0128     /*
0129      * flag to notify whether the memory is mmaped
0130      * or allocated by kernel.
0131      */
0132     bool imc_counter_mmaped;
0133 };
0134 
0135 /*
0136  * Structure to hold id, lock and reference count for the imc events which
0137  * are inited.
0138  */
0139 struct imc_pmu_ref {
0140     struct mutex lock;
0141     unsigned int id;
0142     int refc;
0143 };
0144 
0145 /*
0146  * In-Memory Collection Counters type.
0147  * Data comes from Device tree.
0148  * Three device type are supported.
0149  */
0150 
0151 enum {
0152     IMC_TYPE_THREAD     = 0x1,
0153     IMC_TYPE_TRACE      = 0x2,
0154     IMC_TYPE_CORE       = 0x4,
0155     IMC_TYPE_CHIP           = 0x10,
0156 };
0157 
0158 /*
0159  * Domains for IMC PMUs
0160  */
0161 #define IMC_DOMAIN_NEST     1
0162 #define IMC_DOMAIN_CORE     2
0163 #define IMC_DOMAIN_THREAD   3
0164 /* For trace-imc the domain is still thread but it operates in trace-mode */
0165 #define IMC_DOMAIN_TRACE    4
0166 
0167 extern int init_imc_pmu(struct device_node *parent,
0168                 struct imc_pmu *pmu_ptr, int pmu_id);
0169 extern void thread_imc_disable(void);
0170 extern int get_max_nest_dev(void);
0171 extern void unregister_thread_imc(void);
0172 #endif /* __ASM_POWERPC_IMC_PMU_H */