xref: /freebsd/sys/dev/hwpmc/hwpmc_core.c (revision 62ff619dcc3540659a319be71c9a489f1659e14a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2008 Joseph Koshy
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Intel Core PMCs.
31  */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include <sys/param.h>
37 #include <sys/bus.h>
38 #include <sys/pmc.h>
39 #include <sys/pmckern.h>
40 #include <sys/smp.h>
41 #include <sys/systm.h>
42 
43 #include <machine/intr_machdep.h>
44 #include <x86/apicvar.h>
45 #include <machine/cpu.h>
46 #include <machine/cpufunc.h>
47 #include <machine/md_var.h>
48 #include <machine/specialreg.h>
49 
50 #define	CORE_CPUID_REQUEST		0xA
51 #define	CORE_CPUID_REQUEST_SIZE		0x4
52 #define	CORE_CPUID_EAX			0x0
53 #define	CORE_CPUID_EBX			0x1
54 #define	CORE_CPUID_ECX			0x2
55 #define	CORE_CPUID_EDX			0x3
56 
57 #define	IAF_PMC_CAPS			\
58 	(PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INTERRUPT | \
59 	 PMC_CAP_USER | PMC_CAP_SYSTEM)
60 #define	IAF_RI_TO_MSR(RI)		((RI) + (1 << 30))
61 
62 #define	IAP_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | PMC_CAP_SYSTEM | \
63     PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE |	 \
64     PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE)
65 
66 #define	EV_IS_NOTARCH		0
67 #define	EV_IS_ARCH_SUPP		1
68 #define	EV_IS_ARCH_NOTSUPP	-1
69 
70 /*
71  * "Architectural" events defined by Intel.  The values of these
72  * symbols correspond to positions in the bitmask returned by
73  * the CPUID.0AH instruction.
74  */
75 enum core_arch_events {
76 	CORE_AE_BRANCH_INSTRUCTION_RETIRED	= 5,
77 	CORE_AE_BRANCH_MISSES_RETIRED		= 6,
78 	CORE_AE_INSTRUCTION_RETIRED		= 1,
79 	CORE_AE_LLC_MISSES			= 4,
80 	CORE_AE_LLC_REFERENCE			= 3,
81 	CORE_AE_UNHALTED_REFERENCE_CYCLES	= 2,
82 	CORE_AE_UNHALTED_CORE_CYCLES		= 0
83 };
84 
85 static enum pmc_cputype	core_cputype;
86 static int core_version;
87 
88 struct core_cpu {
89 	volatile uint32_t	pc_iafctrl;	/* Fixed function control. */
90 	volatile uint64_t	pc_globalctrl;	/* Global control register. */
91 	struct pmc_hw		pc_corepmcs[];
92 };
93 
94 static struct core_cpu **core_pcpu;
95 
96 static uint32_t core_architectural_events;
97 static uint64_t core_pmcmask;
98 
99 static int core_iaf_ri;		/* relative index of fixed counters */
100 static int core_iaf_width;
101 static int core_iaf_npmc;
102 
103 static int core_iap_width;
104 static int core_iap_npmc;
105 static int core_iap_wroffset;
106 
107 static u_int pmc_alloc_refs;
108 static bool pmc_tsx_force_abort_set;
109 
110 static int
111 core_pcpu_noop(struct pmc_mdep *md, int cpu)
112 {
113 	(void) md;
114 	(void) cpu;
115 	return (0);
116 }
117 
118 static int
119 core_pcpu_init(struct pmc_mdep *md, int cpu)
120 {
121 	struct pmc_cpu *pc;
122 	struct core_cpu *cc;
123 	struct pmc_hw *phw;
124 	int core_ri, n, npmc;
125 
126 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
127 	    ("[iaf,%d] insane cpu number %d", __LINE__, cpu));
128 
129 	PMCDBG1(MDP,INI,1,"core-init cpu=%d", cpu);
130 
131 	core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri;
132 	npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_num;
133 
134 	if (core_version >= 2)
135 		npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num;
136 
137 	cc = malloc(sizeof(struct core_cpu) + npmc * sizeof(struct pmc_hw),
138 	    M_PMC, M_WAITOK | M_ZERO);
139 
140 	core_pcpu[cpu] = cc;
141 	pc = pmc_pcpu[cpu];
142 
143 	KASSERT(pc != NULL && cc != NULL,
144 	    ("[core,%d] NULL per-cpu structures cpu=%d", __LINE__, cpu));
145 
146 	for (n = 0, phw = cc->pc_corepmcs; n < npmc; n++, phw++) {
147 		phw->phw_state 	  = PMC_PHW_FLAG_IS_ENABLED |
148 		    PMC_PHW_CPU_TO_STATE(cpu) |
149 		    PMC_PHW_INDEX_TO_STATE(n + core_ri);
150 		phw->phw_pmc	  = NULL;
151 		pc->pc_hwpmcs[n + core_ri]  = phw;
152 	}
153 
154 	if (core_version >= 2) {
155 		/* Enable Freezing PMCs on PMI. */
156 		wrmsr(MSR_DEBUGCTLMSR, rdmsr(MSR_DEBUGCTLMSR) | 0x1000);
157 	}
158 
159 	return (0);
160 }
161 
162 static int
163 core_pcpu_fini(struct pmc_mdep *md, int cpu)
164 {
165 	int core_ri, n, npmc;
166 	struct pmc_cpu *pc;
167 	struct core_cpu *cc;
168 
169 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
170 	    ("[core,%d] insane cpu number (%d)", __LINE__, cpu));
171 
172 	PMCDBG1(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu);
173 
174 	if ((cc = core_pcpu[cpu]) == NULL)
175 		return (0);
176 
177 	core_pcpu[cpu] = NULL;
178 
179 	pc = pmc_pcpu[cpu];
180 
181 	KASSERT(pc != NULL, ("[core,%d] NULL per-cpu %d state", __LINE__,
182 		cpu));
183 
184 	npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_num;
185 	core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri;
186 
187 	for (n = 0; n < npmc; n++)
188 		wrmsr(IAP_EVSEL0 + n, 0);
189 
190 	if (core_version >= 2) {
191 		wrmsr(IAF_CTRL, 0);
192 		npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num;
193 	}
194 
195 	for (n = 0; n < npmc; n++)
196 		pc->pc_hwpmcs[n + core_ri] = NULL;
197 
198 	free(cc, M_PMC);
199 
200 	return (0);
201 }
202 
203 /*
204  * Fixed function counters.
205  */
206 
207 static pmc_value_t
208 iaf_perfctr_value_to_reload_count(pmc_value_t v)
209 {
210 
211 	/* If the PMC has overflowed, return a reload count of zero. */
212 	if ((v & (1ULL << (core_iaf_width - 1))) == 0)
213 		return (0);
214 	v &= (1ULL << core_iaf_width) - 1;
215 	return (1ULL << core_iaf_width) - v;
216 }
217 
218 static pmc_value_t
219 iaf_reload_count_to_perfctr_value(pmc_value_t rlc)
220 {
221 	return (1ULL << core_iaf_width) - rlc;
222 }
223 
224 static int
225 iaf_allocate_pmc(int cpu, int ri, struct pmc *pm,
226     const struct pmc_op_pmcallocate *a)
227 {
228 	uint8_t ev, umask;
229 	uint32_t caps, flags, config;
230 	const struct pmc_md_iap_op_pmcallocate *iap;
231 
232 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
233 	    ("[core,%d] illegal CPU %d", __LINE__, cpu));
234 
235 	PMCDBG2(MDP,ALL,1, "iaf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps);
236 
237 	if (ri < 0 || ri > core_iaf_npmc)
238 		return (EINVAL);
239 
240 	if (a->pm_class != PMC_CLASS_IAF)
241 		return (EINVAL);
242 
243 	iap = &a->pm_md.pm_iap;
244 	config = iap->pm_iap_config;
245 	ev = IAP_EVSEL_GET(config);
246 	umask = IAP_UMASK_GET(config);
247 
248 	/* INST_RETIRED.ANY */
249 	if (ev == 0xC0 && ri != 0)
250 		return (EINVAL);
251 	/* CPU_CLK_UNHALTED.THREAD */
252 	if (ev == 0x3C && ri != 1)
253 		return (EINVAL);
254 	/* CPU_CLK_UNHALTED.REF */
255 	if (ev == 0x0 && umask == 0x3 && ri != 2)
256 		return (EINVAL);
257 
258 	pmc_alloc_refs++;
259 	if ((cpu_stdext_feature3 & CPUID_STDEXT3_TSXFA) != 0 &&
260 	    !pmc_tsx_force_abort_set) {
261 		pmc_tsx_force_abort_set = true;
262 		x86_msr_op(MSR_TSX_FORCE_ABORT, MSR_OP_RENDEZVOUS_ALL |
263 		    MSR_OP_WRITE, 1, NULL);
264 	}
265 
266 	flags = 0;
267 	if (config & IAP_OS)
268 		flags |= IAF_OS;
269 	if (config & IAP_USR)
270 		flags |= IAF_USR;
271 	if (config & IAP_ANY)
272 		flags |= IAF_ANY;
273 	if (config & IAP_INT)
274 		flags |= IAF_PMI;
275 
276 	caps = a->pm_caps;
277 	if (caps & PMC_CAP_INTERRUPT)
278 		flags |= IAF_PMI;
279 	if (caps & PMC_CAP_SYSTEM)
280 		flags |= IAF_OS;
281 	if (caps & PMC_CAP_USER)
282 		flags |= IAF_USR;
283 	if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0)
284 		flags |= (IAF_OS | IAF_USR);
285 
286 	pm->pm_md.pm_iaf.pm_iaf_ctrl = (flags << (ri * 4));
287 
288 	PMCDBG1(MDP,ALL,2, "iaf-allocate config=0x%jx",
289 	    (uintmax_t) pm->pm_md.pm_iaf.pm_iaf_ctrl);
290 
291 	return (0);
292 }
293 
294 static int
295 iaf_config_pmc(int cpu, int ri, struct pmc *pm)
296 {
297 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
298 	    ("[core,%d] illegal CPU %d", __LINE__, cpu));
299 
300 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
301 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
302 
303 	PMCDBG3(MDP,CFG,1, "iaf-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
304 
305 	KASSERT(core_pcpu[cpu] != NULL, ("[core,%d] null per-cpu %d", __LINE__,
306 	    cpu));
307 
308 	core_pcpu[cpu]->pc_corepmcs[ri + core_iaf_ri].phw_pmc = pm;
309 
310 	return (0);
311 }
312 
313 static int
314 iaf_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
315 {
316 	int error;
317 	struct pmc_hw *phw;
318 	char iaf_name[PMC_NAME_MAX];
319 
320 	phw = &core_pcpu[cpu]->pc_corepmcs[ri + core_iaf_ri];
321 
322 	(void) snprintf(iaf_name, sizeof(iaf_name), "IAF-%d", ri);
323 	if ((error = copystr(iaf_name, pi->pm_name, PMC_NAME_MAX,
324 	    NULL)) != 0)
325 		return (error);
326 
327 	pi->pm_class = PMC_CLASS_IAF;
328 
329 	if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
330 		pi->pm_enabled = TRUE;
331 		*ppmc          = phw->phw_pmc;
332 	} else {
333 		pi->pm_enabled = FALSE;
334 		*ppmc          = NULL;
335 	}
336 
337 	return (0);
338 }
339 
340 static int
341 iaf_get_config(int cpu, int ri, struct pmc **ppm)
342 {
343 	*ppm = core_pcpu[cpu]->pc_corepmcs[ri + core_iaf_ri].phw_pmc;
344 
345 	return (0);
346 }
347 
348 static int
349 iaf_get_msr(int ri, uint32_t *msr)
350 {
351 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
352 	    ("[iaf,%d] ri %d out of range", __LINE__, ri));
353 
354 	*msr = IAF_RI_TO_MSR(ri);
355 
356 	return (0);
357 }
358 
359 static int
360 iaf_read_pmc(int cpu, int ri, pmc_value_t *v)
361 {
362 	struct pmc *pm;
363 	pmc_value_t tmp;
364 
365 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
366 	    ("[core,%d] illegal cpu value %d", __LINE__, cpu));
367 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
368 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
369 
370 	pm = core_pcpu[cpu]->pc_corepmcs[ri + core_iaf_ri].phw_pmc;
371 
372 	KASSERT(pm,
373 	    ("[core,%d] cpu %d ri %d(%d) pmc not configured", __LINE__, cpu,
374 		ri, ri + core_iaf_ri));
375 
376 	tmp = rdpmc(IAF_RI_TO_MSR(ri));
377 
378 	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
379 		*v = iaf_perfctr_value_to_reload_count(tmp);
380 	else
381 		*v = tmp & ((1ULL << core_iaf_width) - 1);
382 
383 	PMCDBG4(MDP,REA,1, "iaf-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
384 	    IAF_RI_TO_MSR(ri), *v);
385 
386 	return (0);
387 }
388 
389 static int
390 iaf_release_pmc(int cpu, int ri, struct pmc *pmc)
391 {
392 	PMCDBG3(MDP,REL,1, "iaf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc);
393 
394 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
395 	    ("[core,%d] illegal CPU value %d", __LINE__, cpu));
396 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
397 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
398 
399 	KASSERT(core_pcpu[cpu]->pc_corepmcs[ri + core_iaf_ri].phw_pmc == NULL,
400 	    ("[core,%d] PHW pmc non-NULL", __LINE__));
401 
402 	MPASS(pmc_alloc_refs > 0);
403 	if (pmc_alloc_refs-- == 1 && pmc_tsx_force_abort_set) {
404 		pmc_tsx_force_abort_set = false;
405 		x86_msr_op(MSR_TSX_FORCE_ABORT, MSR_OP_RENDEZVOUS_ALL |
406 		    MSR_OP_WRITE, 0, NULL);
407 	}
408 
409 	return (0);
410 }
411 
412 static int
413 iaf_start_pmc(int cpu, int ri)
414 {
415 	struct pmc *pm;
416 	struct core_cpu *cc;
417 
418 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
419 	    ("[core,%d] illegal CPU value %d", __LINE__, cpu));
420 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
421 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
422 
423 	PMCDBG2(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri);
424 
425 	cc = core_pcpu[cpu];
426 	pm = cc->pc_corepmcs[ri + core_iaf_ri].phw_pmc;
427 
428 	cc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl;
429 	wrmsr(IAF_CTRL, cc->pc_iafctrl);
430 
431 	cc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET));
432 	wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
433 
434 	PMCDBG4(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)",
435 	    cc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL),
436 	    cc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL));
437 
438 	return (0);
439 }
440 
441 static int
442 iaf_stop_pmc(int cpu, int ri)
443 {
444 	struct core_cpu *cc;
445 
446 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
447 	    ("[core,%d] illegal CPU value %d", __LINE__, cpu));
448 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
449 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
450 
451 	PMCDBG2(MDP,STA,1,"iaf-stop cpu=%d ri=%d", cpu, ri);
452 
453 	cc = core_pcpu[cpu];
454 
455 	cc->pc_iafctrl &= ~(IAF_MASK << (ri * 4));
456 	wrmsr(IAF_CTRL, cc->pc_iafctrl);
457 
458 	cc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET));
459 	wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
460 
461 	PMCDBG4(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)",
462 	    cc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL),
463 	    cc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL));
464 
465 	return (0);
466 }
467 
468 static int
469 iaf_write_pmc(int cpu, int ri, pmc_value_t v)
470 {
471 	struct core_cpu *cc;
472 	struct pmc *pm;
473 
474 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
475 	    ("[core,%d] illegal cpu value %d", __LINE__, cpu));
476 	KASSERT(ri >= 0 && ri < core_iaf_npmc,
477 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
478 
479 	cc = core_pcpu[cpu];
480 	pm = cc->pc_corepmcs[ri + core_iaf_ri].phw_pmc;
481 
482 	KASSERT(pm,
483 	    ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
484 
485 	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
486 		v = iaf_reload_count_to_perfctr_value(v);
487 
488 	/* Turn off the fixed counter */
489 	wrmsr(IAF_CTRL, cc->pc_iafctrl & ~(IAF_MASK << (ri * 4)));
490 
491 	wrmsr(IAF_CTR0 + ri, v & ((1ULL << core_iaf_width) - 1));
492 
493 	/* Turn on fixed counters */
494 	wrmsr(IAF_CTRL, cc->pc_iafctrl);
495 
496 	PMCDBG6(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx "
497 	    "pmc=%jx", cpu, ri, IAF_RI_TO_MSR(ri), v,
498 	    (uintmax_t) rdmsr(IAF_CTRL),
499 	    (uintmax_t) rdpmc(IAF_RI_TO_MSR(ri)));
500 
501 	return (0);
502 }
503 
504 
505 static void
506 iaf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth)
507 {
508 	struct pmc_classdep *pcd;
509 
510 	KASSERT(md != NULL, ("[iaf,%d] md is NULL", __LINE__));
511 
512 	PMCDBG0(MDP,INI,1, "iaf-initialize");
513 
514 	pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF];
515 
516 	pcd->pcd_caps	= IAF_PMC_CAPS;
517 	pcd->pcd_class	= PMC_CLASS_IAF;
518 	pcd->pcd_num	= npmc;
519 	pcd->pcd_ri	= md->pmd_npmc;
520 	pcd->pcd_width	= pmcwidth;
521 
522 	pcd->pcd_allocate_pmc	= iaf_allocate_pmc;
523 	pcd->pcd_config_pmc	= iaf_config_pmc;
524 	pcd->pcd_describe	= iaf_describe;
525 	pcd->pcd_get_config	= iaf_get_config;
526 	pcd->pcd_get_msr	= iaf_get_msr;
527 	pcd->pcd_pcpu_fini	= core_pcpu_noop;
528 	pcd->pcd_pcpu_init	= core_pcpu_noop;
529 	pcd->pcd_read_pmc	= iaf_read_pmc;
530 	pcd->pcd_release_pmc	= iaf_release_pmc;
531 	pcd->pcd_start_pmc	= iaf_start_pmc;
532 	pcd->pcd_stop_pmc	= iaf_stop_pmc;
533 	pcd->pcd_write_pmc	= iaf_write_pmc;
534 
535 	md->pmd_npmc	       += npmc;
536 }
537 
538 /*
539  * Intel programmable PMCs.
540  */
541 
542 /* Sub fields of UMASK that this event supports. */
543 #define	IAP_M_CORE		(1 << 0) /* Core specificity */
544 #define	IAP_M_AGENT		(1 << 1) /* Agent specificity */
545 #define	IAP_M_PREFETCH		(1 << 2) /* Prefetch */
546 #define	IAP_M_MESI		(1 << 3) /* MESI */
547 #define	IAP_M_SNOOPRESPONSE	(1 << 4) /* Snoop response */
548 #define	IAP_M_SNOOPTYPE		(1 << 5) /* Snoop type */
549 #define	IAP_M_TRANSITION	(1 << 6) /* Transition */
550 
551 #define	IAP_F_CORE		(0x3 << 14) /* Core specificity */
552 #define	IAP_F_AGENT		(0x1 << 13) /* Agent specificity */
553 #define	IAP_F_PREFETCH		(0x3 << 12) /* Prefetch */
554 #define	IAP_F_MESI		(0xF <<  8) /* MESI */
555 #define	IAP_F_SNOOPRESPONSE	(0xB <<  8) /* Snoop response */
556 #define	IAP_F_SNOOPTYPE		(0x3 <<  8) /* Snoop type */
557 #define	IAP_F_TRANSITION	(0x1 << 12) /* Transition */
558 
559 #define	IAP_PREFETCH_RESERVED	(0x2 << 12)
560 #define	IAP_CORE_THIS		(0x1 << 14)
561 #define	IAP_CORE_ALL		(0x3 << 14)
562 #define	IAP_F_CMASK		0xFF000000
563 
564 static pmc_value_t
565 iap_perfctr_value_to_reload_count(pmc_value_t v)
566 {
567 
568 	/* If the PMC has overflowed, return a reload count of zero. */
569 	if ((v & (1ULL << (core_iap_width - 1))) == 0)
570 		return (0);
571 	v &= (1ULL << core_iap_width) - 1;
572 	return (1ULL << core_iap_width) - v;
573 }
574 
575 static pmc_value_t
576 iap_reload_count_to_perfctr_value(pmc_value_t rlc)
577 {
578 	return (1ULL << core_iap_width) - rlc;
579 }
580 
581 static int
582 iap_pmc_has_overflowed(int ri)
583 {
584 	uint64_t v;
585 
586 	/*
587 	 * We treat a Core (i.e., Intel architecture v1) PMC as has
588 	 * having overflowed if its MSB is zero.
589 	 */
590 	v = rdpmc(ri);
591 	return ((v & (1ULL << (core_iap_width - 1))) == 0);
592 }
593 
594 static int
595 iap_event_corei7_ok_on_counter(uint8_t evsel, int ri)
596 {
597 	uint32_t mask;
598 
599 	switch (evsel) {
600 		/*
601 		 * Events valid only on counter 0, 1.
602 		 */
603 		case 0x40:
604 		case 0x41:
605 		case 0x42:
606 		case 0x43:
607 		case 0x51:
608 		case 0x63:
609 			mask = 0x3;
610 		break;
611 
612 		default:
613 		mask = ~0;	/* Any row index is ok. */
614 	}
615 
616 	return (mask & (1 << ri));
617 }
618 
619 static int
620 iap_event_westmere_ok_on_counter(uint8_t evsel, int ri)
621 {
622 	uint32_t mask;
623 
624 	switch (evsel) {
625 		/*
626 		 * Events valid only on counter 0.
627 		 */
628 		case 0x60:
629 		case 0xB3:
630 		mask = 0x1;
631 		break;
632 
633 		/*
634 		 * Events valid only on counter 0, 1.
635 		 */
636 		case 0x4C:
637 		case 0x4E:
638 		case 0x51:
639 		case 0x63:
640 		mask = 0x3;
641 		break;
642 
643 	default:
644 		mask = ~0;	/* Any row index is ok. */
645 	}
646 
647 	return (mask & (1 << ri));
648 }
649 
650 static int
651 iap_event_sb_sbx_ib_ibx_ok_on_counter(uint8_t evsel, int ri)
652 {
653 	uint32_t mask;
654 
655 	switch (evsel) {
656 		/* Events valid only on counter 0. */
657     case 0xB7:
658 		mask = 0x1;
659 		break;
660 		/* Events valid only on counter 1. */
661 	case 0xC0:
662 		mask = 0x2;
663 		break;
664 		/* Events valid only on counter 2. */
665 	case 0x48:
666 	case 0xA2:
667 	case 0xA3:
668 		mask = 0x4;
669 		break;
670 		/* Events valid only on counter 3. */
671 	case 0xBB:
672 	case 0xCD:
673 		mask = 0x8;
674 		break;
675 	default:
676 		mask = ~0;	/* Any row index is ok. */
677 	}
678 
679 	return (mask & (1 << ri));
680 }
681 
682 static int
683 iap_event_ok_on_counter(uint8_t evsel, int ri)
684 {
685 	uint32_t mask;
686 
687 	switch (evsel) {
688 		/*
689 		 * Events valid only on counter 0.
690 		 */
691 	case 0x10:
692 	case 0x14:
693 	case 0x18:
694 	case 0xB3:
695 	case 0xC1:
696 	case 0xCB:
697 		mask = (1 << 0);
698 		break;
699 
700 		/*
701 		 * Events valid only on counter 1.
702 		 */
703 	case 0x11:
704 	case 0x12:
705 	case 0x13:
706 		mask = (1 << 1);
707 		break;
708 
709 	default:
710 		mask = ~0;	/* Any row index is ok. */
711 	}
712 
713 	return (mask & (1 << ri));
714 }
715 
716 static int
717 iap_allocate_pmc(int cpu, int ri, struct pmc *pm,
718     const struct pmc_op_pmcallocate *a)
719 {
720 	uint8_t ev;
721 	const struct pmc_md_iap_op_pmcallocate *iap;
722 
723 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
724 	    ("[core,%d] illegal CPU %d", __LINE__, cpu));
725 	KASSERT(ri >= 0 && ri < core_iap_npmc,
726 	    ("[core,%d] illegal row-index value %d", __LINE__, ri));
727 
728 	if (a->pm_class != PMC_CLASS_IAP)
729 		return (EINVAL);
730 
731 	iap = &a->pm_md.pm_iap;
732 	ev = IAP_EVSEL_GET(iap->pm_iap_config);
733 
734 	switch (core_cputype) {
735 	case PMC_CPU_INTEL_COREI7:
736 	case PMC_CPU_INTEL_NEHALEM_EX:
737 		if (iap_event_corei7_ok_on_counter(ev, ri) == 0)
738 			return (EINVAL);
739 		break;
740 	case PMC_CPU_INTEL_SKYLAKE:
741 	case PMC_CPU_INTEL_SKYLAKE_XEON:
742 	case PMC_CPU_INTEL_ICELAKE:
743 	case PMC_CPU_INTEL_ICELAKE_XEON:
744 	case PMC_CPU_INTEL_BROADWELL:
745 	case PMC_CPU_INTEL_BROADWELL_XEON:
746 	case PMC_CPU_INTEL_SANDYBRIDGE:
747 	case PMC_CPU_INTEL_SANDYBRIDGE_XEON:
748 	case PMC_CPU_INTEL_IVYBRIDGE:
749 	case PMC_CPU_INTEL_IVYBRIDGE_XEON:
750 	case PMC_CPU_INTEL_HASWELL:
751 	case PMC_CPU_INTEL_HASWELL_XEON:
752 		if (iap_event_sb_sbx_ib_ibx_ok_on_counter(ev, ri) == 0)
753 			return (EINVAL);
754 		break;
755 	case PMC_CPU_INTEL_WESTMERE:
756 	case PMC_CPU_INTEL_WESTMERE_EX:
757 		if (iap_event_westmere_ok_on_counter(ev, ri) == 0)
758 			return (EINVAL);
759 		break;
760 	default:
761 		if (iap_event_ok_on_counter(ev, ri) == 0)
762 			return (EINVAL);
763 	}
764 
765 	pm->pm_md.pm_iap.pm_iap_evsel = iap->pm_iap_config;
766 	return (0);
767 }
768 
769 static int
770 iap_config_pmc(int cpu, int ri, struct pmc *pm)
771 {
772 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
773 	    ("[core,%d] illegal CPU %d", __LINE__, cpu));
774 
775 	KASSERT(ri >= 0 && ri < core_iap_npmc,
776 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
777 
778 	PMCDBG3(MDP,CFG,1, "iap-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
779 
780 	KASSERT(core_pcpu[cpu] != NULL, ("[core,%d] null per-cpu %d", __LINE__,
781 	    cpu));
782 
783 	core_pcpu[cpu]->pc_corepmcs[ri].phw_pmc = pm;
784 
785 	return (0);
786 }
787 
788 static int
789 iap_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
790 {
791 	int error;
792 	struct pmc_hw *phw;
793 	char iap_name[PMC_NAME_MAX];
794 
795 	phw = &core_pcpu[cpu]->pc_corepmcs[ri];
796 
797 	(void) snprintf(iap_name, sizeof(iap_name), "IAP-%d", ri);
798 	if ((error = copystr(iap_name, pi->pm_name, PMC_NAME_MAX,
799 	    NULL)) != 0)
800 		return (error);
801 
802 	pi->pm_class = PMC_CLASS_IAP;
803 
804 	if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
805 		pi->pm_enabled = TRUE;
806 		*ppmc          = phw->phw_pmc;
807 	} else {
808 		pi->pm_enabled = FALSE;
809 		*ppmc          = NULL;
810 	}
811 
812 	return (0);
813 }
814 
815 static int
816 iap_get_config(int cpu, int ri, struct pmc **ppm)
817 {
818 	*ppm = core_pcpu[cpu]->pc_corepmcs[ri].phw_pmc;
819 
820 	return (0);
821 }
822 
823 static int
824 iap_get_msr(int ri, uint32_t *msr)
825 {
826 	KASSERT(ri >= 0 && ri < core_iap_npmc,
827 	    ("[iap,%d] ri %d out of range", __LINE__, ri));
828 
829 	*msr = ri;
830 
831 	return (0);
832 }
833 
834 static int
835 iap_read_pmc(int cpu, int ri, pmc_value_t *v)
836 {
837 	struct pmc *pm;
838 	pmc_value_t tmp;
839 
840 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
841 	    ("[core,%d] illegal cpu value %d", __LINE__, cpu));
842 	KASSERT(ri >= 0 && ri < core_iap_npmc,
843 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
844 
845 	pm = core_pcpu[cpu]->pc_corepmcs[ri].phw_pmc;
846 
847 	KASSERT(pm,
848 	    ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu,
849 		ri));
850 
851 	tmp = rdpmc(ri);
852 	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
853 		*v = iap_perfctr_value_to_reload_count(tmp);
854 	else
855 		*v = tmp & ((1ULL << core_iap_width) - 1);
856 
857 	PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
858 	    IAP_PMC0 + ri, *v);
859 
860 	return (0);
861 }
862 
863 static int
864 iap_release_pmc(int cpu, int ri, struct pmc *pm)
865 {
866 	(void) pm;
867 
868 	PMCDBG3(MDP,REL,1, "iap-release cpu=%d ri=%d pm=%p", cpu, ri,
869 	    pm);
870 
871 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
872 	    ("[core,%d] illegal CPU value %d", __LINE__, cpu));
873 	KASSERT(ri >= 0 && ri < core_iap_npmc,
874 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
875 
876 	KASSERT(core_pcpu[cpu]->pc_corepmcs[ri].phw_pmc
877 	    == NULL, ("[core,%d] PHW pmc non-NULL", __LINE__));
878 
879 	return (0);
880 }
881 
882 static int
883 iap_start_pmc(int cpu, int ri)
884 {
885 	struct pmc *pm;
886 	uint32_t evsel;
887 	struct core_cpu *cc;
888 
889 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
890 	    ("[core,%d] illegal CPU value %d", __LINE__, cpu));
891 	KASSERT(ri >= 0 && ri < core_iap_npmc,
892 	    ("[core,%d] illegal row-index %d", __LINE__, ri));
893 
894 	cc = core_pcpu[cpu];
895 	pm = cc->pc_corepmcs[ri].phw_pmc;
896 
897 	KASSERT(pm,
898 	    ("[core,%d] starting cpu%d,ri%d with no pmc configured",
899 		__LINE__, cpu, ri));
900 
901 	PMCDBG2(MDP,STA,1, "iap-start cpu=%d ri=%d", cpu, ri);
902 
903 	evsel = pm->pm_md.pm_iap.pm_iap_evsel;
904 
905 	PMCDBG4(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
906 	    cpu, ri, IAP_EVSEL0 + ri, evsel);
907 
908 	/* Event specific configuration. */
909 
910 	switch (IAP_EVSEL_GET(evsel)) {
911 	case 0xB7:
912 		wrmsr(IA_OFFCORE_RSP0, pm->pm_md.pm_iap.pm_iap_rsp);
913 		break;
914 	case 0xBB:
915 		wrmsr(IA_OFFCORE_RSP1, pm->pm_md.pm_iap.pm_iap_rsp);
916 		break;
917 	default:
918 		break;
919 	}
920 
921 	wrmsr(IAP_EVSEL0 + ri, evsel | IAP_EN);
922 
923 	if (core_version >= 2) {
924 		cc->pc_globalctrl |= (1ULL << ri);
925 		wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
926 	}
927 
928 	return (0);
929 }
930 
931 static int
932 iap_stop_pmc(int cpu, int ri)
933 {
934 	struct pmc *pm __diagused;
935 	struct core_cpu *cc;
936 
937 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
938 	    ("[core,%d] illegal cpu value %d", __LINE__, cpu));
939 	KASSERT(ri >= 0 && ri < core_iap_npmc,
940 	    ("[core,%d] illegal row index %d", __LINE__, ri));
941 
942 	cc = core_pcpu[cpu];
943 	pm = cc->pc_corepmcs[ri].phw_pmc;
944 
945 	KASSERT(pm,
946 	    ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
947 		cpu, ri));
948 
949 	PMCDBG2(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri);
950 
951 	wrmsr(IAP_EVSEL0 + ri, 0);
952 
953 	if (core_version >= 2) {
954 		cc->pc_globalctrl &= ~(1ULL << ri);
955 		wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
956 	}
957 
958 	return (0);
959 }
960 
961 static int
962 iap_write_pmc(int cpu, int ri, pmc_value_t v)
963 {
964 	struct pmc *pm;
965 	struct core_cpu *cc;
966 
967 	KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
968 	    ("[core,%d] illegal cpu value %d", __LINE__, cpu));
969 	KASSERT(ri >= 0 && ri < core_iap_npmc,
970 	    ("[core,%d] illegal row index %d", __LINE__, ri));
971 
972 	cc = core_pcpu[cpu];
973 	pm = cc->pc_corepmcs[ri].phw_pmc;
974 
975 	KASSERT(pm,
976 	    ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
977 		cpu, ri));
978 
979 	if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
980 		v = iap_reload_count_to_perfctr_value(v);
981 
982 	v &= (1ULL << core_iap_width) - 1;
983 
984 	PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
985 	    IAP_PMC0 + ri, v);
986 
987 	/*
988 	 * Write the new value to the counter (or it's alias).  The
989 	 * counter will be in a stopped state when the pcd_write()
990 	 * entry point is called.
991 	 */
992 	wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v);
993 	return (0);
994 }
995 
996 
997 static void
998 iap_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth,
999     int flags)
1000 {
1001 	struct pmc_classdep *pcd;
1002 
1003 	KASSERT(md != NULL, ("[iap,%d] md is NULL", __LINE__));
1004 
1005 	PMCDBG0(MDP,INI,1, "iap-initialize");
1006 
1007 	/* Remember the set of architectural events supported. */
1008 	core_architectural_events = ~flags;
1009 
1010 	pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP];
1011 
1012 	pcd->pcd_caps	= IAP_PMC_CAPS;
1013 	pcd->pcd_class	= PMC_CLASS_IAP;
1014 	pcd->pcd_num	= npmc;
1015 	pcd->pcd_ri	= md->pmd_npmc;
1016 	pcd->pcd_width	= pmcwidth;
1017 
1018 	pcd->pcd_allocate_pmc	= iap_allocate_pmc;
1019 	pcd->pcd_config_pmc	= iap_config_pmc;
1020 	pcd->pcd_describe	= iap_describe;
1021 	pcd->pcd_get_config	= iap_get_config;
1022 	pcd->pcd_get_msr	= iap_get_msr;
1023 	pcd->pcd_pcpu_fini	= core_pcpu_fini;
1024 	pcd->pcd_pcpu_init	= core_pcpu_init;
1025 	pcd->pcd_read_pmc	= iap_read_pmc;
1026 	pcd->pcd_release_pmc	= iap_release_pmc;
1027 	pcd->pcd_start_pmc	= iap_start_pmc;
1028 	pcd->pcd_stop_pmc	= iap_stop_pmc;
1029 	pcd->pcd_write_pmc	= iap_write_pmc;
1030 
1031 	md->pmd_npmc	       += npmc;
1032 }
1033 
1034 static int
1035 core_intr(struct trapframe *tf)
1036 {
1037 	pmc_value_t v;
1038 	struct pmc *pm;
1039 	struct core_cpu *cc;
1040 	int error, found_interrupt, ri;
1041 
1042 	PMCDBG3(MDP,INT, 1, "cpu=%d tf=%p um=%d", curcpu, (void *) tf,
1043 	    TRAPF_USERMODE(tf));
1044 
1045 	found_interrupt = 0;
1046 	cc = core_pcpu[curcpu];
1047 
1048 	for (ri = 0; ri < core_iap_npmc; ri++) {
1049 
1050 		if ((pm = cc->pc_corepmcs[ri].phw_pmc) == NULL ||
1051 		    !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
1052 			continue;
1053 
1054 		if (!iap_pmc_has_overflowed(ri))
1055 			continue;
1056 
1057 		found_interrupt = 1;
1058 
1059 		if (pm->pm_state != PMC_STATE_RUNNING)
1060 			continue;
1061 
1062 		error = pmc_process_interrupt(PMC_HR, pm, tf);
1063 
1064 		v = pm->pm_sc.pm_reloadcount;
1065 		v = iap_reload_count_to_perfctr_value(v);
1066 
1067 		/*
1068 		 * Stop the counter, reload it but only restart it if
1069 		 * the PMC is not stalled.
1070 		 */
1071 		wrmsr(IAP_EVSEL0 + ri, pm->pm_md.pm_iap.pm_iap_evsel);
1072 		wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v);
1073 
1074 		if (__predict_false(error))
1075 			continue;
1076 
1077 		wrmsr(IAP_EVSEL0 + ri, pm->pm_md.pm_iap.pm_iap_evsel | IAP_EN);
1078 	}
1079 
1080 	if (found_interrupt)
1081 		counter_u64_add(pmc_stats.pm_intr_processed, 1);
1082 	else
1083 		counter_u64_add(pmc_stats.pm_intr_ignored, 1);
1084 
1085 	if (found_interrupt)
1086 		lapic_reenable_pmc();
1087 
1088 	return (found_interrupt);
1089 }
1090 
1091 static int
1092 core2_intr(struct trapframe *tf)
1093 {
1094 	int error, found_interrupt = 0, n, cpu;
1095 	uint64_t flag, intrstatus, intrdisable = 0;
1096 	struct pmc *pm;
1097 	struct core_cpu *cc;
1098 	pmc_value_t v;
1099 
1100 	cpu = curcpu;
1101 	PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
1102 	    TRAPF_USERMODE(tf));
1103 
1104 	/*
1105 	 * The IA_GLOBAL_STATUS (MSR 0x38E) register indicates which
1106 	 * PMCs have a pending PMI interrupt.  We take a 'snapshot' of
1107 	 * the current set of interrupting PMCs and process these
1108 	 * after stopping them.
1109 	 */
1110 	intrstatus = rdmsr(IA_GLOBAL_STATUS);
1111 	PMCDBG2(MDP,INT, 1, "cpu=%d intrstatus=%jx", cpu,
1112 	    (uintmax_t) intrstatus);
1113 
1114 	/*
1115 	 * Stop PMCs unless hardware already done it.
1116 	 */
1117 	if ((intrstatus & IA_GLOBAL_STATUS_FLAG_CTR_FRZ) == 0)
1118 		wrmsr(IA_GLOBAL_CTRL, 0);
1119 
1120 	cc = core_pcpu[cpu];
1121 	KASSERT(cc != NULL, ("[core,%d] null pcpu", __LINE__));
1122 
1123 	/*
1124 	 * Look for interrupts from fixed function PMCs.
1125 	 */
1126 	for (n = 0, flag = (1ULL << IAF_OFFSET); n < core_iaf_npmc;
1127 	     n++, flag <<= 1) {
1128 
1129 		if ((intrstatus & flag) == 0)
1130 			continue;
1131 
1132 		found_interrupt = 1;
1133 
1134 		pm = cc->pc_corepmcs[n + core_iaf_ri].phw_pmc;
1135 		if (pm == NULL || pm->pm_state != PMC_STATE_RUNNING ||
1136 		    !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
1137 			continue;
1138 
1139 		error = pmc_process_interrupt(PMC_HR, pm, tf);
1140 		if (__predict_false(error))
1141 			intrdisable |= flag;
1142 
1143 		v = iaf_reload_count_to_perfctr_value(pm->pm_sc.pm_reloadcount);
1144 
1145 		/* Reload sampling count. */
1146 		wrmsr(IAF_CTR0 + n, v);
1147 
1148 		PMCDBG4(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", curcpu,
1149 		    error, (uintmax_t) v, (uintmax_t) rdpmc(IAF_RI_TO_MSR(n)));
1150 	}
1151 
1152 	/*
1153 	 * Process interrupts from the programmable counters.
1154 	 */
1155 	for (n = 0, flag = 1; n < core_iap_npmc; n++, flag <<= 1) {
1156 		if ((intrstatus & flag) == 0)
1157 			continue;
1158 
1159 		found_interrupt = 1;
1160 
1161 		pm = cc->pc_corepmcs[n].phw_pmc;
1162 		if (pm == NULL || pm->pm_state != PMC_STATE_RUNNING ||
1163 		    !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
1164 			continue;
1165 
1166 		error = pmc_process_interrupt(PMC_HR, pm, tf);
1167 		if (__predict_false(error))
1168 			intrdisable |= flag;
1169 
1170 		v = iap_reload_count_to_perfctr_value(pm->pm_sc.pm_reloadcount);
1171 
1172 		PMCDBG3(MDP,INT, 1, "iap-intr cpu=%d error=%d v=%jx", cpu, error,
1173 		    (uintmax_t) v);
1174 
1175 		/* Reload sampling count. */
1176 		wrmsr(core_iap_wroffset + IAP_PMC0 + n, v);
1177 	}
1178 
1179 	if (found_interrupt)
1180 		counter_u64_add(pmc_stats.pm_intr_processed, 1);
1181 	else
1182 		counter_u64_add(pmc_stats.pm_intr_ignored, 1);
1183 
1184 	/*
1185 	 * Reenable all non-stalled PMCs.
1186 	 */
1187 	if ((intrstatus & IA_GLOBAL_STATUS_FLAG_CTR_FRZ) == 0) {
1188 		wrmsr(IA_GLOBAL_OVF_CTRL, intrstatus);
1189 		cc->pc_globalctrl &= ~intrdisable;
1190 		wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
1191 	} else {
1192 		if (__predict_false(intrdisable)) {
1193 			cc->pc_globalctrl &= ~intrdisable;
1194 			wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl);
1195 		}
1196 		wrmsr(IA_GLOBAL_OVF_CTRL, intrstatus);
1197 	}
1198 
1199 	PMCDBG4(MDP, INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx",
1200 	    cpu, (uintmax_t) rdmsr(IAF_CTRL),
1201 	    (uintmax_t) rdmsr(IA_GLOBAL_CTRL),
1202 	    (uintmax_t) rdmsr(IA_GLOBAL_STATUS));
1203 
1204 	if (found_interrupt)
1205 		lapic_reenable_pmc();
1206 
1207 	return (found_interrupt);
1208 }
1209 
1210 int
1211 pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override)
1212 {
1213 	int cpuid[CORE_CPUID_REQUEST_SIZE];
1214 	int flags, nflags;
1215 
1216 	do_cpuid(CORE_CPUID_REQUEST, cpuid);
1217 
1218 	core_cputype = md->pmd_cputype;
1219 	core_version = (version_override > 0) ? version_override :
1220 	    cpuid[CORE_CPUID_EAX] & 0xFF;
1221 
1222 	PMCDBG3(MDP,INI,1,"core-init cputype=%d ncpu=%d version=%d",
1223 	    core_cputype, maxcpu, core_version);
1224 
1225 	if (core_version < 1 || core_version > 5 ||
1226 	    (core_cputype != PMC_CPU_INTEL_CORE && core_version == 1)) {
1227 		/* Unknown PMC architecture. */
1228 		printf("hwpc_core: unknown PMC architecture: %d\n",
1229 		    core_version);
1230 		return (EPROGMISMATCH);
1231 	}
1232 
1233 	core_iap_wroffset = 0;
1234 	if (cpu_feature2 & CPUID2_PDCM) {
1235 		if (rdmsr(IA32_PERF_CAPABILITIES) & PERFCAP_FW_WRITE) {
1236 			PMCDBG0(MDP, INI, 1,
1237 			    "core-init full-width write supported");
1238 			core_iap_wroffset = IAP_A_PMC0 - IAP_PMC0;
1239 		} else
1240 			PMCDBG0(MDP, INI, 1,
1241 			    "core-init full-width write NOT supported");
1242 	} else
1243 		PMCDBG0(MDP, INI, 1, "core-init pdcm not supported");
1244 
1245 	core_pmcmask = 0;
1246 
1247 	/*
1248 	 * Initialize programmable counters.
1249 	 */
1250 	core_iap_npmc = (cpuid[CORE_CPUID_EAX] >> 8) & 0xFF;
1251 	core_iap_width = (cpuid[CORE_CPUID_EAX] >> 16) & 0xFF;
1252 
1253 	core_pmcmask |= ((1ULL << core_iap_npmc) - 1);
1254 
1255 	nflags = (cpuid[CORE_CPUID_EAX] >> 24) & 0xFF;
1256 	flags = cpuid[CORE_CPUID_EBX] & ((1 << nflags) - 1);
1257 
1258 	iap_initialize(md, maxcpu, core_iap_npmc, core_iap_width, flags);
1259 
1260 	/*
1261 	 * Initialize fixed function counters, if present.
1262 	 */
1263 	if (core_version >= 2) {
1264 		core_iaf_ri = core_iap_npmc;
1265 		core_iaf_npmc = cpuid[CORE_CPUID_EDX] & 0x1F;
1266 		core_iaf_width = (cpuid[CORE_CPUID_EDX] >> 5) & 0xFF;
1267 
1268 		iaf_initialize(md, maxcpu, core_iaf_npmc, core_iaf_width);
1269 		core_pmcmask |= ((1ULL << core_iaf_npmc) - 1) << IAF_OFFSET;
1270 	}
1271 
1272 	PMCDBG2(MDP,INI,1,"core-init pmcmask=0x%jx iafri=%d", core_pmcmask,
1273 	    core_iaf_ri);
1274 
1275 	core_pcpu = malloc(sizeof(*core_pcpu) * maxcpu, M_PMC,
1276 	    M_ZERO | M_WAITOK);
1277 
1278 	/*
1279 	 * Choose the appropriate interrupt handler.
1280 	 */
1281 	if (core_version >= 2)
1282 		md->pmd_intr = core2_intr;
1283 	else
1284 		md->pmd_intr = core_intr;
1285 
1286 	md->pmd_pcpu_fini = NULL;
1287 	md->pmd_pcpu_init = NULL;
1288 
1289 	return (0);
1290 }
1291 
1292 void
1293 pmc_core_finalize(struct pmc_mdep *md)
1294 {
1295 	PMCDBG0(MDP,INI,1, "core-finalize");
1296 
1297 	free(core_pcpu, M_PMC);
1298 	core_pcpu = NULL;
1299 }
1300