xref: /freebsd/lib/libpmc/libpmc.c (revision dd41de95a84d979615a2ef11df6850622bf6184e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2003-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 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/module.h>
35 #include <sys/pmc.h>
36 #include <sys/syscall.h>
37 
38 #include <ctype.h>
39 #include <errno.h>
40 #include <err.h>
41 #include <fcntl.h>
42 #include <pmc.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <strings.h>
47 #include <sysexits.h>
48 #include <unistd.h>
49 
50 #include "libpmcinternal.h"
51 
52 /* Function prototypes */
53 #if defined(__amd64__) || defined(__i386__)
54 static int k8_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
55     struct pmc_op_pmcallocate *_pmc_config);
56 #endif
57 #if defined(__amd64__) || defined(__i386__)
58 static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
59     struct pmc_op_pmcallocate *_pmc_config);
60 #endif
61 #if defined(__arm__)
62 static int armv7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
63     struct pmc_op_pmcallocate *_pmc_config);
64 #endif
65 #if defined(__aarch64__)
66 static int arm64_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
67     struct pmc_op_pmcallocate *_pmc_config);
68 #endif
69 #if defined(__mips__)
70 static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec,
71 			     struct pmc_op_pmcallocate *_pmc_config);
72 #endif /* __mips__ */
73 static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
74     struct pmc_op_pmcallocate *_pmc_config);
75 
76 #if defined(__powerpc__)
77 static int powerpc_allocate_pmc(enum pmc_event _pe, char* ctrspec,
78 			     struct pmc_op_pmcallocate *_pmc_config);
79 #endif /* __powerpc__ */
80 
81 #define PMC_CALL(cmd, params)				\
82 	syscall(pmc_syscall, PMC_OP_##cmd, (params))
83 
84 /*
85  * Event aliases provide a way for the user to ask for generic events
86  * like "cache-misses", or "instructions-retired".  These aliases are
87  * mapped to the appropriate canonical event descriptions using a
88  * lookup table.
89  */
90 struct pmc_event_alias {
91 	const char	*pm_alias;
92 	const char	*pm_spec;
93 };
94 
95 static const struct pmc_event_alias *pmc_mdep_event_aliases;
96 
97 /*
98  * The pmc_event_descr structure maps symbolic names known to the user
99  * to integer codes used by the PMC KLD.
100  */
101 struct pmc_event_descr {
102 	const char	*pm_ev_name;
103 	enum pmc_event	pm_ev_code;
104 };
105 
106 /*
107  * The pmc_class_descr structure maps class name prefixes for
108  * event names to event tables and other PMC class data.
109  */
110 struct pmc_class_descr {
111 	const char	*pm_evc_name;
112 	size_t		pm_evc_name_size;
113 	enum pmc_class	pm_evc_class;
114 	const struct pmc_event_descr *pm_evc_event_table;
115 	size_t		pm_evc_event_table_size;
116 	int		(*pm_evc_allocate_pmc)(enum pmc_event _pe,
117 			    char *_ctrspec, struct pmc_op_pmcallocate *_pa);
118 };
119 
120 #define	PMC_TABLE_SIZE(N)	(sizeof(N)/sizeof(N[0]))
121 #define	PMC_EVENT_TABLE_SIZE(N)	PMC_TABLE_SIZE(N##_event_table)
122 
123 #undef	__PMC_EV
124 #define	__PMC_EV(C,N) { #N, PMC_EV_ ## C ## _ ## N },
125 
126 /*
127  * PMC_CLASSDEP_TABLE(NAME, CLASS)
128  *
129  * Define a table mapping event names and aliases to HWPMC event IDs.
130  */
131 #define	PMC_CLASSDEP_TABLE(N, C)				\
132 	static const struct pmc_event_descr N##_event_table[] =	\
133 	{							\
134 		__PMC_EV_##C()					\
135 	}
136 
137 PMC_CLASSDEP_TABLE(iaf, IAF);
138 PMC_CLASSDEP_TABLE(k8, K8);
139 PMC_CLASSDEP_TABLE(armv7, ARMV7);
140 PMC_CLASSDEP_TABLE(armv8, ARMV8);
141 PMC_CLASSDEP_TABLE(beri, BERI);
142 PMC_CLASSDEP_TABLE(mips24k, MIPS24K);
143 PMC_CLASSDEP_TABLE(mips74k, MIPS74K);
144 PMC_CLASSDEP_TABLE(octeon, OCTEON);
145 PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
146 PMC_CLASSDEP_TABLE(ppc970, PPC970);
147 PMC_CLASSDEP_TABLE(power8, POWER8);
148 PMC_CLASSDEP_TABLE(e500, E500);
149 
150 static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
151 
152 #undef	__PMC_EV_ALIAS
153 #define	__PMC_EV_ALIAS(N,CODE) 	{ N, PMC_EV_##CODE },
154 
155 static const struct pmc_event_descr cortex_a8_event_table[] =
156 {
157 	__PMC_EV_ALIAS_ARMV7_CORTEX_A8()
158 };
159 
160 static const struct pmc_event_descr cortex_a9_event_table[] =
161 {
162 	__PMC_EV_ALIAS_ARMV7_CORTEX_A9()
163 };
164 
165 static const struct pmc_event_descr cortex_a53_event_table[] =
166 {
167 	__PMC_EV_ALIAS_ARMV8_CORTEX_A53()
168 };
169 
170 static const struct pmc_event_descr cortex_a57_event_table[] =
171 {
172 	__PMC_EV_ALIAS_ARMV8_CORTEX_A57()
173 };
174 
175 static const struct pmc_event_descr cortex_a76_event_table[] =
176 {
177 	__PMC_EV_ALIAS_ARMV8_CORTEX_A76()
178 };
179 
180 static const struct pmc_event_descr tsc_event_table[] =
181 {
182 	__PMC_EV_TSC()
183 };
184 
185 #undef	PMC_CLASS_TABLE_DESC
186 #define	PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR)	\
187 static const struct pmc_class_descr NAME##_class_table_descr =	\
188 	{							\
189 		.pm_evc_name  = #CLASS "-",			\
190 		.pm_evc_name_size = sizeof(#CLASS "-") - 1,	\
191 		.pm_evc_class = PMC_CLASS_##CLASS ,		\
192 		.pm_evc_event_table = EVENTS##_event_table ,	\
193 		.pm_evc_event_table_size = 			\
194 			PMC_EVENT_TABLE_SIZE(EVENTS),		\
195 		.pm_evc_allocate_pmc = ALLOCATOR##_allocate_pmc	\
196 	}
197 
198 #if	defined(__i386__) || defined(__amd64__)
199 PMC_CLASS_TABLE_DESC(k8, K8, k8, k8);
200 #endif
201 #if	defined(__i386__) || defined(__amd64__)
202 PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
203 #endif
204 #if	defined(__arm__)
205 PMC_CLASS_TABLE_DESC(cortex_a8, ARMV7, cortex_a8, armv7);
206 PMC_CLASS_TABLE_DESC(cortex_a9, ARMV7, cortex_a9, armv7);
207 #endif
208 #if	defined(__aarch64__)
209 PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
210 PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
211 PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64);
212 #endif
213 #if defined(__mips__)
214 PMC_CLASS_TABLE_DESC(beri, BERI, beri, mips);
215 PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
216 PMC_CLASS_TABLE_DESC(mips74k, MIPS74K, mips74k, mips);
217 PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips);
218 #endif /* __mips__ */
219 #if defined(__powerpc__)
220 PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, powerpc);
221 PMC_CLASS_TABLE_DESC(ppc970, PPC970, ppc970, powerpc);
222 PMC_CLASS_TABLE_DESC(power8, POWER8, power8, powerpc);
223 PMC_CLASS_TABLE_DESC(e500, E500, e500, powerpc);
224 #endif
225 
226 static struct pmc_class_descr soft_class_table_descr =
227 {
228 	.pm_evc_name  = "SOFT-",
229 	.pm_evc_name_size = sizeof("SOFT-") - 1,
230 	.pm_evc_class = PMC_CLASS_SOFT,
231 	.pm_evc_event_table = NULL,
232 	.pm_evc_event_table_size = 0,
233 	.pm_evc_allocate_pmc = soft_allocate_pmc
234 };
235 
236 #undef	PMC_CLASS_TABLE_DESC
237 
238 static const struct pmc_class_descr **pmc_class_table;
239 #define	PMC_CLASS_TABLE_SIZE	cpu_info.pm_nclass
240 
241 /*
242  * Mapping tables, mapping enumeration values to human readable
243  * strings.
244  */
245 
246 static const char * pmc_capability_names[] = {
247 #undef	__PMC_CAP
248 #define	__PMC_CAP(N,V,D)	#N ,
249 	__PMC_CAPS()
250 };
251 
252 struct pmc_class_map {
253 	enum pmc_class	pm_class;
254 	const char	*pm_name;
255 };
256 
257 static const struct pmc_class_map pmc_class_names[] = {
258 #undef	__PMC_CLASS
259 #define __PMC_CLASS(S,V,D) { .pm_class = PMC_CLASS_##S, .pm_name = #S } ,
260 	__PMC_CLASSES()
261 };
262 
263 struct pmc_cputype_map {
264 	enum pmc_cputype pm_cputype;
265 	const char	*pm_name;
266 };
267 
268 static const struct pmc_cputype_map pmc_cputype_names[] = {
269 #undef	__PMC_CPU
270 #define	__PMC_CPU(S, V, D) { .pm_cputype = PMC_CPU_##S, .pm_name = #S } ,
271 	__PMC_CPUS()
272 };
273 
274 static const char * pmc_disposition_names[] = {
275 #undef	__PMC_DISP
276 #define	__PMC_DISP(D)	#D ,
277 	__PMC_DISPOSITIONS()
278 };
279 
280 static const char * pmc_mode_names[] = {
281 #undef  __PMC_MODE
282 #define __PMC_MODE(M,N)	#M ,
283 	__PMC_MODES()
284 };
285 
286 static const char * pmc_state_names[] = {
287 #undef  __PMC_STATE
288 #define __PMC_STATE(S) #S ,
289 	__PMC_STATES()
290 };
291 
292 /*
293  * Filled in by pmc_init().
294  */
295 static int pmc_syscall = -1;
296 static struct pmc_cpuinfo cpu_info;
297 static struct pmc_op_getdyneventinfo soft_event_info;
298 
299 /* Event masks for events */
300 struct pmc_masks {
301 	const char	*pm_name;
302 	const uint64_t	pm_value;
303 };
304 #define	PMCMASK(N,V)	{ .pm_name = #N, .pm_value = (V) }
305 #define	NULLMASK	{ .pm_name = NULL }
306 
307 #if defined(__amd64__) || defined(__i386__)
308 static int
309 pmc_parse_mask(const struct pmc_masks *pmask, char *p, uint64_t *evmask)
310 {
311 	const struct pmc_masks *pm;
312 	char *q, *r;
313 	int c;
314 
315 	if (pmask == NULL)	/* no mask keywords */
316 		return (-1);
317 	q = strchr(p, '=');	/* skip '=' */
318 	if (*++q == '\0')	/* no more data */
319 		return (-1);
320 	c = 0;			/* count of mask keywords seen */
321 	while ((r = strsep(&q, "+")) != NULL) {
322 		for (pm = pmask; pm->pm_name && strcasecmp(r, pm->pm_name);
323 		    pm++)
324 			;
325 		if (pm->pm_name == NULL) /* not found */
326 			return (-1);
327 		*evmask |= pm->pm_value;
328 		c++;
329 	}
330 	return (c);
331 }
332 #endif
333 
334 #define	KWMATCH(p,kw)		(strcasecmp((p), (kw)) == 0)
335 #define	KWPREFIXMATCH(p,kw)	(strncasecmp((p), (kw), sizeof((kw)) - 1) == 0)
336 #define	EV_ALIAS(N,S)		{ .pm_alias = N, .pm_spec = S }
337 
338 #if defined(__amd64__) || defined(__i386__)
339 /*
340  * AMD K8 PMCs.
341  *
342  */
343 
344 static struct pmc_event_alias k8_aliases[] = {
345 	EV_ALIAS("branches",		"k8-fr-retired-taken-branches"),
346 	EV_ALIAS("branch-mispredicts",
347 	    "k8-fr-retired-taken-branches-mispredicted"),
348 	EV_ALIAS("cycles",		"tsc"),
349 	EV_ALIAS("dc-misses",		"k8-dc-miss"),
350 	EV_ALIAS("ic-misses",		"k8-ic-miss"),
351 	EV_ALIAS("instructions",	"k8-fr-retired-x86-instructions"),
352 	EV_ALIAS("interrupts",		"k8-fr-taken-hardware-interrupts"),
353 	EV_ALIAS("unhalted-cycles",	"k8-bu-cpu-clk-unhalted"),
354 	EV_ALIAS(NULL, NULL)
355 };
356 
357 #define	__K8MASK(N,V) PMCMASK(N,(1 << (V)))
358 
359 /*
360  * Parsing tables
361  */
362 
363 /* fp dispatched fpu ops */
364 static const struct pmc_masks k8_mask_fdfo[] = {
365 	__K8MASK(add-pipe-excluding-junk-ops,	0),
366 	__K8MASK(multiply-pipe-excluding-junk-ops,	1),
367 	__K8MASK(store-pipe-excluding-junk-ops,	2),
368 	__K8MASK(add-pipe-junk-ops,		3),
369 	__K8MASK(multiply-pipe-junk-ops,	4),
370 	__K8MASK(store-pipe-junk-ops,		5),
371 	NULLMASK
372 };
373 
374 /* ls segment register loads */
375 static const struct pmc_masks k8_mask_lsrl[] = {
376 	__K8MASK(es,	0),
377 	__K8MASK(cs,	1),
378 	__K8MASK(ss,	2),
379 	__K8MASK(ds,	3),
380 	__K8MASK(fs,	4),
381 	__K8MASK(gs,	5),
382 	__K8MASK(hs,	6),
383 	NULLMASK
384 };
385 
386 /* ls locked operation */
387 static const struct pmc_masks k8_mask_llo[] = {
388 	__K8MASK(locked-instructions,	0),
389 	__K8MASK(cycles-in-request,	1),
390 	__K8MASK(cycles-to-complete,	2),
391 	NULLMASK
392 };
393 
394 /* dc refill from {l2,system} and dc copyback */
395 static const struct pmc_masks k8_mask_dc[] = {
396 	__K8MASK(invalid,	0),
397 	__K8MASK(shared,	1),
398 	__K8MASK(exclusive,	2),
399 	__K8MASK(owner,		3),
400 	__K8MASK(modified,	4),
401 	NULLMASK
402 };
403 
404 /* dc one bit ecc error */
405 static const struct pmc_masks k8_mask_dobee[] = {
406 	__K8MASK(scrubber,	0),
407 	__K8MASK(piggyback,	1),
408 	NULLMASK
409 };
410 
411 /* dc dispatched prefetch instructions */
412 static const struct pmc_masks k8_mask_ddpi[] = {
413 	__K8MASK(load,	0),
414 	__K8MASK(store,	1),
415 	__K8MASK(nta,	2),
416 	NULLMASK
417 };
418 
419 /* dc dcache accesses by locks */
420 static const struct pmc_masks k8_mask_dabl[] = {
421 	__K8MASK(accesses,	0),
422 	__K8MASK(misses,	1),
423 	NULLMASK
424 };
425 
426 /* bu internal l2 request */
427 static const struct pmc_masks k8_mask_bilr[] = {
428 	__K8MASK(ic-fill,	0),
429 	__K8MASK(dc-fill,	1),
430 	__K8MASK(tlb-reload,	2),
431 	__K8MASK(tag-snoop,	3),
432 	__K8MASK(cancelled,	4),
433 	NULLMASK
434 };
435 
436 /* bu fill request l2 miss */
437 static const struct pmc_masks k8_mask_bfrlm[] = {
438 	__K8MASK(ic-fill,	0),
439 	__K8MASK(dc-fill,	1),
440 	__K8MASK(tlb-reload,	2),
441 	NULLMASK
442 };
443 
444 /* bu fill into l2 */
445 static const struct pmc_masks k8_mask_bfil[] = {
446 	__K8MASK(dirty-l2-victim,	0),
447 	__K8MASK(victim-from-l2,	1),
448 	NULLMASK
449 };
450 
451 /* fr retired fpu instructions */
452 static const struct pmc_masks k8_mask_frfi[] = {
453 	__K8MASK(x87,			0),
454 	__K8MASK(mmx-3dnow,		1),
455 	__K8MASK(packed-sse-sse2,	2),
456 	__K8MASK(scalar-sse-sse2,	3),
457 	NULLMASK
458 };
459 
460 /* fr retired fastpath double op instructions */
461 static const struct pmc_masks k8_mask_frfdoi[] = {
462 	__K8MASK(low-op-pos-0,		0),
463 	__K8MASK(low-op-pos-1,		1),
464 	__K8MASK(low-op-pos-2,		2),
465 	NULLMASK
466 };
467 
468 /* fr fpu exceptions */
469 static const struct pmc_masks k8_mask_ffe[] = {
470 	__K8MASK(x87-reclass-microfaults,	0),
471 	__K8MASK(sse-retype-microfaults,	1),
472 	__K8MASK(sse-reclass-microfaults,	2),
473 	__K8MASK(sse-and-x87-microtraps,	3),
474 	NULLMASK
475 };
476 
477 /* nb memory controller page access event */
478 static const struct pmc_masks k8_mask_nmcpae[] = {
479 	__K8MASK(page-hit,	0),
480 	__K8MASK(page-miss,	1),
481 	__K8MASK(page-conflict,	2),
482 	NULLMASK
483 };
484 
485 /* nb memory controller turnaround */
486 static const struct pmc_masks k8_mask_nmct[] = {
487 	__K8MASK(dimm-turnaround,		0),
488 	__K8MASK(read-to-write-turnaround,	1),
489 	__K8MASK(write-to-read-turnaround,	2),
490 	NULLMASK
491 };
492 
493 /* nb memory controller bypass saturation */
494 static const struct pmc_masks k8_mask_nmcbs[] = {
495 	__K8MASK(memory-controller-hi-pri-bypass,	0),
496 	__K8MASK(memory-controller-lo-pri-bypass,	1),
497 	__K8MASK(dram-controller-interface-bypass,	2),
498 	__K8MASK(dram-controller-queue-bypass,		3),
499 	NULLMASK
500 };
501 
502 /* nb sized commands */
503 static const struct pmc_masks k8_mask_nsc[] = {
504 	__K8MASK(nonpostwrszbyte,	0),
505 	__K8MASK(nonpostwrszdword,	1),
506 	__K8MASK(postwrszbyte,		2),
507 	__K8MASK(postwrszdword,		3),
508 	__K8MASK(rdszbyte,		4),
509 	__K8MASK(rdszdword,		5),
510 	__K8MASK(rdmodwr,		6),
511 	NULLMASK
512 };
513 
514 /* nb probe result */
515 static const struct pmc_masks k8_mask_npr[] = {
516 	__K8MASK(probe-miss,		0),
517 	__K8MASK(probe-hit,		1),
518 	__K8MASK(probe-hit-dirty-no-memory-cancel, 2),
519 	__K8MASK(probe-hit-dirty-with-memory-cancel, 3),
520 	NULLMASK
521 };
522 
523 /* nb hypertransport bus bandwidth */
524 static const struct pmc_masks k8_mask_nhbb[] = { /* HT bus bandwidth */
525 	__K8MASK(command,	0),
526 	__K8MASK(data,	1),
527 	__K8MASK(buffer-release, 2),
528 	__K8MASK(nop,	3),
529 	NULLMASK
530 };
531 
532 #undef	__K8MASK
533 
534 #define	K8_KW_COUNT	"count"
535 #define	K8_KW_EDGE	"edge"
536 #define	K8_KW_INV	"inv"
537 #define	K8_KW_MASK	"mask"
538 #define	K8_KW_OS	"os"
539 #define	K8_KW_USR	"usr"
540 
541 static int
542 k8_allocate_pmc(enum pmc_event pe, char *ctrspec,
543     struct pmc_op_pmcallocate *pmc_config)
544 {
545 	char		*e, *p, *q;
546 	int		n;
547 	uint32_t	count;
548 	uint64_t	evmask;
549 	const struct pmc_masks	*pm, *pmask;
550 
551 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
552 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
553 
554 	pmask = NULL;
555 	evmask = 0;
556 
557 #define	__K8SETMASK(M) pmask = k8_mask_##M
558 
559 	/* setup parsing tables */
560 	switch (pe) {
561 	case PMC_EV_K8_FP_DISPATCHED_FPU_OPS:
562 		__K8SETMASK(fdfo);
563 		break;
564 	case PMC_EV_K8_LS_SEGMENT_REGISTER_LOAD:
565 		__K8SETMASK(lsrl);
566 		break;
567 	case PMC_EV_K8_LS_LOCKED_OPERATION:
568 		__K8SETMASK(llo);
569 		break;
570 	case PMC_EV_K8_DC_REFILL_FROM_L2:
571 	case PMC_EV_K8_DC_REFILL_FROM_SYSTEM:
572 	case PMC_EV_K8_DC_COPYBACK:
573 		__K8SETMASK(dc);
574 		break;
575 	case PMC_EV_K8_DC_ONE_BIT_ECC_ERROR:
576 		__K8SETMASK(dobee);
577 		break;
578 	case PMC_EV_K8_DC_DISPATCHED_PREFETCH_INSTRUCTIONS:
579 		__K8SETMASK(ddpi);
580 		break;
581 	case PMC_EV_K8_DC_DCACHE_ACCESSES_BY_LOCKS:
582 		__K8SETMASK(dabl);
583 		break;
584 	case PMC_EV_K8_BU_INTERNAL_L2_REQUEST:
585 		__K8SETMASK(bilr);
586 		break;
587 	case PMC_EV_K8_BU_FILL_REQUEST_L2_MISS:
588 		__K8SETMASK(bfrlm);
589 		break;
590 	case PMC_EV_K8_BU_FILL_INTO_L2:
591 		__K8SETMASK(bfil);
592 		break;
593 	case PMC_EV_K8_FR_RETIRED_FPU_INSTRUCTIONS:
594 		__K8SETMASK(frfi);
595 		break;
596 	case PMC_EV_K8_FR_RETIRED_FASTPATH_DOUBLE_OP_INSTRUCTIONS:
597 		__K8SETMASK(frfdoi);
598 		break;
599 	case PMC_EV_K8_FR_FPU_EXCEPTIONS:
600 		__K8SETMASK(ffe);
601 		break;
602 	case PMC_EV_K8_NB_MEMORY_CONTROLLER_PAGE_ACCESS_EVENT:
603 		__K8SETMASK(nmcpae);
604 		break;
605 	case PMC_EV_K8_NB_MEMORY_CONTROLLER_TURNAROUND:
606 		__K8SETMASK(nmct);
607 		break;
608 	case PMC_EV_K8_NB_MEMORY_CONTROLLER_BYPASS_SATURATION:
609 		__K8SETMASK(nmcbs);
610 		break;
611 	case PMC_EV_K8_NB_SIZED_COMMANDS:
612 		__K8SETMASK(nsc);
613 		break;
614 	case PMC_EV_K8_NB_PROBE_RESULT:
615 		__K8SETMASK(npr);
616 		break;
617 	case PMC_EV_K8_NB_HT_BUS0_BANDWIDTH:
618 	case PMC_EV_K8_NB_HT_BUS1_BANDWIDTH:
619 	case PMC_EV_K8_NB_HT_BUS2_BANDWIDTH:
620 		__K8SETMASK(nhbb);
621 		break;
622 
623 	default:
624 		break;		/* no options defined */
625 	}
626 
627 	while ((p = strsep(&ctrspec, ",")) != NULL) {
628 		if (KWPREFIXMATCH(p, K8_KW_COUNT "=")) {
629 			q = strchr(p, '=');
630 			if (*++q == '\0') /* skip '=' */
631 				return (-1);
632 
633 			count = strtol(q, &e, 0);
634 			if (e == q || *e != '\0')
635 				return (-1);
636 
637 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
638 			pmc_config->pm_md.pm_amd.pm_amd_config |=
639 			    AMD_PMC_TO_COUNTER(count);
640 
641 		} else if (KWMATCH(p, K8_KW_EDGE)) {
642 			pmc_config->pm_caps |= PMC_CAP_EDGE;
643 		} else if (KWMATCH(p, K8_KW_INV)) {
644 			pmc_config->pm_caps |= PMC_CAP_INVERT;
645 		} else if (KWPREFIXMATCH(p, K8_KW_MASK "=")) {
646 			if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
647 				return (-1);
648 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
649 		} else if (KWMATCH(p, K8_KW_OS)) {
650 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
651 		} else if (KWMATCH(p, K8_KW_USR)) {
652 			pmc_config->pm_caps |= PMC_CAP_USER;
653 		} else
654 			return (-1);
655 	}
656 
657 	/* other post processing */
658 	switch (pe) {
659 	case PMC_EV_K8_FP_DISPATCHED_FPU_OPS:
660 	case PMC_EV_K8_FP_CYCLES_WITH_NO_FPU_OPS_RETIRED:
661 	case PMC_EV_K8_FP_DISPATCHED_FPU_FAST_FLAG_OPS:
662 	case PMC_EV_K8_FR_RETIRED_FASTPATH_DOUBLE_OP_INSTRUCTIONS:
663 	case PMC_EV_K8_FR_RETIRED_FPU_INSTRUCTIONS:
664 	case PMC_EV_K8_FR_FPU_EXCEPTIONS:
665 		/* XXX only available in rev B and later */
666 		break;
667 	case PMC_EV_K8_DC_DCACHE_ACCESSES_BY_LOCKS:
668 		/* XXX only available in rev C and later */
669 		break;
670 	case PMC_EV_K8_LS_LOCKED_OPERATION:
671 		/* XXX CPU Rev A,B evmask is to be zero */
672 		if (evmask & (evmask - 1)) /* > 1 bit set */
673 			return (-1);
674 		if (evmask == 0) {
675 			evmask = 0x01; /* Rev C and later: #instrs */
676 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
677 		}
678 		break;
679 	default:
680 		if (evmask == 0 && pmask != NULL) {
681 			for (pm = pmask; pm->pm_name; pm++)
682 				evmask |= pm->pm_value;
683 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
684 		}
685 	}
686 
687 	if (pmc_config->pm_caps & PMC_CAP_QUALIFIER)
688 		pmc_config->pm_md.pm_amd.pm_amd_config =
689 		    AMD_PMC_TO_UNITMASK(evmask);
690 
691 	return (0);
692 }
693 
694 #endif
695 
696 #if	defined(__i386__) || defined(__amd64__)
697 static int
698 tsc_allocate_pmc(enum pmc_event pe, char *ctrspec,
699     struct pmc_op_pmcallocate *pmc_config)
700 {
701 	if (pe != PMC_EV_TSC_TSC)
702 		return (-1);
703 
704 	/* TSC events must be unqualified. */
705 	if (ctrspec && *ctrspec != '\0')
706 		return (-1);
707 
708 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
709 	pmc_config->pm_caps |= PMC_CAP_READ;
710 
711 	return (0);
712 }
713 #endif
714 
715 static struct pmc_event_alias generic_aliases[] = {
716 	EV_ALIAS("instructions",		"SOFT-CLOCK.HARD"),
717 	EV_ALIAS(NULL, NULL)
718 };
719 
720 static int
721 soft_allocate_pmc(enum pmc_event pe, char *ctrspec,
722     struct pmc_op_pmcallocate *pmc_config)
723 {
724 	(void)ctrspec;
725 	(void)pmc_config;
726 
727 	if ((int)pe < PMC_EV_SOFT_FIRST || (int)pe > PMC_EV_SOFT_LAST)
728 		return (-1);
729 
730 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
731 	return (0);
732 }
733 
734 #if	defined(__arm__)
735 static struct pmc_event_alias cortex_a8_aliases[] = {
736 	EV_ALIAS("dc-misses",		"L1_DCACHE_REFILL"),
737 	EV_ALIAS("ic-misses",		"L1_ICACHE_REFILL"),
738 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
739 	EV_ALIAS(NULL, NULL)
740 };
741 
742 static struct pmc_event_alias cortex_a9_aliases[] = {
743 	EV_ALIAS("dc-misses",		"L1_DCACHE_REFILL"),
744 	EV_ALIAS("ic-misses",		"L1_ICACHE_REFILL"),
745 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
746 	EV_ALIAS(NULL, NULL)
747 };
748 
749 static int
750 armv7_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
751     struct pmc_op_pmcallocate *pmc_config __unused)
752 {
753 	switch (pe) {
754 	default:
755 		break;
756 	}
757 
758 	return (0);
759 }
760 #endif
761 
762 #if	defined(__aarch64__)
763 static struct pmc_event_alias cortex_a53_aliases[] = {
764 	EV_ALIAS(NULL, NULL)
765 };
766 static struct pmc_event_alias cortex_a57_aliases[] = {
767 	EV_ALIAS(NULL, NULL)
768 };
769 static struct pmc_event_alias cortex_a76_aliases[] = {
770 	EV_ALIAS(NULL, NULL)
771 };
772 static int
773 arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
774     struct pmc_op_pmcallocate *pmc_config __unused)
775 {
776 	switch (pe) {
777 	default:
778 		break;
779 	}
780 
781 	return (0);
782 }
783 #endif
784 
785 #if defined(__mips__)
786 
787 static struct pmc_event_alias beri_aliases[] = {
788 	EV_ALIAS("instructions",	"INST"),
789 	EV_ALIAS(NULL, NULL)
790 };
791 
792 static struct pmc_event_alias mips24k_aliases[] = {
793 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
794 	EV_ALIAS("branches",		"BRANCH_COMPLETED"),
795 	EV_ALIAS("branch-mispredicts",	"BRANCH_MISPRED"),
796 	EV_ALIAS(NULL, NULL)
797 };
798 
799 static struct pmc_event_alias mips74k_aliases[] = {
800 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
801 	EV_ALIAS("branches",		"BRANCH_INSNS"),
802 	EV_ALIAS("branch-mispredicts",	"MISPREDICTED_BRANCH_INSNS"),
803 	EV_ALIAS(NULL, NULL)
804 };
805 
806 static struct pmc_event_alias octeon_aliases[] = {
807 	EV_ALIAS("instructions",	"RET"),
808 	EV_ALIAS("branches",		"BR"),
809 	EV_ALIAS("branch-mispredicts",	"BRMIS"),
810 	EV_ALIAS(NULL, NULL)
811 };
812 
813 #define	MIPS_KW_OS		"os"
814 #define	MIPS_KW_USR		"usr"
815 #define	MIPS_KW_ANYTHREAD	"anythread"
816 
817 static int
818 mips_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
819 		  struct pmc_op_pmcallocate *pmc_config __unused)
820 {
821 	char *p;
822 
823 	(void) pe;
824 
825 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
826 
827 	while ((p = strsep(&ctrspec, ",")) != NULL) {
828 		if (KWMATCH(p, MIPS_KW_OS))
829 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
830 		else if (KWMATCH(p, MIPS_KW_USR))
831 			pmc_config->pm_caps |= PMC_CAP_USER;
832 		else if (KWMATCH(p, MIPS_KW_ANYTHREAD))
833 			pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM);
834 		else
835 			return (-1);
836 	}
837 
838 	return (0);
839 }
840 
841 #endif /* __mips__ */
842 
843 #if defined(__powerpc__)
844 
845 static struct pmc_event_alias ppc7450_aliases[] = {
846 	EV_ALIAS("instructions",	"INSTR_COMPLETED"),
847 	EV_ALIAS("branches",		"BRANCHES_COMPLETED"),
848 	EV_ALIAS("branch-mispredicts",	"MISPREDICTED_BRANCHES"),
849 	EV_ALIAS(NULL, NULL)
850 };
851 
852 static struct pmc_event_alias ppc970_aliases[] = {
853 	EV_ALIAS("instructions", "INSTR_COMPLETED"),
854 	EV_ALIAS("cycles",       "CYCLES"),
855 	EV_ALIAS(NULL, NULL)
856 };
857 
858 static struct pmc_event_alias power8_aliases[] = {
859 	EV_ALIAS("instructions", "INSTR_COMPLETED"),
860 	EV_ALIAS("cycles",       "CYCLES"),
861 	EV_ALIAS(NULL, NULL)
862 };
863 
864 static struct pmc_event_alias e500_aliases[] = {
865 	EV_ALIAS("instructions", "INSTR_COMPLETED"),
866 	EV_ALIAS("cycles",       "CYCLES"),
867 	EV_ALIAS(NULL, NULL)
868 };
869 
870 #define	POWERPC_KW_OS		"os"
871 #define	POWERPC_KW_USR		"usr"
872 #define	POWERPC_KW_ANYTHREAD	"anythread"
873 
874 static int
875 powerpc_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
876 		     struct pmc_op_pmcallocate *pmc_config __unused)
877 {
878 	char *p;
879 
880 	(void) pe;
881 
882 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
883 
884 	while ((p = strsep(&ctrspec, ",")) != NULL) {
885 		if (KWMATCH(p, POWERPC_KW_OS))
886 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
887 		else if (KWMATCH(p, POWERPC_KW_USR))
888 			pmc_config->pm_caps |= PMC_CAP_USER;
889 		else if (KWMATCH(p, POWERPC_KW_ANYTHREAD))
890 			pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM);
891 		else
892 			return (-1);
893 	}
894 
895 	return (0);
896 }
897 
898 #endif /* __powerpc__ */
899 
900 
901 /*
902  * Match an event name `name' with its canonical form.
903  *
904  * Matches are case insensitive and spaces, periods, underscores and
905  * hyphen characters are considered to match each other.
906  *
907  * Returns 1 for a match, 0 otherwise.
908  */
909 
910 static int
911 pmc_match_event_name(const char *name, const char *canonicalname)
912 {
913 	int cc, nc;
914 	const unsigned char *c, *n;
915 
916 	c = (const unsigned char *) canonicalname;
917 	n = (const unsigned char *) name;
918 
919 	for (; (nc = *n) && (cc = *c); n++, c++) {
920 
921 		if ((nc == ' ' || nc == '_' || nc == '-' || nc == '.') &&
922 		    (cc == ' ' || cc == '_' || cc == '-' || cc == '.'))
923 			continue;
924 
925 		if (toupper(nc) == toupper(cc))
926 			continue;
927 
928 
929 		return (0);
930 	}
931 
932 	if (*n == '\0' && *c == '\0')
933 		return (1);
934 
935 	return (0);
936 }
937 
938 /*
939  * Match an event name against all the event named supported by a
940  * PMC class.
941  *
942  * Returns an event descriptor pointer on match or NULL otherwise.
943  */
944 static const struct pmc_event_descr *
945 pmc_match_event_class(const char *name,
946     const struct pmc_class_descr *pcd)
947 {
948 	size_t n;
949 	const struct pmc_event_descr *ev;
950 
951 	ev = pcd->pm_evc_event_table;
952 	for (n = 0; n < pcd->pm_evc_event_table_size; n++, ev++)
953 		if (pmc_match_event_name(name, ev->pm_ev_name))
954 			return (ev);
955 
956 	return (NULL);
957 }
958 
959 /*
960  * API entry points
961  */
962 
963 int
964 pmc_allocate(const char *ctrspec, enum pmc_mode mode,
965     uint32_t flags, int cpu, pmc_id_t *pmcid,
966     uint64_t count)
967 {
968 	size_t n;
969 	int retval;
970 	char *r, *spec_copy;
971 	const char *ctrname;
972 	const struct pmc_event_descr *ev;
973 	const struct pmc_event_alias *alias;
974 	struct pmc_op_pmcallocate pmc_config;
975 	const struct pmc_class_descr *pcd;
976 
977 	spec_copy = NULL;
978 	retval    = -1;
979 
980 	if (mode != PMC_MODE_SS && mode != PMC_MODE_TS &&
981 	    mode != PMC_MODE_SC && mode != PMC_MODE_TC) {
982 		errno = EINVAL;
983 		goto out;
984 	}
985 	bzero(&pmc_config, sizeof(pmc_config));
986 	pmc_config.pm_cpu   = cpu;
987 	pmc_config.pm_mode  = mode;
988 	pmc_config.pm_flags = flags;
989 	pmc_config.pm_count = count;
990 	if (PMC_IS_SAMPLING_MODE(mode))
991 		pmc_config.pm_caps |= PMC_CAP_INTERRUPT;
992 
993 	/*
994 	 * Try to pull the raw event ID directly from the pmu-events table. If
995 	 * this is unsupported on the platform, or the event is not found,
996 	 * continue with searching the regular event tables.
997 	 */
998 	r = spec_copy = strdup(ctrspec);
999 	ctrname = strsep(&r, ",");
1000 	if (pmc_pmu_enabled()) {
1001 		if (pmc_pmu_pmcallocate(ctrname, &pmc_config) == 0)
1002 			goto found;
1003 
1004 		/* Otherwise, reset any changes */
1005 		pmc_config.pm_ev = 0;
1006 		pmc_config.pm_caps = 0;
1007 		pmc_config.pm_class = 0;
1008 	}
1009 	free(spec_copy);
1010 	spec_copy = NULL;
1011 
1012 	/* replace an event alias with the canonical event specifier */
1013 	if (pmc_mdep_event_aliases)
1014 		for (alias = pmc_mdep_event_aliases; alias->pm_alias; alias++)
1015 			if (!strcasecmp(ctrspec, alias->pm_alias)) {
1016 				spec_copy = strdup(alias->pm_spec);
1017 				break;
1018 			}
1019 
1020 	if (spec_copy == NULL)
1021 		spec_copy = strdup(ctrspec);
1022 
1023 	r = spec_copy;
1024 	ctrname = strsep(&r, ",");
1025 
1026 	/*
1027 	 * If a explicit class prefix was given by the user, restrict the
1028 	 * search for the event to the specified PMC class.
1029 	 */
1030 	ev = NULL;
1031 	for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++) {
1032 		pcd = pmc_class_table[n];
1033 		if (pcd != NULL && strncasecmp(ctrname, pcd->pm_evc_name,
1034 		    pcd->pm_evc_name_size) == 0) {
1035 			if ((ev = pmc_match_event_class(ctrname +
1036 			    pcd->pm_evc_name_size, pcd)) == NULL) {
1037 				errno = EINVAL;
1038 				goto out;
1039 			}
1040 			break;
1041 		}
1042 	}
1043 
1044 	/*
1045 	 * Otherwise, search for this event in all compatible PMC
1046 	 * classes.
1047 	 */
1048 	for (n = 0; ev == NULL && n < PMC_CLASS_TABLE_SIZE; n++) {
1049 		pcd = pmc_class_table[n];
1050 		if (pcd != NULL)
1051 			ev = pmc_match_event_class(ctrname, pcd);
1052 	}
1053 
1054 	if (ev == NULL) {
1055 		errno = EINVAL;
1056 		goto out;
1057 	}
1058 
1059 	pmc_config.pm_ev    = ev->pm_ev_code;
1060 	pmc_config.pm_class = pcd->pm_evc_class;
1061 
1062  	if (pcd->pm_evc_allocate_pmc(ev->pm_ev_code, r, &pmc_config) < 0) {
1063 		errno = EINVAL;
1064 		goto out;
1065 	}
1066 
1067 found:
1068 	if (PMC_CALL(PMCALLOCATE, &pmc_config) == 0) {
1069 		*pmcid = pmc_config.pm_pmcid;
1070 		retval = 0;
1071 	}
1072 out:
1073 	if (spec_copy)
1074 		free(spec_copy);
1075 
1076 	return (retval);
1077 }
1078 
1079 int
1080 pmc_attach(pmc_id_t pmc, pid_t pid)
1081 {
1082 	struct pmc_op_pmcattach pmc_attach_args;
1083 
1084 	pmc_attach_args.pm_pmc = pmc;
1085 	pmc_attach_args.pm_pid = pid;
1086 
1087 	return (PMC_CALL(PMCATTACH, &pmc_attach_args));
1088 }
1089 
1090 int
1091 pmc_capabilities(pmc_id_t pmcid, uint32_t *caps)
1092 {
1093 	unsigned int i;
1094 	enum pmc_class cl;
1095 
1096 	cl = PMC_ID_TO_CLASS(pmcid);
1097 	for (i = 0; i < cpu_info.pm_nclass; i++)
1098 		if (cpu_info.pm_classes[i].pm_class == cl) {
1099 			*caps = cpu_info.pm_classes[i].pm_caps;
1100 			return (0);
1101 		}
1102 	errno = EINVAL;
1103 	return (-1);
1104 }
1105 
1106 int
1107 pmc_configure_logfile(int fd)
1108 {
1109 	struct pmc_op_configurelog cla;
1110 
1111 	cla.pm_logfd = fd;
1112 	if (PMC_CALL(CONFIGURELOG, &cla) < 0)
1113 		return (-1);
1114 	return (0);
1115 }
1116 
1117 int
1118 pmc_cpuinfo(const struct pmc_cpuinfo **pci)
1119 {
1120 	if (pmc_syscall == -1) {
1121 		errno = ENXIO;
1122 		return (-1);
1123 	}
1124 
1125 	*pci = &cpu_info;
1126 	return (0);
1127 }
1128 
1129 int
1130 pmc_detach(pmc_id_t pmc, pid_t pid)
1131 {
1132 	struct pmc_op_pmcattach pmc_detach_args;
1133 
1134 	pmc_detach_args.pm_pmc = pmc;
1135 	pmc_detach_args.pm_pid = pid;
1136 	return (PMC_CALL(PMCDETACH, &pmc_detach_args));
1137 }
1138 
1139 int
1140 pmc_disable(int cpu, int pmc)
1141 {
1142 	struct pmc_op_pmcadmin ssa;
1143 
1144 	ssa.pm_cpu = cpu;
1145 	ssa.pm_pmc = pmc;
1146 	ssa.pm_state = PMC_STATE_DISABLED;
1147 	return (PMC_CALL(PMCADMIN, &ssa));
1148 }
1149 
1150 int
1151 pmc_enable(int cpu, int pmc)
1152 {
1153 	struct pmc_op_pmcadmin ssa;
1154 
1155 	ssa.pm_cpu = cpu;
1156 	ssa.pm_pmc = pmc;
1157 	ssa.pm_state = PMC_STATE_FREE;
1158 	return (PMC_CALL(PMCADMIN, &ssa));
1159 }
1160 
1161 /*
1162  * Return a list of events known to a given PMC class.  'cl' is the
1163  * PMC class identifier, 'eventnames' is the returned list of 'const
1164  * char *' pointers pointing to the names of the events. 'nevents' is
1165  * the number of event name pointers returned.
1166  *
1167  * The space for 'eventnames' is allocated using malloc(3).  The caller
1168  * is responsible for freeing this space when done.
1169  */
1170 int
1171 pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
1172     int *nevents)
1173 {
1174 	int count;
1175 	const char **names;
1176 	const struct pmc_event_descr *ev;
1177 
1178 	switch (cl)
1179 	{
1180 	case PMC_CLASS_IAF:
1181 		ev = iaf_event_table;
1182 		count = PMC_EVENT_TABLE_SIZE(iaf);
1183 		break;
1184 	case PMC_CLASS_TSC:
1185 		ev = tsc_event_table;
1186 		count = PMC_EVENT_TABLE_SIZE(tsc);
1187 		break;
1188 	case PMC_CLASS_K8:
1189 		ev = k8_event_table;
1190 		count = PMC_EVENT_TABLE_SIZE(k8);
1191 		break;
1192 	case PMC_CLASS_ARMV7:
1193 		switch (cpu_info.pm_cputype) {
1194 		default:
1195 		case PMC_CPU_ARMV7_CORTEX_A8:
1196 			ev = cortex_a8_event_table;
1197 			count = PMC_EVENT_TABLE_SIZE(cortex_a8);
1198 			break;
1199 		case PMC_CPU_ARMV7_CORTEX_A9:
1200 			ev = cortex_a9_event_table;
1201 			count = PMC_EVENT_TABLE_SIZE(cortex_a9);
1202 			break;
1203 		}
1204 		break;
1205 	case PMC_CLASS_ARMV8:
1206 		switch (cpu_info.pm_cputype) {
1207 		default:
1208 		case PMC_CPU_ARMV8_CORTEX_A53:
1209 			ev = cortex_a53_event_table;
1210 			count = PMC_EVENT_TABLE_SIZE(cortex_a53);
1211 			break;
1212 		case PMC_CPU_ARMV8_CORTEX_A57:
1213 			ev = cortex_a57_event_table;
1214 			count = PMC_EVENT_TABLE_SIZE(cortex_a57);
1215 			break;
1216 		case PMC_CPU_ARMV8_CORTEX_A76:
1217 			ev = cortex_a76_event_table;
1218 			count = PMC_EVENT_TABLE_SIZE(cortex_a76);
1219 			break;
1220 		}
1221 		break;
1222 	case PMC_CLASS_BERI:
1223 		ev = beri_event_table;
1224 		count = PMC_EVENT_TABLE_SIZE(beri);
1225 		break;
1226 	case PMC_CLASS_MIPS24K:
1227 		ev = mips24k_event_table;
1228 		count = PMC_EVENT_TABLE_SIZE(mips24k);
1229 		break;
1230 	case PMC_CLASS_MIPS74K:
1231 		ev = mips74k_event_table;
1232 		count = PMC_EVENT_TABLE_SIZE(mips74k);
1233 		break;
1234 	case PMC_CLASS_OCTEON:
1235 		ev = octeon_event_table;
1236 		count = PMC_EVENT_TABLE_SIZE(octeon);
1237 		break;
1238 	case PMC_CLASS_PPC7450:
1239 		ev = ppc7450_event_table;
1240 		count = PMC_EVENT_TABLE_SIZE(ppc7450);
1241 		break;
1242 	case PMC_CLASS_PPC970:
1243 		ev = ppc970_event_table;
1244 		count = PMC_EVENT_TABLE_SIZE(ppc970);
1245 		break;
1246 	case PMC_CLASS_POWER8:
1247 		ev = power8_event_table;
1248 		count = PMC_EVENT_TABLE_SIZE(power8);
1249 		break;
1250 	case PMC_CLASS_E500:
1251 		ev = e500_event_table;
1252 		count = PMC_EVENT_TABLE_SIZE(e500);
1253 		break;
1254 	case PMC_CLASS_SOFT:
1255 		ev = soft_event_table;
1256 		count = soft_event_info.pm_nevent;
1257 		break;
1258 	default:
1259 		errno = EINVAL;
1260 		return (-1);
1261 	}
1262 
1263 	if ((names = malloc(count * sizeof(const char *))) == NULL)
1264 		return (-1);
1265 
1266 	*eventnames = names;
1267 	*nevents = count;
1268 
1269 	for (;count--; ev++, names++)
1270 		*names = ev->pm_ev_name;
1271 
1272 	return (0);
1273 }
1274 
1275 int
1276 pmc_flush_logfile(void)
1277 {
1278 	return (PMC_CALL(FLUSHLOG,0));
1279 }
1280 
1281 int
1282 pmc_close_logfile(void)
1283 {
1284 	return (PMC_CALL(CLOSELOG,0));
1285 }
1286 
1287 int
1288 pmc_get_driver_stats(struct pmc_driverstats *ds)
1289 {
1290 	struct pmc_op_getdriverstats gms;
1291 
1292 	if (PMC_CALL(GETDRIVERSTATS, &gms) < 0)
1293 		return (-1);
1294 
1295 	/* copy out fields in the current userland<->library interface */
1296 	ds->pm_intr_ignored    = gms.pm_intr_ignored;
1297 	ds->pm_intr_processed  = gms.pm_intr_processed;
1298 	ds->pm_intr_bufferfull = gms.pm_intr_bufferfull;
1299 	ds->pm_syscalls        = gms.pm_syscalls;
1300 	ds->pm_syscall_errors  = gms.pm_syscall_errors;
1301 	ds->pm_buffer_requests = gms.pm_buffer_requests;
1302 	ds->pm_buffer_requests_failed = gms.pm_buffer_requests_failed;
1303 	ds->pm_log_sweeps      = gms.pm_log_sweeps;
1304 	return (0);
1305 }
1306 
1307 int
1308 pmc_get_msr(pmc_id_t pmc, uint32_t *msr)
1309 {
1310 	struct pmc_op_getmsr gm;
1311 
1312 	gm.pm_pmcid = pmc;
1313 	if (PMC_CALL(PMCGETMSR, &gm) < 0)
1314 		return (-1);
1315 	*msr = gm.pm_msr;
1316 	return (0);
1317 }
1318 
1319 int
1320 pmc_init(void)
1321 {
1322 	int error, pmc_mod_id;
1323 	unsigned int n;
1324 	uint32_t abi_version;
1325 	struct module_stat pmc_modstat;
1326 	struct pmc_op_getcpuinfo op_cpu_info;
1327 
1328 	if (pmc_syscall != -1) /* already inited */
1329 		return (0);
1330 
1331 	/* retrieve the system call number from the KLD */
1332 	if ((pmc_mod_id = modfind(PMC_MODULE_NAME)) < 0)
1333 		return (-1);
1334 
1335 	pmc_modstat.version = sizeof(struct module_stat);
1336 	if ((error = modstat(pmc_mod_id, &pmc_modstat)) < 0)
1337 		return (-1);
1338 
1339 	pmc_syscall = pmc_modstat.data.intval;
1340 
1341 	/* check the kernel module's ABI against our compiled-in version */
1342 	abi_version = PMC_VERSION;
1343 	if (PMC_CALL(GETMODULEVERSION, &abi_version) < 0)
1344 		return (pmc_syscall = -1);
1345 
1346 	/* ignore patch & minor numbers for the comparison */
1347 	if ((abi_version & 0xFF000000) != (PMC_VERSION & 0xFF000000)) {
1348 		errno  = EPROGMISMATCH;
1349 		return (pmc_syscall = -1);
1350 	}
1351 
1352 	bzero(&op_cpu_info, sizeof(op_cpu_info));
1353 	if (PMC_CALL(GETCPUINFO, &op_cpu_info) < 0)
1354 		return (pmc_syscall = -1);
1355 
1356 	cpu_info.pm_cputype = op_cpu_info.pm_cputype;
1357 	cpu_info.pm_ncpu    = op_cpu_info.pm_ncpu;
1358 	cpu_info.pm_npmc    = op_cpu_info.pm_npmc;
1359 	cpu_info.pm_nclass  = op_cpu_info.pm_nclass;
1360 	for (n = 0; n < op_cpu_info.pm_nclass; n++)
1361 		memcpy(&cpu_info.pm_classes[n], &op_cpu_info.pm_classes[n],
1362 		    sizeof(cpu_info.pm_classes[n]));
1363 
1364 	pmc_class_table = malloc(PMC_CLASS_TABLE_SIZE *
1365 	    sizeof(struct pmc_class_descr *));
1366 
1367 	if (pmc_class_table == NULL)
1368 		return (-1);
1369 
1370 	for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++)
1371 		pmc_class_table[n] = NULL;
1372 
1373 	/*
1374 	 * Get soft events list.
1375 	 */
1376 	soft_event_info.pm_class = PMC_CLASS_SOFT;
1377 	if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0)
1378 		return (pmc_syscall = -1);
1379 
1380 	/* Map soft events to static list. */
1381 	for (n = 0; n < soft_event_info.pm_nevent; n++) {
1382 		soft_event_table[n].pm_ev_name =
1383 		    soft_event_info.pm_events[n].pm_ev_name;
1384 		soft_event_table[n].pm_ev_code =
1385 		    soft_event_info.pm_events[n].pm_ev_code;
1386 	}
1387 	soft_class_table_descr.pm_evc_event_table_size = \
1388 	    soft_event_info.pm_nevent;
1389 	soft_class_table_descr.pm_evc_event_table = \
1390 	    soft_event_table;
1391 
1392 	/*
1393 	 * Fill in the class table.
1394 	 */
1395 	n = 0;
1396 
1397 	/* Fill soft events information. */
1398 	pmc_class_table[n++] = &soft_class_table_descr;
1399 #if defined(__amd64__) || defined(__i386__)
1400 	if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
1401 		pmc_class_table[n++] = &tsc_class_table_descr;
1402 #endif
1403 
1404 #define	PMC_MDEP_INIT(C) pmc_mdep_event_aliases = C##_aliases
1405 
1406 	/* Configure the event name parser. */
1407 	switch (cpu_info.pm_cputype) {
1408 #if defined(__amd64__) || defined(__i386__)
1409 	case PMC_CPU_AMD_K8:
1410 		PMC_MDEP_INIT(k8);
1411 		pmc_class_table[n] = &k8_class_table_descr;
1412 		break;
1413 #endif
1414 	case PMC_CPU_GENERIC:
1415 		PMC_MDEP_INIT(generic);
1416 		break;
1417 #if defined(__arm__)
1418 	case PMC_CPU_ARMV7_CORTEX_A8:
1419 		PMC_MDEP_INIT(cortex_a8);
1420 		pmc_class_table[n] = &cortex_a8_class_table_descr;
1421 		break;
1422 	case PMC_CPU_ARMV7_CORTEX_A9:
1423 		PMC_MDEP_INIT(cortex_a9);
1424 		pmc_class_table[n] = &cortex_a9_class_table_descr;
1425 		break;
1426 #endif
1427 #if defined(__aarch64__)
1428 	case PMC_CPU_ARMV8_CORTEX_A53:
1429 		PMC_MDEP_INIT(cortex_a53);
1430 		pmc_class_table[n] = &cortex_a53_class_table_descr;
1431 		break;
1432 	case PMC_CPU_ARMV8_CORTEX_A57:
1433 		PMC_MDEP_INIT(cortex_a57);
1434 		pmc_class_table[n] = &cortex_a57_class_table_descr;
1435 		break;
1436 	case PMC_CPU_ARMV8_CORTEX_A76:
1437 		PMC_MDEP_INIT(cortex_a76);
1438 		pmc_class_table[n] = &cortex_a76_class_table_descr;
1439 		break;
1440 #endif
1441 #if defined(__mips__)
1442 	case PMC_CPU_MIPS_BERI:
1443 		PMC_MDEP_INIT(beri);
1444 		pmc_class_table[n] = &beri_class_table_descr;
1445 		break;
1446 	case PMC_CPU_MIPS_24K:
1447 		PMC_MDEP_INIT(mips24k);
1448 		pmc_class_table[n] = &mips24k_class_table_descr;
1449 		break;
1450 	case PMC_CPU_MIPS_74K:
1451 		PMC_MDEP_INIT(mips74k);
1452 		pmc_class_table[n] = &mips74k_class_table_descr;
1453 		break;
1454 	case PMC_CPU_MIPS_OCTEON:
1455 		PMC_MDEP_INIT(octeon);
1456 		pmc_class_table[n] = &octeon_class_table_descr;
1457 		break;
1458 #endif /* __mips__ */
1459 #if defined(__powerpc__)
1460 	case PMC_CPU_PPC_7450:
1461 		PMC_MDEP_INIT(ppc7450);
1462 		pmc_class_table[n] = &ppc7450_class_table_descr;
1463 		break;
1464 	case PMC_CPU_PPC_970:
1465 		PMC_MDEP_INIT(ppc970);
1466 		pmc_class_table[n] = &ppc970_class_table_descr;
1467 		break;
1468 	case PMC_CPU_PPC_POWER8:
1469 		PMC_MDEP_INIT(power8);
1470 		pmc_class_table[n] = &power8_class_table_descr;
1471 		break;
1472 	case PMC_CPU_PPC_E500:
1473 		PMC_MDEP_INIT(e500);
1474 		pmc_class_table[n] = &e500_class_table_descr;
1475 		break;
1476 #endif
1477 	default:
1478 		/*
1479 		 * Some kind of CPU this version of the library knows nothing
1480 		 * about.  This shouldn't happen since the abi version check
1481 		 * should have caught this.
1482 		 */
1483 #if defined(__amd64__) || defined(__i386__)
1484 		break;
1485 #endif
1486 		errno = ENXIO;
1487 		return (pmc_syscall = -1);
1488 	}
1489 
1490 	return (0);
1491 }
1492 
1493 const char *
1494 pmc_name_of_capability(enum pmc_caps cap)
1495 {
1496 	int i;
1497 
1498 	/*
1499 	 * 'cap' should have a single bit set and should be in
1500 	 * range.
1501 	 */
1502 	if ((cap & (cap - 1)) || cap < PMC_CAP_FIRST ||
1503 	    cap > PMC_CAP_LAST) {
1504 		errno = EINVAL;
1505 		return (NULL);
1506 	}
1507 
1508 	i = ffs(cap);
1509 	return (pmc_capability_names[i - 1]);
1510 }
1511 
1512 const char *
1513 pmc_name_of_class(enum pmc_class pc)
1514 {
1515 	size_t n;
1516 
1517 	for (n = 0; n < PMC_TABLE_SIZE(pmc_class_names); n++)
1518 		if (pc == pmc_class_names[n].pm_class)
1519 			return (pmc_class_names[n].pm_name);
1520 
1521 	errno = EINVAL;
1522 	return (NULL);
1523 }
1524 
1525 const char *
1526 pmc_name_of_cputype(enum pmc_cputype cp)
1527 {
1528 	size_t n;
1529 
1530 	for (n = 0; n < PMC_TABLE_SIZE(pmc_cputype_names); n++)
1531 		if (cp == pmc_cputype_names[n].pm_cputype)
1532 			return (pmc_cputype_names[n].pm_name);
1533 
1534 	errno = EINVAL;
1535 	return (NULL);
1536 }
1537 
1538 const char *
1539 pmc_name_of_disposition(enum pmc_disp pd)
1540 {
1541 	if ((int) pd >= PMC_DISP_FIRST &&
1542 	    pd <= PMC_DISP_LAST)
1543 		return (pmc_disposition_names[pd]);
1544 
1545 	errno = EINVAL;
1546 	return (NULL);
1547 }
1548 
1549 const char *
1550 _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
1551 {
1552 	const struct pmc_event_descr *ev, *evfence;
1553 
1554 	ev = evfence = NULL;
1555 	if (pe >= PMC_EV_K8_FIRST && pe <= PMC_EV_K8_LAST) {
1556 		ev = k8_event_table;
1557 		evfence = k8_event_table + PMC_EVENT_TABLE_SIZE(k8);
1558 
1559 	} else if (pe >= PMC_EV_ARMV7_FIRST && pe <= PMC_EV_ARMV7_LAST) {
1560 		switch (cpu) {
1561 		case PMC_CPU_ARMV7_CORTEX_A8:
1562 			ev = cortex_a8_event_table;
1563 			evfence = cortex_a8_event_table + PMC_EVENT_TABLE_SIZE(cortex_a8);
1564 			break;
1565 		case PMC_CPU_ARMV7_CORTEX_A9:
1566 			ev = cortex_a9_event_table;
1567 			evfence = cortex_a9_event_table + PMC_EVENT_TABLE_SIZE(cortex_a9);
1568 			break;
1569 		default:	/* Unknown CPU type. */
1570 			break;
1571 		}
1572 	} else if (pe >= PMC_EV_ARMV8_FIRST && pe <= PMC_EV_ARMV8_LAST) {
1573 		switch (cpu) {
1574 		case PMC_CPU_ARMV8_CORTEX_A53:
1575 			ev = cortex_a53_event_table;
1576 			evfence = cortex_a53_event_table + PMC_EVENT_TABLE_SIZE(cortex_a53);
1577 			break;
1578 		case PMC_CPU_ARMV8_CORTEX_A57:
1579 			ev = cortex_a57_event_table;
1580 			evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57);
1581 			break;
1582 		case PMC_CPU_ARMV8_CORTEX_A76:
1583 			ev = cortex_a76_event_table;
1584 			evfence = cortex_a76_event_table + PMC_EVENT_TABLE_SIZE(cortex_a76);
1585 			break;
1586 		default:	/* Unknown CPU type. */
1587 			break;
1588 		}
1589 	} else if (pe >= PMC_EV_BERI_FIRST && pe <= PMC_EV_BERI_LAST) {
1590 		ev = beri_event_table;
1591 		evfence = beri_event_table + PMC_EVENT_TABLE_SIZE(beri);
1592 	} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
1593 		ev = mips24k_event_table;
1594 		evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);
1595 	} else if (pe >= PMC_EV_MIPS74K_FIRST && pe <= PMC_EV_MIPS74K_LAST) {
1596 		ev = mips74k_event_table;
1597 		evfence = mips74k_event_table + PMC_EVENT_TABLE_SIZE(mips74k);
1598 	} else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) {
1599 		ev = octeon_event_table;
1600 		evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon);
1601 	} else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
1602 		ev = ppc7450_event_table;
1603 		evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
1604 	} else if (pe >= PMC_EV_PPC970_FIRST && pe <= PMC_EV_PPC970_LAST) {
1605 		ev = ppc970_event_table;
1606 		evfence = ppc970_event_table + PMC_EVENT_TABLE_SIZE(ppc970);
1607 	} else if (pe >= PMC_EV_POWER8_FIRST && pe <= PMC_EV_POWER8_LAST) {
1608 		ev = power8_event_table;
1609 		evfence = power8_event_table + PMC_EVENT_TABLE_SIZE(power8);
1610 	} else if (pe >= PMC_EV_E500_FIRST && pe <= PMC_EV_E500_LAST) {
1611 		ev = e500_event_table;
1612 		evfence = e500_event_table + PMC_EVENT_TABLE_SIZE(e500);
1613 	} else if (pe == PMC_EV_TSC_TSC) {
1614 		ev = tsc_event_table;
1615 		evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
1616 	} else if ((int)pe >= PMC_EV_SOFT_FIRST && (int)pe <= PMC_EV_SOFT_LAST) {
1617 		ev = soft_event_table;
1618 		evfence = soft_event_table + soft_event_info.pm_nevent;
1619 	}
1620 
1621 	for (; ev != evfence; ev++)
1622 		if (pe == ev->pm_ev_code)
1623 			return (ev->pm_ev_name);
1624 
1625 	return (NULL);
1626 }
1627 
1628 const char *
1629 pmc_name_of_event(enum pmc_event pe)
1630 {
1631 	const char *n;
1632 
1633 	if ((n = _pmc_name_of_event(pe, cpu_info.pm_cputype)) != NULL)
1634 		return (n);
1635 
1636 	errno = EINVAL;
1637 	return (NULL);
1638 }
1639 
1640 const char *
1641 pmc_name_of_mode(enum pmc_mode pm)
1642 {
1643 	if ((int) pm >= PMC_MODE_FIRST &&
1644 	    pm <= PMC_MODE_LAST)
1645 		return (pmc_mode_names[pm]);
1646 
1647 	errno = EINVAL;
1648 	return (NULL);
1649 }
1650 
1651 const char *
1652 pmc_name_of_state(enum pmc_state ps)
1653 {
1654 	if ((int) ps >= PMC_STATE_FIRST &&
1655 	    ps <= PMC_STATE_LAST)
1656 		return (pmc_state_names[ps]);
1657 
1658 	errno = EINVAL;
1659 	return (NULL);
1660 }
1661 
1662 int
1663 pmc_ncpu(void)
1664 {
1665 	if (pmc_syscall == -1) {
1666 		errno = ENXIO;
1667 		return (-1);
1668 	}
1669 
1670 	return (cpu_info.pm_ncpu);
1671 }
1672 
1673 int
1674 pmc_npmc(int cpu)
1675 {
1676 	if (pmc_syscall == -1) {
1677 		errno = ENXIO;
1678 		return (-1);
1679 	}
1680 
1681 	if (cpu < 0 || cpu >= (int) cpu_info.pm_ncpu) {
1682 		errno = EINVAL;
1683 		return (-1);
1684 	}
1685 
1686 	return (cpu_info.pm_npmc);
1687 }
1688 
1689 int
1690 pmc_pmcinfo(int cpu, struct pmc_pmcinfo **ppmci)
1691 {
1692 	int nbytes, npmc;
1693 	struct pmc_op_getpmcinfo *pmci;
1694 
1695 	if ((npmc = pmc_npmc(cpu)) < 0)
1696 		return (-1);
1697 
1698 	nbytes = sizeof(struct pmc_op_getpmcinfo) +
1699 	    npmc * sizeof(struct pmc_info);
1700 
1701 	if ((pmci = calloc(1, nbytes)) == NULL)
1702 		return (-1);
1703 
1704 	pmci->pm_cpu  = cpu;
1705 
1706 	if (PMC_CALL(GETPMCINFO, pmci) < 0) {
1707 		free(pmci);
1708 		return (-1);
1709 	}
1710 
1711 	/* kernel<->library, library<->userland interfaces are identical */
1712 	*ppmci = (struct pmc_pmcinfo *) pmci;
1713 	return (0);
1714 }
1715 
1716 int
1717 pmc_read(pmc_id_t pmc, pmc_value_t *value)
1718 {
1719 	struct pmc_op_pmcrw pmc_read_op;
1720 
1721 	pmc_read_op.pm_pmcid = pmc;
1722 	pmc_read_op.pm_flags = PMC_F_OLDVALUE;
1723 	pmc_read_op.pm_value = -1;
1724 
1725 	if (PMC_CALL(PMCRW, &pmc_read_op) < 0)
1726 		return (-1);
1727 
1728 	*value = pmc_read_op.pm_value;
1729 	return (0);
1730 }
1731 
1732 int
1733 pmc_release(pmc_id_t pmc)
1734 {
1735 	struct pmc_op_simple	pmc_release_args;
1736 
1737 	pmc_release_args.pm_pmcid = pmc;
1738 	return (PMC_CALL(PMCRELEASE, &pmc_release_args));
1739 }
1740 
1741 int
1742 pmc_rw(pmc_id_t pmc, pmc_value_t newvalue, pmc_value_t *oldvaluep)
1743 {
1744 	struct pmc_op_pmcrw pmc_rw_op;
1745 
1746 	pmc_rw_op.pm_pmcid = pmc;
1747 	pmc_rw_op.pm_flags = PMC_F_NEWVALUE | PMC_F_OLDVALUE;
1748 	pmc_rw_op.pm_value = newvalue;
1749 
1750 	if (PMC_CALL(PMCRW, &pmc_rw_op) < 0)
1751 		return (-1);
1752 
1753 	*oldvaluep = pmc_rw_op.pm_value;
1754 	return (0);
1755 }
1756 
1757 int
1758 pmc_set(pmc_id_t pmc, pmc_value_t value)
1759 {
1760 	struct pmc_op_pmcsetcount sc;
1761 
1762 	sc.pm_pmcid = pmc;
1763 	sc.pm_count = value;
1764 
1765 	if (PMC_CALL(PMCSETCOUNT, &sc) < 0)
1766 		return (-1);
1767 	return (0);
1768 }
1769 
1770 int
1771 pmc_start(pmc_id_t pmc)
1772 {
1773 	struct pmc_op_simple	pmc_start_args;
1774 
1775 	pmc_start_args.pm_pmcid = pmc;
1776 	return (PMC_CALL(PMCSTART, &pmc_start_args));
1777 }
1778 
1779 int
1780 pmc_stop(pmc_id_t pmc)
1781 {
1782 	struct pmc_op_simple	pmc_stop_args;
1783 
1784 	pmc_stop_args.pm_pmcid = pmc;
1785 	return (PMC_CALL(PMCSTOP, &pmc_stop_args));
1786 }
1787 
1788 int
1789 pmc_width(pmc_id_t pmcid, uint32_t *width)
1790 {
1791 	unsigned int i;
1792 	enum pmc_class cl;
1793 
1794 	cl = PMC_ID_TO_CLASS(pmcid);
1795 	for (i = 0; i < cpu_info.pm_nclass; i++)
1796 		if (cpu_info.pm_classes[i].pm_class == cl) {
1797 			*width = cpu_info.pm_classes[i].pm_width;
1798 			return (0);
1799 		}
1800 	errno = EINVAL;
1801 	return (-1);
1802 }
1803 
1804 int
1805 pmc_write(pmc_id_t pmc, pmc_value_t value)
1806 {
1807 	struct pmc_op_pmcrw pmc_write_op;
1808 
1809 	pmc_write_op.pm_pmcid = pmc;
1810 	pmc_write_op.pm_flags = PMC_F_NEWVALUE;
1811 	pmc_write_op.pm_value = value;
1812 	return (PMC_CALL(PMCRW, &pmc_write_op));
1813 }
1814 
1815 int
1816 pmc_writelog(uint32_t userdata)
1817 {
1818 	struct pmc_op_writelog wl;
1819 
1820 	wl.pm_userdata = userdata;
1821 	return (PMC_CALL(WRITELOG, &wl));
1822 }
1823