]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/perfmon.h
xnu-792.17.14.tar.gz
[apple/xnu.git] / osfmk / i386 / perfmon.h
CommitLineData
91447636
A
1/*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
91447636 5 *
8f6c56a5
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.
14 *
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
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)
67typedef struct {
68 uint64_t counter : 40;
69 uint64_t reserved : 24;
70} pmc_counter_t;
71#define PMC_COUNTER_ZERO { 0, 0 }
72
73
74/*
75 * There are 2 basic flavors of PMCsL: P6 and P4/Xeon:
76 */
77typedef enum {
78 pmc_none,
79 pmc_P6,
80 pmc_P4_Xeon,
81 pmc_unknown
82} pmc_machine_t;
83
84/*
85 * P6 MSRs...
86 */
87#define MSR_P6_COUNTER_ADDR(n) (0x0c1 + (n))
88#define MSR_P6_PES_ADDR(n) (0x186 + (n))
89
90typedef struct {
91 uint64_t event_select : 8;
92 uint64_t umask : 8;
93 uint64_t usr : 1;
94 uint64_t os : 1;
95 uint64_t e : 1;
96 uint64_t pc : 1;
97 uint64_t apic_int : 1;
98 uint64_t reserved1 : 1;
99 uint64_t en : 1;
100 uint64_t inv : 1;
101 uint64_t cmask : 8;
102} pmc_evtsel_t;
103#define PMC_EVTSEL_ZERO ((pmc_evtsel_t){ 0,0,0,0,0,0,0,0,0,0,0 })
104
105#define MSR_P6_PERFCTR0 0
106#define MSR_P6_PERFCTR1 1
107
108/*
109 * P4/Xeon MSRs...
110 */
111#define MSR_COUNTER_ADDR(n) (0x300 + (n))
112#define MSR_CCCR_ADDR(n) (0x360 + (n))
113
114typedef enum {
115 MSR_BPU_COUNTER0 = 0,
116 MSR_BPU_COUNTER1 = 1,
117 #define MSR_BSU_ESCR0 7
118 #define MSR_FSB_ESCR0 6
119 #define MSR_MOB_ESCR0 2
120 #define MSR_PMH_ESCR0 4
121 #define MSR_BPU_ESCR0 0
122 #define MSR_IS_ESCR0 1
123 #define MSR_ITLB_ESCR0 3
124 #define MSR_IX_ESCR0 5
125 MSR_BPU_COUNTER2 = 2,
126 MSR_BPU_COUNTER3 = 3,
127 #define MSR_BSU_ESCR1 7
128 #define MSR_FSB_ESCR1 6
129 #define MSR_MOB_ESCR1 2
130 #define MSR_PMH_ESCR1 4
131 #define MSR_BPU_ESCR1 0
132 #define MSR_IS_ESCR1 1
133 #define MSR_ITLB_ESCR1 3
134 #define MSR_IX_ESCR1 5
135 MSR_MS_COUNTER0 = 4,
136 MSR_MS_COUNTER1 = 5,
137 #define MSR_MS_ESCR0 0
138 #define MSR_TBPU_ESCR0 2
139 #define MSR_TC_ESCR0 1
140 MSR_MS_COUNTER2 = 6,
141 MSR_MS_COUNTER3 = 7,
142 #define MSR_MS_ESCR1 0
143 #define MSR_TBPU_ESCR1 2
144 #define MSR_TC_ESCR1 1
145 MSR_FLAME_COUNTER0 = 8,
146 MSR_FLAME_COUNTER1 = 9,
147 #define MSR_FIRM_ESCR0 1
148 #define MSR_FLAME_ESCR0 0
149 #define MSR_DAC_ESCR0 5
150 #define MSR_SAT_ESCR0 2
151 #define MSR_U2L_ESCR0 3
152 MSR_FLAME_COUNTER2 = 10,
153 MSR_FLAME_COUNTER3 = 11,
154 #define MSR_FIRM_ESCR1 1
155 #define MSR_FLAME_ESCR1 0
156 #define MSR_DAC_ESCR1 5
157 #define MSR_SAT_ESCR1 2
158 #define MSR_U2L_ESCR1 3
159 MSR_IQ_COUNTER0 = 12,
160 MSR_IQ_COUNTER1 = 13,
161 MSR_IQ_COUNTER4 = 16,
162 #define MSR_CRU_ESCR0 4
163 #define MSR_CRU_ESCR2 5
164 #define MSR_CRU_ESCR4 6
165 #define MSR_IQ_ESCR0 0
166 #define MSR_RAT_ESCR0 2
167 #define MSR_SSU_ESCR0 3
168 #define MSR_AFL_ESCR0 1
169 MSR_IQ_COUNTER2 = 14,
170 MSR_IQ_COUNTER3 = 15,
171 MSR_IQ_COUNTER5 = 17,
172 #define MSR_CRU_ESCR1 4
173 #define MSR_CRU_ESCR3 5
174 #define MSR_CRU_ESCR5 6
175 #define MSR_IQ_ESCR1 0
176 #define MSR_RAT_ESCR1 2
177 #define MSR_AFL_ESCR1 1
178} pmc_id_t;
179
180typedef int pmc_escr_id_t;
181#define PMC_ESID_MAX 7
182
183/*
184 * ESCR MSR layout:
185 */
186#define PMC_ECSR_NOHTT_RESERVED field(0,1)
187#define PMC_ECSR_T0_USR bit(0)
188#define PMC_ECSR_T0_OS bit(1)
189#define PMC_ECSR_T1_USR bit(2)
190#define PMC_ECSR_T1_OS bit(3)
191#define PMC_ECSR_USR bit(2)
192#define PMC_ECSR_OS bit(3)
193#define PMC_ECSR_TAG_ENABLE bit(4)
194#define PMC_ECSR_TAG_VALUE field(5,8)
195#define PMC_ECSR_EVENT_MASK field(9,24)
196#define PMC_ECSR_EVENT_SELECT field(25,30)
197#define PMC_ECSR_RESERVED2 field(30,64)
198typedef struct {
199 uint64_t reserved1 : 2;
200 uint64_t usr : 1;
201 uint64_t os : 1;
202 uint64_t tag_enable : 1;
203 uint64_t tag_value : 4;
204 uint64_t event_mask : 16;
205 uint64_t event_select : 6;
206 uint64_t reserved2 : 33;
207} pmc_escr_nohtt_t;
208typedef struct {
209 uint64_t t0_usr : 1;
210 uint64_t t0_os : 1;
211 uint64_t t1_usr : 1;
212 uint64_t t1_os : 1;
213 uint64_t tag_enable : 1;
214 uint64_t tag_value : 4;
215 uint64_t event_mask : 16;
216 uint64_t event_select : 6;
217 uint64_t reserved2 : 33;
218} pmc_escr_htt_t;
219typedef union {
220 pmc_escr_nohtt_t u_nohtt;
221 pmc_escr_htt_t u_htt;
222 uint64_t u_u64;
223} pmc_escr_t;
224#define PMC_ESCR_ZERO { .u_u64 = 0ULL }
225
226/*
227 * CCCR MSR layout:
228 */
229#define PMC_CCCR_RESERVED1 field(1,11)
230#define PMC_CCCR_ENABLE bit(12)
231#define PMC_CCCR_ECSR_SELECT field(13,15)
232#define PMC_CCCR_RESERVED2 field(16,17)
233#define PMC_CCCR_HTT_ACTIVE field(16,17)
234#define PMC_CCCR_COMPARE bit(18)
235#define PMC_CCCR_COMPLEMENT bit(19)
236#define PMC_CCCR_THRESHOLD field(20,23)
237#define PMC_CCCR_EDGE bit(24)
238#define PMC_CCCR_FORCE_OVF bit(25)
239#define PMC_CCCR_OVF_PMI bit(26)
240#define PMC_CCCR_NOHTT_RESERVED2 field(27,29)
241#define PMC_CCCR_OVF_PMI_T0 bit(26)
242#define PMC_CCCR_OVF_PMI_T1 bit(27)
243#define PMC_CCCR_HTT_RESERVED2 field(28,29)
244#define PMC_CCCR_CASCADE bit(30)
245#define PMC_CCCR_OVF bit(31)
246typedef struct {
247 uint64_t reserved1 : 12;
248 uint64_t enable : 1;
249 uint64_t escr_select : 3;
250 uint64_t reserved2 : 2;
251 uint64_t compare : 1;
252 uint64_t complement : 1;
253 uint64_t threshold : 4;
254 uint64_t edge : 1;
255 uint64_t force_ovf : 1;
256 uint64_t ovf_pmi : 1;
257 uint64_t reserved3 : 3;
258 uint64_t cascade : 1;
259 uint64_t ovf : 1;
260 uint64_t reserved4 : 32;
261} pmc_cccr_nohtt_t;
262typedef struct {
263 uint64_t reserved1 : 12;
264 uint64_t enable : 1;
265 uint64_t escr_select : 3;
266 uint64_t active_thread : 2;
267 uint64_t compare : 1;
268 uint64_t complement : 1;
269 uint64_t threshold : 4;
270 uint64_t edge : 1;
271 uint64_t force_OVF : 1;
272 uint64_t ovf_pmi_t0 : 1;
273 uint64_t ovf_pmi_t1 : 1;
274 uint64_t reserved3 : 2;
275 uint64_t cascade : 1;
276 uint64_t ovf : 1;
277 uint64_t reserved4 : 32;
278} pmc_cccr_htt_t;
279typedef union {
280 pmc_cccr_nohtt_t u_nohtt;
281 pmc_cccr_htt_t u_htt;
282 uint64_t u_u64;
283} pmc_cccr_t;
284#define PMC_CCCR_ZERO { .u_u64 = 0ULL }
285
286typedef void (pmc_ovf_func_t)(pmc_id_t id, void *state);
287
288/*
289 * In-kernel PMC access primitives:
290 */
291/* Generic: */
8f6c56a5 292extern int pmc_init(void);
91447636
A
293extern int pmc_machine_type(pmc_machine_t *type);
294extern boolean_t pmc_is_reserved(pmc_id_t id);
295extern int pmc_reserve(pmc_id_t id);
296extern int pmc_free(pmc_id_t id);
297extern int pmc_counter_read(pmc_id_t id, pmc_counter_t *val);
298extern int pmc_counter_write(pmc_id_t id, pmc_counter_t *val);
299
300/* P6-specific: */
301extern int pmc_evtsel_read(pmc_id_t id, pmc_evtsel_t *evtsel);
302extern int pmc_evtsel_write(pmc_id_t id, pmc_evtsel_t *evtsel);
303
304/* P4/Xeon-specific: */
305extern int pmc_cccr_read(pmc_id_t id, pmc_cccr_t *cccr);
306extern int pmc_cccr_write(pmc_id_t id, pmc_cccr_t *cccr);
307extern int pmc_escr_read(pmc_id_t id, pmc_escr_id_t esid, pmc_escr_t *escr);
308extern int pmc_escr_write(pmc_id_t id, pmc_escr_id_t esid, pmc_escr_t *escr);
309extern int pmc_set_ovf_func(pmc_id_t id, pmc_ovf_func_t *func);
310
311#endif /* _I386_PERFMON_H_ */