2 * Copyright (c) 2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach/mach_types.h>
30 #include <machine/machine_routines.h>
31 #include <kern/processor.h>
32 #include <kern/kalloc.h>
33 #include <i386/cpuid.h>
34 #include <i386/proc_reg.h>
36 #include <i386/lapic.h>
37 #include <sys/errno.h>
38 #include <kperf/buffer.h>
42 #include <kperf/kperf.h>
43 #include <kperf/sample.h>
44 #include <kperf/context.h>
45 #include <kperf/action.h>
47 #include <chud/chud_xnu.h>
51 /* Fixed counter mask -- three counters, each with OS and USER */
52 #define IA32_FIXED_CTR_ENABLE_ALL_CTRS_ALL_RINGS (0x333)
53 #define IA32_FIXED_CTR_ENABLE_ALL_PMI (0x888)
55 #define IA32_PERFEVTSEL_PMI (1ull << 20)
56 #define IA32_PERFEVTSEL_EN (1ull << 22)
61 #define RDPMC_FIXED_COUNTER_SELECTOR (1ULL<<30)
63 /* track the last config we enabled */
64 static uint32_t kpc_running
= 0;
66 /* PMC / MSR accesses */
69 IA32_FIXED_CTR_CTRL(void)
71 return rdmsr64( MSR_IA32_PERF_FIXED_CTR_CTRL
);
75 IA32_FIXED_CTRx(uint32_t ctr
)
78 return rdpmc64(RDPMC_FIXED_COUNTER_SELECTOR
| ctr
);
79 #else /* !USE_RDPMC */
80 return rdmsr64(MSR_IA32_PERF_FIXED_CTR0
+ ctr
);
81 #endif /* !USE_RDPMC */
84 #ifdef FIXED_COUNTER_RELOAD
86 wrIA32_FIXED_CTRx(uint32_t ctr
, uint64_t value
)
88 return wrmsr64(MSR_IA32_PERF_FIXED_CTR0
+ ctr
, value
);
93 IA32_PMCx(uint32_t ctr
)
97 #else /* !USE_RDPMC */
98 return rdmsr64(MSR_IA32_PERFCTR0
+ ctr
);
99 #endif /* !USE_RDPMC */
103 wrIA32_PMCx(uint32_t ctr
, uint64_t value
)
105 return wrmsr64(MSR_IA32_PERFCTR0
+ ctr
, value
);
109 IA32_PERFEVTSELx(uint32_t ctr
)
111 return rdmsr64(MSR_IA32_EVNTSEL0
+ ctr
);
115 wrIA32_PERFEVTSELx(uint32_t ctr
, uint64_t value
)
117 wrmsr64(MSR_IA32_EVNTSEL0
+ ctr
, value
);
121 /* internal functions */
124 kpc_is_running_fixed(void)
126 return (kpc_running
& KPC_CLASS_FIXED_MASK
) == KPC_CLASS_FIXED_MASK
;
130 kpc_is_running_configurable(void)
132 return (kpc_running
& KPC_CLASS_CONFIGURABLE_MASK
) == KPC_CLASS_CONFIGURABLE_MASK
;
136 kpc_fixed_count(void)
138 i386_cpu_info_t
*info
= NULL
;
142 return info
->cpuid_arch_perf_leaf
.fixed_number
;
146 kpc_configurable_count(void)
148 i386_cpu_info_t
*info
= NULL
;
152 return info
->cpuid_arch_perf_leaf
.number
;
156 kpc_fixed_config_count(void)
158 return KPC_X86_64_FIXED_CONFIGS
;
162 kpc_configurable_config_count(void)
164 return kpc_configurable_count();
168 kpc_fixed_width(void)
170 i386_cpu_info_t
*info
= NULL
;
174 return info
->cpuid_arch_perf_leaf
.fixed_width
;
178 kpc_configurable_width(void)
180 i386_cpu_info_t
*info
= NULL
;
184 return info
->cpuid_arch_perf_leaf
.width
;
190 return (1ULL << kpc_fixed_width()) - 1;
194 kpc_configurable_max(void)
196 return (1ULL << kpc_configurable_width()) - 1;
199 #ifdef FIXED_COUNTER_SHADOW
201 kpc_reload_fixed(int ctr
)
203 uint64_t old
= IA32_FIXED_CTRx(ctr
);
204 wrIA32_FIXED_CTRx(ctr
, FIXED_RELOAD(ctr
));
210 kpc_reload_configurable(int ctr
)
212 uint64_t cfg
= IA32_PERFEVTSELx(ctr
);
214 /* counters must be disabled before they can be written to */
215 uint64_t old
= IA32_PMCx(ctr
);
216 wrIA32_PERFEVTSELx(ctr
, cfg
& ~IA32_PERFEVTSEL_EN
);
217 wrIA32_PMCx(ctr
, CONFIGURABLE_RELOAD(ctr
));
218 wrIA32_PERFEVTSELx(ctr
, cfg
);
222 void kpc_pmi_handler(x86_saved_state_t
*state
);
225 set_running_fixed(boolean_t on
)
227 uint64_t global
= 0, mask
= 0, fixed_ctrl
= 0;
232 /* these are per-thread in SMT */
233 fixed_ctrl
= IA32_FIXED_CTR_ENABLE_ALL_CTRS_ALL_RINGS
| IA32_FIXED_CTR_ENABLE_ALL_PMI
;
235 /* don't allow disabling fixed counters */
238 wrmsr64( MSR_IA32_PERF_FIXED_CTR_CTRL
, fixed_ctrl
);
240 enabled
= ml_set_interrupts_enabled(FALSE
);
242 /* rmw the global control */
243 global
= rdmsr64(MSR_IA32_PERF_GLOBAL_CTRL
);
244 for( i
= 0; i
< (int) kpc_fixed_count(); i
++ )
245 mask
|= (1ULL<<(32+i
));
252 wrmsr64(MSR_IA32_PERF_GLOBAL_CTRL
, global
);
254 ml_set_interrupts_enabled(enabled
);
258 set_running_configurable(boolean_t on
)
260 uint64_t global
= 0, mask
= 0;
264 int ncnt
= (int) kpc_get_counter_count(KPC_CLASS_CONFIGURABLE_MASK
);
266 enabled
= ml_set_interrupts_enabled(FALSE
);
268 /* rmw the global control */
269 global
= rdmsr64(MSR_IA32_PERF_GLOBAL_CTRL
);
270 for( i
= 0; i
< ncnt
; i
++ ) {
273 /* need to save and restore counter since it resets when reconfigured */
274 cfg
= IA32_PERFEVTSELx(i
);
276 wrIA32_PERFEVTSELx(i
, cfg
| IA32_PERFEVTSEL_PMI
| IA32_PERFEVTSEL_EN
);
277 wrIA32_PMCx(i
, save
);
285 wrmsr64(MSR_IA32_PERF_GLOBAL_CTRL
, global
);
287 ml_set_interrupts_enabled(enabled
);
291 kpc_set_running_mp_call( void *vstate
)
293 uint32_t new_state
= *(uint32_t*)vstate
;
295 set_running_fixed((new_state
& KPC_CLASS_FIXED_MASK
) != 0);
296 set_running_configurable((new_state
& KPC_CLASS_CONFIGURABLE_MASK
) != 0);
300 kpc_get_fixed_config(kpc_config_t
*configv
)
302 configv
[0] = IA32_FIXED_CTR_CTRL();
308 kpc_set_fixed_config(kpc_config_t
*configv
)
317 kpc_get_fixed_counters(uint64_t *counterv
)
319 int i
, n
= kpc_fixed_count();
321 #ifdef FIXED_COUNTER_SHADOW
324 /* snap the counters */
325 for( i
= 0; i
< n
; i
++ ) {
326 counterv
[i
] = FIXED_SHADOW(ctr
) +
327 (IA32_FIXED_CTRx(i
) - FIXED_RELOAD(ctr
));
330 /* Grab the overflow bits */
331 status
= rdmsr64(MSR_IA32_PERF_GLOBAL_STATUS
);
333 /* If the overflow bit is set for a counter, our previous read may or may not have been
334 * before the counter overflowed. Re-read any counter with it's overflow bit set so
335 * we know for sure that it has overflowed. The reason this matters is that the math
336 * is different for a counter that has overflowed. */
337 for( i
= 0; i
< n
; i
++ ) {
338 if ((1ull << (i
+ 32)) & status
)
339 counterv
[i
] = FIXED_SHADOW(ctr
) +
340 (kpc_fixed_max() - FIXED_RELOAD(ctr
)) + IA32_FIXED_CTRx(i
);
343 for( i
= 0; i
< n
; i
++ )
344 counterv
[i
] = IA32_FIXED_CTRx(i
);
351 kpc_get_configurable_config(kpc_config_t
*configv
)
353 int i
, n
= kpc_get_config_count(KPC_CLASS_CONFIGURABLE_MASK
);
355 for( i
= 0; i
< n
; i
++ )
356 configv
[i
] = IA32_PERFEVTSELx(i
);
362 kpc_set_configurable_config(kpc_config_t
*configv
)
364 int i
, n
= kpc_get_config_count(KPC_CLASS_CONFIGURABLE_MASK
);
367 for( i
= 0; i
< n
; i
++ ) {
368 /* need to save and restore counter since it resets when reconfigured */
370 wrIA32_PERFEVTSELx(i
, configv
[i
]);
371 wrIA32_PMCx(i
, save
);
378 kpc_get_configurable_counters(uint64_t *counterv
)
380 int i
, n
= kpc_get_config_count(KPC_CLASS_CONFIGURABLE_MASK
);
383 /* snap the counters */
384 for( i
= 0; i
< n
; i
++ ) {
385 counterv
[i
] = CONFIGURABLE_SHADOW(i
) +
386 (IA32_PMCx(i
) - CONFIGURABLE_RELOAD(i
));
389 /* Grab the overflow bits */
390 status
= rdmsr64(MSR_IA32_PERF_GLOBAL_STATUS
);
392 /* If the overflow bit is set for a counter, our previous read may or may not have been
393 * before the counter overflowed. Re-read any counter with it's overflow bit set so
394 * we know for sure that it has overflowed. The reason this matters is that the math
395 * is different for a counter that has overflowed. */
396 for( i
= 0; i
< n
; i
++ ) {
397 if ((1ull << i
) & status
) {
398 counterv
[i
] = CONFIGURABLE_SHADOW(i
) +
399 (kpc_configurable_max() - CONFIGURABLE_RELOAD(i
)) + IA32_PMCx(i
);
407 kpc_set_config_mp_call(void *vmp_config
)
409 struct kpc_config_remote
*mp_config
= vmp_config
;
410 uint32_t classes
= mp_config
->classes
;
411 kpc_config_t
*new_config
= mp_config
->configv
;
415 enabled
= ml_set_interrupts_enabled(FALSE
);
417 if( classes
& KPC_CLASS_FIXED_MASK
)
419 kpc_set_fixed_config(&new_config
[count
]);
420 count
+= kpc_get_config_count(KPC_CLASS_FIXED_MASK
);
423 if( classes
& KPC_CLASS_CONFIGURABLE_MASK
)
425 kpc_set_configurable_config(&new_config
[count
]);
426 count
+= kpc_get_config_count(KPC_CLASS_CONFIGURABLE_MASK
);
429 ml_set_interrupts_enabled(enabled
);
433 kpc_set_reload_mp_call(void *vmp_config
)
435 struct kpc_config_remote
*mp_config
= vmp_config
;
436 uint64_t max
= kpc_configurable_max();
437 uint32_t i
, count
= kpc_get_counter_count(KPC_CLASS_CONFIGURABLE_MASK
);
438 uint64_t *new_period
;
442 classes
= mp_config
->classes
;
443 new_period
= mp_config
->configv
;
445 if (classes
& KPC_CLASS_CONFIGURABLE_MASK
) {
446 enabled
= ml_set_interrupts_enabled(FALSE
);
448 kpc_get_configurable_counters(&CONFIGURABLE_SHADOW(0));
450 for (i
= 0; i
< count
; i
++) {
451 if (new_period
[i
] == 0)
452 new_period
[i
] = kpc_configurable_max();
454 CONFIGURABLE_RELOAD(i
) = max
- new_period
[i
];
456 kpc_reload_configurable(i
);
458 /* clear overflow bit just in case */
459 wrmsr64(MSR_IA32_PERF_GLOBAL_OVF_CTRL
, 1ull << i
);
462 ml_set_interrupts_enabled(enabled
);
467 kpc_set_period_arch( struct kpc_config_remote
*mp_config
)
469 mp_cpus_call( CPUMASK_ALL
, ASYNC
, kpc_set_reload_mp_call
, mp_config
);
475 /* interface functions */
478 kpc_get_classes(void)
480 return KPC_CLASS_FIXED_MASK
| KPC_CLASS_CONFIGURABLE_MASK
;
484 kpc_set_running(uint32_t new_state
)
486 lapic_set_pmi_func((i386_intr_func_t
)kpc_pmi_handler
);
488 /* dispatch to all CPUs */
489 mp_cpus_call( CPUMASK_ALL
, ASYNC
, kpc_set_running_mp_call
, &new_state
);
491 kpc_running
= new_state
;
497 kpc_set_config_arch(struct kpc_config_remote
*mp_config
)
499 mp_cpus_call( CPUMASK_ALL
, ASYNC
, kpc_set_config_mp_call
, mp_config
);
505 void kpc_pmi_handler(__unused x86_saved_state_t
*state
)
507 uint64_t status
, extra
;
511 enabled
= ml_set_interrupts_enabled(FALSE
);
513 status
= rdmsr64(MSR_IA32_PERF_GLOBAL_STATUS
);
515 #ifdef FIXED_COUNTER_SHADOW
516 for (ctr
= 0; ctr
< kpc_fixed_count(); ctr
++) {
517 if ((1ULL << (ctr
+ 32)) & status
) {
518 extra
= kpc_reload_fixed(ctr
);
521 += kpc_fixed_max() - FIXED_RELOAD(ctr
) + extra
;
523 BUF_INFO(PERF_KPC_FCOUNTER
, ctr
, FIXED_SHADOW(ctr
), extra
, FIXED_ACTIONID(ctr
));
525 if (FIXED_ACTIONID(ctr
))
526 kpc_sample_kperf(FIXED_ACTIONID(ctr
));
531 for (ctr
= 0; ctr
< kpc_configurable_count(); ctr
++) {
532 if ((1ULL << ctr
) & status
) {
533 extra
= kpc_reload_configurable(ctr
);
535 CONFIGURABLE_SHADOW(ctr
)
536 += kpc_configurable_max() - CONFIGURABLE_RELOAD(ctr
) + extra
;
538 /* kperf can grab the PMCs when it samples so we need to make sure the overflow
539 * bits are in the correct state before the call to kperf_sample */
540 wrmsr64(MSR_IA32_PERF_GLOBAL_OVF_CTRL
, 1ull << ctr
);
542 BUF_INFO(PERF_KPC_COUNTER
, ctr
, CONFIGURABLE_SHADOW(ctr
), extra
, CONFIGURABLE_ACTIONID(ctr
));
544 if (CONFIGURABLE_ACTIONID(ctr
))
545 kpc_sample_kperf(CONFIGURABLE_ACTIONID(ctr
));
549 ml_set_interrupts_enabled(enabled
);