162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_X86_PERF_EVENT_H
362306a36Sopenharmony_ci#define _ASM_X86_PERF_EVENT_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/static_call.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/*
862306a36Sopenharmony_ci * Performance event hw details:
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define INTEL_PMC_MAX_GENERIC				       32
1262306a36Sopenharmony_ci#define INTEL_PMC_MAX_FIXED				       16
1362306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED				       32
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define X86_PMC_IDX_MAX					       64
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_PERFCTR0			      0xc1
1862306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_PERFCTR1			      0xc2
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
2162306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_EVENT			0x000000FFULL
2462306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_UMASK			0x0000FF00ULL
2562306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_USR			(1ULL << 16)
2662306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_OS			(1ULL << 17)
2762306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_EDGE			(1ULL << 18)
2862306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_PIN_CONTROL		(1ULL << 19)
2962306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_INT			(1ULL << 20)
3062306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_ANY			(1ULL << 21)
3162306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_ENABLE			(1ULL << 22)
3262306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_INV			(1ULL << 23)
3362306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTSEL_CMASK			0xFF000000ULL
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define INTEL_FIXED_BITS_MASK				0xFULL
3662306a36Sopenharmony_ci#define INTEL_FIXED_BITS_STRIDE			4
3762306a36Sopenharmony_ci#define INTEL_FIXED_0_KERNEL				(1ULL << 0)
3862306a36Sopenharmony_ci#define INTEL_FIXED_0_USER				(1ULL << 1)
3962306a36Sopenharmony_ci#define INTEL_FIXED_0_ANYTHREAD			(1ULL << 2)
4062306a36Sopenharmony_ci#define INTEL_FIXED_0_ENABLE_PMI			(1ULL << 3)
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define HSW_IN_TX					(1ULL << 32)
4362306a36Sopenharmony_ci#define HSW_IN_TX_CHECKPOINTED				(1ULL << 33)
4462306a36Sopenharmony_ci#define ICL_EVENTSEL_ADAPTIVE				(1ULL << 34)
4562306a36Sopenharmony_ci#define ICL_FIXED_0_ADAPTIVE				(1ULL << 32)
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define intel_fixed_bits_by_idx(_idx, _bits)			\
4862306a36Sopenharmony_ci	((_bits) << ((_idx) * INTEL_FIXED_BITS_STRIDE))
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define AMD64_EVENTSEL_INT_CORE_ENABLE			(1ULL << 36)
5162306a36Sopenharmony_ci#define AMD64_EVENTSEL_GUESTONLY			(1ULL << 40)
5262306a36Sopenharmony_ci#define AMD64_EVENTSEL_HOSTONLY				(1ULL << 41)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define AMD64_EVENTSEL_INT_CORE_SEL_SHIFT		37
5562306a36Sopenharmony_ci#define AMD64_EVENTSEL_INT_CORE_SEL_MASK		\
5662306a36Sopenharmony_ci	(0xFULL << AMD64_EVENTSEL_INT_CORE_SEL_SHIFT)
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#define AMD64_EVENTSEL_EVENT	\
5962306a36Sopenharmony_ci	(ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32))
6062306a36Sopenharmony_ci#define INTEL_ARCH_EVENT_MASK	\
6162306a36Sopenharmony_ci	(ARCH_PERFMON_EVENTSEL_UMASK | ARCH_PERFMON_EVENTSEL_EVENT)
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#define AMD64_L3_SLICE_SHIFT				48
6462306a36Sopenharmony_ci#define AMD64_L3_SLICE_MASK				\
6562306a36Sopenharmony_ci	(0xFULL << AMD64_L3_SLICE_SHIFT)
6662306a36Sopenharmony_ci#define AMD64_L3_SLICEID_MASK				\
6762306a36Sopenharmony_ci	(0x7ULL << AMD64_L3_SLICE_SHIFT)
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#define AMD64_L3_THREAD_SHIFT				56
7062306a36Sopenharmony_ci#define AMD64_L3_THREAD_MASK				\
7162306a36Sopenharmony_ci	(0xFFULL << AMD64_L3_THREAD_SHIFT)
7262306a36Sopenharmony_ci#define AMD64_L3_F19H_THREAD_MASK			\
7362306a36Sopenharmony_ci	(0x3ULL << AMD64_L3_THREAD_SHIFT)
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#define AMD64_L3_EN_ALL_CORES				BIT_ULL(47)
7662306a36Sopenharmony_ci#define AMD64_L3_EN_ALL_SLICES				BIT_ULL(46)
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#define AMD64_L3_COREID_SHIFT				42
7962306a36Sopenharmony_ci#define AMD64_L3_COREID_MASK				\
8062306a36Sopenharmony_ci	(0x7ULL << AMD64_L3_COREID_SHIFT)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#define X86_RAW_EVENT_MASK		\
8362306a36Sopenharmony_ci	(ARCH_PERFMON_EVENTSEL_EVENT |	\
8462306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_UMASK |	\
8562306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_EDGE  |	\
8662306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_INV   |	\
8762306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_CMASK)
8862306a36Sopenharmony_ci#define X86_ALL_EVENT_FLAGS  			\
8962306a36Sopenharmony_ci	(ARCH_PERFMON_EVENTSEL_EDGE |  		\
9062306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_INV | 		\
9162306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_CMASK | 		\
9262306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_ANY | 		\
9362306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_PIN_CONTROL | 	\
9462306a36Sopenharmony_ci	 HSW_IN_TX | 				\
9562306a36Sopenharmony_ci	 HSW_IN_TX_CHECKPOINTED)
9662306a36Sopenharmony_ci#define AMD64_RAW_EVENT_MASK		\
9762306a36Sopenharmony_ci	(X86_RAW_EVENT_MASK          |  \
9862306a36Sopenharmony_ci	 AMD64_EVENTSEL_EVENT)
9962306a36Sopenharmony_ci#define AMD64_RAW_EVENT_MASK_NB		\
10062306a36Sopenharmony_ci	(AMD64_EVENTSEL_EVENT        |  \
10162306a36Sopenharmony_ci	 ARCH_PERFMON_EVENTSEL_UMASK)
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci#define AMD64_PERFMON_V2_EVENTSEL_EVENT_NB	\
10462306a36Sopenharmony_ci	(AMD64_EVENTSEL_EVENT	|		\
10562306a36Sopenharmony_ci	 GENMASK_ULL(37, 36))
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci#define AMD64_PERFMON_V2_EVENTSEL_UMASK_NB	\
10862306a36Sopenharmony_ci	(ARCH_PERFMON_EVENTSEL_UMASK	|	\
10962306a36Sopenharmony_ci	 GENMASK_ULL(27, 24))
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci#define AMD64_PERFMON_V2_RAW_EVENT_MASK_NB		\
11262306a36Sopenharmony_ci	(AMD64_PERFMON_V2_EVENTSEL_EVENT_NB	|	\
11362306a36Sopenharmony_ci	 AMD64_PERFMON_V2_EVENTSEL_UMASK_NB)
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci#define AMD64_NUM_COUNTERS				4
11662306a36Sopenharmony_ci#define AMD64_NUM_COUNTERS_CORE				6
11762306a36Sopenharmony_ci#define AMD64_NUM_COUNTERS_NB				4
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL		0x3c
12062306a36Sopenharmony_ci#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK		(0x00 << 8)
12162306a36Sopenharmony_ci#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX		0
12262306a36Sopenharmony_ci#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
12362306a36Sopenharmony_ci		(1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci#define ARCH_PERFMON_BRANCH_MISSES_RETIRED		6
12662306a36Sopenharmony_ci#define ARCH_PERFMON_EVENTS_COUNT			7
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci#define PEBS_DATACFG_MEMINFO	BIT_ULL(0)
12962306a36Sopenharmony_ci#define PEBS_DATACFG_GP	BIT_ULL(1)
13062306a36Sopenharmony_ci#define PEBS_DATACFG_XMMS	BIT_ULL(2)
13162306a36Sopenharmony_ci#define PEBS_DATACFG_LBRS	BIT_ULL(3)
13262306a36Sopenharmony_ci#define PEBS_DATACFG_LBR_SHIFT	24
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/* Steal the highest bit of pebs_data_cfg for SW usage */
13562306a36Sopenharmony_ci#define PEBS_UPDATE_DS_SW	BIT_ULL(63)
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/*
13862306a36Sopenharmony_ci * Intel "Architectural Performance Monitoring" CPUID
13962306a36Sopenharmony_ci * detection/enumeration details:
14062306a36Sopenharmony_ci */
14162306a36Sopenharmony_ciunion cpuid10_eax {
14262306a36Sopenharmony_ci	struct {
14362306a36Sopenharmony_ci		unsigned int version_id:8;
14462306a36Sopenharmony_ci		unsigned int num_counters:8;
14562306a36Sopenharmony_ci		unsigned int bit_width:8;
14662306a36Sopenharmony_ci		unsigned int mask_length:8;
14762306a36Sopenharmony_ci	} split;
14862306a36Sopenharmony_ci	unsigned int full;
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ciunion cpuid10_ebx {
15262306a36Sopenharmony_ci	struct {
15362306a36Sopenharmony_ci		unsigned int no_unhalted_core_cycles:1;
15462306a36Sopenharmony_ci		unsigned int no_instructions_retired:1;
15562306a36Sopenharmony_ci		unsigned int no_unhalted_reference_cycles:1;
15662306a36Sopenharmony_ci		unsigned int no_llc_reference:1;
15762306a36Sopenharmony_ci		unsigned int no_llc_misses:1;
15862306a36Sopenharmony_ci		unsigned int no_branch_instruction_retired:1;
15962306a36Sopenharmony_ci		unsigned int no_branch_misses_retired:1;
16062306a36Sopenharmony_ci	} split;
16162306a36Sopenharmony_ci	unsigned int full;
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciunion cpuid10_edx {
16562306a36Sopenharmony_ci	struct {
16662306a36Sopenharmony_ci		unsigned int num_counters_fixed:5;
16762306a36Sopenharmony_ci		unsigned int bit_width_fixed:8;
16862306a36Sopenharmony_ci		unsigned int reserved1:2;
16962306a36Sopenharmony_ci		unsigned int anythread_deprecated:1;
17062306a36Sopenharmony_ci		unsigned int reserved2:16;
17162306a36Sopenharmony_ci	} split;
17262306a36Sopenharmony_ci	unsigned int full;
17362306a36Sopenharmony_ci};
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/*
17662306a36Sopenharmony_ci * Intel "Architectural Performance Monitoring extension" CPUID
17762306a36Sopenharmony_ci * detection/enumeration details:
17862306a36Sopenharmony_ci */
17962306a36Sopenharmony_ci#define ARCH_PERFMON_EXT_LEAF			0x00000023
18062306a36Sopenharmony_ci#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT	0x1
18162306a36Sopenharmony_ci#define ARCH_PERFMON_NUM_COUNTER_LEAF		0x1
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/*
18462306a36Sopenharmony_ci * Intel Architectural LBR CPUID detection/enumeration details:
18562306a36Sopenharmony_ci */
18662306a36Sopenharmony_ciunion cpuid28_eax {
18762306a36Sopenharmony_ci	struct {
18862306a36Sopenharmony_ci		/* Supported LBR depth values */
18962306a36Sopenharmony_ci		unsigned int	lbr_depth_mask:8;
19062306a36Sopenharmony_ci		unsigned int	reserved:22;
19162306a36Sopenharmony_ci		/* Deep C-state Reset */
19262306a36Sopenharmony_ci		unsigned int	lbr_deep_c_reset:1;
19362306a36Sopenharmony_ci		/* IP values contain LIP */
19462306a36Sopenharmony_ci		unsigned int	lbr_lip:1;
19562306a36Sopenharmony_ci	} split;
19662306a36Sopenharmony_ci	unsigned int		full;
19762306a36Sopenharmony_ci};
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ciunion cpuid28_ebx {
20062306a36Sopenharmony_ci	struct {
20162306a36Sopenharmony_ci		/* CPL Filtering Supported */
20262306a36Sopenharmony_ci		unsigned int    lbr_cpl:1;
20362306a36Sopenharmony_ci		/* Branch Filtering Supported */
20462306a36Sopenharmony_ci		unsigned int    lbr_filter:1;
20562306a36Sopenharmony_ci		/* Call-stack Mode Supported */
20662306a36Sopenharmony_ci		unsigned int    lbr_call_stack:1;
20762306a36Sopenharmony_ci	} split;
20862306a36Sopenharmony_ci	unsigned int            full;
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ciunion cpuid28_ecx {
21262306a36Sopenharmony_ci	struct {
21362306a36Sopenharmony_ci		/* Mispredict Bit Supported */
21462306a36Sopenharmony_ci		unsigned int    lbr_mispred:1;
21562306a36Sopenharmony_ci		/* Timed LBRs Supported */
21662306a36Sopenharmony_ci		unsigned int    lbr_timed_lbr:1;
21762306a36Sopenharmony_ci		/* Branch Type Field Supported */
21862306a36Sopenharmony_ci		unsigned int    lbr_br_type:1;
21962306a36Sopenharmony_ci	} split;
22062306a36Sopenharmony_ci	unsigned int            full;
22162306a36Sopenharmony_ci};
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci/*
22462306a36Sopenharmony_ci * AMD "Extended Performance Monitoring and Debug" CPUID
22562306a36Sopenharmony_ci * detection/enumeration details:
22662306a36Sopenharmony_ci */
22762306a36Sopenharmony_ciunion cpuid_0x80000022_ebx {
22862306a36Sopenharmony_ci	struct {
22962306a36Sopenharmony_ci		/* Number of Core Performance Counters */
23062306a36Sopenharmony_ci		unsigned int	num_core_pmc:4;
23162306a36Sopenharmony_ci		/* Number of available LBR Stack Entries */
23262306a36Sopenharmony_ci		unsigned int	lbr_v2_stack_sz:6;
23362306a36Sopenharmony_ci		/* Number of Data Fabric Counters */
23462306a36Sopenharmony_ci		unsigned int	num_df_pmc:6;
23562306a36Sopenharmony_ci	} split;
23662306a36Sopenharmony_ci	unsigned int		full;
23762306a36Sopenharmony_ci};
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistruct x86_pmu_capability {
24062306a36Sopenharmony_ci	int		version;
24162306a36Sopenharmony_ci	int		num_counters_gp;
24262306a36Sopenharmony_ci	int		num_counters_fixed;
24362306a36Sopenharmony_ci	int		bit_width_gp;
24462306a36Sopenharmony_ci	int		bit_width_fixed;
24562306a36Sopenharmony_ci	unsigned int	events_mask;
24662306a36Sopenharmony_ci	int		events_mask_len;
24762306a36Sopenharmony_ci	unsigned int	pebs_ept	:1;
24862306a36Sopenharmony_ci};
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci/*
25162306a36Sopenharmony_ci * Fixed-purpose performance events:
25262306a36Sopenharmony_ci */
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci/* RDPMC offset for Fixed PMCs */
25562306a36Sopenharmony_ci#define INTEL_PMC_FIXED_RDPMC_BASE		(1 << 30)
25662306a36Sopenharmony_ci#define INTEL_PMC_FIXED_RDPMC_METRICS		(1 << 29)
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci/*
25962306a36Sopenharmony_ci * All the fixed-mode PMCs are configured via this single MSR:
26062306a36Sopenharmony_ci */
26162306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_FIXED_CTR_CTRL	0x38d
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci/*
26462306a36Sopenharmony_ci * There is no event-code assigned to the fixed-mode PMCs.
26562306a36Sopenharmony_ci *
26662306a36Sopenharmony_ci * For a fixed-mode PMC, which has an equivalent event on a general-purpose
26762306a36Sopenharmony_ci * PMC, the event-code of the equivalent event is used for the fixed-mode PMC,
26862306a36Sopenharmony_ci * e.g., Instr_Retired.Any and CPU_CLK_Unhalted.Core.
26962306a36Sopenharmony_ci *
27062306a36Sopenharmony_ci * For a fixed-mode PMC, which doesn't have an equivalent event, a
27162306a36Sopenharmony_ci * pseudo-encoding is used, e.g., CPU_CLK_Unhalted.Ref and TOPDOWN.SLOTS.
27262306a36Sopenharmony_ci * The pseudo event-code for a fixed-mode PMC must be 0x00.
27362306a36Sopenharmony_ci * The pseudo umask-code is 0xX. The X equals the index of the fixed
27462306a36Sopenharmony_ci * counter + 1, e.g., the fixed counter 2 has the pseudo-encoding 0x0300.
27562306a36Sopenharmony_ci *
27662306a36Sopenharmony_ci * The counts are available in separate MSRs:
27762306a36Sopenharmony_ci */
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci/* Instr_Retired.Any: */
28062306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_FIXED_CTR0	0x309
28162306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED_INSTRUCTIONS	(INTEL_PMC_IDX_FIXED + 0)
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci/* CPU_CLK_Unhalted.Core: */
28462306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_FIXED_CTR1	0x30a
28562306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED_CPU_CYCLES	(INTEL_PMC_IDX_FIXED + 1)
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/* CPU_CLK_Unhalted.Ref: event=0x00,umask=0x3 (pseudo-encoding) */
28862306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_FIXED_CTR2	0x30b
28962306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED_REF_CYCLES	(INTEL_PMC_IDX_FIXED + 2)
29062306a36Sopenharmony_ci#define INTEL_PMC_MSK_FIXED_REF_CYCLES	(1ULL << INTEL_PMC_IDX_FIXED_REF_CYCLES)
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci/* TOPDOWN.SLOTS: event=0x00,umask=0x4 (pseudo-encoding) */
29362306a36Sopenharmony_ci#define MSR_ARCH_PERFMON_FIXED_CTR3	0x30c
29462306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED_SLOTS	(INTEL_PMC_IDX_FIXED + 3)
29562306a36Sopenharmony_ci#define INTEL_PMC_MSK_FIXED_SLOTS	(1ULL << INTEL_PMC_IDX_FIXED_SLOTS)
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_cistatic inline bool use_fixed_pseudo_encoding(u64 code)
29862306a36Sopenharmony_ci{
29962306a36Sopenharmony_ci	return !(code & 0xff);
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/*
30362306a36Sopenharmony_ci * We model BTS tracing as another fixed-mode PMC.
30462306a36Sopenharmony_ci *
30562306a36Sopenharmony_ci * We choose the value 47 for the fixed index of BTS, since lower
30662306a36Sopenharmony_ci * values are used by actual fixed events and higher values are used
30762306a36Sopenharmony_ci * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr.
30862306a36Sopenharmony_ci */
30962306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED_BTS			(INTEL_PMC_IDX_FIXED + 15)
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci/*
31262306a36Sopenharmony_ci * The PERF_METRICS MSR is modeled as several magic fixed-mode PMCs, one for
31362306a36Sopenharmony_ci * each TopDown metric event.
31462306a36Sopenharmony_ci *
31562306a36Sopenharmony_ci * Internally the TopDown metric events are mapped to the FxCtr 3 (SLOTS).
31662306a36Sopenharmony_ci */
31762306a36Sopenharmony_ci#define INTEL_PMC_IDX_METRIC_BASE		(INTEL_PMC_IDX_FIXED + 16)
31862306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_RETIRING		(INTEL_PMC_IDX_METRIC_BASE + 0)
31962306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_BAD_SPEC		(INTEL_PMC_IDX_METRIC_BASE + 1)
32062306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_FE_BOUND		(INTEL_PMC_IDX_METRIC_BASE + 2)
32162306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_BE_BOUND		(INTEL_PMC_IDX_METRIC_BASE + 3)
32262306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_HEAVY_OPS		(INTEL_PMC_IDX_METRIC_BASE + 4)
32362306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_BR_MISPREDICT		(INTEL_PMC_IDX_METRIC_BASE + 5)
32462306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_FETCH_LAT		(INTEL_PMC_IDX_METRIC_BASE + 6)
32562306a36Sopenharmony_ci#define INTEL_PMC_IDX_TD_MEM_BOUND		(INTEL_PMC_IDX_METRIC_BASE + 7)
32662306a36Sopenharmony_ci#define INTEL_PMC_IDX_METRIC_END		INTEL_PMC_IDX_TD_MEM_BOUND
32762306a36Sopenharmony_ci#define INTEL_PMC_MSK_TOPDOWN			((0xffull << INTEL_PMC_IDX_METRIC_BASE) | \
32862306a36Sopenharmony_ci						INTEL_PMC_MSK_FIXED_SLOTS)
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci/*
33162306a36Sopenharmony_ci * There is no event-code assigned to the TopDown events.
33262306a36Sopenharmony_ci *
33362306a36Sopenharmony_ci * For the slots event, use the pseudo code of the fixed counter 3.
33462306a36Sopenharmony_ci *
33562306a36Sopenharmony_ci * For the metric events, the pseudo event-code is 0x00.
33662306a36Sopenharmony_ci * The pseudo umask-code starts from the middle of the pseudo event
33762306a36Sopenharmony_ci * space, 0x80.
33862306a36Sopenharmony_ci */
33962306a36Sopenharmony_ci#define INTEL_TD_SLOTS				0x0400	/* TOPDOWN.SLOTS */
34062306a36Sopenharmony_ci/* Level 1 metrics */
34162306a36Sopenharmony_ci#define INTEL_TD_METRIC_RETIRING		0x8000	/* Retiring metric */
34262306a36Sopenharmony_ci#define INTEL_TD_METRIC_BAD_SPEC		0x8100	/* Bad speculation metric */
34362306a36Sopenharmony_ci#define INTEL_TD_METRIC_FE_BOUND		0x8200	/* FE bound metric */
34462306a36Sopenharmony_ci#define INTEL_TD_METRIC_BE_BOUND		0x8300	/* BE bound metric */
34562306a36Sopenharmony_ci/* Level 2 metrics */
34662306a36Sopenharmony_ci#define INTEL_TD_METRIC_HEAVY_OPS		0x8400  /* Heavy Operations metric */
34762306a36Sopenharmony_ci#define INTEL_TD_METRIC_BR_MISPREDICT		0x8500  /* Branch Mispredict metric */
34862306a36Sopenharmony_ci#define INTEL_TD_METRIC_FETCH_LAT		0x8600  /* Fetch Latency metric */
34962306a36Sopenharmony_ci#define INTEL_TD_METRIC_MEM_BOUND		0x8700  /* Memory bound metric */
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci#define INTEL_TD_METRIC_MAX			INTEL_TD_METRIC_MEM_BOUND
35262306a36Sopenharmony_ci#define INTEL_TD_METRIC_NUM			8
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cistatic inline bool is_metric_idx(int idx)
35562306a36Sopenharmony_ci{
35662306a36Sopenharmony_ci	return (unsigned)(idx - INTEL_PMC_IDX_METRIC_BASE) < INTEL_TD_METRIC_NUM;
35762306a36Sopenharmony_ci}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_cistatic inline bool is_topdown_idx(int idx)
36062306a36Sopenharmony_ci{
36162306a36Sopenharmony_ci	return is_metric_idx(idx) || idx == INTEL_PMC_IDX_FIXED_SLOTS;
36262306a36Sopenharmony_ci}
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci#define INTEL_PMC_OTHER_TOPDOWN_BITS(bit)	\
36562306a36Sopenharmony_ci			(~(0x1ull << bit) & INTEL_PMC_MSK_TOPDOWN)
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci#define GLOBAL_STATUS_COND_CHG			BIT_ULL(63)
36862306a36Sopenharmony_ci#define GLOBAL_STATUS_BUFFER_OVF_BIT		62
36962306a36Sopenharmony_ci#define GLOBAL_STATUS_BUFFER_OVF		BIT_ULL(GLOBAL_STATUS_BUFFER_OVF_BIT)
37062306a36Sopenharmony_ci#define GLOBAL_STATUS_UNC_OVF			BIT_ULL(61)
37162306a36Sopenharmony_ci#define GLOBAL_STATUS_ASIF			BIT_ULL(60)
37262306a36Sopenharmony_ci#define GLOBAL_STATUS_COUNTERS_FROZEN		BIT_ULL(59)
37362306a36Sopenharmony_ci#define GLOBAL_STATUS_LBRS_FROZEN_BIT		58
37462306a36Sopenharmony_ci#define GLOBAL_STATUS_LBRS_FROZEN		BIT_ULL(GLOBAL_STATUS_LBRS_FROZEN_BIT)
37562306a36Sopenharmony_ci#define GLOBAL_STATUS_TRACE_TOPAPMI_BIT		55
37662306a36Sopenharmony_ci#define GLOBAL_STATUS_TRACE_TOPAPMI		BIT_ULL(GLOBAL_STATUS_TRACE_TOPAPMI_BIT)
37762306a36Sopenharmony_ci#define GLOBAL_STATUS_PERF_METRICS_OVF_BIT	48
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci#define GLOBAL_CTRL_EN_PERF_METRICS		48
38062306a36Sopenharmony_ci/*
38162306a36Sopenharmony_ci * We model guest LBR event tracing as another fixed-mode PMC like BTS.
38262306a36Sopenharmony_ci *
38362306a36Sopenharmony_ci * We choose bit 58 because it's used to indicate LBR stack frozen state
38462306a36Sopenharmony_ci * for architectural perfmon v4, also we unconditionally mask that bit in
38562306a36Sopenharmony_ci * the handle_pmi_common(), so it'll never be set in the overflow handling.
38662306a36Sopenharmony_ci *
38762306a36Sopenharmony_ci * With this fake counter assigned, the guest LBR event user (such as KVM),
38862306a36Sopenharmony_ci * can program the LBR registers on its own, and we don't actually do anything
38962306a36Sopenharmony_ci * with then in the host context.
39062306a36Sopenharmony_ci */
39162306a36Sopenharmony_ci#define INTEL_PMC_IDX_FIXED_VLBR	(GLOBAL_STATUS_LBRS_FROZEN_BIT)
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci/*
39462306a36Sopenharmony_ci * Pseudo-encoding the guest LBR event as event=0x00,umask=0x1b,
39562306a36Sopenharmony_ci * since it would claim bit 58 which is effectively Fixed26.
39662306a36Sopenharmony_ci */
39762306a36Sopenharmony_ci#define INTEL_FIXED_VLBR_EVENT	0x1b00
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci/*
40062306a36Sopenharmony_ci * Adaptive PEBS v4
40162306a36Sopenharmony_ci */
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_cistruct pebs_basic {
40462306a36Sopenharmony_ci	u64 format_size;
40562306a36Sopenharmony_ci	u64 ip;
40662306a36Sopenharmony_ci	u64 applicable_counters;
40762306a36Sopenharmony_ci	u64 tsc;
40862306a36Sopenharmony_ci};
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_cistruct pebs_meminfo {
41162306a36Sopenharmony_ci	u64 address;
41262306a36Sopenharmony_ci	u64 aux;
41362306a36Sopenharmony_ci	u64 latency;
41462306a36Sopenharmony_ci	u64 tsx_tuning;
41562306a36Sopenharmony_ci};
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistruct pebs_gprs {
41862306a36Sopenharmony_ci	u64 flags, ip, ax, cx, dx, bx, sp, bp, si, di;
41962306a36Sopenharmony_ci	u64 r8, r9, r10, r11, r12, r13, r14, r15;
42062306a36Sopenharmony_ci};
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_cistruct pebs_xmm {
42362306a36Sopenharmony_ci	u64 xmm[16*2];	/* two entries for each register */
42462306a36Sopenharmony_ci};
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci/*
42762306a36Sopenharmony_ci * AMD Extended Performance Monitoring and Debug cpuid feature detection
42862306a36Sopenharmony_ci */
42962306a36Sopenharmony_ci#define EXT_PERFMON_DEBUG_FEATURES		0x80000022
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci/*
43262306a36Sopenharmony_ci * IBS cpuid feature detection
43362306a36Sopenharmony_ci */
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci#define IBS_CPUID_FEATURES		0x8000001b
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci/*
43862306a36Sopenharmony_ci * Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but
43962306a36Sopenharmony_ci * bit 0 is used to indicate the existence of IBS.
44062306a36Sopenharmony_ci */
44162306a36Sopenharmony_ci#define IBS_CAPS_AVAIL			(1U<<0)
44262306a36Sopenharmony_ci#define IBS_CAPS_FETCHSAM		(1U<<1)
44362306a36Sopenharmony_ci#define IBS_CAPS_OPSAM			(1U<<2)
44462306a36Sopenharmony_ci#define IBS_CAPS_RDWROPCNT		(1U<<3)
44562306a36Sopenharmony_ci#define IBS_CAPS_OPCNT			(1U<<4)
44662306a36Sopenharmony_ci#define IBS_CAPS_BRNTRGT		(1U<<5)
44762306a36Sopenharmony_ci#define IBS_CAPS_OPCNTEXT		(1U<<6)
44862306a36Sopenharmony_ci#define IBS_CAPS_RIPINVALIDCHK		(1U<<7)
44962306a36Sopenharmony_ci#define IBS_CAPS_OPBRNFUSE		(1U<<8)
45062306a36Sopenharmony_ci#define IBS_CAPS_FETCHCTLEXTD		(1U<<9)
45162306a36Sopenharmony_ci#define IBS_CAPS_OPDATA4		(1U<<10)
45262306a36Sopenharmony_ci#define IBS_CAPS_ZEN4			(1U<<11)
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci#define IBS_CAPS_DEFAULT		(IBS_CAPS_AVAIL		\
45562306a36Sopenharmony_ci					 | IBS_CAPS_FETCHSAM	\
45662306a36Sopenharmony_ci					 | IBS_CAPS_OPSAM)
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci/*
45962306a36Sopenharmony_ci * IBS APIC setup
46062306a36Sopenharmony_ci */
46162306a36Sopenharmony_ci#define IBSCTL				0x1cc
46262306a36Sopenharmony_ci#define IBSCTL_LVT_OFFSET_VALID		(1ULL<<8)
46362306a36Sopenharmony_ci#define IBSCTL_LVT_OFFSET_MASK		0x0F
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci/* IBS fetch bits/masks */
46662306a36Sopenharmony_ci#define IBS_FETCH_L3MISSONLY	(1ULL<<59)
46762306a36Sopenharmony_ci#define IBS_FETCH_RAND_EN	(1ULL<<57)
46862306a36Sopenharmony_ci#define IBS_FETCH_VAL		(1ULL<<49)
46962306a36Sopenharmony_ci#define IBS_FETCH_ENABLE	(1ULL<<48)
47062306a36Sopenharmony_ci#define IBS_FETCH_CNT		0xFFFF0000ULL
47162306a36Sopenharmony_ci#define IBS_FETCH_MAX_CNT	0x0000FFFFULL
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci/*
47462306a36Sopenharmony_ci * IBS op bits/masks
47562306a36Sopenharmony_ci * The lower 7 bits of the current count are random bits
47662306a36Sopenharmony_ci * preloaded by hardware and ignored in software
47762306a36Sopenharmony_ci */
47862306a36Sopenharmony_ci#define IBS_OP_CUR_CNT		(0xFFF80ULL<<32)
47962306a36Sopenharmony_ci#define IBS_OP_CUR_CNT_RAND	(0x0007FULL<<32)
48062306a36Sopenharmony_ci#define IBS_OP_CNT_CTL		(1ULL<<19)
48162306a36Sopenharmony_ci#define IBS_OP_VAL		(1ULL<<18)
48262306a36Sopenharmony_ci#define IBS_OP_ENABLE		(1ULL<<17)
48362306a36Sopenharmony_ci#define IBS_OP_L3MISSONLY	(1ULL<<16)
48462306a36Sopenharmony_ci#define IBS_OP_MAX_CNT		0x0000FFFFULL
48562306a36Sopenharmony_ci#define IBS_OP_MAX_CNT_EXT	0x007FFFFFULL	/* not a register bit mask */
48662306a36Sopenharmony_ci#define IBS_OP_MAX_CNT_EXT_MASK	(0x7FULL<<20)	/* separate upper 7 bits */
48762306a36Sopenharmony_ci#define IBS_RIP_INVALID		(1ULL<<38)
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci#ifdef CONFIG_X86_LOCAL_APIC
49062306a36Sopenharmony_ciextern u32 get_ibs_caps(void);
49162306a36Sopenharmony_ciextern int forward_event_to_ibs(struct perf_event *event);
49262306a36Sopenharmony_ci#else
49362306a36Sopenharmony_cistatic inline u32 get_ibs_caps(void) { return 0; }
49462306a36Sopenharmony_cistatic inline int forward_event_to_ibs(struct perf_event *event) { return -ENOENT; }
49562306a36Sopenharmony_ci#endif
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci#ifdef CONFIG_PERF_EVENTS
49862306a36Sopenharmony_ciextern void perf_events_lapic_init(void);
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci/*
50162306a36Sopenharmony_ci * Abuse bits {3,5} of the cpu eflags register. These flags are otherwise
50262306a36Sopenharmony_ci * unused and ABI specified to be 0, so nobody should care what we do with
50362306a36Sopenharmony_ci * them.
50462306a36Sopenharmony_ci *
50562306a36Sopenharmony_ci * EXACT - the IP points to the exact instruction that triggered the
50662306a36Sopenharmony_ci *         event (HW bugs exempt).
50762306a36Sopenharmony_ci * VM    - original X86_VM_MASK; see set_linear_ip().
50862306a36Sopenharmony_ci */
50962306a36Sopenharmony_ci#define PERF_EFLAGS_EXACT	(1UL << 3)
51062306a36Sopenharmony_ci#define PERF_EFLAGS_VM		(1UL << 5)
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_cistruct pt_regs;
51362306a36Sopenharmony_cistruct x86_perf_regs {
51462306a36Sopenharmony_ci	struct pt_regs	regs;
51562306a36Sopenharmony_ci	u64		*xmm_regs;
51662306a36Sopenharmony_ci};
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ciextern unsigned long perf_instruction_pointer(struct pt_regs *regs);
51962306a36Sopenharmony_ciextern unsigned long perf_misc_flags(struct pt_regs *regs);
52062306a36Sopenharmony_ci#define perf_misc_flags(regs)	perf_misc_flags(regs)
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci#include <asm/stacktrace.h>
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci/*
52562306a36Sopenharmony_ci * We abuse bit 3 from flags to pass exact information, see perf_misc_flags
52662306a36Sopenharmony_ci * and the comment with PERF_EFLAGS_EXACT.
52762306a36Sopenharmony_ci */
52862306a36Sopenharmony_ci#define perf_arch_fetch_caller_regs(regs, __ip)		{	\
52962306a36Sopenharmony_ci	(regs)->ip = (__ip);					\
53062306a36Sopenharmony_ci	(regs)->sp = (unsigned long)__builtin_frame_address(0);	\
53162306a36Sopenharmony_ci	(regs)->cs = __KERNEL_CS;				\
53262306a36Sopenharmony_ci	regs->flags = 0;					\
53362306a36Sopenharmony_ci}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_cistruct perf_guest_switch_msr {
53662306a36Sopenharmony_ci	unsigned msr;
53762306a36Sopenharmony_ci	u64 host, guest;
53862306a36Sopenharmony_ci};
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistruct x86_pmu_lbr {
54162306a36Sopenharmony_ci	unsigned int	nr;
54262306a36Sopenharmony_ci	unsigned int	from;
54362306a36Sopenharmony_ci	unsigned int	to;
54462306a36Sopenharmony_ci	unsigned int	info;
54562306a36Sopenharmony_ci};
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ciextern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
54862306a36Sopenharmony_ciextern u64 perf_get_hw_event_config(int hw_event);
54962306a36Sopenharmony_ciextern void perf_check_microcode(void);
55062306a36Sopenharmony_ciextern void perf_clear_dirty_counters(void);
55162306a36Sopenharmony_ciextern int x86_perf_rdpmc_index(struct perf_event *event);
55262306a36Sopenharmony_ci#else
55362306a36Sopenharmony_cistatic inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
55462306a36Sopenharmony_ci{
55562306a36Sopenharmony_ci	memset(cap, 0, sizeof(*cap));
55662306a36Sopenharmony_ci}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_cistatic inline u64 perf_get_hw_event_config(int hw_event)
55962306a36Sopenharmony_ci{
56062306a36Sopenharmony_ci	return 0;
56162306a36Sopenharmony_ci}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_cistatic inline void perf_events_lapic_init(void)	{ }
56462306a36Sopenharmony_cistatic inline void perf_check_microcode(void) { }
56562306a36Sopenharmony_ci#endif
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
56862306a36Sopenharmony_ciextern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr, void *data);
56962306a36Sopenharmony_ciextern void x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
57062306a36Sopenharmony_ci#else
57162306a36Sopenharmony_cistruct perf_guest_switch_msr *perf_guest_get_msrs(int *nr, void *data);
57262306a36Sopenharmony_cistatic inline void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
57362306a36Sopenharmony_ci{
57462306a36Sopenharmony_ci	memset(lbr, 0, sizeof(*lbr));
57562306a36Sopenharmony_ci}
57662306a36Sopenharmony_ci#endif
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci#ifdef CONFIG_CPU_SUP_INTEL
57962306a36Sopenharmony_ci extern void intel_pt_handle_vmx(int on);
58062306a36Sopenharmony_ci#else
58162306a36Sopenharmony_cistatic inline void intel_pt_handle_vmx(int on)
58262306a36Sopenharmony_ci{
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci}
58562306a36Sopenharmony_ci#endif
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
58862306a36Sopenharmony_ci extern void amd_pmu_enable_virt(void);
58962306a36Sopenharmony_ci extern void amd_pmu_disable_virt(void);
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci#if defined(CONFIG_PERF_EVENTS_AMD_BRS)
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci#define PERF_NEEDS_LOPWR_CB 1
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci/*
59662306a36Sopenharmony_ci * architectural low power callback impacts
59762306a36Sopenharmony_ci * drivers/acpi/processor_idle.c
59862306a36Sopenharmony_ci * drivers/acpi/acpi_pad.c
59962306a36Sopenharmony_ci */
60062306a36Sopenharmony_ciextern void perf_amd_brs_lopwr_cb(bool lopwr_in);
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ciDECLARE_STATIC_CALL(perf_lopwr_cb, perf_amd_brs_lopwr_cb);
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_cistatic __always_inline void perf_lopwr_cb(bool lopwr_in)
60562306a36Sopenharmony_ci{
60662306a36Sopenharmony_ci	static_call_mod(perf_lopwr_cb)(lopwr_in);
60762306a36Sopenharmony_ci}
60862306a36Sopenharmony_ci
60962306a36Sopenharmony_ci#endif /* PERF_NEEDS_LOPWR_CB */
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci#else
61262306a36Sopenharmony_ci static inline void amd_pmu_enable_virt(void) { }
61362306a36Sopenharmony_ci static inline void amd_pmu_disable_virt(void) { }
61462306a36Sopenharmony_ci#endif
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci#define arch_perf_out_copy_user copy_from_user_nmi
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci#endif /* _ASM_X86_PERF_EVENT_H */
619