]> git.saurik.com Git - apple/xnu.git/blame - osfmk/arm64/kpc.c
xnu-4570.51.1.tar.gz
[apple/xnu.git] / osfmk / arm64 / kpc.c
CommitLineData
5ba3f43e
A
1/*
2 * Copyright (c) 2012-2016 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <arm/cpu_data_internal.h>
30#include <arm/cpu_internal.h>
31#include <kern/kalloc.h>
32#include <kern/kpc.h>
33#include <kern/thread.h>
34#include <kern/processor.h>
35#include <mach/mach_types.h>
36#include <machine/machine_routines.h>
37#include <stdint.h>
38#include <sys/errno.h>
39
40#if MONOTONIC
41#include <kern/monotonic.h>
42#endif /* MONOTONIC */
43
44/*
45 * PMCs 8 and 9 were added to Hurricane and to maintain the existing bit
46 * positions of the other PMCs, their configuration bits start at position 32.
47 */
48#define PMCR_PMC_8_9_OFFSET (32)
49#define PMCR_PMC_8_9_SHIFT(PMC) (((PMC) - 8) + PMCR_PMC_8_9_OFFSET)
50#define PMCR_PMC_SHIFT(PMC) (((PMC) <= 7) ? (PMC) : \
51 PMCR_PMC_8_9_SHIFT(PMC))
52
53/*
54 * PMCR0 controls enabling, interrupts, and overflow of performance counters.
55 */
56
57/* PMC is enabled */
58#define PMCR0_PMC_ENABLE_MASK(PMC) (UINT64_C(0x1) << PMCR_PMC_SHIFT(PMC))
59#define PMCR0_PMC_DISABLE_MASK(PMC) (~PMCR0_PMC_ENABLE_MASK(PMC))
60
61/* how interrupts are generated on PMIs */
62#define PMCR0_INTGEN_SHIFT (8)
63#define PMCR0_INTGEN_MASK (UINT64_C(0x7) << PMCR0_INTGEN_SHIFT)
64#define PMCR0_INTGEN_OFF (UINT64_C(0) << PMCR0_INTGEN_SHIFT)
65#define PMCR0_INTGEN_PMI (UINT64_C(1) << PMCR0_INTGEN_SHIFT)
66#define PMCR0_INTGEN_AIC (UINT64_C(2) << PMCR0_INTGEN_SHIFT)
67#define PMCR0_INTGEN_DBG_HLT (UINT64_C(3) << PMCR0_INTGEN_SHIFT)
68#define PMCR0_INTGEN_FIQ (UINT64_C(4) << PMCR0_INTGEN_SHIFT)
69
70/* 10 unused */
71
72/* set by hardware if PMI was generated */
73#define PMCR0_PMAI_SHIFT (11)
74#define PMCR0_PMAI_MASK (UINT64_C(1) << PMCR0_PMAI_SHIFT)
75
76/* overflow on a PMC generates an interrupt */
77#define PMCR0_PMI_OFFSET (12)
78#define PMCR0_PMI_SHIFT(PMC) (PMCR0_PMI_OFFSET + PMCR_PMC_SHIFT(PMC))
79#define PMCR0_PMI_ENABLE_MASK(PMC) (UINT64_C(1) << PMCR0_PMI_SHIFT(PMC))
80#define PMCR0_PMI_DISABLE_MASK(PMC) (~PMCR0_PMI_ENABLE_MASK(PMC))
81
82/* disable counting when a PMI is signaled (except for AIC interrupts) */
83#define PMCR0_DISCNT_SHIFT (20)
84#define PMCR0_DISCNT_ENABLE_MASK (UINT64_C(1) << PMCR0_DISCNT_SHIFT)
85#define PMCR0_DISCNT_DISABLE_MASK (~PMCR0_DISCNT_ENABLE_MASK)
86
87/* 21 unused */
88
89/* block PMIs until ERET retires */
90#define PMCR0_WFRFE_SHIFT (22)
91#define PMCR0_WFRFE_ENABLE_MASK (UINT64_C(1) << PMCR0_WFRE_SHIFT)
92#define PMCR0_WFRFE_DISABLE_MASK (~PMCR0_WFRFE_ENABLE_MASK)
93
94/* count global L2C events */
95#define PMCR0_L2CGLOBAL_SHIFT (23)
96#define PMCR0_L2CGLOBAL_ENABLE_MASK (UINT64_C(1) << PMCR0_L2CGLOBAL_SHIFT)
97#define PMCR0_L2CGLOBAL_DISABLE_MASK (~PMCR0_L2CGLOBAL_ENABLE_MASK)
98
99/* allow user mode access to configuration registers */
100#define PMCR0_USEREN_SHIFT (30)
101#define PMCR0_USEREN_ENABLE_MASK (UINT64_C(1) << PMCR0_USEREN_SHIFT)
102#define PMCR0_USEREN_DISABLE_MASK (~PMCR0_USEREN_ENABLE_MASK)
103
104/* force the CPMU clocks in case of a clocking bug */
105#define PMCR0_CLKEN_SHIFT (31)
106#define PMCR0_CLKEN_ENABLE_MASK (UINT64_C(1) << PMCR0_USEREN_SHIFT)
107#define PMCR0_CLKEN_DISABLE_MASK (~PMCR0_CLKEN_ENABLE_MASK)
108
109/* 32 - 44 mirror the low bits for PMCs 8 and 9 */
110
111/* PMCR1 enables counters in different processor modes */
112
113#define PMCR1_EL0_A32_OFFSET (0)
114#define PMCR1_EL0_A64_OFFSET (8)
115#define PMCR1_EL1_A64_OFFSET (16)
116#define PMCR1_EL3_A64_OFFSET (24)
117
118#define PMCR1_EL0_A32_SHIFT(PMC) (PMCR1_EL0_A32_OFFSET + PMCR_PMC_SHIFT(PMC))
119#define PMCR1_EL0_A64_SHIFT(PMC) (PMCR1_EL0_A64_OFFSET + PMCR_PMC_SHIFT(PMC))
120#define PMCR1_EL1_A64_SHIFT(PMC) (PMCR1_EL1_A64_OFFSET + PMCR_PMC_SHIFT(PMC))
121#define PMCR1_EL3_A64_SHIFT(PMC) (PMCR1_EL0_A64_OFFSET + PMCR_PMC_SHIFT(PMC))
122
123#define PMCR1_EL0_A32_ENABLE_MASK(PMC) (UINT64_C(1) << PMCR1_EL0_A32_SHIFT(PMC))
124#define PMCR1_EL0_A64_ENABLE_MASK(PMC) (UINT64_C(1) << PMCR1_EL0_A64_SHIFT(PMC))
125#define PMCR1_EL1_A64_ENABLE_MASK(PMC) (UINT64_C(1) << PMCR1_EL1_A64_SHIFT(PMC))
126/* PMCR1_EL3_A64 is not supported on PMCs 8 and 9 */
127#if NO_MONITOR
128#define PMCR1_EL3_A64_ENABLE_MASK(PMC) UINT64_C(0)
129#else
130#define PMCR1_EL3_A64_ENABLE_MASK(PMC) (UINT64_C(1) << PMCR1_EL3_A64_SHIFT(PMC))
131#endif
132
133#define PMCR1_EL_ALL_ENABLE_MASK(PMC) (PMCR1_EL0_A32_ENABLE_MASK(PMC) | \
134 PMCR1_EL0_A64_ENABLE_MASK(PMC) | \
135 PMCR1_EL1_A64_ENABLE_MASK(PMC) | \
136 PMCR1_EL3_A64_ENABLE_MASK(PMC))
137#define PMCR1_EL_ALL_DISABLE_MASK(PMC) (~PMCR1_EL_ALL_ENABLE_MASK(PMC))
138
139/* PMESR0 and PMESR1 are event selection registers */
140
141/* PMESR0 selects which event is counted on PMCs 2, 3, 4, and 5 */
142/* PMESR1 selects which event is counted on PMCs 6, 7, 8, and 9 */
143
144#define PMESR_PMC_WIDTH (8)
145#define PMESR_PMC_MASK (UINT8_MAX)
146#define PMESR_SHIFT(PMC, OFF) (8 * ((PMC) - (OFF)))
147#define PMESR_EVT_MASK(PMC, OFF) (PMESR_PMC_MASK << PMESR_SHIFT(PMC, OFF))
148#define PMESR_EVT_CLEAR(PMC, OFF) (~PMESR_EVT_MASK(PMC, OFF))
149
150#define PMESR_EVT_DECODE(PMESR, PMC, OFF) \
151 (((PMESR) >> PMESR_SHIFT(PMC, OFF)) & PMESR_PMC_MASK)
152#define PMESR_EVT_ENCODE(EVT, PMC, OFF) \
153 (((EVT) & PMESR_PMC_MASK) << PMESR_SHIFT(PMC, OFF))
154
155/* system registers in the CPMU */
156
157#define SREG_PMCR0 "S3_1_c15_c0_0"
158#define SREG_PMCR1 "S3_1_c15_c1_0"
159#define SREG_PMCR2 "S3_1_c15_c2_0"
160#define SREG_PMCR3 "S3_1_c15_c3_0"
161#define SREG_PMCR4 "S3_1_c15_c4_0"
162#define SREG_PMESR0 "S3_1_c15_c5_0"
163#define SREG_PMESR1 "S3_1_c15_c6_0"
164#define SREG_PMSR "S3_1_c15_c13_0"
165#define SREG_OPMAT0 "S3_1_c15_c7_0"
166#define SREG_OPMAT1 "S3_1_c15_c8_0"
167#define SREG_OPMSK0 "S3_1_c15_c9_0"
168#define SREG_OPMSK1 "S3_1_c15_c10_0"
169
170#define SREG_PMC0 "S3_2_c15_c0_0"
171#define SREG_PMC1 "S3_2_c15_c1_0"
172#define SREG_PMC2 "S3_2_c15_c2_0"
173#define SREG_PMC3 "S3_2_c15_c3_0"
174#define SREG_PMC4 "S3_2_c15_c4_0"
175#define SREG_PMC5 "S3_2_c15_c5_0"
176#define SREG_PMC6 "S3_2_c15_c6_0"
177#define SREG_PMC7 "S3_2_c15_c7_0"
178#define SREG_PMC8 "S3_2_c15_c9_0"
179#define SREG_PMC9 "S3_2_c15_c10_0"
180
181#if !defined(APPLECYCLONE)
182#define SREG_PMMMAP "S3_2_c15_c15_0"
183#define SREG_PMTRHLD2 "S3_2_c15_c14_0"
184#define SREG_PMTRHLD4 "S3_2_c15_c13_0"
185#define SREG_PMTRHLD6 "S3_2_c15_c12_0"
186#endif
187
188/*
189 * The low 8 bits of a configuration words select the event to program on
190 * PMESR{0,1}. Bits 16-19 are mapped to PMCR1 bits.
191 */
192#define CFGWORD_EL0A32EN_MASK (0x10000)
193#define CFGWORD_EL0A64EN_MASK (0x20000)
194#define CFGWORD_EL1EN_MASK (0x40000)
195#define CFGWORD_EL3EN_MASK (0x80000)
196#define CFGWORD_ALLMODES_MASK (0xf0000)
197
198/* ACC offsets for PIO */
199#define ACC_CPMU_PMC0_OFFSET (0x200)
200#define ACC_CPMU_PMC8_OFFSET (0x280)
201
202/*
203 * Macros for reading and writing system registers.
204 *
205 * SR must be one of the SREG_* defines above.
206 */
207#define SREG_WRITE(SR, V) __asm__ volatile("msr " SR ", %0 ; isb" : : "r"(V))
208#define SREG_READ(SR) ({ uint64_t VAL; \
209 __asm__ volatile("mrs %0, " SR : "=r"(VAL)); \
210 VAL; })
211
212/*
213 * Configuration registers that can be controlled by RAWPMU:
214 *
215 * All: PMCR2-4, OPMAT0-1, OPMSK0-1.
216 * Typhoon/Twister/Hurricane: PMMMAP, PMTRHLD2/4/6.
217 */
218#if defined(APPLECYCLONE)
219#define RAWPMU_CONFIG_COUNT 7
220#else
221#define RAWPMU_CONFIG_COUNT 11
222#endif
223
224/* TODO: allocate dynamically */
225static uint64_t saved_PMCR[MAX_CPUS][2];
226static uint64_t saved_PMESR[MAX_CPUS][2];
227static uint64_t saved_RAWPMU[MAX_CPUS][RAWPMU_CONFIG_COUNT];
228static uint64_t saved_counter[MAX_CPUS][KPC_MAX_COUNTERS];
229static uint64_t kpc_running_cfg_pmc_mask = 0;
230static uint32_t kpc_running_classes = 0;
231static uint32_t kpc_configured = 0;
232
233static int first_time = 1;
234
235/*
236 * The whitelist is disabled by default on development/debug kernel. This can
237 * be changed via the kpc.disable_whitelist sysctl. The whitelist is enabled on
238 * release kernel and cannot be disabled.
239 */
240#if DEVELOPMENT || DEBUG
241static boolean_t whitelist_disabled = TRUE;
242#else
243static boolean_t whitelist_disabled = FALSE;
244#endif
245
246/* List of counter events that are allowed externally */
247static kpc_config_t whitelist[] = {
248 0, /* NO_EVENT */
249
250#if defined(APPLECYCLONE)
251 0x02, /* CORE_CYCLE */
252 0x19, /* BIU_UPSTREAM_CYCLE */
253 0x1a, /* BIU_DOWNSTREAM_CYCLE */
254 0x22, /* L2C_AGENT_LD */
255 0x23, /* L2C_AGENT_LD_MISS */
256 0x24, /* L2C_AGENT_ST */
257 0x25, /* L2C_AGENT_ST_MISS */
258 0x78, /* INST_A32 */
259 0x79, /* INST_THUMB */
260 0x7a, /* INST_A64 */
261 0x7b, /* INST_BRANCH */
262 0xb4, /* SYNC_DC_LOAD_MISS */
263 0xb5, /* SYNC_DC_STORE_MISS */
264 0xb6, /* SYNC_DTLB_MISS */
265 0xb9, /* SYNC_ST_HIT_YNGR_LD */
266 0xc0, /* SYNC_BR_ANY_MISP */
267 0xce, /* FED_IC_MISS_DEM */
268 0xcf, /* FED_ITLB_MISS */
269
270#elif defined(APPLETYPHOON)
271 0x02, /* CORE_CYCLE */
272 0x13, /* BIU_UPSTREAM_CYCLE */
273 0x14, /* BIU_DOWNSTREAM_CYCLE */
274 0x1a, /* L2C_AGENT_LD */
275 0x1b, /* L2C_AGENT_LD_MISS */
276 0x1c, /* L2C_AGENT_ST */
277 0x1d, /* L2C_AGENT_ST_MISS */
278 0x8a, /* INST_A32 */
279 0x8b, /* INST_THUMB */
280 0x8c, /* INST_A64 */
281 0x8d, /* INST_BRANCH */
282 0xbf, /* SYNC_DC_LOAD_MISS */
283 0xc0, /* SYNC_DC_STORE_MISS */
284 0xc1, /* SYNC_DTLB_MISS */
285 0xc4, /* SYNC_ST_HIT_YNGR_LD */
286 0xcb, /* SYNC_BR_ANY_MISP */
287 0xd3, /* FED_IC_MISS_DEM */
288 0xd4, /* FED_ITLB_MISS */
289
290#elif defined(APPLETWISTER) || defined(APPLEHURRICANE)
291 0x02, /* CORE_CYCLE */
292 0x1a, /* L2C_AGENT_LD */
293 0x1b, /* L2C_AGENT_LD_MISS */
294 0x1c, /* L2C_AGENT_ST */
295 0x1d, /* L2C_AGENT_ST_MISS */
296 0x8a, /* INST_A32 */
297 0x8b, /* INST_THUMB */
298 0x8c, /* INST_A64 */
299 0x8d, /* INST_BRANCH */
300 0xbf, /* SYNC_DC_LOAD_MISS */
301 0xc0, /* SYNC_DC_STORE_MISS */
302 0xc1, /* SYNC_DTLB_MISS */
303 0xc4, /* SYNC_ST_HIT_YNGR_LD */
304 0xcb, /* SYNC_BR_ANY_MISP */
305 0xd3, /* FED_IC_MISS_DEM */
306 0xd4, /* FED_ITLB_MISS */
307
308#else
309 /* An unknown CPU gets a trivial { NO_EVENT } whitelist. */
310#endif
311};
312#define WHITELIST_COUNT (sizeof(whitelist)/sizeof(*whitelist))
313
314static boolean_t
315config_in_whitelist(kpc_config_t cfg)
316{
317 unsigned int i;
318
319 for (i = 0; i < WHITELIST_COUNT; i++) {
320 if (cfg == whitelist[i]) {
321 return TRUE;
322 }
323 }
324
325 return FALSE;
326}
327
328#ifdef KPC_DEBUG
329static void dump_regs(void)
330{
331 uint64_t val;
332 kprintf("PMCR0 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMCR0));
333 kprintf("PMCR1 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMCR1));
334 kprintf("PMCR2 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMCR2));
335 kprintf("PMCR3 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMCR3));
336 kprintf("PMCR4 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMCR4));
337 kprintf("PMESR0 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMESR0));
338 kprintf("PMESR1 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMESR1));
339
340 kprintf("PMC0 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC0));
341 kprintf("PMC1 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC1));
342 kprintf("PMC2 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC2));
343 kprintf("PMC3 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC3));
344 kprintf("PMC4 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC4));
345 kprintf("PMC5 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC5));
346 kprintf("PMC6 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC6));
347 kprintf("PMC7 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC7));
348
349#if (KPC_ARM64_CONFIGURABLE_COUNT > 6)
350 kprintf("PMC8 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC8));
351 kprintf("PMC9 = 0x%" PRIx64 "\n", SREG_READ(SREG_PMC9));
352#endif
353}
354#endif
355
356static boolean_t
357enable_counter(uint32_t counter)
358{
359 int cpuid = cpu_number();
360 uint64_t pmcr0 = 0, intgen_type;
361 boolean_t counter_running, pmi_enabled, intgen_correct, enabled;
362
363 pmcr0 = SREG_READ(SREG_PMCR0) | 0x3 /* leave the fixed counters enabled for monotonic */;
364
365 counter_running = (pmcr0 & PMCR0_PMC_ENABLE_MASK(counter)) != 0;
366 pmi_enabled = (pmcr0 & PMCR0_PMI_ENABLE_MASK(counter)) != 0;
367
368 /* TODO this should use the PMI path rather than AIC for the interrupt
369 * as it is faster
370 */
371 intgen_type = PMCR0_INTGEN_AIC;
372 intgen_correct = (pmcr0 & PMCR0_INTGEN_MASK) == intgen_type;
373
374 enabled = counter_running && pmi_enabled && intgen_correct;
375
376 if (!enabled) {
377 pmcr0 |= PMCR0_PMC_ENABLE_MASK(counter);
378 pmcr0 |= PMCR0_PMI_ENABLE_MASK(counter);
379 pmcr0 &= ~PMCR0_INTGEN_MASK;
380 pmcr0 |= intgen_type;
381
382 SREG_WRITE(SREG_PMCR0, pmcr0);
383 }
384
385 saved_PMCR[cpuid][0] = pmcr0;
386 return enabled;
387}
388
389static boolean_t
390disable_counter(uint32_t counter)
391{
392 uint64_t pmcr0;
393 boolean_t enabled;
394 int cpuid = cpu_number();
395
396 if (counter < 2) {
397 return true;
398 }
399
400 pmcr0 = SREG_READ(SREG_PMCR0) | 0x3;
401 enabled = (pmcr0 & PMCR0_PMC_ENABLE_MASK(counter)) != 0;
402
403 if (enabled) {
404 pmcr0 &= PMCR0_PMC_DISABLE_MASK(counter);
405 SREG_WRITE(SREG_PMCR0, pmcr0);
406 }
407
408 saved_PMCR[cpuid][0] = pmcr0;
409 return enabled;
410}
411
412/*
413 * Enable counter in processor modes determined by configuration word.
414 */
415static void
416set_modes(uint32_t counter, kpc_config_t cfgword)
417{
418 uint64_t bits = 0;
419 int cpuid = cpu_number();
420
421 if (cfgword & CFGWORD_EL0A32EN_MASK) {
422 bits |= PMCR1_EL0_A32_ENABLE_MASK(counter);
423 }
424 if (cfgword & CFGWORD_EL0A64EN_MASK) {
425 bits |= PMCR1_EL0_A64_ENABLE_MASK(counter);
426 }
427 if (cfgword & CFGWORD_EL1EN_MASK) {
428 bits |= PMCR1_EL1_A64_ENABLE_MASK(counter);
429 }
430#if !NO_MONITOR
431 if (cfgword & CFGWORD_EL3EN_MASK) {
432 bits |= PMCR1_EL3_A64_ENABLE_MASK(counter);
433 }
434#endif
435
436 /*
437 * Backwards compatibility: Writing a non-zero configuration word with
438 * all zeros in bits 16-19 is interpreted as enabling in all modes.
439 * This matches the behavior when the PMCR1 bits weren't exposed.
440 */
441 if (bits == 0 && cfgword != 0) {
442 bits = PMCR1_EL_ALL_ENABLE_MASK(counter);
443 }
444
445 uint64_t pmcr1 = SREG_READ(SREG_PMCR1);
446 pmcr1 &= PMCR1_EL_ALL_DISABLE_MASK(counter);
447 pmcr1 |= bits;
448 pmcr1 |= 0x30303; /* monotonic compatibility */
449 SREG_WRITE(SREG_PMCR1, pmcr1);
450 saved_PMCR[cpuid][1] = pmcr1;
451}
452
453static uint64_t
454read_counter(uint32_t counter)
455{
456 switch (counter) {
457 // case 0: return SREG_READ(SREG_PMC0);
458 // case 1: return SREG_READ(SREG_PMC1);
459 case 2: return SREG_READ(SREG_PMC2);
460 case 3: return SREG_READ(SREG_PMC3);
461 case 4: return SREG_READ(SREG_PMC4);
462 case 5: return SREG_READ(SREG_PMC5);
463 case 6: return SREG_READ(SREG_PMC6);
464 case 7: return SREG_READ(SREG_PMC7);
465#if (KPC_ARM64_CONFIGURABLE_COUNT > 6)
466 case 8: return SREG_READ(SREG_PMC8);
467 case 9: return SREG_READ(SREG_PMC9);
468#endif
469 default: return 0;
470 }
471}
472
473static void
474write_counter(uint32_t counter, uint64_t value)
475{
476 switch (counter) {
477 // case 0: SREG_WRITE(SREG_PMC0, value); break;
478 // case 1: SREG_WRITE(SREG_PMC1, value); break;
479 case 2: SREG_WRITE(SREG_PMC2, value); break;
480 case 3: SREG_WRITE(SREG_PMC3, value); break;
481 case 4: SREG_WRITE(SREG_PMC4, value); break;
482 case 5: SREG_WRITE(SREG_PMC5, value); break;
483 case 6: SREG_WRITE(SREG_PMC6, value); break;
484 case 7: SREG_WRITE(SREG_PMC7, value); break;
485#if (KPC_ARM64_CONFIGURABLE_COUNT > 6)
486 case 8: SREG_WRITE(SREG_PMC8, value); break;
487 case 9: SREG_WRITE(SREG_PMC9, value); break;
488#endif
489 default: break;
490 }
491}
492
493uint32_t
494kpc_rawpmu_config_count(void)
495{
496 return RAWPMU_CONFIG_COUNT;
497}
498
499int
500kpc_get_rawpmu_config(kpc_config_t *configv)
501{
502 configv[0] = SREG_READ(SREG_PMCR2);
503 configv[1] = SREG_READ(SREG_PMCR3);
504 configv[2] = SREG_READ(SREG_PMCR4);
505 configv[3] = SREG_READ(SREG_OPMAT0);
506 configv[4] = SREG_READ(SREG_OPMAT1);
507 configv[5] = SREG_READ(SREG_OPMSK0);
508 configv[6] = SREG_READ(SREG_OPMSK1);
509#if RAWPMU_CONFIG_COUNT > 7
510 configv[7] = SREG_READ(SREG_PMMMAP);
511 configv[8] = SREG_READ(SREG_PMTRHLD2);
512 configv[9] = SREG_READ(SREG_PMTRHLD4);
513 configv[10] = SREG_READ(SREG_PMTRHLD6);
514#endif
515 return 0;
516}
517
518static int
519kpc_set_rawpmu_config(kpc_config_t *configv)
520{
521 SREG_WRITE(SREG_PMCR2, configv[0]);
522 SREG_WRITE(SREG_PMCR3, configv[1]);
523 SREG_WRITE(SREG_PMCR4, configv[2]);
524 SREG_WRITE(SREG_OPMAT0, configv[3]);
525 SREG_WRITE(SREG_OPMAT1, configv[4]);
526 SREG_WRITE(SREG_OPMSK0, configv[5]);
527 SREG_WRITE(SREG_OPMSK1, configv[6]);
528#if RAWPMU_CONFIG_COUNT > 7
529 SREG_WRITE(SREG_PMMMAP, configv[7]);
530 SREG_WRITE(SREG_PMTRHLD2, configv[8]);
531 SREG_WRITE(SREG_PMTRHLD4, configv[9]);
532 SREG_WRITE(SREG_PMTRHLD6, configv[10]);
533#endif
534 return 0;
535}
536
537static void
538save_regs(void)
539{
540 int cpuid = cpu_number();
541
542 __asm__ volatile("dmb ish");
543
544 assert(ml_get_interrupts_enabled() == FALSE);
545
546 /* Save current PMCR0/1 values. PMCR2-4 are in the RAWPMU set. */
547 saved_PMCR[cpuid][0] = SREG_READ(SREG_PMCR0) | 0x3;
548
549 /* Save event selections. */
550 saved_PMESR[cpuid][0] = SREG_READ(SREG_PMESR0);
551 saved_PMESR[cpuid][1] = SREG_READ(SREG_PMESR1);
552
553 kpc_get_rawpmu_config(saved_RAWPMU[cpuid]);
554
555 /* Disable the counters. */
556 // SREG_WRITE(SREG_PMCR0, clear);
557
558 /* Finally, save state for each counter*/
559 for (int i = 2; i < KPC_ARM64_PMC_COUNT; i++) {
560 saved_counter[cpuid][i] = read_counter(i);
561 }
562}
563
564static void
565restore_regs(void)
566{
567 int cpuid = cpu_number();
568
569 /* Restore PMESR values. */
570 SREG_WRITE(SREG_PMESR0, saved_PMESR[cpuid][0]);
571 SREG_WRITE(SREG_PMESR1, saved_PMESR[cpuid][1]);
572
573 kpc_set_rawpmu_config(saved_RAWPMU[cpuid]);
574
575 /* Restore counter values */
576 for (int i = 2; i < KPC_ARM64_PMC_COUNT; i++) {
577 write_counter(i, saved_counter[cpuid][i]);
578 }
579
580 /* Restore PMCR0/1 values (with PMCR0 last to enable). */
581 SREG_WRITE(SREG_PMCR1, saved_PMCR[cpuid][1] | 0x30303);
582 SREG_WRITE(SREG_PMCR0, saved_PMCR[cpuid][0] | 0x3);
583}
584
585static uint64_t
586get_counter_config(uint32_t counter)
587{
588 uint64_t pmesr;
589
590 switch (counter) {
591 case 2: /* FALLTHROUGH */
592 case 3: /* FALLTHROUGH */
593 case 4: /* FALLTHROUGH */
594 case 5:
595 pmesr = PMESR_EVT_DECODE(SREG_READ(SREG_PMESR0), counter, 2);
596 break;
597 case 6: /* FALLTHROUGH */
598 case 7:
599#if (KPC_ARM64_CONFIGURABLE_COUNT > 6)
600 /* FALLTHROUGH */
601 case 8: /* FALLTHROUGH */
602 case 9:
603#endif
604 pmesr = PMESR_EVT_DECODE(SREG_READ(SREG_PMESR1), counter, 6);
605 break;
606 default:
607 pmesr = 0;
608 break;
609 }
610
611 kpc_config_t config = pmesr;
612
613 uint64_t pmcr1 = SREG_READ(SREG_PMCR1);
614
615 if (pmcr1 & PMCR1_EL0_A32_ENABLE_MASK(counter)) {
616 config |= CFGWORD_EL0A32EN_MASK;
617 }
618 if (pmcr1 & PMCR1_EL0_A64_ENABLE_MASK(counter)) {
619 config |= CFGWORD_EL0A64EN_MASK;
620 }
621 if (pmcr1 & PMCR1_EL1_A64_ENABLE_MASK(counter)) {
622 config |= CFGWORD_EL1EN_MASK;
623#if NO_MONITOR
624 config |= CFGWORD_EL3EN_MASK;
625#endif
626 }
627#if !NO_MONITOR
628 if (pmcr1 & PMCR1_EL3_A64_ENABLE_MASK(counter)) {
629 config |= CFGWORD_EL3EN_MASK;
630 }
631#endif
632
633 return config;
634}
635
636static void
637set_counter_config(uint32_t counter, uint64_t config)
638{
639 int cpuid = cpu_number();
640 uint64_t pmesr = 0;
641
642 switch (counter) {
643 case 2: /* FALLTHROUGH */
644 case 3: /* FALLTHROUGH */
645 case 4: /* FALLTHROUGH */
646 case 5:
647 pmesr = SREG_READ(SREG_PMESR0);
648 pmesr &= PMESR_EVT_CLEAR(counter, 2);
649 pmesr |= PMESR_EVT_ENCODE(config, counter, 2);
650 SREG_WRITE(SREG_PMESR0, pmesr);
651 saved_PMESR[cpuid][0] = pmesr;
652 break;
653
654 case 6: /* FALLTHROUGH */
655 case 7:
656#if KPC_ARM64_CONFIGURABLE_COUNT > 6
657 /* FALLTHROUGH */
658 case 8: /* FALLTHROUGH */
659 case 9:
660#endif
661 pmesr = SREG_READ(SREG_PMESR1);
662 pmesr &= PMESR_EVT_CLEAR(counter, 6);
663 pmesr |= PMESR_EVT_ENCODE(config, counter, 6);
664 SREG_WRITE(SREG_PMESR1, pmesr);
665 saved_PMESR[cpuid][1] = pmesr;
666 break;
667 default:
668 break;
669 }
670
671 set_modes(counter, config);
672}
673
674/* internal functions */
675
676void
677kpc_arch_init(void)
678{
679}
680
681boolean_t
682kpc_is_running_fixed(void)
683{
684 return (kpc_running_classes & KPC_CLASS_FIXED_MASK) == KPC_CLASS_FIXED_MASK;
685}
686
687boolean_t
688kpc_is_running_configurable(uint64_t pmc_mask)
689{
690 assert(kpc_popcount(pmc_mask) <= kpc_configurable_count());
691 return ((kpc_running_classes & KPC_CLASS_CONFIGURABLE_MASK) == KPC_CLASS_CONFIGURABLE_MASK) &&
692 ((kpc_running_cfg_pmc_mask & pmc_mask) == pmc_mask);
693}
694
695uint32_t
696kpc_fixed_count(void)
697{
698 return KPC_ARM64_FIXED_COUNT;
699}
700
701uint32_t
702kpc_configurable_count(void)
703{
704 return KPC_ARM64_CONFIGURABLE_COUNT;
705}
706
707uint32_t
708kpc_fixed_config_count(void)
709{
710 return 0;
711}
712
713uint32_t
714kpc_configurable_config_count(uint64_t pmc_mask)
715{
716 assert(kpc_popcount(pmc_mask) <= kpc_configurable_count());
717 return kpc_popcount(pmc_mask);
718}
719
720int
721kpc_get_fixed_config(kpc_config_t *configv __unused)
722{
723 return 0;
724}
725
726uint64_t
727kpc_fixed_max(void)
728{
729 return (1ULL << KPC_ARM64_COUNTER_WIDTH) - 1;
730}
731
732uint64_t
733kpc_configurable_max(void)
734{
735 return (1ULL << KPC_ARM64_COUNTER_WIDTH) - 1;
736}
737
738static void
739set_running_configurable(uint64_t target_mask, uint64_t state_mask)
740{
741 uint32_t cfg_count = kpc_configurable_count(), offset = kpc_fixed_count();
742 boolean_t enabled;
743
744 enabled = ml_set_interrupts_enabled(FALSE);
745
746 for (uint32_t i = 0; i < cfg_count; ++i) {
747 if (((1ULL << i) & target_mask) == 0)
748 continue;
749 assert(kpc_controls_counter(offset + i));
750
751 if ((1ULL << i) & state_mask) {
752 enable_counter(offset + i);
753 } else {
754 disable_counter(offset + i);
755 }
756 }
757
758 ml_set_interrupts_enabled(enabled);
759}
760
761static uint32_t kpc_xcall_sync;
762static void
763kpc_set_running_xcall( void *vstate )
764{
765 struct kpc_running_remote *mp_config = (struct kpc_running_remote*) vstate;
766 assert(mp_config);
767
768 set_running_configurable(mp_config->cfg_target_mask,
769 mp_config->cfg_state_mask);
770
771 if (hw_atomic_sub(&kpc_xcall_sync, 1) == 0)
772 thread_wakeup((event_t) &kpc_xcall_sync);
773}
774
775static uint32_t kpc_xread_sync;
776static void
777kpc_get_curcpu_counters_xcall(void *args)
778{
779 struct kpc_get_counters_remote *handler = args;
780
781 assert(handler != NULL);
782 assert(handler->buf != NULL);
783
784 int offset = cpu_number() * handler->buf_stride;
785 int r = kpc_get_curcpu_counters(handler->classes, NULL, &handler->buf[offset]);
786
787 /* number of counters added by this CPU, needs to be atomic */
788 hw_atomic_add(&(handler->nb_counters), r);
789
790 if (hw_atomic_sub(&kpc_xread_sync, 1) == 0) {
791 thread_wakeup((event_t) &kpc_xread_sync);
792 }
793}
794
795int
796kpc_get_all_cpus_counters(uint32_t classes, int *curcpu, uint64_t *buf)
797{
798 assert(buf != NULL);
799
800 int enabled = ml_set_interrupts_enabled(FALSE);
801
802 /* grab counters and CPU number as close as possible */
803 if (curcpu) {
804 *curcpu = current_processor()->cpu_id;
805 }
806
807 struct kpc_get_counters_remote hdl = {
808 .classes = classes,
809 .nb_counters = 0,
810 .buf = buf,
811 .buf_stride = kpc_get_counter_count(classes)
812 };
813
814 cpu_broadcast_xcall(&kpc_xread_sync, TRUE, kpc_get_curcpu_counters_xcall, &hdl);
815 int offset = hdl.nb_counters;
816
817 (void)ml_set_interrupts_enabled(enabled);
818
819 return offset;
820}
821
822int
823kpc_get_fixed_counters(uint64_t *counterv)
824{
825#if MONOTONIC
826 mt_fixed_counts(counterv);
827 return 0;
828#else /* MONOTONIC */
829#pragma unused(counterv)
830 return ENOTSUP;
831#endif /* !MONOTONIC */
832}
833
834int
835kpc_get_configurable_counters(uint64_t *counterv, uint64_t pmc_mask)
836{
837 uint32_t cfg_count = kpc_configurable_count(), offset = kpc_fixed_count();
838 uint64_t ctr = 0ULL;
839
840 assert(counterv);
841
842 for (uint32_t i = 0; i < cfg_count; ++i) {
843 if (((1ULL << i) & pmc_mask) == 0)
844 continue;
845 ctr = read_counter(i + offset);
846
847 if (ctr & KPC_ARM64_COUNTER_OVF_MASK) {
848 ctr = CONFIGURABLE_SHADOW(i) +
849 (kpc_configurable_max() - CONFIGURABLE_RELOAD(i) + 1 /* Wrap */) +
850 (ctr & KPC_ARM64_COUNTER_MASK);
851 } else {
852 ctr = CONFIGURABLE_SHADOW(i) +
853 (ctr - CONFIGURABLE_RELOAD(i));
854 }
855
856 *counterv++ = ctr;
857 }
858
859 return 0;
860}
861
862int
863kpc_get_configurable_config(kpc_config_t *configv, uint64_t pmc_mask)
864{
865 uint32_t cfg_count = kpc_configurable_count(), offset = kpc_fixed_count();
866
867 assert(configv);
868
869 for (uint32_t i = 0; i < cfg_count; ++i)
870 if ((1ULL << i) & pmc_mask)
871 *configv++ = get_counter_config(i + offset);
872 return 0;
873}
874
875static int
876kpc_set_configurable_config(kpc_config_t *configv, uint64_t pmc_mask)
877{
878 uint32_t cfg_count = kpc_configurable_count(), offset = kpc_fixed_count();
879 boolean_t enabled;
880
881 assert(configv);
882
883 enabled = ml_set_interrupts_enabled(FALSE);
884
885 for (uint32_t i = 0; i < cfg_count; ++i) {
886 if (((1ULL << i) & pmc_mask) == 0)
887 continue;
888 assert(kpc_controls_counter(i + offset));
889
890 set_counter_config(i + offset, *configv++);
891 }
892
893 ml_set_interrupts_enabled(enabled);
894
895 return 0;
896}
897
898static uint32_t kpc_config_sync;
899static void
900kpc_set_config_xcall(void *vmp_config)
901{
902 struct kpc_config_remote *mp_config = vmp_config;
903 kpc_config_t *new_config = NULL;
904 uint32_t classes = 0ULL;
905
906 assert(mp_config);
907 assert(mp_config->configv);
908 classes = mp_config->classes;
909 new_config = mp_config->configv;
910
911 if (classes & KPC_CLASS_CONFIGURABLE_MASK) {
912 kpc_set_configurable_config(new_config, mp_config->pmc_mask);
913 new_config += kpc_popcount(mp_config->pmc_mask);
914 }
915
916 if (classes & KPC_CLASS_RAWPMU_MASK) {
917 kpc_set_rawpmu_config(new_config);
918 new_config += RAWPMU_CONFIG_COUNT;
919 }
920
921 if (hw_atomic_sub(&kpc_config_sync, 1) == 0)
922 thread_wakeup((event_t) &kpc_config_sync);
923}
924
925static uint64_t
926kpc_reload_counter(uint32_t ctr)
927{
928 assert(ctr < (kpc_configurable_count() + kpc_fixed_count()));
929
930 /* don't reload counters reserved for power management */
931 if (!kpc_controls_counter(ctr))
932 return 0ULL;
933
934 uint64_t old = read_counter(ctr);
935 write_counter(ctr, FIXED_RELOAD(ctr));
936 return old & KPC_ARM64_COUNTER_MASK;
937}
938
939static uint32_t kpc_reload_sync;
940static void
941kpc_set_reload_xcall(void *vmp_config)
942{
943 struct kpc_config_remote *mp_config = vmp_config;
944 uint32_t classes = 0, count = 0, offset = kpc_fixed_count();
945 uint64_t *new_period = NULL, max = kpc_configurable_max();
946 boolean_t enabled;
947
948 assert(mp_config);
949 assert(mp_config->configv);
950 classes = mp_config->classes;
951 new_period = mp_config->configv;
952
953 enabled = ml_set_interrupts_enabled(FALSE);
954
955 if (classes & KPC_CLASS_CONFIGURABLE_MASK) {
956 /*
957 * Update _all_ shadow counters, this cannot be done for only
958 * selected PMCs. Otherwise, we would corrupt the configurable
959 * shadow buffer since the PMCs are muxed according to the pmc
960 * mask.
961 */
962 uint64_t all_cfg_mask = (1ULL << kpc_configurable_count()) - 1;
963 kpc_get_configurable_counters(&CONFIGURABLE_SHADOW(0), all_cfg_mask);
964
965 /* set the new period */
966 count = kpc_configurable_count();
967 for (uint32_t i = 0; i < count; ++i) {
968 /* ignore the counter */
969 if (((1ULL << i) & mp_config->pmc_mask) == 0)
970 continue;
971 if (*new_period == 0)
972 *new_period = kpc_configurable_max();
973 CONFIGURABLE_RELOAD(i) = max - *new_period;
974 /* reload the counter */
975 kpc_reload_counter(offset + i);
976 /* next period value */
977 new_period++;
978 }
979 }
980
981 ml_set_interrupts_enabled(enabled);
982
983 if (hw_atomic_sub(&kpc_reload_sync, 1) == 0)
984 thread_wakeup((event_t) &kpc_reload_sync);
985}
986
987void kpc_pmi_handler(cpu_id_t source);
988void
989kpc_pmi_handler(cpu_id_t source __unused)
990{
991 uint64_t PMSR, extra;
992 int ctr;
993 int enabled;
994
995 enabled = ml_set_interrupts_enabled(FALSE);
996
997 /* The pmi must be delivered to the CPU that generated it */
998 if (source != getCpuDatap()->interrupt_nub) {
999 panic("pmi from IOCPU %p delivered to IOCPU %p", source, getCpuDatap()->interrupt_nub);
1000 }
1001
1002 /* Get the PMSR which has the overflow bits for all the counters */
1003 __asm__ volatile("mrs %0, S3_1_c15_c13_0" : "=r"(PMSR));
1004
1005 for (ctr = 0; ctr < (KPC_ARM64_FIXED_COUNT + KPC_ARM64_CONFIGURABLE_COUNT); ctr++) {
1006 if ((1ull << ctr) & PMSR) {
1007 if (ctr < 2) {
1008#if MONOTONIC
1009 mt_cpu_pmi(getCpuDatap(), PMSR);
1010#endif /* MONOTONIC */
1011 } else {
1012 extra = kpc_reload_counter(ctr);
1013
1014 FIXED_SHADOW(ctr)
1015 += (kpc_fixed_max() - FIXED_RELOAD(ctr) + 1 /* Wrap */) + extra;
1016
1017 if (FIXED_ACTIONID(ctr))
1018 kpc_sample_kperf(FIXED_ACTIONID(ctr));
1019 }
1020 }
1021 }
1022
1023 ml_set_interrupts_enabled(enabled);
1024}
1025
1026uint32_t
1027kpc_get_classes(void)
1028{
1029 return KPC_CLASS_FIXED_MASK | KPC_CLASS_CONFIGURABLE_MASK | KPC_CLASS_RAWPMU_MASK;
1030}
1031
1032int
1033kpc_set_running_arch(struct kpc_running_remote *mp_config)
1034{
1035 int cpu;
1036
1037 assert(mp_config);
1038
1039 if (first_time) {
1040 PE_cpu_perfmon_interrupt_install_handler(kpc_pmi_handler);
1041 int max_cpu = ml_get_max_cpu_number();
1042 for (cpu = 0; cpu <= max_cpu; cpu++) {
1043 cpu_data_t *target_cpu_datap = (cpu_data_t *)CpuDataEntries[cpu].cpu_data_vaddr;
1044 if (target_cpu_datap != NULL)
1045 PE_cpu_perfmon_interrupt_enable(target_cpu_datap->cpu_id, TRUE);
1046 }
1047 first_time = 0;
1048 }
1049
1050 /* dispatch to all CPUs */
1051 cpu_broadcast_xcall(&kpc_xcall_sync, TRUE, kpc_set_running_xcall, mp_config);
1052
1053 kpc_running_cfg_pmc_mask = mp_config->cfg_state_mask;
1054 kpc_running_classes = mp_config->classes;
1055 kpc_configured = 1;
1056
1057 return 0;
1058}
1059
1060int
1061kpc_set_period_arch(struct kpc_config_remote *mp_config)
1062{
1063 assert(mp_config);
1064
1065 /* dispatch to all CPUs */
1066 cpu_broadcast_xcall(&kpc_reload_sync, TRUE, kpc_set_reload_xcall, mp_config);
1067
1068 kpc_configured = 1;
1069
1070 return 0;
1071}
1072
1073int
1074kpc_set_config_arch(struct kpc_config_remote *mp_config)
1075{
1076 uint32_t count = kpc_popcount(mp_config->pmc_mask);
1077
1078 assert(mp_config);
1079 assert(mp_config->configv);
1080
1081 /* check config against whitelist for external devs */
1082 for (uint32_t i = 0; i < count; ++i) {
1083 if (!whitelist_disabled && !config_in_whitelist(mp_config->configv[i])) {
1084 return EPERM;
1085 }
1086 }
1087
1088 /* dispatch to all CPUs */
1089 cpu_broadcast_xcall(&kpc_config_sync, TRUE, kpc_set_config_xcall, mp_config);
1090
1091 kpc_configured = 1;
1092
1093 return 0;
1094}
1095
1096void
1097kpc_idle(void)
1098{
1099 if (kpc_configured) {
1100 save_regs();
1101 }
1102}
1103
1104void
1105kpc_idle_exit(void)
1106{
1107 if (kpc_configured) {
1108 restore_regs();
1109 }
1110}
1111
1112int
1113kpc_set_sw_inc( uint32_t mask __unused )
1114{
1115 return ENOTSUP;
1116}
1117
1118int
1119kpc_disable_whitelist( int val )
1120{
1121 whitelist_disabled = val;
1122 return 0;
1123}
1124
1125int
1126kpc_get_whitelist_disabled( void )
1127{
1128 return whitelist_disabled;
1129}
1130
1131int
1132kpc_get_pmu_version(void)
1133{
1134 return KPC_PMU_ARM_APPLE;
1135}