]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/perfmon.h
xnu-1228.9.59.tar.gz
[apple/xnu.git] / osfmk / i386 / perfmon.h
CommitLineData
91447636
A
1/*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
91447636 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
91447636
A
27 */
28#ifndef _I386_PERFMON_H_
29#define _I386_PERFMON_H_
30
31#include <i386/proc_reg.h>
32
33/*
34 * Handy macros for bit/bitfield definition and manipulations:
35 */
36#define bit(n) (1ULL << (n))
37#define field(n,m) ((bit((m)+1)-1) & ~(bit(n)-1))
38#define field_nbit(fld) (ffs(fld)-1)
39#define field_select(fld,x) ((x) & (fld))
40#define field_clear(fld,x) ((x) & ~(fld))
41#define field_unshift(fld,x) ((x) >> field_nbit(fld))
42#define field_shift(fld,x) ((x) << field_nbit(fld))
43#define field_get(fld,x) (field_unshift(fld,field_select(fld,x)))
44#define field_set(fld,x,val) (field_clear(fld,x) | field_shift(fld,val))
45
46#define PERFMON_AVAILABLE bit(7)
47#define BTS_UNAVAILABLE bit(11)
48
49static inline boolean_t
50pmc_is_available(void)
51{
52 uint32_t lo;
53 uint32_t hi;
54 int ret;
55
56 ret = rdmsr_carefully(MSR_IA32_MISC_ENABLE, &lo, &hi);
57
58 return (ret == 0) && ((lo & PERFMON_AVAILABLE) != 0);
59}
60
61/*
62 * Counter layout:
63 */
64#define PMC_COUNTER_COUNTER field(0,39)
65#define PMC_COUNTER_RESERVED field(40,64)
66#define PMC_COUNTER_MAX ((uint64_t) PMC_COUNTER_COUNTER)
2d21ac55
A
67typedef union {
68 struct {
91447636
A
69 uint64_t counter : 40;
70 uint64_t reserved : 24;
2d21ac55
A
71 } fld;
72 uint64_t u64;
91447636 73} pmc_counter_t;
2d21ac55 74#define PMC_COUNTER_ZERO { .u64 = 0 }
91447636
A
75
76
77/*
2d21ac55 78 * There are 2 basic flavors of PMCs: P6 (or Core) and P4/Xeon:
91447636
A
79 */
80typedef enum {
2d21ac55 81 pmc_none = 0,
91447636
A
82 pmc_P6,
83 pmc_P4_Xeon,
2d21ac55 84 pmc_Core,
91447636
A
85 pmc_unknown
86} pmc_machine_t;
87
2d21ac55
A
88#define MSR_PERF_FIXED_CTR(n) (0x309 + (n))
89#define MSR_PERF_INST_RETIRED MSR_PERF_FIXED_CTR(0)
90#define MSR_PERF_CPU_CLK_UNHALTED_CORE MSR_PERF_FIXED_CTR(1)
91#define MSR_PERF_CPU_CLK_UNHALTED_REF MSR_PERF_FIXED_CTR(2)
92
93#define MSR_PERF_FIXED_CTR_CTRL (0x38d)
94typedef union {
95 struct {
96 uint64_t FIXED_CTR0_enable :2;
97 uint64_t reserved0 :1;
98 uint64_t FIXED_CTR0_pmi :1;
99 uint64_t FIXED_CTR1_enable :2;
100 uint64_t reserved1 :1;
101 uint64_t FIXED_CTR1_pmi :1;
102 uint64_t FIXED_CTR2_enable :2;
103 uint64_t reserved2 :1;
104 uint64_t FIXED_CTR2_pmi :1;
105 } fld;
106 uint64_t u64;
107} pmc_fixed_ctr_ctrl_t;
108
109#define MSR_PERF_GLOBAL_STATUS (0x38e)
110typedef union {
111 struct {
112 uint64_t PMC0_overflow : 1;
113 uint64_t PMC1_overflow : 1;
114 uint64_t reserved1 : 30;
115 uint64_t FIXED_CTR0_overflow : 1;
116 uint64_t FIXED_CTR1_overflow : 1;
117 uint64_t FIXED_CTR2_overflow : 1;
118 uint64_t reserved2 : 27;
119 uint64_t ovf_buffer : 1;
120 uint64_t cond_changed : 1;
121 } fld;
122 uint64_t u64;
123} pmc_global_status_t;
124
125#define MSR_PERF_GLOBAL_CTRL (0x38f)
126typedef union {
127 struct {
128 uint64_t PMC0_enable : 1;
129 uint64_t PMC1_enable : 1;
130 uint64_t reserved1 : 30;
131 uint64_t FIXED_CTR0_enable : 1;
132 uint64_t FIXED_CTR1_enable : 1;
133 uint64_t FIXED_CTR2_enable : 1;
134 } fld;
135 uint64_t u64;
136} pmc_global_ctrl_t;
137
138#define MSR_PERF_GLOBAL_OVF_CTRL (0x390)
139typedef union {
140 struct {
141 uint64_t PMC0_clr_overflow : 1;
142 uint64_t PMC1_clr_overflow : 1;
143 uint64_t reserved1 : 30;
144 uint64_t FIXED_CTR0_clr_overflow : 1;
145 uint64_t FIXED_CTR1_clr_overflow : 1;
146 uint64_t FIXED_CTR2_clr_overflow : 1;
147 uint64_t reserved2 : 27;
148 uint64_t clr_ovf_buffer : 1;
149 uint64_t clr_cond_changed : 1;
150 } fld;
151 uint64_t u64;
152} pmc_global_ovf_ctrl;
153
91447636
A
154/*
155 * P6 MSRs...
156 */
157#define MSR_P6_COUNTER_ADDR(n) (0x0c1 + (n))
158#define MSR_P6_PES_ADDR(n) (0x186 + (n))
2d21ac55
A
159#define MSR_IA32_PMC(n) (0x0c1 + (n))
160#define MSR_IA32_PERFEVTSEL(n) (0x186 + (n))
91447636 161
2d21ac55
A
162typedef union {
163 struct {
91447636
A
164 uint64_t event_select : 8;
165 uint64_t umask : 8;
166 uint64_t usr : 1;
167 uint64_t os : 1;
168 uint64_t e : 1;
169 uint64_t pc : 1;
170 uint64_t apic_int : 1;
171 uint64_t reserved1 : 1;
172 uint64_t en : 1;
173 uint64_t inv : 1;
174 uint64_t cmask : 8;
2d21ac55
A
175 } fld;
176 uint64_t u64;
91447636 177} pmc_evtsel_t;
2d21ac55
A
178#define PMC_EVTSEL_ZERO { .u64 = 0ULL }
179
180
181/*
182 * Non-architectural event selectors. See Vol 3b, section 18.13:
183 */
184#define PMC_EVTSEL_ALLCORES (bit(15)|bit(14))
185#define PMC_EVTSEL_THISCORE (bit(14))
186#define PMC_EVTSEL_ALLAGENTS (bit(14))
187#define PMC_EVTSEL_THISAGENT (0ULL) }
188#define PMC_EVTSEL_PREFETCH_ALL (bit(13)|bit(12))
189#define PMC_EVTSEL_PREFETCH_HW (bit(12))
190#define PMC_EVTSEL_PREFETCH_NOHW (0ULL)
191#define PMC_EVTSEL_MESI_MOD (bit(11))
192#define PMC_EVTSEL_MESI_EXCL (bit(10))
193#define PMC_EVTSEL_MESI_SHRD (bit(9))
194#define PMC_EVTSEL_MESI_INVAL (bit(8))
195
196#define PMC_EVTSEL_SNOOP_HITM (bit(11))
197#define PMC_EVTSEL_SNOOP_HIT (bit(9))
198#define PMC_EVTSEL_SNOOP_CLEAN (bit(8))
199#define PMC_EVTSEL_SNOOP_CMP2I (bit(9))
200#define PMC_EVTSEL_SNOOP_CMP2S (bit(8))
201
202#define PMC_CORE_ITLB_MISS_RETIRED \
203 { .fld.event_select = 0xc9, .fld.umask = 0 }
204#define PMC_CORE_MEM_LOAD_RETIRED_L1D_MISS \
205 { .fld.event_select = 0xcb, .fld.umask = 1 }
206#define PMC_CORE_MEM_LOAD_RETIRED_L1D_LINE_MISS \
207 { .fld.event_select = 0xcb, .fld.umask = 2 }
208#define PMC_CORE_MEM_LOAD_RETIRED_L2_MISS \
209 { .fld.event_select = 0xcb, .fld.umask = 4 }
210#define PMC_CORE_MEM_LOAD_RETIRED_L2_LINE_MISS \
211 { .fld.event_select = 0xcb, .fld.umask = 8 }
212#define PMC_CORE_MEM_LOAD_RETIRED_DTLB_MISS \
213 { .fld.event_select = 0xcb, .fld.umask = 0x10 }
91447636
A
214
215#define MSR_P6_PERFCTR0 0
216#define MSR_P6_PERFCTR1 1
217
218/*
219 * P4/Xeon MSRs...
220 */
221#define MSR_COUNTER_ADDR(n) (0x300 + (n))
222#define MSR_CCCR_ADDR(n) (0x360 + (n))
223
224typedef enum {
225 MSR_BPU_COUNTER0 = 0,
226 MSR_BPU_COUNTER1 = 1,
227 #define MSR_BSU_ESCR0 7
228 #define MSR_FSB_ESCR0 6
229 #define MSR_MOB_ESCR0 2
230 #define MSR_PMH_ESCR0 4
231 #define MSR_BPU_ESCR0 0
232 #define MSR_IS_ESCR0 1
233 #define MSR_ITLB_ESCR0 3
234 #define MSR_IX_ESCR0 5
235 MSR_BPU_COUNTER2 = 2,
236 MSR_BPU_COUNTER3 = 3,
237 #define MSR_BSU_ESCR1 7
238 #define MSR_FSB_ESCR1 6
239 #define MSR_MOB_ESCR1 2
240 #define MSR_PMH_ESCR1 4
241 #define MSR_BPU_ESCR1 0
242 #define MSR_IS_ESCR1 1
243 #define MSR_ITLB_ESCR1 3
244 #define MSR_IX_ESCR1 5
245 MSR_MS_COUNTER0 = 4,
246 MSR_MS_COUNTER1 = 5,
247 #define MSR_MS_ESCR0 0
248 #define MSR_TBPU_ESCR0 2
249 #define MSR_TC_ESCR0 1
250 MSR_MS_COUNTER2 = 6,
251 MSR_MS_COUNTER3 = 7,
252 #define MSR_MS_ESCR1 0
253 #define MSR_TBPU_ESCR1 2
254 #define MSR_TC_ESCR1 1
255 MSR_FLAME_COUNTER0 = 8,
256 MSR_FLAME_COUNTER1 = 9,
257 #define MSR_FIRM_ESCR0 1
258 #define MSR_FLAME_ESCR0 0
259 #define MSR_DAC_ESCR0 5
260 #define MSR_SAT_ESCR0 2
261 #define MSR_U2L_ESCR0 3
262 MSR_FLAME_COUNTER2 = 10,
263 MSR_FLAME_COUNTER3 = 11,
264 #define MSR_FIRM_ESCR1 1
265 #define MSR_FLAME_ESCR1 0
266 #define MSR_DAC_ESCR1 5
267 #define MSR_SAT_ESCR1 2
268 #define MSR_U2L_ESCR1 3
269 MSR_IQ_COUNTER0 = 12,
270 MSR_IQ_COUNTER1 = 13,
271 MSR_IQ_COUNTER4 = 16,
272 #define MSR_CRU_ESCR0 4
273 #define MSR_CRU_ESCR2 5
274 #define MSR_CRU_ESCR4 6
275 #define MSR_IQ_ESCR0 0
276 #define MSR_RAT_ESCR0 2
277 #define MSR_SSU_ESCR0 3
278 #define MSR_AFL_ESCR0 1
279 MSR_IQ_COUNTER2 = 14,
280 MSR_IQ_COUNTER3 = 15,
281 MSR_IQ_COUNTER5 = 17,
282 #define MSR_CRU_ESCR1 4
283 #define MSR_CRU_ESCR3 5
284 #define MSR_CRU_ESCR5 6
285 #define MSR_IQ_ESCR1 0
286 #define MSR_RAT_ESCR1 2
287 #define MSR_AFL_ESCR1 1
288} pmc_id_t;
289
290typedef int pmc_escr_id_t;
291#define PMC_ESID_MAX 7
292
293/*
294 * ESCR MSR layout:
295 */
296#define PMC_ECSR_NOHTT_RESERVED field(0,1)
297#define PMC_ECSR_T0_USR bit(0)
298#define PMC_ECSR_T0_OS bit(1)
299#define PMC_ECSR_T1_USR bit(2)
300#define PMC_ECSR_T1_OS bit(3)
301#define PMC_ECSR_USR bit(2)
302#define PMC_ECSR_OS bit(3)
303#define PMC_ECSR_TAG_ENABLE bit(4)
304#define PMC_ECSR_TAG_VALUE field(5,8)
305#define PMC_ECSR_EVENT_MASK field(9,24)
306#define PMC_ECSR_EVENT_SELECT field(25,30)
307#define PMC_ECSR_RESERVED2 field(30,64)
308typedef struct {
309 uint64_t reserved1 : 2;
310 uint64_t usr : 1;
311 uint64_t os : 1;
312 uint64_t tag_enable : 1;
313 uint64_t tag_value : 4;
314 uint64_t event_mask : 16;
315 uint64_t event_select : 6;
316 uint64_t reserved2 : 33;
317} pmc_escr_nohtt_t;
318typedef struct {
319 uint64_t t0_usr : 1;
320 uint64_t t0_os : 1;
321 uint64_t t1_usr : 1;
322 uint64_t t1_os : 1;
323 uint64_t tag_enable : 1;
324 uint64_t tag_value : 4;
325 uint64_t event_mask : 16;
326 uint64_t event_select : 6;
327 uint64_t reserved2 : 33;
328} pmc_escr_htt_t;
329typedef union {
330 pmc_escr_nohtt_t u_nohtt;
331 pmc_escr_htt_t u_htt;
332 uint64_t u_u64;
333} pmc_escr_t;
334#define PMC_ESCR_ZERO { .u_u64 = 0ULL }
335
336/*
337 * CCCR MSR layout:
338 */
339#define PMC_CCCR_RESERVED1 field(1,11)
340#define PMC_CCCR_ENABLE bit(12)
341#define PMC_CCCR_ECSR_SELECT field(13,15)
342#define PMC_CCCR_RESERVED2 field(16,17)
343#define PMC_CCCR_HTT_ACTIVE field(16,17)
344#define PMC_CCCR_COMPARE bit(18)
345#define PMC_CCCR_COMPLEMENT bit(19)
346#define PMC_CCCR_THRESHOLD field(20,23)
347#define PMC_CCCR_EDGE bit(24)
348#define PMC_CCCR_FORCE_OVF bit(25)
349#define PMC_CCCR_OVF_PMI bit(26)
350#define PMC_CCCR_NOHTT_RESERVED2 field(27,29)
351#define PMC_CCCR_OVF_PMI_T0 bit(26)
352#define PMC_CCCR_OVF_PMI_T1 bit(27)
353#define PMC_CCCR_HTT_RESERVED2 field(28,29)
354#define PMC_CCCR_CASCADE bit(30)
355#define PMC_CCCR_OVF bit(31)
356typedef struct {
357 uint64_t reserved1 : 12;
358 uint64_t enable : 1;
359 uint64_t escr_select : 3;
360 uint64_t reserved2 : 2;
361 uint64_t compare : 1;
362 uint64_t complement : 1;
363 uint64_t threshold : 4;
364 uint64_t edge : 1;
365 uint64_t force_ovf : 1;
366 uint64_t ovf_pmi : 1;
367 uint64_t reserved3 : 3;
368 uint64_t cascade : 1;
369 uint64_t ovf : 1;
370 uint64_t reserved4 : 32;
371} pmc_cccr_nohtt_t;
372typedef struct {
373 uint64_t reserved1 : 12;
374 uint64_t enable : 1;
375 uint64_t escr_select : 3;
376 uint64_t active_thread : 2;
377 uint64_t compare : 1;
378 uint64_t complement : 1;
379 uint64_t threshold : 4;
380 uint64_t edge : 1;
381 uint64_t force_OVF : 1;
382 uint64_t ovf_pmi_t0 : 1;
383 uint64_t ovf_pmi_t1 : 1;
384 uint64_t reserved3 : 2;
385 uint64_t cascade : 1;
386 uint64_t ovf : 1;
387 uint64_t reserved4 : 32;
388} pmc_cccr_htt_t;
389typedef union {
390 pmc_cccr_nohtt_t u_nohtt;
391 pmc_cccr_htt_t u_htt;
392 uint64_t u_u64;
393} pmc_cccr_t;
394#define PMC_CCCR_ZERO { .u_u64 = 0ULL }
395
396typedef void (pmc_ovf_func_t)(pmc_id_t id, void *state);
397
398/*
399 * In-kernel PMC access primitives:
400 */
401/* Generic: */
0c530ab8 402extern void *pmc_alloc(void);
91447636
A
403extern int pmc_machine_type(pmc_machine_t *type);
404extern boolean_t pmc_is_reserved(pmc_id_t id);
405extern int pmc_reserve(pmc_id_t id);
406extern int pmc_free(pmc_id_t id);
407extern int pmc_counter_read(pmc_id_t id, pmc_counter_t *val);
408extern int pmc_counter_write(pmc_id_t id, pmc_counter_t *val);
409
410/* P6-specific: */
411extern int pmc_evtsel_read(pmc_id_t id, pmc_evtsel_t *evtsel);
412extern int pmc_evtsel_write(pmc_id_t id, pmc_evtsel_t *evtsel);
413
414/* P4/Xeon-specific: */
415extern int pmc_cccr_read(pmc_id_t id, pmc_cccr_t *cccr);
416extern int pmc_cccr_write(pmc_id_t id, pmc_cccr_t *cccr);
417extern int pmc_escr_read(pmc_id_t id, pmc_escr_id_t esid, pmc_escr_t *escr);
418extern int pmc_escr_write(pmc_id_t id, pmc_escr_id_t esid, pmc_escr_t *escr);
419extern int pmc_set_ovf_func(pmc_id_t id, pmc_ovf_func_t *func);
420
0c530ab8
A
421extern int pmc_acquire(task_t);
422extern int pmc_release(task_t);
423
91447636 424#endif /* _I386_PERFMON_H_ */