xref: /xnu-11215.61.5/osfmk/arm64/monotonic_arm64.c (revision 4f1223e81cd707a65cc109d0b8ad6653699da3c4)
1 /*
2  * Copyright (c) 2017-2020 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/machine_routines.h>
31 #include <arm64/monotonic.h>
32 #include <kern/assert.h>
33 #include <kern/cpc.h>
34 #include <kern/debug.h> /* panic */
35 #include <kern/kpc.h>
36 #include <kern/monotonic.h>
37 #include <machine/atomic.h>
38 #include <machine/limits.h> /* CHAR_BIT */
39 #include <os/overflow.h>
40 #include <pexpert/arm64/board_config.h>
41 #include <pexpert/device_tree.h> /* SecureDTFindEntry */
42 #include <pexpert/pexpert.h>
43 #include <stdatomic.h>
44 #include <stdint.h>
45 #include <string.h>
46 #include <sys/errno.h>
47 #include <sys/monotonic.h>
48 
49 /*
50  * Ensure that control registers read back what was written under MACH_ASSERT
51  * kernels.
52  *
53  * A static inline function cannot be used due to passing the register through
54  * the builtin -- it requires a constant string as its first argument, since
55  * MSRs registers are encoded as an immediate in the instruction.
56  */
57 #if MACH_ASSERT
58 #define CTRL_REG_SET(reg, val) do { \
59 	__builtin_arm_wsr64((reg), (val)); \
60 	uint64_t __check_reg = __builtin_arm_rsr64((reg)); \
61 	if (__check_reg != (val)) { \
62 	        panic("value written to %s was not read back (wrote %llx, read %llx)", \
63 	            #reg, (val), __check_reg); \
64 	} \
65 } while (0)
66 #else /* MACH_ASSERT */
67 #define CTRL_REG_SET(reg, val) __builtin_arm_wsr64((reg), (val))
68 #endif /* MACH_ASSERT */
69 
70 #pragma mark core counters
71 
72 const bool mt_core_supported = true;
73 
74 static const ml_topology_info_t *topology_info;
75 
76 /*
77  * PMC[0-1] are the 48/64-bit fixed counters -- PMC0 is cycles and PMC1 is
78  * instructions (see arm64/monotonic.h).
79  *
80  * PMC2+ are currently handled by kpc.
81  */
82 #define PMC_0_7(X, A) X(0, A); X(1, A); X(2, A); X(3, A); X(4, A); X(5, A); \
83     X(6, A); X(7, A)
84 
85 #if CORE_NCTRS > 8
86 #define PMC_8_9(X, A) X(8, A); X(9, A)
87 #else // CORE_NCTRS > 8
88 #define PMC_8_9(X, A)
89 #endif // CORE_NCTRS > 8
90 
91 #define PMC_ALL(X, A) PMC_0_7(X, A); PMC_8_9(X, A)
92 
93 #if CPMU_64BIT_PMCS
94 #define PMC_WIDTH (63)
95 #else // UPMU_64BIT_PMCS
96 #define PMC_WIDTH (47)
97 #endif // !UPMU_64BIT_PMCS
98 
99 #define CTR_MAX ((UINT64_C(1) << PMC_WIDTH) - 1)
100 
101 #define CYCLES 0
102 #define INSTRS 1
103 
104 /*
105  * PMC0's offset into a core's PIO range.
106  *
107  * This allows cores to remotely query another core's counters.
108  */
109 
110 #define PIO_PMC0_OFFSET (0x200)
111 
112 /*
113  * The offset of the counter in the configuration registers.  Post-Hurricane
114  * devices have additional counters that need a larger shift than the original
115  * counters.
116  *
117  * XXX For now, just support the lower-numbered counters.
118  */
119 #define CTR_POS(CTR) (CTR)
120 
121 /*
122  * PMCR0 is the main control register for the performance monitor.  It
123  * controls whether the counters are enabled, how they deliver interrupts, and
124  * other features.
125  */
126 
127 #define PMCR0_CTR_EN(CTR) (UINT64_C(1) << CTR_POS(CTR))
128 #define PMCR0_FIXED_EN (PMCR0_CTR_EN(CYCLES) | PMCR0_CTR_EN(INSTRS))
129 /* how interrupts are delivered on a PMI */
130 enum {
131 	PMCR0_INTGEN_OFF = 0,
132 	PMCR0_INTGEN_PMI = 1,
133 	PMCR0_INTGEN_AIC = 2,
134 	PMCR0_INTGEN_HALT = 3,
135 	PMCR0_INTGEN_FIQ = 4,
136 };
137 #define PMCR0_INTGEN_SET(X) ((uint64_t)(X) << 8)
138 
139 #if CPMU_AIC_PMI
140 #define PMCR0_INTGEN_INIT PMCR0_INTGEN_SET(PMCR0_INTGEN_AIC)
141 #else /* CPMU_AIC_PMI */
142 #define PMCR0_INTGEN_INIT PMCR0_INTGEN_SET(PMCR0_INTGEN_FIQ)
143 #endif /* !CPMU_AIC_PMI */
144 
145 #define PMCR0_PMI_SHIFT (12)
146 #define PMCR0_CTR_GE8_PMI_SHIFT (44)
147 #define PMCR0_PMI_EN(CTR) (UINT64_C(1) << (PMCR0_PMI_SHIFT + CTR_POS(CTR)))
148 /* fixed counters are always counting */
149 #define PMCR0_PMI_INIT (PMCR0_PMI_EN(CYCLES) | PMCR0_PMI_EN(INSTRS))
150 /* disable counting on a PMI */
151 #define PMCR0_DISCNT_EN (UINT64_C(1) << 20)
152 /* block PMIs until ERET retires */
153 #define PMCR0_WFRFE_EN (UINT64_C(1) << 22)
154 /* count global (not just core-local) L2C events */
155 #define PMCR0_L2CGLOBAL_EN (UINT64_C(1) << 23)
156 /* user mode access to configuration registers */
157 #define PMCR0_USEREN_EN (UINT64_C(1) << 30)
158 #define PMCR0_CTR_GE8_EN_SHIFT (32)
159 
160 #if HAS_CPMU_PC_CAPTURE
161 #define PMCR0_PCC_INIT (UINT64_C(0x7) << 24)
162 #else /* HAS_CPMU_PC_CAPTURE */
163 #define PMCR0_PCC_INIT (0)
164 #endif /* !HAS_CPMU_PC_CAPTURE */
165 
166 #define PMCR0_INIT (PMCR0_INTGEN_INIT | PMCR0_PMI_INIT | PMCR0_PCC_INIT)
167 
168 /*
169  * PMCR1 controls which execution modes count events.
170  */
171 #define PMCR1_EL0A32_EN(CTR) (UINT64_C(1) << (0 + CTR_POS(CTR)))
172 #define PMCR1_EL0A64_EN(CTR) (UINT64_C(1) << (8 + CTR_POS(CTR)))
173 #define PMCR1_EL1A64_EN(CTR) (UINT64_C(1) << (16 + CTR_POS(CTR)))
174 /* PMCR1_EL3A64 is not supported on systems with no monitor */
175 #if defined(APPLEHURRICANE)
176 #define PMCR1_EL3A64_EN(CTR) UINT64_C(0)
177 #else
178 #define PMCR1_EL3A64_EN(CTR) (UINT64_C(1) << (24 + CTR_POS(CTR)))
179 #endif
180 #define PMCR1_ALL_EN(CTR) (PMCR1_EL0A32_EN(CTR) | PMCR1_EL0A64_EN(CTR) | \
181 	                   PMCR1_EL1A64_EN(CTR) | PMCR1_EL3A64_EN(CTR))
182 
183 /* fixed counters always count in all modes */
184 #define PMCR1_INIT (PMCR1_ALL_EN(CYCLES) | PMCR1_ALL_EN(INSTRS))
185 
186 static inline void
core_init_execution_modes(void)187 core_init_execution_modes(void)
188 {
189 	uint64_t pmcr1;
190 
191 	pmcr1 = __builtin_arm_rsr64("PMCR1_EL1");
192 	pmcr1 |= PMCR1_INIT;
193 	__builtin_arm_wsr64("PMCR1_EL1", pmcr1);
194 #if CONFIG_EXCLAVES
195 	__builtin_arm_wsr64("PMCR1_EL12", pmcr1);
196 #endif
197 }
198 
199 #define PMSR_OVF(CTR) (1ULL << (CTR))
200 
201 static int
core_init(__unused mt_device_t dev)202 core_init(__unused mt_device_t dev)
203 {
204 	/* the dev node interface to the core counters is still unsupported */
205 	return ENOTSUP;
206 }
207 
208 struct mt_cpu *
mt_cur_cpu(void)209 mt_cur_cpu(void)
210 {
211 	return &getCpuDatap()->cpu_monotonic;
212 }
213 
214 uint64_t
mt_core_snap(unsigned int ctr)215 mt_core_snap(unsigned int ctr)
216 {
217 	switch (ctr) {
218 #define PMC_RD(CTR, UNUSED) case (CTR): return __builtin_arm_rsr64(__MSR_STR(PMC ## CTR))
219 		PMC_ALL(PMC_RD, 0);
220 #undef PMC_RD
221 	default:
222 		panic("monotonic: invalid core counter read: %u", ctr);
223 		__builtin_unreachable();
224 	}
225 }
226 
227 void
mt_core_set_snap(unsigned int ctr,uint64_t count)228 mt_core_set_snap(unsigned int ctr, uint64_t count)
229 {
230 	switch (ctr) {
231 	case 0:
232 		__builtin_arm_wsr64("PMC0", count);
233 		break;
234 	case 1:
235 		__builtin_arm_wsr64("PMC1", count);
236 		break;
237 	default:
238 		panic("monotonic: invalid core counter %u write %llu", ctr, count);
239 		__builtin_unreachable();
240 	}
241 }
242 
243 static void
core_set_enabled(void)244 core_set_enabled(void)
245 {
246 	uint32_t kpc_mask = kpc_get_running() &
247 	    (KPC_CLASS_CONFIGURABLE_MASK | KPC_CLASS_POWER_MASK);
248 	uint64_t pmcr0 = __builtin_arm_rsr64("PMCR0_EL1");
249 	pmcr0 |= PMCR0_INIT | PMCR0_FIXED_EN;
250 
251 	if (kpc_mask != 0) {
252 		uint64_t kpc_ctrs = kpc_get_configurable_pmc_mask(kpc_mask) <<
253 		        MT_CORE_NFIXED;
254 #if KPC_ARM64_CONFIGURABLE_COUNT > 6
255 		uint64_t ctrs_ge8 = kpc_ctrs >> 8;
256 		pmcr0 |= ctrs_ge8 << PMCR0_CTR_GE8_EN_SHIFT;
257 		pmcr0 |= ctrs_ge8 << PMCR0_CTR_GE8_PMI_SHIFT;
258 		kpc_ctrs &= (1ULL << 8) - 1;
259 #endif /* KPC_ARM64_CONFIGURABLE_COUNT > 6 */
260 		kpc_ctrs |= kpc_ctrs << PMCR0_PMI_SHIFT;
261 		pmcr0 |= kpc_ctrs;
262 	}
263 
264 	__builtin_arm_wsr64("PMCR0_EL1", pmcr0);
265 #if MACH_ASSERT
266 	/*
267 	 * Only check for the values that were ORed in.
268 	 */
269 	uint64_t pmcr0_check = __builtin_arm_rsr64("PMCR0_EL1");
270 	if ((pmcr0_check & (PMCR0_INIT | PMCR0_FIXED_EN)) != (PMCR0_INIT | PMCR0_FIXED_EN)) {
271 		panic("monotonic: hardware ignored enable (read %llx, wrote %llx)",
272 		    pmcr0_check, pmcr0);
273 	}
274 #endif /* MACH_ASSERT */
275 }
276 
277 static void
core_idle(__unused cpu_data_t * cpu)278 core_idle(__unused cpu_data_t *cpu)
279 {
280 	assert(cpu != NULL);
281 	assert(ml_get_interrupts_enabled() == FALSE);
282 
283 #if DEBUG
284 	uint64_t pmcr0 = __builtin_arm_rsr64("PMCR0_EL1");
285 	if ((pmcr0 & PMCR0_FIXED_EN) == 0) {
286 		panic("monotonic: counters disabled before idling, pmcr0 = 0x%llx", pmcr0);
287 	}
288 	uint64_t pmcr1 = __builtin_arm_rsr64("PMCR1_EL1");
289 	if ((pmcr1 & PMCR1_INIT) == 0) {
290 		panic("monotonic: counter modes disabled before idling, pmcr1 = 0x%llx", pmcr1);
291 	}
292 #endif /* DEBUG */
293 
294 	/* disable counters before updating */
295 	__builtin_arm_wsr64("PMCR0_EL1", PMCR0_INIT);
296 
297 	mt_update_fixed_counts();
298 }
299 
300 #pragma mark uncore performance monitor
301 
302 #if HAS_UNCORE_CTRS
303 
304 static bool mt_uncore_initted = false;
305 
306 static bool mt_uncore_suspended_cpd = false;
307 
308 /*
309  * Uncore Performance Monitor
310  *
311  * Uncore performance monitors provide event-counting for the last-level caches
312  * (LLCs).  Each LLC has its own uncore performance monitor, which can only be
313  * accessed by cores that use that LLC.  Like the core performance monitoring
314  * unit, uncore counters are configured globally.  If there is more than one
315  * LLC on the system, PIO reads must be used to satisfy uncore requests (using
316  * the `_r` remote variants of the access functions).  Otherwise, local MSRs
317  * suffice (using the `_l` local variants of the access functions).
318  */
319 
320 #if UNCORE_PER_CLUSTER
321 #define MAX_NMONITORS MAX_CPU_CLUSTERS
322 static uintptr_t cpm_impl[MAX_NMONITORS] = {};
323 #else
324 #define MAX_NMONITORS (1)
325 #endif /* UNCORE_PER_CLUSTER */
326 
327 #if UNCORE_VERSION >= 2
328 /*
329  * V2 uncore monitors feature a CTI mechanism -- the second bit of UPMSR is
330  * used to track if a CTI has been triggered due to an overflow.
331  */
332 #define UPMSR_OVF_POS 2
333 #else /* UNCORE_VERSION >= 2 */
334 #define UPMSR_OVF_POS 1
335 #endif /* UNCORE_VERSION < 2 */
336 #define UPMSR_OVF(R, CTR) ((R) >> ((CTR) + UPMSR_OVF_POS) & 0x1)
337 #define UPMSR_OVF_MASK    (((UINT64_C(1) << UNCORE_NCTRS) - 1) << UPMSR_OVF_POS)
338 
339 #define UPMPCM_CORE(ID) (UINT64_C(1) << (ID))
340 
341 #if UPMU_64BIT_PMCS
342 #define UPMC_WIDTH (63)
343 #else // UPMU_64BIT_PMCS
344 #define UPMC_WIDTH (47)
345 #endif // !UPMU_64BIT_PMCS
346 
347 /*
348  * The uncore_pmi_mask is a bitmask of CPUs that receive uncore PMIs.  It's
349  * initialized by uncore_init and controllable by the uncore_pmi_mask boot-arg.
350  */
351 static int32_t uncore_pmi_mask = 0;
352 
353 /*
354  * The uncore_active_ctrs is a bitmask of uncore counters that are currently
355  * requested.
356  */
357 static uint16_t uncore_active_ctrs = 0;
358 static_assert(sizeof(uncore_active_ctrs) * CHAR_BIT >= UNCORE_NCTRS,
359     "counter mask should fit the full range of counters");
360 
361 /*
362  * mt_uncore_enabled is true when any uncore counters are active.
363  */
364 bool mt_uncore_enabled = false;
365 
366 /*
367  * The uncore_events are the event configurations for each uncore counter -- as
368  * a union to make it easy to program the hardware registers.
369  */
370 static struct uncore_config {
371 	union {
372 		uint8_t uce_ctrs[UNCORE_NCTRS];
373 		uint64_t uce_regs[UNCORE_NCTRS / 8];
374 	} uc_events;
375 	union {
376 		uint16_t uccm_masks[UNCORE_NCTRS];
377 		uint64_t uccm_regs[UNCORE_NCTRS / 4];
378 	} uc_cpu_masks[MAX_NMONITORS];
379 } uncore_config;
380 
381 static struct uncore_monitor {
382 	/*
383 	 * The last snapshot of each of the hardware counter values.
384 	 */
385 	uint64_t um_snaps[UNCORE_NCTRS];
386 
387 	/*
388 	 * The accumulated counts for each counter.
389 	 */
390 	uint64_t um_counts[UNCORE_NCTRS];
391 
392 	/*
393 	 * Protects accessing the hardware registers and fields in this structure.
394 	 */
395 	lck_spin_t um_lock;
396 
397 	/*
398 	 * Whether this monitor needs its registers restored after wake.
399 	 */
400 	bool um_sleeping;
401 
402 #if MACH_ASSERT
403 	/*
404 	 * Save the last ID that read from this monitor.
405 	 */
406 	uint8_t um_last_read_id;
407 
408 	/*
409 	 * Save whether this monitor has been read since sleeping.
410 	 */
411 	bool um_read_since_sleep;
412 #endif /* MACH_ASSERT */
413 } uncore_monitors[MAX_NMONITORS];
414 
415 /*
416  * Each uncore unit has its own monitor, corresponding to the memory hierarchy
417  * of the LLCs.
418  */
419 static unsigned int
uncore_nmonitors(void)420 uncore_nmonitors(void)
421 {
422 #if UNCORE_PER_CLUSTER
423 	return topology_info->num_clusters;
424 #else /* UNCORE_PER_CLUSTER */
425 	return 1;
426 #endif /* !UNCORE_PER_CLUSTER */
427 }
428 
429 static unsigned int
uncmon_get_curid(void)430 uncmon_get_curid(void)
431 {
432 #if UNCORE_PER_CLUSTER
433 	return cpu_cluster_id();
434 #else /* UNCORE_PER_CLUSTER */
435 	return 0;
436 #endif /* !UNCORE_PER_CLUSTER */
437 }
438 
439 /*
440  * Per-monitor locks are required to prevent races with the PMI handlers, not
441  * from other CPUs that are configuring (those are serialized with monotonic's
442  * per-device lock).
443  */
444 
445 static int
uncmon_lock(struct uncore_monitor * mon)446 uncmon_lock(struct uncore_monitor *mon)
447 {
448 	int intrs_en = ml_set_interrupts_enabled(FALSE);
449 	lck_spin_lock(&mon->um_lock);
450 	return intrs_en;
451 }
452 
453 static void
uncmon_unlock(struct uncore_monitor * mon,int intrs_en)454 uncmon_unlock(struct uncore_monitor *mon, int intrs_en)
455 {
456 	lck_spin_unlock(&mon->um_lock);
457 	(void)ml_set_interrupts_enabled(intrs_en);
458 }
459 
460 static bool
uncmon_is_remote(unsigned int monid)461 uncmon_is_remote(unsigned int monid)
462 {
463 	if (monid >= MAX_NMONITORS) {
464 		panic("monotonic: %s: invalid monid %u (> %u)", __FUNCTION__, monid, MAX_NMONITORS);
465 	}
466 	struct uncore_monitor *mon = &uncore_monitors[monid];
467 #pragma unused(mon)
468 	LCK_SPIN_ASSERT(&mon->um_lock, LCK_ASSERT_OWNED);
469 	return monid == uncmon_get_curid();
470 }
471 
472 /*
473  * Helper functions for accessing the hardware -- these require the monitor be
474  * locked to prevent other CPUs' PMI handlers from making local modifications
475  * or updating the counts.
476  */
477 
478 #if UNCORE_VERSION >= 2
479 #define UPMCR0_INTEN_POS 20
480 #define UPMCR0_INTGEN_POS 16
481 #else /* UNCORE_VERSION >= 2 */
482 #define UPMCR0_INTEN_POS 12
483 #define UPMCR0_INTGEN_POS 8
484 #endif /* UNCORE_VERSION < 2 */
485 enum {
486 	UPMCR0_INTGEN_OFF = 0,
487 	/* fast PMIs are only supported on core CPMU */
488 	UPMCR0_INTGEN_AIC = 2,
489 	UPMCR0_INTGEN_HALT = 3,
490 	UPMCR0_INTGEN_FIQ = 4,
491 };
492 /* always enable interrupts for all counters */
493 #define UPMCR0_INTEN (((1ULL << UNCORE_NCTRS) - 1) << UPMCR0_INTEN_POS)
494 /* route uncore PMIs through the FIQ path */
495 #define UPMCR0_INIT (UPMCR0_INTEN | (UPMCR0_INTGEN_FIQ << UPMCR0_INTGEN_POS))
496 
497 /*
498  * Turn counting on for counters set in the `enctrmask` and off, otherwise.
499  */
500 static inline void
uncmon_set_counting_locked_l(__unused unsigned int monid,uint64_t enctrmask)501 uncmon_set_counting_locked_l(__unused unsigned int monid, uint64_t enctrmask)
502 {
503 	/*
504 	 * UPMCR0 controls which counters are enabled and how interrupts are generated
505 	 * for overflows.
506 	 */
507 	__builtin_arm_wsr64("UPMCR0_EL1", UPMCR0_INIT | enctrmask);
508 }
509 
510 #if UNCORE_PER_CLUSTER
511 
512 /*
513  * Turn counting on for counters set in the `enctrmask` and off, otherwise.
514  */
515 static inline void
uncmon_set_counting_locked_r(unsigned int monid,uint64_t enctrmask)516 uncmon_set_counting_locked_r(unsigned int monid, uint64_t enctrmask)
517 {
518 	const uintptr_t upmcr0_offset = 0x4180;
519 	*(uint64_t *)(cpm_impl[monid] + upmcr0_offset) = UPMCR0_INIT | enctrmask;
520 }
521 
522 #endif /* UNCORE_PER_CLUSTER */
523 
524 /*
525  * The uncore performance monitoring counters (UPMCs) are 48/64-bits wide.  The
526  * high bit is an overflow bit, triggering a PMI, providing 47/63 usable bits.
527  */
528 
529 #define UPMC_MAX ((UINT64_C(1) << UPMC_WIDTH) - 1)
530 
531 /*
532  * The `__builtin_arm_{r,w}sr` functions require constant strings, since the
533  * MSR/MRS instructions encode the registers as immediates.  Otherwise, this
534  * would be indexing into an array of strings.
535  */
536 
537 #define UPMC_0_7(X, A) X(0, A); X(1, A); X(2, A); X(3, A); X(4, A); X(5, A); \
538 	        X(6, A); X(7, A)
539 #if UNCORE_NCTRS <= 8
540 #define UPMC_ALL(X, A) UPMC_0_7(X, A)
541 #else /* UNCORE_NCTRS <= 8 */
542 #define UPMC_8_15(X, A) X(8, A); X(9, A); X(10, A); X(11, A); X(12, A); \
543 	        X(13, A); X(14, A); X(15, A)
544 #define UPMC_ALL(X, A) UPMC_0_7(X, A); UPMC_8_15(X, A)
545 #endif /* UNCORE_NCTRS > 8 */
546 
547 static void
_broadcast_block_trampoline(void * blk)548 _broadcast_block_trampoline(void *blk)
549 {
550 	void (^cb)(unsigned int) = blk;
551 	const ml_topology_info_t *topo = ml_get_topology_info();
552 	unsigned int cpu = cpu_number();
553 	unsigned int cluster = topo->cpus[cpu].cluster_id;
554 	if (topo->clusters[cluster].first_cpu_id == cpu) {
555 		cb(topo->cpus[cpu].cluster_id);
556 	}
557 }
558 
559 __unused
560 static void
561 _broadcast_each_cluster(void (^cb)(unsigned int cluster_id))
562 {
563 	cpu_broadcast_xcall_simple(TRUE, _broadcast_block_trampoline, cb);
564 }
565 
566 __unused
567 static inline uint64_t
uncmon_read_counter_locked_l(__unused unsigned int monid,unsigned int ctr)568 uncmon_read_counter_locked_l(__unused unsigned int monid, unsigned int ctr)
569 {
570 	assert(ctr < UNCORE_NCTRS);
571 	switch (ctr) {
572 #define UPMC_RD(CTR, UNUSED) case (CTR): return __builtin_arm_rsr64(__MSR_STR(UPMC ## CTR))
573 		UPMC_ALL(UPMC_RD, 0);
574 #undef UPMC_RD
575 	default:
576 		panic("monotonic: invalid counter read %u", ctr);
577 		__builtin_unreachable();
578 	}
579 }
580 
581 static inline void
uncmon_write_counter_locked_l(__unused unsigned int monid,unsigned int ctr,uint64_t count)582 uncmon_write_counter_locked_l(__unused unsigned int monid, unsigned int ctr,
583     uint64_t count)
584 {
585 	assert(count < UPMC_MAX);
586 	assert(ctr < UNCORE_NCTRS);
587 	switch (ctr) {
588 #define UPMC_WR(CTR, COUNT) case (CTR): \
589 	        return __builtin_arm_wsr64(__MSR_STR(UPMC ## CTR), (COUNT))
590 		UPMC_ALL(UPMC_WR, count);
591 #undef UPMC_WR
592 	default:
593 		panic("monotonic: invalid counter write %u", ctr);
594 	}
595 }
596 
597 #if UNCORE_PER_CLUSTER
598 
599 uintptr_t upmc_offs[UNCORE_NCTRS] = {
600 	[0] = 0x4100, [1] = 0x4248, [2] = 0x4110, [3] = 0x4250, [4] = 0x4120,
601 	[5] = 0x4258, [6] = 0x4130, [7] = 0x4260, [8] = 0x4140, [9] = 0x4268,
602 	[10] = 0x4150, [11] = 0x4270, [12] = 0x4160, [13] = 0x4278,
603 	[14] = 0x4170, [15] = 0x4280,
604 };
605 
606 static inline uint64_t
uncmon_read_counter_locked_r(unsigned int mon_id,unsigned int ctr)607 uncmon_read_counter_locked_r(unsigned int mon_id, unsigned int ctr)
608 {
609 	assert(mon_id < uncore_nmonitors());
610 	assert(ctr < UNCORE_NCTRS);
611 	return *(uint64_t *)(cpm_impl[mon_id] + upmc_offs[ctr]);
612 }
613 
614 static inline void
uncmon_write_counter_locked_r(unsigned int mon_id,unsigned int ctr,uint64_t count)615 uncmon_write_counter_locked_r(unsigned int mon_id, unsigned int ctr,
616     uint64_t count)
617 {
618 	assert(count < UPMC_MAX);
619 	assert(ctr < UNCORE_NCTRS);
620 	assert(mon_id < uncore_nmonitors());
621 	*(uint64_t *)(cpm_impl[mon_id] + upmc_offs[ctr]) = count;
622 }
623 
624 #endif /* UNCORE_PER_CLUSTER */
625 
626 static inline void
uncmon_update_locked(unsigned int monid,unsigned int ctr)627 uncmon_update_locked(unsigned int monid, unsigned int ctr)
628 {
629 	struct uncore_monitor *mon = &uncore_monitors[monid];
630 	if (!mon->um_sleeping) {
631 		uint64_t snap = 0;
632 #if UNCORE_PER_CLUSTER
633 		snap = uncmon_read_counter_locked_r(monid, ctr);
634 #else /* UNCORE_PER_CLUSTER */
635 		snap = uncmon_read_counter_locked_l(monid, ctr);
636 #endif /* UNCORE_PER_CLUSTER */
637 		if (snap < mon->um_snaps[ctr]) {
638 #if MACH_ASSERT
639 #if UNCORE_PER_CLUSTER
640 			uint64_t remote_value = uncmon_read_counter_locked_r(monid, ctr);
641 #endif /* UNCORE_PER_CLUSTER */
642 			panic("monotonic: UPMC%d on UPMU %d went backwards from "
643 			    "%llx to %llx, read via %s, last was %s from UPMU %hhd%s"
644 #if UNCORE_PER_CLUSTER
645 			    ", re-read remote value is %llx"
646 #endif /* UNCORE_PER_CLUSTER */
647 			    , ctr,
648 			    monid, mon->um_snaps[ctr], snap,
649 			    uncmon_get_curid() == monid ? "local" : "remote",
650 			    mon->um_last_read_id == monid ? "local" : "remote",
651 			    mon->um_last_read_id,
652 			    mon->um_read_since_sleep ? "" : ", first read since sleep"
653 #if UNCORE_PER_CLUSTER
654 			    , remote_value
655 #endif /* UNCORE_PER_CLUSTER */
656 			    );
657 #else /* MACH_ASSERT */
658 			snap = mon->um_snaps[ctr];
659 #endif /* !MACH_ASSERT */
660 		}
661 		mon->um_counts[ctr] += snap - mon->um_snaps[ctr];
662 		mon->um_snaps[ctr] = snap;
663 	}
664 }
665 
666 static inline void
uncmon_program_events_locked_l(unsigned int monid)667 uncmon_program_events_locked_l(unsigned int monid)
668 {
669 	/*
670 	 * UPMESR[01] is the event selection register that determines which event a
671 	 * counter will count.
672 	 */
673 	CTRL_REG_SET("UPMESR0_EL1", uncore_config.uc_events.uce_regs[0]);
674 
675 #if UNCORE_NCTRS > 8
676 	CTRL_REG_SET("UPMESR1_EL1", uncore_config.uc_events.uce_regs[1]);
677 #endif /* UNCORE_NCTRS > 8 */
678 
679 	/*
680 	 * UPMECM[0123] are the event core masks for each counter -- whether or not
681 	 * that counter counts events generated by an agent.  These are set to all
682 	 * ones so the uncore counters count events from all cores.
683 	 *
684 	 * The bits are based off the start of the cluster -- e.g. even if a core
685 	 * has a CPU ID of 4, it might be the first CPU in a cluster.  Shift the
686 	 * registers right by the ID of the first CPU in the cluster.
687 	 */
688 	CTRL_REG_SET("UPMECM0_EL1",
689 	    uncore_config.uc_cpu_masks[monid].uccm_regs[0]);
690 	CTRL_REG_SET("UPMECM1_EL1",
691 	    uncore_config.uc_cpu_masks[monid].uccm_regs[1]);
692 
693 #if UNCORE_NCTRS > 8
694 	CTRL_REG_SET("UPMECM2_EL1",
695 	    uncore_config.uc_cpu_masks[monid].uccm_regs[2]);
696 	CTRL_REG_SET("UPMECM3_EL1",
697 	    uncore_config.uc_cpu_masks[monid].uccm_regs[3]);
698 #endif /* UNCORE_NCTRS > 8 */
699 }
700 
701 #if UNCORE_PER_CLUSTER
702 
703 static inline void
uncmon_program_events_locked_r(unsigned int monid)704 uncmon_program_events_locked_r(unsigned int monid)
705 {
706 	const uintptr_t upmesr_offs[2] = {[0] = 0x41b0, [1] = 0x41b8, };
707 
708 	for (unsigned int i = 0; i < sizeof(upmesr_offs) / sizeof(upmesr_offs[0]);
709 	    i++) {
710 		*(uint64_t *)(cpm_impl[monid] + upmesr_offs[i]) =
711 		    uncore_config.uc_events.uce_regs[i];
712 	}
713 
714 	const uintptr_t upmecm_offs[4] = {
715 		[0] = 0x4190, [1] = 0x4198, [2] = 0x41a0, [3] = 0x41a8,
716 	};
717 
718 	for (unsigned int i = 0; i < sizeof(upmecm_offs) / sizeof(upmecm_offs[0]);
719 	    i++) {
720 		*(uint64_t *)(cpm_impl[monid] + upmecm_offs[i]) =
721 		    uncore_config.uc_cpu_masks[monid].uccm_regs[i];
722 	}
723 }
724 
725 #endif /* UNCORE_PER_CLUSTER */
726 
727 static void
uncmon_clear_int_locked_l(__unused unsigned int monid)728 uncmon_clear_int_locked_l(__unused unsigned int monid)
729 {
730 	__builtin_arm_wsr64("UPMSR_EL1", 0);
731 }
732 
733 #if UNCORE_PER_CLUSTER
734 
735 static void
uncmon_clear_int_locked_r(unsigned int monid)736 uncmon_clear_int_locked_r(unsigned int monid)
737 {
738 	const uintptr_t upmsr_off = 0x41c0;
739 	*(uint64_t *)(cpm_impl[monid] + upmsr_off) = 0;
740 }
741 
742 #endif /* UNCORE_PER_CLUSTER */
743 
744 /*
745  * Get the PMI mask for the provided `monid` -- that is, the bitmap of CPUs
746  * that should be sent PMIs for a particular monitor.
747  */
748 static uint64_t
uncmon_get_pmi_mask(unsigned int monid)749 uncmon_get_pmi_mask(unsigned int monid)
750 {
751 	uint64_t pmi_mask = uncore_pmi_mask;
752 
753 #if UNCORE_PER_CLUSTER
754 	pmi_mask &= topology_info->clusters[monid].cpu_mask;
755 #else /* UNCORE_PER_CLUSTER */
756 #pragma unused(monid)
757 #endif /* !UNCORE_PER_CLUSTER */
758 
759 	return pmi_mask;
760 }
761 
762 /*
763  * Initialization routines for the uncore counters.
764  */
765 
766 static void
uncmon_init_locked_l(unsigned int monid)767 uncmon_init_locked_l(unsigned int monid)
768 {
769 	/*
770 	 * UPMPCM defines the PMI core mask for the UPMCs -- which cores should
771 	 * receive interrupts on overflow.
772 	 */
773 	CTRL_REG_SET("UPMPCM_EL1", uncmon_get_pmi_mask(monid));
774 	uncmon_set_counting_locked_l(monid,
775 	    mt_uncore_enabled ? uncore_active_ctrs : 0);
776 }
777 
778 #if UNCORE_PER_CLUSTER
779 
780 static uintptr_t acc_impl[MAX_NMONITORS] = {};
781 
782 static void
uncmon_init_locked_r(unsigned int monid)783 uncmon_init_locked_r(unsigned int monid)
784 {
785 	const uintptr_t upmpcm_off = 0x1010;
786 
787 	*(uint64_t *)(acc_impl[monid] + upmpcm_off) = uncmon_get_pmi_mask(monid);
788 	uncmon_set_counting_locked_r(monid,
789 	    mt_uncore_enabled ? uncore_active_ctrs : 0);
790 }
791 
792 #endif /* UNCORE_PER_CLUSTER */
793 
794 /*
795  * Initialize the uncore device for monotonic.
796  */
797 static int
uncore_init(__unused mt_device_t dev)798 uncore_init(__unused mt_device_t dev)
799 {
800 #if HAS_UNCORE_CTRS
801 	assert(MT_NDEVS > 0);
802 	mt_devices[MT_NDEVS - 1].mtd_nmonitors = (uint8_t)uncore_nmonitors();
803 #endif
804 
805 #if DEVELOPMENT || DEBUG
806 	/*
807 	 * Development and debug kernels observe the `uncore_pmi_mask` boot-arg,
808 	 * allowing PMIs to be routed to the CPUs present in the supplied bitmap.
809 	 * Do some sanity checks on the value provided.
810 	 */
811 	bool parsed_arg = PE_parse_boot_argn("uncore_pmi_mask", &uncore_pmi_mask,
812 	    sizeof(uncore_pmi_mask));
813 	if (parsed_arg) {
814 #if UNCORE_PER_CLUSTER
815 		if (__builtin_popcount(uncore_pmi_mask) != (int)uncore_nmonitors()) {
816 			panic("monotonic: invalid uncore PMI mask 0x%x", uncore_pmi_mask);
817 		}
818 		for (unsigned int i = 0; i < uncore_nmonitors(); i++) {
819 			if (__builtin_popcountll(uncmon_get_pmi_mask(i)) != 1) {
820 				panic("monotonic: invalid uncore PMI CPU for cluster %d in mask 0x%x",
821 				    i, uncore_pmi_mask);
822 			}
823 		}
824 #else /* UNCORE_PER_CLUSTER */
825 		if (__builtin_popcount(uncore_pmi_mask) != 1) {
826 			panic("monotonic: invalid uncore PMI mask 0x%x", uncore_pmi_mask);
827 		}
828 #endif /* !UNCORE_PER_CLUSTER */
829 	} else
830 #endif /* DEVELOPMENT || DEBUG */
831 	{
832 		/* arbitrarily route to core 0 in each cluster */
833 		uncore_pmi_mask |= 1;
834 	}
835 	assert(uncore_pmi_mask != 0);
836 
837 	for (unsigned int monid = 0; monid < uncore_nmonitors(); monid++) {
838 #if UNCORE_PER_CLUSTER
839 		ml_topology_cluster_t *cluster = &topology_info->clusters[monid];
840 		cpm_impl[monid] = (uintptr_t)cluster->cpm_IMPL_regs;
841 		acc_impl[monid] = (uintptr_t)cluster->acc_IMPL_regs;
842 		assert(cpm_impl[monid] != 0 && acc_impl[monid] != 0);
843 #endif /* UNCORE_PER_CLUSTER */
844 
845 		struct uncore_monitor *mon = &uncore_monitors[monid];
846 		lck_spin_init(&mon->um_lock, &mt_lock_grp, LCK_ATTR_NULL);
847 	}
848 
849 	mt_uncore_initted = true;
850 
851 	return 0;
852 }
853 
854 /*
855  * Support for monotonic's mtd_read function.
856  */
857 
858 static void
uncmon_read_all_counters(unsigned int monid,uint64_t ctr_mask,uint64_t * counts)859 uncmon_read_all_counters(unsigned int monid, uint64_t ctr_mask, uint64_t *counts)
860 {
861 	struct uncore_monitor *mon = &uncore_monitors[monid];
862 
863 	int intrs_en = uncmon_lock(mon);
864 
865 	for (unsigned int ctr = 0; ctr < UNCORE_NCTRS; ctr++) {
866 		if (ctr_mask & (1ULL << ctr)) {
867 			if (!mon->um_sleeping) {
868 				uncmon_update_locked(monid, ctr);
869 			}
870 			counts[ctr] = mon->um_counts[ctr];
871 		}
872 	}
873 #if MACH_ASSERT
874 	mon->um_read_since_sleep = true;
875 #endif /* MACH_ASSERT */
876 
877 	uncmon_unlock(mon, intrs_en);
878 }
879 
880 /*
881  * Read all monitor's counters.
882  */
883 static int
uncore_read(uint64_t ctr_mask,uint64_t * counts_out)884 uncore_read(uint64_t ctr_mask, uint64_t *counts_out)
885 {
886 	assert(ctr_mask != 0);
887 	assert(counts_out != NULL);
888 
889 	if (!uncore_active_ctrs) {
890 		return EPWROFF;
891 	}
892 	if (ctr_mask & ~uncore_active_ctrs) {
893 		return EINVAL;
894 	}
895 
896 	for (unsigned int monid = 0; monid < uncore_nmonitors(); monid++) {
897 		/*
898 		 * Find this monitor's starting offset into the `counts_out` array.
899 		 */
900 		uint64_t *counts = counts_out + (UNCORE_NCTRS * monid);
901 		uncmon_read_all_counters(monid, ctr_mask, counts);
902 	}
903 
904 	return 0;
905 }
906 
907 /*
908  * Support for monotonic's mtd_add function.
909  */
910 
911 /*
912  * Add an event to the current uncore configuration.  This doesn't take effect
913  * until the counters are enabled again, so there's no need to involve the
914  * monitors.
915  */
916 static int
uncore_add(struct monotonic_config * config,uint32_t * ctr_out)917 uncore_add(struct monotonic_config *config, uint32_t *ctr_out)
918 {
919 	if (mt_uncore_enabled) {
920 		return EBUSY;
921 	}
922 
923 	uint8_t selector = (uint8_t)config->event;
924 	uint32_t available = ~uncore_active_ctrs & config->allowed_ctr_mask;
925 
926 	if (available == 0) {
927 		return ENOSPC;
928 	}
929 
930 	if (!cpc_event_allowed(CPC_HW_UPMU, selector)) {
931 		return EPERM;
932 	}
933 
934 	uint32_t valid_ctrs = (UINT32_C(1) << UNCORE_NCTRS) - 1;
935 	if ((available & valid_ctrs) == 0) {
936 		return E2BIG;
937 	}
938 	/*
939 	 * Clear the UPMCs the first time an event is added.
940 	 */
941 	if (uncore_active_ctrs == 0) {
942 		/*
943 		 * Suspend powerdown until the next reset.
944 		 */
945 		assert(!mt_uncore_suspended_cpd);
946 		suspend_cluster_powerdown();
947 		mt_uncore_suspended_cpd = true;
948 
949 		for (unsigned int monid = 0; monid < uncore_nmonitors(); monid++) {
950 			struct uncore_monitor *mon = &uncore_monitors[monid];
951 
952 			int intrs_en = uncmon_lock(mon);
953 			bool remote = uncmon_is_remote(monid);
954 
955 			if (!mon->um_sleeping) {
956 				for (unsigned int ctr = 0; ctr < UNCORE_NCTRS; ctr++) {
957 					if (remote) {
958 #if UNCORE_PER_CLUSTER
959 						uncmon_write_counter_locked_r(monid, ctr, 0);
960 #endif /* UNCORE_PER_CLUSTER */
961 					} else {
962 						uncmon_write_counter_locked_l(monid, ctr, 0);
963 					}
964 				}
965 			}
966 			memset(&mon->um_snaps, 0, sizeof(mon->um_snaps));
967 			memset(&mon->um_counts, 0, sizeof(mon->um_counts));
968 			uncmon_unlock(mon, intrs_en);
969 		}
970 	}
971 
972 	uint32_t ctr = __builtin_ffsll(available) - 1;
973 
974 	uncore_active_ctrs |= UINT64_C(1) << ctr;
975 	uncore_config.uc_events.uce_ctrs[ctr] = selector;
976 	uint64_t cpu_mask = UINT64_MAX;
977 	if (config->cpu_mask != 0) {
978 		cpu_mask = config->cpu_mask;
979 	}
980 	for (unsigned int i = 0; i < uncore_nmonitors(); i++) {
981 #if UNCORE_PER_CLUSTER
982 		const unsigned int shift = topology_info->clusters[i].first_cpu_id;
983 #else /* UNCORE_PER_CLUSTER */
984 		const unsigned int shift = 0;
985 #endif /* !UNCORE_PER_CLUSTER */
986 		uncore_config.uc_cpu_masks[i].uccm_masks[ctr] = (uint16_t)(cpu_mask >> shift);
987 	}
988 
989 	*ctr_out = ctr;
990 	return 0;
991 }
992 
993 /*
994  * Support for monotonic's mtd_reset function.
995  */
996 
997 /*
998  * Reset all configuration and disable the counters if they're currently
999  * counting.
1000  */
1001 static void
uncore_reset(void)1002 uncore_reset(void)
1003 {
1004 	mt_uncore_enabled = false;
1005 
1006 	if (!mt_uncore_suspended_cpd) {
1007 		/* If we haven't already suspended CPD, we need to do so now to ensure we can issue remote reads
1008 		 * to every cluster. */
1009 		suspend_cluster_powerdown();
1010 		mt_uncore_suspended_cpd = true;
1011 	}
1012 
1013 	if (mt_owns_counters()) {
1014 		for (unsigned int monid = 0; monid < uncore_nmonitors(); monid++) {
1015 			struct uncore_monitor *mon = &uncore_monitors[monid];
1016 
1017 			int intrs_en = uncmon_lock(mon);
1018 			bool remote = uncmon_is_remote(monid);
1019 			if (!mon->um_sleeping) {
1020 				if (remote) {
1021 #if UNCORE_PER_CLUSTER
1022 					uncmon_set_counting_locked_r(monid, 0);
1023 #endif /* UNCORE_PER_CLUSTER */
1024 				} else {
1025 					uncmon_set_counting_locked_l(monid, 0);
1026 				}
1027 
1028 				for (int ctr = 0; ctr < UNCORE_NCTRS; ctr++) {
1029 					if (uncore_active_ctrs & (1U << ctr)) {
1030 						if (remote) {
1031 #if UNCORE_PER_CLUSTER
1032 							uncmon_write_counter_locked_r(monid, ctr, 0);
1033 #endif /* UNCORE_PER_CLUSTER */
1034 						} else {
1035 							uncmon_write_counter_locked_l(monid, ctr, 0);
1036 						}
1037 					}
1038 				}
1039 			}
1040 
1041 			memset(&mon->um_snaps, 0, sizeof(mon->um_snaps));
1042 			memset(&mon->um_counts, 0, sizeof(mon->um_counts));
1043 			if (!mon->um_sleeping) {
1044 				if (remote) {
1045 #if UNCORE_PER_CLUSTER
1046 					uncmon_clear_int_locked_r(monid);
1047 #endif /* UNCORE_PER_CLUSTER */
1048 				} else {
1049 					uncmon_clear_int_locked_l(monid);
1050 				}
1051 			}
1052 
1053 			uncmon_unlock(mon, intrs_en);
1054 		}
1055 	}
1056 
1057 	uncore_active_ctrs = 0;
1058 	memset(&uncore_config, 0, sizeof(uncore_config));
1059 
1060 	if (mt_owns_counters()) {
1061 		for (unsigned int monid = 0; monid < uncore_nmonitors(); monid++) {
1062 			struct uncore_monitor *mon = &uncore_monitors[monid];
1063 
1064 			int intrs_en = uncmon_lock(mon);
1065 			bool remote = uncmon_is_remote(monid);
1066 			if (!mon->um_sleeping) {
1067 				if (remote) {
1068 	#if UNCORE_PER_CLUSTER
1069 					uncmon_program_events_locked_r(monid);
1070 	#endif /* UNCORE_PER_CLUSTER */
1071 				} else {
1072 					uncmon_program_events_locked_l(monid);
1073 				}
1074 			}
1075 			uncmon_unlock(mon, intrs_en);
1076 		}
1077 	}
1078 
1079 	/* After reset, no counters should be active, so we can allow powerdown again */
1080 	if (mt_uncore_suspended_cpd) {
1081 		resume_cluster_powerdown();
1082 		mt_uncore_suspended_cpd = false;
1083 	}
1084 }
1085 
1086 /*
1087  * Support for monotonic's mtd_enable function.
1088  */
1089 
1090 static void
uncmon_set_enabled_l_locked(unsigned int monid,bool enable)1091 uncmon_set_enabled_l_locked(unsigned int monid, bool enable)
1092 {
1093 	struct uncore_monitor *mon = &uncore_monitors[monid];
1094 #pragma unused(mon)
1095 	LCK_SPIN_ASSERT(&mon->um_lock, LCK_ASSERT_OWNED);
1096 
1097 	if (enable) {
1098 		uncmon_init_locked_l(monid);
1099 		uncmon_program_events_locked_l(monid);
1100 		uncmon_set_counting_locked_l(monid, uncore_active_ctrs);
1101 	} else {
1102 		uncmon_set_counting_locked_l(monid, 0);
1103 	}
1104 }
1105 
1106 #if UNCORE_PER_CLUSTER
1107 
1108 __unused
1109 static void
uncmon_set_enabled_r_locked(unsigned int monid,bool enable)1110 uncmon_set_enabled_r_locked(unsigned int monid, bool enable)
1111 {
1112 	struct uncore_monitor *mon = &uncore_monitors[monid];
1113 #pragma unused(mon)
1114 	LCK_SPIN_ASSERT(&mon->um_lock, LCK_ASSERT_OWNED);
1115 
1116 	if (!mon->um_sleeping) {
1117 		if (enable) {
1118 			uncmon_init_locked_r(monid);
1119 			uncmon_program_events_locked_r(monid);
1120 			uncmon_set_counting_locked_r(monid, uncore_active_ctrs);
1121 		} else {
1122 			uncmon_set_counting_locked_r(monid, 0);
1123 		}
1124 	}
1125 }
1126 
1127 #endif /* UNCORE_PER_CLUSTER */
1128 
1129 static void
uncore_set_enabled(bool enable)1130 uncore_set_enabled(bool enable)
1131 {
1132 	mt_uncore_enabled = enable;
1133 
1134 	_broadcast_each_cluster(^(unsigned int cluster_id) {
1135 		struct uncore_monitor *mon = &uncore_monitors[cluster_id];
1136 		int intrs_en = uncmon_lock(mon);
1137 		uncmon_set_enabled_l_locked(cluster_id, enable);
1138 		uncmon_unlock(mon, intrs_en);
1139 	});
1140 }
1141 
1142 /*
1143  * Hooks in the machine layer.
1144  */
1145 
1146 static void
uncore_fiq(uint64_t upmsr)1147 uncore_fiq(uint64_t upmsr)
1148 {
1149 	/*
1150 	 * Determine which counters overflowed.
1151 	 */
1152 	uint64_t disable_ctr_mask = (upmsr & UPMSR_OVF_MASK) >> UPMSR_OVF_POS;
1153 	/* should not receive interrupts from inactive counters */
1154 	assert(!(disable_ctr_mask & ~uncore_active_ctrs));
1155 
1156 	if (uncore_active_ctrs == 0) {
1157 		return;
1158 	}
1159 
1160 	unsigned int monid = uncmon_get_curid();
1161 	struct uncore_monitor *mon = &uncore_monitors[monid];
1162 
1163 	int intrs_en = uncmon_lock(mon);
1164 
1165 	/*
1166 	 * Disable any counters that overflowed.
1167 	 */
1168 	uncmon_set_counting_locked_l(monid,
1169 	    uncore_active_ctrs & ~disable_ctr_mask);
1170 
1171 	/*
1172 	 * With the overflowing counters disabled, capture their counts and reset
1173 	 * the UPMCs and their snapshots to 0.
1174 	 */
1175 	for (unsigned int ctr = 0; ctr < UNCORE_NCTRS; ctr++) {
1176 		if (UPMSR_OVF(upmsr, ctr)) {
1177 			uncmon_update_locked(monid, ctr);
1178 			mon->um_snaps[ctr] = 0;
1179 			uncmon_write_counter_locked_l(monid, ctr, 0);
1180 		}
1181 	}
1182 
1183 	/*
1184 	 * Acknowledge the interrupt, now that any overflowed PMCs have been reset.
1185 	 */
1186 	uncmon_clear_int_locked_l(monid);
1187 
1188 	/*
1189 	 * Re-enable all active counters.
1190 	 */
1191 	uncmon_set_counting_locked_l(monid, uncore_active_ctrs);
1192 
1193 	uncmon_unlock(mon, intrs_en);
1194 }
1195 
1196 static void
uncore_save(void)1197 uncore_save(void)
1198 {
1199 	if (!uncore_active_ctrs) {
1200 		return;
1201 	}
1202 
1203 	for (unsigned int monid = 0; monid < uncore_nmonitors(); monid++) {
1204 		struct uncore_monitor *mon = &uncore_monitors[monid];
1205 		int intrs_en = uncmon_lock(mon);
1206 
1207 		if (mt_uncore_enabled) {
1208 			if (uncmon_is_remote(monid)) {
1209 #if UNCORE_PER_CLUSTER
1210 				uncmon_set_counting_locked_r(monid, 0);
1211 #endif /* UNCORE_PER_CLUSTER */
1212 			} else {
1213 				uncmon_set_counting_locked_l(monid, 0);
1214 			}
1215 		}
1216 
1217 		for (unsigned int ctr = 0; ctr < UNCORE_NCTRS; ctr++) {
1218 			if (uncore_active_ctrs & (1U << ctr)) {
1219 				uncmon_update_locked(monid, ctr);
1220 				mon->um_snaps[ctr] = 0;
1221 				uncmon_write_counter_locked_l(monid, ctr, 0);
1222 			}
1223 		}
1224 
1225 		mon->um_sleeping = true;
1226 		uncmon_unlock(mon, intrs_en);
1227 	}
1228 }
1229 
1230 static void
uncore_restore(void)1231 uncore_restore(void)
1232 {
1233 	if (!uncore_active_ctrs) {
1234 		return;
1235 	}
1236 	/* Ensure interrupts disabled before reading uncmon_get_curid */
1237 	bool intr = ml_set_interrupts_enabled(false);
1238 	unsigned int curmonid = uncmon_get_curid();
1239 
1240 	struct uncore_monitor *mon = &uncore_monitors[curmonid];
1241 	int intrs_en = uncmon_lock(mon);
1242 	if (!mon->um_sleeping) {
1243 		goto out;
1244 	}
1245 
1246 	for (unsigned int ctr = 0; ctr < UNCORE_NCTRS; ctr++) {
1247 		if (uncore_active_ctrs & (1U << ctr)) {
1248 			uncmon_write_counter_locked_l(curmonid, ctr, mon->um_snaps[ctr]);
1249 		}
1250 	}
1251 	uncmon_program_events_locked_l(curmonid);
1252 	uncmon_init_locked_l(curmonid);
1253 	mon->um_sleeping = false;
1254 #if MACH_ASSERT
1255 	mon->um_read_since_sleep = false;
1256 #endif /* MACH_ASSERT */
1257 
1258 out:
1259 	uncmon_unlock(mon, intrs_en);
1260 	ml_set_interrupts_enabled(intr);
1261 }
1262 
1263 #endif /* HAS_UNCORE_CTRS */
1264 
1265 #pragma mark common hooks
1266 
1267 void
mt_early_init(void)1268 mt_early_init(void)
1269 {
1270 	topology_info = ml_get_topology_info();
1271 }
1272 
1273 void
mt_cpu_idle(cpu_data_t * cpu)1274 mt_cpu_idle(cpu_data_t *cpu)
1275 {
1276 	core_idle(cpu);
1277 }
1278 
1279 void
mt_cpu_run(cpu_data_t * cpu)1280 mt_cpu_run(cpu_data_t *cpu)
1281 {
1282 	struct mt_cpu *mtc;
1283 
1284 	assert(cpu != NULL);
1285 	assert(ml_get_interrupts_enabled() == FALSE);
1286 
1287 	mtc = &cpu->cpu_monotonic;
1288 
1289 	for (int i = 0; i < MT_CORE_NFIXED; i++) {
1290 		mt_core_set_snap(i, mtc->mtc_snaps[i]);
1291 	}
1292 
1293 	/* re-enable the counters */
1294 	core_init_execution_modes();
1295 
1296 	core_set_enabled();
1297 }
1298 
1299 void
mt_cpu_down(cpu_data_t * cpu)1300 mt_cpu_down(cpu_data_t *cpu)
1301 {
1302 	mt_cpu_idle(cpu);
1303 }
1304 
1305 void
mt_cpu_up(cpu_data_t * cpu)1306 mt_cpu_up(cpu_data_t *cpu)
1307 {
1308 	mt_cpu_run(cpu);
1309 }
1310 
1311 void
mt_sleep(void)1312 mt_sleep(void)
1313 {
1314 #if HAS_UNCORE_CTRS
1315 	uncore_save();
1316 #endif /* HAS_UNCORE_CTRS */
1317 }
1318 
1319 void
mt_wake_per_core(void)1320 mt_wake_per_core(void)
1321 {
1322 #if HAS_UNCORE_CTRS
1323 	if (mt_uncore_initted) {
1324 		uncore_restore();
1325 	}
1326 #endif /* HAS_UNCORE_CTRS */
1327 }
1328 
1329 uint64_t
mt_count_pmis(void)1330 mt_count_pmis(void)
1331 {
1332 	uint64_t npmis = 0;
1333 	for (unsigned int i = 0; i < topology_info->num_cpus; i++) {
1334 		cpu_data_t *cpu = (cpu_data_t *)CpuDataEntries[topology_info->cpus[i].cpu_id].cpu_data_vaddr;
1335 		npmis += cpu->cpu_monotonic.mtc_npmis;
1336 	}
1337 	return npmis;
1338 }
1339 
1340 static void
mt_cpu_pmi(cpu_data_t * cpu,uint64_t pmcr0)1341 mt_cpu_pmi(cpu_data_t *cpu, uint64_t pmcr0)
1342 {
1343 	assert(cpu != NULL);
1344 	assert(ml_get_interrupts_enabled() == FALSE);
1345 
1346 	__builtin_arm_wsr64("PMCR0_EL1", PMCR0_INIT);
1347 	/*
1348 	 * Ensure the CPMU has flushed any increments at this point, so PMSR is up
1349 	 * to date.
1350 	 */
1351 	__builtin_arm_isb(ISB_SY);
1352 
1353 	cpu->cpu_monotonic.mtc_npmis += 1;
1354 	cpu->cpu_stat.pmi_cnt_wake += 1;
1355 
1356 #if MONOTONIC_DEBUG
1357 	if (!PMCR0_PMI(pmcr0)) {
1358 		kprintf("monotonic: mt_cpu_pmi but no PMI (PMCR0 = %#llx)\n",
1359 		    pmcr0);
1360 	}
1361 #else /* MONOTONIC_DEBUG */
1362 #pragma unused(pmcr0)
1363 #endif /* !MONOTONIC_DEBUG */
1364 
1365 	uint64_t pmsr = __builtin_arm_rsr64("PMSR_EL1");
1366 
1367 #if MONOTONIC_DEBUG
1368 	printf("monotonic: cpu = %d, PMSR = 0x%llx, PMCR0 = 0x%llx\n",
1369 	    cpu_number(), pmsr, pmcr0);
1370 #endif /* MONOTONIC_DEBUG */
1371 
1372 #if MACH_ASSERT
1373 	uint64_t handled = 0;
1374 #endif /* MACH_ASSERT */
1375 
1376 	/*
1377 	 * monotonic handles any fixed counter PMIs.
1378 	 */
1379 	for (unsigned int i = 0; i < MT_CORE_NFIXED; i++) {
1380 		if ((pmsr & PMSR_OVF(i)) == 0) {
1381 			continue;
1382 		}
1383 
1384 #if MACH_ASSERT
1385 		handled |= 1ULL << i;
1386 #endif /* MACH_ASSERT */
1387 		uint64_t count = mt_cpu_update_count(cpu, i);
1388 		cpu->cpu_monotonic.mtc_counts[i] += count;
1389 		mt_core_set_snap(i, mt_core_reset_values[i]);
1390 		cpu->cpu_monotonic.mtc_snaps[i] = mt_core_reset_values[i];
1391 
1392 		if (mt_microstackshots && mt_microstackshot_ctr == i) {
1393 			bool user_mode = false;
1394 			arm_saved_state_t *state = get_user_regs(current_thread());
1395 			if (state) {
1396 				user_mode = PSR64_IS_USER(get_saved_state_cpsr(state));
1397 			}
1398 			KDBG_RELEASE(KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_DEBUG, 1),
1399 			    mt_microstackshot_ctr, user_mode);
1400 			mt_microstackshot_pmi_handler(user_mode, mt_microstackshot_ctx);
1401 		} else if (mt_debug) {
1402 			KDBG_RELEASE(KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_DEBUG, 2),
1403 			    i, count);
1404 		}
1405 	}
1406 
1407 	/*
1408 	 * KPC handles the configurable counter PMIs.
1409 	 */
1410 	for (unsigned int i = MT_CORE_NFIXED; i < CORE_NCTRS; i++) {
1411 		if (pmsr & PMSR_OVF(i)) {
1412 #if MACH_ASSERT
1413 			handled |= 1ULL << i;
1414 #endif /* MACH_ASSERT */
1415 			extern void kpc_pmi_handler(unsigned int ctr);
1416 			kpc_pmi_handler(i);
1417 		}
1418 	}
1419 
1420 #if MACH_ASSERT
1421 	uint64_t pmsr_after_handling = __builtin_arm_rsr64("PMSR_EL1");
1422 	if (pmsr_after_handling != 0) {
1423 		unsigned int first_ctr_ovf = __builtin_ffsll(pmsr_after_handling) - 1;
1424 		uint64_t count = 0;
1425 		const char *extra = "";
1426 		if (first_ctr_ovf >= CORE_NCTRS) {
1427 			extra = " (invalid counter)";
1428 		} else {
1429 			count = mt_core_snap(first_ctr_ovf);
1430 		}
1431 
1432 		panic("monotonic: PMI status not cleared on exit from handler, "
1433 		    "PMSR = 0x%llx HANDLE -> -> 0x%llx, handled 0x%llx, "
1434 		    "PMCR0 = 0x%llx, PMC%d = 0x%llx%s", pmsr, pmsr_after_handling,
1435 		    handled, __builtin_arm_rsr64("PMCR0_EL1"), first_ctr_ovf, count, extra);
1436 	}
1437 #endif /* MACH_ASSERT */
1438 
1439 	core_set_enabled();
1440 }
1441 
1442 #if CPMU_AIC_PMI
1443 void
mt_cpmu_aic_pmi(cpu_id_t source)1444 mt_cpmu_aic_pmi(cpu_id_t source)
1445 {
1446 	struct cpu_data *curcpu = getCpuDatap();
1447 	if (source != curcpu->interrupt_nub) {
1448 		panic("monotonic: PMI from IOCPU %p delivered to %p", source,
1449 		    curcpu->interrupt_nub);
1450 	}
1451 	mt_cpu_pmi(curcpu, __builtin_arm_rsr64("PMCR0_EL1"));
1452 }
1453 #endif /* CPMU_AIC_PMI */
1454 
1455 void
mt_fiq(void * cpu,uint64_t pmcr0,uint64_t upmsr)1456 mt_fiq(void *cpu, uint64_t pmcr0, uint64_t upmsr)
1457 {
1458 #if CPMU_AIC_PMI
1459 #pragma unused(cpu, pmcr0)
1460 #else /* CPMU_AIC_PMI */
1461 	mt_cpu_pmi(cpu, pmcr0);
1462 #endif /* !CPMU_AIC_PMI */
1463 
1464 #if HAS_UNCORE_CTRS
1465 	if (upmsr != 0) {
1466 		uncore_fiq(upmsr);
1467 	}
1468 #else /* HAS_UNCORE_CTRS */
1469 #pragma unused(upmsr)
1470 #endif /* !HAS_UNCORE_CTRS */
1471 }
1472 
1473 void
mt_ownership_change(bool available)1474 mt_ownership_change(bool available)
1475 {
1476 #if HAS_UNCORE_CTRS
1477 	/*
1478 	 * No need to take the lock here, as this is only manipulated in the UPMU
1479 	 * when the current task already owns the counters and is on its way out.
1480 	 */
1481 	if (!available && uncore_active_ctrs) {
1482 		uncore_reset();
1483 	}
1484 #else
1485 #pragma unused(available)
1486 #endif /* HAS_UNCORE_CTRS */
1487 }
1488 
1489 static uint32_t mt_xc_sync;
1490 
1491 static void
mt_microstackshot_start_remote(__unused void * arg)1492 mt_microstackshot_start_remote(__unused void *arg)
1493 {
1494 	cpu_data_t *cpu = getCpuDatap();
1495 
1496 	__builtin_arm_wsr64("PMCR0_EL1", PMCR0_INIT);
1497 
1498 	for (int i = 0; i < MT_CORE_NFIXED; i++) {
1499 		uint64_t count = mt_cpu_update_count(cpu, i);
1500 		cpu->cpu_monotonic.mtc_counts[i] += count;
1501 		mt_core_set_snap(i, mt_core_reset_values[i]);
1502 		cpu->cpu_monotonic.mtc_snaps[i] = mt_core_reset_values[i];
1503 	}
1504 
1505 	core_set_enabled();
1506 
1507 	if (os_atomic_dec(&mt_xc_sync, relaxed) == 0) {
1508 		thread_wakeup((event_t)&mt_xc_sync);
1509 	}
1510 }
1511 
1512 int
mt_microstackshot_start_arch(uint64_t period)1513 mt_microstackshot_start_arch(uint64_t period)
1514 {
1515 	uint64_t reset_value = 0;
1516 	int ovf = os_sub_overflow(CTR_MAX, period, &reset_value);
1517 	if (ovf) {
1518 		return ERANGE;
1519 	}
1520 
1521 	mt_core_reset_values[mt_microstackshot_ctr] = reset_value;
1522 	cpu_broadcast_xcall(&mt_xc_sync, TRUE, mt_microstackshot_start_remote,
1523 	    mt_microstackshot_start_remote /* cannot pass NULL */);
1524 	return 0;
1525 }
1526 
1527 #pragma mark dev nodes
1528 
1529 struct mt_device mt_devices[] = {
1530 	[0] = {
1531 		.mtd_name = "core",
1532 		.mtd_init = core_init,
1533 	},
1534 #if HAS_UNCORE_CTRS
1535 	[1] = {
1536 		.mtd_name = "uncore",
1537 		.mtd_init = uncore_init,
1538 		.mtd_add = uncore_add,
1539 		.mtd_reset = uncore_reset,
1540 		.mtd_enable = uncore_set_enabled,
1541 		.mtd_read = uncore_read,
1542 
1543 		.mtd_ncounters = UNCORE_NCTRS,
1544 	}
1545 #endif /* HAS_UNCORE_CTRS */
1546 };
1547 
1548 static_assert(
1549 	(sizeof(mt_devices) / sizeof(mt_devices[0])) == MT_NDEVS,
1550 	"MT_NDEVS macro should be same as the length of mt_devices");
1551