1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#include <lib/zircon-internal/device/cpu-trace/cpu-perf.h>
8
9__BEGIN_CDECLS
10
11// MSRs
12
13#define IPM_MSR_MASK(len, shift) (((1ULL << (len)) - 1) << (shift))
14
15// Bits in the IA32_PERFEVTSELx MSRs.
16
17#define IA32_PERFEVTSEL_EVENT_SELECT_SHIFT (0)
18#define IA32_PERFEVTSEL_EVENT_SELECT_LEN   (8)
19#define IA32_PERFEVTSEL_EVENT_SELECT_MASK \
20  IPM_MSR_MASK(IA32_PERFEVTSEL_EVENT_SELECT_LEN, IA32_PERFEVTSEL_EVENT_SELECT_SHIFT)
21
22#define IA32_PERFEVTSEL_UMASK_SHIFT (8)
23#define IA32_PERFEVTSEL_UMASK_LEN   (8)
24#define IA32_PERFEVTSEL_UMASK_MASK \
25  IPM_MSR_MASK(IA32_PERFEVTSEL_UMASK_LEN, IA32_PERFEVTSEL_UMASK_SHIFT)
26
27#define IA32_PERFEVTSEL_USR_SHIFT (16)
28#define IA32_PERFEVTSEL_USR_LEN   (1)
29#define IA32_PERFEVTSEL_USR_MASK \
30  IPM_MSR_MASK(IA32_PERFEVTSEL_USR_LEN, IA32_PERFEVTSEL_USR_SHIFT)
31
32#define IA32_PERFEVTSEL_OS_SHIFT (17)
33#define IA32_PERFEVTSEL_OS_LEN   (1)
34#define IA32_PERFEVTSEL_OS_MASK \
35  IPM_MSR_MASK(IA32_PERFEVTSEL_OS_LEN, IA32_PERFEVTSEL_OS_SHIFT)
36
37#define IA32_PERFEVTSEL_E_SHIFT (18)
38#define IA32_PERFEVTSEL_E_LEN   (1)
39#define IA32_PERFEVTSEL_E_MASK \
40  IPM_MSR_MASK(IA32_PERFEVTSEL_E_LEN, IA32_PERFEVTSEL_E_SHIFT)
41
42#define IA32_PERFEVTSEL_PC_SHIFT (19)
43#define IA32_PERFEVTSEL_PC_LEN   (1)
44#define IA32_PERFEVTSEL_PC_MASK \
45  IPM_MSR_MASK(IA32_PERFEVTSEL_PC_LEN, IA32_PERFEVTSEL_PC_SHIFT)
46
47#define IA32_PERFEVTSEL_INT_SHIFT (20)
48#define IA32_PERFEVTSEL_INT_LEN   (1)
49#define IA32_PERFEVTSEL_INT_MASK \
50  IPM_MSR_MASK(IA32_PERFEVTSEL_INT_LEN, IA32_PERFEVTSEL_INT_SHIFT)
51
52#define IA32_PERFEVTSEL_ANY_SHIFT (21)
53#define IA32_PERFEVTSEL_ANY_LEN   (1)
54#define IA32_PERFEVTSEL_ANY_MASK \
55  IPM_MSR_MASK(IA32_PERFEVTSEL_ANY_LEN, IA32_PERFEVTSEL_ANY_SHIFT)
56
57#define IA32_PERFEVTSEL_EN_SHIFT (22)
58#define IA32_PERFEVTSEL_EN_LEN   (1)
59#define IA32_PERFEVTSEL_EN_MASK \
60  IPM_MSR_MASK(IA32_PERFEVTSEL_EN_LEN, IA32_PERFEVTSEL_EN_SHIFT)
61
62#define IA32_PERFEVTSEL_INV_SHIFT (23)
63#define IA32_PERFEVTSEL_INV_LEN   (1)
64#define IA32_PERFEVTSEL_INV_MASK \
65  IPM_MSR_MASK(IA32_PERFEVTSEL_INV_LEN, IA32_PERFEVTSEL_INV_SHIFT)
66
67#define IA32_PERFEVTSEL_CMASK_SHIFT (24)
68#define IA32_PERFEVTSEL_CMASK_LEN   (8)
69#define IA32_PERFEVTSEL_CMASK_MASK \
70  IPM_MSR_MASK(IA32_PERFEVTSEL_CMASK_LEN, IA32_PERFEVTSEL_CMASK_SHIFT)
71
72// Bits in the IA32_FIXED_CTR_CTRL MSR.
73
74#define IA32_FIXED_CTR_CTRL_EN_SHIFT(ctr) (0 + (ctr) * 4)
75#define IA32_FIXED_CTR_CTRL_EN_LEN        (2)
76#define IA32_FIXED_CTR_CTRL_EN_MASK(ctr) \
77  IPM_MSR_MASK(IA32_FIXED_CTR_CTRL_EN_LEN, IA32_FIXED_CTR_CTRL_EN_SHIFT(ctr))
78
79#define IA32_FIXED_CTR_CTRL_ANY_SHIFT(ctr) (2 + (ctr) * 4)
80#define IA32_FIXED_CTR_CTRL_ANY_LEN        (1)
81#define IA32_FIXED_CTR_CTRL_ANY_MASK(ctr) \
82  IPM_MSR_MASK(IA32_FIXED_CTR_CTRL_ANY_LEN, IA32_FIXED_CTR_CTRL_ANY_SHIFT(ctr))
83
84#define IA32_FIXED_CTR_CTRL_PMI_SHIFT(ctr) (3 + (ctr) * 4)
85#define IA32_FIXED_CTR_CTRL_PMI_LEN        (1)
86#define IA32_FIXED_CTR_CTRL_PMI_MASK(ctr) \
87  IPM_MSR_MASK(IA32_FIXED_CTR_CTRL_PMI_LEN, IA32_FIXED_CTR_CTRL_PMI_SHIFT(ctr))
88
89// The IA32_PERF_GLOBAL_CTRL MSR.
90
91#define IA32_PERF_GLOBAL_CTRL_PMC_EN_SHIFT(ctr) (ctr)
92#define IA32_PERF_GLOBAL_CTRL_PMC_EN_LEN        (1)
93#define IA32_PERF_GLOBAL_CTRL_PMC_EN_MASK(ctr) \
94  IPM_MSR_MASK(IA32_PERF_GLOBAL_CTRL_PMC_EN_LEN, IA32_PERF_GLOBAL_CTRL_PMC_EN_SHIFT(ctr))
95
96#define IA32_PERF_GLOBAL_CTRL_FIXED_EN_SHIFT(ctr) (32 + (ctr))
97#define IA32_PERF_GLOBAL_CTRL_FIXED_EN_LEN        (1)
98#define IA32_PERF_GLOBAL_CTRL_FIXED_EN_MASK(ctr) \
99  IPM_MSR_MASK(IA32_PERF_GLOBAL_CTRL_FIXED_EN_LEN, IA32_PERF_GLOBAL_CTRL_FIXED_EN_SHIFT(ctr))
100
101// Bits in the IA32_PERF_GLOBAL_STATUS MSR.
102// Note: Use these values for IA32_PERF_GLOBAL_STATUS_RESET and
103// IA32_PERF_GLOBAL_STATUS_SET too.
104
105#define IA32_PERF_GLOBAL_STATUS_PMC_OVF_SHIFT(ctr) (ctr)
106#define IA32_PERF_GLOBAL_STATUS_PMC_OVF_LEN        (1)
107#define IA32_PERF_GLOBAL_STATUS_PMC_OVF_MASK(ctr) \
108  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_PMC_OVF_LEN, IA32_PERF_GLOBAL_STATUS_PMC_OVF_SHIFT(ctr))
109
110#define IA32_PERF_GLOBAL_STATUS_FIXED_OVF_SHIFT(ctr) (32 + (ctr))
111#define IA32_PERF_GLOBAL_STATUS_FIXED_OVF_LEN        (1)
112#define IA32_PERF_GLOBAL_STATUS_FIXED_OVF_MASK(ctr) \
113  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_FIXED_OVF_LEN, IA32_PERF_GLOBAL_STATUS_FIXED_OVF_SHIFT(ctr))
114
115#define IA32_PERF_GLOBAL_STATUS_TRACE_TOPA_PMI_SHIFT (55)
116#define IA32_PERF_GLOBAL_STATUS_TRACE_TOPA_PMI_LEN   (1)
117#define IA32_PERF_GLOBAL_STATUS_TRACE_TOPA_PMI_MASK \
118  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_TRACE_TOPA_PMI_LEN, IA32_PERF_GLOBAL_STATUS_TRACE_TOPA_PMI_SHIFT)
119
120#define IA32_PERF_GLOBAL_STATUS_LBR_FRZ_SHIFT (58)
121#define IA32_PERF_GLOBAL_STATUS_LBR_FRZ_LEN   (1)
122#define IA32_PERF_GLOBAL_STATUS_LBR_FRZ_MASK \
123  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_LBR_FRZ_LEN, IA32_PERF_GLOBAL_STATUS_LBR_FRZ_SHIFT)
124
125#define IA32_PERF_GLOBAL_STATUS_CTR_FRZ_SHIFT (59)
126#define IA32_PERF_GLOBAL_STATUS_CTR_FRZ_LEN   (1)
127#define IA32_PERF_GLOBAL_STATUS_CTR_FRZ_MASK \
128  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_CTR_FRZ_LEN, IA32_PERF_GLOBAL_STATUS_CTR_FRZ_SHIFT)
129
130#define IA32_PERF_GLOBAL_STATUS_ASCI_SHIFT (60)
131#define IA32_PERF_GLOBAL_STATUS_ASCI_LEN   (1)
132#define IA32_PERF_GLOBAL_STATUS_ASCI_MASK \
133  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_ASCI_LEN, IA32_PERF_GLOBAL_STATUS_ASCI_SHIFT)
134
135#define IA32_PERF_GLOBAL_STATUS_UNCORE_OVF_SHIFT (61)
136#define IA32_PERF_GLOBAL_STATUS_UNCORE_OVF_LEN   (1)
137#define IA32_PERF_GLOBAL_STATUS_UNCORE_OVF_MASK \
138  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_UNCORE_OVF_LEN, IA32_PERF_GLOBAL_STATUS_UNCORE_OVF_SHIFT)
139
140#define IA32_PERF_GLOBAL_STATUS_DS_BUFFER_OVF_SHIFT (62)
141#define IA32_PERF_GLOBAL_STATUS_DS_BUFFER_OVF_LEN   (1)
142#define IA32_PERF_GLOBAL_STATUS_DS_BUFFER_OVF_MASK \
143  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_DS_BUFFER_OVF_LEN, IA32_PERF_GLOBAL_STATUS_DS_BUFFER_OVF_SHIFT)
144
145#define IA32_PERF_GLOBAL_STATUS_COND_CHGD_SHIFT (63)
146#define IA32_PERF_GLOBAL_STATUS_COND_CHGD_LEN   (1)
147#define IA32_PERF_GLOBAL_STATUS_COND_CHGD_MASK \
148  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_COND_CHGD_LEN, IA32_PERF_GLOBAL_STATUS_COND_CHGD_SHIFT)
149
150// Bits in the IA32_PERF_GLOBAL_INUSE MSR.
151
152#define IA32_PERF_GLOBAL_STATUS_INUSE_PERFEVTSEL_SHIFT(ctr) (ctr)
153#define IA32_PERF_GLOBAL_STATUS_INUSE_PERFEVTSEL_LEN        (1)
154#define IA32_PERF_GLOBAL_STATUS_INUSE_PERFEVTSEL_MASK(ctr) \
155  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_INUSE_PERFEVTSEL_LEN, IA32_PERF_GLOBAL_STATUS_INUSE_PERFEVTSEL_SHIFT(ctr))
156
157#define IA32_PERF_GLOBAL_STATUS_INUSE_FIXED_CTR_SHIFT(ctr) (32 + (ctr))
158#define IA32_PERF_GLOBAL_STATUS_INUSE_FIXED_CTR_LEN        (1)
159#define IA32_PERF_GLOBAL_STATUS_INUSE_FIXED_CTR_MASK(ctr) \
160  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_INUSE_FIXED_CTR_LEN, IA32_PERF_GLOBAL_STATUS_INUSE_FIXED_CTR_SHIFT(ctr))
161
162#define IA32_PERF_GLOBAL_STATUS_INUSE_PMI_SHIFT (63)
163#define IA32_PERF_GLOBAL_STATUS_INUSE_PMI_LEN   (1)
164#define IA32_PERF_GLOBAL_STATUS_INUSE_PMI_MASK \
165  IPM_MSR_MASK(IA32_PERF_GLOBAL_STATUS_INUSE_PMI_LEN, IA32_PERF_GLOBAL_STATUS_INUSE_PMI_SHIFT)
166
167// Bits in the IA32_PERF_GLOBAL_OVF_CTRL MSR.
168
169#define IA32_PERF_GLOBAL_OVF_CTRL_PMC_CLR_OVF_SHIFT(ctr) (0)
170#define IA32_PERF_GLOBAL_OVF_CTRL_PMC_CLR_OVF_LEN        (1)
171#define IA32_PERF_GLOBAL_OVF_CTRL_PMC_CLR_OVF_MASK(ctr) \
172  IPM_MSR_MASK(IA32_PERF_GLOBAL_OVF_CTRL_PMC_CLR_OVF_LEN, IA32_PERF_GLOBAL_OVF_CTRL_PMC_CLR_OVF_SHIFT(ctr))
173
174#define IA32_PERF_GLOBAL_OVF_CTRL_FIXED_CTR_CLR_OVF_SHIFT(ctr) (32 + (ctr))
175#define IA32_PERF_GLOBAL_OVF_CTRL_FIXED_CTR_CLR_OVF_LEN   (1)
176#define IA32_PERF_GLOBAL_OVF_CTRL_FIXED_CTR_CLR_OVF_MASK(ctr) \
177  IPM_MSR_MASK(IA32_PERF_GLOBAL_OVF_CTRL_FIXED_CTR_CLR_OVF_LEN, IA32_PERF_GLOBAL_OVF_CTRL_FIXED_CTR_CLR_OVF_SHIFT(ctr))
178
179#define IA32_PERF_GLOBAL_OVF_CTRL_UNCORE_CLR_OVF_SHIFT (61)
180#define IA32_PERF_GLOBAL_OVF_CTRL_UNCORE_CLR_OVF_LEN   (1)
181#define IA32_PERF_GLOBAL_OVF_CTRL_UNCORE_CLR_OVF_MASK \
182  IPM_MSR_MASK(IA32_PERF_GLOBAL_OVF_CTRL_UNCORE_CLR_OVF_LEN, IA32_PERF_GLOBAL_OVF_CTRL_UNCORE_CLR_OVF_SHIFT)
183
184#define IA32_PERF_GLOBAL_OVF_CTRL_DS_BUFFER_CLR_OVF_SHIFT (62)
185#define IA32_PERF_GLOBAL_OVF_CTRL_DS_BUFFER_CLR_OVF_LEN   (1)
186#define IA32_PERF_GLOBAL_OVF_CTRL_DS_BUFFER_CLR_OVF_MASK \
187  IPM_MSR_MASK(IA32_PERF_GLOBAL_OVF_CTRL_DS_BUFFER_CLR_OVF_LEN, IA32_PERF_GLOBAL_OVF_CTRL_DS_BUFFER_CLR_OVF_SHIFT)
188
189#define IA32_PERF_GLOBAL_OVF_CTRL_CLR_COND_CHGD_SHIFT (63)
190#define IA32_PERF_GLOBAL_OVF_CTRL_CLR_COND_CHGD_LEN   (1)
191#define IA32_PERF_GLOBAL_OVF_CTRL_CLR_COND_CHGD_MASK \
192  IPM_MSR_MASK(IA32_PERF_GLOBAL_OVF_CTRL_CLR_COND_CHGD_LEN, IA32_PERF_GLOBAL_OVF_CTRL_CLR_COND_CHGD_SHIFT)
193
194// Bits in the IA32_DEBUGCTL MSR.
195
196#define IA32_DEBUGCTL_LBR_SHIFT (0)
197#define IA32_DEBUGCTL_LBR_LEN   (1)
198#define IA32_DEBUGCTL_LBR_MASK \
199  IPM_MSR_MASK(IA32_DEBUGCTL_LBR_LEN, IA32_DEBUGCTL_LBR_SHIFT)
200
201#define IA32_DEBUGCTL_BTF_SHIFT (1)
202#define IA32_DEBUGCTL_BTF_LEN   (1)
203#define IA32_DEBUGCTL_BTF_MASK \
204  IPM_MSR_MASK(IA32_DEBUGCTL_BTF_LEN, IA32_DEBUGCTL_BTF_SHIFT)
205
206#define IA32_DEBUGCTL_TR_SHIFT (6)
207#define IA32_DEBUGCTL_TR_LEN   (1)
208#define IA32_DEBUGCTL_TR_MASK \
209  IPM_MSR_MASK(IA32_DEBUGCTL_TR_LEN, IA32_DEBUGCTL_TR_SHIFT)
210
211#define IA32_DEBUGCTL_BTS_SHIFT (7)
212#define IA32_DEBUGCTL_BTS_LEN   (1)
213#define IA32_DEBUGCTL_BTS_MASK \
214  IPM_MSR_MASK(IA32_DEBUGCTL_BTS_LEN, IA32_DEBUGCTL_BTS_SHIFT)
215
216#define IA32_DEBUGCTL_BTINT_SHIFT (8)
217#define IA32_DEBUGCTL_BTINT_LEN   (1)
218#define IA32_DEBUGCTL_BTINT_MASK \
219  IPM_MSR_MASK(IA32_DEBUGCTL_BTINT_LEN, IA32_DEBUGCTL_BTINT_SHIFT)
220
221#define IA32_DEBUGCTL_BTS_OFF_OS_SHIFT (9)
222#define IA32_DEBUGCTL_BTS_OFF_OS_LEN   (1)
223#define IA32_DEBUGCTL_BTS_OFF_OS_MASK \
224  IPM_MSR_MASK(IA32_DEBUGCTL_BTS_OFF_OS_LEN, IA32_DEBUGCTL_BTS_OFF_OS_SHIFT)
225
226#define IA32_DEBUGCTL_BTS_OFF_USR_SHIFT (10)
227#define IA32_DEBUGCTL_BTS_OFF_USR_LEN   (1)
228#define IA32_DEBUGCTL_BTS_OFF_USR_MASK \
229  IPM_MSR_MASK(IA32_DEBUGCTL_BTS_OFF_USR_LEN, IA32_DEBUGCTL_BTS_OFF_USR_SHIFT)
230
231#define IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_SHIFT (11)
232#define IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_LEN   (1)
233#define IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_MASK \
234  IPM_MSR_MASK(IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_LEN, IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_SHIFT)
235
236#define IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_SHIFT (12)
237#define IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_LEN   (1)
238#define IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_MASK \
239  IPM_MSR_MASK(IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_LEN, IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_SHIFT)
240
241#define IA32_DEBUGCTL_FREEZE_WHILE_SMM_SHIFT (14)
242#define IA32_DEBUGCTL_FREEZE_WHILE_SMM_LEN   (1)
243#define IA32_DEBUGCTL_FREEZE_WHILE_SMM_MASK \
244  IPM_MSR_MASK(IA32_DEBUGCTL_FREEZE_WHILE_SMM_LEN, IA32_DEBUGCTL_FREEZE_WHILE_SMM_SHIFT)
245
246#define IA32_DEBUGCTL_RTM_SHIFT (15)
247#define IA32_DEBUGCTL_RTM_LEN   (1)
248#define IA32_DEBUGCTL_RTM_MASK \
249  IPM_MSR_MASK(IA32_DEBUGCTL_RTM_LEN, IA32_DEBUGCTL_RTM_SHIFT)
250
251// maximum number of programmable counters
252// These are all "events" in our parlance, but on Intel these are all
253// counter events, so we use the more specific term "counter".
254#define IPM_MAX_PROGRAMMABLE_COUNTERS 8
255
256// maximum number of fixed-use counters
257// These are all "events" in our parlance, but on Intel these are all
258// counter events, so we use the more specific term "counter".
259#define IPM_MAX_FIXED_COUNTERS 3
260
261// misc events
262// Some of these events are counters, but not all of them are, so we use
263// the more generic term "events".
264// See, e.g., skylake-misc-events.inc.
265// This isn't the total number of events, it's just the maximum
266// we can collect at one time.
267#define IPM_MAX_MISC_EVENTS 16
268
269///////////////////////////////////////////////////////////////////////////////
270
271// These structs are used for communication between the device driver
272// and the kernel.
273
274// Properties of perf data collection on this system.
275typedef struct {
276    // The H/W Performance Monitor version.
277    uint32_t pm_version;
278    // The number of fixed events.
279    uint32_t num_fixed_events;
280    // The number of programmable events.
281    uint32_t num_programmable_events;
282    // The number of misc events.
283    uint32_t num_misc_events;
284    // For fixed events that are counters, the width in bits.
285    uint32_t fixed_counter_width;
286    // For programmable events that are counters, the width in bits.
287    uint32_t programmable_counter_width;
288    // The PERF_CAPABILITIES MSR.
289    uint64_t perf_capabilities;
290} zx_x86_ipm_properties_t;
291
292// This is for passing buffer specs to the kernel.
293typedef struct {
294    zx_handle_t vmo;
295} zx_x86_ipm_buffer_t;
296
297// IPM configuration.
298typedef struct {
299    // IA32_PERF_GLOBAL_CTRL
300    uint64_t global_ctrl;
301
302    // IA32_FIXED_CTR_CTRL
303    uint64_t fixed_ctrl;
304
305    // IA32_DEBUGCTL
306    uint64_t debug_ctrl;
307
308    // The id of the timebase counter to use.
309    // A "timebase counter" is used to trigger collection of data from other
310    // events. In other words it sets the sample rate for those events.
311    // If zero, then no timebase is in use: Each event must trigger its own
312    // data collection. Otherwise the value is the id of the timebase counter
313    // to use, which must appear in one of |programmable_ids| or |fixed_ids|.
314    cpuperf_event_id_t timebase_id;
315
316    // Ids of each event. These values are written to the trace buffer to
317    // identify the event.
318    // The used entries begin at index zero and are consecutive (no holes).
319    cpuperf_event_id_t fixed_ids[IPM_MAX_FIXED_COUNTERS];
320    cpuperf_event_id_t programmable_ids[IPM_MAX_PROGRAMMABLE_COUNTERS];
321    // Ids of other h/w events to collect data for.
322    cpuperf_event_id_t misc_ids[IPM_MAX_MISC_EVENTS];
323
324    // Initial value of each counter.
325    // The "misc" counters currently do not support initial values.
326    uint64_t fixed_initial_value[IPM_MAX_FIXED_COUNTERS];
327    uint64_t programmable_initial_value[IPM_MAX_PROGRAMMABLE_COUNTERS];
328
329    // Flags for each counter.
330    uint32_t fixed_flags[IPM_MAX_FIXED_COUNTERS];
331    uint32_t programmable_flags[IPM_MAX_PROGRAMMABLE_COUNTERS];
332    uint32_t misc_flags[IPM_MAX_MISC_EVENTS];
333// Both of IPM_CONFIG_FLAG_{PC,TIMEBASE} cannot be set.
334#define IPM_CONFIG_FLAG_MASK     0x3
335// Collect aspace+pc values.
336// Cannot be set with IPM_CONFIG_FLAG_TIMEBASE unless the counter is
337// |timebase_id|.
338#define IPM_CONFIG_FLAG_PC       (1u << 0)
339// Collect this event's value when |timebase_id| counter's data is collected.
340// While redundant, it is ok to set this for the |timebase_id| counter.
341#define IPM_CONFIG_FLAG_TIMEBASE (1u << 1)
342
343    // IA32_PERFEVTSEL_*
344    uint64_t programmable_events[IPM_MAX_PROGRAMMABLE_COUNTERS];
345} zx_x86_ipm_config_t;
346
347///////////////////////////////////////////////////////////////////////////////
348
349// Flags for the events in Intel *-pm-events.inc.
350// See for example Intel Volume 3, Table 19-3.
351// "Non-Architectural Performance Events of the Processor Core Supported by
352// Skylake Microarchitecture and Kaby Lake Microarchitecture"
353
354// Flags for non-architectural counters
355// CounterMask values
356#define IPM_REG_FLAG_CMSK_MASK 0xff
357#define IPM_REG_FLAG_CMSK1   1
358#define IPM_REG_FLAG_CMSK2   2
359#define IPM_REG_FLAG_CMSK4   4
360#define IPM_REG_FLAG_CMSK5   5
361#define IPM_REG_FLAG_CMSK6   6
362#define IPM_REG_FLAG_CMSK8   8
363#define IPM_REG_FLAG_CMSK10 10
364#define IPM_REG_FLAG_CMSK12 12
365#define IPM_REG_FLAG_CMSK16 16
366#define IPM_REG_FLAG_CMSK20 20
367// AnyThread = 1 required
368#define IPM_REG_FLAG_ANYT   0x100
369// Invert = 1 required
370#define IPM_REG_FLAG_INV    0x200
371// Edge = 1 required
372#define IPM_REG_FLAG_EDG    0x400
373// Also supports PEBS and DataLA
374#define IPM_REG_FLAG_PSDLA  0x800
375// Also supports PEBS
376#define IPM_REG_FLAG_PS     0x1000
377
378// Extra flags
379
380// Architectural event
381#define IPM_REG_FLAG_ARCH 0x10000
382
383// Fixed counters
384#define IPM_REG_FLAG_FIXED_MASK 0xf00000
385#define IPM_REG_FLAG_FIXED0     0x100000
386#define IPM_REG_FLAG_FIXED1     0x200000
387#define IPM_REG_FLAG_FIXED2     0x300000
388
389// Flags for misc registers
390
391// The register consists of a set of fields (not a counter).
392// Just print in hex.
393#define IPM_MISC_REG_FLAG_FIELDS (1u << 0)
394// The value uses a non-standard encoding.
395// Just print in hex.
396#define IPM_MISC_REG_FLAG_RAW (1u << 1)
397
398__END_CDECLS
399