summaryrefslogtreecommitdiff
path: root/arch/x86/events/intel/uncore_discovery.h
blob: 0e94aa7db8e7d7d34c9670637c246d6ecdf5d8e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/* SPDX-License-Identifier: GPL-2.0-only */

/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE		0x09a7
/* Capability ID for a discovery table device */
#define UNCORE_EXT_CAP_ID_DISCOVERY		0x23
/* First DVSEC offset */
#define UNCORE_DISCOVERY_DVSEC_OFFSET		0x8
/* Mask of the supported discovery entry type */
#define UNCORE_DISCOVERY_DVSEC_ID_MASK		0xffff
/* PMON discovery entry type ID */
#define UNCORE_DISCOVERY_DVSEC_ID_PMON		0x1
/* Second DVSEC offset */
#define UNCORE_DISCOVERY_DVSEC2_OFFSET		0xc
/* Mask of the discovery table BAR offset */
#define UNCORE_DISCOVERY_DVSEC2_BIR_MASK	0x7
/* Discovery table BAR base offset */
#define UNCORE_DISCOVERY_BIR_BASE		0x10
/* Discovery table BAR step */
#define UNCORE_DISCOVERY_BIR_STEP		0x4
/* Global discovery table size */
#define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE	0x20

#define UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET	28
#define UNCORE_DISCOVERY_PCI_DOMAIN(data)			\
		((data >> UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET) & 0x7)
#define UNCORE_DISCOVERY_PCI_BUS_OFFSET		20
#define UNCORE_DISCOVERY_PCI_BUS(data)				\
		((data >> UNCORE_DISCOVERY_PCI_BUS_OFFSET) & 0xff)
#define UNCORE_DISCOVERY_PCI_DEVFN_OFFSET	12
#define UNCORE_DISCOVERY_PCI_DEVFN(data)			\
		((data >> UNCORE_DISCOVERY_PCI_DEVFN_OFFSET) & 0xff)
#define UNCORE_DISCOVERY_PCI_BOX_CTRL(data)	(data & 0xfff)


#define uncore_discovery_invalid_unit(unit)			\
	(!unit.table1 || !unit.ctl || \
	 unit.table1 == -1ULL || unit.ctl == -1ULL ||	\
	 unit.table3 == -1ULL)

#define GENERIC_PMON_CTL_EV_SEL_MASK	0x000000ff
#define GENERIC_PMON_CTL_UMASK_MASK	0x0000ff00
#define GENERIC_PMON_CTL_EDGE_DET	(1 << 18)
#define GENERIC_PMON_CTL_INVERT		(1 << 23)
#define GENERIC_PMON_CTL_TRESH_MASK	0xff000000
#define GENERIC_PMON_RAW_EVENT_MASK	(GENERIC_PMON_CTL_EV_SEL_MASK | \
					 GENERIC_PMON_CTL_UMASK_MASK | \
					 GENERIC_PMON_CTL_EDGE_DET | \
					 GENERIC_PMON_CTL_INVERT | \
					 GENERIC_PMON_CTL_TRESH_MASK)

#define GENERIC_PMON_BOX_CTL_FRZ	(1 << 0)
#define GENERIC_PMON_BOX_CTL_RST_CTRL	(1 << 8)
#define GENERIC_PMON_BOX_CTL_RST_CTRS	(1 << 9)
#define GENERIC_PMON_BOX_CTL_INT	(GENERIC_PMON_BOX_CTL_RST_CTRL | \
					 GENERIC_PMON_BOX_CTL_RST_CTRS)

enum uncore_access_type {
	UNCORE_ACCESS_MSR	= 0,
	UNCORE_ACCESS_MMIO,
	UNCORE_ACCESS_PCI,

	UNCORE_ACCESS_MAX,
};

struct uncore_global_discovery {
	union {
		u64	table1;
		struct {
			u64	type : 8,
				stride : 8,
				max_units : 10,
				__reserved_1 : 36,
				access_type : 2;
		};
	};

	u64	ctl;		/* Global Control Address */

	union {
		u64	table3;
		struct {
			u64	status_offset : 8,
				num_status : 16,
				__reserved_2 : 40;
		};
	};
};

struct uncore_unit_discovery {
	union {
		u64	table1;
		struct {
			u64	num_regs : 8,
				ctl_offset : 8,
				bit_width : 8,
				ctr_offset : 8,
				status_offset : 8,
				__reserved_1 : 22,
				access_type : 2;
			};
		};

	u64	ctl;		/* Unit Control Address */

	union {
		u64	table3;
		struct {
			u64	box_type : 16,
				box_id : 16,
				__reserved_2 : 32;
		};
	};
};

struct intel_uncore_discovery_unit {
	struct rb_node	node;
	unsigned int	pmu_idx;	/* The idx of the corresponding PMU */
	unsigned int	id;		/* Unit ID */
	unsigned int	die;		/* Die ID */
	u64		addr;		/* Unit Control Address */
};

struct intel_uncore_discovery_type {
	struct rb_node	node;
	enum uncore_access_type	access_type;
	struct rb_root	units;		/* Unit ctrl addr for all units */
	u16		type;		/* Type ID of the uncore block */
	u8		num_counters;
	u8		counter_width;
	u8		ctl_offset;	/* Counter Control 0 offset */
	u8		ctr_offset;	/* Counter 0 offset */
	u16		num_units;	/* number of units */
};

bool intel_uncore_has_discovery_tables(int *ignore);
void intel_uncore_clear_discovery_tables(void);
void intel_uncore_generic_uncore_cpu_init(void);
int intel_uncore_generic_uncore_pci_init(void);
void intel_uncore_generic_uncore_mmio_init(void);

void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box);

void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
					     struct perf_event *event);
void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
					    struct perf_event *event);

void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box);
void intel_generic_uncore_pci_disable_event(struct intel_uncore_box *box,
					    struct perf_event *event);
u64 intel_generic_uncore_pci_read_counter(struct intel_uncore_box *box,
					  struct perf_event *event);

struct intel_uncore_type **
intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra);

int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
					unsigned int pmu_idx);
bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
					  struct intel_uncore_box *box);
void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
			  struct rb_root *root, u16 *num_units);